diff options
322 files changed, 47322 insertions, 0 deletions
@@ -0,0 +1,132 @@ +DOXYGEN Version 0.49-990425 + +INSTALLATION INSTRUCTIONS FOR UNIX: +----------------------------------- + +1. Unpack the archive, unless you already have: + + gunzip doxygen-0.49-990425.src.tar.gz # uncompress the archive + tar xf doxygen-0.49-990425.src.tar # unpack it + +2. Make sure Qt is installed properly (check the environment variable $QTDIR) + + Note: on some systems (like FreeBSD) it is possible that qt is not + installed in one single directory. In this case I suggest to create a + local qt directory to which the QTDIR variable should point. Then + create two links in that directory like this: + ln -s <location_of_the_qt_includes> include + ln -s <location_of_the_qt_libs> lib + +3. Look at the first two entries of Makefile.config and modify them if needed. + Note: Doxygen requires GNU make to build. On some systems this is + known as gmake. If you have such a system, you must edit Makefile.config + and replace make by gmake in rest of this document. + +4. Compile the program. + + Type: + + make + + You'll see a list of all supported platforms/compiler combinations. + + To build for the Linux platform with g++ as the compiler for example, type: + + make linux-g++ + + The program should compile without problems and three binaries (doxygen, + doxytag, and doxysearch) should be available in the bin directory of the + distribution. + +5. Generate the user manual. + + type: + + make docs + + to let doxygen generate the HTML and LaTeX documentation. + (you will need the stream editor `sed' for this) + + type: + + make ps + + to generate a postscript version of the manual. + (you will need latex and dvips for this) + + The html directory of the distribution will now contain the html + documentation (just point a HTML browser to the file index.html in the + html directory). + + The postscript manual doxygen_manual.ps will be located in the latex + directory of the distribution. Just send it to a postscript printer to + print it or use ghostview to view it. + +INSTALLATION INSTRUCTIONS FOR WINDOWS: +-------------------------------------- + +Currently, only Microsoft Visual C++ version 5.0 is supported. For other +platforms you may need to edit the Makefiles a bit. Let me know what you +had to change if you got Doxygen working with another windows compiler. + +You will need to install the windows/dos versions of following tools: +- Perl 5.0+ +- flex (you can use the DJGPP version) +- bison (you can use the DJGPP version, but you need to copy + lib\bison.sim to c:\djgpp\lib\bison.simple and + lib\bison.hai to c:\djgpp\lib\bison.hairy. + The paths seem to be hardcoded in the executable) +- Qt (Hint: only the tools section is required, so you can use the free + X-windows version as well!) +- Microsoft Visual C++ version 5.0, use the vcvars32.bat to set the environment + variables. + +Make sure all tools are accessible from the command-line. + +Open a dos box, goto the doxygen root dir and type: + +make.bat + +This should build the executables doxygen.exe, doxytag.exe, and doxysearch.exe +(The compiler should not produce any warnings or errors). + +To build the examples type: + +nmake -f Makefile.windows examples + +----------------------------------------------------------------------------- +KNOWN CONFIGURATION PROBLEMS + +LATEX RELATED PROBLEMS: + +- the LaTeX translation of HTML tables doesn't seem to work for all + compilers. It is known to work for teTeX (versions 0.4 and 0.9) +- the file a4wide.sty is not available for all distributions. If + your distribution does not have it please select another paper type + in the config file (see PAPER_TYPE) +- the file fancyheader.sty is known as fancyhdr.sty on some systems. + Please change that in src/latexgen.cpp + +HP-UX PROBLEMS: +- If you are compiling for HP-UX with aCC and you get this error: + /opt/aCC/lbin/ld: Unsatisfied symbols: + alloca (code) + then you should edit ce_parse.cpp and replace + extern "C" { + void *alloca (unsigned int); + }; + with + #include <alloca.h> + This seems to be a problem with bison, but I don't know how to fix it. +----------------------------------------------------------------------------- + +That's it! + +Please report any problems to dimitri@stack.nl + +The latest version of doxygen can be obtained at + http://www.stack.nl/~dimitri/doxygen + +Enjoy, + +Dimitri van Heesch (25 April 1999) diff --git a/LANGUAGE.HOWTO b/LANGUAGE.HOWTO new file mode 100644 index 0000000..21cc9c2 --- /dev/null +++ b/LANGUAGE.HOWTO @@ -0,0 +1,49 @@ +This short howto explains how to add support for a new language to Doxygen: + +Just follow these steps: + +1) 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. I'll create a + list on Doxygen's homepage, so everyone knows who is doing what. +2) Create a copy of translator_nl.h and name it + translator_<your_2_letter_counter_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 doxygen.pro and add translator_xx.h to the HEADERS line in the + file doxygen.pro. +5) Edit translator_xx.h: + - Rename TRANSLATOR_NL_H to TRANSLATOR_XX_H twice. + - Rename TranslatorDutch to TranslatorYourlanguage + - In the member latexBabelPackage() change "dutch" into the name of the + latex package that adds support for your language. + - Edit all the strings that are returned by the members that start + with tr. + Look at the corresponding member in translator.h for the english text + that is returned and translate that into your language. + 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. + b) Use html codes like ä for an a with an umlaut. + See the HTML specification for the codes. +6) Recompile everything (do this from the root of the distribution, + because the Makefile.dox* have to be regenerated!) +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 or a diff -u of the changes to me so I can add it + to doxygen. + +Good luck, and let me know if there are problems. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..037c87a --- /dev/null +++ b/Makefile @@ -0,0 +1,178 @@ +# this Makefile need GNU make + +include Makefile.config + +variables: Makefile + @echo + @echo "Select one of the following targets:" + @echo + @echo "aix-g++ aix-xlc " + @echo "dgux-g++ freebsd-g++ " + @echo "gnu-g++ hpux-acc " + @echo "hpux-cc hpux-g++ " + @echo "irix-64 irix-dcc " + @echo "irix-g++ irix-n32 " + @echo "linux-g++ netbsd-g++ " + @echo "openbsd-g++ osf1-cxx " + @echo "osf1-g++ qnx-g++ " + @echo "sco-g++ solaris-cc " + @echo "solaris-g++ sunos-g++ " + @echo "ultrix-g++ unixware-g++ " + @echo + @echo "Make any of them to build Doxygen." + @echo "Make will now abort with an error." + @exit 1 + +aix-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/aix-g++ \ + $(MAKE) + +aix-xlc: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/aix-xlc \ + $(MAKE) + +dgux-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/dgux-g++ \ + $(MAKE) + +freebsd-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/freebsd-g++ \ + $(MAKE) + +hpux-acc: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/hpux-acc \ + $(MAKE) + +hpux-cc: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/hpux-cc \ + $(MAKE) + +hpux-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/hpux-g++ \ + $(MAKE) + +irix-64: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/irix-64 \ + $(MAKE) + +irix-dcc: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/irix-dcc \ + $(MAKE) + +irix-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/irix-g++ \ + $(MAKE) + +irix-n32: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/irix-n32 \ + $(MAKE) + +linux-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/linux-g++ \ + $(MAKE) + +netbsd-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/netbsd-g++ \ + $(MAKE) + +openbsd-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/openbsd-g++ \ + $(MAKE) + +osf1-cxx: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/osf1-cxx \ + $(MAKE) + +osf1-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/osf1-g++ \ + $(MAKE) + +qnx-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/qnx-g++ \ + $(MAKE) + +sco-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/sco-g++ \ + $(MAKE) + +solaris-cc: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/solaris-cc \ + $(MAKE) + +solaris-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/solaris-g++ \ + $(MAKE) + +sunos-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/sunos-g++ \ + $(MAKE) + +ultrix-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/ultrix-g++ \ + $(MAKE) + +unixware-g++: src/version.cpp + cd src; \ + TMAKEPATH=../tmake/lib/unixware-g++ \ + $(MAKE) + + +clean: FORCE + cd examples ; $(MAKE) clean + cd doc ; $(MAKE) clean + -rm -f src/scanner.cpp \ + src/code.cpp \ + src/config.cpp \ + src/pre.cpp \ + src/tag.cpp \ + src/ce_lex.cpp \ + src/ce_parse.cpp \ + src/ce_parse.h \ + src/doxytag.cpp \ + src/declinfo.cpp \ + src/defargs.cpp \ + src/Makefile.doxygen \ + src/Makefile.doxytag \ + src/Makefile.doxysearch \ + src/version.cpp + -rm -f bin/doxy* + -rm -f objects/*.o + +docs: FORCE + cd examples ; $(MAKE) + cd doc ; $(MAKE) + +ps: docs + cd latex ; $(MAKE) + +archive: clean + $(TAR) zcvf backup/dx`date +%y%m%d`.tgz tmake doc examples bin objects \ + src Makefile Makefile.windows INSTALL make.bat Makefile.config \ + LANGUAGE.HOWTO + +src/version.cpp: FORCE + echo "char versionString[]=\"$(VERSION)\";" > src/version.cpp + +FORCE: diff --git a/Makefile.config b/Makefile.config new file mode 100644 index 0000000..0492810 --- /dev/null +++ b/Makefile.config @@ -0,0 +1,12 @@ +# name (and path if needed) of the make tool to use +# note that make must really be GNU make, not BSD or some other make +MAKE = make + +# name (and path if needed) of the perl interpreter +# note that it must be version 5 or higher (check with perl -v) +PERL = perl + +# The values below should probably be left unmodified +TAR = tar # name of the GNU tar tool +TMAKE = ../tmake/bin/tmake +VERSION = 0.49-990425 diff --git a/Makefile.windows b/Makefile.windows new file mode 100644 index 0000000..a662b2e --- /dev/null +++ b/Makefile.windows @@ -0,0 +1,57 @@ +# Makefile for Microsoft Visual C++ + +include Makefile.config + +MAKE = nmake /NOLOGO +TMAKE = ..\tmake\bin\tmake + +all: + @echo " + @echo " Select one of the following targets: " + @echo " " + @echo " win32-msvc " + @echo " " + @echo " Make any of them to build Doxygen. " + @echo " Make will now abort with an error. " + @exit 1 + +win32-msvc: src\version.cpp + cd src + $(MAKE) tmake TMAKE=$(TMAKE) PERL=$(PERL) + $(MAKE) MAKE=$(MAKE) + +clean: FORCE + cd examples + $(MAKE) -f Makefile.windows clean + cd .. + -del src\scanner.cpp + -del src\code.cpp + -del src\config.cpp + -del src\pre.cpp + -del src\tag.cpp + -del src\constexp.lex.cpp + -del src\constexp.parse.cpp + -del src\constexp.parse.h + -del src\doxytag.cpp + -del src\declinfo.cpp + -del src\defargs.cpp + -del src\Makefile.doxygen + -del src\Makefile.doxytag + -del src\Makefile.doxysearch + -del src\version.cpp + -del bin\doxy*.* + -del objects\*.obj + +examples: FORCE + cd examples + $(MAKE) -f Makefile.windows + cd .. + +docs: examples + @echo Docs cannot be made using windows yet. + @echo Get them from the binary distribution... + +src\version.cpp: + echo char versionString[]="$(VERSION)"; >src\version.cpp + +FORCE: @@ -0,0 +1,10 @@ +DOXYGEN Version 0.49-990425 + +Please read INSTALL for compilation instructions. + +The latest version of doxygen can be obtained at + http://www.stack.nl/~dimitri/doxygen + +Enjoy, + +Dimitri van Heesch (25 April 1999) diff --git a/doc/Doxyfile b/doc/Doxyfile new file mode 100644 index 0000000..79cbb31 --- /dev/null +++ b/doc/Doxyfile @@ -0,0 +1,30 @@ +PROJECT_NAME = +OUTPUT_DIRECTORY = .. +HTML_HEADER = +HTML_FOOTER = +QUIET = NO +WARNINGS = YES +DISABLE_INDEX = YES +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +GENERATE_LATEX = YES +GENERATE_HTML = YES +ENABLE_PREPROCESSING = NO +INPUT = index.doc install.doc starting.doc trouble.doc \ + history.doc features.doc \ + doxygen_usage.doc doxytag_usage.doc doxysearch_usage.doc \ + installdox_usage.doc autolink.doc \ + config.doc commands.doc htmlcmds.doc +FILE_PATTERNS = *.cpp *.h *.doc +EXAMPLE_PATH = ../examples +RECURSIVE = NO +TAGFILES = +ALLEXTERNALS = NO +PERL_PATH = /usr/local/bin/perl +SEARCHENGINE = NO +CGI_NAME = search.cgi +CGI_URL = +DOC_URL = +DOC_ABSPATH = +BIN_ABSPATH = /usr/local/bin/ +EXT_DOC_PATHS = diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..953517a --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,22 @@ +include ../Makefile.config + +DOXYDIR=../bin +DOXYGEN_DOCDIR=.. + +all: FORCE + DOXYGEN_DOCDIR=$(DOXYGEN_DOCDIR); \ + export DOXYGEN_DOCDIR; \ + VERSION=$(VERSION) ; \ + export VERSION; \ + $(DOXYDIR)/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 + @cp doxygen_logo.eps ../latex + +clean: + rm -rf ../html ../latex + +FORCE: diff --git a/doc/Makefile.latex b/doc/Makefile.latex new file mode 100644 index 0000000..7ab03a3 --- /dev/null +++ b/doc/Makefile.latex @@ -0,0 +1,14 @@ +all: doxygen_manual.ps + +doxygen_manual.ps: doxygen_manual.dvi + dvips -o doxygen_manual.ps doxygen_manual.dvi + +doxygen_manual.dvi: doxygen_manual.tex doxygen.sty + echo "Running latex..." + latex doxygen_manual.tex + echo "Running makeindex..." + makeindex doxygen_manual.idx + echo "Rerunning latex...." + latex doxygen_manual.tex +clean: + rm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log diff --git a/doc/autolink.doc b/doc/autolink.doc new file mode 100644 index 0000000..b0f0fa4 --- /dev/null +++ b/doc/autolink.doc @@ -0,0 +1,125 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ +/*! \page autolink Automatic link generation + + 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), it does allow you to put these kind of links anywhere in the + documentation. + For \f$\mbox{\LaTeX}\f$ 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. + + \subsection linkclass Links to classes. + + All words in the documentation that correspond to a documented class + 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. + + \subsection 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. + + \subsection 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\>"()"</tt> + <li><tt>(\<className\>"::")<sup>n</sup>\<functionName\></tt> + </ol> + where n>0. + + \par Notice 1: + The patterns above should not contain spaces, tabs or newlines. + \par Notice 2: + For JavaDoc compatibility a \c # may be used instead of a \c :: in + the patterns above. + + 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 5 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 6) 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> + + \subsection linkother Links to variables, typedefs, enum types, enum values and defines. + + 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 6 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 + + \subsection resolving Resolving of defines and typedefs. + + Macro definitions of the form: +\verbatim +#define TypeName ClassName +\endverbatim + will be resolved inside documentation blocks. + + \par Example: + \verbinclude resdefine.cpp + \htmlonly + Click <a href="$(DOXYGEN_DOCDIR)/examples/resdefine/html/exportedname.html">here</a> + for the corresponding HTML documentation that is generated by Doxygen. + \endhtmlonly + + 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.cpp.html">here</a> + for the corresponding HTML documentation that is generated by Doxygen. + \endhtmlonly + +*/ diff --git a/doc/commands.doc b/doc/commands.doc new file mode 100644 index 0000000..c288be7 --- /dev/null +++ b/doc/commands.doc @@ -0,0 +1,1075 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ +/*! \page commands + +\section commands Special Commands + +All commands in the documentation start with a backslash (<b>\\</b>) or an +at-sign (<b>\@</b>). +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 [square] brackets are used the argument is optional. + +Here is an alphabetically sorted list of all commands with references to their +documentation: +\htmlonly +<multicol cols=4> +<ul> +\endhtmlonly +\latexonly +\begin{multicols}{3} +\begin{CompactList} +\endlatexonly +<li> \refitem cmda \a +<li> \refitem cmdaddindex \addindex +<li> \refitem cmdarg \arg +<li> \refitem cmdauthor \author +<li> \refitem cmdb \b +<li> \refitem cmdbrief \brief +<li> \refitem cmdbug \bug +<li> \refitem cmdc \c +<li> \refitem cmdclass \class +<li> \refitem cmdcode \code +<li> \refitem cmddate \date +<li> \refitem cmddef \def +<li> \refitem cmddefgroup \defgroup +<li> \refitem cmddontinclude \dontinclude +<li> \refitem cmde \e +<li> \refitem cmdendcode \endcode +<li> \refitem cmdendhtmlonly \endhtmlonly +<li> \refitem cmdendlatexonly \endlatexonly +<li> \refitem cmdendlink \endlink +<li> \refitem cmdendverbatim \endverbatim +<li> \refitem cmdenum \enum +<li> \refitem cmdexample \example +<li> \refitem cmdexception \exception +<li> \refitem cmdfdollar \f$ +<li> \refitem cmdfbropen \f[ +<li> \refitem cmdfbrclose \f] +<li> \refitem cmdfile \file +<li> \refitem cmdfn \fn +<li> \refitem cmdhtmlonly \htmlonly +<li> \refitem cmdinclude \include +<li> \refitem cmdingroup \ingroup +<li> \refitem cmdinternal \internal +<li> \refitem cmdlatexonly \latexonly +<li> \refitem cmdline \line +<li> \refitem cmdlink \link +<li> \refitem cmdnamespace \namespace +<li> \refitem cmdoverload \overload +<li> \refitem cmdpage \page +<li> \refitem cmdpar \par +<li> \refitem cmdparam \param +<li> \refitem cmdref \ref +<li> \refitem cmdrelates \relates +<li> \refitem cmdreturn \return +<li> \refitem cmdsa \sa +<li> \refitem cmdsection \section +<li> \refitem cmdskip \skip +<li> \refitem cmdskipline \skipline +<li> \refitem cmdstruct \struct +<li> \refitem cmdsubsection \subsection +<li> \refitem cmdtypedef \typedef +<li> \refitem cmdunion \union +<li> \refitem cmduntil \until +<li> \refitem cmdvar \var +<li> \refitem cmdverbatim \verbatim +<li> \refitem cmdverbinclude \verbinclude +<li> \refitem cmdversion \version +<li> \refitem cmdwarning \warning +<li> \refitem cmddollar \$ +<li> \refitem cmdat \@ +<li> \refitem cmdbackslash \\ +<li> \refitem cmdamp \& +<li> \refitem cmdlt \\< +<li> \refitem cmdgt \\> +<li> \refitem cmdhash \# +\htmlonly +</ul> +</multicol> +\endhtmlonly +\latexonly +\end{CompactList} +\end{multicols} +\endlatexonly + +The following subsections provide a list of all commands that are recognized by +Doxygen. Unrecognized commands are treated as normal text. + +<h2>\htmlonly <center> --- \endhtmlonly + Structural indicators + \htmlonly --- </center>\endhtmlonly</h2> + +\subsection 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\>). + + \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> +\subsection cmdcode \code + + \addindex \\code + Starts a block of code. A code block is treated differently + from ordinary text. It is interpreted as C/C++ code. The names of the + classes and members that are documented are automatically replaced by + links to the documentation. + + \sa section \ref cmdendcode, section \ref cmdverbatim + +<hr> +\subsection 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/index.html">here</a> + for the corresponding HTML documentation that is generated by Doxygen. + \endhtmlonly + +<hr> +\subsection cmddefgroup \defgroup <name> (group title) + + \addindex \defgroup + Indicates that a comment block contains documentation for a + group of classes, files or namespaces. This can be used to + categorize classes, files or namespaces, and document those + categories. + \sa section \ref cmdingroup + +<hr> +\subsection cmdendcode \endcode + + \addindex \endcode + Ends a block of code. + \sa section \ref cmdcode + +<hr> +\subsection 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 \\enum comment may be omitted. + + \par Notice: + 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/index.html">here</a> + for the corresponding HTML documentation that is generated by Doxygen. + \endhtmlonly + +<hr> +\subsection 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. + + If more that one source file is needed for the example, + the \\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/index.html">here</a> + for the corresponding HTML documentation that is generated by Doxygen. + \endhtmlonly + + \sa section \ref cmdinclude. + +<hr> +\subsection 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 \\file is left blank) then the documentation block that + contains the \\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/index.html">here</a> + for the corresponding HTML documentation that is generated by Doxygen. + \endhtmlonly + +<hr> +\subsection 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 needed if a + comment block is \e not located before the function declaration + or definition. A full function declaration should be specified after the + \fn command. The argument ends at the end of the line. + + \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 section \ref cmdvar and \ref cmdtypedef + +<hr> +\subsection cmdingroup \ingroup <groupname> + + \addindex \ingroup + If the \\ingroup command is placed in a comment block of a + class, file or namespace, then it will be added to the group. + + \sa section \ref cmddefgroup + +<hr> +\subsection cmdinternal \internal + + \addindex \internal + This command writes the message `For internal use only' to the output. + All text after a \c \internal command is ignored. + +<hr> +\subsection cmdnamespace \namespace <name> + + \addindex \namespace + Indicates that a comment block contains documentation for a + namespace with name \<name\>. + +<hr> +\subsection 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 Notice 1: + You are responsible that there is indeed an + earlier documented member that is overloaded by this one. + \par Notice 2: + The \\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> +\subsection 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 + \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly 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 + + \sa section \ref cmdsection, section \ref cmdsubsection, and + section \ref cmdref + +<hr> +\subsection 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> +\subsection 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 \\class + command. + + \sa section \ref cmdclass. + +<hr> +\subsection cmdtypedef \typedef (typedef declaration) + + \addindex \typedef + Indicates that a comment block contains documentation for a typedef, + typedef (either global or as a member of a class). + This command is equivalent to \\var and \\fn. + + \sa section \ref cmdfn and \ref cmdvar + +<hr> +\subsection 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 \\class + command. + + \sa section \ref cmdclass. + +<hr> +\subsection cmdvar \var (variable declaration) + + \addindex \var + Indicates that a comment block contains documentation for a variable, + enum value (either global or as a member of a class). + This command is equivalent to \\typedef and \\fn. + + \sa section \ref cmdfn and \cmdtypedef + +<hr> + +<h2>\htmlonly <center> --- \endhtmlonly + Section indicators + \htmlonly --- </center>\endhtmlonly</h2> + +\subsection 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 \\author commands will be joined into a single paragraph + and separated by commas. Alternatively, one \\author command may mention + several authors. The \\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_windowsnt.html">here</a> + for the corresponding HTML documentation that is generated by Doxygen. + \endhtmlonly + + \sa Section \ref cmdjdauthor. + +<hr> +\subsection 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 + \\brief commands are present they will be joined. See section + \ref cmdauthor for an example. + + \sa Section \ref cmdjdshort + +<hr> +\subsection 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 \\bug commands will be joined into a single paragraph. + Each bug description will start on a new line. + Alternatively, one \\bug command may mention + several bugs. The \\bug command ends when a blank line or some other + sectioning command is encountered. See section \ref cmdauthor for an + example. + +<hr> +\subsection 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 \\date commands will be joined into a single paragraph. + Each date description will start on a new line. + Alternatively, one \\date command may mention + several dates. The \\date command ends when a blank line or some other + sectioning command is encountered. See section \ref cmdauthor for an + example. + + \sa Section \ref cmdjddate. + +<hr> +\subsection cmdpar \par (paragraph title) { paragraph } + + \addindex \par + Starts a paragraph with a user defined heading. The heading is + specified using the paragraph title argument and extends until the end of the + line. 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. + The \\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> +\subsection cmdparam \param <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 not checked. + The text of the paragraph has no special internal structure. All visual + enhancement commands may be used inside the paragraph. + Multiple adjacent \\param commands will be joined into a single paragraph. + Each parameter description will start on a new line. + The \\param description ends when a blank line or some other + sectioning command is encountered. See section \ref cmdfn for an + example. + + \sa Section \ref cmdjdparam. + +<hr> +\subsection 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 \\exception commands will be joined into a single paragraph. + Each parameter description will start on a new line. + The \\exception description ends when a blank line or some other + sectioning command is encountered. See section \ref cmdfn for an + example. + + \sa Section \ref cmdjdexception. + +<hr> +\subsection 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 \\return commands will be joined into a single paragraph. + The \\return description ends when a blank line or some other + sectioning command is encountered. See section \ref cmdfn for an + example. + + \sa Section \ref cmdjdreturn. + +<hr> +\subsection 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. + The separators \c :: and \c # may be used to separate a class from the + name of its members. One of several overloaded methods or constructors + may be selected by including a parenthesized list of argument types after + the method. + + \sa section \ref autolink for information on how to create links to objects + and section \ref cmdjdsee for the JavaDoc version of this command. + +<hr> +\subsection 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 \\version commands will be joined into a single paragraph. + Each version description will start on a new line. + Alternatively, one \\version command may mention + several dates. The \\version command ends when a blank line or some other + sectioning command is encountered. See section \ref cmdauthor for an + example. + + \sa Section \ref cmdjdversion. + +<hr> +\subsection 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 \\warning commands will be joined into a single paragraph. + Each warning description will start on a new line. + Alternatively, one \\warning command may mention + several warnings. The \\warning command ends when a blank line or some other + sectioning command is encountered. See section \ref cmdauthor for an + example. + +<h2>\htmlonly <center> --- \endhtmlonly + Commands to create links + \htmlonly --- </center>\endhtmlonly</h2> + +\subsection cmdaddindex \addindex <word> + + \addindex \addindex + This command adds \<word\> to the \htmlonly LaTeX\endhtmlonly + \latexonly\LaTeX\ \endlatexonly index. + +\subsection cmdendlink \endlink + + \addindex \endlink + This command ends a link that is started with the \\link command. + + \sa section \ref cmdlink. + +<hr> +\subsection 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 \\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 \\endlink command. All text between + the \\link and \\endlink commands serves as text for a link to + the \<link-object\> specified as the first argument of \\link. + + See section \ref autolink for more information on automatically + generated links and valid link-objects. + + \b Notice: + Keep in mind that links are only meaningful in HTML text; + in \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly + text, the link text is just written to the output. + +<hr> +\subsection cmdref \ref <section-name> + + \addindex \ref + Creates a reference to a named section, subsection, or page. + For HTML documentation the reference command will generate a link to + the section, the title of the section will be used as the link text. + For \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly documentation the reference command will generate a section + number. + + See section \ref cmdpage for an example of the \\ref command. + +<hr> +\subsection 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 \\section + command. + + See section \ref cmdpage for an example of the \\cmdsection command. +<hr> +\subsection 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 \\subsection + command. + + See section \ref cmdpage for an example of the \\cmdsubsection command. +<hr> + +<h2>\htmlonly <center> --- \endhtmlonly + Commands for displaying examples + \htmlonly --- </center>\endhtmlonly</h2> + +\subsection cmddontinclude \dontinclude <file-name> + + \addindex \dontinclude + This command can be used to parse a source file without actually + including it. Any class and member declarations inside the code + are `remembered' during the parsing of the comment block that contained + the \\dontinclude command. + + For line by line description of source files, one or more lines + of the example can be displayed using the \\line, \\skip, \\skipline, and + \\until commands. An internal pointer is used for these commands. The + \\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 + + \sa sections \ref cmdline, \ref cmdskip, \ref cmdskipline, and \ref cmduntil. + +<hr> +\subsection 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. + Include files or directories can be specified using the + \c INCLUDE_PATH tag of Doxygen's configuration file. + + Using the \\include command is equivalent to inserting the file into + the documentation block and surrounding it + with \\code and \\endcode commands. + + The main purpose of the \\include command is to avoid code + duplication in case of example blocks that consist of multiple + source and header files. + + For line by line description of source files, one or more lines + of the example can be displayed using the \\line, \\skip, \\skipline, and + \\until commands. An internal pointer is used for these command. The + \\include command sets the pointer to the first line of the example. + + \sa section \ref cmdexample and \ref cmddontinclude. + +<hr> +\subsection cmdline \line ( pattern ) + + \addindex \line + This command searches line by line through the example that was last + included using \\include or \\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 for an example. + +<hr> +\subsection cmdskip \skip ( pattern ) + + \addindex \skip + This command searches line by line through the example that was last + included using \\include or \\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 for an example. + +<hr> +\subsection cmdskipline \skipline ( pattern ) + + \addindex \skipline + This command searches line by line through the example that was last + included using \\include or \\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 Notice: + The command: + \verbatim\skipline pattern\endverbatim + is equivalent to: +\verbatim +\skip pattern +\line pattern\endverbatim + + See section \ref cmddontinclude for an example. + +<hr> +\subsection cmduntil \until ( pattern ) + + \addindex \until + This command writes all lines of the example that was last + included using \\include or \\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 for an example. + +<hr> +\subsection 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 \\verbatim and \\endverbatim commands around it. + +<hr> +<h2>\htmlonly <center> --- \endhtmlonly + Commands for visual enhancements + \htmlonly --- </center>\endhtmlonly</h2> + +\subsection cmda \a <word> + + \addindex \a + Displays the argument \<word\> using a special font. + Use this command to refer to member arguments in the running text. + + \par Example: + \verbatim + ... the \a x and \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 ... + +<hr> +\subsection cmdarg \arg { item-description } + + \addindex \arg + This command has one argument that continues until the first + blank line or until another \\arg is encountered. + The command can be used to generate a simple, not nested list of + arguments. + Each argument should start with a \\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 Notice: + For nested lists, HTML commands should be used. + +<hr> +\subsection cmdb \b <word> + + \addindex \b + Displays the argument \<word\> using a bold font. + Equivalent to \<b\>word\</b\>. + +<hr> +\subsection 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 ... + +<hr> +\subsection 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 ... + +<hr> +\subsection cmdendhtmlonly \endhtmlonly + + \addindex \endhtmlonly + Ends a block of text that was started with a \\htmlonly command. + + \sa section \ref cmdhtmlonly. + +<hr> +\subsection cmdendlatexonly \endlatexonly + + \addindex \endlatexonly + Ends a block of text that was started with a \\latexonly command. + + \sa section \ref cmdlatexonly. + +<hr> +\subsection cmdendverbatim \endverbatim + + \addindex \endverbatim + Ends a block of text that was started with a \\verbatim command. + + \sa section \ref cmdverbatim. + +<hr> +\subsection cmdfdollar \f$ + + \addindex \\f$ + + Marks the start and end of an in-text formula. + \sa section \ref formulas for an example. + +<hr> +\subsection cmdfbropen \f[ + + \addindex \\f[ + + Marks the start of a long formula that is displayed + centered on a separate line. + \sa section \ref cmdfbrclose and section \ref formulas. + +<hr> +\subsection cmdfbrclose \f] + + \addindex \\f] + + Marks the end of a long formula that is displayed + centered on a separate line. + \sa section \ref cmdfbropen and section \ref formulas. + +<hr> +\subsection cmdhtmlonly \htmlonly + + \addindex \htmlonly + Starts a block of text that will be verbatim included in the + generated HTML documentation only. The block ends with a + endhtmlonly command. + + This command can be used to include HTML code that is too complex + for Doxygen (i.e. images, applets, java-scripts, and HTML tags that + require attributes). You can use the \\latexonly and \\endlatexonly + pair to provide a proper \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly alternative. + + \b Notice: + environment variables (like \$(HOME) ) are resolved inside a + HTML-only block. + + \sa section \ref cmdhtmlonly and section \ref cmdlatexonly. + +<hr> +\subsection cmdlatexonly \latexonly + + \addindex \latexonly + Starts a block of text that will be verbatim included in the + generated \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly documentation only. The block ends with a + endlatexonly command. + + This command can be used to include \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly code that is too complex + for Doxygen (i.e. images, formulas, special characters). You can use the + \\htmlonly and \\endhtmlonly pair to provide a proper HTML alternative. + + \b Notice: + environment variables (like \$(HOME) ) are resolved inside a + \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\endlatexonly-only block. + + \sa section \ref cmdlatexonly and section \ref cmdhtmlonly. + +<hr> +\subsection cmdverbatim \verbatim + + \addindex \verbatim + Starts a block of text that will be verbatim included in both the + HTML and the \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly documentation. The block should end with a + \\endverbatim block. All commands are disabled in a verbatim block. + + \warning Make sure you include a \\endverbatim command for each + \\verbatim command or the parser will get confused! + +<hr> +\subsection cmdbackslash \\ + + \addindex \\ + This command writes a backslash character (\\) to the HTML and \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly output. + The backslash has to be escaped in some cases because Doxygen uses it to + detect commands. + +<hr> +\subsection cmdat \@ + + \addindex \@ + This command writes an at-sign (@) to the HTML and \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly output. + The at-sign has to be escaped in some cases because Doxygen uses it to + detect JavaDoc commands. + +<hr> +\subsection cmdamp \& + + \addindex \& + This command writes the \& character to the HTML and \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly output. This + character has to be escaped because it has a special meaning in HTML. + +<hr> +\subsection cmddollar \$ + + \addindex \$ + This command writes the \$ character to the HTML and \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly output. This + character has to be escaped in some cases, because it is used to expand + environment variables. + +<hr> +\subsection cmdhash \# + + \addindex \# + This command writes the \# character to the HTML and \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly output. This + character has to be escaped in some cases, because it is used to refer + to documented entities. + +<hr> +\subsection cmdlt \\< + + \addindex \\< + This command writes the \< character to the HTML and \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly output. This + character has to be escaped because it has a special meaning in HTML. + +<hr> +\subsection cmdgt \\> + + \addindex \\> + This command writes the \> character to the HTML and \htmlonly LaTeX\endhtmlonly\latexonly\LaTeX\ \endlatexonly output. This + character has to be escaped because it has a special meaning in HTML. + +<hr> + +<h2>\htmlonly <center> --- \endhtmlonly + Commands included for JavaDoc compatibility + \htmlonly --- </center>\endhtmlonly</h2> + +The following command JavaDoc command are support. + +\subsection cmdjdauthor @author { list of authors } + \addindex @author + Equivalent to \\author (see section \ref cmdauthor). +\subsection cmdjddate @date { date description } + \addindex @date + Equivalent to \\date (see section \ref cmddate). +\subsection cmdjdparam @param <parameter-name> { parameter-description } + \addindex @param + Equivalent to \\param (see section \ref cmdparam). +\subsection cmdjdexception @exception <exception-object> { exception-description } + \addindex @exception + Equivalent to \\exception (see section \ref cmdexception). +\subsection cmdjdreturn @return { description of the return value } + \addindex @return + Equivalent to \\return (see section \ref cmdreturn). +\subsection cmdjdsee @see { references } + \addindex @see + Equivalent to \\sa (see section \ref cmdsa). +\subsection cmdjdshort @short { brief description } + \addindex @short + Equivalent to \\brief (see section \ref cmdbrief). +\subsection cmdjdversion @version { version number } + \addindex @version + Equivalent to \\version (see section \ref cmdversion). + +<h2>\htmlonly <center> --- \endhtmlonly + Commands included for Qt compatibility + \htmlonly --- </center>\endhtmlonly</h2> + +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>\\ingroup +<li>\\inherit +<li>\\l +<li>\\postheader +</ul> + +*/ diff --git a/doc/config.doc b/doc/config.doc new file mode 100644 index 0000000..0412634 --- /dev/null +++ b/doc/config.doc @@ -0,0 +1,553 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ +/*! \page config + +\section config Configuration + +\subsection config_format Format + +A configuration file is a free-form ASCII text file with a structure that +is similar to that of a Makefile. It is parsed by a +recursive-descent parser that is built into \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 begin with the \c # character and end 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 \c = character and one or more values. +Values are sequences of non-blanks. If the value should contain one or more +blanks it must be surrounded by quotes ("..."). +Multiple lines can be concatenated by inserting a backslash (\\) +as the last character of a line. +Environment variables can expanded using the pattern \$(ENV_VARIABLE_NAME). + +The configuration options can be divided into several categories. +Below is a list of tags that are recognized for each category. + +\subsection config_general General options +<dl> + +<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) 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. + +<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. + +<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 HTML and Latex 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. + +<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. Possible values are \c YES and \c NO, + where \c YES implies that the messages are off. + If left blank \c NO is used. + +<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 by doxygen. Possible values are \c YES and \c NO, + where \c YES implies that the warnings are on. If left blank \c NO is used. + + \b Tip: Turn warnings on while writing the documentation. + +<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 DISABLE_INDEX tag can be used to turn on/off the condensed index at + top of each page. A value of NO (the default) enables the index and the + value YES disables it. + +<dt>\c EXTRACT_ALL <dd> + \addindex EXTRACT_ALL + If the \c EXTRACT_ALL tag is set to \c YES all classes and functions will be + included in the documentation, even if no documentation was available. + + \b Notice: This will also disable the warnings about undocumented members + that are normally produced when \c WARNINGS is set to \c YES + +<dt>\c EXTRACT_PRIVATE <dd> + \addindex EXTRACT_PRIVATE + If the \c EXTRACT_PRIVATE tag is set to \c YES all + documentation for private members will be extracted as well. + +<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 (the default) these members will be included in the + various overviews, but no documentation section is generated. + +<dt>\c HIDE_UNDOC_CLASSES <dd> + \addindex HIDE_UNDOC_CLASSES + If the \c HIDE_UNDOC_CLASSESS tag is set to \c YES, Doxygen will hide all + undocumented classes. + If set to \c NO (the default) these classes will be included in the + various overviews. + +<dt>\c BRIEF_MEMBER_DESC <dd> + \addindex BRIEF_MEMBER_DESC + If the \c BRIEF_MEMBER_DESC tag is set to \c YES (the default) Doxygen will + include brief member descriptions after the members that are listed in + the file and class documentation (similar to JavaDoc). + Set to NO to disable this. + +<dt>\c INTERNAL_DOCS <dd> + \addindex INTERNAL_DOCS + The \c INTERNAL_DOCS tag determines if documentation + that is typed after a \\internal command is included. If the tag is set + to \c NO (the default) then the documentation will be excluded. + Set it to \c YES to include the internal documentation. + +<dt>\c REPEAT_BRIEF <dd> + \addindex REPEAT_BRIEF + If the \c REPEAT_BRIEF tag is set to \c YES (the default) Doxygen will + prepend the brief description of a member or function before the detailed + description + + \par Notice: + If both \c HIDE_UNDOC_MEMBERS and \c BRIEF_MEMBER_DESC are set to \c NO, the + brief descriptions will be completely suppressed. + +<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 NO the shortest path that makes the file name unique will be used + +<dt>\c STRIP_FROM_PATH <dd> + \addindex STRIP_FROM_PATH + If the \c FULL_PATH_NAMES tag is set to \c YES then the \c STRIP_FROM_PATH tag + can be used to strip a user defined part of the path. Stripping is + only done if the specified string matches the left-hand part of the + path. + +<dt>\c CLASS_DIAGRAMS <dd> + \addindex CLASS_DIAGRAMS + If the \c CLASS_DIAGRAMS tag is set to \c YES (the default) Doxygen will + generate a class diagram (in Html and LaTeX) for classes with base or + super classes. Setting the tag to \c NO turns the diagrams off. + +<dt>\c CASE_SENSE_NAMES <dd> + \addindex CASE_SENSE_NAMES + If the \c CASE_SENSE_NAMES tag is set to \c NO (the default) 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. + +<dt>\c VERBATIM_HEADERS <dd> + \addindex VERBATIM_HEADERS + If the VERBATIM_HEADERS tag is set the YES (the default) then Doxygen\n"; + will generate a verbatim copy of the header file for each class for\n"; + which an include is specified. Set to NO to disable this.\n"; + \sa Section \ref cmdclass. + +</dl> + +\subsection config_input Input related options +<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.<br> + + \b Notice: This tag (and only this tag) is \e required. + +<dt>\c FILE_PATTERNS <dd> + \addindex FILE_PATTERNS + If the value of the \c INPUT tag contains directories, you can use the + \c FILE_PATTERNS tag to specify one or more wildcard patterns + (like \c *.cpp and \c *.h ) to filter out the source-files + in the directories. If left blank all files are included + (i.e. wildcard <tt>*</tt>). + +<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. Possible values are \c YES + and \c NO. If left blank \c NO is used. + +<dt>\c EXCLUDE <dd> + \addindex EXCLUDE + The \c EXCLUDE tag can be used to specify files and/or directories that should + excluded from the \c INPUT source files. This way you can easily exclude a + subdirectory from a directory tree whose root is specified with the \c INPUT tag. + +<dt>\c EXCLUDE_PATTERNS <dd> + \addindex EXCLUDE_PATTERNS + If the value of the 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. + + +<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 \\include command in section \ref cmdinclude). + +<dt>\c INCLUDE_PATH <dd> + \addindex INCLUDE_PATH + The 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. + +<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 popen()) the command: +\verbatim <filter> <input-file> +\endverbatim + + where \<filter\> + is the value of the \c INPUT_FILTER tag, and \<input-file\> is the name of an + input file. Doxygen will then use the output that the filter program writes + to standard output. + +</dl> + +\subsection html_output HTML related options +<dl> + +<dt>\c GENERATE_HTML <dd> + \addindex GENERATE_HTML + If the \c GENERATE_HTML tag is set to \c YES (the default) Doxygen will + generate 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 \c OUTPUT_DIRECTORY will be + put in front of it. If left blank `html' will be used as the default path. + +<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. To get valid HTML the header file + should contain at least a \c <HTML> and a \c <BODY> tag. Example: +\verbatim + <HTML> + <HEAD> + <TITLE>My title</TITLE> + </HEAD> + <BODY BGCOLOR="#FFFFFF"> +\endverbatim + If the tag is left blank doxygen will generate a + standard header. + +<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. To get valid HTML the header file should contain + at least a \c </BODY> and a \c </HTML> tag. Example: +\verbatim + </BODY> + </HTML> +\endverbatim + If the tag is left blank doxygen will generate a standard footer. + +</dl> + +\subsection latex_output LaTeX related options +<dl> + +<dt>\c GENERATE_LATEX <dd> + \addindex GENERATE_LATEX + If the \c GENERATE_LATEX tag is set to \c YES (the default) Doxygen will + generate Latex output. + +<dt>\c LATEX_OUTPUT <dd> + \addindex LATEX_OUTPUT + The \c LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. + If a relative path is entered the value of \c OUTPUT_DIRECTORY will be + put in front of it. If left blank `latex' will be used as the default path. + +<dt>\c COMPACT_LATEX <dd> + \addindex COMPACT_LATEX + If the \c COMPACT_LATEX tag is set to \c YES Doxygen generates more compact + LaTeX documents. This may be useful for small projects and may help to + save some trees in general. + +<dt>\c PAPER_TYPE <dd> + \addindex PAPER_TYPE + The PAPER_TYPE tag can be used to set the paper type that is used + by the printer. Possible values are: + <ul> + <li><code>a4</code> (210 x 297 mm). + <li><code>a4wide</code> (same as a4, but including the a4wide package). + <li><code>letter</code> (8.5 x 11 inches). + <li><code>legal</code> (8.5 x 14 inches). + <li><code>executive</code> (7.25 x 10.5 inches) + </ul> + If left blank a4wide will be used. + +<dt>\c EXTRA_PACKAGES <dd> + \addindex EXTRA_PACKAGES + The EXTRA_PACKAGES tag can be used to specify one or more LaTeX + package names that should be included in the LaTeX 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. +</dl> + +\subsection man_output Man page related options +<dl> + +<dt>\c GENERATE_MAN <dd> + \addindex GENERATE_MAN + If the \c GENERATE_MAN tag is set to \c YES (the default) Doxygen will + generate man pages for classes and files. + +<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 \c OUTPUT_DIRECTORY will be + put in front of it. If left blank `man' will be used as the default path. + A directory man3 will be created inside the directory specified by + \c MAN_OUTPUT. + +</dl> + +\subsection config_prepro Preprocessor related options +<dl> + +<dt>\c ENABLE_PREPROCESSING <dd> + \addindex ENABLE_PREPROCESSING + If the \c ENABLE_PREPROCESSING tag is set to \c YES (the default) Doxygen will + evaluate all C-preprocessor directives found in the sources and include + files. + +<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 (the default) only conditional + compilation will be performed. + +<dt>\c SEARCH_INCLUDES <dd> + \addindex SEARCH_INCLUDES + If the \c SEARCH_INCLUDES tag is set to \c YES (the default) the includes files + in the \c INCLUDE_PATH (see below) will be search if a \#include is found. + +<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. + +<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 + 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 = are omitted =1 is assumed. + +<dt>\c EXPAND_ONLY_PREDEF <dd> + \addindex EXPAND_ONLY_PREDEF + If the \c EXPAND_ONLY_PREDEF and \c MACRO_EXPANSION tags are both set to YES + then the macro expansion is limited to the macros specified with the + \c PREDEFINED tag. + +</dl> + +\subsection config_extref External reference options +<dl> + +<dt>\c TAGFILES <dd> + \addindex TAGFILES + The \c TAGFILES tag can be used to specify one or more tagfiles. + See section \ref doxytag_usage for more information about the usage of + tag files. + + \par Notice: + Each tag file most have a unique name and 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. + +<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 doxytag_usage for more information about the usage of + tag files. + +<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. + +<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 `<tt>which perl</tt>'). + +</dl> +\subsection config_search Search engine options +<dl> + +<dt>\c SEARCHENGINE <dd> + \addindex SEARCHENGINE + The \c SEARCHENGINE tag specifies whether or not a + search should be used. Possible values are \c YES and \c NO. + If set to \c NO or left blank, the values of all other tags in this section + will be ignored. + +<dt>\c CGI_NAME <dd> + \addindex CGI_NAME + The \c CGI_NAME tag should be the name of the CGI script that + starts the search engine (<tt>doxysearch</tt>) with the correct parameters. + A script with this name will be generated by doxygen. + +<dt>\c CGI_URL <dd> + \addindex CGI_URL + The \c CGI_URL tag should be the absolute URL to the directory where the + cgi binaries are located. See the documentation of your http daemon for + details. + +<dt>\c DOC_URL <dd> + \addindex DOC_URL + The \c DOC_URL tag should be the absolute URL to the directory where the + documentation is located. If left blank the absolute path to the + documentation, with <tt>file://</tt> prepended to it, will be used. + This is correct for local viewing only. + +<dt>\c DOC_ABSPATH <dd> + \addindex DOC_ABSPATH + The \c DOC_ABSPATH tag should be the absolute path to the directory where the + documentation is located. If left blank the directory on the local machine + will be used. + +<dt>\c BIN_ABSPATH <dd> + \addindex BIN_ABSPATH + The \c BIN_ABSPATH tag must point to the directory where the doxysearch binary + is installed. + +<dt>\c EXT_DOC_PATHS <dd> + \addindex EXT_DOC_PATHS + The \c EXT_DOC_PATHS tag can be used to specify one or more paths to + documentation generated for other projects. This allows doxysearch to search + the documentation for these projects as well. All paths must be absolute. + +</dl> +<h2>Examples</h2> + +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 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/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/local/bin/perl +SEARCHENGINE = YES +CGI_NAME = search.cgi +CGI_URL = http://www.stack.nl/~dimitri/cgi-bin +DOC_URL = http://www.stack.nl/~dimitri/qdbttabular +DOC_ABSPATH = /home/dimitri/.html/qdbttabular +BIN_ABSPATH = /home/dimitri/bin +\endverbatim + +To regenerate the Qt 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 + +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. + +*/ + diff --git a/doc/doxygen.sty b/doc/doxygen.sty new file mode 100644 index 0000000..33835f0 --- /dev/null +++ b/doc/doxygen.sty @@ -0,0 +1,58 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{doxygen} +\RequirePackage{calc} +\RequirePackage{array} +\pagestyle{fancyplain} +\addtolength{\headwidth}{\marginparsep} +\addtolength{\headwidth}{\marginparwidth} +\newcommand{\clearemptydoublepage}{\newpage{\pagestyle{empty}\cleardoublepage}} +\lhead[\fancyplain{}{\bfseries\thepage}] + {\fancyplain{}{\bfseries\rightmark}} +\rhead[\fancyplain{}{\bfseries\leftmark}] + {\fancyplain{}{\bfseries\thepage}} +\rfoot[\fancyplain{}{\bfseries\scriptsize User Manual for Doxygen $VERSION, written by Dimitri van Heesch \copyright 1997-1998}]{} +\lfoot[]{\fancyplain{}{\bfseries\scriptsize User Manual for Doxygen $VERSION, written by Dimitri van Heesch \copyright 1997-1998}} +\cfoot{} +\newenvironment{CompactList} +{\begin{list}{}{ + \setlength{\leftmargin}{0.5cm} + \setlength{\itemsep}{0pt} + \setlength{\parsep}{0pt} + \setlength{\topsep}{0pt} + \renewcommand{\makelabel}{}}} +{\end{list}} +\newenvironment{CompactItemize} +{ + \begin{itemize} + \setlength{\itemsep}{-4pt} + \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{tabular*}{\linewidth} + {*{#1}{|>{\PBS\raggedright\hspace{0pt}}p{\the\tmplength}}|} +} +{\end{tabular*}\par} +\newcommand{\entrylabel}[1]{ + {\parbox[b]{\labelwidth-4pt}{\makebox[0pt][l]{\textbf{#1}}\\}}} +\newenvironment{Desc} +{\begin{list}{} + { + \settowidth{\labelwidth}{40pt} + \setlength{\leftmargin}{\labelwidth} + \setlength{\parsep}{0pt} + \setlength{\itemsep}{-4pt} + \renewcommand{\makelabel}{\entrylabel} + } +} +{\end{list}} +\setlength{\parindent}{0cm} +\setlength{\parskip}{0.2cm} +\sloppy diff --git a/doc/doxygen_logo.eps b/doc/doxygen_logo.eps new file mode 100644 index 0000000..90c6c92 --- /dev/null +++ b/doc/doxygen_logo.eps @@ -0,0 +1,3976 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: (ImageMagick) +%%Title: (doxygen_logo.eps) +%%CreationDate: (Thu Aug 13 14:21:32 1998) +%%BoundingBox: 0 0 633 196 +%%DocumentData: Clean7Bit +%%LanguageLevel: 1 +%%Pages: 0 +%%EndComments + +%%BeginDefaults +%%PageOrientation: Portrait +%%EndDefaults + +%%BeginProlog +% +% Display a color image. The image is displayed in color on +% Postscript viewers or printers that support color, otherwise +% it is displayed as grayscale. +% +/buffer 512 string def +/byte 1 string def +/color_packet 3 string def +/pixels 768 string def + +/DirectClassPacket +{ + % + % Get a DirectClass packet. + % + % Parameters: + % red. + % green. + % blue. + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + compression 0 gt + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/DirectClassImage +{ + % + % Display a DirectClass image. + % + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { DirectClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayDirectClassPacket } image + } ifelse +} bind def + +/GrayDirectClassPacket +{ + % + % Get a DirectClass packet; convert to grayscale. + % + % Parameters: + % red + % green + % blue + % length: number of pixels minus one of this color (optional). + % + currentfile color_packet readhexstring pop pop + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 gt + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/GrayPseudoClassPacket +{ + % + % Get a PseudoClass packet; convert to grayscale. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + color_packet 0 get 0.299 mul + color_packet 1 get 0.587 mul add + color_packet 2 get 0.114 mul add + cvi + /gray_packet exch def + compression 0 gt + { + /number_pixels 1 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add def + } ifelse + 0 1 number_pixels 1 sub + { + pixels exch gray_packet put + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassPacket +{ + % + % Get a PseudoClass packet. + % + % Parameters: + % index: index into the colormap. + % length: number of pixels minus one of this color (optional). + % + currentfile byte readhexstring pop 0 get + /offset exch 3 mul def + /color_packet colormap offset 3 getinterval def + compression 0 gt + { + /number_pixels 3 def + } + { + currentfile byte readhexstring pop 0 get + /number_pixels exch 1 add 3 mul def + } ifelse + 0 3 number_pixels 1 sub + { + pixels exch color_packet putinterval + } for + pixels 0 number_pixels getinterval +} bind def + +/PseudoClassImage +{ + % + % Display a PseudoClass image. + % + % Parameters: + % class: 0-PseudoClass or 1-Grayscale. + % + currentfile buffer readline pop + token pop /class exch def pop + class 0 gt + { + currentfile buffer readline pop + token pop /depth exch def pop + /grays columns 8 add depth sub depth mul 8 idiv string def + columns rows depth + [ + columns 0 0 + rows neg 0 rows + ] + { currentfile grays readhexstring pop } image + } + { + % + % Parameters: + % colors: number of colors in the colormap. + % colormap: red, green, blue color packets. + % + currentfile buffer readline pop + token pop /colors exch def pop + /colors colors 3 mul def + /colormap colors string def + currentfile colormap readhexstring pop pop + systemdict /colorimage known + { + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { PseudoClassPacket } false 3 colorimage + } + { + % + % No colorimage operator; convert to grayscale. + % + columns rows 8 + [ + columns 0 0 + rows neg 0 rows + ] + { GrayPseudoClassPacket } image + } ifelse + } ifelse +} bind def + +/DisplayImage +{ + % + % Display a DirectClass or PseudoClass image. + % + % Parameters: + % x & y translation. + % x & y scale. + % label pointsize. + % image label. + % image columns & rows. + % class: 0-DirectClass or 1-PseudoClass. + % compression: 0-RunlengthEncodedCompression or 1-NoCompression. + % hex color packets. + % + gsave + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + x y translate + currentfile buffer readline pop + token pop /x exch def + token pop /y exch def pop + currentfile buffer readline pop + token pop /pointsize exch def pop + /NewCenturySchlbk-Roman findfont pointsize scalefont setfont + x y scale + currentfile buffer readline pop + token pop /columns exch def + token pop /rows exch def pop + currentfile buffer readline pop + token pop /class exch def pop + currentfile buffer readline pop + token pop /compression exch def pop + class 0 gt { PseudoClassImage } { DirectClassImage } ifelse + grestore +} bind def +%%EndProlog +%%Page: 1 1 +%%PageBoundingBox: 0 0 633 196 +userdict begin +%%BeginData: +DisplayImage +0 0 +634 197 +18 +634 197 +0 +0 +ffffffffffffffffffffffffffffffffffffffffffffff4bfcfebc03fcfe9a00dcca9400 +fcf4c600ffffffffffffffffffffff68fcfebc00ffffff00fcfebc0bfcfe9a02fcdc8700 +e9d9b900ffffffffffffffffffffff60fcfebc0efcfe9a00fcfebc00fcfe9a01fcfebc00 +fcfe9a02fcfe8001fcdc8700e8cbab00fcf4c600ffffffffffffffffffffff5dfcfebc0f +fcfe9a00fcfebc01fcfe9a03fcfe8000fcf49700fcfe8000fcfe9a00fcfebc00fcf49700 +fcecc400ffffffffffffffffffffff5bfcfebc07fcfe9a00fcfebc04fcfe9a00fcfebc01 +fcfe9a00fcfebc00fcfe9a02fcfe8000fcfe9a00fcfe8000fcfe9a01fcfebc01fcfe9a00 +fcf47100ffffffffffffffffffffff5afcfe9a00fcfebc00fcfe9a00fcfebc02fcfe9a00 +fcfebc03fcfe9a00fcfebc00fcfe9a00fcfebc01fcfe9a00fcfebc00fcfe9a00fcfebc00 +fcfe9a00fcfe8000fcfe9a00fcfe8001fcfe9a01fcfebc00fcfe9a01fcfe8000ffffffff +ffffffffffffff5afcfebc03fcfe9a00fcfebc02fcfe9a00fcfebc03fcfe9a00fcfebc00 +fcfe9a00fcfebc00fcfe9a04fcfe8000fcfe9a00fcfe8001fcfebc01fcfe9a01fcfe8000 +fcfebc00ffffffffffffffffffffff59fcfe9a00fcfebc00fcfe9a00fcfebc03fcfe9a00 +fcfebc01fcfe9a00fcfebc00fcfe9a00fcfebc01fcfe9a01fcfebc00fcfe9a00fcfebc00 +fcfe9a00fcfe8000fcfe9a00fcfe8002fcfe9a00fcfebc01fcfe8001ffffffffffffffff +ffffff5afcfebc01fcfe9a00fcfebc02fcfe9a00fcfebc01fcfe9a00fcfebc01fcfe9a00 +fcfebc00fcfe9a00fcfebc00fcfe9a04fcfe8001fcfe9a00fcfe8000fcfe9a01fcfebc00 +fcfe9a00fcfe8001fcfebc00ffffffffffffffffffffff59fcfebc00fcfe9a00fcfebc01 +fcfe9a00fcfebc06fcfe9a00fcfebc00fcfe9a01fcfebc00fcfe9a00fcfebc00fcfe9a01 +fcfe8001fcfe9a00fcfe8001fcfe9a02fcfe8001ffffffffffffffffffffff5afcfe9a00 +fcfebc00fcfe9a00fcfebc01fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00 +fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a05fcfe8000fcfe9a00fcfe8000fcfe9a00 +fcfe8000fcfebc01fcfe9a00fcfe8001fcfebc00ffffffffffffffffffffff59fcfe9a00 +fcfebc02fcfe9a00fcfebc02fcfe9a00fcfebc02fcfe9a00fcfebc00fcfe9a02fcfebc00 +fcfe9a02fcfe8001fcfe9a00fcfe8001fcfe9a02fcfe8001fcfebc00ffffffffffffffff +ffffff57f4f6f900ffffff00fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00 +fcfe9a00fcfebc01fcfe9a01fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a04 +fcfe8001fcfe9a00fcfe8000fcfe9a01fcfebc00fcfe9a00fcfe8001ffffffffffffffff +ffffff58f4f6f900fcfebc03fcfe9a00fcfebc01fcfe9a00fcfebc00fcfe9a00fcfebc01 +fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a05fcfe8002fcfe9a00fcfe8000fcfe9a02 +fcfe8001fcfebc00ffffffffffffffffffffff56ecf3f501ffffff00fcfe9a01fcfebc01 +fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a00 +fcfebc00fcfe9a01fcfebc00fcfe9a02fcfe8002fcfe9a00fcfe8001fcfebc00fcfe9a01 +fcfe8001fcfebc00ffffffffffffffffffffff55f4f6f900ecf3f500e8ecef00fcf4c600 +fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a00 +fcfebc00fcfe9a00fcfebc01fcfe9a00fcfebc00fcfe9a05fcfe8001fcfe9a00fcfe8001 +fcfe9a01fcfe8001fcfe9a00fcfebc00ffffffffffffffffffffff55f4f6f900e8ecef00 +e0e4e700fcf4c600fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00 +fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a04 +fcfe8002fcfe9a00fcfe8001fcfe9a01fcfe8002fcfebc00ffffffffffffffffffffff55 +f4f6f900e8ecef01fcf4c600fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00 +fcfe9a01fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc01fcfe9a06fcfe8001fcfe9a00 +fcfe8001fcfe9a00fcfe8000fcfe9a00fcfe8001fcfebc00ffffffffffffffffffffff55 +ecf3f500e8ecef00e0e4e700fcf4c600fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00 +fcfe9a00fcfebc00fcfe9a01fcfebc00fcfe9a00fcfebc00fcfe9a01fcfebc00fcfe9a04 +fcfe8002fcfe9a00fcfe8001fcfe9a01fcfe8002fcfebc00ffffffffffffffffffffff55 +f4f6f900e8ecef01fcf4c600fcfe9a03fcfebc00fcfe9a02fcfebc00fcfe9a00fcfebc00 +fcfe9a00fcfebc01fcfe9a01fcfebc00fcfe9a03fcfe8000fcfe9a00fcfe8002fcfe9a00 +fcfe8003fcfebc00ffffffffffffffffffffff55f4f6f900e8ecef01fcf4c600fcfebc00 +fcfe9a00fcfebc00fcfe9a01fcfebc00fcfe9a00fcfebc00fcfe9a01fcfebc00fcfe9a00 +fcfebc00fcfe9a00fcfebc00fcfe9a05fcfe8000fcfe9a00fcfe8004fcfe9a00fcfe8001 +fcfebc00ffffffffffffffffffffff55f4f6f901e0e4e700fcf4c600fcfe9a00fcfebc00 +fcfe9a00fcfebc00fcfe9a03fcfebc00fcfe9a01fcfebc00fcfe9a00fcfebc00fcfe9a00 +fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a00fcfe8001fcfe9a00fcfe8001 +fcfe9a00fcfe8003fcfebc00ffffffffffffffffffffff55f4f6f900ecf3f500e0e4e700 +f4f6f900fcfe9a0afcfebc00fcfe9a00fcfebc00fcfe9a08fcfe8007fcfebc00ffffffff +ffffffffffffff55f4f6f900ecf3f500e8ecef00fcf4c600fcfe9a0dfcfebc00fcfe9a00 +fcfebc00fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe8000fcfe9a01fcfe8006fcfebc00 +ffffffffffffffffffffff55f4f6f900ecf3f500e8ecef00fcf4c600fcfe9a0bfcfebc00 +fcfe9a00fcfebc00fcfe9a00fcfebc00fcfe9a01fcfebc00fcfe9a00fcfe8000fcfe9a00 +fcfe8000fcfe9a00fcfe8004fcf47100fcfebc00ffffffffffffffffffffff56e8ecef01 +fcf4c600fcfe9a04fcfe8000fcfe9a01fcfe8000fcfe9a04fcfebc00fcfe9a01fcfebc00 +fcfe9a05fcfe8002fcf47100fcfe8002fcfebc00ffffffffffffffffffffff55f4f6f900 +ecf3f500e8ecef00fcecc400fcfe9a00fcfe8000fcfe9a00fcfe8000fcfe9a01fcfe8000 +fcfe9a00fcfe8000fcfe9a00fcfe8000fcfe9a04fcfebc00fcfe9a01fcfebc00fcfe9a00 +fcfe8008fcf47100fcfebc00ffffffffffffffffffffff56e8ecef01fcf4c600fcfe8000 +fcfe9a00fcfe8000fcfe9a00fcfe8001fcfe9a00fcfe8000fcfe9a00fcfe8000fcfe9a00 +fcfe8000fcfe9a08fcfe8000fcfe9a00fcfe8001fcfe9a00fcfe8000fcf47100fcfe8002 +fcfebc00ffffffffffffffffffffff55f4f6f901e8ecef00f7ece700fcfe8000fcfe9a00 +fcfe8000fcfe9a00fcfe8000fcfe9a00fcfe8002fcfe9a00fcfe8000fcfe9a06fcfebc00 +fcfe9a02fcfe8008fcfebc00ffffffffffffffffffffff55f4f6f900e8ecef01fcf4c600 +fcfe8001fcfe9a00fcfe8003fcfe9a00fcfe8001fcfe9a00fcfe8000fcfe9a08fcfe8009 +fcfebc00ffffffffffffffffffffff55f4f6f901e0e4e700fcf4c600fcfe9a00fcfe8001 +fcfe9a00fcfe8000fcfe9a00fcfe8002fcfe9a00fcfe8000fcfe9a00fcfe8000fcfe9a07 +fcfe8002fcfe9a00fcfe8005fcfebc00ffffffffffffffffffffff55f4f6f900ecf3f500 +e8ecef00fcf4c600fcfe9a00fcfe8000fcfe9a00fcfe8004fcfe9a00fcfe8002fcfe9a08 +fcfe8009fcfebc00ffffffffffffffffffffff55f4f6f900ecf3f500e8ecef00fcecc400 +fcfe8000fcfe9a00fcfe8001fcfe9a00fcfe8000fcfe9a00fcfe8001fcfe9a01fcfe8000 +fcfe9a00fcfe8000fcfe9a06fcfe8004fcf47101fcfe8002fcfebc00ffffffffffffffff +ffffff56e8ecef01fcf4c600fcfe8002fcfe9a00fcfe8003fcfe9a00fcfe8001fcfe9a02 +fcfe8000fcfe9a05fcfe8003fcf47102fcfe8002fcfebc00ffffffffffffffffffffff55 +f4f6f901e0e4e700fcf4c600fcfe9a00fcfe8003fcfe9a00fcfe8000fcfe9a00fcfe8000 +fcfe9a00fcfe8000fcfe9a00fcfe8000fcfe9a02fcfe8000fcfe9a02fcfe8002fcf47100 +fcfe8000fcf47101fcfe8002fcf47100fcfebc00ffffffffffffffffffffff55f4f6f900 +e8ecef01fcf4c600fcfe8005fcfe9a00fcfe8001fcfe9a00fcfe8000fcfe9a00fcfe8000 +fcfe9a00fcfe8000fcfe9a02fcfe8000fcfe9a00fcfe8003fcf47103fcfe8002fcfebc00 +ffffffffffffffffffffff55f4f6f901e8ecef00fcecc400fcfe8007fcfe9a00fcfe8001 +fcfe9a04fcfe8000fcfe9a02fcfe8001fcf47105fcfe8001fcf47100fcfebc00ffffffff +ffffffffffffff56e8ecef01fcecc400fcfe8005fcfe9a00fcfe8002fcfe9a00fcfe8001 +fcfe9a00fcfe8000fcfe9a00fcfe8000fcfe9a00fcfe8002fcf47100fcfe8000fcf47103 +fcfe8000fcf47101fcfe8000fcfebc00ffffffffffffffffffffff55f4f6f900ecf3f500 +e8ecef00fcecc400fcfe8007fcfe9a00fcfe8000fcfe9a00fcfe8000fcfe9a00fcfe8000 +fcfe9a00fcfe8000fcfe9a00fcfe8000fcfe9a01fcfe8001fcf47101fce66a00fcf47102 +fcfe8000fcf47101fcfebc00ffffffffffffffffffffff55f4f6f900e8ecef01fcecc400 +fcfe8008fcfe9a00fcfe8000fcfe9a00fcfe8000fcfe9a00fcfe8000fcfe9a00fcfe8004 +fcf47102fce66a00fcf47101fcfe8000fcf47102fcfebc00ffffffffffffffffffffff55 +f4f6f901e8ecef00fcecc400fcfe8005fcfe9a00fcfe8000fcfe9a00fcfe8000fcfe9a00 +fcfe8000fcfe9a00fcfe8002fcfe9a00fcfe8000fcfe9a00fcfe8001fcf47102fce66a01 +fcf47101fcfe8000fcf47100fcec7600fcfebc00ffffffffffffffffffffff55f4f6f900 +ecf3f500e8ecef00fcecc400fcfe8007fcfe9a00fcfe8000fcfe9a00fcfe8002fcfe9a00 +fcfe8005fcf47101fce66a02fcf47103fce66a00fcfebc00ffffffffffffffffffffff55 +f4f6f900ecf3f500e8ecef00fcecc400fcfe8005fcfe9a01fcfe8000fcfe9a00fcfe8005 +fcfe9a00fcfe8000fcfe9a00fcfe8001fcf47101fce66a02fcf47104fcfebc00ffffffff +ffffffffffffff56e8ecef01fcecc400fcfe8004fcfe9a00fcfe8001fcfe9a00fcfe8001 +fcfe9a00fcfe8008fcec7600fcf47100fce66a03fcf47102fce66a00fcfebc00ffffffff +ffffffffffffff55f4f6f900ecf3f500e8ecef00fcecc400fcfe8006fcfe9a00fcfe8000 +fcfe9a00fcfe8008fcfe9a00fcfe8000fcf47100fce66a03fcf47103fcec7600fcfebc00 +ffffffffffffffffffffff55f4f6f900e8ecef01fcecc400fcfe8004fcfe9a00fcfe8000 +fcfe9a00fcfe800cfcf47100fce66a04fcf47102fcec7600fcfebc00ffffffffffffffff +ffffff55f4f6f900ecf3f500e8ecef00fcecc400fcfe8005fcfe9a00fcfe800dfcf47100 +fce66a04fcf47100fcec7601fcf47100fcf4c600ffffffffffffffffffffff55f4f6f900 +e8ecef01fcecc400fcfe8004fcfe9a00fcfe8002fcfe9a00fcfe8007fcfe9a00fcfe8001 +fcf47100fce66a01fcdc6600fce66a01fcf47102fcec7600fcfebc00ffffffffffffffff +ffffff55f4f6f900ecf3f500e0e4e700fcecc400fcfe8005fcfe9a00fcfe8000fcfe9a00 +fcfe800bfcec7600fce66a04fcf47100fcec7600fcf47101fcf4c600ffffffffffffffff +ffffff55f4f6f900ecf3f500e8ecef00fcecc400fcfe8004fcfe9a00fcfe8000fcfe9a00 +fcfe800cfcf47100fce66a04fcf47100fcec7600fcf47100fcec7600fcfebc00ffffffff +ffffffffffffff55f4f6f900ecf3f500e0e4e700fcecc400fcfe8006fcfe9a00fcfe800c +fce66a02fcdc6600fce66a01fcec7601fcf47101fcf4c600ffffffffffffffffffffff55 +f4f6f900ecf3f500e8ecef00fcecc400fcfe8007fcfe9a00fcfe8000fcfe9a00fcfe8009 +fcec7600fce66a04fcf47100fcec7600fcf47100fce66a00fcfebc00ffffffffffffffff +ffffff55f4f6f900ecf3f500e0e4e700fcecc400fcfe8005fcfe9a00fcfe800dfce66a00 +fcec7600fce66a02fcec7602fcf47100fce66a00fcfebc00ffffffffffffffffffffff55 +f4f6f900e8ecef01fcecc400fcfe8007fcfe9a00fcfe8000fcfe9a00fcfe8000fcfe9a00 +fcfe8007fce66a01fcdc6600fce66a00fcec7600fce66a00fcec7602fce66a00fcf4c600 +ffffffffffffffffffffff55f4f6f901e0e4e700fcecc400fcfe8009fcfe9a00fcfe8002 +fcfe9a00fcfe8001fcfe9a00fcfe8002fce66a00fcec7600fce66a02fcec7600fce66a00 +fcec7600fcf47100fce66a00fcf49700ffffffffffffffffffffff55f4f6f900e8ecef01 +fcecc400fcfe8007fcfe9a00fcfe8001fcfe9a00fcfe8000fcfe9a00fcfe8006fce66a01 +fcdc6600fce66a00fcec7601fce66a00fcec7600fce66a00fcdc6600fcf4c600ffffffff +ffffffffffffff55f4f6f900ecf3f500e0e4e700fcecc400fcfe8008fcfe9a00fcfe8001 +fcfe9a00fcfe8001fcfe9a00fcfe8000fcfe9a00fcfe8002fce66a08fcdc6600fcf49700 +ffffffffffffffffffffff55f4f6f901e0e4e700fcecc400fcfe8006fcfe9a00fcfe8001 +fcfe9a00fcfe8001fcfe9a00fcfe8000fcfe9a00fcfe8003fcf47100fce66a00fcdc6601 +fce66a05fcdc6600fcf4c600ffffffffffffffffffffff55f4f6f900ecf3f500e0e4e700 +fcecc400fcfe8008fcfe9a00fcfe8001fcfe9a00fcfe8002fcfe9a00fcfe8003fcdc6602 +fce66a02fcdc6600fce66a01fcdc6600fcf49700ffffffffffffffffffffff55ecf3f500 +f4f6f900e0e4e700fcecc400fcfe8009fcfe9a00fcfe8002fcfe9a00fcfe8005fcdc6604 +fce66a00fcdc6601fce66a00fcdc6600fcf4c600ffffffffffffffffffffff55f4f6f900 +ecf3f500e0e4e700fcecc400fcf47100fcfe800afcfe9a00fcfe8006fcf47100fce66a00 +fcd46101fcdc6604fce66a00fcdc6600fcf49700ffffffffffffffffffffff55f4f6f900 +e8ecef01fbe4c100fcfe8000fcf47100fcfe8007fcfe9a00fcfe8008fcf47100fcd46103 +fcdc6601fcd46100fcdc6602fcf4c600ffffffffffffffffffffff55f4f6f900ecf3f500 +e0e4e700fbe4c100fcf47100fcfe8012fcf47100fcd46101fccc5d00fcd46104fcdc6600 +fcd46100fcf4c600ffffffffffffffffffffff55f4f6f900e8ecef01fcecc400fcf47103 +fcfe800ffcf47100fcd46100fccc5d03fcd46100fccc5d00fcd46101fcdc6600fcf4c600 +ffffffffffffffffffffff55f4f6f900ecf3f500e8ecef00fbe4c100fcf47105fcfe8000 +fcf47100fcfe8007fcf47100fcfe8000fcf47101fcec7600fcd46100fccc5d06fcd46101 +fceb9900ffffffffffffffffffffff55f4f6f900ecf3f500e0e4e700fcecc400fce66a01 +fcf47109fcfe8002fcf47104fce66a00fccc5d00fcc45900fccc5d00fcc45901fccc5d00 +fcc45900fccc5d01fcd46100fcf4c600ffffffffffffffffffffff55f4f6f900ecf3f500 +e8ecef00fbe4c100fce66a01fcf47100fcec7600fcf4710dfcec7600fcf47100fce66a00 +fcc45901fcbc5400fcc45900fcbc5400fcc45903fccc5d00fcf4c600ffffffffffffffff +ffffff55f4f6f901e0e4e700fbe4c100fce66a03fcec7607fcf47101fcec7600fcf47100 +fcec7600fcf47100fce66a00fcec7600fcdc6600fcbc5400fcc45902fcbc5400fcc45900 +fcbc5401fcc45900fccc5d00fcecc400ffffffffffffffffffffff55f4f6f900e8ecef01 +fbe4c100fce66a08fcec7600fce66a00fcec7605fce66a00fcec7600fce66a00fcdc6600 +fcbc5400fcc45900fcbc5402fcc45900fcbc5402fccc5d00fceb9900ffffffffffffffff +ffffff54f4f6f900ecf3f500e8ecef00e0e4e700fadcaf00fcdc6601fce66a0afcec7600 +fce66a05fcd46100fcbc5400fcc45900fcbc5401fcb45000fcbc5403fcc45900fcecc400 +ffffff2ffcfebc00ffffffffffffffffffffff0bfcfebc00fcf4c600fcf49700fceb9900 +fcec7600fceb9902fcf49700fcf4c603ffffff00fcf4c600ffffff07f4f6f900ecf3f501 +e0e4e701fadcaf00fcdc6608fce66a08fcdc6600fce66a00fcd46100fcbc5403fcb45000 +fcbc5400fcb45002fcbc5400fceb9900ffffff29fcfe9a00fcf49700fce66a07fcec7601 +fceb9900fcf49700fcf4c601ffffff3dfcfebc00ffffff49fcfebc01ffffffffffffff73 +fcf4c600fcdc8700fcd46103fcdc6601fcd46101fcdc6600fcd46100fcdc6602fce66a00 +fcdc6600fcd46100fccc5d00fcc45900fcbc5401fcc45900fcbc6c00fccd8300fcd48800 +fadcaf00fbe4c100f7ece700e8ecef00e0e4e700d9dcde00fadcaf00fcdc6603fcd46100 +fcdc6600fcd46100fcdc6606fce66a00fcdc6604fccc5d00fcb45001fcbc5400fcb45000 +fcac4c00fcbc5400fcb45000fcac4c01fcb45000fcecc400ffffff25fcfebc00fcec7600 +fce66a0ffcdc6601fcd46100fcc45900fcbc5400fcc45900fadcaf00fcf4c600ffffff35 +fcf49700fce66a00fcd46100fcb45000fcbc5400fcd48800fcf4c600ffffff1ffcfe9a00 +fcf47100fcec7600fcf49700ffffff1dfcfebc00fcfe9a00fcf47100fcec7602fcf4c600 +ffffff2cfcf4c600fccc5d00fce66a00fcec7600fcfe9a00ffffff39fcfebc04ffffff4d +fcf4c600fcecc400fadcaf01fce3a100fceb9900fcec7601fce66a00fcec7601fce66a03 +fcec7600fcf49700fcfe9a00ffffff3cf4f6f900ecf3f505f4f6f900ecf3f500f4f6f900 +ffffff00f4f6f901f7ece700fcecc401fbe4c100fadcaf01fce3a101fceb9901fcec7601 +fce66a00fcec7602fcf49700fcfebc00ffffff42fceb9900fcd46100fcc45900fccc5d03 +fcd46104fcdc6600fcd46101fcdc6604fce66a00fcdc6602fccc5d00fcbc5400fcb45000 +fcac4c01fca44800fcac4c00fca44800fcb45000fcbc6c00e8cbab00facca600fcd46105 +fcdc6600fcd46100fcdc6600fcd46100fcdc6609fccc5d00fcb45003fcac4c00fcb45001 +fcac4c01fcb45000fce3a100ffffff22fcfebc00fce66a02fcdc6600fce66a00fcdc6602 +fce66a01fcdc6600fce66a00fcdc6601fce66a00fcdc6601fce66a00fcdc6606fccc5d00 +fcbc5400fcac4c01fcc45900fadcaf00ffffff30fcf47100fce66a03fcc45900fcac4c01 +fcbc5400ffffff1ffcec7602fcf47100fce66a00fce3a100ffffff18fcfe9a00fcec7600 +fce66a06fcdc6600ffffff2cfcc45900fcd46100fcdc6603fce66a00fcf47100fcfebc00 +ffffff2ffcfebc01fcf47100fcec7607fcf47101fcec7600fcf47101fcf49700fcfe9a00 +fcfebc02ffffff3cf4f6f901fbe4c100fadcaf00fac58900fcbc5400fcac4c00fcb45000 +fcc45900fcdc6600fcec7601fce66a00fcec7601fce66a01fcec7600fce66a04fcec7601 +fcf47102fcfebc01ffffff2ffcecc402fbe4c100fceb9901fce3a100fceb9901fcec7601 +fcecc400e8ecef00e0e4e700e9d9b900fad4b000fac58900fcbc6c00fcb45000fcac4c00 +fcb45000fcac4c01fcb45000fcc45900fcd46100fce66a01fcec7600fce66a0bfcf49700 +fcfebc00ffffff3bfcecc400fccc5d00fcc45903fcbc5400fcc45900fccc5d00fcc45900 +fccc5d02fcd46103fcdc6600fcd46100fcdc6602fcd46100fcdc6601fcd46100fcdc6600 +fcd46101fcc45900fcb45000fcac4c00fca44802fc9c4200fca44801fcb45000fccc5d00 +fcd46100fccc5d00fcd46104fcdc6600fcd4610afcc45900fcac4c00fcb45001fcac4c02 +fca44802fcac4c00fbe4c100ffffff1ffcfebc00fce66a00fcdc6602fcd46100fcdc6613 +fcd46102fcdc6600fcd46101fcc45900fcac4c00fca44800fcac4c00fcbc5400fadcaf00 +ffffff2bfcec7600fce66a06fcb45000fcac4c01fcc45900ffffff1dfcec7600fce66a00 +fcec7600fce66a01fcec7601fce66a00fceb9900ffffff12fcfebc00fcf49700fce66a03 +fcdc6600fce66a00fcdc6600fce66a00fcdc6600fce66a01fcdc6600fcf4c600ffffff2a +fbe4c100fcc45900fcdc6606fce66a01fcec7600fcfe9a00ffffff27fcecc400fce3a100 +fceb9900fcec7600fcf47102fcec7603fce66a01fcec7603fce66a00fcec7608fcf47100 +fcec7602fcf47100fcf49701fcfe9a00fcfebc04ffffff00fcfebc00ffffff01fcfebc00 +ffffff00fcfebc00ffffff00fcfebc03fcfe9a00ffffff1df4f6f900ecf3f500e8ecef00 +fadcaf00fac58900fcb45000fcac4c01fcb45000fcc45900fcdc6600fce66a00fcec7600 +fce66a0efcec7606fcf49700fcfebc00ffffff16f4f6f900ffffff00f4f6f901ecf3f504 +f4f6f901f7ece700fcecc400fbe4c101fce3a101fcdc8701fcd46101fcdc6600fce66a01 +fcec7601fce66a00fcec7602fce66a01fcec7600fcd48800fbb47200fcb45000fcac4c01 +fcb45000fcac4c00fcb45000fcac4c01fcc45900fcd46100fce66a07fcdc6605fce66a00 +fcdc6600fce66a00fcdc6600fce66a00fcdc6600fcec7600fcf4c600ffffff37fce3a100 +fcc45900fcbc5400fcc45900fcbc5403fcc45900fcbc5400fcc45901fccc5d02fcd46107 +fcdc6600fcd46106fccc5d01fcbc5400fca44803fc9c4201fcac4c00fccc5d05fcd46101 +fccc5d00fcd46101fccc5d00fcd46107fcc45900fcac4c05fca44801fc9c4200fca44800 +fce3a100ffffff1dfcf49700fcdc6601fcd46108fcdc6606fcd46101fcdc6600fcd46100 +fcdc6601fcd46105fccc5d00fcd46101fccc5d00fcd46100fcc45900fcac4c00fc9c4200 +fca44800fcac4c00fcbc6c00fcf4c600ffffff25fcfebc00fcec7600fcdc6603fce66a00 +fcdc6600fce66a00fcdc6600fce66a00fccc5d00fcac4c00fca44800fcb45000fce3a100 +ffffff1bfcec7600fce66a05fcec7600fce66a01fcdc6600fceb9900ffffff0cfcfebc00 +fcf49700fcec7600fce66a04fcdc6606fcd46100fcdc6601fcd46100ffffff2afcbc6c00 +fccc5d00fcdc6600fcd46100fcdc6601fcd46100fcdc6603fce66a00fcdc6600fce66a01 +fcec7600fcfebc00ffffff1ff4f6f900fadcaf00fcd48800fcd46100fcec7607fce66a08 +fcec7600fce66a0efcec7600fce66a00fcec7606fce66a01fcec7602fce66a00fcec7602 +fce66a00fcf49700ffffff19f4f6f901ecf3f500e8ecef00e9d9b900fac58900fcb45000 +fca44800fcac4c01fcbc5400fcd46100fce66a00fcec7601fce66a07fcdc6600fce66a00 +fcdc6604fce66a02fcec7602fce66a03fcdc8700fcec7600fcf49700ffffff10f4f6f901 +ecf3f502e8ecef00e9d9b900f9dcd100e8cbab00fac58901fcbc8800fbb47200fcb45000 +fcac4c00fca44800fcbc5400fce66a09fcdc8700fcec7600fce66a07fcbc5400fcac4c06 +fcb45000fcdc6600fce66a02fcdc6604fcd46100fcdc6603fcd46100fcdc6601fcd46100 +fcdc6606fce66a00fcecc400ffffff33fcdc8700fcbc5406fcc45900fcbc5402fcc45902 +fccc5d00fcc45900fccc5d01fcd46108fccc5d04fcc45900fccc5d00fcc45901fcac4c00 +fc9c4201fca44800fc9c4200fca44800fcc45901fccc5d07fcc45900fccc5d08fcc45900 +fcac4c03fc9c4200fcac4c00fc9c4203fbe4c100ffffff1bfceb9900fcd46101fccc5d00 +fcd46100fccc5d01fcd46100fccc5d02fcd46100fccc5d00fcd46110fccc5d08fcd46100 +fcbc5400fcac4c00fc9c4200fca44801fcb45000fadcaf00ffffff21fcfebc00fcdc8700 +fcdc6600fcd46100fcdc6606fce66a00fcdc6601fcbc5400fca44801fcb45000ffffff1a +fceb9900fcdc6602fce66a00fcdc6600fce66a02fcec7600fce66a00fcec7600fcdc8700 +fcd46100fce3a100ffffff07fcf49700fce66a07fcdc6601fcd46100fcdc6600fcd46102 +fccc5d00fcd46104fcf4c600ffffff23f4f6f904fadcaf00fcbc5400fcd46100fcdc6600 +fcd46103fcdc6609fce66a00fcec7600fcfe9a00ffffff1afadcaf00fac58900fcc45900 +fcdc6600fce66a00fcec7600fce66a01fcec7600fce66a0efcdc6601fce66a00fcdc6601 +fce66a00fcdc6600fce66a00fcdc6600fce66a00fcdc6600fce66a00fcdc6600fce66a00 +fcdc6601fce66a03fcec7600fce66a09fcec7600fce66a00fcec7600fcfebc00ffffff17 +ecf3f502e0e4e700facca600fbb47200fca44800fcac4c00fca44800fcac4c00fcbc5400 +fcdc6600fce66a0bfcdc6609fce66a00fcec7600fce66a03fcdc6600fce66a01fcdc6600 +fce66a01fcec7600ffffff0cf4f6f900ecf3f501e8ecef01e0e4e701fac58900fcac4c00 +fca44800fc9c4200fca44802fcac4c00fca44802fcbc5400fcdc6602fce66a00fcdc6600 +fce66a00fcdc6600fce66a00fcdc6600fce66a03fcdc8700fce66a00fcdc8700fce66a00 +fcdc6600fce66a01fcbc5400fcac4c00fca44800fcac4c02fca44800fccc5d00fcdc6600 +fce66a00fcdc6604fcd46100fcdc6600fcd46100fcdc6600fcd46107fcdc6602fcd46101 +fcdc6600fcd46101fcdc6601fcf4c600ffffff2ffcdc8700fcbc540efcc45903fccc5d03 +fcd46100fccc5d05fcc45905fcbc5400fcc45900fcbc5400fcb45000fc9c4202fca44800 +fcc4590dfccc5d00fcc45900fccc5d01fcc45900fccc5d00fcbc5400fca44802fc9c4201 +fca44800fc9c4203fce3a100ffffff19fceb9900fcd46100fccc5d06fcc45900fccc5d00 +fcc45900fccc5d00fcc45900fccc5d03fcd46101fccc5d00fcd46102fccc5d00fcd46102 +fccc5d05fcc45900fccc5d03fcc45900fccc5d00fcc45902fcb45000fc9c4201fc944100 +fca44800fcac4c00fadcaf00ffffff1dfcf4c600fcd46100fccc5d00fcd46105fcdc6606 +fcd46100fcac4c00fc9c4200fca44800fcbc6c00ffffff17f4f6f900fcecc400fcd46102 +fcdc6600fcd46100fcdc6603fce66a00fcdc6600fce66a02fcdc6600fcd46100fbe4c100 +ffffff05fcdc6602fcdc8700fcdc6601fcd46108fccc5d00fcd46100fccc5d04fcd46100 +ffffff21f4f6f900ecf3f501e8ecef03fcbc6c00fcc45900fcd46106fcdc6603fcd46100 +fcdc6606fce66a01ffffff15f7ece700fad4b000fcb45000fcc45900fcdc6600fce66a08 +fcdc6600fce66a00fcdc6600fce66a01fcdc6614fcd46100fcdc6604fce66a00fcdc6600 +fce66a01fcdc6600fce66a00fcdc6600fce66a07ffffff15f4f6f900ecf3f501e8ecef00 +e0e4e700fac58900fca44802fc9c4200fca44800fcbc5400fcd46100fce66a00fcdc6600 +fce66a00fcdc6601fce66a00fcdc6600fce66a00fcdc6605fce66a00fcdc6600fce66a00 +fcdc6606fce66a01fcdc8700fce66a01fcdc6603fce66a00fcdc6601fce66a00fcdc6600 +fceb9900ffffff09ecf3f501e8ecef00e0e4e700d9dcde03efbc8e00fca44800fc9c4203 +fca44801fc9c4202fcbc5400fcdc660cfce66a02fcdc6600fcdc8700fce66a00fcdc6600 +fcbc5400fca44801fcac4c00fc9c4200fcb45000fcd46100fce66a01fcdc6601fcd4610a +fccc5d01fcd4610afccc5d00fcd46101fce3a100ffffff2cfce3a100fcc45900fcbc5404 +fcb45006fcbc5402fcc45900fcbc5401fcc45904fccc5d00fcc45900fccc5d01fcc45906 +fcbc5403fcb45000fcbc5401fcb45000fc9c4200fc944100fc9c4200fcbc5402fcc45900 +fcbc5400fcc45900fcbc5408fcc45904fcb45000fca44800fc9c4200fca44800fc9c4202 +fc944100f38b3600fc944100fc9c4200fadcaf00ffffff17fcf4c600fccd8300fccc5d02 +fcc45907fcbc5400fcc45900fcbc5400fcc45902fccc5d00fcc45901fccc5d00fcc45900 +fccc5d07fcc4590ffcac4c00fc9c4200fc944101fc9c4200fca44800fbe4c100ffffff19 +fcecc400fcd46100fcc45900fccc5d05fcd46103fcdc8700fcd46100fcdc6600fcd46100 +fcdc6601fcc45900fc9c4201fca44800fbe4c100ffffff14f4f6f900e8ecef00f7ece700 +fccd8300fcd46100fccc5d00fcd46104fcdc6603fcd46100fcdc6600fcd46100fcdc6601 +fcd46100fcc45900fadcaf00ffffff03fcdc8700fcd46100fcdc6600fcd46105fccc5d00 +fcd46100fccc5d04fcc45900fccc5d04fcbc5400ffffff20f4f6f900e8ecef01e0e4e703 +e6ccc900fcac4c00fccc5d01fcd46100fccc5d00fcd46102fcdc6600fcd46108fcdc6600 +fcd46100fcdc6601fcf4c600ffffff13f7ece700fac58900fcac4c00fcbc5400fcdc6600 +fce66a00fcdc6605fcd46100fcdc6600fcd46100fcdc6600fcd46100fcdc6601fcd46100 +fcdc6600fcd46100fcdc6600fcd46100fcdc6602fcd46100fcdc6600fcd46100fcdc6600 +fcd46104fcdc6600fcd46109fcdc6603fcdc8700fcdc6600fce66a00fcdc8700fce66a00 +fcdc6600fcdc8700fcdc6601fce66a00fcdc8700fcec7600ffffff13f4f6f900ecf3f501 +e8ecef00e6dcdc00fcbc8800fca44800fc9c4203fcac4c00fcd46100fcdc6602fce66a00 +fcdc6607fce66a00fcdc6608fcd46100fcdc6604fce66a00fcdc660cfcf4c600ffffff06 +ecf3f501e0e4e701d9dcde01d2d4d602efbc8e00fc9c4209fcac4c00fccc5d00fcd4610a +fcdc6600fcd46100fcdc6601fce66a00fcdc6601fce66a00fcb45000fca44801fc9c4200 +fcbc5400fcdc6602fcd46100fcdc6600fcd46104fccc5d00fcd46100fccc5d00fcd46100 +fccc5d07fcd46102fccc5d08fcd46100ffffff29fcf4c600fcbc6c00fcbc5404fcb45001 +fcbc5400fcb45006fcbc5400fcb45000fcbc5405fcc45900fcbc5401fcc45900fcbc5400 +fcc45900fcbc5400fcc45900fcbc5404fcb45007fcac4c00fc9c4201fcbc5402fcb45000 +fcbc5400fcb45000fcbc5400fcb45003fcbc5407fcc45900fcb45000fc9c4201fca44800 +fc9c4202f38b3602fc9c4200fad4b000ffffff16fcd46100fcc45905fcbc5400fcc45900 +fcbc5406fcc45900fcbc5400fcc45900fcbc5400fcc45900fcbc5400fcc4590cfcbc5406 +fcc45900fcbc5406fcb45000fc9c4200f38b3601fc944100fc9c4200fbb47200ffffff16 +fcecc400fcd46100fcc45906fccc5d03fccd8300fccc5d00fcd46101fccd8300fcd46103 +fcac4c00fc9c4201fcac4c00ffffff13ecf3f500e8ecef01fccd8300fcc45900fccc5d04 +fcd46105fcdc6600fcd46100fcdc6600fcd48800fcd46102fccc5d00fcbc6c00fadcaf00 +ffffff01fcecc400fcd46103fccc5d07fcc45909fccd8300ffffff1ef4f6f900e8ecef00 +e0e4e700d9dcde02d2d4d600d9dcde00ecae7c00fcbc5400fccc5d06fcd46104fccc5d00 +fcd46104fcd48800fcd46101ffffff12f4f6f900fac58900fca44800fcb45000fcd46100 +fcdc6606fcd46106fccc5d01fcd46100fccc5d00fcd46112fccc5d00fcd46101fccc5d00 +fcd46104fcdc6603fcdc8700fcdc6602fce66a00fcdc6603fcf4c600ffffff11f4f6f901 +ecf3f500e8ecef00d9dcde00efbc8e00fc9c4200fc944103fc9c4200fcbc5400fcd46102 +fcdc6601fcd46100fcd48800fcdc6600fcd46100fcdc6600fcd46101fcdc6601fcd46100 +fcdc6604fcd46100fcdc6600fcd46103fcdc6601fcdc8700fcdc6600fcdc8700fcdc6601 +fcd46100fcdc6600fcd46109fcec7600ffffff04ecf3f501e0e4e701d9dcde00d2d4d600 +cbcccd02c4c5c500e4ae7c00fc944104fc9c4201fc944102fcac4c00fccc5d04fcd46109 +fcdc6600fcd46100fcdc6602fcb45000fc9c4201fcc45900fcdc6602fcd46100fcdc6600 +fcd46101fccc5d0afcc45900fccc5d00fcc45900fccc5d03fcc45900fccc5d04fcc45900 +fccc5d00fcc45900fccc5d00fcc45900fcd48800ffffff27fccd8300fcb4500afcac4c00 +fcb45000fcac4c00fcb45002fcac4c00fcb4500bfcbc5404fcb45002fcac4c00fcb45000 +fcac4c06fcb45000fc9c4200fcb45004fcac4c00fcb45006fcbc5400fcb45000fcbc5404 +fcb45000fc9c4203fc944100fc9c4200f38b3602fc8c3d00fadcaf00ffffff14fce3a100 +fcbc5401fcc45901fcbc5406fcb45000fcbc5400fcb45002fcbc5400fcb45003fcbc5400 +fcb45000fcbc5404fcc45900fcbc5401fcc45903fcbc5409fcb45000fcbc5400fcb45003 +fcbc5401fcac4c00fc944100f38b3600fb843a00fc944101fccd8300ffffff12fcecc400 +fcc45905fcbc5400fcc45900fcbc5400fcc45905fccc5d00fcc45901fccc5d00fcc45901 +fccc5d01fcc45900fc9c4200fc944101fcbc8800ffffff10f4f6f900e8ecef01e0e4e700 +fcd48800fcc45903fccc5d00fcc45900fccc5d03fcd46102fcd48800fcd46104fccc5d00 +fcd46100fccc5d00fcc45900fcac6600facca600f7ece700fcd48800fcd46100fccd8300 +fccc5d02fcc45900fccc5d00fcc45904fcbc5400fcc45901fcbc5401fcc45900fcbc5402 +fcb45000ffffff1df4f6f900e8ecef00e0e4e700d9dcde00d2d4d601cbcccd01d7c4bd00 +fca44800fcc45901fccc5d11fcd46100fceb9900ffffff10f4f6f900f8d4c900fca44800 +fc9d4c00fcc45900fcd46101fcdc6600fcd46100fcd48800fcdc6600fcd46106fccc5d0c +fcd46100fccc5d00fcd46100fccc5d00fcd46100fccc5d0cfcd46100fccc5d00fcd46105 +fcdc6601fcdc8700fcd46104fcdc6600fcfebc00ffffff10ecf3f500e8ecef01e0e4e700 +e8cbab00f19e5c00f38b3600fc944102f38b3600fcac4c00fcc45900fcd46100fccc5d00 +fcd46101fccd8300fcd4610afcd48800fcd46100fcdc6600fcd48800fcd4610afcdc6600 +fcd46108fccc5d00fcd46102fccc5d01fcd46100ffffff02f4f6f900ecf3f500e8ecef00 +d9dcde01d2d4d600c4c5c501bbbcbd00c4c5c500bbbcbd00d8a47800fc944101f38b3600 +fc944100f38b3600fc944102f38b3601fc9c4200fcc45903fccc5d00fcc45901fccc5d00 +fcc45900fccc5d02fccd8300fcd46106fcac4c00fc9c4200fccc5d00fcd46104fccc5d04 +fcc45900fccc5d00fcc45919fcdc8700ffffff24fcf4c600fcbc6c00fcac4c09fca44800 +fcac4c01fca44800fcac4c01fca44800fcac4c0cfcb45000fcac4c00fcb45000fcac4c00 +fcb45001fcac4c00fcb45000fcac4c02fca44800fcac4c00fca44802fcac4c00fca44800 +fcac4c0dfcb45003fcbc6c00fcbc5402fcac4c00fc944105f38b3602fc944100fcd48800 +ffffff13fccd8300fcb45002fcbc5401fcb45000fcbc5400fcb45006fcac4c00fcb45000 +fcac4c02fcb45000fcac4c01fcb45004fcbc5400fcb45000fcbc5409fcb4500efcbc5400 +fcb45000fc944100f38b3600fb843a00f38b3600fc944100fca46d00ffffff11fbe4c100 +fcbc540afcbc6c00fcc45907fcbc6c00fcc45902fcb45000fc8c3d00f38b3600fc944100 +fbe4c100ffffff0ef4f6f900ecf3f500e0e4e701e9d5d700fcbc5402fcc45905fccc5d04 +fcd46100fccc5d00fccd8300fcd46100fccc5d00fccd8300fccc5d02fcbc5400fc8c3d00 +fc9c4200e6dcdc00fcd48800fccc5d03fcc45906fcbc5400fcc45900fcbc5407fcb45000 +fcd48800ffffff1bf4f6f900e8ecef00e0e4e700d9dcde00d2d4d600d8cccb00c4c5c500 +cbcccd00c4c5c500e4ae7c00fcac4c00fccc5d00fcc45901fccc5d00fcc45902fccc5d00 +fcc45901fccc5d00fcc45901fccc5d00fcc45900fccc5d01fccd8300fccc5d01fccd8300 +ffffff0ef4f6f901e8ecef00efbc8e00fc944100fca44800fcc45900fccc5d01fcd46100 +fccc5d01fcd46100fccc5d00fcd46100fccd8300fcd46100fccd8300fccc5d00fcd46100 +fccc5d02fcc45907fccc5d00fcc45900fccc5d00fcc45900fccc5d00fcc45901fccc5d00 +fcc45900fccc5d00fcc45900fccc5d00fcc45907fccc5d00fcc45900fccc5d02fccd8300 +fcd46102fccd8300fcd46100fccc5d00fcd46100fccc5d00fcd46100fccd8300fcd46101 +ffffff0fecf3f501e8ecef00e0e4e700d9dcde00e4ae7c00fc944101fc9c4200f38b3601 +fc944100fcb45000fccc5d09fccd8300fccc5d00fccd8300fccc5d01fccd8300fccc5d01 +fcd46105fccd8300fccc5d03fcd46102fcd48800fcd46101fccd8300fccc5d07fcc45901 +fccc5d00fcc45900fccc5d00fcc45900fccd8300fcf4c600ffffff00ecf3f500e8ecef00 +d9dcde01cbcccd00c4c5c500bbbcbd02b4b4b401d8a47800f38b3606fc8c3d00f38b3600 +fb843a00fc9c4200fcc45900fcbc5400fcc45900fcbc5401fcc45900fcbc6c00fcc45901 +fcbc6c00fcc45900fccc5d00fcc45901fccc5d00fccd8300fccc5d00fcd46100fccd8300 +fcd46100fcac4c00fcc45900fccc5d03fcc45900fccc5d00fcc4590afcbc5400fcc45900 +fcbc5406fcc45900fcbc5400fcc45900fcbc5400fcc45900fcbc5401fcc45900fcbc5405 +fcf4c600ffffff22fbe4c100fcac4c01fca44801fcac4c01fca44800fcac4c00fca44808 +fc9c4200fca44802fc9c4200fca44800fc9c4202fca44800fc9c4200fca44802fcac4c00 +fca44800fcac4c02fca44800fcac4c00fca44800fcac4c00fca44802fc9c4201fca44800 +fc9c4201fca44803fcac4c00fca44807fcac4c04fcac6600fcb45004fca44800fc944100 +fc8c3d01fc944100f38b3600fb843a04fad4b000ffffff12fcbc6c00fcac4c00fcb45005 +fcac4c01fcb45000fcac4c04fca44800fcac4c00fca44800fcac4c01fca44800fcac4c01 +fca44800fcac4c06fcb45003fcbc5400fcb4500afcac4c04fcb45004fcbc5400fc9c4200 +fb843a02fc8c3d00fc9c4200fcecc400ffffff10fccd8300fcb45009fcbc5403fcbc6c00 +fcbc5400fcc45900fcbc6c00fcbc5400fcc45900fcbc6c00fcc45901fcbc5400fca44800 +f38b3601fc9c4200ffffff0ee8ecef01d9dcde00e9d5d700fcbc6c00fcb45000fcbc5408 +fcc45902fccc5d00fac58900fccc5d02fcc45900fccc5d00fcc45900fccc5d00fcbc5400 +fc944101e8cbab00d9dcde00e6dcdc00fac58900fcc45905fcbc5400fcc45900fcbc5405 +fcb45000fcbc5400fcb45004fcac4c00ffffff1be8ecef01d9dcde00d2d4d600cbcccd00 +c4c5c502c6bcba00fc9c4200fcbc5400fcc4590afccc5d00fcc45900fccc5d00fcc45901 +fccc5d00fcc45902fcdc8700ffffff0df4f6f900ecf3f500f9e4e100f19e5c00fc8c3d00 +fc944100fcbc5400fcc45901fcbc6c00fcc45902fccc5d00fcc45900fccc5d05fcc45906 +fcbc5400fcc45908fcbc5400fcc45900fcbc5400fcc45900fcbc5400fcc45900fcbc5400 +fcc45901fcbc5400fcc45900fcbc5400fcc45900fcbc5400fcc45903fccc5d02fccd8300 +fccc5d05fcc45900fccc5d01fcdc8700ffffff0df4f6f900ecf3f500e8ecef00e0e4e701 +d8cccb00fc9d4c00fc944100f38b3600fc8c3d00f38b3601fc9c4200fcbc5400fcc45900 +fccc5d00fcc45901fccc5d00fcc45900fccc5d00fcc45900fccc5d00fcc45906fccc5d00 +fcc45900fccc5d02fccd8300fccc5d00fccd8300fccc5d05fccd8300fccc5d00fccd8300 +fccc5d04fcc45901fccc5d00fcbc6c00fcc45900fcbc5400fcc45908f7ece700e8ecef00 +e0e4e700d9dcde00d2d4d600cbcccd00bbbcbd00b4b4b401abacad02cc916400f38b3601 +fb843a02f38b3600fb843a00f38b3600fb843a01fc9c4200fcb45000fcbc5400fcb45001 +fcbc5400fcb45000fcbc5403fcc45900fcbc5400fcc45901fcbc5401fcc45905fcbc5400 +fcc45900fcbc5400fcc45902fcbc5400fcc45900fcbc540bfcb45000fcbc5400fcb45000 +fcbc5402fcb45000fcbc5400fcb45000fcbc5403fcb45000fcbc5403fcb45000fcbc5400 +fccd8300ffffff21fadcaf00fca44800fc9d4c00fca44802fc9c4200fca44801fc9c4200 +fca44801fc9c4200fca44800fc9c4213fca44800fc9c4200fca44802fc9c4200fca44800 +fc9c420bfca44800fc9c4201fca44800fc9c4203fca44803fcac4c05fcac6600fcac4c01 +fca44800fc8c3d00f38b3603fb843a02ec742a00f38b3600fcd48800ffffff10f4f6f900 +fcb45000fcac4c03fcac6600fcac4c01fca46d00fcac4c00fca44801fcac4c00fca44805 +fc9c4200fca44800fc9c4200fca44801fc9c4200fca44805fcac4c00fca44800fcac4c03 +fcac6600fcb45001fcac4c01fcb45000fcac4c0dfcb45003fc9c4200fb843a02f38b3600 +fc8c3d00fbe4c100ffffff0ef4f6f900f7ece700fcbc5400fcac4c00fcb45009fcbc5400 +fcb45000fcbc5400fcb45001fcbc5401fcb45000fcbc5403fcb45000fc8c3d00f38b3600 +fb843a00fbb47200ffffff0bf4f6f900ecf3f500e8ecef00e6dcdc00d9dcde00fac58900 +fcb45003fcbc5400fcb45000fcbc5400fcb45000fcbc5403fcbc6c00fcc45900fcbc6c00 +fcc45901fcbc6c00fcc45900fac58900fcc45900fcbc6c01fc9c4200fc8c3d00ecae7c00 +d9dcde00d2d4d601fac58900fcbc5409fcb45006fcac4c01fcb45000fcac4c00fcb45000 +fadcaf00ffffff19ecf3f500e8ecef00e0e4e700d2d4d601cbcccd00c4c5c502e4ae7c00 +fca44800fcc45900fcbc5400fcc45900fcbc5400fcc45901fcbc5400fcc45906fcbc6c00 +fcc45900fac58900fcc45901fac58900fcc45900ffffff0cf4f6f900ecf3f500e8ecef00 +e6dcdc00f19e5c00f38b3600fc8c3d00fcb45000fcbc5403fcc45900fcbc6c00fcc45900 +fcbc6c00fcc4590afcbc5405fcbc6c00fcbc540cfcb45000fcbc5400fcb45001fcbc5400 +fcb45000fcbc5402fcc4590afcbc6c00fcc45902fcf4c600ffffff0cf4f6f900ecf3f500 +e8ecef00e0e4e700d9dcde00d7c4bd00fc944100f38b3603fb843a00fc944100fcc45906 +fcbc6c00fcc45900fcbc6c00fcc45900fcbc6c00fcc45900fcbc6c00fcc45900fcbc6c00 +fcbc5400fcbc6c00fcc45900fcbc6c00fcc45900fac58900fcc45900fccc5d00fcc45900 +fccc5d00fcc45900fccc5d00fcc45900fccd8300fcc45900fccc5d04fcc45901fcbc6c00 +fcc45900fcbc6c00fcc45901fcbc6c00fcc45900fcbc5405fcbc6c00fcbc5400fcc45900 +fcbc5400fcc45900f9dcd100e0e4e700d2d4d600cbcccd00bbbcbd01abacad01a4a5a402 +cc916400fc8c3d00fb7c3800fb843a05fb7c3800ec742a00fc944100fcb45001fcac4c00 +fcb45000fcac4c00fcb45003fcbc5400fcb45003fcbc5401fcb45000fcbc5402fcb45000 +fcbc5401fcb45000fcbc5402fcb45000fcbc5400fcb45001fcbc5401fcb45000fcbc5400 +fcb4501bfcf4c600ffffff1ffad4b000fc9c4200fc944100fc9c4200fc944102fc9c4201 +fc944100fc9c4200fc944100fc9c4200fc944100fc9c4200fc944100fc9c4200fc944100 +fc9c4200fc944100fc9c4200fc944105fc9c4200fc944105fc9c4200fc944100fc9c4200 +fc944100fc9c4200fc944100fc9c4200fc944100fc9c4200fc94410afc9c4200fc944100 +fc9c4201fc944100fc9c4204fca4480afc9c4200f38b3600fb7c3800fb843a00f38b3600 +fb843a01ec742a00fb843a00fb7c3800fb843a00facca600ffffff10fcac4c00fca4480a +fc9c4200fca44800fc9c4200fca44800fc9c4200fca44800fc9c4201fca44800fc9c4201 +fca44800fc9c4200fca44800fc9c4204fca44804fcac4c03fcac6600fcac4c00fcac6600 +fcac4c03fca44800fcac4c00fca44800fcac4c00fca44802fcac4c00fca44800fcac4c06 +fc944100ec742a00fb7c3800ec742a00f38b3600fb843a00fbe4c100ffffff0cf4f6f900 +e8ecef01f9dcd100fca44801fcac4c00fca44800fcac4c03fcb45001fcac4c00fcb4500c +fca44800fb843a02fbe4c100ffffff0af4f6f900e8ecef00e0e4e700d9dcde00e8cbab00 +fcac4c03fcb45000fcac4c00fcb45000fcac4c00fcb45005fcbc5402fcbc6c00fcc45900 +fcbc6c00fcbc5400fcc45900fcbc5400fc9c4200fb843a00f19e5c00d2d4d600cbcccd02 +e6ccc900fcb4500bfcac4c00fcb45000fcac4c08ffffff18f4f6f900ecf3f500e0e4e700 +d9dcde00d2d4d600cbcccd00c4c5c502c6bcba00fc955100fcb45000fcbc540afcc45900 +fcbc6c00fcc45902fcbc6c00fcc45901fcbc5400fccd8300ffffff0af4f6f900ecf3f500 +e8ecef01d9dcde00f19e5c00fb843a01fcac4c00fcb45003fbb47200fcb45001fcbc5402 +fcbc6c00fcc45900fcbc6c00fcc45901fcbc6c00fcc45900fcbc6c00fcbc5404fcb45000 +fcbc5400fcb45006fcac4c00fcb45001fcac4c00fcb45000fcac4c00fcb45002fcac4c00 +fcb45005fcbc5401fcbc6c00fcc45900fcbc6c00fcc45903fcbc5400fcbc6c00fcc45900 +fcbc5400fcc45900fcbc5401ffffff0cecf3f500e8ecef00e0e4e700d9dcde01d8bcb600 +f38b3603fb843a00f38b3600fc944100fcbc5405fcbc6c00fcbc5401fcbc6c00fcbc5402 +fcb45000fcbc5401fcb45000fcbc5402fcbc6c00fcc45901fcbc6c00fcc45901fcbc6c00 +fcc45900fcbc6c00fcc45900fcbc5400fcc45900fcbc6c00fcc45900fcbc6c00fcc45900 +fcbc6c00fcc45900fcbc6c00fcc45900fcbc6c00fcc45900fcbc6c00fcbc5403fcbc6c00 +fcb45000fcbc5408e9d9b900d2d4d600cbcccd00bbbcbd00b4b4b400abacad009c9e9c00 +a4a5a402cc916400fb7c3800fb843a00ec742a00fb7c3800ec742a01f38b3600ec742a00 +f38b3600fb7c3800fc8c3d00fcac4c06fcb45000fcac4c00fcb45000fcac4c00fcb45001 +fcac4c02fcb45000fcac6600fcac4c00fcb4500afcac4c00fcb45000fcac4c00fcb45000 +fcac4c00fcb45000fcac4c00fcb45002fcac4c00fcb45000fcac4c08fcb45000fcac4c02 +fcb45000fcac4c06facca600ffffff1efcecc400fc955100fc944107fc8c3d00fc944101 +fc8c3d00fc944100fc8c3d00fc944100f38b3600fc8c3d04fc944100f38b3600fc8c3d01 +fc944100fc8c3d00fc944110fc8c3d00fc944100fc8c3d00fc944103fc9c4200fc944101 +fc9c4200fc944102fc9c4200fc944100fc9c4201fc9d4c04fca44800fc9d4c00fca44804 +fc9c4200fb7c3801fb843a02ec742a00fb843a00ec742a00fb7c3801facca600ffffff0f +fbb47200fc9c4202fca44800fc9d4c00fca44800fc9d4c00fca44800fc9d4c00fc9c4205 +fc944100fc9c4200fc944100fc9c4200fc944100fc9c4201fc944100fc9c4201fc944100 +fc9c4206fca44814fcac4c00fca44800fcac4c00fca44800fcac4c01fca44800fcac4c00 +fca44801f38b3600ec742a00fb7c3800ec742a00fb7c3800f38b3600f4f6f900ffffff0a +ecf3f500e8ecef00e0e4e701d9dcde00fac58900fca44804fcac4c00fca44800fcac4c0b +fcac6600fcac4c01fcb45000fcac4c00fc8c3d00fb7c3801fc944100ffffff09f4f6f900 +e8ecef00e0e4e700d9dcde00e9d5d700fcb45000fca44800fcac4c00fca44800fcac4c01 +fca44800fcac4c04fcb45003fbb47200fcb45000fcbc5400fcb45000fcbc5400fcbc6c00 +fcb45000fcac4c00fb7c3800f38b3600c4c5c500cbcccd03c4c5c500fcbc8800fcac4c00 +fcb45000fcac4c02fcb45001fcac4c00fcb45000fcac4c00fcb45000fcac4c03fca44800 +fcac4c00fca44801fcac4c00fca44801fbe4c100ffffff17f4f6f900e8ecef00e0e4e700 +d9dcde00d8cccb00cbcccd00c4c5c502d8ac9f00f38b3600fcb45006fbb47200fcbc5400 +fcb45000fcbc6c00fcb45000fcbc6c00fcbc5400fcbc6c01fcbc5401fcbc6c00fcb45000 +fcbc5400fcf4c600ffffff09ecf3f501e8ecef00e0e4e700d9dcde00e8a58f00fb7c3800 +ec742a00fc9c4200fcb45000fcac4c00fcac6600fcb45000fcac4c01fcb45002fbb47200 +fcb45000fcbc5400fcb45000fcbc5400fcb45000fcbc6c00fcb45001fcbc5400fcb45005 +fcac4c00fcb45000fcac4c00fcb45000fcac4c00fcac6600fcac4c02fca44800fcac4c00 +fca44800fcac4c00fca44800fcac4c00fca44800fcac4c01fca44800fcac4c00fca44800 +fcac4c01fcb45002fcbc5403fbb47200fcbc5400fcb45000fcbc5400fcb45004fcbc6c00 +ffffff0af4f6f900ecf3f500e8ecef00e0e4e700d9dcde00d2d4d600c6bcba00f38b3602 +fb843a00ec742a00fb7c3800f38b3600fcac4c00fcbc5401fcb45004fcbc5400fcb45009 +fcac6600fcb45002fcbc5401fcbc6c01fcbc5400fcbc6c00fcbc5401fbb47200fcbc5401 +fcbc6c00fcbc5401fcb45001fcbc5400fcb4500efbb47200fcb45002fbb47200e8cbab00 +c4c5c500bbbcbd00b4b4b400abacad00a4a5a403cc916400f38b3600ec742a02fb843a00 +ec742a00fb7c3800ec742a02fc944100fcac4c02fca44800fcac4c00fca44801fcac4c00 +fca44800fcac4c01fca44801fcac4c00fca44803fcac4c00fca44802fcac4c00fca44801 +fcac4c05fca44800fcac4c00fca44800fcac4c00fca44800fcac4c00fca44801fcac4c00 +fca44800fcac4c00fca44800fcac4c00fca44800fcac4c00fca44801fcac4c00fca44801 +fcac4c00fca44800fcac4c01fca44800fcac4c00fca44802fc9c4200fca44800fc9c4200 +fcac6600ffffff1efc9d4c00fc8c3d0cf38b3601fb843a00f38b3604fb843a00f38b3600 +fb843a00f38b3602fc8c3d04fc944100fc8c3d0cfc944100fc8c3d00fc94410dfc9c4200 +fc944101fc9c4200fc944100fc9d4c01fc955100fc9d4c04fc944100ec742a03fb7c3800 +ec742a04facca600ffffff0efac58900fc944101fc9c4200fc944100fc9c4200fc944100 +fc9d4c00fc944100fc9d4c00fc9c4200fc944100fc9d4c00fc944106fc8c3d00fc944100 +fc8c3d01fc944100fc8c3d00fc944104fc9c4200fc944100fc9c4203fc9d4c01fca44800 +fc9d4c00fca46d00fca44804fc9d4c00fca44800fc9d4c00fc9c4200fca44800fc9c4200 +fca44804fc9c4200fca44806fc9c4200fb843a00ec742a02fb7c3800fc8c3d00ffffff09 +f4f6f900e8ecef00e0e4e700e6dcdc00d9dcde00d2d4d600d9dcde00fbb47200fc9c4201 +fca44812fcac4c00fca44801fb7c3800ec742a01fbb47200ffffff07f4f6f901e0e4e701 +d9dcde00fcb58e00fca4480cfcac4c00fca46d00fcac4c02fcac6600fcb45000fcac6600 +fcb45000fcac4c00fb7c3800f38b3600d8bcb600d8cccb00cbcccd00c4c5c500cbcccd00 +c4c5c500cbcccd00e8c2b000fcac4c00fcac6600fcac4c05fca44800fcac4c00fca44800 +fcac4c00fca44809fcac6600ffffff17ecf3f500e8ecef00d9dcde00d2d4d601c4c5c503 +e68d5600fca44800fcac4c02fcac6600fcac4c00fcac6600fcac4c00fcb45000fcac6600 +fcb45000fcac6600fcb45004fbb47200fcb45002fcbc6c00ffffff08f4f6f900ecf3f500 +e8ecef00e0e4e700d9dcde00d2d4d600d7c4bd00ec742a00fb7c3800fc8c3d00fcac4c00 +fca44800fcac4c01fca44800fcac4c01fca44800fcac6600fcac4c02fcb45000fbb47200 +fcb45001fcac4c00fcb45001fcac4c00fcb45000fcac4c05fca44800fcac4c00fca4480d +fc9c4200fca44805fcac4c01fcb45000fcac6600fcb45001fcac4c00fcb45003fcac4c00 +fcb45001fcac6600fcd48800ffffff09f4f6f900ecf3f500e0e4e700d9dcde01d2d4d600 +c4c5c500e68d5600ec742a00fb843a00ec742a01fb7c3800ec742a00fca44800fcac4c00 +fcb45001fcac4c00fcb45000fcac4c00fcb45000fcac6600fcb45001fcac6600fcb45000 +fcac6600fcac4c00fcac6600fcac4c00fca46d00fca44800fcac4c05fcac6600fcb45004 +fcac4c00fcb45000fcac6600fcac4c00fcb45002fcac6600fcb45000fcac4c00fcac6600 +fcb45003fcac6600fcac4c00fcac6600fcac4c00fcac6600fcac4c00fcac6600fca44800 +fca46d00fcac4c02fcac6600fcac4c01fbb47200c4c5c500bbbcbd00b4b4b400a4a5a404 +cc916400ec742a01fb7c3800ec742a01f38b3600ec742a00f38b3600fb843a00ec742a00 +f38b3600fcac4c00fca44800fcac4c00fca44809fc9d4c03fca44800fc9d4c00fca4480f +fc9c4200fca44800fc9c4200fca44800fc9c4200fca44800fc9c4200fca44802fc9c4200 +fca44807fc9c4200fca44800fc9c4207fcecc400ffffff1cfbb47200fb843a00fc8c3d03 +fb843a00fc8c3d00fb843a11f38b3600fb843a00f38b3602fc8c3d00fc944100fc8c3d0b +fc944100fc8c3d00fc944100fc8c3d00fc944100fc8c3d01fc944101fc8c3d00fc944100 +fc8c3d00fc944100fc8c3d00fc944104fc955100fc9c4200fc944102fc9c4200fc944100 +fc9c4200fc944101fc955100fc9c4200fc944100fc8c3d00ec742a02fb7c3800ec742a05 +facca600ffffff0df9dcd100fc944106fc9c4200fc944109fc8c3d03f38b3601fc8c3d02 +fc944100fc8c3d00fc944108fc9d4c01fc9c4201fc9d4c05fc9c4202fc944100fc9c4202 +fc944100fc9c4205fc9d4c00fc9c4200fca44800fc9d4c00fc9c4200fc8c3d00ec742a04 +fbb47200ffffff07f4f6f900ecf3f500e8ecef00e0e4e700d9dcde00d2d4d601d8cccb01 +fca46d00fc9c4207fc9d4c00fc9c4200fc9d4c00fc9c4200fc9d4c09fca44800fc8c3d00 +ec742a00fc6c3300ec742a00f9dcd100ffffff06ecf3f500e8ecef00e6dcdc00d9dcde00 +fac4ac00fc9c4207fca44800fc9c4200fca44800fc9c4200fca44800fc9d4c00fca44803 +fcac4c01fca44800fcac4c00fca44800fb7c3801d8a47800cbcccd03c4c5c500cbcccd00 +c4c5c500cbcccd00fcac6600fca44800fcac4c00fca44808fc9c4200fca44800fc9c4201 +fca44800fc9c4200fca44800fc9c4200fca44801fc9c4200fcecc400ffffff15f4f6f900 +e8ecef00e0e4e700d9dcde00d2d4d600c4c5c500cbcccd00c4c5c501c8aca500fb7c3800 +fca44800fcac4c00fca44802fcac6600fcac4c05fcac6602fcac4c00fcac6600fcac4c01 +fca46d00fca44800fcecc400ffffff07f4f6f900ecf3f500e0e4e700d9dcde01d2d4d600 +d8cccb00e68d5600ec742a01fca44805fca46d00fca44802fcac4c01fcac6600fcac4c02 +fcac6600fcac4c00fca44800fcac4c00fca44800fcac4c00fca44806fc9d4c00fca44800 +fc9d4c00fc9c4200fc9d4c00fc9c420efca4480bfcac4c00fca44800fcac4c00fca44800 +fcac4c00fcf4c600ffffff08ecf3f501e0e4e700d9dcde00d2d4d601c4c5c500d6938100 +ec742a05fc8c3d00fcac4c00fca44801fcac4c00fca44800fcac6600fca44800fcac4c01 +fca44800fcac6600fcac4c01fca44807fca46d00fca44800fcac4c00fca44800fcac4c00 +fca44800fcac6600fca44800fcac6600fca44800fcac6600fca44800fcac4c01fcac6600 +fcac4c00fcac6600fca44800fcac4c00fca44800fcac4c00fca46d00fcac4c00fca46d00 +fcac4c01fca44800fcac4c00fca44801fcac4c00fca44806fcac4c00fca44800fcac4c00 +fcac6600c6bcba00b4b4b400a4a5a404cc916400ec742a09fb843a00fca44804fc9c4200 +fca44800fc9c4201fc9d4c00fc9c4200fc9d4c01fc9c4202fc944100fc9c4200fc9d4c02 +fca44800fc9d4c00fca44800fc9c4200fca44800fc9c420bfc944100fc9c4211fc944100 +fc9c4201fc944100fc9c4201fc944100fac4ac00ffffff1bfad4b000fb843a04fb7c3800 +fb843a01fb7c3800fb843a12f38b3600fb843a00f38b3601fc8c3d04f38b3603fc8c3d12 +fc944100fc8c3d00fc944103fc955100fc944108fc8c3d01ec742a00ec6c2800ec742a02 +ec6c2800ec742a00ec6c2802fac4ac00ffffff0dfc9d4c00fc8c3d00fc944100fc8c3d02 +fc944106fc8c3d00fc944100fc8c3d00fc944100fc8c3d04fb843a03f38b3600fb843a00 +f38b3600fc8c3d00f38b3600fc8c3d06fc944100fc8c3d00fc944100fc8c3d00fc944100 +fc8c3d00fc944100fc955100fc8c3d00fc944103fc9c4200fc94410afc955100fc944100 +fc9d4c00fc9c4202fb7c3800fc733900ec742a03f9dcd100ffffff06f4f6f900ecf3f500 +e0e4e700e6dcdc00d2d4d602cbcccd00d8cccb00d7c4bd00fc944117fc733900ec6c2801 +fb7c3800ffffff05f4f6f900e8ecef00e0e4e700d9dcde00e6ccc900fca44800fc944100 +fc9c4200fc944104fc9c4200fc944100fc9c4200fc944101fc9c4200fc944100fc9c4201 +fc9d4c05fb843a00ec6c2800e68d5600d8cccb00d2d4d600cbcccd00c4c5c500cbcccd00 +d8cccb00c4c5c500cbcccd01e8bcb000fc9d4c02fca44800fc9d4c00fca44800fc9c4206 +fca44800fc9c4207fcac6600ffffff15ecf3f500e8ecef00d9dcde00d2d4d600cbcccd00 +c4c5c503e68d5600fc944100fca44801fcac4c00fca46d00fca44801fca46d00fca44801 +fca46d00fca44800fca46d00fca44800fcac4c00fca44805fcac6600ffffff07f4f6f900 +e8ecef00e0e4e701d2d4d601cbcccd00d79c7e00ec6c2800ec742a00fc8c3d00fca44800 +fc9d4c00fca44800fc9d4c02fc9c4200fc9d4c00fca44800fc9d4c00fca44800fc9d4c00 +fca44802fcac4c00fca44803fc9d4c00fca44801fc9d4c05fc955100fc9c4200fc955100 +fc9c4201fc944100fc9c4200fc944102fc9d4c00fc944100fc9c4200fc944100fc9c4200 +fc944100fc9c4200fc944100fc9c4204fc9d4c07facca600f7ece700fcf4c600f7ece700 +fcf4c600f4f6f900ffffff08f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd00 +c4c5c500c8aca500ec6c2800ec742a00ec6c2800ec742a00eb642400ec6c2800fc733900 +fc9c4201fc9d4c00fca44801fc9d4c00fca44800fc9d4c00fca44800fc9d4c00fca44806 +fc9d4c01fca44800fc9d4c01fc9c4200fc9d4c06fc944101fc8c3d00fc944100fc955100 +fc9d4c00fca4480cfc9d4c00fca44801fc9d4c02fca44800fc9d4c00fca44800fc9d4c00 +fca44802fc9d4c00fca44800fca46d00b4b4b400a4a5a404c8856300ec6c2800ec742a00 +ec6c2804ec742a00ec6c2801fb7c3800fca44800fc9c4200fca44800fc9c4203fc944100 +fc9c4200fc94410afc9c4200fc9d4c00fc944100fc9c4202fc944100fc9c4200fc944100 +fc9c4200fc94410dfc9c4200fc944100fc9c4200fc944100fc9c4200fc944101fc9c4200 +fc944107fc9c4200fc944101fc9c4200fca46d00ffffff1bfb8d5500fb7c3812fb843a00 +fb7c3803fb843a00fb7c3800fb843a06f38b3604fb843a00fc8c3d00fb843a00f38b3601 +fc8c3d00fb843a00fc8c3d00fb843a00fc8c3d01fb843a00fc8c3d0efc944100fc8c3d00 +fc944100fc8c3d08fb843a00eb642400ec6c2808fac4ac00ffffff0cfcbc8800fb843a00 +fc8c3d00fb843a00fc8c3d04fb843a00fc8c3d08fb843a06fb7c3800fb843a06fb7c3801 +fb843a01fc8c3d00fb843a00fc8c3d02fb8d5500fc8c3d08fc944100fc8c3d00fc944100 +fc8c3d00fc944100fc8c3d04fc944106fc8c3d00ec6c2804fb843a00ffffff06f4f6f900 +e8ecef00e0e4e700d9dcde01d2d4d600d8cccb00cbcccd02efbc8e00fc8c3d12fb8d5500 +fc8c3d00fc944101fc8c3d00ec6c2800eb642401fca46d00ffffff03f4f6f900e8ecef00 +e0e4e700e6dcdc00d9dcde00fca46d00fc944101fc8c3d00fc944106fc8c3d00fc944101 +fc8c3d00fc944101fc8c3d00fc955100fc944100fc955102fb843a00fc653100e7764400 +d2d4d602cbcccd02c4c5c500cbcccd01c4c5c500d7c4bd00fca46d00fc944100fc9d4c00 +fc944110fc9c4200fc944101ffffff14f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600 +cbcccd01c4c5c500c6bcba00c7b5b100fb7c3800fca44804fc9d4c01fc9c4200fc9d4c01 +fca44800fc9d4c00fca44800fc9d4c05fc955100fc9d4c00fad4b000ffffff06f4f6f900 +e8ecef00e0e4e700d9dcde00d2d4d600cbcccd01c7b5b100ec742a00ec6c2800fc733900 +fc9c4200fc9d4c0dfca44800fc9d4c00fca44800fc9d4c03fc955101fc9d4c00fc944102 +fc8c3d00fc944101fc8c3d00fc944100fc8c3d00fc944100fc8c3d00fc955100fc8c3d00 +fc944103fc955100fc8c3d00fc944100fc8c3d00fc944101fc8c3d00fc944100fc955100 +fc944100fc955100fc944104fc955100fc9c4200fc944100fbb47200ffffff0cecf3f500 +e8ecef00e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd00e7764400eb642400 +ec6c2800eb642403fb843a00fc9c4201fc955100fc9d4c0dfc955100fc9c4200fc955100 +fc944100fc9d4c00fc944102fc955100fc9d4c00f9a58b00d79c7e00da846200ec742a00 +eb642401ec6c2803fb7c3800fb843a00fc944100fc9d4c01fca44800fc9d4c09fc9c4200 +fc9d4c00fc944100fc9d4c00fc955100fc9d4c01fc955100fc9c4200fc9d4c00fc9c4201 +fca46d00abacad00a4a5a4009c9e9c00a4a5a401c8856300ec6c2800eb642403ec6c2804 +fb7c3800fc9c4201fc944100fc9c4200fc944103fc8c3d00fc944101fc8c3d00fc944100 +fc8c3d00fc944100fc8c3d00fc944100fc8c3d00fc944104fc955100fc944103fc8c3d00 +fc944100fc8c3d00fc944100fc8c3d05fc944100fc8c3d00fc944103fc8c3d00fc94410c +fc8c3d00fc944100fc8c3d00fc944101fc8c3d00fc944100fcf4c600ffffff19fbb47200 +fc733901fb7c3800fc733900fb7c3800fc733900fb7c3800fc733901fb7c3800fc733901 +fb7c3800fc733901fb7c3800fc733900fb7c380dfb843a00fb7c3801fc733903fb7c3800 +fb843a12fc8c3d01fb843a01fc8c3d00fb843a00fc8c3d02fb843a00fc8c3d00fb843a00 +fc8c3d00fb843a06fb7c3800eb642402ec6c2800eb642405fac4ac00ffffff0bf9e4e100 +fb843a08fc8c3d00fb843a00fc8c3d00fb843a00fc8c3d00fb843a00fc8c3d00fb843a04 +fb7c3808fc6c3300fc653100eb642401e5541f00eb642400e75c2a00eb642400eb826400 +e8a58f00fca46d00fb8d5500fb843a05fb8d5500fb843a00fc8c3d14fb7c3800ec6c2804 +fcb58e00ffffff05f4f6f900ecf3f500e8ecef00e6dcdc00d9dcde00d2d4d601cbcccd00 +d2d4d600cbcccd00d2d4d600f9a58b00fc8c3d01fb843a04fb7c3800fb843a00fb7c3800 +fb843a06fc8c3d02fb8d5500fc8c3d01fc733900e75c2a00eb642401f8cbc000ffffff01 +f4f6f900ecf3f500e8ecef00e0e4e700d9dcde00fcb58e00fc8c3d0ffb8d5500fc8c3d04 +fb843a00eb642400ec6c2800e8c2b000d9dcde01d2d4d601cbcccd02c4c5c500cbcccd02 +eeb48e00fc8c3d01fb8d5500fc8c3d07fc944100fc8c3d02fc944100fc8c3d00fc944104 +fbb47200ffffff13ecf3f500e8ecef00e0e4e700d9dcde00d8cccb00cbcccd00c4c5c502 +d6938100fb843a00fc9c4200fc9d4c08fc955100fc9d4c05fc955100fc944100fc955100 +fc9d4c00ffffff06f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd02d98c7800 +ec6c2800eb642400fc8c3d00fc9d4c03fc955100fc944100fc9d4c00fc944102fc955100 +fc944100fc955100fc944100fc955101fc9d4c00fc955100fc9d4c00fc955100fc9c4200 +fc955100fc944102fc955100fc8c3d01fb8d5500fc8c3d04fb843a00fc8c3d00fb843a00 +fc8c3d00fb843a00fc8c3d02fb843a00fc8c3d00fb8d5500fc8c3d02fb8d5500fc8c3d04 +fc944100fc8c3d00fc955100fc8c3d01fc944100fc8c3d00fc944100fbe4c100ffffff0a +f4f6f900e8ecef00e0e4e700d9dcde00cbcccd00c4c5c501bbbcbd00cc916400e75c2a00 +eb642400e75c2a01e5541f00e75c2a00fc6c3300fc8c3d02fc944102fc955100fc944100 +fc955100fc944100fc955101fc944100fb8d5500fc944101fb8d5500fc8c3d00fc944100 +fc8c3d00fc944100fb8d5500fc8c3d01fc955100e59c8700c8a49d00abacad02a4a5a400 +abacad00b8938b00d3725300eb642404ec6c2800eb642400fc733900fc8c3d00fc955100 +fc9d4c01fc9c4200fc955100fc944100fc955100fc944100fc955100fc944100fc955100 +fc944106fc955100fc944101fc955100fc9d4c00fc944100dba39300a4a5a403c8856300 +eb642402e75c2a00eb642405fc733900fc944103fc8c3d02fb843a00fc8c3d01fb843a00 +fc8c3d06fb843a00fc8c3d06fb843a0cfc8c3d08fb843a00fc8c3d01fb843a00fc8c3d0c +fad4b000ffffff18f7ece700fc733900fc6c3300fc733900fc6c3305fc73390ffb7c3800 +fc733901fb7c3800fc733901fc6c3300eb642401e75c2a00eb642400e75c2a00eb642400 +e75c2a00eb642402fc733900fb843a00fb7c3805fb843a00fb7c3800fb843a02fb7c3800 +fb843a01fb7c3800fb843a00fb7c3800fb843a01fb7c3800fb843a00fb7c3800fb843a04 +fb7c3800fb843a01fb7c3800fb843a00fb7c3800fb843a00fb7c3800fc733900eb642400 +e75c2a00eb642404e75c2a00eb642401efbc8e00ffffff0bfca46d00fb7c3806fb843a01 +fb7c3800fb843a05fb7c3800fb843a00fb7c3800fb843a00fb7c3804fc733900fb7c3800 +fc6c3300fc653100e5541f04e75c2a00ec6c2800d79c7e00d7c4bd00d2d4d600d8cccb00 +cbcccd00d8cccb00e8b3a800fa9c7900fb843a07fc8c3d00fb843a00fc8c3d00fb843a08 +fc8c3d00fb843a00fc8c3d00fb843a00fc8c3d01fb843a01eb642404ec6c2800ffffff06 +f4f6f900e8ecef00e0e4e700d9dcde00d2d4d602d8cccb00cbcccd01d8cccb00fc9d4c00 +fb7c3800fb843a00fb7c380bfb843a08fc653100e75c2a01ec6c2800f7ece700f4f6f900 +ecf3f500e8ecef00e0e4e700d9dcde00e8c2b000fb843a03fc8c3d00fb843a00fc8c3d00 +fb843a00fc8c3d00fb843a00fc8c3d08fb8d5500fc8c3d00fb843a01fc6c3300e75c2a00 +e6ad9b00e0e4e701d9dcde01d2d4d600d8cccb00cbcccd01c4c5c500cbcccd00c4c5c500 +cbcccd00d7c4bd00fb8d5500fb843a0bfc8c3d00fb843a00fc8c3d01fb843a00fc8c3d00 +fb843a00fc8c3d01fb843a00ffffff12f4f6f900ecf3f500e0e4e700d9dcde00d2d4d600 +c4c5c503c7b5b100ec742a00fc944102fc955100fc944100fc955100fc944101fb8d5500 +fc944100fc955100fc944100fc955104fc944100fc955100fc944101facca600ffffff05 +f4f6f900ecf3f500e0e4e700d9dcde00d2d4d600cbcccd01c4c5c500c7b5b100ec6c2801 +fc6c3300fc944101fc955100fc8c3d00fc955100fc944100fc8c3d00fc944100fc955100 +fc8c3d00fc944100fc8c3d00fc944102fc955100fc944101fc955100fc944100fc8c3d00 +fb8d5500fc8c3d02fb843a00fc8c3d00fb8d5500fa9c7900f2a27200e59c8700d8755c00 +fc653100e75c2a00fb5c2e00fc6c3300fc733900fb7c3801fb843a00fb7c3800fb843a00 +fa7c5800fb843a00fb7c3800fb843a00fb7c3800fb843a05fb8d5500fc8c3d00fb843a00 +fc8c3d00fb843a00fc8c3d01fb843a00fb8d5500fc8c3d00fc955100ffffff09f4f6f900 +ecf3f500e0e4e700d9dcde00cbcccd01c4c5c500bbbcbd00b8adaa00eb642400e5541f03 +e75c2a00e5541f00fb843a00fc8c3d02fb8d5500fc8c3d0dfb843a00fc8c3d02fc955100 +e8a58f00b4b4b401abacad07b8938b00dc6c3c00e75c2a00eb642401e75c2a00eb642402 +ec6c2800fb843a00fc8c3d00fc944100fc8c3d00fc944100fc8c3d05fb8d5500fc8c3d01 +fb8d5500fc8c3d02fc944101fc8c3d00fc944101fc955100c7998d00abacad009c9e9c00 +a4a5a400c8856300e75c2a01e5541f01eb642400d9542d00ec6c2800da633600e75c2a01 +fc6c3300fc8c3d03fb843a04fb7c3800fb843a00fb7c3800fb843a00fb7c3800fb843a09 +fb7c380bfb843a00fb7c3800fb843a00fb7c3800fb843a04fb7c3800fb843a02fb7c3800 +fb843a02fb7c3800fb843a0afcb58e00ffffff18fa9c7900fc653100fc6c3300fc653100 +fc6c3302fc653100fc6c3308fc733900fc6c3300fc733900fc6c3300fc733902fc6c3300 +fc733900fc6c3300fc733900fc6c3300fc653100eb642400e75c2a00e5541f02e75c2a00 +e5541f04da633600e68d5600d8b4ac00d7c4bd00ecae7c00fb843a00fb7c3809fc733900 +fb7c3809fc733900fb7c3800fc733900fb7c3802fc733900fb7c3800fc733902fb7c3800 +fc733900e75c2a04e5541f00e75c2a01e5541f00e75c2a00fac4ac00ffffff0afad4b000 +fc733900fb7c3800fc733902fb7c3800fc733900fb7c3812fc6c3300eb642400e5541f02 +e75c2a01e5541f00e7764400d8ac9f00d2d4d600d9dcde00d2d4d604d8cccb00cbcccd00 +e8c2b000fa9c7900fb843a00fb7c3800fb843a02fb7c3800fb843a01fb7c3800fb843a01 +fb7c3800fb843a00fb7c3800fb843a00fb7c3800fb843a01fb7c3800fb843a00fb7c3800 +fb843a01fb7c3800fb843a00fb7c3800fc733900e75c2a00eb642403fa9c7900ffffff05 +f4f6f901e0e4e701d9dcde01d2d4d601cbcccd00d2d4d600cbcccd00d7c4bd00fb843a00 +fb7c3806fc733900fb7c3800fc733900fb7c3807fb843a00fb7c3800fb843a01fc733900 +e5541f02e9947d00e8ecef01e0e4e700d9dcde00e9d5d700fb8d5500fb7c3801fb843a0c +fc8c3d00fb843a05fc6c3300e75c2a00e68d5600e8ecef02e0e4e700e6dcdc00d2d4d601 +cbcccd00d8cccb00c4c5c500cbcccd00c4c5c501cbcccd00f9a58b00fb7c3800fb843a00 +fb7c3800fb843a12fcbc8800ffffff11f4f6f900e8ecef00e0e4e700d2d4d601cbcccd01 +c4c5c501d6938100fb7c3800fc8c3d00fc944100fb8d5500fc8c3d02fb8d5500fc8c3d01 +fb843a00fc8c3d01fb8d5500fc8c3d00fc944100fc8c3d00fb8d5500fc8c3d02fc955100 +ffffff06f4f6f900e0e4e701d2d4d600cbcccd00c4c5c502cc916400e75c2a00eb642400 +fb7c3800fc944100fc8c3d00fc955100fc8c3d02fb8d5500fc8c3d00fb843a00fc8c3d00 +fb8d5500fb843a00fb8d5500fb843a00fc8c3d06fb843a03f9947500e8a58f00c7b5b100 +bbbcbd01b4b4b400bbbcbd00b8adaa00c88b7d00e9644000e5541f00e54d1d00fb5c2e00 +fb6c4100fb7c3806fa7c5800fb843a00fb7c3800fb843a00fa7c5800fb843a00fb7c3800 +fb843a00fb7c3800fb843a02fa7c5800fb843a04fac4ac00ffffff07f4f6f900ecf3f500 +e0e4e700d9dcde00cbcccd01c4c5c500bbbcbd00b4b4b400c8856300e5541f05fc653100 +fb843a07fb8d5500fb843a06fb7c3800fb843a00fb7c3800fb843a01fb8d5500e6ad9b00 +c6bcba00bbbcbd02b4b4b400abacad00b4b4b400abacad05a4a5a400c8856300e5541f05 +e75c2a00e5541f00fc6c3300fb843a09fc8c3d00fb843a00fc8c3d00fb843a00fc8c3d01 +fb8d5500fc8c3d01fb8d5500fc8c3d01fc955100a4a5a402b77c6a00e75c2a00e5541f00 +d9542d00e5541f00d9542d00e75c2a01e5541f00e75c2a00e5541f00fc6c3300fc8c3d00 +fb843a04fb7c3803fb744e00fb7c3807fa7c5800fb7c3802fc733900fb7c3801fc733900 +fb7c3800fc733900fb7c3800fc6c3300fc653100eb642400fb552700e5541f00fb552700 +fc653100fc6c3300fc733900fb7c3801fc733900fb7c3801fc733900fb7c3801fc733900 +fb7c3802fc733900fb7c3800fa7c5800fb7c3801fb843a00fb7c3800fb843a00fb7c3804 +fb843a00fc955100ffffff17f9e4e100fc6c3300fc653101fb5c2e02fc653106fc6c3300 +fc653100fc6c3300fc653100fc6c3309fb5c2e00e5541f08d9542d00e5541f00e75c2a00 +cc916400d7c4bd00d2d4d601cbcccd01d8cccb00e4ae7c00fb843a00fc733906fb7c3800 +fc73390afc6c3300fc733900fc6c3303fc733900fc6c3300fc733903fc653100e5541f04 +e75c2a00e5541f01e75c2a00e5541f00f7b9a600ffffff09f4f6f900f9947500fc6c3302 +fc733907fb7c3801fb744e00fb7c3802fc733900fb7c3801fc733900fb7c3801fc733900 +fc6c3300eb642400e5541f03e75c2a00e5541f00eb642400e6ad9b00e0e4e703e6dcdc00 +d9dcde01d2d4d603cbcccd00d8cccb00d7c4bd00f9947500fc733900fb7c3806fc733900 +fb7c3801fc733900fb7c3801fc733900fb7c3801fc733900fb7c3801fc733900fb7c3802 +fc733900eb642400e5541f00e75c2a02eb642400f7ece700ffffff05f4f6f900e8ecef01 +e6dcdc00d9dcde00d2d4d601cbcccd01d2d4d600cbcccd00e8bcb000fb7c3801fc73390c +fb7c3800fb744e00fb7c3800fb744e00fb7c3800fc733900fb7c3801fc653100e54d1d01 +e5541f00e8bcb000e0e4e701d9dcde00fa9c7900fb7c3800fc733900fb7c3800fc733900 +fb7c3804fb843a00fb7c3800fb843a04fa7c5800fb843a00fb7c3802fb843a00fc733900 +e75c2a00e7764400f7ece700ecf3f501e8ecef00e0e4e700e6dcdc00d9dcde00d2d4d600 +cbcccd03c4c5c500cbcccd00c4c5c500d8bcb600fb843a00fb7c3802fb744e00fb7c3800 +fc733900fb7c3800fc733900fb7c380afa7c5800fb843a00fa7c5800ffffff10f4f6f900 +ecf3f500e0e4e700d9dcde00d2d4d600cbcccd00c4c5c502c6bcba00ec6c2800fb843a01 +fc8c3d00fb843a00fc8c3d00fb843a05f8836200fb843a08fcb58e00ffffff05ecf3f500 +e8ecef00e0e4e700d2d4d601cbcccd00c4c5c501c7b5b100e75c2a01eb642400fb843a01 +fb8d5500fb843a00fc8c3d00fb843a01fc8c3d00fb843a0bfa7c5800fb843a01fa7c5800 +fb8d5500e6ad9b00c6bcba01bbbcbd04b4b4b400bbbcbd00b8adaa00c88b7d00e75c2a00 +d94b2000e4461800fb552700fc653100fc733900fb7c3800fb744e00fb7c3801fc733900 +fb7c3801fb744e00fb7c3804fa7c5800fb7c3805fb843a02ffffff07ecf3f500e0e4e700 +d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd01b8adaa00d9542d00e4461800d94b2000 +e54d1d00d94b2000e5541f00e54d1d00fc733900fb7c3802fa7c5800fb7c3801fa7c5800 +fb7c3802fa7c5800fb7c3800fa7c5800fb7c3800fa7c5800fc733900fb7c3800fa7c5800 +fc733900fa7c5800fca46d00d8cccb00cbcccd01c4c5c500bbbcbd02b4b4b400abacad07 +a89a9500dc6c3c00e5541f07fc653100fb843a00fa7c5800fb7c3800fb843a00fa7c5800 +fb7c3801fa7c5800fb7c3800fb843a00fa7c5800fb843a00fb7c3800fb843a04fc8c3d02 +fb843a00f9947500a4a5a401c8745e00e5541f00d9542d00e5541f02d9542d00e5541f00 +d9542d00e5541f01fc653100fb7c3803fb744e00fc733906fb6c4100fc6c3300fb6c4100 +fc6c3300fc733908fc6c3300fc733900fc6c3300fb5c2e00fb552700e4461803d94b2001 +e4461801e5541f00fb552700fc6c3300fc733901fc6c3300fc733900fc6c3301fc733901 +fc6c3300fc733905fb744e00fc733902fb7c3801fc733900fb7c3800fc733900fb7c3800 +f4f6f900ffffff16fa9c7900fc653100fb552700fb5c2e03fb552702fb5c2e02fc653100 +fb5c2e00fc653101fb5c2e00fc653107fb552700e54d1d00e5541f00d94b2000e54d1d00 +d94b2004e5541f00d94b2000e5541f00da846200d7c4bd00d9dcde03d2d4d602d8cccb00 +cbcccd00f2a27200fc733902fc6c3300fc733900fc6c3301fc733900fc6c3300fc733900 +fc6c3305fc653100fc6c3300fc653101fc6c3300fc653105fc6c3300fc653100fc6c3300 +fc653100e5541f03d9542d00e5541f01d94b2000e5541f01f7b9a600ffffff08f4f6f900 +f8cbc000fc6c3300fc653100fc6c3300fc653101fc6c3300fc653100fc6c3300fc653100 +fc6c3305fc733900fc6c3300fc733901fc6c3300fc733901fc6c3301fb5c2e00e5541f00 +e54d1d02e5541f02eb826400e9d9b900ecf3f501f7ece700e8ecef02e0e4e700d9dcde02 +d2d4d603cbcccd00d8cccb00f9ad9400fb7c3800fb6c4100fc733915fc653100e5541f04 +fa9c7900ffffff06f4f6f900e8ecef00e0e4e700d9dcde01d2d4d602cbcccd00d8cccb00 +cbcccd00f2a27200fc733902fc6c3300fc733900fc6c3300fc733900fc6c3300fc733900 +fc6c3309fc733900fc6c3300fc733900fc6c3300e5541f00e4461801e75c2a00e9d5d700 +d9dcde00f7b9a600fc733907fb7c3800fc733901fb7c3800fc733900fb7c3800fc733900 +fb744e00fb7c3805fc733900e5541f00e75c2a00f9dcd100ffffff01f4f6f901e8ecef01 +d9dcde01d2d4d600cbcccd01c4c5c500cbcccd02c4c5c500fa9c7900fc733905fc6c3300 +fc733905fb7c3800fc733901fb7c3800fb744e00fb7c3800fc733900fb7c3800fc733900 +fac4ac00ffffff0ff4f6f900e8ecef00e0e4e700d9dcde00d2d4d600d8cccb00c4c5c502 +d79c7e00fc6c3300fb7c3800fb843a00fb7c3800fb843a00fb7c3801fa7c5800fb843a00 +fb7c3800fa7c5800fb843a01fb7c3802fa7c5800fb7c3801fa7c5800fb7c3801f4f6f900 +ffffff04f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500c6bcba00 +c4c5c500c88b7d00e5541f00e54d1d00fc653100fb7c3803fa7c5800fb843a01fa7c5800 +fb843a03fb7c3800fb843a00fb7c3800fa7c5800fb7c3800fa7c5800fb843a00fa7c5800 +fb7c3801fb843a00f9ad9400cbcccd01c4c5c500bbbcbd00c4c5c500bbbcbd00c6bcba00 +b4b4b400bbbcbd01b4b4b400bbbcbd01b8adaa00d3725300d94b2000e4461800d9431900 +fb552700fc6c3300fc733907fb6c4100fc733900fb6c4100fc733902fb7c3800fc733901 +fb7c3800fb744e00fc733900fa7c5800fb7c3800fcb58e00ffffff05ecf3f500e8ecef00 +e0e4e700d2d4d600cbcccd00c4c5c500bbbcbd01b4b4b400c97c6700e4461800d9431900 +e4461803fb552700fc6c3300fc733900fb6c4100fc733905fb6c4100fc733906fc6c3300 +fc733900fb7c3800fac4ac00d9dcde01d2d4d600cbcccd01c4c5c500bbbcbd01b4b4b401 +b8adaa00abacad03a4a5a400b98a7c00e5541f00d94b2000e4461800d94b2001e5541f00 +d94b2000e5541f01fc6c3300fb7c3803fc733900fb7c3800fb744e00fb7c3802fc733900 +fb7c3802fa7c5800fb7c3801fa7c5800fb843a00fb7c3800fb843a00fb7c3800fb843a01 +c7998d00a4a5a400c8745e00d94b2003e5541f00d94b2000e5541f00d94b2000e5541f00 +d94b2000fb5c2e00fb7c3800fc733908fc6c330feb826400b78d8500c86d5400d9431905 +e4461800d9431901e4461802fb552700fc653100fc6c330cfc733900fc6c3300fc733900 +fc6c3302fc733900fc6c3300fc733901f9dcd100ffffff15f7ece700fc653100fb552700 +fb5c2e00fb552703fb5c2e00fb552702fb5c2e01fb552700fb5c2e04fb552700fb5c2e01 +fc653101fb5c2e00e5541f00e4461800e54d1d00e4461800d94b2000e54d1d00e4461800 +e54d1d01d94b2000e4461801d9542d00d8ac9f00e0e4e701e8ecef00d9dcde00e0e4e700 +d9dcde02d2d4d601cbcccd00d2d4d600d8bcb600fb843a00fc6c3300fc653101fc6c3300 +fc653105fb5c2e06fc653100fb5c2e00fc653101fb5c2e01fc653100fb5c2e00fc653102 +fb5c2e00e54d1d00e4461800d94b2002e54d1d00d94b2000e54d1d00e4461800d94b2000 +eeb48e00ffffff08f4f6f900fb8d5500fc653100fb5c2e01fc653100fb5c2e01fc653100 +fb5c2e00fc653105fc6c3300fc653102fc6c3300fc653103e54d1d00e4461802d94b2000 +e4461800d9431900d94b2000e9947d00ecf3f500f4f6f904ecf3f500e8ecef01e0e4e701 +e6dcdc00d9dcde00d2d4d602d8cccb00cbcccd01d8bcb600fa7c5800fc6c3301fc653100 +fc6c3301fc653100fc6c3304fc653100fc6c3300fc653100fc6c3307fc653100e5541f00 +e54d1d00d94b2000e54d1d00d94b2000e5541f00ffffff07f4f6f900e8ecef00e0e4e700 +e6dcdc00d2d4d602cbcccd00d2d4d600cbcccd01f9947500fc6c3304fc65310afc6c3300 +fc653100fc6c3303fc653100e4461800d94b2000d9431900da846200d8cccb00fb7c3800 +fc6c3302fc733902fc6c3300fc733900fc6c3300fc733903fc6c3300fc733902fc6c3300 +fc733902fb6c4100fb552700d94b2000fac4ac00ffffff03f4f6f901e8ecef00d9dcde01 +d2d4d600d8cccb00cbcccd00c4c5c500cbcccd00c4c5c501cbcccd00d8bcb600fc6c330a +fc733900fc6c3301fc733901fc6c3300fc733905ffffff0fecf3f500e0e4e700d9dcde00 +d2d4d600cbcccd00c4c5c502c6bcba00dc6c3c00fc6c3300fb7c3801fb744e00fc733900 +fb7c3800fb744e00fb7c3800fc733900fb7c3800fc733904fb6c4100fc6c3300fb6c4100 +fc6c3302fa9c7900ffffff05f4f6f900e8ecef00d9dcde00d2d4d600cbcccd01c4c5c500 +bbbcbd01da633600d9431900e4461800fc6c3300fc733903fb7c3800fc733900fb7c3800 +fc733900fb7c3800fb744e01fb7c3801fb744e00fb7c3806f5886c00e6ccc900d9dcde00 +d2d4d600cbcccd02c4c5c500bbbcbd05b4b4b400bbbcbd02c88b7d00d9431900e4461800 +dc3e1400e4461800fb5c2e00fc6c3300fc733900fc6c3300fb6c4100fc6c3306fb6c4100 +fc6c3300fc733900fb6c4100fc733900fb6c4100fc733901fc6c3300fc733900fb744e00 +ffffff04f4f6f900ecf3f500e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd01b4b4b400 +b8adaa00d94b2000dc3e1400e4461800dc3e1402e4461800fb5c2e00fc6c3310fb6c4100 +fc733900f8cbc000e8ecef00e0e4e700d9dcde01d2d4d600cbcccd00c4c5c501bbbcbd00 +b4b4b400abacad04b99a9400c7634a00e4461803d94b2000e54d1d00e4461801fb552700 +fc6c3300fc733903fb7c3800fc733909fb7c3800fc733900fb7c3801fc733900fb7c3800 +fb744e00fb7c3802fb843a00a4a5a400c86d5400e4461802d9431901e4461800d9431900 +e4461802fb552700fc733900fc6c3300fc733900fc6c3301fc733900fc6c3303fc733900 +fc6c3303fc653101fc6c3300fc653101fc6c3300fc653100fc6c3301fb6c4100cc916400 +9c9e9c02b7746200e4461801d9431900e4461801dc3e1400e4461800d9431900e4461800 +dc3e1400e4461801fb552700fc653100fc6c3300fc653108fc6c3300fc653102fc6c3300 +fc653100fc6c3300fc653100fc6c3303fac4ac00ffffff15f9ad9400fb552717e4461801 +d9431901dc3e1400e4461800d9431901dc3e1400e4461800d9431901da633600d8cccb00 +e8ecef06e0e4e700d9dcde02d2d4d601cbcccd01f9947500fc653101fb5c2e02fc653100 +fb552706fb5c2e00fb552706fb5c2e00fb552700fb5c2e03fb552700d9431901e4461800 +d9431900e4461800dc3e1400e4461800d9431901dc3e1400f7b9a600ffffff07f4f6f900 +f8d4c900fc653100fb552700fc653100fb5c2e06fb552700fb5c2e00fb552700fb5c2e03 +fc653100fb5c2e01fc653101fb552700e4461802d9431900e4461800d9431900dc3e1400 +e4461800e8a58f00f4f6f900ffffff06f4f6f901f7ece700e8ecef00e0e4e701e6dcdc00 +d9dcde00d2d4d603cbcccd00d7c4bd00fa7c5800fc653105fb5c2e01fc653100fb5c2e00 +fc653101fb5c2e00fc653100fb5c2e00fc653103fb5c2e00fc653101fb552700dc3e1400 +e4461800dc3e1400e4461800d9431900fa9c7900ffffff06f4f6f900f7ece700e8ecef00 +e0e4e700d9dcde01d2d4d601cbcccd01d2d4d600d7c4bd00fb7c3800fc6c3301fc65310e +fb5c2e00fc653103fb552700dc3e1400e4461801fb744e00fc653101fc6c3300fc653100 +fc6c3300fc653103fc6c3300fc653102fc6c3300fc653100fc6c3300fc653100fc6c3302 +fb6c4100fc6c3300fb552700d9431900fa9c7900ffffff05f4f6f900e8ecef01d9dcde00 +d2d4d600cbcccd04d8cccb00c4c5c500cbcccd00f8836200fc653104f9653d00fc653101 +fc6c3300fc653101fc6c3300fc653104fc6c3300fc653100fc6c3302f8cbc000ffffff0d +f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd01c4c5c501c8a49d00fb552700 +fc733901fc6c3300fc733901fc6c3303fb6c4100fc6c3300fb6c4100fc653100fb6c4100 +fc653100fc6c3300fc653100fc6c3300fc653100fc6c3300fc653100f9e4e100ffffff04 +f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd00c4c5c500 +c8aca500d9431900dc3e1400fb552700fc6c3306fb6c4100fc6c3300fb6c4100fc733906 +fb6c4100fc733900fb6c4100fc733900fa7c5800f8d4c900e0e4e701d9dcde01d2d4d600 +cbcccd01c4c5c501bbbcbd00c6bcba00b4b4b400bbbcbd02b4b4b402c97c6700dc3e1400 +d9431900dc3e1400e4461800fb5c2e00fc653101fc6c3302fc653100fc6c3300fc653100 +fc6c3300fc653100fc6c330af9ad9400ffffff03ecf3f500e8ecef00d9dcde00d2d4d600 +cbcccd00c4c5c500bbbcbd01b4b4b400c8847200d9431900dc3e1401e4461800dc3e1400 +e4461800e54d1d00fc6c3305fc653100fc6c3301fc653102fc6c3300fc653100fb6c4100 +fc6c3302fc653100fac4ac00f4f6f900e8ecef01e0e4e700d9dcde00d2d4d600cbcccd01 +bbbcbd01b4b4b400bbbcbd00abacad02b9857800d9542d00dc3e1400d9431900dc3e1400 +d9431902dc3e1400e4461800fb5c2e00fc6c3305fb6c4100fc6c3300fc733900fc6c3301 +fb6c4100fc6c3300fb6c4100fc6c3303fb6c4100fc6c3300fb6c4100fc733904fb744e00 +e78b7100a4a5a400c86d5400d9431900dc3e1401d9431900dc3e1401d9431900dc3e1401 +d9431900fb552700fc653100fc6c3303fc653100fc6c3301fc653100fc6c3300fc653101 +fc6c3300fc653109fb6c4100c7998d009c9e9c02a4a5a4009c9e9c00ba654f00dc3e1400 +e4461800dc3e1409fb552700fc653104fc6c3300f9653d00fc65310cfb5c2e00fc653100 +f9a58b00ffffff14f4f6f900fc653100fb552705fb5c2e00fb552700fb5c2e00fb552700 +fb5c2e00fb552701fb5c2e00fb552701fb5c2e00fb552701fb5c2e00fb552702dc3e1402 +d9431906dc3e1401da633600e6dcdc00e8ecef01ecf3f501f7ece700ecf3f501e8ecef02 +e0e4e700d9dcde02d2d4d601cbcccd00e9947d00fb552704fb5c2e03fc653100fb5c2e06 +fb552700fb5c2e01fb552701fb5c2e00fb552701fb5c2e00fb552700e4461800dc3e1401 +e4461800dc3e1402e4461800dc3e1400e4461800f9ad9400ffffff07ecf3f500fa9c7900 +fb5c2e01fb552700fb5c2e02fb552700fb5c2e03fc653100fb5c2e03fb552700fb5c2e00 +fb552700fb5c2e00fb552701e4461801dc3e1405e8866c00ffffff0af4f6f900ecf3f500 +e8ecef01e0e4e700d9dcde02d2d4d601d8cccb00cbcccd00d7c4bd00fc6c3300fb5c2e04 +fc653100fb5c2e01fc653100fb5c2e00fc653102fb5c2e00fc653100fb5c2e00fc653100 +fb552700fc653100fb5c2e01fb552700dc3e1401d9431900dc3e1400d9431900e75c2a00 +ffffff07f4f6f900ecf3f500e8ecef00e6dcdc00d9dcde00d2d4d602d8cccb00cbcccd01 +d8bcb600fc6c3300fc653100fb5c2e00fc653100fb5c2e00fc653100fb5c2e00fc653103 +f9653d00fc653100f9653d00fc653104fb5c2e00fc653101fb5c2e00e4461800dc3e1400 +fb552700fc653103fb5c2e00fc653109fb5c2e00fc653105fb552700dc3e1400e86c4c00 +ffffff07f4f6f900e8ecef00e6dcdc00d9dcde00d2d4d600cbcccd01c4c5c500cbcccd00 +c4c5c500cbcccd00c4c5c500e8b3a800fb6c4100fc6c3300fb6c410bfc6c3300fb6c4100 +fc653105fa7c5800ffffff0decf3f500e8ecef00d9dcde00d2d4d600d8cccb00c4c5c503 +da633600fb5c2e00fc6c3300fc653103fb6c4100fc653100fc6c3300fc653100fb6c4100 +fc653100fc6c3300fb6c4100fc6c3300f9653d00fb6c4100fc6c3300fb6c4102f5886c00 +ffffff05ecf3f500e8ecef00d9dcde00d2d4d600cbcccd00c4c5c501c6bcba00bbbcbd00 +c8847200dc3e1401fb552700fc653101f9653d00fc653101f9653d00fc6c3300fc653100 +fc6c3301fc653100fc6c3301fc653100fc6c3306f7b9a600f4f6f900ecf3f500e8ecef00 +e0e4e700d9dcde01d2d4d601cbcccd00c4c5c501bbbcbd02b4b4b400bbbcbd00b4b4b400 +bbbcbd01b8adaa00d45e4400d9431902e4461800fc653100fb6c4100fc6c3300fb6c4106 +fc6c3300fc653102fc6c3305fc653100fc733900ffffff02f4f6f900ecf3f500e0e4e700 +d9dcde00cbcccd00c4c5c500bbbcbd01b4b4b401c9593b00dc3e1405fb552700fc6c3301 +fc653101fc6c3300f9653d00fc6c3300fc653100f9653d00fc6c3300fb6c4101fc6c3300 +fb6c4100fc653101f9653d00fc6c3300fa9c7900ffffff00f4f6f901ecf3f500e0e4e701 +d2d4d601c4c5c501bbbcbd00b4b4b400abacad00b4b4b400a4a5a400c7634a00dc3e1404 +d9431900dc3e1401e54d1d00fc653101fc6c3300fc653100fc6c3300fc653100fc6c3300 +fc653103fc6c3301fc653100fc6c3300fc653100fc6c3300fc653100fc6c3300fc653100 +fc6c3300fc653102fc6c3301fb6c4100fa7c5800b99a9400a4a5a401b7746200dc3e1401 +d9431901dc3e1400d9431900dc3e1401d9431900dc3e1400e54d1d00fc65310afb6c4100 +fc653100fb6c4100fc6c3300fb6c4100fc6c3300f9653d00fc6c3300fc653100fb6c4100 +fc653100fc6c3300e8866c009c9e9c00a4a5a4009c9e9c03a88c8600d94b2000d9431909 +dc3e1400d9431900fc653100fc6c3300fb6c4101f9653d00fb6c4100fc6c3300fb6c4100 +fc653100f9653d00fc6c3300fc653100fb6c4100fc6c3300f9653d00fc653100f9653d00 +fc653100f9653d00fc653100fb6c4100fc653100f9947500ffffff14fac4ac00fb552705 +fb5c2e00fb552700fb5c2e0de75c2a00d9431902c9452200d9431900d94b2000d9431900 +d94b2000d9431900d94b2000d9431900c9452200d9542d00e6ccc900e8ecef00ecf3f500 +f4f6f902ffffff01f4f6f902f7ece700e8ecef00e0e4e701d9dcde01d2d4d601cbcccd00 +f8836200fb5c2e00fc653100fb5c2e00fc653100fb5c2e05fc653100fb5c2e08fc653100 +fb5c2e02fb552701dc3e1401d9431900dc3e1401d9431900dc3e1400d9431901dc3e1400 +e8b3a800ffffff06f4f6f900f9e4e100fb6c4100fb5c2e01fc653100fb5c2e01fc653100 +fb5c2e00fc653100fb5c2e00fc653100fb5c2e01fc653100fb5c2e01fc653100fb5c2e01 +fc653100fb5c2e00fc653100fb552700dc3e1400d9431901dc3e1400d9431902d95d3b00 +f4f6f900ffffff0bf4f6f901e8ecef02e6dcdc00d9dcde01d2d4d600cbcccd00d2d4d600 +cbcccd00e8b3a800fb5c2e00fc653100fb5c2e00fc653101fb5c2e00fc653105f9653d00 +fc653100fc6c3301fc653103fc6c3300fc653100e5541f00d9431900d94b2000d9431902 +f8cbc000ffffff07f4f6f900e8ecef01e6dcdc00d9dcde01cbcccd00d2d4d600cbcccd00 +d8cccb00cbcccd00e8a58f00fc653107f9653d00fc653100f9653d01fc653100f9653d04 +fc653103fb5c2e00e4461800fc653103f9653d00fc65310af9653d00fc653104fb5c2e00 +d9431900e5541f00f4f6f900ffffff07f4f6f900e8ecef01d9dcde00d2d4d600d8cccb00 +cbcccd00d8cccb00c4c5c500cbcccd00c4c5c500cbcccd01f8836200fb6c4103fb744e00 +fc733900fb744e00fc733900fb744e00fb6c4100fc733900fb6c4100fc733900fb6c4106 +f9653d00fc653100f9e4e100ffffff0bf4f6f900e8ecef00e0e4e700d9dcde00d2d4d600 +cbcccd01c4c5c501c8aca500e54d1d00fc653100fc6c3300fb6c4105fc733900fb6c410b +f9dcd100ffffff04f4f6f900e8ecef00e0e4e700d9dcde00cbcccd01c4c5c502c6bcba00 +d45e4400d9431901fc653100fb6c4100fc6c3300fb6c4102fc6c3300fb6c4101fc6c3300 +f9653d00fc6c3300fc653100f9653d00fc653100f9653d00fc6c3300f9653d00fc653100 +fc6c3300f9653d00fb8d5500ffffff01f4f6f901e8ecef01e0e4e700d9dcde00d2d4d601 +cbcccd00c4c5c501c6bcba00bbbcbd00c6bcba00b4b4b400bbbcbd00b4b4b400bbbcbd01 +b99a9400d94b2000d9431902fb552700fb6c410cfc653100fb6c4100fc653100f9653d00 +fc6c3300f9653d00fc6c3300fb6c4100f8cbc000ffffff01ecf3f500e0e4e700d9dcde00 +d2d4d600cbcccd00c4c5c500bbbcbd00b4b4b401b8938b00dc3e1400d9431903dc3e1400 +e4461800fc6c3300fc653101fb6c4100fc653100f9653d00fc6c3300fb6c4101fc6c3300 +fb6c4100fc6c3300fb6c4100fc6c3300fb6c4101fc6c3300fb6c4100fb744e00f4f6f900 +ffffff02ecf3f500e8ecef00e0e4e700d9dcde00cbcccd01bbbcbd02b4b4b400b98a7c00 +d9542d00d9431907fb5c2e00fc6c3303fb6c4100fc6c3300fb6c4100f9653d00fb6c4100 +fc6c3300fb6c4100fc6c3300f9653d00fc6c3300f9653d00fc6c3300fb6c4102fc6c3300 +fb6c4100f9653d00fc6c3300fb6c4100fc653101fb6c4100d98c7800a4a5a403b66c5900 +d9431900c9452200d9431907fb552700fc6c3300fb6c4104fc6c3300fb6c4103fc6c3300 +fb6c4102fc6c3300f9653d00fc6c3300fb6c4101fc6c3300fb6c4100fb744e00a4a5a401 +9c9e9c01a89a95009c9e9c02ba654f00d9431900c9452200d9431904d94b2000d9431903 +fb552700fb6c4100fc6c3300fb6c4102f9653d00fb6c4100fc6c3300fb6c4102f9653d00 +fc6c3300fb6c4103fc6c3300fb6c4100fc653101fa7c5800ffffff14f5886c00fb552700 +fb5c2e14d94b2000c9452202d94b2000c9452207dba39300e8ecef00f4f6f901ffffff07 +f4f6f900ecf3f500e8ecef01e0e4e700e6dcdc00d9dcde00d2d4d601d8cccb00fb6c4100 +fb5c2e05fc653100fb5c2e03fc653100fb5c2e01fc653100fb5c2e00fc653100fb5c2e03 +fc653100fb5c2e01fb552700d9431901c9452200d9431900c9452200d9431901c9452200 +d9431900c9452200e6ad9b00ffffff06ecf3f500e8bcb000fb5c2e03fc653100fb5c2e00 +fc653101fb5c2e00fc653106fb5c2e00fc653101fb5c2e00fc653100fb552700d9431901 +c9452200d9431902c9452200d9431900e8bcb000ffffff0ef4f6f900e8ecef01e0e4e700 +d9dcde02d2d4d601d8cccb00cbcccd00f5886c00fc653104f9653d00fc653100f9653d01 +fb6c4100f9653d00fb6c4102f9653d00fb6c4105fb5c2e00c74b2a00d94b2000c74b2a00 +d94b2000c74b2a00ea7c5e00ffffff08ecf3f500e8ecef00e0e4e700d9dcde01d2d4d601 +cbcccd00d2d4d600cbcccd01f9947500fc653102f9653d00fc653100fb6c4100f9653d01 +fb6c410af9653d00fc6c3300fb6c4100f9653d00fb6c410cfb744e00fb6c4105f9653d01 +e54d1d00d94b2000f8d4c900ffffff09ecf3f500e8ecef00d9dcde01cbcccd02c4c5c500 +cbcccd01c4c5c500cbcccd00e6ad9b00fb744e00fc733900fb744e0efc733900fb744e00 +fb6c4100fc733900fb744e00f9947500ffffff0bf4f6f900e8ecef00d9dcde00d2d4d601 +cbcccd00c4c5c502c8745e00fb5c2e00fb6c4102fc733900fb6c4100fb744e00fc733900 +fb744e00fc733900fb744e00fc733900fb744e00fc733900fb744e00fc733900fb744e00 +fc733900fb744e00fc733900fb744e00fb8d5500ffffff05f4f6f900e8ecef00e0e4e700 +d2d4d600cbcccd00c4c5c501bbbcbd01b8adaa00d94b2000c9452200e5541f00fb6c4102 +fc733900fb6c4100fc733900fb6c410ef9dcd100ffffff03f4f6f900ecf3f500e8ecef00 +e0e4e700d9dcde00d2d4d601c4c5c502bbbcbd03b4b4b400bbbcbd00b4b4b400bbbcbd00 +c86d5400c9452201c74b2a00c9452200fb6c4100fc733905fb6c4100fc733901fb6c4103 +fc6c3300fb6c4105fca46d00ffffff00f4f6f900ecf3f500e0e4e700d9dcde00cbcccd00 +c4c5c500bbbcbd00b4b4b402b77c6a00d9431905fb552700fc6c3300fb6c4100fc6c3300 +fc653100fb6c4103fc6c3300fb6c4105fc733900fb6c4101fac4ac00ffffff03f4f6f900 +e8ecef00e0e4e700d2d4d601c4c5c501bbbcbd00abacad00c8745e00c74b2a00d9431900 +c9452201d94b2000c9452200d94b2000c9452200e5541f00fc6c3300fb6c4105fc733900 +fb6c4100fc733900fb6c410cfc6c3300fb6c4100fc6c3300f9653d00f8836200c8a49d00 +a4a5a404c8745e00c9452209e54d1d00fb6c410cfc6c3300f9653d00fb6c4101fc653100 +f9653d00fb6c4100f9653d00fb6c4100e78b7100abacad00a4a5a4019c9e9c04a7847c00 +c9452200d9431900c9452207d9431900c9452200d9431900fb6c4107f9653d00fb6c410b +fc733900ffffff13f9e4e100fb5c2e00e75c2a00fb552700e75c2a00fb552700e75c2a00 +fb552700e75c2a04e5541f00e9644000e75c2a03e9644000e75c2a00e9644000e75c2a00 +d9542d00c9452200c74b2a00c9452200c74b2a01c9452200c74b2a01c9452200c74b2a01 +c9452200c86d5400e8ecef00f4f6f901ffffff0af4f6f900e8ecef01e0e4e700e6dcdc00 +d9dcde00d2d4d601d8ac9f00fb5c2e00f9653d00e9644000fb5c2e00f9653d00fb5c2e02 +f9653d00fb5c2e00f9653d00fb5c2e00f9653d00fb5c2e00fc653100fb5c2e00f9653d00 +fb5c2e00fc653101fb5c2e01fc653100fb5c2e00e75c2a00c9452203d94b2000c9452203 +d9431900e8b3a800ffffff05f4f6f900e8ecef00f9947500f9653d04fc653100f9653d0c +fc653100f9653d00e5541f00c9452201d94b2000c9452203da6d5000ffffff10f4f6f900 +ecf3f500e8ecef01e6dcdc00d9dcde00d2d4d601cbcccd00d2d4d600d7c4bd00fb6c4100 +f9653d02fb6c4100f9653d00fb6c410fd94b2000c74b2a02c9452200c9593b00ffffff09 +ecf3f500e8ecef00e6dcdc00d9dcde01d2d4d601cbcccd01d2d4d600d7c4bd00f5886c00 +fb6c4119fc733900fb744e09fc733900fb744e00fb6c4103e5541f00c9452200e8a58f00 +ffffff0af4f6f900e8ecef00e0e4e700d9dcde00d2d4d601cbcccd01c4c5c500cbcccd00 +c4c5c500d8cccb00c4c5c500f8836200fb744e03fa7c5800fb744e00fa7c5806fb744e00 +fa7c5800fb744e05fb6c4100f4f6f900ffffff09f4f6f900ecf3f500e0e4e700d9dcde00 +d2d4d600cbcccd00c4c5c502c7b5b100d9542d00fb6c4101fc733900fb6c4100fb744e00 +fc733900fb744e00fb6c4100fb744e08fa7c5800fb744e00fa7c5800fb744e00f9dcd100 +ffffff04f4f6f900ecf3f500e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500c6bcba00 +c4c5c500bbbcbd00c7998d00c74b2a01fb5c2e00fb744e05fc733900fb744e00fc733903 +fb744e00fc733903fb6c4100fc733901f9947500ffffff06ecf3f500e8ecef00e0e4e700 +d9dcde00d2d4d601c4c5c501bbbcbd02b4b4b400bbbcbd00b4b4b400bbbcbd00b4b4b400 +b99a9400c9452200d94b2000c9452200d94b2000e75c2a00fb6c4100fb744e02fb6c4100 +fb744e00fc733900fb744e00fb6c4100fb744e00fc733902fb6c4104fc733900fb6c4100 +fa7c5800ffffff00ecf3f500e8ecef00d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd01 +b4b4b400b8adaa00c9593b00c9452201d9431900c9452202f9653d00fb6c4102fb744e00 +fc733902fb6c4100fb744e00fc733900fb744e00fc733901fb744e00fc733900fb744e00 +fc733900f8836200ffffff03f4f6f900ecf3f500e8ecef00e0e4e700d9dcde00d2d4d600 +c4c5c501b7a4a000c9593b00c74b2a04c9452200c74b2a01f9653d00fb744e0cfc733900 +fb744e00fc733900fb744e00fc733901fb6c4100fc733900fb6c4104fb744e00e8a58f00 +bbbcbd00abacad00a4a5a404b7746200c9452209e5541f00fc733900fb6c4100fc733900 +fb6c4100fc733900fb6c4110c8a49d00b8adaa00a4a5a4019c9e9c00a89a95009c9e9c02 +a89a9500c945220cfb5c2e00f9653d00fb6c4106fc733900fb6c4100fb744e00fb6c4101 +fb744e00fc733900fb6c4105f4f6f900ffffff12f7b9a600e75c2a07fb5c2e00e75c2a00 +e9644000e75c2a00e9644000e75c2a01e9644000e75c2a00e9644000e75c2a01e9644000 +e75c2a00c74b2a00b9462700c9452200c74b2a01b9462700c9452200b9462700c9452200 +c74b2a00b9462700c9452200c74b2a00d8bcb600f4f6f900ffffff0df4f6f900ecf3f500 +e8ecef01d9dcde01d2d4d601eb826400e75c2a00f9653d00e9644000e75c2a00e9644001 +fb5c2e00e9644001fb5c2e00e9644000fb5c2e00e9644000f9653d00e9644000f9653d01 +fb5c2e00e9644000f9653d01fb5c2e00f9653d00e5541f00c9452203c74b2a00c9452203 +c74b2a00e6ad9b00ffffff05f4f6f900e6dcdc00f9653d06fb6c4101f9653d00fb6c4104 +f9653d00fb6c4100f9653d03fb5c2e00c9452207fac4ac00ffffff11f4f6f900f7ece700 +e8ecef00e0e4e700d9dcde02d2d4d600cbcccd01e59c8700f9653d00fb6c4102f9653d03 +fb6c4100f9653d00fb6c4102fb744e00fb6c4106e75c2a00c9452200c74b2a02c9452200 +f7b9a600ffffff08f4f6f901e8ecef00e6dcdc00d9dcde00d2d4d602cbcccd02d7c4bd00 +fa7c5800fb6c4108fb744e00fb6c4100fb744e00fc733900fb744e1be9644000c74b2a00 +d8846e00ffffff0cecf3f500e8ecef00d9dcde01d8cccb00cbcccd01c4c5c500cbcccd00 +c4c5c500cbcccd00c4c5c500e8a58f00fb744e01fa7c5800fb744e01fa7c5801fb744e00 +fa7c5800fb744e01fa7c5800fb744e00fa7c5800fb744e00fa7c5804fb744e00fa7c5800 +f9a58b00ffffff09f4f6f900e8ecef00e0e4e700d2d4d601cbcccd00c4c5c502c8847200 +fb5c2e00fb744e0cfa7c5800fb744e00fa7c5800fb744e00fa7c5801fb744e00f5886c00 +ffffff05f4f6f900e8ecef00e0e4e700d2d4d600cbcccd01c4c5c500bbbcbd01c4c5c500 +c97c6700c74b2a01fb6c4100fa7c5800fb744e00fa7c5800fb744e07fb6c4100fb744e02 +fb6c4100fb744e03f9dcd100ffffff07ecf3f500e8ecef00e0e4e700d9dcde00d2d4d601 +c4c5c500bbbcbd00c4c5c500b4b4b400bbbcbd00b4b4b400bbbcbd00b4b4b400bbbcbd01 +c7634a00c9452200c74b2a00c9452200c74b2a00fb6c4100fb744e01fc733900fb744e00 +fb6c4100fb744e00fb6c4100fb744e00fc733900fb744e02fc733900fb744e00fc733901 +fb6c4100fb744e01fc733900f9e4e100e8ecef00e0e4e700d9dcde00cbcccd00c4c5c500 +bbbcbd00b4b4b402b8938b00c9452205d94b2000fb6c4100fc733900fb744e01fc733900 +fb744e00fb6c4100fb744e0afac4ac00ffffff03f4f6f900ecf3f500e0e4e700d9dcde00 +d2d4d600cbcccd00c4c5c500b77c6a00c74b2a07d95d3b00fc733900fa7c5800fb744e00 +fa7c5800fb7c3800fa7c5800fb744e00fb7c3800fb744e00fa7c5800fb744e0cfc733900 +fb744e00fc733900fb744e00f9947500d7c4bd00c4c5c500b4b4b401a4a5a404b66c5900 +c9452209e5541f00fb744e00fb6c4101fb744e01fc733900fb744e00fc733900fb744e00 +fc733900fb744e00fb6c4100fc733900fb6c4104fc733900fb6c4100fb744e00f8836200 +bbbcbd00b4b4b400abacad00a4a5a4019c9e9c04ba5d4500c945220be5541f00fb6c4103 +fc733900fb6c4100fb744e00fb6c4100fb744e00fb6c4100fb744e02fb6c4100fb744e04 +fb6c4101f9e4e100ffffff11f4f6f900ea7c5e00e75c2a00d95d3b00e75c2a02d9542d00 +e9644000e75c2a00d95d3b01e75c2a02d95d3b00e9644001d95d3b00e75c2a00e9644000 +d95d3b00e9644000c74b2a00b9462700c9452200b9462702c9452200b9462700c74b2a00 +b9462703c86d5400f4f6f900ffffff0ff4f6f900e8ecef01e0e4e701d9dcde00d2d4d600 +d8b4ac00e9644000e75c2a00fb5c2e00e9644000fb5c2e00e9644002fb5c2e00e9644000 +f9653d00e9644001fb5c2e00e9644000fb5c2e00e9644000f9653d00e9644000fb5c2e00 +e9644000f9653d00e9644000e75c2a00c74b2a02c9452200b9462700c9452200c74b2a02 +c9452200e8b3a800ffffff04f4f6f900e8ecef00e8b3a800f9653d04fb6c4100f9653d01 +fb6c4100f9653d00fb6c4100f9653d00fb6c4100f9653d00fb6c4100f9653d00fb6c4100 +f9653d03d94b2000c9452200c74b2a00c9452200c74b2a02c9452200c86d5400ffffff13 +f4f6f900ecf3f500e8ecef00e0e4e700e6dcdc00d2d4d602d8cccb00d7c4bd00fb6c4100 +f9653d00fb6c4100f9653d00fb6c4109fb744e00fb6c4100fb744e00fb6c4101fb744e00 +f9653d00e9644000c74b2a01c9452200c74b2a01d77c6200ffffff09f4f6f900e8ecef01 +e6dcdc00d9dcde00d2d4d601cbcccd00d2d4d600cbcccd00d8cccb00d8b4ac00fb744e02 +fb6c4100fb744e00fb6c4101fb744e00fb6c4100fb744e01fb6c4100fb744e00fb6c4100 +fb744e12fa7c5800fb744e05fb6c4100c74b2a00c7634a00ffffff0df4f6f900ecf3f500 +e6dcdc00d9dcde00d2d4d600cbcccd04c4c5c500cbcccd00d7c4bd00f8836200fa7c5800 +fb744e00fa7c5800fb744e00fa7c5800fb744e00fa7c5800fb744e00fa7c580bfb744e01 +ffffff08f4f6f900e8ecef01d9dcde00d2d4d600d8cccb00cbcccd00c4c5c501c6bcba00 +c9593b00fb744e09fa7c5800fb744e00fa7c5800fb744e02fa7c5800fb744e00fa7c5800 +fb744e00fa7c5800fad4b000ffffff05ecf3f500e8ecef00d9dcde00d2d4d600cbcccd00 +c4c5c502bbbcbd00c6bcba00b66c5900b7533a00c74b2a00fb744e00fa7c5801fb744e00 +fa7c5801fb744e00fa7c5800fb744e07fa7c5800fb744e02f8836200ffffff09ecf3f500 +e8ecef00e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd00c6bcba00b4b4b400 +bbbcbd00b4b4b400bbbcbd00b4b4b401b9857800b84c3000c74b2a01c9452200e9644000 +fb744e04fc733900fb744e00fb6c4100fb744e00fb6c4100fb744e00fb6c4100fb744e00 +fb6c4100fb744e03fb6c4100fb744e00fac4ac00e8ecef00e0e4e700d2d4d600cbcccd00 +c4c5c500bbbcbd00b4b4b402b7746200b9462700c9452200b9462700c9452202e75c2a00 +fb744e0bfb6c4100fb744e03fa7c5800ffffff03f4f6f900ecf3f500e0e4e701d9dcde00 +cbcccd00c8aca500ba654f00b7533a00b84c3000b7533a00b84c3000b7533a01c74b2a00 +b7533a00e9644000fa7c5809fb744e00fa7c5807fb744e00fa7c5800fb744e04f5886c00 +e8bcb000d9dcde00cbcccd00c4c5c500bbbcbd00abacad00a4a5a404b7746200b9462701 +c9452200b9462701c9452200b9462700c9452200b9462700c9452200d9542d00fb744e03 +fb6c4100fb744e01fb6c4100fb744e01fb6c4100fb744e01fb6c4100fb744e06e9947d00 +bbbcbd00b4b4b400abacad00a4a5a4019c9e9c01a89a95009c9e9c01a9746500b9462706 +c9452200b9462701c9452200b9462700d9542d00fb6c4103fb744e00fb6c4100fb744e00 +fb6c4100fb744e02fb6c4100fb744e03fb6c4100fb744e00fb6c4100fb744e01f9dcd100 +ffffff11f9e4e100d9654700d95d3b04e75c2a00d95d3b00d9542d00e75c2a00d95d3b00 +d9542d00d95d3b01e75c2a00d95d3b01e9644000d95d3b03b946270cd8b4ac00f4f6f900 +ffffff10f4f6f900ecf3f500e8ecef00e0e4e700d9dcde01d2d4d600e8866c00e9644003 +e75c2a00e9644002e75c2a00e964400cd9542d00c74b2a00b9462700c9452200b9462700 +c74b2a00b9462704d8b4ac00ffffff04f4f6f900e8ecef00e78b7100f9653d00e9644001 +e86c4c00e9644000e86c4c00e9644000e86c4c02e9644000e86c4c04e9644000fb6c4100 +e9644000fb6c4100e9644000b84c3000c9452200b84c3000b9462700c74b2a00b9462701 +c74b2a00d8ac9f00ffffff14f4f6f900ecf3f500e8ecef00d9dcde02d2d4d600cbcccd01 +e9947d00fb6c4100f9653d00fb6c4101f9653d00fb6c4100f9653d00fb6c4101e86c4c00 +fb6c4101e86c4c00fb6c4101e86c4c00fb6c4100fb744e00fb6c4100e86c4c00fb6c4100 +c74b2a00b84c3000c74b2a00b84c3001c9593b00ffffff0aecf3f500e8ecef01d9dcde01 +d2d4d601cbcccd03e8a58f00fb744e07fb6c4100fb744e07fa7c5800fb744e00fa7c5803 +fb744e00fa7c5800fb744e00fa7c5801fb744e00fa7c5802fb744e00fa7c5800fb744e00 +fa7c5800fb744e00fa7c5800fb744e00b7533a00c9593b00f9e4e100ffffff0df4f6f900 +ecf3f500e8ecef00d9dcde00d2d4d601cbcccd01c4c5c502cbcccd00c4c5c500e8a58f00 +fb744e00fa7c5802fb744e00fa7c5809f8836200fa7c5805f7b9a600ffffff07f4f6f900 +e8ecef00e0e4e700d9dcde00d2d4d600cbcccd00c4c5c502c88b7d00e75c2a00fb744e00 +fa7c5800fb744e00fa7c5800fb744e00fa7c5804fb744e00fa7c5800fb744e00fa7c5801 +fb7c3800fb744e00fa7c5801fb744e00f8836200ffffff05f4f6f900ecf3f500e0e4e700 +d9dcde00d2d4d600c4c5c501bbbcbd01c4c5c500bbbcbd00c75c4d00b7533a00c9593b00 +f8836200fa7c5806fb744e00fa7c5803fb744e00fa7c5800fb744e00fa7c5803fcb58e00 +ffffff0aecf3f500e0e4e700d9dcde00d2d4d601c4c5c501bbbcbd01b4b4b400bbbcbd00 +b4b4b400bbbcbd00b4b4b400c8a49d00b9462700c74b2a00b84c3000c74b2a01fb744e13 +f9ad9400e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd01b4b4b401abacad00ba5d4500 +c9452200b84c3000b9462700b84c3000b9462700b84c3000fb6c4100fb744e04fa7c5802 +fb744e01fa7c5800fb744e05f9ad9400ffffff02ecf3f501e0e4e701d2d4d600cbcccd00 +b78d8500b7533a00b84c3001c74b2a00b84c3001c74b2a00b84c3000c9593b00fb744e00 +fa7c5819f9ad9400e0e4e700e6dcdc00d9dcde00cbcccd00c4c5c500b4b4b400abacad00 +a4a5a404b7746200b9462709d9542d00fb744e0dfb6c4100fb744e00fb6c4100fb744e03 +d8ac9f00c4c5c500bbbcbd00b4b4b400abacad00a4a5a4009c9e9c04a7847c00b9462704 +c4363800b9462706fb6c4100fb744e02fb6c4100fb744e00fb6c4100fb744e0bfb6c4100 +fb744e00f8d4c900ffffff11e8b3a800d45e4400d95d3b00d45e4401d95d3b00e9644000 +cc545800d95d3b0dc74b2a00b9462704a6442b00b9462700a6442b00b9462700a6442b00 +b9462700a6442b00ba5d4500e8ecef00ffffff12f4f6f900f7ece700e0e4e701d9dcde00 +d2d4d600d8ac9f00e9644000d9654700e9644000d45e4400e9644003e86c4c00e964400c +d95d3b00b84c3000b9462700b84c3001b9462700b84c3000b9462700b84c3002d8ac9f00 +f4f6f900ffffff02f4f6f900ecf3f500e6dcdc00e8745600e86c4c00e9644000e86c4c00 +e9644000fb6c4100e9644000e86c4c01e9644000e86c4c04e9644000e86c4c03e9644000 +d95d3b00b84c3002b9462700b84c3002b7533a00f7ece700ffffff15f7ece700e8ecef01 +e6dcdc00d9dcde00d2d4d601d8cccb00d8b4ac00e86c4c00fb6c4102e86c4c00f9653d00 +fb744e00fb6c4100e86c4c00fb6c4100e86c4c00fb744e00fb6c4100e86c4c00fb744e00 +e86c4c00fb744e00fb6c4100e86c4c00fb744e01d45e4400b84c3001c9593b00b84c3001 +f8cbc000ffffff0aecf3f500e8ecef00e6dcdc00d9dcde01d2d4d601cbcccd00d2d4d600 +d8cccb00cbcccd00e9947d00fb744e0dfa7c5801fb744e00fa7c5800fb744e00fa7c5800 +fb744e00fa7c5801fb744e00fa7c5801fb744e00fa7c5801fb744e00fa7c5800fb744e00 +fa7c5803fb744e00c75c4d00b84c3000e8b3a800ffffff0ff4f6f900e8ecef00e6dcdc00 +d9dcde00d2d4d600d8cccb00c4c5c500cbcccd02c4c5c500cbcccd00d8bcb600fa7c5811 +f8836200fa7c5802ea7c5e00ffffff07ecf3f500e8ecef00d9dcde00d2d4d600cbcccd01 +c4c5c502c7634a00fb744e00fa7c5800fb744e00fa7c5803fb744e00fa7c580cf8cbc000 +ffffff05f4f6f900e8ecef00e0e4e700d2d4d601c4c5c501c6bcba00c4c5c500bbbcbd00 +c7b5b100b7533a01d45e4400f8836200fa7c5809fb744e00fa7c5804fb744e00fa7c5801 +f9e4e100ffffff0af4f6f900ecf3f500e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500 +bbbcbd02b4b4b400bbbcbd00b4b4b400bbbcbd01c75c4d00b84c3000c74b2a00b84c3000 +c74b2a00fb744e00fa7c5800fb744e00fa7c5801fb744e00fa7c5801fb744e00fa7c5806 +fb744e00fa7c5801fb744e00f9a58b00e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd00 +b4b4b402b99a9400b84c3003b9462700b84c3000c74b2a00fb744e00fa7c5800fb744e00 +fa7c5802fb744e00fa7c5800fb744e00fa7c5801fb744e00fa7c5802fb744e00fa7c5800 +fb744e00f9dcd100ffffff00f4f6f900ecf3f500e0e4e701d9dcde00d2d4d600c7b5b100 +a8655400b84c3007da633600fa7c5805f8836200fa7c5800f8836200fa7c5800f8836200 +fa7c5800f8836200fa7c580cf9947500f9dcd100f4f6f900e8ecef00e0e4e700d2d4d600 +cbcccd00c4c5c500bbbcbd00abacad00a4a5a404a9746500b84c3003b9462700b84c3000 +b9462701b84c3000b9462700d45e4400fb744e14d7c4bd00c4c5c500bbbcbd00b4b4b400 +abacad00a4a5a4019c9e9c03a88c8600a6442b01c4363800a6442b00b9462700a6442b01 +c4363800a6442b00b9462700a6442b00b9462701e9644000e86c4c00fb6c4100e86c4c00 +fb744e00e86c4c00fb744e00e86c4c00fb744e00e86c4c00fb744e00e8745600e86c4c00 +fb744e00e8745600e86c4c01fb744e00e8745600e86c4c00fb744e00f9dcd100ffffff11 +d6938100d45e4406d95d3b00d45e4400d95d3b01d45e4400d95d3b00cc545800d95d3b00 +d45e4400cc545800d9542d00d45e4400cc545800d95d3b00b9462700a6442b04b9462700 +a6442b01b9462700a6442b02cc916400f4f6f900ffffff13ecf3f501e8ecef00d9dcde01 +d8cccb00d3725300d9654700e9644000d9654705da6d5000d9654700e86c4c00d9654700 +da6d5000e86c4c00d9654700e86c4c00d9654700e86c4c00d9654700e9644000d9654700 +d95d3b00b84c3009d8ac9f00ffffff00f4f6f903ecf3f500e5c4c200e86c4c03da6d5000 +e86c4c00da6d5000e86c4c00e9644000e86c4c08da6d5000e86c4c00da6d5000b84c3003 +a84d3500b84c3000b7533a00b84c3000c97c6700ffffff17ecf3f500e8ecef00d9dcde01 +d2d4d601cbcccd01ea7c5e00e86c4c06fb744e01e86c4c00fb744e00e8745600e86c4c00 +fb744e00e86c4c00fb744e00e8745600fb744e00e8745601d9654700b7533a01b84c3000 +b7533a01dba39300ffffff0af4f6f900ecf3f500e8ecef00e6dcdc00d9dcde00d2d4d602 +cbcccd02d8cccb00e78b7100fa7c5807fb744e00fa7c5800fb744e00fa7c5801fb744e00 +fa7c5811e8745600fa7c5800ea7c5e00d9654700b7533a00c88b7d00ffffff10f4f6f900 +ecf3f500e8ecef00d9dcde00d2d4d601cbcccd01c4c5c500d8cccb00c4c5c500cbcccd00 +c4c5c500e59c8700fa7c580af8836200fa7c5801f8836200fa7c5803f8836200fa7c5801 +f8cbc000ffffff05f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600d8cccb00c4c5c502 +c7998d00c75c4d00fa7c580af8836200fa7c5801f8836200fa7c5800f8836200fa7c5800 +f8836200fa7c5800f8836200ffffff06ecf3f500e8ecef00d9dcde01cbcccd00c4c5c501 +bbbcbd02b8adaa00b7533a01da633600f8836203fa7c580df8836200fa7c5800ffffff0c +ecf3f500e8ecef00e0e4e700d2d4d600cbcccd00c4c5c500bbbcbd01b4b4b400bbbcbd00 +b4b4b400bbbcbd00b4b4b401b7746200b84c3002b7533a00e86c4c00fa7c5812f9947500 +d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd01b4b4b401a88c8600b84c3000a84d3500 +b84c3003c9593b00fa7c5809fb744e00fa7c5800fb744e00fa7c5800fb744e00fa7c5801 +f5886c00f4f6f901e8ecef00e0e4e701d2d4d600cbcccd00b78d8500a7543f00b84c3000 +a84d3500b84c3000a84d3500b84c3002b7533a00e8745600fa7c5805f8836200fa7c5800 +f8836201ea7c5e00f8836201fa7c5800f8836202fa7c5800f8836200fa7c5800f8836200 +fa7c5800f8836200fa7c5801f5886c00fac4ac00ffffff01f4f6f900e8ecef00e0e4e700 +d2d4d600cbcccd00c4c5c500b4b4b401a4a5a404a96d5f00a84d3500b84c3000a84d3500 +b9462700a84d3500b84c3001a84d3500b84c3001c9593b00fa7c5809fb744e00e8745600 +fa7c5800e8745600fa7c5800e8745604e8866c00d2d4d600cbcccd00c4c5c500b4b4b400 +abacad00a4a5a4009c9e9c0499939300a84d3500a6442b08b9462700a6442b01d95d3b00 +fb744e00e86c4c02fb744e00e86c4c02e8745600e86c4c00e8745609f9dcd100ffffff10 +f4f6f900d3725300c75c4d02d45e4400c75c4d00c9593b01d45e4400c9593b00c75c4d00 +c9593b00cc545800d45e4400c9593b00d45e4400c9593b00d95d3b00c9593b00d95d3b00 +c75c4d00c74b2a00a6442b0cd2d4d600ffffff14f4f6f901e8ecef00e0e4e700d9dcde00 +d2d4d600d6938100d9654704da6d5005e86c4c00d9654700da6d5003e86c4c00da6d5001 +e86c4c00c7634a00b84c3001a84d3500b7533a00a84d3500b7533a01a84d3500b7533a00 +a7543f00d8ac9f00ecf3f500f4f6f902ecf3f500e8ecef00e8a58f00da6d500bd9654700 +da6d5004e86c4c00da6d5000d9654700b84c3000a7543f00a84d3501b7533a00a84d3502 +d8bcb600ffffff17f4f6f900e8ecef01d9dcde01d2d4d601cbcccd00dba39300e8745606 +e86c4c00e8745601e86c4c00e8745608e86c4c00a7543f00b7533a01a7543f00b7533a00 +b66c5900ffffff0bf4f6f900ecf3f500e8ecef00d9dcde00e6dcdc00d2d4d602cbcccd02 +d8bcb600ea7c5e00fa7c5800e8745600fa7c5800e8745600fa7c5800e8745600fb744e00 +fa7c5809ea7c5e00fa7c5801ea7c5e00fa7c5801ea7c5e00fa7c5800ea7c5e01fa7c5800 +ea7c5e01fa7c5800eb826400f8836200dc725400b7533a00b7746200ffffff12f4f6f900 +e8ecef00e0e4e700d9dcde00cbcccd00d8cccb00cbcccd01c4c5c500cbcccd00c4c5c500 +cbcccd00c6bcba00f8836201fa7c5800f8836202fa7c5800f8836206fa7c5800f8836205 +fa7c5800e8866c00ffffff05ecf3f500e8ecef00d9dcde00d2d4d601c4c5c503b7746200 +e8745600f8836213fac4ac00ffffff06e8ecef01d9dcde00d2d4d600cbcccd00c6bcba00 +c4c5c500bbbcbd00c4c5c500bbbcbd00c7b5b100b7533a01da6d5000f8836202fa7c5800 +f8836204fa7c5800f8836201fa7c5800f8836205f5886c00ffffff0cf4f6f900ecf3f500 +e0e4e700d9dcde00d2d4d600c4c5c501c6bcba00bbbcbd00b4b4b400bbbcbd00b4b4b400 +bbbcbd00b4b4b400b77c6a00b84c3000b7533a01b84c3000d9654700fa7c5807f8836200 +fa7c5800f8836207fa7c5800f5886c00d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b403 +b7746200a84d3500b84c3000a84d3500b84c3000a84d3501d9654700f8836200fa7c5803 +ea7c5e00fa7c5802f8836200fa7c5806f9a58b00ecf3f500e8ecef00e0e4e700d9dcde00 +d2d4d600c7b5b100b66c5900a84d3501b84c3000a6442b00a84d3500b84c3000a84d3500 +b84c3000c7634a00fa7c5800ea7c5e00fa7c5800ea7c5e01fa7c5800ea7c5e05fa7c5800 +eb826400ea7c5e00eb826400ea7c5e00f8836200ea7c5e01f8836200ea7c5e00f8836200 +eb826401f8836200f9a58b00f4f6f900ffffff02f4f6f900e8ecef00e0e4e700d9dcde00 +d2d4d600bbbcbd01abacad00a4a5a404a9746500b84c3000a84d3502b84c3000a84d3501 +b84c3000a84d3501c75c4d00e8745601ea7c5e00e8745601fa7c5800e8745603ea7c5e00 +fa7c5800e8745600ea7c5e01e8745600ea7c5e00e8745600ea7c5e00e8745600d69a9000 +d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400a4a5a4019c9e9c00a89a95009c9e9c02 +a84d3500a6442b0bc75c4d00e86c4c01e8745600e86c4c01e8745600e86c4c00e8745600 +e86c4c00e8745600e86c4c00e8745600e86c4c00e8745604e86c4c00e8745600f9dcd100 +ffffff10e9d5d700c9593b03c75c4d00c9593b00c75c4d01c9593b00c75c4d00c9593b00 +c75c4d00c9593b05c75c4d00c9593b01b84c3000a6442b0bba654f00f4f6f900ffffff15 +f4f6f900ecf3f500e8ecef00e6dcdc00d9dcde00d8bcb600d9654700da6d500ad3725300 +da6d5003d3725300da6d5001d3725300c86d5400b7533a00a7543f00b7533a00a7543f00 +b7533a00a7543f01b7533a00a7543f00b7533a00d8b4ac00ecf3f500f4f6f900ecf3f502 +e8ecef00d98c7800da6d5009dc725400da6d5008ba5d4500a84d3501b84c3000a84d3504 +f9e4e100ffffff17f4f6f901e8ecef00e6dcdc00d9dcde00d2d4d601cbcccd00d8bcb600 +dc725400d8755c00e8745600d8755c00e8745601d8755c00e8745600dc725400e8745609 +d77c6200e8745600b7533a00a7543f01b7533a00a7543f01ffffff0cf4f6f900e8ecef01 +d9dcde01d2d4d602d8cccb00cbcccd01d8ac9f00eb826400ea7c5e00fa7c5800ea7c5e00 +fa7c5800ea7c5e10eb826402f8836200ea7c5e00eb826400f8836200eb826401ea7c5e00 +e8745600ba5d4501f9e4e100ffffff12f4f6f900ecf3f500e0e4e700d9dcde01cbcccd02 +c4c5c500cbcccd00c4c5c500cbcccd00c4c5c500e59c8700f8836200e8866c00f8836201 +eb826400f5886c00eb826400f8836200eb826400f8836208fa7c5800eb826400f8836200 +ea7c5e00f8cbc000ffffff03f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd01 +c4c5c501c8a49d00c7634a00f8836201f5886c00f8836201f5886c00f8836202f5886c00 +f8836209f5886c00ffffff06f4f6f900ecf3f500e0e4e700d9dcde00d2d4d600c4c5c500 +bbbcbd01c4c5c500bbbcbd00c4c5c500b8adaa00b7533a01c86d5400fa7c5800f8836203 +fa7c5800f8836201fa7c5800f8836209f5886c00ffffff0decf3f500e8ecef00d9dcde00 +d2d4d600cbcccd00c4c5c500bbbcbd00b4b4b400bbbcbd00b4b4b400bbbcbd00b4b4b400 +bbbcbd00a77c7000a84d3500a7543f00a84d3500b7533a00c7634a00f8836208eb826400 +f5886c00f8836200eb826400f8836200eb826400f8836200eb826400f8836200eb826401 +d2d4d600cbcccd00c4c5c500bbbcbd00b4b4b402abacad00a8655400a84d3504b84c3000 +e8745600ea7c5e01f8836200ea7c5e01f8836200ea7c5e00eb826400fa7c5800ea7c5e00 +fa7c5806e8bcb000e0e4e701d9dcde00d2d4d600b8938b00a7543f00a84d3506b7533a00 +da6d5000fa7c5800ea7c5e00fa7c5800ea7c5e01f8836200ea7c5e00eb826400ea7c5e00 +f8836200eb826406ea7c5e00eb826406f5886c00f8d4c900ffffff04ecf3f500e8ecef00 +e0e4e700d2d4d600cbcccd00c4c5c500b4b4b401a4a5a404a9746500a84d3508b84c3000 +c9593b00ea7c5e00f8836200ea7c5e04fa7c5800ea7c5e00e8745602ea7c5e00e8745602 +ea7c5e00e8745602e8a58f00d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400abacad00 +a4a5a4009c9e9c04a65b4500a6442b0bb84c3000e86c4c00da6d5000e86c4c00e8745600 +da6d5000e86c4c00e8745600e86c4c00dc725400e8745600dc725400e8745600dc725402 +da6d5000dc725401da6d5000e8745600e9d5d700ffffff10d8bcb600ba5d4500c75c4d00 +c9593b00ba5d4500c9593b00c7634a00ba5d4500c9593b01c7634a00c9593b02c75c4d00 +c9593b00c75c4d00c9593b00c75c4d00c9593b01ba5d4500a6442b0cc8938400f4f6f900 +ffffff16f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600c97c6700d9654700d3725300 +c7634a00da6d5000c86d5400da6d5000c86d5400da6d5000c86d5400d3725300c86d5400 +da6d5000d3725300da6d5000d3725300da6d5000d3725300dc725400d8755c00dc725400 +c86d5400a7543f00a65b4500b7533a00a7543f01a65b4500b7533a00a7543f00a65b4501 +c8aca500ecf3f502f4f6f900e8ecef00e0e4e700d8755c00dc725400d3725300dc725400 +d3725300dc725401d3725300dc725400d3725301d8755c00d3725300d8755c02da6d5000 +d8755c00dc725400d3725300dc725400ba5d4500a84d3500a7543f01a84d3501a7543f00 +a84d3500b66c5900ffffff19f4f6f900e8ecef01e6dcdc00d2d4d601d8cccb00cbcccd00 +d8846e00d8755c00d77c6200d8755c03e8745600d8755c01e8745600d8755c00e8745600 +d8755c00e8745600d8755c00ea7c5e00d8755c00d77c6200ea7c5e00d77c6200ba5d4500 +a7543f04f9e4e100ffffff0cf4f6f900e8ecef00e0e4e700e6dcdc00d9dcde00d2d4d600 +cbcccd00d2d4d600cbcccd02e59c8700ea7c5e06fa7c5800ea7c5e02fa7c5800ea7c5e04 +f8836200eb826400f8836200eb826402ea7c5e00eb826406c7634a00a65b4500e8bcb000 +ffffff14f4f6f900e8ecef00e6dcdc00d9dcde00d2d4d600cbcccd02c4c5c500cbcccd00 +c4c5c500cbcccd00d8b4ac00e8866c00f8836200e8866c03f5886c00e8866c03eb82640a +d98c7800ffffff03f4f6f900e8ecef00e6dcdc00d2d4d600d8cccb00cbcccd00c4c5c502 +b77c6a00d8755c00eb826400f5886c01f8836200e8866c00f8836200f5886c00f8836200 +f5886c00f8836200f5886c01f8836200f5886c06f7b9a600ffffff06f4f6f900e8ecef00 +e0e4e700d9dcde00cbcccd00c4c5c502bbbcbd00c4c5c500bbbcbd00c6bcba00a8655400 +b7533a00c86d5400f5886c00f8836200f5886c00f8836201f5886c00f8836202f5886c00 +f8836200f5886c00f8836200f5886c00f8836200f5886c03f9947500ffffff0df4f6f900 +e8ecef00e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd01b4b4b400bbbcbd00b4b4b400 +bbbcbd00b4b4b400b7746200a7543f03c7634a00eb826408f8836200eb826407ea7c5e00 +f5886c00d2d4d600cbcccd00c4c5c500bbbcbd00b4b4b402b8adaa00a7543f00a84d3501 +a7543f00a84d3501a7543f00ea7c5e00eb826406f8836200eb826400f8836200eb826403 +ea7c5e01eb826400e6ccc900d9dcde00d2d4d600c7b5b100a96d5f00a84d3507c7634a00 +ea7c5e04eb826401ea7c5e00eb826403ea7c5e00eb826402e8866c00eb826400e8866c00 +eb826406f9a58b00ffffff06f4f6f900e8ecef00e0e4e700d2d4d600cbcccd00c4c5c500 +bbbcbd00abacad00a4a5a404a9746500a84d3509c7634a00ea7c5e05e8745602ea7c5e00 +e8745603d8755c00e8745600d8755c03d8b4ac00d9dcde00d2d4d600cbcccd00c4c5c500 +b4b4b400abacad00a4a5a4009c9e9c0498594900a6442b0bb7533a00da6d5000e8745600 +dc725400da6d5000e86c4c00dc725400da6d5000dc725403da6d5000dc725406da6d5000 +f9dcd100ffffff0ff4f6f900d69a9000c7634a00ba5d4501c9593b00ba5d4501c9593b00 +ba5d4501c9593b00ba5d4500c7634a00c9593b00ba654f00c7634a00c9593b00c7634a03 +b7533a00a6442b05994f3c00a6442b02994f3c00a6442b00994f3c00d8bcb600ffffff17 +f4f6f900ecf3f500e8ecef00d9dcde01d6938100c86d5401d3725300c86d5400da6d5000 +c86d5401d3725300da6d5000c56e5e00d3725303d8755c01c8745e00d8755c02c56e5e00 +a7543f00a65b4500a7543f00a65b4501a7543f00a65b4501a7543f01c8aca500f7ece700 +ecf3f500e8ecef02e9d5d700d8755c13d3725300a7543f07c8938400ffffff19f4f6f900 +ecf3f500e8ecef00d9dcde01d2d4d600cbcccd01d69a9000d8755c02ea7c5e00d8755c03 +e8745600d8755c01e8745600d8755c01ea7c5e00d8755c00d77c6200e8745600d77c6200 +d8755c00c7634a00a7543f04e8bcb000ffffff0cf4f6f900ecf3f500e8ecef00e6dcdc00 +d9dcde01d2d4d601cbcccd00d8cccb00cbcccd01e9947d00ea7c5e00eb826400ea7c5e00 +eb826404ea7c5e00eb826406e8866c00ea7c5e00e8866c06eb826403cc626500a65b4500 +c8938400ffffff15f4f6f900ecf3f500e0e4e700d9dcde00d2d4d600d8cccb00cbcccd00 +c4c5c500cbcccd00c4c5c501cbcccd00c4c5c500e59c8700e8866c02e78b7100e8866c00 +e78b7102e8866c01e78b7100e8866c00f5886c00e8866c00eb826400e8866c00eb826400 +e8866c00eb826401f5886c00ea7c5e00e9d5d700ffffff01f4f6f900ecf3f500e0e4e700 +d9dcde00d2d4d600cbcccd01c4c5c501c7b5b100ba654f00e8866c00f5886c00eb826400 +e8866c01e78b7100e8866c00e78b7100e8866c00e78b7100e8866c01e78b7100e8866c00 +e78b7100e8866c03e78b7101ffffff07f4f6f900e8ecef00e0e4e700d9dcde00d8cccb00 +c4c5c500bbbcbd00c6bcba00bbbcbd01c4c5c500bbbcbd00b66c5900a65b4500c7634a00 +f5886c03e8866c00f5886c05e8866c00f5886c00e8866c00f5886c00e78b7100f5886c01 +e78b7100f5886c00ffffff0ee8ecef00e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd01 +b4b4b400bbbcbd00b4b4b400bbbcbd00b4b4b400a65b4500a7543f03d3725300e8866c00 +eb826400e8866c00f5886c00eb826401e8866c00eb826400e8866c01eb826401e8866c00 +eb826400e8866c00eb826403e8866c00cbcccd00c4c5c500bbbcbd00b4b4b402abacad00 +a89a9500a7543f05ba5d4500eb826400ea7c5e00eb826400e8866c00eb826401e8866c00 +eb826400e8866c00eb826408d8cccb00d2d4d600b99a9400a65b4500a84d3500994f3c00 +a84d3500a7543f00a84d3502b7533a00d3725300ea7c5e00eb826401f8836200eb826405 +e8866c00eb826400e8866c08eb826400e8866c00eb826400e8866c00e78b7100f9dcd100 +ffffff07f4f6f900e8ecef00e0e4e700d9dcde00cbcccd00c4c5c500b4b4b400abacad00 +a4a5a404a9746500994f3c00a84d3500994f3c00a84d3506ba654f00ea7c5e01e8745601 +ea7c5e00e8745600d77c6200ea7c5e00d77c6200e8745600d77c6200e8745600d8755c01 +e8745600d8755c04e5c4c200e0e4e700d2d4d600cbcccd00c4c5c500b4b4b401a4a5a400 +9c9e9c01a89a95009c9e9c0198594900994f3c00a6442b01994f3c00a6442b017c3a3c00 +a6442b04ba5d4500dc725400d8755c00e8745600dc725400d8755c00dc725404d8755c00 +dc725400d8755c00d3725300dc725402d8755c00dc725400d8755c00e9d5d700ffffff10 +c8847200ba5d4503ba654f00c9593b00ba5d4500ba654f00c9593b00ba654f00c7634a00 +ba654f00ba5d4500c7634a00ba654f00c7634a00ba654f00c7634a00ba654f00c7634a00 +a7543f00a84d3500994f3c04a6442b00994f3c02a6442b00994f3c00a7543f00e0e4e700 +ffffff17f4f6f901e8ecef00e0e4e700d9dcde00c8aca500c56e5e00c86d5400c56e5e01 +c8745e00c56e5e00c8745e00c56e5e00c8745e03c56e5e00c8745e00c56e5e00c8745e04 +c86d5400a7543f00a65b4500a7543f00a65b4500a7543f00a65b4500a7543f0098594900 +a7543f00a65b4500c8aca500e8ecef01ecf3f500e8ecef01d8bcb600c8745e02d8755c00 +c8745e00d77c6200c97c6700d8755c00d77c6200c8745e00d77c6200d8755c00d77c6200 +c97c6701d77c6200c97c6700d77c6200c8745e00d77c6200c56e5e00a7543f04a65b4500 +a7543f00a65b4500d8ac9f00ffffff1af4f6f900e8ecef01d9dcde00d2d4d601cbcccd00 +d8ac9f00d8755c00d77c6200d8755c00d77c6200d8755c00d77c6200d8755c02d77c6200 +d8755c00d77c6201d8755c00d77c6201d8755c00d77c6202c56e5e00a7543f03994f3c00 +d8ac9f00ffffff0df4f6f900ecf3f500e8ecef00e6dcdc00d9dcde00d2d4d603cbcccd01 +c6bcba00e78b7100d8846e00e8866c00eb826400d8846e00ea7c5e00d8846e00eb826400 +e8866c00d77c6200e8866c00d77c6200eb826400d8846e00ea7c5e00e8866c00d77c6200 +e8866c00d8846e00eb826400d8846e00e8866c00d8846e00e8866c01d8846e00e8866c01 +c8745e00a65b4500b77c6a00ffffff17ecf3f500e8ecef00e6dcdc00d2d4d601cbcccd03 +c4c5c500cbcccd00c4c5c500c7b5b100e78b7100e8866c00e78b7101e8866c00e78b7101 +e8866c00e78b7101e8866c00e78b7100e8866c06eb826400e8866c01d69a9000ffffff01 +f4f6f900e8ecef00e0e4e700d2d4d601cbcccd00c4c5c502a7847c00d3725300e8866c01 +e78b7102e8866c00e78b7100e8866c00e78b710bf9ad9400ffffff07f4f6f900e8ecef00 +e0e4e700d2d4d601c4c5c500bbbcbd00c4c5c500bbbcbd00c4c5c500bbbcbd00c4c5c500 +a77c7000a7543f00ba5d4500e78b7100e8866c01e78b7100f5886c00e78b7102e8866c00 +e78b7100e8866c00e78b7102f5886c00e8866c00e78b7102f5886c00f4f6f900ffffff0c +f4f6f900ecf3f500e0e4e700d9dcde00d2d4d600c4c5c500c6bcba00bbbcbd01b4b4b400 +bbbcbd00b4b4b400b99a9400a65b4500994f3c00a65b4500a7543f01d77c6200e8866c12 +e9947d00d2d4d600cbcccd00bbbcbd00b4b4b403a894900098594900a7543f0098594900 +a7543f02ba654f00e8866c0ad77c6200e8866c04e78b7100c6bcba00a96d5f00a7543f00 +994f3c00a7543f02994f3c00a7543f01ba654f00ea7c5e00e8866c00eb826400e8866c00 +eb826400e8866c00eb826400f5886c00e8866c11f7b9a600ffffff09ecf3f500e8ecef00 +e0e4e700d2d4d600cbcccd00c4c5c500bbbcbd00b4b4b400a4a5a404a77c7000994f3c00 +a84d3500994f3c00a84d3500994f3c01a84d3500994f3c02ba5d4500d77c6201eb826400 +d77c6201d8755c00ea7c5e00d8755c0cd7c4bd00d9dcde01cbcccd00c4c5c500b4b4b401 +a4a5a4009c9e9c0498594900a6442b008a514200a6442b008a514200a6442b00994f3c00 +a6442b00994f3c00a6442b007c3a3c00994f3c01ba5d4500d8755c00e8745600d8755c0c +c56e5e00d8755c01c8745e00d8755c00f9dcd100ffffff0fecf3f500b77c6a00ba5d4504 +ba654f01c7634a00ba654f02c7634a00ba654f00c86d5400ba654f02c7634a00ba654f01 +a7543f00994f3c01a6442b00994f3c0898594900f4f6f900ffffff18f4f6f900e8ecef01 +e6dcdc00d7c4bd00c56e5e00c8745e0bc97c6700c8745e02c97c6700c8745e00c97c6700 +b66c590098594902994f3c0098594901994f3c0098594902c8aca500e8ecef04d8b4ac00 +c8745e01d8755c00c97c6700c8745e00d77c6200c8745e00d77c6200c97c6700d77c6200 +c97c6701d77c6200c8745e00d77c6200c97c6700d77c6200c97c6700d77c6200c97c6700 +b66c5900a7543f00a65b4502a7543f00a65b4501a7543f00d7c4bd00ffffff1af4f6f900 +ecf3f500e0e4e700e6dcdc00d2d4d601cbcccd00d8b4ac00d77c6202d8755c00d77c6200 +d8755c00d77c6202d8755c00d77c6203d8755c00d77c6204c8745e00994f3c00a7543f00 +98594900a7543f0098594900c7998d00ffffff0ef4f6f900ecf3f500e8ecef00d9dcde01 +d2d4d601cbcccd01d8cccb00cbcccd00d8b4ac00d8846e00e8866c00d8846e00e8866c00 +d8846e00e8866c00d8846e01eb826400d8846e02ea7c5e00d8846e02d77c6200e8866c00 +d77c6200d8846e01e8866c00d77c6200d8846e00e8866c00d8846e00d77c6200a65b4500 +a8655400f7ece700ffffff17f4f6f900ecf3f500e0e4e700d9dcde00d2d4d601c4c5c502 +cbcccd00c4c5c502e9947d00d98c7800d8846e00e78b7100d98c7800e78b7104d98c7800 +e78b7100d98c7800e8866c00d98c7800e8866c06d77c6200e9d5d700ecf3f500e8ecef00 +e0e4e700d9dcde00d2d4d600cbcccd01c4c5c501c6bcba00ba654f00da846200e8866c03 +e78b7105e9947d00e78b7104e9947d01e78b7100e9947d00ffffff08f4f6f900e8ecef00 +e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd00c4c5c500bbbcbd00c4c5c500bbbcbd01 +b78d850098594900a65b4500e8866c00e78b7101e8866c00e78b7100e8866c01e78b7100 +e8866c00e78b7100e8866c02e78b7106f8cbc000ffffff0decf3f500e8ecef00d9dcde00 +d2d4d600c4c5c500bbbcbd01b4b4b400bbbcbd00b4b4b400bbbcbd00a7847c0098594900 +a65b450098594900a7543f00a65b4500d98c7800e78b7100e8866c00d8846e00e8866c00 +d8846e00e8866c00d8846e00e8866c00d8846e01e78b7100d8846e00e78b7100d8846e00 +e78b7100d8846e00e8866c00d8846e00e8866c00d69a9000cbcccd00c4c5c500bbbcbd00 +b4b4b403a88c8600a7543f0098594900a7543f0098594901a7543f00b66c5900e78b7100 +d98c7800e8866c00e78b7100d98c7800e8866c00d8846e00e8866c00d8846e01e8866c00 +d8846e00e8866c00d8846e03d77c6200a8655400994f3c01a7543f00994f3c02a7543f01 +c8745e00e8866c0ae78b7109d8846e00e78b7100d8846e01e9947d00f9e4e100f4f6f900 +ffffff09ecf3f500e8ecef00e0e4e700d9dcde00cbcccd00c4c5c500b4b4b400abacad00 +a4a5a40497746b00994f3c07a7543f00994f3c00ba654f00ea7c5e00d8846e00d77c6201 +ea7c5e00d77c6200d8755c00d77c6200ea7c5e00d77c6200d8755c00d77c6200ea7c5e00 +d77c6200d8755c00d77c6200ea7c5e00d8755c00d77c6200d8755c00e5c4c200e0e4e700 +d9dcde00cbcccd00c4c5c500bbbcbd00abacad019c9e9c0496635500994f3c00a6442b00 +8a514200a6442b008a514200a6442b00994f3c02a6442b01994f3c00b7533a00d77c6202 +ea7c5e00d77c6203d8755c00d77c6200d8755c00c97c6700d8755c01c8745e00d8755c01 +c8745e00d8755c00c8745e00e9d5d700ffffff0ef4f6f901b66c5900ba654f0ab66c5900 +ba654f05b66c5900ba654f00994f3c0ca77c7000f4f6f900ffffff18f4f6f900ecf3f500 +e0e4e701d2d4d600c8745e00b7746200b66c5900b7746207c47b7d00b7746200c8745e00 +b7746200c47b7d00c8745e00b77c6a00c8745e00b77c6a00b66c590098594909c8a49d00 +e8ecef03e0e4e700d8ac9f00c8745e00c97c6700c8745e00c97c6701c8745e00c97c6701 +c8745e00c97c6700d8755c00c97c6704c8745e00c97c6700c8745e00d77c6200ba654f00 +98594900a7543f0098594900a7543f0098594903e6ccc900ffffff1bf7ece700e8ecef00 +d9dcde01d2d4d600d8cccb00c4c5c500d77c6201c97c6700d77c620bc97c6700d8755c00 +c97c6700d77c6200c97c6700c8745e00a65b450098594900a7543f0098594901c8938400 +ffffff0ff7ece700e8ecef00e0e4e700e6dcdc00d9dcde00d2d4d600d8cccb00d2d4d600 +cbcccd02d8ac9f00d8846e06d77c6200d8846e00d77c6200d8846e02d77c6200d8846e05 +d98c7800d8846e03a8655400a65b4500d7c4bd00ffffff18f4f6f900ecf3f500e8ecef00 +d9dcde00d2d4d601cbcccd00d8cccb00c4c5c500cbcccd00c4c5c500cbcccd00c4c5c500 +d8b4ac00d8846e00d98c7801d8846e00d98c7801d8846e00d98c7800d8846e00d98c7800 +d8846e00d98c7800d8846e00e78b7100d8846e00d98c7800d8846e00d98c7800d8846e02 +e8866c00c7998d00e8ecef01e0e4e700d9dcde00d2d4d600cbcccd00c4c5c502b8938b00 +b66c5900e8866c00e78b7100d98c7800e78b7100d98c7800e78b7100d8846e00d98c7800 +e78b7100d98c7808d8846e00d98c7800e8a58f00ffffff08f4f6f900e8ecef00e0e4e700 +d2d4d601c4c5c500bbbcbd00c4c5c500bbbcbd00c6bcba00bbbcbd00c4c5c500b7a4a000 +98594900a65b4500c97c6700e8866c00d98c7800e78b7100d98c7800e78b7100d98c7800 +e8866c00d98c7800d8846e00d98c7800e78b7100d8846e00d98c7800e8866c00d98c7800 +e78b7100e8866c00e78b7101e59c8700ffffff0cf4f6f900ecf3f500e0e4e700d9dcde00 +d2d4d600cbcccd00bbbcbd02b4b4b400bbbcbd00b4b4b400a8655400a65b450098594900 +a65b450098594900b7746200d98c7800e78b7100d98c7801e8866c00d98c7800e78b7100 +d8846e00d98c7800e8866c00d98c7800e78b7100d8846e00d98c7800e78b7100d98c7800 +e78b7100d98c7802d8b4ac00cbcccd00c4c5c500b4b4b404a88c860098594902a7543f00 +98594901c8745e00e78b7100d98c7802d8846e00d98c7802d8846e00d98c7800d8846e04 +e8866c00d8846e0198594900994f3c0098594900994f3c0098594900a7543f0098594900 +ba654f00d8846e00da846200e78b7100d8846e00e78b7100d8846e00e8866c00e78b7100 +d8846e00e8866c00d98c7800e78b7100d98c7800e78b7101d98c7800e78b7100d98c7800 +e78b7100d98c7800e78b7100d98c7802e8866c00d98c7800f7b9a600ffffff0cecf3f500 +e8ecef00e0e4e700d2d4d600cbcccd00c4c5c500bbbcbd00b4b4b400a4a5a40497746b00 +994f3c0098594900994f3c07ba654f00d8846e03d77c6200d8846e00d77c6203eb826400 +d77c6203d8846e00d77c6203d8cccb00e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00 +b4b4b400a4a5a4019c9e9c02a89a950098594900994f3c008a514200a6442b008a514200 +a6442b00994f3c008a514200a6442b00994f3c03ba5d4500d8755c00d77c6200d8755c00 +d77c6205d8846e00d77c6200d8755c00c97c6700d77c6200d8755c00c97c6700d8755c00 +c97c6700d77c6200c8745e00f9dcd100ffffff0ef4f6f900e8ecef00ba654f07b66c5900 +ba654f00b66c5900ba654f00b66c5908994f3c028a514200994f3c028a51420098594900 +8a514200985949008a51420098594900a77c7000ffffff1aecf3f500e8ecef00e0e4e700 +d9dcde00b77c6a00b7746201c8745e00b7746202c8745e00b7746203c97c6700b7746200 +b77c6a00b7746200b77c6a00b7746200b77c6a00c8745e00a96d5f0098594900994f3c00 +985949028a514200985949008a514202b8adaa00e8ecef01e0e4e700e8ecef00e0e4e700 +dba39300b77c6a00c8745e00c97c6703c47b7d00c97c6702c47b7d00c97c6703d77c6200 +c97c6703a8655400a7543f0098594903a7543f0098594901e6ccc900ffffff1becf3f500 +e8ecef00e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500d77c6202c97c6700d77c6200 +c97c6700d77c6201d8846e00d77c6200d8846e00d77c6200c47b7d00d8846e00c47b7d00 +d8846e01c47b7d00d8846e01c97c670098594902a65b450098594900b8938b00ffffff10 +ecf3f500e8ecef00e0e4e700d9dcde01d2d4d601cbcccd03d69a9000d8846e05c47b7d00 +d8846e01c8847200d8846e00c47b7d00d8846e02c8847200d8846e01d98c7800d8846e00 +d98c7802b66c59009859490096635500f4f6f900ffffff19f4f6f900e8ecef00e0e4e700 +d9dcde00d2d4d600d8cccb00cbcccd01c4c5c501cbcccd00c4c5c501d6938100d98c7803 +d8846e00d98c7802d8846e00d98c7800d8846e00d98c7800d8846e00d98c7801e8866c00 +d98c7801e8866c00d98c7800d8846e00c97c6700d2d4d600e0e4e700d9dcde00d2d4d600 +d8cccb00c4c5c500cbcccd00c4c5c500c6bcba00a96d5f00d8846e00d98c7800e78b7100 +d98c7800e78b7100d98c7800e9947d00d98c7803d8846e00e78b7100d98c7807f7ece700 +ffffff08f4f6f900e8ecef00e0e4e700d9dcde00cbcccd00c4c5c501bbbcbd00c4c5c500 +bbbcbd01c4c5c500b4b4b400a65b450098594900b7746200d98c7800e78b7100d98c7801 +d8846e00d98c7800d8846e00d98c7801d8846e00d98c7803d8846e00d98c7802e78b7101 +ffffff0decf3f500e8ecef00d9dcde00d2d4d600c4c5c500bbbcbd01b4b4b400bbbcbd00 +b4b4b400a894900098594902a65b450098594900d8846e00d98c7800e78b7100d98c7800 +e78b7100d98c7801e78b7100d98c7804e78b7100d98c7802e78b7100d98c7800e78b7100 +d98c7800d8bcb600c4c5c500bbbcbd01b4b4b402abacad00a88c860098594905b7746200 +d98c7801d8846e00d98c7801d8846e01d98c7800d8846e00d98c7801d8846e00d98c7801 +d8846e0398594903994f3c0098594900c8745e00d98c7800d8846e00d98c7800d8846e00 +e78b7100d98c7801e78b7100d8846e00d98c7800e78b7100d8846e00d98c7800e78b7100 +d98c7808d8846e00d98c7800e59c8700f9e4e100ffffff0df4f6f900e8ecef00e0e4e700 +d9dcde00cbcccd00c4c5c500bbbcbd00abacad00a4a5a404987c75008a514200994f3c00 +8a514200994f3c0098594900994f3c04a8655400d77c6201d8846e00d77c6200d8846e00 +d77c6201d8846e00d77c6202d8846e03d77c6200d8846e00c47b7d00d8846e00d77c6200 +d8cccb00e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400abacad009c9e9c04 +96635500994f3c028a514200994f3c028a514200994f3c018a514200994f3c00a65b4500 +d77c6202d8846e00d8755c00c47b7d00d77c6200c97c6700d77c6200c97c6701d8846e00 +c47b7d00d77c6200c97c6700d77c6200c47b7d00d77c6200c97c6701e6dcdc00ffffff0f +e0e4e700a8655400ba654f00a8655400ba654f00a8655400b66c590aba654f00b7746200 +b66c5902985949008a514200994f3c00985949008a514200985949008a51420098594900 +994f3c008a51420098594900994f3c01a7847c00f4f6f900ffffff18f4f6f901e8ecef00 +e0e4e700d9dcde00b9857800b66c5900b7746200b66c5900b7746208b77c6a00b7746202 +b77c6a00b7746200b77c6a00a96d5f008a514200985949008a514202885a4e008a514200 +885a4e0098594900885a4e00c8a49d00e0e4e700e8ecef00e6dcdc00e8ecef00e0e4e700 +c8a49d00c97c6700c8745e00c97c6700b77c6a00c97c6700b77c6a00c97c6702c8847200 +c97c6700c8847200d77c6200c8847201c47b7d00c97c6700c47b7d00c97c6701a8655400 +98594901a65b450098594904d7c4bd00ffffff1bf4f6f900e8ecef00e0e4e700d9dcde00 +d2d4d600cbcccd00d7c4bd00c97c6701d77c6200c47b7d00d77c6200c47b7d00d77c6200 +c47b7d00c97c6701c47b7d00d77c6200c8847200d8846e01c97c6700d8846e00c8847200 +d77c6200c884720198594900a65b4500985949009663550098594900c7998d00ffffff10 +f4f6f900e8ecef01d9dcde01d2d4d601cbcccd00d8cccb00cbcccd00d2d4d600c6bcba00 +c8847200d8846e00c8847201c47b7d00c8847200d8846e00c8847200d8846e00c47b7d00 +d8846e00c8847200d8846e00c8847201d8846e00c8847200d98c7800c8847200d98c7800 +c88b7d00d8846e00c47b7d00a86554009663550098594900b9857800ffffff19f4f6f900 +ecf3f500e8ecef00e6dcdc00d2d4d600cbcccd02c4c5c500d8cccb00c4c5c501cbcccd00 +c8aca500d98c7802c88b7d00d98c7800c88b7d00d98c7800c88b7d00d98c7800c88b7d00 +d98c780bc8a49d00e6dcdc00d9dcde00d2d4d600cbcccd00c4c5c502b99a9400b66c5900 +d98c7800e78b7100d98c7801e78b7100d98c7803d8846e00d98c7804d8846e00d98c7803 +e8a58f00ffffff09f4f6f900e8ecef00e0e4e700d2d4d601c4c5c500bbbcbd00c4c5c500 +bbbcbd00c4c5c500bbbcbd00c6bcba00bbbcbd00a77c700098594900b66c5900d98c7809 +d8846e00d98c7800d8846e00d98c7803d8846e00d6938100d98c7800e8b3a800ffffff0b +f4f6f900ecf3f500e0e4e700d9dcde00d2d4d600c4c5c501bbbcbd00b4b4b400bbbcbd00 +b4b4b400a9746500985949009663550098594901a8655400d98c7800d6938100d98c7801 +d6938100d98c7803e78b7100d98c7800e78b7100d98c7802e78b7100d98c7804cbcccd01 +bbbcbd00b4b4b404a7847c0098594905b77c6a00d98c7802c88b7d00d8846e00c88b7d00 +d8846e00c88b7d00c8847200d98c7800c8847200d98c7800c88b7d00d8846e00c88b7d00 +d98c7800c88b7d00d8846e00966355008a51420098594900994f3c00a96d5f00c8847200 +d98c7805d8846e00d98c7808e9947d00d6938100d98c7800e9947d00d98c7803d6938100 +fac4ac00ffffff0fecf3f500e8ecef00e0e4e700d9dcde00cbcccd00c4c5c500b4b4b401 +a4a5a40497746b008a514209a8655400c8847200d8846e00c47b7d00d77c6200c47b7d00 +d8846e00d77c6200c47b7d00d8846e00c8847200d77c6200c47b7d00d77c6201c47b7d00 +d8846e00c8847200d8846e00c8847200d8846e00d8cccb00e8ecef00d9dcde00d2d4d600 +cbcccd00bbbcbd00b4b4b400a4a5a4019c9e9c00a89a95009c9e9c01966355008a514200 +994f3c008a514200994f3c018a514200994f3c018a514200994f3c02a8655400d8846e00 +d77c6200c47b7d00d77c6200c47b7d00d77c6201c47b7d00d77c6200c47b7d00d77c6200 +c97c6700d8846e00c47b7d00d8846e00c97c6700c8847200c97c6702f9dcd100ffffff0e +f4f6f900e0e4e700b66c5900a96d5f00b66c5900a8655400b7746200a8655400b66c5900 +a96d5f02b66c5900a9746500a96d5f00b66c5900a96d5f00b66c5900b7746200b66c5900 +b7746200b66c5900a96d5f00985949018a514200985949008a514200985949008a514200 +985949008a514200985949008a51420198594900986d6200ffffff1af4f6f900ecf3f500 +e8ecef00e6dcdc00b9857800b66c5900b7746200a9746500b7746200a96d5f00b7746200 +a9746500b7746200a9746500b7746200a77c7000b7746200a77c7000b7746200b77c6a01 +b7746200b77c6a00b7746200a96d5f00885a4e0198594901885a4e0098594900885a4e00 +98594900885a4e0098594900b7a4a000e0e4e704c8a49d00c97c6700b77c6a00b7746200 +c97c6702b77c6a00c47b7d00c8847200c97c6700c8847200c47b7d00c8847201c97c6700 +c8847203c97c6700a96d5f00985949049663550098594901c8aca500ffffff1bf4f6f900 +ecf3f500e0e4e700e6dcdc00d2d4d601c6bcba00c97c6700c8847202c97c6700c8847201 +c97c6700c8847201d8846e00c8847205d8846e00c8847202985949009663550198594900 +96635500c8aca500ffffff11f4f6f900e8ecef00e0e4e700d9dcde00d2d4d601cbcccd03 +c7998d00c8847200c47b7d00c8847203c97c6700c8847200c97c6700c8847204c88b7d00 +c8847200c88b7d01c8847200c88b7d00d8846e00c88b7d00c8847200c97c670098594901 +96635500c8a49d00ffffff19f4f6f900e8ecef00d9dcde01d2d4d600cbcccd01c4c5c500 +cbcccd00c4c5c500cbcccd00c4c5c501d6938100c88b7d03d98c7800c88b7d01d98c7800 +c88b7d00d98c7800c88b7d01d98c7800c88b7d00d98c7800c88b7d00d98c7800c88b7d01 +d98c7800c88b7d00b77c6a00d8cccb00d2d4d600cbcccd01c4c5c502986d6200c8847200 +d98c780cc88b7d00d98c7800c88b7d00d98c7800c88b7d00d98c7800c88b7d00f9e4e100 +ffffff09f4f6f900ecf3f500e0e4e700d9dcde00d2d4d600c4c5c501bbbcbd00c6bcba00 +bbbcbd00c4c5c500bbbcbd01a89490009859490096635500d98c7800d6938100d98c7804 +c88b7d00d8846e00d98c7800c88b7d01d98c7800c8847200d98c7800c88b7d00d8846e00 +c88b7d00d98c7802ffffff0bf4f6f900ecf3f500e0e4e700d9dcde00cbcccd00c4c5c500 +bbbcbd02b4b4b400a89490009859490396635500c97c6700d6938100d98c7800d6938104 +d98c7800d6938100d98c7800d6938100d98c7800d6938100e9947d00d98c7805d69a9000 +d2d4d600c4c5c500bbbcbd00b4b4b404999393008a514202885a4e00985949008a514200 +b7746200d6938100c88b7d00d98c7800c8847201d98c7800c8847201d8846e00c88b7d00 +c8847200c88b7d00d8846e00c88b7d01c8847200d98c7800c88b7d00a8655400885a4e00 +98594900b77c6a00c8847200d98c7800c88b7d00d98c7800c88b7d00d98c7802d6938100 +d98c7800d6938101d98c7800d6938101d98c7800d6938106d98c7801dba39300f4f6f900 +ffffff10f4f6f900e8ecef00e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd00abacad01 +a4a5a40397746b008a514209a65b4500c8847200c47b7d00c8847202c97c6700c8847201 +c97c6700c47b7d00c8847202c97c6700c8847200c97c6700c8847203e6ccc900e0e4e700 +d9dcde00d2d4d600c4c5c500bbbcbd01abacad009c9e9c0496635500994f3c008a514200 +994f3c008a514201994f3c008a514201994f3c008a514201994f3c00a8655400c8847200 +d8846e00c8847200d77c6200c8847200d8846e00c8847209c97c6700c8847200c47b7d00 +c97c6700e6dcdc00ffffff0ef4f6f900e8ecef00b7746200a96d5f01a9746500a96d5f00 +b7746200a9746500a96d5f00b7746200a96d5f00a9746500b66c5900a96d5f00b66c5900 +a9746500b66c5900a96d5f00b7746200a96d5f00b7746200b66c59008a51420098594900 +8a514200985949008a514200985949008a51420398594900885a4e008a51420098594900 +e8ecef00ffffff19f4f6f900ecf3f500e0e4e700d9dcde00b77c6a00a9746500a96d5f00 +b7746201a9746500b7746201a9746500b7746201a9746501b7746200a9746500a77c7000 +b7746200a77c7000b77c6a01a96d5f00885a4e0098594900885a4e0398594900885a4e02 +c8aca500e0e4e701e8ecef00e0e4e701d8ac9f00b77c6a00b7746200c97c6700b77c6a01 +c97c6700b9857800c97c6700b9857800c8847206c97c6700c8847200b77c6a00c8847200 +a974650096635500985949008a6358009859490096635500985949008a63580098594900 +b78d8500ffffff1bf4f6f900e8ecef01d9dcde00d2d4d600d8cccb00c6bcba00c97c6700 +c8847200c47b7d00c97c6700c8847200c97c6700c8847208c88b7d03c8847200b9857800 +98594900966355009859490096635501d7c4bd00ffffff11f4f6f900e8ecef00e0e4e700 +e6dcdc00d2d4d602d8cccb00cbcccd00c8a49d00c8847200c47b7d00c8847201c47b7d00 +c97c6701c47b7d00c8847200c47b7d00c8847200c97c6700c8847200d8846e00c88b7d00 +c8847200d8846e00c88b7d00c8847200d98c7800c88b7d02d98c7800c88b7d00b7746200 +9663550098594901e6ccc900ffffff18f4f6f900ecf3f500e8ecef00d9dcde00d2d4d600 +cbcccd00d8cccb00cbcccd00c4c5c500cbcccd00c4c5c501cbcccd00c8a49d00c88b7d03 +c8847200c88b7d01c8847200c88b7d01c8847200d98c7800c8847200c88b7d00c8847200 +c88b7d01d8846e00c88b7d00c8847200d98c7800c8847200b7a4a000d2d4d600cbcccd01 +c4c5c501b7a4a000a8655400d98c7800d8846e02d98c7801c8847200d98c7800c8847200 +d98c7800c8847200d98c7800c88b7d00c8847200d8846e00c88b7d00c8847202c88b7d00 +d6938100ffffff0af4f6f900ecf3f500e0e4e700d9dcde00d2d4d600c4c5c502bbbcbd01 +c4c5c500bbbcbd00c4c5c500b8adaa008a63580098594900c8847200c88b7d00d6938100 +c88b7d00d6938100c88b7d00d98c7800c88b7d00d6938100c88b7d01d8846e00c88b7d01 +c8847200c88b7d01c8847200c88b7d00c8847200c88b7d00e8bcb000ffffff0aecf3f500 +e8ecef00e0e4e700d2d4d601c4c5c500bbbcbd00b4b4b400bbbcbd00b8adaa00986d6200 +885a4e0098594900885a4e0098594900a8655400c8938400d98c7800d69a9000d6938104 +d69a9000d6938104d98c7800d6938102d98c7801d6938100d8b4ac00cbcccd01bbbcbd00 +b4b4b401abacad00b4b4b401a89a9500885a4e0098594900885a4e008a51420098594900 +885a4e00b7746200c88b7d00d98c7800c8847200d98c7800c88b7d00c8847202c88b7d00 +c8847200d98c7800c88b7d01c8847200d98c7800c88b7d02a96d5f00a8655400c8847200 +c88b7d00d98c7800c88b7d00d98c7800c88b7d00d98c7800c88b7d00d6938100c88b7d01 +d6938100c88b7d00d98c7800d6938100d98c7800d6938108d69a9000f8d4c900ffffff12 +ecf3f500e8ecef00e0e4e700d9dcde00cbcccd00c4c5c500b4b4b401a4a5a4019c9e9c00 +a4a5a401987c75008a51420996635500c8847203c47b7d00c8847201c97c6700c8847201 +c97c6700c8847200c47b7d00c8847206d8cccb00e8ecef00d9dcde00d2d4d600cbcccd00 +bbbcbd00b4b4b400abacad00a4a5a4009c9e9c00a89a95009c9e9c018a635800885a4e00 +8a514204985949008a514201994f3c008a514200994f3c00a8655400c8847201d8846e00 +c8847205d8846e00c8847203c97c6700c8847204e6dcdc00ffffff0eecf3f501b9857800 +a96d5f00a9746500a96d5f00a9746500a96d5f01a9746500a96d5f00a9746500a96d5f00 +a9746502a96d5f00b7746200a9746500b66c5900a9746500b66c5900a974650098594900 +8a514200885a4e008a514200885a4e008a514200885a4e01985949008a514200885a4e00 +8a514200885a4e01d8cccb00ffffff19f4f6f900ecf3f500e8ecef00d8cccb00a9746500 +b7746200a9746500b7746200a9746501b7746200a77c7000b7746200a77c7000a9746504 +b7746200a77c7000b77c6a00a9746500b77c6a00a9746500885a4e0098594900885a4e00 +98594900885a4e0098594900885a4e0198594900885a4e00b8adaa00e0e4e704c7b5b100 +b7746200c97c6700b77c6a01c47b7d00b77c6a00c97c6700b9857800c97c6700b9857800 +c8847200b9857800c8847200b9857800c8847200b9857801c8847200b9857800b77c6a01 +985949008a635800985949008a635800885a4e0096635500885a4e0096635500986d6200 +ffffff1bf4f6f900ecf3f500e8ecef00d9dcde00d2d4d601c8a49d00c8847202b9857800 +c8847204c88b7d00b98a7c00c88b7d04c8847200c88b7d02b77c6a0096635504e6dcdc00 +ffffff11f4f6f901e8ecef00d9dcde01d2d4d600cbcccd01c7b5b100c8847200b77c6a00 +c8847200b77c6a01c8847200b9857800b77c6a00c8847200b9857800c8847200c97c6700 +c8847204c88b7d00c8847200c88b7d00c8847200c88b7d00c8847200c88b7d00c8847200 +c88b7d00c8847200a86554009859490196635500ffffff19ecf3f500e8ecef00e6dcdc00 +d9dcde00d2d4d600cbcccd01c4c5c501d8cccb00c4c5c501c6bcba00c88b7d00c8847200 +c88b7d00c8847200c88b7d00c8847200c88b7d02c8847200c88b7d00c8847201c88b7d01 +c8847200c88b7d00c8847204b77c6a00cbcccd01c4c5c50297746b00b7746200c8847201 +c88b7d00c8847202d8846e00c8847200c88b7d00c8847200c88b7d00c8847200c88b7d02 +c8847200c88b7d01c8847200c88b7d00f8d4c900ffffff0becf3f500e8ecef00d9dcde00 +d2d4d600cbcccd00c4c5c500bbbcbd00c4c5c500bbbcbd00c4c5c500bbbcbd00c6bcba00 +bbbcbd00986d620098594900a9746500d98c7800c88b7d00d6938100c88b7d00d6938100 +c88b7d01c8847200c88b7d03c8847200c88b7d00c8847200c88b7d01c8847200c88b7d01 +c8847200f4f6f900ffffff09ecf3f500e0e4e700d9dcde00d2d4d600c4c5c501bbbcbd01 +b4b4b400987c7500885a4e00966355008a635800885a4e0096635500b9857800d6938100 +c8938400d6938100c8938400d69a9000d6938100d69a9000d6938102d69a9000d6938102 +c8938400d6938101c8938400d6938100c8938400d98c7800d8cccb00d2d4d600c4c5c500 +bbbcbd00b4b4b404a4a5a400885a4e038a514200885a4e00a96d5f00c88b7d03c8847200 +c88b7d01c8847202c88b7d00c8847200c88b7d05c8847200c88b7d02c8938400c88b7d00 +d6938100c88b7d00d6938100c88b7d00d98c7800c88b7d00d6938101c88b7d00d6938100 +c8938400d6938105d69a9000d6938101e8b3a800ffffff14f4f6f900e8ecef00e0e4e700 +d9dcde00cbcccd00c4c5c500bbbcbd00abacad01a4a5a403987c750076524a00885a4e00 +76524a008a51420076524a008a51420076524a008a51420296635500c8847200b9857800 +c8847202b9857800c8847201b9857800c8847200b9857800c8847200b9857800c47b7d00 +b9857800c8847200c47b7d00c8847201b9857800d8cccb00e0e4e700d9dcde00d2d4d600 +cbcccd00bbbcbd01a4a5a4019c9e9c0396635500885a4e008a514200885a4e018a514200 +885a4e008a514205a96d5f00c8847213e6dcdc00ffffff0ef4f6f900e8ecef00b8938b00 +a96d5f00a9746500a96d5f00a9746501a96d5f00a9746500a96d5f00a9746500a96d5f02 +a9746501a96d5f00a974650496635500885a4e018a514200885a4e018a514200885a4e00 +8a514200885a4e04c8aca500ffffff1af7ece700e8ecef00c4c5c500b7746200a9746503 +b7746200a77c7000a9746500a77c7000b7746200a77c7000b7746200a77c7000b77c6a00 +a77c7001b7746200a77c7000b77c6a01a974650098594900885a4e008a63580098594900 +885a4e008a635801985949008a635800885a4e00c8aca500e0e4e704d7c4bd00b77c6a04 +c8847200b9857800c8847200b9857800c8847200b9857800c8847200b9857802c8847200 +b985780496635501885a4e00966355048a635800f9e4e100ffffff1be8ecef01e6dcdc00 +d2d4d601c7998d00b9857803c88b7d00b98a7c02c88b7d00b78d8500c88b7d00b98a7c00 +c88b7d00b98a7c00c88b7d01b78d8500c88b7d00b78d8500c88b7d00a97465008a635800 +966355008a635800966355008a635800ffffff12f4f6f901e0e4e701d2d4d601d8cccb00 +c6bcba00b9857801b77c6a00b9857800b77c6a05c8847200b77c6a00b9857801c47b7d00 +b9857800c8847202c88b7d04d6938100c88b7d00d98c7800c88b7d00c884720096635501 +98594900a77c7000ffffff18f4f6f900ecf3f500e8ecef00d9dcde00d2d4d600cbcccd02 +c4c5c500cbcccd00c4c5c500cbcccd00c4c5c500c7998d00b9857802c88b7d00b9857801 +c8847200b9857800c88b7d00c8847200b9857800c8847202c88b7d00c8847200b9857800 +c88b7d00c8847200c88b7d01b77c6a00b7a4a000c4c5c502b8adaa0098594900c8847204 +c88b7d00c8847200c88b7d00c8847202c88b7d01c8847200c88b7d00c8847200c88b7d01 +c8847200c88b7d00c8938400ffffff0cf4f6f900e8ecef00e0e4e700d2d4d600cbcccd00 +c4c5c501bbbcbd00c6bcba00bbbcbd00c4c5c500bbbcbd01a894900096635501c8938400 +c88b7d01d6938100c88b7d08b9857800c8847200b9857801c88b7d00b9857800b98a7c00 +c88b7d00d69a9000ffffff08ecf3f500e8ecef00e0e4e700d9dcde00d2d4d600c4c5c501 +bbbcbd00b4b4b400987c7500966355008a635800885a4e0096635500885a4e00a77c7000 +d6938100c8938401d69a9000c7998d00d6938100c7998d01d69a9000c7998d00d69a9000 +c7998d00d69a9000c7998d00d69a9001c8938400d69a9000d6938100c8938400d6938100 +c8a49d00d9dcde00cbcccd00c4c5c500bbbcbd00b4b4b402abacad00b4b4b400b8adaa00 +8a63580098594900885a4e0198594900885a4e00a96d5f00c88b7d00c8938400c88b7d02 +c8847200c88b7d07b98a7c00c88b7d04c8938401d6938100c8938403d6938100c7998d00 +d6938100c7998d00d6938100c8938400d6938100c8938400d6938100c8938400d6938100 +c7998d00d6938100d69a9000d6938100d69a9000f8d4c900ffffff15ecf3f500e8ecef00 +e0e4e700d9dcde00cbcccd00c4c5c500b4b4b401a4a5a404987c7500795b54008a514200 +885a4e008a514200885a4e008a514200885a4e0176524a00885a4e00986d6200b98a7c00 +c88b7d00c8847200b98a7c00b9857800c88b7d00b9857801c8847200b9857801b77c6a00 +b9857801b77c6a00b9857802c47b7d00b9857800d8cccb00e8ecef00e0e4e700d2d4d600 +cbcccd00bbbcbd00b4b4b400abacad00a4a5a4009c9e9c038a635800885a4e038a514200 +885a4e008a514200885a4e038a514200986d6200c8847200c88b7d01c8847200c88b7d00 +c8847203b9857800c8847200b9857800c8847201b9857800c8847200b9857800c8847200 +b9857800c8847200e6dcdc00ffffff0eecf3f501b7a4a000a96d5f00986d6200a9746500 +986d6200a96d5f00a9746500a96d5f02a9746500a96d5f01a9746502a96d5f00a9746503 +966355008a514200885a4e028a514200885a4e07a88c8600ffffff19f4f6f900ecf3f500 +e8ecef00c8a49d00a9746501b77c6a00a77c7000a9746500a77c7000a9746500a77c7004 +a9746500a77c7000b7746200a77c7001b77c6a00a77c7000b77c6a0097746b00885a4e00 +8a635800885a4e008a635800885a4e028a635800885a4e008a635800b8adaa00f9e4e100 +e0e4e703d8cccb00b9857800b77c6a00b9857802b77c6a00b985780bc8847200b9857801 +966355018a635800966355008a635804c6bcba00ffffff1af4f6f900ecf3f500e0e4e700 +d9dcde00d2d4d600cbcccd00b98a7c00c8847200b9857801c8847200b98a7c01c88b7d00 +b98a7c01c88b7d00b78d8500c88b7d00b78d8501c88b7d00b8938b00c88b7d00b78d8500 +c88b7d00b78d8500a97465008a635803a77c7000ffffff13e8ecef01e6dcdc00d2d4d601 +c4c5c500c88b7d00b9857800b77c6a01b9857800b77c6a00b9857800b77c6a01b9857800 +b77c6a00b9857800c8847200b77c6a00c8847200b9857800c8847200c88b7d00b9857800 +c8847200c88b7d02d98c7800c88b7d05c8847200885a4e0096635500885a4e00b8938b00 +ffffff18ecf3f500e0e4e700d9dcde01d2d4d600cbcccd01c4c5c503cbcccd00c7b5b100 +b9857803b98a7c00c88b7d00b9857803c88b7d00b9857801c88b7d00b9857800c8847200 +c88b7d00b9857801c8847202a7847c00c4c5c502a7847c00a96d5f00b9857800c8847200 +b9857800c8847202c88b7d00c8847200c88b7d03c8847200c88b7d00b98a7c00c88b7d00 +b78d8500c88b7d00b9857800c88b7d00e6ccc900ffffff0cecf3f500e8ecef00e0e4e700 +d9dcde00cbcccd00c4c5c501bbbcbd01c4c5c500bbbcbd00c4c5c500bbbcbd00b4b4b400 +96635501c8847200c7998d00c8938401c88b7d00c8938400c88b7d02b78d8500c88b7d00 +b9857800b98a7c03c88b7d00b9857800b98a7c00c88b7d00b78d8500b98a7c00c8a49d00 +ffffff06f4f6f900ecf3f500e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd00 +a4a5a400986d62008a635804a77c7000c7998d00d79c7e00c7998d05d69a9000c7998d00 +c8938400c7998d00d69a9000c8938400d69a9000c8938400c7998d00d6938100c7998d00 +d69a9000c8938400d69a9000d8bcb600d2d4d601c4c5c500bbbcbd00b4b4b40597746b00 +885a4e0496635500c8938400c88b7d00c8938400c88b7d01c8938400c88b7d04b78d8500 +c88b7d01c8938400b78d8500c88b7d00b78d8500c8938404c7998d00c8938400d69a9000 +c8938400c7998d00d69a9000c7998d00d69a9000c8938400d69a9000c7998d00d6938100 +c8938400d6938100c7998d00d69a9000c8938401e8bcb000ffffff17f4f6f900ecf3f500 +e0e4e700d2d4d600cbcccd00c4c5c500bbbcbd00abacad00a4a5a404987c750076524a00 +885a4e0076524a00885a4e00795b5400885a4e0076524a00885a4e018a514200986d6200 +c88b7d00b98a7c03b9857807b77c6a00b9857800b77c6a00a7847c00b77c6a00a7847c00 +b9857800d8cccb00e0e4e700d9dcde00d2d4d600cbcccd00bbbcbd01abacad009c9e9c04 +876d6700885a4e0676524a00885a4e018a514200885a4e00986d6200c88b7d00b98a7c00 +b9857800b98a7c00b9857800c88b7d00b9857802c8847200b9857802c88b7d00b9857805 +e6dcdc00ffffff0ef4f6f900e8ecef00c7b5b100986d6200a96d5f00986d6201a9746500 +986d6200a9746500986d6201a9746500986d6200a9746500a96d5f00a974650798594900 +885a4e0b96635500e8ecef00ffffff19e8ecef01b8938b00a77c7000a9746500a77c7000 +a9746500a77c7004a9746500a77c7004b77c6a00a77c7000a7847c00b77c6a00a7847c00 +a97465008a635800885a4e008a635800885a4e008a635804885a4e00b8adaa00e0e4e700 +e8ecef00e0e4e702d9dcde00b8938b00b9857800b77c6a00b9857800b77c6a00b9857800 +b77c6a00b9857803b98a7c00b9857804b98a7c00b9857800b98a7c00b9857800a9746500 +8a635800966355008a635800885a4e00966355008a63580096635500885a4e00a7847c00 +ffffff1af4f6f900e8ecef01e6dcdc00d9dcde00c6bcba00b9857801b98a7c00b9857800 +b78d8500b98a7c00b9857800b98a7c01b78d8502b8938b00c88b7d00b78d8500b8938b00 +c88b7d00b78d8501c88b7d00b78d8500986d62008a635801966355008a635800b7a4a000 +ffffff12f4f6f900e8ecef01d9dcde01d8cccb00c7998d00b9857800b77c6a00b9857801 +b77c6a00b9857800b77c6a00b9857800b77c6a00b9857801b77c6a00b9857803c88b7d00 +b9857800c88b7d00b98a7c00c88b7d03c8938400c88b7d05b77c6a00885a4e02d8bcb600 +ffffff17f4f6f900f7ece700e0e4e700d9dcde00d2d4d600d8cccb00cbcccd00c4c5c500 +d8cccb00c4c5c500cbcccd00c4c5c501b99a9400b9857805c88b7d00b98a7c01b9857800 +c88b7d00b9857805c8847200b98a7c01b9857800b77c6a00b7a4a000c4c5c500bbbcbd00 +885a4e00b77c6a01b9857802c88b7d00b78d8500b9857800b98a7c01c88b7d00b9857800 +b78d8500c88b7d00b78d8500c88b7d00b78d8500c8938400c88b7d00b78d8500c7998d00 +ffffff0df4f6f900ecf3f500e0e4e700d9dcde00d2d4d600c4c5c503bbbcbd00c4c5c500 +bbbcbd00c6bcba00c4c5c500978c8a008a635800a9746500c8938402c7998d00c8938400 +c7998d00c88b7d00b8938b00c88b7d00b78d8501c88b7d00b78d8500c88b7d00b78d8500 +b98a7c00b78d8503c88b7d00b78d8500c8a49d00f7ece700ffffff03f4f6f900ecf3f500 +e8ecef00d9dcde01d2d4d600cbcccd00b4b4b400987c75008a635805b9857800c8938400 +c7998d04d69a9000c7998d03d69a9000c7998d03d69a9000c7998d00d69a9000c7998d03 +d9dcde01d2d4d600c4c5c500bbbcbd00b4b4b40597848100885a4e05c88b7d00c8938400 +c88b7d00c8938401c88b7d00c8938400b78d8500c8938400b78d8500c8938402b78d8500 +c88b7d00c8938402c88b7d00b78d8500c8938403c7998d00c8938400c7998d01c8938400 +c7998d02c8938400c7998d03d6938100c7998d00d69a9000f9e4e100ffffff18ecf3f500 +e8ecef00e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400a4a5a404987c7500 +76524a008a51420076524a018a51420076524a00885a4e0076524a00885a4e0076524a00 +986d6200b98a7c02c88b7d00b98a7c00b9857800b78d8500b9857804b77c6a00b9857800 +a77c7000b9857801a77c7000b9857800b77c6a00cbcccd00e0e4e701d2d4d600cbcccd00 +bbbcbd00b4b4b400abacad00a4a5a4009c9e9c03876d6700885a4e01795b5400885a4e01 +795b5400885a4e05986d6200c88b7d00b78d8500c88b7d00b98a7c00c88b7d00b98a7c01 +b9857803c8847200b9857804c47b7d00b9857801e6dcdc00ffffff0eecf3f501d8cccb00 +986d6202a9746500986d6201a974650097746b00a9746500986d6200a9746500986d6200 +a9746503a77c7001a9746500a77c7000a97465008a635800885a4e0296635500885a4e08 +c6bcba00ffffff18f4f6f900ecf3f500d9dcde00a9746501a77c7000a9746500a77c7007 +b77c6a00a77c7001a7847c00a77c7000b77c6a00a7847c00a77c7000b985780097746b00 +8a635802885a4e008a635800885a4e02795b54008a635800b8adaa00e0e4e701e8ecef00 +e0e4e701d2d4d600c8a49d00a7847c00b9857800b77c6a00a7847c00b77c6a00a7847c00 +b9857800a77c7000b9857804b98a7c00b9857802a7847c00b9857801a7847c008a635803 +885a4e008a635800885a4e008a635800885a4e00e8ecef00ffffff19f4f6f900ecf3f500 +e0e4e700d9dcde00d2d4d600c8a49d00b98a7c03b9857800b78d8500b98a7c00b78d8500 +b98a7c00b78d8504b8938b00b98a7c00b8938b00b98a7c00b8938b00b78d8500b9857800 +8a635804d8cccb00ffffff12f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600c8aca500 +b985780cb98a7c00b9857800c8847200b98a7c00c88b7d00b98a7c00c88b7d01c8938400 +b78d8500c8938402c88b7d00c8938400c88b7d00b8938b00c88b7d00b8938b00c88b7d00 +97746b008a635800885a4e008a635800e6dcdc00ffffff17ecf3f500e8ecef00d9dcde00 +d2d4d601cbcccd01c4c5c500cbcccd00c4c5c500cbcccd00c4c5c500c7b5b100b9857801 +b78d8500b98a7c00b78d8500b98a7c05b78d8500c88b7d00b78d8500c88b7d00b98a7c02 +b9857800b98a7c00c88b7d00b98a7c00a7847c00c4c5c500a88c8600986d6200b9857803 +b98a7c02c88b7d00b78d8500c88b7d00b78d8500c8938400b78d8500c8938400b78d8500 +c8938400b78d8500c8938400b78d8500c8938400d7c4bd00ffffff0eecf3f500e8ecef00 +d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd00c6bcba00bbbcbd01c4c5c500bbbcbd01 +b4b4b400986d62008a635800c8938400c7998d03b8938b00c8938400b8938b00c8938400 +b8938b00c88b7d00b8938b00b78d8502c8938400b78d8501c8938400b78d8500b8938b01 +c88b7d00b8938b00d7c4bd00f4f6f900ffffff00f4f6f900ecf3f500e8ecef00d9dcde01 +cbcccd00a4a5a400987c7500885a4e008a635800885a4e008a635800885a4e008a635800 +97746b00b98a7c00c7998d10c8938400c7998d01c8938400c7998d00d69a9000d8bcb600 +e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd00b4b4b401abacad00b4b4b401abacad00 +a89a9500885a4e0077646000885a4e008a635800885a4e01a7847c00c8938400b78d8500 +c8938400b78d8500c8938400b78d8500c8938402b78d8500c8938402b78d8500c8938400 +b78d8500c8938401c7998d00c8938400b8938b00c7998d00c8938400c7998d08c8938400 +c7998d00c8938400c7998d01d8b4ac00ffffff1af4f6f900e8ecef00e0e4e700d9dcde00 +cbcccd00c4c5c500bbbcbd00abacad019c9e9c00a4a5a402867c7b0076524a01795b5400 +8a51420076524a018a51420076524a018a514200986d6200b9857800b98a7c00b9857800 +b98a7c00b9857802b98a7c01a7847c00b9857800a7847c00b9857800a7847c00a77c7000 +a7847c00a77c7000b9857800a77c7000a7847c00d8cccb00e0e4e700d9dcde00d2d4d600 +cbcccd00bbbcbd01abacad00a4a5a4009c9e9c0199939300a4a5a400876d6700795b5400 +885a4e00795b5400885a4e00795b5400885a4e008a635800795b5400885a4e0077646000 +885a4e008a635800986d6200b8938b00c88b7d00b78d8500c88b7d00b78d8500b98a7c00 +c88b7d00b985780aa77c7000b9857800e6dcdc00ffffff0ef4f6f900ecf3f500e6dcdc00 +97746b00986d620497746b00a96d5f0097746b00986d6200a974650097746b00a9746500 +97746b00a77c7001a9746500a77c7001a9746500a77c7000986d6200885a4e09795b5400 +885a4e00795b5400a7847c00ffffff18f4f6f900e8ecef00c7b5b10097746b02987c7500 +97746b01a77c700097746b00a77c7003a7847c00a77c7002a7847c00a77c7000a7847c00 +a77c7000a7847c0097746b00885a4e01795b54008a635800795b5400885a4e0077646000 +8a635800795b5400885a4e00b7a4a000e8ecef01e0e4e700e8ecef00e0e4e700d9dcde00 +c7b5b100b9857800a77c7000a7847c01b77c6a00a7847c00a77c7000b9857800a7847c08 +b9857800b98a7c00a7847c00b985780096635500885a4e028a635800795b5400885a4e00 +77646000885a4e00b8adaa00ffffff19f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600 +b8938b00b98a7c00b9857800b78d8500b9857800a88c8600b9857800b78d8505b8938b00 +b78d8503b8938b00b98a7c00b8938b00a77c70008a635803876d6700ffffff12f4f6f901 +e8ecef00e0e4e700d9dcde00c7b5b100a88c8600b9857800a7847c00b9857803a7847c00 +b9857802b78d8500b9857800b98a7c01c88b7d00b78d8501b98a7c00c8938400b78d8500 +c8938400b78d8500c88b7d00b78d8500c8938400b78d8500b8938b00b78d8501b8938b00 +c88b7d00b78d8500c88b7d00b98a7c00986d62008a63580197746b00ffffff17f4f6f900 +e8ecef00e0e4e700d9dcde00d2d4d600cbcccd02c4c5c500cbcccd00c4c5c502a8949000 +b98a7c00a7847c00b98a7c00b78d8500a7847c00b98a7c00b78d8500b98a7c01b78d8504 +b98a7c00b78d8500b98a7c00b9857800b78d8500b9857800b98a7c00a77c7000b7a4a000 +885a4e00a7847c00b9857800b98a7c02b78d8500b9857800b78d850dffffff0ff4f6f900 +e8ecef00e0e4e700d9dcde00cbcccd00c4c5c502bbbcbd00c4c5c500bbbcbd00c6bcba00 +c4c5c500bbbcbd00a89a95008a63580097746b00c7998d06b8938b00c7998d00b8938b02 +c8938400b8938b00b78d8500b8938b01b78d8500b8938b01b78d8500b8938b01b78d8500 +c7998d00c7b5b100c6bcba00b4b4b400b8adaa00a89a9500987c75008a635800885a4e00 +795b5403885a4e0097746b00b98a7c00c7998d01c8938400c7998d14c8a49d00e0e4e700 +e8ecef00d9dcde00d2d4d600cbcccd00bbbcbd00b4b4b405a4a5a4008a635800795b5400 +8a635800885a4e00795b54008a635800a9746500c8938400b8938b00c8938400b8938b00 +c8938400b8938b00c8938400b8938b00c8938402b8938b00c8938401c7998d00c8938400 +c7998d00b8938b00c8938400b8938b00c8938400c7998d00c8938400b8938b00c8938400 +c7998d03c8938400c7998d00c8938401c7998d01c8a49d00f9e4e100ffffff1becf3f500 +e8ecef00e0e4e700d9dcde00cbcccd00c4c5c500b4b4b401a4a5a404987c750076524a04 +795b540076524a038a635800b78d8500b9857800b78d8500b9857800b78d8500a7847c00 +b9857800a7847c00b9857800a7847c00b98a7c00b9857800a77c7000b9857800a77c7001 +b9857800a77c7000a7847c00a77c7000d8cccb00e0e4e701d2d4d600cbcccd00bbbcbd00 +b4b4b400abacad00a4a5a40099939300a4a5a4009c9e9c01876d6700795b5400885a4e00 +795b5401885a4e00795b5401885a4e00795b5400885a4e00795b5400885a4e0097746b00 +b78d8500b8938b02b78d8502b98a7c00b78d8500b9857807a7847c00b9857800a77c7000 +e6dcdc00ffffff0ef4f6f900ecf3f500e8ecef00a88c8600986d620297746b00986d6201 +97746b00986d620097746b00986d620097746b00a77c7001a9746500987c7500a77c7000 +a9746500a77c7000a9746500a77c7000986d6200885a4e00795b5400885a4e00795b5401 +885a4e00795b5403885a4e00795b540076524a008a635800d9dcde00ffffff17ecf3f500 +e8ecef00a894900097746b00a974650097746b00a77c700097746b00a77c700097746b00 +987c7500a77c7000987c7501a77c7002a7847c00a77c7001a7847c00a77c7000a7847c00 +a77c700097746b008a63580077646000885a4e00795b54008a635800795b5404b8adaa00 +e8ecef00e0e4e700e8ecef00e0e4e701e6dcdc00cbcccd00a7847c00a77c7004a7847c00 +a77c7002a7847c00a77c7001b9857800a77c7000b9857800a7847c0497746b00885a4e00 +77646000885a4e00795b54008a635800795b5400885a4e0077646000986d6200ffffff19 +ecf3f500e8ecef00e6dcdc00d9dcde00c7b5b100a7847c00b9857800a88c8600a7847c00 +b98a7c00b9857800a88c8600b78d8503b8938b00b78d8502b8938b00b78d8500b8938b00 +b78d850297746b008a635801776460008a635800a88c8600ffffff12f4f6f900e8ecef00 +e0e4e701d8cccb00b78d8500b9857800a7847c00b98a7c00a88c8600b78d8500a7847c00 +b78d8500b9857800b78d8500a88c8600b78d8501b98a7c00b78d8500b8938b00b78d8500 +b8938b00c8938400b78d8500c8938400b78d8501c8938400b78d8500c8938400b78d8500 +c8938400b78d8500c8938400b78d8500c88b7d00b8938b00b78d8500b8938b00c88b7d00 +b98a7c008a635801885a4e00a7847c00ffffff16f4f6f900ecf3f500e8ecef00d9dcde00 +d2d4d601cbcccd01c4c5c501d8cccb00c4c5c500cbcccd00c8aca500a7847c00b98a7c00 +a7847c00b98a7c00a88c8600b98a7c00a88c8600b78d8500b98a7c00b78d8503c8938400 +b78d8500b98a7c00b78d8500b98a7c00b78d8500b9857800b78d8500b9857800876d6701 +b9857801a7847c00b78d8500b9857800b78d8500b98a7c02b78d8501b98a7c00b78d8502 +b8938b00b78d8503d8bcb600ffffff0ff4f6f900ecf3f500e0e4e700d9dcde00d2d4d600 +cbcccd00c4c5c500bbbcbd00c4c5c500bbbcbd02c4c5c500bbbcbd00c4c5c50097848100 +8a635800b78d8500c7998d00b8938b00c7998d00b99a9400b8938b00c7998d00b99a9400 +c7998d00b8938b00c7998d00b8938b00b99a9400b8938b02b78d8500b8938b03b98a7c00 +b8938b00b78d8501b8938b00c88b7d00b78d850097746b00986d6200795b54038a635800 +986d6200987c7500b98a7c00b8938b05c8938400b99a9400c7998d03b99a9400c7998d0c +e6dcdc00f4f6f900e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b40687747000 +795b5401885a4e0077646000885a4e00876d6700c7998d00b8938b01c8938400b8938b00 +c8938400b8938b00c8938400b99a9400c7998d00b99a9400c7998d09b8938b00c7998d01 +b99a9400c8938400b8938b00c8938400b8938b00c8938400b8938b03d8bcb600ffffff1d +f4f6f900ecf3f500e0e4e700d2d4d601c4c5c500bbbcbd00abacad01a4a5a4029c9e9c00 +8774700076524a09986d6200a7847c00b9857800a7847c02b9857800a7847c02b9857800 +a7847c01a77c7001a7847c00a77c7003a7847c00d8cccb00e0e4e700d9dcde00d2d4d600 +cbcccd00bbbcbd01a4a5a4019c9e9c03876d670076524a00795b5407885a4e00795b5401 +97746b00b98a7c00b8938b00b98a7c00b8938b00b78d8500c88b7d00b78d8500b9857800 +a7847c00b9857800a7847c03a77c7000a7847c00a77c7000a7847c00a77c7001e6dcdc00 +ffffff0ef4f6f900ecf3f500e8ecef00b8adaa00986d6200876d6700986d6200876d6700 +986d620497746b03a77c700097746b00a9746500987c750097746b00a77c700097746b01 +8a635800885a4e00795b5400885a4e0076524a00795b5402885a4e0076524a00795b5400 +76524a00795b540076524a00a89a9500ffffff16f4f6f901d9dcde0097746b04987c7500 +97746b00a77c700097746b00987c750097746b00a77c7000987c7501a77c7000987c7500 +a77c7000987c7500a77c7000a7847c00a77c700197746b00885a4e00795b54058a635800 +795b5401b8adaa00e8ecef02f7ece700e0e4e701d2d4d600a88c8600a77c7000987c7500 +a77c7000987c7500a77c7000987c7500a7847c00a77c7006a7847c00a77c7000a7847c00 +b77c6a00a7847c01a77c70008a63580077646000885a4e0077646000885a4e0077646000 +885a4e0077646000885a4e00c4c5c500ffffff17f4f6f900e8ecef01d9dcde01b99a9400 +a88c8600b98a7c00a7847c00b98a7c00a7847c00a88c8600b78d8501a88c8600b78d8507 +a88c8600b8938b00b78d8501876d67008a635800776460008a635801c4c5c500ffffff11 +f4f6f901e8ecef00e0e4e700d8cccb00b8938b00a7847c00a88c8600b98a7c00a88c8600 +b78d8500a7847c00b78d8500a7847c00b78d8500a88c8600b98a7c00b78d8503b8938b01 +b78d8500b8938b0fb78d8500b8938b00b78d8500a7847c008a635801795b5400b7a4a000 +ffffff16f4f6f900e8ecef00e6dcdc00d9dcde00d2d4d600cbcccd02c4c5c504b8938b00 +a7847c00a88c8600b98a7c00a88c8600b78d8505b8938b00b78d8508a7847c00a77c7001 +a88c8600b9857800a88c8600b9857800a88c8600a7847c01a88c8600a7847c00b78d8500 +a88c8600b78d8506a88c8600b78d8500ffffff11f4f6f900e8ecef00e0e4e700d2d4d600 +cbcccd00c4c5c502bbbcbd00c4c5c501bbbcbd0397746b00876d6700b8938b00c7998d00 +b99a9400c7998d00b99a9400c7998d00b8938b00b99a9400c7998d00b99a9400b8938b00 +b99a9400b8938b10b98a7c00a88c8600b9857800a88c8600b98a7c00b8938b0ac7998d00 +b8938b00b99a9401c7998d00b99a9401c7998d00b99a9403c7998d00b99a9400c7998d02 +e6ccc900ffffff00ecf3f500e8ecef00d9dcde00d2d4d600cbcccd00c4c5c500b4b4b403 +abacad00b4b4b401978481008a635800795b54038a635800b78d8500c8938400b8938b00 +c8938400b8938b01c8938400b8938b00c7998d00b8938b00c7998d02b99a9400c7998d00 +b99a9400c8938400b99a9400c7998d00b99a9400c7998d01b99a9400c7998d01b8938b00 +c7998d00b99a9400c8938400b99a9400b8938b00c8938400c8a49d00f7ece700ffffff1e +ecf3f500e8ecef00e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd00b4b4b400a4a5a404 +867c7b0076524a01684f490076524a068a635800a7847c02b9857800a7847c00a77c7000 +a7847c02a77c7000a7847c00a77c7000a7847c00a77c7001a7847c00a77c7000a7847c01 +a77c7000cbcccd00e8ecef00d9dcde00d2d4d600cbcccd00bbbcbd00b4b4b400abacad00 +9c9e9c02999393009c9e9c0077646000795b540076524a00795b540076524a00795b5400 +76524a00795b5405986d6200b78d8501b8938b00b78d8500b8938b00a88c8600b78d8501 +a7847c00b78d8500a7847c00b9857800a7847c00b9857800a7847c01a77c7000a7847c02 +e6dcdc00ffffff0fecf3f500e8ecef00c4c5c500986d6200876d6700986d62008a635800 +97746b00876d670097746b00986d620097746b0c986d620076524a00795b540276524a00 +795b540076524a00795b540176524a00795b540176524a0077646000e8ecef00ffffff15 +f4f6f900ecf3f500b7a4a000986d620097746b05987c7501a77c7000987c7501a77c7000 +987c7501a77c7000987c7500a77c7000987c7502a77c700087747000795b5409b8adaa00 +e8ecef04d9dcde01b7a4a000987c7500a77c7000987c7500a77c7000987c7500a77c7000 +97746b00987c7502a77c7000987c7501a77c7000a7847c00a77c7000a7847c04876d6700 +885a4e0077646000795b540177646000885a4e0077646000795b540097746b00ffffff17 +f4f6f900ecf3f500e0e4e700e6dcdc00cbcccd00a88c8600b98a7c00a88c8602b98a7c00 +a88c8600b78d8500a88c8600b78d8501a8949000b78d8500a88c8600b8938b00a88c8600 +b78d8500a88c8600b78d8500a88c8600b8938b00978481008a635800776460008a635800 +776460008a635800ffffff12f4f6f900e0e4e701d9dcde00b7a4a000b78d8500a88c8600 +b98a7c00a88c8600b9857800a88c8600b98a7c00a88c8600b98a7c00a88c8600a7847c00 +b78d8500a88c8600b78d8500b8938b11b78d8500b8938b00b78d8500b8938b00b98a7c00 +b78d8501987c7500795b5402d7c4bd00ffffff15f4f6f900ecf3f500e8ecef00d9dcde00 +d2d4d600d8cccb00cbcccd00c4c5c500cbcccd00c4c5c500cbcccd00c4c5c500cbcccd00 +b8adaa00b78d8501a88c8600b78d8500a88c8600b78d8500a88c8600b8938b00b78d8500 +b8938b01b78d8500b8938b02b78d8508a88c8600b78d8500a88c8600b78d8501a88c8600 +b78d8501a88c8600b78d8500b8938b00a88c8600b78d8500a88c8600b78d8500a88c8601 +b9857800c8aca500ffffff11f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd00 +c4c5c501bbbcbd00c6bcba00bbbcbd01c4c5c500bbbcbd01b8adaa00876d670097746b00 +b99a9402c7998d00b99a9404b8938b14b78d8500b8938b01a88c8600b8938b01a88c8600 +b8938b08c7998d00b99a9401c7998d00b99a9401c7998d01b99a9400c7998d00b99a9400 +c7998d00b99a9401d7c4bd00ffffff01ecf3f500e8ecef00e0e4e700d2d4d600cbcccd00 +c4c5c500b4b4b405abacad00a4a5a400795b540177646000885a4e00795b5401a7847c00 +b8938b00b99a9400b8938b00b99a9403c7998d00b99a9400c7998d00b99a9401c7998d00 +b99a9400c7998d00b99a9400c7998d00b99a9400c7998d00b99a9400b8938b00c7998d00 +b99a9400c7998d00b8938b00c8938400b8938b02c8938400d7c4bd00ffffff20f4f6f900 +ecf3f500e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd00abacad019c9e9c00a4a5a402 +87747000684f490176524a00684f490076524a00684f490076524a038a635800b98a7c00 +a7847c05a77c7001987c7500a77c700097848100a77c7000a7847c06cbcccd00e0e4e700 +d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400abacad00a4a5a4009c9e9c02a89a9500 +7764600076524a00684f4900795b5400684f490076524a04795b540076524a01876d6700 +a88c8602b78d8500a88c8600b78d8500a88c8601b78d8500a7847c00a88c8600a7847c03 +a77c7000a7847c01a77c7000a7847c00e6dcdc00ffffff0ef4f6f901e8ecef00e0e4e700 +987c7500876d6702986d6200876d6700986d62008774700097746b0d795b540176524a01 +795b540076524a00795b540076524a00684f4900795b5400684f490076524a00684f4900 +76524a00a8949000ffffff15f4f6f900e6dcdc00987c7500876d670097746b0087747000 +97746b05987c7501a77c7000987c7501a77c7000987c7502a77c7000987c7500a77c7000 +987c750097746b00795b5409b8adaa00f7ece700e8ecef03e6dcdc00d9dcde00c6bcba00 +987c750097746b01987c750097746b00987c750097746b06987c7502a77c7000987c7500 +a7847c02987c7500795b540077646000795b54008a635800795b540077646000795b5400 +77646001c6bcba00ffffff16f4f6f900e8ecef00e0e4e700d9dcde00b7a4a000a88c8601 +a7847c01a88c8601b78d8500a88c8600b78d8500a88c8600b78d8500a88c8600b78d8500 +a88c8600b78d8500a88c8600b78d8500a88c8600b8938b00a88c8600b78d850097746b00 +776460008a63580077646000885a4e00978c8a00ffffff11f4f6f900e8ecef00e0e4e700 +d9dcde00c8aca500a7847c01a88c8600a7847c00a88c8603a7847c00a88c8600b98a7c00 +a88c8601b78d8500a88c8601b8938b00a88c8600b8938b00a8949000b8938b0bb78d8500 +b8938b00a88c8600b78d8501a88c8600b78d8500a88c8600b9857800876d6700795b5401 +77646000f7ece700ffffff15f4f6f900e0e4e701d9dcde00d2d4d600d8cccb00cbcccd00 +c4c5c503cbcccd00c6bcba00a8949000a88c8601b78d8500a8949000b78d8500a8949000 +b78d8500a8949000b8938b00b78d8500a8949000b78d8500b8938b00b78d8500b8938b00 +b78d8502a88c8600b78d8500a88c8601b78d8500b8938b00b78d8501a88c8601b78d8500 +a88c8601b78d8500a88c8601b78d8500a88c8600b78d8500a88c8600a7847c00a88c8600 +a7847c00f4f6f900ffffff12f4f6f900e8ecef00e0e4e700d2d4d600cbcccd01c4c5c502 +bbbcbd00c4c5c500bbbcbd00c6bcba00bbbcbd01b8adaa00776d6b00a77c7000b99a9406 +b8938b00b99a9400b8938b03a8949000b8938b07b78d8501a88c8600b78d8500b8938b00 +a88c8600b8938b00a88c8600b8938b00a88c8600b8938b01a8949000b8938b0ab99a9400 +b8938b00b99a9406c7998d00b99a9401e5c4c200ffffff02f4f6f900e8ecef00e0e4e700 +d9dcde00cbcccd00c4c5c500bbbcbd00b4b4b406876d6700795b54037764600097746b00 +b8938b02b99a9400b8938b00b99a9400b8938b00b99a9400c7998d00b99a9401c7998d00 +b99a9402c7998d00b8938b00b99a9400b8938b00c7998d00b99a9400c7998d00b8938b00 +c7998d00b8938b00b99a9400b8938b00b99a9400c8a49d00f4f6f900ffffff15e8ecef00 +876d6700867c7b00a89a9500c7b5b100d2d4d600f4f6f900ffffff04ecf3f500e8ecef00 +e0e4e700d2d4d601c4c5c500bbbcbd00b4b4b400a4a5a4048774700076524a00684f4903 +76524a00684f49038a635800a7847c05987c7500a77c7000987c7500a77c7001987c7500 +a7847c01987c7500a7847c04cbcccd00e0e4e700d9dcde00d2d4d600cbcccd00bbbcbd00 +b4b4b400abacad009c9e9c0477646000684f4902795b5400684f4901795b5400684f4901 +76524a00675c5a0076524a008a635800a88c8601a7847c00a88c8601a7847c00b78d8500 +a7847c00a88c8600a7847c00b78d8500a7847c08e6dcdc00ffffff0ff4f6f900ecf3f500 +e8ecef00b99a9400986d6200876d6700986d6200876d670197746b00876d670097746b00 +876d670097746b00876d670097746b008774700097746b0087747000986d620087747000 +986d62008774700097746b00877470008a635800684f4900795b5400684f4904795b5400 +684f4901795b5400684f4901795b5400d9dcde00ffffff14ecf3f500b8adaa00876d6702 +97746b008774700297746b00987c7505a7847c00987c750097746b00987c750597746b00 +795b540376524a00795b5402684f4900795b5400b8adaa00ecf3f501f7ece700ecf3f500 +e8ecef00e0e4e700d9dcde00d2d4d600a7847c0097746b07876d670097746b02987c7500 +97746b00987c7502a7847c0097848100a7847c01876d67008a63580077646000795b5400 +77646000795b540077646000885a4e00795b5400776d6b00f4f6f900ffffff14f4f6f900 +ecf3f500e8ecef00e6dcdc00cbcccd00a88c8601a7847c00a88c8604a8949000a88c8600 +a8949000a88c8604b8938b00a88c8602b78d8500a88c86008a635800795b540077646000 +795b540077646000d8cccb00ffffff10f4f6f900e8ecef00e0e4e701c6bcba00a7847c02 +a88c8600a7847c00a88c8600a7847c01a88c8600a7847c00a88c8600a7847c00a88c8600 +a7847c00a88c8601b78d8500a88c8600a8949000b78d8500a8949000b8938b00a8949003 +b8938b00a8949000a88c8600a8949000b78d8500a8949000a88c860a8a635800795b5401 +87747000ffffff15f4f6f900ecf3f500e0e4e700d9dcde00d2d4d600cbcccd02c4c5c500 +cbcccd00c4c5c501cbcccd00b7a4a000b8938b00a88c8600a8949000a88c8601b78d8500 +a88c8603b78d8500a88c8605b78d8500a88c8600b78d8500a88c8600b8938b01a8949000 +b8938b00a8949000b78d8500a88c8600b8938b00a88c8603b78d8500a88c8604a7847c00 +c8a49d00ffffff13f4f6f900ecf3f500e0e4e700e6dcdc00d2d4d600cbcccd00c4c5c502 +bbbcbd00c6bcba00bbbcbd01c4c5c500bbbcbd01a4a5a400876d6700a7847c00b99a9404 +b8938b00a89a9500b8938b00a8949002b8938b00a8949000b8938b00a8949000a88c8600 +a8949000b78d8500a8949000a88c8600a8949000a88c8601b78d8500a88c8602b78d8500 +a8949000b8938b00a8949000b8938b00a8949000b8938b00a8949000b8938b00a89a9500 +b8938b00a89a9500b8938b01a8949000b8938b00a8949000b8938b00a8949000b8938b01 +b99a9405b8938b00b99a9400d7c4bd00ffffff03f4f6f900ecf3f500e0e4e700d2d4d601 +c4c5c500bbbcbd00b4b4b403abacad00b4b4b401978c8a00795b540077646000795b5400 +77646000795b54008a635800a8949000b99a9402b8938b00b99a9406b8938b00c7998d00 +b99a9401c7998d00b99a9400c7998d00b99a9403b8938b00b99a9400b8938b00c7998d00 +e9d5d700ffffff16e6dcdc0077646000795b5400684f4900795b5400675c5a0076524a00 +795b5401987c7500a89a9500b4b4b400e8ecef00f4f6f900ecf3f500e0e4e700d9dcde00 +cbcccd00c4c5c500bbbcbd00abacad01a4a5a40387747000684f490776524a00684f4900 +8a635800a7847c01987c7500a77c7000987c7500a77c7000987c7500a77c7000987c7500 +a7847c00987c7500a77c7000987c7500a7847c02987c7500a7847c02cbcccd00e0e4e700 +d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400abacad009c9e9c0477646000684f4900 +76524a00684f4905795b5400684f490076524a00684f4900876d6700a88c8600a7847c02 +a88c8600a7847c00a88c8600a7847c02a88c8600a7847c02987c7500a7847c03987c7500 +d9dcde00ffffff0ff4f6f900ecf3f500e8ecef00c4c5c50087747000876d670397746b00 +87747001986d6200876d670187747000876d6700986d6200876d6703986d6200876d6702 +795b5400684f4901795b5400684f4900795b5400684f4901795b5400684f4901675c5a00 +684f490187747000f4f6f900ffffff12f4f6f900e0e4e70097746b00876d6700986d6200 +876d670297746b0187747000987c750a97746b00987c75028774700076524a00795b5401 +76524a00675c5a00795b5400684f4900675c5a00795b5400684f4900b4b4b400ecf3f502 +f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600b7a4a000876d67008774700097746b00 +876d670097746b00876d670097746b00876d67008774700197746b008774700097746b00 +987c750497848100a7847c01987c750077646001795b540177646000795b540077646001 +795b540097848100ffffff14f4f6f900e8ecef00e0e4e700d9dcde00b99a9400a88c8600 +a7847c01a88c8600a7847c00a88c8602b78d8500a88c8602b78d8500a88c8600b8938b00 +a88c8602b98a7c00a88c8601987c7500776460008a635800776460008a63580087747000 +ffffff10f4f6f900e8ecef01e0e4e700c4c5c500a88c8600a7847c0097848100a7847c01 +a88c8600a7847c0497848100a7847c00a88c8600a7847c00a88c8605a8949002b8938b00 +a8949000b8938b00a8949000b8938b00a8949000b78d8500a8949000a88c8603a7847c03 +a88c860397848100795b540177646000978c8a00ffffff15f4f6f900e8ecef00d9dcde01 +d2d4d600cbcccd01c4c5c502cbcccd00c4c5c500c6bcba00a8949001a88c860fa8949001 +b8938b00a8949001b8938b00a8949000b8938b00a8949000b8938b00a8949000a88c8601 +b8938b00a88c8605a7847c00a88c8600f7ece700ffffff14f4f6f900e8ecef00e0e4e700 +d9dcde00d2d4d600cbcccd00c4c5c502bbbcbd00c4c5c500bbbcbd01c4c5c500bbbcbd00 +c6bcba00a89a9500776d6b00a88c8600b99a9401a8949000b99a9400a8949000b8938b00 +a8949001b8938b00a88c8603a8949000b78d8500a88c8601a8949000b78d8500a88c8600 +b78d8500a88c8607b8938b00a88c8600a8949000b8938b00a8949002b8938b00a8949000 +b8938b00a8949000b8938b00a8949000a88c8601b8938b00a8949000b8938b00a8949000 +b8938b00b99a9400b8938b00b99a9401b8938b00e9d5d700ffffff04f4f6f900ecf3f500 +e8ecef00d9dcde00cbcccd01bbbcbd01b4b4b400abacad00b4b4b403a4a5a400795b5405 +a88c8600b8938b00b99a9407c7998d00b99a9403b8938b00b99a9400b8938b00b99a9401 +b8938b00c7998d00b99a9400b8938b00b99a9400c8aca500ffffff17c4c5c500675c5a00 +684f4904795b5400684f4900675c5a0176524a0087747000c6bcba00ecf3f500e8ecef00 +e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400a4a5a40487747000684f4900 +55454100684f49007c3a3c00684f49057764600097848100a7847c00987c7500a7847c01 +987c7500a7847c00987c750097848100a77c7000987c7501a7847c00987c7500a7847c00 +97848100a7847c0197848100a7847c00cbcccd00e0e4e700d9dcde00d2d4d600c4c5c500 +bbbcbd00b4b4b400abacad009c9e9c0477646000684f490b8a635800a7847c0097848100 +a7847c05a88c8600a7847c0297848100a7847c0097848100a7847c0097848100a7847c00 +97848100a7847c00e6dcdc00ffffff0ff4f6f901e8ecef00e0e4e700987c7500876d6707 +87747000986d6200876d67028a635800876d67038774700097746b00876d6701684f4900 +675c5a00684f4901675c5a00684f490899939300ffffff12ecf3f500a89a950087747000 +876d670397746b008774700197746b008774700097746b008774700097746b0087747000 +97746b008774700097746b0187747000987c750097746b00987c750097746b00987c7500 +876d670076524a00675c5a00684f4900675c5a0076524a00684f4900675c5a00684f4902 +b4b4b400f4f6f902ecf3f501e8ecef00e0e4e700d9dcde00c4c5c50097746b00876d6702 +8774700097746b00876d670087747000986d62008774700197746b00987c750097746b00 +987c750297848101a7847c00978c8a00a7847c00987c7500795b540077646001795b5400 +77646000795b540077646002a89a9500ffffff12f4f6f901e8ecef00e0e4e700c7b5b100 +978c8a00a7847c00978c8a00a7847c00a88c861197746b0077646000795b540077646001 +b8adaa00ffffff10ecf3f500e8ecef00e6dcdc00d2d4d600a8949000a7847c0097848101 +a7847c0097848102a7847c00978c8a0097848100a7847c0097848103a7847c00978c8a00 +a7847c00a88c860fa7847c00978c8a00a88c860097848100a88c8603a8949000a88c8600 +a8949000987c750077646000795b5401b8adaa00ffffff14f4f6f900e8ecef00e0e4e700 +d9dcde00d2d4d600d8cccb00cbcccd00c4c5c500d8cccb00c4c5c501cbcccd00c4c5c500 +b7a4a000a8949000a88c860eb8938b00a88c8600b78d8500a8949000a88c860da7847c00 +a88c8600a7847c00a88c8600b99a9400ffffff16ecf3f500e8ecef00d9dcde01d2d4d600 +cbcccd00c4c5c501bbbcbd00c4c5c500bbbcbd00c4c5c500bbbcbd03a4a5a40077646000 +a88c8600a8949004a88c8613a8949000a88c8600a8949002b8938b00a88c8600a8949000 +b8938b00a8949001b99a9400a8949000b8938b00a8949000b8938b00a89a9500b8938b00 +a8949000b8938b00a89a9500b99a9401a8949000b99a9402e0e4e700ffffff06ecf3f500 +e0e4e701d2d4d600cbcccd00c4c5c500bbbcbd00b4b4b402abacad00b4b4b401b8adaa00 +8774700077646000795b540177646000795b540087747000b8938b01b99a9403b8938b00 +b99a9400b8938b00b99a9401b8938b00b99a9407b8938b00b99a9401e6dcdc00ffffff0f +f4f6f901ecf3f501f4f6f901ffffff00f4f6f9009c9e9c00684f490a87747000a88c8600 +a8949000e0e4e700ecf3f500e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd00abacad01 +a4a5a40377747400684f490055454100684f4900584c4800684f490055454100684f4903 +885a4e0097848100a77c700097848101987c7500a7847c0097848100a77c700097848100 +a7847c0097848100a7847c0097848100a7847c0097848100a7847c01978c8a00a7847c00 +a88c8600cbcccd00e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400a4a5a401 +9c9e9c01a89a95009c9e9c0077646000684f490b77646000a7847c00987c750097848103 +a7847c0097848100a7847c0097848100a7847c0097848100a7847c0097848102a7847c00 +97848100a7847c00978c8a00e6dcdc00ffffff10f4f6f900e8ecef01b7a4a000876d6701 +8a635800876d6709776d6b008a635800876d670677646000684f490a584c4800684f4901 +a89a9500ffffff10f4f6f900d8cccb00876d67078774700097746b0087747001987c7500 +8774700097746b00867c7b0097746b00867c7b0097746b00867c7b0097746b00867c7b00 +8774700197746b00876d6700675c5a00684f4902675c5a00684f4904b8adaa00f4f6f904 +e8ecef00e0e4e700d9dcde00d2d4d60099939300986d6200876d670797746b0087747001 +987c7500867c7b00987c750097848100987c750097848101a7847c0097848101876d6700 +795b540077646004675c5a00795b540077646000978c8a00ffffff11f4f6f900e8ecef00 +e0e4e700cbcccd00978c8a00a7847c0097848101a88c8600978c8a00a7847c00978c8a00 +a88c8601a8949000a88c8601a8949000a88c8607a7847c0077646004ffffff10e8ecef01 +e0e4e700d9dcde00a89a950097848105a7847c0097848106a7847c0097848101a7847c00 +97848100978c8a00a88c8600978c8a00987c750077646000a88c8601a8949000a88c8608 +a7847c0097848100a88c860097848100a88c8605a89490008774700077646000675c5a00 +795b5400d9dcde00ffffff13f4f6f901e8ecef00e0e4e700d2d4d601cbcccd01c4c5c500 +cbcccd00c4c5c502c6bcba00a8949000a88c8603a7847c00978c8a00a7847c00a88c8609 +a8949000a88c8601a8949001a88c8600a8949000a88c8607978c8a00a88c860097848100 +a88c860097848100e8ecef00ffffff16f4f6f901e0e4e700d9dcde00d2d4d600cbcccd01 +c4c5c502bbbcbd01c6bcba00bbbcbd00c4c5c500bbbcbd00c6bcba00a4a5a400876d6700 +978c8a00b8938b00a88c8600a8949000a88c8601a8949000a88c8603978c8a00a88c860a +a8949000a88c8604a8949004a89a9500b8938b00a8949001a89a9500b99a9400a89a9500 +b8938b00a89a9500b99a9400a89a9500b99a9401a89a9500b99a9401b7a4a000ffffff08 +f4f6f900ecf3f500e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd00b4b4b405abacad00 +99939300795b540077646000675c5a00795b540177646000a8949000b99a9400b8938b00 +b99a9400b8938b00b99a9403b8938b00b99a9403b8938b01b99a9400b8938b01b99a9400 +b8938b00c7b5b100ffffff10ecf3f501e8ecef03ecf3f500e0e4e700867c7b0055454103 +584c4802684f4900584c4800684f490197746b00a88c860097848100a7847c00bbbcbd00 +e8ecef00e0e4e700d2d4d601c4c5c500b4b4b401a4a5a4048774700055454100684f4900 +55454100684f4900584c48007c3a3c00684f490055454101684f4900795b5400a77c7000 +97848100987c7500a7847c00987c750097848100a7847c0097848100987c750097848100 +987c750097848100a7847c0097848101a7847c0097848100a88c8601978c8a00cbcccd00 +e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400abacad009c9e9c0099939300 +9c9e9c02675c5a0055454104684f49068a63580097848100987c7502a77c700097848100 +a7847c00978c8a00a7847c0097848103987c7500a7847c0097848103a7847c00d9dcde00 +ffffff10f4f6f900ecf3f500e8ecef00cbcccd00876d6701776d6b008a635800876d6705 +776460008a635800776d6b0077646000776d6b008a635800776d6b00876d670287747000 +876d6701684f4904584c4800684f4900584c4800684f4900584c4800684f4901584c4801 +684f4900867c7b00e8ecef00ffffff0ed9dcde0087747000876d6703776d6b00876d6703 +8774700497746b0087747000867c7b008774700197746b008774700297746b00867c7b00 +876d6700684f4907584c4800684f4900b4b4b400f4f6f900ffffff00f4f6f902e8ecef00 +e0e4e700e6dcdc00d2d4d600b4b4b400876d670087747000876d67068774700197746b00 +867c7b0097746b00867c7b00987c750097848101a7847c0097848101a88c860097848100 +776d6b0077646000795b5400675c5a00795b540077646000795b5400675c5a0077646000 +795b540087747000d2d4d600ffffff0ef4f6f900ecf3f500e0e4e700d8cccb00a88c8600 +97848106a88c8600978c8a00a88c8602a8949000a88c8601a8949000a88c8602a8949000 +a88c8601867c7b0077646000795b540077646000795b5400a4a5a400ffffff0ff4f6f900 +e8ecef00e0e4e700e6dcdc00b8adaa0097848100987c750097848100987c750097848104 +987c750097848100987c750097848101987c750097848102978c8a00a7847c0097848100 +a88c86009784810077646000675c5a00978c8a00a88c8600978c8a00a88c8600978c8a01 +a88c8600978c8a01a88c8600978c8a01a88c8600978c8a00a7847c00978c8a00a88c8600 +978c8a00a88c8601a8949001a88c8601776d6b00795b5400675c5a0077646000ffffff14 +f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500cbcccd00c4c5c501 +cbcccd00c4c5c501a89a9500a88c8600978c8a00a7847c00978c8a0097848100a88c8600 +97848100a88c8600978c8a00a7847c00978c8a0097848100a88c8600978c8a00a88c8600 +978c8a00a88c8609978c8a00a88c860097848100978c8a00a7847c00978c8a00a7847c00 +97848100978c8a0097848100a8949000ffffff18f4f6f900e8ecef01d9dcde00d2d4d601 +cbcccd00c4c5c501bbbcbd00c4c5c500bbbcbd01c6bcba00bbbcbd02a4a5a40087747000 +97848100a8949000a88c8603978c8a01a88c860097848100a7847c00978c8a0097848100 +978c8a00a88c8600978c8a00a88c8600978c8a00a88c8600978c8a00a88c8600978c8a00 +a88c8602a8949000a88c8600a8949000b8938b00a8949000b8938b00a8949001b8938b00 +a8949000a89a9500b99a9400a8949001a89a9500b99a9400a89a9500b99a9400a89a9500 +b99a9400a89a9500b99a9400a89a9500c4c5c500ffffff09f4f6f900ecf3f500e0e4e700 +d9dcde00d2d4d600c4c5c500bbbcbd01b4b4b402abacad00b4b4b401abacad0077646000 +675c5a00795b5400675c5a0077646000795b5400a88c8600a89a9500b99a9400a89a9500 +b99a9401a8949000b99a9401a8949000b99a9400b8938b00b99a9400a8949000b99a9401 +a89a9500b99a9400a89a9500b99a9401d8cccb00ffffff0ef4f6f900ecf3f500e0e4e702 +d9dcde00e0e4e701b4b4b400675c5a0055454109684f4900867c7b0097848103a8949000 +e0e4e701d9dcde00cbcccd00c4c5c500bbbcbd00b4b4b400a4a5a40487747000684f4900 +584c480055454100684f490055454100584c4800684f490055454100684f490055454100 +795b540097848100987c750097848100987c750097848100987c750097848106a7847c00 +978c8a0097848100a88c860097848100a88c860097848100d2d4d600e0e4e700d2d4d601 +c4c5c500bbbcbd00b4b4b400a4a5a4019c9e9c03675c5a0055454102684f490055454105 +684f49005545410077646000987c750297848100987c750197848104987c750097848100 +987c750097848100987c750097848100a7847c0097848101e6dcdc00ffffff10f4f6f900 +ecf3f500e8ecef00e0e4e700978c8a0077646000876d670077646000776d6b0077646001 +776d6b0077646000776d6b0077646000776d6b008a63580077646001776d6b0077646002 +776d6b00876d670077646001876d6700675c5a00584c4800684f4900584c4800684f4900 +584c4800684f4900584c4800684f4900584c4802684f4900584c480177646000bbbcbd00 +ffffff0cd9dcde00867c7b00876d6701776d6b00876d6700776d6b00876d6701776d6b00 +876d670087747000876d67008774700597746b0087747003876d67018774700177646000 +684f4902584c4800684f4900584c4804b4b4b400ffffff03f4f6f901e0e4e701d9dcde00 +d8cccb0097848100876d670787747004867c7b00987c750397848104876d6700675c5a00 +795b540077646000675c5a0077646000675c5a0077646000675c5a01795b540099939300 +f4f6f900ffffff0bf4f6f901e8ecef00c4c5c50097848101987c750097848100987c7500 +97848102a7847c0097848101a88c8600978c8a00a88c8600978c8a00a88c8600978c8a00 +a88c860199939300a88c860199939300a88c860077646004f4f6f900ffffff0ef4f6f900 +e8ecef00e0e4e700d9dcde00c6bcba0097848108867c7b00987c7500867c7b00987c7500 +867c7b00987c750097848100987c750097848101a7847c00978c8a01a88c8600776d6b00 +76524a00867c7b00c4c5c500a89a950097848100978c8a0097848100a88c8600978c8a00 +a88c8600978c8a00a88c8600978c8a00a88c8600978c8a00a88c8600978c8a00a88c8600 +97848100978c8a01a88c860099939300a88c8600a8949000a88c8600978c8a0077646000 +684f4900675c5a00867c7b00ffffff14e8ecef01d9dcde00d2d4d601d8cccb00c4c5c500 +cbcccd00c4c5c503bbbcbd0097848100a88c860097848101a88c860097848100a88c8600 +978c8a00a88c860097848100a88c860097848100a7847c0097848100978c8a00a7847c00 +978c8a0097848100978c8a03a88c8600978c8a00a88c860097848100978c8a0097848101 +a7847c00978c8a0097848100978c8a01a7847c00978c8a00e9d5d700ffffff19f4f6f900 +e8ecef00e0e4e700d9dcde00d2d4d600cbcccd01c4c5c502bbbcbd00c4c5c500bbbcbd01 +c4c5c500bbbcbd00c6bcba00b8adaa00776d6b0097848100a8949001a88c8600978c8a00 +a88c8600978c8a00a7847c0097848102a7847c0097848102a88c8600978c8a00a88c8600 +978c8a00a88c8601978c8a00a88c8600978c8a00a88c8600a8949000a88c8600a8949001 +a89a9500b99a9400a89a9501b99a9400a89a9500a8949001a89a9500b8938b00a89a9500 +b99a9400a8949000b99a9400a89a9500b99a9400a89a9500d7c4bd00ffffff0becf3f500 +e8ecef00d9dcde00d2d4d600c4c5c501bbbcbd00b4b4b404abacad00b4b4b40088848400 +795b5400675c5a0077646000795b5400675c5a00876d6700a8949001b99a9400a89a9500 +a8949000b99a9400a8949000a89a9500b99a9401a89a9500a8949000b99a9400a89a9500 +b99a9400a8949000b99a9401a8949000a89a9500b99a9400e6dcdc00ffffff0cecf3f501 +e0e4e701d9dcde00d2d4d601cbcccd008c8b8c005545410a684f490087747000987c7502 +97848100987c750088848400c4c5c500e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00 +b4b4b400a4a5a4048774700055454100684f490055454100684f4900584c4800684f4900 +55454100684f490055454100584c4800795b5400987c750097848101987c750097848100 +987c750097848100987c750197848104a88c860097848100978c8a01a88c8600978c8a00 +cbcccd00e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00abacad019c9e9c0476524a00 +5545410b795b5400867c7b00987c7500867c7b00987c750197848100987c750297848100 +987c750097848100987c750197848101987c750097848102d9dcde00ffffff11f4f6f900 +e8ecef01c6bcba00776d6b00776460028a635800776d6b008a63580077646006795b5400 +77646004776d6b0077646002795b5400584c4800684f4900584c4800684f4900584c4801 +684f4900584c4800684f490055454100584c480055454100584c48005545410187747000 +cbcccd00ffffff09c4c5c50087747000876d670077646000876d6700776d6b0077646000 +876d6700776d6b00876d670177747400876d670087747000876d670087747003867c7b00 +87747003876d670077747400876d67018774700077646000584c4804684f4900584c4801 +684f4900584c4800b4b4b400ffffff03f4f6f900ecf3f500e8ecef00e0e4e700d9dcde00 +d2d4d600b8adaa0077646000876d6700776d6b00876d6700776d6b00876d6701776d6b00 +876d670087747003987c750087747000867c7b0088848400987c750088848400987c7501 +97848101978c8a00987c750077646000675c5a00795b5400675c5a00795b5400675c5a00 +77646001675c5a0077646000675c5a009c9e9c00f7ece700ffffff08f4f6f901e0e4e700 +b7a4a00097848101867c7b0097848103987c7500978c8a0097848100978c8a00a88c8600 +978c8a00a88c8600978c8a00a88c8600a8949000978c8a00a88c8600978c8a00a88c8600 +99939300978c8a00a88c86008774700077646001675c5a0077646000a89a9500ffffff0e +f4f6f900e8ecef01e0e4e700cbcccd00978c8a0097848107987c7500867c7b00987c7500 +867c7b00987c7500867c7b009784810188848400987c750097848102a7847c0087747000 +684f4900675c5a00c4c5c500d8cccb00c6bcba00a88c8600978c8a0097848100978c8a00 +97848100a88c8600978c8a01a88c8600978c8a00a88c8600978c8a01a88c8600978c8a00 +a88c8601978c8a00a88c8600a894900099939300a88c8600978c8a0097848100675c5a00 +684f490199939300ffffff13f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd01 +c4c5c500cbcccd00c4c5c501d7c4bd00c4c5c500a894900097848104978c8a00a7847c00 +978c8a0197848101978c8a00a7847c0097848100978c8a0097848103a7847c00978c8a01 +a88c8600978c8a0097848106a7847c0097848101a8949000ffffff1bf4f6f900e8ecef00 +e0e4e700d9dcde01cbcccd01c4c5c501bbbcbd01c4c5c500bbbcbd03b4b4b400684f4901 +87747000978c8a01a7847c00978c8a0097848101978c8a0097848103a7847c00978c8a01 +a88c8600978c8a00a88c8600978c8a00a88c8600978c8a00a88c8600a894900199939300 +a8949003a89a9500a8949000a89a9500a8949000a89a9500b99a9400a89a9504b99a9400 +a89a9503a8949000e6dcdc00ffffff0aecf3f500e8ecef00e0e4e700d9dcde00cbcccd00 +c4c5c500bbbcbd00b4b4b401abacad00b4b4b403a4a5a400675c5a01684f4900675c5a00 +795b5400675c5a00a88c8600a8949004b99a9400a8949000a89a9500a8949000b99a9400 +a89a9500a8949000a89a9500a8949000a89a9500b99a9400a89a9500a8949000b99a9400 +a8949000a89a9500e0e4e700ffffff09ecf3f501e8ecef00e0e4e700d9dcde00d2d4d601 +cbcccd00abacad00636465005545410a77646000987c7500867c7b01987c7500867c7b00 +987c75019784810099939300e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd00b4b4b400 +a4a5a40477747400584c480055454100684f490055454100684f490055454100684f4900 +55454100684f4901675c5a0097848100987c750197848100867c7b0097848100987c7500 +8884840097848100987c750097848106978c8a0097848100978c8a00cbcccd00e0e4e700 +d9dcde00cbcccd00c4c5c500bbbcbd00b4b4b400a4a5a4009c9e9c0399939300675c5a00 +5545410b76524a0087747000987c750087747000987c7500867c7b0087747000867c7b00 +987c7500867c7b00987c7501867c7b02987c750088848400987c750097848100987c7500 +978c8a00e6dcdc00ffffff11f4f6f900ecf3f500e8ecef00e6dcdc00867c7b0077646004 +675c5a0077646000795b540077646002795b54007764600c684f4900584c480455454101 +584c480055454102584c48005545410277747400bbbcbd00ffffff05e0e4e700a89a9500 +77646000876d6700776d6b0177646000876d6700776d6b0077646000776d6b01876d6700 +776d6b00876d6700776d6b0087747000876d6700877470097774740087747000776d6b00 +77646000684f4900584c4801684f4900584c4805b4b4b400ffffff04f4f6f900e8ecef00 +e0e4e701d2d4d600cbcccd00867c7b00876d670077646000876d6701776d6b00876d6701 +776d6b0087747000876d670087747000876d670087747000867c7b0087747000867c7b00 +987c7500867c7b01888484009784810288848400987c750087747000675c5a0077646000 +675c5a0077646000675c5a03795b5400675c5a01978c8a00c4c5c500ffffff05f4f6f900 +ecf3f500c6bcba00978c8a0088848400987c75008884840097848100867c7b0097848100 +867c7b0097848104978c8a02a88c8600978c8a01a88c8600978c8a0099939300a88c8600 +978c8a00a88c8600978c8a0077646000675c5a0077646000675c5a0077646000f4f6f900 +ffffff0ee8ecef01e6dcdc00d2d4d600a8949000978c8a0097848103978c8a0097848101 +978c8a009784810088848400987c750088848400867c7b00987c7500867c7b00987c7500 +9784810188848400987c750097848100867c7b00684f490054545500b8adaa00cbcccd01 +c4c5c500b8adaa0097848100a88c860097848100a88c8600978c8a01a88c8600978c8a00 +a88c860099939300a88c8600978c8a00a88c8600978c8a00a88c8600978c8a00a88c8600 +99939300978c8a00a88c8600978c8a0287747000684f490054545500684f4900bbbcbd00 +ffffff12f4f6f901e0e4e700d9dcde00d2d4d600cbcccd01d8cccb00c4c5c501cbcccd00 +c4c5c501b8adaa0097848101978c8a0097848102978c8a0097848101a88c860097848103 +987c750097848101987c75009784810388848400987c750097848101987c750088848400 +987c750097848104d8cccb00ffffff1cf4f6f900e8ecef00e6dcdc00d9dcde00d2d4d600 +cbcccd00c4c5c503bbbcbd00c6bcba00bbbcbd00c4c5c500bbbcbd009c9e9c00584c4800 +684f4900584c480087747000a7847c00978c8a0097848100a88c8600978c8a00a7847c00 +97848100987c750097848101978c8a01a88c860199939300a88c860099939300a88c8600 +99939300a88c860099939300a8949001a89a9506b99a9400a89a9501a8949000b99a9400 +a89a9500b99a9400a89a9503a8949000b99a9400a89a9501e6dcdc00ffffff0aecf3f500 +e0e4e700d9dcde00cbcccd01bbbcbd01b4b4b403abacad00b4b4b401867c7b00684f4900 +675c5a0387747000a8949003a89a9501a8949000a89a9500a8949004b99a9400a8949000 +a89a9500a8949000a89a9500a8949003d2d4d600ffffff06ecf3f502e0e4e701d9dcde00 +d2d4d600cbcccd00abacad006a6c6e00584c480055454105463d3c0055454102684f4900 +876d6700987c7500867c7b00987c7500867c7b06c4c5c500d9dcde00d2d4d600c4c5c500 +bbbcbd00b4b4b400a4a5a4048774700055454100584c480055454104684f490055454100 +584c4800675c5a0097848101867c7b00987c7500867c7b0097848100867c7b00987c7500 +867c7b00987c750088848400987c75008884840097848102978c8a0097848100978c8a01 +cbcccd00e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400abacad009c9e9c03 +a89a9500675c5a00554541047c3a3c0055454105675c5a00867c7b0087747002867c7b00 +87747001867c7b0087747000867c7b0087747000867c7b00987c7500867c7b00987c7500 +867c7b0097848102978c8a00d9dcde00ffffff12f4f6f900e8ecef00e0e4e700b8adaa00 +77646001675c5a00795b5400675c5a0077646000795b54006364650077646000675c5a00 +77646000636465007764600d675c5a00584c480055454105584c480055454103584c4800 +4544450055454101684f490099939300cbcccd00ecf3f500e8ecef00b4b4b40087747000 +77646000776d6b0077646000776d6b0077646000776d6b0077646001776d6b01876d6700 +776d6b00876d6700777474008774700177747400877470007774740087747001867c7b00 +8774700077747400877470007774740087747000876d6700777474008774700077646000 +584c4803684f4900584c4800684f4900584c4800684f4900584c4800bbbcbd00ffffff04 +f4f6f901e8ecef00e6dcdc00d9dcde00d2d4d600b8adaa00876d6700776d6b00876d6700 +776d6b00876d6700776d6b00876d6700776d6b00876d6700776d6b008774700077747400 +876d670087747001867c7b0087747000867c7b00987c750188848400987c750097848103 +88848400876d6700675c5a00795b5400675c5a00795b5400675c5a0077646000675c5a00 +795b5400675c5a027764600088848400b8adaa00c4c5c500d9dcde00d2d4d600c4c5c500 +a88c860088848400867c7b00987c7500867c7b0097848100867c7b009784810288848400 +987c75008884840097848100978c8a01a88c8600978c8a01a8949000978c8a01a88c8600 +978c8a02a88c8600867c7b0077646000675c5a0077646000675c5a00b4b4b400ffffff0e +ecf3f500e8ecef00e0e4e700d9dcde00a4a5a400a88c8600978c8a0197848100978c8a00 +97848101978c8a009784810388848400987c7500867c7b01978481008884840097848102 +88848400867c7b00675c5a00684f490097848100d2d4d600cbcccd03a89a950097848100 +978c8a0097848100978c8a00a88c8600978c8a01a88c8600978c8a00a894900099939300 +978c8a00a894900099939300a88c860099939300978c8a00a88c8600978c8a0297848101 +776d6b00684f4900584c480054545500e6dcdc00ffffff12ecf3f500e8ecef00e0e4e700 +d9dcde00d2d4d600cbcccd00c4c5c500cbcccd00c4c5c501cbcccd00c4c5c50197848101 +987c750097848100978c8a009784810688848400867c7b00987c7500867c7b02987c7500 +88848400987c750088848400987c7500867c7b03987c7500867c7b029784810088848400 +97848100ffffff1df4f6f900ecf3f500e8ecef00d9dcde01d2d4d600cbcccd00c4c5c501 +bbbcbd03c6bcba00bbbcbd00867c7b00584c480287747000978c8a0097848100a88c8600 +978c8a0097848104978c8a00a88c8600978c8a00a88c860099939300a88c860099939300 +a88c860099939300a894900099939300a894900199939300a8949000a89a9500a8949000 +a89a9504a8949000a89a9503a8949000a89a9500a8949000a89a9504a8949000a89a9500 +e0e4e700ffffff09ecf3f500e8ecef00e0e4e700d2d4d600cbcccd00c4c5c500bbbcbd00 +b4b4b406a4a5a400675c5a01684f4900675c5a00684f4900675c5a00a8949004a89a9502 +a8949000a89a9500a8949001a89a9500a8949002a89a9500a8949005c6bcba00f4f6f900 +ffffff01f4f6f900ecf3f501e8ecef00e0e4e701d9dcde00d2d4d600b4b4b4008c8b8c00 +675c5a0045444500584c480055454109795b5400867c7b0387747000867c7b00987c7500 +867c7b00987c7500867c7b00987c7500867c7b00a4a5a400d9dcde00cbcccd00c4c5c500 +bbbcbd00b4b4b400a4a5a40477747400584c4804684f490055454102684f4900675c5a00 +987c7500867c7b01987c7500867c7b01987c7500867c7b0088848400987c7500867c7b01 +978481008884840097848105cbcccd00e0e4e700d2d4d601c4c5c500bbbcbd00b4b4b400 +a4a5a4009c9e9c04675c5a00463d3c0055454100463d3c0055454100463d3c0055454106 +76524a00867c7b00987c750087747000867c7b0087747001867c7b0087747001867c7b00 +87747001867c7b0197848100867c7b0097848101978c8a01e6dcdc00ffffff12f4f6f900 +ecf3f500e8ecef00d9dcde007774740077646000675c5a0077646000675c5a0077646000 +675c5a0177646000675c5a0077646003675c5a0077646000675c5a00795b540063646500 +77646002776d6b0077646000776d6b0177646001675c5a00584c480155454100584c4800 +5545410345444500554541004544450055454101454445005545410045444500584c4800 +776d6b00867c7b008774700077646000776d6b0077646000776d6b0077646000876d6700 +776d6b0277646000876d6700776d6b03876d670077747400877470027774740087747001 +867c7b0187747000867c7b0087747000777474008774700177646000584c4802684f4900 +584c480054545500684f4900584c480054545500684f4900b4b4b400ffffff05f4f6f900 +e8ecef00e0e4e701d2d4d600cbcccd00867c7b0087747001876d670077747400876d6700 +776d6b0087747000776d6b00877470007774740087747003867c7b01987c750088848401 +987c7500888484008c8b8c00978481008c8b8c00978481028c8b8c008774700077646000 +63646500675c5a0963646500876d6700867c7b0097848100867c7b0088848400987c7500 +88848400867c7b0088848400987c75008884840097848100888484009784810088848400 +97848102978c8a01a88c8600978c8a04a88c8600978c8a00999393009784810077646001 +675c5a0187747000ffffff0ef4f6f900e8ecef00e0e4e700d9dcde00b8adaa0097848100 +978c8a00a7847c00978c8a0197848100978c8a0097848100978c8a0097848100978c8a00 +978481018884840097848100867c7b0097848100888484009784810288848400987c7500 +77646000584c4800776d6b00cbcccd05c4c5c50097848101978c8a0097848100978c8a0f +97848102867c7b00675c5a00584c4801675c5a00ffffff12f4f6f901e0e4e700d9dcde00 +d2d4d600d8cccb00cbcccd00c4c5c500cbcccd00c4c5c503a4a5a400867c7b0097848100 +8884840097848102978c8a0097848100978c8a0097848101867c7b0097848100867c7b01 +987c7500867c7b01987c7500867c7b0cc6bcba00ffffff1ef4f6f900e8ecef00e0e4e700 +d9dcde00d2d4d600cbcccd00c4c5c501bbbcbd01c4c5c500bbbcbd02675c5a00584c4801 +684f4900867c7b0097848100978c8a02a88c8600978c8a0397848100978c8a00a88c8600 +978c8a00a8949000978c8a00a894900099939300a894900099939300a894900199939300 +a8949000a89a9500a8949000a89a9500a8949000a89a9500a8949000a89a9500a8949000 +a89a9503a8949000a89a950af4f6f900ffffff08f4f6f900ecf3f500e0e4e700d9dcde00 +cbcccd00c4c5c500bbbcbd01b4b4b401abacad00b4b4b401abacad00b4b4b400867c7b00 +675c5a01684f4900675c5a018774700099939301a8949001a89a9501a8949000a89a9500 +a8949000a89a9500a8949000a89a9500a8949000a89a9500a8949001a89a9500a8949000 +a89a950099939300a8949000978c8a0099939300b8adaa00e0e4e700ecf3f501e8ecef00 +e0e4e700d2d4d600bbbcbd009c9e9c007b7b7d00585c5e00554541004544450055454100 +584c480055454100584c480055454100584c480055454100584c480055454101584c4800 +795b540087747000867c7b0387747000867c7b0187747000867c7b0087747000867c7b00 +87747000867c7b0088848400cbcccd00d2d4d600c4c5c500bbbcbd00abacad01a4a5a403 +87747000584c480055454101584c480055454100584c4804675c5a009784810088848400 +97848100867c7b0097848100867c7b0088848400987c7500867c7b01987c750088848400 +97848102978c8a018c8b8c0097848100978c8a00c4c5c500e0e4e700d9dcde00d2d4d600 +c4c5c500bbbcbd00b4b4b400a4a5a4019c9e9c03684f4900463d3c0155454100463d3c00 +55454101463d3c0155454103684f4900867c7b0297746b00867c7b0187747004867c7b00 +87747000867c7b00987c75008884840097848102978c8a00d9dcde00ffffff12f4f6f900 +ecf3f500e8ecef00e0e4e700b8adaa00675c5a00776460006364650077646000675c5a00 +776460006364650077646000675c5a007764600063646500776460006364650077646000 +63646500776460006364650077646001636465007764600063646500776460006a6c6e00 +776460006364650077646002675c5a00584c480145444500554541004544450055454105 +584c4800675c5a0077646000877470007774740087747000776d6b0077747400876d6700 +776d6b0277646000776d6b00876d6700776d6b02876d6700776d6b0087747000776d6b00 +77747400877470007774740087747000777474008774700077747400877470007b7b7d00 +87747000867c7b0087747000867c7b01877470007b7b7d00776d6b00584c4800684f4900 +54545500584c4800684f490054545500584c4800675c5a00584c480054545500c6bcba00 +ffffff05f4f6f900ecf3f500e8ecef00d9dcde01d2d4d600b4b4b400776d6b0087747000 +777474008774700177747400876d670077747400877470027b7b7d00867c7b0187747000 +867c7b02987c750088848401987c750097848101978c8a0097848102978c8a0097848100 +8884840087747000776d6b0077646000675c5a0077646000675c5a0077646000776d6b00 +87747000867c7b00978481008884840097848100867c7b009784810088848400867c7b01 +987c7500867c7b0088848400867c7b0088848400987c750088848400978481008c8b8c00 +88848400978c8a0b87747000675c5a03d2d4d600ffffff0df4f6f900e8ecef00e0e4e700 +e6dcdc00c6bcba00978c8a0297848100978c8a0097848100978c8a0097848100978c8a00 +97848101888484009784810088848401987c750088848400987c75008884840097848100 +8884840097848101776d6b00584c4800684f4900bbbcbd00d2d4d602cbcccd03b8adaa00 +8884840097848102978c8a0d97848100978c8a0088848400978481008884840087747000 +584c480055454100584c480077747400ffffff12ecf3f500e8ecef00e0e4e700d9dcde00 +d2d4d600cbcccd01c4c5c501cbcccd00c4c5c500cbcccd00c6bcba00978c8a0088848400 +97848101978c8a01978481008c8b8c00978c8a0097848100888484009784810088848400 +867c7b0088848400867c7b0188848400867c7b0088848400987c7500867c7b0187747003 +867c7b0087747000867c7b01987c7500ffffff20ecf3f500e8ecef00d9dcde01cbcccd01 +c4c5c500c6bcba00bbbcbd03a4a5a40055454101584c4800684f4900978c8a0097848100 +978c8a0097848100978c8a0397848100978c8a0399939300978c8a00a8949000978c8a00 +a8949000978c8a00a894900099939301a894900099939300a89490009c9e9c00a8949000 +9c9e9c00a8949000a89a9500a8949000a89a9501a8949000a89a9506a8949000a89a9504 +a8949000a4a5a400ffffff09ecf3f500e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500 +bbbcbd00b4b4b403abacad00b4b4b401a4a5a400675c5a00584c4800675c5a0054545500 +675c5a01978c8a00a894900099939300a89a9500a8949000a89a9500a8949000a89a9500 +99939300a894900099939300a89a950099939300a89a950099939300a89a95009c9e9c00 +a894900099939300a894900099939300a8949000978c8a01a89a95009c9e9c0088848400 +777474006a6c6e00584c480355454100584c480055454101454445005545410145444500 +55454101584c4800675c5a0077646000867c7b0188848400987c7500867c7b0087747001 +867c7b0087747001867c7b0087747001867c7b0087747000867c7b0097848100abacad00 +d2d4d600c4c5c500bbbcbd00b4b4b400a4a5a40477747400584c480255454100584c4800 +55454102584c480055454100675c5a0097848100867c7b009784810088848400867c7b00 +97848100867c7b008884840097848100867c7b0088848400978481008c8b8c0097848100 +8c8b8c00978c8a00978481018c8b8c0097848100cbcccd00e0e4e700d9dcde00cbcccd00 +c4c5c500bbbcbd00b4b4b400a4a5a4009c9e9c02999393009c9e9c0054545500463d3c05 +55454100463d3c0055454100463d3c0055454101684f4900867c7b0187747000867c7b01 +87747000867c7b0387747000867c7b0288848400867c7b0097848101978c8a0097848100 +e0e4e700ffffff13f4f6f900ecf3f500e0e4e700d9dcde007b7b7d007764600163646500 +77646000675c5a0077646000675c5a007764600063646500795b540063646500675c5a00 +77646000675c5a0177646000675c5a007764600063646500776460006364650077646000 +636465007764600263646500776d6b00675c5a0077646000675c5a02684f490054545500 +684f490054545500585c5e00675c5a0077646000776d6b0077747401867c7b0087747000 +7774740087747000876d6700776d6b0487747000776d6b0077747400876d6700776d6b06 +8774700077747401877470007b7b7d008774700077747400867c7b06776d6b00684f4900 +54545500684f490054545500684f490054545500684f490054545500684f490054545500 +bbbcbd00ffffff06f4f6f900e8ecef01d9dcde00d2d4d600d8cccb00978c8a00776d6b00 +8774700077747400877470007774740087747000777474008774700077747400867c7b03 +88848400867c7b0088848400987c750088848401987c7500888484008c8b8c0097848100 +8c8b8c00978481008c8b8c00888484008c8b8c0097848101888484009784810088848400 +978481008884840197848100867c7b0188848400987c750088848400867c7b0097848100 +888484019784810088848400867c7b0488848403978481008884840097848100978c8a08 +9784810063646500675c5a02a89a9500ffffff0df4f6f900e8ecef01d9dcde00cbcccd00 +99939300978c8a0097848100978c8a0197848100978c8a0197848101978c8a0097848100 +978c8a0097848101888484009784810088848400978481008884840097848100867c7b00 +88848400867c7b00684f4900584c48009c9e9c00d9dcde01d2d4d601d8cccb00cbcccd02 +c4c5c500a89a95008884840297848100978c8a0097848100978c8a0597848100978c8a00 +97848100978c8a0088848400978c8a0097848100888484009784810088848400867c7b00 +776d6b00584c4800554541019c9e9c00ffffff12e8ecef00e0e4e700d9dcde00d2d4d600 +d8cccb00c4c5c500d8cccb00c4c5c504a4a5a40097848100978c8a0897848100867c7b00 +97848100867c7b0097848100867c7b067b7b7d00877470007b7b7d007774740087747000 +7774740087747001b8adaa00ffffff20ecf3f500e8ecef00e0e4e700d2d4d601cbcccd00 +c4c5c500bbbcbd01c4c5c500bbbcbd00c6bcba0088848400554541004544450055454100 +63646500867c7b008884840097848101978c8a09a894900099939303978c8a00a8949000 +99939300a894900099939300978c8a00999393009c9e9c00a89490019c9e9c00a8949000 +9c9e9c00a89a950099939300a89a950099939300a89a950099939300a89a950099939300 +a89a950199939300a89a950199939300a89a9501a8949000b8adaa00ffffff08ecf3f500 +e8ecef00e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd00b4b4b401abacad00b4b4b403 +abacad008c8b8c00684f490054545500684f4900584c4800675c5a0087747000978c8a01 +99939308a894900099939300a89a950099939300a89490009c9e9c00a89a9500a8949000 +99939302978c8a0099939300978c8a01867c7b0077646000675c5a00584c480855454100 +675c5a01776d6b0087747000867c7b0188848400867c7b0587747000867c7b0087747000 +867c7b0087747000867c7b0087747000867c7b01888484008c8b8c00cbcccd00c4c5c500 +bbbcbd00b4b4b400abacad00a4a5a40377747400584c480055454100584c480455454100 +584c4801675c5a009784810088848400867c7b0097848101888484009784810188848400 +97848100888484008c8b8c0097848100978c8a03978481008c8b8c0088848400c4c5c500 +e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400abacad009c9e9c03a89a9500 +675c5a00463d3c0b545455008774700077747400877470007774740087747001867c7b00 +87747002867c7b0288848400987c7500867c7b0088848402978c8a00d9dcde00ffffff13 +f4f6f900ecf3f500e8ecef00e0e4e700b4b4b40063646500776460006364650077646000 +63646500675c5a0b6364650077646000675c5a0077646000675c5a007764600063646500 +675c5a006364650077646000675c5a00776d6b00675c5a00776d6b00675c5a0077646000 +6a6c6e00776460006a6c6e0077646000776d6b0277747400877470007774740087747000 +7b7b7d00867c7b0077747402876d670077747400776d6b00877470007774740187747000 +776d6b0487747000776d6b0077747400776d6b00877470007774740287747000867c7b01 +77747400867c7b0287747000867c7b00776d6b0054545500684f4900585c5e00684f4900 +54545500684f4900585c5e00684f490054545500684f4900bbbcbd00ffffff06f4f6f900 +ecf3f500e0e4e701d9dcde00d2d4d600bbbcbd0087747000777474008774700077747400 +87747000777474008774700077747400867c7b00877470007b7b7d00867c7b02987c7500 +88848402987c7500888484019784810088848400978481008c8b8c009784810088848400 +97848100888484029784810088848403867c7b0088848400867c7b0088848400867c7b00 +888484009784810088848400867c7b0088848400867c7b06978481008884840097848100 +8884840197848100978c8a09776d6b00675c5a027b7b7d00ffffff0df4f6f900ecf3f500 +e0e4e701d2d4d600a8949000978c8a0097848101978c8a04978481008c8b8c0097848100 +8c8b8c009784810088848400978481008884840097848100888484009784810088848401 +867c7b01675c5a00584c48007b7b7d00e0e4e701d9dcde01d2d4d601cbcccd03c4c5c500 +978c8a0088848401978481008c8b8c00978c8a0788848400978481008c8b8c0097848100 +978c8a0088848403867c7b01675c5a00584c48004544450055454100c4c5c500ffffff11 +ecf3f500e8ecef00d9dcde01d2d4d600cbcccd00c4c5c501d8cccb00c4c5c500cbcccd00 +c4c5c500c6bcba00978c8a0088848400978c8a018c8b8c00978c8a038c8b8c0088848401 +867c7b05877470007b7b7d00867c7b0087747000867c7b00777474008774700077747400 +87747000777474008774700077747400ffffff21f4f6f900ecf3f500e0e4e700d9dcde00 +d2d4d600c4c5c502bbbcbd01c4c5c500bbbcbd0063646500463d3c0055454101776d6b00 +88848400867c7b00978481008884840097848101978c8a02a88c8600978c8a02a88c8600 +99939300978c8a00a88c860099939300a894900099939300a894900099939302a8949000 +99939300a8949000999393009c9e9c00a894900099939300a894900099939300a89a9500 +9c9e9c00a89a950199939300a89a950199939300a89a950199939300a89a950099939300 +a89a950099939300a89a95009c9e9c00c4c5c500ffffff08ecf3f500e0e4e700d9dcde00 +d2d4d600cbcccd00c4c5c500bbbcbd00b4b4b402abacad00b4b4b402abacad006a6c6e00 +684f4900585c5e00684f490054545500675c5a008884840099939300978c8a0199939300 +a894900099939301a894900099939304a89a950099939300a89a950099939302a8949000 +978c8a0099939300978c8a0099939300978c8a0388848400867c7b00776d6b006a6c6e00 +63646500776460006a6c6e00776d6b0077747400867c7b0b87747000867c7b0087747000 +777474008774700077747400867c7b0077747400867c7b0188848400867c7b0097848100 +b4b4b400c4c5c500bbbcbd00b4b4b400a4a5a40477747400584c48034a4c4d00584c4803 +55454100675c5a0088848400867c7b00978481008884840097848100978c8a008c8b8c00 +888484009784810088848400978481018c8b8c00978c8a028c8b8c0188848401c4c5c500 +e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400a4a5a4009c9e9c0454545500 +463d3c0155454100463d3c08684f49007774740087747000777474008774700077747401 +8774700077747400867c7b017b7b7d00867c7b0288848400867c7b009784810088848401 +97848100d9dcde00ffffff14f4f6f900e8ecef01e0e4e7008c8b8c007764600063646500 +675c5a0263646500675c5a0363646500675c5a02636465007764600063646500675c5a01 +63646501675c5a0463646500675c5a006364650177646000636465007764600063646500 +776460006a6c6e0077646000776d6b02777474017b7b7d00877470007b7b7d0087747000 +777474008774700077747403776d6b0177747400776d6b0277747400776d6b0177747401 +776d6b0077747400776d6b01877470007774740187747000867c7b047b7b7d00776d6b00 +684f490054545501684f490054545501684f4900585c5e00684f490054545500bbbcbd00 +ffffff07ecf3f500f7ece700e0e4e700d9dcde01d2d4d600a4a5a400776d6b0077747401 +87747000776d6b0077747400867c7b00877470007b7b7d00867c7b0087747000867c7b05 +88848403978481008884840a97848100867c7b008884840197848100867c7b0088848401 +867c7b0088848400867c7b0088848400867c7b0888848400987c7500888484018c8b8c00 +88848400978c8a008c8b8c0097848100978c8a0197848100978c8a0087747000675c5a02 +63646500e8ecef00ffffff0de8ecef02d2d4d600a4a5a400978c8a018c8b8c0097848100 +978c8a0197848100978c8a00978481008c8b8c00978c8a009784810088848400978c8a00 +888484009784810088848400978481008884840197848100867c7b01776d6b00584c4800 +675c5a00d9dcde00e8ecef01e0e4e700e6dcdc00d9dcde00d2d4d600cbcccd00d8cccb00 +cbcccd02b4b4b4009784810088848401978c8a07978481008c8b8c00978c8a0088848400 +8c8b8c009784810088848401987c750088848400867c7b0177747400675c5a00584c4800 +5545410054545500e8ecef00ffffff10f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600 +cbcccd02c4c5c504a4a5a400978481008c8b8c00978c8a018c8b8c00978c8a008c8b8c01 +9784810088848400867c7b0477747400867c7b007b7b7d0087747000867c7b0077747400 +877470007774740387747000777474009c9e9c00ffffff22e8ecef01d9dcde00d2d4d600 +cbcccd00c4c5c500c6bcba00c4c5c502b4b4b40055454100463d3c0155454100867c7b01 +88848401978481008c8b8c0097848100978c8a0499939300978c8a0099939300978c8a00 +99939301a89a950099939300a89a950099939301a894900099939303a89a950099939300 +a89a9500999393009c9e9c00a89a950099939300a89a950099939301a89a950099939300 +a894900099939302a89a950099939300a89a950099939300a89a950099939301a8949000 +e8ecef00ffffff07ecf3f501e0e4e700d2d4d600cbcccd00c4c5c500bbbcbd00b4b4b405 +abacad00b8adaa009c9e9c00675c5a0054545501684f490054545500776d6b00978c8a00 +a8949000978c8a009993930ca894900099939301978c8a0099939300978c8a048c8b8c01 +978c8a008c8b8c00978481008884840097848100888484019784810088848401867c7b00 +88848400867c7b0c77747401867c7b04888484008c8b8c009c9e9c00c4c5c500bbbcbd00 +b4b4b400a4a5a40477747400584c48014a4c4d00584c480345444500584c4801675c5a00 +9784810088848400978481008884840397848100888484028c8b8c00978c8a018c8b8c00 +978c8a0288848401c4c5c500e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400 +a4a5a4019c9e9c03684f4900463d3c0a55454100545455008774700077747400776d6b00 +7774740187747000777474027b7b7d0087747000867c7b0388848400867c7b0088848402 +d9dcde00ffffff15f4f6f900e8ecef00e0e4e700cbcccd0063646500675c5a0963646500 +675c5a056364650077646000675c5a016364650077646000675c5a006364650077646000 +675c5a0077646000675c5a006a6c6e0063646500776d6b00776460006a6c6e00776d6b00 +6a6c6e00776d6b01777474018774700077747401877470007774740387747000776d6b00 +77747400776d6b0077747400776d6b0277747400776d6b0177747400776d6b0087747000 +77747400776d6b0177747400776d6b0077747402867c7b0077747400867c7b03776d6b00 +54545500684f4900675c5a0054545500675c5a00684f4900585c5e00584c4800585c5e00 +684f4900bbbcbd00ffffff08ecf3f500e8ecef00e0e4e700d9dcde00d2d4d600d8cccb00 +8884840077747400776d6b00777474018774700077747401867c7b0077747400867c7b00 +7b7b7d0087747000867c7b0488848400867c7b0088848404867c7b0088848400867c7b00 +97848100867c7b0088848400867c7b0088848402867c7b0088848400867c7b0588848400 +867c7b0188848401867c7b0288848400867c7b0088848401867c7b008884840197848100 +978c8a0088848400978c8a008c8b8c01978c8a008c8b8c00867c7b00675c5a03d2d4d600 +ffffff0df4f6f900e8ecef00e0e4e700d9dcde00b8adaa00978c8a078c8b8c00978c8a00 +978481008c8b8c01978481008c8b8c00978c8a008c8b8c00978481008c8b8c0097848100 +88848400867c7b008884840087747000584c480054545500bbbcbd00f4f6f900e8ecef02 +e0e4e700d9dcde01d2d4d601cbcccd03a4a5a40088848402978c8a008c8b8c00978c8a03 +8c8b8c00978c8a008c8b8c00978481008c8b8c0088848404867c7b0088848400867c7b01 +77747400584c48015545410063646500ffffff11ecf3f500e8ecef00d9dcde00d2d4d601 +cbcccd00c4c5c501cbcccd00c4c5c502bbbcbd00888484008c8b8c00978c8a008c8b8c00 +978c8a008c8b8c00978c8a0088848403867c7b017b7b7d00867c7b02777474007b7b7d00 +77747400877470007774740187747000776d6b007774740187747000e8ecef00ffffff22 +ecf3f500e8ecef00d9dcde01cbcccd00c4c5c502cbcccd019c9e9c00463d3c02684f4900 +7b7b7d0087747000867c7b0088848402978481008c8b8c00978c8a0299939300a8949000 +a4a5a400abacad00b8adaa00b4b4b401bbbcbd02b4b4b401abacad00a4a5a400a8949000 +a89a9500999393009c9e9c00999393009c9e9c0099939300a89a950099939302a89a9500 +99939304a894900099939308a89a9500ffffff08ecf3f500e0e4e700d9dcde00d2d4d600 +cbcccd00c4c5c500bbbcbd00b4b4b402abacad00b4b4b401abacad00b4b4b40088848400 +584c480154545500684f4900585c5e0088848400978c8a0099939302978c8a0099939300 +978c8a0099939300978c8a0099939305978c8a0099939301978c8a028c8b8c00978c8a00 +8c8b8c01978c8a0088848400978c8a00888484008c8b8c0088848402867c7b0088848400 +867c7b0188848401867c7b097b7b7d00877470007b7b7d0087747000867c7b0077747400 +867c7b0288848401978481008c8b8c00b4b4b400bbbcbd00b4b4b400abacad00a4a5a403 +77747400584c48004a4c4d00584c480055454100584c4805675c5a0088848401867c7b00 +888484019784810088848400978481008c8b8c00978481008c8b8c00978481008c8b8c00 +978c8a028c8b8c00978481008c8b8c0088848400c4c5c500e0e4e700d9dcde00cbcccd00 +c4c5c500bbbcbd00b4b4b400a4a5a4009c9e9c02a89a95009c9e9c0054545500463d3c08 +55454100463d3c01684f490077747402776d6b0077747400776d6b007774740287747000 +777474007b7b7d0087747000867c7b0488848401d9dcde00ffffff15f4f6f901e0e4e701 +a4a5a400675c5a02585c5e00675c5a00585c5e00675c5a00585c5e00675c5a0163646500 +675c5a0863646500675c5a0063646500675c5a0363646501675c5a007764600063646500 +776d6b0063646500776d6b00776460006a6c6e00776d6b01777474018774700077747400 +7b7b7d00867c7b007774740087747000777474018774700077747401776d6b016a6c6e00 +776d6b0177747401776d6b0077747401776d6b0077747401776d6b017774740187747000 +77747400867c7b04776d6b0054545500675c5a0054545500584c480054545501684f4900 +54545500584c480054545500bbbcbd00ffffff08f4f6f900e8ecef00e0e4e700e6dcdc00 +d9dcde00d2d4d600c4c5c50087747000776d6b01777474008774700077747400867c7b02 +877470007b7b7d00867c7b007b7b7d00867c7b007b7b7d00867c7b0188848400867c7b00 +88848400867c7b0088848400867c7b01888484059784810088848400867c7b0088848400 +867c7b0088848400867c7b037b7b7d00867c7b0588848401867c7b06888484028c8b8c00 +9784810088848400978c8a00888484008c8b8c0077646000585c5e00675c5a01d2d4d600 +ffffff0df4f6f900e8ecef00e0e4e700d9dcde00c6bcba00978c8a048c8b8c00978c8a00 +8c8b8c00978c8a008c8b8c0088848400978c8a0088848400978c8a00888484018c8b8c00 +9784810088848404867c7b00675c5a0054545500978c8a00ffffff02f4f6f900e8ecef01 +e0e4e700d9dcde00d2d4d601cbcccd03c4c5c500978c8a00888484009784810088848400 +8c8b8c00978c8a00999393008c8b8c00978c8a0088848400978c8a00888484008c8b8c00 +978c8a0097848100888484009784810088848400867c7b0088848400867c7b03776d6b00 +584c48005545410045444500867c7b00ffffff10f4f6f900e8ecef00e0e4e700d9dcde00 +d2d4d600cbcccd01c4c5c501cbcccd00c4c5c5029c9e9c00888484008c8b8c0099939300 +978c8a0188848400978c8a0088848401867c7b0288848401867c7b007b7b7d00867c7b01 +77747403776d6b0077747400776d6b007774740099939300ffffff23ecf3f500e8ecef00 +e0e4e700d9dcde00d2d4d602cbcccd00d2d4d601867c7b00463d3c026364650077747400 +867c7b0288848402978c8a0099939300abacad00bbbcbd00c4c5c500cbcccd00c4c5c502 +bbbcbd00c4c5c500bbbcbd00b4b4b400bbbcbd00b4b4b400bbbcbd00b4b4b400bbbcbd00 +b4b4b400abacad0099939301a894900099939300a89a950099939304978c8a0a99939304 +c4c5c500ffffff07ecf3f501e0e4e700d2d4d600cbcccd00c4c5c500bbbcbd01b4b4b401 +abacad00b4b4b401abacad00b4b4b400abacad0077747400584c480154545500584c4800 +675c5a00978c8a0299939307978c8a0099939300978c8a0199939301978c8a008c8b8c00 +978c8a008c8b8c02978c8a008c8b8c01978c8a008c8b8c00978c8a008c8b8c0097848100 +88848403867c7b0288848400867c7b007b7b7d00867c7b007b7b7d00867c7b0777747401 +7b7b7d00867c7b007b7b7d00867c7b02888484018c8b8c00a4a5a400bbbcbd00b4b4b400 +a4a5a40477747400584c48024a4c4d00584c48004a4c4d00584c48004a4c4d00584c4801 +675c5a0088848400867c7b008884840097848100867c7b00888484008c8b8c0297848100 +8c8b8c01978c8a018c8b8c00978c8a008c8b8c0188848401c4c5c500e0e4e700d9dcde00 +d2d4d600c4c5c500bbbcbd00b4b4b400abacad009c9e9c04584c4800463d3c0135343400 +463d3c0535343400463d3c015454550077747400776d6b0077747400776d6b0177747400 +776d6b0277747400776d6b0077747400776d6b0077747402867c7b0288848400d9dcde00 +ffffff16ecf3f500e8ecef01d9dcde008884840054545500675c5a0054545500675c5a01 +54545500675c5a03585c5e01675c5a0054545500675c5a00585c5e00675c5a0463646500 +7764600063646500675c5a00636465007764600063646500776460006a6c6e0063646500 +7764600063646500776d6b0063646500776d6b006a6c6e00776d6b0177747402867c7b00 +77747401867c7b0077747404776d6b0077747400776d6b016a6c6e00776d6b0077747401 +87747000777474008774700077747400776d6b0077747400776d6b008774700077747400 +867c7b017b7b7d00867c7b017b7b7d00867c7b00776d6b0054545500584c4800684f4900 +585c5e00584c480054545502584c480054545500bbbcbd00ffffff09f4f6f900e8ecef00 +e0e4e700d9dcde01d2d4d600b4b4b400776d6b0177747401867c7b00777474007b7b7d01 +867c7b007b7b7d00877470007b7b7d0077747400867c7b0077747400867c7b0588848400 +867c7b0288848400867c7b0088848401867c7b0088848400867c7b017b7b7d0077747400 +867c7b007b7b7d00777474007b7b7d0077747400867c7b007b7b7d01867c7b007b7b7d00 +867c7b01888484007b7b7d00888484007b7b7d0088848402867c7b00888484038c8b8c01 +88848400978c8a00776d6b00585c5e00675c5a006a6c6e00d2d4d600ffffff0df4f6f900 +e8ecef01e6dcdc00cbcccd00999393008c8b8c03978c8a008c8b8c00978c8a008c8b8c00 +978c8a008c8b8c00978c8a008c8b8c0088848400978c8a0088848400978481008c8b8c00 +88848403867c7b0088848400776d6b00584c48006a6c6e00f4f6f900ffffff03f4f6f900 +e8ecef01e6dcdc00d9dcde00d2d4d601d8cccb00cbcccd02bbbcbd0088848401978c8a00 +8c8b8c00978c8a008c8b8c00978c8a008c8b8c01888484009784810088848403867c7b01 +88848400867c7b0277747400867c7b00777474006a6c6e0045444501463d3c009c9e9c00 +ffffff0ff4f6f901e0e4e700e6dcdc00d2d4d600d8cccb00cbcccd00c4c5c503d7c4bd00 +c4c5c500b4b4b400978c8a008c8b8c03978c8a008c8b8c0088848404867c7b0088848401 +867c7b007b7b7d0087747000777474008774700077747403776d6b0077747400d9dcde00 +ffffff23ecf3f500e8ecef00e0e4e700d9dcde01d2d4d602d9dcde0154545500463d3c01 +55454100776d6b00867c7b0288848402a89a9500bbbcbd00d9dcde02d2d4d601cbcccd01 +c4c5c502bbbcbd04b4b4b401bbbcbd00b4b4b401867c7b008884840099939302a89a9500 +99939303978c8a0099939300978c8a008c8b8c01978c8a0099939300978c8a0499939303 +f4f6f900ffffff07ecf3f500e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd00 +b4b4b404abacad00b4b4b401abacad006a6c6e004a4c4d00584c48004a4c4d00584c4800 +636465008c8b8c00978c8a0399939301978c8a0099939300978c8a0299939300978c8a00 +8c8b8c00978c8a028c8b8c01978481008c8b8c0088848400978c8a008c8b8c0197848100 +8c8b8c0088848402867c7b017b7b7d00867c7b017b7b7d00867c7b007b7b7d00867c7b00 +7b7b7d00867c7b017b7b7d00867c7b007b7b7d00867c7b007b7b7d00867c7b0388848406 +978c8a008c8b8c00978c8a00b4b4b401a4a5a4047774740054545500584c48024a4c4d00 +584c48024a4c4d00584c48006364650088848404978481008c8b8c00978481008c8b8c01 +978481008c8b8c00978c8a008c8b8c00978c8a008c8b8c00888484009784810088848400 +867c7b00cbcccd00e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400a4a5a400 +9c9e9c0454545500463d3c0235343400463d3c0135343400463d3c04584c480077747401 +776d6b0077747401776d6b0177747400776d6b0077747401776d6b00777474037b7b7d01 +867c7b01d9dcde00ffffff16f4f6f901e8ecef00e0e4e700d2d4d60077747400675c5a02 +585c5e00675c5a0163646500675c5a00585c5e00675c5a0154545500675c5a0054545500 +675c5a0054545500675c5a0063646500675c5a0063646501675c5a0063646501675c5a01 +6364650177646000636465017764600063646503776d6b0077747400776d6b0077747402 +7b7b7d00867c7b007b7b7d00777474018774700077747402776d6b0077747402776d6b01 +77747403776d6b0077747403867c7b00777474007b7b7d0077747400867c7b007b7b7d00 +867c7b007b7b7d00776d6b0054545502584c480054545501684f490054545501584c4800 +bbbcbd00ffffff09f4f6f901e8ecef00e0e4e700d9dcde00d2d4d601a4a5a4006a6c6e00 +776d6b007774740287747000777474007b7b7d00777474007b7b7d01877470007b7b7d00 +867c7b007b7b7d00867c7b007b7b7d00888484007b7b7d00867c7b0688848400867c7b02 +7b7b7d01777474008774700077747405867c7b00777474007b7b7d00867c7b007b7b7d01 +867c7b007b7b7d00867c7b007b7b7d00867c7b0288848405978c8a0088848400776d6b00 +585c5e00675c5a0088848400e8ecef00ffffff0df4f6f901e0e4e701d2d4d60099939300 +88848400978c8a0188848400978c8a008c8b8c00978481008c8b8c00978c8a0088848400 +8c8b8c00978c8a00888484008c8b8c00888484008c8b8c0088848403867c7b0188848400 +776d6b00584c4801d9dcde00ffffff05f4f6f900e8ecef00e0e4e700d9dcde01d2d4d600 +cbcccd02c4c5c500cbcccd00b8adaa00888484008c8b8c00888484008c8b8c00978c8a00 +888484008c8b8c00978481008c8b8c0088848403867c7b0088848400867c7b0377747400 +7b7b7d00777474008774700077747400675c5a00463d3c0135343400d2d4d600ffffff0f +f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600d8cccb00c4c5c500d8cccb00c4c5c501 +cbcccd00c4c5c50199939300978c8a018c8b8c00978c8a008c8b8c01888484027b7b7d00 +888484007b7b7d00867c7b0088848401867c7b007b7b7d00867c7b007b7b7d0077747401 +8774700077747401978c8a00ffffff24f4f6f900ecf3f500e8ecef00e0e4e700d9dcde02 +e0e4e701bbbcbd00554541004544450055454100584c48007b7b7d02867c7b0088848400 +a89a9500cbcccd00e8ecef00ecf3f500e8ecef01e0e4e701d9dcde00d2d4d602c4c5c502 +bbbcbd00c6bcba00b4b4b400bbbcbd02b4b4b400bbbcbd00b4b4b400abacad00675c5a00 +6a6c6e008c8b8c00999393068c8b8c00978c8a028c8b8c00978c8a008c8b8c0099939300 +978c8a008c8b8c0099939304bbbcbd00ffffff07f4f6f900ecf3f500e0e4e700d9dcde00 +d2d4d600c4c5c500bbbcbd01b4b4b405abacad00b4b4b400abacad007774740055454100 +454445004a4c4d00584c4800776d6b008c8b8c02978c8a028c8b8c00978c8a008c8b8c00 +999393008c8b8c00978c8a008c8b8c01978c8a008c8b8c04978c8a00888484008c8b8c00 +888484018c8b8c0088848402867c7b017b7b7d00777474007b7b7d01867c7b007b7b7d00 +867c7b007b7b7d00867c7b017b7b7d00867c7b007b7b7d00867c7b007b7b7d00867c7b00 +888484007b7b7d0088848400867c7b01888484018c8b8c00978c8a00888484008c8b8c02 +88848400abacad00b4b4b400a4a5a40477747400584c48014a4c4d00584c480054545500 +584c48004a4c4d00584c4802675c5a00888484058c8b8c01978481008c8b8c01978c8a00 +8c8b8c00978c8a008c8b8c02888484017b7b7d00c4c5c500e0e4e700d9dcde00d2d4d600 +c4c5c500bbbcbd00b4b4b400abacad009c9e9c00a89a95009c9e9c01a89a950054545500 +463d3c0735343400463d3c02584c480077747403776d6b017774740a7b7b7d00867c7b00 +7b7b7d00d9dcde00ffffff17f4f6f900ecf3f500e0e4e701cbcccd0077747400675c5a00 +63646500675c5a0063646501675c5a0063646500675c5a0154545500675c5a0054545500 +675c5a0054545500675c5a01585c5e00675c5a0063646500675c5a006364650177646000 +63646501675c5a0063646504675c5a00636465007764600063646500776d6b006a6c6e00 +776d6b0077747401867c7b017b7b7d0077747400867c7b007b7b7d017774740087747000 +777474078774700077747402776d6b0087747000777474077b7b7d0077747400776d6b00 +584c480054545500684f490054545501584c480054545500584c480154545500bbbcbd00 +ffffff0af4f6f900ecf3f500e8ecef00e0e4e700d9dcde01d2d4d600a4a5a400776d6b00 +6a6c6e00776d6b0077747404867c7b00777474007b7b7d00777474017b7b7d01867c7b00 +7b7b7d00867c7b007b7b7d01888484007b7b7d00867c7b007b7b7d00867c7b017b7b7d01 +776d6b0077747400776d6b00777474017b7b7d00777474008774700077747400867c7b00 +777474007b7b7d0077747400877470007b7b7d00867c7b007b7b7d00867c7b007b7b7d01 +867c7b007b7b7d02867c7b02888484018c8b8c0088848400776d6b0054545500675c5a00 +a4a5a400ffffff0ef4f6f900ecf3f500e8ecef00e0e4e700d2d4d600a4a5a4008c8b8c00 +978c8a00888484008c8b8c02888484008c8b8c0388848400978c8a008c8b8c00978c8a00 +8c8b8c00978c8a0088848401867c7b037b7b7d00585c5e0055454100abacad00ffffff07 +f4f6f900e8ecef00e0e4e700d9dcde00d2d4d601d8cccb00cbcccd02c4c5c50099939300 +978c8a018c8b8c00978c8a008c8b8c0088848404867c7b007b7b7d00867c7b007b7b7d01 +867c7b007b7b7d0077747400867c7b0077747403776d6b004544450035343400463d3c00 +45444500ffffff0ff4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd02c4c5c504 +b8adaa008c8b8c02978c8a008c8b8c0188848402867c7b0088848407867c7b027b7b7d00 +867c7b007b7b7d00d2d4d600ffffff25ecf3f501e8ecef00e0e4e700e8ecef00e0e4e700 +e8ecef00ecf3f5009c9e9c00463d3c0055454100463d3c0063646500867c7b0299939300 +cbcccd00f4f6f900ffffff00f4f6f901ecf3f501e8ecef01e0e4e700d9dcde01d2d4d600 +cbcccd01c4c5c501bbbcbd05b4b4b400bbbcbd019993930054545500675c5a007b7b7d00 +99939305978c8a00999393008c8b8c02999393008c8b8c00999393028c8b8c0099939304 +ffffff08ecf3f500e8ecef00d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd01b4b4b401 +abacad00b4b4b401abacad00b4b4b400abacad00b8adaa00888484004a4c4d0055454100 +45444500584c480077747400888484018c8b8c02978c8a008c8b8c08888484028c8b8c02 +88848404867c7b007b7b7d0177747402867c7b00777474007b7b7d00867c7b007b7b7d01 +867c7b007b7b7d00867c7b007b7b7d00867c7b007b7b7d00888484078c8b8c0088848400 +8c8b8c01978c8a008c8b8c0199939300b4b4b401abacad00a4a5a403777474004a4c4d00 +584c48004a4c4d00584c48004a4c4d00584c48014a4c4d00584c480163646500978c8a00 +888484008c8b8c0088848400978c8a00888484008c8b8c00978c8a008c8b8c01978c8a00 +8c8b8c00999393008c8b8c01978481008c8b8c00867c7b00888484007b7b7d00c4c5c500 +e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400a4a5a4019c9e9c03585c5e00 +45444501463d3c09584c4800777474007b7b7d00777474007b7b7d0177747408867c7b00 +7b7b7d00867c7b0288848400d9dcde00ffffff18f4f6f901e0e4e701cbcccd00867c7b00 +63646501675c5a0063646502675c5a02585c5e00675c5a00585c5e00675c5a00585c5e00 +675c5a0163646500675c5a0063646500675c5a0163646500675c5a0a636465016a6c6e00 +776d6b01777474007b7b7d00867c7b0077747400867c7b0077747404776d6b0077747400 +776d6b0077747401776d6b0077747403776d6b00777474038774700077747402776d6b01 +77747402776d6b0054545500584c480054545500584c480254545500584c480054545500 +584c4800b4b4b400ffffff0bf4f6f900f7ece700e8ecef00e0e4e700d9dcde01d2d4d600 +b4b4b400777474006a6c6e00776d6b0077747400776d6b0077747400776d6b0077747401 +7b7b7d00777474037b7b7d00777474007b7b7d0877747403776d6b0077747401776d6b00 +777474057b7b7d00777474027b7b7d05867c7b017b7b7d01888484036364650054545500 +867c7b00e0e4e700ffffff0ff4f6f900e8ecef00e0e4e700d9dcde00b8adaa0088848400 +8c8b8c00888484008c8b8c00978c8a0088848400978c8a00888484008c8b8c0188848400 +978c8a008c8b8c00888484008c8b8c01888484008c8b8c00888484017b7b7d03675c5a00 +463d3c0077747400ffffff08f4f6f900e8ecef01e6dcdc00d9dcde00d2d4d601cbcccd03 +bbbcbd00999393008c8b8c00978c8a008c8b8c01888484008c8b8c00867c7b0088848400 +867c7b00888484007b7b7d00777474017b7b7d01867c7b007b7b7d00777474036a6c6e00 +776d6b00675c5a00463d3c003534340163646500ffffff0ff4f6f900e8ecef00e0e4e700 +d9dcde00d2d4d600cbcccd00c4c5c501cbcccd00c4c5c503999393008c8b8c05867c7b00 +888484017b7b7d00888484018c8b8c00888484057b7b7d01867c7b0088848400ffffff26 +f4f6f902e8ecef01ecf3f500f4f6f9019c9e9c0045444502776d6b007b7b7d0088848400 +bbbcbd00ffffff07f4f6f900ecf3f500e8ecef00e0e4e700d9dcde02cbcccd01c4c5c501 +bbbcbd00c6bcba00b4b4b400bbbcbd00b4b4b400bbbcbd00b4b4b400bbbcbd00b4b4b400 +77747400545455017b7b7d00999393008c8b8c00999393018c8b8c00999393008c8b8c05 +999393008c8b8c00999393038c8b8c0099939301d2d4d600ffffff07f4f6f900ecf3f500 +e8ecef00d9dcde00d2d4d601c4c5c500bbbcbd01b4b4b402abacad00b4b4b400abacad00 +b4b4b400abacad0199939300545455004a4c4d00454445004a4c4d007774740088848400 +8c8b8c02888484008c8b8c01978c8a008c8b8c04888484008c8b8c00888484087b7b7d00 +867c7b007b7b7d01777474037b7b7d02867c7b017b7b7d02867c7b007b7b7d00867c7b00 +888484038c8b8c00888484008c8b8c00888484008c8b8c04888484009c9e9c00c4c5c500 +bbbcbd00b4b4b400a4a5a404777474004a4c4d00584c48004a4c4d01584c48004a4c4d01 +584c48004a4c4d00584c480063646500888484008c8b8c00888484028c8b8c0088848400 +8c8b8c03978c8a008c8b8c00978c8a008c8b8c0088848401867c7b007b7b7d01c4c5c500 +e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400abacad009c9e9c04675c5a00 +45444500584c4800463d3c004a4c4d004544450055454100463d3c0055454100463d3c02 +4544450054545500777474007b7b7d00877470007b7b7d00777474007b7b7d0377747404 +867c7b00777474007b7b7d01888484007b7b7d00d9dcde00ffffff19ecf3f500e8ecef01 +e0e4e700d2d4d600978c8a00636465017764600063646504675c5a03585c5e0063646500 +675c5a0063646500675c5a0063646500675c5a0063646500675c5a00585c5e00675c5a00 +585c5e01675c5a0054545500585c5e0054545500585c5e01675c5a016364650077646000 +6a6c6e01776d6b0077747405776d6b0177747400776d6b0077747400776d6b0063646500 +776d6b0077747400776d6b0077747409776d6b0277747400776d6b007b7b7d0077747400 +6a6c6e00584c480054545500584c480154545500584c48004a4c4d00584c48004a4c4d01 +bbbcbd00ffffff0cf4f6f900ecf3f500e8ecef00e0e4e700e6dcdc00d9dcde00d2d4d600 +c4c5c5008884840063646500776d6b0377747400776d6b0077747400776d6b0077747407 +8774700077747400776d6b0077747400776d6b0077747402776d6b0077747400776d6b00 +77747400776d6b0077747400776d6b0177747402776d6b00777474017b7b7d0077747400 +867c7b0077747401867c7b01888484007b7b7d00888484007b7b7d00888484007b7b7d00 +8884840077747400675c5a0063646500c4c5c500ffffff10f4f6f900e8ecef00e0e4e700 +e6dcdc00bbbcbd008c8b8c00888484008c8b8c00888484008c8b8c00888484008c8b8c00 +888484008c8b8c00888484018c8b8c00888484008c8b8c01888484008c8b8c0188848401 +7b7b7d01776d6b007774740063646500463d3c0054545500f4f6f900ffffff09f4f6f900 +e8ecef01d9dcde01d2d4d600d8cccb00cbcccd03b4b4b4008c8b8c03888484027b7b7d03 +777474017b7b7d00777474007b7b7d0077747401776d6b026a6c6e02675c5a0035343401 +978c8a00ffffff0ff4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd01c4c5c502 +cbcccd00c4c5c501abacad00888484028c8b8c00888484008c8b8c00888484068c8b8c03 +888484027b7b7d00867c7b00d2d4d600ffffff27f4f6f903ffffff03a4a5a4004a4c4d01 +7b7b7d00a4a5a400f4f6f900ffffff0af4f6f900ecf3f500e8ecef00e0e4e700d9dcde00 +d2d4d601cbcccd00c4c5c501bbbcbd03b4b4b401bbbcbd00b4b4b400a89a950054545500 +684f4900585c5e00888484008c8b8c00999393028c8b8c00999393008c8b8c00978c8a00 +8c8b8c01999393008c8b8c00999393058c8b8c0099939300abacad00ffffff08f4f6f900 +ecf3f500e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd01b4b4b403b8adaa00 +abacad00b4b4b402a4a5a40077747400584c480045444500584c48006a6c6e0088848411 +867c7b027b7b7d00867c7b007b7b7d0177747402776d6b0177747401867c7b007b7b7d00 +867c7b007b7b7d00867c7b007b7b7d00867c7b007b7b7d00888484038c8b8c0088848400 +8c8b8c03888484018c8b8c0088848400978c8a00abacad00cbcccd00c4c5c500bbbcbd00 +b4b4b400a4a5a404776d6b00454445004a4c4d0045444500584c48004a4c4d00584c4800 +4a4c4d00584c48004a4c4d01675c5a008884840a8c8b8c01888484027b7b7d0277747400 +c4c5c500e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400a4a5a4019c9e9c01 +99939300a4a5a400545455004544450255454101454445024a4c4d0055454100463d3c00 +45444500585c5e00867c7b007b7b7d0477747400867c7b02888484007b7b7d00867c7b00 +7b7b7d02867c7b007b7b7d01867c7b00d9dcde00ffffff1af4f6f900e8ecef00e0e4e700 +d9dcde01abacad00776d6b0063646500776460006a6c6e00776460006a6c6e00675c5a00 +63646500585c5e0063646500675c5a0063646500675c5a01585c5e00675c5a02585c5e00 +675c5a00585c5e00675c5a0054545503675c5a0054545502585c5e00636465046a6c6e01 +77747400776d6b0177747400776d6b016a6c6e00776d6b006a6c6e00776d6b00585c5e00 +54545500776d6b0077747400776d6b00777474007b7b7d0077747400867c7b0077747402 +6a6c6e00776d6b006a6c6e03776d6b00777474026a6c6e00584c48024a4c4d0545444500 +b4b4b400ffffff0df4f6f900e8ecef01e0e4e701d9dcde00d2d4d601a4a5a400776d6b00 +6a6c6e02776d6b0177747403776d6b0077747400776d6b0077747400776d6b007b7b7d00 +77747400776d6b007b7b7d0077747402776d6b0077747400776d6b0077747402776d6b00 +6a6c6e00777474006a6c6e00776d6b01777474067b7b7d04888484007b7b7d00867c7b00 +7b7b7d0077747400636465006a6c6e00b4b4b400ffffff11f4f6f900e8ecef00e0e4e701 +c4c5c5008c8b8c00888484068c8b8c00888484038c8b8c00888484008c8b8c0088848403 +7b7b7d0177747401776d6b004a4c4d0045444500c4c5c500ffffff0bf4f6f900e8ecef00 +e6dcdc00d9dcde00d2d4d601cbcccd03c4c5c5009c9e9c008c8b8c0288848400867c7b00 +888484007b7b7d00867c7b01777474007b7b7d0077747406776d6b006a6c6e00776d6b00 +6364650254545500584c4800ffffff10f4f6f900ecf3f500e8ecef00d9dcde00d2d4d600 +d8cccb00cbcccd01c4c5c504867c7b007b7b7d00888484038c8b8c00888484028c8b8c00 +888484038c8b8c04888484007b7b7d008c8b8c00ffffff31c4c5c500776d6b00d9dcde00 +ffffff0df4f6f900ecf3f500e0e4e701d9dcde00d2d4d601c4c5c501bbbcbd00c6bcba00 +b4b4b400bbbcbd00b4b4b400bbbcbd00b4b4b400bbbcbd00b4b4b4006a6c6e0054545501 +636465008c8b8c00999393008c8b8c00999393028c8b8c00999393008c8b8c0099939300 +8c8b8c00999393018c8b8c02999393008c8b8c03ffffff09f4f6f900ecf3f500e0e4e700 +d9dcde00d2d4d600cbcccd00c4c5c501bbbcbd01b4b4b401abacad00b4b4b400abacad00 +b4b4b400abacad00b4b4b400abacad009c9e9c00675c5a0045444501636465007b7b7d01 +888484007b7b7d00888484047b7b7d00888484057b7b7d00888484007b7b7d0477747400 +7b7b7d0077747401776d6b01777474007b7b7d01867c7b007b7b7d00867c7b007b7b7d00 +867c7b007b7b7d00888484048c8b8c04888484008c8b8c0299939300c4c5c500d9dcde00 +cbcccd00c4c5c500bbbcbd00abacad01a4a5a40377747400454445025545410045444502 +4a4c4d00584c48004a4c4d006364650088848400867c7b00888484037b7b7d0088848407 +7b7b7d0277747401c4c5c500e0e4e700d9dcde00d2d4d600cbcccd00bbbcbd00b4b4b400 +abacad009c9e9c04675c5a00454445005545410045444500463d3c004544450255454100 +454445014a4c4d0045444500675c5a007b7b7d01867c7b007b7b7d02867c7b007b7b7d00 +888484007b7b7d00867c7b007b7b7d00867c7b007b7b7d03867c7b007b7b7d01d2d4d600 +ffffff1af4f6f901ecf3f500e8ecef00e0e4e700d9dcde00c4c5c5008884840063646503 +6a6c6e00675c5a0063646501585c5e00675c5a00585c5e0354545500585c5e015454550a +675c5a00585c5e00675c5a0063646500776d6b0063646500776460006a6c6e0263646500 +6a6c6e00776d6b006a6c6e03545455004544450054545500776d6b006a6c6e0177747402 +776d6b026a6c6e01636465006a6c6e00675c5a006a6c6e02776d6b02636465004a4c4d03 +554541004a4c4d00554541024a4c4d00b4b4b400ffffff0ff4f6f900e8ecef00e0e4e701 +d9dcde01d2d4d600c4c5c5008c8b8c006a6c6e02776d6b006a6c6e00776d6b0177747401 +776d6b0277747404776d6b0177747400776d6b00777474006a6c6e0077747400776d6b00 +777474006a6c6e0077747400776d6b006a6c6e00777474006a6c6e0077747400776d6b00 +77747400776d6b00777474017b7b7d00777474007b7b7d02888484007b7b7d026a6c6e00 +77747400b4b4b400ffffff13f4f6f900ecf3f500e0e4e700d2d4d6009993930088848400 +7b7b7d00888484057b7b7d00888484007b7b7d00888484007b7b7d00888484057b7b7d00 +88848400777474016a6c6e0054545500554541008c8b8c00ffffff0cf4f6f900ecf3f500 +e8ecef00d9dcde01d2d4d601d8cccb00cbcccd02c4c5c500978c8a00888484017b7b7d06 +777474017b7b7d0077747400867c7b007b7b7d00777474016a6c6e00777474006a6c6e01 +63646500776460008c8b8c00e8ecef00ffffff11ecf3f500e8ecef00e6dcdc00d9dcde00 +cbcccd01c4c5c501cbcccd00c4c5c501b4b4b400585c5e00867c7b00888484038c8b8c00 +888484068c8b8c0588848401c4c5c500ffffff43f4f6f901e8ecef00e0e4e700d9dcde00 +d2d4d600cbcccd01c4c5c500bbbcbd02b4b4b400bbbcbd00b4b4b401bbbcbd00978c8a00 +584c480054545501777474008c8b8c00999393008c8b8c01999393008c8b8c0ee0e4e700 +ffffff09f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd02 +b4b4b402abacad00b4b4b400abacad00b4b4b400abacad028c8b8c005454550045444500 +545455007b7b7d01888484037b7b7d01888484007b7b7d00888484007b7b7d0088848400 +7b7b7d01888484007b7b7d03777474007b7b7d0077747402776d6b00777474006a6c6e00 +777474007b7b7d03888484007b7b7d00888484038c8b8c00888484018c8b8c00978c8a00 +8c8b8c0488848400a4a5a400d9dcde00e0e4e700d2d4d601c4c5c500bbbcbd00b4b4b400 +a4a5a404776d6b003b3c3d00463d3c003b3c3d00463d3c004544450055454101463d3c00 +45444501675c5a007b7b7d00888484007b7b7d03888484007b7b7d00888484017b7b7d07 +77747401bbbcbd00e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400abacad00 +9c9e9c04585c5e00454445004a4c4d00454445005545410045444503463d3c0045444500 +5545410045444500585c5e007b7b7d03867c7b007b7b7d01888484007b7b7d0677747400 +7b7b7d03d9dcde00ffffff1bf4f6f901e8ecef01e0e4e700d9dcde01abacad0077747400 +63646501675c5a0063646501585c5e00675c5a00585c5e0054545506584c480054545500 +584c480054545500584c480054545500584c480054545501584c480054545501675c5a00 +636465086a6c6e01776d6b006a6c6e00675c5a0045444502584c48006a6c6e03776d6b00 +6a6c6e04675c5a0063646500675c5a0063646501675c5a00636465006a6c6e0263646500 +4a4c4d02554541004a4c4d0045444500463d3c00454445003b3c3d00463d3c00bbbcbd00 +ffffff0ff4f6f901f7ece700e8ecef00e0e4e701d9dcde01d2d4d600b4b4b400867c7b00 +6a6c6e04777474006a6c6e00777474096a6c6e00777474006a6c6e00777474006a6c6e00 +777474026a6c6e00777474016a6c6e00777474016a6c6e0077747403776d6b0077747402 +7b7b7d027774740099939300cbcccd00ffffff15f4f6f900e8ecef00e0e4e700d2d4d600 +abacad008c8b8c00888484007b7b7d01888484007b7b7d00888484007b7b7d0088848400 +7b7b7d03777474007b7b7d0777747400636465004544450063646500ffffff0ef4f6f900 +e8ecef01d9dcde01d2d4d600cbcccd01c4c5c500cbcccd01abacad008c8b8c007b7b7d00 +888484007b7b7d00888484007b7b7d02777474086a6c6e00776d6b006a6c6e00776d6b00 +a4a5a400e8ecef00ffffff13f4f6f900e8ecef00d9dcde01cbcccd01c4c5c5047b7b7d00 +6a6c6e007b7b7d00888484007b7b7d00888484058c8b8c007b7b7d00888484018c8b8c05 +888484008c8b8c00ffffff46e8ecef01e0e4e700d9dcde00d2d4d600cbcccd00c4c5c500 +c6bcba00bbbcbd02b4b4b400bbbcbd01b4b4b400abacad00585c5e00584c4801585c5e00 +8c8b8c05888484008c8b8c01888484008c8b8c09bbbcbd00ffffff09f4f6f901ecf3f500 +e0e4e700d9dcde00d2d4d600cbcccd01c4c5c500bbbcbd02b4b4b401abacad00b8adaa00 +abacad00b4b4b400abacad00b4b4b400b8adaa00abacad0088848400545455004a4c4d00 +636465007b7b7d00888484007b7b7d00888484027b7b7d00888484007b7b7d0088848400 +7b7b7d00888484007b7b7d01777474007b7b7d00777474007b7b7d00777474046a6c6e02 +776d6b00777474017b7b7d04888484038c8b8c02999393008c8b8c028884840099939300 +c4c5c500ecf3f500e8ecef00e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd00abacad00 +a4a5a404776d6b00353434013b3c3d00463d3c003b3c3d02454445005545410045444500 +585c5e007b7b7d02888484007b7b7d02888484007b7b7d05777474007b7b7d0277747400 +6a6c6e00c4c5c500e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400abacad00 +9c9e9c01a89a95009c9e9c01675c5a0045444500554541004a4c4d004544450155454100 +4a4c4d014544450255454100545455007b7b7d0e867c7b00777474007b7b7d02d2d4d600 +ffffff1df4f6f900ecf3f500e8ecef00e0e4e701d9dcde00d2d4d6009c9e9c0077747400 +63646501675c5a0054545500585c5e0054545503584c480354545501584c480054545502 +584c480054545505585c5e00675c5a01585c5e0063646502675c5a006364650354545500 +45444500463d3c013b3c3d0045444500636465026a6c6e0163646504675c5a0063646501 +585c5e00675c5a00585c5e0063646502776d6b00675c5a005545410045444500463d3c00 +45444500463d3c01454445003b3c3d00463d3c0063646500d2d4d600ffffff11f4f6f900 +ecf3f500e8ecef01e0e4e700e6dcdc00d9dcde01d2d4d600b8adaa007b7b7d006a6c6e00 +776d6b006a6c6e00776d6b00777474016a6c6e00777474006a6c6e00777474006a6c6e01 +776d6b006a6c6e01777474006a6c6e0077747400776d6b00777474017b7b7d0077747402 +6a6c6e00776d6b006a6c6e01777474006a6c6e00777474006a6c6e017774740488848400 +abacad00e0e4e700ffffff17f4f6f900ecf3f500e8ecef00d9dcde01d2d4d600bbbcbd00 +9c9e9c008c8b8c007b7b7d00888484017b7b7d03777474047b7b7d04777474006a6c6e00 +4a4c4d01d2d4d600ffffff0fecf3f500e8ecef00e6dcdc00d9dcde00d2d4d602d8cccb00 +cbcccd029c9e9c00888484007b7b7d01777474007b7b7d01777474026a6c6e0077747404 +6a6c6e0188848400bbbcbd00ffffff16ecf3f500e8ecef00e0e4e700d9dcde00cbcccd01 +c4c5c500d8cccb00c4c5c501b4b4b40054545500888484037b7b7d00888484007b7b7d00 +888484027b7b7d00888484028c8b8c0588848400bbbcbd00ffffff46f4f6f900ecf3f500 +e0e4e700d9dcde00d2d4d601c4c5c501bbbcbd01b4b4b400bbbcbd00b4b4b401bbbcbd00 +b4b4b400776d6b0054545502777474008c8b8c00888484047b7b7d00888484007b7b7d00 +888484018c8b8c079c9e9c00ffffff0bf4f6f900ecf3f500e0e4e701d9dcde00d2d4d600 +cbcccd00c4c5c501bbbcbd02b4b4b402abacad00b4b4b400abacad02b8adaa00abacad00 +8c8b8c0063646500545455006a6c6e007b7b7d01888484027b7b7d00888484007b7b7d00 +888484007b7b7d02777474056a6c6e00777474006a6c6e00777474006a6c6e02776d6b00 +777474017b7b7d01888484008c8b8c007b7b7d008c8b8c00888484008c8b8c0599939300 +8c8b8c00abacad00ecf3f500ffffff00ecf3f500e8ecef00e0e4e700d2d4d601bbbcbd01 +b4b4b400a4a5a40463646500353434033b3c3d00463d3c003b3c3d02463d3c0054545500 +7b7b7d0b777474066a6c6e00bbbcbd00e8ecef00d9dcde00d2d4d600c4c5c500bbbcbd00 +b4b4b400abacad00a4a5a4009c9e9c035454550045444501463d3c00454445004a4c4d00 +4544450155454100454445004a4c4d0045444501585c5e00867c7b007b7b7d0288848400 +7b7b7d00888484007b7b7d0b77747400d2d4d600ffffff1ef4f6f901e8ecef01e0e4e701 +d9dcde00cbcccd009c9e9c006a6c6e00585c5e00675c5a0054545503584c480054545500 +4a4c4d00545455004a4c4d00545455004a4c4d0154545500584c48004a4c4d0054545500 +4a4c4d00584c480154545505585c5e00675c5a0054545500585c5e0163646500675c5a00 +585c5e0045444500463d3c00353434013b3c3d0054545500776d6b00585c5e00675c5a03 +63646501675c5a0063646500675c5a0063646500585c5e00675c5a0054545500585c5e00 +54545501675c5a00636465015454550045444500463d3c0045444500463d3c003b3c3d00 +545455007b7b7d00abacad00e8ecef00ffffff14f4f6f901f7ece700e8ecef01e0e4e701 +d9dcde01d2d4d600b4b4b4008c8b8c006a6c6e00777474006a6c6e00777474006a6c6e00 +77747400776d6b006a6c6e01777474006a6c6e01776d6b006a6c6e00777474006a6c6e00 +777474017b7b7d00777474007b7b7d00777474046a6c6e00777474006a6c6e0277747402 +7b7b7d0099939300cbcccd00ffffff1bf4f6f900e8ecef00e0e4e701d9dcde02cbcccd00 +b4b4b40099939300888484017b7b7d01777474026a6c6e037774740454545500463d3c00 +a4a5a400ffffff11ecf3f500e8ecef00e6dcdc00d9dcde00d2d4d601cbcccd02d2d4d600 +cbcccd008c8b8c007b7b7d01777474007b7b7d00777474026a6c6e00777474016a6c6e00 +777474017b7b7d009c9e9c00d9dcde00ffffff18f4f6f900e8ecef00e0e4e700d9dcde00 +d8cccb00cbcccd00c4c5c501cbcccd00c4c5c500867c7b00636465007b7b7d0688848400 +7b7b7d00888484018c8b8c007b7b7d008c8b8c007b7b7d008c8b8c05ffffff48f4f6f900 +ecf3f500e8ecef00d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd02b4b4b401bbbcbd00 +b4b4b400bbbcbd008884840054545500584c480054545500636465008c8b8c007b7b7d00 +8c8b8c007b7b7d008c8b8c007b7b7d03888484007b7b7d018c8b8c007b7b7d0088848401 +8c8b8c03ffffff0bf4f6f901ecf3f500e8ecef00d9dcde01d2d4d601cbcccd00c4c5c500 +bbbcbd03b4b4b402abacad00b4b4b401abacad039c9e9c0077747400636465007b7b7d03 +888484007b7b7d00888484007b7b7d05777474006a6c6e007b7b7d006a6c6e0077747400 +6a6c6e01636465006a6c6e00636465006a6c6e03777474007b7b7d02888484007b7b7d00 +888484008c8b8c03999393008c8b8c009c9e9c00e0e4e700ffffff02ecf3f500e8ecef00 +e0e4e700d9dcde00cbcccd00c4c5c500bbbcbd00abacad00a4a5a4046a6c6e0035343402 +2e2c2d00353434002e2c2d00353434003b3c3d00353434003b3c3d004a4c4d0077747400 +6a6c6e00777474006a6c6e00777474017b7b7d00777474026a6c6e00777474006a6c6e00 +777474006a6c6e00777474006a6c6e03bbbcbd00e0e4e700d9dcde00d2d4d600c4c5c500 +bbbcbd00b4b4b400abacad009c9e9c04675c5a00454445004a4c4d00454445004a4c4d00 +454445004a4c4d00454445024a4c4d004544450055454100636465007b7b7d0588848400 +7b7b7d01777474007b7b7d00777474007b7b7d00777474007b7b7d02777474017b7b7d00 +d2d4d600ffffff1ff4f6f901ecf3f500e8ecef00e0e4e702d9dcde00d8cccb009c9e9c00 +6a6c6e0054545501584c48004a4c4d02584c48004a4c4d02584c4800545455004a4c4d01 +54545500584c4800545455004a4c4d0054545503585c5e0054545500585c5e0054545505 +45444500353434003b3c3d0054545500867c7b00a4a5a400c4c5c500d2d4d600b8adaa00 +585c5e04675c5a00585c5e02675c5a00585c5e00675c5a00585c5e0054545504585c5e00 +675c5a00545455003b3c3d004a4c4d006364650099939300c4c5c500f4f6f900ffffff19 +f4f6f900ecf3f500f4f6f900e8ecef01e0e4e701d9dcde02c4c5c5009c9e9c007b7b7d00 +6a6c6e00777474016a6c6e00777474006a6c6e0177747400776d6b00777474057b7b7d01 +777474007b7b7d00777474026a6c6e03777474006a6c6e00777474007b7b7d00abacad00 +e0e4e700ffffff1df4f6f901e8ecef00e0e4e701d9dcde02d2d4d601c4c5c500a4a5a400 +8c8b8c007b7b7d00777474016a6c6e01636465016a6c6e0177747402585c5e00463d3c00 +63646500ffffff12f4f6f900ecf3f500e8ecef00d9dcde01d2d4d600d9dcde00d2d4d602 +d9dcde00c4c5c5007b7b7d03777474007b7b7d00777474016a6c6e017774740088848400 +b4b4b400ecf3f500ffffff1aecf3f500e8ecef00d9dcde01cbcccd01c4c5c502b4b4b400 +4a4c4d00777474007b7b7d08888484007b7b7d00888484047b7b7d008c8b8c0188848400 +b4b4b400ffffff49ecf3f500e8ecef00e0e4e700d9dcde00cbcccd00c4c5c501bbbcbd00 +b4b4b400bbbcbd01b4b4b400bbbcbd00b4b4b4009c9e9c004a4c4d00545455004a4c4d00 +54545500888484008c8b8c01888484008c8b8c007b7b7d058c8b8c007b7b7d008c8b8c00 +888484007b7b7d008c8b8c007b7b7d008c8b8c01ecf3f500ffffff0cf4f6f900ecf3f501 +e0e4e700d9dcde01d2d4d601cbcccd00c4c5c500bbbcbd02b4b4b403abacad00b4b4b400 +abacad00b4b4b400abacad038c8b8c007b7b7d018c8b8c007b7b7d07777474027b7b7d00 +6a6c6e00777474006a6c6e00636465026a6c6e00636465006a6c6e00777474006a6c6e00 +777474007b7b7d02888484007b7b7d008c8b8c007b7b7d008c8b8c029c9e9c00c4c5c500 +ffffff04f4f6f900e8ecef00e0e4e700d2d4d600cbcccd00c4c5c500b4b4b401a4a5a404 +776d6b00353434042e2c2d01353434024a4c4d006a6c6e03777474006a6c6e0ebbbcbd00 +e8ecef00d9dcde00d2d4d600c4c5c500bbbcbd00b4b4b400abacad009c9e9c04675c5a00 +454445004a4c4d00554541004544450055454100454445024a4c4d00463d3c0045444501 +585c5e007b7b7d00888484007b7b7d00888484037b7b7d04777474007b7b7d0077747405 +d2d4d600ffffff21f4f6f902e8ecef01e0e4e701d9dcde01abacad00867c7b0054545501 +4a4c4d02584c48004a4c4d04545455004a4c4d0054545502584c480054545504584c4800 +54545500584c4800545455026364650088848400b8adaa00d2d4d600e0e4e701d9dcde00 +e0e4e700d9dcde00b4b4b40054545507584c480054545505584c4800585c5e00776d6b00 +7b7b7d008c8b8c01abacad00d9dcde00ecf3f500ffffff1ef4f6f901f7ece700e8ecef02 +e0e4e701d9dcde01d2d4d600b4b4b4008c8b8c00777474016a6c6e00777474006a6c6e00 +777474036a6c6e00777474027b7b7d03777474016a6c6e047b7b7d009c9e9c00cbcccd00 +ffffff21f4f6f901e8ecef02e0e4e701d9dcde03d2d4d600bbbcbd009993930077747400 +6a6c6e0063646500585c5e026a6c6e00636465006a6c6e0063646500463d3c00585c5e00 +ecf3f500ffffff13f4f6f900e8ecef01e0e4e700d9dcde00e6dcdc00d9dcde01e6dcdc00 +d9dcde00e0e4e700b4b4b400888484007b7b7d00777474007b7b7d00777474006a6c6e02 +8c8b8c00cbcccd00ffffff1cf4f6f901e8ecef00d9dcde01cbcccd01c4c5c501cbcccd00 +867c7b00585c5e00777474077b7b7d03888484018c8b8c047b7b7d008c8b8c00ffffff4b +ecf3f500e0e4e700d9dcde00d2d4d600c4c5c501bbbcbd01b4b4b402bbbcbd00b4b4b400 +a4a5a4004a4c4d00545455004a4c4d00545455007b7b7d00888484067b7b7d0488848400 +7b7b7d00888484018c8b8c00888484008c8b8c00d2d4d600ffffff0eecf3f501e8ecef00 +e0e4e700d9dcde01d2d4d601cbcccd00c4c5c501bbbcbd02b4b4b403abacad00b4b4b400 +abacad04a4a5a4008c8b8c037b7b7d04777474006a6c6e00777474016a6c6e0077747400 +6a6c6e01636465036a6c6e01777474027b7b7d02888484007b7b7d00888484008c8b8c00 +99939300c4c5c500ffffff06ecf3f500e8ecef00d9dcde00d2d4d600cbcccd00c4c5c500 +bbbcbd00abacad01a4a5a400abacad00a4a5a4017b7b7d0045444500463d3c0035343400 +463d3c00353434042e2c2d00454445006a6c6e04636465006a6c6e00636465026a6c6e00 +636465066a6c6e01bbbcbd00e0e4e700d9dcde00d2d4d600cbcccd00bbbcbd00b4b4b400 +abacad009c9e9c00a4a5a4009c9e9c00a4a5a4009c9e9c006a6c6e00454445054a4c4d01 +454445004a4c4d0145444500585c5e007b7b7d00888484017b7b7d00888484007b7b7d00 +888484008c8b8c007b7b7d00888484007b7b7d01777474016a6c6e0277747402d2d4d600 +ffffff22f4f6f901ecf3f500e8ecef02e0e4e701d9dcde00e0e4e700c4c5c5009c9e9c00 +776d6b00545455004a4c4d08545455084a4c4d00545455007774740099939300bbbcbd00 +d9dcde00e8ecef06e0e4e701bbbcbd00585c5e0154545502636465006a6c6e0077747400 +7b7b7d008c8b8c009c9e9c00a4a5a400b4b4b400c6bcba00cbcccd00d9dcde00e0e4e700 +e8ecef00ecf3f501f4f6f902ffffff21f4f6f902e8ecef03e0e4e702d9dcde00d2d4d600 +b4b4b400999393007b7b7d00777474006a6c6e00777474006a6c6e007b7b7d0077747400 +7b7b7d00777474007b7b7d04777474006a6c6e00777474006a6c6e007b7b7d0099939300 +c4c5c500ecf3f500ffffff24f4f6f900ffffff00f4f6f900e8ecef02e0e4e702d9dcde00 +e0e4e702d2d4d600b4b4b40088848400585c5e01636465026a6c6e00454445008c8b8c00 +ffffff16f4f6f900ecf3f500e8ecef01e0e4e700e8ecef00e0e4e700e8ecef01ecf3f500 +e8ecef00999393007b7b7d01777474017b7b7d00a4a5a400e8ecef00ffffff1ef4f6f900 +ecf3f500e0e4e700e6dcdc00d2d4d600cbcccd01c4c5c501b4b4b4004a4c4d006a6c6e01 +777474046a6c6e007b7b7d006a6c6e007b7b7d028c8b8c00888484018c8b8c0088848400 +8c8b8c0088848401abacad00ffffff4becf3f500e8ecef00e0e4e700d9dcde00cbcccd00 +c4c5c500bbbcbd01b4b4b400c6bcba00bbbcbd00b4b4b400bbbcbd00a4a5a4004a4c4d00 +584c48004a4c4d00584c480063646500888484027b7b7d008c8b8c007b7b7d0a8c8b8c00 +7b7b7d01bbbcbd00ffffff0ff4f6f900ecf3f500e8ecef00e0e4e701d9dcde01d2d4d601 +cbcccd01c4c5c501bbbcbd02b4b4b400bbbcbd00b4b4b408abacad009c9e9c0088848400 +7b7b7d036a6c6e00777474006a6c6e01777474006a6c6e01636465056a6c6e027b7b7d04 +8c8b8c00b4b4b400d9dcde00f4f6f900ffffff07f4f6f900e8ecef00e0e4e700d9dcde00 +d2d4d600cbcccd00bbbcbd01abacad00b4b4b404a4a5a4008c8b8c00776d6b004a4c4d00 +463d3c013b3c3d0035343402454445006a6c6e04636465006a6c6e00636465006a6c6e00 +636465016a6c6e00636465066a6c6e00bbbcbd00e8ecef00d9dcde01cbcccd00c4c5c500 +bbbcbd00b4b4b400abacad00a4a5a400abacad03a4a5a4008c8b8c0077747400585c5e00 +4a4c4d014544450055454100454445004a4c4d00454445004a4c4d00585c5e007b7b7d00 +888484037b7b7d00888484007b7b7d00888484007b7b7d036a6c6e00777474026a6c6e00 +777474006a6c6e00d2d4d600ffffff25f4f6f901e8ecef03e0e4e702d9dcde00cbcccd00 +a4a5a4007b7b7d00636465004a4c4d03545455004a4c4d0054545504585c5e006a6c6e00 +888484009c9e9c00bbbcbd00e0e4e700e8ecef01ecf3f500f4f6f904ecf3f501f7ece700 +e8ecef01d9dcde00abacad00bbbcbd00c4c5c500cbcccd00d9dcde00e0e4e701e8ecef06 +ecf3f501f4f6f903ffffff27f4f6f901f7ece700ecf3f500e8ecef03e0e4e702d9dcde00 +c4c5c500a4a5a4009c9e9c00888484007b7b7d00777474027b7b7d00777474016a6c6e00 +7b7b7d008c8b8c009c9e9c00b4b4b400d2d4d600f4f6f900ffffff2af4f6f901ecf3f501 +e8ecef04e0e4e700ecf3f500e8ecef00ecf3f500d9dcde00a4a5a400777474006a6c6e00 +636465006a6c6e00cbcccd00ffffff18f4f6f901f7ece700ecf3f500e8ecef00ecf3f501 +f4f6f902e0e4e7007b7b7d018c8b8c00c4c5c500f4f6f900ffffff20f4f6f900e8ecef00 +e0e4e700d9dcde00d2d4d600cbcccd01c4c5c5018884840054545500777474017b7b7d01 +777474007b7b7d03777474006a6c6e007b7b7d04888484028c8b8c0088848400ecf3f500 +ffffff35f4f6f900ffffff14f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600c4c5c500 +c6bcba00bbbcbd01b4b4b400bbbcbd00b4b4b4019c9e9c004a4c4d03585c5e0088848400 +8c8b8c007b7b7d008c8b8c007b7b7d046a6c6e00777474007b7b7d05888484007b7b7d00 +abacad00ffffff10f4f6f901ecf3f501e0e4e701d9dcde01d2d4d601cbcccd02c4c5c502 +bbbcbd08c4c5c500bbbcbd00c4c5c500bbbcbd00b4b4b4009c9e9c00888484007b7b7d01 +6a6c6e0463646502585c5e00636465026a6c6e03888484009c9e9c00c4c5c500e8ecef00 +ffffff0bf4f6f900ecf3f500e8ecef00e0e4e700d9dcde00d2d4d600c4c5c501bbbcbd00 +b4b4b400bbbcbd05c4c5c500bbbcbd00a4a5a4008c8b8c006364650045444500463d3c01 +4a4c4d00777474016a6c6e01777474006a6c6e037b7b7d018c8b8c009c9e9c00a4a5a400 +b4b4b400bbbcbd00cbcccd00d2d4d600e0e4e700e8ecef02e0e4e700d9dcde00d2d4d601 +c4c5c500bbbcbd00b4b4b405bbbcbd00b4b4b401bbbcbd00b4b4b4009c9e9c008c8b8c00 +6a6c6e0054545500463d3c004544450055454100585c5e007b7b7d00888484028c8b8c00 +7b7b7d00888484007b7b7d018c8b8c019c9e9c00a4a5a400abacad00bbbcbd01cbcccd00 +d9dcde00e8ecef00ecf3f500ffffff27f4f6f900ffffff00f4f6f900e8ecef03e0e4e704 +d9dcde00cbcccd00b4b4b4009c9e9c00978c8a00888484018c8b8c019c9e9c00b4b4b400 +c4c5c500d2d4d600e0e4e700e8ecef02ecf3f501f4f6f902ffffff01f4f6f900ffffff00 +f4f6f905e8ecef05ecf3f500e8ecef00f4f6f900e8ecef00f4f6f901ecf3f500f4f6f903 +ffffff2df4f6f901ecf3f501e8ecef08d9dcde00d2d4d600c4c5c500bbbcbd00c4c5c500 +bbbcbd00cbcccd00d9dcde00e8ecef00ecf3f500ffffff30f4f6f902ecf3f505f4f6f901 +ffffff02d9dcde00b4b4b400ffffff1df4f6f902ffffff04d9dcde01f4f6f900ffffff22 +f4f6f900e8ecef00d9dcde00d2d4d601cbcccd00c4c5c501c6bcba004a4c4d006a6c6e01 +777474007b7b7d006a6c6e007b7b7d01777474016a6c6e027b7b7d006a6c6e007b7b7d01 +8c8b8c007b7b7d008c8b8c007b7b7d008c8b8c009c9e9c00ffffff35b4b4b4004a4c4d00 +d9dcde00ffffff14ecf3f500e0e4e700d9dcde00d2d4d600c4c5c501bbbcbd00b4b4b402 +bbbcbd01978c8a004a4c4d00454445004a4c4d0154545500888484007b7b7d008c8b8c00 +7b7b7d008c8b8c007b7b7d046a6c6e007b7b7d006a6c6e007b7b7d059c9e9c00ffffff12 +f4f6f901ecf3f500e8ecef00e0e4e701d9dcde02d2d4d601cbcccd04c4c5c500cbcccd00 +c4c5c505cbcccd00c4c5c500d2d4d600cbcccd00d2d4d600cbcccd00bbbcbd00abacad00 +9c9e9c007b7b7d00777474006a6c6e0163646505777474008c8b8c00abacad00cbcccd00 +ecf3f500f4f6f900ffffff0ef4f6f900ecf3f500e8ecef00e0e4e700d9dcde01cbcccd01 +c4c5c504cbcccd02c4c5c500cbcccd01d2d4d602abacad008c8b8c006a6c6e008c8b8c00 +9c9e9c00abacad00bbbcbd00c4c5c500d2d4d600e0e4e700e8ecef00f4f6f900ffffff09 +ecf3f502e8ecef00e0e4e700d9dcde00d2d4d600c4c5c501bbbcbd04c4c5c500bbbcbd00 +c4c5c500bbbcbd00c4c5c501cbcccd00d2d4d601d9dcde00c4c5c500a4a5a40088848400 +7b7b7d009c9e9c00abacad00b4b4b400c4c5c500cbcccd00d9dcde00e0e4e700e8ecef00 +ecf3f500f4f6f900ffffff03f4f6f900ffffff01f4f6f900ffffff2cf4f6f902ecf3f501 +e8ecef03e0e4e700e8ecef00e0e4e705e8ecef05ecf3f501f4f6f902ffffff0bf4f6f90a +ffffff00f4f6f900ffffff35f4f6f900ecf3f500ffffff00ecf3f50bf4f6f902ffffff38 +f4f6f900ffffff53f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd02c4c5c500 +8c8b8c004a4c4d00777474006a6c6e00777474026a6c6e017b7b7d006a6c6e007b7b7d00 +6a6c6e027b7b7d006a6c6e007b7b7d05e0e4e700ffffff34d2d4d600454445014a4c4d00 +d2d4d600ffffff12f4f6f900ecf3f500e8ecef00e0e4e700d2d4d600cbcccd00bbbcbd03 +b4b4b400bbbcbd00b4b4b40077747400454445004a4c4d038c8b8c007b7b7d008c8b8c00 +7b7b7d06777474007b7b7d016a6c6e007b7b7d006a6c6e007b7b7d0299939300ffffff14 +f4f6f901ecf3f501e8ecef00e0e4e701d9dcde03d2d4d601cbcccd00d2d4d600cbcccd01 +d2d4d600cbcccd00d2d4d606d9dcde01e0e4e702e8ecef00d9dcde00cbcccd00c4c5c500 +bbbcbd00c4c5c500bbbcbd00d2d4d600e0e4e700ecf3f500ffffff15ecf3f502e0e4e700 +d9dcde01d2d4d600cbcccd02d2d4d601cbcccd02d2d4d602d9dcde00e0e4e701e8ecef00 +ecf3f500f4f6f900ffffff13ecf3f501e8ecef00e0e4e700d9dcde01d2d4d601c4c5c503 +cbcccd00c4c5c501cbcccd03d2d4d600d9dcde00e0e4e702ecf3f502f4f6f906ffffff3a +f4f6f901ecf3f500f4f6f900e8ecef00ecf3f500e8ecef04ecf3f500e8ecef00ecf3f500 +e8ecef00ecf3f500e8ecef00f4f6f904ffffff12f4f6f900ffffff44f4f6f900ffffff02 +f4f6f900ffffff93ecf3f500e8ecef00d9dcde01d2d4d600cbcccd00c4c5c501bbbcbd00 +4a4c4d00636465006a6c6e01777474006a6c6e02777474006a6c6e007b7b7d006a6c6e06 +7b7b7d038c8b8c00ffffff34e0e4e700454445003b3c3d00463d3c00454445004a4c4d00 +d2d4d600ffffff12ecf3f500e8ecef00d9dcde00d2d4d600cbcccd00c4c5c500bbbcbd00 +b4b4b401bbbcbd00b4b4b40154545500454445004a4c4d00454445004a4c4d017b7b7d01 +8c8b8c007b7b7d076a6c6e007b7b7d006a6c6e007b7b7d00777474016a6c6e007b7b7d00 +8c8b8c00ffffff16f4f6f901ecf3f502e0e4e702d9dcde0de0e4e704e8ecef01ecf3f502 +f4f6f901ffffff1becf3f501e8ecef01d9dcde01d2d4d600d9dcde02d2d4d600d9dcde04 +e0e4e702ecf3f501f4f6f902ffffff12f4f6f900ecf3f502e0e4e701d9dcde00d2d4d602 +cbcccd00d2d4d607d9dcde01e0e4e700e8ecef00ecf3f502f4f6f900ffffff44f4f6f908 +ecf3f500f4f6f904fffffff4f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd01 +c4c5c500cbcccd008c8b8c004a4c4d006a6c6e0c777474006a6c6e047b7b7d006a6c6e00 +d2d4d600ffffff2ff4f6f902ffffff00e8ecef00545455003b3c3d034a4c4d0088848400 +ffffff12ecf3f500e8ecef00e0e4e700d2d4d600cbcccd00c4c5c500bbbcbd01b4b4b400 +bbbcbd00b4b4b40099939300454445024a4c4d0045444500585c5e008c8b8c007b7b7d07 +6a6c6e007b7b7d016a6c6e007b7b7d006a6c6e017b7b7d006a6c6e00777474008c8b8c00 +ffffff17f4f6f901ecf3f502e8ecef01e0e4e702d9dcde00e0e4e700d9dcde03e0e4e700 +d9dcde00e0e4e704e8ecef01ecf3f503f4f6f900ffffff1df4f6f900ecf3f502e8ecef00 +e0e4e701d9dcde04e0e4e700d9dcde00e0e4e704e8ecef00ecf3f502f4f6f900ffffff13 +f4f6f900ecf3f501e8ecef01e0e4e701d9dcde00d2d4d607d9dcde02e0e4e701e8ecef00 +ecf3f502f4f6f901ffffff44f4f6f900ffffff00f4f6f904ecf3f500f4f6f900ffffff00 +f4f6f901fffffff7f4f6f900e8ecef00e0e4e700d2d4d600d8cccb00cbcccd00c4c5c500 +cbcccd00c6bcba004a4c4d006a6c6e0c7b7b7d006a6c6e067b7b7d00ffffff2eecf3f501 +e8ecef00ecf3f501e8ecef0063646500353434013b3c3d0145444500636465007b7b7d00 +c4c5c500ffffff11ecf3f500e8ecef00d9dcde01cbcccd00c4c5c500b4b4b400bbbcbd00 +b4b4b400bbbcbd00b4b4b40063646500454445015545410045444501636465007b7b7d07 +6a6c6e007b7b7d006a6c6e017b7b7d006a6c6e007b7b7d006a6c6e007b7b7d006a6c6e01 +a4a5a400ffffff17f4f6f901ecf3f501e8ecef00e0e4e700e8ecef00e0e4e702d9dcde00 +e0e4e700d9dcde00e0e4e700d9dcde02e0e4e704e8ecef03ecf3f502f4f6f901ffffff1b +f4f6f901ecf3f501e8ecef01e0e4e701d9dcde02e0e4e700d9dcde01e0e4e701d9dcde00 +e0e4e702e8ecef01ecf3f501f4f6f902ffffff10ecf3f502e8ecef01e0e4e701d9dcde01 +d2d4d601d9dcde00d2d4d600d9dcde00d2d4d600d9dcde01d2d4d600d9dcde01e0e4e701 +ecf3f500e8ecef00ecf3f501f4f6f900ffffff43f4f6f900ffffff00f4f6f901ffffff00 +f4f6f90bfffffff3f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd02c4c5c500 +8c8b8c004a4c4d00636465006a6c6e13c4c5c500ffffff2decf3f500e8ecef01e0e4e702 +7b7b7d002e2c2d00353434013b3c3d01585c5e007b7b7d02ffffff11ecf3f500e8ecef00 +d9dcde00d2d4d600cbcccd00bbbcbd01b4b4b400bbbcbd00b4b4b4009c9e9c0045444500 +463d3c00454445036a6c6e007b7b7d046a6c6e007b7b7d006a6c6e077b7b7d006a6c6e02 +b4b4b400ffffff17f4f6f902ecf3f500e8ecef01e0e4e702d9dcde00e0e4e700d9dcde02 +e0e4e700d9dcde00e0e4e700d9dcde00e0e4e702e8ecef00e0e4e700e8ecef02ecf3f501 +f4f6f902ffffff19f4f6f901ecf3f502e8ecef01e0e4e701d9dcde02e0e4e700d9dcde00 +e0e4e701d9dcde00e0e4e704e8ecef02ecf3f504f4f6f90decf3f502e8ecef02e0e4e701 +d9dcde02d2d4d602d9dcde00d2d4d600d9dcde00d2d4d601d9dcde01e0e4e703ecf3f502 +f4f6f901ffffff43f4f6f90effffff00f4f6f900fffffff2f4f6f900e8ecef00e0e4e700 +d2d4d601cbcccd00c4c5c50254545500636465036a6c6e11f4f6f900ffffff2bf4f6f900 +ecf3f500e8ecef00e0e4e700d9dcde0299939300353434002e2c2d00353434002e2c2d00 +353434004a4c4d00777474017b7b7d019c9e9c00ffffff10ecf3f500e8ecef00d9dcde00 +d2d4d600cbcccd00c4c5c500bbbcbd00b4b4b402585c5e003b3c3d01454445024a4c4d00 +7b7b7d056a6c6e0a7b7b7d006a6c6e01d2d4d600ffffff16f4f6f901ecf3f502e8ecef01 +e0e4e703d9dcde00e0e4e700d9dcde02e0e4e700d9dcde00e0e4e704e8ecef02ecf3f504 +f4f6f900ecf3f500f4f6f901ffffff00f4f6f900ffffff00f4f6f900ffffff00f4f6f901 +ffffff00f4f6f907ecf3f500f4f6f900ecf3f500f4f6f900ecf3f500f4f6f900ecf3f502 +e8ecef01e0e4e700e8ecef00e0e4e702d9dcde00e0e4e700d9dcde03e0e4e700d9dcde00 +e0e4e700d9dcde00e0e4e702e8ecef00e0e4e700e8ecef02ecf3f501e8ecef00ecf3f502 +e8ecef00ecf3f500e8ecef06ecf3f500e8ecef03e0e4e702d9dcde03d2d4d604d9dcde02 +d2d4d600d9dcde00d2d4d600d9dcde00e0e4e701e8ecef00ecf3f502f4f6f901ffffff41 +f4f6f911fffffff2f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd02c4c5c500 +999393003b3c3d00636465056a6c6e00636465006a6c6e03636465026a6c6e0463646500 +abacad00ffffff2cecf3f500e8ecef00d9dcde01d2d4d601a4a5a4003b3c3d0035343400 +2e2c2d01353434003b3c3d006a6c6e02777474007b7b7d01c4c5c500ffffff0ef4f6f900 +e8ecef00e0e4e700d9dcde00d2d4d600c4c5c500bbbcbd02b4b4b400888484003b3c3d04 +45444500636465007b7b7d046a6c6e007b7b7d006a6c6e02636465056a6c6e03e0e4e700 +ffffff09f4f6f900ffffff00f4f6f900ffffff00f4f6f900ffffff00f4f6f901ffffff00 +f4f6f901ecf3f500e8ecef03e0e4e703d9dcde02d2d4d601cbcccd00d2d4d602cbcccd00 +d2d4d608d9dcde03e0e4e700d9dcde07d2d4d600d9dcde00d2d4d608cbcccd00d2d4d600 +cbcccd06c4c5c504bbbcbd0bb4b4b400bbbcbd09b4b4b400bbbcbd00b4b4b401bbbcbd00 +b4b4b402bbbcbd00b4b4b400abacad00b4b4b400abacad00b4b4b400abacad00b4b4b400 +abacad02a4a5a400abacad00a4a5a4019c9e9c00a4a5a4009c9e9c02a4a5a4009c9e9c07 +a4a5a402abacad02b4b4b402bbbcbd01cbcccd00ffffff2fe8ecef00b4b4b4009c9e9c04 +999393009c9e9c01999393009c9e9c01999393009c9e9c028c8b8c009c9e9c018c8b8c00 +9c9e9c00999393019c9e9c00999393068c8b8c00999393048c8b8c02999393008c8b8c01 +999393008c8b8c01999393008c8b8c0b888484048c8b8c00888484018c8b8c0088848400 +8c8b8c00888484047b7b7d008c8b8c00888484017b7b7d00888484007b7b7d00867c7b00 +7b7b7d01888484007b7b7d01867c7b007b7b7d0a777474007b7b7d007774740a6a6c6e00 +777474006a6c6e00777474006a6c6e00777474006a6c6e00777474006a6c6e0077747400 +6a6c6e0c636465006a6c6e00636465006a6c6e00636465006a6c6e00636465006a6c6e00 +636465006a6c6e00675c5a0063646502675c5a0063646505585c5e00675c5a00585c5e00 +675c5a00585c5e0063646500585c5e00675c5a00585c5e00675c5a00585c5e0154545500 +585c5e0054545500585c5e0054545500585c5e0054545500585c5e0054545500585c5e00 +545455094a4c4d00584c48004a4c4d00584c48004a4c4d00584c48004a4c4d01584c4800 +4a4c4d00584c48004a4c4d00454445004a4c4d00454445004a4c4d0145444500584c4800 +4a4c4d00454445004a4c4d004544450a463d3c003b3c3d00454445003b3c3d00463d3c00 +3b3c3d00463d3c003b3c3d00463d3c003b3c3d00463d3c003b3c3d00353434003b3c3d00 +353434003b3c3d00353434003b3c3d00353434003b3c3d00353434003b3c3d003534340a +2e2c2d00353434002e2c2d03353434002e2c2d00353434022e2c2d00353434002e2c2d03 +675c5a00ffffff00ecf3f500e8ecef00e0e4e700d9dcde00d2d4d600cbcccd00c4c5c502 +5454550163646501585c5e0063646501585c5e0063646500585c5e0063646500585c5e00 +63646502585c5e00636465006a6c6e0063646504ecf3f500ffffff06867c7b00150e0d00 +1a1b1a00150e0d011a1b1a00150e0d0a0c0b0c02150e0d000c0b0c00150e0d05e0e4e700 +ffffff07ecf3f500e8ecef00d9dcde01d2d4d600cbcccd00b4b4b4004544450035343402 +2e2c2d003b3c3d00636465016a6c6e01777474007b7b7d00777474007b7b7d00d9dcde00 +ffffff0decf3f500e8ecef00d9dcde01cbcccd00c4c5c501bbbcbd00b4b4b4008c8b8c00 +3b3c3d00353434003b3c3d02454445016a6c6e007b7b7d026a6c6e007b7b7d006a6c6e04 +63646502585c5e02636465016a6c6e007b7b7d00e0e4e700150e0d000402049e2e2c2d00 +7b7b7d00cbcccd00ffffff27e8ecef00b4b4b4006a6c6e001a1b1a00040204ff04020410 +585c5e00f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd01c4c5c5019c9e9c00 +3534340063646501585c5e0063646503585c5e0063646500585c5e0163646500585c5e00 +63646506585c5e009c9e9c00ffffff05f4f6f900e0e4e7000402041b24232400ffffff06 +ecf3f500e8ecef00d9dcde01d2d4d600cbcccd00bbbcbd00545455003b3c3d0035343402 +3b3c3d00585c5e006a6c6e00636465006a6c6e03777474007b7b7d008c8b8c00d2d4d600 +ffffff0becf3f500e8ecef00e0e4e700d9dcde00d2d4d601c4c5c500bbbcbd00b4b4b400 +7b7b7d00353434023b3c3d00353434003b3c3d01585c5e007b7b7d006a6c6e007b7b7d00 +6a6c6e007b7b7d006a6c6e007b7b7d006a6c6e0263646502585c5e0063646500585c5e01 +636465016a6c6e009c9e9c01040204a3353434007b7b7d00d2d4d600ffffff1ff4f6f900 +bbbcbd006a6c6e0024232400040204ff04020414bbbcbd00ecf3f500e8ecef00e0e4e700 +d9dcde00d8cccb00cbcccd01c4c5c501585c5e004a4c4d0063646500585c5e006a6c6e00 +63646504585c5e00636465046a6c6e0063646500585c5e0063646500585c5e0063646500 +585c5e00d9dcde00ffffff02f4f6f901ecf3f501777474000402041ca4a5a400ffffff04 +f4f6f900e8ecef00e0e4e700d9dcde00d2d4d600cbcccd00c4c5c5006a6c6e003b3c3d01 +35343402545455006a6c6e047b7b7d02777474007b7b7d006a6c6e008c8b8c00d2d4d600 +ffffff08ecf3f500e8ecef00e0e4e701d2d4d600cbcccd00c4c5c5019c9e9c004a4c4d00 +2e2c2d03353434013b3c3d00454445006a6c6e01777474006a6c6e007b7b7d006a6c6e03 +63646501585c5e0063646503585c5e00636465016a6c6e01b4b4b4002e2c2d0004020430 +170204000402040217020400040204021702040004020400170204000402040017020400 +040204001702040004020400170204000402040017020400040204001702040104020400 +170204020402040017020402040204001702042127020400170204002702040017020400 +270204001702040027020400170204012702040017020400270204001702040027020400 +170204002702040017020400270204001702040027020400170204002702041f58020400 +a6442b00e8bcb000ffffff1ba65b4500580204003a020406480204003a02040348020400 +3a020401480204003a020401480204013a020400480204013a020400480204013a020400 +480204165802040048020400580204004802040158020400480204005802040048020400 +580204004802040058020401480204005802041568020400580204036802040058020401 +680204005802040068020400580204006802040058020400680204005802040068020400 +580204006802041779020400680204017902040068020402790204006802040079020400 +680204007902040068020400790204016802040079020401680204007902041688020400 +790204008802040079020400880204007902040088020400790204008802040079020400 +88020403790204008802041c940204018802040094020401880204009402040188020400 +9402040ca002040094020400a002040094020400a002040094020400a002040094020400 +a002040094020400a002040294020400a002041cc4363800ecf3f500f7ece700e0e4e700 +d9dcde00d2d4d600cbcccd01c4c5c501a4a5a4003b3c3d00585c5e026a6c6e0163646500 +6a6c6e0063646502585c5e00636465036a6c6e0163646501585c5e018c8b8c00ffffff02 +f4f6f900ecf3f500e8ecef01d9dcde0004020401b302041bbf181800ffffff03ecf3f500 +e8ecef00e0e4e700d2d4d601cbcccd017b7b7d00454445013b3c3d013534340054545500 +6a6c6e00636465006a6c6e067b7b7d006a6c6e007b7b7d00636465003b3c3d0063646500 +b4b4b400ecf3f500ffffff04ecf3f501e0e4e701d2d4d601c4c5c5008c8b8c004a4c4d00 +2e2c2d00242324002e2c2d04353434003b3c3d00585c5e006a6c6e0763646503585c5e00 +63646500585c5e006a6c6e047b7b7d00abacad0004020405b3020400a0020400b3020400 +a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400 +a0020400b3020401a0020400b3020401a0020400b3020400a0020400b3020400a0020400 +b3020400a0020400b3020401a0020400b3020402a0020400b3020401a0020400b3020400 +a0020400b3020401a0020400b3020400a0020400b3020400a0020400b3020400a0020401 +b3020400a0020401b3020400a0020401b3020400a0020402b3020400a0020402b3020400 +a0020402b3020400a002043894020400a002040094020400a002040094020400a0020400 +94020400a002040094020400a002040094020400a002040294020400a002040194020400 +a002040194020400a002040bcc626500ffffff1af9e4e100c4363800a0020400b3020400 +a0020400b3020400a0020401b3020400a0020401b3020400a0020400b3020400a0020400 +b3020400a0020401b3020400a0020400b3020400a0020400b3020400a0020401b3020400 +a0020400b3020400a0020400b3020400a0020401b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020400b302040aa0020400b3020404a0020400b3020404 +a0020400b3020402a0020400b3020401a0020400b3020484bc0b0e00b3020400bc0b0e01 +b3020400bc0b0e01b3020400bc0b0e01b3020400bc0b0e00b3020404bc0b0e00b3020404 +bc0b0e00b3020404bc0b0e00b3020423bc0b0e01b3020401bc0b0e00b3020400bc0b0e00 +b3020403e8a58f00e8ecef01e0e4e700d9dcde00d2d4d600cbcccd01c4c5c501585c5e00 +4a4c4d00636465036a6c6e00585c5e0063646501585c5e0263646500585c5e0063646501 +6a6c6e0063646500585c5e0063646501585c5e00d2d4d600f4f6f901ecf3f500e8ecef00 +e0e4e701d9dcde0077747400040204003a020400b302041cea7c5e00ffffff01f4f6f900 +ecf3f500e0e4e700d9dcde00d2d4d600cbcccd01999393003b3c3d01454445013b3c3d00 +4a4c4d006a6c6e087b7b7d006a6c6e01777474006a6c6e013b3c3d00353434003b3c3d00 +6364650099939300c4c5c500d9dcde00ecf3f500e8ecef00e0e4e700d9dcde00bbbcbd00 +8c8b8c00636465002e2c2d00242324022e2c2d0535343400545455006a6c6e0863646500 +585c5e0063646500585c5e026a6c6e037b7b7d006a6c6e008c8b8c004a4c4d0004020404 +58020400a0020400b3020401a0020400b3020401a0020400b3020400a0020400b3020401 +a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020400b3020400a0020401b3020400a0020400b3020400 +a0020400b3020400a0020400b3020400a0020401b3020400a0020402b3020400a0020401 +b3020400a0020401b3020400a0020402b3020400a0020403b3020400a0020401b3020400 +a0020401b3020400a002044194020400a002040194020400a002040294020400a0020401 +94020400a002040194020400a002040094020400a002040094020400a002040094020400 +a002040094020400a002040094020400a002040094020401a002040094020400a0020400 +94020405a002040094020400b2181a00e9d5d700ffffff19f4f6f900d8846e00b3020400 +a0020401b3020400a0020401b3020400a0020400b3020400a0020401b3020400a0020401 +b3020400a0020400b3020400a0020400b3020400a0020401b3020400a0020400b3020400 +a0020401b3020400a0020400b3020400a0020400b3020400a0020401b3020400a0020400 +b3020400a0020400b3020400a0020401b3020400a0020401b3020400a0020401b3020400 +a0020400b3020400a0020400b3020400a0020401b3020401a0020400b3020400a0020400 +b3020400a0020400b3020402a0020400b3020401a0020400b3020402a0020400b3020400 +a0020400b3020401a0020400b3020401a0020400b302044ebc0b0e00b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b302040d +bc0b0e00b3020405bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e01 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e02b3020400bc0b0e04 +b3020400bc0b0e05b3020400bc0b0e07b3020400bc0b0e01b3020400bc0b0e02b3020400 +bc0b0e02b3020400bc0b0e00b3020402bc0b0e06b3020400bc0b0e02b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e01c4232400 +e8ecef01e0e4e700d9dcde00d2d4d600d8cccb00cbcccd00c4c5c501a4a5a4003b3c3d00 +585c5e0063646500585c5e0063646504585c5e0463646500585c5e01636465006a6c6e00 +6364650288848400ecf3f500f4f6f900ecf3f500e0e4e701d9dcde01d8cccb0004020401 +a0020400b3020402bc0b0e00b3020401bc0b0e00b3020400bc0b0e00b3020401bc0b0e00 +b3020411e5c4c200f4f6f900e8ecef00e0e4e700d9dcde01cbcccd01a4a5a4003b3c3d00 +353434003b3c3d00454445003b3c3d004a4c4d007b7b7d006a6c6e007b7b7d006a6c6e03 +636465016a6c6e027b7b7d006a6c6e02636465004a4c4d0035343401242324002e2c2d00 +242324003b3c3d01454445002e2c2d001a1b1a03242324042e2c2d012423240035343400 +54545500636465046a6c6e00636465006a6c6e0063646502585c5e01636465026a6c6e05 +9c9e9c0004020405a0020400b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020400b3020401a0020400b3020400a0020400b3020400a0020400b3020400 +a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400 +a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020401 +b3020400a0020401b3020400a0020400b3020400a0020402b3020400a0020409b3020400 +a0020400b3020400a0020400b3020400a0020400b3020400a0020401b3020400a0020401 +b3020400a0020401b3020400a0020401b3020400a002041f94020400a002040394020400 +a002040094020400a002040094020400a002040094020400a002040194020400a0020401 +94020400a002040094020400a002040194020400a002040194020400a002040294020400 +a002040194020400a002040194020400a002040094020400a002040094020400a0020400 +94020401a002040094020400a002040194020400a002040094020401a0020401d98c7800 +ffffff1ad7c4bd00bf181800a0020401b3020400a0020401b3020400a0020401b3020400 +a0020400b3020400a0020400b3020400a0020401b3020400a0020400b3020400a0020400 +b3020400a0020401b3020400a0020400b3020400a0020400b3020400a0020400b3020400 +a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020401a0020400 +b3020401a0020400b3020401a0020400b3020401a0020400b3020402a0020400b3020401 +a0020400b3020400a0020400b3020401a0020400b3020401a0020400b3020401a0020400 +b3020400a0020400b3020403a0020400b3020404a0020400b3020400a0020400b3020400 +a0020400b3020401a0020400b3020401a0020400b302043bbc0b0e00b3020400bc0b0e00 +b3020400bc0b0e00b3020404bc0b0e00b3020401bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e07b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e01b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e01b3020400 +bc0b0e00b3020400bc0b0e02b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e01 +b3020400bc0b0e01b3020400bc0b0e02b3020400bc0b0e00b3020400bc0b0e00b3020401 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e02b3020400bc0b0e00 +b3020400bc0b0e00b3020401e59c8700e8ecef01e0e4e700d9dcde00d2d4d600cbcccd01 +c4c5c500cbcccd00636465004a4c4d0063646503585c5e0d63646502c4c5c500ecf3f501 +e0e4e700d9dcde01d2d4d600cbcccd007b7b7d000402040027020400b3020401bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020402bc0b0e00b3020401bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020408b0262800 +d9dcde00e8ecef00d9dcde01cbcccd01c4c5c500636465002e2c2d01353434003b3c3d00 +45444500777474007b7b7d01777474006a6c6e0263646501585c5e006a6c6e0763646500 +585c5e004544450035343400242324002e2c2d001a1b1a04242324001a1b1a0124232400 +1a1b1a0124232402353434004a4c4d00585c5e0463646502585c5e0063646502585c5e00 +63646500585c5e00636465026a6c6e00636465006a6c6e017b7b7d014a4c4d0004020404 +27020400b3020400a0020400b3020402a0020400b3020401a0020400b3020400a0020400 +b3020400a0020400b3020400a0020400b3020400a0020400b3020401a0020400b3020400 +a0020401b3020400a0020400b3020400a0020400b3020400a0020401b3020400a0020401 +b3020400a0020401b3020400a0020400b3020400a0020400b3020400a0020401b3020400 +a0020401b3020400a0020403b3020400a0020400b3020400a0020401b3020400a0020400 +b3020400a0020400b3020400a0020400b3020400a0020418b3020400a002041d94020400 +a002040794020400a002040294020400a002040294020400a002040194020400a0020400 +94020400a002040094020400a002040194020400a002040094020400a002040094020400 +a002040194020400a002040194020400a002040094020400a002040094020402a0020400 +94020400a002040094020400a002040094020400a0020400b0262800f9e4e100ffffff08 +f4f6f900ffffff0ef4f6f900e0e4e700c75c4d00b3020400a0020400b3020400a0020401 +b3020400a0020400b3020400a0020401b3020400a0020401b3020400a0020401b3020400 +a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400 +a0020400b3020400a0020400b3020400a0020400b3020401a0020400b3020400a0020400 +b3020401a0020400b3020400a0020400b3020401a0020400b3020404a0020400b3020400 +a0020400b3020401a0020400b3020404a0020400b3020404a0020400b3020405a0020400 +b3020408a0020400b3020428bc0b0e00b3020401bc0b0e00b3020402bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020404bc0b0e01b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020401bc0b0e00b3020400 +bc0b0e00b3020406bc0b0e00b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e01b3020400bc0b0e00b3020401bc0b0e00b3020400bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e02b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e00 +b3020400bc0b0e02b3020400bc0b0e00b3020400bc0b0e03b3020401bc0b0e00b3020400 +bc0b0e01b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e02b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e02b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020401bc0b0e01b3020400bc0b0e01bf181800e0e4e700 +e8ecef00e0e4e700d9dcde00d2d4d600cbcccd02c4c5c500a4a5a4003b3c3d00585c5e00 +63646504585c5e0063646500585c5e0354545500585c5e0363646500585c5e0063646501 +7b7b7d00ecf3f501e0e4e701d2d4d600cbcccd02170204000402040094020400bc0b0e00 +b3020401bc0b0e00b3020403bc0b0e00b3020401bc0b0e00b3020401bc0b0e00b3020401 +bc0b0e00b3020403bc0b0e00b3020408a8655400d9dcde01d2d4d600cbcccd00c4c5c501 +a4a5a400353434002e2c2d013b3c3d0063646500777474006a6c6e01777474006a6c6e01 +63646502585c5e00636465006a6c6e05585c5e0063646502585c5e004a4c4d0035343400 +2e2c2d00242324001a1b1a06242324001a1b1a00242324002e2c2d004a4c4d0054545500 +585c5e10636465026a6c6e038c8b8c000402040588020400b3020401a0020400b3020400 +a0020400b3020401a0020400b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020401b3020400a0020400b3020401a0020401b3020400 +a0020401b3020400a0020400b3020400a0020400b3020400a0020401b3020400a0020400 +b3020400a0020402b3020400a0020400b3020400a0020400b3020400a0020401b3020400 +a0020400b3020400a0020403b3020400a0020408b3020400a0020401b3020400a0020402 +b3020400a0020401b3020400a0020401b3020400a002042294020400a002040194020400 +a002040294020400a002040194020400a002040094020400a002040294020400a0020402 +94020400a002040294020400a002040194020400a002040194020400a002040094020400 +a002040094020400a002040194020400a002040094020400a002040094020400a0020400 +94020400a002040094020400a002040194020400a002040094020400a002040094020400 +a002040094020401a0020401dba39300ffffff04f4f6f900ffffff11f4f6f900ecf3f500 +e8ecef00c8a49d00b3020400a0020400b3020400a0020401b3020400a0020401b3020400 +a0020401b3020400a0020400b3020400a0020401b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400 +a0020400b3020400a0020400b3020401a0020400b3020401a0020400b3020400a0020400 +b3020400a0020400b3020401a0020400b3020400a0020400b3020401a0020400b3020401 +a0020400b3020400a0020400b3020400a0020400b3020403a0020400b3020401a0020400 +b3020400a0020400b3020401a0020400b3020400a0020400b302040ba0020400b3020401 +a0020400b3020405a0020400b3020422bc0b0e00b3020409bc0b0e00b3020401bc0b0e00 +b3020401bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020401bc0b0e00b3020402 +bc0b0e00b3020401bc0b0e00b3020400bc0b0e00b3020401bc0b0e00b3020400bc0b0e04 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00 +b3020401bc0b0e01b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e01b3020400 +bc0b0e01b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e02b3020400 +bc0b0e00b3020400bc0b0e02b3020401bc0b0e03b3020400bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e02b3020400bc0b0e00b3020400bc0b0e02b3020400bc0b0e00 +b3020400bc0b0e02b3020400bc0b0e00b3020400bc0b0e00b3020400e78b7100e8ecef00 +e0e4e700e6dcdc00d9dcde00d2d4d600cbcccd01c4c5c501636465004a4c4d00585c5e03 +63646500585c5e0263646500585c5e0863646500585c5e0063646500b4b4b400ecf3f500 +e8ecef00d9dcde00d2d4d601cbcccd00c4c5c500888484000402040017020400b3020401 +bc0b0e00b3020401bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00 +b3020401bc0b0e00b3020401bc0b0e00b3020401bc0b0e00b3020403bc0b0e00b3020401 +bc0b0e00b3020403a0020400b7a4a000d2d4d600cbcccd00c4c5c502bbbcbd008c8b8c00 +2e2c2d0035343400545455006a6c6e046364650b585c5e0063646500585c5e0063646503 +585c5e014a4c4d003b3c3d002e2c2d001a1b1a01242324022e2c2d003b3c3d004a4c4d00 +545455004a4c4d01545455004a4c4d02545455004a4c4d03585c5e08636465016a6c6e01 +7b7b7d01454445000402040417020400b3020400a0020400b3020401a0020400b3020400 +a0020400b3020400a0020400b3020401a0020400b3020400a0020400b3020401a0020400 +b3020400a0020400b3020400a0020400b3020400a0020401b3020400a0020400b3020400 +a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020401b3020400a0020400b3020400a0020402b3020400a0020401b3020400 +a0020400b3020400a0020401b3020400a0020403b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020405b3020400a0020409b3020400a002042894020400 +a002040194020400a002040094020400a002040194020400a002040094020400a0020401 +94020400a002040194020400a002040094020400a002040094020400a002040094020400 +a002040194020400a002040094020400a002040094020400a002040194020400a0020400 +94020400a002040094020401a002040094020401a002040094020402a002040094020400 +a002040094020400a0020400cf4d4f00e8ecef00ffffff15f4f6f901e8ecef00e0e4e700 +d8cccb00b9462700a0020401b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020401b3020400a0020400b3020400a0020401b3020400a0020400b3020400 +a0020400b3020400a0020401b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400 +a0020400b3020401a0020400b3020400a0020400b3020401a0020400b3020400a0020400 +b3020400a0020400b3020401a0020400b3020401a0020400b3020400a0020400b3020401 +a0020400b3020403a0020400b3020404a0020400b3020401a0020400b3020400a0020400 +b3020401a0020400b3020406a0020400b3020404a0020400b3020402a0020400b3020423 +bc0b0e00b3020400bc0b0e00b3020404bc0b0e00b3020402bc0b0e00b3020401bc0b0e00 +b3020402bc0b0e01b3020401bc0b0e00b3020401bc0b0e00b3020400bc0b0e00b3020401 +bc0b0e00b3020403bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e01 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e01b3020400 +bc0b0e01b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e01b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e02b3020400bc0b0e02b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e02b3020400bc0b0e00b3020400bc0b0e01b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e00b3020401bc0b0e00 +b3020400bc0b0e00b3020400bf181800e6dcdc00e8ecef00e0e4e700d9dcde00d2d4d600 +d8cccb00cbcccd00c4c5c501abacad002e2c2d00585c5e0463646502585c5e026a6c6e00 +585c5e01636465006a6c6e0063646500585c5e00636465026a6c6e00e8ecef01e0e4e700 +d9dcde01cbcccd00c4c5c5011a1b1a000402040088020400b3020401bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020403bc0b0e00b3020401bc0b0e00 +b3020405bc0b0e00b302040988020400c4c5c503bbbcbd02585c5e0045444500585c5e00 +63646504585c5e0063646500585c5e0163646506585c5e0263646500585c5e0063646500 +585c5e05545455014a4c4d01545455034a4c4d07454445024a4c4d04545455024a4c4d01 +585c5e02636465016a6c6e007b7b7d000402040579020400b3020400a0020400b3020400 +a0020400b3020401a0020400b3020401a0020400b3020400a0020400b3020401a0020400 +b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400 +a0020400b3020400a0020400b3020400a0020400b3020400a0020401b3020400a0020401 +b3020400a0020401b3020400a0020400b3020400a0020400b3020400a0020400b3020400 +a0020401b3020400a0020402b3020400a0020402b3020400a0020400b3020400a0020408 +b3020400a0020400b3020400a0020403b3020400a0020402b3020400a0020406b3020400 +a0020407b3020400a002040e94020400a002040394020400a002040394020400a0020402 +94020400a002040494020400a002040394020400a002040094020400a002040094020400 +a002040194020400a002040394020400a002040194020400a002040094020400a0020400 +94020400a002040094020400a002040094020400a002040094020400a002040094020400 +a002040094020400a002040094020400a002040094020400a002040094020400a0020400 +94020400a0020401e8bcb000ffffff03f4f6f900ffffff10f4f6f900ecf3f500e8ecef01 +e0e4e700c88b7d00b3020400a0020402b3020400a0020401b3020400a0020400b3020400 +a0020400b3020400a0020400b3020400a0020401b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020400b3020400a0020400b3020401a0020400b3020400 +a0020400b3020400a0020400b3020400a0020400b3020401a0020400b3020400a0020400 +b3020402a0020400b3020401a0020400b3020402a0020400b3020401a0020400b3020403 +a0020400b3020401a0020400b3020400a0020400b3020402a0020400b3020400a0020400 +b302040ba0020400b302042ebc0b0e00b3020401bc0b0e00b3020404bc0b0e00b3020402 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020401bc0b0e00b3020400bc0b0e00 +b3020401bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020401bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020401bc0b0e00b3020400bc0b0e01 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e01b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e01b3020400bc0b0e02b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e01 +b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e01b3020400 +bc0b0e01b3020400d8846e00e8ecef00e0e4e701d9dcde00d2d4d600cbcccd00c4c5c501 +cbcccd00636465003b3c3d00585c5e05636465046a6c6e00636465006a6c6e0063646503 +585c5e02b4b4b400ecf3f501e8ecef00d9dcde01d2d4d601b4b4b4000402040017020400 +b3020401bc0b0e00b3020401bc0b0e00b3020403bc0b0e00b3020400bc0b0e00b3020401 +bc0b0e00b3020401bc0b0e00b3020400bc0b0e00b302040e7c3a3c00c4c5c501bbbcbd03 +abacad006a6c6e0063646500585c5e0063646500585c5e0763646500585c5e0063646500 +585c5e0063646500585c5e0463646503585c5e02545455044a4c4d06454445064a4c4d00 +454445014a4c4d06585c5e03636465017b7b7d008c8b8c000402040417020400b3020400 +a0020400b3020401a0020400b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400 +a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020401b3020400a0020400b3020400a0020400b3020400 +a0020402b3020400a0020400b3020400a0020400b3020400a0020402b3020400a0020401 +b3020400a0020405b3020400a0020400b3020400a0020401b3020400a002040ab3020400 +a0020402b3020400a002042494020400a002040394020400a002040294020400a0020400 +94020400a002040194020400a002040094020400a002040194020400a002040194020400 +a002040094020400a002040094020401a002040094020400a002040094020400a0020401 +94020400a002040094020400a002040094020401a002040094020401a002040094020400 +a002040094020401a002040094020402a002040094020403a002040094020400cc626500 +ffffff15f4f6f901e8ecef01e0e4e700d8bcb600c42c3000a0020400b3020400a0020401 +b3020400a0020400b3020400a0020401b3020400a0020401b3020400a0020400b3020400 +a0020401b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020400b3020401a0020400b3020400a0020400b3020401a0020400b3020400 +a0020400b3020401a0020400b3020400a0020400b3020400a0020400b3020401a0020400 +b3020401a0020400b3020401a0020400b3020400a0020400b3020401a0020400b3020401 +a0020400b3020401a0020400b3020406a0020400b3020401a0020400b3020401a0020400 +b3020404a0020400b3020402a0020400b302042dbc0b0e00b3020402bc0b0e00b3020400 +bc0b0e00b3020404bc0b0e00b3020401bc0b0e00b3020400bc0b0e00b3020401bc0b0e00 +b3020400bc0b0e00b3020401bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020401 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020401bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e01b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e00 +b3020400bc0b0e01b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e01b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e01b3020400bc0b0e00 +b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e02b3020400bc0b0e01b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e01b3020400bc0b0e02 +b3020400bc0b0e00b3020400bc0b0e01b3020401bc0b0e01b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e01e6dcdc00e8ecef01 +d9dcde00d2d4d600cbcccd02c4c5c500b4b4b4002e2c2d004a4c4d00545455014a4c4d00 +54545500585c5e04636465016a6c6e01636465006a6c6e0163646501585c5e016a6c6e00 +ecf3f500f4f6f901ecf3f500e8ecef00d9dcde02c4c5c5000402040079020400b3020402 +bc0b0e00b3020401bc0b0e00b3020400bc0b0e00b3020401bc0b0e00b3020400bc0b0e00 +b3020401bc0b0e00b3020403bc0b0e00b3020401bc0b0e00b3020401bc0b0e00b3020407 +a0020400978c8a00c4c5c500bbbcbd00c4c5c500bbbcbd02a4a5a40063646500585c5e05 +54545501585c5e0463646500585c5e0063646501585c5e0063646500585c5e0063646504 +585c5e04545455014a4c4d02454445013b3c3d004544450b3b3c3d00454445004a4c4d05 +585c5e00636465029c9e9c00cbcccd00b4b4b400241a18000402040279020400a0020400 +b3020401a0020400b3020400a0020400b3020401a0020400b3020401a0020400b3020400 +a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020401b3020400a0020400b3020400a0020401b3020400a0020400b3020400 +a0020400b3020400a0020401b3020400a0020400b3020400a0020400b3020400a0020404 +b3020400a0020400b3020400a0020400b3020400a0020402b3020400a0020400b3020400 +a0020400b3020400a0020407b3020400a0020402b3020400a0020400b3020400a0020409 +b3020400a0020404b3020400a002041594020400a002040694020400a002040394020400 +a002040294020400a002040194020400a002040194020400a002040194020400a0020401 +94020400a002040294020400a002040094020400a002040094020401a002040094020400 +a002040094020401a002040094020400a002040094020400a002040094020401a0020400 +94020401a002040094020400a002040094020402a002040094020400a002040094020401 +b2181a00d2d4d600ffffff00f4f6f900ffffff13ecf3f501e8ecef01d9dcde00c8745e00 +b3020400a0020400b3020400a0020401b3020400a0020400b3020400a0020400b3020400 +a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400 +a0020400b3020401a0020400b3020400a0020400b3020401a0020400b3020400a0020400 +b3020401a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020401 +a0020400b3020401a0020400b3020402a0020400b3020402a0020400b3020401a0020400 +b3020400a0020400b3020400a0020400b3020402a0020400b3020404a0020400b3020411 +a0020400b3020419bc0b0e00b3020402bc0b0e00b3020401bc0b0e00b3020402bc0b0e00 +b3020401bc0b0e00b3020401bc0b0e00b3020400bc0b0e00b3020401bc0b0e00b3020403 +bc0b0e00b3020403bc0b0e00b3020400bc0b0e00b3020401bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e00b3020401bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020401bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e00b3020400 +bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e02b3020400bc0b0e01b3020400 +bc0b0e00b3020400bc0b0e03b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00 +b3020400bc0b0e00b3020400bc0b0e01b3020400bc0b0e00b3020400bc0b0e01b3020400 +bc0b0e01b3020400bc0b0e00b3020400bc0b0e00b3020400bc0b0e00d8755c00f7ece700 +e0e4e700e6dcdc00d9dcde00d2d4d600cbcccd01c4c5c5016a6c6e002e2c2d0054545500 +4a4c4d0054545501585c5e004a4c4d00585c5e0263646500585c5e00636465006a6c6e00 +636465016a6c6e0163646500585c5e02a4a5a400f4f6f900ffffff00f4f6f900ecf3f500 +e8ecef01e0e4e700d9dcde00e0e4e7003a020400b3020402bc0b0e00b3020401bc0b0e00 +b3020401bc0b0e00b3020400bc0b0e00b3020402bc0b0e00b3020401bc0b0e00b3020401 +bc0b0e00b3020401bc0b0e00b3020401bc0b0e00b30204099c161400c6bcba00bbbcbd05 +99939300585c5e00545455024a4c4d0154545502585c5e0463646500585c5e0063646500 +585c5e02636465016a6c6e0063646500585c5e06545455004a4c4d00545455004a4c4d00 +4544450f4a4c4d00454445004a4c4d0354545500585c5e01636465007b7b7d00cbcccd00 +d2d4d601d9dcde007b7b7d000402040017020400b3020401a0020400b3020401a0020400 +b3020400a0020400b3020400a0020400b3020400a0020400b3020401a0020400b3020400 +a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020400b3020400a0020400b3020400a0020400b3020400 +a0020401b3020400a0020401b3020400a0020400b3020400a0020400b3020400a0020400 +b3020400a0020402b3020400a0020402b3020400a0020400b3020400a0020405b3020400 +a0020400b3020400a0020400b3020400a0020403b3020400a0020408b3020400a0020423 +94020400a002040294020400a002040194020400a002040294020400a002040094020400 +a002040194020400a002040194020400a002040094020400a002040194020400a0020401 +94020400a002040094020400a002040194020400a002040094020400a002040094020400 +a002040094020400a002040094020400a002040094020400a002040094020401a0020400 +94020401a002040094020401a002040094020400a002040094020400a002040094020402 +a002040094020400a0020401c47b7d00ffffff15f4f6f901e8ecef01e0e4e700d8b4ac00 +b2181a00a0020401b3020400a0020402b3020400a0020401b3020400a0020400b3020400 +a0020400b3020400a0020400b3020400a0020401b3020400a0020400b3020400a0020400 +b3020400a0020400b3020400a0020400b3020401a0020400b3020400a0020400b3020401 +a0020400b3020412a0020400b3020427bc0b0e00b3020405bc0b0e00b3020402bc0b0e00 +b3020401bc0b0e00b3020400bc0b0e0cbf181800bc0b0e06bf181800bc0b0e00bf181800 +bc0b0e00bf181800bc0b0e00bf181801bc0b0e00bf181800bc0b0e00bf18180ec4232400 +bf181801c4232400bf181803c4232402bf181800c4232402bf181800c4232403c42c3000 +c4232400c42c3000c4232401c42c3000c4232400c42c3000c4232400c42c300ac4363801 +c42c3000c4363800c42c3000c4363800c42c3000c4363800c42c3000c4363800c42c3000 +c436380acc3c3f00c4363800cc3c3f00c4363800cc3c3f00c4363802cc3c3f00c4363801 +cc3c3f0acc444400cc3c3f00cc444400cc3c3f00cc444400cc3c3f00cc444400cc3c3f00 +cc444400cc3c3f00cc444401cf4d4f00cc444400cf4d4f06e9d5d700e8ecef00e0e4e700 +d9dcde00d2d4d600d8cccb00cbcccd00c4c5c501b4b4b4002e2c2d00454445004a4c4d01 +54545500585c5e0054545500585c5e0054545500585c5e0363646500585c5e0063646500 +585c5e0063646500585c5e0063646501585c5e0063646500ecf3f500ffffff02f4f6f900 +ecf3f500e8ecef03c47b7d00c75c4d00cc54580ad45e4400cc626500cc545801cc626500 +cc545800d45e4400cc545800cc626500cc545800cc626505d9654700cc626502cc545800 +cc626501cc545800ba5d4500cc545800b7533a00b7a4a000bbbcbd00c4c5c500bbbcbd04 +7b7b7d0054545500585c5e0054545501585c5e004a4c4d0054545502585c5e0863646502 +6a6c6e0163646501585c5e06545455004a4c4d01454445013b3c3d00454445003b3c3d00 +454445023b3c3d00454445003b3c3d00454445013b3c3d00454445014a4c4d0354545501 +585c5e0063646501b4b4b400d9dcde00e0e4e700d9dcde02bbbcbd00b77c6a00c47b7d00 +c8745e00c47b7d00c8745e00c47b7d01c97c6700c47b7d32c8847200c47b7d00c8847200 +c47b7d00b9857800c47b7d00b9857800c47b7d00b9857800c47b7d00c8847200c47b7d00 +c88b7d00c47b7d00b9857800c88b7d00c47b7d00c88b7d00c47b7d00c88b7d00c47b7d00 +c88b7d00b78d8500c88b7d00b98a7c00c88b7d02b98a7c00c88b7d00b98a7c00c88b7d00 +b98a7c00c88b7d00b78d8500c88b7d00b78d8500c88b7d01b78d8500c88b7d00b78d8500 +c88b7d00b98a7c00c8938400b78d8500c8938400b78d8500c8938400b78d8500c8938400 +b78d8504b8938b03c8938400b78d8500b8938b01c8938400b78d8500b8938b05b78d8500 +b8938b00b78d8500b8938b00b78d8500b8938b00b99a9400b8938b02b99a9400b8938b03 +b99a940ac8a49d00b7a4a000c8aca502d8b4ac00d8bcb601d7c4bd00e5c4c200e6ccc900 +e9d5d701f8d4c900e9d5d708e6dcdc00e9d5d700f9dcd100e9d5d700f4f6f900ffffff15 +f4f6f902ecf3f501e8ecef00e6ccc901d7c4bd00d8cccb00e6ccc900d8cccb01e6ccc900 +d8cccb07e9d5d700d8cccb00d2d4d600e9d5d700d8cccb00d2d4d600e9d5d700d2d4d600 +e9d5d700d2d4d600e9d5d700d9dcde00e9d5d700e6dcdc00e9d5d700d9dcde00e9d5d700 +d9dcde00e6dcdc00d9dcde00e9d5d700d9dcde00e6dcdc02d9dcde00e0e4e700e6dcdc02 +d9dcde00e6dcdc00e0e4e703e6dcdc00e8ecef00e6dcdc00e0e4e701e6dcdc00e0e4e700 +e8ecef00e0e4e700e8ecef00e0e4e700e8ecef0aecf3f500e8ecef00ecf3f500e8ecef00 +ecf3f500e8ecef00ecf3f500e8ecef00f4f6f900e8ecef00f4f6f900e8ecef00f4f6f900 +e8ecef00f4f6f900e8ecef00f4f6f900e8ecef00ecf3f500e8ecef00ecf3f500f7ece700 +ecf3f501e8ecef00f4f6f900e8ecef01f4f6f900f7ece700f4f6f900e8ecef00f4f6f900 +f7ece700f4f6f900f7ece700f4f6f900f7ece700f4f6f900f7ece700f4f6f900f7ece700 +f4f6f902f7ece700f4f6f901f7ece700f4f6f909f7ece700f4f6f902f7ece700f4f6f901 +f7ece700f4f6f900f7ece700f4f6f904f7ece700f4f6f90dffffff01f4f6f906ffffff00 +f4f6f91dffffff00f4f6f902ffffff00f4f6f903ffffff00f4f6f901ffffff00f4f6f91a +ffffff00f4f6f903ffffff00f4f6f900ffffff09f4f6f901e8ecef01e0e4e700d9dcde00 +d2d4d600cbcccd01c4c5c501777474002e2c2d004a4c4d0254545500585c5e0054545500 +585c5e0e9c9e9c00f4f6f900ffffff04f4f6f900ecf3f503e8ecef00f4f6f902ecf3f500 +f4f6f900ecf3f500f4f6f900ecf3f500f4f6f900ecf3f500f4f6f900e8ecef00f4f6f902 +f7ece700ecf3f501f4f6f900f7ece700ecf3f500f4f6f907f7ece700e8ecef01e0e4e700 +d9dcde01d2d4d600cbcccd00c4c5c501c6bcba00bbbcbd067b7b7d004a4c4d0054545506 +585c5e0a6a6c6e0163646500585c5e04545455004a4c4d00545455014a4c4d0054545500 +4a4c4d03454445004a4c4d04454445024a4c4d06585c5e004a4c4d00585c5e028c8b8c00 +e8ecef01e0e4e700e8ecef01e0e4e700e8ecef00e0e4e707e6dcdc00e0e4e700d9dcde00 +e0e4e700d9dcde00e0e4e700d9dcde00e0e4e700d9dcde00e0e4e702d9dcde00e0e4e701 +d9dcde00e0e4e700d9dcde00e0e4e701d9dcde00e0e4e700d9dcde00e0e4e700d9dcde00 +e0e4e700d9dcde00e0e4e700d9dcde00e0e4e704d9dcde00e0e4e700d9dcde00e0e4e700 +d9dcde00e0e4e700d9dcde00e0e4e700d9dcde15e0e4e700d9dcde0bd2d4d600d9dcde00 +d2d4d600d9dcde00d2d4d616d9dcde00d2d4d600d9dcde00d2d4d600d9dcde00d2d4d60a +cbcccd00d2d4d602cbcccd00d2d4d600cbcccd00d2d4d600cbcccd00d2d4d600cbcccd00 +d2d4d600cbcccd01d2d4d600cbcccd00d2d4d600cbcccd03d2d4d600cbcccd03d2d4d600 +cbcccd00d2d4d600cbcccd00d2d4d601e0e4e701e8ecef01ecf3f501ffffff2bf4f6f902 +e8ecef00ecf3f500e8ecef11ecf3f500f7ece700e8ecef02f4f6f900e8ecef00ecf3f500 +e8ecef00ecf3f501e8ecef00ecf3f500f4f6f900e8ecef00ecf3f505f4f6f902ecf3f501 +f4f6f901ecf3f500f4f6f903ecf3f501f7ece700ecf3f500f4f6f900ecf3f500f4f6f904 +f7ece700f4f6f900ecf3f500f7ece700f4f6f90bffffff00f4f6f905ffffff00f4f6f902 +ffffff00f4f6f914ffffff00f4f6f900ffffff00f4f6f900ffffff00f4f6f900ffffff13 +f4f6f900ffffff01f4f6f900ffffff01f4f6f900ffffff71f4f6f901e8ecef00e0e4e700 +d9dcde00d2d4d600cbcccd01c4c5c501bbbcbd0035343400454445004a4c4d04585c5e00 +4a4c4d00585c5e004a4c4d0054545502585c5e004a4c4d0454545501585c5e00ecf3f500 +ffffff09f4f6f900ffffff01f4f6f901ffffff00f4f6f906ffffff00f4f6f901ffffff00 +f4f6f900ffffff01f4f6f900ffffff01f4f6f900ffffff06f4f6f901ecf3f500e8ecef00 +e0e4e700d9dcde00d2d4d601cbcccd00c4c5c502bbbcbd00c4c5c500bbbcbd01c4c5c500 +bbbcbd00b4b4b40077747400585c5e0054545500585c5e00545455014a4c4d0054545502 +585c5e004a4c4d0054545504585c5e0263646502585c5e0554545501585c5e0054545501 +4a4c4d04545455004a4c4d07545455004a4c4d00585c5e0054545502585c5e026a6c6e00 +e0e4e700ecf3f50ce8ecef25e0e4e700e8ecef00e0e4e700e8ecef00e0e4e702e8ecef00 +e0e4e702e8ecef00e0e4e703e8ecef01e0e4e700e8ecef00e0e4e701e8ecef00e0e4e700 +e8ecef00e0e4e700e8ecef01e0e4e701e8ecef00e0e4e701e8ecef00e0e4e700e8ecef00 +e0e4e707d9dcde00e0e4e701d9dcde00e0e4e702d9dcde00e0e4e701d9dcde00e0e4e701 +d9dcde00e0e4e701d9dcde00e0e4e700d9dcde00e0e4e700d9dcde00e0e4e702d9dcde01 +e0e4e700d9dcde03e0e4e700d9dcde00e0e4e700d9dcde0cd2d4d600d9dcde0cd2d4d600 +d9dcde03d2d4d600d9dcde03e0e4e702e8ecef00ecf3f500f4f6f902ffffff2cf4f6f915 +ecf3f500f4f6f90bffffff00f4f6f901ffffff00f4f6f900ffffff01f4f6f900ffffff03 +f4f6f900ffffff00f4f6f903ffffff00f4f6f900ffffff01f4f6f901ffffff00f4f6f902 +ffffff00f4f6f900ffffff01f4f6f900ffffffc0f4f6f900ecf3f500e8ecef00e0e4e700 +d9dcde00d2d4d600d8cccb00cbcccd00c4c5c5017b7b7d002e2c2d004a4c4d0554545500 +4a4c4d00585c5e014a4c4d0a8c8b8c00ffffff2bf4f6f900ecf3f500e8ecef00e0e4e700 +d9dcde00d2d4d601cbcccd00c4c5c501bbbcbd06b4b4b4007b7b7d00585c5e0054545504 +585c5e004a4c4d00545455004a4c4d00545455004a4c4d00585c5e004a4c4d00585c5e03 +63646500585c5e0163646500585c5e02545455004a4c4d0054545500585c5e0054545500 +585c5e005454550a4a4c4d00545455004a4c4d00585c5e0054545500585c5e0254545500 +585c5e0263646500d2d4d600ecf3f501f4f6f902ffffff02f4f6f906ffffff00f4f6f912 +ecf3f500f4f6f901ecf3f500f4f6f909ecf3f501f4f6f900ecf3f50fe8ecef00ecf3f501 +e8ecef00ecf3f501e8ecef00ecf3f501e8ecef00ecf3f500e8ecef00ecf3f500e8ecef00 +ecf3f501e8ecef00ecf3f500e8ecef00ecf3f501e8ecef01ecf3f500e8ecef08e0e4e700 +e8ecef08e0e4e700e8ecef05e0e4e700e8ecef02e0e4e700e8ecef03e0e4e700e8ecef04 +e0e4e700e8ecef00e0e4e704d9dcde00e0e4e704d9dcde00e0e4e702d9dcde00e0e4e70f +e8ecef03ecf3f501f4f6f901ffffff11f4f6f900ffffff1ff4f6f900ffffff01f4f6f900 +ffffff00f4f6f900ffffff00f4f6f900ffffff01f4f6f900fffffff3f4f6f901e0e4e700 +e6dcdc00d2d4d601cbcccd01c4c5c500bbbcbd00353434004a4c4d00545455004a4c4d04 +454445004a4c4d00454445004a4c4d01454445004a4c4d003b3c3d0645444500e8ecef00 +ffffff2df4f6f900e8ecef01d9dcde00d2d4d601cbcccd00c4c5c503bbbcbd04b4b4b400 +7b7b7d004a4c4d00585c5e0054545500585c5e0054545500585c5e00545455014a4c4d02 +545455004a4c4d01585c5e08545455044a4c4d0054545502585c5e0154545500585c5e00 +54545501585c5e0254545502585c5e0763646500bbbcbd00ffffff29f4f6f900ffffff04 +f4f6f900ffffff00f4f6f900ffffff00f4f6f900ffffff00f4f6f900ffffff00f4f6f900 +ffffff00f4f6f904ecf3f500f4f6f905ecf3f500f4f6f907ecf3f500f4f6f901ecf3f500 +f4f6f901ecf3f500f4f6f901ecf3f500f4f6f903ecf3f500f4f6f900ecf3f50be8ecef00 +ecf3f515e8ecef04ecf3f500e8ecef12e0e4e700e8ecef01e0e4e700e8ecef05e0e4e700 +e8ecef02ecf3f502f4f6f903ffffff0ff4f6f900ffffffffffffff20ecf3f500e8ecef00 +e0e4e700d9dcde00d2d4d600cbcccd01c4c5c5017b7b7d002e2c2d004a4c4d0345444501 +3b3c3d004a4c4d00454445033b3c3d087b7b7d00f4f6f900ffffff2ef4f6f900e8ecef00 +e0e4e701d2d4d601cbcccd00c4c5c501bbbcbd01c4c5c500bbbcbd03b4b4b4007b7b7d00 +585c5e01545455034a4c4d00545455004a4c4d03585c5e0054545500585c5e0554545500 +4a4c4d00545455004a4c4d0254545503585c5e0054545500585c5e0054545500585c5e00 +54545500585c5e0054545500585c5e0254545500585c5e0363646500585c5e0263646500 +bbbcbd00f4f6f900ffffff5af4f6f900ffffff01f4f6f900ffffff02f4f6f900ffffff00 +f4f6f917ffffff00f4f6f909ecf3f500f4f6f901ecf3f51ff4f6f903ffffffffffffff32 +f4f6f900ecf3f500e8ecef00e0e4e700d2d4d601cbcccd01c4c5c500bbbcbd0035343400 +3b3c3d004a4c4d01454445004a4c4d00454445033b3c3d004a4c4d00454445004a4c4d00 +3b3c3d08d9dcde00ffffff30f4f6f900ecf3f500e0e4e700d9dcde01d2d4d600cbcccd01 +c4c5c502bbbcbd058c8b8c0054545500585c5e0054545500585c5e00545455014a4c4d00 +545455004a4c4d01545455004a4c4d0054545502585c5e05545455024a4c4d0054545500 +4a4c4d0054545501585c5e0054545501585c5e004a4c4d0054545502585c5e0663646500 +585c5e026a6c6e00d9dcde00ffffff8af4f6f900ffffff02f4f6f901ffffff00f4f6f917 +ffffff00f4f6f900ffffff13f4f6f900ffffff00f4f6f900ffffff00f4f6f900ffffffff +ffffff1df4f6f900ecf3f500e0e4e700d9dcde00d2d4d600cbcccd01c4c5c5017b7b7d00 +242324004a4c4d003b3c3d06454445094a4c4d00454445016a6c6e00f4f6f900ffffff31 +f4f6f900ecf3f500e8ecef00d9dcde01d2d4d600cbcccd00c4c5c502bbbcbd00c4c5c500 +bbbcbd049c9e9c00585c5e0054545500585c5e0054545503585c5e0154545500585c5e00 +54545504585c5e02545455014a4c4d0054545502585c5e01545455024a4c4d0154545501 +585c5e0463646501585c5e0063646500585c5e0063646500585c5e008c8b8c00ecf3f500 +ffffffc1f4f6f900ffffffffffffff20ecf3f500e8ecef00e6dcdc00d2d4d601cbcccd00 +c4c5c5024a4c4d003b3c3d04454445003b3c3d04454445014a4c4d003b3c3d0045444506 +d9dcde00ffffff33f4f6f900e8ecef01e0e4e700d9dcde01d2d4d600cbcccd01c4c5c501 +bbbcbd00c4c5c500bbbcbd03a4a5a4006a6c6e0054545500585c5e0054545501585c5e05 +545455014a4c4d00585c5e0354545500585c5e0054545504585c5e0154545500585c5e00 +545455004a4c4d0154545500585c5e02636465067b7b7d00d2d4d600ffffffc1f4f6f900 +ffffff02f4f6f900ffffffffffffff1eecf3f500e8ecef00e0e4e700d9dcde00d2d4d600 +cbcccd02bbbcbd002e2c2d003b3c3d012e2c2d00353434013b3c3d01454445004a4c4d01 +454445004a4c4d00454445003b3c3d004a4c4d00454445004a4c4d046a6c6e00f4f6f900 +ffffff35ecf3f500e8ecef00e0e4e701d9dcde00d2d4d601cbcccd01c4c5c502bbbcbd00 +c4c5c500bbbcbd01b4b4b40088848400585c5e0163646500585c5e0e54545504585c5e00 +54545500585c5e0154545500585c5e05636465016a6c6e03bbbcbd00f4f6f901ffffffc0 +f4f6f900ffffff01f4f6f900ffffffffffffff20f4f6f900e8ecef00e0e4e700d9dcde00 +d2d4d602cbcccd00a4a5a4002e2c2d00353434012e2c2d00353434002e2c2d003b3c3d01 +454445013b3c3d00454445013b3c3d004a4c4d00454445014a4c4d01454445004a4c4d01 +cbcccd00ffffff37ecf3f501e0e4e701d9dcde01d2d4d601cbcccd02c4c5c503bbbcbd01 +a4a5a4007b7b7d0063646501585c5e0d54545501585c5e0054545501585c5e004a4c4d00 +585c5e0054545502585c5e02636465016a6c6e00636465006a6c6e007b7b7d00b4b4b400 +ffffffc8f4f6f900ffffff00f4f6f900ffffffffffffff1eecf3f500e8ecef00e0e4e701 +d9dcde00d2d4d60188848400353434002e2c2d01353434002e2c2d00353434013b3c3d00 +454445004a4c4d0b6a6c6e00f4f6f900ffffff38f4f6f900ecf3f501e0e4e701d9dcde02 +d2d4d601cbcccd02c4c5c500cbcccd00c4c5c501bbbcbd009c9e9c007b7b7d0063646500 +585c5e0463646500585c5e024a4c4d00585c5e004a4c4d0054545501585c5e004a4c4d00 +585c5e0054545501585c5e004a4c4d0054545500585c5e0054545500585c5e0263646502 +8c8b8c00cbcccd00f4f6f901ffffffc5f4f6f900ffffffffffffff23f4f6f901e8ecef00 +e0e4e703a4a5a4006a6c6e00585c5e003b3c3d002e2c2d00353434002e2c2d003b3c3d02 +454445004a4c4d00454445004a4c4d02545455034a4c4d01bbbcbd00ffffff3bf4f6f900 +ecf3f500e8ecef00ecf3f500e0e4e701d9dcde02d2d4d603cbcccd00d2d4d600cbcccd02 +b4b4b4008c8b8c006a6c6e00585c5e054a4c4d00585c5e0054545500585c5e014a4c4d00 +54545505585c5e004a4c4d00545455004a4c4d01585c5e0163646500a4a5a400e8ecef00 +f4f6f900ffffffc7f4f6f900ffffff01f4f6f900ffffff00f4f6f900ffffffffffffff20 +f4f6f901e8ecef03e0e4e703c4c5c500b4b4b4009c9e9c008c8b8c007b7b7d0063646500 +4a4c4d003b3c3d004a4c4d01545455044a4c4d0054545500585c5e00ffffff3ef4f6f900 +ecf3f501e8ecef01e0e4e702d9dcde03d2d4d601d9dcde00d2d4d600d9dcde00d2d4d601 +bbbcbd009c9e9c0077747400585c5e004a4c4d01585c5e014a4c4d00585c5e004a4c4d0b +585c5e009c9e9c00d2d4d600f4f6f901ffffffcbf4f6f900ffffff02f4f6f900ffffffff +ffffff21f4f6f901ecf3f504e8ecef00ecf3f500e8ecef00ecf3f500e8ecef00ecf3f502 +e0e4e700cbcccd00bbbcbd00abacad008c8b8c007b7b7d00585c5e0054545502b4b4b400 +ffffff3ff4f6f901ecf3f502e8ecef01e0e4e702d9dcde00e0e4e701d9dcde00e0e4e700 +d9dcde01e0e4e700d9dcde01e0e4e700d9dcde00c4c5c500a4a5a4008c8b8c007b7b7d00 +585c5e00545455014a4c4d06585c5e008c8b8c00b4b4b400e0e4e700ffffff00f4f6f900 +ffffffcdf4f6f900ffffff01f4f6f900ffffffffffffff27f4f6f902ecf3f504f4f6f903 +ffffff00f4f6f902ffffff00f4f6f900ffffff00ecf3f500e0e4e700f4f6f900ffffff42 +f4f6f900ecf3f500f4f6f900ecf3f502e8ecef02e0e4e700e8ecef00e0e4e700e8ecef01 +e0e4e700e8ecef03ecf3f504e0e4e700d2d4d601c4c5c500cbcccd00d2d4d600d9dcde00 +e0e4e700ecf3f500ffffff00f4f6f901ffffffcdf4f6f900ffffff03f4f6f900ffffff01 +f4f6f900ffffffffffffff81f4f6f901ecf3f500f4f6f900ecf3f50cf4f6f901ffffff00 +f4f6f900ffffff00f4f6f900ffffff00f4f6f900ffffff00f4f6f900ffffffd5f4f6f900 +ffffff00f4f6f900ffffff01f4f6f900ffffffffffffff86f4f6f900ffffff00f4f6f902 +ecf3f500f4f6f902ffffffe0f4f6f900ffffff04f4f6f900ffffff01f4f6f900ffffff00 + +%%EndData +end +%%PageTrailer +%%Trailer +%%BoundingBox: 0 0 633 196 +%%EOF diff --git a/doc/doxygen_logo.gif b/doc/doxygen_logo.gif Binary files differnew file mode 100644 index 0000000..6b45597 --- /dev/null +++ b/doc/doxygen_logo.gif diff --git a/doc/doxygen_logo_low.gif b/doc/doxygen_logo_low.gif Binary files differnew file mode 100644 index 0000000..02e3c9a --- /dev/null +++ b/doc/doxygen_logo_low.gif diff --git a/doc/doxygen_manual.tex b/doc/doxygen_manual.tex new file mode 100644 index 0000000..8d28a55 --- /dev/null +++ b/doc/doxygen_manual.tex @@ -0,0 +1,42 @@ +\documentclass[a4paper]{article} +\usepackage{a4wide} +\usepackage{makeidx} +\usepackage{fancyheadings} +\usepackage{epsf} +\usepackage{doxygen} +\usepackage{multicol} +\makeindex +\setcounter{tocdepth}{1} +\setlength{\footrulewidth}{0.4pt} +\begin{document} +\begin{titlepage} +\setlength{\epsfxsize}{\textwidth} +\epsffile{doxygen_logo.eps} +\begin{center} +Manual for version $VERSION\\[2ex] +Written by Dimitri van Heesch\\[2ex] +\copyright 1997-1998 +\end{center} +\end{titlepage} +\clearemptydoublepage +\tableofcontents +\clearemptydoublepage +\pagenumbering{arabic} +\include{index} +\part{User Manual} +\input{install} +\input{starting} +\input{trouble} +\part{Reference Manual} +\input{features} +\input{history} +\input{doxygen_usage} +\input{doxytag_usage} +\input{doxysearch_usage} +\input{installdox_usage} +\input{autolink} +\input{config} +\input{commands} +\input{htmlcmds} +\printindex +\end{document} diff --git a/doc/doxygen_usage.doc b/doc/doxygen_usage.doc new file mode 100644 index 0000000..e6fee75 --- /dev/null +++ b/doc/doxygen_usage.doc @@ -0,0 +1,47 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ +/*! \page doxygen_usage Doxygen usage + +Doxygen is a command line based utility. Calling \c doxygen with the +\c -h 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 optionally an argument. + +To generate a class browser you typically need to follow these steps: +<ol> +<li> You document your source code with + special documentation blocks. +<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 also want a search engine to be generated, you should look +at section \ref doxysearch_usage. + +*/ diff --git a/doc/doxysearch_usage.doc b/doc/doxysearch_usage.doc new file mode 100644 index 0000000..a4a3e96 --- /dev/null +++ b/doc/doxysearch_usage.doc @@ -0,0 +1,169 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ +/*! \page doxysearch_usage Doxysearch usage + +Doxysearch is a small, fast and highly portable search engine that allows +you to search for strings or words in the documentation generated by +<a href="doxygen_usage.html">doxygen</a> or +in the Qt documentation (see <a href="#searchqt">below</a>). +Doxysearch must be run as a CGI binary. This implies the following: +<ul> +<li> There must be a HTTP daemon running on the system where you want to + install the documentation (the <em>target</em>) +<li> You must have permission to install and execute a CGI binary on the + target. +</ul> +Ask you system administrator or provider if you are unsure if this is possible. + +In order to be able to search fast and efficient, doxysearch does not +search the generated documentation directly. Instead, it uses an +<em>index file</em>, that should be generated with +<a href="doxytag_usage.html">doxytag</a>. The index file is extracted from +the generated HTML files and contains all words and substrings of words +present in the HTML files, in a compact form, together with their +frequencies and links. Although I tried to store all information +as compactly as possible, the size of the index is still quite large. +Usually it is about the same size as the original HTML files. + +I have tried to make the search engine highly portable, because it +must run on the target system. As a result doxysearch does not require the +Qt library. All that is required to build doxysearch is a C++ compiler. +If you are using \c g++ for example, you can build the search engine manually, +by typing: +\verbatim + g++ doxysearch.cpp -o doxysearch +\endverbatim + +<a name="se"> +<h3>Generating the search engine</h3> +</a> + +To include a search engine in the documentation generated by doxygen +follow these steps: +<ol> +<li>Generate a configuration file with + <a href="doxygen_usage.html">doxygen</a> using the + <code>-g</code> option, if you haven't done this already. + +<li>Edit the search engine section (see section \ref config_search of + the configuration file). + Make sure the \c SEARCHENGINE tag is set to \c YES + and that all paths are correct. + +<li>Use <a href="doxygen_usage.html">doxygen</a> to generate the + documentation. Apart from the documentation, Doxygen will create the + following files: + <ul> + <li>A small CGI script. the name of the script is determined by the + \c CGI_NAME tag in the configuration file. + The script is a small wrapper that calls \c doxysearch with + the correct parameters. Using this script allows multiple + search engines for different projects to be present in one directory. + <li>\c search.cfg: this file is a small configuration file + for the search engine. It contains two lines of text. The first line + should be the absolute URL to the documentation. The second line should + be the absolute URL to the CGI script. This information is taken from + the configuration file. + <li>\c search.gif: this is the image that is used for the search button. + </ul> + +<li>Copy (or move) the CGI script to the directory where the CGI binaries + are located. + This is usually a special directory on your system or in your + home directory. + Consult the manual of your HTTP daemon or your system administrator to + find out, where this directory resides on your system. + +<li>Goto the directory where the generated HTML files are located and run + doxytag as follows: + <pre>doxytag -s search.idx</pre> + This will create a search index with the name <code>search.idx</code>. + Currently the index file <em>must</em> be called like this. + +<li>Run <a href="installdox_usage.html">installdox</a> to replace + any dummy links in the documentation with real links. + + <b>Notice:</b> When using a search engine this step is <em>required</em> + even if no tag files are used. If tag files are used you must specify + the correct options. +</ol> + +<a name="searchqt"> +<h3>Creating a search engine to search in the Qt documentation</h3> +</a> + +Using <code>doxytag</code> and <code>doxysearch</code> it is possible to create a search engine for +the Qt documentation, without needing the sources! +This can be done by carefully following these steps: +<ol> +<li>Goto the html directory of the Qt-distribution: + <pre>cd $QTDIR/html</pre> +<li>Generate the search index by typing: + <pre>doxytag -s search.idx *.html</pre> + This will parse all files and build a search index. + Apart from the file <code>search.idx</code> two other files + will be generated: <code>search.gif</code> and <code>search.cgi</code> + + \par Notice: + Doxytag requires quite a large amount of memory to + generate the search index (about 30 Mb on my Linux box)! + The resulting index file requires about 3 Mb space on your disk. + +<li>Edit the shell script <code>search.cgi</code> with a text editor. + + Fill in the absolute path to the <code>doxysearch</code> binary after + the <code>DOXYSEARCH=</code> tag. + On my system this becomes: + <pre>DOXYSEARCH=/usr/local/bin/doxysearch</pre> + + Fill in the absolute path to the qt documentation after the + <code>DOXYPATH=</code> tag. + On my system this becomes: + <pre>DOXYPATH=/usr/local/qt/html</pre> +<li> + CGI binaries are usually located in a special directory. + Consult the manual of your HTTP daemon or your system administrator to + find out, where this directory resides on your system. + Copy (or move) the <code>search.cgi</code> script to this directory. + If needed you may change the name of the script. + On my system, this becomes: + <pre>cp search.cgi /usr/local/lib/httpd/cgi-bin/</pre> + +<li>Create a text-file with the name <code>search.cfg</code>. + On the first line, you must put the <em>absolute</em> URL to the Qt + documentation. + Since, I only use the search engine on my own standalone system, I use + the <code>file:</code> protocol. + On the second line, you must put the <em>absolute</em> URL to the + cgi script. + On my system the resulting file looks like this: +\verbatim +file:///usr/local/qt/html +http://blizzard/cgi-bin/search.cgi +\endverbatim + +<li>Add a link to the search engine in the Qt documentation. + On my system, I have put a line +\verbatim +<li><a href="http://blizzard/cgi-bin/search.cgi">Search the documentation<a> +\endverbatim + in the additional information section of the <code>index.html</code> file. +<li>Start your favourite web browser and click on the link. + If everything is ok, you should get a page where you can enter + search terms. +</ol> + +*/ diff --git a/doc/doxytag_usage.doc b/doc/doxytag_usage.doc new file mode 100644 index 0000000..fb966fd --- /dev/null +++ b/doc/doxytag_usage.doc @@ -0,0 +1,116 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ +/*! \page doxytag_usage Doxytag usage + +Doxytag is a small command line based utility. +It has two functions: +<ul> +<li> + Doxytag can generate <em>tag files</em>. + These tag files can be used with <a href="doxygen_usage.html">doxygen</a> + to generate references to external documentation + (i.e. documentation not contained in the input files that are used by + doxygen). + A tag file contains information about files, classes and members + documented in external documentation. Doxytag extracts this information + directly from the HTML files. This has the advantage that you do not need + to have the sources from which the documentation was extracted. + If you do have the sources you can also let \c doxygen generate the + tag file by putting the name of the tag file after \c GENERATE_TAGFILE in + the configuration file. +<li> + Doxytag can generate a <em>search index</em> for the documentation + generated with doxygen or for the Qt documentation. See the documentation of + <a href="doxysearch_usage.html">doxysearch</a> for more information on how + to do this. + A search index contains information about all the words (and all substrings + thereof) that are contained in the documentation. + For each string the index contains the set of documentation blocks that + contain the string and the frequency of occurrence. This way + <code>doxysearch</code> can search for words very quickly + (most queries are processed within a few milliseconds on my system.) +</ul> +In both cases the input of doxytag consists of a set of HTML files. + +\par Important: + If you use tag files or use a search engine, the links that + are generated by doxygen will contain \e dummy links. You have to run + the \c installdox script to change these dummy links into real links. + See \ref installdox_usage for more information. + The use of dummy links may seem redundant, but it is really useful, + if you want to move the external documentation to another location. + Then the documentation does not need to be regenerated by \c doxygen, + only \c installdox has to be run. + +\par Notice: +Because the HTML files are expected to have a certain +structure, only HTML files generated with doxygen or with Qt's class +browser generator can be used. Doxytag only <em>reads</em> the HTML files, +they are not altered in any way. + +Doxytag expects a list of all HTML files that form the documentation +or a directory that contains all HTML files. If neither is present doxytag +will read all files with a <tt>.html</tt> extension from the current directory. +If doxytag is used with the <code>-t</code> flag it generates a tag file. + +\par Example 1: + Suppose the file \c example.cpp from the \c examples directory that is listed + below is included in some package for which you do not have the sources. + Fortunately, the distributor of the packages included the HTML documentation + that was generated by doxygen in the package. + \verbinclude example.cpp + Now you can create a tag file from the HTML files in the package by + typing: +\verbatim +doxytag -t example.tag example/html +\endverbatim + from the examples directory. + Finally you can use this tag file with your own piece of code, such + as done in the following example: + \verbinclude tag.cpp + Doxygen will now include links to the external package in your own + documentation. Because the tag file does not specify where the + documentation is located, you will have to specify that by running the + installdox script that doxygen generates + (See \ref installdox_usage for more information). + + Notice that this is actually a feature because if you (or someone else) + moves the external documentation to a different + directory or URL you can simply run the script again and all links in + the HTML files will be updated. + + \htmlonly + Click <a href="$(DOXYGEN_DOCDIR)/examples/tag/html/index.html">here</a> + for the corresponding HTML documentation that is generated by Doxygen using + only the tag file and second piece of code. + \endhtmlonly + +\par Example 2: + To generate a tag file of the Qt documentation you can do the following: +\verbatim +doxytag -t qt.tag $QTDIR/html +\endverbatim + +A typical example to use doxytag to generate a search index is: +\verbatim +doxytag -s search.idx +\endverbatim + +\par Notice: +In the current version of doxygen, the search index must be +called \c search.idx. + +*/ diff --git a/doc/features.doc b/doc/features.doc new file mode 100644 index 0000000..2f34e18 --- /dev/null +++ b/doc/features.doc @@ -0,0 +1,79 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ +/*! \page features.html + +\section features Features + +\addindex features +<UL> +<li>Requires very little overhead from the writer of the documentation. + Plain text will do, but for more fancy or structured output HTML tags + and/or some of doxygen's special commands can be used. +<li>Outputs documentation in on-line format (HTML and man page) and off-line + format (LaTeX) simulatiously (one can be disabled if desired). + Both formats are optimized for ease of reading. +<li>Allows documentation of files, classes, templates, variables, functions, + typedefs, enums and defines. +<li>Includes a full C preprocessor to allow proper parsing of conditional + code fragments and to allow expansion of all or part of the define macros. +<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 of class diagrams in HTML (as clickable + image maps) and Latex (as encapsulated postscript). +<li>JavaDoc (1.1) and Qt-Doc compatible. +<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. +<li>Automatic generation of references to documented classes, files and + members. Documentation of global functions, globals variables, + typedefs, defines and enumerations is also supported. +<li>Documentation may be placed either at the declaration or at the definition + of a member function or class. Most documentation systems (such as Javadoc) only + support the former, others (such as Qt) only the latter. +<li>You can type normal HTML tags in your documentation. Doxygen will convert + them to Latex automatically. +<li>Allows references to documentation generated for other 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>All options are read from an easy to edit and documented configuration + file. +<li>Documentation and search engine can be transferred to another + location or machine without regenerating the documentation. +<li>Can cope with large projects easily. +</UL> + +Although doxygen can be used in any C or C++ project, it was specifically +designed to be used for projects that make use of Troll Tech's +<A HREF="http://www.troll.no/qt">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 very similar to the +one that is generated by Troll Tech. Doxygen understands the C++ extensions +used by Qt such as signals and slots. + +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! + +*/ diff --git a/doc/history.doc b/doc/history.doc new file mode 100644 index 0000000..3571bd6 --- /dev/null +++ b/doc/history.doc @@ -0,0 +1,140 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + + +/*! \page history Doxygen History + +<h3>TODO/Wish list</h3> +<ul> +<li>Add support for grouping members, and document then as a group. +<li>Support for K&R-style function arguments. +<li>More ouput formats: suggested are info format and RTF format. +<li>Reintroduction of the multi-column class list (and file list) to quickly + select a class or file +<li>Split long lists in an index to a set of smaller lists. +<li>Add a nice graphical front-end for creating and modifying the + configuration file (it should be flexible enough to quickly add new options). +<li>Improve the search index generation, so it uses less memory and + is easier to get running. +<li>Generate code metrics (Anyone know a good book about code metrics?) +<li>Add features that you think are missing... So if you know any that are + not yet listed here, please let me know. +</ul> + +<h3>Features scheduled for version 0.5</h3> +<ul> +<li>Proper support for namespaces. +<li>Include LaTeX style formulas in LaTeX and HTML output (in HTML as a gif). +<li>Proper support for template classes, members, functions and specializations. +<li>Multi-lingual support. +<li>Generation of class diagrams (clickable image maps in HTML, eps images in + postscript). +<li>Add generator for man pages format. +</ul> + +<h3>Version 0.4</h3> + +<h4>New features:</h4> +<ul> +<li>LaTeX output generation. +<li>Full JavaDoc support. +<li>Build-in C-preprocessor for correct conditional parsing of source code + that is read by Doxygen. +<li>Build-in HTML to LaTeX converter. This allows you to use HTML tags in + your documentation, while doxygen still generates proper LaTeX output. +<li>Many new commands (there are now more than 60!) to document + more entities, to make the documentation look nicer, and to include + examples or pieces of examples. +<li>Enum types, enum values, typedefs, #defines, and files can now be + documented. +<li>Completely new documentation, that is now generated by Doxygen. +<li>A lot of small examples are now included. +</ul> +<h4>Bug fixes:</h4> +<ul> +<li>A lot of parser bugs are fixed. +<li>Improved support for documenting C code. +</ul> + +<h3>Version 0.3</h3> +<h4>New features:</h4> +<ul> +<li>A search engine <a href="doxysearch_usage.html">doxysearch</a>, + that allows you to search through the generated documentation. +<li>A configuration file instead of command-line options. A default + configuration file can be generated + by <a href="doxygen_usage.html">doxygen</a>. +<li>Added an option to generate output for undocumented classes. +<li>Added an option to generate output for private members. +<li>Every page now contains a condensed index page, allowing much faster + navigation through the documentation. +<li>Global and member variables can now be documented. +<li>A project name can now given, which will be included in the + documentation. +</ul> + +<h4>Bug fixes:</h4> +<ul> +<li>Fixed bug when files with the same name but in different directories + are used as include files. +<li>Template classes now work. +<li>Inner classes now work. +<li>Fixed a bug regarding unrelated functions and <code>\fn</code>. +<li>Fixed parse bug with <code>/**/</code> comments +<li>Fixed a bug regarding inline friend functions. +<li>The list of all members now also contains the undocumented members. +<li>Special documentation is now removed from code blocks. +<li>Doxygen should compile on Sun Solaris (with <code>CC</code>), HP-UX (with + <code>CC</code>), Irix (with DCC) and Linux (with <code>GCC</code>) +<li>Fixed several minor bugs. +</ul> + +<h3>Version 0.2</h3> +<h4>New features:</h4> +<ul> +<li>Blocks of code are now parsed. Function calls and variables are + replaced by links to their documentation if possible. +<li>Special example documentation block added. This can be used to + provide cross references between the documentation and some example code. +<li>Documentation blocks can now be placed inside the body of a class. +<li>Documentation blocks with line range may now be created using + special <code>//!</code> C++ line comments. +<li>Unrelated members can now be documented. A page containing a + list of these members is generated. +<li>Added an <code>\include</code> command to insert blocks of source code + into the documentation. +<li>Warnings are generated for members that are undocumented. +<li>You can now specify your own HTML headers and footers for the + generated pages. +<li>Option added to generated indices containing all external classes + instead of only the used ones. +</ul> + +<h4>Bug fixes:</h4> +<ul> +<li>Fixed a link generation problem with mixed case filenames are used. +<li>Made doxygen a little more portable. + (doxygen should now compile on Linux (with g++) and HP-UX (with CC)) +<li>Fixed a bug in err() function. +<li>Fixed a problem with the type cast operator. +<li>Removed some typo's from the docs. +<li>Several small bug fixes and enhancements. +</ul> + +<h3>Version 0.1</h3> +Initial version. + +*/ diff --git a/doc/htmlcmds.doc b/doc/htmlcmds.doc new file mode 100644 index 0000000..7a35200 --- /dev/null +++ b/doc/htmlcmds.doc @@ -0,0 +1,111 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ +/*! \page htmlcmds HTML Commands + +Here is a list of all HTML commands that may be used inside the +documentation. Notice that all attributes of a HTML tag are ignored +(the HREF and NAME attributes for the A tag are the only exception). + +<ul> +<li><tt>\<A HREF="..."\></tt> Starts a HTML hyper-link (HTML only). +<li><tt>\<A NAME="..."\></tt> Starts an named anchor (HTML only). +<li>\c </A> Ends a link or anchor (HTML only). +<li>\c <B> Starts a piece of text displayed in a bold font. +<li>\c </B> Ends a \c <B> section. +<li>\c <BODY> Does not generate any output. +<li>\c </BODY> Does not generate any output. +<li>\c <BR> Forces a line break. +<li>\c <CENTER> starts a section of centered text. +<li>\c </CENTER> ends a section of centered text. +<li>\c <CODE> Starts a piece of text displayed in a typewriter font. +<li>\c </CODE> End a \c <CODE> section. +<li>\c <DD> Starts an item description. +<li>\c <DFN> Starts a piece of text displayed in a typewriter font. +<li>\c </DFN> Ends a \c <DFN> section. +<li>\c <DL> Starts a description list. +<li>\c </DL> Ends a description list. +<li>\c <DT> Starts a item title. +<li>\c </DT> Does not generate any output. +<li>\c <EM> Starts a piece of text displayed in an italic font. +<li>\c </EM> Ends a \c <EM> section. +<li>\c <FORM> Does not generate any output. +<li>\c </FORM> Does not generate any output. +<li>\c <HR> Writes a horizontal ruler. +<li>\c <H1> Starts an unnumbered section. +<li>\c </H1> Ends an unnumberd section. +<li>\c <H2> Starts an unnumbered subsection. +<li>\c </H2> Ends an unnumbered subsection. +<li>\c <H?> Where ? is one of {3,4,5,6}, starts an unnumbered subsubsection. +<li>\c </H?> Where ? is one of {3,4,5,6}, ends an unnumbered subsubsection. +<li>\c <I> Starts a piece of text displayed in an italic font. +<li>\c <INPUT> Does not generated any output. +<li>\c </I> Ends a \c <I> section. +<li>\c <IMG> This command is written with attributes to the HTML output only. +<li>\c <LI> Starts a new list item. +<li>\c </LI> Does not generate any output. +<li>\c <META> Does not generate any output. +<li>\c <MULTICOL> ignored by Doxygen. +<li>\c </MUTLICOL> ignored by Doxygen. +<li>\c <OL> Starts a numbered item list. +<li>\c </OL> Ends a numbered item list. +<li>\c <P> Starts a new paragraph. +<li>\c </P> Does not generate any output. +<li>\c <PRE> starts a code fragment, + equivalent to the command \\code (see section \ref cmdcode). +<li>\c </PRE> ends a code fragment, + equivalent to the command \\endcode (see section \ref cmdendcode). +<li>\c <SMALL> starts a section of text displayed in a smaller font. +<li>\c </SMALL> ends a \c <SMALL> section. +<li>\c <STRONG> starts a section of bold text. +<li>\c </STRONG> ends a section of bold text. +<li>\c <SUB> Starts a piece of text displayed in superscript. +<li>\c </SUB> Ends a \c <SUB> section. +<li>\c <SUP> Starts a piece of text displayed in subscript. +<li>\c </SUP> Ends a \c </SUP> section. +<li>\c <TABLE> starts a table, the available space of a page is always + divided equally amount the columns. +<li>\c </TABLE> ends a table +<li>\c <TD> Starts a new table element. +<li>\c </TD> Does not generate any output. +<li>\c <TR> Starts a new table row. +<li>\c </TR> Does not generate any output. +<li>\c <TT> Starts a piece of text displayed in a typewriter font. +<li>\c </TT> Ends a \c <TT> section. +<li>\c <UL> Starts an unnumbered item list. +<li>\c </UL> Ends an unnumbered item list. +<li>\c <VAR> Starts a piece of text displayed in an italic font. +<li>\c </VAR> Ends a \c </VAR> section. +</ul> + +The special HTML characters entities that are recognized by Doxygen: + +<ul> +<li>\c © the copyright symbol +<li>\c " a double quote +<li>\c &?uml; where ? is one of {A,E,I,O,U,Y,a,e,i,o,u,y}, + writes a character with a diaeresis accent (like ä). +<li>\c &?acute; where ? is one of {A,E,I,O,U,Y,a,e,i,o,u,y}, + writes a character with a acute accent (like á). +<li>\c &?grave; where ? is one of {A,E,I,O,U,a,e,i,o,u,y}, + writes a character with a grave accent (like à). +<li>\c &?circ; where ? is one of {A,E,I,O,U,a,e,i,o,u,y}, + writes a character with a circumflex accent (like â). +<li>\c &?tilde; where ? is one of {A,N,O,a,n,o}, + writes a character with a tilde accent (like ã). +</ul> + +*/ + diff --git a/doc/index.doc b/doc/index.doc new file mode 100644 index 0000000..add62b4 --- /dev/null +++ b/doc/index.doc @@ -0,0 +1,163 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ +/*! \page index +<center> +\htmlonly +<img align=center lowsrc="doxygen_logo_low.gif" src="doxygen_logo.gif" + width=634 height=197 alt="doxygen"><br> +Version: $(VERSION) +\endhtmlonly +</center> + +<h2>Doxygen license</h2> +\addindex license +\addindex GPL + +Copyright © 1997-1999 by +<a href="mailto:dimitri@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 GNU General Public License for more details. +<p> +All output generated by Doxygen is not covered by this license. + +<h2>Introduction</h2> +Doxygen is a documentation system for C and C++. It can generate an on-line +class browser (in HTML) and/or an off-line reference manual +(in \f$\mbox{\LaTeX}\f$) from a set +of documented source files. The documentation is extracted directly from the +sources. Doxygen is developed on a <a href="http://www.linux.org">Linux</a> +platform, but it runs on most other UNIX flavors as well. +An executable for Windows 95/NT is also available. + +Doxygen can also be configured to extract the code-structure from undocumented +source files. This can be very useful to quickly find your way in large +source distributions. + +You can even `abuse' doxygen for creating normal documentation (as I did +for this manual). + +This manual is divided into two parts, each of which is divided into several +sections. + +The first part forms a user manual: +<ul> +<li>Section \ref install discusses how to download, 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 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 history shows what has changed during the development + of Doxygen and what still has to be done. +<li>Section \ref doxygen_usage shows how to use the \c doxygen program. +<li>Section \ref doxytag_usage shows how to use the \c doxytag program. +<li>Section \ref doxysearch_usage shows how to use the \c doxysearch program. +<li>Section \ref installdox_usage shows how to use the \c installdox + script that is generated by Doxygen if you use tag files. +<li>Section \ref autolink shows how to put links to files, classes, + and members in the documentation. +<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. +</ul> + +<h2>Acknowledgements</h2> +\addindex acknowledgements +Thanks go to: +<ul> +\addindex Doc++ +<li>Malte Zöckler and Roland Wunderling, authors of Doc++. + The first version of Doxygen was based on 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 Troll Tech, for creating a beautiful GUI Toolkit. + (which is even useful for GUI-less applications like doxygen :-) +<li>My brother <a href="http://www.stack.nl/~fidget/index.html">Frank</a> + for rendering the logos. +<li> +Arnt Gulbrandsen, +Adam P. Jenkins, +Frank van de Pol, +Ulrich Quill, +Karl Robillard, +Frugal the Curious, +Michael Figley, +Eric Bos, +Barry Roberts, +Mark Tigges, +Jan Ekholm, +Andre Johansen, +Martin Franken, +Martin Hofmann, +Ulrich Ring, +Andy Guy, +Ryan Mclean, +Joseph Reklow, +Morten Eriksen, +Arthur Pope, +Andreas Felber, +Matthias Schwartz, +Björn Bon, +Volker Börchers, +Baruch Even, +Kor de Jong, +Thomas Eschenbacher, +Bert Scholten, +Germar Morgenthaler, +Daniel Bellen, +Terry Brown, +Anke Selig, +David Aspinwall, +Hellmar Becker, +Harald Krummeck, +Christoph Koegl, +Martin Reinecke, +Joseph Turian, +Craig P Earls, +Greg Sjaardema, +Vlado Sironja, +Jens Schmidt, +Lutz Sammer, +Robert Dale, +Ionutz Borcoman, +Markus Noga, +Darren Kelly, +Joerg Ott, +Kostya Serebrainy, +Marco Molteni, +Johannes Zellner, +Ole Gerden, +Olaf Meeuwissen, +Feiyi Wang, +Robert J. Clark, +Matthias Baas and +Walter Mueller + for suggestions, patches and bug reports. +</ul> +*/ + diff --git a/doc/install.doc b/doc/install.doc new file mode 100644 index 0000000..2c5f0ac --- /dev/null +++ b/doc/install.doc @@ -0,0 +1,99 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ +/*! \page install Installation + +\addindex installation +First go to the +<a href="http://www.stack.nl/~dimitri/doxygen/download.html">download</a> page +\latexonly({\tt http://www.stack.nl/$\sim$dimitri/doxygen/download.html})\endlatexonly +to get the latest distribution and unpack it. + +If you downloaded the source distribution, you need at least the +following to build the executable: +<UL> +<LI>Troll Tech's GUI toolkit <A HREF="http://www.troll.no/dl">Qt</A> + \latexonly(see {\tt http://www.troll.no/dl})\endlatexonly. + \addindex Qt +<LI>The <a href="ftp://prep.ai.mit.edu/pub/gnu">GNU</a> tools + flex, bison and make + \latexonly(see {\tt ftp://prep.ai.mit.edu/pub/gnu})\endlatexonly. + \addindex flex + \addindex bison + \addindex make +<LI>In order to generate a Makefile for your platform, you need + <a href="http://www.perl.com>perl</a> + \latexonly(see {\tt http://www.perl.com})\endlatexonly. + \addindex perl +</UL> + +\addindex HTTP +\addindex CGI +To use the search engine \c doxysearch, you will also need +a HTTP daemon running on the target system and permission to execute a +CGI binary. + +Once you have Qt installed correctly, you can simply enter: +\verbatim +make +\endverbatim +to get a list of all supported platforms/compilers. +Typing <tt>make</tt> followed by your platform will compile doxygen. +For Linux you can enter the following: +\verbatim +make linux-g++ +\endverbatim + +Doxygen should compile without errors or warnings. +If it does not, please send the compilation errors or warnings along +with a description of your platform to +<a href="mailto:dimitri@stack.nl>dimitri@stack.nl</a>. + +After compilation, the binaries will be located in the \c bin +directory of the distribution. +You may want to copy these files to a location in your path +(\c /usr/local/bin for instance) or add the \c bin +directory of the distribution to your search path. + +The following binaries should now be available: +<UL> +<LI>\c doxygen: for generating the class browser. +<LI>\c doxytag: for creating a tag file containing references + to external documentation. +<LI>\c doxysearch: the search engine. This binary should not be + executed directly. It must be called from an CGI script that will be + generated by doxygen. +</UL> + +Doxygen was developed and tested under Linux using the following tools: +<ul> +<li>GCC version 2.8.1 +<li>GNU flex version 2.5.4 +<li>GNU bison version 1.25 +<li>GNU make version 3.77 +<li>Perl version 5.001 (patch level 1m) +<li>VIM version 5.3 +<li>Netscape 4.04 & 4.5 +<li>Troll Tech's tmake version 1.2 (included in the distribution) +<li>teTeX version 0.4 +</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/installdox_usage.doc b/doc/installdox_usage.doc new file mode 100644 index 0000000..d22e4a7 --- /dev/null +++ b/doc/installdox_usage.doc @@ -0,0 +1,61 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ +/*! \page installdox_usage Installdox usage + +Installdox is a perl script that is generated by doxygen whenever +tag files are used (See \c TAGFILES +in section \ref config_extref) +or the search engine is enabled (See \c SEARCHENGINE +in section \ref config_search). The script is +located in the same directory where the HTML files are located. + +Its purpose is to set the location of the external documentation +for each tag file and to set the correct links to the search engine +at install time. + +Calling \c installdox with option <b>-h</b> at the command line +will give you a brief description of the usage of the program. + +The following options are available: +<dl> +<dt><b>-l <tt>\<tagfile\>\@\<location\></tt></b><dd> + Each tag file contains information about the files, classes and members + documented in a set of HTML files. A user can install these + HTML files anywhere on his/her hard disk or web site. + Therefore installdox \e requires the location of the + documentation for each tag file <tt>\<tagfile\></tt> + that is used by doxygen. The location <tt>\<location\></tt> can be + an absolute path or a URL. + + \par Notice: + Each <tagfile> must be unique and should only be the name of the + file, not including the path. + +<dt><b>-q</b><dd> + When this option is specified, installdox will generate no output other + than fatal errors. +</dl> +Optionally a list of HTML files may be given. +These files are scanned and modified if needed. +If this list is omitted all files in the current directory +that end with \c .html are used. + +The \c installdox script is unique for each generated class browser +in the sense that it `knows' what tag files are used. It will generate an error if +the <b>-l</b> option is missing for a tag file or if an invalid tag file +is given. + +*/ diff --git a/doc/starting.doc b/doc/starting.doc new file mode 100644 index 0000000..1d3cbcd --- /dev/null +++ b/doc/starting.doc @@ -0,0 +1,411 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ +/*! \page starting Getting started + +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. + +The executable \c doxytag is only needed if you want to generate references +to external documentation (i.e. documentation that was generated by Doxygen) +for which you do not have the sources or to create a search index for +the search engine. See section \ref doxytag_usage for more detailed usage +information. + +The executable \c doxysearch is only needed if you want to use the search +engine. See section \ref doxysearch_usage for more detailed usage information. + +\subsection 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 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. + +The configuration file has a format that is similar to that of a (simple) +Makefile. It contains 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 to their default value. + +The \c INPUT tag is the only tag for which you are required to provide +a value. See section \ref config for more details about the configuration file. +For a small project consisting of a few C and/or C++ source and header files, +you can add the names of the files after the \c INPUT tag. +If you have a larger project consisting of a source directory or tree +this may become tiresome. In this case you should put the root directory or +directories after the \c INPUT tag, and add one or more file +patterns to the \c FILE_PATTERN tag. Only files that match one of the +patterns will be parsed (if the patterns are omitted all files will be parsed). +For recursive parsing of a source tree you must set +the \c RECURSIVE tag to \c YES. To further finetune the list of files +that is parsed the \c EXCLUDE and \c EXCLUDE_PATTERNS tags can be used. + +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 documented result would be. To do so, you must set the \c EXTRACT_ALL +tag in the configuration file to \c YES. Then, Doxygen will pretend +everything in your sources is documented. Please note that warnings of +undocumented members will not be generated as long as \c EXTRACT_ALL is set +to \c YES. + +\subsection step2 Step 2: Running doxygen + +To generate the documentation you can now enter: +\verbatim +doxygen <config-file> +\endverbatim + +Doxygen will create a \c html, \c latex and/or \c man directory inside +the output directory. +As the names suggest the \c html directory contains the +generated documentation in HTML format and the \c latex directory contains the +generated documentation in \f$\mbox{\LaTeX}\f$ format. Man pages are put +in a man3 directory inside the \c man directory. + +The default output directory is the directory in which \c doxygen +is started. The directory to which the output is written can be changed +using the \c OUTPUT_DIRECTORY , \c HTML_OUTPUT, \c LATEX_OUTPUT, and +\c MAN_OUTPUT tags of the configuration file. If the output directory does not +exist, \c doxygen will try to create it for you. + +\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 currently using Netscape 4.0 to test the generated output). +\addindex LaTeX + +The generated \f$\mbox{\LaTeX}\f$ documentation must first be compiled by +a \f$\mbox{\LaTeX}\f$ compiler. (I use teTeX distribution version 0.4 +that contains \f$\mbox{\TeX}\f$ version 3.14159). To simplify the process +of compiling the generated +documentation, \c doxygen writes a \c Makefile into the \c latex directory. +By typing \c make in the \c latex directory the dvi file \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 <code>make ps</code> +(this requires \c dvips ). The 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. + +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 MANPATH +environment variable). Notice 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 step3 Step 3: Documenting the sources + +Although documenting the source is presented as step 3, in a new project +this should ofcourse 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 as well. + +If the \c EXTRACT_ALL option is set to \c NO in the configuration file +(the default), then doxygen will only generate documentation for +\e documented members, files, classes and namespaces. So how do you document +these? For members, classes and namespaces there are basicly two options: +<ol> +<li>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 documention directly after the + member. See section \ref specialblock to learn more about special + documentation blocks. +<li>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 object that can be documented (e.g. a member, class, + namespace or file). See section \ref structuralcommands to learn more + about structural commands. +</ol> +Files can only be documented using the second option. +The text inside a special documentation block is parsed +before it is written to the HTML and/or \f$\mbox{\LaTeX}\f$ output files. + +\addindex parsing +During parsing the following steps take place: +<ul> +<li> The special commands inside the documentation are executed. See + section \ref commands for an overview of all commands. +<li> If a line starts with some whitespace followed by one or more asterixes + (<tt>*</tt>) then the whitespace and asterixes are removed. +<li> 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. +<li> Links are created for words corresponding to documented classes. +<li> 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. +<li> HTML tags that are in the documentation are interpreted and converted + to \f$\mbox{\LaTeX}\f$ equivalents for the \f$\mbox{\LaTeX}\f$ output. + See section \ref htmlcmds for an overview of all supported HTML tags. +</ul> + +\subsection specialblock Special documentation blocks + +The following types of special documentation blocks are supported by Doxygen: +<ul> +<li>The Qt style, where special documentation blocks look like: +\verbatim +/*! + ... text ... +*/ +\endverbatim and the one line version: +\verbatim +//! ... one line of text ... +\endverbatim +<li>The JavaDoc style, where special documentation blocks look like: +\verbatim +/** + * ... text ... + */ +\endverbatim and the one line version: +\verbatim +/// ... one line of text ... +\endverbatim +</ul> + +Here is an example of a documented piece of C++ code using the Qt style: +\verbinclude 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 one-line comments should contain a brief description, +whereas the multi-line comment blocks contain a more detailed description. +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 omitted by setting \c BRIEF_MEMBER_DESC to \c NO in +the config file). By default the brief descriptions are also the first +sentence of the detailed description +(this can be changed by setting the \c REPEAT_BRIEF tag to \c NO). +Both the brief and the detailed descriptions are optional +for the Qt style. + +Here is the same piece of code, this time documented using the JavaDoc +style: +\verbinclude 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 + +Notice that the first sentence of the documentation (until the <tt>.</tt>) +is treated as a brief description, whereas the documentation block as a whole +forms the detailed description. The brief description is required for the +JavaDoc style. + +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 +(assuming you use the Qt style comments). + +\subsection structuralcommands Structural commands + +So far we have assumed that the documentation blocks are always located in +front of the declaration or definition of a file, class or namespace or in +front of one of its members. +Although this is often comfortable, it may sometimes be better to put the +documentation somewhere else. For some types of documentation blocks (like file +documentation) this is even required. 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), as long as you put a +structural command inside the documentation block. + +Structural commands (like all other commands) start with a backslash +(<tt>\\</tt>) 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 indicated 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 \file to document a file. +<li>\c \namespace to document a namespace. +</ul> +See section \ref commands for detailed information about these and other +commands. Notice that the documentation block belonging to a file +should always contain a structural command. + +To document a member of a C++ class, you must also document the class +itself. The same holds for namespaces. To document a 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). + +Here is an example of a C header named \c structcmd.h that is documented +using structural commands: +\verbinclude structcmd.h + \htmlonly + Click <a href="$(DOXYGEN_DOCDIR)/examples/structcmd/html/structcmd.h.html">here</a> + for the corresponding HTML documentation that is generated by Doxygen. + \endhtmlonly + +\par Notice: + 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! + +\subsection memberdoc Documenting compound members. + +If you want to document the members of a file, struct, union, class, or enum +and you want to put the documentation for these members inside the compound, +it is sometimes desired to place the documentation block after the member +instead of before. For this purpose Doxygen has the following +additional comment blocks: +\verbatim +/*!< ... */ +\endverbatim +This block can be used to put a qt style documentation blocks after a member. +The one line version look as follows: +\verbatim +//!< ... +\endverbatim +There are also JavaDoc versions: +\verbatim +/**< ... */ +\endverbatim +and +\verbatim +///< ... +\endverbatim +Notice that these blocks have the same structure and meaning as the +special comment blocks above only the \< indicates that the member is +located in front of the block instead of after the block. + +Here is an example of a the use of these comment blocks: +\verbinclude 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. + They cannot be used to document file classes, unions, structs and + enums. Furthermore, the structural commands mentioned in the + previous section are ignored inside these comment blocks. + +\subsection formulas Including formulas in the documentation + +Doxygen allows you to put \f$\mbox{\LaTeX}\f$ formulas in the +output (this works only for the HTML and \f$\mbox{\LaTeX}\f$ formats, +not 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 \f$\mbox{\LaTeX}\f$ compiler, needed to parse the formulas. + To test I have used the teTeX 0.4 distribution. +<li>\c dvips: a tool to convert dvi files to postscript files + I have used version 5.58f from Radical Eye software for testing. +<li>\c gs: the ghostscript interpreter for converting postscript files + to bitmaps. I have used Aladdin Ghostscript 5.01 for testing. +</ul> + +There are two 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] +</ol> +Formulas should be valid commands in \f$\mbox{\LaTeX}\f$'s math-mode. + +\warning Currently, Doxygen is not very fault tolerant in recovering +from typos in formulas. It may have to be necessary to remove the +file formula.repository that is written in the html directory to +a rid of an incorrect formula + +\subsection moreinfo More information + +\addindex QdbtTabular +For a more elaborate example see <a href="http://www.stack.nl/~dimitri/qdbttabular/html/index.html"> +the documentation of QdbtTabular</a> \latexonly +({\tt http://www.stack.nl/$\sim$dimitri/qdbttabular/html})\endlatexonly. +\htmlonly +I hope that was clear. If not, please let me know, so I can improve this document. If you have problems +take a look at the <a href="trouble.html">troubleshooting</a> section. +\endhtmlonly + +*/ diff --git a/doc/trouble.doc b/doc/trouble.doc new file mode 100644 index 0000000..5103bda --- /dev/null +++ b/doc/trouble.doc @@ -0,0 +1,67 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ +/*! \page trouble Troubleshooting + +<h2>Known problems:</h2> +<ul> +<li>Doxygen is <em>not</em> a compiler, it is only a lexical scanner. + This means that it can and will not detect errors in your source code. +<li>Since it 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>Using declarations and directives are not yet. They are + simply ignored. +<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, because only the syntax is analysed, + 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. +</ul> + + +<h2>How to help</h2> +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. + +Furthermore, I would appreciate a mail if you have found +a bug, or if you have ideas (or even better some code or a patch) +how to fix existing bugs and limitations. + +My email address: <a href="mailto:dimitri@stack.nl">dimitri@stack.nl</a> +*/ + diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 0000000..dd97c2c --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,94 @@ +include ../Makefile.config +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 \ + resdefine/html/index.html \ + restypedef/html/index.html \ + afterdoc/html/index.html \ + template/html/index.html \ + tag/html/index.html + +clean: + rm -rf class define enum file func page relates author \ + par overload example include qtstyle jdstyle structcmd \ + autolink tag resdefine restypedef afterdoc template + +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 + sed -e "1,1s.perl.$(PERL).g" tag/html/installdox >tag/html/installdox.perl + cd tag/html ; $(PERL) installdox.perl -lexample.tag@../../example/html + +resdefine/html/index.html: resdefine.cpp resdefine.cfg + $(DOXYDIR)/doxygen resdefine.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 diff --git a/examples/Makefile.windows b/examples/Makefile.windows new file mode 100644 index 0000000..da7cd09 --- /dev/null +++ b/examples/Makefile.windows @@ -0,0 +1,93 @@ +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 \ + tag/html/index.html \ + resdefine/html/index.html \ + restypedef/html/index.html \ + afterdoc/html/index.html + +clean: + deltree /y class define enum file + deltree /y func page relates author + deltree /y par overload example include qtstyle + deltree /y jdstyle structcmd autolink tag resdefine + deltree /y restypedef + +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 + cd tag\html + echo perl installdox -lexample.tag@../../example/html >runperl.bat + runperl.bat + cd ..\.. + +resdefine/html/index.html: resdefine.cpp resdefine.cfg + $(DOXYDIR)\doxygen resdefine.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 diff --git a/examples/afterdoc.cfg b/examples/afterdoc.cfg new file mode 100644 index 0000000..9ebe07a --- /dev/null +++ b/examples/afterdoc.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "AfterDocs" +OUTPUT_DIRECTORY = afterdoc +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = afterdoc.h +QUIET = YES 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..f099903 --- /dev/null +++ b/examples/author.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Author Command" +OUTPUT_DIRECTORY = author +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = author.cpp +QUIET = YES diff --git a/examples/author.cpp b/examples/author.cpp new file mode 100644 index 0000000..ce1c58c --- /dev/null +++ b/examples/author.cpp @@ -0,0 +1,14 @@ +/*! \class WindowsNT + * \brief Windows Nice Try. + * \author Bill Gates + * \author Several hundred furry animals gathered in a cave and grooving + * with a pit. + * \version 4.0 + * \date 1996-1998 + * \bug It crashes a lot and requires huge amounts of memory. + * \bug The class introduces the more bugs, the longer it is used. + * \warning This class may explode in your face. + * \warning If you inherit anything from this class, you're doomed. + */ + +class WindowsNT {}; diff --git a/examples/autolink.cfg b/examples/autolink.cfg new file mode 100644 index 0000000..ff77f83 --- /dev/null +++ b/examples/autolink.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Automatic link generation" +OUTPUT_DIRECTORY = autolink +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = autolink.cpp +QUIET = YES diff --git a/examples/autolink.cpp b/examples/autolink.cpp new file mode 100644 index 0000000..924256b --- /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: ::Val1 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..dfc59eb --- /dev/null +++ b/examples/class.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Class Command" +OUTPUT_DIRECTORY = class +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = class.h +QUIET = YES diff --git a/examples/class.h b/examples/class.h new file mode 100644 index 0000000..e5c4e2d --- /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/define.cfg b/examples/define.cfg new file mode 100644 index 0000000..4960748 --- /dev/null +++ b/examples/define.cfg @@ -0,0 +1,7 @@ +PROJECT_NAME = "Define Command" +OUTPUT_DIRECTORY = define +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = define.h +ENABLE_PREPROCESSING = YES +QUIET = YES diff --git a/examples/define.h b/examples/define.h new file mode 100644 index 0000000..9a8e4d0 --- /dev/null +++ b/examples/define.h @@ -0,0 +1,11 @@ +/*! \file define.h + \brief testing defines + + This is to test the documentation of defines. +*/ + +/*! \def ABS(x) + The define ABS computes the absolute value of its argument \a x. +*/ + +#define ABS(x) (((x)>0)?(x):-(x)) diff --git a/examples/enum.cfg b/examples/enum.cfg new file mode 100644 index 0000000..b38291a --- /dev/null +++ b/examples/enum.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Enum Command" +OUTPUT_DIRECTORY = enum +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = enum.h +QUIET = YES diff --git a/examples/enum.h b/examples/enum.h new file mode 100644 index 0000000..1586074 --- /dev/null +++ b/examples/enum.h @@ -0,0 +1,17 @@ +class Test +{ + public: + enum TEnum { Val1, Val2 }; +}; + +/*! \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..a30b3ff --- /dev/null +++ b/examples/example.cfg @@ -0,0 +1,7 @@ +PROJECT_NAME = "Example Command" +OUTPUT_DIRECTORY = example +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = example.cpp +EXAMPLE_PATH = example_test.cpp +QUIET = YES 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..3998b90 --- /dev/null +++ b/examples/example.tag @@ -0,0 +1,2 @@ +>Test: +example a0 "()" 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..52b766a --- /dev/null +++ b/examples/file.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "File Command" +OUTPUT_DIRECTORY = file +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = file.h +QUIET = YES 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..44d67c6 --- /dev/null +++ b/examples/func.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Fn Command" +OUTPUT_DIRECTORY = func +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = func.h +QUIET = YES 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/include.cfg b/examples/include.cfg new file mode 100644 index 0000000..c4f997e --- /dev/null +++ b/examples/include.cfg @@ -0,0 +1,7 @@ +PROJECT_NAME = "Include Command" +OUTPUT_DIRECTORY = include +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = include.cpp +EXAMPLE_PATH = example_test.cpp +QUIET = YES diff --git a/examples/include.cpp b/examples/include.cpp new file mode 100644 index 0000000..c50ab96 --- /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 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/examples/jdstyle.cfg b/examples/jdstyle.cfg new file mode 100644 index 0000000..833a4aa --- /dev/null +++ b/examples/jdstyle.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "JavaDoc Style" +OUTPUT_DIRECTORY = jdstyle +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = jdstyle.cpp +QUIET = YES diff --git a/examples/jdstyle.cpp b/examples/jdstyle.cpp new file mode 100644 index 0000000..bbd2149 --- /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 chararcter 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/overload.cfg b/examples/overload.cfg new file mode 100644 index 0000000..690edae --- /dev/null +++ b/examples/overload.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Overloaded Command" +OUTPUT_DIRECTORY = overload +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = overload.cpp +QUIET = YES 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..40a8869 --- /dev/null +++ b/examples/page.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Page Command" +OUTPUT_DIRECTORY = page +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = page.doc +QUIET = YES diff --git a/examples/page.doc b/examples/page.doc new file mode 100644 index 0000000..41c9e02 --- /dev/null +++ b/examples/page.doc @@ -0,0 +1,12 @@ +/*! \page page1 A documentation page + This page contains the subsections \ref subsection1 and \ref subsection2. + For more info see section \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..76dab9f --- /dev/null +++ b/examples/par.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Par Command" +OUTPUT_DIRECTORY = par +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = par.cpp +QUIET = YES diff --git a/examples/par.cpp b/examples/par.cpp new file mode 100644 index 0000000..144d1af --- /dev/null +++ b/examples/par.cpp @@ -0,0 +1,9 @@ +/*! \class Test + * Normal text. + * \par User defined paragraph: + * Contents of the paragraph. + * + * More normal text. + */ + +class Test {}; diff --git a/examples/qtstyle.cfg b/examples/qtstyle.cfg new file mode 100644 index 0000000..6d20b53 --- /dev/null +++ b/examples/qtstyle.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Qt Style" +OUTPUT_DIRECTORY = qtstyle +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = qtstyle.cpp +QUIET = YES diff --git a/examples/qtstyle.cpp b/examples/qtstyle.cpp new file mode 100644 index 0000000..de5ad34 --- /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 chararcter 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..83e2be5 --- /dev/null +++ b/examples/relates.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Relates Command" +OUTPUT_DIRECTORY = relates +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = relates.cpp +QUIET = YES diff --git a/examples/relates.cpp b/examples/relates.cpp new file mode 100644 index 0000000..d5e483d --- /dev/null +++ b/examples/relates.cpp @@ -0,0 +1,24 @@ +/*! + * 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/resdefine.cfg b/examples/resdefine.cfg new file mode 100644 index 0000000..009a4e8 --- /dev/null +++ b/examples/resdefine.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Resolving Defines" +OUTPUT_DIRECTORY = resdefine +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = resdefine.cpp +QUIET = YES diff --git a/examples/resdefine.cpp b/examples/resdefine.cpp new file mode 100644 index 0000000..05a77c5 --- /dev/null +++ b/examples/resdefine.cpp @@ -0,0 +1,21 @@ +#define ExportedName InternalName + +class InternalName +{ + public: + InternalName() {} + ~InternalName() {} +}; + +/*! \class ExportedName + * This class's real name is InternalName but everyone should use + * ExportedName. + */ + +/*! \fn ExportedName::ExportedName() + * The constructor + */ + +/*! \fn ExportedName::~ExportedName() + * The destructor + */ diff --git a/examples/restypedef.cfg b/examples/restypedef.cfg new file mode 100644 index 0000000..f17ba4d --- /dev/null +++ b/examples/restypedef.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Resolving Typedefs" +OUTPUT_DIRECTORY = restypedef +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = restypedef.cpp +QUIET = YES diff --git a/examples/restypedef.cpp b/examples/restypedef.cpp new file mode 100644 index 0000000..2cd3f8f --- /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 struct 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..bbc4e71 --- /dev/null +++ b/examples/structcmd.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Structural commands" +OUTPUT_DIRECTORY = structcmd +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = structcmd.h +QUIET = YES 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..79c2ec0 --- /dev/null +++ b/examples/tag.cfg @@ -0,0 +1,8 @@ +PROJECT_NAME = "Tag Files" +OUTPUT_DIRECTORY = tag +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = tag.cpp +TAGFILES = example.tag +PERL_PATH = perl +QUIET = YES 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/templ.cfg b/examples/templ.cfg new file mode 100644 index 0000000..ec16654 --- /dev/null +++ b/examples/templ.cfg @@ -0,0 +1,6 @@ +PROJECT_NAME = "Template Test" +OUTPUT_DIRECTORY = template +GENERATE_LATEX = NO +GENERATE_MAN = NO +INPUT = templ.cpp +QUIET = YES diff --git a/examples/templ.cpp b/examples/templ.cpp new file mode 100644 index 0000000..c838c6e --- /dev/null +++ b/examples/templ.cpp @@ -0,0 +1,37 @@ +/*! A template class */ +template<class T,int i=100> class Test +{ + public: + Test(); + Test(const Test &); + friend void friendTempFunc(Test &, int=5); +}; + +/*! 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,i> &t) {} + +/*! A friend function of a template class */ +template<class T,int i> void friendTempFunc(Test<T,i> &t,int a) {} + +/*! The constructor of the specilization */ +template<> Test<void *,200>::Test() {} + +/*! The constructor of the partial specilization */ +template<class T> Test<T*>::Test() {} diff --git a/make.bat b/make.bat new file mode 100644 index 0000000..a8a2f4e --- /dev/null +++ b/make.bat @@ -0,0 +1,4 @@ +REM make script for Microsoft Visual C++ + +set TMAKEPATH=..\tmake\lib\win32-msvc +nmake /NOLOGO -f Makefile.windows win32-msvc diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..e57994c --- /dev/null +++ b/src/Makefile @@ -0,0 +1,44 @@ +# +# $Id$ +# +# 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. +# +# All output generated with Doxygen is not covered by this license. +# + +include ../Makefile.config + +all: Makefile.doxygen Makefile.doxytag Makefile.doxysearch Makefile + $(MAKE) -f Makefile.doxygen $@ + $(MAKE) -f Makefile.doxytag $@ + $(MAKE) -f Makefile.doxysearch $@ + +Makefile.doxygen: doxygen.pro doxygen.t + $(PERL) $(TMAKE) doxygen.pro >Makefile.doxygen + +Makefile.doxytag: doxytag.pro doxytag.t + $(PERL) $(TMAKE) doxytag.pro >Makefile.doxytag + +Makefile.doxysearch: doxysearch.pro + $(PERL) $(TMAKE) doxysearch.pro >Makefile.doxysearch + +tmake: + $(PERL) $(TMAKE) doxygen.pro >Makefile.doxygen + $(PERL) $(TMAKE) doxytag.pro >Makefile.doxytag + $(PERL) $(TMAKE) doxysearch.pro >Makefile.doxysearch + +clean: + $(MAKE) -f Makefile.doxygen clean + $(MAKE) -f Makefile.doxytag clean + $(MAKE) -f Makefile.doxysearch clean + -rm -f scanner.cpp code.cpp config.cpp pre.cpp ce_lex.cpp \ + ce_parse.cpp ce_parse.h doxytag.cpp tag.cpp \ + declinfo.cpp defargs.cpp version.cpp + +FORCE: diff --git a/src/classdef.cpp b/src/classdef.cpp new file mode 100644 index 0000000..079252d --- /dev/null +++ b/src/classdef.cpp @@ -0,0 +1,900 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <stdio.h> +#include <qfile.h> +#include <qregexp.h> +#include "classdef.h" +#include "classlist.h" +#include "entry.h" +#include "scanner.h" +#include "doxygen.h" +#include "membername.h" +#include "message.h" +#include "config.h" +#include "util.h" +#include "diagram.h" +#include "language.h" + +static QString stripExtension(const char *fName) +{ + QString result=fName; + if (result.right(5)==".html") result=result.left(result.length()-5); + return result; +} + +// constructs a new class definition +ClassDef::ClassDef(const char *nm,int ct,const char *ref,const char *fName) + : Definition(removeRedundantWhiteSpace(nm)) +{ + //name=n; + if (fName) + fileName=stripExtension(fName); + else + fileName="class_"+nameToFile(nm); + if (ref) + { + //url=(QString)"doxygen=\""+ref+":\" href=\""+fileName; + exampleList = 0; + exampleDict = 0; + } + else + { + //url="href=\""+fileName; + exampleList = new ExampleList; + exampleDict = new ExampleDict(29); + } + memListFileName="class_"+nameToFile(nm)+"-members"; + inherits = new BaseClassList; + inherits->setAutoDelete(TRUE); + inheritedBy = new BaseClassList; + inheritedBy->setAutoDelete(TRUE); + allMemberNameInfoList = new MemberNameInfoList; + allMemberNameInfoList->setAutoDelete(TRUE); + allMemberNameInfoDict = new MemberNameInfoDict(1009); + visited=FALSE; + reference=ref; + compType=ct; + incFile=0; + tempArgs=0; + prot=Public; + nspace=0; +} + +// destroy the class definition +ClassDef::~ClassDef() +{ + delete inherits; + delete inheritedBy; + delete allMemberNameInfoList; + delete allMemberNameInfoDict; + delete exampleList; + delete exampleDict; +} + +// inserts a base class in the inheritance list +void ClassDef::insertBaseClass(ClassDef *cd,Protection p, + Specifier s,const char *t) +{ + inherits->inSort(new BaseClassDef(cd,p,s,t)); +} + +// inserts a super class in the inherited list +void ClassDef::insertSuperClass(ClassDef *cd,Protection p, + Specifier s,const char *t) +{ + inheritedBy->inSort(new BaseClassDef(cd,p,s,t)); +} + +// adds new member definition to the class +void ClassDef::insertMember(const MemberDef *md) +{ + //printf("adding %s::%s\n",name(),md->name()); + if (!reference) + { + if (md->isRelated() && (extractPrivateFlag || md->protection()!=Private)) + { + related.append(md); + } + else if (md->isFriend()) + { + friends.append(md); + } + else + { + switch (md->memberType()) + { + case MemberDef::Signal: + signals.append(md); + break; + case MemberDef::Slot: + switch (md->protection()) + { + case Protected: proSlots.append(md); break; + case Public: pubSlots.append(md); break; + case Private: priSlots.append(md); break; + } + break; + default: // any of the other members + if (md->isStatic()) + { + switch (md->protection()) + { + case Protected: proStaticMembers.append(md); break; + case Public: pubStaticMembers.append(md); break; + case Private: priStaticMembers.append(md); break; + } + } + else + { + switch (md->protection()) + { + case Protected: proMembers.append(md); break; + case Public: pubMembers.append(md); break; + case Private: priMembers.append(md); break; + } + } + break; + } + } + } + // check if we should add this member in the `all members' list + if (md->isFriend() || md->protection()!=Private || extractPrivateFlag) + { + MemberInfo *mi = new MemberInfo((MemberDef *)md,Public,Normal); + MemberNameInfo *mni; + if ((mni=(*allMemberNameInfoDict)[md->name()])) + { + mni->append(mi); + } + else + { + mni = new MemberNameInfo(md->name()); + mni->append(mi); + allMemberNameInfoList->inSort(mni); + allMemberNameInfoDict->insert(mni->memberName(),mni); + } + } +} + + +// compute the anchors for all members +void ClassDef::computeAnchors() +{ + setAnchors('a',&pubMembers); + setAnchors('b',&proMembers); + setAnchors('c',&priMembers); + setAnchors('d',&pubStaticMembers); + setAnchors('e',&proStaticMembers); + setAnchors('f',&priStaticMembers); + setAnchors('g',&pubSlots); + setAnchors('h',&proSlots); + setAnchors('i',&priSlots); + setAnchors('j',&signals); + setAnchors('k',&related); + setAnchors('l',&friends); +} + +// add a file name to the used files set +void ClassDef::insertUsedFile(const char *f) +{ + if (files.find(f)==-1) files.append(f); +} + +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(); + } +} + +// write all documentation for this class +void ClassDef::writeDocumentation(OutputList &ol) +{ + // write title + QString pageTitle=name().copy(); + QString pageType; + switch(compType) + { + case Class: pageType=" Class"; break; + case Struct: pageType=" Struct"; break; + case Union: pageType=" Union"; break; + default: pageType+=compType; break; // an error + } + pageTitle+=pageType+" Reference"; + startFile(ol,fileName,pageTitle); + startTitle(ol); + ol.docify(name()+" "+pageType.right(pageType.length()-1)+" "); + parseDoc(ol,0,0,theTranslator->trReference()); + endTitle(ol,name()); + + // write brief description + OutputList briefOutput(&ol); + if (!briefDescription().isEmpty()) + { + parseDoc(briefOutput,name(),0,briefDescription()); + ol+=briefOutput; + ol.writeString(" \n"); + ol.disableAllBut(OutputGenerator::Html); + ol.startTextLink(0,"details"); + parseDoc(ol,0,0,theTranslator->trMore()); + ol.endTextLink(); + ol.enableAll(); + } + ol.disable(OutputGenerator::Man); + ol.newParagraph(); + ol.enable(OutputGenerator::Man); + ol.writeSynopsis(); + + if (incFile) + { + QString nm=incName.copy(); + if (incName.isNull()) nm=incFile->name(); + ol.startTypewriter(); + ol.docify("#include <"); + ol.disable(OutputGenerator::Man); + if (verbatimHeaderFlag) + { + ol.writeObjectLink(0,fileName+"-include",0,nm); + } + else + { + ol.docify(nm); + } + ol.enable(OutputGenerator::Man); + ol.disableAllBut(OutputGenerator::Man); + ol.docify(nm); + ol.enableAll(); + ol.docify(">"); + ol.endTypewriter(); + ol.newParagraph(); + } + + if (genTagFile.length()>0) tagFile << ">" << name() << ":"; + + if (classDiagramFlag) ol.disableAllBut(OutputGenerator::Man); + + // write superclasses + int count; + if ((count=inherits->count())>0) + { + parseDoc(ol,0,0,theTranslator->trInherits()+" "); + BaseClassDef *bcd=inherits->first(); + while (bcd) + { + ClassDef *cd=bcd->classDef; + if (cd->hasDocumentation() || cd->isReference()) + { + if (genTagFile.length()>0) tagFile << cd->classFile() << "?"; + ol.writeObjectLink(cd->getReference(),cd->classFile(),0,cd->name()+bcd->templSpecifiers); + } + else + { + ol.docify(cd->name()); + } + writeInheritanceSpecifier(ol,bcd); + bcd=inherits->next(); + if (bcd) + { + if (inherits->at()==count-1) + parseDoc(ol,0,0," "+theTranslator->trAnd()+" "); + else + ol.writeString(", "); + } + } + ol.writeString("."); + ol.newParagraph(); + } + + if (genTagFile.length()>0) tagFile << " \"" << fileName << ".html\"\n"; + + // write subclasses + if ((count=inheritedBy->count())>0) + { + parseDoc(ol,0,0,theTranslator->trInheritedBy()+" "); + BaseClassDef *bcd=inheritedBy->first(); + while (bcd) + { + ClassDef *cd=bcd->classDef; + if (cd->hasDocumentation() || cd->isReference()) + { + ol.writeObjectLink(cd->getReference(),cd->classFile(),0,cd->name()); + } + else + { + ol.docify(cd->name()); + } + writeInheritanceSpecifier(ol,bcd); + bcd=inheritedBy->next(); + if (bcd) + { + if (inheritedBy->at()==count-1) + parseDoc(ol,0,0," "+theTranslator->trAnd()+" "); + else + ol.writeString(", "); + } + } + ol.writeString("."); + ol.newParagraph(); + } + + if (classDiagramFlag) ol.enableAll(); + + count=0; + BaseClassDef *ibcd; + ibcd=inheritedBy->first(); + while (ibcd) + { + ClassDef *icd=ibcd->classDef; + if (//(icd->protection()!=Private || extractPrivateFlag) && + //(icd->hasDocumentation() || !hideClassFlag || icd->isReference()) + icd->isVisibleExt() + ) count++; + ibcd=inheritedBy->next(); + } + ibcd=inherits->first(); + while (ibcd) + { + ClassDef *icd=ibcd->classDef; + if (//(icd->protection()!=Private || extractPrivateFlag) && + //(icd->hasDocumentation() || !hideClassFlag | icd->isReference()) + icd->isVisibleExt() + ) count++; + ibcd=inherits->next(); + } + if (classDiagramFlag && count>0) + // write class diagram + { + ClassDiagram diagram(this); // create a diagram of this class. + ol.startClassDiagram(); + ol.disable(OutputGenerator::Man); + parseDoc(ol,name(),0,theTranslator->trClassDiagram(name())); + ol.enable(OutputGenerator::Man); + ol.endClassDiagram(diagram,fileName,name()); + } + + // write link to list of all members (HTML only) + if (allMemberNameInfoList->count()>0 && compType==Class) + { + ol.disableAllBut(OutputGenerator::Html); + ol.startTextLink(memListFileName,0); + parseDoc(ol,0,0,theTranslator->trListOfAllMembers()); + ol.endTextLink(); + ol.enableAll(); + } + + // write member groups + writeMemberDecs(ol,this,0,0,"Public Members",0,&pubMembers); + writeMemberDecs(ol,this,0,0,"Public Slots",0,&pubSlots); + writeMemberDecs(ol,this,0,0,"Signals",0,&signals); + writeMemberDecs(ol,this,0,0,"Static Public Members",0,&pubStaticMembers); + writeMemberDecs(ol,this,0,0,"Protected Members",0,&proMembers); + writeMemberDecs(ol,this,0,0,"Protected Slots",0,&proSlots); + writeMemberDecs(ol,this,0,0,"Static Protected Members",0,&proStaticMembers); + if (extractPrivateFlag) + { + writeMemberDecs(ol,this,0,0,"Private Members",0,&priMembers); + writeMemberDecs(ol,this,0,0,"Private Slots",0,&priSlots); + writeMemberDecs(ol,this,0,0,"Static Private Members",0,&priStaticMembers); + } + writeMemberDecs(ol,this,0,0,"Friends",0,&friends); + writeMemberDecs(ol,this,0,0, + theTranslator->trRelatedFunctions(), + theTranslator->trRelatedSubscript(), + &related + ); + + // write detailed description + bool exampleFlag=hasExamples(); + if (!briefDescription().isEmpty() || !documentation().isEmpty() || exampleFlag) + { + ol.writeRuler(); + ol.writeAnchor("details"); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trDetailedDescription()); + ol.endGroupHeader(); + if (tempArgs) // class is a template + { + ol.startSubsubsection(); + ArgumentList *al=tempArgs; + ol.docify("template<"); + Argument *a=al->first(); + while (a) + { + ol.docify(a->type); + ol.docify(a->name); + if (a->defval.length()!=0) + { + ol.docify(" = "); + ol.docify(a->defval); + } + a=al->next(); + if (a) ol.docify(", "); + } + ol.docify("> "+pageType.lower()+" "+name()); + ol.endSubsubsection(); + ol.writeString("\n"); + } + + // repeat brief description + if (!briefDescription().isEmpty()) + { + ol+=briefOutput; + ol.newParagraph(); + } + // write documentation + if (!documentation().isEmpty()) + { + parseDoc(ol,name(),0,documentation()+"\n"); + } + // write examples + if (exampleFlag) + { + ol.startDescList(); + ol.startBold(); + parseDoc(ol,0,0,theTranslator->trExamples()+": "); + ol.endBold(); + ol.endDescTitle(); + ol.writeDescItem(); + writeExample(ol); + //ol.endDescItem(); + ol.endDescList(); + } + } + + pubMembers.countDocMembers(); + proMembers.countDocMembers(); + priMembers.countDocMembers(); + pubStaticMembers.countDocMembers(); + proStaticMembers.countDocMembers(); + priStaticMembers.countDocMembers(); + pubSlots.countDocMembers(); + proSlots.countDocMembers(); + priSlots.countDocMembers(); + related.countDocMembers(); + friends.countDocMembers(); + signals.countDocMembers(); + + if ( pubMembers.typedefCount() + proMembers.typedefCount() + + (extractPrivateFlag ? priMembers.typedefCount() : 0 ) + ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trMemberTypedefDocumentation()); + ol.endGroupHeader(); + + writeMemberDocs(ol,&pubMembers,name(),MemberDef::Typedef); + writeMemberDocs(ol,&proMembers,name(),MemberDef::Typedef); + if (extractPrivateFlag) + { + writeMemberDocs(ol,&priMembers,name(),MemberDef::Typedef); + } + } + + if (pubMembers.enumCount() + + proMembers.enumCount() + + ( extractPrivateFlag ? priMembers.enumCount() : 0 ) + ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trMemberEnumerationDocumentation()); + ol.endGroupHeader(); + + writeMemberDocs(ol,&pubMembers,name(),MemberDef::Enumeration); + writeMemberDocs(ol,&proMembers,name(),MemberDef::Enumeration); + if (extractPrivateFlag) + { + writeMemberDocs(ol,&priMembers,name(),MemberDef::Enumeration); + } + } + + if (pubMembers.enumValueCount() + + proMembers.enumValueCount() + + ( extractPrivateFlag ? priMembers.enumValueCount() : 0 ) + ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trEnumerationValueDocumentation()); + ol.endGroupHeader(); + + writeMemberDocs(ol,&pubMembers,name(),MemberDef::EnumValue); + writeMemberDocs(ol,&proMembers,name(),MemberDef::EnumValue); + if (extractPrivateFlag) + { + writeMemberDocs(ol,&priMembers,name(),MemberDef::EnumValue); + } + } + + if ( pubMembers.funcCount() + pubSlots.funcCount() + + pubStaticMembers.funcCount() + + proMembers.funcCount() + proSlots.funcCount() + + proStaticMembers.funcCount() + + (extractPrivateFlag ? + priMembers.funcCount() + priSlots.funcCount() + + priStaticMembers.funcCount() : 0 + ) + ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trMemberFunctionDocumentation()); + ol.endGroupHeader(); + + writeMemberDocs(ol,&pubMembers,name(),MemberDef::Function); + writeMemberDocs(ol,&pubSlots,name(),MemberDef::Slot); + writeMemberDocs(ol,&signals,name(),MemberDef::Signal); + writeMemberDocs(ol,&pubStaticMembers,name(),MemberDef::Function); + writeMemberDocs(ol,&proMembers,name(),MemberDef::Function); + writeMemberDocs(ol,&proSlots,name(),MemberDef::Slot); + writeMemberDocs(ol,&proStaticMembers,name(),MemberDef::Function); + if (extractPrivateFlag) + { + writeMemberDocs(ol,&priMembers,name(),MemberDef::Function); + writeMemberDocs(ol,&priSlots,name(),MemberDef::Slot); + writeMemberDocs(ol,&priStaticMembers,name(),MemberDef::Function); + } + } + + if ( friends.count() + related.count() ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trRelatedFunctionDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,&friends,name(),MemberDef::Friend); + writeMemberDocs(ol,&related,name(),MemberDef::Function); + } + + + if ( pubMembers.varCount() + pubStaticMembers.varCount() + + proMembers.varCount() + proStaticMembers.varCount() + + (extractPrivateFlag ? + priMembers.varCount() + priStaticMembers.varCount() : 0 + ) + ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trMemberDataDocumentation()); + ol.endGroupHeader(); + + writeMemberDocs(ol,&pubMembers,name(),MemberDef::Variable); + writeMemberDocs(ol,&pubStaticMembers,name(),MemberDef::Variable); + writeMemberDocs(ol,&proMembers,name(),MemberDef::Variable); + writeMemberDocs(ol,&proStaticMembers,name(),MemberDef::Variable); + if (extractPrivateFlag) + { + writeMemberDocs(ol,&priMembers,name(),MemberDef::Variable); + writeMemberDocs(ol,&priStaticMembers,name(),MemberDef::Variable); + } + } + + // write the list of used files (Html and LaTeX only) + ol.disable(OutputGenerator::Man); + ol.writeRuler(); + parseDoc(ol,0,0, + theTranslator->trGeneratedFrom(pageType.lower(), + files.count()==1)); + ol.startItemList(); + + const char *file = files.first(); + while (file) + { + QFileInfo fi(file); + ol.writeListItem(); + FileDef *fd; + bool ambig; + if ((fd=findFileDef(&inputNameDict,fi.absFilePath(),ambig)) + && fd->hasDocumentation()) + { + ol.writeObjectLink(fd->getReference(),fd->diskName(),0, + fi.fileName()); + } + else + { + ol.docify(fi.fileName()); + } + file=files.next(); + } + + ol.endItemList(); + ol.enable(OutputGenerator::Man); + + // write Author section (Man only) + ol.disableAllBut(OutputGenerator::Man); + ol.writeString("\n"); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trAuthor()); + ol.endGroupHeader(); + parseDoc(ol,0,0,theTranslator->trGeneratedAutomatically(projectName)); + ol.enableAll(); + + endFile(ol); +} + +// write the list of all (inherited) members for this class +void ClassDef::writeMemberList(OutputList &ol) +{ + if (allMemberNameInfoList->count()==0) return; + // do not generate Latex output + ol.disableAllBut(OutputGenerator::Html); + startFile(ol,memListFileName,theTranslator->trMemberList()); + startTitle(ol); + parseDoc(ol,name(),0,name()+" "+theTranslator->trMemberList()); + endTitle(ol,0); + parseDoc(ol,0,0,theTranslator->trThisIsTheListOfAllMembers()); + ol.writeString(" "); + ol.writeObjectLink(reference,fileName,0,name()); + ol.writeString(", "); + parseDoc(ol,0,0,theTranslator->trIncludingInheritedMembers()); + + ol.startItemList(); + + MemberNameInfo *mni=allMemberNameInfoList->first(); + while (mni) + { + MemberInfo *mi=mni->first(); + while (mi) + { + MemberDef *md=mi->memberDef; + ClassDef *cd=md->memberClass(); + + // 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; + } + + //printf("Member %s of class %s mi->prot=%d prot=%d\n", + // md->name().data(),cd->name().data(),mi->prot,protect); + + Specifier virt=md->virtualness(); + MemberDef *rmd=md->reimplements(); + while (rmd && virt==Normal) + { + virt = rmd->virtualness()==Normal ? Normal : Virtual; + rmd = rmd->reimplements(); + } + + if (cd && !md->name().isEmpty() && md->name()[0]!='@' && + ( + md->isFriend() || + (mi->prot!=Private && (protect!=Private || extractPrivateFlag)) + ) + ) + { + bool memberWritten=FALSE; + if (cd->isVisible() && (md->hasDocumentation() || md->isReference())) + // create a link to the documentation + { + QString name=mi->ambiguityResolutionScope+md->name(); + ol.writeListItem(); + ol.writeObjectLink(cd->getReference(),cd->classFile(), + md->anchor(),name); + if ( md->isFunction() || md->isSignal() || md->isSlot() ) + ol.docify(md->argsString()); + else if (md->isEnumerate()) + parseDoc(ol,0,0," "+theTranslator->trEnumName()); + else if (md->isEnumValue()) + parseDoc(ol,0,0," "+theTranslator->trEnumValue()); + else if (md->isTypedef()) + ol.docify(" typedef"); + else if (md->isFriend() && !strcmp(md->typeString(),"friend class")) + ol.docify(" class"); + ol.writeString("\n"); + memberWritten=TRUE; + } + else if (!hideMemberFlag) // no documentation, + // generate link to the class instead. + { + ol.writeListItem(); + ol.writeBoldString(md->name()); + if ( md->isFunction() || md->isSignal() || md->isSlot() ) + ol.docify(md->argsString()); + else if (md->isEnumerate()) + parseDoc(ol,0,0," "+theTranslator->trEnumName()); + else if (md->isEnumValue()) + parseDoc(ol,0,0," "+theTranslator->trEnumValue()); + else if (md->isTypedef()) + ol.docify(" typedef"); + ol.writeString(" ("); + parseDoc(ol,0,0,theTranslator->trDefinedIn()+" "); + if (cd->isVisible()) + { + ol.writeObjectLink(cd->getReference(),cd->classFile(),0,cd->name()); + } + else + { + ol.writeBoldString(cd->name()); + } + ol.writeString(")"); + memberWritten=TRUE; + } + if ((protect!=Public || md->isStatic() || virt!=Normal || + md->isFriend() || md->isRelated() + ) + && memberWritten) + { + ol.startTypewriter(); + ol.docify(" ["); + QStrList sl; + if (md->isFriend()) sl.append("friend"); + else if (md->isRelated()) sl.append("related"); + else + { + if (protect==Protected) sl.append("protected"); + else if (protect==Private) sl.append("private"); + if (virt==Virtual) 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"); + } + const char *s=sl.first(); + while (s) + { + ol.docify(s); + s=sl.next(); + if (s) ol.docify(", "); + } + ol.docify("]"); + ol.endTypewriter(); + } + } + mi=mni->next(); + } + mni=allMemberNameInfoList->next(); + } + ol.endItemList(); + endFile(ol); + ol.enableAll(); +} + +void ClassDef::writeIncludeFile(OutputList &ol) +{ + if (!incFile) return; + //printf("incFile=%s\n",incFile->absFilePath().data()); + ol.disableAllBut(OutputGenerator::Html); + startFile(ol,fileName+"-include",name()+" Include File"); + startTitle(ol); + QString n=incName.copy(); + if (incName.isNull()) n=incFile->name(); + parseDoc(ol,0,0,n); + endTitle(ol,0); + parseDoc(ol,0,0,theTranslator->trVerbatimText(incFile->name())); + ol.writeRuler(); + ol.startCodeFragment(); + parseCode(ol,n,fileToString(incFile->absFilePath()),FALSE,0); + ol.endCodeFragment(); + endFile(ol); + ol.enableAll(); +} + +// add a reference to an example +bool ClassDef::addExample(const char *anchor,const char *nameStr, + const char *file) +{ + if (exampleDict && !exampleDict->find(nameStr)) + { + Example *e=new Example; + e->anchor=anchor; + e->name=nameStr; + e->file=file; + exampleDict->insert(nameStr,e); + exampleList->inSort(e); + return TRUE; + } + return FALSE; +} + +// returns TRUE if this class is used in an example +bool ClassDef::hasExamples() +{ + if (exampleList==0) + return FALSE; + else + return exampleList->count()>0; +} + +// write the list of all examples that are use this class. +void ClassDef::writeExample(OutputList &ol) +{ + Example *e=exampleList->first(); + while (e) + { + ol.writeObjectLink(0,e->file,e->anchor,e->name); + e=exampleList->next(); + if (e) + { + if (exampleList->at()==(int)exampleList->count()-1) + parseDoc(ol,0,0," "+theTranslator->trAnd()+" "); + else + ol.writeString(", "); + } + } + ol.writeString("."); +} + +void ClassDef::setTemplateArguments(ArgumentList *al) +{ + if (al==0) return; + if (!tempArgs) delete tempArgs; // delete old list if needed + tempArgs=new ArgumentList; + tempArgs->setAutoDelete(TRUE); + ArgumentListIterator ali(*al); + Argument *a; + for (;(a=ali.current());++ali) + { + tempArgs->append(new Argument(*a)); + } +} + +QString ClassDef::getTemplateNameString() +{ + QString result; + if (!tempArgs || tempArgs->count()==0) return result; + result="<"; + Argument *a=tempArgs->first(); + while (a) + { + if (a->name.length()>0) // add template argument name + { + 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); + } + } + a=tempArgs->next(); + if (a) result+=", "; + } + result+=">"; + return result; +} + +bool ClassDef::hasNonReferenceSuperClass() +{ + bool found=!isReference(); + BaseClassListIterator bcli(*inheritedBy); + for ( ; bcli.current() && !found ; ++bcli ) + found=found || bcli.current()->classDef->hasNonReferenceSuperClass(); + return found; +} diff --git a/src/classdef.h b/src/classdef.h new file mode 100644 index 0000000..8fe0f21 --- /dev/null +++ b/src/classdef.h @@ -0,0 +1,169 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef CLASSDEF_H +#define CLASSDEF_H + +#include <qstring.h> +#include <qfileinf.h> +#include <qlist.h> +#include <qdict.h> +#include <qtstream.h> +#include <qstrlist.h> + +#include "membername.h" +#include "memberlist.h" +#include "memberdef.h" +#include "example.h" +#include "entry.h" +#include "definition.h" + +typedef QDict<MemberDef> MemberDict; +class ClassList; +class OutputList; +class FileDef; +class BaseClassList; +class MemberInfoList; +class MemberInfoDict; +class NamespaceDef; + +class ClassDef : public Definition +{ + public: + + enum CompoundType { Class=Entry::CLASS_SEC, + Struct=Entry::STRUCT_SEC, + Union=Entry::UNION_SEC + }; + + ClassDef(const char *name,int ct,const char *ref=0,const char *fName=0); + ~ClassDef(); + QString classFile() const { return fileName; } + int compoundType() const { return compType; } + const char *memberListFileName() const { return memListFileName; } + void insertBaseClass(ClassDef *,Protection p,Specifier s,const char *t=0); + BaseClassList *baseClasses() { return inherits; } + void insertSuperClass(ClassDef *,Protection p,Specifier s,const char *t=0); + BaseClassList *superClasses() { return inheritedBy; } + void setIncludeFile(FileDef *fd) { incFile=fd; } + FileDef *includeFile() const { return incFile; } + void setIncludeName(const char *n_) { incName=n_; } + MemberNameInfoList *memberNameInfoList() { return allMemberNameInfoList; } + MemberNameInfoDict *memberNameInfoDict() { return allMemberNameInfoDict; } + bool isReference() { return !reference.isNull(); } + const char *getReference() const { return reference; } + void insertMember(const MemberDef *); + void insertUsedFile(const char *); + void computeAnchors(); + void setAnchor(MemberDef *); + void dumpMembers(); + void writeDocumentation(OutputList &ol); + void writeMemberList(OutputList &ol); + void writeIncludeFile(OutputList &ol); + bool addExample(const char *anchor,const char *name, const char *file); + bool hasExamples(); + void writeExample(OutputList &ol); + void setProtection(Protection p) { prot=p; } + Protection protection() const { return prot; } + bool isVisible() + { return !name().isEmpty() && name().at(0)!='@' && + (prot!=Private || extractPrivateFlag) && + hasDocumentation(); + } + bool hasNonReferenceSuperClass(); + bool isVisibleExt() + { return (allExtFlag || hasNonReferenceSuperClass()) && + !name().isEmpty() && name().at(0)!='@' && + (prot!=Private || extractPrivateFlag) && + (hasDocumentation() || !hideClassFlag || !reference.isNull()); + } + + // template argument functions + ArgumentList *templateArguments() const { return tempArgs; } + void setTemplateArguments(ArgumentList *al); + QString getTemplateNameString(); + void setNamespace(NamespaceDef *nd) { nspace = nd; } + NamespaceDef *getNamespace() { return nspace; } + + bool visited; + + private: + //QString name; // name of the class + QString fileName; // HTML containing the class docs + //QString doc; // general class documentation + FileDef *incFile; // header file to refer to + QString incName; // alternative include file name + //QString brief; // brief class discription + QString memListFileName; + BaseClassList *inherits; + BaseClassList *inheritedBy; + NamespaceDef *nspace; // the namespace this class is in + MemberList pubMembers; + MemberList proMembers; + MemberList priMembers; + MemberList pubStaticMembers; + MemberList proStaticMembers; + MemberList priStaticMembers; + MemberList pubSlots; + MemberList proSlots; + MemberList priSlots; + MemberList related; + MemberList signals; + MemberList friends; + MemberNameInfoList *allMemberNameInfoList; + MemberNameInfoDict *allMemberNameInfoDict; + ArgumentList *tempArgs; + QStrList files; + QString reference; + ExampleList *exampleList; + ExampleDict *exampleDict; + int compType; + Protection prot; +}; + + +struct BaseClassDef +{ + BaseClassDef(ClassDef *cd,Protection p,Specifier v,const char *t) : + classDef(cd), prot(p), virt(v), templSpecifiers(t) {} + ClassDef *classDef; + Protection prot; + Specifier virt; + QString templSpecifiers; +}; + +class BaseClassList : public QList<BaseClassDef> +{ + public: + int compareItems(GCI item1,GCI item2) + { + ClassDef *c1=((BaseClassDef *)item1)->classDef; + ClassDef *c2=((BaseClassDef *)item2)->classDef; + if (c1==0 || c2==0) + return FALSE; + else + return strcmp(c1->name(),c2->name()); + } +}; + +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..518f757 --- /dev/null +++ b/src/classlist.cpp @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include "classlist.h" + +ClassList::ClassList() : QList<ClassDef>() +{ +} + +ClassList::~ClassList() +{ +} + +int ClassList::compareItems(GCI item1, GCI item2) +{ + ClassDef *c1=(ClassDef *)item1; + ClassDef *c2=(ClassDef *)item2; + return strcmp(c1->name(),c2->name()); +} + +ClassListIterator::ClassListIterator(const ClassList &cllist) : + QListIterator<ClassDef>(cllist) +{ +} diff --git a/src/classlist.h b/src/classlist.h new file mode 100644 index 0000000..28d8454 --- /dev/null +++ b/src/classlist.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef CLASSLIST_H +#define CLASSLIST_H + +#include "classdef.h" + +class ClassList : public QList<ClassDef> +{ + public: + ClassList(); + ~ClassList(); + + int compareItems(GCI item1,GCI item2); +}; + +class ClassListIterator : public QListIterator<ClassDef> +{ + public: + ClassListIterator(const ClassList &list); +}; + +#endif diff --git a/src/code.h b/src/code.h new file mode 100644 index 0000000..4b781fb --- /dev/null +++ b/src/code.h @@ -0,0 +1,28 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef CODE_H +#define CODE_H + +#include <stdio.h> +#include <qstring.h> + +class OutputList; + +extern void parseCode(OutputList &,const char *,const QString &, + bool ,const char *); +extern void initParseCodeContext(); +#endif diff --git a/src/code.l b/src/code.l new file mode 100644 index 0000000..8bff410 --- /dev/null +++ b/src/code.l @@ -0,0 +1,747 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +%{ + +/* + * includes + */ +#include <stdio.h> +#include <iostream.h> +#include <assert.h> +#include <ctype.h> + +#include <qstring.h> + +#include "scanner.h" +#include "entry.h" +#include "doxygen.h" +#include "message.h" +#include "outputlist.h" +#include "util.h" + +#define YY_NO_UNPUT +#define YY_NEVER_INTERACTIVE 1 + +class CodeClassDef +{ + public: + CodeClassDef() {} + CodeClassDef(const CodeClassDef &d) + { + name = d.name; + bases = d.bases; + } + ~CodeClassDef() {} + + QString name; + QStrList bases; +}; + +class CodeVarDef +{ + public: + CodeVarDef() {} + CodeVarDef(const CodeVarDef &d) + { + name = d.name; + type = d.type; + classScope = d.classScope; + } + ~CodeVarDef() {} + + QString name; + QString type; + QString classScope; +}; + +typedef QList<CodeClassDef> CodeClassList; +typedef QDict<CodeClassDef> CodeClassDict; +typedef QList<CodeVarDef> CodeVarList; + +static CodeClassList codeClassList; +static CodeClassDict codeClassDict(17); +static CodeVarList codeVarList; +static CodeVarList codeParmList; + +/* ----------------------------------------------------------------- + * + * statics + */ + +static const char * inputString; +static int inputPosition; +static int lastCContext; +static int lastDContext; +static int lastStringContext; +static int bracketCount = 0; +static int curlyCount = 0; +static int sharpCount = 0; +static int yyLineNr = 0; +static QString type; +static QString name; +static QString args; +static QString parmType; +static QString parmName; +static bool inClass; +static QString classScope; +static OutputList *code; +static CodeClassDef ccd; +static CodeVarDef cvd; +static bool exampleBlock; +static QString exampleName; +static QString exampleFile; +static int anchorCount; + +static void addType() +{ + if (name=="const") { name.resize(0); return; } + if (type.length()) type += ' ' ; + type += name ; + name.resize(0) ; + if (type.length()) type += ' ' ; + type += args ; + args.resize(0) ; +} + +static void addParmType() +{ + if (parmName=="const") { parmName.resize(0); return; } + if (parmType.length()) parmType += ' ' ; + parmType += parmName ; + parmName.resize(0) ; +} + +static void setClassScope(const QString &name) +{ + QString n=name; + n=n.simplifyWhiteSpace(); + int index; + if ((index=n.find("::"))!=-1) + classScope=n.left(index); + else + classScope.resize(0); + //printf("--->New class scope `%s'\n",classScope.data()); +} + +static void addVariable() +{ + cvd.name=name.copy().simplifyWhiteSpace(); + cvd.type=type.copy().simplifyWhiteSpace(); + if (type.length()==0) + return; + else if ((getClass(cvd.type)) || (codeClassDict[cvd.type])) + { + cvd.classScope=classScope; + codeVarList.append(new CodeVarDef(cvd)); // add it to a list + } +} + +static void addParameter() +{ + cvd.name=parmName.copy().simplifyWhiteSpace(); + cvd.type=parmType.copy().simplifyWhiteSpace(); + if (cvd.type.length()==0) + return; + else if ((getClass(cvd.type)) || (codeClassDict[cvd.type])) + { + cvd.classScope=classScope; + codeParmList.append(new CodeVarDef(cvd)); // add it to a list + } +} + +static void generateClassLink(OutputList &ol,const char *clName) +{ + QString className=clName; + if (className.length()==0) return; + ClassDef *cd; + if ((cd=getClass(className)) && cd->isVisible()) + { + if (exampleBlock) + { + QString anchor; + anchor.sprintf("a%d",anchorCount); + //printf("addExampleClass(%s,%s,%s)\n",anchor.data(),exampleName.data(), + // exampleFile.data()); + if (cd->addExample(anchor,exampleName,exampleFile)) + { + ol.writeAnchor(anchor); + anchorCount++; + } + } + ol.writeCodeLink(cd->getReference(),cd->classFile(),0,className); + } + else + { + ol.codify(clName); + } +} + +static bool getLink(const char *className, + const char *memberName,OutputList &result) +{ + MemberDef *md; + ClassDef *cd; + FileDef *fd; + QString m=memberName; + QString c=className; + //printf("Trying `%s'::`%s'\n",c.data(),m.data()); + if (getDefs(m,c,"()",md,cd,fd) && + (md->hasDocumentation() || md->isReference())) + { + //printf("Found!\n"); + if (exampleBlock) + { + QString anchor; + anchor.sprintf("a%d",anchorCount); + //printf("addExampleFile(%s,%s,%s)\n",anchor.data(),exampleName.data(), + // exampleFile.data()); + if (md->addExample(anchor,exampleName,exampleFile)) + { + result.writeAnchor(anchor); + anchorCount++; + } + } + if (cd) + { + result.writeCodeLink(cd->getReference(),cd->classFile(), + md->anchor(),memberName); + return TRUE; + } + else if (fd) + { + result.writeCodeLink(fd->getReference(),fd->diskName(), + md->anchor(),memberName); + return TRUE; + } + } + + return FALSE; +} + +static void generateMemberLink(OutputList &ol,const char *varName, + const char *memName) +{ + //printf("generateMemberLink(object=%s,mem=%s) classScope=%s\n", + // varName,memName,classScope.data()); + CodeVarDef *cvd=codeParmList.last(); + while (cvd && cvd->name!=varName) cvd=codeParmList.prev(); + if (!cvd) + { + cvd=codeVarList.last(); + while (cvd && cvd->name!=varName) cvd=codeVarList.prev(); + } + if (cvd) // variable found + { + CodeClassDef *ccd=codeClassDict[cvd->type]; + if (ccd) + { + char *s=ccd->bases.first(); + while (s) + { + OutputList result(&ol); + if (getLink(s,memName,result)) + { + ol+=result; + return; + } + s=ccd->bases.next(); + } + } + else + { + OutputList result(&ol); + if (getLink(cvd->type,memName,result)) + { + ol+=result; + } + else + { + ol.codify(memName); + } + return; + } + } + ol.codify(memName); + return; +} + +static void generateFunctionLink(OutputList &ol,const char *funcName) +{ + //printf("generateFunctionLink(%s) classScope=%s\n",funcName,classScope.data()); + OutputList result(&ol); + CodeClassDef *ccd=0; + if (classScope.length()>0 && (ccd=codeClassDict[classScope])) + { + //printf("using classScope %s\n",classScope.data()); + char *s=ccd->bases.first(); + while (s) + { + if (getLink(s,funcName,result)) + { + ol+=result; + return; + } + s=ccd->bases.next(); + } + } + if (getLink(classScope,funcName,result)) + { + ol+=result; + } + else + { + ol.codify(funcName); + } + 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 c=0; + while( c < max_size && inputString[inputPosition] ) + { + *buf = inputString[inputPosition++] ; + c++; buf++; + } + return c; +} + +%} + +ID [a-z_A-Z][a-z_A-Z0-9]* + +%x SkipString +%x SkipCPP +%x SkipComment +%x SkipSpecialComment +%x SkipCxxComment +%x SkipSpecialCxxComment +%x Body +%x FuncCall +%x MemberCall +%x MemberCall2 +%x SkipInits +%x ClassName +%x Bases +%x SkipSharp +%x ReadInclude + +%% + +<*>\x0d +<Body>^([ \t]*"#include"[ \t]*)("<"|"\"") { + code->codify(yytext); + BEGIN( ReadInclude ); + } +<Body>("class"|"struct"|"union")[ \t\n]+ { + code->codify(yytext); + BEGIN( ClassName ); + } +<ReadInclude>[a-z_A-Z0-9.]+(("/"[a-z_A-Z0-9.]+)*)/(">"|"\"") { + //FileInfo *f; + bool ambig; + FileDef *fd; + if ((fd=findFileDef(&inputNameDict,yytext,ambig)) && + fd->hasDocumentation()) + { + code->writeCodeLink(0,fd->diskName(),0,yytext); + } + else + { + code->codify(yytext); + } + char c=yyinput(); + QString text; + text+=c; + code->codify(text); + BEGIN( Body ); + } +<Body>^[ \t]*"#" { + code->codify(yytext); + BEGIN( SkipCPP ) ; + } +<SkipCPP>. { + code->codify(yytext); + } +<SkipCPP>\\\n { + code->codify(yytext); + yyLineNr++ ; + } +<SkipCPP>\n { + yyLineNr++ ; + code->codify(yytext); + BEGIN( Body ) ; + } +<SkipCPP>"//" { + code->codify(yytext); + } +<Body>"{" { + code->codify(yytext); + curlyCount++; + type.resize(0); name.resize(0); + } +<Body>"}" { + code->codify(yytext); + inClass=FALSE; + if (--curlyCount<=0) + { + classScope.resize(0); + codeParmList.clear(); + } + } +<ClassName>";" { + code->codify(yytext); + BEGIN( Body ); + } +<ClassName>[*&]+ { + addType(); + code->codify(yytext); + } +<ClassName>{ID} { + ccd.name=yytext; + addType(); + generateClassLink(*code,yytext); + } +<ClassName>[ \t\n]*":"[ \t\n]* { + code->codify(yytext); + BEGIN( Bases ); + } +<Bases,ClassName>[ \t]*"{"[ \t]* { + code->codify(yytext); + curlyCount++; + inClass=TRUE; + if (ccd.name.length()>0) + { + classScope=ccd.name.copy(); + CodeClassDef *cd=new CodeClassDef(ccd); + codeClassList.append(cd); + codeClassDict.insert(cd->name,cd); + } + BEGIN( Body ); + } +<Bases>"virtual" { + code->codify(yytext); + } +<Bases>"public" { + code->codify(yytext); + } +<Bases>"protected" { + code->codify(yytext); + } +<Bases>"private" { + code->codify(yytext); + } +<Bases>{ID} { + //printf("%s:addBase(%s)\n",ccd.name.data(),yytext); + ccd.bases.inSort(yytext); + generateClassLink(*code,yytext); + } +<Bases>"<" { + code->codify(yytext); + sharpCount=1; + BEGIN ( SkipSharp ); + } +<SkipSharp>"<" { + code->codify(yytext); + ++sharpCount; + } +<SkipSharp>">" { + code->codify(yytext); + if (--sharpCount<=0) + BEGIN ( Bases ); + } +<Bases>"," { + code->codify(yytext); + } + + +<Body>("asm"|"auto"|"break"|"case"|"catch"|"continue"|"default"|"delete"|"do"|"else"|"for"|"goto"|"if"|"new"|"return"|"switch"|"this"|"throw"|"try"|"typedef"|"while")([ \t\n]*)/"(" { + code->codify(yytext); + name.resize(0);type.resize(0); + } +<Body>("asm"|"auto"|"break"|"case"|"catch"|"continue"|"default"|"delete"|"do"|"else"|"for"|"goto"|"if"|"new"|"return"|"switch"|"this"|"throw"|"try"|"typedef"|"while")([ \t\n]*) { + code->codify(yytext); + name.resize(0);type.resize(0); + } +<Body>([a-z_A-Z~][a-z_A-Z0-9]*)/([ \t]*) { + generateClassLink(*code,yytext); + addType(); + name+=yytext; + } +<Body>[a-z_A-Z~]([a-z_A-Z0-9]*[ \t\n]*"::")+[ \t\n]*[~a-z_A-Z][a-z_A-Z0-9]*[ \t\n]* { + code->codify(yytext); + addType(); + name+=yytext; + } +<Body>([a-z_A-Z~][a-z_A-Z0-9:]*)/([ \t]*"(") { + addType(); + if (type.length()==0) + generateFunctionLink(*code,yytext); + else + code->codify(yytext); + bracketCount=1; + args.resize(0); + name+=yytext; + BEGIN( FuncCall ); + } +<FuncCall,Body,MemberCall>\" { + code->codify(yytext); + lastStringContext=YY_START; + BEGIN( SkipString ); + } +<SkipString>[^\"\\]* { + code->codify(yytext); + } +<SkipString>\" { + code->codify(yytext); + BEGIN( lastStringContext ); + } +<SkipString>\\\" { + code->codify(yytext); + } +<Body>":" { + code->codify(yytext); + name.resize(0);type.resize(0); + } +<Body>"'"."'" { + code->codify(yytext); + } +<Body>"."|"->" { + code->codify(yytext); + BEGIN( MemberCall ); + } +<MemberCall>([a-z_A-Z~][a-z_A-Z0-9]*)/([ \t\n]*"(") { + if (name.length()>0) + generateMemberLink(*code,name,yytext); + else + code->codify(yytext); + name.resize(0);type.resize(0); + bracketCount=0; + BEGIN(FuncCall); + } +<MemberCall>[^a-z_A-Z0-9(] { + code->codify(yytext); + type.resize(0); + name.resize(0); + BEGIN(Body); + } +<Body>[,=;\[] { + code->codify(yytext); + if (type.length()>0) + addVariable(); + name.resize(0); + if (*yytext!=',') type.resize(0); + args.resize(0); + } +<Body>[0-9]+ { + code->codify(yytext); + } +<MemberCall2,FuncCall>[a-z_A-Z][:a-z_A-Z0-9]* { + addParmType(); + parmName=yytext; + generateClassLink(*code,yytext); + } +<MemberCall2,FuncCall>, { + code->codify(yytext); + addParameter(); + parmType.resize(0);parmName.resize(0); + } +<MemberCall2,FuncCall>"(" { + code->codify(yytext); + bracketCount++; + } +<MemberCall2,FuncCall>")" { + code->codify(yytext); + if (--bracketCount<=0) + name.resize(0);args.resize(0); + parmType.resize(0);parmName.resize(0); + BEGIN( Body ); + } +<MemberCall2,FuncCall>")"[ \t\n]*";" { + code->codify(yytext); + bracketCount=0; + if (!inClass && type.length()>0) + addVariable(); + name.resize(0);type.resize(0); + parmType.resize(0);parmName.resize(0); + BEGIN( Body ); + } +<MemberCall2,FuncCall>")"[ \t\n]*"{" { + addParameter(); + parmType.resize(0);parmName.resize(0); + if (name.length()>0) setClassScope(name); + code->codify(yytext); + curlyCount++; + type.resize(0); name.resize(0); + BEGIN( Body ); + } +<MemberCall2,FuncCall>")"[ \t\n]*":" { + addParameter(); + parmType.resize(0);parmName.resize(0); + if (name.length()>0) setClassScope(name); + code->codify(yytext); + type.resize(0); name.resize(0); + BEGIN( SkipInits ); + } +<SkipInits>"{" { + code->codify(yytext); + curlyCount++; + BEGIN( Body ); + } +<SkipInits>{ID} { + generateClassLink(*code,yytext); + } +<FuncCall>([a-z_A-Z][a-z_A-Z0-9]*)/"(" { + generateFunctionLink(*code,yytext); + } +<FuncCall>([a-z_A-Z][a-z_A-Z0-9]*)/("."|"->") { + code->codify(yytext); + args=yytext; + BEGIN( MemberCall2 ); + } +<MemberCall2>([a-z_A-Z][a-z_A-Z0-9]*)/([ \t\n]*"(") { + if (args.length()>0) + generateMemberLink(*code,args,yytext); + else + code->codify(yytext); + args.resize(0); + BEGIN( FuncCall ); + } +<MemberCall2>([a-z_A-Z][a-z_A-Z0-9]*)/([ \t\n]*("."|"->")) { + code->codify(yytext); + args=yytext; + } +<SkipComment>"//" { + code->codify(yytext); + } +<SkipComment>[ \t]*"*/" { + code->codify(yytext); + BEGIN( lastCContext ) ; + } +<SkipCxxComment>.*\n { + code->codify(yytext); + yyLineNr++ ; + BEGIN( lastCContext ) ; + } +<SkipSpecialComment>"//" + /*! +<SkipSpecialComment>[ \t]*"* /"[ \t]* /"\n" { + BEGIN( lastDContext ) ; + } + */ +<SkipSpecialComment>[ \t]*"*/" { + BEGIN( lastDContext ) ; + } +<SkipSpecialComment>[ \t]*"*/"[ \t\n]*"\n"/"/*" { + //code->codify("\n"); + QString lineText=yytext; + yyLineNr+=lineText.contains('\n'); + BEGIN( lastDContext ) ; + } +<SkipSpecialComment>. +<SkipSpecialComment>\n { yyLineNr++; } +<SkipSpecialCxxComment>.*/\n { + yyLineNr++ ; + BEGIN( lastDContext ) ; + } +<SkipSpecialCxxComment>. +<SkipSpecialCxxComment>\n { yyLineNr++; } +<*>[ \t]*"/*!"|"/**" { + lastDContext = YY_START ; + BEGIN( SkipSpecialComment ); + } +<*>"/*" { + code->codify(yytext); + lastCContext = YY_START ; + BEGIN( SkipComment ) ; + } +<*>[ \t]*"//!" { + lastDContext = YY_START ; + BEGIN( SkipSpecialCxxComment ); + } +<*>"//" { + code->codify(yytext); + lastCContext = YY_START ; + BEGIN( SkipCxxComment ) ; + } +<*>. { + code->codify(yytext); + } +<*>\n { + code->codify(yytext); + } +<*>([ \t\n]*"\n"){2,} { // combine multiple blank lines + QString sepLine=yytext; + code->codify("\n\n"); + yyLineNr+=sepLine.contains('\n'); + } + +%% + +/*@ ---------------------------------------------------------------------------- + */ + +void initParseCodeContext() +{ + codeClassList.setAutoDelete(TRUE); + codeVarList.setAutoDelete(TRUE); + codeParmList.setAutoDelete(TRUE); + codeClassDict.clear(); + codeClassList.clear(); + codeVarList.clear(); + codeParmList.clear(); + ccd.bases.clear(); + anchorCount = 0; +} + +void parseCode(OutputList &ol,const char *className,const QString &s, + bool e, const char *exName) +{ + code = new OutputList(&ol); + if (s.length()==0) return; + inputString = s; + inputPosition = 0; + yyLineNr = 0; + curlyCount = 0; + bracketCount = 0; + sharpCount = 0; + classScope = className; + exampleBlock = e; + exampleName = exName; + exampleFile = convertSlashes(exampleName,TRUE)+"-example"; + type.resize(0); + name.resize(0); + args.resize(0); + parmName.resize(0); + parmType.resize(0); + codeYYrestart( codeYYin ); + BEGIN( Body ); + codeYYlex(); + ol+=*code; + delete code; + return; +} + +extern "C" { // some bogus code to keep the compiler happy + int codeYYwrap() { return 1 ; } + void codeYYdummy() { yy_flex_realloc(0,0); } +} diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..6269e85 --- /dev/null +++ b/src/config.h @@ -0,0 +1,80 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef CONFIG_H +#define CONFIG_H + +#include <qstring.h> +#include <qstrlist.h> +#include <qfile.h> + +extern void parseConfig(const QString &config); +extern void writeTemplateConfig(QFile *f,bool shortList); + +extern QString projectName; // the name of the project +extern QString projectNumber; // the number of the project +extern QString htmlOutputDir; // the directory to put the HTML files +extern QString latexOutputDir; // the directory to put the Latex files +extern QString manOutputDir; // the directory to put the man pages +extern QString headerFile; // the name of the personal HTML header +extern QString footerFile; // the name of the personal HTML footer +extern QString cgiName; // the name of the CGI binary +extern QString cgiURL; // the absolute URL to the CGI binary +extern QString docURL; // the absolute URL to the documentation +extern QString binAbsPath; // the absolute path to the doxysearch +extern QString docAbsPath; // the absolute path to the documentation +extern QString perlPath; // the absolute path to perl +extern QString genTagFile; // the tag file to generate +extern QString inputFilter; // a filter command that is applied to input files +extern QString paperType; // the page type to generate docs for +extern QString stripFromPath; // the string to strip from the file path +extern QStrList includePath; // list of include paths +extern QStrList examplePath; // list of example paths +extern QStrList inputSources; // list of input files +extern QStrList excludeSources; // list of files to exclude from the input +extern QStrList filePatternList; // list of file patterns +extern QStrList excludePatternList; // list of patterns to exclude from input +extern QStrList tagFileList; // list of tag files +extern QStrList extDocPathList; // list of external doc. directories. +extern QStrList predefined; // list of predefined macro names. +extern QStrList extraPackageList; // list of extra LaTeX packages. +extern bool quietFlag; // generate progress messages flag +extern bool warningFlag; // generate warnings flag +extern bool recursiveFlag; // scan directories recursively +extern bool allExtFlag; // include all external classes flag +extern bool searchEngineFlag; // generate search engine flag +extern bool extractAllFlag; // gererate docs for all classes flag +extern bool extractPrivateFlag; // generate docs for private members flag +extern bool noIndexFlag; // generate condensed index flag +extern bool generateHtml; // generate HTML output +extern bool generateLatex; // generate Latex output +extern bool generateMan; // generate Man pages +extern bool preprocessingFlag; // enable preprocessing +extern bool briefMemDescFlag; // enable `inline' brief member descr. +extern bool hideMemberFlag; // hide undocumented members. +extern bool hideClassFlag; // hide undocumented members. +extern bool searchIncludeFlag; // search for included files +extern bool macroExpansionFlag; // expand macros in the source. +extern bool onlyPredefinedFlag; // expand only predefined macros +extern bool fullPathNameFlag; // using full path name in output +extern bool classDiagramFlag; // enable the generation of class diagrams. +extern bool compactLatexFlag; // generate compact LaTeX documentation. +extern bool repeatBriefFlag; // repeat brief descriptions. +extern bool internalDocsFlag; // determines what happens to internal docs. +extern bool caseSensitiveNames; // determines if output can be mixed case. +extern bool verbatimHeaderFlag; // enable/disable generation of verb headers. + +#endif diff --git a/src/config.l b/src/config.l new file mode 100644 index 0000000..232f531 --- /dev/null +++ b/src/config.l @@ -0,0 +1,1112 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +%{ + +/* + * includes + */ +#include <stdio.h> +#include <iostream.h> +#include <assert.h> +#include <ctype.h> + +#include <qstring.h> +#include <qfileinf.h> +#include <qdir.h> +#include <qtstream.h> + +#include "doxygen.h" +#include "config.h" +#include "message.h" +#include "pre.h" +#include "version.h" +#include "language.h" + +#define YY_NEVER_INTERACTIVE 1 + +/* ----------------------------------------------------------------- + * + * exported variables + */ + +QString projectName; +QString projectNumber; +QString outputDir; +QString htmlOutputDir; +QString latexOutputDir; +QString manOutputDir; +QString headerFile; +QString footerFile; +QString cgiName; +QString cgiURL; +QString docURL; +QString binAbsPath; +QString docAbsPath; +QString perlPath; +QString genTagFile; +QString inputFilter; +QString paperType; +QString outputLanguage; +QString stripFromPath; +QStrList includePath; +QStrList examplePath; +QStrList inputSources; +QStrList excludeSources; +QStrList filePatternList; +QStrList excludePatternList; +QStrList tagFileList; +QStrList extDocPathList; +QStrList predefined; +QStrList extraPackageList; +bool quietFlag = FALSE; +bool warningFlag = FALSE; +bool recursiveFlag = FALSE; +bool allExtFlag = FALSE; +bool searchEngineFlag = FALSE; +bool extractAllFlag = FALSE; +bool extractPrivateFlag = FALSE; +bool noIndexFlag = FALSE; +bool hideMemberFlag = FALSE; +bool hideClassFlag = FALSE; +bool macroExpansionFlag = FALSE; +bool onlyPredefinedFlag = FALSE; +bool fullPathNameFlag = FALSE; +bool compactLatexFlag = FALSE; +bool internalDocsFlag = FALSE; +bool caseSensitiveNames = FALSE; +bool generateHtml = TRUE; +bool generateLatex = TRUE; +bool generateMan = TRUE; +bool preprocessingFlag = TRUE; +bool briefMemDescFlag = TRUE; +bool searchIncludeFlag = TRUE; +bool classDiagramFlag = TRUE; +bool repeatBriefFlag = TRUE; +bool verbatimHeaderFlag = TRUE; + +/* ----------------------------------------------------------------- + * + * static variables + */ + +static const char * inputString; +static int inputPosition; +static int yyLineNr; +static QString tmpString; +static QString * s=0; +static bool * b=0; +static QStrList * l=0; +static int lastState; +static int lastEnvState; +static QString elemStr; + +/* ----------------------------------------------------------------- + */ +#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; +} + +%} + +%x Start +%x SkipComment +%x GetString +%x GetBool +%x GetStrList +%x GetQuotedString +%x GetEnvVar + +%% + +<*>\0x0d +<Start,GetString,GetStrList,GetBool>"#" { BEGIN(SkipComment); } +<Start>"PROJECT_NAME"[ \t]*"=" { BEGIN(GetString); s=&projectName; } +<Start>"PROJECT_NUMBER"[ \t]*"=" { BEGIN(GetString); s=&projectNumber; } +<Start>"OUTPUT_DIRECTORY"[ \t]*"=" { BEGIN(GetString); s=&outputDir; } +<Start>"HTML_OUTPUT"[ \t]*"=" { BEGIN(GetString); s=&htmlOutputDir; } +<Start>"MAN_OUTPUT"[ \t]*"=" { BEGIN(GetString); s=&manOutputDir; } +<Start>"LATEX_OUTPUT"[ \t]*"=" { BEGIN(GetString); s=&latexOutputDir; } +<Start>"HTML_HEADER"[ \t]*"=" { BEGIN(GetString); s=&headerFile; } +<Start>"HTML_FOOTER"[ \t]*"=" { BEGIN(GetString); s=&footerFile; } +<Start>"CGI_NAME"[ \t]*"=" { BEGIN(GetString); s=&cgiName; } +<Start>"CGI_URL"[ \t]*"=" { BEGIN(GetString); s=&cgiURL; } +<Start>"DOC_URL"[ \t]*"=" { BEGIN(GetString); s=&docURL; } +<Start>"BIN_ABSPATH"[ \t]*"=" { BEGIN(GetString); s=&binAbsPath; } +<Start>"DOC_ABSPATH"[ \t]*"=" { BEGIN(GetString); s=&docAbsPath; } +<Start>"PERL_PATH"[ \t]*"=" { BEGIN(GetString); s=&perlPath; } +<Start>"GENERATE_TAGFILE"[ \t]*"=" { BEGIN(GetString); s=&genTagFile; } +<Start>"INPUT_FILTER"[ \t]*"=" { BEGIN(GetString); s=&inputFilter; } +<Start>"PAPER_TYPE"[ \t]*"=" { BEGIN(GetString); s=&paperType; } +<Start>"OUTPUT_LANGUAGE"[ \t]*"=" { BEGIN(GetString); s=&outputLanguage; } +<Start>"STRIP_FROM_PATH"[ \t]*"=" { BEGIN(GetString); s=&stripFromPath; } +<Start>"INCLUDE_PATH"[ \t]*"=" { BEGIN(GetStrList); l=&includePath; elemStr=""; } +<Start>"EXAMPLE_PATH"[ \t]*"=" { BEGIN(GetStrList); l=&examplePath; elemStr=""; } +<Start>"INPUT"[ \t]*"=" { BEGIN(GetStrList); l=&inputSources; elemStr=""; } +<Start>"EXCLUDE"[ \t]*"=" { BEGIN(GetStrList); l=&excludeSources; elemStr=""; } +<Start>"FILE_PATTERNS"[ \t]*"=" { BEGIN(GetStrList); l=&filePatternList; elemStr=""; } +<Start>"EXCLUDE_PATTERNS"[ \t]*"=" { BEGIN(GetStrList); l=&excludePatternList; elemStr=""; } +<Start>"TAGFILES"[ \t]*"=" { BEGIN(GetStrList); l=&tagFileList; elemStr=""; } +<Start>"EXT_DOC_PATHS"[ \t]*"=" { BEGIN(GetStrList); l=&extDocPathList; elemStr=""; } +<Start>"PREDEFINED"[ \t]*"=" { BEGIN(GetStrList); l=&predefined; elemStr=""; } +<Start>"EXTRA_PACKAGES"[ \t]*"=" { BEGIN(GetStrList); l=&extraPackageList; elemStr=""; } +<Start>"QUIET"[ \t]*"=" { BEGIN(GetBool); b=&quietFlag; } +<Start>"WARNINGS"[ \t]*"=" { BEGIN(GetBool); b=&warningFlag; } +<Start>"RECURSIVE"[ \t]*"=" { BEGIN(GetBool); b=&recursiveFlag; } +<Start>"ALLEXTERNALS"[ \t]*"=" { BEGIN(GetBool); b=&allExtFlag; } +<Start>"SEARCHENGINE"[ \t]*"=" { BEGIN(GetBool); b=&searchEngineFlag; } +<Start>"EXTRACT_ALL"[ \t]*"=" { BEGIN(GetBool); b=&extractAllFlag; } +<Start>"EXTRACT_PRIVATE"[ \t]*"=" { BEGIN(GetBool); b=&extractPrivateFlag; } +<Start>"DISABLE_INDEX"[ \t]*"=" { BEGIN(GetBool); b=&noIndexFlag; } +<Start>"GENERATE_LATEX"[ \t]*"=" { BEGIN(GetBool); b=&generateLatex; } +<Start>"GENERATE_HTML"[ \t]*"=" { BEGIN(GetBool); b=&generateHtml; } +<Start>"GENERATE_MAN"[ \t]*"=" { BEGIN(GetBool); b=&generateMan; } +<Start>"ENABLE_PREPROCESSING"[ \t]*"=" { BEGIN(GetBool); b=&preprocessingFlag; } +<Start>"MACRO_EXPANSION"[ \t]*"=" { BEGIN(GetBool); b=¯oExpansionFlag; } +<Start>"SEARCH_INCLUDES"[ \t]*"=" { BEGIN(GetBool); b=&searchIncludeFlag; } +<Start>"BRIEF_MEMBER_DESC"[ \t]*"=" { BEGIN(GetBool); b=&briefMemDescFlag; } +<Start>"HIDE_UNDOC_MEMBERS"[ \t]*"=" { BEGIN(GetBool); b=&hideMemberFlag; } +<Start>"HIDE_UNDOC_CLASSES"[ \t]*"=" { BEGIN(GetBool); b=&hideClassFlag; } +<Start>"EXPAND_ONLY_PREDEF"[ \t]*"=" { BEGIN(GetBool); b=&onlyPredefinedFlag; } +<Start>"FULL_PATH_NAMES"[ \t]*"=" { BEGIN(GetBool); b=&fullPathNameFlag; } +<Start>"CLASS_DIAGRAMS"[ \t]*"=" { BEGIN(GetBool); b=&classDiagramFlag; } +<Start>"COMPACT_LATEX"[ \t]*"=" { BEGIN(GetBool); b=&compactLatexFlag; } +<Start>"REPEAT_BRIEF"[ \t]*"=" { BEGIN(GetBool); b=&repeatBriefFlag; } +<Start>"INTERNAL_DOCS"[ \t]*"=" { BEGIN(GetBool); b=&internalDocsFlag; } +<Start>"CASE_SENSE_NAMES"[ \t]*"=" { BEGIN(GetBool); b=&caseSensitiveNames; } +<Start>"VERBATIM_HEADERS"[ \t]*"=" { BEGIN(GetBool); b=&verbatimHeaderFlag; } +<Start>[a-z_A-Z0-9]+ { err("Warning: ignoring unknown tag `%s' at line %d\n",yytext,yyLineNr); } +<GetString,GetBool>\n { yyLineNr++; BEGIN(Start); } +<GetStrList>\n { + yyLineNr++; + if (elemStr.length()>0) + { + //printf("elemStr1=`%s'\n",elemStr.data()); + l->append(elemStr); + } + BEGIN(Start); + } +<GetStrList>[ \t]+ { + if (elemStr.length()>0) + { + //printf("elemStr2=`%s'\n",elemStr.data()); + l->append(elemStr); + } + elemStr.resize(0); + } +<GetString>[^ \"\$\t\r\n]+ { (*s)+=yytext; } +<GetString,GetStrList>"\"" { lastState=YY_START; + BEGIN(GetQuotedString); + tmpString.resize(0); + } +<GetString,GetStrList,GetQuotedString>"\$\(" { + //printf(">> Enter env\n"); + lastEnvState=YY_START; + BEGIN(GetEnvVar); + } +<GetEnvVar>[a-z_A-Z0-9]+")" { + yytext[yyleng-1]='\0'; + const char *env=getenv(yytext); + int i; + int l=strlen(env); + //printf("env name=`%s' text=`%s'\n",yytext,env); + for (i=l-1;i>=0;i--) unput(env[i]); + BEGIN(lastEnvState); + } +<GetQuotedString>"\""|"\n" { + //printf("Quoted String = `%s'\n",tmpString.data()); + if (lastState==GetString) + (*s)+=tmpString; + else + elemStr+=tmpString; + if (*yytext=='\n') + { + err("Warning: Missing end quote (\") on line %d\n",yyLineNr); + yyLineNr++; + } + BEGIN(lastState); + } +<GetQuotedString>"\\\"" { + tmpString+='"'; + } +<GetQuotedString>. { tmpString+=*yytext; } +<GetBool>[a-zA-Z]+ { + QString bs=yytext; + bs=bs.upper(); + if (bs=="YES") + *b=TRUE; + else if (bs=="NO") + *b=FALSE; + else + { + *b=FALSE; + warn("Warning: Invalid value `%s' for " + "boolean tag in line %d; use YES or NO\n", + bs.data(),yyLineNr); + } + } + /* +<GetStrList>[a-z_A-Z.*:?~0-9/\\\-]+ { + elemStr+=yytext; + } + */ +<GetStrList>[^ \#\"\$\t\r\n]+ { + elemStr+=yytext; + } +<SkipComment>\n { yyLineNr++; BEGIN(Start); } +<SkipComment>\\[ \r\t]*\n { yyLineNr++; BEGIN(Start); } +<*>\\[ \r\t]*\n { yyLineNr++; } +<*>. +<*>\n { yyLineNr++ ; } + +%% + +/*@ ---------------------------------------------------------------------------- + */ + + +void dumpConfig() +{ + printf("projectName=`%s'\n",projectName.data()); + printf("outputDir=`%s'\n", outputDir.data()); + printf("headerFile=`%s'\n", headerFile.data()); + printf("footerFile=`%s'\n", footerFile.data()); + char *ip=includePath.first(); + while (ip) + { + printf("includePath=`%s'\n",ip); + ip=includePath.next(); + } + printf("quiet=`%d'\n", quietFlag); + printf("warnings=`%d'\n", warningFlag); + char *is=inputSources.first(); + while (is) + { + printf("inputSources=`%s'\n",is); + is=inputSources.next(); + } + char *fp=filePatternList.first(); + while (fp) + { + printf("filePattern=`%s'\n",fp); + fp=filePatternList.next(); + } + printf("recusive=`%d'\n",recursiveFlag); + printf("inputFilter=`%s'\n",inputFilter.data()); + char *tf=tagFileList.first(); + while (tf) + { + printf("tagFile=`%s'\n",tf); + tf=tagFileList.next(); + } + printf("allExternals=`%d'\n",allExtFlag); + printf("searchEngine=`%d'\n",searchEngineFlag); + printf("cgiName=`%s'\n",cgiName.data()); + printf("cgiURL=`%s'\n",cgiURL.data()); + printf("docURL=`%s'\n",docURL.data()); + printf("binAbsPath=`%s'\n",binAbsPath.data()); + char *ed=extDocPathList.first(); + while (ed) + { + printf("binAbsPathFile=`%s'\n",ed); + ed=extDocPathList.next(); + } +} + +void writeTemplateConfig(QFile *f,bool sl) +{ + QTextStream t(f); + t << "# Doxyfile " << versionString << endl; + if (!sl) + { + t << "# This file describes the settings to be used by doxygen for a project\n"; + t << "#\n"; + t << "# All text after a hash (#) is considered a comment and will be ignored\n"; + t << "# The format is:\n"; + t << "# TAG = value [value, ...]\n"; + t << "# Values that contain spaces should be placed between quotes (\" \")\n"; + t << "\n"; + t << "#---------------------------------------------------------------------------\n"; + t << "# General configuration options\n"; + t << "#---------------------------------------------------------------------------\n"; + t << "\n"; + t << "# The PROJECT_NAME tag is a single word (or a sequence of word surrounded\n"; + t << "# by quotes) that should identify the project. \n"; + t << "\n"; + } + t << "PROJECT_NAME =\n"; + if (!sl) + { + t << "\n"; + t << "# The PROJECT_NUMBER tag can be used to enter a project or revision number.\n" ; + t << "# This could be handy for archiving the generated documentation or \n"; + t << "# if some version control system is used.\n"; + t << "\n"; + } + t << "PROJECT_NUMBER =\n"; + if (!sl) + { + t << "\n"; + t << "# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) \n"; + t << "# base path where the generated documentation will be put. \n"; + t << "# If a relative path is entered, it will be relative to the location \n"; + t << "# where doxygen was started. If left blank the current directory will be used.\n"; + t << "\n"; + } + t << "OUTPUT_DIRECTORY =\n"; + if (!sl) + { + t << "\n"; + t << "# The OUTPUT_LANGUAGE tag is used to specify the language in which all\n"; + t << "# documentation generated by doxygen is written. Doxygen will use this\n"; + t << "# information to generate all constant output in the proper language.\n"; + t << "# The default language is English, other supported languages are: Dutch\n"; + t << "\n"; + } + t << "OUTPUT_LANGUAGE = English\n"; + if (!sl) + { + t << "\n"; + t << "# The QUIET tag can be used to turn on/off the messages that are generated\n"; + t << "# by doxygen. Possible values are YES and NO. If left blank NO is used.\n"; + t << "\n"; + } + t << "QUIET = NO\n"; + if (!sl) + { + t << "\n"; + t << "# The WARNINGS tag can be used to turn on/off the warning messages that are\n"; + t << "# generated by doxygen. Possible values are YES and NO. If left blank\n"; + t << "# NO is used.\n"; + t << "\n"; + } + t << "WARNINGS = YES\n"; + if (!sl) + { + t << "\n"; + t << "# The DISABLE_INDEX tag can be used to turn on/off the condensed index at\n"; + t << "# top of each HTML page. The value NO (the default) enables the index and\n"; + t << "# the value YES disables it.\n"; + t << "\n"; + } + t << "DISABLE_INDEX = NO\n"; + if (!sl) + { + t << "\n"; + t << "# If the EXTRACT_ALL tag is set to YES all classes and functions will be\n"; + t << "# included in the documentation, even if no documentation was available.\n"; + t << "\n"; + } + t << "EXTRACT_ALL = NO\n"; + if (!sl) + { + t << "\n"; + t << "# If the EXTRACT_PRIVATE tag is set to YES all private members of a class\n"; + t << "# will be included in the documentation.\n"; + t << "\n"; + } + t << "EXTRACT_PRIVATE = NO\n"; + if (!sl) + { + t << "\n"; + t << "# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all\n"; + t << "# undocumented members inside documented classes or files.\n"; + t << "\n"; + } + t << "HIDE_UNDOC_MEMBERS = NO\n"; + if (!sl) + { + t << "\n"; + t << "# If the HIDE_UNDOC_CLASSESS tag is set to YES, Doxygen will hide all\n"; + t << "# undocumented classes.\n"; + t << "\n"; + } + t << "HIDE_UNDOC_CLASSES = NO\n"; + if (!sl) + { + t << "\n"; + t << "# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will\n"; + t << "# include brief member descriptions after the members that are listed in \n"; + t << "# the file and class documentation (similar to JavaDoc).\n"; + t << "# Set to NO to disable this.\n"; + t << "\n"; + } + t << "BRIEF_MEMBER_DESC = YES\n"; + if (!sl) + { + t << "\n"; + t << "# The INTERNAL_DOCS tag determines if documentation\n"; + t << "# that is typed after a \\internal command is included. If the tag is set \n"; + t << "# to NO (the default) then the documentation will be excluded.\n"; + t << "# Set it to YES to include the internal documentation.\n"; + t << "\n"; + } + t << "INTERNAL_DOCS = NO\n"; + if (!sl) + { + t << "\n"; + t << "# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend\n"; + t << "# the brief description of a member or function before the detailed description.\n"; + t << "# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the \n"; + t << "# brief descriptions will be completely suppressed.\n"; + t << "\n"; + } + t << "REPEAT_BRIEF = YES\n"; + if (!sl) + { + t << "\n"; + t << "# If the FULL_PATH_NAMES tag is set to YES Doxygen will prepend the full\n"; + t << "# path before files name in the file list and in the header files. If set\n" ; + t << "# to NO the shortest path that makes the file name unique will be used.\n"; + t << "\n"; + } + t << "FULL_PATH_NAMES = NO\n"; + if (!sl) + { + t << "\n"; + t << "# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag\n"; + t << "# can be used to strip a user defined part of the path. Stripping is\n" ; + t << "# only done if the specified string matches the left-hand part of the path.\n"; + t << "\n"; + } + t << "STRIP_FROM_PATH =\n"; + if (!sl) + { + t << "\n"; + t << "# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will\n"; + t << "# generate a class diagram (in Html and LaTeX) for classes with base or\n"; + t << "# super classes. Setting the tag to NO turns the diagrams off.\n"; + t << "\n"; + } + t << "CLASS_DIAGRAMS = YES\n"; + if (!sl) + { + t << "\n"; + t << "# If the CASE_SENSE_NAMES tag is set to NO (the default) then Doxygen\n"; + t << "# will only generate file names in lower case letters. If set to\n"; + t << "# YES upper case letters are also allowed. This is useful if you have\n"; + t << "# classes or files whose names only differ in case and if your file system\n"; + t << "# supports case sensitive file names.\n"; + t << "\n"; + } + t << "CASE_SENSE_NAMES = NO\n"; + if (!sl) + { + t << "\n"; + t << "# If the VERBATIM_HEADERS tag is set the YES (the default) then Doxygen\n"; + t << "# will generate a verbatim copy of the header file for each class for\n"; + t << "# which an include is specified. Set to NO to disable this.\n"; + t << "\n"; + } + t << "VERBATIM_HEADERS = YES\n"; + if (!sl) + { + t << "\n"; + t << "#---------------------------------------------------------------------------\n"; + t << "# configuration options related to the input files\n"; + t << "#---------------------------------------------------------------------------\n"; + t << "\n"; + t << "# The INPUT tag can be used to specify the files and/or directories that contain \n"; + t << "# documented source files. You may enter file names like \"myfile.cpp\" or \n"; + t << "# directories like \"/usr/src/myproject\". Separate the files or directories \n"; + t << "# with spaces.\n"; + t << "\n"; + } + t << "INPUT =\n"; + if (!sl) + { + t << "\n"; + t << "# If the value of the INPUT tag contains directories, you can use the \n"; + t << "# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \n"; + t << "# and *.h) to filter out the source-files in the directories. If left \n"; + t << "# blank all files are included.\n"; + t << "\n"; + } + t << "FILE_PATTERNS =\n"; + if (!sl) + { + t << "\n"; + t << "# The RECURSIVE tag can be used to turn specify whether or not subdirectories\n"; + t << "# should be searched for input files as well. Possible values are YES and NO.\n"; + t << "# If left blank NO is used.\n"; + t << "\n"; + } + t << "RECURSIVE = NO\n"; + if (!sl) + { + t << "\n"; + t << "# The EXCLUDE tag can be used to specify files and/or directories that should\n"; + t << "# excluded from the INPUT source files. This way you can easily exclude a \n"; + t << "# subdirectory from a directory tree whose root is specified with the INPUT tag.\n"; + t << "\n"; + } + t << "EXCLUDE =\n"; + if (!sl) + { + t << "\n"; + t << "# If the value of the INPUT tag contains directories, you can use the\n"; + t << "# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude\n"; + t << "# certain files from those directories.\n"; + t << "\n"; + } + t << "EXCLUDE_PATTERNS =\n"; + if (!sl) + { + t << "\n"; + t << "# The EXAMPLE_PATH tag can be used to specify one or more files or \n"; + t << "# directories that contain example code fragments that are included (see \n"; + t << "# the \\include command).\n"; + t << "\n"; + } + t << "EXAMPLE_PATH =\n"; + if (!sl) + { + t << "\n"; + t << "# The INPUT_FILTER tag can be used to specify a program that doxygen should\n"; + t << "# invoke to filter for each input file. Doxygen will invoke the filter program \n"; + t << "# by executing (via popen()) the command <filter> <input-file>, where <filter>\n"; + t << "# is the value of the INPUT_FILTER tag, and <input-file> is the name of an\n"; + t << "# input file. Doxygen will then use the output that the filter program writes\n"; + t << "# to standard output.\n"; + t << "\n"; + } + t << "INPUT_FILTER =\n"; + if (!sl) + { + t << "\n"; + t << "#---------------------------------------------------------------------------\n"; + t << "# configuration options related to the HTML output\n"; + t << "#---------------------------------------------------------------------------\n"; + t << "\n"; + t << "# If the GENERATE_HTML tag is set to YES (the default) Doxygen will\n"; + t << "# generate HTML output\n"; + t << "\n"; + } + t << "GENERATE_HTML = YES\n"; + if (!sl) + { + t << "\n"; + t << "# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.\n"; + t << "# If a relative path is entered the value of OUTPUT_DIRECTORY will be\n"; + t << "# put in front of it. If left blank `html' will be used as the default path.\n"; + t << "\n"; + } + t << "HTML_OUTPUT =\n"; + if (!sl) + { + t << "\n"; + t << "# The HTML_HEADER tag can be used to specify a personal HTML header for \n"; + t << "# each generated HTML page. If it is left blank doxygen will generate a \n"; + t << "# standard header.\n"; + t << "\n"; + } + t << "HTML_HEADER =\n"; + if (!sl) + { + t << "\n"; + t << "# The HTML_FOOTER tag can be used to specify a personal HTML footer for \n"; + t << "# each generated HTML page. If it is left blank doxygen will generate a \n"; + t << "# standard footer.\n"; + t << "\n"; + } + t << "HTML_FOOTER =\n"; + if (!sl) + { + t << "\n"; + t << "#---------------------------------------------------------------------------\n"; + t << "# configuration options related to the LaTeX output\n"; + t << "#---------------------------------------------------------------------------\n"; + t << "\n"; + t << "# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will\n"; + t << "# generate Latex output.\n"; + t << "\n"; + } + t << "GENERATE_LATEX = YES\n"; + if (!sl) + { + t << "\n"; + t << "# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.\n"; + t << "# If a relative path is entered the value of OUTPUT_DIRECTORY will be\n"; + t << "# put in front of it. If left blank `latex' will be used as the default path.\n"; + t << "\n"; + } + t << "LATEX_OUTPUT =\n"; + if (!sl) + { + t << "\n"; + t << "# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact\n"; + t << "# LaTeX documents. This may be useful for small projects and may help to\n"; + t << "# save some trees in general.\n"; + t << "\n"; + } + t << "COMPACT_LATEX = NO\n"; + if (!sl) + { + t << "\n"; + t << "# The PAPER_TYPE tag can be used to set the paper type that is used\n"; + t << "# by the printer. Possible values are: a4, a4wide, letter, legal and \n"; + t << "# executive. If left blank a4wide will be used.\n"; + t << "\n"; + } + t << "PAPER_TYPE = a4wide\n"; + if (!sl) + { + t << "\n"; + t << "# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX\n"; + t << "# packages that should be included in the LaTeX output.\n"; + t << "\n"; + } + t << "EXTRA_PACKAGES =\n"; + if (!sl) + { + t << "\n"; + t << "#---------------------------------------------------------------------------\n"; + t << "# configuration options related to the man page output\n"; + t << "#---------------------------------------------------------------------------\n"; + t << "\n"; + t << "# If the GENERATE_MAN tag is set to YES (the default) Doxygen will\n"; + t << "# generate man pages\n"; + t << "\n"; + } + t << "GENERATE_MAN = YES\n"; + if (!sl) + { + t << "\n"; + t << "# The MAN_OUTPUT tag is used to specify where the man pages will be put.\n"; + t << "# If a relative path is entered the value of OUTPUT_DIRECTORY will be\n"; + t << "# put in front of it. If left blank `man' will be used as the default path.\n"; + t << "\n"; + } + t << "MAN_OUTPUT =\n"; + if (!sl) + { + t << "\n"; + t << "#---------------------------------------------------------------------------\n"; + t << "# Configuration options related to the preprocessor \n"; + t << "#---------------------------------------------------------------------------\n"; + t << "\n"; + t << "# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will\n"; + t << "# evaluate all C-preprocessor directives found in the sources and include\n"; + t << "# files.\n"; + t << "\n"; + } + t << "ENABLE_PREPROCESSING = YES\n"; + if (!sl) + { + t << "\n"; + t << "# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro\n"; + t << "# names in the source code. If set to NO (the default) only conditional \n"; + t << "# compilation will be performed.\n"; + t << "\n"; + } + t << "MACRO_EXPANSION = NO\n"; + if (!sl) + { + t << "\n"; + t << "# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files\n"; + t << "# in the INCLUDE_PATH (see below) will be search if a #include is found.\n"; + t << "\n"; + } + t << "SEARCH_INCLUDES = YES\n"; + if (!sl) + { + t << "\n"; + t << "# The INCLUDE_PATH tag can be used to specify one or more directories that\n"; + t << "# contain include files that are not input files but should be processed by\n"; + t << "# the preprocessor.\n" ; + t << "\n"; + } + t << "INCLUDE_PATH =\n"; + if (!sl) + { + t << "\n"; + t << "# The PREDEFINED tag can be used to specify one or more macro names that\n"; + t << "# are defined before the preprocessor is started (similar to the -D option of\n"; + t << "# gcc). The argument of the tag is a list of macros of the form: name\n"; + t << "# or name=definition (no spaces). If the definition and the = are \n"; + t << "# omitted =1 is assumed.\n"; + t << "\n"; + } + t << "PREDEFINED =\n"; + if (!sl) + { + t << "\n"; + t << "# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES\n"; + t << "# then the macro expansion is limited to the macros specified with the\n"; + t << "# PREDEFINED tag.\n"; + t << "\n"; + } + t << "EXPAND_ONLY_PREDEF = NO\n"; + if (!sl) + { + t << "\n"; + t << "#---------------------------------------------------------------------------\n"; + t << "# Configuration options related to external references \n"; + t << "#---------------------------------------------------------------------------\n"; + t << "\n"; + t << "# The TAGFILES tag can be used to specify one or more tagfiles. \n"; + t << "\n"; + } + t << "TAGFILES =\n"; + if (!sl) + { + t << "\n"; + t << "# When a file name is specified after GENERATE_TAGFILE, doxygen will create\n"; + t << "# a tag file that is based on the input files it reads.\n"; + t << "\n"; + } + t << "GENERATE_TAGFILE =\n"; + if (!sl) + { + t << "\n"; + t << "# If the ALLEXTERNALS tag is set to YES all external classes will be listed\n"; + t << "# in the class index. If set to NO only the inherited external classes\n"; + t << "# will be listed.\n"; + t << "\n"; + } + t << "ALLEXTERNALS = NO\n"; + if (!sl) + { + t << "\n"; + t << "# The PERL_PATH should be the absolute path and name of the perl script\n"; + t << "# interpreter (i.e. the result of `which perl').\n"; + t << "\n"; + } + t << "PERL_PATH = /usr/local/bin/perl\n"; + if (!sl) + { + t << "\n"; + t << "#---------------------------------------------------------------------------\n"; + t << "# Configuration options related to the search engine \n"; + t << "#---------------------------------------------------------------------------\n"; + t << "\n"; + t << "# The SEARCHENGINE tag specifies whether or not a search engine should be \n"; + t << "# used. If set to NO the values of all tags below this one will be ignored.\n"; + t << "\n"; + } + t << "SEARCHENGINE = NO\n"; + if (!sl) + { + t << "\n"; + t << "# The CGI_NAME tag should be the name of the CGI script that\n"; + t << "# starts the search engine (doxysearch) with the correct parameters.\n"; + t << "# A script with this name will be generated by doxygen.\n"; + t << "\n"; + } + t << "CGI_NAME = search.cgi\n"; + if (!sl) + { + t << "\n"; + t << "# The CGI_URL tag should be the absolute URL to the directory where the\n"; + t << "# cgi binaries are located. See the documentation of your http daemon for \n"; + t << "# details.\n"; + t << "\n"; + } + t << "CGI_URL =\n"; + if (!sl) + { + t << "\n"; + t << "# The DOC_URL tag should be the absolute URL to the directory where the\n"; + t << "# documentation is located. If left blank the absolute path to the \n"; + t << "# documentation, with file:// prepended to it, will be used.\n"; + t << "\n"; + } + t << "DOC_URL =\n"; + if (!sl) + { + t << "\n"; + t << "# The DOC_ABSPATH tag should be the absolute path to the directory where the\n"; + t << "# documentation is located. If left blank the directory on the local machine\n"; + t << "# will be used.\n"; + t << "\n"; + } + t << "DOC_ABSPATH =\n"; + if (!sl) + { + t << "\n"; + t << "# The BIN_ABSPATH tag must point to the directory where the doxysearch binary\n"; + t << "# is installed.\n"; + t << "\n"; + } + t << "BIN_ABSPATH = /usr/local/bin/\n"; + if (!sl) + { + t << "\n"; + t << "# The EXT_DOC_PATHS tag can be used to specify one or more paths to \n"; + t << "# documentation generated for other projects. This allows doxysearch to search\n"; + t << "# the documentation for these projects as well.\n"; + t << "\n"; + } + t << "EXT_DOC_PATHS =\n"; +} + +void checkConfig() +{ + //if (projectName.length()>0) + //{ + // projectName[0]=toupper(projectName[0]); + //} + + paperType = paperType.lower().stripWhiteSpace(); + if (paperType.isEmpty()) + { + paperType = "a4wide"; + } + if (paperType!="a4" && paperType!="a4wide" && paperType!="letter" && + paperType!="legal" && paperType!="executive") + { + err("Error: Unknown page type specified"); + } + + outputLanguage=outputLanguage.stripWhiteSpace(); + if (outputLanguage.isEmpty()) + { + setTranslator("English"); + } + else + { + if (!setTranslator(outputLanguage)) + { + err("Error: Output language %s not supported! Using english instead.\n", + outputLanguage.data()); + } + } + + // Test to see if output directory is valid + if (outputDir.isEmpty()) + outputDir=QDir::currentDirPath(); + else + { + QDir dir(outputDir); + if (!dir.exists()) + { + dir.setPath(QDir::currentDirPath()); + if (!dir.mkdir(outputDir)) + { + err("Error: tag OUTPUT_DIRECTORY: Output directory `%s' does not " + "exist and cannot be created\n",outputDir.data()); + exit(1); + } + else if (!quietFlag) + { + err("Notice: Output directory `%s' does not exist. " + "I have created it for you.\n", outputDir.data()); + } + dir.cd(outputDir); + } + outputDir=dir.absPath(); + } + + if (htmlOutputDir.isEmpty() && generateHtml) + { + htmlOutputDir=outputDir+"/html"; + } + else if (htmlOutputDir && htmlOutputDir[0]!='/') + { + htmlOutputDir.prepend(outputDir+'/'); + } + QDir htmlDir(htmlOutputDir); + if (!htmlDir.exists() && !htmlDir.mkdir(htmlOutputDir)) + { + err("Could not create output directory %s\n",htmlOutputDir.data()); + exit(1); + } + + if (latexOutputDir.isEmpty() && generateLatex) + { + latexOutputDir=outputDir+"/latex"; + } + else if (latexOutputDir && latexOutputDir[0]!='/') + { + latexOutputDir.prepend(outputDir+'/'); + } + QDir latexDir(latexOutputDir); + if (!latexDir.exists() && !latexDir.mkdir(latexOutputDir)) + { + err("Could not create output directory %s\n",latexOutputDir.data()); + exit(1); + } + + if (manOutputDir.isEmpty() && generateMan) + { + manOutputDir=outputDir+"/man"; + } + else if (manOutputDir && manOutputDir[0]!='/') + { + manOutputDir.prepend(outputDir+'/'); + } + QDir manDir(manOutputDir); + if (!manDir.exists() && !manDir.mkdir(manOutputDir)) + { + err("Could not create output directory %s\n",manOutputDir.data()); + exit(1); + } + + // Test to see if HTML header is valid + if (headerFile.length()>0) + { + QFileInfo fi(headerFile); + if (!fi.exists()) + { + err("Error: tag HTML_HEADER: header file `%s' " + "does not exist\n",headerFile.data()); + exit(1); + } + } + // Test to see if HTML footer is valid + if (footerFile.length()>0) + { + QFileInfo fi(footerFile); + if (!fi.exists()) + { + err("Error: tag HTML_FOOTER: footer file `%s' " + "does not exist\n",footerFile.data()); + exit(1); + } + } + // check include path + char *s=includePath.first(); + while (s) + { + QFileInfo fi(s); + if (!fi.exists()) err("Warning: tag INCLUDE_PATH: include path `%s' " + "does not exist\n",s); + addSearchDir(fi.absFilePath()); + s=includePath.next(); + } + // check input + if (inputSources.count()==0) + { + err("Error: tag INPUT: no input files specified after the INPUT tag.\n"); + exit(1); + } + else + { + s=inputSources.first(); + while (s) + { + QFileInfo fi(s); + if (!fi.exists()) + { + err("Error: tag INPUT: input source `%s' does not exist\n",s); + exit(1); + } + s=inputSources.next(); + } + } + // add default pattern if needed + if (filePatternList.count()==0) + { + filePatternList.append("*"); + } + + // more checks needed if and only if the search engine is enabled. + if (searchEngineFlag) + { + // check cgi name + if (cgiName.length()==0) + { + err("Error: tag CGI_NAME: no cgi script name after the CGI_NAME tag.\n"); + exit(1); + } + // check cgi URL + if (cgiURL.length()==0) + { + err("Error: tag CGI_URL: no URL to cgi directory specified.\n"); + exit(1); + } + else if (cgiURL.left(7)!="http://") + { + err("Error: tag CGI_URL: URL to cgi directory is invalid (must " + "start with http://).\n"); + exit(1); + } + // check documentation URL + if (docURL.length()==0) + { + docURL = outputDir.copy().prepend("file://").append("html"); + } + else if (docURL.left(7)!="http://" && docURL.left(7)!="file://") + { + err("Error: tag DOC_URL: URL to documentation is invalid or " + "not absolute.\n"); + exit(1); + } + // check absolute documentation path + if (docAbsPath.length()==0) + { + docAbsPath = outputDir+"/html"; + } + else if (docAbsPath && docAbsPath[0]!='/') + { + err("Error: tag DOC_ABSPATH: path is not absolute\n"); + exit(1); + } + // check path to doxysearch + if (binAbsPath.length()==0) + { + err("Error: tag BIN_ABSPATH: no absolute path to doxysearch " + "specified.\n"); + exit(1); + } + else + { + if (binAbsPath && binAbsPath[0]!='/') + { + err("Error: tag BIN_ABSPATH: path is not absolute " + "(must start with /).\n"); + exit(1); + } + } + // check perl path + if (perlPath.length()==0) + { + perlPath="/usr/local/bin/perl"; + } + QFileInfo fi(perlPath); + if (!fi.exists()) + { + err("Error: tag PERL_PATH: perl interpreter not found at `%s'\n", + perlPath.data()); + exit(1); + } + } +} + +void parseConfig(const QString &s) +{ + inputString = s; + inputPosition = 0; + yyLineNr = 1; + configYYrestart( configYYin ); + BEGIN( Start ); + configYYlex(); + checkConfig(); +} + +extern "C" { // some bogus code to keep the compiler happy + int configYYwrap() { return 1 ; } +} diff --git a/src/constexp.h b/src/constexp.h new file mode 100644 index 0000000..9979bfd --- /dev/null +++ b/src/constexp.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef _CONSTEXP_H +#define _CONSTEXP_H + +#include <qstring.h> +#include "cppvalue.h" + +extern bool parseCppExpression(const QString &s); +extern int cppExpYYparse(); +extern int cppExpYYdebug; +extern QString strToken; +extern CPPValue resultValue; + +#endif diff --git a/src/constexp.l b/src/constexp.l new file mode 100644 index 0000000..f023507 --- /dev/null +++ b/src/constexp.l @@ -0,0 +1,110 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +%{ + +#include "constexp.h" +#include "cppvalue.h" +#include "ce_parse.h" // generated header file + +#define YY_NO_UNPUT +#define YY_NEVER_INTERACTIVE 1 + +QString strToken; + +static const char *inputString; +static int inputPosition; +CPPValue resultValue; + +#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; +} + +%} + +%% + +"?" { 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]+))))"'" { + strToken=yytext; + return TOK_CHARACTER; + } +0[0-7]*[uUlL]* { strToken=yytext; + return TOK_OCTALINT; + } +[1-9][0-9]*[uUlL]* { strToken=yytext; + return TOK_DECIMALINT; + } +(0x|0X)[0-9a-fA-F]+[uUlL]* { strToken=yytext; return TOK_HEXADECIMALINT; } +(([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+))([eE]([\-\+])?[0-9]+)?([fFlL])? { + strToken=yytext; return TOK_FLOAT; + } +([0-9]+[eE])([\-\+])?[0-9]+([fFlL])? { + strToken=yytext; return TOK_FLOAT; + } +. +\n + +%% + +bool parseCppExpression(const QString &s) +{ + //printf("Expression: `%s'\n",s.data()); + inputString = s; + inputPosition = 0; + cppExpYYrestart( cppExpYYin ); + cppExpYYparse(); + //printf("Result: %ld\n",(long)resultValue); + return (long)resultValue!=0; +} + +extern "C" { + int cppExpYYwrap() { return 1; } +} diff --git a/src/constexp.y b/src/constexp.y new file mode 100644 index 0000000..fa13d6e --- /dev/null +++ b/src/constexp.y @@ -0,0 +1,275 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +%{ + +#include "cppvalue.h" +#include "constexp.h" + +#if defined(_MSC_VER) +#define MSDOS +#endif + +#define YYSTYPE CPPValue + +#include <stdio.h> +#include <stdlib.h> + +int cppExpYYerror(const char *s) +{ + printf("ERROR: %s\n",s); + return 0; +} + +int cppExpYYlex(); + +%} + +%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 + { 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/cppvalue.cpp b/src/cppvalue.cpp new file mode 100644 index 0000000..ab2a1d4 --- /dev/null +++ b/src/cppvalue.cpp @@ -0,0 +1,85 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <stdlib.h> + +#include "cppvalue.h" +#include "constexp.h" + +CPPValue parseOctal() +{ + long val = 0; + for (const char *p = 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 = 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 = 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; + } + return CPPValue(val); +} + +CPPValue parseCharacter() // does not work for '\n' and the alike +{ + if (strToken[1]=='\\') + { + switch(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': return parseOctal(); + case 'x': + case 'X': return parseHexadecimal(); + default: printf("Invalid escape sequence %s found!\n",strToken.data()); + return CPPValue(0L); + } + } + return CPPValue((long)strToken[1]); +} + +CPPValue parseFloat() +{ + return CPPValue(atof(strToken)); +} diff --git a/src/cppvalue.h b/src/cppvalue.h new file mode 100644 index 0000000..d3751b2 --- /dev/null +++ b/src/cppvalue.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef _CPPVALUE_H +#define _CPPVALUE_H + +#include <stdio.h> +#include <qglobal.h> + +class CPPValue +{ + friend CPPValue parseOctal(); + friend CPPValue parseDecimal(); + friend CPPValue parseHexadecimal(); + friend CPPValue parseCharacter(); + friend CPPValue parseFloat(); + + 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; +}; + +#endif diff --git a/src/debug.cpp b/src/debug.cpp new file mode 100644 index 0000000..fc2731d --- /dev/null +++ b/src/debug.cpp @@ -0,0 +1,62 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include "debug.h" +#include <stdarg.h> +#include <stdio.h> +#include <qstring.h> + +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) +{ + QString label=l; + if (label=="FindMembers") + return Debug::FindMembers; + else if (label=="Functions") + return Debug::Functions; + else if (label=="Variables") + return Debug::Variables; + else + return 0; +} + +void Debug::setFlag(const char *lab) +{ + curMask = (DebugMask)(curMask | labelToEnumValue(lab)); +} + +void Debug::clearFlag(const char *lab) +{ + curMask = (DebugMask)(curMask & ~labelToEnumValue(lab)); +} + +void Debug::setPriority(int p) +{ + curPrio = p; +} diff --git a/src/debug.h b/src/debug.h new file mode 100644 index 0000000..b2b389f --- /dev/null +++ b/src/debug.h @@ -0,0 +1,39 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef _DEBUG_H +#define _DEBUG_H + +class Debug +{ + public: + enum DebugMask { Quiet = 0x00000000, + FindMembers = 0x00000001, + Functions = 0x00000002, + Variables = 0x00000004 + }; + static void print(DebugMask mask,int prio,const char *fmt,...); + static void setFlag(const char *label); + static void clearFlag(const char *label); + 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..4ec3ec5 --- /dev/null +++ b/src/declinfo.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef DECLINFO_H +#define DECLINFO_H + +#include <stdio.h> +#include <qstring.h> + +extern void parseFuncDecl(const QString &decl, + QString &clName, + QString &classTempList, + QString &type, + QString &name, + QString &args, + QString &funcTempList, + QString &exceptions + ); +#endif diff --git a/src/declinfo.l b/src/declinfo.l new file mode 100644 index 0000000..0f0505d --- /dev/null +++ b/src/declinfo.l @@ -0,0 +1,292 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +%{ + +/* + * includes + */ +#include <stdio.h> +#include <iostream.h> +#include <assert.h> +#include <ctype.h> + +#include "declinfo.h" +#include "util.h" + + +#define YY_NO_UNPUT + +/* ----------------------------------------------------------------- + * + * statics + */ + +static const char * inputString; +static int inputPosition; +static QString scope; +static QString className; +static QString classTempList; +static QString funcTempList; +static QString type; +static QString name; +static QString args; +static QString tmpType; +static int sharpCount; +static bool classTempListFound; +static bool funcTempListFound; +static QString exceptionString; + +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.isNull()) 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()) return; + if (!type.isNull()) 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][a-z_A-Z0-9]* + +%x Start +%x Template +%x ReadArgs +%x Operator +%x FuncPtr +%x EndTemplate +%x StripTempArgs +%x SkipSharp +%x ReadExceptions + +%% + +<Start>"operator" { // operator rule must be before {ID} rule + name += yytext; + BEGIN(Operator); + } +<Start>(~{B}*)?{ID} { + 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>[*&]+ { + addType(); + type+=yytext; + } +<Start>{B}+ { + addType(); + } +<Start>{B}*"("{B}*"*" { + addType(); + type+="(*"; + } +<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+="<"; + sharpCount++; + } +<Template>">" { + name+=">"; + if (sharpCount) + --sharpCount; + else + { + BEGIN(Start); + } + } +<Template>. { + name+=*yytext; + } +<Operator>{B}*"()"{B}*"<>"{B}*/"(" { + name+="() <>"; + BEGIN(ReadArgs); + } +<Operator>{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; + } +<*>. + +%% + +/*@ ---------------------------------------------------------------------------- + */ + +void parseFuncDecl(const QString &decl,QString &cl,QString &ctl,QString &t, + QString &n,QString &a,QString &ftl,QString &exc) +{ + inputString = decl; + //printf("Input=`%s'\n",inputString); + if (inputString==0) return; + inputPosition = 0; + classTempListFound = FALSE; + funcTempListFound = FALSE; + 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(); + + cl=scope.copy(); + int i; + if ((i=cl.find('<'))!=-1) // split up scope and template arguments + { + ctl=removeRedundantWhiteSpace(cl.right(cl.length()-i)); + cl=cl.left(i); + } + n=removeRedundantWhiteSpace(name); + if ((i=n.find('<'))!=-1 && n.left(8)!="operator") + { + ftl=removeRedundantWhiteSpace(n.right(n.length()-i)); + n=n.left(i); + } + + //ctl=classTempList.copy(); + //ftl=funcTempList.copy(); + t=removeRedundantWhiteSpace(type); + a=removeRedundantWhiteSpace(args); + exc=removeRedundantWhiteSpace(exceptionString); + + if (t.length()>0 && t.at(t.length()-1)==')') + { + 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()); + + 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) +{ + QString className; + QString classTNames; + QString type; + QString name; + QString args; + QString funcTNames; + printf("-----------------------------------------\n"); + parseFuncDecl(s,className,classTNames,type,name,args,funcTNames); + printf("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 diff --git a/src/defargs.h b/src/defargs.h new file mode 100644 index 0000000..d2cd8f2 --- /dev/null +++ b/src/defargs.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef DEFARGS_H +#define DEFARGS_H + +#include <stdio.h> +#include <qstring.h> + +class ArgumentList; + +extern void stringToArgumentList(const char *argsString,ArgumentList* &argList); + +#endif diff --git a/src/defargs.l b/src/defargs.l new file mode 100644 index 0000000..b7dfd57 --- /dev/null +++ b/src/defargs.l @@ -0,0 +1,298 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +%{ + +/* + * 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" + +#define YY_NO_UNPUT +#define YY_NEVER_INTERACTIVE 1 + +/* ----------------------------------------------------------------- + * + * statics + */ + +static const char *inputString; +static int inputPosition; +static ArgumentList *argList; +static QString *copyArgValue; +static QString curArgTypeName; +static QString curArgDefValue; +static QString curArgName; +static int argRoundCount; +static int argSharpCount; +static int argCurlyCount; +static int readArgContext; + + + +/* ----------------------------------------------------------------- + */ +#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][a-z_A-Z0-9]* + +%x Start +%x CopyArgString +%x CopyArgRound +%x CopyArgRound2 +%x CopyArgSharp +%x CopyArgCurly +%x ReadFuncArgType +%x ReadFuncArgDef +%x ReadFuncArgPtr +%x FuncQual + + +%% + +<Start>[<(] { BEGIN(ReadFuncArgType); } + +<ReadFuncArgType>{B}* { + curArgTypeName+=" "; + } +<ReadFuncArgDef>"'"\\[0-7]{1,3}"'" { curArgDefValue+=yytext; } +<ReadFuncArgDef>"'"\\."'" { curArgDefValue+=yytext; } +<ReadFuncArgDef>"'"."'" { curArgDefValue+=yytext; } +<ReadFuncArgDef>\" { + curArgDefValue+=*yytext; + BEGIN( CopyArgString ); + } +<ReadFuncArgType>"("([^:)]+{B}*"::")*{B}*[&*]+{B}*/{ID} { + // function pointer as argument + curArgTypeName+=yytext; + //curArgTypeName=curArgTypeName.simplifyWhiteSpace(); + BEGIN( ReadFuncArgPtr ); + } +<ReadFuncArgPtr>{ID} { + curArgName=yytext; + } +<ReadFuncArgPtr>")"{B}*"(" { + curArgTypeName+=yytext; + //curArgTypeName=curArgTypeName.simplifyWhiteSpace(); + readArgContext = ReadFuncArgType; + copyArgValue=&curArgTypeName; + argRoundCount=0; + BEGIN( CopyArgRound2 ); + } +<ReadFuncArgPtr>")" { // redundant braces detected / remove them + int i=curArgTypeName.findRev('('),l=curArgTypeName.length(); + if (i!=-1) + curArgTypeName=curArgTypeName.left(i)+ + curArgTypeName.right(l-i-1); + curArgTypeName+=curArgName; + BEGIN( ReadFuncArgType ); + } +<ReadFuncArgType,ReadFuncArgDef>[({<] { + if (YY_START==ReadFuncArgType) + { + curArgTypeName+=*yytext; + copyArgValue=&curArgTypeName; + } + else // YY_START==ReadFuncArgDef + { + curArgDefValue+=*yytext; + copyArgValue=&curArgDefValue; + } + readArgContext = YY_START; + if (*yytext=='(') + { + argRoundCount=0; + BEGIN( CopyArgRound ); + } + else if (*yytext=='{') + { + argCurlyCount=0; + BEGIN( CopyArgCurly ); + } + else // yytext=='<' + { + argSharpCount=0; + BEGIN( CopyArgSharp ); + } + } +<CopyArgRound,CopyArgRound2>"(" { + argRoundCount++; + *copyArgValue += *yytext; + } +<CopyArgRound,CopyArgRound2>")" { + *copyArgValue += *yytext; + if (argRoundCount>0) + { + argRoundCount--; + } + else + { + if (YY_START==CopyArgRound2) + { + *copyArgValue+=" "+curArgName; + } + BEGIN( readArgContext ); + } + } +<CopyArgSharp>"<" { + argSharpCount++; + *copyArgValue += *yytext; + } +<CopyArgSharp>">" { + *copyArgValue += *yytext; + if (argSharpCount>0) argSharpCount--; + else BEGIN( readArgContext ); + } +<CopyArgCurly>"{" { + argCurlyCount++; + *copyArgValue += *yytext; + } +<CopyArgSharp>"}" { + *copyArgValue += *yytext; + if (argCurlyCount>0) argCurlyCount--; + else BEGIN( readArgContext ); + } +<CopyArgString>\\. { + curArgDefValue+=yytext; + } +<CopyArgString>\" { + curArgDefValue+=*yytext; + BEGIN( ReadFuncArgDef ); + } +<ReadFuncArgType>"=" { + BEGIN( ReadFuncArgDef ); + } +<ReadFuncArgType,ReadFuncArgDef>[,)>] { + curArgTypeName=removeRedundantWhiteSpace( + curArgTypeName.simplifyWhiteSpace()); + curArgDefValue=curArgDefValue.stripWhiteSpace(); + int l=curArgTypeName.length(); + if (l>0) + { + int i=l-1; + while (i>=0 && + ( + isspace(curArgTypeName.at(i)) || + isId(curArgTypeName.at(i)) + ) + ) i--; + Argument *a = new Argument; + if (i>=0 && curArgTypeName.at(i)!=':') + { // type contains a name + a->type = curArgTypeName.left(i+1).stripWhiteSpace(); + a->name = curArgTypeName.right(curArgTypeName.length()-i-1); + } + else // assume only the type was specified, try to determine name later + { + a->type = curArgTypeName.stripWhiteSpace(); + } + a->defval = curArgDefValue.copy(); + //printf("----> Adding argument `%s' `%s' `%s'\n",a->type.data(),a->name.data(),a->defval.data()); + argList->append(a); + } + curArgTypeName.resize(0); + curArgDefValue.resize(0); + if (*yytext==')') + { + BEGIN(FuncQual); + //printf(">>> end of argument list\n"); + } + else + { + BEGIN( ReadFuncArgType ); + } + } +<ReadFuncArgType,ReadFuncArgPtr>{ID} { + QString name=yytext; //resolveDefines(yytext); + //printf("resolveName `%s'->`%s'\n",yytext,name.data()); + curArgTypeName+=name; + } +<ReadFuncArgType,ReadFuncArgPtr>. { + curArgTypeName+=*yytext; + } +<ReadFuncArgDef,CopyArgString>. { + curArgDefValue+=*yytext; + } +<CopyArgRound,CopyArgRound2,CopyArgSharp,CopyArgCurly>{ID} { + QString name=yytext; //resolveDefines(yytext); + *copyArgValue+=name; + } +<CopyArgRound,CopyArgRound2,CopyArgSharp,CopyArgCurly>. { + *copyArgValue += *yytext; + } +<FuncQual>"const" { + argList->constSpecifier=TRUE; + } +<FuncQual>"volatile" { + argList->volatileSpecifier=TRUE; + } +<FuncQual>"="{B}*"0" { + argList->pureSpecifier=TRUE; + } +<*>. + +%% + +/* ---------------------------------------------------------------------------- + */ + +// converts an argument string into a list of Arguments. +// an Argument consists of a type, an optional name, and an optional +// default initializer. + +void stringToArgumentList(const char *argsString,ArgumentList* &al) +{ + //if (al==0) al=new ArgumentList; // allocate new list if needed. + if (al==0) return; + if (!argsString) return; + inputString = argsString; + inputPosition = 0; + curArgTypeName.resize(0); + curArgDefValue.resize(0); + curArgName.resize(0); + argList = al; + defargsYYrestart( defargsYYin ); + BEGIN( Start ); + defargsYYlex(); +} + +extern "C" { // some bogus code to keep the compiler happy + int defargsYYwrap() { return 1 ; } + void defargsYYdummy() { yy_flex_realloc(0,0); } +} diff --git a/src/define.cpp b/src/define.cpp new file mode 100644 index 0000000..2fa7fa4 --- /dev/null +++ b/src/define.cpp @@ -0,0 +1,43 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include "define.h" +#include "config.h" + +Define::Define() +{ + undef=FALSE; + fileDef=0; +} + +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; + nargs=d.nargs; + undef=d.undef; + fileDef=0; +} + +Define::~Define() +{ +} + +bool Define::hasDocumentation() +{ + return definition && (doc || extractAllFlag); +} diff --git a/src/define.h b/src/define.h new file mode 100644 index 0000000..14ac008 --- /dev/null +++ b/src/define.h @@ -0,0 +1,88 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef DEFINE_H +#define DEFINE_H + +#include <qdict.h> +#include <qstring.h> +#include "util.h" + +class FileDef; + +class Define +{ + public: + Define(); + Define(const Define &d); + ~Define(); + bool hasDocumentation(); + QString name; + QString definition; + QString fileName; + QString doc; + QString brief; + QString args; + QString anchor; + FileDef *fileDef; + int lineNr; + int nargs; + bool undef; + bool varArgs; +}; + +class DefineList : public QList<Define> +{ + public: + DefineList() : QList<Define>() {} + ~DefineList() {} + int compareItems(GCI i1,GCI i2) + { + return strcmp(((Define *)i1)->name,((Define *)i2)->name); + } +}; + +class DefineName : public QList<Define> +{ + public: + DefineName(const char *n) : QList<Define>() { name=n; } + ~DefineName() {} + const char *nameString() const { return name; } + int compareItems(GCI i1,GCI i2) + { + return strcmp(((Define *)i1)->name,((Define *)i2)->name); + } + + private: + QString name; +}; + +class DefineNameList : public QList<DefineName> +{ + public: + DefineNameList() : QList<DefineName>() {} + ~DefineNameList() {} + int compareItems(GCI i1,GCI i2) + { + return stricmp(((DefineName *)i1)->nameString(), + ((DefineName *)i2)->nameString()); + } +}; + +typedef QDict<Define> DefineDict; +typedef QDict<DefineName> DefineNameDict; + +#endif diff --git a/src/definition.cpp b/src/definition.cpp new file mode 100644 index 0000000..535612b --- /dev/null +++ b/src/definition.cpp @@ -0,0 +1,44 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <ctype.h> +#include "definition.h" + +QString Definition::nameToFile(const char *name) +{ + QString result; + char c; + const char *p=name; + while ((c=*p++)!=0) + { + switch(c) + { + case ':': break; + case '<': result+="_lt"; break; + case '>': result+="_gt"; break; + case '*': result+="_ast"; break; + case '&': result+="_amp"; break; + case ' ': break; + default: + if (caseSensitiveNames) + result+=c; + else + result+=tolower(c); + break; + } + } + return result; +} diff --git a/src/definition.h b/src/definition.h new file mode 100644 index 0000000..2dbee89 --- /dev/null +++ b/src/definition.h @@ -0,0 +1,64 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef DEFINITION_H +#define DEFINITION_H + +#include <qstring.h> +#include "config.h" + +/*! The common base class of all definitions. */ +class Definition +{ + public: + //! create a new definition + Definition(const char *name,const char *b=0,const char *d=0) + { n=name; brief=b; doc=d; } + //! destroys the definition + virtual ~Definition() {} + //! returns the name of the definition + QString name() const { return n; } + //! returns the detailed description of this definition + QString documentation() const { return doc; } + //! returns the brief description of this definition + QString briefDescription() const { return brief; } + //! sets a new name for the definition + void setName(const char *name) { n=name; } + //! sets the documentation of this definition + void setDocumentation(const char *d) + { + doc=d; doc=doc.stripWhiteSpace(); + } + //! sets the brief description of this definition + void setBriefDescription(const char *b) + { + brief=b; brief=brief.stripWhiteSpace(); + int bl=brief.length(); + if (bl>0 && brief.at(bl-1)!='.' && brief.at(bl-1)!='!' && + brief.at(bl-1)!='?') brief+='.'; + } + //! returns TRUE iff the definition is documented + bool hasDocumentation() + { return !doc.isNull() || !brief.isNull() || extractAllFlag; } + QString nameToFile(const char *name); + + private: + QString n; // name of the definition + QString brief; // brief description + QString doc; // detailed description +}; + +#endif diff --git a/src/diagram.cpp b/src/diagram.cpp new file mode 100644 index 0000000..0fd30a5 --- /dev/null +++ b/src/diagram.cpp @@ -0,0 +1,1236 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <qlist.h> +#include <qstring.h> +#include <qarray.h> +#include <qtstream.h> +#include <qfile.h> + +#include "diagram.h" +#include "image.h" +#include "classdef.h" +#include "config.h" +#include "message.h" +#include "util.h" +#include "latexgen.h" +#include "htmlgen.h" + +//----------------------------------------------------------------------------- + +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 QString escapeLatex(const char *s) +//{ +// QString 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 Protected: return 0xcccccccc; + case Private: return 0xaaaaaaaa; + } + return 0; +} + +static uint protToColor(Protection p) +{ + switch(p) + { + case Public: return 6; + case Protected: return 5; + case Private: return 4; + } + return 0; +} + +static QString protToString(Protection p) +{ + switch(p) + { + case Public: return "solid"; + 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) +{ + DiagramItem *di=dil->first(); + Protection result=di->protection(); + di=dil->next(); + while (di) + { + Protection p=di->protection(); + if (p!=result) + { + if (result==Protected && p==Public) result=p; + else if (result==Private) result=p; + } + di=dil->next(); + } + 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 = 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(QTextStream &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(QTextStream &t,ClassDef *cd,int x,int y,int w,int h) +{ + if (cd->hasDocumentation() || cd->isReference()) + { + t << "<area "; + if (cd->getReference()) t << "doxygen=\"" << cd->getReference() << ":\" "; + t << "href=\"" << cd->classFile() << ".html\" "; + t << "ALT=\"" << cd->name(); + 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; +} + +QString DiagramItem::label() const +{ + return classDef->name()+templSpec; +} + +QString DiagramItem::fileName() const +{ + return classDef->classFile(); +} + +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) +{ + DiagramItem *di=new DiagramItem(parent, diagram->at(level)->count(), + cd,prot,virt,ts); + if (parent) parent->addChild(di); + di->move(count()*gridWidth,level*gridHeight); + append(di); + BaseClassList *bcl=doBases ? cd->baseClasses() : cd->superClasses(); + /* there are base/super classes */ + int count=0; + BaseClassDef *bcd=bcl->first(); + while (bcd) + { + ClassDef *ccd=bcd->classDef; + if (ccd && ccd->isVisibleExt() + //(ccd->protection()!=Private || extractPrivateFlag) && + //(ccd->hasDocumentation() || !hideClassFlag) + ) count++; + bcd=bcl->next(); + } + 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 */ + BaseClassDef *bcd=bcl->last(); + while (bcd) + { + ClassDef *ccd=bcd->classDef; + if (ccd && ccd->isVisibleExt() + //(ccd->protection()!=Private || extractPrivateFlag) && + //(ccd->hasDocumentation() || !hideClassFlag) + ) + { + row->insertClass(di,ccd,doBases,bcd->prot, + doBases?bcd->virt:Normal, + doBases?bcd->templSpecifiers.data():""); + } + bcd=bcl->prev(); + } + } +} + +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(); + DiagramItem *di=dil->first(); + while (di) + { + di->move(dx,0); + moveChildren(di,dx); + di=dil->next(); + } +} + +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 + DiagramItem *di=dil->first(); + while (di && !moved && !di->isInList()) + { + moved = moved || layoutTree(di,r+1); + di=dil->next(); + } + } + return moved; +} + +void TreeDiagram::computeLayout() +{ + DiagramRow *row=first(); + while (row && row->count()<maxTreeWidth) row=next(); + if (row) + { + //printf("computeLayout() list row at %d\n",row->number()); + DiagramItem *di=row->first(); + DiagramItem *opi=0; + int delta=0; + bool first=TRUE; + while (di) + { + 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(); + di=row->next(); + } + } + + // re-organize the diagram items + DiagramItem *root=getFirst()->getFirst(); + while (layoutTree(root,0)); + + // move first items of the lists + if (row) + { + DiagramItem *di=row->first(); + while (di) + { + DiagramItem *pi=di->parentItem(); + if (pi->getChildren()->count()>1) + { + di->move(gridWidth,0); + while (di && di->parentItem()==pi) di=row->next(); + } + else + { + di=row->next(); + } + } + } +} + +uint TreeDiagram::computeRows() +{ + //printf("TreeDiagram::computeRows()=%d\n",count()); + int count=0; + DiagramRow *row=first(); + while (row && !row->getFirst()->isInList()) + { + count++; + row=next(); + } + //printf("count=%d row=%p\n",count,row); + if (row) + { + int maxListLen=0; + int curListLen=0; + DiagramItem *di=row->first(),*opi=0; + while (di) + { + if (di->parentItem()!=opi) curListLen=1; else curListLen++; + if (curListLen>maxListLen) maxListLen=curListLen; + opi=di->parentItem(); + di=row->next(); + } + //printf("maxListLen=%d\n",maxListLen); + count+=maxListLen; + } + return count; +} + +#if 0 +uint TreeDiagram::computeCols() +{ + uint count=0; + DiagramRow *row=first(); + while (row && !row->getFirst()->isInList()) + { + if (row->count()>count) count=row->count(); + row=next(); + } + if (row) + { + row=prev(); + uint cols=row->count(); + if (row->getLast()->getChildren()->count()>1) cols++; + if (cols>count) count=cols; + } + return count; +}; +#endif + +void TreeDiagram::computeExtremes(uint *maxLabelLen,uint *maxXPos) +{ + uint ml=0,mx=0; + DiagramRow *dr=first(); + bool done=FALSE; + while (dr && !done) + { + DiagramItem *di=dr->first(); + while (di) + { + if (di->isInList()) done=TRUE; + if (maxXPos) mx=QMAX(mx,(uint)di->xPos()); + if (maxLabelLen) ml=QMAX(ml,stringLength(di->label())); + di=dr->next(); + } + dr=next(); + } + if (maxLabelLen) *maxLabelLen=ml; + if (maxXPos) *maxXPos=mx; +} + +void TreeDiagram::drawBoxes(QTextStream &t,Image *image, + bool doBase,bool bitmap, + uint baseRows,uint superRows, + uint cellWidth,uint cellHeight) +{ + DiagramRow *dr=first(); + if (!doBase) dr=next(); + bool done=FALSE; + bool firstRow = doBase; + while (dr && !done) + { + int x=0,y=0; + float xf=0.0,yf=0.0; + DiagramItem *di=dr->first(); + if (di->isInList()) // put boxes in a list + { + DiagramItem *opi=0; + if (doBase) di=dr->last(); + while (di) + { + if (di->parentItem()==opi) + { + if (bitmap) + { + if (doBase) y -= cellHeight+labelVertSpacing; + else y += cellHeight+labelVertSpacing; + } + else + { + if (doBase) yf += 1.0; + else yf -= 1.0; + } + } + 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()->hasDocumentation() || + di->getClassDef()->isReference(); + writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow, + hasDocs,di->getChildren()->count()>0); + if (!firstRow) writeMapArea(t,di->getClassDef(),x,y,cellWidth,cellHeight); + } + else + { + writeVectorBox(t,di,xf,yf,di->getChildren()->count()>0); + } + + if (doBase) di=dr->prev(); else di=dr->next(); + } + done=TRUE; + } + else // draw a tree of boxes + { + while (di) + { + 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()->hasDocumentation() || + di->getClassDef()->isReference(); + writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,hasDocs); + if (!firstRow) writeMapArea(t,di->getClassDef(),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); + } + + di=dr->next(); + } + } + dr=next(); + firstRow=FALSE; + } +} + +void TreeDiagram::drawConnectors(QTextStream &t,Image *image, + bool doBase,bool bitmap, + uint baseRows,uint superRows, + uint cellWidth,uint cellHeight) +{ + DiagramRow *dr=first(); + bool done=FALSE; + while (dr && !done) // for each row + { + DiagramItem *di=dr->first(); + if (di->isInList()) // row consists of list connectors + { + int x=0,y=0,ys=0; + float xf=0.0,yf=0.0,ysf=0.0; + while (di) + { + 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.5; + } + else + { + ysf = (float)superRows-0.25-di->yPos()/(float)gridHeight; + yf = ysf - 0.25; + } + } + 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.0; + } + else + { + t << "0 " << xf << " " << yf << " hedge\n"; + yf -= 1.0; + } + } + di=dr->next(); + } + // 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"; + } + } + } + di=dr->next(); + } + done=TRUE; // the tree is drawn now + } + else // normal tree connector + { + while (di) + { + 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->first(); + DiagramItem *last = dil->last(); + 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"; + } + } + } + } + di=dr->next(); + } + dr=next(); + } + } +} + +ClassDiagram::ClassDiagram(ClassDef *root) +{ + base = new TreeDiagram(root,TRUE); + base->computeLayout(); + super = new TreeDiagram(root,FALSE); + super->computeLayout(); + DiagramItem *baseItem = base->first()->first(); + DiagramItem *superItem = super->first()->first(); + 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(QTextStream &output,const char *path, + const char *fileName) +{ + 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.0; // 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" + "\\begin{figure}[H]\n" + "\\begin{center}\n" + "\\leavevmode\n"; + output << "\\setlength{\\epsfysize}{" << realHeight << "cm}\n"; + output << "\\epsfbox{" << fileName << ".eps}\n" + "\\end{center}\n" + "\\end{figure}\n"; + + //printf("writeFigure rows=%d cols=%d\n",rows,cols); + + QFile f1((QString)path+"/"+fileName+".eps"); + if (!f1.open(IO_WriteOnly)) + { + err("Could not open file %s for writing\n",f1.name()); + exit(1); + } + QTextStream t(&f1); + + //printf("writeEPS() rows=%d cols=%d\n",rows,cols); + + // generate EPS header and postscipt 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; + DiagramRow *dr=base->first(); + while (dr && !done) + { + DiagramItem *di=dr->first(); + while (di) + { + done=di->isInList(); + t << "(" << di->label() << ") cw\n"; + di=dr->next(); + } + dr=base->next(); + } + dr=super->first(); + dr=super->next(); + done=FALSE; + while (dr && !done) + { + DiagramItem *di=dr->first(); + while (di) + { + done=di->isInList(); + t << "(" << di->label() << ") cw\n"; + di=dr->next(); + } + dr=super->next(); + } + + 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); +} + + +void ClassDiagram::writeImageMap(QTextStream &t,const char *path, + const char *fileName) +{ + uint baseRows=base->computeRows(); + uint superRows=super->computeRows(); + uint rows=baseRows+superRows-1; + +// t << "<p>Class diagram for "; +// HtmlGenerator::docifyStatic(t,name); +// t << ".\n<p><center><img src=\"" +// << fileName << ".gif\" usemap=\"#" << name << "_map\"" +// << " border=\"0\"></center>" << endl +// << "<map name=\"" << name << "_map\"><p>" << endl; + + 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); + super->drawBoxes(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight); + base->drawConnectors(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight); + super->drawConnectors(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight); + + image.save((QString)path+"/"+fileName+".gif"); + + t << "</MAP></P>" << endl; +} + diff --git a/src/diagram.h b/src/diagram.h new file mode 100644 index 0000000..5bc30f8 --- /dev/null +++ b/src/diagram.h @@ -0,0 +1,128 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include "entry.h" + +class ClassDef; +class DiagramRow; +class TreeDiagram; +class ClassDiagram; +class DiagramItemList; +class Image; + +class DiagramItem +{ + public: + DiagramItem(DiagramItem *p,int number,ClassDef *cd, + Protection prot,Specifier virt,const char *ts); + ~DiagramItem(); + QString label() const; + QString 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; + QString templSpec; + bool inList; + ClassDef *classDef; +}; + +class DiagramItemList : public QList<DiagramItem> +{ + public: + DiagramItemList() : QList<DiagramItem>() {} + ~DiagramItemList() {} +}; + +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 DiagramRowIterator : public QListIterator<DiagramRow> +{ + public: + DiagramRowIterator(const QList<DiagramRow> &d) + : QListIterator<DiagramRow>(d) {} +}; + +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(QTextStream &t,Image *image, + bool doBase,bool bitmap, + uint baseRows,uint superRows, + uint cellWidth,uint cellHeight); + void drawConnectors(QTextStream &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 &); +}; + +class ClassDiagram +{ + public: + ClassDiagram(ClassDef *root); + ~ClassDiagram(); + void writeFigure(QTextStream &t,const char *path, + const char *file); + void writeImageMap(QTextStream &t,const char *path, + const char *file); + private: + TreeDiagram *base; + TreeDiagram *super; +}; diff --git a/src/doxygen.cpp b/src/doxygen.cpp new file mode 100644 index 0000000..3d641ef --- /dev/null +++ b/src/doxygen.cpp @@ -0,0 +1,3763 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <qstring.h> +#include <qfileinf.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 "version.h" +#include "doxygen.h" +#include "scanner.h" +#include "entry.h" +#include "index.h" +#include "logos.h" +#include "instdox.h" +#include "message.h" +#include "code.h" +#include "config.h" +#include "util.h" +#include "pre.h" +#include "tag.h" + +#include "outputlist.h" +#include "declinfo.h" +#include "htmlgen.h" +#include "latexgen.h" +#include "mangen.h" +#include "language.h" +#include "debug.h" + +#if defined(_MSC_VER) +#define popen _popen +#endif + + +// lists +ClassList classList; // list of all documented classes +NamespaceList namespaceList; // list of all namespaces +PageList exampleList; // list of all example files +PageList pageList; // list of all related documentation pages +MemberNameList memberNameList; // list of class member + related functions +MemberNameList functionNameList; // list of all unrelated functions +FileNameList inputNameList; // list of all input files +StringList inputFiles; +FileList includeFiles; +GroupList groupList; // list of all groups +FormulaList formulaList; // list of all formulas + +// dictionaries +PageDict pageDict(1009); // dictionary of all doc pages +PageDict exampleDict(1009); // dictionary of all examples +ClassDict classDict(1009); // dictionary of all documented classes +NamespaceDict namespaceDict(257); // dictionary of all documented namespaces +MemberNameDict memberNameDict(10007); // dictionary of all member names +MemberNameDict functionNameDict(10007); // dictionary of all functions +StringDict substituteDict(1009); // dictionary of class name substitutes +SectionDict sectionDict(257); // dictionary of all page sections +FileNameDict inputNameDict(1009); // dictionary of sections +StringDict excludeNameDict(1009); // dictionary of sections +FileNameDict includeNameDict(1009); // dictionary of include names +FileNameDict exampleNameDict(1009); // dictionary of examples +FileDict includeDict(1009); // dictionary of include files +DefineDict defineDict(10007); // dictionary of all defines +StringDict typedefDict(1009); // dictionary of all typedefs +GroupDict groupDict(257); // dictionary of all groups +FormulaDict formulaDict(1009); // dictionary of all formulas +FormulaDict formulaNameDict(1009); // dictionary of the label name of all formulas + +OutputList *outputList; // list of output generating objects + +//bool unrelatedFunctionsUsed; + +//ClassDef unrelatedClass("nothing",ClassDef::Class); + // dummy class for unrelated functions + +int annotatedClasses; +int hierarchyClasses; +int documentedFunctions; +int documentedMembers; +int documentedFiles; +int documentedGroups; +int documentedNamespaces; + +QTextStream tagFile; + +void addMemberDocs(Entry *root,MemberDef *md, const char *funcDecl, + bool over_load); + + +//---------------------------------------------------------------------- +// Returns the standard string that is generated when the \overload +// command is used. + +const char *getOverloadDocs() +{ + return "This is an overloaded member function, " + "provided for convenience. It differs from the above " + "function only in what argument(s) it accepts."; +} + +//---------------------------------------------------------------------------- + + +void buildGroupList(Entry *root) +{ + if (root->section==Entry::GROUPDOC_SEC && root->name.length()>0) + { + //printf("Found group %s title=`%s'\n",root->name.data(),root->type.data()); + + GroupDef *gd; + + if ((gd=groupDict[root->name])) + { + warn("Warning: group %s already documented\n" + " skipping documentation in file %s at line %d\n", + root->name.data(),root->fileName.data(),root->startLine); + } + else + { + gd = new GroupDef(root->name,root->type); + gd->setBriefDescription(root->brief); + gd->setDocumentation(root->doc); + groupList.inSort(gd); + groupDict.insert(root->name,gd); + } + } + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + buildGroupList(e); + } +} + +//---------------------------------------------------------------------- + +//void computeGroupRelations(Entry *root) +//{ +// if (root->section==Entry::GROUPDOC_SEC && root->name.length()>0) +// { +// GroupDef *gd; +// +// if ((gd=groupDict[root->name])) +// { +// QListIterator<QString> sli(*root->groups); +// QString *s; +// for (;(s=sli.current());++sli) +// { +// GroupDef *pgd; +// if (s->length()>0 && (pgd=groupDict[*s])) +// { +// pgd->addGroup(gd); +// printf("Group %s: in group %s\n",gd->groupName(),s->data()); +// } +// } +// } +// } +// EntryListIterator eli(*root->sublist); +// Entry *e; +// for (;(e=eli.current());++eli) +// { +// computeGroupRelations(e); +// } +//} + +//---------------------------------------------------------------------- + +void buildFileList(Entry *root) +{ + if (((root->section==Entry::FILEDOC_SEC) || + ((root->section & Entry::FILE_MASK) && extractAllFlag)) && + root->name.length()>0 + ) + { + bool ambig; + FileDef *fd=findFileDef(&inputNameDict,root->name,ambig); + if (fd && !ambig) + { + if ((root->doc.length()>0 && fd->documentation()) || + (root->brief.length()>0 && fd->briefDescription())) + { + warn("Warning: file %s already documented\n" + " skipping documentation in file %s at line %d\n", + root->name.data(),root->fileName.data(),root->startLine); + } + else + { + fd->setDocumentation(root->doc); + fd->setBriefDescription(root->brief); + QListIterator<QString> sli(*root->groups); + QString *s; + for (;(s=sli.current());++sli) + { + GroupDef *gd=0; + if (s->length()>0 && (gd=groupDict[*s])) + { + gd->addFile(fd); + //printf("File %s: in group %s\n",fd->name().data(),s->data()); + } + } + } + } + else + { + warn("Warning: the name `%s' supplied as " + "the second argument in the \\file statement in file " + "%s at line %d ", + root->name.data(), + root->fileName.data(), + root->startLine); + if (ambig) // name is ambigious + { + warn("matches the following input files:\n"); + showFileDefMatches(&inputNameDict,root->name); + warn("Please use a more specific name by " + "including a (larger) part of the path!\n"); + } + else // name is not an input file + warn("is not an input file\n"); + } + } + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + buildFileList(e); + } +} + +void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root) +{ + //printf(">>>>>> includeFile=%s\n",root->includeFile.data()); + + bool ambig; + FileDef *fd=0; + // see if we need to include a verbatim copy of the header file + if (!root->includeFile.isNull() && + (fd=findFileDef(&inputNameDict,root->includeFile,ambig))==0 + ) + { // explicit request + warn("Warning: the name `%s' supplied as " + "the second argument in the \\class statement in file " + "%s at line %d ", + root->includeFile.data(), + root->fileName.data(), + root->startLine); + if (ambig) // name is ambigious + { + warn("matches the following input files:\n"); + showFileDefMatches(&inputNameDict,root->includeFile); + warn("Please use a more specific name by " + "including a (larger) part of the path!\n"); + } + else // name is not an input file + warn("is not an input file\n"); + } + else if (root->includeFile.length()==0 && + // see if the file extension makes sense + guessSection(root->includeFile)==Entry::HEADER_SEC) + { // implicit assumption + fd=ifd; + } + + // if a file is found, we mark it for verbatim inclusion. + if (fd) + { + //printf("fd->name()=%s fd->absFilePath()=%s\n",fd->name().data(), + // fd->absFilePath().data()); + // set include file definition + cd->setIncludeFile(fd); + // set include supplied name + cd->setIncludeName(root->includeName); + fd->setIncludeName((QString)cd->classFile()+"-include"); + if (includeDict[fd->absFilePath()]==0) // include not inserted earlier + { + includeFiles.inSort(fd); + includeDict.insert(fd->absFilePath(),fd); + } + } +} + +/*! Input is a scopeName, output is the scopename split into a + * namespace part (as large as possible) and a classname part. + */ +void extractNamespaceName(const QString &scopeName, + QString &className,QString &namespaceName) +{ + QString clName=scopeName.copy(); + QString nsName; + if (clName.length()>0 && namespaceDict[clName]) + { // the whole name is a namespace + namespaceName=clName.copy(); + className.resize(0); + return; + } + int i,p=clName.length()-2; + while (p>=0 && (i=clName.findRev("::",p))!=-1) + // see if the first part is a namespace + { + if (i>0 && namespaceDict[clName.left(i)]) + { + namespaceName=clName.left(i); + className=clName.right(clName.length()-i-2); + return; + } + p=i-2; // try a smaller piece of the scope + } + className=scopeName.copy(); + namespaceName.resize(0); + return; +} + +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; + if (!e->name.isEmpty() && (nd=namespaceDict[e->name])) + { + cd->setNamespace(nd); + nd->insertClass(cd); + return TRUE; + } + } + e=e->parent; + } + } + return FALSE; +} + +//---------------------------------------------------------------------- +// build a list of all classes mentioned in the documentation +// and all classes that have a documentation block before their definition. +void buildClassList(Entry *root) +{ + if ( + ((root->section & Entry::COMPOUNDDOC_MASK) || + ((root->section & Entry::COMPOUND_MASK))) && + root->name.length()>0 + ) + { + QString fullName=root->name.copy(); + if (fullName.length()==0) + { + // this should not be called + warn("Warning: invalid class found in file %s at %d\n", + root->fileName.data(),root->startLine); + } + else + { + //QString className; + //QString namespaceName; + //extractNamespaceName(fullName,className,namespaceName); + + //printf("Found class %s in %s at line %d\n",fullName.data(), + // root->fileName.data(),root->startLine); + // add class name substitution entry iff the class name is alterned by a + // define. This is needed to properly document Qt's template classes + // (although, it's quite general) + //if (resolveDefines(fullName)!=fullName) + //{ + // substituteDict.insert(resolveDefines(fullName),new QString(fullName)); + //} + + bool ambig; + ClassDef *cd; + if ((cd=getClass(fullName))) + { + if (cd->templateArguments()==0) + { + //printf("existing ClassDef tempArgList=%p\n",root->tArgList); + cd->setTemplateArguments(root->tArgList); + } + if (root->doc.length()>0 || root->brief.length()>0) // block contains docs + { + if (cd->documentation()) // class already documented + { + warn("Warning: class %s already documented\n" + " skipping documentation in file %s at line %d\n", + fullName.data(),root->fileName.data(),root->startLine); + } + else // class not documented, use docs in block + { + cd->setDocumentation(root->doc); + cd->setBriefDescription(root->brief); + cd->setName(fullName); // change name to match docs + } + } + if (cd->includeFile()==0) + { + addIncludeFile(cd, + findFileDef(&inputNameDict,root->fileName,ambig), + root + ); + } + addNamespace(root,cd); + } + else if (fullName[0]!='@' /* && + (root->doc.length()>0 || + root->brief.length()>0 || + extractAllFlag + )*/ + ) + // new class + { + int sec=ClassDef::Class; + switch(root->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; + } + ClassDef *cd=new ClassDef(fullName,sec); + cd->setDocumentation(root->doc); // copy docs to definition + cd->setBriefDescription(root->brief); + //printf("new ClassDef tempArgList=%p\n",root->tArgList); + cd->setTemplateArguments(root->tArgList); + cd->setProtection(root->protection); + + QListIterator<QString> sli(*root->groups); + QString *s; + for (;(s=sli.current());++sli) + { + GroupDef *gd=0; + if (s->length()>0 && (gd=groupDict[*s])) + { + gd->addClass(cd); + //printf("Compound %s: in group %s\n",cd->name().data(),s->data()); + } + } + + bool found=addNamespace(root,cd); + + // file definition containing the class cd + FileDef *ifd=findFileDef(&inputNameDict,root->fileName,ambig); + + addIncludeFile(cd,ifd,root); + + // if the class is not in a namespace then we insert + // it in the file definition + if (!found && ifd) ifd->insertClass(cd); + + // the empty string test is needed for extract all case + cd->setBriefDescription(root->brief); + cd->insertUsedFile(root->fileName); + // add class to the list + classList.inSort(cd); + //printf("ClassDict.insert(%s)\n",resolveDefines(fullName).data()); + //classDict.insert(resolveDefines(fullName),cd); + classDict.insert(fullName,cd); + } + } + } + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + buildClassList(e); + } +} + +//---------------------------------------------------------------------- +// build a list of all namespaces mentioned in the documentation +// and all namespaces that have a documentation block before their definition. +void buildNamespaceList(Entry *root) +{ + if ( + (root->section==Entry::NAMESPACE_SEC) || + (root->section==Entry::NAMESPACEDOC_SEC) && + root->name.length()>0 + ) + { + QString fullName=root->name.copy(); + if (fullName.length()==0) + { + // this should not be called + warn("Warning: invalid namespace found in file %s at %d\n", + root->fileName.data(),root->startLine); + } + else + { + //printf("Found namespace %s in %s at line %d\n",root->name.data(), + // root->fileName.data(), root->startLine); + NamespaceDef *nd; + if ((nd=namespaceDict[fullName])) + { + if (root->doc.length()>0 || root->brief.length()>0) // block contains docs + { + if (nd->documentation().isEmpty() && root->doc.length()>0) + { + nd->setDocumentation(root->doc); + nd->setName(fullName); // change name to match docs + } + else if (!nd->documentation().isEmpty() && root->doc.length()>0) + { + warn("Warning: namespace %s already has a detailed description,\n" + " skipping documentation in file %s at line %d\n", + fullName.data(),root->fileName.data(),root->startLine); + } + if (nd->briefDescription().isEmpty() && root->brief.length()>0) + { + nd->setBriefDescription(root->brief); + nd->setName(fullName); // change name to match docs + } + else if (!nd->briefDescription().isEmpty() && root->brief.length()>0) + { + warn("Warning: namespace %s already has a brief description,\n" + " skipping documentation in file %s at line %d\n", + fullName.data(),root->fileName.data(),root->startLine); + } + } + } + else if (root->doc.length()>0 || + root->brief.length()>0 || + extractAllFlag + ) + { + NamespaceDef *nd=new NamespaceDef(fullName); + nd->setDocumentation(root->doc); // copy docs to definition + nd->setBriefDescription(root->brief); + + QListIterator<QString> sli(*root->groups); + QString *s; + for (;(s=sli.current());++sli) + { + GroupDef *gd=0; + if (s->length()>0 && (gd=groupDict[*s])) + gd->addNamespace(nd); + } + + bool ambig; + // file definition containing the class cd + FileDef *fd=findFileDef(&inputNameDict,root->fileName,ambig); + // 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); + nd->insertUsedFile(root->fileName); + // add class to the list + namespaceList.inSort(nd); + namespaceDict.insert(fullName,nd); + } + } + } + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + buildNamespaceList(e); + } +} + + +//---------------------------------------------------------------------- +// Searches the Entry tree for Variable documentation sections. +// If found they are stored in their class or in the global list. + +void buildVarList(Entry *root) +{ + QRegExp re("([^)]*)"); + int i=-1; + if (root->name.length()>0 && + root->type!="class" && + ( + (root->section==Entry::VARIABLE_SEC + ) || + (root->section==Entry::FUNCTION_SEC && // function variable + !root->type.isNull() && root->type.find(re,0)!=-1 && + root->type.find("operator")==-1 && root->type.find(")(")==-1 + ) + ) + ) // documented variable + { + Debug::print(Debug::Variables,0, + "VARIABLE_SEC: \n" + " type=`%s' name=`%s' args=`%s'\n", + root->type.data(), + root->name.data(), + root->args.data() + ); + //printf("root->parent->name=%s\n",root->parent->name.data()); + + if (root->type.isNull() && root->name.find("operator")==-1 && + (root->name.find('*')!=-1 || root->name.find('&')!=-1)) + { + // recover from parse error caused by redundant braces + root->type=root->name; + QRegExp re("[a-z_A-Z][a-z_A-Z0-9]*"); + int i,l; + i=re.match(root->args,0,&l); + 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 + { + QRegExp re("([^)]*)"); + i=root->type.find(re,0); + if (i!=-1) // function variable + { + root->type=root->type.left(root->type.length()-1); + root->args.prepend(")"); + } + } + + QString scope,name=root->name.copy(); + bool stat=root->stat; + ClassDef *cd=0; + Entry *p = root->parent; + while ((p->section & Entry::COMPOUND_MASK)) + { + if (p->name.length()>0 && p->name[0]!='@') + { + if (!scope.isEmpty()) scope.prepend("::"); + scope.prepend(p->name); + } + p=p->parent; + } + + //printf("scope=%s\n",scope.data()); + + int ni; + if ((ni=root->name.findRev("::"))!=-1) + { + if (scope.length()>0) scope+="::"; + scope+=root->name.left(ni); + name=root->name.right(root->name.length()-ni-2); + stat=TRUE; + } + + MemberDef::MemberType mtype; + QString type=root->type.stripWhiteSpace(); + if (type=="@") + mtype=MemberDef::EnumValue; + else if (type.left(8)=="typedef ") + mtype=MemberDef::Typedef; + else if (type.left(7)=="friend ") + mtype=MemberDef::Friend; + else + mtype=MemberDef::Variable; + + if (scope.length()>0 && name.length()>0 && (cd=getClass(scope))) + { + + Debug::print(Debug::Variables,0, + " class variable:\n" + " %s' %s'::`%s' `%s' prot=`%d\n", + root->type.data(), + scope.data(), + name.data(), + root->args.data(), + root->protection + ); + // add template names, if the class is a non-specialized template + //if (scope.find('<')==-1 && cd->templateArguments()) + //{ + // scope+=cd->getTemplateNameString(); + //} + // generate member definition. + QString def; + if (root->type.length()>0) + { + if (mtype==MemberDef::Friend) + { + def=root->type+" "+name+root->args; + } + else + { + def=root->type+" "+scope+"::"+name+root->args; + } + } + else + { + def=scope+"::"+name+root->args; + } + if (def.left(7)=="static ") def=def.right(def.length()-7); + + // 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) + bool found=FALSE; + MemberName *mn=memberNameDict[name]; + if (mn) + { + MemberDef *md=mn->first(); + while (md) + { + if (md->memberClass()==cd) // member already in the scope + { + addMemberDocs(root,md,def,FALSE); + found=TRUE; + } + md=mn->next(); + } + } + if (!found) // found a fresh variable + { + // new member variable, typedef or enum value + MemberDef *md=new MemberDef(root->type,name,root->args,0, + root->protection,Normal,stat,FALSE, + mtype,0,0); + md->setMemberClass(cd); + md->setDefFile(root->fileName); + md->setDefLine(root->startLine); + md->setDocumentation(root->doc); + md->setBriefDescription(root->brief); + md->setDefinition(def); + + // add the member to the global list + if (mn) + { + //printf("Member already found! %s\n",md->name()); + //addMemberDocs(root,mn->first(),def,FALSE); + //delete md; + mn->inSort(md); + } + else // new variable name + { + mn = new MemberName(name); + mn->inSort(md); + //printf("Adding memberName=%s\n",mn->memberName()); + memberNameDict.insert(name,mn); + memberNameList.inSort(mn); + // add the member to the class + } + cd->insertMember(md); + + //TODO: insert FileDef instead of filename strings. + cd->insertUsedFile(root->fileName); + } + } + else if (name.length()>0) // global variable + { + Debug::print(Debug::Variables,0, + " global variable:\n" + " type=`%s' scope=`%s' name=`%s' args=`%s' prot=`%d\n", + root->type.data(), + scope.data(), + name.data(), + root->args.data(), + root->protection + ); + + // new global variable, enum value or typedef + MemberDef *md=new MemberDef(root->type,name,root->args,0, + Public, Normal,root->stat,FALSE, + mtype,0,0); + md->setDefFile(root->fileName); + md->setDefLine(root->startLine); + md->setDocumentation(root->doc); + md->setBriefDescription(root->brief); + QString def; + + // see if the function is inside a namespace + NamespaceDef *nd = 0; + if (root->parent->section == Entry::NAMESPACE_SEC ) + { + nd = namespaceDict[root->parent->name]; + } + if (nd) + { + nd->insertMember(md); + md->setNamespace(nd); + } + else + { + // find file definition + FileDef *fd=0; + bool ambig; + if (root->fileName.length()>0 && + (fd=findFileDef(&inputNameDict,root->fileName,ambig)) + ) + { + fd->insertMember(md); + md->setFileDef(fd); + } + } + + // determine the definition of the global variable + if (nd) // variable is inside a namespace, so put the scope + // before the name + { + if (root->type.length()>0) + { + def=root->type+" "+nd->name()+"::"+name+root->args; + } + else + { + def=nd->name()+"::"+name+root->args; + } + } + else + { + if (root->type.length()>0) + { + def=root->type+" "+name+root->args; + } + else + { + def=name+root->args; + } + } + if (def.left(7)=="static ") def=def.right(def.length()-7); + md->setDefinition(def); + + MemberName *mn; + // add member definition to the list of globals + if ((mn=functionNameDict[name])) + { + mn->inSort(md); + } + else + { + mn = new MemberName(name); + mn->inSort(md); + functionNameDict.insert(name,mn); + functionNameList.inSort(mn); + } + } + } + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + if (e->section!=Entry::ENUM_SEC) buildVarList(e); + } +} + +//---------------------------------------------------------------------- +// Searches the Entry tree for Function sections. +// If found they are stored in their class or in the global list. + +void buildMemberList(Entry *root) +{ + if (root->section==Entry::FUNCTION_SEC) + { + Debug::print(Debug::Functions,0, + "FUNCTION_SEC:\n" + " `%s' `%s'::`%s' `%s' relates=`%s' file=`%s' #targs=%d\n", + root->type.data(), + root->parent->name.data(), + root->name.data(), + root->args.data(), + root->relates.data(), + root->fileName.data(), + root->tArgList ? (int)root->tArgList->count() : -1 + ); + + bool isFriend=root->type.find("friend ")!=-1; + //if (isFriend && root->relates.length()==0) + // root->relates=root->parent->name.copy(); + if (root->name.length()>0 /* && !isFriend */) + { + + ClassDef *cd=0; + // check if this function's parent is a class + QRegExp re("([a-zA-Z0-9: ]*[ *]*[ ]*"); + //printf("root->parent=`%s' cd=%p root->type.find(re,0)=%d\n", + // root->parent->name.data(),getClass(root->parent->name), + // root->type.find(re,0)); + int i; + if (root->parent && + root->parent->name.length()>0 && + (root->parent->section & Entry::COMPOUND_MASK) && + (cd=getClass(root->parent->name)) && + // do some fuzzy things to exclude function pointers + (root->type.isNull() || root->type.find(re,0)==-1 || + root->type.find(")(")!=-1 || root->type.find("operator")!=-1 + ) + ) + { + int l; + if ((i=re.match(root->type,0,&l))!=-1) // function variable + { + root->args+=root->type.right(root->type.length()-i-l); + root->type=root->type.left(i+l); + } + + QString name=removeRedundantWhiteSpace(root->name); + if (name.left(2)=="::") name=name.right(name.length()-2); + + MemberDef::MemberType mtype; + if (isFriend) mtype=MemberDef::Friend; + else if (root->sig) mtype=MemberDef::Signal; + else if (root->slot) mtype=MemberDef::Slot; + else mtype=MemberDef::Function; + // new member of function, signal or slot. + MemberDef *md=new MemberDef(root->type,name,root->args,root->exception, + root->protection,root->virt,root->stat,root->relates.length()>0, + mtype,root->tArgList,root->argList); + md->setMemberClass(cd); + md->setDefFile(root->fileName); + md->setDefLine(root->startLine); + md->setDocumentation(root->doc); + md->setBriefDescription(root->brief); + QString def; + if (root->relates.length()>0 || isFriend) + { + if (root->type.length()>0) + { + 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 + { + QString scope=root->parent->name.copy(); + if (root->type.length()>0) + { + if (root->argList) + { + def=root->type+" "+scope+"::"+name; + } + else + { + def=root->type+" "+scope+"::"+name+root->args; + } + } + else + { + if (root->argList) + { + def=scope+"::"+name; + } + else + { + def=scope+"::"+name+root->args; + } + } + } + if (def.left(7)=="friend ") def=def.right(def.length()-7); + md->setDefinition(def); + + Debug::print(Debug::Functions,0, + " Func Member:\n" + " `%s' `%s'::`%s' `%s' proto=%d\n" + " def=`%s'\n", + root->type.data(), + root->parent->name.data(), + root->name.data(), + root->args.data(), + root->proto, + def.data() + ); + + // add member to the global list of all members + MemberName *mn; + if ((mn=memberNameDict[name])) + { + mn->inSort(md); + } + else + { + mn = new MemberName(name); + mn->inSort(md); + //printf("Adding memberName=%s\n",mn->memberName()); + memberNameDict.insert(name,mn); + memberNameList.inSort(mn); + } + + // add member to the class cd + cd->insertMember(md); + // add file to list of used files + cd->insertUsedFile(root->fileName); + } + else if (root->parent && + !(root->parent->section & Entry::COMPOUND_MASK) && + root->name.find("::")==-1 && + root->relates.length()==0 && + root->type.left(7)!="extern ") + // 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 *fmd; + if ((mn=functionNameDict[root->name])) + { + MemberDef *md=mn->first(); + while (md && !found) + { + if (md->getFileDef() && + md->getFileDef()->absFilePath()==root->fileName && + /*matchArguments(md->argsString(),root->args)*/ + matchArguments(md->argumentList(),root->argList) + ) + { + // function already found in the same file, one is probably + // a prototype. + found=TRUE; + if (!md->documentation() && !root->doc.isEmpty()) + { + md->setDocumentation(root->doc); + } + if (!md->briefDescription() && !root->brief.isEmpty()) + { + md->setBriefDescription(root->brief); + } + } + md=mn->next(); + } + } + if (!found) /* global function is unique with respect to the file */ + { + //printf("New function type=`%s' name=`%s' args=`%s'\n", + // root->type.data(),root->name.data(),root->args.data()); + + // new global function + QString name=removeRedundantWhiteSpace(root->name); + MemberDef *md=new MemberDef(root->type,name,root->args,root->exception, + root->protection,root->virt,root->stat,FALSE, + MemberDef::Function,root->tArgList,root->argList); + md->setDefFile(root->fileName); + md->setDefLine(root->startLine); + md->setDocumentation(root->doc); + md->setBriefDescription(root->brief); + md->setPrototype(root->proto); + QString def; + if (root->type.length()>0) + { + if (root->argList) + { + def=root->type+" "+name; + } + else + { + def=root->type+" "+name+root->args; + } + } + else + { + if (root->argList) + { + def=name.copy(); + } + else + { + def=name+root->args; + } + } + Debug::print(Debug::Functions,0, + " Global Function:\n" + " `%s' `%s'::`%s' `%s' proto=%d\n" + " def=`%s'\n", + root->type.data(), + root->parent->name.data(), + root->name.data(), + root->args.data(), + root->proto, + def.data() + ); + md->setDefinition(def); + + // see if the function is inside a namespace + NamespaceDef *nd = 0; + if (root->parent->section == Entry::NAMESPACE_SEC ) + { + nd = namespaceDict[root->parent->name]; + } + if (nd) + { + nd->insertMember(md); + md->setNamespace(nd); + } + else + { + // find file definition + FileDef *fd=0; + bool ambig; + if (root->fileName.length()>0 && + (fd=findFileDef(&inputNameDict,root->fileName,ambig)) + ) + { + // add member to the file + fd->insertMember(md); + md->setFileDef(fd); + } + } + + // add member to the list of file members + MemberName *mn; + if ((mn=functionNameDict[name])) + { + mn->inSort(md); + } + else + { + mn = new MemberName(name); + mn->inSort(md); + functionNameDict.insert(name,mn); + functionNameList.inSort(mn); + } + } + else + { + //printf("Function already found!\n"); + } + + //printf("unrelated function %d `%s' `%s' `%s'\n", + // root->parent->section,root->type.data(),root->name.data(),root->args.data()); + } + } + else if (root->name.length()==0) + { + warn("Warning: Illegal member name found in file %s at line %d\n", + root->fileName.data(),root->startLine); + } + } + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + buildMemberList(e); + } +} + +//---------------------------------------------------------------------- + +void findFriends() +{ + //printf("findFriends()\n"); + MemberNameListIterator fnli(functionNameList); + MemberName *fn; + for (;(fn=fnli.current());++fnli) // for each global function name + { + //printf("Function name=`%s'\n",fn->memberName()); + MemberName *mn; + if ((mn=memberNameDict[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()); + NamespaceDef *nd=mmd->getNamespace(); + if ((mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) && + matchArguments(mmd->argumentList(), + fmd->argumentList(), + mmd->memberClass()->name(), + nd ? nd->name().data() : 0 + ) + ) // if the member is related and the arguments match then the + // function is actually a friend. + { + //printf("Found friend function\n"); + mergeArguments(mmd->argumentList(),fmd->argumentList()); + if (fmd->documentation()) + mmd->setDocumentation(fmd->documentation()); + else if (mmd->documentation()) + fmd->setDocumentation(mmd->documentation()); + if (!mmd->briefDescription() && fmd->briefDescription()) + mmd->setBriefDescription(fmd->briefDescription()); + else if (mmd->briefDescription() && !fmd->briefDescription()) + fmd->setBriefDescription(mmd->briefDescription()); + } + } + } + } + } +} + +//---------------------------------------------------------------------- + +void transferFunctionDocumentation() +{ + //printf("transferFunctionDocumentation()\n"); + MemberNameListIterator mnli(functionNameList); + 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; + if (md->isFunction() && !md->isStatic() && !md->isPrototype()) mdef=md; + } + if (mdef && mdec && + matchArguments(mdef->argumentList(),mdec->argumentList()) + ) /* match found */ + { + //printf("Found member %s: def in %s and dec in %s\n", + // mn->memberName(),mdef->getFileDef()->name(),mdec->getFileDef()->name()); + + /* copy documentation between function definition and declaration */ + if (mdec->briefDescription()) + { + mdef->setBriefDescription(mdec->briefDescription()); + } + else if (mdef->briefDescription()) + { + mdec->setBriefDescription(mdef->briefDescription()); + } + if (mdef->documentation()) + { + mdec->setDocumentation(mdef->documentation()); + } + else if (mdec->documentation()) + { + mdef->setDocumentation(mdec->documentation()); + } + } + } +} + + +//---------------------------------------------------------------------- +// Computes the base and super classes for each class in the tree + +void computeClassRelations(Entry *root) +{ + if ( + ( + ( + root->section & Entry::COMPOUND_MASK + ) + || + ( + (root->section & Entry::COMPOUNDDOC_MASK) && root->extends->count()>0 + ) + ) + && + root->name.length()>0 + ) + { + ClassDef *cd; + if ((cd=getClass(root->name))) + { + //printf("Class %s %d\n",cd->name().data(),root->extends->count()); + if (!cd->visited) + { + cd->visited=TRUE; // mark class as used (in case the are multiple classes + // with the same name!) + if (root->extends->count()>0) // there are base classes + { + QString scopePrefix; + Entry *p=root->parent; + // For nested classes the base class could also be nested! + // To find the correct scope, we try to prepend the scope to the base + // name, starting with the largest, most inner scope. + while (p->section&Entry::COMPOUND_MASK) + { + scopePrefix=p->name+"::"; + QList<BaseInfo> *baseList=root->extends; + BaseInfo *bi=baseList->first(); + while (bi) // for each base class + { + QString cName=scopePrefix+bi->name; + //printf("Base class %s\n",cName.data()); + ClassDef *baseClass=getClass(cName); + if (baseClass) // base class is documented + { + //printf("Adding!\n"); + // add base class to this class + cd->insertBaseClass(baseClass,bi->prot,bi->virt); + // add this class as super class to the base class + baseClass->insertSuperClass(cd,bi->prot,bi->virt); + } + //else // base class not documented + //{ + // warn("Warning: Base class %s referred to in file %s at line %d is not " + // "documented\n",s->data(),root->fileName.data(),root->startLine); + //} + bi=baseList->next(); + } + p=p->parent; + } + // The base class could ofcouse also be a non-nested class + QList<BaseInfo> *baseList=root->extends; + BaseInfo *bi=baseList->first(); + while (bi) // for each base class + { + ClassDef *baseClass=getClass(bi->name); + //printf("baseClass %s of %s found (%s and %s)\n", + // bi->name.data(), + // root->name.data(), + // (bi->prot==Private)?"private":((bi->prot==Protected)?"protected":"public"), + // (bi->virt==Normal)?"normal":"virtual" + // ); + int i; + QString templSpec,baseClassName=bi->name.copy(); + if (!baseClass && (i=bi->name.find('<'))!=-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. + baseClassName=bi->name.left(i); + baseClass=getClass(baseClassName); + templSpec=bi->name.right(bi->name.length()-i); + } + if (baseClass) // base class is documented + { + // add base class to this class + cd->insertBaseClass(baseClass,bi->prot,bi->virt,templSpec); + // add this class as super class to the base class + baseClass->insertSuperClass(cd,bi->prot,bi->virt,templSpec); + } + else // base class not documented + { + //printf("Found undocumented base class %s\n",bi->name.data()); + NamespaceDef *nd=cd->getNamespace(); + if (nd && (baseClass=getClass(nd->name()+"::"+baseClassName))) + // class is defined inside namespace + { + // add base class to this class + cd->insertBaseClass(baseClass,bi->prot,bi->virt,templSpec); + // add this class as super class to the base class + baseClass->insertSuperClass(cd,bi->prot,bi->virt,templSpec); + } + else // undocumented base class + { + baseClass=new ClassDef(bi->name,Entry::CLASS_SEC); + // add base class to this class + cd->insertBaseClass(baseClass,bi->prot,bi->virt,templSpec); + // add this class as super class to the base class + baseClass->insertSuperClass(cd,bi->prot,bi->virt,templSpec); + // the undocumented base was found in this file + baseClass->insertUsedFile(root->fileName); + // add class to the list + classList.inSort(baseClass); + //printf("ClassDict.insert(%s)\n",resolveDefines(fullName).data()); + //classDict.insert(resolveDefines(bi->name),baseClass); + classDict.insert(bi->name,baseClass); + } + } + bi=baseList->next(); + } + } +// else // class has no base classes +// { +// QString resName=resolveDefines(root->name); +// int i; +// // Check if this class is a template instance of another class. +// // If this is the case, we act as if this class `inherits' from the +// // template class. +// if ((i=resName.find('<'))!=-1) +// { +// ClassDef *baseClass=getClass(resName.left(i)); +// if (baseClass) +// { +// // add base class to this class +// cd->insertBaseClass(baseClass,Public,Normal); +// // add this class as super class to the base class +// baseClass->insertSuperClass(cd,Public,Normal); +// } +// } +// } + } // else class is already found + } + else if (root->name.right(2)!="::") + { + if (root->name.length()>0 && root->name[0]!='@') + warn("Warning: Compound %s\n" + " defined in file %s at line %d\n" + " is not documented\n", + root->name.data(),root->fileName.data(),root->startLine); + } + } + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + computeClassRelations(e); + } +} + +//----------------------------------------------------------------------- +// compute the references (anchors in HTML) for each member in the class + +void computeMemberReferences() +{ + ClassDef *cd=classList.first(); + while (cd) + { + cd->computeAnchors(); + cd=classList.next(); + } +} + +//----------------------------------------------------------------------- +// compute the references (anchors in HTML) for each function in the file + +void computeFunctionReferences() +{ + FileName *fn=inputNameList.first(); + while (fn) + { + FileDef *fd=fn->first(); + while (fd) + { + fd->computeAnchors(); + fd=fn->next(); + } + fn=inputNameList.next(); + } + NamespaceDef *nd=namespaceList.first(); + while (nd) + { + nd->computeAnchors(); + nd=namespaceList.next(); + } +} + + + +//---------------------------------------------------------------------- +// 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. + +void addMemberDocs(Entry *root,MemberDef *md, const char *funcDecl, + bool over_load) +{ + //printf("addMemberDocs: `%s'::`%s' `%s' funcDecl=`%s'\n", + // root->parent->name.data(),md->name().data(),md->argsString(),funcDecl); + QString fDecl=funcDecl; + // strip extern specifier + if (fDecl.left(7)=="extern ") fDecl=fDecl.right(fDecl.length()-7); + md->setDefinition(fDecl); + ClassDef *cd=md->memberClass(); + NamespaceDef *nd=md->getNamespace(); + if (matchArguments(md->argumentList(),root->argList, + cd ? cd->name().data() : 0, + nd ? nd->name().data() : 0 + ) + ) mergeArguments(md->argumentList(),root->argList); + if (over_load) // the \overload keyword was used + { + QString doc=getOverloadDocs(); + if (!root->doc.isNull()) + { + doc+="<p>"; + doc+=root->doc; + } + md->setDocumentation(doc); + } + else + { + // documentation outside a compound overrides the documentation inside it + if ( /* !md->isStatic() && !root->stat && do not replace doc of a static */ + ( + !md->documentation() || /* no docs yet */ + (root->parent->name.isNull() && /* or overwrite prototype docs */ + !root->proto && md->isPrototype() /* with member definition docs */ + ) + ) && root->doc.length()>0 + ) + { + md->setDocumentation(root->doc); + } + + // brief descriptions inside a compound override the documentation + // outside it + if ( /* !md->isStatic() && !root->stat && do not replace doc of static */ + ( + !md->briefDescription() || /* no docs yet */ + !root->parent->name.isNull() /* member of a class */ + ) && root->brief.length()>0 + ) + { + md->setBriefDescription(root->brief); + } + } + md->setDefFile(root->fileName); + md->setDefLine(root->startLine); + if (cd) cd->insertUsedFile(root->fileName); +} + +//---------------------------------------------------------------------- +// 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. + +bool findUnrelatedFunction(Entry *root, + const QString &namespaceName, + const char *name, + const char *, + const char *decl) +{ + MemberName *mn=0; + QString n=name; + if (n.find("::")!=-1) return FALSE; // skip undefined class members + //printf("findUnrelatedFunction(%s)\n",name); + if (n.length()>0 && (mn=functionNameDict[n])) // function name defined + { + int count=0; + MemberDef *md=mn->first(); + while (md) + { + NamespaceDef *nd=md->getNamespace(); + QString nsName = nd ? nd->name().data() : ""; + if (namespaceName.length()==0 || + nsName==namespaceName) + { + //printf("Searching for match between %s and %s\n", + // argListToString(md->argumentList()).data(), + // argListToString(root->argList).data()); + bool matching= + /*matchArguments(md->argsString(),args);*/ + (md->argumentList()==0 && root->argList->count()==0) || + matchArguments(md->argumentList(),root->argList,0,nsName); + if (matching) // add docs to the member + { + //printf("Match found\n"); + addMemberDocs(root,md,decl,FALSE); + count++; + } + } + md=mn->next(); + } + if (count==0) // more than one match (each member will get the same docs)! + { + warn("Warning: no matching members found for \n%s\n" + "in file %s at line %d\n", + decl,root->fileName.data(),root->startLine); + } +#if 0 + else if (count>1) // no match! + { + warn("Warning: multiple matching members for\n%s\n",decl); + if (mn->count()>0) // there is a member with that name + { + warn("Possible candidates are:\n"); + MemberDef *md=mn->first(); + while (md) // list all possible members with the same name + { + warn(" %s%s\n",md->name(),md->argsString()); + md=mn->next(); + } + } + } +#endif + } + else // got docs for an undefined member! + { + warn("Warning: documented function `%s' in file %s at line %d " + "was not defined \n",decl, + root->fileName.data(),root->startLine); + } + return TRUE; +} + + +//---------------------------------------------------------------------- +// This function tries to find a member (in a documented class/file/namespace) +// that corresponds to the function declaration given in `funcDecl'. +// +// The related field may be used to specify a related class name. +// It is only used if the class name cannot be extracted from the function +// declaration. +// +// The boolean overloaded is used to specify whether or not a standard +// overload documentation line should be generated. + +void findMember(Entry *root,QString funcDecl,QString related,bool overloaded, + bool isFunc) +{ + Debug::print(Debug::FindMembers,0, + "findMember(root=%p,funcDecl=`%s',related=`%s',overload=%d,isFunc=%d)\n", + root,funcDecl.data(),related.data(),overloaded,isFunc + ); + + QString scopeName; + QString className; + QString namespaceName; + QString classTempList; + QString funcType; + QString funcName; + QString funcArgs; + QString funcTempList; + QString exceptions; + bool isRelated=FALSE; + bool isFriend=FALSE; + + if (funcDecl.left(7)=="friend ") // treat friends as related members + { + funcDecl=funcDecl.right(funcDecl.length()-7); + isFriend=TRUE; + } + + // 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.length()>0 && funcDecl[0]!=' ') funcDecl.prepend(" "); + + // remove some superfluous spaces + funcDecl=substitute( + substitute( + substitute(funcDecl,"~ ","~"), + ":: ","::" + ), + " ::","::" + ); + + // extract information from the declarations + parseFuncDecl(funcDecl,scopeName,classTempList,funcType,funcName, + funcArgs,funcTempList,exceptions + ); + + // 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'\n",scopeName.data(),className.data()); + if (/*scopeName.isEmpty() &&*/ !related.isEmpty() && !isRelated) + { + isRelated=TRUE; + //scopeName=resolveDefines(related); + if (!scopeName.isEmpty() && scopeName!=related) + scopeName+="::"+related; + else + scopeName=related.copy(); + } + else if (scopeName.isEmpty() && related.isEmpty() && root->parent && + !root->parent->name.isNull()) + { + Entry *p=root->parent; + while (p) // get full scope as class name + { + if (((p->section & Entry::COMPOUND_MASK) || + p->section == Entry::NAMESPACE_SEC + ) && !p->name.isEmpty() && p->name[0]!='@' + ) + { + if (!scopeName.isEmpty()) scopeName.prepend("::"); + scopeName.prepend(p->name); + break; // stop here because the class name already contains + // the whole scope! + } + p=p->parent; + } + } + + if (scopeName.length()>0 && scopeName.find('<')==-1 && classTempList.length()==0 ) + { // class is a template, but no template name list found + ClassDef *cd=getClass(scopeName); + if (cd) // class exists + { + classTempList = cd->getTemplateNameString(); + } + } + + //printf("scopeName=`%s' className=`%s'\n",scopeName.data(),className.data()); + // rebuild the function declaration (needed to get the scope right). + if (scopeName.length()>0 && !isRelated && !isFriend) + { + if (funcType.length()>0) + { + if (isFunc) // a function -> we use argList for the arguments + { + funcDecl=funcType+" "+scopeName+classTempList+"::"+funcName+funcTempList; + } + else + { + funcDecl=funcType+" "+scopeName+classTempList+"::"+funcName+funcArgs; + } + } + else + { + if (isFunc) // a function => we use argList for the arguments + { + funcDecl=scopeName+classTempList+"::"+funcName+funcTempList; + } + else // variable => add `argument' list + { + funcDecl=scopeName+classTempList+"::"+funcName+funcArgs; + } + } + } + else // build declaration without scope + { + if (funcType.length()>0) // 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; + } + } + } + + QString fullFuncDecl=funcDecl.copy(); + if (isFunc) fullFuncDecl+=argListToString(root->argList); + + //printf("scopeName=`%s' className=`%s'\n",scopeName.data(),className.data()); + // see if (part of) the scope name is a namespace name + extractNamespaceName(scopeName,className,namespaceName); + //printf("scopeName=`%s' className=`%s'\n",scopeName.data(),className.data()); + + // destructor => do backward class name substitution if needed + //if (funcName.length()>0 && funcName[0]=='~') + // funcName="~"+resolveDefines(className); + // constructor => do backward class name substitution if needed + //if (funcName==className) funcName=resolveDefines(className); + //if (funcDecl.left(7)=="inline ") funcDecl=funcDecl.right(funcDecl.length()-7); + + Debug::print(Debug::FindMembers,0, + "findMember() Parse results:\n" + " namespaceName=`%s'\n" + " className=`%s`\n" + " classTempList=`%s'\n" + " funcType=`%s'\n" + " funcName=`%s'\n" + " funcArgs=`%s'\n" + " funcTempList=`%s'\n" + " funcDecl=`%s'\n" + " related=`%s'\n" + " exceptions=`%s'\n" + " isRelated=%d\n" + " isFiend=%d\n" + " isFunc=%d\n\n", + namespaceName.data(),className.data(),classTempList.data(), + funcType.data(),funcName.data(),funcArgs.data(),funcTempList.data(), + funcDecl.data(),related.data(),exceptions.data(),isRelated,isFriend, + isFunc + ); + + MemberName *mn; + if (funcName.length()>0) // function name is valid + { + if (!isRelated && (mn=memberNameDict[funcName])) // function name already found + { + if (className.length()>0) // class name is valid + { + int count=0; + MemberDef *md=mn->first(); + while (md) + { + ClassDef *cd=md->memberClass(); + //printf("Member %s member className=%s this className=%s\n",md->name().data(),cd->name().data(),className.data()); + ClassDef *tcd=0; + if (classTempList.length()>0) // try to find the correct specialization + { + tcd=getClass(scopeName+classTempList); + if (!tcd) tcd=getClass(scopeName); // try general class + } + else + { + tcd=getClass(scopeName); + } + //printf("tcd=%p\n",tcd); + if (cd && tcd==cd) + { + //printf("Class %s\n",cd->name().data()); + bool matching= + md->isVariable() || md->isTypedef() || // needed for function pointers + (md->argumentList()==0 && root->argList->count()==0) || + matchArguments(md->argumentList(), root->argList, + className,namespaceName); + if (matching) + { + addMemberDocs(root,md,funcDecl,overloaded); + count++; + } + } + md=mn->next(); + } + if (count==0) + warn("Warning: no matching member found for \n%s\n" + "in file %s at line %d\n", + fullFuncDecl.data(),root->fileName.data(),root->startLine); +#if 0 + else if (count>1) + { + warn("Warning: multiple matching members for\n%s\n",funcDecl.data()); + int matchCount=0; + MemberDef *md=mn->first(); + while (md) + { + if (md->memberClass() && className==md->memberClass()->name()) + matchCount++; + md=mn->next(); + } + if (matchCount>0) + { + warn("Possible candidates are:\n"); + md=mn->first(); + while (md) + { + ClassDef *cd=md->memberClass(); + if (cd && className==cd->name()) + warn(" %s::%s%s\n",md->memberClass()->name(), + md->name(),md->argsString()); + md=mn->next(); + } + } + } +#endif + } + 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 compatable. Using this should + // however be avoided, because it is error prone + MemberDef *md=mn->first(); + ASSERT(md); + ClassDef *cd=md->memberClass(); + ASSERT(cd); + QString className=cd->name().copy(); + md=mn->next(); + bool unique=TRUE; + while (md) + { + ClassDef *cd=md->memberClass(); + if (className!=cd->name()) unique=FALSE; + md=mn->next(); + } + if (unique) + { + MemberDef::MemberType mtype; + if (root->sig) mtype=MemberDef::Signal; + else if (root->slot) mtype=MemberDef::Slot; + else mtype=MemberDef::Function; + + // new overloaded member function + MemberDef *md=new MemberDef(funcType,funcName,funcArgs,exceptions, + root->protection,root->virt,root->stat,TRUE, + mtype,root->tArgList,root->argList); + md->setMemberClass(cd); + md->setDefinition(funcDecl); + QString doc=getOverloadDocs(); + doc+="<p>"; + doc+=root->doc; + md->setDocumentation(doc); + //md->setDecFile(root->fileName); + //md->setDecLine(root->startLine); + md->setDefFile(root->fileName); + md->setDefLine(root->startLine); + md->setPrototype(root->proto); + mn->inSort(md); + cd->insertMember(md); + cd->insertUsedFile(root->fileName); + } + } + else // unrelated function with the same name as a member + { + if (!findUnrelatedFunction(root,namespaceName,funcName+funcTempList,funcArgs,funcDecl)) + { + warn("Warning: Cannot determine class for function\n%s\n" + "in file %s at line %d\n",fullFuncDecl.data(), + root->fileName.data(),root->startLine); + } + } + } + else if (isRelated && related.length()>0) + { + if (className.isEmpty()) className=related.copy(); + ClassDef *cd; + if ((cd=getClass(scopeName))) + { + bool newMember=TRUE; // assume we have a new member + bool newMemberName=FALSE; + if ((mn=memberNameDict[funcName])==0) + { + mn=new MemberName(funcName); + newMemberName=TRUE; // we create a new member name + } + else + { + MemberDef *rmd=mn->first(); + while (rmd && newMember) // see if we got another member with matching arguments + { + newMember=newMember && + !matchArguments(rmd->argumentList(),root->argList,className,namespaceName); + if (newMember) rmd=mn->next(); + } + if (!newMember && rmd) // member already exists as rmd -> add docs + { + addMemberDocs(root,rmd,funcDecl,overloaded); + } + } + if (newMember) // need to create a new member + { + MemberDef::MemberType mtype; + if (root->sig) + mtype=MemberDef::Signal; + else if (root->slot) + mtype=MemberDef::Slot; + else + mtype=MemberDef::Function; + + // new related (member) function + MemberDef *md=new MemberDef(funcType,funcName,funcArgs,exceptions, + root->protection,root->virt,root->stat,TRUE, + mtype,root->tArgList,root->argList); + //printf("Related member name=`%s' decl=`%s'\n",funcName.data(),funcDecl.data()); + md->setMemberClass(cd); + md->setDefinition(funcDecl); + md->setDocumentation(root->doc); + md->setBriefDescription(root->brief); + md->setDefFile(root->fileName); + md->setDefLine(root->startLine); + md->setPrototype(root->proto); + mn->inSort(md); + cd->insertMember(md); + cd->insertUsedFile(root->fileName); + if (newMemberName) + { + //printf("Adding memberName=%s\n",mn->memberName()); + memberNameList.inSort(mn); + memberNameDict.insert(funcName,mn); + } + } + } + else + { + warn("Warning: class `%s' for related function `%s' is not " + "documented\n", className.data(),funcName.data()); + } + } + else // unrelated not overloaded member found + { + if (className.length()==0 && + !findUnrelatedFunction(root,namespaceName,funcName+funcTempList,funcArgs,funcDecl)) + { + warn("Warning: class for member %s (file %s at line %d) cannot " + "be found\n", funcName.data(),root->fileName.data(), + root->startLine); + } + } + } + else + { + // this should not be called + warn("Warning: member with no name found in %s at line %d\n", + root->fileName.data(),root->startLine); + } + return; +} + +//---------------------------------------------------------------------- +// find the members corresponding to the different documentation blocks +// that are extracted from the sources. + +void findMemberDocumentation(Entry *root) +{ + int i,l; + QRegExp re("([a-zA-Z0-9: ]*[ *]+[ ]*"); + Debug::print(Debug::FindMembers,0, + "root->type=`%s' root->name=`%s' root->args=`%s'\n", + root->type.data(),root->name.data(),root->args.data() + ); + bool isFunc=TRUE; + if ((i=re.match(root->type,0,&l))!=-1) // func variable/typedef to func ptr + { + root->args+=root->type.right(root->type.length()-i-l); + root->type=root->type.left(i+l); + isFunc=FALSE; + } + else if (root->name.find(re)!=-1 && root->name.find("operator")!=-1) + // func ptr entered with \fn, \var or \typedef + { + isFunc=FALSE; + } + else if ((root->type.isEmpty() && root->name.left(8)=="typedef ") + || root->args.find('(')==-1) + { + 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()); + findMember(root,root->name+root->args+root->exception,root->relates,FALSE,isFunc); + } + else if (root->section==Entry::OVERLOADDOC_SEC) + { + //printf("Overloaded member %s found\n",root->name.data()); + findMember(root,root->name,root->relates,TRUE,isFunc); + } + else if (root->section==Entry::FUNCTION_SEC && + (root->doc.length()>0 || root->brief.length()>0 || extractAllFlag)) + { + //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.length()>0) + { + findMember(root, + root->type+" "+root->inside+root->name+root->args+root->exception, + root->relates, + FALSE,isFunc); + } + else + { + findMember(root, + root->inside+root->name+root->args+root->exception, + root->relates, + FALSE,isFunc); + } + } + else if (root->section==Entry::VARIABLEDOC_SEC) + { + //printf("Documentation for variable %s found\n",root->name.data()); + //if (root->relates.length()>0) printf(" Relates %s\n",root->relates.data()); + findMember(root,root->name,root->relates,FALSE,FALSE); + } + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + if (e->section!=Entry::ENUM_SEC) findMemberDocumentation(e); + } +} + +//---------------------------------------------------------------------- +// find and add the enumeration to their classes, namespaces or files + +void findEnums(Entry *root) +{ + if (root->section==Entry::ENUM_SEC) + // non anonymous enumeration + { + MemberDef *md=0; + ClassDef *cd=0; + FileDef *fd=0; + NamespaceDef *nd=0; + MemberNameDict *mnd=0; + MemberNameList *mnl=0; + bool isGlobal; + //printf("Found enum with name `%s'\n",root->name.data()); + int i; + + QString name; + if ((i=root->name.findRev("::"))!=-1) // scope is specified + { + QString scope=root->name.left(i); // extract scope + name=root->name.right(root->name.length()-i-2); // extract name + cd=getClass(scope); + if (!cd) nd=namespaceDict[scope]; + } + else // no scope, check the scope in which the docs where found + { + if (( root->parent->section & Entry::COMPOUND_MASK ) + && root->parent->name.length()>0 + ) // found enum docs inside a compound + { + cd=getClass(root->parent->name); + } + name=root->name.copy(); + } + if (cd && name.length()>0) // found a enum inside a compound + { + //printf("Enum `%s'::`%s'\n",cd->name(),name.data()); + fd=0; + mnd=&memberNameDict; + mnl=&memberNameList; + isGlobal=FALSE; + } + else if (nd) // found enum inside namespace + { + mnd=&functionNameDict; + mnl=&functionNameList; + isGlobal=TRUE; + } + else // found a global enum + { + bool ambig; + fd=findFileDef(&inputNameDict,root->fileName,ambig); + mnd=&functionNameDict; + mnl=&functionNameList; + isGlobal=TRUE; + } + if (name.length()>0) + { + // new enum type + md = new MemberDef(0,name,0,0,root->protection,Normal,FALSE,FALSE, + MemberDef::Enumeration,0,0); + if (!isGlobal) md->setMemberClass(cd); else md->setFileDef(fd); + md->setDefFile(root->fileName); + md->setDefLine(root->startLine); + if (nd) + { + md->setDefinition(nd->name()+"::"+name); + nd->insertMember(md); + md->setNamespace(nd); + } + else if (isGlobal) + { + md->setDefinition(name); + fd->insertMember(md); + } + else if (cd) + { + md->setDefinition(cd->name()+"::"+name); + cd->insertMember(md); + cd->insertUsedFile(root->fileName); + } + md->setDocumentation(root->doc); + md->setBriefDescription(root->brief); + + MemberName *mn; + if ((mn=(*mnd)[name])) + { + // this is used if the same enum is in multiple namespaces/classes + mn->inSort(md); + } + else // new enum name + { + mn = new MemberName(name); + mn->inSort(md); + mnd->insert(name,mn); + mnl->inSort(mn); + //printf("add %s to new memberName. Now %d members\n", + // name.data(),mn->count()); + } + + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + MemberName *fmn=0; + if (e->name.length()>0 && (fmn=(*mnd)[e->name])) + // get list of members with the same name as the field + { + MemberDef *fmd=fmn->first(); + while (fmd) // search for the class with the right name + { + if (nd) + { + NamespaceDef *fnd=fmd->getNamespace(); + if (fnd==nd) + { + md->insertEnumField(fmd); + fmd->setEnumScope(md); + } + } + else if (isGlobal) + { + FileDef *ffd=fmd->getFileDef(); + if (ffd==fd) + { + md->insertEnumField(fmd); + fmd->setEnumScope(md); + } + } + else + { + ClassDef *fcd=fmd->memberClass(); + if (fcd==cd) + { + md->insertEnumField(fmd); // add field def to list + fmd->setEnumScope(md); // cross ref with enum name + } + } + fmd=fmn->next(); + } + } + } + } + } + else + { + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + findEnums(e); + } + } +} + +//---------------------------------------------------------------------- +// find the documentation blocks for the enumerations + +void findEnumDocumentation(Entry *root) +{ + if (root->section==Entry::ENUMDOC_SEC + && root->name.length()>0 + && root->name[0]!='@' // skip anonymous enums + ) + { + //printf("Found docs for enum with name `%s'\n",root->name.data()); + int i; + ClassDef *cd=0; + QString name; + if ((i=root->name.findRev("::"))!=-1) // scope is specified + { + QString scope=root->name.left(i); // extract scope + name=root->name.right(root->name.length()-i-2); // extract name + cd=getClass(scope); + //printf("Scope=`%s' Name=`%s'\n",scope.data(),name.data()); + } + else // no scope, check the scope in which the docs where found + { + if (( root->parent->section & Entry::COMPOUND_MASK ) + && root->parent->name.length()>0 + ) // found enum docs inside a compound + { + cd=getClass(root->parent->name); + } + name=root->name.copy(); + } + if (name.length()>0) + { + bool found=FALSE; + if (cd) + { + //printf("Enum: scope=`%s' name=`%s'\n",cd->name(),name.data()); + QString className=cd->name().copy(); + MemberName *mn=memberNameDict[name]; + if (mn) + { + MemberDef *md=mn->first(); + while (md && !found) + { + ClassDef *cd=md->memberClass(); + if (cd && cd->name()==className) + { + // documentation outside a compound overrides the documentation inside it + if (!md->documentation() || root->parent->name.length()==0) + { + md->setDocumentation(root->doc); + } + + // brief descriptions inside a compound override the documentation + // outside it + if (!md->briefDescription() || root->parent->name.length()>0) + { + md->setBriefDescription(root->brief); + } + found=TRUE; + } + md=mn->next(); + } + } + else + { + //printf("MemberName %s not found!\n",name.data()); + } + } + else // enum outside class + { + MemberDef *md; + MemberName *mn=functionNameDict[name]; + if (mn && (md=mn->first())) + { + md->setDocumentation(root->doc); + md->setBriefDescription(root->brief); + found=TRUE; + } + } + if (!found) + { + warn("Warning: Documentation for undefined enum `%s' found at" + " line %d of file %s\n",name.data(), + root->startLine,root->fileName.data()); + } + } + } + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + findEnumDocumentation(e); + } +} + +//---------------------------------------------------------------------- +// recursive function: +// returns TRUE iff class definition `bcd' represents an (in)direct base +// class of class definition `cd'. + +bool isBaseClass(ClassDef *bcd,ClassDef *cd) +{ + bool found=FALSE; + //printf("isBaseClass(cd=%s) looking for %s\n",cd->name().data(),bcd->name().data()); + BaseClassListIterator bcli(*cd->baseClasses()); + for ( ; bcli.current() && !found ; ++bcli) + { + ClassDef *ccd=bcli.current()->classDef; + //printf("isBaseClass() baseclass %s\n",ccd->name().data()); + if (ccd==bcd) + found=TRUE; + else + found=isBaseClass(bcd,ccd); + } + return found; +} + +//---------------------------------------------------------------------- +// 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. + +void computeMemberRelations() +{ + MemberName *mn=memberNameList.first(); + while (mn) // for each member name + { + MemberNameIterator mdi(*mn); + for ( ; mdi.current() ; ++mdi) // for each function with a specific name + { + MemberDef *md=mdi.current(); + MemberNameIterator bmdi(*mn); + for ( ; bmdi.current() ; ++bmdi) // for each other function with that name + { + MemberDef *bmd=bmdi.current(); + if (md!=bmd && bmd->memberClass() && md->memberClass() && + isBaseClass(bmd->memberClass(),md->memberClass())) + { + //printf("Checking Base: %s\nWith normal : %s\n",bmd->definition(),md->definition()); + if (/*matchArguments(bmd->argsString(),md->argsString())*/ + matchArguments(bmd->argumentList(),md->argumentList()) + ) + { + //printf("Base: %s\nNorm: %s\n",bmd->definition(),md->definition()); + ClassDef *bmcd = bmd->memberClass(); + ClassDef *mcd = md->memberClass(); + if (mcd && bmcd && + (bmcd->protection()!=Private || extractPrivateFlag) && + (bmcd->hasDocumentation() || !hideClassFlag) && + (mcd->protection()!=Private || extractPrivateFlag) && + (mcd->hasDocumentation() || !hideClassFlag) + ) + { + md->setReimplements(bmd); + bmd->insertReimplementedBy(md); + } + } + } + } + } + mn=memberNameList.next(); + } +} + +//---------------------------------------------------------------------------- +// recusively merges the `all members' lists of class cd's base classes +// with that of class `cd' itself. + +void mergeMembers(ClassDef *cd,BaseClassList *bcl) +{ + //if (mcd->flag==TRUE) + //{ + // err("Error: Cyclic inhertance dependency found for class %s\n",mcd->name()); + // return; + //} + //mcd->flag=TRUE; + + BaseClassListIterator bcli(*bcl); + BaseClassDef *bcd; + for ( ; (bcd=bcli.current()) ; ++bcli ) + { + ClassDef *bClass=bcd->classDef; + // merge the members of bClass with the onces from cd + + mergeMembers(bClass,bClass->baseClasses()); + // the all member list of the branch until bClass is now complete + // so we can merge it with cd + + MemberNameInfoList *srcMnl = bClass->memberNameInfoList(); + MemberNameInfoDict *dstMnd = cd->memberNameInfoDict(); + MemberNameInfoList *dstMnl = cd->memberNameInfoList(); + + MemberNameInfoListIterator srcMnili(*srcMnl); + MemberNameInfo *srcMni; + for ( ; (srcMni=srcMnili.current()) ; ++srcMnili) + { + //printf("Base member name %s\n",srcMni->memberName()); + MemberNameInfo *dstMni; + if ((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 super 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; + MemberNameInfoIterator dstMnii(*dstMni); + MemberInfo *dstMi; + for ( ; (dstMi=dstMnii.current()) && !found; ++dstMnii ) + { + MemberDef *dstMd = dstMi->memberDef; + if (srcMd!=dstMd) // different members + { + ClassDef *srcCd = srcMd->memberClass(); + ClassDef *dstCd = dstMd->memberClass(); + //printf("Is %s a base class of %s?\n",srcCd->name(),dstCd->name()); + if (srcCd==dstCd || isBaseClass(srcCd,dstCd)) + // member is in the same or a base class + { + found = + /*matchArguments(srcMd->argsString(),dstMd->argsString());*/ + matchArguments(srcMd->argumentList(),dstMd->argumentList()); + } + 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()); + + QString scope=dstMi->scopePath.left(dstMi->scopePath.find("::")+2); + 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 + if ((srcMi->virt==Virtual && dstMi->virt==Virtual) || + bClass->name()+"::"+srcMi->scopePath == dstMi->scopePath + ) 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()); + + QString scope=dstMi->scopePath.left(dstMi->scopePath.find("::")+2); + if (scope!=dstMi->ambiguityResolutionScope.left(scope.length())) + dstMi->ambiguityResolutionScope.prepend(scope); + ambigue=TRUE; + } + } + } + if (!found && srcMd->protection()!=Private) + { + Specifier virt=srcMi->virt; + if (srcMi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt; + MemberInfo *newMi = new MemberInfo(srcMd,bcd->prot,virt); + //if (srcMi->memberDef->memberClass()!=bClass) + newMi->scopePath=bClass->name()+"::"+srcMi->scopePath; + if (ambigue) + { + //printf("$$ New member %s %s add scope %s::\n", + // srcMi->ambiguityResolutionScope.data(), + // srcMd->name().data(), + // bClass->name().data()); + + QString scope=bClass->name().copy(); scope+="::"; + if (scope!=srcMi->ambiguityResolutionScope.left(scope.length())) + newMi->ambiguityResolutionScope= + scope+srcMi->ambiguityResolutionScope; + } + dstMni->append(newMi); + } + } + } + else // base class has a member that is not in the super class => copy + { + // create a deep copy of the list (only the MemberInfo's will be + // copied, not the actual MemberDef's) + MemberNameInfo *newMni = new MemberNameInfo(srcMni->memberName()); + + // copy the member(s) from the base to the super class + MemberNameInfoIterator mnii(*srcMni); + MemberInfo *mi; + for (;(mi=mnii.current());++mnii) + { + if (mi->memberDef->protection()!=Private) + { + Specifier virt=mi->virt; + if (mi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt; + MemberInfo *newMi=new MemberInfo(mi->memberDef,bcd->prot,virt); + //if (mi->memberDef->memberClass()!=bClass) + newMi->scopePath=bClass->name()+"::"+mi->scopePath; + newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope.copy(); + newMni->append(newMi); + } + } + + // add it to the list and dictionary + dstMnl->inSort(newMni); + dstMnd->insert(newMni->memberName(),newMni); + } + } + } +} + +//---------------------------------------------------------------------------- +// builds the list of all members for each class + +void buildCompleteMemberLists() +{ + ClassDef *cd; + ClassListIterator cli(classList); + for (;(cd=cli.current());++cli) + { + //if (!cd->isReference()) printf("Building member for class %s\n",cd->name()); + //ClassListIterator vcli(classList); + //for (;(vcd=vcli.current());++vcli) vcd->flag = FALSE; + if (!cd->isReference() && // not an external class + cd->superClasses()->count()==0 && // is a root of the hierarchy + cd->baseClasses()->count()>0) // and has at least one base class + { + //printf("merging members for class %s\n",cd->name()); + mergeMembers(cd,cd->baseClasses()); + } + } +} + +//---------------------------------------------------------------------------- + +void generateFileDocs() +{ + if (documentedFiles==0) return; + writeFileIndex(*outputList); + + if (inputNameList.count()>0) + { + FileName *fn=inputNameList.first(); + while (fn) + { + FileDef *fd=fn->first(); + while (fd) + { + if (!fd->isReference() && fd->hasDocumentation()) + { + msg("Generating docs for file %s...\n",fd->name().data()); + fd->writeDocumentation(*outputList); + } + fd=fn->next(); + } + fn=inputNameList.next(); + } + } +} + +//---------------------------------------------------------------------------- +// generate the documentation of all classes + +void generateClassDocs() +{ + // write the installdox script if necessary + if (generateHtml && (tagFileList.count()>0 || searchEngineFlag)) + writeInstallScript(); + + msg("Generating index page...\n"); + writeIndex(*outputList); + + msg("Generating compound index...\n"); + writeAnnotatedIndex(*outputList); + + msg("Generating hierarchical class index...\n"); + writeHierarchicalIndex(*outputList); + + if (includeFiles.count()>0) + { + msg("Generating header index...\n"); + writeHeaderIndex(*outputList); + } + + msg("Generating member index...\n"); + writeMemberIndex(*outputList); + + if (exampleList.count()>0) + { + msg("Generating example index...\n"); + } + + ClassListIterator cli(classList); + for ( ; cli.current() ; ++cli ) + { + ClassDef *cd=cli.current(); + if (!cd->isReference() && + //!cd->name().isEmpty() && + //cd->name().at(0)!='@' && + //(cd->protection()!=Private || extractPrivateFlag) && + //(cd->hasDocumentation() || !hideClassFlag) + cd->isVisible() + ) + // skip external references and anonymous compounds + { + msg("Generating docs for compound %s...\n",cd->name().data()); + + cd->writeDocumentation(*outputList); + cd->writeMemberList(*outputList); + if (verbatimHeaderFlag) cd->writeIncludeFile(*outputList); + } + } +} + +//---------------------------------------------------------------------------- + +void findDefineDocumentation(Entry *root) +{ + if ((root->section==Entry::DEFINEDOC_SEC || + root->section==Entry::DEFINE_SEC) && root->name.length()>0 + ) + { + //printf("found define `%s' `%s' brief=`%s' doc=`%s'\n", + // root->name.data(),root->args.data(),root->brief.data(),root->doc.data()); + MemberName *mn=functionNameDict[root->name]; + if (mn) + { + int count=0; + MemberDef *md=mn->first(); + while (md) + { + if (md->memberType()==MemberDef::Define) count++; + md=mn->next(); + } + if (count==1) + { + md=mn->first(); + while (md) + { + if (md->memberType()==MemberDef::Define) + { + if (md->documentation().isEmpty()) + md->setDocumentation(root->doc); + if (md->briefDescription().isEmpty()) + md->setBriefDescription(root->brief); + } + md=mn->next(); + } + } + else if (count>1 && (root->doc.length()>0 || root->brief.length()>0)) + // multiple defines don't know where to add docs + { + md=mn->first(); + while (md) + { + if (md->memberType()==MemberDef::Define) + { + FileDef *fd=md->getFileDef(); + if (fd && fd->absFilePath()==root->fileName) + // doc and define in the same file assume they belong together. + { + if (md->documentation().isEmpty()) + md->setDocumentation(root->doc); + if (md->briefDescription().isEmpty()) + md->setBriefDescription(root->brief); + } + } + md=mn->next(); + } + //warn("Warning: 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 // define not found + { + warn("Warning: documentation for unknown define %s found at line %d of " + "file %s\n",root->name.data(),root->startLine,root->fileName.data()); + } + } + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + findDefineDocumentation(e); + } +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// create a (sorted) list of separate documentation pages + +void buildPageList(Entry *root) +{ + if (root->section == Entry::PAGEDOC_SEC) + { + if (root->name.length()>0) + { + PageInfo *pi=0; + if ((pi=pageDict[root->name])) + { + //warn("Warning: Page %s was already documented. Ignoring documentation " + // "at line %d of %s\n",root->name.data(),root->startLine, + // root->fileName.data()); + + // append documentation block to the page. + pi->doc+="\n\n"+root->doc; + } + else + { + QString baseName=root->name.copy(); + if (baseName.right(4)==".tex") + baseName=baseName.left(baseName.length()-4); + else if (baseName.right(5)==".html") + baseName=baseName.left(baseName.length()-5); + pi=new PageInfo(baseName, root->doc, + root->args.stripWhiteSpace()); + pageList.append(pi); + pageDict.insert(baseName,pi); + if (pi->title.length()>0) + { + QString pageName; + if (caseSensitiveNames) + pageName=pi->name.copy(); + else + pageName=pi->name.lower(); + //outputList->writeTitle(pi->name,pi->title); + SectionInfo *si=new SectionInfo(pageName+".html", + pi->name,pi->title,FALSE); + //printf("Adding section info %s\n",pi->name.data()); + sectionDict.insert(pi->name,si); + } + } + } + } + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + buildPageList(e); + } +} + +//---------------------------------------------------------------------------- +// generate all separate documentation pages + +void generatePageDocs() +{ + PageInfo *pi=pageList.first(); + while (pi) + { + if (!pi->title.isEmpty()) + { + msg("Generating docs for page %s...\n",pi->title.data()); + } + else + { + msg("Generating docs for page %s...\n",pi->name.data()); + } + outputList->disable(OutputGenerator::Man); + QString pageName; + if (caseSensitiveNames) + pageName=pi->name.copy(); + else + pageName=pi->name.lower(); + + startFile(*outputList,pageName,pi->title); + SectionInfo *si=0; + if (pi->title.length()>0 && pi->name.length()>0 && + (si=sectionDict[pi->name])!=0) + { + outputList->writeSection(si->label,si->title,FALSE); + } + parseDoc(*outputList,0,0,pi->doc); + endFile(*outputList); + outputList->enable(OutputGenerator::Man); + pi=pageList.next(); + } +} + +//---------------------------------------------------------------------------- +// create a (sorted) list & dictionary of example pages + +void buildExampleList(Entry *root) +{ + if (root->section == Entry::EXAMPLE_SEC) + { + if (root->name.length()>0) + { + if (exampleDict[root->name]) + { + warn("Warning: Example %s was already documented. Ignoring " + "documentation at line %d of %s\n",root->name.data(), + root->startLine,root->fileName.data()); + } + else + { + PageInfo *pi=new PageInfo(root->name,root->doc,root->args); + exampleList.inSort(pi); + exampleDict.insert(root->name,pi); + } + } + } + //EntryList *entryList=root->sublist; + //Entry *e = entryList->first(); + //while (e) + //{ + // buildExampleList(e); + // e=entryList->next(); + //} + EntryListIterator eli(*root->sublist); + Entry *e; + for (;(e=eli.current());++eli) + { + buildExampleList(e); + } +} + +//---------------------------------------------------------------------------- +// generate the example documentation + +void generateExampleDocs() +{ + PageInfo *pi=exampleList.first(); + while (pi) + { + msg("Generating docs for example %s...\n",pi->name.data()); + QString n=convertSlashes(pi->name,TRUE)+"-example"; + startFile(*outputList,n,"Example Documentation"); + //outputList->writeTitle(pi->name,pi->name); + parseExample(*outputList,pi->doc+"\n\\include "+pi->name,pi->name); + endFile(*outputList); + pi=exampleList.next(); + } +} + +//---------------------------------------------------------------------------- +// generate module pages + +void generateGroupDocs() +{ + GroupListIterator gli(groupList); + GroupDef *gd; + for (;(gd=gli.current());++gli) + { + //printf("group %s #members=%d\n",gd->name().data(),gd->countMembers()); + if (gd->countMembers()>0) gd->writeDocumentation(*outputList); + } +} + +//---------------------------------------------------------------------------- +// generate module pages + +void generateNamespaceDocs() +{ + writeNamespaceIndex(*outputList); + + NamespaceListIterator nli(namespaceList); + NamespaceDef *nd; + for (;(nd=nli.current());++nli) + { + msg("Generating docs for namespace %s\n",nd->name().data()); + nd->writeDocumentation(*outputList); + } +} + +//---------------------------------------------------------------------------- +// generate files for the search engine + +void generateSearchIndex() +{ + if (searchEngineFlag && generateHtml) + { + // create search index + QString fileName; + writeSearchButton(htmlOutputDir); + + // create cgi script + fileName = htmlOutputDir+"/"+cgiName; + QFile f(fileName); + if (f.open(IO_WriteOnly)) + { + QTextStream t(&f); + t << "#!/bin/sh" << endl + << "DOXYSEARCH=" << binAbsPath << "/doxysearch" << endl + << "DOXYPATH=" << docAbsPath << " "; + + char *s=extDocPathList.first(); + while (s) + { + t << s << " "; + s=extDocPathList.next(); + } + + t << endl + << "if [ -f $DOXYSEARCH ]" << endl + << "then" << endl + << " $DOXYSEARCH $DOXYPATH" << endl + << "else" << endl + << " echo \"Content-Type: text/html\"" << endl + << " echo \"\"" << endl + << " echo \"<H1>Error: $DOXYSEARCH not found. Check cgi script!\"" << endl + << "fi" << endl; + + f.close(); + struct stat stat_struct; + stat(fileName,&stat_struct); +#if !defined(_WIN32) + chmod(fileName,stat_struct.st_mode|S_IXUSR|S_IXGRP|S_IXOTH); +#endif + } + else + { + err("Error: Cannot open file %s for writing\n",fileName.data()); + } + + // create config file + fileName = htmlOutputDir+"/search.cfg"; + f.setName(fileName); + if (f.open(IO_WriteOnly)) + { + QTextStream t(&f); + t << docURL << endl << cgiURL << "/" << cgiName << endl; + f.close(); + } + else + { + err("Error: Cannot open file %s for writing\n",fileName.data()); + } + //outputList->generateExternalIndex(); + outputList->disableAllBut(OutputGenerator::Html); + startFile(*outputList,"header.html","Search Engine",TRUE); + outputList->endPlainFile(); + outputList->startPlainFile("footer.html"); + endFile(*outputList,TRUE); + outputList->enableAll(); + } +} + +//---------------------------------------------------------------------------- +// generate the configuration file + +void generateConfigFile(const char *configFile,bool shortList) +{ + QFileInfo fi(configFile); + QFile f(configFile); + + if (fi.exists()) // create a backup + { + QDir dir=fi.dir(); + dir.rename(fi.fileName(),fi.fileName()+".bak"); + } + if (f.open(IO_WriteOnly)) + { + writeTemplateConfig(&f,shortList); + f.close(); + msg("\n\nConfiguration file `%s' created.\n\n",configFile); + msg("Now edit the configuration file and enter\n\n"); + if (strcmp(configFile,"Doxyfile") || strcmp(configFile,"doxyfile")) + msg(" doxygen %s\n\n",configFile); + else + msg(" doxygen\n\n"); + msg("to generate the documentation for your project\n\n"); + } + else + { + err("Error: Cannot open file %s for writing\n"); + exit(1); + } +} + +//---------------------------------------------------------------------------- +// read and parse a tag file + +bool readLineFromFile(QFile &f,QString &s) +{ + char c=0; + s.resize(0); + while (!f.atEnd() && (c=f.getch())!='\n') s+=c; + return f.atEnd(); +} + +void readTagFile(const char *file) +{ + QFileInfo fi(file); + if (!fi.exists() || !fi.isFile()) + { + err("Error: Tag file `%s' does not exist or is not a file\n",file); + exit(1); + } + msg("Reading tag file %s...\n",file); + parseTagFile(file); +} + +//---------------------------------------------------------------------------- +// returns TRUE if the name of the file represented by `fi' matches +// one of the file patterns in the `patList' list. + +bool patternMatch(QFileInfo *fi,QStrList *patList) +{ + bool found=FALSE; + if (patList) + { + char *pattern=patList->first(); + while (pattern && !found) + { + found = found || QDir::match(pattern,fi->fileName()); + pattern=patList->next(); + } + } + return found; +} + +//---------------------------------------------------------------------------- +// reads a file into an array and filters out any 0x00 and 0x06 bytes, +// because these are special for the parser. + +void copyAndFilterFile(const char *fileName,BufStr &dest) +{ + // try to open file + int size=0; + uint oldPos = dest.curPos(); + + QFileInfo fi(fileName); + if (!fi.exists()) return; + if (inputFilter.isEmpty()) + { + QFile f(fileName); + if (!f.open(IO_ReadOnly)) + { + err("Error: could not open file %s\n",fileName); + return; + } + size=fi.size(); + // read the file + dest.skip(size); + if (f.readBlock(dest.data()+oldPos,size)!=size) + { + err("Error while reading file %s\n",fileName); + return; + } + } + else + { + int c; +// char *p=dest; + QString cmd=inputFilter+" "+fileName; + FILE *f=popen(cmd,"r"); + if (!f) + { + err("Error: could not execute filter %s\n",inputFilter.data()); + return; + } + while ((c=fgetc(f))!=EOF) dest.addChar(c),size++; + } + // filter unwanted bytes from the resulting data + uchar *p=(uchar *)dest.data()+oldPos; + uchar conv[256]; + int i; + for (i=0;i<256;i++) conv[i]=i; + conv[0x06]=0x20; // replace the offending characters with spaces + conv[0x00]=0x20; + // remove any special markers from the input + for (i=0;i<size;i++,p++) *p=conv[*p]; + // adjust pointer +} + +//---------------------------------------------------------------------------- +// Reads a file to a string. +// The name of the file is written in front of the file's contents and +// between 0x06 markers + + +void readFiles(BufStr &output) +{ + QString *s=inputFiles.first(); +// char *p=output.data(); + while (s) + { + QString fileName=*s; + + //int fileSize=fi->fileInfo()->size(); + int fileNameSize=fileName.length(); + //int streamLength=fileSize+fileNameSize+4; + + //QString fileText(streamLength); + + // add begin filename marker +// *p++=0x06; + output.addChar(0x06); + // copy filename +// memcpy(p,fileName.data(),fileNameSize); +// p+=fileNameSize; + output.addArray(fileName.data(),fileNameSize); + + // add end filename marker +// *p++=0x06; + output.addChar(0x06); +// *p++='\n'; // to make ^ work while scanning the first line of a file! + output.addChar('\n'); + if (preprocessingFlag) + { + msg("Preprocessing %s...\n",s->data()); + preprocessFile(fileName,output); + } + else + { + msg("Reading %s...\n",s->data()); + copyAndFilterFile(fileName,output); + } + + s=inputFiles.next(); + } +// *p++='\0'; + output.addChar(0); + //printf("Output after preprocessing:\n---------\n%s\n----------\n",output.data()); + //printf("Final length = %d\n",p-output.data()); +} + +//---------------------------------------------------------------------------- +// 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 + ) +{ + QDir dir((const char *)fi->absFilePath()); + dir.setFilter( QDir::Files | QDir::Dirs ); + int totalSize=0; + + const QFileInfoList *list = dir.entryInfoList(); + QFileInfoListIterator it( *list ); + QFileInfo *cfi; + + while ((cfi=it.current())) + { + if (exclDict==0 || exclDict->find(cfi->absFilePath())==0) + { // file should not be excluded + if (!cfi->exists() || !cfi->isReadable()) + { + err("Error: source %s is not a readable file or directory... skipping.\n",cfi->absFilePath().data()); + } + else if (cfi->isFile() && + patternMatch(cfi,patList) && !patternMatch(cfi,exclPatList)) + { + totalSize+=cfi->size()+cfi->absFilePath().length()+3; + QString name=cfi->fileName(); + if (fnDict) + { + FileDef *fd=new FileDef(cfi->dirPath()+"/",name); + FileName *fn=0; + if (name.length()>0 && (fn=(*fnDict)[name])) + { + fn->append(fd); + } + else + { + fn = new FileName(name); + fn->append(fd); + if (fnList) fnList->inSort(fn); + fnDict->insert(name,fn); + } + } + QString *rs=0; + if (resultList || resultDict) + { + rs=new QString(cfi->absFilePath()); + } + if (resultList) resultList->append(rs); + if (resultDict) resultDict->insert(cfi->absFilePath(),rs); + } + else if (recursiveFlag && cfi->isDir() && cfi->fileName()!="." && + cfi->fileName()!="..") + { + cfi->setFile(cfi->absFilePath()); + totalSize+=readDir(cfi,fnList,fnDict,exclDict, + patList,exclPatList,resultList,resultDict); + } + } + ++it; + } + return totalSize; +} + +//---------------------------------------------------------------------------- +// read the file with name `name' into a string. + +QString readExampleFile(const char *name) +{ + QString example; + QFileInfo fi(name); + if (fi.exists()) + { + QFile f((const char *)fi.absFilePath()); + if (f.open(IO_ReadOnly)) + { + example.resize(fi.size()+1); + if ((int)fi.size()!=f.readBlock(example.data(),fi.size())) + { + err("Error while reading file %s\n",fi.absFilePath().data()); + //exit(1); + return ""; + } + example.at(fi.size())='\0'; + } + else + { + err("Error opening file %s\n",fi.absFilePath().data()); + //exit(1); + return ""; + } + } + else + { + err("Error: example file %s does not exist\n",name); + exit(1); + } + return example; +} + +//---------------------------------------------------------------------------- +// 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 + ) +{ + QFileInfo fi(s); + int totalSize=0; + { + if (exclDict==0 || exclDict->find(fi.absFilePath())==0) + { + if (!fi.exists() || !fi.isReadable()) + { + err("Error: source %s is not a readable file or directory... skipping.\n",s); + } + else if (fi.isFile()) + { + totalSize+=fi.size()+fi.absFilePath().length()+3; //readFile(&fi,fiList,input); + //fiList->inSort(new FileInfo(fi)); + QString name=fi.fileName(); + if (fnDict) + { + FileDef *fd=new FileDef(fi.dirPath(TRUE)+"/",name); + FileName *fn=0; + if (name.length()>0 && (fn=(*fnDict)[name])) + { + fn->append(fd); + } + else + { + fn = new FileName(name); + fn->append(fd); + if (fnList) fnList->inSort(fn); + fnDict->insert(name,fn); + } + } + QString *rs=0; + if (resultList || resultDict) + { + rs=new QString(fi.absFilePath()); + } + if (resultList) resultList->append(rs); + if (resultDict) resultDict->insert(fi.absFilePath(),rs); + } + else if (fi.isDir()) // readable dir + totalSize+=readDir(&fi,fnList,fnDict,exclDict,patList, + exclPatList,resultList,resultDict); + } + } + return totalSize; +} + +//---------------------------------------------------------------------------- + +void readFormulaRepository() +{ + QFile f(htmlOutputDir+"/formula.repository"); + if (f.open(IO_ReadOnly)) // open repository + { + QTextStream t(&f); + QString line; + while (!t.eof()) + { + line=t.readLine(); + int se=line.find(':'); // find name and text separator. + if (se==-1) + { + warn("Warning: formula.repository is corrupted!\n"); + break; + } + else + { + QString formName = line.left(se); + QString formText = line.right(line.length()-se-1); + Formula *f=new Formula(formText); + formulaList.append(f); + formulaDict.insert(formText,f); + formulaNameDict.insert(formName,f); + } + } + } +} + +//---------------------------------------------------------------------------- +// print the usage of doxygen + +void usage(const char *name) +{ + msg("Doxygen version %s\nCopyright Dimitri van Heesch 1997-1999\n\n",versionString); + msg("You can use doxygen in two ways:\n\n"); + msg("1) Use doxygen to generate a template configuration file:\n"); + msg(" %s [-s] -g [configName]\n\n",name); + msg(" if -s is specified the comments in the config file will be omitted.\n\n"); + msg("2) Use doxygen to generate documentation using an existing "); + msg("configuration file:\n"); + msg(" %s [configName]\n\n",name); + msg("If configName is omitted `Doxyfile' will be used as a default.\n\n"); + exit(1); +} + +//---------------------------------------------------------------------------- +// read the argument of option `c' from the comment argument list and +// update the option index `optind'. + +const char *getArg(int argc,char **argv,int &optind) +{ + char *s=0; + if (strlen(&argv[optind][2])>0) + s=&argv[optind][2]; + else if (optind+1<argc) + s=argv[++optind]; + return s; +} + +//---------------------------------------------------------------------------- + +int main(int argc,char **argv) +{ + + initPreprocessor(); + + /************************************************************************** + * Handle arguments * + **************************************************************************/ + + char *s; + int optind=1; + const char *configName=0; + const char *debugLabel; + bool genConfig=FALSE; + bool shortList=FALSE; + while (optind<argc && argv[optind][0]=='-') + { + switch(argv[optind][1]) + { + case 'g': + genConfig=TRUE; + configName=getArg(argc,argv,optind); + if (!configName) configName="Doxyfile"; + break; + case 'd': + debugLabel=getArg(argc,argv,optind); + Debug::setFlag(debugLabel); + break; + case 's': + shortList=TRUE; + break; + case 'h': + case '?': + usage(argv[0]); + break; + default: + err("Unknown option -%c\n",argv[optind][1]); + usage(argv[0]); + } + optind++; + } + + /************************************************************************** + * Parse or generate the config file * + **************************************************************************/ + + if (genConfig) + { + generateConfigFile(configName,shortList); + exit(1); + } + + QFileInfo configFileInfo1("Doxyfile"),configFileInfo2("doxyfile"); + QString config; + if (optind>=argc) + { + if (configFileInfo1.exists()) + config=fileToString("Doxyfile"); + else if (configFileInfo2.exists()) + { + config=fileToString("doxyfile"); + } + else + { + err("Doxyfile not found and no input file specified!\n"); + usage(argv[0]); + } + } + else + config=fileToString(argv[1]); + + parseConfig(config); + + /************************************************************************** + * Initialize output generators * + **************************************************************************/ + + outputList = new OutputList(TRUE); + if (generateHtml) + { + outputList->add(new HtmlGenerator); + HtmlGenerator::init(); + } + if (generateLatex) + { + outputList->add(new LatexGenerator); + LatexGenerator::init(); + } + if (generateMan) + { + outputList->add(new ManGenerator); + ManGenerator::init(); + } + + /************************************************************************** + * Read and preprocess input * + **************************************************************************/ + + // gather names of all files in the include path + msg("Searching for include files...\n"); + s=includePath.first(); + while (s) + { + readFileOrDirectory(s,0,&includeNameDict,0,&filePatternList, + &excludePatternList,0,0); + s=includePath.next(); + } + + msg("Searching for example files...\n"); + s=examplePath.first(); + while (s) + { + readFileOrDirectory(s,0,&exampleNameDict,0,&filePatternList, + &excludePatternList,0,0); + s=examplePath.next(); + } + + msg("Searching for files to exclude\n"); + s=excludeSources.first(); + while (s) + { + readFileOrDirectory(s,0,0,0,&filePatternList, + 0,0,&excludeNameDict); + s=excludeSources.next(); + } + + msg("Reading input files...\n"); + int inputSize=0; + s=inputSources.first(); + while (s) + { + inputSize+=readFileOrDirectory(s,&inputNameList, + &inputNameDict,&excludeNameDict, + &filePatternList,&excludePatternList, + &inputFiles,0); + s=inputSources.next(); + } + //msg("Input size %d bytes\n",inputSize); + + BufStr input(inputSize+1); // Add one byte extra for \0 termination + readFiles(input); + + if (input.length()==0) + { + warn("No input read, no output generated!\n"); + exit(1); + } + else + { + msg("Read %d bytes\n",input.length()); + } + + /************************************************************************** + * Handle Tag Files * + **************************************************************************/ + + msg("Reading tag files\n"); + + s=tagFileList.first(); + while (s) + { + readTagFile(s); + s=tagFileList.next(); + } + + QFile *tag =new QFile(genTagFile); + if (genTagFile.length()>0) + { + if (!tag->open(IO_WriteOnly)) + { + err("Error: cannot open tag file %s for writing\n",genTagFile.data()); + exit(1); + } + tagFile.setDevice(tag); + } + + /************************************************************************** + * Gather information * + **************************************************************************/ + + // Notice: the order of the function calls below is very important! + + if (generateHtml) + { + msg("Reading formula repository...\n"); + readFormulaRepository(); + } + + Entry *root=new Entry; + root->program=input; + + msg("Parsing input...\n"); + parseMain(root); // build a tree of entries + + msg("Freeing input...\n"); + input.resize(0); + + msg("Building namespace list...\n"); + buildNamespaceList(root); + + msg("Building group list...\n"); + buildGroupList(root); + + //msg("Computing group relations...\n"); + //computeGroupRelations(root); + + msg("Building file list...\n"); + buildFileList(root); + + msg("Building class list...\n"); + buildClassList(root); + + msg("Building example list...\n"); + buildExampleList(root); + + msg("Building page list...\n"); + buildPageList(root); + +// msg("Adding compounds to file pages...\n"); +// findClassDefsInFiles(root); + + msg("Building member list...\n"); // using class info only ! + buildMemberList(root); + transferFunctionDocumentation(); + + msg("Searching for friends...\n"); + findFriends(); + + + msg("Searching for documented variables...\n"); + buildVarList(root); + + msg("Searching for documented defines...\n"); + findDefineDocumentation(root); + + msg("Computing class relations...\n"); + computeClassRelations(root); + + msg("Searching for enumerations...\n"); + findEnums(root); + findEnumDocumentation(root); + +// msg("Searching for function prototypes...\n"); +// findPrototypes(root); // may introduce new members ! + + msg("Searching for member function documentation...\n"); + findMemberDocumentation(root); // may introduce new members ! + + msg("Freeing entry tree\n"); + delete root; + + msg("Computing member references...\n"); + computeMemberReferences(); + + msg("Computing function references...\n"); + computeFunctionReferences(); + + msg("Computing member relations...\n"); + computeMemberRelations(); + + msg("Building full member lists recursively...\n"); + buildCompleteMemberLists(); + + //unrelatedFunctionsUsed=hasUnrelatedFunctions(); + + /************************************************************************** + * Generate documentation * + **************************************************************************/ + + // count the number of documented elements in the lists we have built. + // If the result is 0 we do not generate the lists and omit the + // corresponding links in the index. + msg("Counting data structures...\n"); + annotatedClasses = countAnnotatedClasses(); + hierarchyClasses = countClassHierarchy(); + documentedMembers = countMemberList(); + documentedFunctions = countFunctionList(); + documentedFiles = countFileList(); + documentedGroups = countGroupList(); + documentedNamespaces = countNamespaceList(); + + // compute the shortest possible names of all files + // without loosing the uniqueness of the file names. + msg("Generating disk names...\n"); + inputNameList.generateDiskNames(); + + msg("Generating example documentation...\n"); + generateExampleDocs(); + + msg("Generating file documentation...\n"); + generateFileDocs(); + + msg("Generating class documentation...\n"); + generateClassDocs(); + + msg("Generating page documentation...\n"); + generatePageDocs(); + + msg("Generating group documentation...\n"); + generateGroupDocs(); + + msg("Generating namespace index...\n"); + generateNamespaceDocs(); + + msg("Generating group index...\n"); + writeGroupIndex(*outputList); + + msg("Generating example index...\n"); + writeExampleIndex(*outputList); + + msg("Generating function index...\n"); + writeFunctionIndex(*outputList); + +// msg("Generating define index...\n"); +// writeDefineIndex(*outputList); + + msg("Generating page index...\n"); + writePageIndex(*outputList); + + msg("Generating search index...\n"); + generateSearchIndex(); + + msg("Generating style sheet...\n"); + outputList->writeStyleInfo(0); // write first part + outputList->disableAllBut(OutputGenerator::Latex); + parseDoc(*outputList,0,0, + theTranslator->trGeneratedAt(dateToString(TRUE),projectName) + ); + outputList->writeStyleInfo(1); // write second part + parseDoc(*outputList,0,0, theTranslator->trWrittenBy()); + outputList->writeStyleInfo(2); // write third part + parseDoc(*outputList,0,0, + theTranslator->trGeneratedAt(dateToString(TRUE),projectName) + ); + outputList->writeStyleInfo(3); // write fourth part + parseDoc(*outputList,0,0, theTranslator->trWrittenBy()); + outputList->writeStyleInfo(4); // write last part + outputList->enableAll(); + + if (formulaList.count()>0 && generateHtml) + { + msg("Generating bitmaps for formulas in HTML...\n"); + formulaList.generateBitmaps(htmlOutputDir); + } + + if (searchEngineFlag || tagFileList.count()>0) + { + msg("\nNow copy the file\n\n %s\n\nto the directory where the CGI binaries are " + "located and don't forget to run\n\n",(htmlOutputDir+"/"+cgiName).data()); + msg(" %s/installdox\n\nto replace any dummy links.\n\n", + htmlOutputDir.data()); + } + + delete tag; + return 0; +} diff --git a/src/doxygen.h b/src/doxygen.h new file mode 100644 index 0000000..05ca854 --- /dev/null +++ b/src/doxygen.h @@ -0,0 +1,134 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef DOXYGEN_H +#define DOXYGEN_H + +#include "groupdef.h" +#include "filedef.h" +#include "classdef.h" +#include "memberdef.h" +#include "classlist.h" +#include "membername.h" +#include "filename.h" +#include "define.h" +#include "namespacedef.h" +#include "formula.h" + +struct PageInfo +{ + PageInfo(const char *n,const char *d,const char *t) + { name=n; doc=d; title=t; } + QString name; + QString doc; + QString title; +}; + +class PageList : public QList<PageInfo> +{ + int compareItems(GCI i1,GCI i2) + { + return stricmp(((PageInfo *)i1)->name,((PageInfo *)i2)->name); + } +}; + +class BufStr : public QString +{ + public: + BufStr(int size) : QString(size), offset(0), spareRoom(10240) {} + void addChar(char c) + { + if (offset>=size()) resize(size()+spareRoom); + data()[offset++]=c; + } + void addArray(const char *a,int len) + { + if (offset+len>=size()) resize(size()+len+spareRoom); + memcpy(data()+offset,a,len); + offset+=len; + } + uint curPos() { return offset; } + void skip(uint s) + { + if (offset+s>=size()) resize(size()+s+spareRoom); + offset+=s; + } + private: + uint offset; + const int spareRoom; // 10Kb extra room to avoid frequent resizing +}; + +struct SectionInfo +{ + SectionInfo(const char *n,const char *l,const char *t,bool sub) + { pageName=n; label=l; title=t; isSubsection=sub; } + QString pageName; + QString label; + QString title; + bool isSubsection; +}; + +typedef QList<QString> StringList; +typedef QDict<MemberDef> MemberDict; +typedef QDict<ClassDef> ClassDict; +typedef QDict<FileDef> FileDict; +typedef QDict<QString> StringDict; +typedef QDict<PageInfo> PageDict; +typedef QDict<SectionInfo> SectionDict; +typedef QDict<GroupDef> GroupDict; + +extern const char * getOverloadDocs(); +extern ClassList classList; +extern ClassDict classDict; +extern QStrList tagfileList; +extern PageList exampleList; +extern PageDict exampleDict; +extern PageList pageList; +extern PageDict pageDict; +extern MemberNameList memberNameList; +extern MemberNameList functionNameList; +extern MemberNameDict memberNameDict; +extern MemberNameDict functionNameDict; +extern StringDict substituteDict; +extern FileList fileList; +extern FileDict fileDict; +extern DefineDict defineDict; +extern ClassDef unrelatedClass; +extern QTextStream tagFile; +extern SectionDict sectionDict; +extern FileNameList inputNameList; +extern FileNameDict includeNameDict; +extern FileNameDict exampleNameDict; +extern FileNameDict inputNameDict; +extern FileList includeFiles; +extern StringDict typedefDict; +extern GroupList groupList; +extern NamespaceList namespaceList; +extern FormulaList formulaList; +extern FormulaDict formulaDict; +extern FormulaDict formulaNameDict; + +extern int annotatedClasses; +extern int hierarchyClasses; +extern int documentedFunctions; +extern int documentedMembers; +extern int documentedDefines; +extern int documentedFiles; +extern int documentedGroups; +extern int documentedNamespaces; + +#endif diff --git a/src/doxygen.pro b/src/doxygen.pro new file mode 100644 index 0000000..e6dd3c0 --- /dev/null +++ b/src/doxygen.pro @@ -0,0 +1,38 @@ +# +# $Id$ +# +# 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. +# +# All output generated with Doxygen is not covered by this license. +# +# TMake project file for doxygen + +TEMPLATE = doxygen.t +CONFIG = console qt warn_on release #debug +HEADERS = doxygen.h scanner.h classdef.h classlist.h memberdef.h \ + membername.h index.h memberlist.h definition.h \ + entry.h logos.h instdox.h message.h code.h \ + filedef.h util.h cppvalue.h constexp.h \ + outputgen.h outputlist.h htmlgen.h latexgen.h tag.h \ + filename.h defargs.h groupdef.h gifenc.h diagram.h image.h \ + namespacedef.h version.h language.h translator.h \ + translator_nl.h translator_se.h translator_cz.h translator_fr.h \ + translator_it.h formula.h debug.h +SOURCES = doxygen.cpp scanner.cpp classdef.cpp classlist.cpp memberdef.cpp \ + membername.cpp index.cpp memberlist.cpp \ + entry.cpp logos.cpp instdox.cpp message.cpp code.cpp \ + config.cpp filedef.cpp util.cpp groupdef.cpp \ + outputgen.cpp outputlist.cpp htmlgen.cpp latexgen.cpp mangen.cpp \ + cppvalue.cpp ce_lex.cpp ce_parse.cpp pre.cpp \ + tag.cpp filename.cpp declinfo.cpp defargs.cpp define.cpp \ + diagram.cpp gifenc.cpp image.cpp namespacedef.cpp \ + version.cpp language.cpp definition.cpp formula.cpp debug.cpp +win32:INCLUDEPATH += . +TARGET = ../bin/doxygen +OBJECTS_DIR = ../objects diff --git a/src/doxygen.t b/src/doxygen.t new file mode 100644 index 0000000..badf33e --- /dev/null +++ b/src/doxygen.t @@ -0,0 +1,76 @@ +# +# $Id$ +# +# 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. +# +# All output generated with Doxygen is not covered by this license. +#! +#! doxygen.t: This is a custom template for building Doxygen +#! +#$ IncludeTemplate("app.t"); + +LEX = flex +YACC = bison + +#${ +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("scanner.cpp","scanner.l"); + $(LEX) -PscanYY -t scanner.l >scanner.cpp + +#$ GenerateDep("code.cpp","code.l"); + $(LEX) -PcodeYY -t code.l >code.cpp + +#$ GenerateDep("pre.cpp","pre.l"); + $(LEX) -PpreYY -t pre.l >pre.cpp + +#$ GenerateDep("tag.cpp","tag.l"); + $(LEX) -PtagYY -t tag.l >tag.cpp + +#$ GenerateDep("config.cpp","config.l"); + $(LEX) -PconfigYY -t config.l >config.cpp + +#$ GenerateDep("declinfo.cpp","declinfo.l"); + $(LEX) -PdeclinfoYY -t declinfo.l >declinfo.cpp + +#$ GenerateDep("defargs.cpp","defargs.l"); + $(LEX) -PdefargsYY -t defargs.l >defargs.cpp + +#$ GenerateDep("ce_lex.cpp","constexp.l","ce_parse.h"); + $(LEX) -PcppExpYY -t constexp.l >ce_lex.cpp + +#$ GenerateDep("ce_parse.cpp","constexp.y"); + $(YACC) -l -p cppExpYY constexp.y -o ce_parse.cpp + +#$ GenerateDep("ce_parse.h","constexp.y"); + $(YACC) -l -d -p cppExpYY constexp.y -o ce_parse.c + -rm ce_parse.c + diff --git a/src/doxysearch.cpp b/src/doxysearch.cpp new file mode 100644 index 0000000..cd59d02 --- /dev/null +++ b/src/doxysearch.cpp @@ -0,0 +1,1022 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +// includes + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <stdlib.h> +#include <ctype.h> +#include <sys/stat.h> +#ifdef PROFILING +#include <sys/time.h> +#include <unistd.h> +#endif + +// defines + +#ifndef bool +#define bool int +#endif + +#define MAXSTRLEN 1024 +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define NORMAL 1 // OR search results +#define INCLUDE 2 // AND search results +#define EXCLUDE 3 // AND NOT search results + +#define TERMMASK (1<<31) +#define OFFSETMASK (~TERMMASK) + +// structs + +//---------------------------------------------------------------------------- + +struct FileInfo +{ + FileInfo() { f=0; url=0; } + ~FileInfo() { if (f) fclose(f); + delete[] url; + } + FILE *f; + int index; + int refOffset; + char *url; + FileInfo *next; +}; + +//---------------------------------------------------------------------------- + +struct FileList +{ + FileList() { first=0; last=0; index=0; } + ~FileList() { FileInfo *fi=first; + while (fi) { FileInfo *ofi=fi; fi=fi->next; delete ofi; } + } + FileInfo *add() + { + FileInfo *nf=new FileInfo; + nf->next=0; + nf->index=index++; + if (last) { last->next=nf; last=nf; } else { first=nf; last=nf; } + return nf; + } + FileInfo *first; + FileInfo *last; + int index; +}; + +//---------------------------------------------------------------------------- + +struct WordInfo +{ + WordInfo() { word=0; } + ~WordInfo() { delete[] word; } + char *word; + int freq; + WordInfo *next; +}; + +//---------------------------------------------------------------------------- + +struct WordList +{ + WordList() { first=0; last=0; } + ~WordList() { WordInfo *wi=first; + while (wi) { WordInfo *owi=wi; wi=wi->next; delete owi; } + } + void add(const char *word,int freq) + { + WordInfo *nw=new WordInfo; + nw->word = new char[strlen(word)+1]; + strcpy(nw->word,word); + nw->freq=freq; + nw->next=0; + if (last) { last->next=nw; last=nw; } else { first=nw; last=nw; } + } + WordInfo *first; + WordInfo *last; +}; + +//---------------------------------------------------------------------------- + +struct SearchDoc +{ + FileInfo *fileInfo; + int index; + int freq; + double rank; + SearchDoc *next; +}; + +//---------------------------------------------------------------------------- + +struct SearchResults +{ + SearchResults() { totalFreq=0; docList=0; last=0; } + ~SearchResults() { SearchDoc *d=docList; + while (d) { SearchDoc *od=d; d=d->next; delete od; } + } + void add(FileInfo *fi,int index,int freq) + { + SearchDoc *nd=new SearchDoc; + nd->fileInfo=fi; + nd->index=index; + nd->freq=freq; + nd->next=0; + if (last) { last->next=nd; last=nd; } else { docList=nd; last=nd; } + } + SearchDoc *docList; + SearchDoc *last; + int totalFreq; +}; + +//---------------------------------------------------------------------------- + +// global vars + +static WordList wordList; +static FileList fileList; +static char cgiBin[MAXSTRLEN]; +static char queryInput[MAXSTRLEN]; +static char encQueryInput[MAXSTRLEN]; +static char firstDocUrl[MAXSTRLEN]; +static bool nameOnly; +static bool wordOnly; +static bool helpOnly; +static int page; +static char *headerBuf=0; +static char *footerBuf=0; + +//---------------------------------------------------------------------------- + +// functions + +void printHeader() +{ + if (headerBuf) + { + printf("Content-Type: text/html\r\n\r\n%s",headerBuf); + } + else + { + printf("Content-Type: text/html\r\n\r\n"); + printf("<html><head><title>Search the documentation</title></head>\n" + "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#0000ee\" \n" + "vlink=\"#551a8b\" alink=\"#ff0000\">\n"); + } +} + +//---------------------------------------------------------------------------- + +void printFooter() +{ + if (footerBuf) + { + printf("%s",footerBuf); + } + else + { + printf("</body></html>\n"); + } +} + +//---------------------------------------------------------------------------- + +void message(char *fmt,...) +{ + printHeader(); + printf("<h2>"); + va_list args; + va_start(args, fmt); + vfprintf(stdout, fmt, args); + va_end(args); + printf("</h2>"); + printFooter(); +} + +//---------------------------------------------------------------------------- + +void printSearchPage(bool open=FALSE) +{ + printf("<form name=doxyform method=GET action=\"%s\">\n" + "<center>\n" + "<input type=hidden name=page value=0>\n" + "<table border=0 bgcolor=\"#ffffcc\" cellspacing=0 cellpadding=4>\n" + " <tr>\n" + " <td valign=top><font size=-1 face=\"arial, helvetica\"><b>" + " Search for\n" + " <select name=which>\n" + " <option value=string %s>strings\n" + " <option value=word %s>words\n" + " </select>\n" + " in function and class\n" + " <select name=what>\n" + " <option value=doc %s>documentation\n" + " <option value=name %s>names</select></b></font>\n" + " </td>\n" + " <td valign=top align=right>\n" + " <a href=\"%s?help=on\"><font size=-1>Help</font></a>\n" + " </td>\n" + " </tr>\n" + " <tr>\n" + " <td><input name=query size=44 wrap=virtual maxlength=1000 value=\"%s\">\n" + " </td>\n" + " <td><input type=image src=\"%s/search.gif\" height=26 width=120 border=0 name=\"search\">\n" + " </td>\n" + " </tr>\n", + cgiBin, + (wordOnly?"":"selected"),(wordOnly?"selected":""), + (nameOnly?"":"selected"),(nameOnly?"selected":""), + cgiBin,queryInput,firstDocUrl); + if (!open) + { + printf("</table>\n</center></form>\n"); + } +} + +//---------------------------------------------------------------------------- + +int readInt(FILE *f) +{ + return (fgetc(f)<<24)+(fgetc(f)<<16)+(fgetc(f)<<8)+fgetc(f); +} + +//---------------------------------------------------------------------------- + +int readEncodedNumber(FILE *f) +{ + int n=0,b,s=0; + do { b=fgetc(f); n|=(b&0x7f)<<s; s+=7; } while (b&0x80); + return n; +} + +void readString(FILE *f,char *s,int n) +{ + int i=0,b; + if (n<=0) return; + while (i<n-1 && (b=fgetc(f))!=0) s[i++]=b; + s[i]='\0'; +} + +//---------------------------------------------------------------------------- + +bool searchRecursive(SearchResults *sr,FileInfo *fi,const char *word) +{ + char entry[MAXSTRLEN]; + readString(fi->f,entry,MAXSTRLEN); + while (entry[0]!='\0') + { + //printf("Found entry `%s'\n",entry); + int i=0, w=word[0], e=entry[0]; + while (w!=0 && e!=0 && w==e) { i++; w=word[i]; e=entry[i]; } + if (w==0 && e!=0) // word is a substring of entry + { + if (wordOnly) return FALSE; // no full word match + //printf("Word found as substring of `%s%s'\n",&word[-index],&entry[i]); + int offset=readInt(fi->f); // <= follow for extensions + if (!(offset&TERMMASK)) // extra info available + { + int tfreq=readEncodedNumber(fi->f); + sr->totalFreq+=tfreq; + //printf("Total frequency %d\n",tfreq); + int s=-1,k; + while ((k=readEncodedNumber(fi->f))!=0) + { + bool inName = (k&2)==2; + s+=(k>>3); + int freq=readEncodedNumber(fi->f); + //printf("Doc index %d frequency %d\n",s,freq); + if (!nameOnly || inName) + //addResult(fi,sr,s,freq); + sr->add(fi,s,freq); + } + } + return TRUE; + } + else if (e==0) // entry is a substring of word + { + if (w==0) // word is equal to entry => exact match found + { + int offset=readInt(fi->f); // <= follow for extensions + if (!(offset&TERMMASK)) // extra info available + { + //printf("Match found\n"); + int tfreq=readEncodedNumber(fi->f); + sr->totalFreq+=tfreq; + //printf("Total frequency %d\n",tfreq); + int s=-1,k; + while ((k=readEncodedNumber(fi->f))!=0) + { + bool fullWord = (k&1)==1; + bool inName = (k&2)==2; + bool wordInName = (k&4)==4; + s+=(k>>3); + int freq=readEncodedNumber(fi->f); + if (nameOnly && wordOnly) + { + if (wordInName) sr->add(fi,s,freq); + } + else if (!nameOnly && wordOnly) + { + if (fullWord) sr->add(fi,s,freq); + } + else if (nameOnly && !wordOnly) + { + if (inName) sr->add(fi,s,freq); + } + else // !nameOnly && !wordOnly + { + sr->add(fi,s,freq); + } + } + } + return TRUE; + } + else // follow branch to next entry + { + int offset=readInt(fi->f); + if ((offset&OFFSETMASK)==0) // no next entry (leaf node) + { + return FALSE; + } + else // follow branch + { + fseek(fi->f,offset&OFFSETMASK,SEEK_SET); + //printf("Recursive call; jump to %lx\n",ftell(f)); + return searchRecursive(sr,fi,&word[i]); + } + } + } + else // skip rest of the entry + { + int offset=readInt(fi->f); + if (!(offset&TERMMASK)) while (readEncodedNumber(fi->f)!=0); + } + readString(fi->f,entry,MAXSTRLEN); + } + //printf("Sorry no match found\n"); + return FALSE; +} + +//---------------------------------------------------------------------------- + + +void searchIndex(const char *word,SearchResults *results) +{ + FileInfo *fi=fileList.first; + while (fi) + { + fseek(fi->f,8,SEEK_SET); + searchRecursive(results,fi,word); + fi=fi->next; + } + + SearchDoc *ds = results->docList; + while (ds) + { + ds->rank = ds->freq/(double)results->totalFreq; + ds = ds->next; + } + + wordList.add(word,results->totalFreq); +} + +//---------------------------------------------------------------------------- + +int sortResults(const void *a1,const void *a2) +{ + SearchDoc **d1=(SearchDoc **)a1; + SearchDoc **d2=(SearchDoc **)a2; + if ((*d1)->rank > (*d2)->rank) + return -1; + else if ((*d1)->rank == (*d2)->rank) + return 0; + else + return 1; +} + +//---------------------------------------------------------------------------- + +void generateResults(SearchResults *sr) +{ + // compute the maximum rank + SearchDoc *ds = sr->docList; + double maxRank = 0.00000001; + int resultCount=0; + if (ds) + { + while (ds) + { + if (ds->rank>maxRank) maxRank = ds->rank; + ds = ds->next; + } + + // scale ranks, so the highest is 1 and count the number of links + double oneOverMaxRank = 1.0/maxRank; + ds = sr->docList; + while (ds) + { + ds->rank *= oneOverMaxRank; + resultCount++; + ds = ds->next; + } + } + SearchDoc **docPtrArray=0; + if (resultCount>0) + { + docPtrArray=(SearchDoc **)calloc(resultCount,sizeof(SearchDoc *)); + int offset=0; + ds = sr->docList; + while (ds) + { + docPtrArray[offset++]=ds; + ds = ds->next; + } + qsort(docPtrArray,resultCount,sizeof(SearchDoc *),sortResults); + } + + // start generating output + printHeader(); + printSearchPage(TRUE); + + printf(" <tr bgcolor=#ffffff>\n" + " <td colspan=2>" + "<br><h3>Search results</h3>\n" + " </td>\n" + " </tr>\n"); + if (resultCount==0) // nothing found + { + printf(" <tr bgcolor=#ffffff>\n" + " <td colspan=2>Sorry, no documents matching your query.\n" + " </td>\n" + " </tr>\n"); + } + else // something found + { + printf(" <tr bgcolor=#ffffff>\n" + " <td colspan=2>" + "Found <b>%d</b> document%s matching your query. ", + resultCount,resultCount==1?"":"s"); + + if (resultCount>1) + printf("Showing best matches first.\n"); + + printf(" <br><br>\n"); + printf(" </td>\n" + " </tr>\n"); + + const int lpp=20; + int numPages = (resultCount+lpp-1)/lpp; + + // clip page + if (page<0) page=0; + if (page>=numPages) page=numPages-1; + int skipEntries = page * lpp; + int pageEntries = lpp; + + printf(" <tr><td colspan=2 bgcolor=\"#4040c0\">" + "<center><b><font color=\"#ffffff\">Page %d / %d</font></b>" + "</center></td></tr>\n",page+1,numPages); + printf(" <tr bgcolor=#ffffff>\n" + " <td colspan=2>\n" + " <dl compact>\n"); + int i; + for (i=0 ; i < resultCount && pageEntries > 0; i++) + { + if (skipEntries == 0) + { + SearchDoc *d=docPtrArray[i]; + FILE *f=d->fileInfo->f; + fseek(f,d->fileInfo->refOffset+d->index*4,SEEK_SET); + int offset=readInt(f); + fseek(f,offset,SEEK_SET); + char linkName[MAXSTRLEN]; + char htmlName[MAXSTRLEN]; + readString(f,linkName,MAXSTRLEN); + readString(f,htmlName,MAXSTRLEN); + int rank=(int)(d->rank*100+0.5); + if (rank==0) rank++; + printf(" <dt><b><font color=#%2x00%2x>%d</font></b>" + "<dd><a href=\"%s/%s\">%s</a>\n", + rank*2+55, 255-rank*2, rank, + d->fileInfo->url, htmlName, linkName); + pageEntries--; + } + else + { + skipEntries--; + } + } + printf(" </dl>\n" + " </td>\n" + " </tr>\n" + " <tr><td colspan=2 bgcolor=\"#4040c0\"><center> "); + + if (page>0) + { + printf("<a href=\"%s?page=%d&which=%s&what=%s&query=%s\">" + "<font color=\"ffffff\">prev</font></a> ", + cgiBin, page-1, + wordOnly?"word":"doc", + nameOnly?"name":"string", + encQueryInput); + } + int startPage = page-5 < 0 ? 0 : page-5; + int endPage = page+6 > numPages ? numPages : page+5; + if (endPage-startPage>1) + { + for (i=startPage;i<endPage;i++) + { + if (i!=page) + { + printf("<a href=\"%s?page=%d&which=%s&what=%s&query=%s\">" + "<font color=\"ffffff\">%d</font></a> ", + cgiBin, i, + wordOnly?"word":"doc", + nameOnly?"name":"string", + encQueryInput, i+1); + } + else + { + printf("<b><font color=\"ffffff\">%d</font></b></a> ",i+1); + } + } + } + if (page<numPages-1) + { + printf("<a href=\"%s?page=%d&which=%s&what=%s&query=%s\">" + "<font color=\"ffffff\">next</font></a>", + cgiBin, page+1, + wordOnly?"word":"doc", + nameOnly?"name":"string", + encQueryInput); + } + printf(" </center></td></tr>\n" + " <tr bgcolor=#ffffff>\n" + " <td colspan=2><p>\n" + " Occurrence count: "); + WordInfo *wi=wordList.first; + while (wi) + { + printf("<b><font color=#ff0000>%s</font></b> ",wi->word); + if (wi->freq>0) printf("(%d)",wi->freq); else printf("(ignored)"); + wi=wi->next; + if (wi) + { + if (wi->next) printf(", "); else printf(" and "); + } + } + printf("\n" + " </td>\n" + " </tr>\n"); + } + printf("</table>\n</center>\n</form>\n"); + printFooter(); + free(docPtrArray); +} + +//---------------------------------------------------------------------------- + +void generateHelpPage() +{ + printHeader(); + printf("<h3>Doxysearch help page</h3>\n" + "<b>Basic search instructions</b>\n" + "<ul>\n" + "Just type in one or more words or fragments of words and press the " + "search button. Doxysearch will return a list of functions and class names, " + "whose documentation or name matches one or more of the words. " + "Documents containing more matches will appear earlier in the list. " + "\n" + "</ul>\n" + "<b>Search modes</b>\n" + "<ul>\n" + "Doxysearch has four search modes. From least restrictive to most " + "restrictive they are:\n" + " <ul><p>\n" + " <li><em>Search for strings in the documentation:</em>\n" + " The words you type will be searched in the documentation as substrings." + " Typing the word "<b>the</b>" for example, will find " + " documents containing the words "<b>the</b>", " + " "<b>the</b>re", and "fea<b>the</b>r".<p>\n" + " <li><em>Search for words in the documentation:</em>\n" + " The words you type will be searched in the documentation as words." + " Typing the word "<b>the</b>" for example, will look " + " for documents containing the word "<b>the</b>" and not for" + " documents containing the word "<b>the</b>re".<p>\n" + " <li><em>Search for strings in the function and class names:</em>\n" + " The words you type will be searched in the function and class names " + " as substrings. Typing the word "<b>set</b>" for example, will " + " result in a list of links to the documentation of all functions and classes " + " that contain the word "<b>set</b>" in the name, such as the function " + " <code><b>set</b>Cursor</code>.<p>\n" + " <li><em>Search for words in the function and class names:</em>\n" + " The words you type will be matched against the function and class names." + " The result will be a list of links to the documentation of all function " + " and class names that are equal to one of the words.\n" + " </ul>\n" + "</ul>\n" + "<b>Requiring/Excluding words</b>\n" + "<ul>\n" + " Often you will know a word that will be guaranteed to appear in a document " + " for which you are searching. If this is the case, require that the word appears " + " in all of the results by attaching a "<b>+</b>" to the beginning of " + " the word. You can quickly reject results by adding a word that appears only " + " in unwanted documents with a "<b>-</b>" before it." + "</ul>\n" + ); + + printFooter(); +} + +//---------------------------------------------------------------------------- + +void mergeSearchResults(SearchResults *totalResults, + SearchResults *sr,int mode) +{ + SearchDoc *otd = 0, + *td = totalResults->docList, + *d = sr->docList; + totalResults->totalFreq += sr->totalFreq; + if (!d) return; // nothing to add + while (td && d) + { + int otdih = otd ? otd->fileInfo->index : -1, + otdil = otd ? otd->index : -1, + tdih = td->fileInfo->index, + tdil = td->index, + dih = d->fileInfo->index, + dil = d->index; + if (tdih==dih && tdil==dil) // combine results + { + if (mode != EXCLUDE) + { + td->rank += d->rank; + td->rank *= 2; // put extra emphasis on multiple word matches + td->freq += d->freq; + d = d->next; + otd = td; td = td->next; + } + else // mode == EXCLUDE => remove entry from results + { + SearchDoc *tmp=td; + td=td->next; + if (otd) otd->next=td; else totalResults->docList = td; + delete tmp; + } + } + else if ((otdih<dih || (otdih==dih && otdil<dil)) && + (tdih>dih || (tdih==dih && tdil>dil))) // insert + { + if (mode == NORMAL) + { + SearchDoc *nd = new SearchDoc(*d); + if (otd) otd->next = nd; else totalResults->docList = nd; + nd->next = td; + td = nd; + } + d = d->next; + } + else if (tdih<dih || (tdih==dih && tdil<dil)) // remove or skip + { + if (mode == INCLUDE) + { + SearchDoc *tmp=td; + td=td->next; + if (otd) otd->next=td; else totalResults->docList = td; + delete tmp; + } + else // mode == EXCLUDE or mode == NORMAL + { + otd = td; td = td->next; + } + } + } + if (td==0 && d && mode==NORMAL) // append rest of sr to totalResults + { + while (d) + { + SearchDoc *nd = new SearchDoc(*d); + if (otd) otd->next = nd; else totalResults->docList = nd; + nd->next = 0; + d = d->next; + otd = nd; + } + } + if (td && d==0 && mode==INCLUDE) // delete the rest of the results + { + while (td) + { + SearchDoc *tmp=td; + td=td->next; + if (otd) otd->next = td; else totalResults->docList = td; + delete tmp; + } + } +} + +//---------------------------------------------------------------------------- + +int asciiToHex(char c) +{ + char l=tolower(c); + if (l>='0' && l<='9') + return l-'0'; + else if (l>='a' && l<='f') + return l+10-'a'; + else // invalid hex char + return 0; +} + +//---------------------------------------------------------------------------- + +void fileToBuf(const char *name, char **buf) +{ + FILE *f; + struct stat file_stats; + if ((f=fopen(name,"r"))==NULL) return; + if (stat(name,&file_stats)==-1) + { + message("Error: could not fstat header file %s\n",name); + exit(1); + } + unsigned int len=file_stats.st_size; + if ((*buf=(char *)malloc(len+1))==NULL) + { + message("Error: out of memory\n"); + exit(1); + } + if (fread(*buf,1,len,f)!=len) + { + message("Error: could not read header file %s\n",name); + exit(1); + } + (*buf)[len]='\0'; + fclose(f); +} + +//---------------------------------------------------------------------------- + +void getConfig(const char *s) +{ + int l; + char configFile[MAXSTRLEN]; + strcpy(configFile,s); + strcat(configFile,"/search.cfg"); + + FILE *f; + if ((f=fopen(configFile,"r"))==NULL) + { + message("Error: could not open config file %s\n",configFile); + exit(1); + } + + // get the URL to the documentation + fgets(firstDocUrl,MAXSTRLEN,f); + l=strlen(firstDocUrl)-1; + if (firstDocUrl[l]=='\n') firstDocUrl[l]='\0'; + l=strlen(firstDocUrl); + if (firstDocUrl[l]=='/') firstDocUrl[l]='\0'; + + // get the URL to the cgi script + fgets(cgiBin,MAXSTRLEN,f); + l=strlen(cgiBin)-1; + if (cgiBin[l]=='\n') cgiBin[l]='\0'; + + fclose(f); + + char headerFile[MAXSTRLEN]; + strcpy(headerFile,s); + strcat(headerFile,"/header.html"); + fileToBuf(headerFile,&headerBuf); + + char footerFile[MAXSTRLEN]; + strcpy(footerFile,s); + strcat(footerFile,"/footer.html"); + fileToBuf(footerFile,&footerBuf); + +} + +//---------------------------------------------------------------------------- +// copy and convert string to lower case + +void strlowercpy(char *d,const char *s) +{ + while (*s!='\0') *d++=tolower(*s++); *d='\0'; +} + +//---------------------------------------------------------------------------- + +int main(int argc,char **argv) +{ +#ifdef PROFILING + struct timeval tv_start,tv_end; + gettimeofday(&tv_start,0); +#endif + char *argString=getenv("QUERY_STRING"); + if (argc==1) + { + message("Error: invalid number of arguments. " + "Usage: %s doc_path [doc_path ...]",argv[0]); + exit(1); + } + // read the configuration file for this instance of the search engine + getConfig(argv[1]); + + if (!argString) + { + printHeader(); + printSearchPage(); + printFooter(); + exit(1); + } + + SearchResults tsr; + + // parse cgi arguments + char *arg=strtok(argString,"&"); + char *query = 0; + char *what = 0; + char *which = 0; + char *help = 0; + page = 0; + while (arg) + { + int namelen=strcspn(arg,"="); + if (!strncmp(arg,"query", namelen)) query = &arg[namelen+1]; + else if (!strncmp(arg,"what", namelen)) what = &arg[namelen+1]; + else if (!strncmp(arg,"which", namelen)) which = &arg[namelen+1]; + else if (!strncmp(arg,"help", namelen)) help = &arg[namelen+1]; + else if (!strncmp(arg,"page", namelen)) page = atoi(&arg[namelen+1]); + arg=strtok(0,"&"); + } + + wordOnly=which ? strcmp(which,"word")==0 : FALSE; + nameOnly=what ? strcmp(what, "name")==0 : FALSE; + helpOnly=help ? strcmp(help, "on" )==0 : FALSE; + + // store encoded query string + if (query) strcpy(encQueryInput,query); else encQueryInput[0]='\0'; + + // convert query string to original input + char *s=query,*d=queryInput; + if (s) + { + while (*s!='\0') + { + char c=*s++; + if (c=='+') + *d++=' '; + else if (c=='%') + *d++=asciiToHex(*s++)*16+asciiToHex(*s++); + else + *d++=c; + } + } + *d='\0'; + + if (helpOnly) + { + generateHelpPage(); + exit(1); + } + + // read search index files + int argIndex=0; + for (argIndex=1;argIndex<argc;argIndex++) + { + char configFile[MAXSTRLEN]; + strcpy(configFile,argv[argIndex]); + strcat(configFile,"/search.cfg"); + + char indexFile[MAXSTRLEN]; + strcpy(indexFile,argv[argIndex]); + strcat(indexFile,"/search.idx"); + + FileInfo *fi=fileList.add(); + FILE *g; + + if ((fi->f=fopen(indexFile,"r"))==NULL) + { + message("Error: could not open index file %s\n",indexFile); + exit(1); + } + if ((g=fopen(configFile,"r"))==NULL) + { + message("Error: could not open config file %s\n",configFile); + exit(1); + } + + // get URL to the documentation + char tmp[MAXSTRLEN]; + fgets(tmp,MAXSTRLEN,g); + if (tmp[strlen(tmp)-1]=='\n') tmp[strlen(tmp)-1]='\0'; + if (tmp[strlen(tmp)-1]=='/') tmp[strlen(tmp)-1]='\0'; + fi->url = new char[strlen(tmp)+1]; + strcpy(fi->url,tmp); + fclose(g); + + // read & check the format of the search index file + fseek(fi->f,0,SEEK_SET); + char header[5]; + if (fread(header,1,4,fi->f)!=4) + { + message("Error: Couldn't read header of the index file %s\n",indexFile); + exit(1); + } + header[4]='\0'; + if (strcmp(header,"DOXI")) + { + message("Error: Index file %s has an unknown format\n",indexFile); + exit(1); + } + // read and store the offset to the link index + fi->refOffset=readInt(fi->f); + } + + char *word; + char wordString[MAXSTRLEN]; + + // search for included words + strlowercpy(wordString,queryInput); + word=strtok(wordString," "); + bool first=TRUE; + while (word) + { + if (word[0]=='+') // + character => include + { + SearchResults sr; + searchIndex(&word[1],&sr); + if (first) + mergeSearchResults(&tsr,&sr,NORMAL); + else + mergeSearchResults(&tsr,&sr,INCLUDE); + first=FALSE; + } + word=strtok(0," "); + } + + // search for normal words + strlowercpy(wordString,queryInput); + word=strtok(wordString," "); + while (word) + { + if (word[0]!='-' && word[0]!='+') // normal word + { + SearchResults sr; + searchIndex(word,&sr); + mergeSearchResults(&tsr,&sr,NORMAL); + } + word=strtok(0," "); + } + + // search for excluded words + strlowercpy(wordString,queryInput); + word=strtok(wordString," "); + while (word) + { + if (word[0]=='-') // - character => exclude + { + SearchResults sr; + searchIndex(&word[1],&sr); + mergeSearchResults(&tsr,&sr,EXCLUDE); + } + word=strtok(0," "); + } + + // write results to HTML page + generateResults(&tsr); + + free(headerBuf); + free(footerBuf); + +#ifdef PROFILING + gettimeofday(&tv_end,0); + printf("processing time %3.3f msec\n", + ((tv_end.tv_sec-tv_start.tv_sec)*1000000+ + tv_end.tv_usec-tv_start.tv_usec)/1000.0 + ); +#endif + return 0; +} diff --git a/src/doxysearch.pro b/src/doxysearch.pro new file mode 100644 index 0000000..ab34adc --- /dev/null +++ b/src/doxysearch.pro @@ -0,0 +1,18 @@ +# +# $Id$ +# +# 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. +# +# All output generated with Doxygen is not covered by this license. + +TEMPLATE = app.t +CONFIG = console warn_on release +SOURCES = doxysearch.cpp +TARGET = ../bin/doxysearch +OBJECTS_DIR = ../objects diff --git a/src/doxytag.l b/src/doxytag.l new file mode 100644 index 0000000..4f9fac1 --- /dev/null +++ b/src/doxytag.l @@ -0,0 +1,634 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +%{ +/* + * includes + */ +#include <stdio.h> +#include <iostream.h> +#include <assert.h> +#include <ctype.h> + +#include <qstring.h> +#include <qstrlist.h> +#include <qfileinf.h> +#include <qfile.h> +#include <qdict.h> +#include <qtstream.h> +#include <qdir.h> + +#include "version.h" +#include "suffixtree.h" +#include "searchindex.h" +#include "logos.h" + +struct MemberDef +{ + QString name; + QString anchor; + QString args; +}; + +struct ClassDef +{ + QString name; + QStrList bases; + QString fileName; + bool isFile; + QList<MemberDef> memberList; +}; + +QList<ClassDef> classList; +QDict<ClassDef> classDict(1009); +QList<ClassDef> fileList; +QDict<ClassDef> fileDict(1009); + +static bool genTag; +static bool genIndex; + +static QStrList bases; +static QString inputString; +static int inputPosition; +static QString yyFileName; +static int yyLineNr; +static QString classFile; +static QString memberRef; +static QString memberName; +static QString memberArgs; +static QString className; +//static bool newClass; +static QString docBaseLink; +static QString docAnchor; +static QString docRefName; +static bool nameBug; +static SearchIndex searchIndex; + +#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; +} + +static void addClass(const char *clName) +{ + if (classDict[clName]==0) + { + ClassDef *cd=new ClassDef; + cd->name=clName; + cd->fileName=yyFileName; + cd->isFile=FALSE; + classList.append(cd); + classDict.insert(clName,cd); + } +} + +static void addFile(const char *fName) +{ + if (classDict[fName]==0) + { + ClassDef *fd=new ClassDef; + fd->name=fName; + fd->fileName=yyFileName; + fd->isFile=TRUE; + classList.append(fd); + classDict.insert(fName,fd); + } +} + +static void addBases(const char *clName) +{ + ClassDef *cd=0; + if (clName && (cd=classDict[clName])) cd->bases=bases; +} + +static void addMember(const char *memName,const char *memRef,const char *memArgs) +{ + ClassDef *cd=classList.last(); + MemberDef *md; + md=new MemberDef; + md->name=memName; + md->anchor=memRef; + md->args=memArgs; + cd->memberList.append(md); +} + +static void addReference() +{ + //printf("addReference() key: %s ref:%s\n", + // docRefName.data(),(docBaseLink+"#"+docAnchor).data()); + if (genIndex && docRefName.length()>0 && docBaseLink.length()>0) + { + if (docAnchor.length()==0) + searchIndex.addReference(docRefName,docBaseLink); + else + searchIndex.addReference(docRefName,docBaseLink+"#"+docAnchor); + searchIndex.addWord(docRefName,docRefName,TRUE); + } +} + +QString unhtmlify(const char *str) +{ + QString result; + const char *p=str; + char c; + while ((c=*p)!='\0') + { + if (c!='&') { result+=c; p++; } + else + { + if (strncmp(p,"&",5)==0) { result+='&'; p+=5; } + else if (strncmp(p,"<",4)==0) { result+='<'; p+=4; } + else if (strncmp(p,">",4)==0) { result+='>'; p+=4; } + else /* should not happen */ { result+='&'; p++; } + } + } + return result; +} + +%} + +%x Start +%x SearchClassFile +%x ReadClassFile +%x CheckClassName +%x ReadClassName +%x SearchMemberRef +%x ReadMemberRef +%x SearchMemberName +%x ReadMemberName +%x ReadOperator +%x SearchBaseClasses +%x ReadBaseClass +%x SearchRefName +%x ReadRefName +%x SearchArgs +%x ReadArgs +%x SearchWords +%x SkipHTMLTag +%x CheckConstructor +%x SkipPreformated + +%% + +<Start>^"<li>" { + BEGIN( SearchClassFile ); + } +<Start>^"<h1 align=center>" { // Qt variant + BEGIN( ReadClassName ); + } +<Start>^"<h1>" { // Doxygen variant + BEGIN( ReadClassName ); + } +<Start>^"Inherits " { + //printf("Inherits found\n"); + BEGIN( SearchBaseClasses ); + } +<Start>^"<h3 class=\"fn\">"/[a-z_A-Z0-9] { // needed due to inconsistency in the Qt docs + BEGIN( CheckConstructor ); + } +<Start>"<pre>" { + BEGIN( SkipPreformated ); + } +<Start>"<a name=\"" { + BEGIN( SearchWords ); + } +<Start>"<" { + BEGIN( SkipHTMLTag ); + } +<Start>"&"[a-zA-Z]+";" +<Start>[a-z_A-Z][a-z_A-Z0-9]* { + //printf("tag: %s#%s ref: %s word: `%s'\n", + // docBaseLink.data(),docAnchor.data(), + // docRefName.data(),yytext); + if (genIndex && docRefName.length()>0 && yyleng>2) + searchIndex.addWord(docRefName, + yytext,FALSE + ); + } +<SkipPreformated>"</pre>" { + BEGIN( Start ); + } +<SkipPreformated>[^\<]+ +<CheckConstructor>[a-z_A-Z0-9~:]+ { + QString s=yytext; + if (s.find("::")!=-1) + { + docRefName=yytext; + addReference(); + nameBug=TRUE; + } + else + { + nameBug=FALSE; + } + BEGIN( Start ); + } +<SearchWords>[a-z_A-Z0-9]+ { + docAnchor = yytext; + if (docAnchor=="details") + { + docRefName=className.copy(); + addReference(); + BEGIN( Start ); + } + else + { + BEGIN( SearchRefName ); + } + } +<SearchRefName>"\" doxytag=\"" { + BEGIN( ReadRefName ); + } +<SearchRefName>"\"></a>" { + if (nameBug) + BEGIN( Start ); + else + BEGIN( ReadRefName ); + } + +<ReadRefName>[a-z_A-Z0-9:\.\+\-]*"operator"[ \t]*("new"|"delete"|("&"("&"|"=")*)|(">"(">"|"=")*)|("<"("<"|"=")*)|("->"[*]*)|[+\-*%/|~!=,\^]|[+\-*%/\^!|~=\[(][=|+\-\])]) { // hmm, looks impressive :-) + docRefName=unhtmlify(yytext); + addReference(); + BEGIN( Start ); + } +<ReadRefName>[a-z_A-Z0-9~:\.\+\-]+ { + //printf("ReadRef=%s\n",yytext); + docRefName=yytext; + addReference(); + BEGIN( Start ); + } +<SearchBaseClasses>"<a "[a-z_A-Z0-9 .:\=\"\-\+\/\@]+">" { + //printf("Search %s\n",yytext); + BEGIN( ReadBaseClass ); + } +<SearchBaseClasses>\n { + addBases(className); + BEGIN( Start ); + } +<ReadBaseClass>[a-z_A-Z0-9]+ { + bases.append(yytext); + BEGIN( SearchBaseClasses ); + } +<SearchClassFile>"<a class=\"el\" href=\"" { + BEGIN( ReadClassFile ); + } +<SearchClassFile>"<a href=\"" { + BEGIN( ReadClassFile ); + } +<ReadClassName>[a-z_A-Z0-9:\.\-\+]+ { + className=yytext; + BEGIN( CheckClassName); + } +<CheckClassName>"Class Reference" { + //printf("className=%s\n",className.data()); + addClass(className); + BEGIN( Start ); + } +<CheckClassName>"File Reference" { + //printf("className=%s\n",className.data()); + addFile(className); + BEGIN( Start ); + } +<CheckClassName>[a-z_A-Z0-9]+ { // not a class file + className.resize(0); + BEGIN( Start ); + } +<ReadClassFile>[a-z_A-Z0-9.\-\+]+ { + classFile=yytext; + BEGIN( SearchMemberRef ); + } +<SearchMemberRef>"#" { + BEGIN( ReadMemberRef ); + } +<ReadMemberRef>[a-z_A-Z0-9]+ { + memberRef=yytext; + BEGIN( SearchMemberName ); + } +<SearchMemberName>"<strong>" { + BEGIN( ReadMemberName ); + } +<SearchMemberName>[a-z_A-Z~] { + unput(*yytext); + BEGIN( ReadMemberName ); + } +<ReadMemberName>"operator" { + memberName="operator"; + BEGIN( ReadOperator ); + } +<ReadOperator>[+\-*/%\^&|~!=()\[\]] { memberName+=*yytext; } +<ReadOperator>"<" { memberName+="<"; } +<ReadOperator>">" { memberName+=">"; } +<ReadOperator>"new" { memberName+=" new"; } +<ReadOperator>"delete" { memberName+=" delete"; } +<ReadOperator>"<" { BEGIN( SearchArgs ); } +<ReadMemberName>[a-z_A-Z0-9]+ { + memberName=yytext; + BEGIN( SearchArgs ); + } +<SearchArgs>"</a>" { + //printf("SearchArg className=%s memberName=%s\n",className.data(),memberName.data()); + if (className.length()>0 && memberName.length()>0) + BEGIN( ReadArgs ); + else + BEGIN( Start ); + } +<ReadArgs>"&" { memberArgs+="&"; } +<ReadArgs>"<" { memberArgs+="<"; } +<ReadArgs>">" { memberArgs+=">"; } + /* +<ReadArgs>[{}] { // handle enums + memberArgs.resize(0); + addMember(memberName,memberRef,memberArgs); + if (*yytext=='}') + BEGIN( Start ); + else + BEGIN( SearchClassFile ); + } + */ +<ReadArgs>"<"|"\n" { + //printf("adding member %s\n",memberName.data()); + memberArgs=memberArgs.stripWhiteSpace(); + //if (newClass) + //{ + // newClass=FALSE; + // addClass(className); + //} + addMember(memberName,memberRef,memberArgs); + memberArgs.resize(0); + if (*yytext=='<') + BEGIN( SkipHTMLTag); + else + BEGIN( Start ); + } +<ReadArgs>. { memberArgs+=(*yytext)&0x7f; } +<SkipHTMLTag>">" { BEGIN( Start ); } +<SkipHTMLTag>[a-zA-Z]+ +<*>. +<*>\n { yyLineNr++; + if (YY_START!=SkipHTMLTag) BEGIN( Start ); + } + +%% + +/*@ ---------------------------------------------------------------------------- + */ + + +void parse(QString &s) +{ + bases.clear(); + nameBug = FALSE; + //newClass = TRUE; + inputString = s; + inputPosition = 0; + yyLineNr = 0; + tagYYrestart( tagYYin ); + BEGIN( Start ); + tagYYlex(); + //printf("Number of lines scanned: %d\n",yyLineNr); +} + +void parseFile(QFileInfo &fi) +{ + fprintf(stderr,"Parsing file %s...\n",fi.fileName().data()); + QFile f(fi.absFilePath()); + if (f.open(IO_ReadOnly)) + { + yyFileName = fi.fileName(); + className.resize(0); + memberName.resize(0); + //printf("Parsing file %s...\n",fi.fileName().data()); + QString input(fi.size()+1); + docBaseLink=fi.fileName(); + docRefName=fi.fileName().copy(); + searchIndex.addReference(docRefName,docBaseLink); + searchIndex.addWord(docRefName,docRefName,TRUE); + f.readBlock(input.data(),fi.size()); + input.at(fi.size())='\0'; + parse(input); + } + else + { + fprintf(stderr,"Warning: Cannot open file %s\n",fi.fileName().data()); + } +} + +void parseFileOrDir(const char *fileName) +{ + QFileInfo fi(fileName); + if (fi.exists()) + { + if (fi.isFile()) + { + parseFile(fi); + } + else if (fi.isDir()) + { + QDir dir(fileName); + dir.setFilter( QDir::Files ); + dir.setNameFilter( "*.html" ); + const QFileInfoList *list = dir.entryInfoList(); + QFileInfoListIterator it( *list ); + QFileInfo *cfi; + for ( it.toFirst() ; (cfi=it.current()) ; ++it) + { + if (cfi->isFile()) + { + parseFile(*cfi); + } + } + } + } + else + { + fprintf(stderr,"Warning: File %s does not exist\n",fileName); + } +} + +void usage(const char *name) +{ + fprintf(stderr,"Doxytag version %s\nCopyright Dimitri van Heesch 1997-1999\n\n", + versionString); + fprintf(stderr," Generates a tag file and/or a search index for a set of HTML files\n\n"); + fprintf(stderr,"Usage: %s [-t tag_file] [-s index_file] [ html_file [html_file...] ]\n",name); + fprintf(stderr,"Options:\n"); + fprintf(stderr," -t <tag_file> Generate tag file <tag_file>.\n"); + fprintf(stderr," -s <index_file> Generate search index <index_file>.\n\n"); + fprintf(stderr,"If no HTML files are given all files in the current dir that\n" + "have a .html extension are parsed.\n\n"); + exit(1); +} + +const char *getArg(int argc,char **argv,int &optind,const char c) +{ + char *s=0; + if (strlen(&argv[optind][2])>0) + s=&argv[optind][2]; + else if (optind+1<argc) + s=argv[++optind]; + else + { + fprintf(stderr,"option -%c requires an argument\n",c); + exit(1); + } + return s; +} + +int main(int argc,char **argv) +{ + QString tagName; + QString indexName; + + int optind=1; + const char *arg; + while (optind<argc && argv[optind][0]=='-') + { + switch(argv[optind][1]) + { + case 't': + arg=getArg(argc,argv,optind,'t'); + tagName=arg; + break; + case 's': + arg=getArg(argc,argv,optind,'s'); + indexName=arg; + break; + case 'h': + case '?': + usage(argv[0]); + break; + default: + fprintf(stderr,"Unknown option -%c\n",argv[optind][1]); + usage(argv[0]); + } + optind++; + } + + genTag = tagName.length()>0; + genIndex = indexName.length()>0; + + if (!genTag && !genIndex) + { + fprintf(stderr,"Nothing to do !\n\n"); + usage(argv[0]); + } + + int i; + if (optind>=argc) + { + parseFileOrDir("."); + } + else + { + for (i=optind;i<argc;i++) + { + parseFileOrDir(argv[i]); + } + } + if (genIndex) + { + printf("Writing search index\n"); + if (!searchIndex.saveIndex(indexName)) + { + fprintf(stderr,"Error: Could not write search index\n"); + } + QFileInfo fi(indexName); + if (fi.exists()) + { + QString dir=fi.dir().absPath(); + fi.setFile(dir+"/search.gif"); + if (!fi.exists()) writeSearchButton(dir); + fi.setFile(dir+"/doxygen.gif"); + if (!fi.exists()) writeLogo(dir); + fi.setFile(dir+"/search.cgi"); + if (!fi.exists()) + { + QFile f(dir+"/search.cgi"); + if (f.open(IO_WriteOnly)) + { + QTextStream t(&f); + t << "#!/bin/sh" << endl + << "DOXYSEARCH=" << endl + << "DOXYPATH=" << endl + << "if [ -f $DOXYSEARCH ]" << endl + << "then" << endl + << " $DOXYSEARCH $DOXYPATH" << endl + << "else" << endl + << " echo \"Content-Type: text/html\"" << endl + << " echo \"\"" << endl + << " echo \"<H1>Error: $DOXYSEARCH not found. Check cgi script!\"" << endl + << "fi" << endl; + f.close(); + } + else + { + fprintf(stderr,"Error: could not open file %s for writing\n",(dir+"/search.cgi").data()); + } + } + } + } + if (genTag) + { + QFile f(tagName); + if (f.open(IO_WriteOnly)) + { + QTextStream t(&f); + ClassDef *cd=classList.first(); + while (cd) + { + if (cd->isFile) t << "&"; else t << ">"; + t << cd->name << ":"; + char *base=cd->bases.first(); + while (base) + { + t << base << "?"; + base=cd->bases.next(); + } + if (!cd->isFile) t << " \"" << cd->fileName << "\""; + t << endl; + MemberDef *md=cd->memberList.first(); + while (md) + { + t << md->name << " " << md->anchor << " \"" << md->args << "\"" << endl; + md=cd->memberList.next(); + } + cd=classList.next(); + } + } + else + { + fprintf(stderr,"Error: Could not write tag file %s\n",tagName.data()); + } + } + return 0; +} + +extern "C" { +int tagYYwrap() { return 1 ; } +}; diff --git a/src/doxytag.pro b/src/doxytag.pro new file mode 100644 index 0000000..3389c00 --- /dev/null +++ b/src/doxytag.pro @@ -0,0 +1,24 @@ +# +# $Id$ +# +# 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. +# +# All output generated with Doxygen is not covered by this license. +# +# TMake project file for doxytag + +TEMPLATE = doxytag.t +CONFIG = console warn_on qt release +HEADERS = suffixtree.h searchindex.h logos.h version.h +SOURCES = doxytag.cpp suffixtree.cpp searchindex.cpp \ + logos.cpp version.cpp +TARGET = ../bin/doxytag +win32:INCLUDEPATH += . +#unix:INCLUDEPATH += /usr/include +OBJECTS_DIR = ../objects diff --git a/src/doxytag.t b/src/doxytag.t new file mode 100644 index 0000000..1ee8ec5 --- /dev/null +++ b/src/doxytag.t @@ -0,0 +1,49 @@ +# +# $Id$ +# +# 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. +# +# All output generated with Doxygen is not covered by this license. +# +#! +#! doxytag.t: This is a custom template for building Doxytag +#! +#$ IncludeTemplate("app.t"); + +LEX = flex + +#${ +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("doxytag.cpp","doxytag.l"); + $(LEX) -PtagYY -t doxytag.l >doxytag.cpp + + diff --git a/src/entry.cpp b/src/entry.cpp new file mode 100644 index 0000000..2520fa3 --- /dev/null +++ b/src/entry.cpp @@ -0,0 +1,242 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include "entry.h" + +static int newCount=0; + +Entry::Entry() +{ + num=newCount++; + //printf("New Entry %d\n",num); + parent=0; + sublist = new QList<Entry>; + sublist->setAutoDelete(TRUE); + extends = new QList<BaseInfo>; + extends->setAutoDelete(TRUE); + groups = new QList<QString>; + groups->setAutoDelete(TRUE); + argList = new ArgumentList; + argList->setAutoDelete(TRUE); + //printf("Entry::Entry() tArgList=0\n"); + tArgList = 0; + reset(); +} + +Entry::Entry(const Entry &e) +{ + num=newCount++; + //printf("Copy New Entry %d\n",num); + section = e.section; + protection = e.protection; + sig = e.sig; + slot = e.slot; + stat = e.stat; + virt = e.virt; + parent = e.parent; + type = e.type.copy(); + name = e.name.copy(); + args = e.args.copy(); + exception = e.exception.copy(); + program = e.program.copy(); + includeFile = e.includeFile.copy(); + includeName = e.includeFile.copy(); + doc = e.doc.copy(); + relates = e.relates.copy(); + brief = e.brief.copy(); + inside = e.inside.copy(); + fileName = e.fileName.copy(); + startLine = e.startLine; + sublist = new QList<Entry>; + sublist->setAutoDelete(TRUE); + extends = new QList<BaseInfo>; + extends->setAutoDelete(TRUE); + groups = new QList<QString>; + groups->setAutoDelete(TRUE); + argList = new ArgumentList; + argList->setAutoDelete(TRUE); + //printf("Entry::Entry(copy) tArgList=0\n"); + tArgList = 0; + + // deep copy of the child entry list + QListIterator<Entry> eli(*e.sublist); + Entry *cur; + for (;(cur=eli.current());++eli) + { + 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<QString> sli(*e.groups); + QString *s; + for (;(s=sli.current());++sli) + { + groups->append(new QString(*s)); + } + + // deep copy argument list + QListIterator<Argument> ali(*e.argList); + Argument *a; + for (;(a=ali.current());++ali) + { + argList->append(new Argument(*a)); + } + argList->constSpecifier = e.argList->constSpecifier; + argList->volatileSpecifier = e.argList->volatileSpecifier; + argList->pureSpecifier = e.argList->pureSpecifier; + + // deep copy template argument list + if (e.tArgList) + { + tArgList = new ArgumentList; + tArgList->setAutoDelete(TRUE); + //printf("Entry::Entry(copy) new tArgList=%p\n",tArgList); + QListIterator<Argument> tali(*e.tArgList); + for (;(a=tali.current());++tali) + { + tArgList->append(new Argument(*a)); + //printf("appending argument %s %s\n",a->type.data(),a->name.data()); + } + } +} + +Entry::~Entry() +{ + //printf("Deleting entry %d name %s type %x chilren %d\n", + // num,name.data(),section,sublist->count()); + delete sublist; + delete extends; + delete groups; + delete argList; + //printf("Entry::~Entry() tArgList=%p\n",tArgList); + delete tArgList; +} + +void Entry::addSubEntry(Entry *current) +{ + //printf("Entry %d with name %s type 0x%x added\n", + // current->num,current->name.data(),current->section); + //printf("Entry::addSubEntry(%s) %p\n",current->name.data(),current->tArgList); + current->parent=this; + sublist->append(current); + + //if (current->tArgList) + //{ + // Argument * a=current->tArgList->first(); + // while (a) + // { + // printf("type=%s name=%s\n",a->type.data(),a->name.data()); + // a=current->tArgList->next(); + // } + //} + +} + +void Entry::reset() +{ + name.resize(0); + type.resize(0); + args.resize(0); + exception.resize(0); + program.resize(0); + includeFile.resize(0); + includeName.resize(0); + doc.resize(0); + relates.resize(0); + brief.resize(0); + inside.resize(0); + fileName.resize(0); + section = EMPTY_SEC; + sig = FALSE; + virt = Normal; + slot = FALSE; + stat = FALSE; + proto = FALSE; + protection = Public; + sublist->clear(); + extends->clear(); + groups->clear(); + argList->clear(); + if (tArgList) { delete tArgList; tArgList=0; } +} + + +int Entry::getSize() +{ + int size=sizeof(Entry); + size+=type.length()+1; + size+=name.length()+1; + size+=args.length()+1; + size+=exception.length()+1; + size+=program.length()+1; + size+=includeFile.length()+1; + size+=includeName.length()+1; + size+=doc.length()+1; + size+=relates.length()+1; + size+=brief.length()+1; + size+=inside.length()+1; + size+=fileName.length()+1; + BaseInfo *bi=extends->first(); + while (bi) + { + size+=sizeof(QLNode); + size+=bi->name.length()+1+sizeof(bi->prot)+sizeof(bi->virt); + bi=extends->next(); + } + QString *s=groups->first(); + while (s) + { + size+=sizeof(QLNode); + size+=s->length()+1; + s=groups->next(); + } + Entry *e=sublist->first(); + while (e) + { + size+=e->getSize(); + e=sublist->next(); + } + Argument *a=argList->first(); + while (e) + { + size+=sizeof(Argument); + size+=a->type.length()+1 + +a->name.length()+1 + +a->defval.length()+1; + a=argList->next(); + } + if (tArgList) + { + a=tArgList->first(); + while (e) + { + size+=sizeof(Argument); + size+=a->type.length()+1 + +a->name.length()+1 + +a->defval.length()+1; + a=tArgList->next(); + } + } + return size; +} diff --git a/src/entry.h b/src/entry.h new file mode 100644 index 0000000..40624d8 --- /dev/null +++ b/src/entry.h @@ -0,0 +1,153 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef ENTRY_H +#define ENTRY_H + +#include <qstring.h> +#include <qlist.h> + +enum Protection { Public, Protected, Private } ; +enum Specifier { Normal, Virtual, Pure } ; + +struct BaseInfo +{ + BaseInfo(const char *n,Protection p,Specifier v) : name(n),prot(p),virt(v) {} + QString name; // the name of the base class + Protection prot; // inheritance type + Specifier virt; // virtualness +}; + +struct Argument +{ + Argument() {} + Argument(const Argument &a) + { + type=a.type.copy(); + name=a.name.copy(); + defval=a.defval.copy(); + } + Argument &operator=(const Argument &a) + { + if (this!=&a) + { + type=a.type.copy(); + name=a.name.copy(); + defval=a.defval.copy(); + } + return *this; + } + + QString type; // argument type + QString name; // argument name (if any) + QString defval; // argument default value (if any) +}; + +class ArgumentList : public QList<Argument> +{ + public: + ArgumentList() : QList<Argument>(), + constSpecifier(FALSE), + volatileSpecifier(FALSE), + pureSpecifier(FALSE) {} + bool constSpecifier; + bool volatileSpecifier; + bool pureSpecifier; +}; + +typedef QListIterator<Argument> ArgumentListIterator; + +class Entry +{ + public: + + enum Sections { + CLASS_SEC = 0x00000001, + STRUCT_SEC = 0x00000002, + UNION_SEC = 0x00000004, + ENUM_SEC = 0x00000008, + EMPTY_SEC = 0x00000010, + PAGEDOC_SEC = 0x00000020, + VARIABLE_SEC = 0x00000040, + FUNCTION_SEC = 0x00000080, + TYPEDEF_SEC = 0x00000100, + CLASSDOC_SEC = 0x00000200, + MEMBERDOC_SEC = 0x00000400, + OVERLOADDOC_SEC = 0x00000800, + EXAMPLE_SEC = 0x00001000, + VARIABLEDOC_SEC = 0x00002000, + ENUMDOC_SEC = 0x00004000, + UNIONDOC_SEC = 0x00008000, + STRUCTDOC_SEC = 0x00010000, + SOURCE_SEC = 0x00020000, + HEADER_SEC = 0x00040000, + FILEDOC_SEC = 0x00080000, + DEFINEDOC_SEC = 0x00100000, + INCLUDE_SEC = 0x00200000, + DEFINE_SEC = 0x00400000, + GROUPDOC_SEC = 0x00800000, + NAMESPACE_SEC = 0x01000000, + NAMESPACEDOC_SEC = 0x02000000, + COMPOUND_MASK = CLASS_SEC | STRUCT_SEC | UNION_SEC, + COMPOUNDDOC_MASK = CLASSDOC_SEC | STRUCTDOC_SEC | UNIONDOC_SEC, + SCOPE_MASK = COMPOUND_MASK | NAMESPACE_SEC, + FILE_MASK = SOURCE_SEC | HEADER_SEC + }; + + Entry(); + Entry(const Entry &); + ~Entry(); + int getSize(); + + void addSubEntry (Entry* e) ; + void reset(); + + int section; // entry type; + Protection protection; // class protection + bool sig; // a Qt signal ? + bool slot; // a Qt slot ? + bool stat; // static ? + bool proto; // prototype ? + Specifier virt; // virtualness of the entry + Entry *parent; // parent node in the tree + QString type; // member type + QString name; // member name + QString args; // member argument string + ArgumentList *argList; // member arguments as a list + ArgumentList *tArgList; // template argument list + ArgumentList *tNameList; // template name list + QString program; // the program text + QString includeFile; // include file (2 arg of \class, must be unique) + QString includeName; // include name (3 arg of \class) + QString doc; // documentation block (partly parsed) + QString relates; // related class (doc block) + QString brief; // brief description (doc block) + QString inside; // name of the class in which documents are found + QString exception; // throw specification + QList<Entry> *sublist; // entries that are children of this one + QList<BaseInfo> *extends; // list of base classes + QList<QString> *groups; // list of groups this entry belongs to + QString fileName; // file this entry was extracted from + int startLine; // start line of entry in the source + int num; + private: + Entry &operator=(const Entry &); +} ; + +typedef QList<Entry> EntryList; +typedef QListIterator<Entry> EntryListIterator; + +#endif diff --git a/src/example.h b/src/example.h new file mode 100644 index 0000000..eef33ce --- /dev/null +++ b/src/example.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef EXAMPLE_H +#define EXAMPLE_H + +#include <qstring.h> + +class ClassDef; +class MemberName; + +struct Example +{ + QString anchor; + QString name; + QString file; +}; + +class ExampleList : public QList<Example> +{ + public: + ExampleList() : QList<Example>() {} + ~ExampleList() {} + int compareItems(GCI item1,GCI item2) + { + return stricmp(((Example *)item1)->name,((Example *)item2)->name); + } +}; + +typedef QDict<Example> ExampleDict; + +#endif diff --git a/src/filedef.cpp b/src/filedef.cpp new file mode 100644 index 0000000..54266a5 --- /dev/null +++ b/src/filedef.cpp @@ -0,0 +1,291 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include "memberlist.h" +#include "classlist.h" +#include "define.h" +#include "filedef.h" +#include "scanner.h" +#include "doxygen.h" +#include "memberdef.h" +#include "classdef.h" +#include "namespacedef.h" +#include "util.h" +#include "language.h" + +/*! create a new file definition, where \a p is the file path, + \a the file name, and \a ref 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 *ref) + : Definition(nm) +{ + path=p; + filepath=path+nm; + filename=nameToFile(nm); + reference=ref; + memList = new MemberList; + classList = new ClassList; + includeList = new FileList; + defineList = new DefineList; + namespaceList = new NamespaceList; +} + +/*! destroy the file definition */ +FileDef::~FileDef() +{ + delete memList; + delete classList; + delete includeList; + delete defineList; +} + +/*! Compute the HTML anchor names for all members in the class */ +void FileDef::computeAnchors() +{ + setAnchors('a',memList); +} + +/*! Write the documentation page for this file to the file of output + generators \a ol. +*/ +void FileDef::writeDocumentation(OutputList &ol) +{ + //funcList->countDecMembers(); + + QString pageTitle=name()+" File Reference"; + startFile(ol,diskname,pageTitle); + startTitle(ol); + ol.docify(pageTitle); + endTitle(ol,name()); + //ol.newParagraph(); + + if (genTagFile.length()>0) tagFile << "&" << name() << ":\n"; + + //brief=brief.stripWhiteSpace(); + //int bl=brief.length(); + OutputList briefOutput(&ol); + if (briefDescription()) + { + //if (brief.at(bl-1)!='.' && brief.at(bl-1)!='!' && brief.at(bl!='?')) + // brief+='.'; + parseDoc(briefOutput,0,0,briefDescription()); + ol+=briefOutput; + ol.writeString(" \n"); + ol.disableAllBut(OutputGenerator::Html); + ol.startTextLink(0,"details"); + parseDoc(ol,0,0,theTranslator->trMore()); + ol.endTextLink(); + ol.enableAll(); + } + ol.disable(OutputGenerator::Man); + ol.newParagraph(); + ol.enable(OutputGenerator::Man); + ol.writeSynopsis(); + + if (classList->count()>0) + { + ClassDef *cd=classList->first(); + bool found=FALSE; + while (cd) + { + if (//cd->name()[0]!='@' && + //(cd->protection()!=Private || extractPrivateFlag) && + //(cd->hasDocumentation() || !hideClassFlag)) + cd->isVisibleExt() + ) + { + if (!found) + { + ol.startMemberHeader(); + parseDoc(ol,0,0,theTranslator->trCompounds()); + ol.endMemberHeader(); + ol.startMemberList(); + found=TRUE; + } + ol.startMemberItem(); + switch (cd->compoundType()) + { + case ClassDef::Class: ol.writeString("class"); break; + case ClassDef::Struct: ol.writeString("struct"); break; + case ClassDef::Union: ol.writeString("union"); break; + } + ol.writeString(" "); + if (cd->hasDocumentation()) + { + ol.writeObjectLink(cd->getReference(), + cd->classFile(), + 0, + cd->name() + ); + } + else + { + ol.startBold(); + ol.docify(cd->name()); + ol.endBold(); + } + ol.endMemberItem(); + } + cd=classList->next(); + } + if (found) ol.endMemberList(); + } + + writeMemberDecs(ol,0,0,this,0,0,memList); + + //doc=doc.stripWhiteSpace(); + //int bl=brief.length(); + //int dl=doc.length(); + if (!briefDescription().isEmpty() || !documentation().isEmpty()) + { + ol.writeRuler(); + ol.writeAnchor("details"); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trDetailedDescription()); + ol.endGroupHeader(); + if (!briefDescription().isEmpty()) + { + ol+=briefOutput; + ol.newParagraph(); + } + if (!documentation().isEmpty()) + { + //if (doc.at(dl-1)!='.' && doc.at(dl-1)!='!' && doc.at(dl-1)!='?') + // doc+='.'; + parseDoc(ol,0,0,documentation()+"\n"); + ol.newParagraph(); + } + } + + memList->countDocMembers(); + + if ( memList->defineCount()>0 ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trDefineDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,memList,name(),MemberDef::Define); + } + + if ( memList->protoCount()>0 ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trFunctionPrototypeDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,memList,name(),MemberDef::Prototype); + } + + if ( memList->typedefCount()>0 ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trTypedefDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,memList,name(),MemberDef::Typedef); + } + + if ( memList->enumCount()>0 ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trEnumerationTypeDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,memList,name(),MemberDef::Enumeration); + } + + if ( memList->enumValueCount()>0 ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trEnumerationValueDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,memList,name(),MemberDef::EnumValue); + } + + if ( memList->funcCount()>0 ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trFunctionDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,memList,name(),MemberDef::Function); + } + + if ( memList->varCount()>0 ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trVariableDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,memList,name(),MemberDef::Variable); + } + + // write Author section (Man only) + ol.disableAllBut(OutputGenerator::Man); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trAuthor()); + ol.endGroupHeader(); + parseDoc(ol,0,0,theTranslator->trGeneratedAutomatically(projectName)); + ol.enableAll(); + endFile(ol); +} + +/*! Adds member definition \a md to the list of all members of this file */ +void FileDef::insertMember(MemberDef *md) +{ + memList->append(md); +} + +/*! Adds compound definition \a cd to the list of all compounds of this file */ +void FileDef::insertClass(ClassDef *cd) +{ + classList->append(cd); +} + +/*! Adds namespace definition \a nd to the list of all compounds of this file */ +void FileDef::insertNamespace(NamespaceDef *nd) +{ + namespaceList->append(nd); +} + +//----------------------------------------------------------------------------- + +/*! Creates a file list. */ +FileList::FileList() : QList<FileDef>() +{ +} + +/*! Destroys a file list */ +FileList::~FileList() +{ +} + +/*! Compares two files by name. */ +int FileList::compareItems(GCI item1, GCI item2) +{ + FileDef *c1=(FileDef *)item1; + FileDef *c2=(FileDef *)item2; + return strcmp(c1->name(),c2->name()); +} + +/*! Create a file list iterator. */ +FileListIterator::FileListIterator(const FileList &cllist) : + QListIterator<FileDef>(cllist) +{ +} diff --git a/src/filedef.h b/src/filedef.h new file mode 100644 index 0000000..36ce9cb --- /dev/null +++ b/src/filedef.h @@ -0,0 +1,158 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef FILEDEF_H +#define FILEDEF_H + +#include <qlist.h> +#include "index.h" +#include "config.h" +#include "definition.h" + +class MemberList; +class FileList; +class ClassList; +class MemberDef; +class ClassDef; +class OutputList; +class DefineList; +class NamespaceDef; +class NamespaceList; + +/*! \class FileDef filedef.h + \brief A File definition. + + 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); + ~FileDef(); + + /*! Returns the unique file name (this may include part of the path). */ + QString name() const + { + if (fullPathNameFlag) + return filename; + else + return Definition::name(); + } + + /*! Returns nameString with all slashes replaced by underscores. */ + const char *diskName() const { return diskname; } + + /*! Returns the absolute path including the file name. */ + QString absFilePath() const { return filepath; } + + /*! Returns the name of the verbatim copy of this file (if any). */ + const char *includeName() const { return incName; } + + /*! Returns the documentation that was available for this file. */ + //const char *documentation() const { return doc; } + + /*! Returns the brief description that was given for this file. */ + //const char *briefDescription() const { return brief; } + + /*! Sets the name of the include file to \a n. */ + void setIncludeName(const char *n_) { incName=n_; } + + /*! Sets the name of the include file to \a n. */ + //void setBriefDescription(const char *b) { brief=b; } + + /*! Sets the documentaton of this file to \a d. */ + //void setDocumentation(const char *d) { doc=d; } + + /*! Returns the absolute path of this file. */ + QString getPath() const { return path; } + + /*! Returns true iff any documentation for this file is found. */ + //bool hasDocumentation() + // { return extractAllFlag || !doc.isNull() || !brief.isNull(); } + + /*! Returns true iff this file was externally defined + (i.e. read from a tag file) */ + bool isReference() { return !reference.isNull(); } + + /*! Returns the reference name of the external file, if any or 0 + if the file is not defined. */ + const char *getReference() { return reference; } + + //void setFileType(FileType ft) { ftype = ft; } + //FileType fileType() const { return ftype; } + + void writeDocumentation(OutputList &ol); + friend void generatedFileNames(); + void insertMember(MemberDef *fd); + void insertClass(ClassDef *cd); + void insertNamespace(NamespaceDef *nd); + void computeAnchors(); + + private: + MemberList *memList; + ClassList *classList; + FileList *includeList; + NamespaceList *namespaceList; + DefineList *defineList; + //QString n; + //QString doc; + //QString brief; + QString reference; + QString path; + QString filepath; + QString diskname; + QString filename; + QString incName; + //FileType ftype; +}; + +/*! \class FileList filedef.h + \brief This class is list of file definitions. + + It is based on QList. +*/ + +class FileList : public QList<FileDef> +{ + public: + FileList(); + ~FileList(); + + int compareItems(GCI item1,GCI item2); +}; + +/*! \class FileListIterator filedef.h + \brief This class represents a file list iterator. + + It is based on QListIterator. +*/ + +class FileListIterator : public QListIterator<FileDef> +{ + public: + FileListIterator(const FileList &list); +}; + +#endif diff --git a/src/filename.cpp b/src/filename.cpp new file mode 100644 index 0000000..60367dc --- /dev/null +++ b/src/filename.cpp @@ -0,0 +1,133 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include "filename.h" +#include "util.h" + +FileName::FileName(const char *n) : QList<FileDef>() +{ + name=n; +} + +FileName::~FileName() +{ +} + +//static QString convertSlashes(const char *s) +//{ +// QString result=s; +// int i,l=result.length(); +// for (i=0;i<l;i++) if (result.at(i)=='/') result.at(i)='_'; +// return result; +//} + +void FileName::generateDiskNames() +{ + QString commonPrefix; + FileDef *fd=first(); + int count=0; + while (fd) { if (!fd->isReference()) count++; fd=next(); } + if (count==1) + { + fd=first(); + // skip references + while (fd && fd->isReference()) fd=next(); + // name if unique, so diskname is simply the name + fd->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) + { + fd=first(); + while (fd && fd->isReference()) fd=next(); + char c=fd->path.at(i); + if (c=='/') j=i; // remember last position of dirname + while (fd && !found) + { + if (!fd->isReference()) + { + //printf("i=%d fd->path=`%s' fd->name=`%s'\n",i,fd->path.data(),fd->name().data()); + if (i==(int)fd->path.length()) + { + warning("Warning: Input file found multiple times!\n" + " The generated documentation for this file may not be correct!\n"); + found=TRUE; + } + else if (fd->path[i]!=c) + { + found=TRUE; + } + } + fd=next(); + } + i++; + } + fd=first(); + while (fd) + { + //printf("fd->setName(%s)\n",(fd->path.right(fd->path.length()-j-1)+name).data()); + fd->setName(fd->path.right(fd->path.length()-j-1)+name); + fd->diskname=convertSlashes(fd->name()); + fd=next(); + } + } +} + +int FileName::compareItems(GCI item1, GCI item2) +{ + FileName *f1=(FileName *)item1; + FileName *f2=(FileName *)item2; + return stricmp(f1->fileName(),f2->fileName()); +} + +FileNameIterator::FileNameIterator(const FileName &fname) : + QListIterator<FileDef>(fname) +{ +} + +FileNameList::FileNameList() : QList<FileName>() +{ +} + +FileNameList::~FileNameList() +{ +} + +void FileNameList::generateDiskNames() +{ + FileName *fn=first(); + while (fn) + { + fn->generateDiskNames(); + fn=next(); + } +} + +int FileNameList::compareItems(GCI item1, GCI item2) +{ + FileName *f1=(FileName *)item1; + FileName *f2=(FileName *)item2; + return stricmp(f1->fileName(),f2->fileName()); +} + +FileNameListIterator::FileNameListIterator(const FileNameList &fnlist) : + QListIterator<FileName>(fnlist) +{ +} diff --git a/src/filename.h b/src/filename.h new file mode 100644 index 0000000..2932d18 --- /dev/null +++ b/src/filename.h @@ -0,0 +1,63 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef FILENAME_H +#define FILENAME_H + +#include <qdict.h> +#include "filedef.h" + +class FileName : public QList<FileDef> +{ + public: + FileName(const char *name); + ~FileName(); + const char *fileName() const { return name; } + void generateDiskNames(); + int compareItems(GCI item1,GCI item2); + + private: + QString name; +}; + +class FileNameIterator : public QListIterator<FileDef> +{ + public: + FileNameIterator(const FileName &list); +}; + +class FileNameList : public QList<FileName> +{ + public: + FileNameList(); + ~FileNameList(); + void generateDiskNames(); + int compareItems(GCI item1,GCI item2); +}; + +class FileNameListIterator : public QListIterator<FileName> +{ + public: + FileNameListIterator( const FileNameList &list ); +}; + +class FileNameDict : public QDict<FileName> +{ + public: + FileNameDict(uint size) : QDict<FileName>(size) {} +}; + +#endif diff --git a/src/formula.cpp b/src/formula.cpp new file mode 100644 index 0000000..53e8b38 --- /dev/null +++ b/src/formula.cpp @@ -0,0 +1,286 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <stdlib.h> +#include <unistd.h> + +#include <qfile.h> +#include <qtstream.h> +#include <qfileinf.h> +#include <qdir.h> + +#include "formula.h" +#include "image.h" +#include "util.h" +#include "message.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("Error: Output dir %s does not exist!\n",path); exit(1); } + QString oldDir = QDir::currentDirPath().copy(); + // goto the html output directory (i.e. path) + QDir::setCurrent(d.absPath()); + QDir thisDir; + // generate a latex file containing one formula per page. + QString texName="_formulas.tex"; + QList<int> pagesToGenerate; + pagesToGenerate.setAutoDelete(TRUE); + FormulaListIterator fli(*this); + Formula *formula; + QFile f(texName); + if (f.open(IO_WriteOnly)) + { + QTextStream t(&f); + t << "\\documentclass{article}" << endl; + t << "\\usepackage{epsf}" << endl; // for those who want to include images + t << "\\pagestyle{empty}" << endl; + t << "\\begin{document}" << endl; + int page=0; + for (fli.toFirst();(formula=fli.current());++fli) + { + QString resultName; + resultName.sprintf("form-%d.gif",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)); + } + 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"); + system("latex _formulas.tex"); + //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.gif for formula\n",pageNum); + char dviCmd[256]; + QString formBase; + formBase.sprintf("_form%d",pageNum); + // run dvips to convert the page with number pageIndex to an + // encapsulated postscript. + sprintf(dviCmd,"dvips -q -D 600 -E -n 1 -p %d -o %s.eps _formulas.dvi", + pageIndex,formBase.data()); + system(dviCmd); + // now we read the generated postscript file to extract the bounding box + QFileInfo fi(formBase+".eps"); + if (fi.exists()) + { + QString 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("Error: 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)) + { + QTextStream 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. + const double scaleFactor = 16.0/3.0; + int gx = (((int)((x2-x1)*scaleFactor))+3)&~2; + int gy = (((int)((y2-y1)*scaleFactor))+3)&~2; + char gsCmd[256]; + // Then we run ghostscript to convert the postscript to a pixmap + // The pixmap is a truecolor image, where only black and white are + // used. + sprintf(gsCmd,"gs -q -g%dx%d -r%dx%dx -sDEVICE=ppmraw " + "-sOutputFile=%s.pnm -DNOPAUSE -- %s.ps", + gx,gy,(int)(scaleFactor*72),(int)(scaleFactor*72), + formBase.data(),formBase.data() + ); + //printf("Running ghostscript...\n"); + system(gsCmd); + 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); + QString s; + if (!t.eof()) + s=t.readLine(); + if (s.length()<2 || s.left(2)!="P6") + err("Error: ghostscript produced an illegal image format!"); + else + { + // assume the size if after the first line that does not start with + // # excluding the first line of the file. + while (!t.eof() && (s=t.readLine()) && !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. + 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 gif + QString resultName; + resultName.sprintf("form-%d.gif",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"); + thisDir.remove("_formulas.log"); + thisDir.remove("_formulas.aux"); + } + // remove the latex file itself + thisDir.remove("_formulas.tex"); + // write/update the formula repository so we know what text the + // generated gifs represent (we use this next time to avoid regeneration + // of the gifs, and to avoid forcing the user to delete all gifs in order + // to let a browser refresh the images). + f.setName("formula.repository"); + if (f.open(IO_WriteOnly)) + { + QTextStream 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..977ccfe --- /dev/null +++ b/src/formula.h @@ -0,0 +1,57 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef FORMULA_H +#define FORMULA_H + +#include <qstring.h> +#include <qlist.h> +#include <qdict.h> + +class Formula +{ + public: + Formula(const char *text); + ~Formula(); + int getId(); + QString getFormulaText() const { return form; } + + private: + int number; + QString form; +}; + +class FormulaList : public QList<Formula> +{ + public: + void generateBitmaps(const char *path); +}; + +class FormulaListIterator : public QListIterator<Formula> +{ + public: + FormulaListIterator(const FormulaList &l) : + QListIterator<Formula>(l) {} +}; + +class FormulaDict : public QDict<Formula> +{ + public: + FormulaDict(uint size) : + QDict<Formula>(size) {} +}; + +#endif diff --git a/src/gifenc.cpp b/src/gifenc.cpp new file mode 100644 index 0000000..1160531 --- /dev/null +++ b/src/gifenc.cpp @@ -0,0 +1,293 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + * The GIF compression code below is based on the file ppmtogif.c of the + * netpbm package. The original copyright message follows: + * + * --------------------------------------------------------------------------- + * + * Copyright (C) 1989 by Jef Poskanzer. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. This software is provided "as is" without express or + * implied warranty. + * + * --------------------------------------------------------------------------- + * + * The Graphics Interchange Format(c) is the Copyright property of + * CompuServe Incorporated. GIF(sm) is a Service Mark property of + * CompuServe Incorporated. + */ + +#include "gifenc.h" + +static const unsigned int masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, + 0x001F, 0x003F, 0x007F, 0x00FF, + 0x01FF, 0x03FF, 0x07FF, 0x0FFF, + 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; + +GifEncoder::GifEncoder(Byte *rawBytes,Color *p,int w,int h, Byte d, + int t) + : colorResolution(8),globalPaletteFlag(0x80),bits(12), + maxMaxCode(1<<bits) +{ + width = w; + height = h; + depth = d; + transIndex = t; + palette = p; + data = rawBytes; + dataPtr = data; +} + +GifEncoder::~GifEncoder() +{ +} + +void GifEncoder::writeGIF(QFile &fp) +{ + // Write the Magic header + fp.writeBlock( transIndex < 0 ? "GIF87a" : "GIF89a", 6 ); + + // Write the logical screen descriptor + putWord( width, fp ); + putWord( height, fp ); + Byte pack = globalPaletteFlag | ((colorResolution-1)<<4) | (depth-1); + putByte( pack, fp ); + putByte( 0, fp ); // the background color + putByte( 0, fp ); // no aspect ration defined + + // Write global color table + int i; for ( i=0 ; i< (1<<depth) ; i++) + { + putByte(palette[i].red, fp); + putByte(palette[i].green,fp); + putByte(palette[i].blue, fp); + } + + if ( transIndex >= 0) + { + // Write graphic control extension (needed for GIF transparancy) + putByte( 0x21, fp); // extension introducer + putByte( 0xf9, fp); // graphic control label + putByte( 4, fp); // block size + putByte( 1, fp); // announce transparacy value + putWord( 0, fp); // zero delay time + putByte( transIndex, fp); // write transparant index + putByte( 0, fp); // end block + } + + // Write the image descriptor + putByte( 0x2c, fp); // image separator + putWord( 0, fp); // image left position + putWord( 0, fp); // image top position + putWord( width, fp); // image width + putWord( height, fp); // image height + putByte( 0, fp); // no local color table, no interlacing + + // Write table based image data + Byte initCodeSize = depth<=1 ? 2 : depth; + putByte( initCodeSize, fp); // LZW Minimum Code Size + compress( initCodeSize+1, fp); + putByte( 0, fp); // end of blocks + + // Write GIF Trailer + putByte( 0x3b, fp); +} + +void GifEncoder::compress( int ibits, QFile &outfile ) +{ + int i; + int entry; + + initBits = ibits; + numPixels = width*height; + dataPtr = data; + clearFlag = FALSE; + nBits = initBits; + maxCode = (1<<nBits) -1; + ClearCode = (1 << (initBits - 1)); + EOFCode = ClearCode + 1; + freeEntry = ClearCode + 2; + aCount = 0; + curAccum = 0; + curBits = 0; + + entry = nextPixel(); + + int hshift = 0; + int fcode; + for ( fcode = hashTableSize; fcode < 65536L; fcode *= 2L ) ++hshift; + hshift = 8 - hshift; /* set hash code range bound */ + + clearHashTable(); /* clear hash table */ + + writeCode( ClearCode,outfile ); + + int c; + while ( (c = nextPixel()) != EOF ) + { + fcode = (c << bits) + entry; + i = (c << hshift) ^ entry; /* xor hashing */ + + bool found=FALSE; + if (htab[i]==fcode) + { + entry = codetab[i]; + found=TRUE; + } + else if (htab[i]>=0) + { + int disp = hashTableSize - i; + if (i==0) disp=1; + do + { + if ((i-=disp)<0) i+=hashTableSize; + if (htab[i]==fcode) + { + entry=codetab[i]; + found=TRUE; + } + } while (htab[i]>0 && !found); + } + if (!found) + { + writeCode( entry, outfile ); + entry = c; + if ( freeEntry < maxMaxCode ) + { + codetab[i] = freeEntry++; /* code -> hashtable */ + htab[i] = fcode; + } + else + { + clearHashTable(); + freeEntry = ClearCode + 2; + clearFlag = TRUE; + writeCode( ClearCode, outfile ); + } + } + } + writeCode( entry, outfile ); + writeCode( EOFCode, outfile ); +} + +void GifEncoder::putWord( Word w, QFile &fp ) +{ + fp.putch( w & 0xff ); + fp.putch( (w>>8) & 0xff ); +} + +void GifEncoder::putByte( Byte b, QFile &fp ) +{ + fp.putch( b ); +} + +int GifEncoder::nextPixel() +{ + if ( --numPixels < 0) return EOF; + return *dataPtr++; +} + +void GifEncoder::writeCode( int code, QFile &outfile ) +{ + curAccum &= masks[ curBits ]; + + if ( curBits > 0 ) + { + curAccum |= (code << curBits); + } + else + { + curAccum = code; + } + + curBits += nBits; + + while( curBits >= 8 ) + { + writeChar( (Byte)(curAccum & 0xff),outfile ); + curAccum >>= 8; + curBits -= 8; + } + + /* + * If the next entry is going to be too big for the code size, + * then increase it, if possible. + */ + if ( freeEntry > maxCode || clearFlag ) + { + if( clearFlag ) + { + nBits = initBits; + maxCode = (1<<nBits)-1; + clearFlag = FALSE; + } + else + { + ++nBits; + if ( nBits == bits ) + maxCode = maxMaxCode; + else + maxCode = (1<<nBits)-1; + } + } + + if ( code == EOFCode ) + { + /* At EOF, write the rest of the buffer. */ + while( curBits > 0 ) + { + writeChar( (Byte)(curAccum & 0xff), outfile ); + curAccum >>= 8; + curBits -= 8; + } + + writePacket(outfile); + } +} + +/* + * Add a character to the end of the current packet, and if it is 254 + * characters, flush the packet to disk. + */ +void GifEncoder::writeChar( Byte c, QFile &fp ) +{ + accum[ aCount++ ] = c; + if( aCount >= 254 ) writePacket(fp); +} + +/* + * Flush the packet to disk, and reset the accumulator + */ +void GifEncoder::writePacket(QFile &fp) +{ + if ( aCount > 0 ) + { + fp.putch( aCount ); + fp.writeBlock( (const char *)accum, aCount ); + aCount = 0; + } +} + +void GifEncoder::clearHashTable() /* reset code table */ +{ + int *htab_p = htab; + int i; for (i=0;i<hashTableSize;i++) *htab_p++ = -1; +} + diff --git a/src/gifenc.h b/src/gifenc.h new file mode 100644 index 0000000..161e032 --- /dev/null +++ b/src/gifenc.h @@ -0,0 +1,85 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef _GIFENC_H +#define _GIFENC_H +#include <qfile.h> + +typedef unsigned char Byte; +typedef unsigned short Word; + +struct Color +{ + Byte red; + Byte green; + Byte blue; +}; + +const int hashTableSize=5003; // size of the hash table + +class GifEncoder +{ + public: + GifEncoder(Byte *rawBytes,Color *p,int w,int h,Byte d,int t); + ~GifEncoder(); + void writeGIF(QFile &fp); + + protected: + void putWord( Word w, QFile &fp ); + void putByte( Byte b, QFile &fp ); + void compress(int csize, QFile &fp); + void writeCode(int code, QFile &fp); + void writeChar( Byte c, QFile &fp ); + void writePacket(QFile &fp); + int nextPixel(); + void clearHashTable(); + + private: + const int colorResolution; // 8 bit for Red, Green and Blue; + const int globalPaletteFlag; + const int bits; + const int maxMaxCode; + + // image variables + int width; // image width + int height; // image height + Byte depth; // bits per CLUT entry + int transIndex; // index of the transparant color; -1 = none + Color *palette; // pointer to the color palette + int numPixels; // total number of pixel (i.e. width * height) + Byte *data; // pointer to the image data (one byte per pixel) + Byte *dataPtr; // pointer located at the current pixel. + + // compression variables + bool clearFlag; // clear hash table flag + int freeEntry; // first free entry in the hash table + unsigned int curAccum; // encoded bit accumulator + int curBits; // number of bits in curAccum + Byte accum[256]; // Buffer for a packet + int aCount; // Number of characters so far in this 'packet' + int nBits; // number of bits/code + int maxCode; // maximum code, given n_bits + int initBits; // initial number of bits + int EOFCode; // code for signaling the end of the file + int ClearCode; // the clear code for the decompressor + + // tables + int htab[hashTableSize]; // the hash table + Word codetab[hashTableSize]; // the code table +}; + +#endif diff --git a/src/groupdef.cpp b/src/groupdef.cpp new file mode 100644 index 0000000..6a2d79b --- /dev/null +++ b/src/groupdef.cpp @@ -0,0 +1,158 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <ctype.h> +#include "groupdef.h" +#include "classdef.h" +#include "filedef.h" +#include "classlist.h" +#include "outputlist.h" +#include "scanner.h" +#include "namespacedef.h" +#include "language.h" +#include "util.h" + +GroupDef::GroupDef(const char *na,const char *t) : Definition(na) +{ + fileList = new FileList; + classList = new ClassList; +// groupList = new GroupList; +// name = n; + if (t) + title = t; + else + { + title = na; + title.at(0)=toupper(title.at(0)); + } + fileName = "group_"+nameToFile(na); +} + +GroupDef::~GroupDef() +{ + delete fileList; + delete classList; +// delete groupList; +} + +void GroupDef::addFile(const FileDef *def) +{ + fileList->append(def); +} + +void GroupDef::addClass(const ClassDef *def) +{ + classList->append(def); +} + +void GroupDef::addNamespace(const NamespaceDef *def) +{ + namespaceList->append(def); +} + +//void GroupDef::addGroup(const GroupDef *def) +//{ +// groupList->append(def); +//} + +int GroupDef::countMembers() const +{ + return fileList->count()+classList->count(); +} + +void GroupDef::writeDocumentation(OutputList &ol) +{ + ol.disable(OutputGenerator::Man); + startFile(ol,fileName,title); + startTitle(ol); + ol.docify(title); + endTitle(ol,name()); + + //brief=brief.stripWhiteSpace(); + //int bl=brief.length(); + OutputList briefOutput(&ol); + if (!briefDescription().isEmpty()) + { + parseDoc(briefOutput,name(),0,briefDescription()); + ol+=briefOutput; + ol.writeString(" \n"); + ol.disable(OutputGenerator::Latex); + ol.startTextLink(0,"details"); + parseDoc(ol,0,0,theTranslator->trMore()); + ol.enable(OutputGenerator::Latex); + } + if (fileList->count()>0) + { + ol.startMemberHeader(); + parseDoc(ol,0,0,theTranslator->trFiles()); + ol.endMemberHeader(); + ol.startIndexList(); + FileDef *fd=fileList->first(); + while (fd) + { + ol.writeStartAnnoItem("file ",fd->diskName(),0,fd->name()); + ol.writeEndAnnoItem(fd->name()); + fd=fileList->next(); + } + ol.endIndexList(); + } + if (classList->count()>0) + { + ol.startMemberHeader(); + parseDoc(ol,0,0,theTranslator->trCompounds()); + ol.endMemberHeader(); + ol.startIndexList(); + ClassDef *cd=classList->first(); + while (cd) + { + QString type; + switch (cd->compoundType()) + { + case ClassDef::Class: type="class"; break; + case ClassDef::Struct: type="struct"; break; + case ClassDef::Union: type="union"; break; + } + ol.writeStartAnnoItem(type,cd->classFile(),0,cd->name()); + ol.writeEndAnnoItem(cd->name()); + cd=classList->next(); + } + ol.endIndexList(); + } + //int dl=doc.length(); + //doc=doc.stripWhiteSpace(); + if (!briefDescription().isEmpty() || !documentation().isEmpty()) + { + ol.writeRuler(); + ol.writeAnchor("details"); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trDetailedDescription()); + ol.endGroupHeader(); + // repeat brief description + if (!briefDescription().isEmpty()) + { + ol+=briefOutput; + ol.newParagraph(); + } + // write documentation + if (!documentation().isEmpty()) + { + parseDoc(ol,name(),0,documentation()+"\n"); + } + } + + endFile(ol); + ol.enable(OutputGenerator::Man); +} diff --git a/src/groupdef.h b/src/groupdef.h new file mode 100644 index 0000000..421b701 --- /dev/null +++ b/src/groupdef.h @@ -0,0 +1,64 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef GROUPDEF_H +#define GROUPDEF_H + +#include <qstring.h> +#include <qlist.h> +#include "definition.h" + +class FileList; +class ClassList; +class FileDef; +class ClassDef; +class NamespaceDef; +class GroupList; +class OutputList; +class NamespaceList; + +class GroupDef : public Definition +{ + public: + GroupDef(const char *name,const char *title); + ~GroupDef(); + const char *groupFile() const { return fileName; } + const char *groupTitle() const { return title; } + void addFile(const FileDef *def); + void addClass(const ClassDef *def); + void addNamespace(const NamespaceDef *def); + void writeDocumentation(OutputList &ol); + int countMembers() const; + + private: + QString title; // title of the group + QString fileName; // base name of the generated file + FileList *fileList; // list of all files in the group + ClassList *classList; // list of all classes in the group + NamespaceList *namespaceList; // list of all namespace in the group +}; + +class GroupList : public QList<GroupDef> +{ +}; + +class GroupListIterator : public QListIterator<GroupDef> +{ + public: + GroupListIterator(const GroupList &l) : QListIterator<GroupDef>(l) {} +}; + +#endif diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp new file mode 100644 index 0000000..4ab337f --- /dev/null +++ b/src/htmlgen.cpp @@ -0,0 +1,512 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <qdir.h> +#include <stdlib.h> +#include "message.h" +#include "htmlgen.h" +#include "config.h" +#include "util.h" +#include "doxygen.h" +#include "logos.h" +#include "diagram.h" + +HtmlGenerator::HtmlGenerator() : OutputGenerator() +{ + if (headerFile.length()>0) header=fileToString(headerFile); + if (footerFile.length()>0) footer=fileToString(footerFile); + dir=htmlOutputDir; +} + +HtmlGenerator::~HtmlGenerator() +{ +} + +void HtmlGenerator::append(const OutputGenerator *g) +{ + t << g->getContents(); +} + +void HtmlGenerator::init() +{ + QDir d(htmlOutputDir); + if (!d.exists() && !d.mkdir(htmlOutputDir)) + { + err("Could not create output directory %s\n",htmlOutputDir.data()); + exit(1); + } + writeLogo(htmlOutputDir); +} + +//void HtmlGenerator::generateExternalIndex() +//{ +// //printf("Generating external index...\n"); +// QFile f; +// f.setName(htmlOutputDir+"/header.html"); +// if (f.open(IO_WriteOnly)) +// { +// QTextStream tt(&f); +// if (header.length()==0) +// { +// tt << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" +// "<html><head><meta name=\"robots\" content=\"noindex\">\n" +// "<title>Doxysearch</title>\n" +// "</head><body bgcolor=\"#ffffff\">\n"; +// } +// else +// { +// tt << header; +// } +// if (!noIndexFlag) +// { +// tt << "<center>"; +// if (documentedGroups>0) +// tt << "<a doxygen=\"_doc:\" href=\"/modules.html\">Modules</a> "; +// if (hierarchyClasses>0) +// tt << "<a doxygen=\"_doc:\" href=\"/hierarchy.html\">Class hierarchy</a> "; +// if (annotatedClasses>0) +// tt << "<a doxygen=\"_doc:\" href=\"/annotated.html\">Compound list</a> "; +// if (documentedFiles>0) +// tt << "<a doxygen=\"_doc:\" href=\"/files.html\">File list</a> "; +// if (includeFiles.count()>0) +// tt << "<a doxygen=\"_doc:\" href=\"/headers.html\">Header files</a> "; +// if (documentedMembers>0) +// tt << "<a doxygen=\"_doc:\" href=\"/functions.html\">Compound Members</a> "; +// if (documentedFunctions>0) +// tt << "<a doxygen=\"_doc:\" href=\"/globals.html\">File Members</a> "; +// if (pageList.count()>0) +// tt << "<a doxygen=\"_doc:\" href=\"/pages.html\">Related Pages</a> "; +// if (exampleList.count()>0) +// tt << "<a doxygen=\"_doc:\" href=\"/examples.html\">Examples</a> "; +// if (searchEngineFlag) +// tt << "<a doxygen=\"_cgi:\" href=\"\">Search</a>"; +// tt << endl << "</center><hr>" << endl; +// } +// } +// f.close(); +// +// f.setName(htmlOutputDir+"/footer.html"); +// if (f.open(IO_WriteOnly)) +// { +// QTextStream tt(&f); +// if (footer.length()==0) +// { +// tt << "<hr><address><small>Generated at " << dateToString(TRUE); +// if (projectName.length()>0) tt << " for " << projectName; +// tt << " by <a href=\"http://www.stack.nl/~dimitri/doxygen/index.html\">" +// "doxygen</a> written by <a href=" +// "\"mailto:dimitri@stack.nl\">Dimitri van Heesch</a>, © " +// "1997-1999</small></address>\n</body>\n</html>\n"; +// } +// else +// { +// tt << footer; +// } +// } +// f.close(); +//} + +void HtmlGenerator::startFile(const char *name,const char *title,bool external) +{ + QString fileName=name; + if (fileName.right(5)!=".html") fileName+=".html"; + startPlainFile(fileName); + if (header.length()==0) + { + t << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" + "<html><head><meta name=\"robots\" content=\"noindex\">\n" + "<title>" << title << "</title>\n"; + t << "<link "; + if (external) + t << "doxygen=\"_doc:\" href=\"/"; + else + t << "href=\""; + t << "doxygen.css\" rel=\"stylesheet\" type=\"text/css\">\n" + "</head><body bgcolor=\"#ffffff\">\n"; + } + else + { + t << header; + } + +// if (!noIndexFlag) +// { +// t << "<center>"; +// if (documentedGroups>0) +// t << "<a href=\"modules.html\">Modules</a> "; +// if (hierarchyClasses>0) +// t << "<a href=\"hierarchy.html\">Class hierarchy</a> "; +// if (annotatedClasses>0) +// t << "<a href=\"annotated.html\">Compound list</a> "; +// if (documentedFiles>0) +// t << "<a href=\"files.html\">File list</a> "; +// if (includeFiles.count()>0) +// t << "<a href=\"headers.html\">Header files</a> "; +// if (documentedMembers>0) +// t << "<a href=\"functions.html\">Compound Members</a> "; +// if (documentedFunctions>0) +// t << "<a href=\"globals.html\">File Members</a> "; +// if (pageList.count()>0) +// t << "<a href=\"pages.html\">Related Pages</a> "; +// if (exampleList.count()>0) +// t << "<a href=\"examples.html\">Examples</a> "; +// if (searchEngineFlag) +// t << "<a doxygen=\"_cgi:\" href=\"\">Search</a>"; +// t << endl << "</center><hr>" << endl; +// } +} + +void HtmlGenerator::startQuickIndexItem(const char *s,const char *l) +{ + t << "<a "; + if (s) t << "doxygen=\"" << s << "\" "; + t << "href=\"" << l << "\">"; +} + +void HtmlGenerator::endQuickIndexItem() +{ + t << "</a> "; +} + +void HtmlGenerator::writeFooter(int part,bool external) +{ + switch (part) + { + case 0: + if (footer.length()==0) + t << "<hr><address><small>"; + else + t << footer; + break; + case 1: + if (footer.length()==0) + { + t << " <a href=\"http://www.stack.nl/~dimitri/doxygen/index.html\">"; + t << "<img "; + if (external) + { + t << "doxygen=\"_doc:\" src=\"/"; + } + else + { + t << "src=\""; + } + t << "doxygen.gif\" alt=\"doxygen\" align=center border=0 " + "width=118 height=53></a> "; + } + break; + default: + if (footer.length()==0) + t << " <a href=\"mailto:dimitri@stack.nl\">Dimitri van Heesch</a>, © " + "1997-1999</small></address>\n</body>\n</html>\n"; + break; + + } +} + +void HtmlGenerator::endFile() +{ +// if (footer.length()==0) +// { +// t << "<hr><address><small>Generated at " << dateToString(TRUE); +// if (projectName.length()>0) +// { +// t << " for "; +// docify(projectName); +// } +// t << " by <a href=\"http://www.stack.nl/~dimitri/doxygen/index.html\">" +// "<img src=\"doxygen.gif\" alt=\"doxygen\" align=center border=0 " +// "width=118 height=53></a> written by <a href=" +// "\"mailto:dimitri@stack.nl\">Dimitri van Heesch</a>, © " +// "1997-1999</small></address>\n</body>\n</html>\n"; +// } +// else +// { +// t << footer; +// } + endPlainFile(); +} + +void HtmlGenerator::startProjectNumber() +{ + t << "<h3 align=center>"; +} + +void HtmlGenerator::endProjectNumber() +{ + t << "</h3>"; +} + +//void HtmlGenerator::writeIndex() +//{ +// startFile("index.html","Main Index"); +// t << "<h1 align=center>"; +// docify(projectName); +// t << " Documentation</h1>" +// << "<p>" << endl << "<p>" << endl; +// if (!projectNumber.isEmpty()) +// { +// t << "<h3 align=center>"; +// docify(projectNumber); +// t << "</h3>\n<p>\n<p>\n"; +// } +// if (noIndexFlag) +// { +// t << "<ul>" << endl; +// if (hierarchyClasses>0) +// t << "<li><a href=\"hierarchy.html\">Class hierarchy</a>" << endl; +// if (annotatedClasses>0) +// t << "<li><a href=\"annotated.html\">Compound list</a>" << endl; +// if (documentedFiles>0) +// t << "<li><a href=\"files.html\">File list</a>" << endl; +// if (includeFiles.count()>0) +// t << "<li><a href=\"headers.html\">Header files</a>" << endl; +// if (documentedMembers>0) +// t << "<li><a href=\"functions.html\">Compound Members</a>" << endl; +// if (documentedFunctions>0) +// t << "<li><a href=\"globals.html\">File Members</a>" << endl; +// if (pageList.count()>0) +// t << "<li><a href=\"pageList.html\">Related Pages</a>" << endl; +// if (exampleList.count()>0) +// t << "<li><a href=\"examples.html\">Examples</a>" << endl; +// if (searchEngineFlag) +// t << "<li><a doxygen=\"_cgi:\" href=\"\">Search</a>" << endl; +// t << "</ul>" << endl; +// } +// endFile(); +//} + +void HtmlGenerator::writeStyleInfo(int part) +{ + if (part==0) + { + startPlainFile("doxygen.css"); + t << "H1 { border-width: thin; border: solid; text-align: center }" << endl + << "A.el { text-decoration: none; font-weight: bold }" << endl + << "DL.el { margin-left: -1cm }" << endl + << "DIV.fragment { width: 100%; border: none; background-color: #eeeeee }" << endl + << "DIV.in { margin-left: 16 }" << endl + << endl; + endPlainFile(); + } +} + +void HtmlGenerator::writeDoxyAnchor(const char *,const char *anchor, const char *name) +{ + t << "<a name=\"" << anchor << "\" doxytag=\"" << name << "\"></a>"; +} + +void HtmlGenerator::newParagraph() +{ + t << endl << "<p>" << endl; +} + +void HtmlGenerator::writeString(const char *text) +{ + t << text; +} + +void HtmlGenerator::writeIndexItem(const char *ref,const char *f, + const char *name) +{ + t << "<li>"; + if (ref || f) + { + t << "<a class=\"el\" "; + if (ref) t << "doxygen=\"" << ref << ":\" "; + t << "href=\""; + if (f) t << f << ".html\">"; + } + else + { + t << "<b>"; + } + docify(name); + if (ref || f) + { + t << "</a>" << endl; + } + 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 << ".html\">"; + docify(name); + t << "</a> "; +} + +void HtmlGenerator::writeObjectLink(const char *ref,const char *f, + const char *anchor, const char *name) +{ + t << "<a class=\"el\" "; + if (ref) t << "doxygen=\"" << ref << ":\" "; + t << "href=\""; + if (f) t << f << ".html"; + if (anchor) t << "#" << anchor; + t << "\">"; + docify(name); + t << "</a>"; +} + +void HtmlGenerator::startTextLink(const char *f,const char *anchor) +{ + t << "<a href=\""; + if (f) t << f << ".html"; + if (anchor) t << "#" << anchor; + t << "\">"; +} + +void HtmlGenerator::endTextLink() +{ + t << "</a>"; +} + +void HtmlGenerator::writeHtmlLink(const char *url,const char *text) +{ + t << "<a href=\""; + if (url) t << url; + t << "\">"; + docify(text); + t << "</a>"; +} + +void HtmlGenerator::startGroupHeader() +{ + t << "<h2>"; +} + +void HtmlGenerator::endGroupHeader() +{ + t << "</h2>" << endl; +} + +void HtmlGenerator::writeSection(const char *lab,const char *title,bool sub) +{ + t << "<a name=\"" << lab << "\">"; + if (sub) t << "<h3>"; else t << "<h2>"; + docify(title); + if (sub) t << "</h3>"; else t << "</h2>"; + t << "</a>" << endl; +} + +void HtmlGenerator::writeSectionRef(const char *name,const char *lab, + const char *title) +{ + QString refName=name; + if (refName.right(5)!=".html") refName+=".html"; + t << ""<a href=\"" << refName << "#" << lab << "\">"; + docify(title); + t << "</a>""; +} + +void HtmlGenerator::writeSectionRefItem(const char *name,const char *lab, + const char *title) +{ + QString refName=name; + if (refName.right(5)!=".html") refName+=".html"; + t << "<a href=\"" << refName << "#" << lab << "\">"; + docify(title); + t << "</a>"; +} + +//void HtmlGenerator::docify(const char *str) +//{ +// docifyStatic(t,str); +//} + +//void HtmlGenerator::docifyStatic(QTextStream &t,const char *str) +void HtmlGenerator::docify(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 '\\': + if (*p=='<') + { t << "<"; p++; } + else if (*p=='>') + { t << ">"; p++; } + else + t << "\\"; + break; + default: t << c; + } + } + } +} + +void HtmlGenerator::codify(const char *str) +{ + docify(str); +} + +void HtmlGenerator::writeChar(char c) +{ + char cs[2]; + cs[0]=c; + cs[1]=0; + docify(cs); +} + +void HtmlGenerator::startClassDiagram() +{ + t << "<p>"; +} + +void HtmlGenerator::endClassDiagram(ClassDiagram &d, + const char *fileName,const char *name) +{ + t << ":\n<p><center><img src=\"" + << fileName << ".gif\" usemap=\"#" << name << "_map\"" + << " border=\"0\"></center>" << endl + << "<map name=\"" << name << "_map\"><p>" << endl; + + d.writeImageMap(t,dir,fileName); +} + +void HtmlGenerator::startColorFont(uchar red,uchar green,uchar blue) +{ + QString colorString; + colorString.sprintf("%02x%02x%02x",red,green,blue); + t << "<font color=\"#" << colorString << "\">"; +} + +void HtmlGenerator::endColorFont() +{ + t << "</font>"; +} + +void HtmlGenerator::writeFormula(const char *n,const char *text) +{ + if (text && text[0]=='\\') t << "<p><center>" << endl; + t << "<img align=\"top\" src=\"" << n << "\">" << endl; + if (text && text[0]=='\\') t << "</center></p>" << endl; +} diff --git a/src/htmlgen.h b/src/htmlgen.h new file mode 100644 index 0000000..c8a5223 --- /dev/null +++ b/src/htmlgen.h @@ -0,0 +1,174 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef HTMLGEN_H +#define HTMLGEN_H + +#include "outputgen.h" + +class QFile; + +class HtmlGenerator : public OutputGenerator +{ + public: + HtmlGenerator(); + ~HtmlGenerator(); + + OutputGenerator *copy() { return new HtmlGenerator; } + //OutputGenerator *clone() { return new HtmlGenerator(*this); } + void append(const OutputGenerator *o); + void enable() { active=TRUE; } + void disable() { active=FALSE; } + void enableIf(OutputType o) { if (o==Html) active=TRUE; } + void disableIf(OutputType o) { if (o==Html) active=FALSE; } + void disableIfNot(OutputType o) { if (o!=Html) active=FALSE; } + bool isEnabled(OutputType o) { return (o==Html && active); } + OutputGenerator *get(OutputType o) { return (o==Html) ? this : 0; } + + static void init(); + //void generateExternalIndex(); + void startFile(const char *name,const char *title,bool external); + void writeFooter(int,bool); + void endFile(); + void clearBuffer(); + + //void writeIndex(); + void startIndexSection(IndexSections) {} + void endIndexSection(IndexSections) {} + void startProjectNumber(); + void endProjectNumber(); + void writeStyleInfo(int part); + void startTitleHead() { startTitle(); } + void endTitleHead(const char *) { endTitle(); } + void startTitle() { t << "<h1>"; } + void endTitle() { t << "</h1>"; } + + void newParagraph(); + void writeString(const char *text); + void startIndexList() { t << "<ul>" << endl; } + void endIndexList() { t << "</ul>" << endl; } + void startItemList() { t << "<ul>" << endl; } + void endItemList() { t << "</ul>" << endl; } + void startEnumList() { t << "<ol>" << endl; } + void endEnumList() { t << "</ol>" << endl; } + void writeIndexItem(const char *ref,const char *file,const char *name); + 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 *f, + const char *anchor,const char *name) + { writeObjectLink(ref,f,anchor,name); } + void startTextLink(const char *file,const char *anchor); + void endTextLink(); + void writeHtmlLink(const char *url,const char *text); + void startTypewriter() { t << "<code>"; } + void endTypewriter() { t << "</code>"; } + void startGroupHeader(); + void endGroupHeader(); + void writeListItem() { t << "<li>"; } + + void startMemberHeader() { startGroupHeader(); } + void endMemberHeader() { endGroupHeader(); } + void startMemberList() { t << "<ul>" << endl; } + void endMemberList() { t << "</ul>" << endl; } + void startMemberItem() { t << "<li>"; } + void endMemberItem() { t << endl; } + + void writeRuler() { t << "<hr>"; } + void writeAnchor(const char *name) + { t << "<a name=\"" << name <<"\"></a>"; } + void startCodeFragment() { t << "<div class=\"fragment\"><pre>"; } + void endCodeFragment() { t << "</div></pre>"; } + void writeBoldString(const char *text) + { t << "<b>"; docify(text); t << "</b>"; } + void startEmphasis() { t << "<em>"; } + void endEmphasis() { t << "</em>"; } + void startBold() { t << "<b>"; } + void endBold() { t << "</b>"; } + void startDescription() { t << endl << "<dl compact>" << endl; } + void endDescription() { t << endl << "</dl>" << endl; } + void startDescItem() { t << "<dt>"; } + void endDescItem() { t << "<dd>"; } + void lineBreak() { t << "<br>" << endl; } + void writeChar(char c); + void startMemberDoc(const char *,const char *,const char *) + { t << endl << "<h3>"; } + void endMemberDoc() { t << "</h3>" << endl; } + void writeDoxyAnchor(const char *clName,const char *anchor, + const char *name); + 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 startSubscript() { t << "<sub>"; } + void endSubscript() { t << "</sub>"; } + void startSuperscript() { t << "<sup>"; } + void endSuperscript() { t << "</sup>"; } + void startTable(int) { t << "<table border=1 cellspacing=3 cellpadding=3>"; } + void endTable() { t << "</table>" << endl; } + void nextTableRow() { t << endl << "<tr><td>"; } + void endTableRow() { t << "</tr>" << endl; } + void nextTableColumn() { t << "<td>"; } + void endTableColumn() { t << "</td>"; } + void writeCopyright() { t << "©"; } + void writeQuote() { t << """; } + void writeUmlaut(char c) { t << "&" << c << "uml;"; } + void writeAcute(char c) { t << "&" << c << "acute;"; } + void writeGrave(char c) { t << "&" << c << "grave;"; } + void writeCirc(char c) { t << "&" << c << "circ;"; } + void writeTilde(char c) { t << "&" << c << "tilde;"; } + void startMemberDescription() { t << "<dl class=\"el\"><dd><font size=-1><em>"; } + void endMemberDescription() { t << "</em></font></dl>"; } + void startDescList() { t << "<dl compact><dt>" << endl; } + void endDescTitle() {} + void writeDescItem() { t << "<dd>" << endl; } + void endDescList() { t << "</dl>"; } + void writeSection(const char *,const char *,bool); + void writeSectionRef(const char *,const char *,const char *); + void writeSectionRefItem(const char *,const char *,const char *); + void addToIndex(const char *,const char *) {} + void startIndent() { t << "<div class=\"in\">" << endl; } + void endIndent() { t << "</div>" << endl; } + void writeSynopsis() {} + void startClassDiagram(); + void endClassDiagram(ClassDiagram &,const char *,const char *); + void startColorFont(uchar r,uchar g,uchar b); + void endColorFont(); + void writePageRef(const char *,const char *) {} + void startQuickIndexItem(const char *,const char *); + void endQuickIndexItem(); + void writeFormula(const char *,const char *); + + //static void docifyStatic(QTextStream &t,const char *str); + + private: + QString header; + QString footer; + + HtmlGenerator &operator=(const HtmlGenerator &g); + HtmlGenerator(const HtmlGenerator &g); +}; + +#endif diff --git a/src/image.cpp b/src/image.cpp new file mode 100644 index 0000000..853d4ea --- /dev/null +++ b/src/image.cpp @@ -0,0 +1,443 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include "image.h" +#include "gifenc.h" +#include <qglobal.h> +#include <qstring.h> + +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 +}; + + +#if 0 +const int charSetWidth=68; +const int charHeight=12; +const int numChars=80; + +unsigned short charPos[numChars] = + { 0, 7, 14, 21, 28, 35, 42, 49, + 56, 63, 70, 73, 76, 83, 90, 97, + 104,116,125,133,142,151,159,167, + 176,185,188,195,203,210,221,230, + 240,248,258,266,274,281,289,298, + 309,318,327,336,339,343,346,352, + 359,362,369,376,383,390,397,401, + 407,414,417,420,426,429,438,445, + 452,459,465,470,476,479,486,493, + 502,508,515,521,525,528,532,539 + }; + +unsigned char charWidth[numChars] = + { + 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, 6, + 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] = { + 0x38, 0x20, 0xe1, 0xc0, 0x8f, 0x8e, 0x3e, 0x38, 0x70, 0x00, 0x00, 0x00, + 0x1c, 0x0f, 0x80, 0x83, 0xe0, 0xf1, 0xf0, 0xfc, 0xfc, 0x3c, 0x41, 0x20, + 0x48, 0x48, 0x10, 0x12, 0x08, 0x78, 0x7c, 0x1e, 0x1f, 0x0f, 0x3f, 0xa1, + 0x20, 0x91, 0x12, 0x09, 0x04, 0xfe, 0x71, 0x80, 0x00, 0x80, 0x20, 0x00, + 0x08, 0x01, 0x80, 0x81, 0x24, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xc0, 0x00, 0x44, 0xe1, 0x12, 0x21, + 0x88, 0x11, 0x02, 0x44, 0x88, 0x00, 0x00, 0x00, 0x22, 0x30, 0x41, 0x42, + 0x11, 0x09, 0x08, 0x80, 0x80, 0x42, 0x41, 0x20, 0x48, 0x88, 0x18, 0x33, + 0x08, 0x84, 0x42, 0x21, 0x10, 0x90, 0x84, 0x21, 0x20, 0x91, 0x11, 0x11, + 0x04, 0x02, 0x50, 0x88, 0x01, 0x00, 0x20, 0x00, 0x08, 0x02, 0x00, 0x80, + 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x22, 0x20, 0x00, 0x44, 0x20, 0x10, 0x22, 0x88, 0x10, 0x04, 0x44, + 0x88, 0x00, 0x00, 0x00, 0x22, 0x26, 0xa1, 0x42, 0x12, 0x01, 0x04, 0x80, + 0x80, 0x80, 0x41, 0x20, 0x49, 0x08, 0x18, 0x32, 0x89, 0x02, 0x42, 0x40, + 0x90, 0x90, 0x04, 0x21, 0x11, 0x11, 0x11, 0x10, 0x88, 0x04, 0x48, 0x94, + 0x01, 0x8e, 0x2c, 0x38, 0x68, 0xe7, 0x34, 0xb1, 0x24, 0x92, 0x91, 0x61, + 0xc5, 0x86, 0x94, 0xce, 0x89, 0x14, 0x46, 0x14, 0x4f, 0x22, 0x20, 0x00, + 0x44, 0x20, 0x20, 0xc2, 0x8f, 0x16, 0x04, 0x38, 0x89, 0x20, 0xc0, 0x18, + 0x04, 0x49, 0x22, 0x22, 0x12, 0x01, 0x04, 0x80, 0x80, 0x80, 0x41, 0x20, + 0x4a, 0x08, 0x14, 0x52, 0x89, 0x02, 0x42, 0x40, 0x90, 0x8c, 0x04, 0x21, + 0x11, 0x09, 0x20, 0xa0, 0x88, 0x08, 0x48, 0xa2, 0x00, 0x11, 0x32, 0x44, + 0x99, 0x12, 0x4c, 0xc9, 0x25, 0x13, 0x69, 0x92, 0x26, 0x49, 0x99, 0x24, + 0x89, 0x14, 0x45, 0x24, 0x41, 0x22, 0x20, 0x00, 0x44, 0x20, 0x40, 0x24, + 0x80, 0x99, 0x08, 0x44, 0x78, 0x03, 0x0f, 0x86, 0x04, 0x51, 0x22, 0x23, + 0xe2, 0x01, 0x04, 0xfc, 0xf8, 0x8e, 0x7f, 0x20, 0x4e, 0x08, 0x14, 0x52, + 0x49, 0x02, 0x7c, 0x40, 0x9f, 0x03, 0x04, 0x21, 0x11, 0x0a, 0xa0, 0x40, + 0x50, 0x10, 0x44, 0x80, 0x00, 0x01, 0x22, 0x40, 0x89, 0x12, 0x44, 0x89, + 0x26, 0x12, 0x49, 0x12, 0x24, 0x48, 0x91, 0x04, 0x89, 0x12, 0x48, 0xc4, + 0x42, 0x22, 0x26, 0x40, 0x44, 0x20, 0x80, 0x28, 0x80, 0x91, 0x08, 0x44, + 0x08, 0x0c, 0x00, 0x01, 0x88, 0x51, 0x23, 0xe2, 0x12, 0x01, 0x04, 0x80, + 0x80, 0x82, 0x41, 0x20, 0x49, 0x08, 0x12, 0x92, 0x29, 0x02, 0x40, 0x44, + 0x91, 0x00, 0x84, 0x21, 0x0a, 0x0a, 0xa0, 0xa0, 0x20, 0x20, 0x44, 0x80, + 0x00, 0x0f, 0x22, 0x40, 0x89, 0xf2, 0x44, 0x89, 0x26, 0x12, 0x49, 0x12, + 0x24, 0x48, 0x90, 0xc4, 0x88, 0xa2, 0x48, 0xc4, 0x84, 0x42, 0x19, 0x80, + 0x44, 0x21, 0x02, 0x2f, 0xc8, 0x91, 0x08, 0x44, 0x08, 0x03, 0x0f, 0x86, + 0x08, 0x53, 0x44, 0x12, 0x12, 0x01, 0x04, 0x80, 0x80, 0x82, 0x41, 0x24, + 0x48, 0x88, 0x12, 0x92, 0x29, 0x02, 0x40, 0x42, 0x90, 0x90, 0x84, 0x21, + 0x0a, 0x04, 0x41, 0x10, 0x20, 0x40, 0x44, 0x80, 0x00, 0x11, 0x22, 0x40, + 0x89, 0x02, 0x44, 0x89, 0x25, 0x12, 0x49, 0x12, 0x24, 0x48, 0x90, 0x24, + 0x88, 0xa2, 0xa9, 0x22, 0x84, 0x22, 0x20, 0x00, 0x44, 0x21, 0x02, 0x20, + 0x88, 0x91, 0x10, 0x44, 0x88, 0x00, 0xc0, 0x18, 0x00, 0x4d, 0x84, 0x12, + 0x11, 0x09, 0x08, 0x80, 0x80, 0x46, 0x41, 0x24, 0x48, 0x48, 0x11, 0x12, + 0x18, 0x84, 0x40, 0x21, 0x10, 0x90, 0x84, 0x21, 0x04, 0x04, 0x41, 0x10, + 0x20, 0x80, 0x42, 0x80, 0x00, 0x11, 0x32, 0x44, 0x99, 0x12, 0x4c, 0x89, + 0x24, 0x92, 0x49, 0x12, 0x26, 0x49, 0x91, 0x24, 0x98, 0x41, 0x12, 0x12, + 0x88, 0x22, 0x20, 0x00, 0x38, 0x21, 0xf1, 0xc0, 0x87, 0x0e, 0x10, 0x38, + 0x71, 0x20, 0x00, 0x00, 0x08, 0x20, 0x04, 0x13, 0xe0, 0xf1, 0xf0, 0xfc, + 0x80, 0x3a, 0x41, 0x23, 0x88, 0x2f, 0x91, 0x12, 0x08, 0x78, 0x40, 0x1e, + 0x90, 0x8f, 0x04, 0x1e, 0x04, 0x04, 0x42, 0x08, 0x20, 0xfe, 0x42, 0x80, + 0x00, 0x0e, 0xac, 0x38, 0x68, 0xe2, 0x34, 0x89, 0x24, 0x52, 0x49, 0x11, + 0xc5, 0x86, 0x90, 0xc6, 0x68, 0x41, 0x12, 0x11, 0x0f, 0x22, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x1f, 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, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x22, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 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, 0x40, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x22, 0x20, 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, 0x61, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x1a, 0xc0, 0x00 +}; +#endif + +static Color palette[] = +{ + { 0xff, 0xff, 0xff }, + { 0x00, 0x00, 0x00 }, + { 0xff, 0xff, 0xc0 }, + { 0x9f, 0x9f, 0x60 }, + { 0x90, 0x00, 0x00 }, + { 0x00, 0x90, 0x00 }, + { 0x00, 0x00, 0x90 }, + { 0xc0, 0xc0, 0xc0 } +}; + +static Color palette2[] = +{ + { 0xff, 0xff, 0xff }, + { 0xe0, 0xe0, 0xe0 }, + { 0xd0, 0xd0, 0xd0 }, + { 0xc0, 0xc0, 0xc0 }, + { 0xb0, 0xb0, 0xb0 }, + { 0xa0, 0xa0, 0xa0 }, + { 0x90, 0x90, 0x90 }, + { 0x80, 0x80, 0x80 }, + { 0x70, 0x70, 0x70 }, + { 0x60, 0x60, 0x60 }, + { 0x50, 0x50, 0x50 }, + { 0x40, 0x40, 0x40 }, + { 0x30, 0x30, 0x30 }, + { 0x20, 0x20, 0x20 }, + { 0x10, 0x10, 0x10 }, + { 0x00, 0x00, 0x00 } +}; + +Image::Image(int w,int h) +{ + 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 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 width,int height,uchar colIndex,uint mask) +{ + int xp,yp,xi,yi; + for (yp=y,yi=0;yp<y+height;yp++,yi++) + for (xp=x,xi=0;xp<x+width;xp++,xi++) + if (mask&(1<<((xi+yi)&0x1f))) + setPixel(xp,yp,colIndex); +} + +bool Image::save(const char *fileName,int mode) +{ + 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; + } +} diff --git a/src/image.h b/src/image.h new file mode 100644 index 0000000..a48a1f8 --- /dev/null +++ b/src/image.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * + * $Id$ + * + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef _IMAGE_H +#define _IMAGE_H +#include <qglobal.h> + +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; } + + private: + int width; + int height; + uchar *data; +}; + +#endif diff --git a/src/index.cpp b/src/index.cpp new file mode 100644 index 0000000..d472542 --- /dev/null +++ b/src/index.cpp @@ -0,0 +1,975 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <qtstream.h> +#include <qdatetm.h> +#include <qdir.h> +#include <stdlib.h> + +#include "message.h" +#include "index.h" +#include "doxygen.h" +#include "scanner.h" +#include "code.h" +#include "config.h" +#include "filedef.h" +#include "outputlist.h" +#include "util.h" +#include "groupdef.h" +#include "language.h" + +//---------------------------------------------------------------------------- + +// strips w from s iff s starts with w +bool stripWord(QString &s,QString 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 :^) +QString abbreviate(const char *s,const char *name) +{ + QString result=s; + QString start1=(QString)"The "+name+" class "; + QString start2=(QString)"The "+name+" widget "; + QString start3=(QString)"The "+name+" file "; + result=result.simplifyWhiteSpace(); + // strip trailing . + if (result.length()>0 && result.at(result.length()-1)=='.') + result=result.left(result.length()-1); + bool found=FALSE; + found = found || stripWord(result,start1); + found = found || stripWord(result,start2); + found = found || stripWord(result,start3); + if (found) + { + bool found=FALSE; + found = found || stripWord(result,"is "); + found = found || stripWord(result,"provides "); + found = found || stripWord(result,"specifies "); + found = found || stripWord(result,"contains "); + found = found || stripWord(result,"represents "); + if (found) + { + stripWord(result,"a "); + stripWord(result,"an "); + stripWord(result,"the "); + } + } + if (result.length()>0) + { + int c=result[0]; + if (c>='a' && c<='z') c+='A'-'a'; + result[0]=c; + } + return result; +} + +//---------------------------------------------------------------------------- + +void initBaseClassHierarchy(BaseClassList *bcl) +{ + BaseClassListIterator bcli(*bcl); + for ( ; bcli.current(); ++bcli) + { + ClassDef *cd=bcli.current()->classDef; + if (cd->baseClasses()->count()==0) // no base classes => new root + { + initBaseClassHierarchy(cd->baseClasses()); + } + cd->visited=FALSE; + } +} + +//---------------------------------------------------------------------------- + +void initClassHierarchy(ClassList *cl) +{ + ClassListIterator cli(*cl); + ClassDef *cd; + for ( ; (cd=cli.current()); ++cli) + { + cd->visited=FALSE; + initBaseClassHierarchy(cd->baseClasses()); + } +} + +//---------------------------------------------------------------------------- + +bool hasVisibleRoot(BaseClassList *bcl) +{ + BaseClassListIterator bcli(*bcl); + for ( ; bcli.current(); ++bcli) + { + ClassDef *cd=bcli.current()->classDef; + if (cd->isVisibleExt()) return TRUE; + hasVisibleRoot(cd->baseClasses()); + } + return FALSE; +} + +//---------------------------------------------------------------------------- + +void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper) +{ + BaseClassListIterator bcli(*bcl); + bool started=FALSE; + for ( ; bcli.current() ; ++bcli) + { + ClassDef *cd=bcli.current()->classDef; + if (cd->isVisibleExt() && hasVisibleRoot(cd->baseClasses())) + { + if (!started) + { + ol.startIndexList(); + started=TRUE; + } + //printf("Passed...\n"); + if (cd->hasDocumentation() || cd->isReference()) + { + ol.writeIndexItem(cd->getReference(),cd->classFile(),cd->name()); + if (cd->isReference()) + { + ol.startTypewriter(); + ol.docify(" [external]"); + ol.endTypewriter(); + } + } + else + { + ol.writeIndexItem(0,0,cd->name()); + } + if (!cd->visited && !hideSuper && cd->superClasses()->count()>0) + { + writeClassTree(ol,cd->superClasses(),cd->visited); + cd->visited=TRUE; + } + } + } + if (started) ol.endIndexList(); +} + +//---------------------------------------------------------------------------- + +void writeClassHierarchy(OutputList &ol) +{ + initClassHierarchy(&classList); + + bool started=FALSE; + ClassListIterator cli(classList); + for (;cli.current(); ++cli) + { + ClassDef *cd=cli.current(); + if (!hasVisibleRoot(cd->baseClasses())) + { + if (cd->isVisibleExt()) + { + if (!started) + { + ol.startIndexList(); + started=TRUE; + } + if (cd->hasDocumentation() || cd->isReference()) + { + ol.writeIndexItem(cd->getReference(),cd->classFile(),cd->name()); + if (cd->isReference()) + { + ol.startTypewriter(); + ol.docify(" [external]"); + ol.endTypewriter(); + } + } + else + { + ol.writeIndexItem(0,0,cd->name()); + } + } + if (!cd->visited && cd->superClasses()->count()>0) + { + writeClassTree(ol,cd->superClasses(),cd->visited); + cd->visited=TRUE; + } + } + } + if (started) ol.endIndexList(); +} + +//---------------------------------------------------------------------------- + +int countClassHierarchy() +{ + initClassHierarchy(&classList); + int count=0; + ClassListIterator cli(classList); + for ( ; cli.current(); ++cli) + { + if (cli.current()->superClasses()->count()>0) count++; + } + return count; +} + +//---------------------------------------------------------------------------- + +void writeHierarchicalIndex(OutputList &ol) +{ + if (hierarchyClasses==0) return; + ol.disable(OutputGenerator::Man); + startFile(ol,"hierarchy","Hierarchical Index"); + startTitle(ol); + parseDoc(ol,0,0,projectName+" "+theTranslator->trClassHierarchy()); + endTitle(ol,0); + parseDoc(ol,0,0,theTranslator->trClassHierarchyDescription()); + ol.newParagraph(); + writeClassHierarchy(ol); + endFile(ol); + ol.enable(OutputGenerator::Man); +} + +//---------------------------------------------------------------------------- + +int countFileList() +{ + int count=0; + FileNameListIterator fnli(inputNameList); + FileName *fn; + for (;(fn=fnli.current());++fnli) + { + FileNameIterator fni(*fn); + FileDef *fd; + for (;(fd=fni.current());++fni) + { + if (fd->hasDocumentation()) count++; + } + } + return count; +} + +//---------------------------------------------------------------------------- + +void writeFileIndex(OutputList &ol) +{ + if (documentedFiles==0) return; + ol.disable(OutputGenerator::Man); + startFile(ol,"files","File Index"); + startTitle(ol); + parseDoc(ol,0,0,projectName+" "+theTranslator->trFileList()); + endTitle(ol,0); + ol.newParagraph(); + parseDoc(ol,0,0,theTranslator->trFileListDescription(extractAllFlag)); + ol.newParagraph(); + + ol.startIndexList(); + FileName *fn=inputNameList.first(); + while (fn) + { + FileDef *fd=fn->first(); + while (fd) + { + if (fd->hasDocumentation() && !fd->isReference()) + { + //ol.writeIndexItem(fd->getReference(),fd->diskName(), + // fd->name()); + QString path; + if (fullPathNameFlag) + { + path=fd->getPath().copy(); + // strip part of the path + if (path.left(stripFromPath.length())==stripFromPath) + path=path.right(path.length()-stripFromPath.length()); + } + + ol.writeStartAnnoItem("file", + fd->diskName(), + path, + fd->name() + ); + ol.docify(" ("); + if (fd->briefDescription()) + { + OutputList briefOutput(&ol); + parseDoc(briefOutput,0,0, + abbreviate(fd->briefDescription(),fd->name())); + ol+=briefOutput; + } + else + { + ol.startEmphasis(); + parseDoc(ol,0,0,theTranslator->trNoDescriptionAvailable()); + ol.endEmphasis(); + } + ol.docify(")"); + ol.writeEndAnnoItem(fd->name()); + } + fd=fn->next(); + } + fn=inputNameList.next(); + } + ol.endIndexList(); + endFile(ol); + ol.enable(OutputGenerator::Man); +} + +//---------------------------------------------------------------------------- + +int countNamespaceList() +{ + int count=0; + NamespaceListIterator nli(namespaceList); + NamespaceDef *nd; + for (;(nd=nli.current());++nli) + { + if (nd->hasDocumentation()) count++; + } + return count; +} + +//---------------------------------------------------------------------------- + +void writeNamespaceIndex(OutputList &ol) +{ + if (documentedNamespaces==0) return; + ol.disable(OutputGenerator::Man); + startFile(ol,"namespaces","Namespace Index"); + startTitle(ol); + parseDoc(ol,0,0,projectName+" "+theTranslator->trNamespaceList()); + endTitle(ol,0); + ol.newParagraph(); + parseDoc(ol,0,0,theTranslator->trNamespaceListDescription(extractAllFlag)); + ol.newParagraph(); + + ol.startIndexList(); + NamespaceDef *nd=namespaceList.first(); + while (nd) + { + if (nd->hasDocumentation()) + { + ol.writeStartAnnoItem("namespace",nd->namespaceFile(),0,nd->name()); + ol.docify(" ("); + if (nd->briefDescription()) + { + OutputList briefOutput(&ol); + parseDoc(briefOutput,nd->name(),0, + abbreviate(nd->briefDescription(),nd->name())); + ol+=briefOutput; + } + else + { + ol.startEmphasis(); + parseDoc(ol,0,0,theTranslator->trNoDescriptionAvailable()); + ol.endEmphasis(); + } + ol.docify(")"); + ol.writeEndAnnoItem(nd->name()); + } + nd=namespaceList.next(); + } + ol.endIndexList(); + endFile(ol); + ol.enable(OutputGenerator::Man); +} + +//---------------------------------------------------------------------------- + +int countAnnotatedClasses() +{ + int count=0; + //ClassDef *cd=classList.first(); + ClassListIterator cli(classList); + ClassDef *cd; + for (;(cd=cli.current());++cli) + { + if (!cd->isReference() && cd->isVisible()) + { + //printf("Annotated class %s\n",cd->name().data()); + count++; + } + } + return count; +} + +//---------------------------------------------------------------------- + +void writeAnnotatedClassList(OutputList &ol) +{ + ol.startIndexList(); + //ClassDef *cd=classList.first(); + //while (cd) + ClassListIterator cli(classList); + ClassDef *cd; + for (;(cd=cli.current());++cli) + { + if (!cd->isReference() && + //!cd->name().isEmpty() && cd->name()[0]!='@' && + //(cd->protection()!=Private || extractPrivateFlag) && + //(cd->hasDocumentation() || !hideClassFlag) + cd->isVisible() + ) + { + QString type; + switch (cd->compoundType()) + { + case ClassDef::Class: type="class"; break; + case ClassDef::Struct: type="struct"; break; + case ClassDef::Union: type="union"; break; + default: type="unknown"; break; // an error + } + ol.writeStartAnnoItem(type,cd->classFile(),0,cd->name()); + ol.docify(" ("); + if (cd->briefDescription()) + { + OutputList briefOutput(&ol); + parseDoc(briefOutput,cd->name(),0, + abbreviate(cd->briefDescription(),cd->name())); + ol+=briefOutput; + } + else + { + ol.startEmphasis(); + parseDoc(ol,0,0,theTranslator->trNoDescriptionAvailable()); + ol.endEmphasis(); + } + ol.docify(")"); + ol.writeEndAnnoItem(cd->name()); + } + cd=classList.next(); + } + ol.endIndexList(); +} + +//---------------------------------------------------------------------------- + +void writeAnnotatedIndex(OutputList &ol) +{ + if (annotatedClasses==0) return; + + //if (classList.count()==0) return; + ol.disable(OutputGenerator::Man); + startFile(ol,"annotated","Annotated Index"); + startTitle(ol); + parseDoc(ol,0,0,projectName+" "+theTranslator->trCompoundList()); + endTitle(ol,0); + parseDoc(ol,0,0,theTranslator->trCompoundListDescription()); + writeAnnotatedClassList(ol); + endFile(ol); + ol.enable(OutputGenerator::Man); +} + +//---------------------------------------------------------------------------- + +void writeMemberList(OutputList &ol) +{ + ol.startItemList(); + MemberName *mn=memberNameList.first(); + while (mn) + { + MemberDef *md=mn->first(); + bool found=FALSE; + bool isFunc=FALSE; + while (md && !found) + { + ClassDef *cd; + if ((md->isFriend() || md->protection()!=Private || extractPrivateFlag) && + !md->isReference() && md->hasDocumentation() && + md->name()[0]!='@' && (cd=md->memberClass()) && + cd->isVisible() + ) + { + found=TRUE; + isFunc=md->isFunction(); + } + md=mn->next(); + } + if (found) + { + ol.writeListItem(); + ol.docify(substituteClassNames(mn->memberName())); + if (isFunc) ol.docify("()"); + ol.writeString("\n"); + + int count=0; + md=mn->first(); + QString prevName; + while (md) + { + ClassDef *cd=md->memberClass(); + if (cd && (md->isFriend() || md->protection()!=Private || extractPrivateFlag) && + !md->isReference() && md->hasDocumentation() && + prevName!=cd->name() && + cd->isVisible() + ) + { + if (count==0) + ol.docify(": "); + else + ol.docify(", "); + ol.writeObjectLink(cd->getReference(),cd->classFile(),md->anchor(), + cd->name()); + count++; + prevName=cd->name(); + } + md=mn->next(); + } + } + mn=memberNameList.next(); + } + ol.endItemList(); +} + +//---------------------------------------------------------------------------- + +int countMemberList() +{ + int count=0; + MemberName *mn=memberNameList.first(); + while (mn) + { + MemberDef *md=mn->first(); + bool found=FALSE; + MemberDef *otherMd=0; + ClassDef *cd; + while (md && !found) + { + if ((md->isFriend() || md->protection()!=Private || extractPrivateFlag) && + !md->isReference() && !md->isRelated() && md->hasDocumentation() && + md->name()[0]!='@' && (cd=md->memberClass()) && cd->isVisible()) + otherMd=md; + if ((md->isFriend() || md->protection()!=Private || extractPrivateFlag) && + !md->isReference() && md->isRelated() && md->hasDocumentation() && + md->name()[0]!='@' && (cd=md->memberClass()) && cd->isVisible()) + found=TRUE; + else + md=mn->next(); + } + if (found || otherMd) count++; + mn=memberNameList.next(); + } + return count; +} + +//---------------------------------------------------------------------------- + +void writeMemberIndex(OutputList &ol) +{ + if (memberNameList.count()==0) return; + ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Latex); + startFile(ol,"functions","Compound Member Index"); + startTitle(ol); + parseDoc(ol,0,0,projectName+" "+theTranslator->trCompoundMembers()); + endTitle(ol,0); + parseDoc(ol,0,0,theTranslator->trCompoundMembersDescription(extractAllFlag)); + writeMemberList(ol); + endFile(ol); + ol.enable(OutputGenerator::Latex); + ol.enable(OutputGenerator::Man); +} + +//---------------------------------------------------------------------------- + +void writeFunctionList(OutputList &ol) +{ + ol.startItemList(); + MemberName *mn=functionNameList.first(); + while (mn) + { + MemberDef *md=mn->first(); + bool found=FALSE; + while (md && !found) + { + FileDef *fd=md->getFileDef() ? md->getFileDef() : md->getFileDec(); + bool hasDocs = + (md->getFileDef() && md->getFileDef()->hasDocumentation()) || + (md->getFileDec() && md->getFileDec()->hasDocumentation()); + + if (fd && hasDocs && + !md->isReference() && + md->hasDocumentation() && + md->name()[0]!='@') found=TRUE; + else + md=mn->next(); + } + if (found) // function is documented + { + ol.writeListItem(); + ol.docify(md->name()); + if (md->isFunction()) ol.docify("()"); + ol.writeString("\n"); + + int count=0; + md=mn->first(); + QString prevName; + while (md) + { + FileDef *fd=md->getFileDef() ? md->getFileDef() : md->getFileDec(); + bool hasDocs = + (md->getFileDef() && md->getFileDef()->hasDocumentation()) || + (md->getFileDec() && md->getFileDec()->hasDocumentation()); + if (fd && hasDocs && + !md->isReference() && + md->hasDocumentation() && + md->name()[0]!='@' && + prevName!=fd->name()) + { + if (count==0) + ol.docify(": "); + else + ol.docify(", "); + QString baseName=fd->name().copy(); + //int s; + //if ((s=baseName.findRev("/"))!=-1) + // baseName=baseName.right(baseName.length()-s-1); + ol.writeObjectLink(fd->getReference(), + fd->diskName(),md->anchor(), baseName); + count++; + prevName=fd->name(); + } + md=mn->next(); + } + } + mn=functionNameList.next(); + } + ol.endItemList(); +} + +//---------------------------------------------------------------------------- + +int countFunctionList() +{ + int count=0; + MemberName *mn=functionNameList.first(); + while (mn) + { + MemberDef *md=mn->first(); + FileDef *fd; + bool found=FALSE; + while (md && !found) + { + if (!md->isReference() && md->hasDocumentation() && + md->name()[0]!='@' && + (((fd=md->getFileDef()) && fd->hasDocumentation()) + || + ((fd=md->getFileDec()) && fd->hasDocumentation()) + ) + ) + found=TRUE; + else + md=mn->next(); + } + if (found) count++; + mn=functionNameList.next(); + } + return count; +} + +//---------------------------------------------------------------------------- + +void writeFunctionIndex(OutputList &ol) +{ + if (documentedFunctions==0) return; + ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Latex); + startFile(ol,"globals","File Member Index"); + startTitle(ol); + parseDoc(ol,0,0,projectName+" "+theTranslator->trFileMembers()); + endTitle(ol,0); + parseDoc(ol,0,0,theTranslator->trFileMembersDescription(extractAllFlag)); + writeFunctionList(ol); + endFile(ol); + ol.enable(OutputGenerator::Latex); + ol.enable(OutputGenerator::Man); +} + +//---------------------------------------------------------------------------- + +void writeHeaderFileList(OutputList &ol) +{ + if (includeFiles.count()>0) + { + ol.startItemList(); + FileDef *fd=includeFiles.first(); + while (fd) + { + ol.writeListItem(); + QString path; + if (fullPathNameFlag) + { + path=fd->getPath().copy(); + // strip part of the path + if (path.left(stripFromPath.length())==stripFromPath) + path=path.right(path.length()-stripFromPath.length()); + } + if (!path.isEmpty()) ol.docify(path); + ol.writeObjectLink(0,fd->includeName(),0,fd->name()); + ol.writeString("\n"); + fd=includeFiles.next(); + } + ol.endItemList(); + } +} + +//---------------------------------------------------------------------------- + +void writeHeaderIndex(OutputList &ol) +{ + if (includeFiles.count()==0) return; + ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Latex); + startFile(ol,"headers","Header File Index"); + startTitle(ol); + parseDoc(ol,0,0,projectName+" "+theTranslator->trHeaderFiles()); + endTitle(ol,0); + parseDoc(ol,0,0,theTranslator->trHeaderFilesDescription()); + writeHeaderFileList(ol); + endFile(ol); + ol.enable(OutputGenerator::Latex); + ol.enable(OutputGenerator::Man); +} + +//---------------------------------------------------------------------------- + +void writeExampleIndex(OutputList &ol) +{ + if (exampleList.count()==0) return; + ol.disable(OutputGenerator::Man); + startFile(ol,"examples","Example Index"); + startTitle(ol); + parseDoc(ol,0,0,projectName+" "+theTranslator->trExamples()); + endTitle(ol,0); + parseDoc(ol,0,0,theTranslator->trExamplesDescription()); + ol.startIndexList(); + PageInfo *pi=exampleList.first(); + while (pi) + { + ol.writeListItem(); + QString n=convertSlashes(pi->name,TRUE)+"-example"; + if (!pi->title.isEmpty()) + { + ol.writeObjectLink(0,n,0,pi->title); + } + else + { + ol.writeObjectLink(0,n,0,pi->name); + } + ol.writeString("\n"); + pi=exampleList.next(); + } + ol.endIndexList(); + endFile(ol); + ol.enable(OutputGenerator::Man); +} + +//---------------------------------------------------------------------------- + +void writePageIndex(OutputList &ol) +{ + if (pageList.count()==0) return; + ol.disable(OutputGenerator::Man); + startFile(ol,"pages","Page Index"); + startTitle(ol); + ol.docify(projectName+" "+theTranslator->trRelatedPages()); + endTitle(ol,0); + parseDoc(ol,0,0,theTranslator->trRelatedPagesDescription()); + ol.startIndexList(); + PageInfo *pi=pageList.first(); + while (pi) + { + QString pageName; + if (caseSensitiveNames) + pageName=pi->name.copy(); + else + pageName=pi->name.lower(); + ol.writeListItem(); + ol.writeObjectLink(0,pageName,0,pi->name); + ol.writeString("\n"); + pi=pageList.next(); + } + ol.endIndexList(); + endFile(ol); + ol.enable(OutputGenerator::Man); +} + +//---------------------------------------------------------------------------- + +int countGroupList() +{ + int count=0; + GroupListIterator gli(groupList); + GroupDef *gd; + for (;(gd=gli.current());++gli) + { + if (gd->countMembers()>0) count++; + gd=groupList.next(); + } + return count; +} + +//---------------------------------------------------------------------------- + +void writeGroupList(OutputList &ol) +{ + ol.startDescription(); + GroupListIterator gli(groupList); + GroupDef *gd; + for (;(gd=gli.current());++gli) + { + if (gd->countMembers()>0) + { + ol.startDescItem(); + ol.startTextLink(gd->groupFile(),0); + parseDoc(ol,0,0,gd->groupTitle()); + ol.endTextLink(); + ol.endDescItem(); + parseDoc(ol,0,0,gd->briefDescription()); + ol.newParagraph(); + } + } + ol.endDescription(); +} + +//---------------------------------------------------------------------------- + +void writeGroupIndex(OutputList &ol) +{ + if (documentedGroups==0) return; + ol.disable(OutputGenerator::Man); + startFile(ol,"modules","Module Index"); + startTitle(ol); + parseDoc(ol,0,0,projectName+" "+theTranslator->trModules()); + endTitle(ol,0); + parseDoc(ol,0,0,theTranslator->trModulesDescription()); + writeGroupList(ol); + endFile(ol); + ol.enable(OutputGenerator::Man); +} + +void writeIndex(OutputList &ol) +{ + // save old generator state + bool manEnabled = ol.isEnabled(OutputGenerator::Man); + bool texEnabled = ol.isEnabled(OutputGenerator::Latex); + bool htmEnabled = ol.isEnabled(OutputGenerator::Html); + + QString projPrefix; + if (!projectName.isEmpty()) + { + projPrefix=projectName+" "; + } + // write HTML index + ol.disable(OutputGenerator::Man); + ol.disable(OutputGenerator::Latex); + ol.startFile("index","Main Index",FALSE); + if (!noIndexFlag) writeQuickLinks(ol,TRUE); + ol.startTitleHead(); + parseDoc(ol,0,0,projPrefix+theTranslator->trDocumentation()); + ol.endTitleHead(0); + ol.newParagraph(); + if (!projectNumber.isEmpty()) + { + ol.startProjectNumber(); + parseDoc(ol,0,0,projectNumber); + ol.endProjectNumber(); + } + if (noIndexFlag) writeQuickLinks(ol,FALSE); + endFile(ol); + ol.disable(OutputGenerator::Html); + + // write LaTeX index + ol.enable(OutputGenerator::Latex); + ol.startFile("refman",0,FALSE); + ol.startIndexSection(isTitlePageStart); + parseDoc(ol,0,0,projPrefix+theTranslator->trReferenceManual()); + if (!projectNumber.isEmpty()) + { + ol.startProjectNumber(); + parseDoc(ol,0,0,projectNumber); + ol.endProjectNumber(); + } + ol.endIndexSection(isTitlePageStart); + ol.startIndexSection(isTitlePageAuthor); + parseDoc(ol,0,0,theTranslator->trGeneratedBy()); + ol.endIndexSection(isTitlePageAuthor); + if (documentedGroups>0) + { + ol.startIndexSection(isModuleIndex); + parseDoc(ol,0,0,projPrefix+theTranslator->trModuleIndex()); + ol.endIndexSection(isModuleIndex); + } + if (hierarchyClasses>0) + { + ol.startIndexSection(isClassHierarchyIndex); + parseDoc(ol,0,0,projPrefix+theTranslator->trHierarchicalIndex()); + ol.endIndexSection(isClassHierarchyIndex); + } + if (annotatedClasses>0) + { + ol.startIndexSection(isCompoundIndex); + parseDoc(ol,0,0,projPrefix+theTranslator->trCompoundIndex()); + ol.endIndexSection(isCompoundIndex); + } + if (documentedFiles>0) + { + ol.startIndexSection(isFileIndex); + parseDoc(ol,0,0,projPrefix+theTranslator->trFileIndex()); + ol.endIndexSection(isFileIndex); + } + if (documentedGroups>0) + { + ol.startIndexSection(isModuleDocumentation); + parseDoc(ol,0,0,projPrefix+theTranslator->trModuleDocumentation()); + ol.endIndexSection(isModuleDocumentation); + } + if (annotatedClasses>0) + { + ol.startIndexSection(isClassDocumentation); + parseDoc(ol,0,0,projPrefix+theTranslator->trClassDocumentation()); + ol.endIndexSection(isClassDocumentation); + } + if (documentedFiles>0) + { + ol.startIndexSection(isFileDocumentation); + parseDoc(ol,0,0,projPrefix+theTranslator->trFileDocumentation()); + ol.endIndexSection(isFileDocumentation); + } + if (exampleList.count()>0) + { + ol.startIndexSection(isExampleDocumentation); + parseDoc(ol,0,0,projPrefix+theTranslator->trExampleDocumentation()); + ol.endIndexSection(isExampleDocumentation); + } + if (pageList.count()>0) + { + ol.startIndexSection(isPageDocumentation); + parseDoc(ol,0,0,projPrefix+theTranslator->trPageDocumentation()); + ol.endIndexSection(isPageDocumentation); + } + ol.endIndexSection(isEndIndex); + endFile(ol); + + // restore generator state + if (manEnabled) ol.enable(OutputGenerator::Man); + else ol.disable(OutputGenerator::Man); + if (texEnabled) ol.enable(OutputGenerator::Latex); + else ol.disable(OutputGenerator::Latex); + if (htmEnabled) ol.enable(OutputGenerator::Html); + else ol.disable(OutputGenerator::Html); +} diff --git a/src/index.h b/src/index.h new file mode 100644 index 0000000..5b3cc67 --- /dev/null +++ b/src/index.h @@ -0,0 +1,65 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef INDEX_H +#define INDEX_H + +#include <qfile.h> +#include <qtstream.h> + +enum IndexSections +{ + isTitlePageStart, + isTitlePageAuthor, + isModuleIndex, + isClassHierarchyIndex, + isCompoundIndex, + isFileIndex, + isModuleDocumentation, + isClassDocumentation, + isFileDocumentation, + isExampleDocumentation, + isPageDocumentation, + isEndIndex +}; + +class OutputList; + +void writeIndex(OutputList &ol); +void writeHierarchicalIndex(OutputList &ol); +void writeClassHierarchy(OutputList &ol); +void writeFileIndex(OutputList &ol); +void writeAnnotatedIndex(OutputList &ol); +void writeAnnotatedClassList(OutputList &ol); +void writeMemberIndex(OutputList &ol); +void writeMemberList(OutputList &ol); +void writeHeaderIndex(OutputList &ol); +void writeHeaderFileList(OutputList &ol); +void writeExampleIndex(OutputList &ol); +void writePageIndex(OutputList &ol); +void writeFunctionIndex(OutputList &ol); +void writeGroupIndex(OutputList &ol); +void writeNamespaceIndex(OutputList &ol); + +int countClassHierarchy(); +int countMemberList(); +int countFunctionList(); +int countFileList(); +int countGroupList(); +int countNamespaceList(); +int countAnnotatedClasses(); + +#endif diff --git a/src/instdox.cpp b/src/instdox.cpp new file mode 100644 index 0000000..ad22c89 --- /dev/null +++ b/src/instdox.cpp @@ -0,0 +1,164 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <qstring.h> +#include <qfile.h> +#include <qfileinf.h> +#include <qtstream.h> + +#include "instdox.h" +#include "doxygen.h" +#include "config.h" +#include "message.h" + +void writeInstallScript() +{ + QString fileName=htmlOutputDir+"/installdox"; + QFile f(fileName); + if (f.open(IO_WriteOnly)) + { + QTextStream t(&f); + t << "#!" << perlPath << endl << endl << "%subst = ( "; + + char *s=tagFileList.first(); + while (s) + { + QFileInfo fi(s); + t << "\"" << fi.fileName() << "\", \"\""; + s=tagFileList.next(); + if (s) t << ", "; + } + + t << ");\n"; + t << "$quiet = 0;\n"; + t << "\n"; + t << "if (open(F,\"search.cfg\"))\n"; + t << "{\n"; + t << " $_=<F> ; s/[ \\t\\n]*$//g ; $subst{\"_doc\"} = $_;\n"; + t << " $_=<F> ; s/[ \\t\\n]*$//g ; $subst{\"_cgi\"} = $_;\n"; + t << "}\n"; + t << "\n"; + t << "while ( @ARGV ) {\n"; + t << " $_ = shift @ARGV;\n"; + t << " if ( s/^-// ) {\n"; + t << " if ( /^l(.*)/ ) {\n"; + t << " $v = ($1 eq \"\") ? shift @ARGV : $1;\n"; + t << " ($v =~ /\\/$/) || ($v .= \"/\");\n"; + t << " $_ = $v;\n"; + t << " if ( /(.+)\\@(.+)/ ) {\n"; + t << " if ( exists $subst{$1} ) {\n"; + t << " $subst{$1} = $2;\n"; + t << " } else {\n"; + t << " print STDERR \"Unknown tag file $1 given with option -l\\n\";\n"; + t << " &usage();\n"; + t << " }\n"; + t << " } else {\n"; + t << " print STDERR \"Argument $_ is invalid for option -l\\n\";\n"; + t << " &usage();\n"; + t << " }\n"; + t << " }\n"; + t << " elsif ( /^q/ ) {\n"; + t << " $quiet = 1;\n"; + t << " }\n"; + t << " elsif ( /^\\?|^h/ ) {\n"; + t << " &usage();\n"; + t << " }\n"; + t << " else {\n"; + t << " print STDERR \"Illegal option -$_\\n\";\n"; + t << " &usage();\n"; + t << " }\n"; + t << " }\n"; + t << " else {\n"; + t << " push (@files, $_ );\n"; + t << " }\n"; + t << "}\n"; + t << "\n"; + t << "foreach $sub (keys %subst)\n"; + t << "{\n"; + t << " if ( $subst{$sub} eq \"\" ) \n"; + t << " {\n"; + t << " print STDERR \"No substitute given for tag file `$sub'\\n\";\n"; + t << " &usage();\n"; + t << " }\n"; + t << " elsif ( ! $quiet && $sub!=\"_doc\" && $sub!=\"_cgi\" )\n"; + t << " {\n"; + t << " print \"Substituting $subst{$sub} for each occurence of tag file $sub\\n\"; \n"; + t << " }\n"; + t << "}\n"; + t << "\n"; + t << "if ( ! @files ) {\n"; + t << " if (opendir(D,\".\")) {\n"; + t << " foreach $file ( readdir(D) ) {\n"; + t << " $match = \".html\";\n"; + t << " next if ( $file =~ /^\\.\\.?$/ );\n"; + t << " ($file =~ /$match/) && (push @files, $file);\n"; + t << " }\n"; + t << " closedir(D);\n"; + t << " }\n"; + t << "}\n"; + t << "\n"; + t << "if ( ! @files ) {\n"; + t << " print STDERR \"Warning: No input files given and non found!\\n\";\n"; + t << "}\n"; + t << "\n"; + t << "foreach $f (@files)\n"; + t << "{\n"; + t << " if ( ! $quiet ) {\n"; + t << " print \"Editing: $f...\\n\";\n"; + t << " }\n"; + t << " $oldf = $f;\n"; + t << " $f .= \".bak\";\n"; + t << " unless (rename $oldf,$f) {\n"; + t << " print STDERR \"Error: cannot rename file $oldf\\n\";\n"; + t << " exit 1;\n"; + t << " }\n"; + t << " if (open(F,\"<$f\")) {\n"; + t << " unless (open(G,\">$oldf\")) {\n"; + t << " print STDERR \"Error: opening file $oldf for writing\\n\";\n"; + t << " exit 1;\n"; + t << " }\n"; + t << " while (<F>) {\n"; + t << " s/doxygen\\=\\\"([^ \\\"\\:\\t\\>\\<]*)\\:([^ \\\"\\t\\>\\<]*)\\\" (href|src)=\\\"\\2/doxygen\\=\\\"$1:$subst{$1}\\\" \\3=\\\"$subst{$1}/g;\n"; + t << " print G \"$_\";\n"; + t << " }\n"; + t << " } \n"; + t << " else {\n"; + t << " print STDERR \"Warning file $f does not exist\\n\";\n"; + t << " }\n"; + t << " unlink $f;\n"; + t << "}\n"; + t << "\n"; + t << "sub usage {\n"; + t << " print STDERR \"Usage: installdox [options] [html-file [html-file ...]]\\n\";\n"; + t << " print STDERR \"Options:\\n\";\n"; + t << " print STDERR \" -l tagfile\\@linkName tag file + URL or directory \\n\";\n"; + t << " print STDERR \" -q Quiet mode\\n\\n\";\n"; + t << " exit 1;\n"; + t << "}\n"; + } + else + { + err("Error: Cannot open file %s for writing\n",fileName.data()); + } + f.close(); + struct stat stat_struct; + stat(fileName,&stat_struct); +#if !defined(_WIN32) + chmod(fileName,stat_struct.st_mode|S_IXUSR|S_IXGRP|S_IXOTH); +#endif +} diff --git a/src/instdox.h b/src/instdox.h new file mode 100644 index 0000000..a149310 --- /dev/null +++ b/src/instdox.h @@ -0,0 +1,22 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef INSTDOX_H +#define INSTDOX_H + +extern void writeInstallScript(); + +#endif diff --git a/src/language.cpp b/src/language.cpp new file mode 100644 index 0000000..f5e2dde --- /dev/null +++ b/src/language.cpp @@ -0,0 +1,61 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include "language.h" +#include "translator_nl.h" +#include "translator_se.h" +#include "translator_cz.h" +#include "translator_fr.h" +#include "translator_it.h" +#include <qstring.h> + +#define L_EQUAL(a) !stricmp(langName,a) + +Translator *theTranslator=0; + +bool setTranslator(const char *langName) +{ + if (L_EQUAL("english")) + { + theTranslator=new Translator; + } + else if (L_EQUAL("dutch")) + { + theTranslator=new TranslatorDutch; + } + else if (L_EQUAL("swedish")) + { + theTranslator=new TranslatorSwedish; + } + else if (L_EQUAL("czech")) + { + theTranslator=new TranslatorCzech; + } + else if (L_EQUAL("french")) + { + theTranslator=new TranslatorFrench; + } + else if (L_EQUAL("italian")) + { + theTranslator=new TranslatorItalian; + } + else // use the default language (i.e. english) + { + theTranslator=new Translator; + return FALSE; + } + return TRUE; +} diff --git a/src/language.h b/src/language.h new file mode 100644 index 0000000..c18eaed --- /dev/null +++ b/src/language.h @@ -0,0 +1,25 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered 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/latexgen.cpp b/src/latexgen.cpp new file mode 100644 index 0000000..50ec496 --- /dev/null +++ b/src/latexgen.cpp @@ -0,0 +1,876 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered 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" + +//static QString escapeLabelName(const QString &s) +//{ +// QString result; +// uint i; +// for (i=0;i<s.length();i++) +// { +// char c=s.at(i); +// switch (c) +// { +// case '~': result+=".1"; break; +// case '%': result+=".2"; break; +// default: result+=c; +// } +// } +// return result; +//} + + +LatexGenerator::LatexGenerator() + : OutputGenerator() +{ + dir=latexOutputDir; + col=0; +} + +LatexGenerator::~LatexGenerator() +{ +} + +//LatexGenerator::LatexGenerator(const LatexGenerator &g) +// : OutputGenerator(g) +//{ +// col=g.col; +//} + +void LatexGenerator::append(const OutputGenerator *g) +{ + t << g->getContents(); + col+=((LatexGenerator *)g)->col; +} + + +void LatexGenerator::init() +{ + QString dir=latexOutputDir; + QDir d(dir); + if (!d.exists() && !d.mkdir(dir)) + { + err("Could not create output directory %s\n",dir.data()); + exit(1); + } + + QString fileName=dir+"/Makefile"; + QFile file(fileName); + if (!file.open(IO_WriteOnly)) + { + err("Could not open file %s for writing\n",fileName.data()); + exit(1); + } + QTextStream t(&file); + t << "all: refman.dvi" << endl + << endl + << "ps: refman.ps" << endl + << endl + << "refman.ps: refman.dvi" << endl + << "\tdvips -o refman.ps refman.dvi" << endl + << endl + << "refman.dvi: refman.tex doxygen.sty" << endl + << "\techo \"Running latex...\"" << endl + << "\tlatex refman.tex" << endl + << "\techo \"Running makeindex...\"" << endl + << "\tmakeindex refman.idx" << endl + << "\techo \"Rerunning latex....\"" << endl + << "\tlatex refman.tex" << endl + << "clean:" << endl + << "\trm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log" << endl; +} + +void LatexGenerator::startFile(const char *name,const char *,bool) +{ + QString fileName=name; + if (fileName.right(4)!=".tex" && fileName.right(4)!=".sty") fileName+=".tex"; + startPlainFile(fileName); +} + +void LatexGenerator::endFile() +{ + endPlainFile(); +} + +//void LatexGenerator::writeIndex() +//{ +// startFile("refman.tex"); +//} + +void LatexGenerator::startProjectNumber() +{ + t << "\\\\[1ex]\\large "; +} + +void LatexGenerator::startIndexSection(IndexSections is) +{ + QString paperName; + switch (is) + { + case isTitlePageStart: + { + if (paperType=="a4wide") paperName="a4"; else paperName=paperType; + t << "\\documentclass[" << paperName << "paper]{"; + if (compactLatexFlag) t << "article"; else t << "book"; + t << "}\n"; + if (paperType=="a4wide") t << "\\usepackage{a4wide}\n"; + t << "\\usepackage{makeidx}\n" + "\\usepackage{fancyheadings}\n" + "\\usepackage{epsf}\n" + "\\usepackage{float}\n" + "\\usepackage{doxygen}\n"; + if (!theTranslator->latexBabelPackage().isEmpty()) + { + t << "\\usepackage{" << theTranslator->latexBabelPackage() << "}\n"; + } + const char *s=extraPackageList.first(); + while (s) + { + t << "\\usepackage{" << s << "}\n"; + s=extraPackageList.next(); + } + t << "\\makeindex\n" + "\\setcounter{tocdepth}{1}\n" + "\\setlength{\\footrulewidth}{0.4pt}\n" + "\\begin{document}\n" + "\\title{"; + //docify(projectName); + //t << " Reference Manual"; + //if (!projectNumber.isEmpty()) + //{ + // t << "\\\\[1ex]\\large "; + // docify(projectNumber); + //} + } + break; + case isTitlePageAuthor: + t << "}\n\\author{"; + break; + case isModuleIndex: + if (compactLatexFlag) t << "\\section"; else t << "\\chapter"; + t << "{"; //Module Index}\n" + break; + case isClassHierarchyIndex: + if (compactLatexFlag) t << "\\section"; else t << "\\chapter"; + t << "{"; //Hierarchical Index}\n" + break; + case isCompoundIndex: + if (compactLatexFlag) t << "\\section"; else t << "\\chapter"; + t << "{"; //Annotated Compound Index}\n" + break; + case isFileIndex: + if (compactLatexFlag) t << "\\section"; else t << "\\chapter"; + t << "{"; //Annotated File Index}\n" + break; + case isModuleDocumentation: + { + GroupDef *gd=groupList.first(); + bool found=FALSE; + while (gd && !found) + { + if (gd->hasDocumentation() || gd->countMembers()>0) + { + if (compactLatexFlag) t << "\\section"; else t << "\\chapter"; + t << "{"; //Module Documentation}\n"; + found=TRUE; + } + gd=groupList.next(); + } + } + break; + case isClassDocumentation: + { + ClassDef *cd=classList.first(); + bool found=FALSE; + while (cd && !found) + { + //if (cd->classFile()[0]!='@' && !cd->getReference() && + // (cd->hasDocumentation() || !hideClassFlag) && + // (cd->protection()!=Private || extractPrivateFlag) + // ) + + if (!cd->isReference() && cd->isVisible()) + { + if (compactLatexFlag) t << "\\section"; else t << "\\chapter"; + t << "{"; //Compound Documentation}\n"; + found=TRUE; + } + cd=classList.next(); + } + } + break; + case isFileDocumentation: + { + bool isFirst=TRUE; + FileName *fn=inputNameList.first(); + while (fn) + { + FileDef *fd=fn->first(); + while (fd) + { + if (fd->hasDocumentation() && !fd->isReference()) + { + if (isFirst) + { + if (compactLatexFlag) t << "\\section"; else t << "\\chapter"; + t << "{"; //File Documentation}\n"; + isFirst=FALSE; + break; + } + } + fd=fn->next(); + } + fn=inputNameList.next(); + } + } + break; + case isExampleDocumentation: + { + if (compactLatexFlag) t << "\\section"; else t << "\\chapter"; + t << "{"; //Example Documentation}\n"; + } + break; + case isPageDocumentation: + { + if (compactLatexFlag) t << "\\section"; else t << "\\chapter"; + t << "{"; //Page Documentation}\n"; + } + break; + case isEndIndex: + break; + } +} + +void LatexGenerator::endIndexSection(IndexSections is) +{ + switch (is) + { + case isTitlePageStart: + break; + case isTitlePageAuthor: + t << " Doxygen}\n" + "\\date{" << dateToString(TRUE) << "}\n" + "\\maketitle\n" + "\\pagenumbering{roman}\n"; + if (!compactLatexFlag) t << "\\clearemptydoublepage\n"; + t << "\\tableofcontents\n"; + if (!compactLatexFlag) t << "\\clearemptydoublepage\n"; + t << "\\pagenumbering{arabic}\n"; + break; + case isModuleIndex: + t << "}\n\\input{modules}\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 isModuleDocumentation: + { + GroupDef *gd=groupList.first(); + bool found=FALSE; + while (gd && !found) + { + if (gd->hasDocumentation() || gd->countMembers()>0) + { + t << "}\n\\input{" << gd->groupFile() << "}\n"; + found=TRUE; + } + gd=groupList.next(); + } + while (gd) + { + if (gd->hasDocumentation() || gd->countMembers()>0) + { + if (compactLatexFlag) t << "\\input"; else t << "\\include"; + t << "{" << gd->groupFile() << "}\n"; + } + gd=groupList.next(); + } + } + break; + case isClassDocumentation: + { + ClassDef *cd=classList.first(); + bool found=FALSE; + while (cd && !found) + { + //if (cd->classFile()[0]!='@' && !cd->getReference() && + // (cd->hasDocumentation() || !hideClassFlag) && + // (cd->protection()!=Private || extractPrivateFlag) + // ) + if (!cd->isReference() && cd->isVisible()) + { + t << "}\n\\input{" << cd->classFile() << "}\n"; + found=TRUE; + } + cd=classList.next(); + } + while (cd) + { + //if (cd->classFile()[0]!='@' && !cd->getReference() && + // (cd->hasDocumentation() || !hideClassFlag) && + // (cd->protection()!=Private || extractPrivateFlag) + // ) + if (!cd->isReference() && cd->isVisible()) + { + if (compactLatexFlag) t << "\\input"; else t << "\\include"; + t << "{" << cd->classFile() << "}\n"; + } + cd=classList.next(); + } + } + break; + case isFileDocumentation: + { + bool isFirst=TRUE; + FileName *fn=inputNameList.first(); + while (fn) + { + FileDef *fd=fn->first(); + while (fd) + { + if (fd->hasDocumentation() && !fd->isReference()) + { + if (isFirst) + { + t << "}\n\\input{" << fd->diskName() << "}\n"; + isFirst=FALSE; + } + else + { + if (compactLatexFlag) t << "\\input" ; else t << "\\include"; + t << "{" << fd->diskName() << "}\n"; + } + } + fd=fn->next(); + } + fn=inputNameList.next(); + } + } + break; + case isExampleDocumentation: + { + t << "}\n"; + PageInfo *pi=exampleList.first(); + if (pi) + { + t << "\\input{" << convertSlashes(pi->name,TRUE) << "-example}\n"; + pi=exampleList.next(); + } + while (pi) + { + if (compactLatexFlag) t << "\\input" ; else t << "\\include"; + t << "{" << convertSlashes(pi->name,TRUE) << "-example}\n"; + pi=exampleList.next(); + } + } + break; + case isPageDocumentation: + { + t << "}\n"; + PageInfo *pi=pageList.first(); + if (pi) + { + QString pageName; + if (caseSensitiveNames) + pageName=pi->name.copy(); + else + pageName=pi->name.lower(); + t << "\\input{" << pageName << "}\n"; + pi=pageList.next(); + } + while (pi) + { + if (compactLatexFlag) t << "\\input" ; else t << "\\include"; + QString pageName; + if (caseSensitiveNames) + pageName=pi->name.copy(); + else + pageName=pi->name.lower(); + t << "{" << pageName << "}\n"; + pi=pageList.next(); + } + } + break; + case isEndIndex: + t << "\\printindex\n"; + t << "\\end{document}\n"; + break; + } +} +void LatexGenerator::writeStyleInfo(int part) +{ + switch(part) + { + case 0: + { + QString pname=projectName.stripWhiteSpace(); + startPlainFile("doxygen.sty"); + t << "\\NeedsTeXFormat{LaTeX2e}\n"; + t << "\\ProvidesPackage{doxygen}\n"; + t << "\\RequirePackage{calc}\n"; + t << "\\RequirePackage{array}\n"; + t << "\\pagestyle{fancyplain}\n"; + t << "\\addtolength{\\headwidth}{\\marginparsep}\n"; + t << "\\addtolength{\\headwidth}{\\marginparwidth}\n"; + t << "\\newcommand{\\clearemptydoublepage}{\\newpage{\\pagestyle{empty}"; + t << "\\cleardoublepage}}\n"; + if (!compactLatexFlag) + t << "\\renewcommand{\\chaptermark}[1]{\\markboth{#1}{}}\n"; + t << "\\renewcommand{\\sectionmark}[1]{\\markright{\\thesection\\ #1}}\n"; + t << "\\lhead[\\fancyplain{}{\\bfseries\\thepage}]\n"; + t << " {\\fancyplain{}{\\bfseries\\rightmark}}\n"; + t << "\\rhead[\\fancyplain{}{\\bfseries\\leftmark}]\n"; + t << " {\\fancyplain{}{\\bfseries\\thepage}}\n"; + t << "\\rfoot[\\fancyplain{}{\\bfseries\\scriptsize "; + } + break; + case 1: + case 3: + t << " Doxygen "; + break; + case 2: + { + t << " Dimitri van Heesch \\copyright 1997-1999}]{}\n"; + //QString dtString=dateToString(FALSE); + t << "\\lfoot[]{\\fancyplain{}{\\bfseries\\scriptsize "; + } + break; + case 4: + { + t << " Dimitri van Heesch \\copyright 1997-1999}}\n"; + t << "\\cfoot{}\n"; + t << "\\newenvironment{CompactList}\n"; + t << "{\\begin{list}{}{\n"; + t << " \\setlength{\\leftmargin}{0.5cm}\n"; + t << " \\setlength{\\itemsep}{0pt}\n"; + t << " \\setlength{\\parsep}{0pt}\n"; + t << " \\setlength{\\topsep}{0pt}\n"; + t << " \\renewcommand{\\makelabel}{}}}\n"; + t << "{\\end{list}}\n"; + t << "\\newenvironment{CompactItemize}\n"; + t << "{\n"; + t << " \\begin{itemize}\n"; + t << " \\setlength{\\itemsep}{-4pt}\n"; + t << " \\setlength{\\parsep}{0pt}\n"; + t << " \\setlength{\\topsep}{0pt}\n"; + t << " \\setlength{\\partopsep}{0pt}\n"; + t << "}\n"; + t << "{\\end{itemize}}\n"; + t << "\\newcommand{\\PBS}[1]{\\let\\temp=\\\\#1\\let\\\\=\\temp}\n"; + t << "\\newlength{\\tmplength}\n"; + t << "\\newenvironment{TabularC}[1]\n"; + t << "{\n"; + t << "\\setlength{\\tmplength}\n"; + t << " {\\linewidth/(#1)-\\tabcolsep*2-\\arrayrulewidth*(#1+1)/(#1)}\n"; + t << " \\par\\begin{tabular*}{\\linewidth}\n"; + t << " {*{#1}{|>{\\PBS\\raggedright\\hspace{0pt}}p{\\the\\tmplength}}|}\n"; + t << "}\n"; + t << "{\\end{tabular*}\\par}\n"; + t << "\\newcommand{\\entrylabel}[1]{\n"; + t << " {\\parbox[b]{\\labelwidth-4pt}{\\makebox[0pt][l]{\\textbf{#1}}\\\\}}}\n"; + t << "\\newenvironment{Desc}\n"; + t << "{\\begin{list}{}\n"; + t << " {\n"; + t << " \\settowidth{\\labelwidth}{40pt}\n"; + t << " \\setlength{\\leftmargin}{\\labelwidth}\n"; + t << " \\setlength{\\parsep}{0pt}\n"; + t << " \\setlength{\\itemsep}{-4pt}\n"; + t << " \\renewcommand{\\makelabel}{\\entrylabel}\n"; + t << " }\n"; + t << "}\n"; + t << "{\\end{list}}\n"; + t << "\\setlength{\\parindent}{0cm}\n"; + t << "\\setlength{\\parskip}{0.2cm}\n"; + t << "\\sloppy\n"; + endPlainFile(); + } + break; + } +} + +void LatexGenerator::endTitleHead(const char *name) +{ + t << "}" << endl; + if (name) + { + t << "\\label{" << name << "}\\index{" + << name << "@{"; + docify(name); + t << "}}"; + } + t << endl; +} + +void LatexGenerator::newParagraph() +{ + t << endl << endl; +} + +void LatexGenerator::writeString(const char *text) +{ + t << text; +} + +void LatexGenerator::writeIndexItem(const char *ref,const char *fn, + const char *name) +{ + t << "\\item "; + if (!ref && fn) + { + t << "\\contentsline{section}{"; + docify(name); + t << "}{\\pageref{" << name << "}}" << endl; + } + else + docify(name); +} + +//void LatexGenerator::writeIndexFileItem(const char *,const char *text) +//{ +// t << "\\item\\contentsline{section}{"; +// docify(text); +// t << "}{\\pageref{" << text << "}}" << endl; +//} + + +void LatexGenerator::writeHtmlLink(const char *url,const char *text) +{ + docify(text); + if (url) + { + // 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::writeClassLink(const char *,const char *, +// const char *,const char *name) +//{ +// t << "{\\bf "; +// docify(name); +// t << "}"; +//} + +void LatexGenerator::writeObjectLink(const char *, const char *, + const char *, const char *text) +{ + t << "{\\bf "; + docify(text); + t << "}"; +} + +void LatexGenerator::writePageRef(const char *clname, const char *anchor) +{ + t << " {\\rm (p. \\pageref{"; + if (clname) t << clname; + if (anchor) t << "_" << anchor; + t << "})}"; +} + +void LatexGenerator::writeCodeLink(const char *,const char *, + const char *,const char *name) +{ + t << name; + col+=strlen(name); +} + + +void LatexGenerator::startTitle() +{ + if (compactLatexFlag) t << "\\subsection{"; else t << "\\section{"; +} + +void LatexGenerator::startGroupHeader() +{ + if (compactLatexFlag) t << "\\subsubsection*{"; else t << "\\subsection*{"; +} + +void LatexGenerator::endGroupHeader() +{ + t << "}" << endl; +} + +void LatexGenerator::startMemberDoc(const char *clname, + const char *memname,const char *) +{ + t << "\\index{"; + if (clname) + { + t << clname << "@{"; + docify(clname); + t << "}!"; + } + t << memname << "@{"; + docify(memname); + t << "}}" << endl; + + t << "\\index{" << memname << "@{"; + docify(memname); + t << "}"; + if (clname) + { + t << "!" << clname << "@{"; + docify(clname); + t << "}"; + } + t << "}" << endl; + // + if (compactLatexFlag) t << "\\subsubsection{"; else t << "\\subsection{"; + t << "\\setlength{\\rightskip}{0pt plus 5cm}"; +} + +void LatexGenerator::writeDoxyAnchor(const char *clname,const char *anchor,const char *) +{ + t << "\\label{"; + if (clname) t << clname; + if (anchor) t << "_" << anchor; + t << "}" << endl; +} + +void LatexGenerator::addToIndex(const char *s1,const char *s2) +{ + if (s1) + { + t << "\\index{" << s1 << "@{"; + docify(s1); + t << "}"; + if (s2) + { + t << "!" << s2 << "@{"; + docify(s2); + t << "}"; + } + t << "}"; + } +} + +void LatexGenerator::writeSection(const char *lab,const char *title,bool sub) +{ + t << "\\"; + if (sub) t << "subsection{"; else t << "section{"; + docify(title); + t << "}\\label{" << lab << "}" << endl; +} + +void LatexGenerator::writeSectionRef(const char *,const char *lab, + const char *) +{ + t << "\\ref{" << lab << "}"; +} + +void LatexGenerator::writeSectionRefItem(const char *,const char *lab, + const char *title) +{ + t << "\\contentsline{section}{"; + docify(title); + t << "}{\\ref{" << lab << "}}" << endl; +} + +//void LatexGenerator::docify(const char *str) +//{ +// docifyStatic(t,str); +//} + +//void LatexGenerator::docifyStatic(QTextStream &t,const char *str) +void LatexGenerator::docify(const char *str) +{ + if (str) + { + const unsigned char *p=(const unsigned char *)str; + unsigned char c; + unsigned char pc='\0'; + while (*p) + { + c=*p++; + switch(c) + { + case '#': t << "\\#"; break; + case '$': t << "\\$"; break; + case '%': t << "\\%"; break; + case '^': t << "$^\\wedge$"; break; + case '&': t << "\\&"; break; + case '*': t << "$\\ast$"; break; + case '_': t << "\\_\\-"; break; + case '{': t << "\\{"; break; + case '}': t << "\\}"; break; + case '<': t << "$<$"; break; + case '>': t << "$>$"; break; + case '|': t << "$|$"; break; + case '~': t << "$\\sim$"; break; + case '-': if (*p=='>') + { t << " $\\rightarrow$ "; p++; } + else + { t << (char)c; } + break; + case '\\': if (*p=='<') + { t << "$<$"; p++; } + else if (*p=='>') + { t << "$>$"; p++; } + else + { t << "$\\backslash$"; } + break; + // the Latin-1 characters + case 161: t << "!`"; break; + case 181: t << "$\\mu$"; break; + case 191: t << "?`"; break; + case 192: t << "\\`{A}"; break; + case 193: t << "\\'{A}"; break; + case 194: t << "\\^{A}"; break; + case 195: t << "\\~{A}"; break; + case 196: t << "\\\"{A}"; break; + case 197: t << "\\AA "; break; + case 198: t << "\\AE "; break; + case 199: t << "\\c{C}"; break; + case 200: t << "\\`{E}"; break; + case 201: t << "\\'{E}"; break; + case 202: t << "\\^{E}"; break; + case 203: t << "\\\"{E}"; break; + case 204: t << "\\`{I}"; break; + case 205: t << "\\'{I}"; break; + case 206: t << "\\^{I}"; break; + case 207: t << "\\\"{I}"; break; + case 208: t << "D "; break; // anyone know the real code? + case 209: t << "\\~{N}"; break; + case 210: t << "\\`{O}"; break; + case 211: t << "\\'{O}"; break; + case 212: t << "\\^{O}"; break; + case 213: t << "\\~{O}"; break; + case 214: t << "\\\"{O}"; break; + case 215: t << "$\\times$"; break; + case 216: t << "\\O"; break; + case 217: t << "\\`{U}"; break; + case 218: t << "\\'{U}"; break; + case 219: t << "\\^{U}"; break; + case 220: t << "\\\"{U}"; break; + case 221: t << "\\'{Y}"; break; + case 223: t << "\"s "; break; // assumes german package + case 224: t << "\\`{a}"; break; + case 225: t << "\\'{a}"; break; + case 226: t << "\\^{a}"; break; + case 227: t << "\\~{a}"; break; + case 228: t << "\\\"{a}"; break; + case 229: t << "\\aa "; break; + case 230: t << "\\ae "; break; + case 231: t << "\\c{c}"; break; + case 232: t << "\\`{e}"; break; + case 233: t << "\\'{e}"; break; + case 234: t << "\\^{e}"; break; + case 235: t << "\\\"{e}"; break; + case 236: t << "\\`{\\i}"; break; + case 237: t << "\\'{\\i}"; break; + case 238: t << "\\^{\\i}"; break; + case 239: t << "\\\"{\\i}"; break; + case 241: t << "\\~{n}"; break; + case 242: t << "\\`{o}"; break; + case 243: t << "\\'{o}"; break; + case 244: t << "\\^{o}"; break; + case 245: t << "\\~{o}"; break; + case 246: t << "\\\"{o}"; break; + case 248: t << "\\o "; break; + case 249: t << "\\`{u}"; break; + case 250: t << "\\'{u}"; break; + case 251: t << "\\^{u}"; break; + case 252: t << "\\\"{u}"; break; + case 253: t << "\\'{y}"; break; + case 255: t << "\\\"{y}"; break; + + default: + if ((isupper(c) && islower(pc)) + // || + // (pc!=':' && c==':') || + // (pc==':' && c!=':') + ) t << "\\-"; + t << (char)c; + } + pc = c; + } + } +} + +void LatexGenerator::codify(const char *str) +{ + static char spaces[]=" "; + if (str) + { + const char *p=str; + char c; + while (*p) + { + c=*p++; + switch(c) + { + case '\t': t << &spaces[col&7]; col+=8-(col&7); break; + case '\n': t << '\n'; col=0; break; + default: t << c; col++; break; + } + } + } +} + +void LatexGenerator::writeChar(char c) +{ + char cs[2]; + cs[0]=c; + cs[1]=0; + docify(cs); +} + +void LatexGenerator::startClassDiagram() +{ + if (compactLatexFlag) t << "\\subsubsection*"; else t << "\\subsection*"; + t << "{"; +} + +void LatexGenerator::endClassDiagram(ClassDiagram &d, + const char *fileName,const char *) +{ + d.writeFigure(t,dir,fileName); +} + +void LatexGenerator::writeFormula(const char *,const char *text) +{ + t << text; +} diff --git a/src/latexgen.h b/src/latexgen.h new file mode 100644 index 0000000..5a3dd1c --- /dev/null +++ b/src/latexgen.h @@ -0,0 +1,178 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef OUTPUT_H +#define OUTPUT_H + +#include "outputgen.h" + +class QFile; + +class LatexGenerator : public OutputGenerator +{ + public: + LatexGenerator(); + ~LatexGenerator(); + + OutputGenerator *copy() { return new LatexGenerator; } + //OutputGenerator *clone() { return new LatexGenerator(*this); } + void append(const OutputGenerator *o); + void enable() { active=TRUE; } + void disable() { active=FALSE; } + void enableIf(OutputType o) { if (o==Latex) active=TRUE; } + void disableIf(OutputType o) { if (o==Latex) active=FALSE; } + void disableIfNot(OutputType o) { if (o!=Latex) active=FALSE; } + bool isEnabled(OutputType o) { return (o==Latex && active); } + OutputGenerator *get(OutputType o) { return (o==Latex) ? this : 0; } + + static void init(); + void startFile(const char *name,const char *title, bool external); + void writeFooter(int,bool) {} + void endFile(); + void clearBuffer(); + + //void writeIndex(); + void startIndexSection(IndexSections); + void endIndexSection(IndexSections); + void startProjectNumber(); + void endProjectNumber() {} + void writeStyleInfo(int part); + void startTitleHead() { startTitle(); } + void startTitle(); + void endTitleHead(const char *name); + void endTitle() { t << "}"; } + + void newParagraph(); + void writeString(const char *text); + void startIndexList() { t << "\\begin{CompactList}" << endl; } + void endIndexList() { t << "\\end{CompactList}" << endl; } + void startItemList() { t << "\\begin{CompactItemize}" << endl; } + void endItemList() { t << "\\end{CompactItemize}" << endl; } + void startEnumList() { t << "\\begin{enumerate}" << endl; } + void endEnumList() { t << "\\end{enumerate}" << endl; } + void writeIndexItem(const char *ref,const char *file,const char *name); + void docify(const char *text); + void codify(const char *text); + void writeObjectLink(const char *ref,const char *file, + const char *anchor,const char *text); + void writeCodeLink(const char *ref, const char *file, + const char *anchor,const char *text); + void startTextLink(const char *,const char *) {} + void endTextLink() {} + void writeHtmlLink(const char *,const char *); + void startTypewriter() { t << "{\\tt "; } + void endTypewriter() { t << "}"; } + void startGroupHeader(); + void endGroupHeader(); + void writeListItem() { t << "\\item " << endl; } + + void startMemberHeader() { startGroupHeader(); } + void endMemberHeader() { endGroupHeader(); } + void startMemberList() { t << "\\begin{CompactItemize}" << endl; } + void endMemberList() { t << "\\end{CompactItemize}" << endl; } + void startMemberItem() { t << "\\item " << endl; } + void endMemberItem() { t << endl; } + + void writeRuler() { t << "\\vspace{0.4cm}\\hrule\\vspace{0.2cm}"; } + void writeAnchor(const char *) {} + void startCodeFragment() { t << "\\small\\begin{verbatim}"; } + void endCodeFragment() { t << "\\end{verbatim}\\normalsize "; } + void writeBoldString(const char *text) + { t << "{\\bf "; docify(text); t << "}"; } + void startEmphasis() { t << "{\\em "; } + void endEmphasis() { t << "}"; } + void startBold() { t << "{\\bf "; } + void endBold() { t << "}"; } + void startDescription() { t << "\\begin{description}" << endl; } + void endDescription() { t << "\\end{description}" << endl; } + void startDescItem() { t << "\\item["; } + void endDescItem() { t << "]"; } + void lineBreak() { t << "\\par\n"; } + void startMemberDoc(const char *,const char *,const char *); + void endMemberDoc() { t << "}"; } + void writeDoxyAnchor(const char *,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 startSubscript() { t << "$_{\\mbox{"; } + void endSubscript() { t << "}}$"; } + void startSuperscript() { t << "$^{\\mbox{"; } + void endSuperscript() { t << "}}$"; } + void startTable(int c) { t << "\\begin{TabularC}{" << c + << "}\n\\hline\n"; + } + void endTable() { t << "\\\\\\hline\n\\end{TabularC}\n"; } + void nextTableRow() {} + void endTableRow() { t << "\\\\\\hline\n"; } + void nextTableColumn() { t << "&"; } + void endTableColumn() {} + void writeCopyright() { t << "\\copyright"; } + void writeQuote() { t << "''"; } + void writeUmlaut(char c) { if (c=='i') t << "\\\"{\\i}"; else + t << "\\\"{" << c << "}"; + } + void writeAcute(char c) { if (c=='i') t << "\\'{\\i}"; else + t << "\\'{" << c << "}"; + } + void writeGrave(char c) { if (c=='i') t << "\\`{\\i}"; else + t << "\\`{" << c << "}"; + } + void writeCirc(char c) { if (c=='i') t << "\\^{\\i}"; else + t << "\\^{" << c << "}"; + } + void writeTilde(char c) { t << "\\~{" << c << "}"; } + void startMemberDescription() { t << "\\begin{CompactList}\\small\\item\\em "; } + void endMemberDescription() { t << "\\item\\end{CompactList}"; } + void startDescList() { t << "\\begin{Desc}\\item["; } + void endDescTitle() { t << "]"; } + void writeDescItem() { t << "\\par "; } + void endDescList() { t << "\\end{Desc}"; } + void writeSection(const char *,const char *,bool); + void writeSectionRef(const char *,const char *,const char *); + void writeSectionRefItem(const char *,const char *,const char *); + void addToIndex(const char *,const char *); + void startIndent() {} + void endIndent() {} + void writeSynopsis() {} + //void generateExternalIndex() {} + void startClassDiagram(); + void endClassDiagram(ClassDiagram &,const char *,const char *); + void startColorFont(uchar,uchar,uchar) {} + void endColorFont() {} + void writePageRef(const char *,const char *); + void startQuickIndexItem(const char *,const char *) {} + void endQuickIndexItem() {} + void writeFormula(const char *,const char *); + + //static void docifyStatic(QTextStream &t,const char *str); + + private: + LatexGenerator(const LatexGenerator &); + LatexGenerator &operator=(const LatexGenerator &); + int col; +}; + +#endif diff --git a/src/logos.cpp b/src/logos.cpp new file mode 100644 index 0000000..090309a --- /dev/null +++ b/src/logos.cpp @@ -0,0 +1,519 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <qstring.h> +#include <qfile.h> +#include <stdio.h> + +unsigned char logo_data[] = { + 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x76, 0x00, 0x35, 0x00, 0xf7, 0x00, + 0x00, 0x31, 0x7b, 0x6b, 0x31, 0x7b, 0x73, 0x31, 0x84, 0x7b, 0x31, 0x84, + 0x84, 0x31, 0x8c, 0x7b, 0x31, 0x8c, 0x84, 0x31, 0x8c, 0x8c, 0x39, 0x7b, + 0x7b, 0x39, 0x84, 0x7b, 0x39, 0x84, 0x84, 0x39, 0x8c, 0x84, 0x39, 0x94, + 0x8c, 0x39, 0x94, 0x94, 0x39, 0x9c, 0x94, 0x42, 0x7b, 0x73, 0x42, 0x8c, + 0x84, 0x42, 0x94, 0x8c, 0x42, 0x9c, 0x8c, 0x42, 0x9c, 0x94, 0x42, 0xa5, + 0x9c, 0x4a, 0x5a, 0x5a, 0x4a, 0x84, 0x84, 0x4a, 0x8c, 0x84, 0x4a, 0x94, + 0x8c, 0x4a, 0x94, 0x94, 0x4a, 0x9c, 0x94, 0x4a, 0xa5, 0x94, 0x4a, 0xa5, + 0x9c, 0x4a, 0xa5, 0xa5, 0x52, 0x52, 0x52, 0x52, 0x73, 0x73, 0x52, 0x7b, + 0x7b, 0x52, 0x84, 0x84, 0x52, 0x94, 0x8c, 0x52, 0x9c, 0x94, 0x52, 0xa5, + 0x9c, 0x52, 0xad, 0xa5, 0x52, 0xb5, 0xad, 0x5a, 0x5a, 0x5a, 0x5a, 0x63, + 0x63, 0x5a, 0x6b, 0x6b, 0x5a, 0x7b, 0x7b, 0x5a, 0x8c, 0x84, 0x5a, 0x8c, + 0x8c, 0x5a, 0x94, 0x8c, 0x5a, 0x94, 0x94, 0x5a, 0x9c, 0x94, 0x5a, 0xa5, + 0x9c, 0x5a, 0xa5, 0xa5, 0x5a, 0xad, 0xa5, 0x5a, 0xb5, 0xad, 0x5a, 0xbd, + 0xb5, 0x63, 0x63, 0x63, 0x63, 0x6b, 0x6b, 0x63, 0x73, 0x73, 0x63, 0x7b, + 0x7b, 0x63, 0x84, 0x84, 0x63, 0x8c, 0x8c, 0x63, 0x94, 0x94, 0x63, 0xa5, + 0x9c, 0x63, 0xa5, 0xa5, 0x63, 0xad, 0xa5, 0x63, 0xb5, 0xad, 0x63, 0xb5, + 0xb5, 0x63, 0xbd, 0xbd, 0x6b, 0x6b, 0x6b, 0x6b, 0x73, 0x73, 0x6b, 0x7b, + 0x7b, 0x6b, 0x8c, 0x8c, 0x6b, 0x9c, 0x94, 0x6b, 0xa5, 0x9c, 0x6b, 0xad, + 0xa5, 0x6b, 0xb5, 0xad, 0x6b, 0xb5, 0xb5, 0x6b, 0xbd, 0xb5, 0x6b, 0xbd, + 0xbd, 0x6b, 0xc6, 0xbd, 0x6b, 0xc6, 0xc6, 0x6b, 0xce, 0xc6, 0x73, 0x73, + 0x73, 0x73, 0x7b, 0x7b, 0x73, 0x84, 0x84, 0x73, 0x8c, 0x8c, 0x73, 0x94, + 0x8c, 0x73, 0x94, 0x94, 0x73, 0x9c, 0x94, 0x73, 0x9c, 0x9c, 0x73, 0xa5, + 0x9c, 0x73, 0xa5, 0xa5, 0x73, 0xad, 0xad, 0x73, 0xb5, 0xad, 0x73, 0xb5, + 0xb5, 0x73, 0xbd, 0xbd, 0x73, 0xce, 0xce, 0x7b, 0x7b, 0x7b, 0x7b, 0x8c, + 0x8c, 0x7b, 0x94, 0x94, 0x7b, 0x9c, 0x9c, 0x7b, 0xa5, 0xa5, 0x7b, 0xb5, + 0xb5, 0x7b, 0xbd, 0xb5, 0x7b, 0xbd, 0xbd, 0x7b, 0xc6, 0xc6, 0x7b, 0xce, + 0xc6, 0x7b, 0xce, 0xce, 0x7b, 0xd6, 0xce, 0x7b, 0xd6, 0xd6, 0x7b, 0xde, + 0xd6, 0x84, 0x84, 0x84, 0x84, 0x8c, 0x8c, 0x84, 0x9c, 0x94, 0x84, 0x9c, + 0x9c, 0x84, 0xa5, 0x9c, 0x84, 0xad, 0xad, 0x84, 0xb5, 0xb5, 0x84, 0xc6, + 0xc6, 0x84, 0xce, 0xce, 0x84, 0xd6, 0xd6, 0x8c, 0x7b, 0x7b, 0x8c, 0x84, + 0x84, 0x8c, 0x8c, 0x8c, 0x8c, 0xa5, 0xa5, 0x8c, 0xad, 0xad, 0x8c, 0xb5, + 0xb5, 0x8c, 0xbd, 0xb5, 0x8c, 0xbd, 0xbd, 0x8c, 0xc6, 0xc6, 0x8c, 0xce, + 0xce, 0x8c, 0xde, 0xde, 0x94, 0x7b, 0x7b, 0x94, 0x94, 0x94, 0x94, 0x9c, + 0x9c, 0x94, 0xa5, 0xa5, 0x94, 0xad, 0xad, 0x94, 0xbd, 0xb5, 0x94, 0xc6, + 0xbd, 0x9c, 0x9c, 0x9c, 0x9c, 0xa5, 0xa5, 0x9c, 0xb5, 0xb5, 0x9c, 0xbd, + 0xbd, 0x9c, 0xc6, 0xbd, 0x9c, 0xc6, 0xc6, 0x9c, 0xce, 0xc6, 0x9c, 0xce, + 0xce, 0x9c, 0xd6, 0xd6, 0xa5, 0x5a, 0x5a, 0xa5, 0x63, 0x63, 0xa5, 0x84, + 0x84, 0xa5, 0x94, 0x94, 0xa5, 0xa5, 0xa5, 0xa5, 0xad, 0xa5, 0xa5, 0xbd, + 0xbd, 0xa5, 0xc6, 0xc6, 0xa5, 0xce, 0xce, 0xa5, 0xd6, 0xd6, 0xa5, 0xde, + 0xde, 0xa5, 0xe7, 0xde, 0xad, 0x21, 0x18, 0xad, 0x21, 0x21, 0xad, 0x52, + 0x52, 0xad, 0x63, 0x63, 0xad, 0x7b, 0x7b, 0xad, 0xad, 0xad, 0xad, 0xb5, + 0xb5, 0xad, 0xbd, 0xbd, 0xad, 0xce, 0xc6, 0xad, 0xce, 0xce, 0xad, 0xd6, + 0xce, 0xad, 0xd6, 0xd6, 0xb5, 0x21, 0x21, 0xb5, 0x52, 0x52, 0xb5, 0x5a, + 0x5a, 0xb5, 0x63, 0x63, 0xb5, 0x6b, 0x6b, 0xb5, 0xb5, 0xb5, 0xb5, 0xc6, + 0xc6, 0xb5, 0xce, 0xce, 0xb5, 0xd6, 0xce, 0xb5, 0xd6, 0xd6, 0xb5, 0xde, + 0xd6, 0xb5, 0xde, 0xde, 0xb5, 0xe7, 0xe7, 0xbd, 0x21, 0x21, 0xbd, 0x29, + 0x29, 0xbd, 0x42, 0x42, 0xbd, 0x52, 0x52, 0xbd, 0x73, 0x73, 0xbd, 0x7b, + 0x7b, 0xbd, 0x84, 0x84, 0xbd, 0xbd, 0xbd, 0xbd, 0xc6, 0xc6, 0xbd, 0xce, + 0xce, 0xbd, 0xd6, 0xd6, 0xbd, 0xde, 0xde, 0xc6, 0x39, 0x39, 0xc6, 0x73, + 0x73, 0xc6, 0x7b, 0x7b, 0xc6, 0x84, 0x84, 0xc6, 0x8c, 0x8c, 0xc6, 0x94, + 0x94, 0xc6, 0xc6, 0xc6, 0xc6, 0xce, 0xce, 0xc6, 0xd6, 0xd6, 0xc6, 0xde, + 0xde, 0xc6, 0xef, 0xe7, 0xce, 0x7b, 0x7b, 0xce, 0x8c, 0x8c, 0xce, 0x94, + 0x94, 0xce, 0xce, 0xce, 0xce, 0xd6, 0xd6, 0xce, 0xde, 0xde, 0xce, 0xe7, + 0xe7, 0xd6, 0x84, 0x84, 0xd6, 0x94, 0x8c, 0xd6, 0x94, 0x94, 0xd6, 0x9c, + 0x9c, 0xd6, 0xad, 0xad, 0xd6, 0xd6, 0xd6, 0xd6, 0xe7, 0xde, 0xd6, 0xef, + 0xef, 0xde, 0xa5, 0xa5, 0xde, 0xbd, 0xbd, 0xde, 0xce, 0xce, 0xde, 0xde, + 0xde, 0xde, 0xe7, 0xe7, 0xde, 0xef, 0xe7, 0xde, 0xef, 0xef, 0xe7, 0xbd, + 0xbd, 0xe7, 0xe7, 0xe7, 0xe7, 0xef, 0xef, 0xe7, 0xf7, 0xf7, 0xef, 0xd6, + 0xd6, 0xef, 0xef, 0xef, 0xef, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xff, + 0xf7, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xf7, 0xff, 0xff, 0xff, 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, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x35, 0x00, 0x00, 0x08, + 0xfe, 0x00, 0xdd, 0x09, 0x1c, 0x48, 0xb0, 0xa0, 0xba, 0x45, 0x71, 0x76, + 0xc8, 0x29, 0xc8, 0xb0, 0xa1, 0xc3, 0x87, 0x10, 0x23, 0x4a, 0x9c, 0x48, + 0xb1, 0xa2, 0x3a, 0x74, 0xe4, 0xb4, 0x05, 0x10, 0x10, 0xa0, 0x48, 0xc5, + 0x8f, 0x20, 0x43, 0x8a, 0x1c, 0x59, 0x10, 0x5d, 0xb6, 0x5e, 0xae, 0x14, + 0x08, 0x10, 0xe0, 0x91, 0xa4, 0xcb, 0x97, 0x30, 0x43, 0xaa, 0xfb, 0xd6, + 0x4b, 0x50, 0x1b, 0x08, 0x1c, 0x8d, 0xc4, 0xdc, 0xc9, 0xb3, 0xe7, 0x40, + 0x75, 0xd9, 0x2a, 0x3d, 0x09, 0xb2, 0x40, 0xa5, 0x4e, 0x9f, 0x48, 0x93, + 0xca, 0x84, 0x86, 0xe8, 0x09, 0x8d, 0x05, 0x0b, 0x04, 0x1c, 0x55, 0x4a, + 0xb5, 0xaa, 0x43, 0x93, 0x88, 0x82, 0xd0, 0xb8, 0xb0, 0x60, 0xc0, 0x54, + 0xab, 0x60, 0xad, 0x02, 0xcd, 0x4a, 0x43, 0x42, 0xd4, 0x23, 0x61, 0xd3, + 0x56, 0x55, 0xc7, 0x34, 0x48, 0x8d, 0x0d, 0x10, 0x14, 0x60, 0x51, 0x4b, + 0x17, 0x29, 0x5b, 0xb2, 0x19, 0x24, 0x14, 0xf8, 0x5a, 0xb7, 0xaf, 0xcb, + 0xb1, 0x41, 0x4e, 0x60, 0x90, 0xa0, 0x00, 0xad, 0xdf, 0xc3, 0x24, 0xef, + 0x6a, 0xcd, 0xab, 0x80, 0x2f, 0xe2, 0xc7, 0x13, 0xd1, 0xb5, 0xad, 0x31, + 0xc2, 0xac, 0x61, 0xc8, 0x98, 0x1d, 0x5e, 0x64, 0xa6, 0xe9, 0x8f, 0x9f, + 0x38, 0x42, 0x68, 0x90, 0x20, 0x7c, 0x59, 0xa0, 0x3a, 0x75, 0xe0, 0x64, + 0x39, 0xfa, 0x03, 0xa9, 0x96, 0x39, 0x87, 0xe6, 0x82, 0x31, 0x04, 0x06, + 0xcc, 0xdd, 0xe9, 0x69, 0xb3, 0x50, 0x35, 0x54, 0x17, 0x2c, 0xd8, 0xeb, + 0x9f, 0xea, 0xd2, 0x2d, 0xcb, 0xc4, 0xa8, 0x14, 0x30, 0x69, 0xe1, 0xc0, + 0x81, 0x33, 0xa8, 0x4e, 0x1a, 0x26, 0x39, 0x87, 0x62, 0x95, 0x2b, 0xb8, + 0xae, 0x9c, 0xb4, 0x5f, 0xda, 0xd4, 0x4d, 0x3b, 0xe5, 0xa7, 0xd1, 0x34, + 0xcd, 0xe8, 0xc0, 0xfe, 0xbd, 0xda, 0xf2, 0x03, 0xc8, 0x92, 0x25, 0x40, + 0x62, 0xdc, 0xa8, 0xbc, 0xe0, 0xb2, 0x3a, 0x72, 0xdf, 0x0c, 0xbd, 0x28, + 0xf1, 0xc3, 0x89, 0x13, 0x26, 0x4d, 0x38, 0xa5, 0x13, 0x88, 0x51, 0x9b, + 0x26, 0x34, 0x4e, 0x7c, 0xf7, 0x1e, 0x39, 0xd2, 0x2c, 0x50, 0x00, 0x16, + 0xc9, 0x64, 0xb1, 0x80, 0x04, 0x1b, 0xfc, 0xe6, 0x0e, 0x46, 0x19, 0x95, + 0xc0, 0xe0, 0x21, 0x0f, 0x96, 0x13, 0x1f, 0x09, 0x25, 0x4c, 0x30, 0xc0, + 0x4a, 0x01, 0x74, 0x88, 0xc0, 0x7e, 0x17, 0x81, 0xe3, 0x0b, 0x16, 0x12, + 0x44, 0x10, 0x41, 0x89, 0x0f, 0x30, 0x72, 0x1a, 0x39, 0xe4, 0x44, 0xd3, + 0x61, 0x00, 0x71, 0x5c, 0x02, 0x01, 0x07, 0x24, 0x28, 0x70, 0x00, 0x85, + 0x25, 0x7d, 0x03, 0x4d, 0x1c, 0x1b, 0xc8, 0xf0, 0x43, 0x79, 0x33, 0xfc, + 0x20, 0x03, 0x09, 0x70, 0xb5, 0x67, 0x9b, 0x49, 0xbe, 0xec, 0x30, 0x01, + 0x09, 0x32, 0xe0, 0x77, 0x46, 0x13, 0x4d, 0x74, 0x51, 0xc7, 0x36, 0x26, + 0x21, 0x83, 0x49, 0x13, 0xf6, 0x9d, 0x61, 0x21, 0x32, 0xbd, 0xbc, 0xd0, + 0xd5, 0x02, 0x7a, 0xc4, 0xb1, 0xe0, 0x06, 0x8f, 0x98, 0xf6, 0x0d, 0x32, + 0xae, 0xf0, 0xc1, 0xc1, 0x06, 0x0b, 0x98, 0x42, 0xce, 0x49, 0x2e, 0x18, + 0xc0, 0xc1, 0x0c, 0x1c, 0x14, 0xc5, 0x51, 0x87, 0x56, 0xb4, 0x83, 0xce, + 0x99, 0x70, 0x44, 0xa0, 0x81, 0x06, 0x7e, 0x6a, 0xf0, 0x80, 0x02, 0x04, + 0x60, 0x71, 0x66, 0x2f, 0x89, 0x00, 0xb0, 0xd1, 0x03, 0x03, 0x48, 0x20, + 0x43, 0x09, 0x06, 0x0a, 0xb0, 0x0c, 0x41, 0x26, 0xf5, 0xf2, 0x06, 0x04, + 0x1b, 0x8c, 0x50, 0x82, 0x0c, 0x48, 0xf8, 0x30, 0xe4, 0x06, 0x66, 0xb5, + 0x77, 0x11, 0x34, 0xa2, 0xe4, 0xc0, 0xa0, 0x0c, 0x3e, 0x70, 0x91, 0x05, + 0x19, 0x67, 0x38, 0x81, 0x46, 0x17, 0xfe, 0x74, 0x64, 0xe3, 0x8a, 0x20, + 0x82, 0xf8, 0xe1, 0x04, 0x94, 0x87, 0xf4, 0x82, 0x88, 0x11, 0x05, 0x30, + 0x50, 0xc0, 0x0e, 0x6c, 0xe0, 0x01, 0x41, 0x03, 0x1b, 0xc4, 0x90, 0xce, + 0x7b, 0xba, 0xe2, 0x11, 0x03, 0xa8, 0x30, 0x9c, 0x59, 0x89, 0x0e, 0x0b, + 0xd2, 0x07, 0x43, 0x06, 0x76, 0x06, 0x70, 0x85, 0x36, 0xe5, 0x40, 0xe3, + 0x8a, 0x1b, 0x10, 0x44, 0x30, 0xc2, 0x08, 0x2c, 0x54, 0x91, 0x50, 0x04, + 0x0a, 0x04, 0x20, 0x46, 0x25, 0x6c, 0x44, 0xd1, 0xa1, 0x00, 0x0a, 0x2c, + 0xb0, 0xc1, 0x0c, 0x30, 0xb0, 0xa9, 0x40, 0x1c, 0x03, 0xed, 0xe9, 0x0a, + 0x1e, 0x17, 0x40, 0xc0, 0xe0, 0x0e, 0x37, 0xd0, 0x40, 0x03, 0x0a, 0x21, + 0x80, 0x6a, 0x99, 0x64, 0x95, 0x7c, 0xc1, 0xe0, 0x06, 0x24, 0x10, 0xa1, + 0x55, 0x10, 0x6e, 0xcc, 0xe1, 0x44, 0x1a, 0x6a, 0x68, 0x52, 0x89, 0x17, + 0x41, 0xb0, 0xe1, 0x47, 0x13, 0x3f, 0x94, 0xf0, 0x46, 0x14, 0x02, 0x8b, + 0xd0, 0x46, 0x10, 0x4f, 0x5c, 0x21, 0xc1, 0x04, 0x1b, 0xa0, 0x02, 0xd4, + 0xc4, 0x39, 0xac, 0x29, 0xc1, 0x22, 0x35, 0xe1, 0xa0, 0x2f, 0x07, 0x3f, + 0xe0, 0x70, 0xc2, 0x09, 0x29, 0xe0, 0x24, 0x40, 0x08, 0x6f, 0x8a, 0xc2, + 0x46, 0x08, 0x7e, 0xee, 0x30, 0x44, 0x10, 0x41, 0x78, 0x41, 0xc8, 0x05, + 0xe4, 0x12, 0x10, 0x45, 0x60, 0x2b, 0x25, 0x00, 0x81, 0x05, 0x28, 0x0c, + 0x91, 0xc5, 0x68, 0x0b, 0xbc, 0x60, 0x1a, 0x39, 0x35, 0xd9, 0xb0, 0xa0, + 0x04, 0x2d, 0xe0, 0xc1, 0x86, 0x53, 0x1d, 0x74, 0x10, 0x82, 0x04, 0x10, + 0xb4, 0xf7, 0x8d, 0x2b, 0x6c, 0x7c, 0x50, 0x02, 0x93, 0x57, 0x08, 0xb2, + 0x35, 0x0d, 0x41, 0xb4, 0x71, 0x46, 0x17, 0x69, 0xd0, 0x31, 0xca, 0x1d, + 0x40, 0xbf, 0x01, 0xa5, 0x0f, 0x9e, 0x62, 0x28, 0x81, 0xfe, 0x22, 0x78, + 0x68, 0x15, 0x85, 0x04, 0x19, 0x4c, 0xe0, 0x03, 0x39, 0xc8, 0xf4, 0xfd, + 0x02, 0xa8, 0x23, 0xf8, 0x32, 0xb1, 0x07, 0x0c, 0x6c, 0x50, 0x42, 0x18, + 0x5c, 0x9b, 0x90, 0x83, 0x4a, 0x01, 0x5c, 0x42, 0xb6, 0x10, 0x19, 0x8c, + 0x10, 0x43, 0x1e, 0x78, 0x38, 0x45, 0x44, 0x0f, 0x23, 0x68, 0x00, 0x41, + 0x11, 0x50, 0x98, 0x40, 0x41, 0x00, 0x08, 0x14, 0x80, 0x41, 0x10, 0x26, + 0x98, 0xf0, 0x84, 0x0f, 0xa0, 0x2a, 0xa0, 0x8e, 0x6d, 0x41, 0x3d, 0xe1, + 0xc0, 0x02, 0x79, 0x29, 0x82, 0x12, 0x22, 0x5e, 0xd0, 0xd0, 0x81, 0x07, + 0x70, 0x0d, 0xb0, 0x03, 0x32, 0x82, 0x04, 0x81, 0x00, 0x91, 0x89, 0xa3, + 0x29, 0x88, 0x53, 0x41, 0xf4, 0x01, 0xb7, 0x1a, 0xb0, 0x4c, 0xcc, 0x36, + 0x1c, 0x4c, 0x64, 0xbc, 0xc1, 0x06, 0x1c, 0x18, 0x02, 0x8d, 0xf4, 0x4f, + 0xe8, 0xc0, 0x01, 0x83, 0xa6, 0x4c, 0x7c, 0x03, 0x09, 0x13, 0x48, 0xd0, + 0x47, 0x2f, 0x77, 0xd0, 0x80, 0x40, 0x04, 0x24, 0xfc, 0x30, 0x0a, 0xef, + 0xfe, 0x46, 0xa1, 0x92, 0x00, 0x71, 0x2c, 0x9f, 0x02, 0x93, 0x5b, 0xb8, + 0x82, 0xc8, 0x17, 0x58, 0x54, 0x2f, 0xc3, 0x16, 0x97, 0x10, 0x85, 0x17, + 0x4c, 0x87, 0x00, 0x01, 0xec, 0xa5, 0x6f, 0x26, 0x08, 0xc2, 0xd3, 0x30, + 0x00, 0x81, 0xd9, 0xa1, 0xa3, 0x17, 0x7d, 0x4b, 0x80, 0x02, 0x24, 0xf0, + 0x82, 0x6f, 0xec, 0x09, 0x19, 0x4d, 0x31, 0xc1, 0x09, 0x44, 0x50, 0x94, + 0x1d, 0xb8, 0xc2, 0x0b, 0x6f, 0x81, 0x00, 0x04, 0xc6, 0x80, 0x11, 0x9a, + 0x14, 0x8f, 0x06, 0x60, 0x80, 0x58, 0x1a, 0x68, 0x41, 0x3c, 0xe6, 0x59, + 0x01, 0x08, 0x32, 0x00, 0xd5, 0x1e, 0x30, 0x02, 0x41, 0x7f, 0x49, 0x01, + 0x54, 0x13, 0xc8, 0x42, 0xf1, 0x0e, 0x27, 0x81, 0x11, 0x28, 0x43, 0x7a, + 0xfe, 0x15, 0x90, 0x40, 0xfb, 0xb4, 0x41, 0x3c, 0xad, 0x40, 0x61, 0x7e, + 0x55, 0x60, 0x43, 0x10, 0x58, 0x10, 0x03, 0x19, 0x2c, 0x42, 0x14, 0x79, + 0x50, 0xc2, 0x7d, 0x96, 0xc0, 0x07, 0x68, 0x64, 0x43, 0x80, 0x1a, 0x2c, + 0xe0, 0x02, 0xf6, 0x20, 0x40, 0x7f, 0x61, 0x01, 0x06, 0x60, 0x63, 0x87, + 0x3b, 0xc6, 0xd6, 0x3b, 0x05, 0xe8, 0x8b, 0x07, 0xb3, 0x7b, 0x0f, 0xd9, + 0x68, 0x70, 0x82, 0x10, 0x84, 0xad, 0x05, 0x42, 0x41, 0xc1, 0x02, 0x18, + 0x20, 0x81, 0x32, 0x3d, 0xa8, 0x76, 0x34, 0x88, 0x42, 0x17, 0xd6, 0xa0, + 0x06, 0x5a, 0x8c, 0x0d, 0x0f, 0xbe, 0xb3, 0xc1, 0xa3, 0x24, 0xa4, 0x8c, + 0x8b, 0xe0, 0xf1, 0x09, 0x2f, 0x20, 0x01, 0x09, 0x38, 0x10, 0x85, 0x1a, + 0x70, 0x80, 0x03, 0x25, 0xe8, 0x43, 0xed, 0x4c, 0x80, 0x03, 0x21, 0xce, + 0x20, 0x18, 0x57, 0x74, 0x0a, 0x0e, 0x0a, 0x50, 0x00, 0x01, 0x80, 0x81, + 0x62, 0x22, 0x68, 0x52, 0x19, 0xe4, 0x70, 0x2b, 0x27, 0x94, 0xe1, 0x12, + 0xd9, 0xb0, 0x50, 0x17, 0x6b, 0xa0, 0x12, 0x08, 0x1c, 0xc2, 0x17, 0x80, + 0xa4, 0x01, 0x16, 0x48, 0x90, 0x81, 0x06, 0x8e, 0x51, 0x14, 0x4e, 0x79, + 0x00, 0xe0, 0x46, 0xb0, 0x9f, 0x07, 0x15, 0x91, 0x06, 0x1b, 0xa8, 0xa5, + 0x0b, 0xb2, 0x72, 0x82, 0xca, 0x48, 0x00, 0x09, 0x53, 0x5b, 0x23, 0x15, + 0xba, 0xc0, 0x4c, 0x66, 0x48, 0x86, 0x98, 0x48, 0x80, 0xe1, 0x06, 0x1a, + 0xd0, 0x83, 0x63, 0x51, 0x2d, 0x96, 0x37, 0xc4, 0xde, 0x0a, 0x54, 0x80, + 0xbd, 0x0d, 0x48, 0x03, 0x8f, 0x43, 0x10, 0xe2, 0x0f, 0xcc, 0x10, 0xbd, + 0x27, 0xdc, 0x20, 0x03, 0x0a, 0x28, 0xc0, 0x02, 0x06, 0xe1, 0x94, 0x22, + 0xd4, 0x87, 0x0b, 0x50, 0x72, 0xc2, 0x2b, 0xc9, 0x71, 0x1a, 0x32, 0xd2, + 0xc0, 0x06, 0xe9, 0xfe, 0x5c, 0xc0, 0x22, 0x7e, 0x39, 0x4b, 0xb8, 0xcc, + 0xee, 0x1b, 0x42, 0xa1, 0x41, 0x0a, 0x32, 0x40, 0xd0, 0x49, 0xb1, 0x43, + 0x32, 0x82, 0x10, 0x68, 0x06, 0xd8, 0xb4, 0x03, 0xb2, 0xb8, 0x80, 0x41, + 0x24, 0xd8, 0x86, 0x40, 0xec, 0xb9, 0x05, 0x66, 0xa2, 0xc1, 0x1c, 0xcf, + 0x7c, 0x82, 0x11, 0x96, 0x10, 0xa4, 0x35, 0x4d, 0x80, 0x0c, 0x0f, 0x62, + 0x8a, 0x53, 0x9e, 0x30, 0x82, 0x0d, 0x2c, 0x09, 0x7b, 0x13, 0x18, 0xc3, + 0x4c, 0xd6, 0x18, 0x04, 0x2b, 0x38, 0x6e, 0x06, 0x40, 0x40, 0xc2, 0xe1, + 0x20, 0x60, 0x00, 0x05, 0x5c, 0x22, 0x2b, 0x94, 0xc4, 0x8f, 0x7d, 0xe6, + 0xf0, 0x8a, 0x6c, 0xd0, 0xb3, 0x9e, 0x1f, 0xa4, 0x81, 0x10, 0xbe, 0xc4, + 0x08, 0x68, 0x9c, 0xd0, 0x08, 0x23, 0x10, 0xa1, 0x18, 0xc9, 0xd1, 0x45, + 0x1b, 0x2c, 0x74, 0x03, 0x3d, 0x28, 0x07, 0xb2, 0xda, 0x60, 0x83, 0x92, + 0xc2, 0x65, 0x07, 0x01, 0xc5, 0x81, 0x22, 0x65, 0x50, 0x86, 0x72, 0x98, + 0x44, 0x28, 0x56, 0xc0, 0x92, 0x1a, 0x38, 0xb1, 0x52, 0x3c, 0x50, 0xe1, + 0x56, 0x4b, 0x38, 0xc2, 0x16, 0x1c, 0xc7, 0x81, 0x4c, 0xb0, 0x83, 0x26, + 0x6c, 0x60, 0x23, 0x0e, 0x48, 0x36, 0x01, 0x92, 0x6d, 0x60, 0x19, 0xed, + 0x28, 0x47, 0x0b, 0x69, 0xf0, 0x84, 0x22, 0xf4, 0xe8, 0x51, 0xdf, 0x33, + 0x4b, 0x29, 0x26, 0x79, 0x82, 0x24, 0x70, 0xe1, 0x0c, 0x65, 0x80, 0xc6, + 0x37, 0xc8, 0x81, 0x8e, 0xd3, 0xa0, 0x02, 0x13, 0x4d, 0x2d, 0xca, 0x02, + 0x1a, 0x61, 0x54, 0xad, 0xe8, 0x40, 0x60, 0xb3, 0x23, 0x5c, 0x2c, 0x5d, + 0x60, 0x55, 0x1f, 0x98, 0xc2, 0x17, 0x89, 0x98, 0x02, 0x06, 0xbe, 0x75, + 0xbd, 0x23, 0x04, 0x55, 0x08, 0x89, 0x64, 0x92, 0x19, 0x50, 0x71, 0x89, + 0x37, 0x64, 0x81, 0x09, 0xae, 0x4a, 0xfe, 0xc3, 0x34, 0x08, 0x27, 0x88, + 0x2f, 0x38, 0x81, 0x99, 0x4b, 0x10, 0x42, 0x1b, 0x62, 0x18, 0x03, 0x0e, + 0x48, 0xe3, 0x99, 0xac, 0x3b, 0x41, 0x8f, 0x38, 0x30, 0x81, 0x12, 0x24, + 0xc1, 0x4c, 0x64, 0x5b, 0x18, 0xc2, 0xce, 0x26, 0xb0, 0x01, 0xf0, 0x81, + 0x8c, 0xad, 0x33, 0x02, 0x96, 0x9a, 0xa0, 0x09, 0x6d, 0x64, 0x23, 0x1a, + 0xca, 0x80, 0x04, 0x13, 0xb8, 0x30, 0x8a, 0xde, 0x0d, 0x75, 0x00, 0x05, + 0xa0, 0xec, 0x09, 0x75, 0x20, 0x01, 0xb0, 0x39, 0x50, 0xa4, 0x34, 0xc0, + 0xc1, 0x08, 0x14, 0xb9, 0x5e, 0x84, 0x2d, 0x52, 0x91, 0x24, 0x88, 0x81, + 0x16, 0x7e, 0x29, 0x05, 0x12, 0xc0, 0x94, 0x09, 0x5d, 0x40, 0x03, 0x80, + 0xcc, 0x80, 0xa5, 0x4d, 0x90, 0x63, 0x7b, 0x51, 0xe0, 0x82, 0x7e, 0xbb, + 0x10, 0x06, 0xb6, 0x89, 0x01, 0x08, 0x68, 0x90, 0x41, 0x0c, 0xc4, 0x31, + 0x36, 0x36, 0x98, 0xa0, 0x03, 0x20, 0x60, 0x6e, 0x09, 0x64, 0x51, 0xaf, + 0xed, 0xf5, 0x2e, 0x05, 0x23, 0x58, 0x81, 0x07, 0x50, 0xa0, 0x82, 0x5a, + 0x72, 0xb2, 0x14, 0x45, 0x34, 0x81, 0x10, 0xe0, 0xc9, 0x85, 0x2e, 0xa8, + 0x81, 0x0e, 0x5c, 0x60, 0xc2, 0x76, 0x65, 0x50, 0x08, 0xef, 0xa6, 0x53, + 0x01, 0x45, 0x1d, 0x6f, 0x2d, 0x6d, 0x39, 0x13, 0x08, 0xfa, 0x0d, 0x06, + 0xf0, 0x25, 0x99, 0x22, 0x79, 0x80, 0x63, 0x12, 0x6c, 0xa1, 0xc1, 0x5a, + 0xc1, 0x41, 0x12, 0x96, 0x60, 0xd1, 0x34, 0xa0, 0x01, 0x4b, 0x9a, 0xc8, + 0x19, 0x1b, 0xb4, 0x90, 0x86, 0x34, 0x74, 0xc1, 0x11, 0xcb, 0xe3, 0xeb, + 0x0e, 0x0e, 0x56, 0x06, 0x74, 0x14, 0xb1, 0x03, 0x27, 0x28, 0x01, 0x07, + 0x30, 0xe0, 0x83, 0xd9, 0x99, 0xa9, 0x26, 0x78, 0xf8, 0x42, 0x1b, 0x28, + 0x66, 0x02, 0x1a, 0x7c, 0x61, 0x04, 0x45, 0xe1, 0xc1, 0xfe, 0x15, 0x7b, + 0x87, 0xc2, 0x2d, 0x60, 0x09, 0x40, 0x4e, 0x48, 0x31, 0x13, 0xca, 0xa0, + 0x08, 0xef, 0x1a, 0x08, 0x02, 0xe2, 0xd5, 0x0a, 0x0b, 0x82, 0x89, 0x81, + 0x75, 0xf0, 0xe7, 0x8a, 0x4a, 0xbc, 0xe7, 0x0a, 0x60, 0xf0, 0x3d, 0x0c, + 0x94, 0x60, 0x05, 0x35, 0x90, 0x81, 0xa2, 0xfd, 0x40, 0x30, 0x25, 0x02, + 0xad, 0x08, 0x5c, 0x00, 0x44, 0x1d, 0xd2, 0xd0, 0x84, 0x3e, 0x00, 0x83, + 0x45, 0x2d, 0x94, 0x42, 0x16, 0xd4, 0x00, 0x88, 0x68, 0xd4, 0x64, 0x28, + 0x82, 0x50, 0xf4, 0x23, 0xc4, 0x71, 0x32, 0xd6, 0xa5, 0x40, 0xcb, 0x13, + 0xd0, 0x04, 0x41, 0x46, 0xd5, 0x0b, 0x52, 0xf4, 0xa2, 0x17, 0xa2, 0x88, + 0xf2, 0x13, 0xc2, 0x00, 0x95, 0x0d, 0x80, 0x83, 0x29, 0x14, 0x0b, 0xc2, + 0x10, 0xb0, 0xe0, 0x2a, 0xb4, 0x72, 0x21, 0x13, 0xda, 0x58, 0xe3, 0x10, + 0x8a, 0x22, 0x01, 0xf1, 0x0a, 0x21, 0x08, 0x3a, 0x58, 0x68, 0x06, 0xbc, + 0x1c, 0xd2, 0x59, 0x79, 0x61, 0x28, 0x42, 0xc0, 0x01, 0x11, 0xa8, 0xf0, + 0x05, 0x2f, 0xb0, 0x81, 0x10, 0xaf, 0x20, 0x47, 0x3b, 0x46, 0xe5, 0x6c, + 0x68, 0x4f, 0x21, 0x0e, 0x7a, 0x18, 0x85, 0x4f, 0xdf, 0xb3, 0x3d, 0x3c, + 0xdc, 0xa1, 0x12, 0xbf, 0xa0, 0x92, 0xac, 0xd4, 0x36, 0x08, 0x52, 0x44, + 0x23, 0x8d, 0x93, 0xe4, 0xc1, 0x90, 0x48, 0x30, 0x1d, 0x4a, 0xc1, 0x67, + 0xb1, 0x6f, 0xba, 0x17, 0xd0, 0xc0, 0x90, 0x97, 0x11, 0x6c, 0x83, 0x70, + 0x95, 0xc0, 0x43, 0xae, 0xa1, 0x60, 0x85, 0x2c, 0xc4, 0x81, 0x11, 0xd1, + 0xc0, 0x88, 0xb3, 0xdb, 0x10, 0x07, 0x4c, 0x28, 0x23, 0x1c, 0x41, 0x61, + 0x83, 0x17, 0xc4, 0xb0, 0x08, 0x60, 0x7c, 0xe7, 0x27, 0x55, 0x12, 0x05, + 0x22, 0x68, 0x85, 0x08, 0x51, 0xb8, 0x42, 0x14, 0x95, 0x10, 0x45, 0x2f, + 0xfe, 0xb2, 0xd1, 0xd8, 0x15, 0x65, 0x03, 0x4d, 0x88, 0xd8, 0x78, 0xc7, + 0x91, 0x31, 0x6e, 0x43, 0xc2, 0xda, 0x15, 0xc8, 0xb0, 0xe0, 0x7b, 0x64, + 0xe5, 0x0a, 0x57, 0x44, 0xe3, 0xa7, 0x19, 0xbd, 0x81, 0x0c, 0x66, 0x50, + 0x02, 0x48, 0xb0, 0xa3, 0x1d, 0x18, 0xc7, 0x88, 0x3a, 0x32, 0x31, 0x0d, + 0xe0, 0xd2, 0xa0, 0x08, 0xc8, 0x13, 0x07, 0x46, 0xb4, 0x55, 0x09, 0x41, + 0xe0, 0x01, 0x0f, 0x82, 0xb0, 0xc4, 0xc8, 0x19, 0xfb, 0x5f, 0x8d, 0x8b, + 0x02, 0x19, 0xf4, 0xb4, 0x57, 0x25, 0x2a, 0xe1, 0x8a, 0x6f, 0x30, 0xfb, + 0x48, 0xe4, 0xf0, 0x86, 0x31, 0x8a, 0xc1, 0x0b, 0x5e, 0xec, 0x82, 0x17, + 0xc5, 0x28, 0xc6, 0xd8, 0x8b, 0xe1, 0x8c, 0x67, 0x5c, 0xe3, 0xed, 0x6f, + 0x7f, 0x86, 0x31, 0x8c, 0x61, 0xf6, 0x5d, 0xa4, 0xdd, 0x19, 0xd6, 0xb8, + 0x46, 0xde, 0xad, 0xf1, 0x8c, 0x63, 0xa8, 0x1d, 0xef, 0x7b, 0x97, 0xfb, + 0xdc, 0xf1, 0x0e, 0x77, 0x5e, 0xd0, 0x8d, 0x07, 0x40, 0xf8, 0xc1, 0x0c, + 0xa4, 0x41, 0x0e, 0xbd, 0x57, 0xe3, 0xf1, 0xdd, 0xb0, 0xa2, 0x29, 0x8c, + 0x2b, 0x8d, 0x22, 0xde, 0xc0, 0x53, 0x25, 0x58, 0x02, 0x39, 0xb0, 0x41, + 0x0c, 0x62, 0xe8, 0xa2, 0x15, 0xac, 0x08, 0x3d, 0x2b, 0x5a, 0x31, 0x8c, + 0xce, 0x37, 0xc3, 0xf3, 0xad, 0x48, 0x7d, 0xe9, 0x4f, 0xaf, 0x8b, 0xcf, + 0x93, 0xbe, 0x19, 0xd4, 0xb0, 0x06, 0xd0, 0x6d, 0xf3, 0xa6, 0x5e, 0xe8, + 0xe2, 0x16, 0xb7, 0x48, 0x05, 0xee, 0x77, 0xbf, 0x7b, 0xdd, 0xf3, 0x1e, + 0xf7, 0xb6, 0xe0, 0x7d, 0xf0, 0x6d, 0x11, 0xfc, 0xdd, 0x0f, 0xdf, 0xf8, + 0xb7, 0x20, 0xfe, 0xf1, 0x81, 0x8f, 0x8b, 0x27, 0x0c, 0x01, 0x08, 0x30, + 0x2d, 0x03, 0x32, 0x8c, 0x41, 0xfc, 0x54, 0xd8, 0x22, 0x15, 0xc2, 0xa8, + 0x44, 0x21, 0x7e, 0xfe, 0x34, 0x03, 0x19, 0x64, 0x21, 0x0c, 0x3a, 0xe0, + 0xfe, 0x0f, 0x58, 0x76, 0xfd, 0x54, 0x98, 0xff, 0xfc, 0xe8, 0x37, 0xbf, + 0x27, 0xd0, 0xef, 0x89, 0xf6, 0xbb, 0xff, 0xfd, 0x9e, 0xe8, 0x44, 0x2e, + 0xce, 0xf1, 0x20, 0x9a, 0x80, 0x7c, 0x12, 0x91, 0xf8, 0x84, 0xfe, 0xf3, + 0xff, 0x89, 0xfc, 0x47, 0x42, 0x15, 0xfd, 0x07, 0x80, 0xfe, 0x07, 0x80, + 0xfb, 0xb7, 0x0a, 0x91, 0x60, 0x80, 0xab, 0x00, 0x0a, 0x0a, 0xb8, 0x80, + 0x0c, 0xd8, 0x80, 0xa0, 0xc0, 0x0a, 0xad, 0xd7, 0x0a, 0x81, 0xa0, 0x40, + 0x5d, 0x00, 0x25, 0x8a, 0x50, 0x09, 0xa1, 0x00, 0x0a, 0xad, 0xa0, 0x0b, + 0x9e, 0x07, 0x0a, 0x76, 0xc0, 0x06, 0x5c, 0x90, 0x78, 0x42, 0x12, 0x24, + 0xe6, 0x01, 0x04, 0x5c, 0x60, 0x09, 0x94, 0x10, 0x09, 0x0a, 0x28, 0x09, + 0xa0, 0x10, 0x09, 0x91, 0x20, 0x09, 0x2a, 0xf8, 0x82, 0x32, 0x08, 0x83, + 0x30, 0x38, 0x83, 0x92, 0x70, 0x83, 0x1a, 0xc8, 0x0b, 0xcf, 0xc0, 0x0d, + 0xd7, 0x30, 0x0e, 0xb6, 0xa1, 0x23, 0xae, 0x50, 0x09, 0x88, 0xb0, 0x75, + 0x89, 0xb0, 0x75, 0x5b, 0x37, 0x84, 0x46, 0x58, 0x09, 0x45, 0x68, 0x84, + 0x4b, 0x98, 0x84, 0x44, 0x28, 0x84, 0x50, 0x58, 0x84, 0x43, 0x38, 0x84, + 0x52, 0x58, 0x84, 0x22, 0xd7, 0x0b, 0x13, 0x33, 0x04, 0x50, 0xd2, 0x04, + 0x73, 0x00, 0x6b, 0x56, 0xd8, 0x0b, 0xd0, 0x80, 0x0c, 0x13, 0x13, 0x04, + 0x42, 0x90, 0x05, 0x4d, 0x00, 0x7d, 0x4b, 0xb0, 0x85, 0x3c, 0x05, 0x72, + 0x4e, 0xd8, 0x86, 0x6e, 0xc8, 0x86, 0x4e, 0xe8, 0x71, 0x31, 0xd7, 0x4b, + 0xfc, 0xf1, 0x26, 0xd0, 0x10, 0x86, 0xc8, 0x90, 0x87, 0x7a, 0x88, 0x87, + 0x7a, 0xd8, 0x87, 0x79, 0x18, 0x86, 0x80, 0x88, 0x0c, 0x81, 0x18, 0x86, + 0xc9, 0x80, 0x87, 0x84, 0x68, 0x88, 0xbf, 0x82, 0x78, 0x87, 0xba, 0xf2, + 0x04, 0x60, 0x50, 0x06, 0x73, 0xd0, 0x05, 0xc0, 0x90, 0x0d, 0x77, 0x78, + 0x87, 0xda, 0xf0, 0x0d, 0x27, 0x21, 0x08, 0xb9, 0x86, 0x03, 0x47, 0x90, + 0x86, 0x4d, 0xe0, 0x07, 0xb2, 0x60, 0x89, 0x92, 0x38, 0x89, 0xa2, 0x38, + 0x8a, 0xa4, 0x58, 0x8a, 0x77, 0x98, 0x0d, 0x8b, 0xf5, 0x75, 0x47, 0x82, + 0x0e, 0xac, 0xd8, 0x8a, 0xae, 0xf8, 0x8a, 0xb0, 0x18, 0x8b, 0xb2, 0x38, + 0x8b, 0xac, 0x58, 0x75, 0xb4, 0x22, 0x0a, 0x24, 0x77, 0x1a, 0xaf, 0x78, + 0x11, 0x34, 0xd1, 0x74, 0x12, 0x17, 0x2c, 0x95, 0x30, 0x72, 0xac, 0x78, + 0x11, 0xb0, 0x48, 0x8c, 0xc6, 0x38, 0x8c, 0x8d, 0x95, 0x8c, 0xe9, 0x90, + 0x8c, 0x17, 0xd1, 0x8c, 0xaa, 0xb8, 0x6a, 0x03, 0xd1, 0x0e, 0x62, 0x34, + 0x7b, 0x11, 0xf1, 0x8c, 0x32, 0xf1, 0x5f, 0x79, 0x38, 0x6e, 0x9a, 0x31, + 0x73, 0x68, 0x52, 0x73, 0x82, 0xc8, 0x58, 0xd4, 0x98, 0x19, 0x69, 0x71, + 0x11, 0x2c, 0x82, 0x0e, 0xe1, 0xb8, 0x1b, 0xb5, 0x58, 0x8e, 0x8d, 0x25, + 0x8e, 0xec, 0xd8, 0x8e, 0xee, 0xf8, 0x8e, 0xf0, 0x18, 0x8f, 0xf2, 0x38, + 0x8f, 0xf4, 0x58, 0x8f, 0xf6, 0x78, 0x8f, 0xf8, 0x98, 0x8f, 0xfa, 0xb8, + 0x8f, 0xfc, 0xd8, 0x8f, 0xfe, 0xf8, 0x8f, 0x00, 0x19, 0x90, 0x02, 0x39, + 0x90, 0x04, 0xb9, 0x8f, 0x01, 0x01, 0x00, 0x3b +}; +const unsigned int logo_len = 3536; + +unsigned char search_data[] = { + 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x78, 0x00, 0x1a, 0x00, 0xe7, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x01, 0x4c, 0x01, 0x01, 0x4c, 0x00, + 0x02, 0x4c, 0x01, 0x02, 0x4c, 0x02, 0x01, 0x63, 0x01, 0x02, 0x63, 0x02, + 0x02, 0x63, 0x01, 0x04, 0x63, 0x02, 0x04, 0x63, 0x04, 0x04, 0x63, 0x04, + 0x07, 0x72, 0x02, 0x04, 0x72, 0x04, 0x04, 0x72, 0x04, 0x07, 0x72, 0x07, + 0x07, 0x72, 0x04, 0x09, 0x72, 0x07, 0x09, 0x7d, 0x07, 0x09, 0x7d, 0x09, + 0x09, 0x7d, 0x09, 0x0d, 0x87, 0x09, 0x0d, 0x87, 0x09, 0x11, 0x87, 0x0d, + 0x11, 0x90, 0x0d, 0x11, 0x90, 0x0d, 0x15, 0x90, 0x11, 0x15, 0x9a, 0x11, + 0x15, 0x9a, 0x11, 0x1a, 0x9a, 0x15, 0x1a, 0xa2, 0x15, 0x1a, 0xa2, 0x15, + 0x20, 0xa2, 0x1a, 0x20, 0xa9, 0x1a, 0x20, 0xa9, 0x1a, 0x26, 0xa0, 0x20, + 0x28, 0xa0, 0x24, 0x28, 0xa7, 0x2f, 0x37, 0xa7, 0x32, 0x37, 0xb0, 0x20, + 0x26, 0xb0, 0x20, 0x2d, 0xb7, 0x26, 0x2d, 0xbd, 0x2d, 0x2d, 0xb7, 0x26, + 0x34, 0xb2, 0x29, 0x36, 0xb7, 0x2d, 0x34, 0xbd, 0x2d, 0x34, 0xb5, 0x32, + 0x3c, 0xad, 0x3e, 0x45, 0x8e, 0x43, 0x3b, 0xad, 0x41, 0x45, 0xbf, 0x43, + 0x4e, 0xb3, 0x4d, 0x53, 0xb3, 0x53, 0x4f, 0xb3, 0x50, 0x53, 0xba, 0x5e, + 0x62, 0xb8, 0x71, 0x5f, 0xc3, 0x34, 0x3b, 0xc9, 0x3b, 0x44, 0xc9, 0x3b, + 0x4d, 0xc9, 0x44, 0x4d, 0xcf, 0x44, 0x56, 0xcf, 0x4d, 0x56, 0xd5, 0x4d, + 0x5f, 0xd5, 0x56, 0x5f, 0xcc, 0x54, 0x61, 0xda, 0x56, 0x6b, 0xda, 0x5f, + 0x6b, 0xdf, 0x5f, 0x6b, 0xc0, 0x6b, 0x70, 0xc0, 0x6d, 0x70, 0xcd, 0x7f, + 0x6a, 0xc6, 0x7a, 0x7f, 0xc6, 0x7c, 0x7f, 0xd7, 0x64, 0x72, 0xd6, 0x66, + 0x72, 0xd7, 0x6f, 0x72, 0xd7, 0x6d, 0x79, 0xd6, 0x71, 0x71, 0xe5, 0x6b, + 0x75, 0xe5, 0x75, 0x75, 0xe9, 0x75, 0x8c, 0xcd, 0x81, 0x6e, 0xcd, 0x85, + 0x72, 0xcd, 0x88, 0x8d, 0xcd, 0x8a, 0x8d, 0xd3, 0x98, 0x9a, 0xd9, 0xa7, + 0xa9, 0xdc, 0xaa, 0xa0, 0xdf, 0xb6, 0xb7, 0xee, 0x80, 0x8c, 0xe5, 0x8b, + 0x92, 0xee, 0x8c, 0x9a, 0xf2, 0x8c, 0x9a, 0xea, 0x8c, 0xa0, 0xec, 0x99, + 0xa3, 0xf7, 0x9a, 0xb4, 0xe1, 0xac, 0xa3, 0xea, 0xae, 0xa0, 0xef, 0xae, + 0xb1, 0xe6, 0xb5, 0xac, 0xf7, 0xa6, 0xb4, 0xfc, 0xa6, 0xc1, 0xfa, 0xaf, + 0xc0, 0xf3, 0xc1, 0xb3, 0xf2, 0xd6, 0xac, 0xff, 0xff, 0xa3, 0xe6, 0xc4, + 0xc6, 0xec, 0xd2, 0xd0, 0xec, 0xd3, 0xd4, 0xf6, 0xcd, 0xc9, 0xfb, 0xc5, + 0xd1, 0xfb, 0xc9, 0xd4, 0xf2, 0xd6, 0xd3, 0xf7, 0xd3, 0xd2, 0xf5, 0xd0, + 0xd7, 0xf3, 0xdc, 0xdc, 0xf9, 0xd4, 0xd7, 0xfa, 0xd1, 0xd8, 0xfa, 0xd6, + 0xda, 0xf9, 0xda, 0xd5, 0xf9, 0xdf, 0xe1, 0xfc, 0xde, 0xe0, 0xff, 0xff, + 0xcb, 0xff, 0xff, 0xcc, 0xf2, 0xe2, 0xe2, 0xfa, 0xe5, 0xe8, 0xfe, 0xed, + 0xe9, 0xfe, 0xef, 0xf0, 0xf9, 0xf0, 0xf1, 0xfd, 0xf0, 0xf1, 0xff, 0xf4, + 0xf0, 0xff, 0xf6, 0xf2, 0xff, 0xf8, 0xf8, 0xff, 0xfa, 0xf8, 0xff, 0xfb, + 0xfa, 0xff, 0xfb, 0xfb, 0xff, 0xfd, 0xfa, 0xff, 0xfd, 0xfd, 0xff, 0xff, + 0xfd, 0xff, 0xff, 0xff, 0x00, 0xcc, 0x22, 0x00, 0xcc, 0x55, 0x00, 0xcc, + 0x99, 0x00, 0xcc, 0xcc, 0x00, 0xaa, 0xcc, 0x00, 0x66, 0xcc, 0x00, 0x33, + 0xcc, 0x00, 0x00, 0xcc, 0x11, 0x00, 0xcc, 0x44, 0x00, 0xcc, 0x55, 0x00, + 0xcc, 0x88, 0x00, 0xcc, 0xbb, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0x00, + 0xbb, 0xcc, 0x00, 0x88, 0xcc, 0x00, 0x66, 0xcc, 0x00, 0x44, 0xcc, 0x00, + 0x22, 0x99, 0x00, 0x00, 0x99, 0x11, 0x00, 0x99, 0x33, 0x00, 0x99, 0x44, + 0x00, 0x99, 0x66, 0x00, 0x99, 0x88, 0x00, 0x99, 0x99, 0x00, 0x88, 0x99, + 0x00, 0x66, 0x99, 0x00, 0x55, 0x99, 0x00, 0x33, 0x99, 0x00, 0x11, 0x99, + 0x00, 0x00, 0x99, 0x00, 0x00, 0x99, 0x11, 0x00, 0x99, 0x44, 0x00, 0x99, + 0x77, 0x00, 0x99, 0x99, 0x00, 0x77, 0x99, 0x00, 0x55, 0x99, 0x00, 0x22, + 0x99, 0x00, 0x00, 0x99, 0x11, 0x00, 0x99, 0x33, 0x00, 0x99, 0x44, 0x00, + 0x99, 0x66, 0x00, 0x99, 0x88, 0x00, 0x99, 0x99, 0x00, 0x99, 0x99, 0x00, + 0x88, 0x99, 0x00, 0x66, 0x99, 0x00, 0x55, 0x99, 0x00, 0x33, 0x99, 0x00, + 0x11, 0x66, 0x00, 0x00, 0x66, 0x11, 0x00, 0x66, 0x22, 0x00, 0x66, 0x33, + 0x00, 0x66, 0x44, 0x00, 0x66, 0x55, 0x00, 0x66, 0x66, 0x00, 0x55, 0x66, + 0x00, 0x44, 0x66, 0x00, 0x33, 0x66, 0x00, 0x22, 0x66, 0x00, 0x11, 0x66, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x66, 0x11, 0x00, 0x66, 0x22, 0x00, 0x66, + 0x44, 0x00, 0x66, 0x66, 0x00, 0x55, 0x66, 0x00, 0x33, 0x66, 0x00, 0x11, + 0x66, 0x00, 0x00, 0x66, 0x11, 0x00, 0x66, 0x22, 0x00, 0x66, 0x33, 0x00, + 0x66, 0x44, 0x00, 0x66, 0x55, 0x00, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, + 0x55, 0x66, 0x00, 0x44, 0x66, 0x00, 0x33, 0x66, 0x00, 0x22, 0x66, 0x00, + 0x11, 0x33, 0x00, 0x00, 0x33, 0x00, 0x00, 0x33, 0x11, 0x00, 0x33, 0x11, + 0x00, 0x33, 0x22, 0x00, 0x33, 0x22, 0x00, 0x33, 0x33, 0x00, 0x33, 0x33, + 0x00, 0x22, 0x33, 0x00, 0x11, 0x33, 0x00, 0x11, 0x33, 0x00, 0x00, 0x33, + 0x00, 0x00, 0x33, 0x00, 0x00, 0x33, 0x00, 0x00, 0x33, 0x11, 0x00, 0x33, + 0x22, 0x00, 0x33, 0x33, 0x00, 0x22, 0x33, 0x00, 0x11, 0x33, 0x00, 0x00, + 0x33, 0x00, 0x00, 0x33, 0x00, 0x00, 0x33, 0x11, 0x00, 0x33, 0x11, 0x00, + 0x33, 0x22, 0x00, 0x33, 0x22, 0x00, 0x33, 0x33, 0x00, 0x33, 0x33, 0x00, + 0x22, 0x33, 0x00, 0x22, 0x33, 0x00, 0x11, 0x33, 0x00, 0x11, 0x33, 0x00, + 0x00, 0x21, 0xf9, 0x04, 0x09, 0x01, 0x00, 0x7c, 0x00, 0x2c, 0x00, 0x00, + 0x00, 0x00, 0x78, 0x00, 0x1a, 0x00, 0x00, 0x08, 0xff, 0x00, 0xf9, 0x08, + 0x1c, 0x48, 0xb0, 0xa0, 0xc1, 0x83, 0x08, 0x13, 0x2a, 0x5c, 0xc8, 0xb0, + 0xa1, 0xc3, 0x87, 0x08, 0xd3, 0xa0, 0x21, 0x43, 0xe6, 0xcb, 0x17, 0x22, + 0x42, 0x80, 0x68, 0xdc, 0xc8, 0xb1, 0xa3, 0xc7, 0x8f, 0x20, 0x43, 0x8a, + 0x1c, 0x49, 0x52, 0xa4, 0x8f, 0x1d, 0x2e, 0x50, 0x70, 0x90, 0x20, 0x01, + 0x07, 0x96, 0x34, 0x0c, 0x25, 0xa2, 0x59, 0x43, 0x73, 0xcc, 0x17, 0x33, + 0x5d, 0xb4, 0x68, 0xe1, 0xc2, 0xb3, 0xa7, 0xcf, 0x9f, 0x40, 0x83, 0x0a, + 0x1d, 0x4a, 0xb4, 0xa8, 0x51, 0xa1, 0x51, 0x9e, 0xf8, 0x70, 0x71, 0x02, + 0xc4, 0x06, 0x96, 0x37, 0xb0, 0x28, 0x9c, 0xc8, 0xa6, 0x8f, 0x9f, 0x3c, + 0x6e, 0xc6, 0x68, 0x11, 0xf2, 0xc3, 0x87, 0xd7, 0xaf, 0x60, 0xc3, 0x8a, + 0x1d, 0x4b, 0xb6, 0xac, 0xd9, 0xb3, 0x68, 0xcd, 0xf6, 0xe0, 0x91, 0x23, + 0x85, 0x08, 0x0f, 0x1b, 0x34, 0x48, 0x70, 0x50, 0x43, 0xea, 0x1e, 0x83, + 0x13, 0xf1, 0xf8, 0xa1, 0xb3, 0xe6, 0x8b, 0x93, 0x20, 0x30, 0x3e, 0x08, + 0x1e, 0x4c, 0xb8, 0xb0, 0xe1, 0xc3, 0x88, 0x13, 0x2b, 0x5e, 0xcc, 0xb8, + 0xf1, 0x60, 0x10, 0x70, 0x33, 0x5c, 0x90, 0xc0, 0xa0, 0x2e, 0x5e, 0x32, + 0x74, 0xfc, 0xac, 0xd9, 0xb2, 0x64, 0x06, 0x8b, 0x11, 0x20, 0x3a, 0x88, + 0x1e, 0xdd, 0x81, 0x84, 0x8d, 0xd3, 0x36, 0x48, 0xab, 0x5e, 0xcd, 0xba, + 0xb5, 0xeb, 0xd7, 0xac, 0x4d, 0xa0, 0x36, 0x01, 0xbb, 0x36, 0x07, 0x0d, + 0x18, 0x2a, 0xb0, 0xac, 0x41, 0x86, 0xa0, 0xc4, 0x3c, 0x7e, 0xd0, 0x38, + 0x81, 0x41, 0x22, 0x34, 0x6b, 0x23, 0x6d, 0x18, 0x29, 0x57, 0x1e, 0xc8, + 0x0a, 0xe9, 0x2b, 0xcb, 0xa3, 0x47, 0x97, 0xa1, 0x3a, 0x49, 0xf4, 0x35, + 0xab, 0xa1, 0x4b, 0x5f, 0xde, 0x27, 0x89, 0x6a, 0x12, 0x55, 0xfa, 0x48, + 0xff, 0xef, 0x43, 0x7d, 0xb4, 0x78, 0xe5, 0xce, 0x47, 0x6b, 0x67, 0xd4, + 0x86, 0xf4, 0xed, 0x0a, 0x13, 0x24, 0x20, 0xb8, 0x71, 0x97, 0x4f, 0x1a, + 0x32, 0x68, 0x34, 0x3b, 0x79, 0x61, 0x7c, 0x35, 0x89, 0xe4, 0xdb, 0x29, + 0x67, 0xc4, 0x68, 0x81, 0x04, 0xc8, 0x9d, 0x6a, 0x32, 0x14, 0xb8, 0x5c, + 0x7b, 0xaa, 0x29, 0x68, 0x20, 0x23, 0xa9, 0x89, 0x76, 0x83, 0x83, 0xd2, + 0x05, 0x42, 0x5b, 0x07, 0x32, 0x4c, 0x47, 0x9a, 0x83, 0xde, 0xb9, 0x97, + 0x01, 0x05, 0x12, 0x34, 0x80, 0x80, 0x13, 0x02, 0x89, 0xf1, 0xc5, 0x1b, + 0x77, 0x78, 0x01, 0x43, 0x7f, 0xab, 0xad, 0xb1, 0xdc, 0x15, 0x37, 0x58, + 0x11, 0x5d, 0x15, 0x12, 0x3e, 0x88, 0x9e, 0x6a, 0x00, 0x46, 0xa7, 0xda, + 0x0d, 0xd7, 0xad, 0x91, 0xa3, 0x72, 0x34, 0x76, 0x60, 0x84, 0x8d, 0x8c, + 0x74, 0x28, 0xa3, 0x72, 0x7d, 0x90, 0xc6, 0xe3, 0x72, 0x17, 0x92, 0xb6, + 0xc1, 0x64, 0x10, 0x34, 0x40, 0x82, 0x40, 0x5b, 0x6c, 0x71, 0xc6, 0x19, + 0x4b, 0xa0, 0xe0, 0xda, 0x90, 0xca, 0x31, 0xd8, 0x81, 0x8b, 0x40, 0x8a, + 0xb6, 0x9e, 0x97, 0xae, 0x1d, 0x29, 0x9d, 0x6a, 0xeb, 0x25, 0x59, 0xe3, + 0x72, 0x37, 0x74, 0xb0, 0xa4, 0x72, 0x59, 0x50, 0x97, 0xe0, 0x8b, 0xa2, + 0x9d, 0xc7, 0x48, 0x7a, 0x62, 0x2e, 0xc8, 0x1a, 0x07, 0x93, 0x3d, 0x20, + 0x22, 0x4c, 0x38, 0x00, 0xc1, 0xc5, 0x16, 0x33, 0xb0, 0xa8, 0x5a, 0x16, + 0xcb, 0x35, 0x77, 0x03, 0x09, 0x32, 0x34, 0x59, 0x5a, 0x74, 0x1d, 0xba, + 0x66, 0xc3, 0x72, 0x55, 0xe8, 0xb8, 0xe1, 0x72, 0x78, 0x56, 0xca, 0x5c, + 0x69, 0x0e, 0x5e, 0x41, 0x9a, 0x15, 0x6b, 0x58, 0x61, 0x84, 0x9c, 0x1a, + 0x12, 0xb8, 0x5c, 0xa4, 0xaa, 0x65, 0x30, 0x81, 0x9f, 0x06, 0x48, 0x25, + 0x83, 0x0e, 0x43, 0x00, 0xff, 0xc1, 0xc2, 0x6b, 0x88, 0x6e, 0x97, 0x45, + 0x84, 0xa2, 0x71, 0xd9, 0x25, 0x4d, 0xbc, 0x66, 0x41, 0x1a, 0x09, 0x0a, + 0xf6, 0x41, 0x82, 0xa5, 0x6b, 0x2a, 0x97, 0x84, 0x0d, 0x31, 0x46, 0xd7, + 0xa6, 0xa6, 0x8c, 0x04, 0x42, 0xc2, 0x6b, 0x66, 0xda, 0xe8, 0xa8, 0x93, + 0x14, 0x38, 0xd0, 0x40, 0xab, 0x7c, 0x68, 0xc0, 0x82, 0x0e, 0x39, 0x88, + 0xf0, 0xda, 0x9b, 0xdb, 0x79, 0x2a, 0x5a, 0xad, 0x06, 0x8a, 0x3b, 0xee, + 0x72, 0xa9, 0x11, 0xdb, 0xc1, 0x7a, 0x06, 0x0e, 0xd8, 0x81, 0x9d, 0x41, + 0xba, 0x66, 0xe7, 0x83, 0x64, 0xaa, 0xb6, 0x41, 0x05, 0xd6, 0x62, 0x7b, + 0x01, 0x08, 0x29, 0xa4, 0x60, 0xe8, 0x6a, 0x36, 0x80, 0xb9, 0x1d, 0x6d, + 0xc3, 0xda, 0xd8, 0xa6, 0x68, 0xd6, 0xdd, 0xd8, 0x81, 0xba, 0x14, 0x46, + 0xd7, 0xc7, 0x15, 0x17, 0x4e, 0xba, 0x5c, 0x79, 0xad, 0x65, 0x48, 0x64, + 0x91, 0xae, 0xdd, 0xeb, 0xc0, 0x02, 0xd8, 0x52, 0xa0, 0x01, 0x08, 0x21, + 0x78, 0xc0, 0x9a, 0xa1, 0x26, 0x24, 0x41, 0xae, 0x72, 0xa9, 0xe9, 0x0a, + 0x21, 0x6a, 0xa8, 0x8d, 0x36, 0xa7, 0x72, 0x37, 0x9c, 0x56, 0x2a, 0xb8, + 0x55, 0x08, 0x1c, 0x88, 0xbb, 0x1d, 0x30, 0x1b, 0x88, 0x6a, 0x46, 0x1c, + 0x2c, 0x9a, 0x99, 0x7d, 0x54, 0x21, 0x74, 0x15, 0x27, 0x4f, 0x4b, 0x9a, + 0x06, 0x13, 0x6c, 0x4c, 0x80, 0x54, 0x11, 0x5c, 0xa0, 0x81, 0x6b, 0x26, + 0x08, 0x9d, 0xc5, 0x1a, 0x14, 0x47, 0xfb, 0x2c, 0xb9, 0xbe, 0xba, 0xf6, + 0x63, 0x80, 0x11, 0x8e, 0xd9, 0x81, 0x09, 0xd1, 0xed, 0x2c, 0x9a, 0xc0, + 0xd8, 0x8d, 0x26, 0x71, 0x20, 0x41, 0xda, 0x89, 0xe7, 0xba, 0x7a, 0xb6, + 0xc6, 0x41, 0x06, 0x12, 0x28, 0x40, 0xc0, 0xd2, 0x7c, 0xd4, 0x40, 0x81, + 0xd3, 0x1c, 0x70, 0xa0, 0x1a, 0x08, 0x34, 0x28, 0xff, 0x3b, 0x1a, 0xb9, + 0x9e, 0x16, 0x2c, 0x60, 0x99, 0x17, 0x47, 0xc8, 0xa1, 0x68, 0x14, 0x46, + 0x68, 0x73, 0x79, 0x13, 0xb2, 0xd9, 0x81, 0xc4, 0xca, 0x51, 0xdc, 0xc1, + 0xe1, 0xad, 0x3d, 0xe9, 0x80, 0xdc, 0xc3, 0xc0, 0x84, 0x45, 0x04, 0x77, + 0x67, 0x90, 0x37, 0x69, 0x20, 0x40, 0xce, 0x5e, 0xcf, 0xe4, 0x0a, 0x2b, + 0x24, 0x91, 0xbe, 0x8a, 0xfe, 0x60, 0x6a, 0xe0, 0x5e, 0x28, 0x30, 0x23, + 0xee, 0x32, 0xab, 0xdc, 0x1a, 0x14, 0x8a, 0x9b, 0xa6, 0x92, 0xd1, 0x19, + 0x2d, 0x1a, 0x07, 0xf7, 0x36, 0x90, 0x00, 0x01, 0x38, 0xc0, 0x94, 0x46, + 0x0d, 0x11, 0x48, 0x50, 0x01, 0x06, 0x9f, 0x8f, 0x06, 0xc3, 0xbc, 0xd2, + 0xb5, 0x51, 0xde, 0xc9, 0x01, 0x1a, 0x01, 0xec, 0xa9, 0xa4, 0x89, 0x9e, + 0x9a, 0xd7, 0xa2, 0xc9, 0x1e, 0xa4, 0x09, 0x0d, 0x47, 0x87, 0xa7, 0x83, + 0xf1, 0xb2, 0xdd, 0x65, 0xc6, 0x17, 0x3c, 0x90, 0x40, 0x00, 0x31, 0x4c, + 0x31, 0x10, 0x16, 0x31, 0x14, 0x7f, 0xfc, 0x06, 0x79, 0xe7, 0x3d, 0xc2, + 0xcb, 0x61, 0x57, 0xf1, 0xec, 0xa3, 0x44, 0x92, 0x40, 0x6e, 0xd9, 0x66, + 0x47, 0x97, 0x1a, 0xe5, 0x8f, 0xbb, 0xce, 0x68, 0x1a, 0xd7, 0x3c, 0x5c, + 0xb5, 0x6e, 0x34, 0x82, 0xc3, 0xd8, 0x6a, 0x78, 0x77, 0x81, 0x08, 0x28, + 0xe0, 0x00, 0x01, 0xa8, 0x41, 0x7d, 0x04, 0xc2, 0x3e, 0xf7, 0x61, 0x00, + 0x03, 0x19, 0x80, 0x5f, 0xfc, 0x68, 0x80, 0x04, 0x2a, 0x50, 0x01, 0x09, + 0x34, 0x88, 0x9f, 0xfc, 0x68, 0x40, 0xc2, 0x12, 0x9a, 0x90, 0x06, 0x30, + 0x18, 0x81, 0x09, 0x47, 0x20, 0x42, 0x0e, 0xa8, 0xb0, 0x84, 0x23, 0x78, + 0x21, 0x09, 0x59, 0x38, 0xc2, 0x12, 0xc2, 0xa0, 0x85, 0x34, 0xf0, 0x20, + 0x15, 0x8a, 0x70, 0x43, 0x11, 0x96, 0xc0, 0x84, 0x22, 0x94, 0x21, 0x0d, + 0xb7, 0x68, 0x18, 0xbf, 0x0d, 0x6c, 0x00, 0x03, 0x16, 0x78, 0xc0, 0x03, + 0xd1, 0x67, 0x05, 0x83, 0x54, 0xd0, 0x01, 0x2c, 0xa9, 0x40, 0x05, 0x2e, + 0x70, 0x81, 0x0c, 0x58, 0xf1, 0x8a, 0x58, 0xcc, 0xa2, 0x16, 0xb7, 0xc8, + 0xc5, 0x2e, 0x7a, 0xf1, 0x8b, 0x60, 0x0c, 0xa3, 0x15, 0x31, 0x70, 0x81, + 0x0a, 0x3c, 0xe0, 0x72, 0x07, 0x10, 0x40, 0x30, 0xd4, 0x77, 0x10, 0xf6, + 0x0d, 0x23, 0x18, 0x0d, 0x70, 0xc0, 0x03, 0x1e, 0x10, 0x81, 0x3a, 0xda, + 0xf1, 0x8e, 0x78, 0xcc, 0xa3, 0x1e, 0xf7, 0xc8, 0xc7, 0x3e, 0xfa, 0xf1, + 0x8f, 0x80, 0xb4, 0xe3, 0x03, 0x16, 0xa0, 0x80, 0x04, 0x1c, 0x20, 0x8d, + 0xc2, 0xc0, 0x81, 0x42, 0xd2, 0xe0, 0xc6, 0x60, 0x1c, 0xc0, 0x90, 0x09, + 0x50, 0x80, 0x24, 0x27, 0x49, 0xc9, 0x4a, 0x5a, 0xf2, 0x92, 0x98, 0xcc, + 0xa4, 0x26, 0x37, 0xc9, 0xc9, 0x4e, 0x4a, 0xd2, 0x90, 0x06, 0x20, 0x80, + 0x30, 0x6a, 0x50, 0x85, 0x86, 0x30, 0xb2, 0x7d, 0x02, 0x48, 0xa5, 0x00, + 0x02, 0x10, 0x80, 0x01, 0xb0, 0xf2, 0x95, 0xb0, 0x8c, 0xa5, 0x2c, 0x67, + 0x49, 0xcb, 0x5a, 0xda, 0xf2, 0x96, 0xb8, 0xbc, 0x25, 0x01, 0x58, 0x39, + 0x8c, 0x18, 0x58, 0x01, 0x26, 0x10, 0x09, 0xa6, 0x30, 0x87, 0x49, 0xcc, + 0x62, 0x3a, 0x24, 0x20, 0x00, 0x3b +}; +unsigned int search_len = 2010; + + +void writeLogo(const char *dir) +{ + QString fileName=(QString)dir+"/doxygen.gif"; + QFile f(fileName); + if (f.open(IO_WriteOnly)) + f.writeBlock((char *)logo_data,logo_len); + else + { + fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data()); + } + f.close(); +} + +void writeSearchButton(const char *dir) +{ + QString fileName=(QString)dir+"/search.gif"; + QFile f(fileName); + if (f.open(IO_WriteOnly)) + f.writeBlock((char *)search_data,search_len); + else + { + fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data()); + } + f.close(); +} + + diff --git a/src/logos.h b/src/logos.h new file mode 100644 index 0000000..1054fdb --- /dev/null +++ b/src/logos.h @@ -0,0 +1,23 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef LOGOS_H +#define LOGOS_H + +extern void writeLogo(const char *dir); +extern void writeSearchButton(const char *dir); + +#endif diff --git a/src/mangen.cpp b/src/mangen.cpp new file mode 100644 index 0000000..55bf8c7 --- /dev/null +++ b/src/mangen.cpp @@ -0,0 +1,341 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <qdir.h> +#include <stdlib.h> +#include "message.h" +#include "mangen.h" +#include "config.h" +#include "util.h" +#include "doxygen.h" + +ManGenerator::ManGenerator() : OutputGenerator() +{ + dir=manOutputDir+"/man3"; + firstCol=TRUE; + paragraph=FALSE; + col=0; + upperCase=FALSE; +} + +ManGenerator::~ManGenerator() +{ +} + +void ManGenerator::append(const OutputGenerator *g) +{ + QString r=g->getContents(); + if (upperCase) + t << r.upper(); + else + t << r; + if (r.length()>0) + firstCol = r.at(r.length()-1)=='\n'; + else + firstCol = ((ManGenerator *)g)->firstCol; + col+=((ManGenerator *)g)->col; + paragraph=FALSE; +} + +void ManGenerator::init() +{ + QDir d(manOutputDir); + if (!d.exists() && !d.mkdir(manOutputDir)) + { + err("Could not create output directory %s\n",manOutputDir.data()); + exit(1); + } + d.setPath(manOutputDir+"/man3"); + if (!d.exists() && !d.mkdir(manOutputDir+"/man3")) + { + err("Could not create output directory %s/man3\n",manOutputDir.data()); + exit(1); + } +} + +void ManGenerator::startFile(const char *name,const char *,bool) +{ + QString fileName=name; + if (fileName.left(6)=="class_") + { + fileName=fileName.right(fileName.length()-6); + } + int i; + if ((i=fileName.findRev('.'))!=-1) + { + fileName=fileName.left(i); + } + if (fileName.right(2)!=".3") fileName+=".3"; + startPlainFile(fileName); + firstCol=TRUE; +} + +void ManGenerator::endFile() +{ + endPlainFile(); +} + +void ManGenerator::writeDoxyAnchor(const char *, const char *,const char *) +{ +} + +void ManGenerator::endTitleHead(const char *name) +{ + t << ".TH " << name << " 3 \"" << dateToString(FALSE) << "\" \""; + if (projectName.isEmpty()) + t << "Doxygen"; + else + t << projectName; + t << "\" \\\" -*- nroff -*-" << endl; + t << ".ad l" << endl; + t << ".nh" << endl; + t << ".SH NAME" << endl; + t << name << " \\- "; + firstCol=FALSE; +} + +void ManGenerator::newParagraph() +{ + if (!paragraph) + { + if (!firstCol) t << endl; + t << ".PP" << endl; + firstCol=TRUE; + } + paragraph=TRUE; +} + +void ManGenerator::writeString(const char *text) +{ + docify(text); +} + +void ManGenerator::writeIndexItem(const char *,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) +{ + docify(name); +} + +void ManGenerator::writeHtmlLink(const char *,const char *text) +{ + docify(text); +} + +void ManGenerator::startGroupHeader() +{ + if (!firstCol) t << endl; + t << ".SH "; + upperCase=TRUE; + firstCol=FALSE; +} + +void ManGenerator::endGroupHeader() +{ + t << "\n.PP " << endl; + firstCol=TRUE; + paragraph=TRUE; + upperCase=FALSE; +} + +void ManGenerator::startMemberHeader() +{ + 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 << "\\\\"; col++; break; + case '\n': t << "\n"; col=0; 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; + while (*p) + { + c=*p++; + switch(c) + { + case '\t': t << &spaces[col&7]; col+=8-(col&7); break; + case '\n': t << "\n.br\n"; firstCol=TRUE; col=0; break; + case '\\': t << "\\\\"; col++; break; + default: t << c; 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; + default: t << c; break; + } + //printf("%c",c);fflush(stdout); + paragraph=FALSE; +} + +void ManGenerator::startDescList() +{ + if (!firstCol) + { t << endl << ".PP" << endl; + firstCol=TRUE; paragraph=TRUE; + col=0; + } + paragraph=FALSE; +} + +void ManGenerator::startTitle() +{ + if (!firstCol) t << endl; + t << ".SH "; + firstCol=FALSE; + paragraph=FALSE; +} + +void ManGenerator::writeListItem() +{ + if (!firstCol) t << endl; + t << ".TP" << endl; + firstCol=TRUE; + paragraph=FALSE; + col=0; +} + +void ManGenerator::startCodeFragment() +{ + newParagraph(); + t << ".nf"; + firstCol=FALSE; + 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 *) +{ + if (!firstCol) t << endl; + t << ".SS "; + firstCol=FALSE; + paragraph=FALSE; +} + +void ManGenerator::startSubsection() +{ + if (!firstCol) t << endl; + t << ".SS "; + firstCol=FALSE; + paragraph=FALSE; +} + +void ManGenerator::startSubsubsection() +{ + if (!firstCol) t << endl; + t << "\n.SS "; + firstCol=FALSE; + paragraph=FALSE; +} + +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() +{ + paragraph=TRUE; +} + +void ManGenerator::writeDescItem() +{ + if (!firstCol) t << endl; + if (!paragraph) t << ".in -1c" << endl; + t << ".in +1c" << endl; + firstCol=TRUE; + paragraph=FALSE; + col=0; +} + +void ManGenerator::endDescItem() +{ + t << "\" 1c" << endl; + firstCol=TRUE; +} diff --git a/src/mangen.h b/src/mangen.h new file mode 100644 index 0000000..d091782 --- /dev/null +++ b/src/mangen.h @@ -0,0 +1,171 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef MANGEN_H +#define MANGEN_H + +#include "outputgen.h" + +class QFile; + +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() { active=TRUE; } + void disable() { active=FALSE; } + void enableIf(OutputType o) { if (o==Man) active=TRUE; } + void disableIf(OutputType o) { if (o==Man) active=FALSE; } + void disableIfNot(OutputType o) { if (o!=Man) active=FALSE; } + bool isEnabled(OutputType o) { return (o==Man && active); } + OutputGenerator *get(OutputType o) { return (o==Man) ? this : 0; } + + static void init(); + void startFile(const char *name,const char *title,bool external); + void writeFooter(int,bool) {} + void endFile(); + void clearBuffer(); + + //void writeIndex(); + void startIndexSection(IndexSections) {} + void endIndexSection(IndexSections) {} + void startProjectNumber() {} + void endProjectNumber() {} + void writeStyleInfo(int) {} + void startTitleHead() {} + void endTitleHead(const char *); + void startTitle(); + void endTitle() {} + + void newParagraph(); + void writeString(const char *text); + void startIndexList() {} + void endIndexList() {} + void startItemList() {} + void endItemList() {} + void startEnumList() {} + void endEnumList() {} + void writeIndexItem(const char *ref,const char *file,const char *name); + 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 *f, + const char *anchor,const char *name); + void startTextLink(const char *,const char *) {} + void endTextLink() {} + void writeHtmlLink(const char *url,const char *text); + void startTypewriter() { t << "\\fC"; firstCol=FALSE; } + void endTypewriter() { t << "\\fR"; firstCol=FALSE; } + void startGroupHeader(); + void endGroupHeader(); + void startMemberHeader(); + void endMemberHeader(); + void writeListItem(); + void startMemberList() { t << "\n.in +1c"; firstCol=FALSE; } + void endMemberList() { t << "\n.in -1c"; firstCol=FALSE; } + void startMemberItem() { if (firstCol) t << ".in +1c"; + t << "\n.ti -1c\n.RI \""; + firstCol=FALSE; + } + void endMemberItem() { t << "\"\n.br"; } + void writeRuler() {} + void writeAnchor(const char *) {} + void startCodeFragment(); + void endCodeFragment(); + void writeBoldString(const char *text) + { t << "\\fB"; docify(text); t << "\\fR"; firstCol=FALSE; } + void startEmphasis() { t << "\\fI"; firstCol=FALSE; } + void endEmphasis() { t << "\\fR"; firstCol=FALSE; } + void startBold() { t << "\\fB"; firstCol=FALSE; } + void endBold() { t << "\\fR"; firstCol=FALSE; } + void startDescription() {} + void endDescription() {} + void startDescItem(); + void endDescItem(); + void lineBreak() { t << "\n.br" << endl; } + void writeChar(char c); + void startMemberDoc(const char *,const char *,const char *); + void endMemberDoc() {} + void writeDoxyAnchor(const char *clName,const char *anchor,const char *name); + 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 startSubscript() { t << "\\*<"; firstCol=FALSE; } + void endSubscript() { t << "\\*>"; firstCol=FALSE; } + void startSuperscript() { t << "\\*{"; firstCol=FALSE; } + void endSuperscript() { t << "\\*}"; firstCol=FALSE; } + void startTable(int) {} + void endTable() {} + void nextTableRow() {} + void endTableRow() {} + void nextTableColumn() {} + void endTableColumn() {} + void writeCopyright() { t << "(c)"; firstCol=FALSE; } + void writeQuote() { t << "\""; firstCol=FALSE; } + void writeUmlaut(char c) { t << c << "\\*'"; firstCol=FALSE; } + void writeAcute(char c) { t << c << "\\*`"; firstCol=FALSE; } + void writeGrave(char c) { t << c << "\\*:"; firstCol=FALSE; } + void writeCirc(char c) { t << c << "\\*^"; firstCol=FALSE; } + void writeTilde(char c) { t << c << "\\*~"; firstCol=FALSE; } + void startMemberDescription() { t << "\n.RI \"\\fI"; firstCol=FALSE; } + void endMemberDescription() { t << "\\fR\""; firstCol=FALSE; } + void startDescList(); + void endDescTitle(); + void writeDescItem(); + void endDescList() {} + void writeSection(const char *,const char *,bool) {} + void writeSectionRef(const char *,const char *,const char *) {} + void writeSectionRefItem(const char *,const char *,const char *) {} + void addToIndex(const char *,const char *) {} + void startIndent() {} + void endIndent() {} + void writeSynopsis(); + //void generateExternalIndex() {} + void startClassDiagram() {} + void endClassDiagram(ClassDiagram &,const char *,const char *) {} + void startColorFont(uchar,uchar,uchar) {} + void endColorFont() {} + void writePageRef(const char *,const char *) {} + void startQuickIndexItem(const char *,const char *) {} + void endQuickIndexItem() {} + void writeFormula(const char *,const char *) {} + + private: + bool firstCol; + bool paragraph; + int col; + bool upperCase; + + ManGenerator(const ManGenerator &g); + ManGenerator &operator=(const ManGenerator &g); +}; + +#endif diff --git a/src/memberdef.cpp b/src/memberdef.cpp new file mode 100644 index 0000000..f96a2d6 --- /dev/null +++ b/src/memberdef.cpp @@ -0,0 +1,180 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <stdio.h> +#include <qregexp.h> +#include "memberdef.h" +#include "membername.h" +#include "doxygen.h" +#include "util.h" + +/*! Creates a new member definition. + * Members can be function/variables/enums/etc. inside a class or inside a + * file. + * + * \param t A string representing the type of the member. + * \param n A string representing the name of the member. + * \param a A string representing the arguments of the member. + * \param p The type of protection of the member, possible values are: + * \c Public, \c Protected, \c Private. + * \param v The `virtualness' of the member, possible values are: + * \c Normal, \c Virtual, \c Pure. + * \param s A boolean that is true if the member is static. + * \param r A boolean that is true if the member is only related. + * \param mt The kind of member. See #MemberDef::MemberType for a list of + * all types. + */ + +MemberDef::MemberDef(const char *t,const char *na,const char *a,const char *e, + Protection p,Specifier v,bool s,bool r,MemberType mt, + const ArgumentList *tal,const ArgumentList *al + ) : Definition(substituteClassNames(na)) +{ + //printf("++++++ MemberDef(%s,%s,%s) ++++++ \n",t,na,a); + classDef=0; + fileDef=0; + fileDec=0; + redefines=0; + redefinedBy=0; + nspace=0; + memDef=0; + memDec=0; + exampleList=0; + exampleDict=0; + enumFields=0; + enumScope=0; + enumDeclList=0; + type=substituteClassNames(t); + args=substituteClassNames(a); + if (type.isNull()) decl=name()+args; else decl=type+" "+name()+args; + declLine=0; + defLine=0; + virt=v; + prot=p; + related=r; + stat=s; + mtype=mt; + exception=e; + eUsed=FALSE; + proto=FALSE; + docEnumValues=FALSE; + // copy function template arguments (if any) + if (tal) + { + tArgList = new ArgumentList; + tArgList->setAutoDelete(TRUE); + ArgumentListIterator ali(*tal); + Argument *a; + for (;(a=ali.current());++ali) + { + tArgList->append(new Argument(*a)); + } + } + else + { + tArgList=0; + } + // copy function arguments (if any) + if (al) + { + argList = new ArgumentList; + argList->setAutoDelete(TRUE); + ArgumentListIterator ali(*al); + Argument *a; + for (;(a=ali.current());++ali) + { + argList->append(new Argument(*a)); + } + argList->constSpecifier = al->constSpecifier; + argList->volatileSpecifier = al->volatileSpecifier; + argList->pureSpecifier = al->pureSpecifier; + } + else + { + argList=0; + } + +} + +MemberDef::~MemberDef() +{ + delete redefinedBy; + delete exampleList; + delete exampleDict; + delete enumFields; + delete argList; + delete tArgList; +} + +void MemberDef::insertReimplementedBy(MemberDef *md) +{ + if (redefinedBy==0) redefinedBy = new MemberList; + redefinedBy->inSort(md); +} + +void MemberDef::insertEnumField(MemberDef *md) +{ + if (enumFields==0) enumFields=new MemberList; + 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 (exampleDict==0) exampleDict = new ExampleDict; + if (exampleList==0) exampleList = new ExampleList; + if (exampleDict->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; + exampleDict->insert(nameStr,e); + exampleList->inSort(e); + return TRUE; + } + return FALSE; +} + +bool MemberDef::hasExamples() +{ + if (exampleList==0) + return FALSE; + else + return exampleList->count()>0; +} + + +void MemberDef::writeExample(OutputList &ol) +{ + Example *e=exampleList->first(); + while (e) + { + ol.writeObjectLink(0,e->file,e->anchor,e->name); + e=exampleList->next(); + if (e) + { + if (exampleList->at()==(int)exampleList->count()-1) + ol.writeString(" and "); + else + ol.writeString(", "); + } + } + ol.writeString("."); +} + diff --git a/src/memberdef.h b/src/memberdef.h new file mode 100644 index 0000000..fba76f8 --- /dev/null +++ b/src/memberdef.h @@ -0,0 +1,186 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef MEMBERDEF_H +#define MEMBERDEF_H + +#include <qstring.h> +#include <qlist.h> +#include <qdict.h> + +#include "entry.h" +#include "example.h" +#include "config.h" +#include "outputlist.h" +#include "definition.h" +#include "config.h" + +class FileDef; +class MemberList; +class NamespaceDef; + +class MemberDef : public Definition +{ + public: + + enum MemberType { + Define, + Function, + Variable, + Typedef, + Enumeration, + EnumValue, + Prototype, + Signal, + Slot, + Friend + }; + + MemberDef(const char *type,const char *name,const char *args, + const char *excp,Protection prot,Specifier virt,bool stat, + bool related,MemberType t,const ArgumentList *tal, + const ArgumentList *al); + ~MemberDef(); + + const char *declaration() const { return decl; } + const char *definition() const { return def; } + const char *typeString() const { return type; } + const char *argsString() const { return args; } + const char *excpString() const { return exception; } + const char *anchor() const { return ref; } + ClassDef *memberClass() { return classDef; } + Protection protection() const { return prot; } + Specifier virtualness() const { return virt; } + MemberType memberType() const { return mtype; } + void setMemberType(MemberType t) { mtype=t; } + void setDefinition(const char *d) { def=d; } + void setDefFile(const char *f) { defFile=f; } + void setDefLine(int l) { defLine=l; } + void setFileDef(FileDef *fd) { fileDef=fd; } + void setFileDec(FileDef *fd) { fileDec=fd; } + void setAnchor(const char *a) { ref=a; } + FileDef *getFileDef() { return fileDef; } + FileDef *getFileDec() { return fileDec; } + void setMemberClass(ClassDef *cd) { classDef=cd; } + bool isRelated() const { return related; } + bool isStatic() const { return stat; } + bool detailsAreVisible() const + { return !documentation().isEmpty() || + (mtype==Enumeration && docEnumValues) || + (mtype==EnumValue && !briefDescription().isEmpty()) || + (!briefDescription().isEmpty() && + !briefMemDescFlag && repeatBriefFlag); + } + + // relation to other members + void setReimplements(MemberDef *md) { redefines=md; } + void insertReimplementedBy(MemberDef *md); + MemberDef *reimplements() { return redefines; } + MemberList *reimplementedBy() { return redefinedBy; } + + // enumeration specific members + void insertEnumField(MemberDef *md); + void setEnumScope(MemberDef *md) { enumScope=md; } + MemberDef *getEnumScope() const { return enumScope; } + void setEnumDecl(OutputList &ed) { enumDeclList=new OutputList(&ed); } + void setEnumUsed() { eUsed=TRUE; } + bool enumUsed() const { return eUsed; } + OutputList *enumDecl() const { return enumDeclList; } + MemberList *enumFieldList() { return enumFields; } + void setDocumentedEnumValues(bool value) { docEnumValues=value; } + bool hasDocumentedEnumValues() const { return docEnumValues; } + + // example related members + bool addExample(const char *anchor,const char *name,const char *file); + void writeExample(OutputList &ol); + bool hasExamples(); + + // prototype related members + const char *getDefFile() { return defFile; } + int getDefLine() { return defLine; } + void setDecFile(const char *f) { declFile=f; } + void setDecLine(int l) { defLine=l; } + + // convenience members + bool isSignal() const { return mtype==Signal; } + bool isSlot() const { return mtype==Slot; } + bool isVariable() const { return mtype==Variable; } + bool isEnumerate() const { return mtype==Enumeration; } + bool isEnumValue() const { return mtype==EnumValue; } + bool isTypedef() const { return mtype==Typedef; } + bool isFunction() const { return mtype==Function; } + bool isDefine() const { return mtype==Define; } + bool isFriend() const { return mtype==Friend; } + + // prototype related members + void setPrototype(bool p) { proto=p; } + bool isPrototype() const { return proto; } + + // tag file related members + void setReference(const char *r) { external=r; } + bool isReference() { return !external.isNull(); } + + // argument related members + ArgumentList *argumentList() const { return argList; } + ArgumentList *templateArguments() const { return tArgList; } + + // namespace related members + NamespaceDef *getNamespace() { return nspace; } + void setNamespace(NamespaceDef *nd) { nspace=nd; } + + private: + ClassDef *classDef; // member of or related to + FileDef *fileDef; // member of file definition + FileDef *fileDec; // member of file declaration + MemberDef *redefines; // the member that is redefined by this one + MemberDef *enumScope; // the enclosing scope, if this is an enum field + MemberList *redefinedBy; // the list of members that redefine this one + MemberDef *memDef; // member definition for this declaration + MemberDef *memDec; // member declaration for this definition + ExampleList *exampleList; // a list of all examples using this member + ExampleDict *exampleDict; // a dictionary of all examples for quick access + MemberList *enumFields; // enumeration fields + OutputList *enumDeclList; // stored piece of documentation for enumeration. + NamespaceDef *nspace; // the namespace this member is in. + QString type; // return type + QString args; // function arguments/variable array specifiers + QString exception; // exceptions that can be thrown + QString decl; // member declaration in class + QString declFile; // file where the declaration was found + int declLine; // line where the declaration was found + QString def; // member definition in code (fully qualified name) + QString defFile; // file where the definition was found + int defLine; // line where the definition was found + QString ref; // HTML anchor name + Specifier virt; // normal/virtual/pure virtual + Protection prot; // protection type [Public/Protected/Private] + bool related; // is this a member that is only related to a class + QString external; // anchor of a member if extracted from a tag file + bool stat; // is it a static function? + MemberType mtype; // returns the kind of member + bool eUsed; // is the enumerate already placed in a list + bool proto; // is it a prototype; + bool docEnumValues; // is an enum with documented enum values. + ArgumentList *argList; // argument list of this member + ArgumentList *tArgList; // template argument list of function template + + // disable copying of member defs + MemberDef(const MemberDef &); + MemberDef &operator=(const MemberDef &); +}; + + +#endif diff --git a/src/memberlist.cpp b/src/memberlist.cpp new file mode 100644 index 0000000..4d7cc73 --- /dev/null +++ b/src/memberlist.cpp @@ -0,0 +1,148 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include "memberlist.h" +#include "classdef.h" +#include "message.h" +#include <qregexp.h> + +MemberList::MemberList() : QList<MemberDef>() +{ +} + +MemberList::~MemberList() +{ +} + +int MemberList::compareItems(GCI item1, GCI item2) +{ + MemberDef *c1=(MemberDef *)item1; + MemberDef *c2=(MemberDef *)item2; + return strcmp(c1->name(),c2->name()); +} + +void MemberList::countDecMembers() +{ + varCnt=funcCnt=enumCnt=enumValCnt=typeCnt=protoCnt=defCnt=friendCnt=0; + MemberDef *md=first(); + while (md) + { + if ((!hideMemberFlag || md->hasDocumentation()) && + (!hideMemberFlag || !md->documentation().isEmpty() || + briefMemDescFlag || repeatBriefFlag + ) || extractAllFlag + ) + { + switch(md->memberType()) + { + case MemberDef::Variable: varCnt++; break; + case MemberDef::Function: // fall through + case MemberDef::Signal: // fall through + case MemberDef::Slot: funcCnt++; break; + case MemberDef::Enumeration: enumCnt++; break; + case MemberDef::EnumValue: enumValCnt++; break; + case MemberDef::Typedef: typeCnt++; break; + case MemberDef::Prototype: protoCnt++; break; + case MemberDef::Define: if (extractAllFlag || md->argsString() || md->hasDocumentation() ) + defCnt++; + break; + case MemberDef::Friend: friendCnt++; break; + default: + err("Error: Unknown member type found!"); + } + } + md=next(); + } +} + +void MemberList::countDocMembers() +{ + varCnt=funcCnt=enumCnt=enumValCnt=typeCnt=protoCnt=defCnt=friendCnt; + MemberDef *md=first(); + while (md) + { + //if (extractAllFlag || /*md->hasDocumentation()*/ + // !md->documentation().isEmpty() || + // (!md->briefDescription().isEmpty() && + // !briefMemDescFlag && + // repeatBriefFlag + // ) + // ) + if (extractAllFlag || md->detailsAreVisible()) + { + QRegExp r("@[0-9]+"); + int dummy; + switch(md->memberType()) + { + case MemberDef::Variable: + varCnt++; + break; + case MemberDef::Function: + case MemberDef::Signal: + case MemberDef::Slot: + funcCnt++; + break; + case MemberDef::Enumeration: + if (r.match(md->name(),0,&dummy)==-1) + { + enumCnt++; + } + break; + case MemberDef::EnumValue: + { + MemberDef *scope; + scope=md->getEnumScope(); + if (scope && r.match(scope->name(),0,&dummy)!=-1) + enumValCnt++; + } + break; + case MemberDef::Typedef: + typeCnt++; + break; + case MemberDef::Prototype: + protoCnt++; + break; + case MemberDef::Define: + defCnt++; + break; + case MemberDef::Friend: + friendCnt++; + } + } + md=next(); + } +} + +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) +{ +} + diff --git a/src/memberlist.h b/src/memberlist.h new file mode 100644 index 0000000..c26f055 --- /dev/null +++ b/src/memberlist.h @@ -0,0 +1,56 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef MEMBERLIST_H +#define MEMBERLIST_H + +#include <qlist.h> +#include "memberdef.h" + +class MemberList : public QList<MemberDef> +{ + public: + MemberList(); + ~MemberList(); + bool insert(uint index,const MemberDef *md); + void inSort(const MemberDef *md); + void append(const MemberDef *md); + int compareItems(GCI item1,GCI item2); + int varCount() const { return varCnt; } + int funcCount() const { return funcCnt; } + int enumCount() const { return enumCnt; } + int enumValueCount() const { return enumValCnt; } + int typedefCount() const { return typeCnt; } + int protoCount() const { return protoCnt; } + int defineCount() const { return defCnt; } + int friendCount() const { return friendCnt; } + void countDecMembers(); + void countDocMembers(); + int totalCount() const + { return varCnt+funcCnt+enumCnt+enumValCnt+typeCnt+ + protoCnt+defCnt+friendCnt; } + + private: + int varCnt,funcCnt,enumCnt,enumValCnt,typeCnt,protoCnt,defCnt,friendCnt; +}; + +class MemberListIterator : public QListIterator<MemberDef> +{ + public: + MemberListIterator(const QList<MemberDef> &list); +}; + +#endif diff --git a/src/membername.cpp b/src/membername.cpp new file mode 100644 index 0000000..2605f86 --- /dev/null +++ b/src/membername.cpp @@ -0,0 +1,96 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include "membername.h" +#include "classdef.h" +#include "util.h" +#include "filedef.h" + +MemberName::MemberName(const char *n) : QList<MemberDef>() +{ + name=n; +} + +MemberName::~MemberName() +{ +} + +int MemberName::compareItems(GCI item1, GCI item2) +{ + MemberDef *m1=(MemberDef *)item1; + MemberDef *m2=(MemberDef *)item2; + ClassDef *c1=m1->memberClass(); + ClassDef *c2=m2->memberClass(); + FileDef *f1=m1->getFileDef(); + FileDef *f2=m2->getFileDef(); + if (c1 && c2) + return stricmp(c1->name(),c2->name()); + else if (f1 && f2) + return stricmp(f1->name(),f2->name()); + else + return 0; +} + +MemberNameInfo::MemberNameInfo(const char *n) : QList<MemberInfo>() +{ + name=n; + setAutoDelete(TRUE); +} + +MemberNameInfo::~MemberNameInfo() +{ +} + +int MemberNameInfo::compareItems(GCI item1, GCI item2) +{ + MemberInfo *m1=(MemberInfo *)item1; + MemberInfo *m2=(MemberInfo *)item2; + ClassDef *c1=m1->memberDef->memberClass(); + ClassDef *c2=m2->memberDef->memberClass(); + FileDef *f1=m1->memberDef->getFileDef(); + FileDef *f2=m2->memberDef->getFileDef(); + if (c1 && c2) + return stricmp(c1->name(),c2->name()); + else if (f1 && f2) + return stricmp(f1->name(),f2->name()); + else + return 0; +} +MemberNameIterator::MemberNameIterator(const MemberName &mnlist) : + QListIterator<MemberDef>(mnlist) +{ +} + +MemberNameList::MemberNameList() : QList<MemberName>() +{ +} + +MemberNameList::~MemberNameList() +{ +} + +int MemberNameList::compareItems(GCI item1, GCI item2) +{ + MemberName *n1=(MemberName *)item1; + MemberName *n2=(MemberName *)item2; + return stricmp(n1->memberName(),n2->memberName()); +} + +MemberNameListIterator::MemberNameListIterator(const MemberNameList &mnlist) : + QListIterator<MemberName>(mnlist) +{ +} + diff --git a/src/membername.h b/src/membername.h new file mode 100644 index 0000000..4754fa7 --- /dev/null +++ b/src/membername.h @@ -0,0 +1,111 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef MEMBERNAME_H +#define MEMBERNAME_H + +#include <qlist.h> +#include "memberdef.h" + +class MemberName : public QList<MemberDef> +{ + public: + MemberName(const char *name); + ~MemberName(); + const char *memberName() const { return name; } + + int compareItems(GCI item1,GCI item2); + private: + QString name; +}; + +class MemberNameIterator : public QListIterator<MemberDef> +{ + public: + MemberNameIterator( const MemberName &list); +}; + +class MemberNameList : public QList<MemberName> +{ + public: + MemberNameList(); + ~MemberNameList(); + + int compareItems(GCI item1,GCI item2); +}; + +class MemberNameListIterator : public QListIterator<MemberName> +{ + public: + MemberNameListIterator( const MemberNameList &list ); +}; + +typedef QDict<MemberName> MemberNameDict; + +struct MemberInfo +{ + MemberInfo(MemberDef *md,Protection p,Specifier v) : + memberDef(md), prot(p), virt(v) {} + MemberDef *memberDef; + Protection prot; + Specifier virt; + QString scopePath; + QString ambiguityResolutionScope; +}; + +class MemberNameInfo : public QList<MemberInfo> +{ + public: + MemberNameInfo(const char *name); + ~MemberNameInfo(); + const char *memberName() const { return name; } + int compareItems(GCI item1,GCI item2); + private: + QString name; +}; + +class MemberNameInfoIterator : public QListIterator<MemberInfo> +{ + public: + MemberNameInfoIterator(const MemberNameInfo &mnii) + : QListIterator<MemberInfo>(mnii) {} +}; + +class MemberNameInfoList : public QList<MemberNameInfo> +{ + public: + int compareItems(GCI item1,GCI item2) + { return stricmp( + ((MemberNameInfo *)item1)->memberName(), + ((MemberNameInfo *)item2)->memberName() + ); + } +}; + +class MemberNameInfoDict : public QDict<MemberNameInfo> +{ + public: + MemberNameInfoDict(int size) : QDict<MemberNameInfo>(size) {} +}; + +class MemberNameInfoListIterator : public QListIterator<MemberNameInfo> +{ + public: + MemberNameInfoListIterator(const MemberNameInfoList &mil) : + QListIterator<MemberNameInfo>(mil) {} +}; + +#endif diff --git a/src/message.cpp b/src/message.cpp new file mode 100644 index 0000000..9f98107 --- /dev/null +++ b/src/message.cpp @@ -0,0 +1,49 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <stdarg.h> +#include <stdio.h> +#include "config.h" + +void msg(const char *fmt, ...) +{ + if (!quietFlag) + { + va_list args; + va_start(args, fmt); + vfprintf(stdout, fmt, args); + va_end(args); + } +} + +void warn(const char *fmt, ...) +{ + if (warningFlag) + { + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + } +} + +void err(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); +} diff --git a/src/message.h b/src/message.h new file mode 100644 index 0000000..f7586ca --- /dev/null +++ b/src/message.h @@ -0,0 +1,24 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef MESSAGE_H +#define MESSAGE_H + +extern void msg(const char *fmt, ...); +extern void warn(const char *fmt, ...); +extern void err(const char *fmt, ...); + +#endif diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp new file mode 100644 index 0000000..9d055b2 --- /dev/null +++ b/src/namespacedef.cpp @@ -0,0 +1,220 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include "namespacedef.h" +#include "outputlist.h" +#include "util.h" +#include "scanner.h" +#include "language.h" +#include "classdef.h" +#include "classlist.h" +#include "memberlist.h" + +NamespaceDef::NamespaceDef(const char *name) : Definition(name) +{ + fileName="namespace_"+nameToFile(name); + classList = new ClassList; + memList = new MemberList; +} + +NamespaceDef::~NamespaceDef() +{ + delete classList; + delete memList; +} + +void NamespaceDef::insertUsedFile(const char *f) +{ + if (files.find(f)==-1) files.append(f); +} + +void NamespaceDef::insertClass(ClassDef *cd) +{ + classList->append(cd); +} + +void NamespaceDef::insertMember(MemberDef *md) +{ + memList->append(md); +} + +void NamespaceDef::computeAnchors() +{ + setAnchors('a',memList); +} + +void NamespaceDef::writeDocumentation(OutputList &ol) +{ + QString pageTitle=name()+" Namespace Reference"; + startFile(ol,fileName,pageTitle); + startTitle(ol); + ol.docify(pageTitle); + endTitle(ol,name()); + + OutputList briefOutput(&ol); + if (briefDescription()) + { + parseDoc(briefOutput,0,0,briefDescription()); + ol+=briefOutput; + ol.writeString(" \n"); + ol.disableAllBut(OutputGenerator::Html); + ol.startTextLink(0,"details"); + parseDoc(ol,0,0,theTranslator->trMore()); + ol.endTextLink(); + ol.enableAll(); + } + ol.disable(OutputGenerator::Man); + ol.newParagraph(); + ol.enable(OutputGenerator::Man); + ol.writeSynopsis(); + + if (classList->count()>0) + { + ClassDef *cd=classList->first(); + bool found=FALSE; + while (cd) + { + if (cd->isVisibleExt()) + { + if (!found) + { + ol.startMemberHeader(); + parseDoc(ol,0,0,theTranslator->trCompounds()); + ol.endMemberHeader(); + ol.startMemberList(); + found=TRUE; + } + QString clName=cd->name().copy(); + if (clName.left(name().length()+2)==name()+"::") + { + clName = clName.right(clName.length()-name().length()-2); + } + + ol.startMemberItem(); + switch (cd->compoundType()) + { + case ClassDef::Class: ol.writeString("class"); break; + case ClassDef::Struct: ol.writeString("struct"); break; + case ClassDef::Union: ol.writeString("union"); break; + } + ol.writeString(" "); + if (cd->hasDocumentation()) + { + ol.writeObjectLink(cd->getReference(), + cd->classFile(), + 0, + clName + ); + } + else + { + ol.startBold(); + ol.docify(clName); + ol.endBold(); + } + ol.endMemberItem(); + } + cd=classList->next(); + } + if (found) ol.endMemberList(); + } + + writeMemberDecs(ol,0,this,0,0,0,memList); + + if (!briefDescription().isEmpty() || !documentation().isEmpty()) + { + ol.writeRuler(); + ol.writeAnchor("details"); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trDetailedDescription()); + ol.endGroupHeader(); + if (!briefDescription().isEmpty()) + { + ol+=briefOutput; + ol.newParagraph(); + } + if (!documentation().isEmpty()) + { + parseDoc(ol,0,0,documentation()+"\n"); + ol.newParagraph(); + } + } + + memList->countDocMembers(); + + if ( memList->protoCount()>0 ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trFunctionPrototypeDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,memList,name(),MemberDef::Prototype); + } + + if ( memList->typedefCount()>0 ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trTypedefDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,memList,name(),MemberDef::Typedef); + } + + if ( memList->enumCount()>0 ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trEnumerationTypeDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,memList,name(),MemberDef::Enumeration); + } + + if ( memList->enumValueCount()>0 ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trEnumerationValueDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,memList,name(),MemberDef::EnumValue); + } + + if ( memList->funcCount()>0 ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trFunctionDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,memList,name(),MemberDef::Function); + } + + if ( memList->varCount()>0 ) + { + ol.writeRuler(); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trVariableDocumentation()); + ol.endGroupHeader(); + writeMemberDocs(ol,memList,name(),MemberDef::Variable); + } + + // write Author section (Man only) + ol.disableAllBut(OutputGenerator::Man); + ol.startGroupHeader(); + parseDoc(ol,0,0,theTranslator->trAuthor()); + ol.endGroupHeader(); + parseDoc(ol,0,0,theTranslator->trGeneratedAutomatically(projectName)); + ol.enableAll(); + endFile(ol); +} diff --git a/src/namespacedef.h b/src/namespacedef.h new file mode 100644 index 0000000..9da6b2c --- /dev/null +++ b/src/namespacedef.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef NAMESPACEDEF_H +#define NAMESPACEDEF_H + +#include <qstring.h> +#include <qstrlist.h> +#include <qdict.h> +#include "definition.h" + +class ClassDef; +class OutputList; +class ClassList; +class MemberList; +class MemberDef; + +class NamespaceDef : public Definition +{ + public: + NamespaceDef(const char *name); + ~NamespaceDef(); + QString namespaceFile() const { return fileName; } + void insertUsedFile(const char *fname); + void writeDocumentation(OutputList &ol); + void insertClass(ClassDef *cd); + void insertMember(MemberDef *md); + void computeAnchors(); + + private: + QString fileName; + QStrList files; + ClassList *classList; + MemberList *memList; +}; + +class NamespaceList : public QList<NamespaceDef> +{ + public: + int compareItems(GCI item1,GCI item2) + { + return strcmp(((NamespaceDef *)item1)->name(), + ((NamespaceDef *)item2)->name() + ); + } +}; + +class NamespaceListIterator : public QListIterator<NamespaceDef> +{ + public: + NamespaceListIterator(const NamespaceList &l) : + QListIterator<NamespaceDef>(l) {} +}; + +typedef QDict<NamespaceDef> NamespaceDict; + +#endif diff --git a/src/outputgen.cpp b/src/outputgen.cpp new file mode 100644 index 0000000..ca07302 --- /dev/null +++ b/src/outputgen.cpp @@ -0,0 +1,77 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <stdlib.h> +#include "outputgen.h" +#include <qstring.h> +#include "message.h" + +OutputGenerator::OutputGenerator() +{ + //printf("OutputGenerator::OutputGenerator()\n"); + file=0; + b.setBuffer(a); + b.open( IO_WriteOnly ); + t.setDevice(&b); + active=TRUE; +} + +OutputGenerator::~OutputGenerator() +{ + //printf("OutputGenerator::~OutputGenerator()\n"); + delete file; +} + +void OutputGenerator::startPlainFile(const char *name) +{ + //printf("startPlainFile(%s)\n",name); + QString 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); + } + fs.setDevice(file); +} + +void OutputGenerator::endPlainFile() +{ + //printf("endPlainFile(%s)\n",file->name()); + fs.writeRawBytes(a.data(),a.size()) ; // write string buffer to file + delete file; + file=0; + b.close(); + a.resize(0); + b.setBuffer(a); + b.open(IO_WriteOnly); + t.setDevice(&b); +} + +QString OutputGenerator::getContents() const +{ + QString s; + s.resize(a.size()+1); + memcpy(s.data(),a.data(),a.size()); + s.at(a.size())='\0'; + return s; +} + diff --git a/src/outputgen.h b/src/outputgen.h new file mode 100644 index 0000000..457dd80 --- /dev/null +++ b/src/outputgen.h @@ -0,0 +1,182 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef OUTPUTGEN_H +#define OUTPUTGEN_H + +#include <qstring.h> +#include <qtstream.h> +#include <qbuffer.h> +#include <qfile.h> +#include "index.h" + +class ClassDiagram; + +class OutputGenerator +{ + public: + enum OutputType { Html, Latex, Man }; + + OutputGenerator(); + virtual ~OutputGenerator(); + + virtual OutputGenerator *copy() = 0; + //virtual OutputGenerator *clone() = 0; + virtual void append(const OutputGenerator *) = 0; + 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; + + virtual void startFile(const char *name,const char *title,bool ext) = 0; + virtual void writeFooter(int,bool) = 0; + virtual void endFile() = 0; + //virtual void writeIndex() = 0; + virtual void startIndexSection(IndexSections) = 0; + virtual void endIndexSection(IndexSections) = 0; + virtual void startProjectNumber() = 0; + virtual void endProjectNumber() = 0; + virtual void writeStyleInfo(int part) = 0; + virtual void startTitleHead() = 0; + virtual void endTitleHead(const char *name) = 0; + virtual void startTitle() = 0; + virtual void endTitle() = 0; + virtual void newParagraph() = 0; + virtual void writeString(const char *text) = 0; + virtual void startIndexList() = 0; + virtual void endIndexList() = 0; + virtual void startItemList() = 0; + virtual void endItemList() = 0; + virtual void startEnumList() = 0; + virtual void endEnumList() = 0; + virtual void startBold() = 0; + virtual void endBold() = 0; + virtual void writeIndexItem(const char *ref,const char *file, + const char *text) = 0; + virtual void docify(const char *s) = 0; + virtual void codify(const char *s) = 0; + virtual void writeObjectLink(const char *ref,const char *file, + const char *anchor, const char *text) = 0; + virtual void writeCodeLink(const char *ref,const char *file, + const char *anchor,const char *text) = 0; + virtual void startTextLink(const char *file,const char *anchor) = 0; + virtual void endTextLink() = 0; + virtual void writeHtmlLink(const char *url,const char *text) = 0; + virtual void startTypewriter() = 0; + virtual void endTypewriter() = 0; + virtual void startGroupHeader() = 0; + virtual void endGroupHeader() = 0; + virtual void writeListItem() = 0; + + virtual void startMemberHeader() = 0; + virtual void endMemberHeader() = 0; + virtual void startMemberList() = 0; + virtual void endMemberList() = 0; + virtual void startMemberItem() = 0; + virtual void endMemberItem() = 0; + + virtual void writeRuler() = 0; + virtual void writeAnchor(const char *name) = 0; + virtual void startCodeFragment() = 0; + virtual void endCodeFragment() = 0; + virtual void writeBoldString(const char *text) = 0; + virtual void startEmphasis() = 0; + virtual void endEmphasis() = 0; + virtual void writeChar(char c) = 0; + virtual void startMemberDoc(const char *,const char *,const char *) = 0; + virtual void endMemberDoc() = 0; + virtual void writeDoxyAnchor(const char *clName,const char *anchor,const char *name) = 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 startDescription() = 0; + virtual void endDescription() = 0; + virtual void startDescItem() = 0; + virtual void endDescItem() = 0; + virtual void startSubsection() = 0; + virtual void endSubsection() = 0; + virtual void startSubsubsection() = 0; + virtual void endSubsubsection() = 0; + virtual void startCenter() = 0; + virtual void endCenter() = 0; + virtual void startSmall() = 0; + virtual void endSmall() = 0; + virtual void startSubscript() = 0; + virtual void endSubscript() = 0; + virtual void startSuperscript() = 0; + virtual void endSuperscript() = 0; + virtual void startTable(int cols) = 0; + virtual void endTable() = 0; + virtual void nextTableRow() = 0; + virtual void endTableRow() = 0; + virtual void nextTableColumn() = 0; + virtual void endTableColumn() = 0; + virtual void writeQuote() = 0; + virtual void writeCopyright() = 0; + virtual void writeUmlaut(char) = 0; + virtual void writeAcute(char) = 0; + virtual void writeGrave(char) = 0; + virtual void writeCirc(char) = 0; + virtual void writeTilde(char) = 0; + virtual void startMemberDescription() = 0; + virtual void endMemberDescription() = 0; + virtual void startDescList() = 0; + virtual void endDescTitle() = 0; + virtual void writeDescItem() = 0; + virtual void endDescList() = 0; + virtual void writeSection(const char *,const char *,bool) = 0; + virtual void writeSectionRef(const char *,const char *,const char *) = 0; + virtual void writeSectionRefItem(const char *,const char *,const char *) = 0; + virtual void lineBreak() = 0; + virtual void addToIndex(const char *s1,const char *s2) = 0; + virtual void startIndent() = 0; + virtual void endIndent() = 0; + virtual void writeSynopsis() = 0; + //virtual void generateExternalIndex() = 0; + virtual void startClassDiagram() = 0; + virtual void endClassDiagram(ClassDiagram &,const char *,const char *) = 0; + virtual void startColorFont(uchar r,uchar g,uchar b) = 0; + virtual void endColorFont() = 0; + virtual void writePageRef(const char *,const char *) = 0; + virtual void startQuickIndexItem(const char *s,const char *l) = 0; + virtual void endQuickIndexItem() = 0; + virtual void writeFormula(const char *,const char *) = 0; + + void clear() { b.close(); a.resize(0); b.setBuffer(a); + b.open(IO_WriteOnly); t.setDevice(&b); } + void startPlainFile(const char *name); + void endPlainFile(); + QString getContents() const; + bool isEnabled() const { return active; } + protected: + QTextStream fs; + QByteArray a; + QBuffer b; + QTextStream t; + QFile *file; + QString dir; + bool active; + + private: + OutputGenerator(const OutputGenerator &o); + OutputGenerator &operator=(const OutputGenerator &o); +}; + +#endif diff --git a/src/outputlist.cpp b/src/outputlist.cpp new file mode 100644 index 0000000..daa83ed --- /dev/null +++ b/src/outputlist.cpp @@ -0,0 +1,239 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered 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" + +OutputList::OutputList(bool) +{ + //printf("OutputList::OutputList()\n"); + outputs = new QList<OutputGenerator>; + outputs->setAutoDelete(TRUE); +} + +OutputList::OutputList(const OutputList *olist) +{ + //printf("OutputList::OutputList() deep copy\n"); + outputs = new QList<OutputGenerator>; + outputs->setAutoDelete(TRUE); + + QList<OutputGenerator> *ol=olist->outputs; + OutputGenerator *og=ol->first(); + while (og) + { + OutputGenerator *ogc=og->copy(); + outputs->append(ogc); + if (og->isEnabled()) ogc->enable(); else ogc->disable(); + og=ol->next(); + } + //printf("OutputList::OutputList dst=%d res=%d\n",ol->count(),outputs->count()); +} + +OutputList::~OutputList() +{ + delete outputs; +} + +OutputList &OutputList::operator=(const OutputList &olist) +{ + if (this!=&olist) + { + QList<OutputGenerator> *ol=olist.outputs; + OutputGenerator *ogsrc=ol->first(); + OutputGenerator *ogdst=outputs->first(); + //printf("OutputList::operator= src=%d dst=%d\n",outputs->count(),ol->count()); + while (ogdst) + { + ogdst=ogsrc->copy(); + ogsrc=ol->next(); + ogdst=outputs->next(); + } + } + return *this; +} + +void OutputList::add(const OutputGenerator *og) +{ + if (og) outputs->append(og); +} + +//HtmlGenerator *OutputList::getHtmlGenerator() +//{ +// OutputGenerator *og=outputs->first(); +// while (og) +// { +// if (og->get(OutputGenerator::Html)) return (HtmlGenerator *)og; +// og=outputs->next(); +// } +// return 0; // should not happen! +//} + +void OutputList::disableAllBut(OutputGenerator::OutputType o) +{ + OutputGenerator *og=outputs->first(); + while (og) + { + og->disableIfNot(o); + og=outputs->next(); + } +} + +void OutputList::enableAll() +{ + OutputGenerator *og=outputs->first(); + while (og) + { + og->enable(); + og=outputs->next(); + } +} + +void OutputList::disable(OutputGenerator::OutputType o) +{ + OutputGenerator *og=outputs->first(); + while (og) + { + og->disableIf(o); + og=outputs->next(); + } +} + +void OutputList::enable(OutputGenerator::OutputType o) +{ + OutputGenerator *og=outputs->first(); + while (og) + { + og->enableIf(o); + og=outputs->next(); + } +} + +bool OutputList::isEnabled(OutputGenerator::OutputType o) +{ + bool result=FALSE; + OutputGenerator *og=outputs->first(); + while (og) + { + result=result || og->isEnabled(o); + og=outputs->next(); + } + return result; +} + +OutputList &OutputList::operator+=(const OutputList &outputList) +{ + OutputList *ol=(OutputList *)&outputList; + OutputGenerator *ogsrc=ol->outputs->first(); + OutputGenerator *ogdst=outputs->first(); + //printf("OutputList::operator+= src=%d dst=%d\n",outputs->count(),ol->outputs->count()); + while (ogdst && ogsrc) + { + ogdst->append(ogsrc); + ogsrc=ol->outputs->next(); + ogdst=outputs->next(); + } + return *this; +} + +//-------------------------------------------------------------------------- +// 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)()) +{ + OutputGenerator *og=outputs->first(); + while (og) + { + if (og->isEnabled()) (og->*func)(); + og=outputs->next(); + } +} + +// one argument +#define FORALL1(a1,p1) \ +void OutputList::forall(void (OutputGenerator::*func)(a1),a1) \ +{ \ + OutputGenerator *og=outputs->first(); \ + while (og) \ + { \ + if (og->isEnabled()) (og->*func)(p1); \ + og=outputs->next(); \ + } \ +} + +// two arguments +#define FORALL2(a1,a2,p1,p2) \ +void OutputList::forall(void (OutputGenerator::*func)(a1,a2),a1,a2) \ +{ \ + OutputGenerator *og=outputs->first(); \ + while (og) \ + { \ + if (og->isEnabled()) (og->*func)(p1,p2); \ + og=outputs->next(); \ + } \ +} + +// three arguments +#define FORALL3(a1,a2,a3,p1,p2,p3) \ +void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3),a1,a2,a3) \ +{ \ + OutputGenerator *og=outputs->first(); \ + while (og) \ + { \ + if (og->isEnabled()) (og->*func)(p1,p2,p3); \ + og=outputs->next(); \ + } \ +} + +// 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) \ +{ \ + OutputGenerator *og=outputs->first(); \ + while (og) \ + { \ + if (og->isEnabled()) (og->*func)(p1,p2,p3,p4); \ + og=outputs->next(); \ + } \ +} + +// now instantiate only the ones we need. + +FORALL1(const char *a1,a1) +FORALL1(char a1,a1) +FORALL1(int a1,a1) +FORALL1(IndexSections a1,a1) +FORALL2(const char *a1,const char *a2,a1,a2) +FORALL2(int a1,bool a2,a1,a2) +FORALL3(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(uchar a1,uchar a2,uchar a3,a1,a2,a3) +FORALL4(const char *a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4) + + +//-------------------------------------------------------------------------- diff --git a/src/outputlist.h b/src/outputlist.h new file mode 100644 index 0000000..2c57dad --- /dev/null +++ b/src/outputlist.h @@ -0,0 +1,298 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef OUTPUTLIST_H +#define OUTPUTLIST_H + +#include <qlist.h> +#include <qstring.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) + +class ClassDiagram; + +class OutputList +{ + public: + OutputList(bool); + ~OutputList(); + OutputList(const OutputList *ol); + OutputList &operator=(const OutputList &ol); + OutputList &operator+=(const OutputList &ol); + + void add(const OutputGenerator *); + + void disableAllBut(OutputGenerator::OutputType o); + void enableAll(); + void disable(OutputGenerator::OutputType o); + void enable(OutputGenerator::OutputType o); + bool isEnabled(OutputGenerator::OutputType o); + + //void writeIndex() + //{ forall(&OutputGenerator::writeIndex); } + void startIndexSection(IndexSections is) + { forall(&OutputGenerator::startIndexSection,is); } + void endIndexSection(IndexSections is) + { forall(&OutputGenerator::endIndexSection,is); } + 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 *title,bool external) + { forall(&OutputGenerator::startFile,name,title,external); } + void startPlainFile(const char *name) + { forall(&OutputGenerator::startPlainFile,name); } + void writeFooter(int fase,bool external) + { forall(&OutputGenerator::writeFooter,fase,external); } + void endFile() + { forall(&OutputGenerator::endFile); } + void endPlainFile() + { forall(&OutputGenerator::endPlainFile); } + void startTitleHead() + { forall(&OutputGenerator::startTitleHead); } + void endTitleHead(const char *name) + { forall(&OutputGenerator::endTitleHead,name); } + void startTitle() + { forall(&OutputGenerator::startTitle); } + void endTitle() + { forall(&OutputGenerator::endTitle); } + void newParagraph() + { forall(&OutputGenerator::newParagraph); } + void writeString(const char *text) + { forall(&OutputGenerator::writeString,text); } + void startIndexList() + { forall(&OutputGenerator::startIndexList); } + void endIndexList() + { forall(&OutputGenerator::endIndexList); } + void startItemList() + { forall(&OutputGenerator::startItemList); } + void endItemList() + { forall(&OutputGenerator::endItemList); } + void startEnumList() + { forall(&OutputGenerator::startEnumList); } + void endEnumList() + { forall(&OutputGenerator::endEnumList); } + void writeIndexItem(const char *ref,const char *file,const char *text) + { forall(&OutputGenerator::writeIndexItem,ref,file,text); } + 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 *text) + { forall(&OutputGenerator::writeObjectLink,ref,file,anchor,text); } + void writeCodeLink(const char *ref,const char *file, + const char *anchor,const char *text) + { forall(&OutputGenerator::writeCodeLink,ref,file,anchor,text); } + void startTextLink(const char *file,const char *anchor) + { forall(&OutputGenerator::startTextLink,file,anchor); } + void endTextLink() + { forall(&OutputGenerator::endTextLink); } + void writeHtmlLink(const char *url,const char *text) + { forall(&OutputGenerator::writeHtmlLink,url,text); } + 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() + { forall(&OutputGenerator::startGroupHeader); } + void endGroupHeader() + { forall(&OutputGenerator::endGroupHeader); } + void writeListItem() + { forall(&OutputGenerator::writeListItem); } + void startMemberHeader() + { forall(&OutputGenerator::startMemberHeader); } + void endMemberHeader() + { forall(&OutputGenerator::endMemberHeader); } + void startMemberList() + { forall(&OutputGenerator::startMemberList); } + void endMemberList() + { forall(&OutputGenerator::endMemberList); } + void startMemberItem() + { forall(&OutputGenerator::startMemberItem); } + void endMemberItem() + { forall(&OutputGenerator::endMemberItem); } + void writeRuler() + { forall(&OutputGenerator::writeRuler); } + void writeAnchor(const char *name) + { forall(&OutputGenerator::writeAnchor,name); } + void startCodeFragment() + { forall(&OutputGenerator::startCodeFragment); } + void endCodeFragment() + { forall(&OutputGenerator::endCodeFragment); } + void writeBoldString(const char *text) + { forall(&OutputGenerator::writeBoldString,text); } + 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) + { forall(&OutputGenerator::startMemberDoc,clName,memName,anchor); } + void endMemberDoc() + { forall(&OutputGenerator::endMemberDoc); } + void writeDoxyAnchor(const char *clName,const char *anchor,const char *name) + { forall(&OutputGenerator::writeDoxyAnchor,clName,anchor,name); } + 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 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 startSubscript() + { forall(&OutputGenerator::startSubscript); } + void endSubscript() + { forall(&OutputGenerator::endSubscript); } + void startSuperscript() + { forall(&OutputGenerator::startSuperscript); } + void endSuperscript() + { forall(&OutputGenerator::endSuperscript); } + void startTable(int cols) + { forall(&OutputGenerator::startTable,cols); } + void endTable() + { forall(&OutputGenerator::endTable); } + void nextTableRow() + { forall(&OutputGenerator::nextTableRow); } + void endTableRow() + { forall(&OutputGenerator::endTableRow); } + void nextTableColumn() + { forall(&OutputGenerator::nextTableColumn); } + void endTableColumn() + { forall(&OutputGenerator::endTableColumn); } + void lineBreak() + { forall(&OutputGenerator::lineBreak); } + void startBold() + { forall(&OutputGenerator::startBold); } + void endBold() + { forall(&OutputGenerator::endBold); } + void writeCopyright() + { forall(&OutputGenerator::writeCopyright); } + void writeQuote() + { forall(&OutputGenerator::writeQuote); } + void writeUmlaut(char c) + { forall(&OutputGenerator::writeUmlaut,c); } + void writeAcute(char c) + { forall(&OutputGenerator::writeAcute,c); } + void writeGrave(char c) + { forall(&OutputGenerator::writeGrave,c); } + void writeCirc(char c) + { forall(&OutputGenerator::writeCirc,c); } + void writeTilde(char c) + { forall(&OutputGenerator::writeTilde,c); } + void startMemberDescription() + { forall(&OutputGenerator::startMemberDescription); } + void endMemberDescription() + { forall(&OutputGenerator::endMemberDescription); } + void startDescList() + { forall(&OutputGenerator::startDescList); } + void endDescTitle() + { forall(&OutputGenerator::endDescTitle); } + void writeDescItem() + { forall(&OutputGenerator::writeDescItem); } + void endDescList() + { forall(&OutputGenerator::endDescList); } + void startIndent() + { forall(&OutputGenerator::startIndent); } + void endIndent() + { forall(&OutputGenerator::endIndent); } + void writeSection(const char *lab,const char *title,bool sub) + { forall(&OutputGenerator::writeSection,lab,title,sub); } + void writeSectionRef(const char *page,const char *lab, const char *title) + { forall(&OutputGenerator::writeSectionRef,page,lab,title); } + void writeSectionRefItem(const char *page,const char *lab, const char *title) + { forall(&OutputGenerator::writeSectionRefItem,page,lab,title); } + void addToIndex(const char *s1,const char *s2) + { forall(&OutputGenerator::addToIndex,s1,s2); } + void writeSynopsis() + { forall(&OutputGenerator::writeSynopsis); } + //void generateExternalIndex() + //{ forall(&OutputGenerator::generateExternalIndex); } + void startClassDiagram() + { forall(&OutputGenerator::startClassDiagram); } + void endClassDiagram(ClassDiagram &d,const char *f,const char *n) + { forall(&OutputGenerator::endClassDiagram,d,f,n); } + void startColorFont(uchar r,uchar g,uchar b) + { forall(&OutputGenerator::startColorFont,r,g,b); } + void endColorFont() + { forall(&OutputGenerator::endColorFont); } + void writePageRef(const char *c,const char *a) + { forall(&OutputGenerator::writePageRef,c,a); } + void startQuickIndexItem(const char *s,const char *l) + { forall(&OutputGenerator::startQuickIndexItem,s,l); } + void endQuickIndexItem() + { forall(&OutputGenerator::endQuickIndexItem); } + void writeFormula(const char *n,const char *t) + { forall(&OutputGenerator::writeFormula,n,t); } + + private: + void debug(); + void clear(); + + void forall(void (OutputGenerator::*func)()); + FORALLPROTO1(const char *); + FORALLPROTO1(char); + FORALLPROTO1(int); + FORALLPROTO1(IndexSections); + FORALLPROTO2(const char *,const char *); + FORALLPROTO2(int,bool); + FORALLPROTO3(const char *,const char *,bool); + FORALLPROTO3(uchar,uchar,uchar); + FORALLPROTO3(const char *,const char *,const char *); + FORALLPROTO3(ClassDiagram &,const char *,const char *); + FORALLPROTO4(const char *,const char *,const char *,const char *); + + OutputList(const OutputList &ol); + QList<OutputGenerator> *outputs; +}; + +#endif diff --git a/src/pre.h b/src/pre.h new file mode 100644 index 0000000..5028929 --- /dev/null +++ b/src/pre.h @@ -0,0 +1,41 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef PRE_H +#define PRE_H + +#include <stdio.h> +#include <qstring.h> +#include <qfile.h> + +#if 0 +class Define +{ + public: + Define(const char *n) { name=n; } + ~Define(); + + private: + QString name; + QStrList args; +}; +#endif + +void initPreprocessor(); +void addSearchDir(const char *dir); +void preprocessFile(const char *fileName,BufStr &output); + +#endif diff --git a/src/pre.l b/src/pre.l new file mode 100644 index 0000000..92f7553 --- /dev/null +++ b/src/pre.l @@ -0,0 +1,1636 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +%{ + +/* + * includes + */ + +#include <stdio.h> +#include <iostream.h> +#include <assert.h> +#include <ctype.h> + +#include <qarray.h> +#include <qstring.h> +#include <qstack.h> +#include <qfile.h> +#include <qstrlist.h> +#include <qdict.h> +#include <qregexp.h> + +#include "constexp.h" +#include "define.h" +#include "doxygen.h" +#include "message.h" +#include "util.h" + +#if defined(_MSC_VER) +#define popen _popen +#define pclose _pclose +#endif + +#define YY_NEVER_INTERACTIVE 1 + +#define DUMP_OUTPUT 0 // set this to one to see what the preprocessor + // produces. +#define SHOW_INCLUDES 0 // set this to one to list all parsed include files + +struct FileState +{ + int lineNr; + FILE *filePtr; + YY_BUFFER_STATE bufState; + QString fileName; +}; + +/* ----------------------------------------------------------------- + * + * statics + */ + +static int yyLineNr = 1; +static QString yyFileName; +static int ifcount = 0; +static QStrList *pathList = 0; +static QStack<FileState> includeStack; +static QDict<int> *argDict; +static int defArgs = 0; +static QString defName; +static QString defText; +static QString defArgsStr; +static bool defVarArgs; +static int level; +static int lastCContext; +static int lastCPPContext; +static QArray<int> levelGuard; +static QString guardExpr; +static BufStr *outputBuf; +//static DefineCache *fileDefineCache; +static int roundCount; +//static const Define *expandDefine; +static bool quoteArg; +static DefineDict *fileDefineDict; +static DefineDict *expandedDict; +static int findDefArgContext; + + +static void incrLevel() +{ + level++; + levelGuard.resize(level); + levelGuard[level-1]=FALSE; + //printf("%s line %d: incrLevel %d\n",yyFileName.data(),yyLineNr,level); +} + +static void decrLevel() +{ + //printf("%s line %d: decrLevel %d\n",yyFileName.data(),yyLineNr,level); + if (level > 0) + { + level--; + levelGuard.resize(level); + } + else + { + err("Error: More #endif's than #if's found.\n"); + } +} + +static bool otherCaseDone() +{ + return levelGuard[level-1]; +} + +static void setCaseDone(bool value) +{ + levelGuard[level-1]=value; +} + +static Define *isDefined(const char *name) +{ + if (name) + { + Define *def; + //if ((def=fileDefineCache->findDefine(yyFileName,name)) && !def->undef) + // return def; + if ((def=fileDefineDict->find(name)) && !def->undef) return def; + } + return 0; +} + +static FILE *findFile(const char *fileName) +{ + if (pathList==0) + { + return 0; + } + char *s=pathList->first(); + while (s) + { + QString absName=(QString)s+"/"+fileName; + QFileInfo fi(absName); + if (fi.exists()) + { + FILE *f; + if (!inputFilter.isEmpty()) + { + QString cmd = inputFilter+" "+absName; + f=popen(cmd,"r"); + if (!f) warn("Warning: could not execute filter %s\n",cmd.data()); + } + else + { + f=fopen(absName,"r"); + if (!f) warn("Warning: could not open file %s for reading\n",absName.data()); + } + if (f) + { + yyFileName=absName; + yyLineNr=1; + return f; + } + } + s=pathList->next(); + } + return 0; +} + + +static int getNextChar(const QString &expr,QString *rest,uint &pos); +static int getCurrentChar(const QString &expr,QString *rest,uint pos); +static void unputChar(const QString &expr,QString *rest,uint &pos,char c); +static void expandExpression(QString &expr,QString *rest,int pos); + +static QString stringize(const QString &s) +{ + QString 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(QString &expr) +{ + QRegExp r("[ \\t\\n]*##[ \\t\\n]*"); + int l,n,i=0; + while ((n=r.match(expr,i,&l))!=-1) + { + if (n+l+1<(int)expr.length() && expr.at(n+l)=='@' && expr.at(n+l+1)=='-') + { + // remove no-rescan marker after ID + l+=2; + } + // 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+l; + } +} + +/*! 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. + * The characters from the input file will be read. + * 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 QString &expr,QString *rest,int pos,int &len,const Define *def,QString &result) +{ + //printf("replaceFunctionMacro(expr=%s,rest=%s,pos=%d,def=%s) level=%d\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),level); + //bool replaced=FALSE; + uint j=pos; + len=0; + result.resize(0); + int cc; + // TODO: use a checkNextChar function. + //while ((cc=getNextChar(expr,rest,j))!=EOF && cc==' ') len++; + //if (cc!='(') return FALSE; + while ((cc=getCurrentChar(expr,rest,j))!=EOF && cc==' ') + { + len++; + getNextChar(expr,rest,j); + } + if (cc!='(') + { + unputChar(expr,rest,j,' '); + return FALSE; + } + getNextChar(expr,rest,j); // eat the `(' character + + //while (j<expr.length() && expr.at(j)!='(') j++; + //j++; // skip opening paren + + QDict<QString> argTable; // list of arguments + argTable.setAutoDelete(TRUE); + QString arg; + int argCount=0; + bool done=FALSE; + // FASE 1: read the macro arguments + while ((argCount<def->nargs || def->varArgs) && + ((cc=getNextChar(expr,rest,j))!=EOF) && !done + ) + { + 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) + { + char c=(char)cc; + if (c=='\'' || c=='\"') // skip ('s and )'s inside strings + { + if (term!='\0') + { + if (c==term && expr.at(j-2)!='\\') term='\0'; + } + else + { + term=c; + } + } + if (term=='\0' && c==')') + { + level--; + arg+=c; + if (level==0) break; + } + else if (term=='\0' && 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 + { + QString argKey; + argKey.sprintf("@%d",argCount++); // key name + arg=arg.stripWhiteSpace(); + // add argument to the lookup table + argTable.insert(argKey, new QString(arg)); + arg.resize(0); + if (c==')') // end of the argument list + { + done=TRUE; + } + } + } + else if (c=='\"') // append literal strings + { + arg+=c; + char pc=c; + bool found=FALSE; + while (!found && (cc=getNextChar(expr,rest,j))!=EOF) + { + found = pc!='\\' && cc=='"'; + c=(char)cc; + pc=c; + arg+=c; + } + } + else if (c=='\'') // append literal characters + { + arg+=c; + char pc=c; + bool found=FALSE; + while (!found && (cc=getNextChar(expr,rest,j))!=EOF) + { + found = pc!='\\' && cc=='\''; + c=(char)cc; + pc=c; + arg+=c; + } + } + else // append other characters + { + arg+=c; + } + } + + // FASE 2: apply the macro function + if (argCount==def->nargs || + (argCount>def->nargs && def->varArgs)) // matching parameters lists + { + uint k=0; + // substitution of all formal arguments + QString resExpr; + const QString d=def->definition.stripWhiteSpace(); + 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 + { + QString key="@"; + QString *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(),args[key]->data()); + if (key.length()>1 && (subst=argTable[key])) + { + QString substArg=*subst; + // 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 + { + 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)!='\\') + { + 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; + } + else + { + 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 QString &expr,int p,int *l) +{ + int n; + while (p<(int)expr.length()) + { + char c=expr.at(p++); + 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 pc=c; + if (p<(int)expr.length()) c=expr.at(p); + while (p<(int)expr.length() && (c!='"' || pc=='\\')) + { + pc=c; + c=expr.at(p); + 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(QString &expr,QString *rest,int pos) +{ + //printf("expandExpression(%s,%s)\n",expr.data(),rest ? rest->data() : 0); + QString macroName; + QString expMacro; + 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 found\n",macroName.data()); + if (p<2 || !(expr.at(p-2)=='@' && expr.at(p-1)=='-')) // no-rescan marker? + { + if (expandedDict->find(macroName)==0) // expand macro + { + Define *def=isDefined(macroName); + //printf("name is not an expanded macro def=%s\n",def ? def->name.data() : 0); + if (def && def->nargs==0) // simple macro + { + // substitute the definition of the macro + 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; + } + + if (replaced) // expand the macro and rescan the expression + { + //printf("replacing `%s'->`%s'\n",expr.mid(p,len).data(),expMacro.data()); + QString resultExpr=expMacro; + QString restExpr=expr.right(expr.length()-len-p); + processConcatOperators(resultExpr); + expandedDict->insert(macroName,def); + expandExpression(resultExpr,&restExpr,0); + 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 @ + * All identifiers found are replaced by 0L + * \par assumption: + * \a s only contains pairs of @@'s. + */ +QString removeIdsAndMarkers(const char *s) +{ + //printf("removeIdsAndMarkers(%s)\n",s); + const char *p=s; + char c; + bool inNum=FALSE; + QString result; + if (p) + { + while ((c=*p)) + { + if (c=='@') // replace @@ with @ + { + if (*(p+1)=='@') + { + result+=c; + } + p+=2; + } + else if (isdigit(c)) + { + result+=c; + p++; + inNum=TRUE; + } + else if ((isalpha(c) || c=='_') && !inNum) // replace identifier with 0L + { + result+="0L"; + p++; + while ((c=*p) && isId(c)) p++; + } + else + { + result+=c; + char lc=tolower(c); + if (lc!='l' && lc!='u') inNum=FALSE; + p++; + } + } + } + return result; +} + +/*! replaces all occurrences of @@ in \a s by @ + * \par assumption: + * \a s only contains pairs of @@'s + */ +QString removeMarkers(const char *s) +{ + const char *p=s; + char c; + QString result; + if (p) + { + while ((c=*p)) + { + if (c=='@') // replace @@ with @ + { + if (*(p+1)=='@') + { + result+=c; + } + p+=2; + } + else + { + result+=c; + p++; + } + } + } + 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 QString &expr) +{ + QString e=expr; + expandExpression(e,0,0); + e = removeIdsAndMarkers(e); + if (e.length()==0) return FALSE; + //printf("computeExpession(%s)\n",e.data()); + return parseCppExpression(e); +} + +/*! expands the macro definition in \a name + * If needed the function may read additional characters from the input + */ + +QString expandMacro(const QString &name) +{ + QString 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 = defName; + def->definition = defText.stripWhiteSpace(); + def->nargs = defArgs; + def->fileName = yyFileName; + def->lineNr = yyLineNr; + def->varArgs = defVarArgs; + return def; +} + +void addDefine() +{ + bool ambig; + FileDef *fd=findFileDef(&inputNameDict,yyFileName,ambig); + MemberDef *md=new MemberDef("#define",defName,defArgsStr,0, + Public,Normal,FALSE,FALSE,MemberDef::Define,0,0); + md->setDefFile(yyFileName); + md->setDefLine(yyLineNr); + md->setFileDef(fd); + md->setDefinition("#define "+defName+defArgsStr); + + MemberName *mn=functionNameDict[defName]; + if (mn==0) + { + mn = new MemberName(defName); + functionNameList.inSort(mn); + functionNameDict.insert(defName,mn); + } + mn->append(md); + if (fd) fd->insertMember(md); + + Define *d; + if ((d=defineDict[defName])==0) defineDict.insert(defName,newDefine()); + +} + +static void outputChar(char c) +{ + if (includeStack.isEmpty()) outputBuf->addChar(c); +} + +static void outputArray(const char *a,int len) +{ + if (includeStack.isEmpty()) outputBuf->addArray(a,len); +} + +static void readIncludeFile(const QString &inc) +{ + if (!searchIncludeFlag) return; // do not read include files + 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; + // 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 + { + QString incFileName=inc.mid(s,i-s).stripWhiteSpace(); + + FILE *f; + QString oldFileName=yyFileName.copy(); + if ((f=findFile(incFileName))) // see if the include file can be found + { +#if SHOW_INCLUDES + for (i=0;i<includeStack.count();i++) msg(" "); + msg("#include %s: parsing...\n",incFileName.data()); +#endif + // store the state of the old file + FileState *fs=new FileState; + fs->bufState=YY_CURRENT_BUFFER; + fs->lineNr=yyLineNr; + fs->fileName=oldFileName; + fs->filePtr=f; + // push the state on the stack + includeStack.push(fs); + // set the scanner to the include file + preYYin=f; + yy_switch_to_buffer(yy_create_buffer(preYYin, YY_BUF_SIZE)); + } + else + { +#if SHOW_INCLUDES + msg("#include %s: not found! skipping...\n",incFileName.data()); + //printf("Error: include file %s not found\n",yytext); +#endif + } + } +} + +/* ----------------------------------------------------------------- */ + +%} + +ID [a-z_A-Z][a-z_A-Z0-9]* +B [ \t] +BN [ \t\r\n] + +%x Start +%x Command +%x SkipCommand +%x SkipLine +%x CopyLine +%x Include +%x IncludeID +%x DefineName +%x DefineArg +%x DefineText +%x SkipCPPBlock +%x Ifdef +%x Ifndef +%x SkipCComment +%x SkipCPPComment +%x RemoveCComment +%x RemoveCPPComment +%x Guard +%x DefinedExpr1 +%x DefinedExpr2 +%x SkipDoubleQuote +%x SkipSingleQuote +%x UndefName +%x IgnoreLine +%x FindDefineArgs +%x ReadString + +%% + +<*>\x06 +<*>\x00 +<*>\r + /* +<Start>^{B}*([^ \t#\n\/][^\n]*)?"\n" { + //printf("%s line %d: %s",yyFileName.data(),yyLineNr,yytext); + if (includeStack.isEmpty()) + { + //preprocessedFile+=yytext; + //char *s=yytext,c; + //if (s) while ((c=*s++)) *dataPtr++=c; + outputBuf->addArray(yytext,yyleng); + } + yyLineNr++; + } + */ +<Start>^{B}*"#" { BEGIN(Command); } +<Start>^{B}*/[^#] { + outputArray(yytext,yyleng); + BEGIN(CopyLine); + } + /* +<CopyLine>[^\n/]+ { + outputArray(yytext,yyleng); + } + */ +<CopyLine>{ID}/{BN}*"(" { + if (includeStack.isEmpty() && + macroExpansionFlag && + /* (expandDefine=fileDefineCache->findDefine(yyFileName,yytext)) */ + fileDefineDict->find(yytext) + ) + { + roundCount=0; + defArgsStr=yytext; + findDefArgContext = CopyLine; + BEGIN(FindDefineArgs); + } + else + { + outputArray(yytext,yyleng); + } + } +<CopyLine>{ID} { + Define *def=0; + if (includeStack.isEmpty() && + macroExpansionFlag && + (def=fileDefineDict->find(yytext)) && + def->nargs==0 + ) + { + QString name=yytext; + QString result=expandMacro(name); + outputArray(result,result.length()); + } + else + { + outputArray(yytext,yyleng); + } + } +<CopyLine>. { + outputChar(*yytext); + } +<CopyLine>\n { + outputChar('\n'); + BEGIN(Start); + yyLineNr++; + } +<FindDefineArgs>"(" { + defArgsStr+='('; + roundCount++; + } +<FindDefineArgs>")" { + defArgsStr+=')'; + roundCount--; + if (roundCount==0) + { + QString result=expandMacro(defArgsStr); + if (findDefArgContext==CopyLine) + { + outputArray(result,result.length()); + BEGIN(findDefArgContext); + } + else // findDefArgContext==IncludeID + { + readIncludeFile(result); + BEGIN(Start); + } + } + } + /* +<FindDefineArgs>")"{B}*"(" { + defArgsStr+=yytext; + } + */ +<FindDefineArgs>"\"" { + defArgsStr+=*yytext; + BEGIN(ReadString); + } +<FindDefineArgs>\n { + yyLineNr++; + outputChar('\n'); + } +<FindDefineArgs>"@" { + defArgsStr+="@@"; + } +<FindDefineArgs>. { + defArgsStr+=*yytext; + } +<ReadString>"\\\"" { + defArgsStr+=yytext; + } +<ReadString>"\"" { + defArgsStr+=*yytext; + BEGIN(FindDefineArgs); + } +<ReadString>. { + defArgsStr+=*yytext; + } +<Command>"include"{B}*/{ID} { + if (macroExpansionFlag) + BEGIN(IncludeID); + } +<Command>"include"{B}*[<"] { + BEGIN(Include); + } +<Command>"define"{B}+ { + //printf("!!!DefineName\n"); + BEGIN(DefineName); + } +<Command>"ifdef"/{B}*"(" { + incrLevel(); + guardExpr.resize(0); + BEGIN(DefinedExpr2); + } +<Command>"ifdef"/{B}+ { + //printf("Pre.l: ifdef\n"); + incrLevel(); + guardExpr.resize(0); + BEGIN(DefinedExpr1); + } +<Command>"ifndef"/{B}*"(" { + incrLevel(); + guardExpr="! "; + BEGIN(DefinedExpr2); + } +<Command>"ifndef"/{B}+ { + incrLevel(); + guardExpr="! "; + BEGIN(DefinedExpr1); + } +<Command>"if"/[ \t(] { + incrLevel(); + guardExpr.resize(0); + BEGIN(Guard); + } +<Command>"elif"/[ \t(] { + if (!otherCaseDone()) + { + guardExpr.resize(0); + BEGIN(Guard); + } + else + { + ifcount=0; + BEGIN(SkipCPPBlock); + } + } +<Command>"else"/[^a-z_A-Z0-9] { + //printf("else levelGuard[%d]=%d\n",level-1,levelGuard[level-1]); + if (otherCaseDone()) + { + ifcount=0; + BEGIN(SkipCPPBlock); + } + else + { + setCaseDone(TRUE); + //levelGuard[level-1]=TRUE; + } + } +<Command>"undef"{B}+ { + BEGIN(UndefName); + } +<Command>"elif"/[ \t(] { + if (!otherCaseDone()) + { + guardExpr.resize(0); + BEGIN(Guard); + } + } +<Command>"endif"/[^a-z_A-Z0-9] { + //printf("Pre.l: #endif\n"); + decrLevel(); + } +<Command,IgnoreLine>\n { + outputChar('\n'); + BEGIN(Start); + yyLineNr++; + } +<Command>{ID} { // unknown directive + BEGIN(IgnoreLine); + } +<IgnoreLine>. +<Command>. +<UndefName>{ID} { + Define *def; + if ((def=isDefined(yytext))) + { + //printf("undefining %s\n",yytext); + def->undef=TRUE; + } + BEGIN(Start); + } +<Guard>\\\n { + outputChar('\n'); + guardExpr+=' '; + yyLineNr++; + } +<Guard>"defined"/{B}*"(" { + BEGIN(DefinedExpr2); + } +<Guard>"defined"/{B}+ { + BEGIN(DefinedExpr1); + } +<Guard>. { guardExpr+=*yytext; } +<Guard>\n { + outputChar('\n'); + yyLineNr++; + //printf("Guard: `%s'\n", + // guardExpr.data()); + bool guard=computeExpression(guardExpr); + setCaseDone(guard); + //printf("if levelGuard[%d]=%d\n",level-1,levelGuard[level-1]); + if (guard) + { + BEGIN(Start); + } + else + { + ifcount=0; + BEGIN(SkipCPPBlock); + } + } +<DefinedExpr1,DefinedExpr2>\\\n { yyLineNr++; outputChar('\n'); } +<DefinedExpr1>{ID} { + if (isDefined(yytext)) + guardExpr+=" 1L "; + else + guardExpr+=" 0L "; + BEGIN(Guard); + } +<DefinedExpr2>{ID} { + if (isDefined(yytext)) + guardExpr+=" 1L "; + else + guardExpr+=" 0L "; + } +<DefinedExpr1,DefinedExpr2>\n { // should not happen, handle anyway + ifcount=0; + BEGIN(SkipCPPBlock); + } +<DefinedExpr2>")" { + BEGIN(Guard); + } +<DefinedExpr1,DefinedExpr2>. +<SkipCPPBlock>^{B}*"#" { BEGIN(SkipCommand); } +<SkipCPPBlock>^{B}*/[^#] { BEGIN(SkipLine); } +<SkipCPPBlock>. +<SkipCommand>"if"(("n")?("def"))?/[ \t(] { + incrLevel(); + ifcount++; + //printf("#if... depth=%d\n",ifcount); + } +<SkipCommand>"else"/[^a-z_A-Z0-9] { + //printf("Else! ifcount=%d otherCaseDone=%d\n",ifcount,otherCaseDone()); + if (ifcount==0 && !otherCaseDone()) + { + setCaseDone(TRUE); + //outputChar('\n'); + BEGIN(Start); + } + } +<SkipCommand>"elif"/[ \t(] { + if (ifcount==0) + { + if (!otherCaseDone()) + { + guardExpr.resize(0); + BEGIN(Guard); + } + else + { + BEGIN(Start); + } + } + } +<SkipCommand>"endif"/[^a-z_A-Z0-9] { + decrLevel(); + if (--ifcount<0) + { + //outputChar('\n'); + BEGIN(Start); + } + } +<SkipCommand>\n { + outputChar('\n'); + yyLineNr++; + BEGIN(SkipCPPBlock); + } +<SkipCommand>{ID} { // unknown directive + BEGIN(SkipLine); + } +<SkipCommand>. +<SkipLine>[^/\n]+ +<SkipLine>. +<SkipLine>"//" { + lastCPPContext=YY_START; + BEGIN(RemoveCPPComment); + } +<SkipLine>"/*" { + lastCContext=YY_START; + BEGIN(RemoveCComment); + } +<SkipLine>\n { + outputChar('\n'); + yyLineNr++; + BEGIN(SkipCPPBlock); + } +<IncludeID>{ID}{B}*/"(" { + roundCount=0; + defArgsStr=yytext; + findDefArgContext = IncludeID; + BEGIN(FindDefineArgs); + } +<IncludeID>{ID} { + readIncludeFile(expandMacro(yytext)); + BEGIN(Start); + } +<Include>[^\">\n]+[\">] { + QString incName=yytext; + //int l=incName.length(); + //QString incFileName=incName.left(l-1); + //if (fileDefineCache->fileCached(incFileName)) + //{ + // printf("file already cached!\n"); + // fileDefineCache->merge(incFileName,yyFileName); + //} + //else if ((f=findFile(incFileName))) + readIncludeFile(incName); + + BEGIN(Start); + } +<DefineName>{ID}/"(" { + //printf("Define() `%s'\n",yytext); + argDict = new QDict<int>(31); + argDict->setAutoDelete(TRUE); + defArgs = 0; + defArgsStr.resize(0); + defText.resize(0); + defName = yytext; + defVarArgs = FALSE; + BEGIN(DefineArg); + } +<DefineName>{ID}/{B}* { + //printf("Define `%s'\n",yytext); + argDict = 0; + defArgs = 0; + defArgsStr.resize(0); + defText.resize(0); + defName = yytext; + defVarArgs = FALSE; + QString tmp=(QString)"#define "+defName+defArgsStr; + outputArray(tmp.data(),tmp.length()); + quoteArg=FALSE; + BEGIN(DefineText); + } +<DefineArg>","{B}* { defArgsStr+=yytext; } +<DefineArg>"("{B}* { defArgsStr+=yytext; } +<DefineArg>")"{B}* { + defArgsStr+=yytext; + QString tmp=(QString)"#define "+defName+defArgsStr; + outputArray(tmp.data(),tmp.length()); + quoteArg=FALSE; + BEGIN(DefineText); + } +<DefineArg>{ID}("..."?) { + //printf("Define addArg(%s)\n",yytext); + QString argName=yytext; + defVarArgs = yytext[yyleng-1]=='.'; + if (defVarArgs) + argName=argName.left(argName.length()-3); + defArgsStr+=yytext; + argDict->insert(argName,new int(defArgs)); + defArgs++; + } +<DefineText>"/*" { + outputChar('/');outputChar('*'); + defText+=' '; + lastCContext=YY_START; + BEGIN(SkipCComment); + } +<DefineText>"//" { + outputChar('/');outputChar('/'); + lastCPPContext=YY_START; + BEGIN(SkipCPPComment); + } +<SkipCComment>"*/" { + outputChar('*');outputChar('/'); + BEGIN(lastCContext); + } +<SkipCComment>"//" { + outputChar('/');outputChar('/'); + } +<SkipCComment>"/*" { + outputChar('/');outputChar('*'); + } +<SkipCComment>[^*\n]+ { + outputArray(yytext,yyleng); + } +<SkipCComment>\n { + yyLineNr++; + outputChar('\n'); + } +<SkipCComment>. { + outputChar(*yytext); + } +<RemoveCComment>"*/" { BEGIN(lastCContext); } +<RemoveCComment>"//" +<RemoveCComment>"/*" +<RemoveCComment>[^*\n]+ +<RemoveCComment>\n { yyLineNr++; outputChar('\n'); } +<RemoveCComment>. +<SkipCPPComment,RemoveCPPComment>\n { + unput(*yytext); + BEGIN(lastCPPContext); + } +<SkipCPPComment>"/*" { + outputChar('/');outputChar('*'); + } +<SkipCPPComment>"//" { + outputChar('/');outputChar('/'); + } +<SkipCPPComment>[^\n]+ { + outputArray(yytext,yyleng); + } +<SkipCPPComment>. { + outputChar(*yytext); + } +<RemoveCPPComment>"/*" +<RemoveCPPComment>"//" +<RemoveCPPComment>[^\n]+ +<RemoveCPPComment>. +<DefineText>"#" { + quoteArg=TRUE; + } +<DefineText>{ID} { + //bool quote=FALSE; + //char *p=yytext; + //if (p[0]=='#') + //{ + // p++; + // quote=TRUE; + // defText+="\""; + //} + if (quoteArg) + { + defText+="\""; + } + if (defArgs>0) + { + int *n; + if ((n=(*argDict)[yytext])) + { + if (!quoteArg) defText+=' '; + defText+='@'; + QString numStr; + numStr.setNum(*n); + defText+=numStr; + if (!quoteArg) defText+=' '; + } + else + { + defText+=yytext; + } + } + else + { + defText+=yytext; + } + if (quoteArg) + { + defText+="\""; + } + quoteArg=FALSE; + } +<DefineText>\\\n { + outputChar('\n'); + defText += ' '; yyLineNr++; + } +<DefineText>\n { + outputChar('\n'); + Define *def=0; + //printf("Define name=`%s' text=`%s'\n",defName.data(),defText.data()); + if (includeStack.isEmpty()) addDefine(); + if (!onlyPredefinedFlag && (def=fileDefineDict->find(defName))==0) + { + fileDefineDict->insert(defName,newDefine()); + } + //if ((def=fileDefineCache->findDefine(yyFileName,defName))==0) + //{ + // printf("define is not found\n"); + // fileDefineCache->insertDefine(yyFileName,defName,newDefine()); + //} + else if (def)// name already exists + { + //printf("define found\n"); + if (def->undef) // undefined name + { + def->undef = FALSE; + def->name = defName; + def->definition = defText.stripWhiteSpace(); + def->nargs = defArgs; + def->fileName = yyFileName; + def->lineNr = yyLineNr; + } + else + { + //printf("Error: define %s is defined more than once!\n",defName.data()); + } + } + delete argDict; + yyLineNr++; + BEGIN(Start); + } +<DefineText>{B}* { defText += ' '; } +<DefineText>{B}*"##"{B}* { defText += "##"; } +<DefineText>"@" { defText += "@@"; } +<DefineText>\" { defText += *yytext; + BEGIN(SkipDoubleQuote); + } +<DefineText>\' { defText += *yytext; + BEGIN(SkipSingleQuote); + } +<SkipDoubleQuote>\" { + defText += *yytext; + BEGIN(DefineText); + } +<SkipSingleQuote>\' { + defText += *yytext; + BEGIN(DefineText); + } +<SkipDoubleQuote>. { defText += *yytext; } +<SkipSingleQuote>. { defText += *yytext; } +<DefineText>. { defText += *yytext; } +<<EOF>> { + //printf("End of include file\n"); + //printf("Include stack depth=%d\n",includeStack.count()); + if (includeStack.isEmpty()) + { + //printf("Terminating scanner!\n"); + yyterminate(); + } + else + { + FileState *fs=includeStack.pop(); + //fileDefineCache->merge(yyFileName,fs->fileName); + if (inputFilter.isEmpty()) + fclose(fs->filePtr); + else + pclose(fs->filePtr); + YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER; + yy_switch_to_buffer( fs->bufState ); + yy_delete_buffer( oldBuf ); + yyLineNr=fs->lineNr; + yyFileName=fs->fileName.copy(); + //printf("######## FileName %s\n",yyFileName.data()); + delete fs; + } + } +<*>"/*" { + outputChar('/');outputChar('*'); + lastCContext=YY_START; + BEGIN(SkipCComment); + } +<*>"//" { + outputChar('/');outputChar('/'); + lastCPPContext=YY_START; + BEGIN(SkipCPPComment); + } +<*>\n { + outputChar('\n'); + yyLineNr++; + } +<*>. { + outputChar(*yytext); + } + +%% + +/*@ ---------------------------------------------------------------------------- + */ + +static int getNextChar(const QString &expr,QString *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->length()>0) + { + int cc=rest->at(0); + *rest=rest->right(rest->length()-1); + //printf("%c=rest\n",cc); + return cc; + } + else + { + int cc=yyinput(); + //printf("%c=yyinput()\n",cc); + return cc; + } +} + +static int getCurrentChar(const QString &expr,QString *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->length()>0) + { + int cc=rest->at(0); + //printf("%c=rest\n",cc); + return cc; + } + else + { + int cc=yyinput();unput(cc); + //printf("%c=yyinput()\n",cc); + return cc; + } +} + +static void unputChar(const QString &expr,QString *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); + } + //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()) pathList->append(fi.absFilePath()); +} + +void initPreprocessor() +{ + pathList = new QStrList; + addSearchDir("."); + //defineNameList.setAutoDelete(TRUE); + //defineNameList.clear(); + defineDict.clear(); + //fileDefineCache = new DefineCache(1009); + expandedDict = new DefineDict(17); + fileDefineDict = new DefineDict(1009); +} + +void cleanupPreprocessor() +{ + //delete fileDefineCache; + delete fileDefineDict; + delete expandedDict; + delete pathList; +} + + +void preprocessFile(const char *fileName,BufStr &output) +{ +#if DUMP_OUTPUT + uint orgOffset=output.curPos(); +#endif + + outputBuf=&output; + includeStack.setAutoDelete(TRUE); + includeStack.clear(); + fileDefineDict->setAutoDelete(TRUE); + fileDefineDict->clear(); + expandedDict->setAutoDelete(FALSE); + expandedDict->clear(); + + // add predefined macros + char *defStr = predefined.first(); + while (defStr) + { + QString ds = defStr; + int i; + if ((i=ds.find('='))==-1) + { + if (ds.length()>0) + { + Define *def = new Define; + def->name = ds; + def->definition = "1"; + def->nargs = 0; + fileDefineDict->insert(ds,def); + } + } + else + { + if (i>0 && (int)ds.length()>i) + { + Define *def = new Define; + def->name = ds.left(i); + def->definition = ds.right(ds.length()-i-1); + def->nargs = 0; + fileDefineDict->insert(ds.left(i),def); + } + } + defStr=predefined.next(); + } + + if (inputFilter.isEmpty()) + { + preYYin = fopen(fileName,"r"); + if (!preYYin) + { + err("Error: could not open file %s\n",fileName); + return; + } + } + else + { + QString cmd = inputFilter+" "+fileName; + preYYin = popen(cmd,"r"); + if (!preYYin) + { + err("Error: could not execute filter %s\n",cmd.data()); + return; + } + } + yyLineNr = 1; + level = 0; + yyFileName = fileName; + BEGIN( Start ); + preYYlex(); + if (inputFilter.isEmpty()) + fclose(preYYin); + else + pclose(preYYin); + +#if DUMP_OUTPUT + char *orgPos=output.data()+orgOffset; + char *newPos=output.data()+output.curPos(); + printf("Resulting size: %d bytes\n",newPos-orgPos); + int line=1; + printf("---------\n00001 "); + while (orgPos<newPos) + { + putchar(*orgPos); + if (*orgPos=='\n') printf("%05d ",++line); + orgPos++; + } + printf("\n---------\n"); +#endif +} + + +extern "C" { // some bogus code to keep the compiler happy + int preYYwrap() { return 1 ; } + void preYYdummy() { yy_flex_realloc(0,0); } +} diff --git a/src/scanner.h b/src/scanner.h new file mode 100644 index 0000000..59d5966 --- /dev/null +++ b/src/scanner.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef SCANNER_H +#define SCANNER_H + +#include <stdio.h> +#include <qlist.h> +#include <qstring.h> + +#include "entry.h" +#include "code.h" + +class OutputList; + +extern void parseMain(Entry *); +extern void parseDoc(OutputList &ol,const char *clName, const char *memName, + const QString &docString); +extern void parseExample(OutputList &ol,const QString &docString, + const char *fileName); +#endif diff --git a/src/scanner.l b/src/scanner.l new file mode 100644 index 0000000..0beadae --- /dev/null +++ b/src/scanner.l @@ -0,0 +1,3386 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +%{ + +/* + * includes + */ +#include <stdio.h> +#include <stdlib.h> +#include <iostream.h> +#include <assert.h> +#include <ctype.h> + +#include <qarray.h> +#include <qstring.h> +#include <qstack.h> +#include <qregexp.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" + +#ifndef WIN32 +#include <unistd.h> +#endif + +#define YY_NEVER_INTERACTIVE 1 + +/* ----------------------------------------------------------------- + * + * statics + */ +static bool insideArgumentList; +static QString className; +static QString memberName; +static QString refName; +static OutputList * outDoc; +static QString code; +static QString linkRef; +static QString linkText; +static QString codeBlock; +static const char * inputString; +static int inputPosition; +static int lastContext; +static int lastCContext; +static int lastDocContext; +static int lastDocRelContext; +static int lastCPPContext; +static int lastSkipSharpContext; +static int lastSkipRoundContext; +static int lastBriefContext; +static int lastVerbState; +static int lastStringContext; +static int lastCurlyContext; +static int lastCodeState; +static int lastAfterDocContext; +static int lastGroupContext; +static int lastFormulaContext; +static int nextDefContext; +static Protection protection; +static Protection baseProt; +static int bracketCount = 0 ; +static int sharpCount = 0 ; +static int roundCount = 0 ; +static int ifCount = 0 ; +static Entry* current_root = 0 ; +static Entry* global_root = 0 ; +static Entry* current = 0 ; +static int yyLineNr = 0 ; +static int anonCount = 0 ; +static char yyFileName[2048] ; +static bool sig; +static bool slot; +static bool gstat; +static bool removeSlashes; +static Specifier virt; +static Specifier baseVirt; +static bool exampleDoc; +static QString exampleName; +static QString htmlUrl,htmlText; +static QString currentIncludeFile; +static QString msType,msName,msArgs; +static int includeFileOffset = 0; +static int includeFileLength = 0; +static bool firstLine; +static bool isTypedef; +static bool inParamBlock; +static bool inExceptionBlock; +static bool inSeeBlock; +static bool inReturnBlock; +static bool inAuthorBlock; +static bool inVersionBlock; +static bool inDateBlock; +static bool inBugBlock; +static bool inWarningBlock; +static bool inParBlock; +static bool firstSeeArg; +static bool javaDocSee; +static char afterDocTerminator; +static int tmpDocType; +static QString sectionLabel; +static QString sectionTitle; +static bool isSubsection; +static QString funcPtrType; +static QString templateStr; +static QString baseName; +static QString *specName; +static QString formulaText; +static QString sectionRef; + +// state variable for reading the argument list of a function +static int argRoundCount; +static int argSharpCount; +static int currentArgumentContext; +static int lastCopyArgStringContext; +static int lastCopyArgContext; +static QString *copyArgString; + + + +//----------------------------------------------------------------------------- + +static void initParser() +{ + insideArgumentList=FALSE; + className.resize(0); + memberName.resize(0); + refName.resize(0); + code.resize(0); + linkRef.resize(0); + linkText.resize(0); + codeBlock.resize(0); + htmlUrl.resize(0); + htmlText.resize(0); + currentIncludeFile.resize(0); + sectionLabel.resize(0); + sectionTitle.resize(0); + baseName.resize(0); + formulaText.resize(0); + protection = Public; + baseProt = Public; + bracketCount = 0; + sharpCount = 0; + roundCount = 0; + ifCount = 0; + sig = FALSE; + slot = FALSE; + gstat = FALSE; + virt = Normal; + baseVirt = Normal; + includeFileOffset = 0; + includeFileLength = 0; + firstLine = TRUE; + isTypedef = FALSE; + inParamBlock = FALSE; + inExceptionBlock = FALSE; + inSeeBlock = FALSE; + inReturnBlock = FALSE; + inAuthorBlock = FALSE; + inVersionBlock = FALSE; + inDateBlock = FALSE; + inBugBlock = FALSE; + inWarningBlock = FALSE; + inParBlock = FALSE; + firstSeeArg = FALSE; + javaDocSee = FALSE; + isSubsection = FALSE; +} + +//----------------------------------------------------------------------------- + +void scanString(const char *s); + +//----------------------------------------------------------------------------- + +class TableElem +{ + public: + TableElem(int r,int c); + ~TableElem(); + int getRow() { return row; } + int getCol() { return col; } + OutputList *outputList() { return ol; } + + private: + OutputList *ol; + int row; + int col; +}; + +TableElem::TableElem(int r,int c) +{ + //printf("TableElem::TableElem(%d,%d)\n",r,c); + ol=new OutputList(outDoc); + outDoc=ol; + row=r; + col=c; +} + +TableElem::~TableElem() +{ + //printf("TableElem::~TableElem(%d,%d)\n",row,col); + delete ol; +} + +class Table +{ + public: + Table(); + ~Table(); + void newRow(); + void newElem(); + + private: + OutputList *parentDoc; + QList<TableElem> *elemList; + int curRow; + int curCol; + int rows; + int cols; +}; + +Table::Table() +{ + parentDoc=outDoc; + elemList=new QList<TableElem>; + elemList->setAutoDelete(TRUE); + curRow=curCol=rows=cols=0; +} + +Table::~Table() +{ + //printf("Table::~Table()\n"); + // use elemList & cols & rows + if (cols>0 && rows>0) + { + parentDoc->startTable(cols); + TableElem *e=elemList->first(); + while (e) + { + if (e->getRow()>0) + { + if (e->getCol()==0) + { + if (e->getRow()>1) parentDoc->endTableRow(); + parentDoc->nextTableRow(); + } + else + { + parentDoc->nextTableColumn(); + } + *parentDoc+=*e->outputList(); + parentDoc->endTableColumn(); + } + e=elemList->next(); + } + parentDoc->endTable(); + } + delete elemList; + outDoc=parentDoc; +} + +void Table::newRow() +{ + //printf("Table::newRow()\n"); + curRow++; + if (curRow>rows) rows=curRow; + curCol=0; +} + +void Table::newElem() +{ + //printf("Table::newElem(%d,%d)\n",curRow,curCol); + TableElem *te = new TableElem(curRow,curCol); + elemList->append(te); + + curCol++; + if (curCol>cols) cols=curCol; +} + +static QStack<Table> tableStack; +static Table *curTable; + +static void startTable() +{ + //printf("startTable()\n"); + curTable=new Table; + tableStack.push(curTable); +} + +static void endTable() +{ + //printf("endTable()\n"); + delete tableStack.pop(); // the destructor adds the table to the stream! + curTable=tableStack.top(); +} + +//----------------------------------------------------------------------------- + +static void lineCount() +{ + for( const char* c = yytext ; *c ; ++c ) + yyLineNr += (*c == '\n') ; +} + +static void endArgumentList() +{ + if (insideArgumentList) + { + insideArgumentList=FALSE; + outDoc->endItemList(); + } +} + +static void addType( Entry* current ) +{ + if( current->type.length() ) + current->type += ' ' ; + current->type += current->name ; + current->name.resize(0) ; + if( current->type.length() ) + current->type += ' ' ; + current->type += current->args ; + current->args.resize(0) ; + current->argList->clear(); +} + +static void includeFile(OutputList &ol,const char *fileName,bool quiet) +{ + //FileInfo *f; + bool ambig; + FileDef *fd; + if ((fd=findFileDef(&exampleNameDict,fileName,ambig))) + { + currentIncludeFile=fileToString(fd->absFilePath()); + includeFileOffset=0; + includeFileLength=currentIncludeFile.length(); + OutputList codeFrag(&ol); + parseCode(codeFrag,0,currentIncludeFile,exampleDoc,exampleName); + if (!quiet) + { + ol.startCodeFragment(); + ol+=codeFrag; + ol.endCodeFragment(); + } + } + else if (ambig) + { + warn("Include file name %s is ambigious.\n",fileName); + warn("Possible candidates:\n"); + //includeFileList.writeMatches(fileName); + showFileDefMatches(&exampleNameDict,fileName); + } + else + { + warn("Warning: example file %s is not found. ",fileName); + warn("Check your EXAMPLE_PATH\n"); + } +} + +static void verbIncludeFile(OutputList &ol,const char *name) +{ + //FileInfo *f; + bool ambig; + FileDef *fd; + if ((fd=findFileDef(&exampleNameDict,name,ambig))) + { + ol.startCodeFragment(); + ol.codify(fileToString(fd->absFilePath())); + ol.endCodeFragment(); + } + else if (ambig) + { + warn("Include file name %s is ambigious.\n",name); + warn("Possible candidates:\n"); + showFileDefMatches(&exampleNameDict,name); + } + else + { + warn("Warning: example file %s is not found. ",name); + warn("Check your EXAMPLE_PATH\n"); + } +} + + +static QString stripQuotes(const char *s) +{ + QString 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 QString stripKnownExtensions(const char *text) +{ + QString result=text; + if (result.right(4)==".tex") result=result.left(result.length()-4); + else if (result.right(5)==".html") result=result.left(result.length()-5); + //printf("%s stripKnowExtensions(%s)\n",result.data(),text); + return result; +} + +static void skipLine(OutputList &ol,const char *key) +{ + bool found=FALSE; + while (!found) + { + QString s; + char c; + while ( includeFileOffset<includeFileLength && + (c=currentIncludeFile[includeFileOffset++])!='\n' && c!=0 + ) s+=c; + if (s.find(key)!=-1) + { + found=TRUE; + ol.writeString(" "); + parseCode(ol,className,s,exampleDoc,exampleName); + ol.writeString("\n"); + } + else if (includeFileOffset==includeFileLength) found=TRUE; + } +} + +static void skipUntil(const char *key) +{ + bool found=FALSE; + while (!found) + { + QString s; + int i=includeFileOffset; + char c; + while ( i<includeFileLength && + (c=currentIncludeFile[i++])!='\n' && c!=0 + ) s+=c; + if (s.find(key)!=-1 || i==includeFileLength) + { + found=TRUE; + } + else + { + includeFileOffset=i; + } + } +} + +static void showLine(OutputList &ol,const char *key) +{ + QString s; + char c; + bool found=FALSE; + while (!found) + { + while ( includeFileOffset<includeFileLength && + (c=currentIncludeFile[includeFileOffset++])!='\n' && c!=0 + ) s+=c; + if (s.stripWhiteSpace().length()>0 || + includeFileOffset==includeFileLength) found=TRUE; + } + if (s.find(key)!=-1) + { + ol.writeString(" "); + parseCode(ol,className,s,exampleDoc,exampleName); + ol.writeString("\n"); + } +} + +static void showUntil(OutputList &ol,const char *key) +{ + bool found=FALSE; + while (!found) + { + QString s; + char c; + while ( includeFileOffset<includeFileLength && + (c=currentIncludeFile[includeFileOffset++])!='\n' && c!=0 + ) s+=c; + if (s.stripWhiteSpace().length()>0) + { + ol.writeString(" "); + parseCode(ol,className,s,exampleDoc,exampleName); + ol.writeString("\n"); + if (s.find(key)!=-1) found=TRUE; + } + if (includeFileOffset==includeFileLength) found=TRUE; + } +} + +static void newDocState(); + +//----------------------------------------------------------------- + +static bool inBlock() +{ + return inParamBlock || inSeeBlock || inReturnBlock || inAuthorBlock || + inVersionBlock || inDateBlock || inWarningBlock || inBugBlock || + inParBlock || inExceptionBlock; +} + +static void endBlock() +{ + outDoc->endDescList(); + inParamBlock=inSeeBlock=inReturnBlock=inAuthorBlock= + inVersionBlock=inDateBlock=inBugBlock=inWarningBlock= + inParBlock=inExceptionBlock=FALSE; +} + +static void addSection() +{ + //printf("New section pageName=%s label=%s title=%s\n", + // current->name.data(),sectionLabel.data(),sectionTitle.data()); + SectionInfo *si=new SectionInfo(current->name, + sectionLabel,sectionTitle,isSubsection); + sectionDict.insert(sectionLabel,si); +} + + +// Adds a formula text to the list/dictionary of formulas if it was +// not already added. Returns the label of the formula. +static QString addFormula() +{ + QString formLabel; + QString fText=formulaText.simplifyWhiteSpace(); + Formula *f=0; + if ((f=formulaDict[fText])==0) + { + f = new Formula(fText); + formulaList.append(f); + formulaDict.insert(fText,f); + formLabel.sprintf("\\form#%d",f->getId()); + formulaNameDict.insert(formLabel,f); + } + else + { + formLabel.sprintf("\\form#%d",f->getId()); + } + return formLabel; +} + +/* ----------------------------------------------------------------- + */ +#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; +} + +//ATTR ((({BN}+[^\>]+)/">")?) +%} + +BN [ \t\n\r] +BL [ \t\r]*"\n" +B [ \t] +BS ^(({B}*"//")?)(({B}*"*"+)?){B}* +FILE ([a-z_A-Z0-9\.\\:\/\-\+]+)|("\""[^\n\"]+"\"") +FILEMASK [a-z_A-Z0-9\.\\:\/\-\+]+"."[a-z_A-Z0-9\.\-\+]*[a-z_A-Z0-9\-\+] +ID [a-z_A-Z][a-z_A-Z0-9]* +SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?) +SCOPENAME (({ID}?{BN}*"::"{BN}*)*)((~{BN}*)?{ID}) +SCOPEMASK {ID}?(("::"|"#")?(~)?{ID})+ +URLMASK [a-z_A-Z0-9\~\:\@\#\.\-\+\/]+ +ATTR ({B}+[^>\n]*)? +A [aA] +BOLD [bB] +BODY [bB][oO][dD][yY] +BR [bB][rR] +EM [eE][mM] +CENTER [cC][eE][nN][tT][eE][rR] +CODE [cC][oO][dD][eE] +DL [dD][lL] +DD [dD][dD] +DT [dD][tT] +DFN [dD][fF][nN] +FORM [fF][oO][rR][mM] +H1 [hH]1 +H2 [hH]2 +H3 [hH][3-6] +HEAD [hH][eE][aA][dD] +HR [hH][rR] +HREF [hH][rR][eE][fF] +I [iI] +IMG [iI][mM][gG] +INPUT [iI][nN][pP][uU][tT] +LI [lL][iI] +META [mM][eE][tT][aA] +MULTICOL [mM][uU][lL][tT][iI][cC][oO][lL] +NAME [nN][aA][mM][eE] +OL [oO][lL] +P [pP] +PRE [pP][rR][eE] +SMALL [sS][mM][aA][lL][lL] +STRONG [sS][tT][rR][oO][nN][gG] +SUB [sS][uU][bB] +SUP [sS][uU][pP] +SRC [sS][rR][cC] +TABLE [tT][aA][bB][lL][eE] +TITLE [tT][iI][tT][lL][eE] +TD [tT][dD] +TR [tT][rR] +TT [tT][tT] +UL [uU][lL] +VAR [vV][aA][rR] + +%x Define +%x DefineArg +%x DefineEnd +%x Include +%x ClassName +%x ClassVar +%x Bases +%x NextSemi +%x FindMembers +%x FindMemberName +%x FindFields +%x FindFieldArg +%x Function +%x FuncRound +%x ExcpRound +%x FuncQual +%x Operator +%x Array +%x Curly +%x Using +%x NameSpaceDocArg1 +%x SkipCurly +%x SkipCurlyCpp +%x SkipString +%x SkipInits +%x SkipCPP +%x SkipCPPBlock +%x SkipComment +%x SkipCxxComment +%x SkipBlock +%x SkipCode +%x Sharp +%x SkipSharp +%x SkipRound +%x TypedefName +%x Comment +%x Doc +%x JavaDoc +%x ClassDoc +%x LineDoc +%x DefLineDoc +%x ClassDocArg1 +%x ClassDocArg2 +%x ClassDocArg3 +%x ClassDocFunc +%x ClassDocFuncPtr +%x ClassDocFuncQual +%x ClassDocFuncExc +%x ClassDocDefine +%x ClassDocRelates +%x ClassDocBrief +%x ClassDocOverload +%x ClassDefineArgs +%x GroupDocArg1 +%x GroupDocArg2 +%x GroupName +%x AfterDoc +%x AfterDocBrief +%x AfterDocLine +%x PageDoc +%x PageDocTitle +%x PageDocArg1 +%x PageDocArg2 +%x FileDocArg1 +%x FileDocArg2 +%x ExampleDoc +%x ExampleDocArg1 +%x EnumDoc +%x EnumDocArg1 +%x FuncPtr +%x EndFuncPtr +%x FuncFunc +%x FuncFuncEnd +%x FuncFuncType +%x MemberSpec +%x MemberSpecSkip +%x SkipVerbatim +%x DocScan +%x DocParam +%x DocException +%x DocHtmlScan +%x DocLatexScan +%x DocEmphasis +%x DocBold +%x DocCode +%x DocCodeBlock +%x DocInternal +%x DocLink +%x DocLinkText +%x DocSkipWord +%x DocInclude +%x DocDontInclude +%x DocDescItem +%x DocHtmlLink +%x DocHtmlAnchor +%x DocHtmlHref1 +%x DocHtmlHref2 +%x DocBaseClass +%x DocSkiplineKey +%x DocSkipKey +%x DocLineKey +%x DocUntilKey +%x DocKeyEnd +%x DocPar +%x DocRefName +%x DocVerbatim +%x DocVerbInc +%x DocIndexWord +%x DocRef +%x DocRefItem +%x DocRefItemName +%x SectionLabel +%x SectionTitle +%x EndTemplate +%x CopyArgString +%x CopyArgRound +%x CopyArgSharp +%x ReadFuncArgType +%x ReadTempArgs +%x Specialization +%x DocSkipHtmlComment +%x ReadFormulaShort +%x ReadFormulaLong + +%% + +<*>\x06[^\x06]*\x06 { // new file + yyLineNr= 1 ; + int i; + for( i = 0 ; yytext[i+1] != 6 ; i++ ) + yyFileName[i] = yytext[i+1] ; + yyFileName[i] = 0 ; + msg("Parsing file %s...\n",yyFileName); + current_root = global_root ; + initParser(); + current->reset(); + int sec=guessSection(yyFileName); + if (sec) + { + current->name = yyFileName; + current->name = current->name; + current->section = sec; + current_root->addSubEntry(current); + current = new Entry; + } + BEGIN( FindMembers ); + } +<*>\x0d + /* +<DocScan>^{BL} { + if (insideArgumentList) + { + insideArgumentList=FALSE; + outDoc->endItemList(); + } + else + { + outDoc->newParagraph(); + } + if (inBlock()) endBlock(); + } + */ +<DocScan>"<!--" { BEGIN(DocSkipHtmlComment); } +<DocSkipHtmlComment>"--"[!]?">" { BEGIN(DocScan); } +<DocSkipHtmlComment>. +<DocScan>"©" { outDoc->writeCopyright(); } +<DocScan>""" { outDoc->writeQuote(); } +<DocScan>"&"[AEIOUYaeiouy]"uml;" { outDoc->writeUmlaut(yytext[1]); } +<DocScan>"&"[AEIOUYaeiouy]"acute;" { outDoc->writeAcute(yytext[1]); } +<DocScan>"&"[AEIOUaeiou]"grave;" { outDoc->writeGrave(yytext[1]); } +<DocScan>"&"[AEIOUaeiou]"circ;" { outDoc->writeCirc(yytext[1]); } +<DocScan>"&"[ANOano]"tilde;" { outDoc->writeTilde(yytext[1]); } +<DocScan,DocHtmlScan,DocLatexScan>"$("[a-z_A-Z]+")" { + QString envvar=&yytext[2]; + envvar=envvar.left(envvar.length()-1); + outDoc->docify(getenv(envvar)); + } +<DocScan>("\\"|"@")"htmlonly"/[^a-z_A-Z0-9] { + outDoc->disableAllBut(OutputGenerator::Html); + BEGIN(DocHtmlScan); + } +<DocHtmlScan>("\\"|"@")"endhtmlonly"/[^a-z_A-Z0-9] { + outDoc->enableAll(); + BEGIN(DocScan); + } +<DocScan>("\\"|"@")"latexonly"/[^a-z_A-Z0-9] { + outDoc->disableAllBut(OutputGenerator::Latex); + BEGIN(DocLatexScan); + } +<DocHtmlScan,DocLatexScan>"//"|"/*"|"*/" { + outDoc->writeString(yytext); + } +<DocHtmlScan,DocLatexScan>. { + char c[2]; + c[0]=*yytext;c[1]='\0'; + outDoc->writeString(c); + } +<DocLatexScan>("\\"|"@")"endlatexonly"/[^a-z_A-Z0-9] { + outDoc->enableAll(); + BEGIN(DocScan); + } +<DocScan>"\\postheader"/{BN} +<DocScan>"\\functionindex"/{BN} { writeMemberList(*outDoc); } +<DocScan>"\\classhierarchy"/{BN} { writeClassHierarchy(*outDoc); } +<DocScan>"\\annotatedclasslist"/{BN} { writeAnnotatedClassList(*outDoc); } +<DocScan>"\\headerfilelist"/{BN} { /*TODO: fix this writeHeaderFileList(*outDoc); */ } +<DocScan>"\\header"/{BN} { BEGIN( DocSkipWord ); } +<DocScan>"\\define"/{BN} { BEGIN( DocSkipWord ); } +<DocScan>("\\"|"@")"verbinclude"/{BN} { BEGIN( DocVerbInc ); } +<DocVerbInc>{FILE} { + verbIncludeFile(*outDoc,stripQuotes(yytext)); + BEGIN( DocScan ); + } +<DocScan>("\\"|"@")"verbatim"/[^a-z_A-Z0-9] { + outDoc->startCodeFragment(); + BEGIN(DocVerbatim); + } +<DocVerbatim>("\\"|"@")"endverbatim"/[^a-z_A-Z0-9] { + outDoc->endCodeFragment(); + BEGIN(DocScan); + } +<DocVerbatim>[^\n\\]*"\n" { + //printf("docifying: %s\n",yytext); + outDoc->codify(yytext); + } +<DocVerbatim>"\n"|"//"|"/*"|"*/" { + outDoc->codify(yytext); + } +<DocVerbatim>. { + //printf("char %c\n",*yytext); + char c[2];c[0]=*yytext;c[1]='\0'; + outDoc->codify(c); + } +<DocScan>("\\"|"@")"internal"/{BN} { + if (!internalDocsFlag) + { + outDoc->newParagraph(); + scanString(theTranslator->trForInternalUseOnly()+"\n"); + //outDoc->writeString("For internal use only.\n"); + BEGIN( DocInternal ); + } + } +<DocScan>"\\reimp"/{BN} { + outDoc->newParagraph(); + scanString(theTranslator->trReimplementedForInternalReasons()+"\n"); + } +<DocScan>("\\"|"@")"link"/{BN} { BEGIN( DocLink ); } +<DocSkipWord>[a-z_A-Z0-9.:()]+ { BEGIN( DocScan ); } +<DocLink>[a-z_A-Z0-9:#.~/()\-\+]+ { + linkRef = stripKnownExtensions(yytext); + linkText = ""; + BEGIN( DocLinkText ); + } +<DocLinkText>. { linkText += *yytext; } +<DocLinkText>"\n" { linkText += " "; } +<DocLink,DocLinkText>("\\"|"@")"endlink"/[^a-z_A-Z0-9] { // <- needed for things like \endlink. + generateLink(*outDoc,className,linkRef,inSeeBlock,linkText); + BEGIN( DocScan ); + } +<DocScan>"@ref"{B}+ { + BEGIN(DocRef); + } +<DocRef>{SCOPENAME} { + generateLink(*outDoc,className,yytext,TRUE,0); + BEGIN( DocScan ); + } +<DocScan>("\\"|"@")"endlink"/[^a-z_A-Z0-9] { warn("Warning: \\endlink without \\link " + "in documentation of %s\n", refName.data()); + } +<DocScan>("\\"|"@")"addindex"/{BN} { + BEGIN(DocIndexWord); + } +<DocScan>"\\form#"[0-9]+ { + Formula *formula=formulaNameDict[yytext]; + if (formula) + { + QString formName; + formName.sprintf("form-%d.gif",formula->getId()); + outDoc->writeFormula(formName,formula->getFormulaText()); + } + } +<DocIndexWord>[^\n\t ]+ { + //printf("Adding %s to index\n",yytext); + outDoc->addToIndex(yytext,0); + BEGIN(DocScan); + } +<DocScan>("\\"|"@")"arg"{BN}+ { + if (insideArgumentList) + { + outDoc->writeListItem(); + } + else + { + outDoc->startItemList(); + outDoc->writeListItem(); + insideArgumentList=TRUE; + } + } +<DocScan>("\\"|"@")"par"{B}+ { + BEGIN(DocPar); + } +<DocPar>[^\n]*{BN}+ { + endArgumentList(); + if (inBlock()) endBlock(); + inParBlock=TRUE; + outDoc->startDescList(); + outDoc->startBold(); + outDoc->docify(((QString)yytext).stripWhiteSpace()); + outDoc->endBold(); + outDoc->endDescTitle(); + outDoc->writeDescItem(); + BEGIN(DocScan); + } +<DocScan>("\\"|"@")"warning"{BN}+ { + endArgumentList(); + if (!inWarningBlock) + { + if (inBlock()) endBlock(); + inWarningBlock=TRUE; + outDoc->startDescList(); + //outDoc->writeBoldString("Warning: "); + outDoc->startBold(); + scanString(theTranslator->trWarning()+": "); + outDoc->endBold(); + outDoc->endDescTitle(); + outDoc->writeDescItem(); + } + else + { + outDoc->writeDescItem(); + } + } +<DocScan>("\\"|"@")"bug"{BN}+ { + endArgumentList(); + if (!inBugBlock) + { + if (inBlock()) endBlock(); + inBugBlock=TRUE; + outDoc->startDescList(); + //outDoc->writeBoldString("Bugs and limitations: "); + outDoc->startBold(); + scanString(theTranslator->trBugsAndLimitations()+": "); + outDoc->endBold(); + outDoc->endDescTitle(); + outDoc->writeDescItem(); + } + else + { + outDoc->writeDescItem(); + } + } +<DocScan>("\\"|"@")"version"{BN}+ { + endArgumentList(); + if (!inVersionBlock) + { + if (inBlock()) endBlock(); + inVersionBlock=TRUE; + outDoc->startDescList(); + //outDoc->writeBoldString("Version: "); + outDoc->startBold(); + scanString(theTranslator->trVersion()+": "); + outDoc->endBold(); + outDoc->endDescTitle(); + outDoc->writeDescItem(); + } + else + { + outDoc->writeDescItem(); + } + } +<DocScan>("\\"|"@")"date"{BN}+ { + endArgumentList(); + if (!inDateBlock) + { + if (inBlock()) endBlock(); + inDateBlock=TRUE; + outDoc->startDescList(); + //outDoc->writeBoldString("Date: "); + outDoc->startBold(); + scanString(theTranslator->trDate()+": "); + outDoc->endBold(); + outDoc->endDescTitle(); + outDoc->writeDescItem(); + } + else + { + outDoc->writeDescItem(); + } + } +<DocScan>("\\"|"@")"author"{BN}+ { + endArgumentList(); + if (!inAuthorBlock) + { + if (inBlock()) endBlock(); + inAuthorBlock=TRUE; + outDoc->startDescList(); + //outDoc->writeBoldString("Author(s): "); + outDoc->startBold(); + scanString(theTranslator->trAuthors()+": "); + outDoc->endBold(); + outDoc->endDescTitle(); + outDoc->writeDescItem(); + } + else + { + outDoc->docify(", "); + } + } +<DocScan>("\\"|"@")"return"{BN}+ { + endArgumentList(); + if (!inReturnBlock) + { + if (inBlock()) endBlock(); + inReturnBlock=TRUE; + outDoc->startDescList(); + //outDoc->writeBoldString("Returns: "); + outDoc->startBold(); + scanString(theTranslator->trReturns()+": "); + outDoc->endBold(); + outDoc->endDescTitle(); + outDoc->writeDescItem(); + } + } +<DocScan>("\\sa"|"@see"){BN}+ { + endArgumentList(); + if (!inSeeBlock) + { + if (inBlock()) endBlock(); + inSeeBlock=TRUE; + //firstSeeArg=TRUE; + //javaDocSee=!strcmp(yytext,"@see"); + outDoc->startDescList(); + //outDoc->writeBoldString("See also: "); + outDoc->startBold(); + scanString(theTranslator->trSeeAlso()+": "); + outDoc->endBold(); + outDoc->endDescTitle(); + outDoc->writeDescItem(); + } + else + { + outDoc->docify(", "); + } + } +<DocScan>("\\"|"@")"param"{BN}+ { + endArgumentList(); + if (!inParamBlock) + { + if (inBlock()) endBlock(); + inParamBlock=TRUE; + outDoc->startDescList(); + //outDoc->writeBoldString("Parameters: "); + outDoc->startBold(); + scanString(theTranslator->trParameters()+": "); + outDoc->endBold(); + outDoc->endDescTitle(); + } + BEGIN(DocParam); + } +<DocScan>("\\"|"@")"exception"{BN}+ { + endArgumentList(); + if (!inExceptionBlock) + { + if (inBlock()) endBlock(); + inExceptionBlock=TRUE; + outDoc->startDescList(); + //outDoc->writeBoldString("Exceptions: "); + outDoc->startBold(); + scanString(theTranslator->trExceptions()+": "); + outDoc->endBold(); + outDoc->endDescTitle(); + } + BEGIN(DocException); + } +<DocScan>"\\capt".* +<DocParam>{SCOPENAME} { + outDoc->writeDescItem(); + outDoc->startEmphasis(); + outDoc->docify(yytext); + outDoc->endEmphasis(); + outDoc->docify(" - "); + BEGIN(DocScan); + } +<DocException>{SCOPENAME} { + outDoc->writeDescItem(); + outDoc->startEmphasis(); + outDoc->docify(yytext); + outDoc->endEmphasis(); + outDoc->docify(" - "); + BEGIN(DocScan); + } +<DocScan>("\\"|"@")"section "{ID}"\n" { + QString secName=&yytext[9]; // skip "\section " + secName=secName.left(secName.length()-1); // remove \n + //printf("SectionName %s found\n",secName.data()); + SectionInfo *sec; + if ((sec=sectionDict[secName])) + { + //printf("Title %s\n",sec->title.data()); + outDoc->writeSection(sec->label,sec->title,sec->isSubsection); + } + } +<DocScan>"\\ref" { + BEGIN(DocRefName); + } +<DocScan>"\\refitem" { + BEGIN(DocRefItem); + } +<DocRefName>{ID} { + QString ref=yytext; + SectionInfo *sec; + if ((sec=sectionDict[ref])) + { + outDoc->writeSectionRef(sec->pageName,sec->label,sec->title); + } + else + { + warn("Warning: reference to unknown section %s!\n",yytext); + outDoc->writeBoldString("unknown reference!"); + } + BEGIN(DocScan); + } +<DocRefItem>{ID} { + sectionRef=yytext; + BEGIN(DocRefItemName); + } +<DocRefItemName>.*/"\n" { + SectionInfo *sec; + if ((sec=sectionDict[sectionRef])) + { + outDoc->writeSectionRefItem(sec->pageName,sec->label,yytext); + } + else + { + warn("Warning: reference to unknown section %s!\n",sectionRef.data()); + outDoc->writeBoldString("unknown reference!"); + } + BEGIN(DocScan); + } +<DocScan>("\\"|"@")"code"/{BN}+ { + outDoc->startCodeFragment(); + codeBlock.resize(0); + BEGIN( DocCodeBlock ); + } +<DocScan>("\\"|"@")"endcode"/[^a-z_A-Z0-9] { + warn("Warning: \\endcode without <PRE> or \\code " + "in the documentation of %s\n",refName.data()); + } +<DocScan>{SCOPEMASK}"("[a-z_A-Z,\<\> \t\*\&]+")" { + generateRef(*outDoc,className,yytext,inSeeBlock); + } +<DocScan>{SCOPEMASK}(("()")?) { + generateRef(*outDoc,className,yytext,inSeeBlock); + } +<DocScan>({SCOPEMASK}"::")?"operator"[^(\r\n.,]*"("[a-z_A-Z,\<\> \t\*\&]*")" { + QString oName=yytext; + generateRef(*outDoc,className, + removeRedundantWhiteSpace(oName),inSeeBlock); + } +<DocScan>({SCOPEMASK}"::")?"operator()("[a-z_A-Z,\<\> \t\*\&]*")" { + QString oName=yytext; + generateRef(*outDoc,className, + removeRedundantWhiteSpace(oName),inSeeBlock); + } +<DocScan>{FILEMASK} { + generateFileRef(*outDoc,yytext); + } +<DocCodeBlock>{BN}*("\\"|"@")"endcode"/[^a-z_A-Z0-9] { // needed to match things like \endcode. (note the dot) + parseCode(*outDoc,className,codeBlock,exampleDoc,exampleName); + //printf("Code block\n-------------\n%s\n--------------\n",codeBlock.data()); + outDoc->endCodeFragment(); + BEGIN( DocScan ); + } +<DocCodeBlock>"</"{PRE}{ATTR}">" { + parseCode(*outDoc,className,codeBlock,exampleDoc,exampleName); + //printf("Code block\n-------------\n%s\n--------------\n",codeBlock.data()); + outDoc->endCodeFragment(); + BEGIN( DocScan ); + } +<DocScan>("\\"|"@")"e"{BN}+ { BEGIN( DocEmphasis ); } +<DocScan>("\\"|"@")"a"{BN}+ { BEGIN( DocEmphasis ); } +<DocScan>("\\"|"@")"b"{BN}+ { BEGIN( DocBold ); } +<DocScan>("\\"|"@")"c"{BN}+ { BEGIN( DocCode ); } +<DocScan>("\\"|"@")"l"{BN}+ +<DocScan>("\\"|"@")"include"{BN}+ { BEGIN( DocInclude ); } +<DocScan>("\\"|"@")"dontinclude"{BN}+ { BEGIN( DocDontInclude ); } +<DocScan>("\\"|"@")"skip"{BN}+ { BEGIN( DocSkipKey ); } +<DocScan>("\\"|"@")"skipline"{BN}+ { BEGIN( DocSkiplineKey ); firstLine=TRUE; } +<DocScan>("\\"|"@")"line"{BN}+ { BEGIN( DocLineKey ); firstLine=TRUE; } +<DocScan>("\\"|"@")"until"{BN}+ { BEGIN( DocUntilKey ); firstLine=TRUE; } +<DocSkipKey>[^ \t\r\n]+ { + if (includeFileLength>0) + skipUntil(yytext); + BEGIN( DocScan ); + } +<DocLineKey>[^ \t\r\n]+ { + if (includeFileLength>0) + { + if (firstLine) outDoc->startCodeFragment(); + firstLine=FALSE; + showLine(*outDoc,yytext); + BEGIN( DocKeyEnd ); + } + else + { + BEGIN( DocScan ); + } + } +<DocSkiplineKey>[^ \t\r\n]+ { + if (includeFileLength>0) + { + if (firstLine) outDoc->startCodeFragment(); + firstLine=FALSE; + skipLine(*outDoc,yytext); + BEGIN( DocKeyEnd ); + } + else + { + BEGIN( DocScan ); + } + } +<DocUntilKey>[^ \t\r\n]+ { + if (includeFileLength>0) + { + if (firstLine) outDoc->startCodeFragment(); + firstLine=FALSE; + showUntil(*outDoc,yytext); + BEGIN( DocKeyEnd ); + } + else + { + BEGIN( DocScan ); + } + } +<DocKeyEnd>("\\"|"@")"line"{BN}+ { BEGIN(DocLineKey); } +<DocKeyEnd>("\\"|"@")"until"{BN}+ { BEGIN(DocUntilKey); } +<DocKeyEnd>("\\"|"@")"skipline"{BN}+ { BEGIN(DocSkiplineKey); } +<DocKeyEnd>\n +<DocKeyEnd>. { + unput(*yytext); + if (!firstLine) outDoc->endCodeFragment(); + BEGIN( DocScan ); + } +<DocScan>"<"{MULTICOL}{ATTR}">" +<DocScan>"</"{MULTICOL}{ATTR}">" +<DocScan>"<"{STRONG}{ATTR}">" { outDoc->startBold(); } +<DocScan>"</"{STRONG}{ATTR}">" { outDoc->endBold(); } +<DocScan>"<"{CENTER}{ATTR}">" { outDoc->startCenter(); } +<DocScan>"</"{CENTER}{ATTR}">" { outDoc->endCenter(); } +<DocScan>"<"{TABLE}{ATTR}">" { + startTable(); + /*outDoc->startTable();*/ } +<DocScan>"</"{TABLE}{ATTR}">" { + endTable(); + /*outDoc->endTable();*/ + } +<DocScan>"<"{INPUT}{ATTR}">" +<DocScan>"<"{SMALL}{ATTR}">" { outDoc->startSmall(); } +<DocScan>"</"{SMALL}{ATTR}">" { outDoc->endSmall(); } +<DocScan>"<"{META}{ATTR}">" +<DocScan>"<"{FORM}{ATTR}">" +<DocScan>"</"{FORM}{ATTR}">" +<DocScan>"<"{HEAD}{ATTR}">" +<DocScan>"</"{HEAD}{ATTR}">" +<DocScan>"<"{BODY}{ATTR}">" +<DocScan>"</"{BODY}{ATTR}">" +<DocScan>"<"{CODE}{ATTR}">" { outDoc->startTypewriter(); } +<DocScan>"</"{CODE}{ATTR}">" { outDoc->endTypewriter(); } +<DocScan>"<"{DFN}{ATTR}">" { outDoc->startTypewriter(); } +<DocScan>"</"{DFN}{ATTR}">" { outDoc->endTypewriter(); } +<DocScan>"<"{VAR}{ATTR}">" { outDoc->startEmphasis(); } +<DocScan>"</"{VAR}{ATTR}">" { outDoc->endEmphasis(); } +<DocScan>"<"{IMG}{ATTR}">" { outDoc->disableAllBut(OutputGenerator::Html); + outDoc->writeString(yytext); + outDoc->enableAll(); + } +<DocScan>"<"{PRE}{ATTR}">" { + outDoc->startCodeFragment(); + codeBlock.resize(0); + BEGIN( DocCodeBlock ); + } +<DocScan>"</"{PRE}{ATTR}">" { + warn("Warning: </PRE> without <PRE> or \\code" + "in the documentation of %s\n",refName.data()); + } +<DocScan>"<"{SUB}{ATTR}">" { outDoc->startSubscript(); } +<DocScan>"</"{SUB}{ATTR}">" { outDoc->endSubscript(); } +<DocScan>"<"{SUP}{ATTR}">" { outDoc->startSuperscript(); } +<DocScan>"</"{SUP}{ATTR}">" { outDoc->endSuperscript(); } +<DocScan>"<"{TR}{ATTR}">" { if (curTable) curTable->newRow(); } +<DocScan>"</"{TR}{ATTR}">" +<DocScan>"<"{TD}{ATTR}">" { if (curTable) curTable->newElem(); } +<DocScan>"</"{TD}{ATTR}">" +<DocScan>"<"{OL}{ATTR}">" { outDoc->startEnumList(); } +<DocScan>"</"{OL}{ATTR}">" { outDoc->endEnumList(); } +<DocScan>"<"{UL}{ATTR}">" { outDoc->startItemList(); } +<DocScan>"</"{UL}{ATTR}">" { outDoc->endItemList(); } +<DocScan>"<"{LI}{ATTR}">" { outDoc->writeListItem(); } +<DocScan>"</"{LI}{ATTR}">" +<DocScan>"<"{TT}{ATTR}">" { outDoc->startTypewriter(); } +<DocScan>"</"{TT}{ATTR}">" { outDoc->endTypewriter(); } +<DocScan>"<"{EM}{ATTR}">" { outDoc->startEmphasis(); } +<DocScan>"</"{EM}{ATTR}">" { outDoc->endEmphasis(); } +<DocScan>"<"{HR}{ATTR}">" { outDoc->writeRuler(); } +<DocScan>"<"{DL}{ATTR}">" { outDoc->startDescription(); } +<DocScan>"</"{DL}{ATTR}">" { outDoc->endDescription(); } +<DocScan>"<"{DT}{ATTR}">" { outDoc->startDescItem(); } +<DocScan>"</"{DT}{ATTR}">" +<DocScan>"<"{DD}{ATTR}">" { outDoc->endDescItem(); } +<DocScan>"</"{DD}{ATTR}">" +<DocScan>"<"{BR}{ATTR}">" { outDoc->lineBreak(); } +<DocScan>"<"{I}{ATTR}">" { outDoc->startEmphasis(); } +<DocScan>"</"{I}{ATTR}">" { outDoc->endEmphasis(); } +<DocScan>"</"{A}{ATTR}">" +<DocScan>"<"{A} { BEGIN(DocHtmlLink); } +<DocScan>"<"{BOLD}{ATTR}">" { outDoc->startBold(); } +<DocScan>"</"{BOLD}{ATTR}">" { outDoc->endBold(); } +<DocScan>"<"{P}{ATTR}">" { + if (inBlock()) endBlock(); + outDoc->newParagraph(); } +<DocScan>"</"{P}{ATTR}">" +<DocScan>"<"{H1}{ATTR}">" { outDoc->startTitle(); } +<DocScan>"</"{H1}{ATTR}">" { outDoc->endTitle(); } +<DocScan>"<"{H2}{ATTR}">" { outDoc->startSubsection(); } +<DocScan>"</"{H2}{ATTR}">" { outDoc->endSubsection(); } +<DocScan>"<"{H3}{ATTR}">" { outDoc->startSubsubsection(); } +<DocScan>"</"{H3}{ATTR}">" { outDoc->endSubsubsection(); } +<DocHtmlLink>{NAME}{BN}*"="{BN}*("\""?) { BEGIN(DocHtmlAnchor); } +<DocHtmlAnchor>[a-z_A-Z0-9.\-\+\/]+ { outDoc->writeAnchor(yytext); } +<DocHtmlLink>{HREF}{BN}*"="{BN}*("\""?) { + htmlUrl.resize(0); + htmlText.resize(0); + BEGIN(DocHtmlHref1); } +<DocHtmlHref1>{URLMASK}+ { + htmlUrl=yytext; + } +<DocHtmlHref1>">" { BEGIN(DocHtmlHref2); } +<DocHtmlHref2>[^<]* { htmlText+=yytext; } + /* +<DocHtmlHref2>\n { htmlText+='\n'; } + */ +<DocHtmlHref2>"<" { + outDoc->writeHtmlLink(htmlUrl,htmlText); + unput(*yytext); + BEGIN(DocScan); + } +<DocHtmlLink,DocHtmlAnchor>">" { BEGIN(DocScan); } + +<DocScan>"\\\\" { + outDoc->docify("\\"); + } +<DocScan>"\\@" { + outDoc->docify("@"); + } +<DocScan>"\\<" { + outDoc->docify("<"); + } +<DocScan>"\\>" { + outDoc->docify(">"); + } +<DocScan>"\\&" { + outDoc->docify("&"); + } +<DocScan>"\\$" { + outDoc->docify("$"); + } +<DocScan>"\\#" { + outDoc->docify("#"); + } +<DocScan>"\\%" { + outDoc->docify("%"); + } +<DocScan>"%"[a-zA-Z_0-9\-]+ { + outDoc->docify(yytext+1); + } +<DocEmphasis>[^ \t\n\r]+ { + outDoc->startEmphasis(); + generateRef(*outDoc,className,yytext,inSeeBlock); + outDoc->endEmphasis(); + BEGIN( DocScan ); + //addToIndex(yytext); + } +<DocBold>[^ \t\n\r]+ { + outDoc->startBold(); + generateRef(*outDoc,className,yytext,inSeeBlock); + outDoc->endBold(); + BEGIN( DocScan ); + } +<DocCode>[^ \t\n\r]+ { + outDoc->startTypewriter(); + generateRef(*outDoc,className,yytext,inSeeBlock); + outDoc->endTypewriter(); + BEGIN( DocScan ); + } +<DocInclude>{FILE} { + includeFile(*outDoc,stripQuotes(yytext),FALSE); + BEGIN( DocScan ); + } +<DocDontInclude>{FILE} { + includeFile(*outDoc,stripQuotes(yytext),TRUE); + BEGIN( DocScan ); + } +<DocCodeBlock>"//" { codeBlock += yytext; } +<DocCodeBlock>"/*" { codeBlock += yytext; } +<DocCodeBlock>\n { codeBlock += '\n'; } +<DocCodeBlock>[^\/\\\<\n]* { codeBlock += yytext; } +<DocCodeBlock>. { codeBlock += *yytext; } +<DocCode,DocEmphasis,DocScan,DocBold>"//" { + outDoc->docify(yytext); + } +<DocCode,DocEmphasis,DocScan,DocBold>"/*" { + outDoc->docify(yytext); + } +<DocCode,DocEmphasis,DocBold>"\n" { outDoc->writeChar('\n'); } +<DocScan>({B}*"\n"{B}*){2,} { + if (insideArgumentList) + { + insideArgumentList=FALSE; + outDoc->endItemList(); + } + else + { + outDoc->newParagraph(); + } + if (inBlock()) endBlock(); + } +<DocScan>{BN}+ { + outDoc->writeChar(' '); + } +<DocCode,DocEmphasis,DocBold,DocScan>. { + outDoc->writeChar(*yytext); + } +<NextSemi>"{" { BEGIN(SkipBlock); } +<SkipBlock>"{" { ++bracketCount ; } +<SkipBlock>"}" { if( bracketCount ) + --bracketCount ; + else + BEGIN( NextSemi ) ; + } +<NextSemi>\" { + lastStringContext=NextSemi; + BEGIN(SkipString); + } +<NextSemi>[;,] { + unput(*yytext); + BEGIN( FindMembers ) ; + } +<FindMembers>{B}*"signals"{BN}*":"{BN}* { current->sig = sig = TRUE; + current->slot = slot = FALSE; + 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"{BN}*":"{BN}* { + current->protection = protection = Public ; + current->slot = slot = TRUE; + current->sig = sig = FALSE; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount(); + } + +<FindMembers>{B}*"protected"{BN}*"slots"{BN}*":"{BN}* { + current->protection = protection = Protected ; + current->slot = slot = TRUE; + current->sig = sig = FALSE; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount(); + } + +<FindMembers>{B}*"private"{BN}*"slots"{BN}*":"{BN}* { + current->protection = protection = Private ; + current->slot = slot = TRUE; + current->sig = sig = FALSE; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount(); + } + +<FindMembers>{B}*"public"{BN}*":"{BN}* { + current->protection = protection = Public ; + current->slot = slot = FALSE; + current->sig = sig = FALSE; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount() ; + } +<FindMembers>{B}*"protected"{BN}*":"{BN}* { + current->protection = protection = Protected ; + current->slot = slot = FALSE; + current->sig = sig = FALSE; + 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->slot = slot = FALSE; + current->sig = sig = FALSE; + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + lineCount() ; + } + /* +<FindMembers>"inline" + */ +<FindMembers>{B}*"static"{BN}+ { //current->type += " static "; + current->stat = TRUE; + lineCount(); + } +<FindMembers>{B}*"extern"{BN}+ { + current->stat = FALSE; + lineCount(); + } +<FindMembers>{B}*"virtual"{BN}+ { current->type += " virtual "; + current->virt = Virtual; + lineCount(); + } +<FindMembers>{B}*"inline"{BN}+ { lineCount(); } +<FindMembers>{B}*"typename"{BN}+ { lineCount(); } +<FindMembers>{B}*"namespace"{BN}+ { + isTypedef=FALSE; + current->section = Entry::NAMESPACE_SEC; + current->type = "namespace" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + lineCount(); + BEGIN( ClassName ); + } +<FindMembers>{B}*(("typedef"{BN}+)?)"class"{BN}+ { + isTypedef=((QString)yytext).find("typedef")!=-1; + current->section = Entry::CLASS_SEC ; + addType( current ) ; + current->type += " class" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + lineCount() ; + BEGIN( ClassName ) ; + } +<FindMembers>{B}*(("typedef"{BN}+)?)"struct"{BN}+ { + isTypedef=((QString)yytext).find("typedef")!=-1; + current->section = Entry::STRUCT_SEC ; + addType( current ) ; + current->type += " struct" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + lineCount() ; + BEGIN( ClassName ) ; + } +<FindMembers>{B}*(("typedef"{BN}+)?)"union"{BN}+ { + isTypedef=((QString)yytext).find("typedef")!=-1; + current->section = Entry::UNION_SEC ; + addType( current ) ; + current->type += " union" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + lineCount() ; + BEGIN( ClassName ) ; + } +<FindMembers>{B}*(("typedef"{BN}+)?)"enum"{BN}+ { + isTypedef=((QString)yytext).find("typedef")!=-1; + current->section = Entry::ENUM_SEC ; + addType( current ) ; + current->type += " enum" ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + lineCount() ; + BEGIN( ClassName ) ; + } +<Operator>"("{BN}*")"{BN}*/"(" { + lineCount(); + current->name += yytext ; + current->name = current->name.simplifyWhiteSpace(); + BEGIN( FindMembers ) ; + } +<Operator>[^(] { + current->name += *yytext ; + } +<Operator>"<>" { /* skip guided templ specifiers */ } +<Operator>"(" { + current->name = current->name.simplifyWhiteSpace(); + unput(*yytext); + BEGIN( FindMembers ) ; + } +<FindMembers>"template"({BN}*)"<"/[>]? { + lineCount(); + if (current->tArgList) + { + //printf("scanner.l current->tArgList->clear() %p\n",current->tArgList); + current->tArgList->clear(); + } + else + { + current->tArgList = new ArgumentList; + current->tArgList->setAutoDelete(TRUE); + //printf("scanner.l new tArgList %p\n",current->tArgList); + } + templateStr="<"; + copyArgString=&templateStr; + currentArgumentContext = FindMembers; + //printf("Start template list\n"); + BEGIN( ReadTempArgs ); + } + /* +<FindMembers>({ID}{BN}*"::")*{BN}*"operator"{BN}*[<=]+ { + lineCount(); + addType( current ); + current->name = yytext; + } +<FindMembers>"operator"{BN}*"/"[=]?/[^/ *] { space added! + lineCount(); + addType( current ); + current->name = yytext; + } +<FindMembers>"operator"{BN}*"({B}*)"{BN}* /"(" { space added! + lineCount(); + addType( current ); + current->name = yytext; + } +<FindMembers>"operator"{BN}*[^(/]+ { + lineCount(); + addType( current ) ; + current->name = yytext ; + } + */ +<FindMembers>"using"{BN}+ { lineCount(); BEGIN(Using); } +<Using>";" { BEGIN(FindMembers); } +<FindMembers>{SCOPENAME}{BN}*"<>" { // guided template decl + QString n=yytext; + addType( current ); + current->name=n.left(n.length()-2); + } +<FindMembers>{SCOPENAME}{BN}*/"<" { + sharpCount=0; + lineCount(); + addType( current ); + current->name=yytext; + current->name=current->name.stripWhiteSpace(); + if (current->name.right(8)=="operator") + BEGIN( Operator ); + else + BEGIN( EndTemplate ); + } +<EndTemplate>"<" { + current->name+='<'; + sharpCount++; + } + /* +<EndTemplate>">"({BN}*"::"{SCOPENAME})? { + */ +<EndTemplate>">" { + current->name+=*yytext; + if (--sharpCount<=0) + { + //printf("Found %s\n",current->name.data()); + BEGIN(FindMembers); + } + } +<EndTemplate>">"{BN}*"(" { + lineCount(); + current->name+='>'; + if (--sharpCount<=0) + { + current->args = "("; + currentArgumentContext = FuncQual; + copyArgString=¤t->args; + //printf("Found %s\n",current->name.data()); + BEGIN( ReadFuncArgType ) ; + } + } +<EndTemplate>">"{BN}*/"::" { + lineCount(); + current->name+='>'; + if (--sharpCount<=0) + { + BEGIN(FindMemberName); + } + } +<EndTemplate>. { current->name+=*yytext; } +<FindMembers,FindMemberName>{SCOPENAME} { + lineCount(); + if (YY_START==FindMembers) + { + addType( current ) ; + current->name = yytext; + } + else + { + current->name += yytext; + } + QString tmp=yytext; + if (tmp.right(8)=="operator") + BEGIN( Operator ); + else + BEGIN(FindMembers); + } +<FindMembers>^{B}*"#" { lastCPPContext = YY_START; + BEGIN( SkipCPP ) ; + } +<FindMembers>^{B}*"#define" { + BEGIN( Define ); + } +<SkipCPP>. +<SkipCPP>\\[\r]*"\n"[\r]* { yyLineNr++ ; } +<SkipCPP>[\r]*\n[\r]* { yyLineNr++ ; + BEGIN( lastCPPContext) ; + } +<Define>{ID}/"(" { + current->name = yytext; + BEGIN( DefineArg ); + } +<DefineArg>")" { + //printf("Define with args\n"); + current->args += ')'; + BEGIN( DefineEnd ); + } +<DefineArg>. { + current->args += *yytext; + } +<Define>{ID} { + //printf("Define `%s' without args\n",yytext); + current->name = yytext; + BEGIN(DefineEnd); + } +<DefineEnd>\n { + //printf("End define\n"); + current->fileName = yyFileName; + current->startLine = yyLineNr; + 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 ; + current->protection = protection ; + current->sig = sig; + current->virt = virt; + current->stat = gstat; + current->slot = slot; + BEGIN(FindMembers); + } +<DefineEnd>\\\n +<DefineEnd>. + +<FindMembers>[*&]+ { current->name += yytext ; } +<FindMembers,MemberSpec,Function,NextSemi>";"{BN}*("/**"|"//!"|"/*!")"<" { + lineCount(); + current->doc.resize(0); + current->brief.resize(0); + lastAfterDocContext = YY_START; + afterDocTerminator = ';'; + if (yytext[yyleng-3]=='/') + BEGIN(AfterDocLine); + else if (yytext[yyleng-2]=='*') + BEGIN(AfterDocBrief); + else + BEGIN(AfterDoc); + } +<MemberSpec,FindFields,FindMembers,NextSemi>","{BN}*("/**"|"//!"|"/*!")"<" { + lineCount(); + current->doc.resize(0); + current->brief.resize(0); + lastAfterDocContext = YY_START; + afterDocTerminator = ','; + if (yytext[yyleng-3]=='/') + BEGIN(AfterDocLine); + else if (yytext[yyleng-2]=='*') + BEGIN(AfterDocBrief); + else + BEGIN(AfterDoc); + } +<DefineEnd,FindFields,FindFieldArg>{BN}*("/**"|"//!"|"/*!")"<" { + lineCount(); + current->doc.resize(0); + current->brief.resize(0); + lastAfterDocContext = YY_START; + if (YY_START==DefineEnd) + afterDocTerminator = '\n'; + else + afterDocTerminator = 0; + if (yytext[yyleng-3]=='/') + BEGIN(AfterDocLine); + else if (yytext[yyleng-2]=='*') + BEGIN(AfterDocBrief); + else + BEGIN(AfterDoc); + } +<FindMembers>"=" { + BEGIN(NextSemi); + } +<FindMembers>[:;,] { + QString oldType = current->type.copy(); + QString oldDocs = current->doc.copy(); + current->type=current->type.simplifyWhiteSpace(); + current->args=current->args.simplifyWhiteSpace(); + current->name=current->name.stripWhiteSpace(); + current->section = Entry::VARIABLE_SEC ; + current->fileName = yyFileName; + current->startLine = yyLineNr; + current_root->addSubEntry( current ) ; + current = new Entry ; + // variable found + current->section = Entry::EMPTY_SEC ; + current->protection = protection; + current->slot = slot = FALSE; + current->sig = sig = FALSE; + current->virt = Normal; + current->stat = gstat; + // skip expression or bitfield if needed + if ( *yytext == ':') + BEGIN( NextSemi ); + else + { + if ( *yytext == ',' ) + { + int i=oldType.length(); + while (i>0 && (oldType[i-1]=='*' || oldType[i-1]==' ')) i--; + current->type = oldType.left(i); + current->doc = oldDocs; + } + BEGIN( FindMembers ) ; + } + } + +<FindMembers>"[" { current->args += yytext ; + sharpCount=1; + BEGIN( Array ) ; + } +<Array>"]" { current->args += *yytext ; + if (--sharpCount<=0) + BEGIN( FindMembers ) ; + } +<Array>"[" { current->args += *yytext ; + sharpCount++; + } +<Array>. { current->args += *yytext ; } + +<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} { + current->name = yytext; + } +<FindFields>"=" { + BEGIN(FindFieldArg); + } +<FindFields>"," { + //printf("adding `%s' `%s' `%s' to enum `%s'\n", + // current->type.data(), current->name.data(), + // current->args.data(), current_root->name.data()); + current->fileName = yyFileName; + current->startLine = yyLineNr; + 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); + current = new Entry(*current); + // add to the scope surrounding the enum (copy!) + current_root->parent->addSubEntry(current); + current = new Entry ; + current->protection = protection ; + current->sig = sig; + current->virt = virt; + current->stat = gstat; + current->slot = slot; + } +<FindFieldArg>"," { unput(*yytext); BEGIN(FindFields); } +<Curly>[^\r\n{}"/]* { current->program += yytext ; } +<Curly>"//".* { current->program += yytext ; } +<Curly>\"[^\r\n"]*\" { current->program += yytext ; } +<Curly>"/*"{B}* { current->program += yytext ; + lastContext = Curly ; + BEGIN( Comment ) ; + } +<Curly>"/*"{BL} { current->program += yytext ; + ++yyLineNr ; + lastContext = Curly ; + BEGIN( Comment ) ; + } +<Curly>"{" { current->program += yytext ; + ++bracketCount ; + } +<Curly>"}" { if ( bracketCount ) + { + current->program += yytext ; + --bracketCount ; + } + else + { + QString &cn = current->name; + QString &rn = current_root->name; + //printf("current->name=`%s' current_root->name=`%s'\n", + // cn.data(),rn.data()); + if (cn && cn[0]!='@' && + (current_root->section & Entry::SCOPE_MASK)) + { + cn.prepend(rn+"::"); + } + if (isTypedef && cn.length()==0) + { + //printf("Typedef Name\n"); + BEGIN( TypedefName ); + } + else + { + if (current->section == Entry::ENUM_SEC) + { + current->program+=','; // add field terminator + } + // add compound definition to the tree + current->args = current->args.simplifyWhiteSpace(); + current->type = current->type.simplifyWhiteSpace(); + current->name = current->name.stripWhiteSpace(); + //printf("adding `%s' `%s' `%s' brief=%s\n",current->type.data(),current->name.data(),current->args.data(),current->brief.data()); + current_root->addSubEntry( current ) ; + current = new Entry(*current); + if (current->section == Entry::NAMESPACE_SEC) + { // a namespace ends with a closing bracket + current->reset(); + current->protection = protection ; + current->sig = sig; + current->virt = virt; + current->stat = gstat; + current->slot = slot; + BEGIN( FindMembers ) ; + } + else + BEGIN( MemberSpec ) ; + } + } + } +<TypedefName>{ID} { + if (current->section == Entry::ENUM_SEC) + { + current->program+=","; // add field terminator + } + current->name=yytext; + if (current_root->section & Entry::SCOPE_MASK) + { + current->name.prepend(current_root->name+"::"); + } + 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 ) ; + current = new Entry; + current->protection = protection ; + current->sig = sig; + current->virt = virt; + current->stat = gstat; + current->slot = slot; + BEGIN(MemberSpecSkip); + } +<MemberSpec>([*&]*{BN}*)*{ID}("["[a-z_A-Z0-9]*"]")* { // the [] part could be improved. + lineCount(); + int i=0,l=yyleng,j; + while (i<l && (!isalpha(yytext[i]))) i++; + msName = yytext; + msName = msName.right(msName.length()-i); + j=msName.find("["); + if (j!=-1) + { + msArgs=msName.right(msName.length()-j); + msName=msName.left(j); + } + msType = yytext; msType=msType.left(i); + } +<MemberSpec>[,;] { + if (msName.length()>0) + { + Entry *varEntry=new Entry; + varEntry->protection = current->protection ; + varEntry->sig = current->sig; + varEntry->virt = current->virt; + varEntry->stat = current->stat; + varEntry->slot = current->slot; + varEntry->section = Entry::VARIABLE_SEC; + varEntry->name = msName.stripWhiteSpace(); + varEntry->type = current->type.simplifyWhiteSpace()+" "; + varEntry->args = msArgs; //current->args.simplifyWhiteSpace(); + //if (current->name.length()>0 && current->name[0]!='@' && + // current->parent->section & Entry::COMPOUND_MASK) + // varEntry->type+=current->parent->name+"::"; + if (isTypedef) + varEntry->type.prepend("typedef "); + varEntry->type+=current->name+msType; + varEntry->fileName = yyFileName; + varEntry->startLine = yyLineNr; + varEntry->doc = current->doc.copy(); + varEntry->brief = current->brief.copy(); + //printf("Add: type=`%s',name=`%s',args=`%s'\n", + // varEntry->type.data(),varEntry->name.data(),varEntry->args.data()); + current_root->addSubEntry(varEntry); + } + if (*yytext==';') + { + msType.resize(0); + msName.resize(0); + msArgs.resize(0); + isTypedef=FALSE; + current->reset(); + current->protection = protection ; + current->sig = sig; + current->virt = virt; + current->stat = gstat; + current->slot = slot; + BEGIN( FindMembers ); + } + } +<MemberSpec>"=" { BEGIN(MemberSpecSkip); } +<MemberSpecSkip>"{" { + bracketCount=0; + lastCurlyContext = MemberSpecSkip; + BEGIN(SkipCurly); + } +<MemberSpecSkip>"," { BEGIN(MemberSpec); } +<MemberSpecSkip>";" { unput(';'); BEGIN(MemberSpec); } +<Curly>\n { current->program += yytext ; + yyLineNr++ ; + } +<Curly>. { current->program += yytext ; } + +<FindMembers>"("({ID}{BN}*"::"{BN}*)*("*"{BN}*)+ { + lineCount(); + addType(current); + funcPtrType=yytext; + //current->type += yytext; + BEGIN( FuncPtr ); + } +<FuncPtr>{SCOPENAME} { + current->name = yytext; + BEGIN( EndFuncPtr ); + } +<FuncPtr>. { + //printf("Error: FuncPtr `%c' unexpected at line %d of %s\n",*yytext,yyLineNr,yyFileName); + } +<EndFuncPtr>")"{BN}*/";" { // a variable with extra braces + lineCount(); + current->type+=funcPtrType.data()+1; + BEGIN(FindMembers); + } +<EndFuncPtr>")"{BN}*/"(" { // a variable function + lineCount(); + current->type+=funcPtrType+")"; + BEGIN(FindMembers); + } +<EndFuncPtr>"(" { // a function returning a function + current->args += *yytext ; + bracketCount=0; + BEGIN( FuncFunc ); + } +<EndFuncPtr>")" { + BEGIN(FindMembers); + } +<FuncFunc>"(" { + current->args += *yytext ; + ++bracketCount; + } +<FuncFunc>")" { + current->args += *yytext ; + if ( bracketCount ) + --bracketCount; + else + { + BEGIN(FuncFuncEnd); + } + } +<FuncFuncEnd>")"{BN}*"(" { + lineCount(); + current->type+=funcPtrType+")("; + BEGIN(FuncFuncType); + } +<FuncFuncEnd>")"{BN}*/[;{] { + lineCount(); + current->type+=funcPtrType.data()+1; + BEGIN(Function); + } +<FuncFuncEnd>. { + current->args += *yytext; + } +<FuncFuncType>"(" { + current->type += *yytext; + bracketCount++; + } +<FuncFuncType>")" { + current->type += *yytext; + if (bracketCount) + --bracketCount; + else + BEGIN(Function); + } +<FuncFuncType>{BN}*","{BN}* { lineCount() ; current->type += ", " ; } +<FuncFuncType>{BN}+ { lineCount() ; current->type += ' ' ; } +<FuncFuncType>. { + current->type += *yytext; + } +<FindMembers>"(" { current->args = yytext; + currentArgumentContext = FuncQual; + copyArgString=¤t->args; + BEGIN( ReadFuncArgType ) ; + //printf(">>> Read function arguments!\n"); + } + /* +<FindMembers>"("{BN}*("void"{BN}*)?")" { + lineCount(); + current->args = "()"; + BEGIN( FuncQual ); + } + */ + + /*- Function argument reading rules ---------------------------------------*/ + +<ReadFuncArgType>[^ \/\r\t\n\)\(\"\']+ { *copyArgString+=yytext; } +<CopyArgString>[^\n\\\"\']+ { *copyArgString+=yytext; } +<CopyArgRound>[^\/\n\)\(\"\']+ { *copyArgString+=yytext; } +<ReadFuncArgType,ReadTempArgs>{BN}* { + *copyArgString+=" "; + lineCount(); + } +<ReadFuncArgType,CopyArgRound,CopyArgSharp,ReadTempArgs>\" { + *copyArgString+=*yytext; + lastCopyArgStringContext = YY_START; + BEGIN( CopyArgString ); + } +<ReadFuncArgType,ReadTempArgs>"(" { + *copyArgString+=*yytext; + argRoundCount=0; + lastCopyArgContext = YY_START; + BEGIN( CopyArgRound ); + } +<ReadFuncArgType>")" { + *copyArgString+=*yytext; + stringToArgumentList(*copyArgString,current->argList); + BEGIN( currentArgumentContext ); + } +<ReadTempArgs>"<" { + *copyArgString+=*yytext; + argSharpCount=0; + BEGIN( CopyArgSharp ); + } +<ReadTempArgs>">" { + *copyArgString+=*yytext; + //printf("end template list %s\n",copyArgString->data()); + stringToArgumentList(*copyArgString,current->tArgList); + BEGIN( currentArgumentContext ); + } +<CopyArgRound>"(" { + argRoundCount++; + *copyArgString+=*yytext; + } +<CopyArgRound>")" { + *copyArgString+=*yytext; + if (argRoundCount>0) + argRoundCount--; + else + BEGIN( lastCopyArgContext ); + } +<CopyArgSharp>"<" { + argSharpCount++; + *copyArgString+=*yytext; + } +<CopyArgSharp>">" { + *copyArgString+=*yytext; + if (argRoundCount>0) + argRoundCount--; + else + BEGIN( ReadTempArgs ); + } +<CopyArgString>\\. { + *copyArgString+=yytext; + } +<CopyArgString>\" { + *copyArgString+=*yytext; + BEGIN( lastCopyArgStringContext ); + } +<ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSharp>"'"\\[0-7]{1,3}"'" { *copyArgString+=yytext; } +<ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSharp>"'"\\."'" { *copyArgString+=yytext; } +<ReadFuncArgType,ReadTempArgs,CopyArgRound,CopyArgSharp>"'"."'" { *copyArgString+=yytext; } +<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgRound,CopyArgSharp>\n { yyLineNr++; *copyArgString+=*yytext; } +<ReadFuncArgType,ReadTempArgs,CopyArgString,CopyArgRound,CopyArgSharp>. { *copyArgString+=*yytext; } + + + + /*------------------------------------------------------------------------*/ + + +<FuncRound>"(" { current->args += *yytext ; + ++bracketCount ; + } +<FuncRound>")" { current->args += *yytext ; + if ( bracketCount ) + --bracketCount ; + else + BEGIN( FuncQual ) ; + } + /* +<FuncQual>"#" { lastCPPContext = YY_START; + BEGIN(SkipCPP); + } + */ +<FuncQual>[{:;] { unput(*yytext); BEGIN( Function ); } +<FuncQual>{BN}*"const"{BN}* { + lineCount() ; + current->args += " const "; + current->argList->constSpecifier=TRUE; + } +<FuncQual>{BN}*"volatile"{BN}* { + lineCount() ; + current->args += " volatile "; + current->argList->volatileSpecifier=TRUE; + } +<FuncQual>{BN}*"="{BN}*"0"{BN}* { + lineCount() ; + current->args += " = 0"; + current->virt = Pure; + current->argList->pureSpecifier=TRUE; + } +<FuncRound,FuncFunc>{BN}*","{BN}* { + lineCount() ; + current->args += ", " ; + } +<FuncQual,FuncRound,FuncFunc>{BN}+ { + lineCount() ; + current->args += ' ' ; + } +<FuncQual,FuncRound,FuncFunc>. { current->args += *yytext; } +<FuncQual>{BN}*"throw"{BN}*"(" { + current->exception = " throw(" ; + lineCount() ; + BEGIN( ExcpRound ) ; + } +<ExcpRound>"(" { current->exception += *yytext ; + ++bracketCount ; + } +<ExcpRound>")" { current->exception += *yytext ; + if ( bracketCount ) + --bracketCount ; + else + BEGIN( FuncQual ) ; + } +<ExcpRound>. { + current->exception += yytext; + } +<Function>"(" { current->type += current->name ; + current->name = current->args ; + current->args = yytext ; + BEGIN( FuncRound ) ; + } +<Function>"#" { lastCPPContext = YY_START; + BEGIN(SkipCPP); + } +<Function>[:;{] { + current->name=current->name.simplifyWhiteSpace(); + current->type=current->type.simplifyWhiteSpace(); + current->args=current->args.simplifyWhiteSpace(); + QString &cn=current->name; + QString &rn=current_root->name; + //printf("current_root->name=`%s'\n",rn.data()); + //printf("Function: `%s' `%s' `%s'\n",current->type.data(),cn.data(),current->args.data()); + int i; + if ((i=cn.findRev("::"))!=-1) // name contains scope + { + if (cn.left(i)==rn.right(i)) // scope name is redundant + { + cn=cn.right(cn.length()-i-2); // strip scope + //printf("new name=`%s'\n",cn.data()); + } + } + //if (cname.left(current_root->name.length()+2)==current_root->name+"::") + //{ // strip redundant scope + // current->name=current->name.right(current->name.length()-current_root->name.length()-2); + // printf("new name=`%s'\n",current->name.data()); + //} + current->fileName = yyFileName; + current->startLine = yyLineNr; + if (*yytext!=';' || (current_root->section&Entry::SCOPE_MASK) ) + { + int tempArg=current->name.find('<'); + QString tempName; + if (tempArg==-1) + tempName=current->name; + else + tempName=current->name.left(tempArg); + if (current->type.isNull() && tempName.find("operator")==-1 && + (tempName.find('*')!=-1 || tempName.find('&')!=-1)) + { + //printf("Scanner.l: found in class variable: `%s' `%s' `%s'\n", + // current->type.data(),current->name.data(),current->args.data()); + 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 ; + } + } + 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()); + QRegExp re("([^)])"); + if (!current->type.isNull() && current->type.find(re,0)!=-1) + { + //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; + } + } + current_root->addSubEntry(current); + current = new Entry ; + current->protection = protection; + current->sig = sig; + current->virt = virt; + current->stat = gstat; + current->slot = slot; + lastCurlyContext = FindMembers; + if( *yytext == '{' ) + BEGIN( SkipCurly ) ; + else if( *yytext == ':' ) + BEGIN( SkipInits ) ; + else + BEGIN( FindMembers ) ; + } + +<SkipInits>"{" { + lastCurlyContext = FindMembers; + BEGIN( SkipCurly ) ; + } +<SkipCurly,SkipCurlyCpp>"{" { ++bracketCount ; } +<SkipCurly,SkipCurlyCpp>"}" { if( bracketCount ) + --bracketCount ; + else + //BEGIN( FindMembers ) ; + BEGIN( lastCurlyContext ) ; + } +<SkipCurly>\'.\' +<SkipCurly>\" { + lastStringContext=SkipCurly; + BEGIN( SkipString ); + } +<SkipCurly>^{B}*"#" { BEGIN( SkipCurlyCpp ); } +<SkipCurlyCpp>\n { yyLineNr++; + lastCurlyContext = FindMembers; + BEGIN( SkipCurly ); + } +<SkipCurlyCpp>\\[\r]*"\n"[\r]* { yyLineNr++; } +<SkipCurlyCpp>"/*" +<SkipCurlyCpp>"*/" +<SkipCurlyCpp>"//" +<SkipString>\\. +<SkipString>\" { BEGIN( lastStringContext ); } +<SkipString>"/*" +<SkipString>"*/" +<SkipString>"//" + +<Bases,ClassName>";" { + current->section = Entry::EMPTY_SEC ; + current->type.resize(0) ; + current->name.resize(0) ; + current->args.resize(0) ; + current->argList->clear(); + BEGIN( FindMembers ) ; + } +<ClassName>{ID} { + current->name = yytext ; + BEGIN( ClassVar ); + } + /* +<ClassVar>{ID}/{BN}*"{" { // we probably got some M$ extension + current->name = yytext ; + } +<ClassVar>{ID}/{BN}*":" { // we probably got some M$ extension + current->name = yytext ; + } + */ +<ClassVar>{ID} { + if (isTypedef) + { + typedefDict.insert(yytext,new QString(current->name)); + current->type.prepend("typedef "); + } + current->type += ' ' ; + current->type += current->name ; + current->name = yytext ; + //BEGIN( FindMembers ); + } +<ClassVar>"(" { + roundCount=1; + lastSkipRoundContext=YY_START; + BEGIN(SkipRound); + } +<ClassVar>":" { + current->type.resize(0); + baseProt=Private; + baseVirt=Normal; + baseName.resize(0); + BEGIN( Bases ) ; + } +<ClassVar>[;=*&] { + unput(*yytext); + BEGIN( FindMembers ); + } +<ClassName,ClassVar>{B}*"{"{B}* { current->fileName = yyFileName ; + current->startLine = yyLineNr ; + if (current->name.length()==0 && !isTypedef) // anonymous compound + current->name.sprintf("@%d",anonCount++); + BEGIN( Curly ) ; + } +<Bases>"virtual" { baseVirt = Virtual; } +<Bases>"public" { baseProt = Public; } +<Bases>"protected" { baseProt = Protected; } +<Bases>"private" { baseProt = Private; } +<Bases>({ID}{BN}*"::"{BN}*)*{ID} { + //current->extends->append( + // new BaseInfo(yytext,baseProt,baseVirt) + //) ; + baseName += yytext; + current->args += ' ' ; + current->args += yytext ; + } +<ClassVar>"<" { current->name += *yytext; + sharpCount=1; + lastSkipSharpContext = YY_START; + specName = ¤t->name; + BEGIN ( Specialization ); + } +<Bases>"<" { baseName += *yytext; + sharpCount=1; + lastSkipSharpContext = YY_START; + specName = &baseName; + BEGIN ( Specialization ); + } +<Specialization>"<" { *specName += *yytext; + sharpCount++; + } +<Specialization>">" { + *specName += *yytext; + if (--sharpCount<=0) + BEGIN(lastSkipSharpContext); + } +<Specialization>{BN}+ { lineCount(); *specName +=' '; } +<Specialization>. { + *specName += *yytext; + } +<SkipSharp>"<" { ++sharpCount; } +<SkipSharp>">" { if (--sharpCount<=0) + BEGIN ( lastSkipSharpContext ); + } +<SkipRound>"(" { ++roundCount; } +<SkipRound>")" { if (--roundCount<=0) + BEGIN ( lastSkipRoundContext ); + } +<Bases>"," { current->args += ',' ; + if (baseName.length()>0) + current->extends->append( + new BaseInfo(baseName,baseProt,baseVirt) + ); + baseProt=Private; + baseVirt=Normal; + baseName.resize(0); + } +<Bases>{B}*"{"{B}* { current->fileName = yyFileName ; + current->startLine = yyLineNr ; + if (baseName.length()>0) + current->extends->append( + new BaseInfo(baseName,baseProt,baseVirt) + ); + BEGIN( Curly ) ; + } +<Comment>\n { current->program += yytext ; + yyLineNr++ ; + } +<Comment>"/*" { current->program += yytext ; } +<Comment>"//" { current->program += yytext ; } +<Comment>. { current->program += *yytext ; } +<Comment>.*"*/" { current->program += yytext ; + BEGIN( Curly ) ; + } + +<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator>("//"{B}*)?"/*!" { + removeSlashes=(yytext[1]=='/'); + tmpDocType=-1; + if (YY_START==Curly) + current->doc+="\n\n"; + else + current->doc.resize(0); + lastDocContext = YY_START; + if (current_root->section & Entry::SCOPE_MASK) + current->inside = current_root->name+"::"; + BEGIN( Doc ); + } +<FindMembers,FindFields,MemberSpec,FuncQual,SkipCurly,Operator>("//"{B}*)?"/**"/[^/*] { + removeSlashes=(yytext[1]=='/'); + if (current_root->section & Entry::SCOPE_MASK) + current->inside = current_root->name+"::"; + if (YY_START==Curly) + { + tmpDocType=-1; + current->doc+="\n\n"; + lastDocContext = Curly; + BEGIN( Doc ); + } + else + { + tmpDocType=Doc; + current->doc.resize(0); + current->brief.resize(0); + lastDocContext = YY_START; + BEGIN( JavaDoc ); + } + } +<FindMembers,FindFields,MemberSpec,FuncQual,Operator>"//!" { + current->brief.resize(0); + tmpDocType=-1; + lastDocContext = YY_START; + if (current_root->section & Entry::SCOPE_MASK) + current->inside = current_root->name+"::"; + BEGIN( LineDoc ); + } +<FindMembers,FindFields,MemberSpec,FuncQual,Operator>"///"/[^/] { + current->brief.resize(0); + tmpDocType=-1; + lastDocContext = YY_START; + if (current_root->section & Entry::SCOPE_MASK) + current->inside = current_root->name+"::"; + BEGIN( LineDoc ); + } +<FindMembers>"extern"{BN}+"\"C"("++")?"\""{BN}+("{")? +<FindMembers>"{" { + current->type.resize(0); + current->name.resize(0); + current->args.resize(0); + current->argList->clear(); + bracketCount=0; + BEGIN( SkipBlock ); + + } +<JavaDoc>"@short"{B}+ { + lastBriefContext=Doc; + BEGIN( ClassDocBrief ); + } +<JavaDoc>^(({B}*"*"+)?){BL} { + lineCount(); + if (!current->brief.stripWhiteSpace().isEmpty()) + { + BEGIN( tmpDocType ); + } + } +<JavaDoc>"@" { + unput(*yytext); + BEGIN(Doc); + } +<JavaDoc>^{B}*"*"+/[^/] { + //printf("---> removing %s\n",yytext); + } + /* +<JavaDoc>[^\n\@\*\.\\]+ { + current->brief+=yytext; + } + */ +<JavaDoc>. { + //printf("---> copy %c\n",*yytext); + current->brief+=*yytext; + } +<JavaDoc>\n { + current->brief+=' '; + lineCount(); + } +<JavaDoc>"."[ \t\r\n] { + lineCount(); + current->brief+="."; + BEGIN( tmpDocType ); + } +<JavaDoc>("\\"|"@")"internal" { + current->doc+="\\internal"; + BEGIN( tmpDocType ); + } +<Doc,JavaDoc>{B}*("\\"|"@")("fn"|"var"|"typedef"){B}* { + current->section = Entry::MEMBERDOC_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + BEGIN( ClassDocFunc ); + } +<LineDoc,Doc,JavaDoc>{B}*("\\"|"@")"def"{B}* { + nextDefContext = YY_START==LineDoc ? DefLineDoc : ClassDoc; + current->section = Entry::DEFINEDOC_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + BEGIN( ClassDocDefine ); + } +<Doc,JavaDoc>{B}*("\\"|"@")"overload"{B}* { + BEGIN( ClassDocOverload ); + } +<ClassDocOverload>{B}*"\n" { + QString orgDoc = current->doc; + current->doc = getOverloadDocs(); + current->doc += "\n\n"; + current->doc += orgDoc; + yyLineNr++; + BEGIN( Doc ); + } +<ClassDocOverload>. { unput(*yytext); + current->section = Entry::OVERLOADDOC_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + BEGIN( ClassDocFunc ); + } +<Doc,JavaDoc>{B}*("\\"|"@")"enum"{B}* { + current->section = Entry::ENUMDOC_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + BEGIN( EnumDocArg1 ); + } +<Doc,JavaDoc>{B}*("\\"|"@")"defgroup"{B}* { + current->section = Entry::GROUPDOC_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + BEGIN( GroupDocArg1 ); + } +<Doc,JavaDoc>{B}*("\\"|"@")"namespace"{B}* { + current->section = Entry::NAMESPACEDOC_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + BEGIN( NameSpaceDocArg1 ); + } +<Doc,JavaDoc>{B}*("\\"|"@")"class"{B}* { + current->section = Entry::CLASSDOC_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + BEGIN( ClassDocArg1 ); + } +<Doc,JavaDoc>{B}*("\\"|"@")"union"{B}* { + current->section = Entry::UNIONDOC_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + BEGIN( ClassDocArg1 ); + } +<Doc,JavaDoc>{B}*("\\"|"@")"struct"{B}* { + current->section = Entry::STRUCTDOC_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + BEGIN( ClassDocArg1 ); + } +<Doc,JavaDoc>{B}*("\\"|"@")"page"{B}* { + current->section = Entry::PAGEDOC_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + BEGIN( PageDocArg1 ); + } +<Doc,JavaDoc>{B}*("\\"|"@")"file"{B}* { + current->section = Entry::FILEDOC_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + BEGIN( FileDocArg1 ); + } +<Doc,JavaDoc>{B}*("\\"|"@")"example"{B}* { + current->section = Entry::EXAMPLE_SEC; + current->fileName = yyFileName; + current->startLine = yyLineNr; + BEGIN( ExampleDocArg1 ); + } +<ExampleDocArg1>{FILE} { + current->name = stripQuotes(yytext); + BEGIN( ExampleDoc ); + } +<ClassDoc,Doc,JavaDoc>{B}*("\\"|"@")"relate"[sd]{B}* { + lastDocRelContext = YY_START; + BEGIN( ClassDocRelates ); + } +<ClassDocRelates>{ID} { + current->relates = yytext; + BEGIN( lastDocRelContext ); + } +<NameSpaceDocArg1>{SCOPENAME} { + current->name = yytext; + newDocState(); + } +<NameSpaceDocArg1>"\n" { + warn("Warning: missing argument after " + "\\namespace at line %d of %s.\n",yyLineNr,yyFileName); + yyLineNr++; + } +<ClassDocArg1>{SCOPENAME} { + current->name = yytext; + // prepend outer scope name + if (current_root->section & Entry::SCOPE_MASK) + { + current->name.prepend(current_root->name+"::"); + } + BEGIN( ClassDocArg2 ); + } +<ClassDocArg1>"\n" { + warn("Warning: missing argument after " + "\\class at line %d of %s.\n",yyLineNr,yyFileName); + yyLineNr++; + + } +<GroupDocArg1>{ID}(".html"?) { + current->name = yytext; + if (current->name.right(5)==".html") + current->name=current->name.left(current->name.length()-5); + BEGIN(GroupDocArg2); + } +<GroupDocArg1>"\n" { + warn("Warning: missing argument after " + "\\defgroup at line %d of %s.\n",yyLineNr,yyFileName); + yyLineNr++; + BEGIN( Doc ); + } +<GroupDocArg2>.* { + current->type = yytext; + current->type = current->type.stripWhiteSpace(); + newDocState(); + } +<GroupDocArg2>"\n" { + newDocState(); + } +<ClassDocArg2>{FILE} { + //printf("ClassDocArg2=%s\n",yytext); + current->includeFile = stripQuotes(yytext); + BEGIN( ClassDocArg3 ); + } +<ClassDocArg2>{BL} { yyLineNr++; + newDocState(); + } +<ClassDocArg3>{FILE} { + //printf("ClassDocArg3=%s\n",yytext); + current->includeName = stripQuotes(yytext); + newDocState(); + } +<ClassDocArg3>{BL} { yyLineNr++; + newDocState(); + } +<FileDocArg1>{FILE} { + current->name = stripQuotes(yytext); + newDocState(); + } +<FileDocArg1>"\n" { + //warn("Warning: missing argument after " + // "\\file at line %d of %s.\n",yyLineNr,yyFileName); + current->name = yyFileName; + yyLineNr++; + newDocState(); + } +<PageDocArg1>{FILE} { + current->name = stripQuotes(yytext); + BEGIN( PageDocArg2 ); + } +<PageDocArg1>"\n" { + warn("Warning: missing argument after " + "\\page at line %d of %s.\n",yyLineNr,yyFileName); + yyLineNr++; + BEGIN( Doc ); + } +<PageDocArg2>.*"\n" { + yyLineNr++; + current->args = yytext; + BEGIN( PageDoc ); + } +<EnumDocArg1>{SCOPEID} { + current->name = yytext; + if (current_root->section & Entry::SCOPE_MASK) + { + current->name.prepend(current_root->name+"::"); + } + newDocState(); + } +<EnumDocArg1>"\n" { + warn("Warning: missing argument after " + "\\enum at line %d of %s.\n",yyLineNr,yyFileName); + yyLineNr++; + BEGIN( Doc ); + } +<PageDoc>"\\refitem".*"\n" { + current->doc+=yytext; + } +<PageDoc>("\\"|"@")"section"{B}+ { + isSubsection=FALSE; + BEGIN(SectionLabel); + } +<PageDoc>("\\"|"@")"subsection"{B}+ { + isSubsection=TRUE; + BEGIN(SectionLabel); + } +<Doc,PageDoc,JavaDoc,ClassDoc>"\\\\verbatim"/[^a-z_A-Z0-9] { + current->doc+="\\\\verbatim"; + } +<Doc,PageDoc,JavaDoc,ClassDoc>("\\"|"@")"verbatim"/[^a-z_A-Z0-9] { + lastVerbState=YY_START; + current->doc+="\\verbatim"; + BEGIN(SkipVerbatim); + } +<Doc,PageDoc,JavaDoc,ClassDoc>"\\\\code"/[^a-z_A-Z0-9] { + current->doc+="\\\\code"; + } +<Doc,PageDoc,JavaDoc,ClassDoc>("\\"|"@")"code"/[^a-z_A-Z0-9] { + lastCodeState=YY_START; + current->doc+="\\code"; + BEGIN(SkipCode); + } +<Doc,PageDoc,JavaDoc,ClassDoc>"<"{PRE}{ATTR}">" { + lastCodeState=YY_START; + current->doc+="<PRE>"; + BEGIN(SkipCode); + } +<SkipVerbatim>("\\"|"@")"endverbatim"/[^a-z_A-Z0-9] { + current->doc+=yytext; + BEGIN(lastVerbState); + } +<SkipVerbatim>[^ \t\/\\\n]* { + current->doc+=yytext; + } +<SkipVerbatim>^"//" { + if (!removeSlashes) + current->doc+=yytext; + } + /* +<SkipVerbatim>^"//"({B}*"*"+)? { + if (!removeSlashes) + current->doc+=yytext; + } +<SkipVerbatim>^{B}*"*"+ + */ +<SkipVerbatim>"//"|"/*" { + current->doc+=yytext; + } +<SkipVerbatim>"\n" { + yyLineNr++; + current->doc+=*yytext; + } +<SkipVerbatim>. { + current->doc+=*yytext; + } +<SkipCode>("\\"|"@")"endcode" { + current->doc+="\\endcode"; + BEGIN(lastCodeState); + } +<SkipCode>"</"{PRE}{ATTR}">" { + current->doc+="</PRE>"; + BEGIN(lastCodeState); + } +<SkipCode>^"//"({B}*"*"+)? { + if (!removeSlashes) + current->doc+=yytext; + } +<SkipCode>^{B}*"*"+ +<SkipCode>"//" { + current->doc+=yytext; + } +<SkipCode>[^ \*\t\/\\\n]+ { + current->doc+=yytext; + } +<SkipCode>\n { + yyLineNr++; + current->doc+=*yytext; + } +<SkipCode>. { + current->doc+=*yytext; + } +<SectionLabel>[a-z_A-Z0-9]+ { + sectionLabel=yytext; + sectionTitle.resize(0); + BEGIN(SectionTitle); + } +<SectionTitle>[^\n*]*/"\n" { + sectionTitle+=yytext; + sectionTitle=sectionTitle.stripWhiteSpace(); + addSection(); + current->doc += "\\section "+sectionLabel+"\n"; + BEGIN(PageDoc); + } +<SectionTitle>"*" { + sectionTitle+=yytext; + } +<ExampleDoc,PageDoc,ClassDoc>"\n" { yyLineNr++ ; current->doc+=yytext; } +<ExampleDoc,PageDoc,ClassDoc>[a-z_A-Z0-9 \t]+ { current->doc += yytext; } +<ExampleDoc,PageDoc,ClassDoc>. { current->doc += yytext; } +<Doc,JavaDoc,LineDoc,ExampleDoc,PageDoc,ClassDoc>^{B}*"//" +<Doc,JavaDoc,LineDoc,ExampleDoc,PageDoc,ClassDoc>"//" { current->doc += yytext; } +<Doc,JavaDoc,LineDoc,ExampleDoc,ClassDocBrief,PageDoc,ClassDoc>"\\\\f"[$\[\]] { + current->doc += &yytext[1]; + } +<Doc,JavaDoc,LineDoc,ExampleDoc,ClassDocBrief,PageDoc,ClassDoc>"\\f$" { + lastFormulaContext = YY_START; + formulaText="$"; + BEGIN(ReadFormulaShort); + } +<Doc,JavaDoc,LineDoc,ExampleDoc,ClassDocBrief,PageDoc,ClassDoc>"\\f[" { + lastFormulaContext = YY_START; + formulaText="\\["; + BEGIN(ReadFormulaLong); + } +<ReadFormulaShort>"\\f$" { + formulaText+="$"; + if (lastFormulaContext==ClassDocBrief) + current->brief += addFormula(); + else + current->doc += addFormula(); + BEGIN(lastFormulaContext); + } +<ReadFormulaLong>"\\f]" { + formulaText+="\\]"; + if (lastFormulaContext==ClassDocBrief) + current->brief += addFormula(); + else + current->doc += addFormula(); + BEGIN(lastFormulaContext); + } +<ReadFormulaLong,ReadFormulaShort>. { formulaText+=*yytext; } +<ExampleDoc,PageDoc,ClassDocBrief,ClassDoc>"*/" { + if (YY_START==ClassDocBrief && + lastBriefContext==Doc) + { + current->doc += "\n\n"; + BEGIN( lastDocContext ); + } + else + { + current->doc += "\n\n"; + //printf("Add docs for class %s\n",current->name.data()); + current_root->addSubEntry(current); + current = new Entry ; + current->protection = protection ; + current->sig = sig; + current->virt = virt; + current->stat = gstat; + current->slot = slot; + } + BEGIN( FindMembers ); + } +<PageDoc>"<"{TITLE}">" { + current->args.resize(0); + current->argList->clear(); + BEGIN( PageDocTitle); + } +<PageDocTitle>\n { yyLineNr++; current->args+=" "; } +<PageDocTitle>[^\n\<] { current->args+=yytext; } +<PageDocTitle>"</"{TITLE}">" { BEGIN( PageDoc ); } +<ClassDoc,Doc,JavaDoc>("\\"|"@")"ingroup"{B}+ { + lastGroupContext = YY_START; + lineCount(); + BEGIN( GroupName ); + } +<GroupName>{ID} { + current->groups->append( + new QString(yytext) + ); + } +<GroupName>\n { + yyLineNr++; BEGIN( lastGroupContext ); + } +<ClassDoc,Doc>{B}*("\\brief"|"@short") { + lastBriefContext=YY_START; + BEGIN( ClassDocBrief ); + } +<ClassDoc>{B}*"\\inherit"{B}+ { BEGIN( DocBaseClass ); } +<DocBaseClass>{ID} { + //printf("Adding base class %s\n",yytext); + current->extends->append( + new BaseInfo(yytext,Public,Normal) + ); + } +<DocBaseClass>\n { yyLineNr++; BEGIN( ClassDoc ); } +<ClassDocBrief>{BS}{BL} { + current->brief=current->brief.stripWhiteSpace(); + yyLineNr++; + BEGIN( lastBriefContext ); + } +<ClassDocBrief>"\n" { yyLineNr++ ; current->brief += " "; } +<ClassDocBrief>"<"{BR}{ATTR}">" +<ClassDocBrief>{BS}/("\\"|"@")"ingroup" { + current->brief=current->brief.stripWhiteSpace(); + BEGIN( lastBriefContext ); + } +<ClassDocBrief>{BS}/("\\"|"@")"author" { BEGIN( lastBriefContext ); } +<ClassDocBrief>{BS}/("\\"|"@")"internal" { BEGIN( lastBriefContext ); } +<ClassDocBrief>{BS}/("\\"|"@")"version" { BEGIN( lastBriefContext ); } +<ClassDocBrief>{BS}/"\\date" { BEGIN( lastBriefContext ); } +<ClassDocBrief>{BS}/("\\"|"@")"param" { BEGIN( lastBriefContext ); } +<ClassDocBrief>{BS}/("\\"|"@")"exception" { BEGIN( lastBriefContext ); } +<ClassDocBrief>{BS}/("\\"|"@")"return" { BEGIN( lastBriefContext ); } +<ClassDocBrief>{BS}/("\\sa"|"@see") { BEGIN( lastBriefContext ); } +<ClassDocBrief>{BS}/("\\"|"@")"bug" { BEGIN( lastBriefContext ); } +<ClassDocBrief>{BS}/("\\"|"@")"warning" { BEGIN( lastBriefContext ); } +<ClassDocBrief>{BS}/("\\"|"@")"par"{BN}+ { BEGIN( lastBriefContext ); } +<ClassDocBrief>{BS}/("\\brief"|"@short"){BN}+ { + lastBriefContext=YY_START; + BEGIN( ClassDocBrief ); + } +<ClassDocBrief>. { current->brief += *yytext; } +<ClassDocDefine>{ID}/"(" { + current->name = yytext; + BEGIN( ClassDefineArgs ); + } +<ClassDocDefine>{ID} { + current->name = yytext; + if (nextDefContext==ClassDoc) + newDocState(); + else + BEGIN( nextDefContext ); + } +<ClassDefineArgs>")" { + current->args+=")"; + if (nextDefContext==ClassDoc) + newDocState(); + else + BEGIN( nextDefContext ); + } +<ClassDefineArgs>. { + current->args+= yytext; + } +<ClassDocFunc>"\n" { + yyLineNr++; + current->name = current->name.stripWhiteSpace(); + if (current->section == Entry::MEMBERDOC_SEC && current->args.length()==0) + current->section = Entry::VARIABLEDOC_SEC; + newDocState(); + } +<ClassDocFunc>"(" { + current->args+=*yytext; + currentArgumentContext = ClassDocFuncQual; + copyArgString=¤t->args; + BEGIN( ReadFuncArgType ) ; + } +<ClassDocFunc>"("({B}*"*")+ { + current->name+="(*"; + BEGIN( ClassDocFuncPtr ); + } +<ClassDocFuncPtr>{SCOPENAME} { + current->name+=yytext; + } +<ClassDocFuncPtr>")" { + current->name+=')'; + BEGIN( ClassDocFunc ); + } +<ClassDocFuncQual>{B}*"const"{B}* { + current->args += " const "; + current->argList->constSpecifier=TRUE; + } +<ClassDocFuncQual>{B}*"volatile"{B}* { + current->args += " volatile "; + current->argList->volatileSpecifier=TRUE; + } +<ClassDocFuncQual>{B}*"="{B}*"0"{B}* { + current->args += " = 0"; + current->virt = Pure; + current->argList->pureSpecifier=TRUE; + } +<ClassDocFuncQual>"throw"{B}*"(" { + current->exception = "throw("; + BEGIN(ClassDocFuncExc); + } +<ClassDocFuncExc>")" { + current->exception += ')'; + BEGIN(ClassDocFuncQual); + } +<ClassDocFuncExc>. { + current->exception += *yytext; + } +<ClassDocFunc,ClassDocFuncQual>. { + current->name += *yytext; + } +<ClassDocFuncQual>"\n" { + yyLineNr++; + current->name = current->name.stripWhiteSpace(); + newDocState(); + } +<Doc>. { current->doc += *yytext; } +<DefLineDoc,LineDoc>. { current->brief += *yytext; } +<Doc>\n { yyLineNr++; current->doc += *yytext; } +<LineDoc>\n { + yyLineNr++; + BEGIN( lastDocContext ); + } +<DefLineDoc>\n { + yyLineNr++; + unput('/');unput('*'); + BEGIN( ClassDoc ); + } + +<AfterDocLine>"/*"|"//" { current->brief+=yytext; } +<AfterDocLine>\n { + if (afterDocTerminator!=0) + unput(afterDocTerminator); + BEGIN(lastAfterDocContext); + } +<AfterDocLine>. { current->brief+=yytext; } +<AfterDocBrief>"/*"|"//" { current->brief+=yytext; } +<AfterDocBrief>^{B}*"*"+/[^/\n] +<AfterDocBrief>\n { current->brief+=yytext; yyLineNr++; } +<AfterDocBrief>. { current->brief+=*yytext; } +<AfterDocBrief>^{B}*"*"/[^/\n]{BL} { yyLineNr++; + if (!current->brief.stripWhiteSpace().isEmpty()) + BEGIN(AfterDoc); + } +<AfterDocBrief>"*/" { + if (afterDocTerminator!=0) + unput(afterDocTerminator); + BEGIN(lastAfterDocContext); + } +<AfterDocBrief>"."/{BN} { BEGIN(AfterDoc); } +<AfterDoc>("\\"|"@")"brief" { BEGIN(AfterDocBrief); } +<AfterDoc>"/*"|"//" { current->doc+=yytext; } +<AfterDoc>^{B}*"*"+/[^/] +<AfterDoc>\n { current->doc+=yytext; yyLineNr++; } +<AfterDoc>. { current->doc+=*yytext; } +<AfterDoc>"*/" { + if (afterDocTerminator!=0) + unput(afterDocTerminator); + BEGIN(lastAfterDocContext); + } +<ClassDocRelates,ClassDocFunc,ClassDocDefine,GroupDocArg1,ClassDocArg1,SectionTitle,EnumDocArg1,FileDocArg1,PageDocArg1,ExampleDocArg1,ClassDefineArgs>"*/" { + current->doc += "\n\n"; + err("Warning: unexpected end of " + "documentation block found in " + "file %s at line %d\n",yyFileName,yyLineNr); + BEGIN( lastDocContext ); + } +<Doc>"*/" { + current->doc += "\n\n"; + BEGIN( lastDocContext ); + } +<JavaDoc>"*/" { + unput('/');unput('*'); + BEGIN( tmpDocType ); + } +<Doc,JavaDoc,ClassDoc,PageDoc,ExampleDoc,ReadFormulaShort,ReadFormulaLong,ClassDocBrief>^{B}*(("//"{B}*)?)"*"+/[^/] +<DefLineDoc,LineDoc,ClassDoc,Doc>"/*" { current->doc += yytext; } + +<SkipCxxComment>.*\n { yyLineNr++ ; + BEGIN( lastCContext ) ; + } +<*>. +<*>\n { yyLineNr++ ; } +<SkipComment>"//"|"/*" +<*>"/*" { lastCContext = YY_START ; + BEGIN( SkipComment ) ; + } +<SkipComment>{B}*"*/" { BEGIN( lastCContext ) ; } +<*>"//" { + lastCContext = YY_START ; + BEGIN( SkipCxxComment ) ; + } +%% + +//---------------------------------------------------------------------------- + +void scanString(const char *s) +{ + const char *oldInputString = inputString; + int oldInputPosition = inputPosition; + YY_BUFFER_STATE oldBuffer = YY_CURRENT_BUFFER; + yy_switch_to_buffer(yy_create_buffer(scanYYin, YY_BUF_SIZE)); + inputString = s; + inputPosition = 0; + scanYYlex(); + yy_delete_buffer(YY_CURRENT_BUFFER); + yy_switch_to_buffer(oldBuffer); + inputString = oldInputString; + inputPosition = oldInputPosition; +} + +//---------------------------------------------------------------------------- + +static void newDocState() +{ + if (tmpDocType!=-1) + { + tmpDocType=ClassDoc; + BEGIN(JavaDoc); + } + else + { + BEGIN(ClassDoc); + } +} + +//---------------------------------------------------------------------------- + +void parseCompounds(Entry *rt) +{ + //printf("parseCompounds(%s)\n",rt->name.data()); + EntryListIterator eli(*rt->sublist); + Entry *ce; + for (;(ce=eli.current());++eli) + { + if (ce->program.length()>0) + { + //printf("-- %s ---------\n%s\n---------------\n", + // ce->name.data(),ce->program.data()); + // init scanner state + inputString = ce->program; + inputPosition = 0; + scanYYrestart( scanYYin ) ; + if (ce->section==Entry::ENUM_SEC) + BEGIN( FindFields ) ; + else + BEGIN( FindMembers ) ; + current_root = ce ; + strcpy( yyFileName, ce->fileName ) ; + yyLineNr = ce->startLine ; + //current->reset(); + current = new Entry; + // set default protection based on the compound type + if( ce->section==Entry::CLASS_SEC ) // class + current->protection = protection = Private ; + else if (ce->section == Entry::ENUM_SEC ) // enum + current->protection = protection = ce->protection; + else if (ce->name.length()>0 && ce->name.at(0)=='@') // anonymous union + current->protection = protection = ce->protection; + else // named struct or union + current->protection = protection = Public ; + sig = FALSE; + slot = FALSE; + gstat = FALSE; + virt = Normal; + scanYYlex() ; + delete current; + ce->program.resize(0); + } + parseCompounds(ce); + } +} + +//---------------------------------------------------------------------------- + +void parseMain(Entry *rt) +{ + initParser(); + anonCount = 0; + protection = Public; + sig = FALSE; + slot = FALSE; + gstat = FALSE; + virt = Normal; + current_root = rt; + global_root = rt; + current = new Entry; + inputString = rt->program; + inputPosition = 0; + ifCount=0; + scanYYrestart( scanYYin ); + BEGIN( FindMembers ); + scanYYlex(); + rt->program.resize(0); + delete current; + parseCompounds(rt); +} + +//---------------------------------------------------------------------------- + +void parseDocument(OutputList &ol,const QString &docString) +{ + //inParamBlock=inSeeBlock=inReturnBlock=FALSE; + curTable = 0; + outDoc = new OutputList(&ol); + currentIncludeFile.resize(0); + includeFileOffset=0; + includeFileLength=0; + if (!docString) return; + linkRef = ""; + linkText = ""; + inputString = docString; + inputPosition = 0; + scanYYrestart( scanYYin ); + BEGIN( DocScan ); + insideArgumentList = FALSE; + scanYYlex(); + if (insideArgumentList) { insideArgumentList=FALSE; outDoc->endItemList(); } + if (inBlock()) endBlock(); + ol+=*outDoc; + delete outDoc; + return; +} + +//---------------------------------------------------------------------------- + +void parseDoc(OutputList &ol,const char *clName, + const char *memName,const QString &docString) +{ + initParser(); + initParseCodeContext(); + exampleDoc=FALSE; // do not cross reference with member docs + className=clName; + memberName=memName; + if (memName) + { + refName=className+"::"+memberName; + } + else + { + refName=className; + } + parseDocument(ol,docString); +} + +//---------------------------------------------------------------------------- + +void parseExample(OutputList &ol,const QString &docString, + const char *fileName) +{ + initParser(); + initParseCodeContext(); + exampleDoc=TRUE; // cross reference with member docs + exampleName=fileName; + parseDocument(ol,docString); +} + +//---------------------------------------------------------------------------- + +extern "C" { // some sillyness to keep the compiler happy +int scanYYwrap() { return 1 ; } +void bogus() { yy_flex_realloc(0,0); } +} + diff --git a/src/searchindex.cpp b/src/searchindex.cpp new file mode 100644 index 0000000..241d0a8 --- /dev/null +++ b/src/searchindex.cpp @@ -0,0 +1,124 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include "searchindex.h" +#include "suffixtree.h" + +SearchIndex::SearchIndex() : refDict(10007), nameIndex(10007) +{ + indexCount=1; + //indexTree = new IndexTree; + suffixTree = new SuffixTree; +} + +SearchIndex::~SearchIndex() +{ + //delete indexTree; + delete suffixTree; +} + +void SearchIndex::addReference(const char *key,const char *ref) +{ + DocRef *dr=new DocRef(indexCount,key,ref); + nameIndex.insert(indexCount,dr); + refList.append(dr); + refDict.insert(key,dr); + indexCount++; +} + +bool SearchIndex::addWord(const char *key,const char *word,bool special) +{ + DocRef *dr=0; + if (word && key && strlen(key)>0 && (dr=refDict[key])) + { + suffixTree->insertWord(((QString)word).lower(),dr->index(),special); + return TRUE; + } + else if (word) + { + printf("SearchIndex::addWord() key `%s' not found!\n",key); + return FALSE; + } + else + { + printf("SearchIndex::addWord() trying to insert word with length 0\n"); + return FALSE; + } +} + +bool SearchIndex::saveIndex(const char *fileName) +{ + QFile f(fileName); + if (!f.open(IO_WriteOnly)) return FALSE; + + // write header + if (f.writeBlock("DOXI",4)!=4) return FALSE; // write header + + // compute forward offsets for all children of each node. + suffixTree->resolveForwardReferences(); + + // compute offset to the reference index table + int offset=suffixTree->size()+9; + + // write the offset + if (writeNumber(f,offset)) return FALSE; + + // write the suffix tree + if (!suffixTree->write(f)) return FALSE; + + f.putch(0); + + // write the index reference table + DocRef *dr=refList.first(); + offset+=refList.count()*4; + while (dr) + { + writeNumber(f,offset); + offset+=strlen(dr->name())+strlen(dr->url())+2; + dr=refList.next(); + } + + // write the references + dr=refList.first(); + while (dr) + { + writeString(f,dr->name()); + writeString(f,dr->url()); + dr=refList.next(); + } + + //printf("Building index tree\n"); + printf("Size of the suffix tree is %d bytes\n",suffixTree->size()); + printf("Number of tree nodes is %d\n",suffixTree->numberOfNodes()); + printf("Number of links %d\n",indexCount); + //suffixTree->buildIndex(); + //printf("Computing reference offsets\n"); + //int offset=suffixTree->size()+8; + //indexTree->setOffsets(&nameIndex); + //printf("Saving suffix tree\n"); + //printf("Saving index tree\n"); + //result&=indexTree->write(f); + //printf("Saving reference list\n"); + //dr=refList.first(); + //while (dr) + //{ + // result&=!writeString(f,dr->name()); + // result&=!writeString(f,dr->url()); + // dr=refList.next(); + //} + //suffixTree->dump(); + return TRUE; +} diff --git a/src/searchindex.h b/src/searchindex.h new file mode 100644 index 0000000..64071fb --- /dev/null +++ b/src/searchindex.h @@ -0,0 +1,71 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef _SEARCHINDEX_H +#define _SEARCHINDEX_H + +#include <qintdict.h> +#include <qstring.h> +#include <qlist.h> +#include <qdict.h> + +#include "suffixtree.h" + +//class IndexTree; +class SuffixTree; + +class DocRef +{ + public: + DocRef(int index,const char *name,const char *url) + { i=index; n=name; u=url; } + ~DocRef() {} + void setOffset(int offset) { o=offset; } + const char *name() const { return n; } + const char *url() const { return u; } + int index() const { return i; } + int offset() const { return o; } + + private: + QString n; + QString u; + int i; + int o; +}; + +typedef QList<DocRef> DocRefList; +typedef QDict<DocRef> DocRefDict; + +class SearchIndex +{ + public: + SearchIndex(); + ~SearchIndex(); + void addReference(const char *key,const char *ref); + bool addWord(const char *key,const char *word,bool special); + bool saveIndex(const char *fileName); + void dump() { suffixTree->dump(); } + + private: + //IndexTree *indexTree; + SuffixTree *suffixTree; + DocRefList refList; + DocRefDict refDict; + QIntDict<DocRef> nameIndex; + int indexCount; +}; + +#endif diff --git a/src/suffixtree.cpp b/src/suffixtree.cpp new file mode 100644 index 0000000..604531f --- /dev/null +++ b/src/suffixtree.cpp @@ -0,0 +1,355 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <stdio.h> +#include "suffixtree.h" + +#define MAXWORDLEN 1024 + +//---------------------------------------------------------------------------- + +bool writeString(QFile &f,const char *s) +{ + int len=strlen(s)+1; + return (f.writeBlock(s,len)!=len); +} + +bool writeNumber(QFile &f,int num) +{ + return (f.putch((num>>24)&0xff)==-1) || + (f.putch((num>>16)&0xff)==-1) || + (f.putch((num>>8)&0xff)==-1) || + (f.putch(num&0xff)==-1); +} + +bool writeEncodedNumber(QFile &f,uint number) +{ + bool error=FALSE; + uint n=number; + while (n>=128) + { + int frac=n&0x7f; + error = error || (f.putch(frac|0x80)==-1); + n>>=7; + } + error = error || (f.putch(n)==-1); + return error; +} + +int encodedNumberSize(uint number) +{ + uint n=number; + int size=1; + while (n>=128) { size++; n>>=7; } + return size; +} + +//---------------------------------------------------------------------------- + +int SuffixNodeList::compareItems(GCI item1,GCI item2) +{ + SuffixNode *n1=(SuffixNode *)item1; + SuffixNode *n2=(SuffixNode *)item2; + return strcmp(n1->label,n2->label); +} + +SuffixNode::SuffixNode(const char *lab) : references(0) +{ + children = new SuffixNodeList; + children->setAutoDelete(TRUE); + label=lab; + totalFreq=0; + branchOffset=0; +} + +SuffixNode::~SuffixNode() +{ + delete children; +} + +void SuffixNode::addReference(int refId,int inName,int fullWord) +{ + totalFreq++; + uint s=references.size(); + if (s>0 && references.at(s-1).id==refId) // word occured in the same document + { + references.at(s-1).freq++; // increase word's frequency + references.at(s-1).flags=((references.at(s-1).flags & INNAME_MASK) + | (inName<<INNAME_BIT)) + +((references.at(s-1).flags & FULLWORD_MASK) + | (fullWord<<FULLWORD_BIT)) + +((references.at(s-1).flags & WORDINNAME_MASK) + | ((inName & fullWord)<<WORDINNAME_BIT)); + } + else + { + references.resize(s+1); + references.at(s).id=refId; + references.at(s).freq=1; + references.at(s).flags=(inName<<INNAME_BIT) + +(fullWord<<FULLWORD_BIT) + +((inName && fullWord)<<WORDINNAME_BIT); + } +} + +int SuffixNode::insert(const char *word,int refId,int inName,int fullWord) +{ + int numNewNodes=0; + //printf("SuffixNode::insert(%s,%d)\n",word,refId); + SuffixNode *sn=children->first(); + while (sn) + { + char *lab=sn->label.data(); + char w=word[0],l=lab[0],i=0; + while (w!=0 && l!=0 && w==l) { i++; w=word[i]; l=lab[i]; } + if (w==0 && l==0) // match found + { + sn->addReference(refId,inName,fullWord); + return numNewNodes; + } + if (i>0) // w and l contain a common prefix of length i + { + if (l==0) // w!=0 => follow this branch + { + sn->addReference(refId,inName,FALSE); + numNewNodes+=sn->insert(&word[i],refId,inName,fullWord); + } + else // l!=0 => split branch + { + char leftlab[MAXWORDLEN]; + memcpy(leftlab,lab,i); + leftlab[i]='\0'; + SuffixNode *r = new SuffixNode(leftlab); + numNewNodes++; + SuffixNode *n2 = children->take(); + // copy reference info + r->references = n2->references.copy(); + int j,refSize = r->references.size(); + for (j=0;j<refSize;j++) + { + //r->references[j].fullWord=FALSE; + //r->references[j].wordInName=FALSE; + r->references[j].flags &= ~(FULLWORD_MASK|WORDINNAME_MASK); + } + r->totalFreq = n2->totalFreq; + //printf("root branch `%s'\n",leftlab); + if (w!=0) // two sub branches + { + SuffixNode *n1 = new SuffixNode(&word[i]); + numNewNodes++; + n1->addReference(refId,inName,fullWord); + r->addReference(refId,inName,FALSE); + r->children->append(n1); + //printf("Right branch `%s'\n",&word[i]); + } + else // one sub branch + { + r->addReference(refId,inName,fullWord); + } + //printf("Left branch `%s'\n",&lab[i]); + n2->label=&lab[i]; + r->children->append(n2); + children->append(r); + } + return numNewNodes; + } + sn=children->next(); + } + //printf("new branch `%s'\n",word); + SuffixNode *n=new SuffixNode(word); + numNewNodes++; + n->addReference(refId,inName,fullWord); + children->append(n); + return numNewNodes; +} + +void SuffixNode::dump(int level,const char *prefix) +{ + uint i; + if (references.size()>0) + { + printf("%s (level=%d offset=%d freq=%d) ", + prefix,level,branchOffset,totalFreq); + for (i=0;i<references.size();i++) + printf("%d->%d ",references.at(i).id,references.at(i).freq); + printf("\n"); + } + SuffixNode *sn=children->first(); + while (sn) + { + sn->dump(level+1,prefix+("-"+sn->label)); + sn=children->next(); + } +} + +void SuffixNode::resolveForwardReferences(int &offset) +{ + if (children->count()>0) + { + if (label.length()>0) offset++; // terminator for the previous level + branchOffset=offset; + } + else + branchOffset=0; + SuffixNode *sn=children->first(); + while (sn) + { + offset+=sn->label.length()+5; + uint i,refs=sn->references.size(); + if (refs>0) + { + offset+=encodedNumberSize(sn->totalFreq); + offset+=encodedNumberSize((sn->references[0].id<<3)+ + sn->references[0].flags); + offset+=encodedNumberSize(sn->references[0].freq); + for (i=1;i<refs;i++) + { + offset+=encodedNumberSize( + ((sn->references.at(i).id - sn->references.at(i-1).id)<<3)+ + sn->references.at(i).flags); + offset+=encodedNumberSize(sn->references.at(i).freq); + } + offset+=encodedNumberSize(0); + } + //printf("Lab=%s offset=%d\n",sn->lab.data(),offset); + sn=children->next(); + } + sn=children->first(); + while (sn) + { + //printf("Lab=%s offset=%d\n",sn->lab.data(),offset); + sn->resolveForwardReferences(offset); + sn=children->next(); + } +} + +int SuffixNode::size() +{ + int s=0; + if (label.length()>0 && children->count()>0) s++; // for the terminator + SuffixNode *sn=children->first(); + while (sn) + { + uint i,refs=sn->references.size(); + s+=sn->size()+sn->label.length()+5; + if (refs>0) + { + s+=encodedNumberSize(sn->totalFreq); + s+=encodedNumberSize( + (sn->references[0].id<<3)+ + sn->references[0].flags); + s+=encodedNumberSize(sn->references[0].freq); + for (i=1;i<refs;i++) + { + s+=encodedNumberSize( + ((sn->references.at(i).id - sn->references.at(i-1).id)<<3)+ + sn->references.at(i).flags); + s+=encodedNumberSize(sn->references.at(i).freq); + } + s+=encodedNumberSize(0); + } + sn=children->next(); + } + return s; +} + +bool SuffixNode::write(QFile &f) +{ + bool error=FALSE; + if (children->count()>0 && label.length()>0) error=error || (f.putch(0)==-1); + SuffixNode *sn=children->first(); + while (sn) + { + //offset+=sn->lab.length()+1+2*sizeof(int); + int i,refs=sn->references.size(); + error=error || writeString(f,sn->label); + error=error || writeNumber(f,sn->branchOffset|((refs==0)?0x80000000:0)); + if (refs>0) + { + error=error || writeEncodedNumber(f,sn->totalFreq); + error=error || writeEncodedNumber(f, + (sn->references[0].id<<3)+ + sn->references[0].flags); + error=error || writeEncodedNumber(f,sn->references[0].freq); + for (i=1;i<refs;i++) + { + error=error || writeEncodedNumber(f, + ((sn->references[i].id - sn->references[i-1].id)<<3)+ + sn->references[i].flags); + error=error || writeEncodedNumber(f,sn->references[i].freq); + } + error=error || writeEncodedNumber(f,0); + } + //printf("Lab=%s offset=%d\n",sn->lab.data(),offset); + sn=children->next(); + } + sn=children->first(); + while (sn) + { + error=error || sn->write(f); + sn=children->next(); + } + return error; +} + +//---------------------------------------------------------------------------- + +SuffixTree::SuffixTree() +{ + root=new SuffixNode(""); + nodes=1; +} + +SuffixTree::~SuffixTree() +{ + delete root; +} + +void SuffixTree::insertWord(const char *word,int index,bool inName) +{ + QString suffix=word; + uint i; + for (i=2;i<suffix.length()-1;i++) + { + //printf("Inserting suffix %s\n",suffix.right(i).data()); + nodes+=root->insert(suffix.right(i),index,inName?1:0,FALSE); + } + nodes+=root->insert(word,index,inName?1:0,TRUE); +} + +void SuffixTree::dump() +{ + root->dump(0,""); +} + +void SuffixTree::resolveForwardReferences() +{ + int offset=8; + root->resolveForwardReferences(offset); +} + +int SuffixTree::size() +{ + return root->size(); +} + +bool SuffixTree::write(QFile &f) +{ + if (!f.isOpen()) { printf("File not open\n"); return FALSE; } + bool error=FALSE; + error = error || root->write(f); + return !error; +} diff --git a/src/suffixtree.h b/src/suffixtree.h new file mode 100644 index 0000000..381253c --- /dev/null +++ b/src/suffixtree.h @@ -0,0 +1,93 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef SUFFIXTREE_H +#define SUFFIXTREE_H + +#include <qlist.h> +#include <qarray.h> +#include <qstring.h> +#include <qfile.h> + +class SuffixNodeList; +class IndexTree; + +enum WordRefMasks { WORDINNAME_MASK=4, INNAME_MASK=2, FULLWORD_MASK=1 }; +enum WordRefBits { WORDINNAME_BIT=2, INNAME_BIT=1, FULLWORD_BIT=0 }; + +// bool inName; +// bool fullWord; +// bool wordInName; + +struct WordRef +{ + int id; + short freq; + char flags; +}; + +class SuffixNode +{ + friend class SuffixTree; + friend class IndexNode; + friend class SuffixNodeList; + public: + SuffixNode(const char *); + ~SuffixNode(); + int insert(const char *word,int refId,int inName,int full); + void addReference(int refId,int inName,int fullWord); + void dump(int,const char *); + void resolveForwardReferences(int &offset); + int size(); // return the size of the tree whose root is this node + bool write(QFile &f); + private: + SuffixNodeList *children; + QArray<WordRef> references; + QString label; + int branchOffset; + int totalFreq; +}; + +class SuffixNodeList : public QList<SuffixNode> +{ + public: + SuffixNodeList() : QList<SuffixNode>() {} + ~SuffixNodeList() {} + int compareItems(GCI item1,GCI item2); +}; + +class SuffixTree +{ + friend class SuffixNode; + public: + SuffixTree(); + ~SuffixTree(); + void insertWord(const char *word,int index,bool inName); + //void buildIndex(); + void resolveForwardReferences(); + void dump(); + int size(); // return the size of the (flat) tree in bytes + bool write(QFile &f); + int numberOfNodes() { return nodes; } + private: + int nodes; + SuffixNode *root; +}; + +extern bool writeNumber(QFile &f,int); +extern bool writeString(QFile &f,const char *s); + +#endif diff --git a/src/tag.h b/src/tag.h new file mode 100644 index 0000000..d301f4d --- /dev/null +++ b/src/tag.h @@ -0,0 +1,22 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef TAG_H +#define TAG_H + +extern void parseTagFile(const char *fileName); + +#endif diff --git a/src/tag.l b/src/tag.l new file mode 100644 index 0000000..edc5cf1 --- /dev/null +++ b/src/tag.l @@ -0,0 +1,243 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +%{ + +/* + * includes + */ +#include <stdio.h> +#include <qstring.h> +#include <qfileinf.h> + +#include "classdef.h" +#include "filedef.h" +#include "memberdef.h" +#include "doxygen.h" +#include "util.h" +#include "message.h" + +#define YY_NO_UNPUT +#define YY_NEVER_INTERACTIVE 1 + +static int yyLineNr; +static QString className; +static QString fileName; +static QString tagName; +static QString memberName; +static QString anchorName; +static QString argString; +static ClassDef *cd; +static FileDef *fd; + +static void addClass(const char *name,const char *fileName) +{ + //printf("adding class %s\n",name); + if (name!=0 && strlen(name)>0 && classDict[name]==0) + { + cd = new ClassDef(name,ClassDef::Class,tagName,fileName); + fd = 0; + classList.inSort(cd); + classDict.insert(className,cd); + } +} + +static void addFile(const char *name) +{ + //printf("adding file %s\n",name); + fd = new FileDef(0,name,tagName); + FileName *mn; + if ((mn=inputNameDict[name])) + { + mn->append(fd); + } + else + { + mn = new FileName(name); + mn->append(fd); + inputNameList.inSort(mn); + inputNameDict.insert(name,mn); + } + cd = 0; + //fileList.inSort(fd); + //fileDict.insert(fileName,fd); +} + +static void addMember(const char *name,const char *anchor,const char *args) +{ + //printf("adding member %s\n",name); + if (cd || fd) + { + MemberNameDict *mnd=0; + MemberNameList *mnl=0; + MemberDef *md; + md=new MemberDef(0,name,args,0,Public,Normal,FALSE,FALSE, + MemberDef::Function,0,0); + md->setReference(anchor); + if (cd) + { + //md=new MemberDef(cd,name,args,anchor,tagName); + md->setMemberClass(cd); + cd->insertMember(md); + //printf("Adding member %s %s to class\n",name,args); + mnd=&memberNameDict; + mnl=&memberNameList; + } + else + { + //md=new MemberDef(&unrelatedClass,name,args,anchor,tagName); + md->setFileDef(fd); + fd->insertMember(md); + //printf("Adding global member %s %s\n",name,args); + mnd=&functionNameDict; + mnl=&functionNameList; + } + MemberName *mn; + if ((mn=(*mnd)[memberName])) + { + //printf("mn->inSort()\n"); + mn->append(md); + } + else + { + //printf("mn->append()\n"); + mn=new MemberName(memberName); + mn->append(md); + //printf("Adding memberName=%s\n",mn->memberName()); + mnl->inSort(mn); + mnd->insert(memberName,mn); + } + } +} + +/* ----------------------------------------------------------------- + */ + +%} + +ID [a-z_A-Z][a-z_A-Z0-9]* +FILE [a-z_A-Z0-9\.\-\+\:\\\/]+ + +%x Pass1 +%x Pass2 +%x AnchorName +%x ArgString1 +%x ArgString2 +%x ClassName1 +%x ClassName2 +%x FileName +%x BaseClasses +%x ClassFile1 +%x ClassFile2 + +%% + +<Pass1>^">" { + BEGIN(ClassName1); + } +<Pass1>^"&" { + BEGIN(FileName); + } +<Pass1>^[~a-z_A-Z][^ \n]*/" " { + memberName=yytext; + BEGIN(AnchorName); + } +<Pass2>^">" { + BEGIN(ClassName2); + } +<AnchorName>{ID} { + anchorName=yytext; + BEGIN(ArgString1); + } +<ArgString1>"\"" { + BEGIN(ArgString2); + } +<ArgString2>[^\"\n]*/"\"" { + argString=yytext; + addMember(memberName,anchorName,argString); + BEGIN(Pass1); + } +<FileName>{FILE}/":" { + fileName=yytext; + addFile(yytext); + BEGIN(Pass1); + } +<ClassName1>{ID}/":" { + className=yytext; + BEGIN(ClassFile1); + } +<ClassFile1>\" { + BEGIN(ClassFile2); + } +<ClassFile2>[^\"]*/\" { + addClass(className,yytext); + BEGIN(Pass1); + } +<ClassFile2>\n { + yyLineNr++; + BEGIN(Pass1); + } +<ClassName2>{ID}/":" { + cd=getClass(yytext); + BEGIN(BaseClasses); + } +<BaseClasses>{ID}/"?" { + ClassDef *bcd=getClass(yytext); + if (cd && bcd) + { + cd->insertBaseClass(bcd,Public,Normal); + bcd->insertSuperClass(cd,Public,Normal); + } + } +<BaseClasses>\n { + yyLineNr++; + BEGIN(Pass2); + } +<*>. +<*>\n { yyLineNr++ ; } + +%% + +/*@ ---------------------------------------------------------------------------- + */ + +void parseTagFile(const char *fileName) +{ + FILE *f=fopen(fileName,"r"); + QFileInfo fi(fileName); + if (!f || !fi.exists()); + tagName = fi.fileName(); + tagYYin = f; + + cd=0; + yyLineNr = 1; + tagYYrestart( tagYYin ); + BEGIN(Pass1); + tagYYlex(); + + rewind(f); + cd=0; + yyLineNr = 1; + tagYYrestart( tagYYin ); + BEGIN(Pass2); + tagYYlex(); + + fclose(f); +} + +extern "C" { // some bogus code to keep the compiler happy + int tagYYwrap() { return 1 ; } +} diff --git a/src/translator.h b/src/translator.h new file mode 100644 index 0000000..55b6eaf --- /dev/null +++ b/src/translator.h @@ -0,0 +1,280 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef TRANSLATOR_H +#define TRANSLATOR_H + +#include <qstring.h> + +class Translator +{ + public: + virtual QString latexBabelPackage() + { return ""; } + virtual QString trInherits() + { return "Inherits"; } + virtual QString trAnd() + { return "and"; } + virtual QString trInheritedBy() + { return "Inherited By"; } + virtual QString trRelatedFunctions() + { return "Related Functions"; } + virtual QString trRelatedSubscript() + { return "(Note that these are not member functions.)"; } + virtual QString trDetailedDescription() + { return "Detailed Description"; } + virtual QString trMemberTypedefDocumentation() + { return "Member Typedef Documentation"; } + virtual QString trMemberEnumerationDocumentation() + { return "Member Enumeration Documentation"; } + virtual QString trMemberFunctionDocumentation() + { return "Member Function Documentation"; } + virtual QString trMemberDataDocumentation() + { return "Member Data Documentation"; } + virtual QString trGeneratedFrom(const char *s,bool single) + { // here s is one of " Class", " Struct" or " Union" + // single is true implies a single file + QString result=(QString)"The documentation for this"+s+ + " was generated from the following file"; + if (single) result+=":"; else result+="s:"; + return result; + } + virtual QString trMore() + { return "More..."; } + virtual QString trReference() + { return "Reference"; } + virtual QString trListOfAllMembers() + { return "List of all members."; } + virtual QString trMemberList() + { return "Member List"; } + virtual QString trThisIsTheListOfAllMembers() + { return "This is the complete list of members for"; } + virtual QString trIncludingInheritedMembers() + { return "including all inherited members."; } + virtual QString trGeneratedAutomatically(const char *s) + { QString result="Generated automatically by Doxygen"; + if (s) result+=(QString)" for "+s; + result+=" from the source code."; + return result; + } + virtual QString trEnumName() + { return "enum name"; } + virtual QString trEnumValue() + { return "enum value"; } + virtual QString trDefinedIn() + { return "defined in"; } + virtual QString trIncludeFile() + { return "Include File"; } + virtual QString trVerbatimText(const char *f) + { return (QString)"This is the verbatim text of the "+f+" include file."; } + + + virtual QString trModules() + { return "Modules"; } + virtual QString trClassHierarchy() + { return "Class Hierarchy"; } + virtual QString trCompoundList() + { return "Compound List"; } + virtual QString trFileList() + { return "File List"; } + virtual QString trHeaderFiles() + { return "Header Files"; } + virtual QString trCompoundMembers() + { return "Compound Members"; } + virtual QString trFileMembers() + { return "File Members"; } + virtual QString trRelatedPages() + { return "Related Pages"; } + virtual QString trExamples() + { return "Examples"; } + virtual QString trSearch() + { return "Search"; } + + virtual QString trClassHierarchyDescription() + { return "This inheritance list is sorted roughly, " + "but not completely, alphabetically:"; + } + virtual QString trFileListDescription(bool extractAll) + { + QString result="Here is a list of all "; + if (!extractAll) result+="documented "; + result+="files with brief descriptions:"; + return result; + } + virtual QString trCompoundListDescription() + { return "Here are the classes, structs and " + "unions with brief descriptions:"; + } + virtual QString trCompoundMembersDescription(bool extractAll) + { + QString result="Here is a list of all "; + if (!extractAll) result+="documented "; + result+="class members with links to "; + if (extractAll) + result+="the class documentation for each member:"; + else + result+="the classes they belong to:"; + return result; + } + virtual QString trFileMembersDescription(bool extractAll) + { + QString result="Here is a list of all "; + if (!extractAll) result+="documented "; + result+="file members with links to "; + if (extractAll) + result+="the file documentation for each member:"; + else + result+="the files they belong to:"; + return result; + } + virtual QString trHeaderFilesDescription() + { return "Here are the header files that make up the API:"; } + virtual QString trExamplesDescription() + { return "Here is a list of all examples:"; } + virtual QString trRelatedPagesDescription() + { return "Here is a list of all related documentation pages:"; } + virtual QString trModulesDescription() + { return "Here is a list of all modules:"; } + virtual QString trNoDescriptionAvailable() + { return "No description available"; } + + virtual QString trDocumentation() + { return "Documentation"; } + virtual QString trModuleIndex() + { return "Module Index"; } + virtual QString trHierarchicalIndex() + { return "Hierarchical Index"; } + virtual QString trCompoundIndex() + { return "Compound Index"; } + virtual QString trFileIndex() + { return "File Index"; } + virtual QString trModuleDocumentation() + { return "Module Documentation"; } + virtual QString trClassDocumentation() + { return "Class Documentation"; } + virtual QString trFileDocumentation() + { return "File Documentation"; } + virtual QString trExampleDocumentation() + { return "Example Documentation"; } + virtual QString trPageDocumentation() + { return "Page Documentation"; } + virtual QString trReferenceManual() + { return "Reference Manual"; } + + virtual QString trDefines() + { return "Defines"; } + virtual QString trFuncProtos() + { return "Function Prototypes"; } + virtual QString trTypedefs() + { return "Typedefs"; } + virtual QString trEnumerations() + { return "Enumerations"; } + virtual QString trFunctions() + { return "Functions"; } + virtual QString trVariables() + { return "Variables"; } + virtual QString trEnumerationValues() + { return "Enumeration values"; } + virtual QString trReimplementedFrom() + { return "Reimplemented from"; } + virtual QString trReimplementedIn() + { return "Reimplemented in"; } + virtual QString trAuthor() + { return "Author"; } + virtual QString trDefineDocumentation() + { return "Define Documentation"; } + virtual QString trFunctionPrototypeDocumentation() + { return "Function Prototype Documentation"; } + virtual QString trTypedefDocumentation() + { return "Typedef Documentation"; } + virtual QString trEnumerationTypeDocumentation() + { return "Enumeration Type Documentation"; } + virtual QString trEnumerationValueDocumentation() + { return "Enumeration Value Documentation"; } + virtual QString trFunctionDocumentation() + { return "Function Documentation"; } + virtual QString trVariableDocumentation() + { return "Variable Documentation"; } + virtual QString trCompounds() + { return "Compounds"; } + virtual QString trFiles() + { return "Files"; } + + virtual QString trGeneratedAt(const char *date,const char *projName) + { + QString result=(QString)"Generated at "+date; + if (projName) result+=(QString)" for "+projName; + result+=(QString)" by"; + return result; + } + virtual QString trWrittenBy() + { + return "written by"; + } + + virtual QString trClassDiagram(const char *clName) + { + return (QString)"Class diagram for "+clName; + } + + virtual QString trForInternalUseOnly() + { return "For internal use only."; } + virtual QString trReimplementedForInternalReasons() + { return "Reimplemented for internal reasons; the API is not affected."; } + virtual QString trWarning() + { return "Warning"; } + virtual QString trBugsAndLimitations() + { return "Bugs and limitations"; } + virtual QString trVersion() + { return "Version"; } + virtual QString trDate() + { return "Date"; } + virtual QString trAuthors() + { return "Author(s)"; } + virtual QString trReturns() + { return "Returns"; } + virtual QString trSeeAlso() + { return "See also"; } + virtual QString trParameters() + { return "Parameters"; } + virtual QString trExceptions() + { return "Exceptions"; } + virtual QString trGeneratedBy() + { return "Generated by"; } + + // new since 0.49-990307 + + virtual QString trNamespaces() + { return "Namespaces"; } + virtual QString trNamespaceList() + { return "Namespace List"; } + virtual QString trNamespaceListDescription(bool extractAll) + { + QString result="Here is a list of all "; + if (!extractAll) result+="documented "; + result+="namespaces with brief descriptions:"; + return result; + } + virtual QString trFriends() + { return "Friends"; } + + // new since 0.49-990405 + + virtual QString trRelatedFunctionDocumentation() + { return "Friends And Related Function Documentation"; } +}; + +#endif diff --git a/src/translator_cz.h b/src/translator_cz.h new file mode 100644 index 0000000..9a0656e --- /dev/null +++ b/src/translator_cz.h @@ -0,0 +1,278 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef TRANSLATOR_CZ_H +#define TRANSLATOR_CZ_H + +#include <qstring.h> + +// The translation from English to Czech by Vlastimil Havran. +// In the cases where are more translations possible I hope +// that I have selected the most reasonable text. If not, please, +// mail the comments and text proposals to +// +// havran@fel.cvut.cz, 1999/04/11 + +class TranslatorCzech : public Translator +{ + public: + QString latexBabelPackage() + { return "czech"; } + QString trInherits() + { return "Dedi"; } + QString trAnd() + { return "a"; } + QString trInheritedBy() + { return "Je Potomkem"; } + QString trRelatedFunctions() + { return "Pribuzne Metody"; } + QString trRelatedSubscript() + { return "(Tyto funkce nejsou metody.)"; } + QString trDetailedDescription() + { return "Podrobna Dokumentace"; } + QString trMemberTypedefDocumentation() + { return "Dokumentace pro Deklaraci Typu (typedef) ve Tride";} + QString trMemberEnumerationDocumentation() + { return "Dokumentace Vyctovych Typu"; } + QString trEnumerationValueDocumentation() + { return "Dokumentace Hodnot Vyctovych Typu"; } + QString trMemberFunctionDocumentation() + { return "Dokumentace Metod"; } + QString trMemberDataDocumentation() + { return "Dokumentace Datovych Slozek Tridy"; } + QString trGeneratedFrom(const char *s,bool single) + { + QString result=(QString)"Dokumentace pro tento"+s+ + " byla generovana z nasledujiciho souboru"; + if (single) result+=":"; else result+="s:"; + return result; + } + QString trMore() + { return "Detaily"; } + QString trReference() + { return "Reference"; } + QString trListOfAllMembers() + { return "Seznam vsech datovych slozek a metod tridy."; } + QString trMemberList() + { return "Seznam datovych polozek a metod tridy"; } + QString trThisIsTheListOfAllMembers() + { return "Toto je uplny seznam datovych slozek a metod tridy pro"; } + QString trIncludingInheritedMembers() + { return "zahrnuje vsechny nasledujici zdedene datove slozky a metody."; } + QString trGeneratedAutomatically(const char *s) + { QString result="Automaticky vygenerovany pomoci programu Doxygen"; + if (s) result+=(QString)" pro "+s; + result+=" ze zdrojoveho souboru."; + return result; + } + QString trEnumName() + { return "pojmenovani vyctoveho typu"; } + QString trEnumValue() + { return "hodnota vyctoveho typu"; } + QString trDefinedIn() + { return "definovany v"; } + QString trIncludeFile() + { return "Vklada soubor"; } + QString trVerbatimText(const char *f) + { return (QString)"Toto je presny text z vlozeneho souboru "+f+""; } + QString trModules() + { return "Moduly"; } + QString trClassHierarchy() + { return "Hierarchie trid"; } + QString trCompoundList() + { return "Seznam objektovych typu"; } + QString trFileList() + { return "Seznam souboru"; } + QString trHeaderFiles() + { return "Hlavickove soubory"; } + QString trCompoundMembers() + { return "Datove slozky a metody objektovych typu"; } + QString trFileMembers() + { return "Globalni deklarace"; } + QString trRelatedPages() + { return "Souvisejici stranky"; } + QString trExamples() + { return "Priklady:"; } + QString trSearch() + { return "Hledej"; } + QString trClassHierarchyDescription() + { return "Tento seznam dedicnych zavislosti je temer setriden" + " podle abecedy:"; + } + QString trFileListDescription(bool extractAll) + { + QString result="A toto je seznam vsech "; + if (!extractAll) result+="dokumentovanych "; + result+="souboru s kratkymi popisy:"; + return result; + } + QString trCompoundListDescription() + { return "Zde jsou tridy, struktury a " + "unie s kratkymi popisy:"; + } + QString trCompoundMembersDescription(bool extractAll) + { + QString result="Zde je seznam vsech "; + if (!extractAll) result+="dokumentovanych "; + result+="clenu tridy (metod a datovych slozek) s odkazy na "; + if (extractAll) result+="dokumentaci tridy pro kazdo polozku:"; + else result+="tridy, kam patri:"; + return result; + } + QString trFileMembersDescription(bool extractAll) + { + QString result="Zde je seznam vsech "; + if (!extractAll) result+="zdokumentovanych "; + result+="globalnich deklaraci s odkazy "; + if (extractAll) result+="na dokumentaci k souboru pro kazdou deklaraci:"; + else result+="na soubory, kde jsou umisteny:"; + return result; + } + QString trHeaderFilesDescription() + {return "Zde jsou hlavickove soubory ktere tvori programove" + " rozhrani aplikace(API):"; + } + QString trExamplesDescription() + { return "Zde je seznam vsech prikladu:"; } + QString trRelatedPagesDescription() + { return "Zde je seznam vsech souvisejicich stranek dokumentace:"; } + QString trModulesDescription() + { return "Zde je seznam vsech modulu:"; } + QString trNoDescriptionAvailable() + { return "Zadny popis neni k dispozici."; } + + QString trDocumentation() + { return "Dokumentace"; } + QString trModuleIndex() + { return "Index modulu"; } + QString trHierarchicalIndex() + { return "Index Hierarchie"; } + QString trCompoundIndex() + { return "Index objektovych typu"; } + QString trFileIndex() + { return "Index souboru"; } + QString trModuleDocumentation() + { return "Dokumentace modulu"; } + QString trClassDocumentation() + { return "Dokumentace tridy"; } + QString trFileDocumentation() + { return "Dokumentace souboru"; } + QString trExampleDocumentation() + { return "Dokumentace prikladu"; } + QString trPageDocumentation() + { return "Dokumentace stranek"; } + QString trReferenceManual() + { return "Referencni manual"; } + + QString trDefines() + { return "Definice"; } + QString trFuncProtos() + { return "Prototypy funkci"; } + QString trTypedefs() + { return "Deklarace datovych typu(typedefs)"; } + QString trEnumerations() + { return "Vyctove typy (enumerations)"; } + QString trFunctions() + { return "Funkce"; } + QString trVariables() + { return "Promenne"; } + QString trEnumerationValues() + { return "Hodnoty vyctovych typu"; } + QString trReimplementedFrom() + { return "Je znovu implementovan z"; } + QString trReimplementedIn() + { return "Je znovu implementovan v"; } + QString trAuthor() + { return "Autor"; } + QString trDefineDocumentation() + { return "Dokumentace definic pomoci maker"; } + QString trFunctionPrototypeDocumentation() + { return "Dokumentace prototypu funkci"; } + QString trTypedefDocumentation() + { return "Dokumentace deklaraci datovych typu(typedefs)"; } + QString trEnumerationTypeDocumentation() + { return "Dokumentace vyctovych typu"; } + QString trFunctionDocumentation() + { return "Dokumentace funkci"; } + QString trVariableDocumentation() + { return "Dokumentace promennych"; } + QString trCompounds() + { return "Polozky objektovych typu"; } + QString trFiles() + { return "Soubory:"; } + QString trGeneratedAt(const char *date,const char *projName) + { + QString result=(QString)"Gegenerovany v "+date; + if (projName) result+=(QString)" pro "+projName; + result+=(QString)" "; + return result; + } + QString trWrittenBy() + { + return "napsany "; + } + QString trClassDiagram(const char *clName) + { + return (QString)"Diagram trid pro "+clName; + } + QString trForInternalUseOnly() + { return "Jen pro interni pouziti."; } + QString trReimplementedForInternalReasons() + { + return "Znovu implementovany z internich duvodu; programove rozhrani" + " aplikace(API) neni zmeneno."; + } + QString trWarning() + { return "Upozorneni"; } + QString trBugsAndLimitations() + { return "Chyby a omezeni"; } + QString trVersion() + { return "Verze"; } + QString trDate() + { return "Datum"; } + QString trAuthors() + { return "Autor(i)"; } + QString trReturns() + { return "ma navratovou hodnotu"; } + QString trSeeAlso() + { return "Podivej se take na"; } + QString trParameters() + { return "Parametry"; } + QString trExceptions() + { return "Vyjimky"; } + QString trGeneratedBy() + { return "Gegenerovan podle"; } + + // new since 0.49-990307 + + QString trNamespaces() + { return "Prostory jmen"; } + QString trNamespaceList() + { return "Seznam prostoru jmen"; } + QString trNamespaceListDescription(bool extractAll) + { + QString result="Zde jsou vsechny "; + if (!extractAll) result+="dokumentovane "; + result+="prostory jem s kratkymi popisy:"; + return result; + } + QString trFriends() + { return "Spratelene tridy, funkce a metody"; } +}; + +#endif // TRANSLATOR_CZ_H + + diff --git a/src/translator_fr.h b/src/translator_fr.h new file mode 100644 index 0000000..cd78053 --- /dev/null +++ b/src/translator_fr.h @@ -0,0 +1,270 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef TRANSLATOR_FR_H +#define TRANSLATOR_FR_H + +#include <qstring.h> + +class TranslatorFrench : public Translator +{ + public: + QString latexBabelPackage() + { return "french"; } + QString trInherits() + { return "Hérite de"; } + QString trAnd() + { return "et"; } + QString trInheritedBy() + { return "Dérivée par"; } + QString trRelatedFunctions() + { return "Fonctions associées"; } + QString trRelatedSubscript() + { return "(Noter que ces fonctions ne sont pas des méthodes de la classe)"; } + QString trDetailedDescription() + { return "Description détaillée"; } + QString trMemberTypedefDocumentation() + { return "Documentation des types imbriqués"; } + QString trMemberEnumerationDocumentation() + { return "Documentation des énumérations imbriqués"; } + QString trMemberFunctionDocumentation() + { return "Documentation des méthodes"; } + QString trMemberDataDocumentation() + { return "Documentation des données imbriqués"; } + QString trGeneratedFrom(const char *s,bool single) + { + QString result=(QString)"La documentation pour cette"+s+ + " a été générée à partir "; + if (single) result+="du fichier suivant:"; + else result+="des fichiers suivants:"; + return result; + } + QString trMore() + { return "Plus de détails..."; } + QString trReference() + { return "Référence"; } + QString trListOfAllMembers() + { return "Liste de tous les membres"; } + QString trMemberList() + { return "Liste des membres"; } + QString trThisIsTheListOfAllMembers() + { return "Ceci est la liste complète des membres de"; } + QString trIncludingInheritedMembers() + { return "y compris des membres des classes héritées."; } + QString trGeneratedAutomatically(const char *s) + { QString result="Généré automatiquement par Doxygen"; + if (s) result+=(QString)" pour "+s; + result+=" à partir du code source."; + return result; + } + QString trEnumName() + { return "énumération"; } + QString trEnumValue() + { return "élément d'une énumération"; } + QString trDefinedIn() + { return "défini dans"; } + QString trIncludeFile() + { return "Fichier inclu"; } + QString trVerbatimText(const char *f) + { return (QString)"Ce texte provient du fichier inclu "+f+"."; } + + + QString trModules() + { return "Modules"; } + QString trClassHierarchy() + { return "Hiérarchie des classes"; } + QString trCompoundList() + { return "Liste des composants"; } + QString trFileList() + { return "Liste des fichiers"; } + QString trHeaderFiles() + { return "Fichiers d'entête"; } + QString trCompoundMembers() + { return "Composants"; } + QString trFileMembers() + { return "Déclarations"; } + QString trRelatedPages() + { return "Pages associées"; } + QString trExamples() + { return "Exemples"; } + QString trSearch() + { return "Recherche"; } + QString trClassHierarchyDescription() + { return "Cette liste d'héritage est, autant que possible, " + "classée par ordre alphabétique"; } + QString trFileListDescription(bool extractAll) + { + QString result="Liste de tous les fichiers "; + if (!extractAll) result+="documentés "; + result+="avec une brève description :"; + return result; + } + QString trCompoundListDescription() + { return "Liste des classes, des strutures et des unions " + "avec une brève description :"; + } + QString trCompoundMembersDescription(bool extractAll) + { + QString result="Liste de tous les membres de classe "; + if (!extractAll) result+="documentés "; + result+="avec les liens vers "; + if (extractAll) result+="la documentation de la classe correspondante :"; + else result+="les classes auxquelles ils appartiennent :"; + return result; + } + QString trFileMembersDescription(bool extractAll) + { + QString result="Liste de toutes les déclarations"; + if (!extractAll) result+="documentées "; + result+="avec liens sur "; + if (extractAll) result+="la documentation du fichier correspondant " + "pour chacune :"; + else result+="les fichiers dans lesquels elles sont définies :"; + return result; + } + QString trHeaderFilesDescription() + { return "Liste de tous les fichiers d'entête constituant " + "l'interface de programmation :"; } + QString trExamplesDescription() + { return "Liste de tous les exemples :"; } + QString trRelatedPagesDescription() + { return "Liste de toutes les pages de documentation associées :"; } + QString trModulesDescription() + { return "Liste de tous les modules"; } + QString trNoDescriptionAvailable() + { return "Aucune description n'est disponible"; } + + QString trDocumentation() + { return "Documentation"; } + QString trModuleIndex() + { return "Index des modules"; } + QString trHierarchicalIndex() + { return "Index hiérarchique"; } + QString trCompoundIndex() + { return "Index des composants"; } + QString trFileIndex() + { return "Index des fichiers"; } + QString trModuleDocumentation() + { return "Documentation du module"; } + QString trClassDocumentation() + { return "Documentation de la classe"; } + QString trFileDocumentation() + { return "Documentation du fichier"; } + QString trExampleDocumentation() + { return "Documentation de l'exemple"; } + QString trPageDocumentation() + { return "Documentation de la page"; } + QString trReferenceManual() + { return "Manuel de référence"; } + + QString trDefines() + { return "Définitions des macros"; } + QString trFuncProtos() + { return "Prototypes des fonctions"; } + QString trTypedefs() + { return "Définitions des types"; } + QString trEnumerations() + { return "Enumérations"; } + QString trFunctions() + { return "Fonctions"; } + QString trVariables() + { return "Variables"; } + QString trEnumerationValues() + { return "Eléments énumérés"; } + QString trReimplementedFrom() + { return "Redéfini à partir de"; } + QString trReimplementedIn() + { return "Redéfini dans"; } + QString trAuthor() + { return "Auteur"; } + QString trDefineDocumentation() + { return "Documentation de la macro"; } + QString trFunctionPrototypeDocumentation() + { return "Documentation du prototype de la fonction"; } + QString trTypedefDocumentation() + { return "Documentation du type"; } + QString trEnumerationTypeDocumentation() + { return "Documentation du type de l'énumeration"; } + QString trEnumerationValueDocumentation() + { return "Documentation de l'élément de l'énumeration"; } + QString trFunctionDocumentation() + { return "Documentation de la fonction"; } + QString trVariableDocumentation() + { return "Documentation de la variable"; } + QString trCompounds() + { return "Composants"; } + QString trFiles() + { return "Fichiers"; } + QString trGeneratedAt(const char *date,const char *projName) + { + QString result=(QString)"Généré le "+date; + if (projName) result+=(QString)" pour "+projName; + result+=(QString)" par "; + return result; + } + QString trWrittenBy() + { + return "écrit par"; + } + QString trClassDiagram(const char *clName) + { + return (QString)"Graphe d'héritage de la classe "+clName; + } + QString trForInternalUseOnly() + { return "A usage interne uniquement."; } + QString trReimplementedForInternalReasons() + { return "Redéfini pour des raisons internes; " + "l'interface n'est pas modifiée"; + } + QString trWarning() + { return "Avertissement"; } + QString trBugsAndLimitations() + { return "Bogues et limitations"; } + QString trVersion() + { return "Version"; } + QString trDate() + { return "Date"; } + QString trAuthors() + { return "Auteur(s)"; } + QString trReturns() + { return "Renvoie"; } + QString trSeeAlso() + { return "Voir également"; } + QString trParameters() + { return "Paramètres"; } + QString trExceptions() + { return "Exceptions"; } + QString trGeneratedBy() + { return "Généré par"; } + + // new since 0.49-990307 + + virtual QString trNamespaces() + { return "Namespaces"; } + virtual QString trNamespaceList() + { return "List des Namespaces"; } + virtual QString trNamespaceListDescription(bool extractAll) + { + QString result="Liste de tous les namespaces "; + if (!extractAll) result+="documentés "; + result+="avec une brève description :"; + return result; + } + virtual QString trFriends() + { return "Friends"; } +}; + +#endif diff --git a/src/translator_it.h b/src/translator_it.h new file mode 100644 index 0000000..316f43a --- /dev/null +++ b/src/translator_it.h @@ -0,0 +1,266 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef TRANSLATOR_IT_H +#define TRANSLATOR_IT_H + +#include <qstring.h> + +class TranslatorItalian : public Translator +{ + public: + QString latexBabelPackage() + { return "italian"; } + QString trInherits() + { return "eredita"; } + QString trAnd() + { return "e"; } + QString trInheritedBy() + { return "Ereditato da"; } + QString trRelatedFunctions() + { return "Funzioni relative"; } + QString trRelatedSubscript() + { return "(Nota che questo no sono funzioni membro)"; } + QString trDetailedDescription() + { return "Descrizione dettagliata"; } + QString trMemberTypedefDocumentation() + { return "Documentazione dei membri Typedef"; } + QString trMemberEnumerationDocumentation() + { return "Documentazione dei membri enumerati"; } + QString trEnumerationValueDocumentation() + { return "Documentazione dei tipi enumerati"; } + QString trMemberFunctionDocumentation() + { return "Documentazione delle funzioni membro"; } + QString trMemberDataDocumentation() + { return "Documentazione dei dati membro"; } + QString trGeneratedFrom(const char *s,bool single) + { + QString result=(QString)"La documentazione di questa "+s+ + " e stata generata dal seguente file"; + if (single) result+=":"; else result+=":"; + return result; + } + QString trMore() + { return "Continua..."; } + QString trReference() + { return "Riferimento"; } + QString trListOfAllMembers() + { return "Lista di tuti i memberi."; } + QString trMemberList() + { return "Lista membri"; } + QString trThisIsTheListOfAllMembers() + { return "Questa e la lista completa di tutti i membri"; } + QString trIncludingInheritedMembers() + { return "includendo tutti i membri ereditati."; } + QString trGeneratedAutomatically(const char *s) + { QString result="Generato automaticalmenta da Doxygen"; + if (s) result+=(QString)" per "+s; + result+=" dall codice."; + return result; + } + QString trEnumName() + { return "nome dell enum"; } + QString trEnumValue() + { return "valore dell enum"; } + QString trDefinedIn() + { return "definito in"; } + QString trIncludeFile() + { return "Include il file"; } + QString trVerbatimText(const char *f) + { return (QString)"Questo e il contenuto verbatim dell file "+f+"."; } + QString trModules() + { return "Moduli"; } + QString trClassHierarchy() + { return "gerarchia delle classi"; } + QString trCompoundList() + { return "Lista dei tipi composti"; } + QString trFileList() + { return "Lista dei file"; } + QString trHeaderFiles() + { return "List dei fei file header"; } + QString trCompoundMembers() + { return "Membri composti"; } + QString trFileMembers() + { return "Membri dell file"; } + QString trRelatedPages() + { return "Relativo a pagina"; } + QString trExamples() + { return "Esempio"; } + QString trSearch() + { return "Ricerca"; } + QString trClassHierarchyDescription() + { return "Qua sono la lista delle classi, structs e unions" + "gesorte:"; + } + QString trFileListDescription(bool extractAll) + { + QString result="Hieronder volgt de lijst met alle "; + if (!extractAll) result+="gedocumenteerde "; + result+="files, elk met een korte beschrijving:"; + return result; + } + QString trCompoundListDescription() + { return "Hieronder volgen de klassen, structs en " + "unions met voor elk een korte beschrijving:"; + } + QString trCompoundMembersDescription(bool extractAll) + { + QString result="Hieronder volgt de lijst met alle "; + if (!extractAll) result+="gedocumenteerde "; + result+="klasse members met links naar "; + if (extractAll) result+="de klasse Documentazione voor elke member:"; + else result+="de klassen waartoe ze behoren:"; + return result; + } + QString trFileMembersDescription(bool extractAll) + { + QString result="Hieronder volgt de lijst met alle "; + if (!extractAll) result+="gedocumenteerde "; + result+="file members met links naar "; + if (extractAll) result+="de file Documentazione voor elke member:"; + else result+="de files waartoe ze behoren:"; + return result; + } + QString trHeaderFilesDescription() + { return "Hieronder volgen de header files die de API vormen:"; } + QString trExamplesDescription() + { return "Hieronder volgt de lijst met alle voorbeelden:"; } + QString trRelatedPagesDescription() + { return "Hieronder volgt de lijst met alle pagina's die gerelateerde Documentazione bevatten:"; } + QString trModulesDescription() + { return "Hieronder volgt de lijst met alle modules:"; } + QString trNoDescriptionAvailable() + { return "Geen korte beschrijving beschikbaar"; } + + QString trDocumentation() + { return "Documentazione"; } + QString trModuleIndex() + { return "Module Index"; } + QString trHierarchicalIndex() + { return "Hiërarchische Index"; } + QString trCompoundIndex() + { return "Compound Index"; } + QString trFileIndex() + { return "File Index"; } + QString trModuleDocumentation() + { return "Module Documentazione"; } + QString trClassDocumentation() + { return "Klasse Documentazione"; } + QString trFileDocumentation() + { return "File Documentazione"; } + QString trExampleDocumentation() + { return "Documentazione di voorbeelden"; } + QString trPageDocumentation() + { return "Documentazione di gerelateerde pagina's"; } + QString trReferenceManual() + { return "Naslagwerk"; } + + QString trDefines() + { return "Defines"; } + QString trFuncProtos() + { return "Functie Prototypes"; } + QString trTypedefs() + { return "Typedefs"; } + QString trEnumerations() + { return "Enumeraties"; } + QString trFunctions() + { return "Functies"; } + QString trVariables() + { return "Variabelen"; } + QString trEnumerationValues() + { return "Enumeratie waarden"; } + QString trReimplementedFrom() + { return "Nieuwe implementatie di"; } + QString trReimplementedIn() + { return "Opnieuw geïmplementeerd in"; } + QString trAuthor() + { return "auteur"; } + QString trDefineDocumentation() + { return "Lista "; } + QString trFunctionPrototypeDocumentation() + { return "Documentazione di functie Prototypes"; } + QString trTypedefDocumentation() + { return "Documentazione di typedefs"; } + QString trEnumerationTypeDocumentation() + { return "Documentazione di enumeratie types"; } + QString trFunctionDocumentation() + { return "Documentazione di functies"; } + QString trVariableDocumentation() + { return "Lista variabelen"; } + QString trCompounds() + { return "Compounds"; } + QString trFiles() + { return "Files"; } + QString trGeneratedAt(const char *date,const char *projName) + { + QString result=(QString)"Gegenereerd op "+date; + if (projName) result+=(QString)" voor "+projName; + result+=(QString)" door"; + return result; + } + QString trWrittenBy() + { + return "geschreven door"; + } + QString trClassDiagram(const char *clName) + { + return (QString)"Klasse diagram voor "+clName; + } + QString trForInternalUseOnly() + { return "Alleen voor intern gebruik."; } + QString trReimplementedForInternalReasons() + { return "Om interne rederene opnieuwd geïmplemented; " + "de API wordt er niet door beïnvloed."; + } + QString trWarning() + { return "Waarschuwing"; } + QString trBugsAndLimitations() + { return "Fouten en beperkingen"; } + QString trVersion() + { return "Versie"; } + QString trDate() + { return "Datum"; } + QString trAuthors() + { return "Auteur(s)"; } + QString trReturns() + { return "Retourneerd"; } + QString trSeeAlso() + { return "Zie ook"; } + QString trParameters() + { return "Parameters"; } + QString trExceptions() + { return "Excepties"; } + QString trGeneratedBy() + { return "Gegenereerd door"; } + + // new since 0.49-990307 + + QString trNamespaces() + { return "Namespaces"; } + QString trNamespaceList() + { return "Namespace Lijst"; } + QString trNamespaceListDescription(bool extractAll) + { + QString result="Hier is een lijst met alle "; + if (!extractAll) result+="gedocumenteerde "; + result+="namespaces met voor elk een korte beschrijving:"; + return result; + } + QString trFriends() + { return "Friends"; } +}; + +#endif diff --git a/src/translator_nl.h b/src/translator_nl.h new file mode 100644 index 0000000..25e7ed4 --- /dev/null +++ b/src/translator_nl.h @@ -0,0 +1,266 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef TRANSLATOR_NL_H +#define TRANSLATOR_NL_H + +#include <qstring.h> + +class TranslatorDutch : public Translator +{ + public: + QString latexBabelPackage() + { return "dutch"; } + QString trInherits() + { return "Erft over van"; } + QString trAnd() + { return "en"; } + QString trInheritedBy() + { return "Wordt overgeërfd door"; } + QString trRelatedFunctions() + { return "Gerelateerde functies"; } + QString trRelatedSubscript() + { return "(Merk op dat dit geen member functies zijn.)"; } + QString trDetailedDescription() + { return "Gedetaileerde Beschrijving"; } + QString trMemberTypedefDocumentation() + { return "Documentatie van type definitie members"; } + QString trMemberEnumerationDocumentation() + { return "Documentatie van enumeratie members"; } + QString trEnumerationValueDocumentation() + { return "Documentatie van enumeratie waarden"; } + QString trMemberFunctionDocumentation() + { return "Documentatie van functie members"; } + QString trMemberDataDocumentation() + { return "Documentatie van data members"; } + QString trGeneratedFrom(const char *s,bool single) + { + QString result=(QString)"De documentatie voor deze"+s+ + " is gegenereerd op grond van de volgende file"; + if (single) result+=":"; else result+="s:"; + return result; + } + QString trMore() + { return "Meer..."; } + QString trReference() + { return "Referentie"; } + QString trListOfAllMembers() + { return "Lijst van alle members."; } + QString trMemberList() + { return "Member Lijst"; } + QString trThisIsTheListOfAllMembers() + { return "Dit is de complete lijst van alle members voor"; } + QString trIncludingInheritedMembers() + { return "inclusief alle overgeërfde members."; } + QString trGeneratedAutomatically(const char *s) + { QString result="Automatisch gegenereerd door Doxygen"; + if (s) result+=(QString)" voor "+s; + result+=" uit de programmacode."; + return result; + } + QString trEnumName() + { return "enum naam"; } + QString trEnumValue() + { return "enum waarde"; } + QString trDefinedIn() + { return "gedefinieerd in"; } + QString trIncludeFile() + { return "Include File"; } + QString trVerbatimText(const char *f) + { return (QString)"Dit is de letterlijke tekst van de include file "+f+"."; } + QString trModules() + { return "Modules"; } + QString trClassHierarchy() + { return "Klasse Hiërarchie"; } + QString trCompoundList() + { return "Compound Lijst"; } + QString trFileList() + { return "File Lijst"; } + QString trHeaderFiles() + { return "Header Lijst"; } + QString trCompoundMembers() + { return "Compound Members"; } + QString trFileMembers() + { return "File members"; } + QString trRelatedPages() + { return "Gerelateerde pagina's"; } + QString trExamples() + { return "Voorbeelden"; } + QString trSearch() + { return "Zoeken"; } + QString trClassHierarchyDescription() + { return "Deze inheritance lijst is min of meer alfabetisch " + "gesorteerd:"; + } + QString trFileListDescription(bool extractAll) + { + QString result="Hieronder volgt de lijst met alle "; + if (!extractAll) result+="gedocumenteerde "; + result+="files, elk met een korte beschrijving:"; + return result; + } + QString trCompoundListDescription() + { return "Hieronder volgen de klassen, structs en " + "unions met voor elk een korte beschrijving:"; + } + QString trCompoundMembersDescription(bool extractAll) + { + QString 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; + } + QString trFileMembersDescription(bool extractAll) + { + QString result="Hieronder volgt de lijst met alle "; + if (!extractAll) result+="gedocumenteerde "; + result+="file members met links naar "; + if (extractAll) result+="de file documentatie voor elke member:"; + else result+="de files waartoe ze behoren:"; + return result; + } + QString trHeaderFilesDescription() + { return "Hieronder volgen de header files die de API vormen:"; } + QString trExamplesDescription() + { return "Hieronder volgt de lijst met alle voorbeelden:"; } + QString trRelatedPagesDescription() + { return "Hieronder volgt de lijst met alle pagina's die gerelateerde documentatie bevatten:"; } + QString trModulesDescription() + { return "Hieronder volgt de lijst met alle modules:"; } + QString trNoDescriptionAvailable() + { return "Geen korte beschrijving beschikbaar"; } + + QString trDocumentation() + { return "Documentatie"; } + QString trModuleIndex() + { return "Module Index"; } + QString trHierarchicalIndex() + { return "Hiërarchische Index"; } + QString trCompoundIndex() + { return "Compound Index"; } + QString trFileIndex() + { return "File Index"; } + QString trModuleDocumentation() + { return "Module Documentatie"; } + QString trClassDocumentation() + { return "Klasse Documentatie"; } + QString trFileDocumentation() + { return "File Documentatie"; } + QString trExampleDocumentation() + { return "Documentatie van voorbeelden"; } + QString trPageDocumentation() + { return "Documentatie van gerelateerde pagina's"; } + QString trReferenceManual() + { return "Naslagwerk"; } + + QString trDefines() + { return "Defines"; } + QString trFuncProtos() + { return "Functie Prototypes"; } + QString trTypedefs() + { return "Typedefs"; } + QString trEnumerations() + { return "Enumeraties"; } + QString trFunctions() + { return "Functies"; } + QString trVariables() + { return "Variabelen"; } + QString trEnumerationValues() + { return "Enumeratie waarden"; } + QString trReimplementedFrom() + { return "Nieuwe implementatie van"; } + QString trReimplementedIn() + { return "Opnieuw geïmplementeerd in"; } + QString trAuthor() + { return "auteur"; } + QString trDefineDocumentation() + { return "Documentatie van defines"; } + QString trFunctionPrototypeDocumentation() + { return "Documentatie van functie Prototypes"; } + QString trTypedefDocumentation() + { return "Documentatie van typedefs"; } + QString trEnumerationTypeDocumentation() + { return "Documentatie van enumeratie types"; } + QString trFunctionDocumentation() + { return "Documentatie van functies"; } + QString trVariableDocumentation() + { return "Documentatie van variabelen"; } + QString trCompounds() + { return "Compounds"; } + QString trFiles() + { return "Files"; } + QString trGeneratedAt(const char *date,const char *projName) + { + QString result=(QString)"Gegenereerd op "+date; + if (projName) result+=(QString)" voor "+projName; + result+=(QString)" door"; + return result; + } + QString trWrittenBy() + { + return "geschreven door"; + } + QString trClassDiagram(const char *clName) + { + return (QString)"Klasse diagram voor "+clName; + } + QString trForInternalUseOnly() + { return "Alleen voor intern gebruik."; } + QString trReimplementedForInternalReasons() + { return "Om interne rederene opnieuwd geïmplemented; " + "de API wordt er niet door beïnvloed."; + } + QString trWarning() + { return "Waarschuwing"; } + QString trBugsAndLimitations() + { return "Fouten en beperkingen"; } + QString trVersion() + { return "Versie"; } + QString trDate() + { return "Datum"; } + QString trAuthors() + { return "Auteur(s)"; } + QString trReturns() + { return "Retourneerd"; } + QString trSeeAlso() + { return "Zie ook"; } + QString trParameters() + { return "Parameters"; } + QString trExceptions() + { return "Excepties"; } + QString trGeneratedBy() + { return "Gegenereerd door"; } + + // new since 0.49-990307 + + QString trNamespaces() + { return "Namespaces"; } + QString trNamespaceList() + { return "Namespace Lijst"; } + QString trNamespaceListDescription(bool extractAll) + { + QString result="Hier is een lijst met alle "; + if (!extractAll) result+="gedocumenteerde "; + result+="namespaces met voor elk een korte beschrijving:"; + return result; + } + QString trFriends() + { return "Friends"; } +}; + +#endif diff --git a/src/translator_se.h b/src/translator_se.h new file mode 100644 index 0000000..15b6c18 --- /dev/null +++ b/src/translator_se.h @@ -0,0 +1,250 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef TRANSLATOR_SE_H +#define TRANSLATOR_SE_H + +#include <qstring.h> + +class TranslatorSwedish : public Translator +{ + public: + QString latexBabelPackage() + { return "swedish"; } + QString trInherits() + { return "Ärver"; } + QString trAnd() + { return "och"; } + QString trInheritedBy() + { return "Ärvd av"; } + QString trRelatedFunctions() + { return "Besläktade funktioner"; } + QString trRelatedSubscript() + { return "(Observera att dessa inte är medlemsfunktioner)"; } + QString trDetailedDescription() + { return "Utökad beskrivning"; } + QString trMemberTypedefDocumentation() + { return "Har inte en aning..."; } + QString trMemberEnumerationDocumentation() + { return "Uppräknad dokumentation???"; } + QString trEnumerationValueDocumentation() + { return "Documentatie van enumeratie waarden"; } + QString trMemberFunctionDocumentation() + { return "Dokumentation av medlemsfunktioner"; } + QString trMemberDataDocumentation() + { return "Dokumentation av datamedlemmar"; } + QString trGeneratedFrom(const char *s,bool single) + { + QString result=(QString)"Dokumentationen för detta"+s+ + " är skapad ur följande fil"; + if (single) result+=":"; else result+="s:"; + return result; + } + QString trMore() + { return "Fler..."; } + QString trReference() + { return "Hänvisning?"; } + QString trListOfAllMembers() + { return "Lista över alla medlemmar."; } + QString trMemberList() + { return "Medlemslista"; } + QString trThisIsTheListOfAllMembers() + { return "Det här är en fullständig lista av medlemmar för?"; } + QString trIncludingInheritedMembers() + { return "med alla ärvda medlemmar."; } + QString trGeneratedAutomatically(const char *s) + { QString result="Automatiskt skapad av Doxygen"; + if (s) result+=(QString)" för "+s; + result+=" från källkoden."; + return result; + } + QString trEnumName() + { return "enum namn?"; } + QString trEnumValue() + { return "enum värde?"; } + QString trDefinedIn() + { return "deklarerad i"; } + QString trIncludeFile() + { return "Include Fil"; } + QString trVerbatimText(const char *f) + { return (QString)"Detta är den ordagranna texten av "+f+" include fil."; } + QString trModules() + { return "Moduler?"; } + QString trClassHierarchy() + { return "Klasshierarki?"; } + QString trCompoundList() + { return "Inhägnad lista???"; } + QString trFileList() + { return "Fillista"; } + QString trHeaderFiles() + { return "Headerfiler"; } + QString trCompoundMembers() + { return "Inhägnade medlemmar??"; } + QString trFileMembers() + { return "Filmedlemmar???"; } + QString trRelatedPages() + { return "Besläktade sidor"; } + QString trExamples() + { return "Exempel"; } + QString trSearch() + { return "Sök"; } + QString trClassHierarchyDescription() + { return "Denna lista över arv är grovsorterad, men inte helt " + "i alfabetisk ordning:"; + } + QString trFileListDescription(bool extractAll) + { + QString result="Här följer en lista över alla "; + if (!extractAll) result+="dokumenterade "; + result+="filer, med en kort beskrivning:"; + return result; + } + QString trCompoundListDescription() + { return "Här följer klasserna, structs och " + "unions? med en kort beskrivning:"; + } + QString trCompoundMembersDescription(bool extractAll) + { + QString result="Här följer en lista över alla "; + if (!extractAll) result+="dokumenterade "; + result+="klassmedlemmar med länkar till "; + if (extractAll) result+="klassdokumentationen för varje medlem:"; + else result+="klasserna som de tillhör:"; + return result; + } + QString trFileMembersDescription(bool extractAll) + { + QString result="Här följer en lista över alla "; + if (!extractAll) result+="dokumenterade "; + result+="filmedlemmar? med länkar till "; + if (extractAll) result+="dokumentationsfilen för varje medlem:"; + else result+="filerna som de tillhör:"; + return result; + } + QString trHeaderFilesDescription() + { return "Här följer headerfilerna som API:n består av???:"; } + QString trExamplesDescription() + { return "Här följer en lista med alla exempel:"; } + QString trRelatedPagesDescription() + { return "Här följer en lista med alla relevanta? dokumentationssidor:"; } + QString trModulesDescription() + { return "Här följer en lista över alla moduler:"; } + QString trNoDescriptionAvailable() + { return "Beskrivning saknas"; } + + QString trDocumentation() + { return "Dokumentation"; } + QString trModuleIndex() + { return "Module Index"; } + QString trHierarchicalIndex() + { return "Hierarkiskt Index"; } + QString trCompoundIndex() + { return "Compound Index"; } + QString trFileIndex() + { return "Fil Index"; } + QString trModuleDocumentation() + { return "Dokumentation över moduler"; } + QString trClassDocumentation() + { return "Dokumentation över klasser"; } + QString trFileDocumentation() + { return "Dokumentation över filer"; } + QString trExampleDocumentation() + { return "Dokumentation över exempel"; } + QString trPageDocumentation() + { return "Dokumentation av sidor"; } + QString trReferenceManual() + { return "Uppslagsbok"; } + + QString trDefines() + { return "Definerar"; } + QString trFuncProtos() + { return "Funktionsprototyper"; } + QString trTypedefs() + { return "Typedefs"; } + QString trEnumerations() + { return "Uppräkning???"; } + QString trFunctions() + { return "Funktioner"; } + QString trVariables() + { return "Variabler"; } + QString trEnumerationValues() + { return "Enum värden??"; } + QString trReimplementedFrom() + { return "Återanvänd från???"; } + QString trReimplementedIn() + { return "Återanvänd i??"; } + QString trAuthor() + { return "Författare"; } + QString trDefineDocumentation() + { return "Definiera dokumentation"; } + QString trFunctionPrototypeDocumentation() + { return "Dokumentation över funktionsprototyper"; } + QString trTypedefDocumentation() + { return "Dokumentation över typedefs"; } + QString trEnumerationTypeDocumentation() + { return "Dokumentation över enum typer"; } + QString trFunctionDocumentation() + { return "Dokumentation över funktioner"; } + QString trVariableDocumentation() + { return "Dokumentation över variabler"; } + QString trCompounds() + { return "Compounds??"; } + QString trFiles() + { return "Filer"; } + QString trGeneratedAt(const char *date,const char *projName) + { + QString result=(QString)"Skapad "+date; + if (projName) result+=(QString)" för "+projName; + result+=(QString)" av"; + return result; + } + QString trWrittenBy() + { + return "skriven av"; + } + QString trClassDiagram(const char *clName) + { + return (QString)"Klass diagram för "+clName; + } + QString trForInternalUseOnly() + { return "Endast för internt bruk."; } + QString trReimplementedForInternalReasons() + { return "Omskriven av interna orsaker???; " + "API:n påverkas inte."; + } + QString trWarning() + { return "Varning"; } + QString trBugsAndLimitations() + { return "Fel och begränsningar"; } + QString trVersion() + { return "Version"; } + QString trDate() + { return "Datum"; } + QString trAuthors() + { return "Författare"; } + QString trReturns() + { return "Returnerar"; } + QString trSeeAlso() + { return "Se även"; } + QString trParameters() + { return "Parametrar"; } + QString trExceptions() + { return "Undantag"; } + QString trGeneratedBy() + { return "Skapad av"; } +}; + +#endif diff --git a/src/unistd.h b/src/unistd.h new file mode 100644 index 0000000..46a5fbc --- /dev/null +++ b/src/unistd.h @@ -0,0 +1,7 @@ +/* this is a dummy file, that is needed for compiling files that are + * generated with flex under Windows 95/NT. + */ +#if defined(_MSC_VER) +#include <io.h> +#endif + diff --git a/src/util.cpp b/src/util.cpp new file mode 100644 index 0000000..6b4578d --- /dev/null +++ b/src/util.cpp @@ -0,0 +1,2174 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#include <stdlib.h> +#include <qregexp.h> +#include <qstring.h> +#include <ctype.h> +#include "util.h" +#include "message.h" +#include "classdef.h" +#include "filedef.h" +#include "doxygen.h" +#include "scanner.h" +#include "outputlist.h" +#include "defargs.h" +#include "language.h" +#include "config.h" + +// an inheritance tree of depth of 100000 should be enough for everyone :-) +const int maxInheritanceDepth = 100000; + +bool isId(char c) +{ + return c=='_' || isalnum(c); +} + + +// try to determine if this files is a source or a header file by looking +// at the extension (5 variations are allowed in both upper and lower case) +// If anyone knows or uses another extension please let me know :-) +int guessSection(const char *name) +{ + QString n=((QString)name).lower(); + if (n.right(2)==".c" || + n.right(3)==".cc" || + n.right(4)==".cxx" || + n.right(4)==".cpp" || + n.right(4)==".c++" + ) return Entry::SOURCE_SEC; + if (n.right(2)==".h" || + n.right(3)==".hh" || + n.right(4)==".hxx" || + n.right(4)==".hpp" || + n.right(4)==".h++" + ) return Entry::HEADER_SEC; + return 0; +} + + +//QString resolveDefines(const char *n) +//{ +// return n; +// if (n) +// { +// Define *def=defineDict[n]; +// if (def && def->nargs==0 && !def->definition.isNull()) +// { +// return def->definition; +// } +// return n; +// } +// return 0; +//} + +QString resolveTypedefs(const QString &n) +{ + QString *subst=typedefDict[n]; + if (subst && !subst->isNull()) + { + return *subst; + } + else + { + return n; + } +} + +ClassDef *getClass(const char *name) +{ + if (!name) return 0; + //QString key=resolveTypedefs(resolveDefines(name)); + //Define *def=defineDict[key]; + //if (def && def->nargs==0 && def->definition.length()>0) // normal define + // key=def->definition; // use substitution + + return classDict[resolveTypedefs(name)]; +} + +QString removeRedundantWhiteSpace(const QString &s) +{ + if (s.length()==0) return s; + QString result; + uint i; + for (i=0;i<s.length();i++) + { + char c=s.at(i); + if (c!=' ' || + (i!=0 && i!=s.length()-1 && isId(s.at(i-1)) && isId(s.at(i+1))) + ) + { + if ((c=='*' || c=='&') && + result.length()>0 && isId(result.at(result.length()-1)) + ) result+=' '; + result+=c; + } + } + return result; +} + +void writeTemplatePrefix(OutputList &ol,ArgumentList *al) +{ + ol.docify("template<"); + Argument *a=al->first(); + while (a) + { + ol.docify(a->type); + ol.docify(a->name); + if (a->defval.length()!=0) + { + ol.docify(" = "); + ol.docify(a->defval); + } + a=al->next(); + if (a) ol.docify(", "); + } + ol.docify("> "); + bool latexEnabled = ol.isEnabled(OutputGenerator::Latex); + bool manEnabled = ol.isEnabled(OutputGenerator::Man); + if (latexEnabled) ol.disable(OutputGenerator::Latex); + if (manEnabled) ol.disable(OutputGenerator::Man); + ol.lineBreak(); + if (latexEnabled) ol.enable(OutputGenerator::Latex); + if (manEnabled) ol.enable(OutputGenerator::Man); +} + +QString addTemplateNames(const QString &s,const QString &n,const QString &t) +{ + //printf("addTemplateNames(%s)\n",s.data()); + QString result; + QString clRealName=n; + int p=0,i; + if ((i=clRealName.find('<'))!=-1) + { + clRealName=clRealName.left(i); // strip template specialization + } + 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("result=%s\n",result.data()); + return result; +} + +static void linkifyText(OutputList &ol,const char *clName,const char *name,const char *text) +{ + //printf("class %s name %s Text: %s\n",clName,name,text); + QRegExp regExp("[a-z_A-Z0-9:<>]+"); + QString txtStr=text; + OutputList result(&ol); + int matchLen; + int index=0; + int newIndex; + int skipIndex=0; + // read a word from the text string + while ((newIndex=regExp.match(txtStr,index,&matchLen))!=-1) + { + // add non-word part to the result + result.docify(txtStr.mid(skipIndex,newIndex-skipIndex)); + // get word from string + QString word=txtStr.mid(newIndex,matchLen); + ClassDef *cd=0; + FileDef *fd=0; + MemberDef *md=0; + + // check if `word' is a documented class name + if (word.length()>0 && word!=name && word!=clName) + { + if ((cd=getClass(word))) + { + // add link to the result + if (cd->isVisible()) + { + result.writeObjectLink(cd->getReference(),cd->classFile(),0,word); + } + else + { + result.docify(word); + } + } + else if (getDefs(word,clName,0,md,cd,fd) && md->hasDocumentation()) + { + if (cd && cd->isVisible() && !md->isFunction()) // word is a member of cd + { + result.writeObjectLink(cd->getReference(), + cd->classFile(),md->anchor(),word); + } + else if (fd && fd->hasDocumentation()) // word is a global in file fd + { + result.writeObjectLink(fd->getReference(), + fd->diskName(),md->anchor(),word); + } + else // add word to the result + { + result.docify(word); + } + } + else // add word to the result + { + result.docify(word); + } + } + else // add word to the result + { + result.docify(word); + } + // set next start point in the string + skipIndex=index=newIndex+matchLen; + } + // add last part of the string to the result. + result.docify(txtStr.right(txtStr.length()-skipIndex)); + //printf("linkify: %s\n",result.data()); + ol+=result; +} + +static void writeDefArgumentList(OutputList &ol,ClassDef *cd, + const QString &scopeName,MemberDef *md) +{ + ArgumentList *argList=md->argumentList(); + if (argList==0) return; // member has no function like argument list + ol.docify(" ("); // start argument list + Argument *a=argList->first(); + QString cName; + if (cd && cd->templateArguments()) + { + cName=cd->getTemplateNameString(); + } + while (a) + { + QRegExp re(")("); + int vp; + if ((vp=a->type.find(re))!=-1) // argument type is a function pointer + { + QString n=a->type.left(vp); + if (cName.length()>0) n=addTemplateNames(n,cd->name(),cName); + linkifyText(ol,scopeName,md->name(),n); + } + else // non-function pointer type + { + QString n=a->type; + if (cName.length()>0) n=addTemplateNames(n,cd->name(),cName); + linkifyText(ol,scopeName,md->name(),n); + } + if (a->name.length()>0) // argument has a name + { + ol.docify(" "); + ol.disable(OutputGenerator::Man); + ol.startEmphasis(); + ol.enable(OutputGenerator::Man); + ol.docify(a->name); + ol.disable(OutputGenerator::Man); + ol.endEmphasis(); + ol.enable(OutputGenerator::Man); + } + if (vp!=-1) // write the part of the argument type + // that comes after the name + { + linkifyText(ol,scopeName,md->name(),a->type.right(a->type.length()-vp)); + } + if (a->defval.length()>0) // write the default value + { + QString n=a->defval; + if (cName.length()>0) n=addTemplateNames(n,cd->name(),cName); + ol.docify(" = "); + linkifyText(ol,scopeName,md->name(),n); + } + a=argList->next(); + if (a) ol.docify(", "); // there are more arguments + } + ol.docify(")"); // end argument list + if (argList->constSpecifier) + { + ol.docify(" const"); + } + if (argList->volatileSpecifier) + { + ol.docify(" volatile"); + } +} + +QString argListToString(ArgumentList *al) +{ + QString result; + if (al==0) return result; + Argument *a=al->first(); + result+="("; + while (a) + { + result+= a->type+" "+a->name; + a = al->next(); + if (a) result+=","; + } + result+=")"; + if (al->constSpecifier) result+=" const"; + if (al->volatileSpecifier) result+=" volatile"; + return result; +} + +static void writeLink(OutputList &ol,ClassDef *cd,NamespaceDef *nd, + FileDef *fd,MemberDef *md,const char *name) +{ + if (nd) + ol.writeObjectLink(0 /*TODO: references */,nd->namespaceFile(),md->anchor(),name); + else if (fd) + ol.writeObjectLink(fd->getReference(),fd->diskName(),md->anchor(),name); + else + ol.writeObjectLink(cd->getReference(),cd->classFile(),md->anchor(),name); +} + +static void warnForUndocumentedMember(MemberDef *md) +{ + ClassDef *cd=md->memberClass(); + FileDef *fd=md->getFileDef(); + if (cd) + { + if (!md->hasDocumentation() && md->name() && md->name()[0]!='@') + warn("Warning: Member %s of class %s is not documented\n", + md->name().data(),cd->name().data()); + } + else if (fd) + { + if (!md->hasDocumentation() && md->name() && md->name()[0]!='@') + warn("Warning: Member %s of file %s is not documented\n", + md->name().data(),fd->name().data()); + } +} + +static bool manIsEnabled; + +void startTitle(OutputList &ol) +{ + ol.startTitleHead(); + manIsEnabled=ol.isEnabled(OutputGenerator::Man); + if (manIsEnabled) ol.disable(OutputGenerator::Man); +} + +void endTitle(OutputList &ol,const char *name) +{ + if (manIsEnabled) ol.enable(OutputGenerator::Man); + ol.endTitleHead(name); +} + +void writeQuickLinks(OutputList &ol,bool compact,bool ext) +{ + bool manEnabled = ol.isEnabled(OutputGenerator::Man); + bool texEnabled = ol.isEnabled(OutputGenerator::Latex); + QString extLink,absPath; + if (ext) { extLink="_doc:"; absPath="/"; } + if (manEnabled) ol.disable(OutputGenerator::Man); + if (texEnabled) ol.disable(OutputGenerator::Latex); + if (compact) ol.startCenter(); else ol.startItemList(); + if (documentedGroups>0) + { + if (!compact) ol.writeListItem(); + ol.startQuickIndexItem(extLink,absPath+"modules.html"); + parseDoc(ol,0,0,theTranslator->trModules()); + ol.endQuickIndexItem(); + } + if (documentedNamespaces>0) + { + if (!compact) ol.writeListItem(); + ol.startQuickIndexItem(extLink,absPath+"namespaces.html"); + parseDoc(ol,0,0,theTranslator->trNamespaces()); + ol.endQuickIndexItem(); + } + if (hierarchyClasses>0) + { + if (!compact) ol.writeListItem(); + ol.startQuickIndexItem(extLink,absPath+"hierarchy.html"); + parseDoc(ol,0,0,theTranslator->trClassHierarchy()); + ol.endQuickIndexItem(); + } + if (annotatedClasses>0) + { + if (!compact) ol.writeListItem(); + ol.startQuickIndexItem(extLink,absPath+"annotated.html"); + parseDoc(ol,0,0,theTranslator->trCompoundList()); + ol.endQuickIndexItem(); + } + if (documentedFiles>0) + { + if (!compact) ol.writeListItem(); + ol.startQuickIndexItem(extLink,absPath+"files.html"); + parseDoc(ol,0,0,theTranslator->trFileList()); + ol.endQuickIndexItem(); + } + if (includeFiles.count()>0 && verbatimHeaderFlag) + { + if (!compact) ol.writeListItem(); + ol.startQuickIndexItem(extLink,absPath+"headers.html"); + parseDoc(ol,0,0,theTranslator->trHeaderFiles()); + ol.endQuickIndexItem(); + } + if (documentedMembers>0) + { + if (!compact) ol.writeListItem(); + ol.startQuickIndexItem(extLink,absPath+"functions.html"); + parseDoc(ol,0,0,theTranslator->trCompoundMembers()); + ol.endQuickIndexItem(); + } + if (documentedFunctions>0) + { + if (!compact) ol.writeListItem(); + ol.startQuickIndexItem(extLink,absPath+"globals.html"); + parseDoc(ol,0,0,theTranslator->trFileMembers()); + ol.endQuickIndexItem(); + } + if (pageList.count()>0) + { + if (!compact) ol.writeListItem(); + ol.startQuickIndexItem(extLink,absPath+"pages.html"); + parseDoc(ol,0,0,theTranslator->trRelatedPages()); + ol.endQuickIndexItem(); + } + if (exampleList.count()>0) + { + if (!compact) ol.writeListItem(); + ol.startQuickIndexItem(extLink,absPath+"examples.html"); + parseDoc(ol,0,0,theTranslator->trExamples()); + ol.endQuickIndexItem(); + } + if (searchEngineFlag) + { + if (!compact) ol.writeListItem(); + ol.startQuickIndexItem("_cgi:",""); + parseDoc(ol,0,0,theTranslator->trSearch()); + ol.endQuickIndexItem(); + } + if (compact) + { + ol.endCenter(); + ol.writeRuler(); + } + else + { + ol.endItemList(); + } + if (manEnabled) ol.enable(OutputGenerator::Man); + if (texEnabled) ol.enable(OutputGenerator::Latex); +} + +void startFile(OutputList &ol,const char *name,const char *title,bool external) +{ + ol.startFile(name,title,external); + if (!noIndexFlag) writeQuickLinks(ol,TRUE,external); +} + +void endFile(OutputList &ol,bool external) +{ + bool latexEnabled = ol.isEnabled(OutputGenerator::Latex); + bool manEnabled = ol.isEnabled(OutputGenerator::Man); + if (latexEnabled) ol.disable(OutputGenerator::Latex); + if (manEnabled) ol.disable(OutputGenerator::Man); + ol.writeFooter(0,external); // write the footer + if (footerFile.length()==0) + { + parseDoc(ol,0,0,theTranslator->trGeneratedAt( + dateToString(TRUE), + projectName + )); + } + ol.writeFooter(1,external); // write the link to the picture + if (footerFile.length()==0) + { + parseDoc(ol,0,0,theTranslator->trWrittenBy()); + } + ol.writeFooter(2,external); // end the footer + if (latexEnabled) ol.enable(OutputGenerator::Latex); + if (manEnabled) ol.enable(OutputGenerator::Man); + ol.endFile(); +} + + +static void writeMemberDef(OutputList &ol, ClassDef *cd, NamespaceDef *nd, + FileDef *fd, MemberDef *md) +{ + int i,l; + bool hasDocs=md->hasDocumentation(); + if ((!hasDocs && hideMemberFlag) || + (hideMemberFlag && + md->documentation().isEmpty() && + !briefMemDescFlag && + !repeatBriefFlag + ) + ) return; + QString type=md->typeString(); + QRegExp r("@[0-9]+"); + if ((i=r.match(type,0,&l))==-1 || !md->enumUsed()) + { + // strip `static' keyword from type + if (type.left(7)=="static ") type=type.right(type.length()-7); + // strip `friend' keyword from type + if (type.left(7)=="friend ") type=type.right(type.length()-7); + + if (genTagFile.length()>0) + { + tagFile << md->name() << " " << md->anchor() << " \"" + << md->argsString() << "\"\n"; + } + + QString cname; + if (cd) cname=cd->name(); + else if (nd) cname=nd->name(); + else if (fd) cname=fd->name(); + + // If there is no detailed description we need to write the anchor here. + if (!md->detailsAreVisible() && !extractAllFlag) + { + ol.writeDoxyAnchor(cname,md->anchor(),md->name()); + ol.addToIndex(md->name(),cname); + ol.addToIndex(cname,md->name()); + ol.docify("\n"); + } + + ol.startMemberItem(); + + // write type + if (i!=-1) + { + QString newType = type.left(i) + " { ... } " + + type.right(type.length()-i-l); + type = newType; + ol.docify(type); + } + else + { + ol.docify(type); + } + QString name=md->name().copy(); + if (type.length()>0) ol.writeString(" "); + + // write name + if ( extractAllFlag || + (md->briefDescription().isEmpty() || !briefMemDescFlag) && + (!md->documentation().isEmpty() || + (!md->briefDescription().isEmpty() && + !briefMemDescFlag && + repeatBriefFlag + ) + ) + ) + { + //printf("writeLink %s->%d\n",name.data(),md->hasDocumentation()); + writeLink(ol,cd,nd,fd,md,name); + } + else // there is a brief member description and brief member + // descriptions are enabled or there is no detailed description. + { + ol.writeBoldString(name); + } + + if (md->argsString()) + { + ol.writeString(" "); + ol.docify(md->argsString()); + } + + if (md->excpString()) + { + ol.writeString(" "); + ol.docify(md->excpString()); + } + + ol.endMemberItem(); + + // write brief description + if (!md->briefDescription().isEmpty() && briefMemDescFlag) + { + ol.startMemberDescription(); + parseDoc(ol,cname,md->name(),md->briefDescription()); + if (!md->documentation().isEmpty()) + { + ol.disableAllBut(OutputGenerator::Html); + ol.endEmphasis(); + ol.docify(" "); + ol.startTextLink(0,md->anchor()); + //ol.writeObjectLink(0,0,md->anchor()," More..."); + parseDoc(ol,0,0,theTranslator->trMore()); + ol.endTextLink(); + ol.startEmphasis(); + ol.enableAll(); + } + ol.endMemberDescription(); + ol.newParagraph(); + } + } + warnForUndocumentedMember(md); +} + + +// write a list in HTML of all members of a certain category +// cd!=0 => ml is a list of class members +// fd!=0 => ml is a list of file `members' +void writeMemberDecs(OutputList &ol,ClassDef *cd,NamespaceDef *nd, FileDef *fd, + const char *title, const char *subtitle,MemberList *ml) +{ + ml->countDecMembers(); + if (ml->totalCount()==0) return; + if (title) + { + ol.startMemberHeader(); + parseDoc(ol,0,0,title); + ol.endMemberHeader(); + } + if (subtitle) ol.writeString(subtitle); + + + if (!fd && !nd) ol.startMemberList(); + MemberDef *md; + + if (fd && ml->defineCount()>0) + { + ol.startMemberHeader(); + parseDoc(ol,0,0,theTranslator->trDefines()); + ol.endMemberHeader(); + ol.startMemberList(); + MemberListIterator mli(*ml); + for ( ; (md=mli.current()); ++mli ) + { + if (md->isDefine() && + (md->argsString() || md->hasDocumentation() || extractAllFlag) + ) + writeMemberDef(ol,cd,nd,fd,md); + } + ol.endMemberList(); + } + + if ((fd || nd) && ml->protoCount()>0) + { + ol.startMemberHeader(); + parseDoc(ol,0,0,theTranslator->trFuncProtos()); + ol.startMemberList(); + MemberListIterator mli(*ml); + for ( ; (md=mli.current()); ++mli ) + { + if (md->isPrototype()) writeMemberDef(ol,cd,nd,fd,md); + } + ol.endMemberList(); + } + + if (ml->typedefCount()>0) + { + if (fd || nd) + { + ol.startMemberHeader(); + parseDoc(ol,0,0,theTranslator->trTypedefs()); + ol.endMemberHeader(); + //ol.writeMemberHeader("Typedefs"); + ol.startMemberList(); + } + MemberListIterator mli(*ml); + for ( ; (md=mli.current()) ; ++mli ) + { + if (md->isTypedef()) writeMemberDef(ol,cd,nd,fd,md); + } + if (fd || nd) ol.endMemberList(); + } + + // write enums + if (ml->enumCount()>0) + { + if (fd || nd) + { + ol.startMemberHeader(); + parseDoc(ol,0,0,theTranslator->trEnumerations()); + ol.endMemberHeader(); + ol.startMemberList(); + } + MemberListIterator mli(*ml); + for ( ; (md=mli.current()) ; ++mli ) + { + bool hasDocs=md->hasDocumentation(); + QString type=md->typeString(); + type=type.stripWhiteSpace(); + if (md->isEnumerate() && (hasDocs || !hideMemberFlag)) + { + // see if there are any documented enum values + // we need this info to decide if we need to generate a link. + QList<MemberDef> *fmdl=md->enumFieldList(); + int documentedEnumValues=0; + if (fmdl) + { + MemberDef *fmd=fmdl->first(); + while (fmd) + { + if (fmd->hasDocumentation()) documentedEnumValues++; + fmd=fmdl->next(); + } + } + if (documentedEnumValues>0) md->setDocumentedEnumValues(TRUE); + + if (!hideMemberFlag || // do not hide undocumented members or + !md->documentation().isEmpty() || // member has detailed descr. or + documentedEnumValues>0 || // member has documented enum vales. + briefMemDescFlag || // brief descr. is shown or + repeatBriefFlag // brief descr. is repeated. + ) + { + OutputList typeDecl(&ol); + QString name=md->name().copy(); + int i=name.findRev("::"); + if (i!=-1) name=name.right(name.length()-i-2); // strip scope + if (name[0]!='@') // not an anonymous enum + { + if (extractAllFlag || + (md->briefDescription().isEmpty() || !briefMemDescFlag) && + (!md->documentation().isEmpty() || documentedEnumValues>0 || + (!md->briefDescription().isEmpty() && + !briefMemDescFlag && + repeatBriefFlag + ) + ) + ) + { + if (genTagFile.length()>0) + tagFile << md->name() << " " << md->anchor() + << " \"" << md->argsString() << "\""; + writeLink(typeDecl,cd,nd,fd,md,name); + } + else + { + typeDecl.writeBoldString(name); + } + typeDecl.writeChar(' '); + } + + typeDecl.docify("{ "); + if (fmdl) + { + MemberDef *fmd=fmdl->first(); + while (fmd) + { + if (fmd->hasDocumentation()) + { + if (genTagFile.length()>0) + tagFile << fmd->name() << " " << fmd->anchor() + << " \"" << fmd->argsString() << "\""; + writeLink(typeDecl,cd,nd,fd,fmd,fmd->name()); + } + else + typeDecl.writeBoldString(fmd->name()); + fmd=fmdl->next(); + if (fmd) typeDecl.writeString(", "); + typeDecl.disable(OutputGenerator::Man); + typeDecl.writeString("\n"); // to prevent too long lines in LaTeX + typeDecl.enable(OutputGenerator::Man); + } + } + typeDecl.docify(" }"); + md->setEnumDecl(typeDecl); + int enumVars=0; + MemberListIterator vmli(*ml); + MemberDef *vmd; + if (name[0]=='@') // anonymous enum => append variables + { + for ( ; (vmd=vmli.current()) ; ++vmli) + { + QString vtype=vmd->typeString(); + if ((vtype.find(name))!=-1) enumVars++; + } + } + if (enumVars==0) // no variable of this enum type + { + ol.startMemberItem(); + ol.writeString("enum "); + ol+=typeDecl; + ol.endMemberItem(); + //QString brief=md->briefDescription(); + //brief=brief.stripWhiteSpace(); + if (!md->briefDescription().isEmpty() && briefMemDescFlag) + { + ol.startMemberDescription(); + parseDoc(ol,cd?cd->name().data():0, + md->name().data(),md->briefDescription()); + if (!md->documentation().isEmpty() || documentedEnumValues>0) + { + ol.disableAllBut(OutputGenerator::Html); + ol.endEmphasis(); + ol.docify(" "); + ol.startTextLink(0,md->anchor()); + //ol.writeObjectLink(0,0,md->anchor()," More..."); + parseDoc(ol,0,0,theTranslator->trMore()); + ol.endTextLink(); + ol.startEmphasis(); + ol.enableAll(); + } + ol.endMemberDescription(); + ol.disable(OutputGenerator::Man); + ol.newParagraph(); + ol.enable(OutputGenerator::Man); + } + } + warnForUndocumentedMember(md); + } + } // md->isEnumerate() + } // enum loop + if (fd || nd) ol.endMemberList(); + } // write enums + + // write functions + if (ml->funcCount()>0) + { + if (fd || nd) + { + ol.startMemberHeader(); + parseDoc(ol,0,0,theTranslator->trFunctions()); + ol.endMemberHeader(); + ol.startMemberList(); + } + MemberListIterator mli(*ml); + for ( ; (md=mli.current()) ; ++mli ) + { + if ( md->isFunction() || md->isSignal() || + md->isSlot()) + writeMemberDef(ol,cd,nd,fd,md); + } + if (fd || nd) ol.endMemberList(); + } + + if (ml->friendCount()>0) + { + MemberListIterator mli(*ml); + for ( ; (md=mli.current()) ; ++mli ) + { + if ( md->isFriend()) + { + QString type=md->typeString(); + //printf("Friend: type=%s name=%s\n",type.data(),md->name().data()); + if (md->hasDocumentation() && type!="friend class") + { + writeMemberDef(ol,cd,nd,fd,md); + } + else // friend is undocumented as a member but it is a class, + // so generate a link to the class if that is documented. + { + ClassDef *cd=getClass(md->name()); + if (md->hasDocumentation()) // friend is documented + { + ol.startMemberItem(); + ol.docify("class "); + ol.writeObjectLink(0,0,md->anchor(),md->name()); + ol.endMemberItem(); + } + else if (cd && cd->isVisibleExt()) // class is documented + { + ol.startMemberItem(); + ol.docify("class "); + ol.writeObjectLink(cd->getReference(),cd->classFile(),0,cd->name()); + ol.endMemberItem(); + } + else if (!hideMemberFlag) // no documentation + { + ol.startMemberItem(); + ol.docify("class "); + ol.writeBoldString(md->name()); + ol.endMemberItem(); + } + } + } + } + } + + // write variables + if (ml->varCount()>0) + { + if (fd || nd) + { + ol.startMemberHeader(); + parseDoc(ol,0,0,theTranslator->trVariables()); + ol.endMemberHeader(); + ol.startMemberList(); + } + MemberListIterator mli(*ml); + for ( ; (md=mli.current()) ; ++mli ) + { + if (md->isVariable()) writeMemberDef(ol,cd,nd,fd,md); + } + if (fd || nd) ol.endMemberList(); + } + + if (!fd && !nd) { ol.endMemberList(); ol.writeChar('\n'); } +} + +// compute the HTML anchors for a list of members +void setAnchors(char id,MemberList *ml) +{ + int count=0; + MemberDef *md=ml->first(); + while (md) + { + QString anchor; + anchor.sprintf("%c%d",id,count++); + //printf("Member %s anchor %s\n",md->name(),anchor.data()); + md->setAnchor(anchor); + md=ml->next(); + } +} + +void writeMemberDocs(OutputList &ol,MemberList *ml,const char *scopeName, + MemberDef::MemberType m) +{ + MemberListIterator mli(*ml); + MemberDef *md; + for ( ; (md=mli.current()) ; ++mli) + { + bool hasDocs = md->detailsAreVisible(); + // !md->documentation().isEmpty() || // member has a detailed description + // (md->memberType()==MemberDef::Enumeration && // or member is an enum and + // md->hasDocumentedEnumValues() // one of its values is documented + // ) || // or + // (!md->briefDescription().isEmpty() && // member has brief description and + // !briefMemDescFlag && // brief description not shown earlier and + // repeatBriefFlag // brief description should be repeated. + // ); + if (md->memberType()==m && // filter member type + (extractAllFlag || hasDocs) + ) + { + if (extractAllFlag && !hasDocs) + { + ol.disable(OutputGenerator::Latex); // Latex cannot insert a pagebreak + // if there are a lot of empty sections, + // so we disable LaTeX for all empty + // sections even if extractAllFlag is enabled + } + QString cname; + NamespaceDef *nd=md->getNamespace(); + ClassDef *cd=md->memberClass(); + FileDef *fd=md->getFileDef(); + if (cd) cname=cd->name(); + else if (nd) cname=nd->name(); + else if (fd) cname=fd->name(); + // get member name + QString doxyName=md->name().copy(); + // prepend scope if there is any (TODO: prepend namespace scope as well) + if (scopeName) doxyName.prepend((QString)scopeName+"::"); + + QString def = md->definition(); + if (md->isEnumerate()) def.prepend("enum "); + MemberDef *smd; + if (md->isEnumValue() && def[0]=='@') def = def.right(def.length()-2); + int i=0,l,dummy; + QRegExp r("@[0-9]+"); + if (md->isEnumerate() && r.match(def,0,&l)!=-1) continue; + if (md->isEnumValue() && (smd = md->getEnumScope()) + && r.match(smd->name(),0,&dummy)==-1) continue; + if ((md->isVariable() || md->isTypedef()) && (i=r.match(def,0,&l))!=-1) + { + // find enum type an insert it in the definition + MemberListIterator vmli(*ml); + MemberDef *vmd; + bool found=FALSE; + for ( ; (vmd=vmli.current()) && !found ; ++vmli) + { + if (vmd->isEnumerate() && def.mid(i,l)==vmd->name()) + { + ol.startMemberDoc(cname,md->name(),md->anchor()); + ol.writeDoxyAnchor(cname,md->anchor(),doxyName); + linkifyText(ol,scopeName,md->name(),def.left(i)); + ol+=*vmd->enumDecl(); + linkifyText(ol,scopeName,md->name(),def.right(def.length()-i-l)); + found=TRUE; + } + } + if (!found) // anonymous compound + { + ol.startMemberDoc(cname,md->name(),md->anchor()); + ol.writeDoxyAnchor(cname,md->anchor(),doxyName); + linkifyText(ol,scopeName,md->name(),def.left(i)); + ol.docify(" { ... } "); + linkifyText(ol,scopeName,md->name(),def.right(def.length()-i-l)); + } + } + else + { + ol.startMemberDoc(cname,md->name(),md->anchor()); + ol.writeDoxyAnchor(cname,md->anchor(),doxyName); + ArgumentList *al=0; + if (cd && (!md->isRelated() || !md->templateArguments()) && + (al=cd->templateArguments())) // class template prefix + { + writeTemplatePrefix(ol,al); + } + if (al && md->templateArguments()) ol.docify(" "); + al=md->templateArguments(); + if (al) // function template prefix + { + writeTemplatePrefix(ol,al); + } + if (cd && cd->templateArguments()) + { + // add template name lists to all occurrences of the class name. + def=addTemplateNames(def,cd->name(),cd->getTemplateNameString()); + } + linkifyText(ol,scopeName,md->name(),def); + writeDefArgumentList(ol,cd,scopeName,md); + if (md->excpString()) + { + ol.docify(" "); + linkifyText(ol,scopeName,md->name(),md->excpString()); + } + } + + Specifier virt=md->virtualness(); + MemberDef *rmd=md->reimplements(); + while (rmd && virt==Normal) + { + virt = rmd->virtualness()==Normal ? Normal : Virtual; + rmd = rmd->reimplements(); + } + + if (md->isStatic() || md->protection()!=Public || + virt!=Normal || md->isSignal() || md->isFriend() || + md->isRelated() || md->isSlot() + ) + { + // write the member specifier list + ol.writeLatexSpacing(); + ol.startTypewriter(); + ol.docify(" ["); + QStrList sl; + if (md->isFriend()) sl.append("friend"); + else if (md->isRelated()) sl.append("related"); + else + { + if (md->isStatic()) sl.append("static"); + if (md->protection()==Protected) sl.append("protected"); + else if (md->protection()==Private) sl.append("private"); + if (virt==Virtual) sl.append("virtual"); + else if (virt==Pure) sl.append("pure virtual"); + if (md->isSignal()) sl.append("signal"); + if (md->isSlot()) sl.append("slot"); + } + const char *s=sl.first(); + while (s) + { + ol.docify(s); + s=sl.next(); + if (s) ol.docify(", "); + } + ol.docify("]"); + ol.endTypewriter(); + } + ol.endMemberDoc(); + ol.startIndent(); + ol.newParagraph(); + + if (!md->briefDescription().isEmpty() && + (repeatBriefFlag || + (!briefMemDescFlag && md->documentation().isEmpty()) + ) + ) + { + parseDoc(ol,scopeName,md->name(),md->briefDescription()); + ol.newParagraph(); + } + if (!md->documentation().isEmpty()) + { + parseDoc(ol,scopeName,md->name(),md->documentation()+"\n"); + } + + if (md->isEnumerate()) + { + bool first=TRUE; + MemberList *fmdl=md->enumFieldList(); + if (fmdl) + { + MemberDef *fmd=fmdl->first(); + while (fmd) + { + if (fmd->hasDocumentation()) + { + if (first) + { + ol.newParagraph(); + ol.startBold(); + parseDoc(ol,0,0,theTranslator->trEnumerationValues()); + //ol.writeBoldString("Enumeration values:"); + ol.docify(":"); + ol.endBold(); + ol.startMemberList(); + } + ol.writeDoxyAnchor(cname,fmd->anchor(),fmd->name()); + ol.addToIndex(fmd->name(),cname); + ol.addToIndex(cname,fmd->name()); + ol.writeListItem(); + first=FALSE; + ol.startBold(); + ol.docify(fmd->name()); + ol.endBold(); + ol.newParagraph(); + + if (!fmd->briefDescription().isEmpty()) + { + parseDoc(ol,scopeName,fmd->name(),fmd->briefDescription()); + ol.newParagraph(); + } + if (!fmd->documentation().isEmpty()) + { + parseDoc(ol,scopeName,fmd->name(),fmd->documentation()+"\n"); + } + ol.disable(OutputGenerator::Man); + ol.newParagraph(); + ol.enable(OutputGenerator::Man); + } + fmd=fmdl->next(); + } + } + if (!first) { ol.endMemberList(); ol.writeChar('\n'); } + } + + MemberDef *bmd=md->reimplements(); + if (bmd) + { + if (virt!=Normal) // search for virtual member of the deepest base class + { + MemberDef *lastBmd=bmd; + while (lastBmd) + { + if (lastBmd->virtualness()!=Normal) bmd=lastBmd; + lastBmd=lastBmd->reimplements(); + } + } + // write class that contains a member that is reimplemented by this one + ClassDef *bcd = bmd->memberClass(); + ol.newParagraph(); + parseDoc(ol,0,0,theTranslator->trReimplementedFrom()); + //ol.writeString("Reimplemented from "); + ol.docify(" "); + if (bmd->hasDocumentation()) + { + ol.writeObjectLink(bcd->getReference(),bcd->classFile(), + bmd->anchor(),bcd->name()); + if ( + !bcd->isReference() && + //(bcd->hasDocumentation() || !hideClassFlag) && + //(bcd->protection()!=Private || extractPrivateFlag) + bcd->isVisible() + /*&& bmd->detailsAreVisible()*/ + ) ol.writePageRef(bcd->name(),bmd->anchor()); + } + else + { + ol.writeObjectLink(bcd->getReference(),bcd->classFile(), + 0,bcd->name()); + if ( + !bcd->isReference() && + //(bcd->hasDocumentation() || !hideClassFlag) && + //(bcd->protection()!=Private || extractPrivateFlag) + bcd->isVisible() + ) ol.writePageRef(bcd->name(),0); + } + ol.writeString("."); + } + MemberList *bml=md->reimplementedBy(); + int count; + if (bml && (count=bml->count())>0) + { + // write the list of classes that overwrite this member + ol.newParagraph(); + parseDoc(ol,0,0,theTranslator->trReimplementedIn()); + //ol.writeString("Reimplemented in "); + ol.docify(" "); + bmd=bml->first(); + while (bmd) + { + ClassDef *bcd = bmd->memberClass(); + if (bmd->hasDocumentation()) + { + ol.writeObjectLink(bcd->getReference(),bcd->classFile(), + bmd->anchor(),bcd->name()); + if ( + !bcd->isReference() && + //(bcd->hasDocumentation() || !hideClassFlag) && + //(bcd->protection()!=Private || extractPrivateFlag) + bcd->isVisible() + /*&& bmd->detailsAreVisible()*/ + ) ol.writePageRef(bcd->name(),bmd->anchor()); + } + else + { + ol.writeObjectLink(bcd->getReference(),bcd->classFile(), + 0,bcd->name()); + if ( + !bcd->isReference() && + //(bcd->hasDocumentation() || !hideClassFlag) && + //(bcd->protection()!=Private || extractPrivateFlag) + bcd->isVisible() + ) ol.writePageRef(bcd->name(),0); + } + bmd=bml->next(); + if (bmd) + { + if (bml->at()==count-1) + //ol.writeString(" and "); + parseDoc(ol,0,0," "+theTranslator->trAnd()+" "); + else + ol.writeString(", "); + } + } + ol.writeString("."); + } + // write the list of examples that use this member + if (md->hasExamples()) + { + ol.startDescList(); + ol.startBold(); + parseDoc(ol,0,0,theTranslator->trExamples()+": "); + //ol.writeBoldString("Examples: "); + ol.endBold(); + ol.endDescTitle(); + ol.writeDescItem(); + md->writeExample(ol); + //ol.endDescItem(); + ol.endDescList(); + } + ol.endIndent(); + // enable LaTeX again + if (extractAllFlag && !hasDocs) ol.enable(OutputGenerator::Latex); + + } + } +} + +//---------------------------------------------------------------------------- +// read a file with `name' to a string. + +QString fileToString(const char *name) +{ + if (name==0 || name[0]==0) return 0; + QFileInfo fi(name); + if (!fi.exists() || !fi.isFile()) + { + err("Error: file `%s' not found\n",name); + exit(1); + } + QFile f(name); + if (!f.open(IO_ReadOnly)) + { + err("Error: cannot open file `%s'\n",name); + exit(1); + } + int fsize=fi.size(); + QString contents(fsize+1); + f.readBlock(contents.data(),fsize); + contents[fsize]='\0'; + f.close(); + return contents; +} + +QString dateToString(bool includeTime) +{ + if (includeTime) + { + return QDateTime::currentDateTime().toString(); + } + else + { + const QDate &d=QDate::currentDate(); + QString result; + result.sprintf("%d %s %d", + d.day(), + d.monthName(d.month()), + d.year()); + return result; + } + //QDate date=dt.date(); + //QTime time=dt.time(); + //QString dtString; + //dtString.sprintf("%02d:%02d, %04d/%02d/%02d", + // time.hour(),time.minute(),date.year(),date.month(),date.day()); + //return dtString; +} + + +//---------------------------------------------------------------------- +// recursive function that returns the number of branches in the +// inheritance tree that the base class `bcd' is below the class `cd' + +static int minClassDistance(ClassDef *cd,ClassDef *bcd,int level=0) +{ + if (cd==bcd) return level; + BaseClassListIterator bcli(*cd->baseClasses()); + int m=maxInheritanceDepth; + for ( ; bcli.current() ; ++bcli) + { + m=QMIN(minClassDistance(bcli.current()->classDef,bcd,level+1),m); + } + return m; +} + +//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.length()>0?a->name.data():"",a->defval.length()>0?a->defval.data():""); +// } +// printf(")"); +//} + +// strip any template specifiers that follow className in string s +static QString trimTemplateSpecifiers(const QString &className,const QString &s) +{ + // first we resolve any defines + //int i=0,p,l; + //QString result; + //QRegExp r("[A-Z_a-z][A-Z_a-z0-9]*"); + //while ((p=r.match(s,i,&l))!=-1) + //{ + // if (p>i) result+=s.mid(i,p-i); + // result+=resolveDefines(s.mid(p,l)); + // i=p+l; + //} + //if (i<(int)s.length()) result+=s.mid(i,s.length()-i); + + // We strip the template arguments following className (if any) + QString result=s.copy(); + int l=className.length(); + if (l>0) // there is a class name + { + int i,p=0; + while ((i=result.find(className,p))!=-1) // class name is in the argument type + { + uint s=i+l; + if (s<result.length() && result.at(s)=='<') // class has template args + { + int b=1; + uint e=s+1; + while (b>0 && e<result.length()) // find matching > + { + if (result.at(e)=='<') b++; + else if (result.at(e)=='>') b--; + e++; + } + // remove template argument + result=result.left(s)+result.right(result.length()-e); + if (result.length()>s && (result.at(s)=='*' || result.at(s)=='&')) + { + // insert a space to keep the argument in the canonical form + result=result.left(s)+" "+result.right(result.length()-s); + } + } + p=i+l; + } + } + return result; +} + +// removes the (one and only) occurrence of name:: from s. +static QString trimScope(const QString &name,const QString &s) +{ + int spos; + spos=s.find(name+"::"); + if (spos!=-1) + { + return s.left(spos)+s.right(s.length()-spos-name.length()-2); + } + return s; +} + +static QString trimBaseClassScope(BaseClassList *bcl,const QString &s) +{ + BaseClassListIterator bcli(*bcl); + BaseClassDef *bcd; + for (;(bcd=bcli.current());++bcli) + { + ClassDef *cd=bcd->classDef; + int spos=s.find(cd->name()); + if (spos!=-1) + { + return s.left(spos)+s.right( + s.length()-spos-cd->name().length()-2 + ); + } + if (cd->baseClasses()->count()>0) + trimBaseClassScope(cd->baseClasses(),s); + } + return s; +} + +//---------------------------------------------------------------------- +// 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) +{ + QString className=cl; + QString namespaceName=ns; + //printf("matchArguments(%s,%s) className=%s namespaceName=%s\n", + // srcAl ? argListToString(srcAl).data() : "", + // dstAl ? argListToString(dstAl).data() : "", + // cl,ns); + if (srcAl==0 || dstAl==0) + { + return srcAl==dstAl; // at least one of the members is not a function + } + 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); + } + 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); + return TRUE; + } + if (srcAl->count() != dstAl->count()) + { + return FALSE; // different number of arguments -> no match + } + if (srcAl->constSpecifier != dstAl->constSpecifier) + { + return FALSE; // one member is const, the other not -> no match + } + if (srcAl->volatileSpecifier != dstAl->volatileSpecifier) + { + 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) + { + QString srcAType=trimTemplateSpecifiers(className,srcA->type); + QString dstAType=trimTemplateSpecifiers(className,dstA->type); + + if (srcAType!=dstAType) // check if the argument only differs on name + { + //printf("`%s' <=> `%s'\n",srcAType.data(),dstAType.data()); + + QString srcScope; + QString dstScope; + + // strip redundant scope specifiers + if (!className.isEmpty()) + { + srcAType=trimScope(className,srcAType); + dstAType=trimScope(className,dstAType); + ClassDef *cd=getClass(className); + if (cd->baseClasses()->count()>0) + { + srcAType=trimBaseClassScope(cd->baseClasses(),srcAType); + dstAType=trimBaseClassScope(cd->baseClasses(),dstAType); + } + } + if (!namespaceName.isEmpty()) + { + srcAType=trimScope(namespaceName,srcAType); + dstAType=trimScope(namespaceName,dstAType); + } + + //printf("`%s' <=> `%s'\n",srcAType.data(),dstAType.data()); + 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++; + } + if (srcPos<srcAType.length() && dstPos<dstAType.length()) + { + // 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 || isalnum(srcAType.at(srcPos-1)) || + // dstPos==0 || isalnum(dstAType.at(dstPos-1))) { printf("No match1\n"); return FALSE; } + int srcStart=srcPos; + int dstStart=dstPos; + if (srcPos==0 || dstPos==0) return FALSE; + if (isId(srcAType.at(srcPos)) && isId(dstAType.at(dstPos))) + { + // check if a name if already found -> if no then there is no match + if (srcA->name.length()>0 || dstA->name.length()>0) return FALSE; + while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++; + while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++; + if (srcPos<srcAType.length() || dstPos<dstAType.length()) return FALSE; + // find the start of the name + while (srcStart>=0 && isId(srcAType.at(srcStart))) srcStart--; + while (dstStart>=0 && isId(dstAType.at(dstStart))) dstStart--; + if (srcStart>0) // move the name from the type to the name field + { + srcA->name=srcAType.right(srcAType.length()-srcStart-1); + srcA->type=srcAType.left(srcStart+1).stripWhiteSpace(); + } + if (dstStart>0) // move the name from the type to the name field + { + dstA->name=dstAType.right(dstAType.length()-dstStart-1); + dstA->type=dstAType.left(dstStart+1).stripWhiteSpace(); + } + } + else + { + // otherwise we assume that a name starts at the current position. + while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++; + while (dstPos<dstAType.length() && 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!=srcAType.length() || dstPos!=dstAType.length()) { return FALSE; } + dstA->name=dstAType.right(dstAType.length()-dstStart); + dstA->type=dstAType.left(dstStart).stripWhiteSpace(); + srcA->name=srcAType.right(dstAType.length()-srcStart); + srcA->type=srcAType.left(srcStart).stripWhiteSpace(); + } + } + else if (dstPos<dstAType.length()) + { + if (!isspace(dstAType.at(dstPos))) // maybe the names differ + { + int startPos=dstPos; + while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++; + if (dstPos!=dstAType.length()) return FALSE; // more than a difference in name -> no match + while (startPos>=0 && isId(dstAType.at(startPos))) startPos--; + if (startPos>0) + { + dstA->name=dstAType.right(dstAType.length()-startPos-1); + dstA->type=dstAType.left(startPos+1).stripWhiteSpace(); + } + } + else // maybe dst has a name while src has not + { + dstPos++; + int startPos=dstPos; + while (dstPos<dstAType.length() && isId(dstAType.at(dstPos))) dstPos++; + if (dstPos!=dstAType.length()) return FALSE; // nope not a name -> no match + else // its a name (most probably) so move it + { + dstA->name=dstAType.right(dstAType.length()-startPos); + dstA->type=dstAType.left(startPos).stripWhiteSpace(); + } + } + } + else if (srcPos<srcAType.length()) + { + if (!isspace(srcAType.at(srcPos))) // maybe the names differ + { + int startPos=srcPos; + while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++; + if (srcPos!=srcAType.length()) return FALSE; // more than a difference in name -> no match + while (startPos>=0 && isId(srcAType.at(startPos))) startPos--; + if (startPos>0) + { + srcA->name=srcAType.right(srcAType.length()-startPos-1); + srcA->type=srcAType.left(startPos+1).stripWhiteSpace(); + } + } + else // maybe src has a name while dst has not + { + srcPos++; + int startPos=srcPos; + while (srcPos<srcAType.length() && isId(srcAType.at(srcPos))) srcPos++; + if (srcPos!=srcAType.length()) return FALSE; // nope not a name -> no match + else // its a name (most probably) so move it + { + srcA->name=srcAType.right(srcAType.length()-startPos); + srcA->type=srcAType.left(startPos).stripWhiteSpace(); + } + } + } + else // without scopes the names match exactly + { + } + } + else if (srcA->name.length()==0 && dstA->name.length()==0) + // arguments match exactly but no name -> + // see if we can find the name + { + int i=srcAType.length()-1; + while (i>=0 && isId(srcAType.at(i))) i--; + if (i>0 && i<(int)srcAType.length()-1 && srcAType.at(i)!=':') + // there is (probably) a name + { + srcA->name=srcAType.right(srcAType.length()-i-1); + srcA->type=srcAType.left(i+1).stripWhiteSpace(); + dstA->name=dstAType.right(dstAType.length()-i-1); + dstA->type=dstAType.left(i+1).stripWhiteSpace(); + } + } + } + //printf("Match found!\n"); + 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) +{ + //printf("mergeArguments `%s', `%s'\n", + // argListToString(srcAl).data(),argListToString(dstAl).data()); + //printArgList(srcAl);printf(" <=> "); + //printArgList(dstAl);printf("\n"); + 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.length()==0 && dstA->defval.length()>0) + { + //printf("Defval changing `%s'->`%s'\n",srcA->defval.data(),dstA->defval.data()); + srcA->defval=dstA->defval.copy(); + } + else if (srcA->defval.length()>0 && dstA->defval.length()==0) + { + //printf("Defval changing `%s'->`%s'\n",dstA->defval.data(),srcA->defval.data()); + dstA->defval=srcA->defval.copy(); + } + 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(); + } + 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(); + } + } + //printf("result mergeArguments `%s', `%s'\n", + // argListToString(srcAl).data(),argListToString(dstAl).data()); +} + +//---------------------------------------------------------------------- +// searches for the class and member definitions corresponding with +// memberName and className. +// These classes are returned using `md' and `cd'. +// returns TRUE if the class and member both could be found + +bool getDefs(const QString &memberName,const QString &className, + const char *args,MemberDef *&md, ClassDef *&cd, FileDef *&fd) +{ + //printf("Search for %s::%s %s\n",className.data(),memberName.data(),args); + fd=0; md=0; cd=0; + if (memberName.length()==0) return FALSE; + MemberName *mn; + if ((mn=memberNameDict[memberName]) && className.length()>0) + { + //printf(" >member name found\n"); + ClassDef *fcd=0; + if ((fcd=getClass(className))) + { + //printf(" >member class found\n"); + MemberDef *mmd=mn->first(); + int mdist=maxInheritanceDepth; + while (mmd) + { + if ((mmd->protection()!=Private || extractPrivateFlag) && + mmd->hasDocumentation() + /*mmd->detailsAreVisible()*/ + /* && (args==0 || matchArgumentsOld(mmd->argsString(),args)) */ + ) + { + bool match=TRUE; + ArgumentList *argList=0; + if (args) + { + match=FALSE; + argList=new ArgumentList; + stringToArgumentList(args,argList); + match=matchArguments(mmd->argumentList(),argList); + } + if (match) + { + ClassDef *mcd=mmd->memberClass(); + int m=minClassDistance(fcd,mcd); + if (m<mdist && mcd->isVisible()) + { + mdist=m; + cd=mcd; + md=mmd; + fd=0; + } + } + if (argList) + { + delete argList; + } + } + mmd=mn->next(); + } + if (mdist==maxInheritanceDepth && !strcmp(args,"()")) + // no exact match found, but if args="()" an arbitrary member will do + { + //printf(" >Searching for arbitrary member\n"); + mmd=mn->first(); + while (mmd) + { + if ((mmd->protection()!=Private || extractPrivateFlag) && + ( + mmd->hasDocumentation() + /*mmd->detailsAreVisible()*/ + || mmd->isReference() + ) + ) + { + ClassDef *mcd=mmd->memberClass(); + //printf(" >Class %s found\n",mcd->name().data()); + int m=minClassDistance(fcd,mcd); + if (m<mdist && mcd->isVisible()) + { + //printf("Class distance %d\n",m); + mdist=m; + cd=mcd; + md=mmd; + fd=0; + } + } + mmd=mn->next(); + } + } + //printf(" >Succes=%d\n",mdist<maxInheritanceDepth); + return mdist<maxInheritanceDepth; + } + } + else // maybe an unrelated member ? + { + MemberName *mn; + if ((mn=functionNameDict[memberName])) + { + md=mn->first(); + while (md) + { + if (/*md->detailsAreVisible()*/ md->hasDocumentation()) + { + fd=md->getFileDef(); + if (fd && fd->hasDocumentation()) + { + cd=0; + return TRUE; + } + } + md=mn->next(); + } + } + } + return FALSE; +} + +//---------------------------------------------------------------------- +// Generate a hypertext link to the class with name `clName'. +// If linkTxt is not null this text is used as the link, otherwise +// the name of the class will be used. If the class could be found a +// hypertext link (in HTML) is written, otherwise the text of the link will +// be written. + +void generateClassRef(OutputList &ol,const char *clName,const char *linkTxt) +{ + QString className=clName; + QString linkText=linkTxt ? linkTxt : (const char *)className; + if (className.length()==0) + { + ol.docify(linkText); + return; + } + ClassDef *cd; + if ((cd=getClass(className)) && cd->isVisible()) + { + ol.writeObjectLink(cd->getReference(),cd->classFile(),0,linkText); + if (!cd->isReference()) ol.writePageRef(cd->name(),0); + } + else + ol.docify(linkText); +} + +//---------------------------------------------------------------------- +// generate a reference to a class or member. +// `clName' is the name of the class that contains the documentation +// string that is returned. +// `name' is the name of the member or class that we want to link to. +// `name' may have five formats: +// 1) "ClassName" +// 2) "memberName()" one of the (overloaded) function or define +// with name memberName. +// 3) "memberName(...)" a specific (overloaded) function or define +// with name memberName +// 4) "::memberName a non-function member or define +// 5) ("ClassName::")+"memberName()" +// 6) ("ClassName::")+"memberName(...)" +// 7) ("ClassName::")+"memberName" + +void generateRef(OutputList &ol,const char *clName, + const char *name,bool inSeeBlock,const char *rt) +{ + //printf("generateRef(clName=%s,name=%s,rt=%s)\n",clName,name,rt); + + // check if we have a plane name + QString tmpName = substitute(name,"#","::"); + QString linkText = rt; + int scopePos=tmpName.findRev("::"); + int bracePos=tmpName.find('('); + if (scopePos==-1 && bracePos==-1) + { + if (!inSeeBlock) /* check for class link */ + { + if (linkText.isNull()) linkText=tmpName; + // check if this is a class reference + if (clName!=tmpName) + generateClassRef(ol,name,linkText); + else + ol.docify(linkText); + return; + } + else /* check if it is a class, if not continue to search */ + { + if (clName!=tmpName && getClass(tmpName)!=0) + { + generateClassRef(ol,tmpName,linkText); + return; + } + } + } + + // extract scope + QString scopeStr; + if (scopePos>0) scopeStr=tmpName.left(scopePos); else scopeStr=clName; + + // extract name + int startNamePos=scopePos!=-1 ? scopePos+2 : 0; + int endNamePos=bracePos!=-1 ? bracePos : tmpName.length(); + QString nameStr=tmpName.mid(startNamePos,endNamePos-startNamePos); + + // extract arguments + QString argsStr; + if (bracePos!=-1) argsStr=tmpName.right(tmpName.length()-bracePos); + + bool explicitLink=TRUE; + // create a default link text if none was explicitly given + if (linkText.isNull()) + { + if (!scopeStr.isNull() && scopePos>0) linkText=scopeStr+"::"; + linkText+=nameStr; + explicitLink=FALSE; + } + + //printf("scope=`%s' name=`%s' arg=`%s' linkText=`%s'\n", + // scopeStr.data(),nameStr.data(),argsStr.data(),linkText.data()); + + //Define *d=0; + MemberDef *md; + ClassDef *cd; + FileDef *fd; + // check if nameStr is a member or global. + if (getDefs(nameStr,scopeStr,argsStr,md,cd,fd)) + { + QString anchor = md->hasDocumentation() ? md->anchor() : 0; + QString cName,aName; + if (cd) // nameStr is a member of cd + { + //printf("addObjectLink(%s,%s,%s,%s)\n",cd->getReference(), + // cd->classFile(),anchor.data(),resultName.stripWhiteSpace().data()); + ol.writeObjectLink(cd->getReference(), + cd->classFile(),anchor, + linkText.stripWhiteSpace()); + cName=cd->name(); + aName=md->anchor(); + } + else if (fd) // nameStr is a global in file fd + { + //printf("addFileLink(%s,%s,%s)\n",fd->diskName(),anchor.data(), + // resultName.stripWhiteSpace().data()); + ol.writeObjectLink(fd->getReference(),fd->diskName(), + anchor, linkText.stripWhiteSpace()); + cName=fd->name(); + aName=md->anchor(); + } + else // should not be reached + { + //printf("add no link fd=cd=0\n"); + ol.docify(linkText); + } + + // for functions we add the arguments if explicitly specified or else "()" + if (!rt && (md->isFunction() || md->isPrototype() || md->isSignal() || md->isSlot())) + { + if (argsStr.isNull()) + ol.writeString("()"); + else + ol.docify(argsStr); + } + + // generate the page reference (for LaTeX) + if (cName.length()>0 || aName.length()>0) + { + if (/*md->detailsAreVisible() &&*/ + ( + (cd && !cd->isReference() && + // (cd->hasDocumentation() || !hideClassFlag) && + // (cd->protection()!=Private || extractPrivateFlag) + cd->isVisible() + ) || + (fd && !fd->isReference()) + ) + ) ol.writePageRef(cName,aName); + } + } +// else if (!nameStr.isNull() && (d=defineDict[nameStr])) +// // check if nameStr is perhaps a define +// { +// if (d->hasDocumentation() && d->fileDef) +// { +// ol.writeObjectLink(0,d->fileDef->diskName(),d->anchor, +// linkText.stripWhiteSpace()); +// if (!explicitLink) ol.docify(argsStr); +// } +// } + else // nameStr is a false alarm or a typo. + { + if (rt) + ol.docify(rt); + else + { + ol.docify(linkText); + if (!argsStr.isNull()) ol.docify(argsStr); + } + } + return; +} + +//---------------------------------------------------------------------- +// 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. + +void generateLink(OutputList &ol,const char *clName, + const char *lr,bool inSeeBlock,const char *lt) +{ + QString linkRef=lr; + //PageInfo *pi=0; + //printf("generateLink(%s,%s)\n",lr,lt); + //FileInfo *fi=0; + FileDef *fd; + bool ambig; + if (linkRef.length()==0) // no reference name! + ol.docify(lt); + else if ((pageDict[linkRef])) // link to a page + ol.writeObjectLink(0,linkRef,0,lt); + else if ((exampleDict[linkRef])) // link to an example + ol.writeObjectLink(0,linkRef+"-example",0,lt); + else if ((fd=findFileDef(&inputNameDict,linkRef,ambig)) + && fd->hasDocumentation()) + // link to documented input file + ol.writeObjectLink(fd->getReference(),fd->diskName(),0,lt); + else // probably a class or member reference + generateRef(ol,clName,lr,inSeeBlock,lt); +} + +void generateFileRef(OutputList &ol,const char *name,const char *text) +{ + QString linkText = text ? text : name; + //FileInfo *fi; + FileDef *fd; + bool ambig; + if ((fd=findFileDef(&inputNameDict,name,ambig)) && + fd->hasDocumentation()) + // link to documented input file + ol.writeObjectLink(fd->getReference(),fd->diskName(),0,linkText); + else + ol.docify(linkText); +} + +//---------------------------------------------------------------------- + +QString substituteClassNames(const QString &s) +{ + int i=0,l,p; + QString result; + QRegExp r("[a-z_A-Z][a-z_A-Z0-9]*"); + while ((p=r.match(s,i,&l))!=-1) + { + QString *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; +} + +//---------------------------------------------------------------------- + +QString convertSlashes(const QString &s,bool dots) +{ + QString result; + int i,l=s.length(); + for (i=0;i<l;i++) + if (s.at(i)!='/' && (!dots || s.at(i)!='.')) + { + if (caseSensitiveNames) + { + result+=s[i]; + } + else + { + result+=tolower(s[i]); + } + } + else + result+="_"; + return result; +} + +//---------------------------------------------------------------------- +// substitute all occurences of `src' in `s' by `dst' + +QString substitute(const char *s,const char *src,const char *dst) +{ + QString input=s; + QString output; + int i=0,p; + while ((p=input.find(src,i))!=-1) + { + output+=input.mid(i,p-i); + output+=dst; + i=p+strlen(src); + } + output+=input.mid(i,input.length()-i); + return output; +} + +//---------------------------------------------------------------------- + +FileDef *findFileDef(const FileNameDict *fnDict,const char *n,bool &ambig) +{ + ambig=FALSE; + QString name=n; + QString path; + if (name.isNull()) return 0; + int slashPos=QMAX(name.findRev('/'),name.findRev('\\')); + if (slashPos!=-1) + { + path=name.left(slashPos+1); + name=name.right(name.length()-slashPos-1); + } + //printf("findFileDef path=`%s' name=`%s'\n",path.data(),name.data()); + if (name.isNull()) return 0; + FileName *fn; + if ((fn=(*fnDict)[name])) + { + if (fn->count()==1) + { + return fn->first(); + } + else // file name alone is ambigious + { + int count=0; + FileDef *fd=fn->first(); + FileDef *lastMatch=0; + while (fd) + { + if (path.isNull() || fd->getPath().right(path.length())==path) + { + count++; + lastMatch=fd; + } + fd=fn->next(); + } + ambig=(count>1); + return lastMatch; + } + } + return 0; +} + +//---------------------------------------------------------------------- + +void showFileDefMatches(const FileNameDict *fnDict,const char *n) +{ + QString name=n; + QString 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])) + { + FileDef *fd=fn->first(); + while (fd) + { + if (path.isNull() || fd->getPath().right(path.length())==path) + { + msg(" %s\n",fd->absFilePath().data()); + } + fd=fn->next(); + } + } +} + diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..9dfd097 --- /dev/null +++ b/src/util.h @@ -0,0 +1,82 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef UTIL_H +#define UTIL_H + +#include <qlist.h> +#include <qtstream.h> +#include <ctype.h> +//#include "filedef.h" +//#include "filename.h" +#include "memberdef.h" +//#include "outputlist.h" + + +class ClassDef; +class FileDef; +class MemberList; +class NamespaceDef; +class FileNameDict; +class ArgumentList; +class OutputList; + +extern void writeMemberDecs(OutputList &ol, ClassDef *cd, NamespaceDef *nd, + FileDef *fd, const char *title, const char *subtitle, + MemberList *ml); +extern void writeMemberDocs(OutputList &ol, + MemberList *ml,const char *scopeName,MemberDef::MemberType m); +extern void setAnchors(char id,MemberList *ml); +//extern int countMemberDocs(MemberList *ml,MemberDef::MemberType m); +extern QString fileToString(const char *name); +extern QString dateToString(bool); +//extern OutputList linkifyText(const char *clName,const char *name, +// const char *text); +extern bool getDefs(const QString &memberName,const QString &className, + const char *, MemberDef *&md, ClassDef *&cd,FileDef *&fd); +extern void generateRef(OutputList &ol,const char *, + const char *,bool inSeeBlock,const char * =0); +extern void generateLink(OutputList &ol,const char *, + const char *,bool inSeeBlock,const char *); +extern void generateClassRef(OutputList &ol,const char *clName, + const char *linkTxt=0); +extern void generateFileRef(OutputList &ol,const char *, + const char *linkTxt=0); +extern bool matchArguments(ArgumentList *,ArgumentList *, + const char *cl=0,const char *ns=0); +extern void mergeArguments(ArgumentList *,ArgumentList *); +extern QString substituteClassNames(const QString &s); +extern QString convertSlashes(const QString &s,bool dots=FALSE); +extern QString substitute(const char *s,const char *src,const char *dst); +extern QString resolveDefines(const char *n); +extern ClassDef *getClass(const char *key); +//extern int strcscmp(const char *s1,const char *s2); +extern FileDef *findFileDef(const FileNameDict *fnDict,const char *n, + bool &ambig); +extern void showFileDefMatches(const FileNameDict *fnDict,const char *n); +extern int guessSection(const char *name); +//extern QString nameToFile(const char *name); +extern bool isId(char c); +extern QString removeRedundantWhiteSpace(const QString &s); +extern void startTitle(OutputList &ol); +extern void endTitle(OutputList &ol,const char *name); +void startFile(OutputList &ol,const char *name, + const char *title,bool external=FALSE); +void endFile(OutputList &ol,bool external=FALSE); +void writeQuickLinks(OutputList &ol,bool compact,bool external=FALSE); +QString argListToString(ArgumentList *al); + +#endif diff --git a/src/version.h b/src/version.h new file mode 100644 index 0000000..c148ab7 --- /dev/null +++ b/src/version.h @@ -0,0 +1,22 @@ +/****************************************************************************** + * + * $Id$ + * + * 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. + * + * All output generated with Doxygen is not covered by this license. + * + */ + +#ifndef VERSION_H +#define VERSION_H + +extern char versionString[]; + +#endif diff --git a/tmake/CHANGES b/tmake/CHANGES new file mode 100644 index 0000000..000ac7d --- /dev/null +++ b/tmake/CHANGES @@ -0,0 +1,39 @@ + 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..2836b6a --- /dev/null +++ b/tmake/LICENSE @@ -0,0 +1,9 @@ + License Statement for tmake + +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 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..defb697 --- /dev/null +++ b/tmake/README @@ -0,0 +1,7 @@ + tmake version 1.2 + +tmake is an easy-to-use tool for creating and maintaining makefiles across +many platforms and compilers. The tmake manual (doc/tmake.html) explains +how to install and use tmake. + +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..8237fd5 --- /dev/null +++ b/tmake/bin/progen @@ -0,0 +1,249 @@ +#!/usr/bin/perl +############################################################################ +# $Id$ +# +# 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"; + +@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/; + } +} + +@hdr = sort grep(/\.(h|hh|hpp|hxx)$/i,@files); +@src = sort grep(/\.(c|cpp|cc|cxx)$/i && ! /moc_/i,@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)); +} +@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,@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/progen.bat b/tmake/bin/progen.bat new file mode 100644 index 0000000..54475ee --- /dev/null +++ b/tmake/bin/progen.bat @@ -0,0 +1,266 @@ +@rem = '--*-PERL-*--'; +@rem = ' +@echo off +rem setlocal +set ARGS= +:loop +if .%1==. goto endloop +set ARGS=%ARGS% %1 +shift +goto loop +:endloop +rem ***** This assumes PERL is in the PATH ***** +perl.exe -S progen.bat %ARGS% +goto endofperl +@rem '; +#!/usr/bin/perl +############################################################################ +# $Id$ +# +# 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"; + +@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/; + } +} + +@hdr = sort grep(/\.(h|hh|hpp|hxx)$/i,@files); +@src = sort grep(/\.(c|cpp|cc|cxx)$/i && ! /moc_/i,@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)); +} +@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,@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; +} +__END__ +:endofperl diff --git a/tmake/bin/tmake b/tmake/bin/tmake new file mode 100755 index 0000000..2d7e6a7 --- /dev/null +++ b/tmake/bin/tmake @@ -0,0 +1,1099 @@ +#!/usr/bin/perl +############################################################################ +# $Id$ +# +# 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. +# +############################################################################ + +if ($] < 5.0) { + &tmake_error("This program requires perl version 5 or newer"); +} + +$cpp_ext = "cpp"; +$obj_ext = "o"; +$moc_aware = 0; +$moc_pre = "moc_"; +$moc_ext = "moc"; +$moc_cmd = '$(MOC)'; +$linebreak = "\\"; +$dir_sep = "/"; +$is_unix = 1; +$really_unix = &check_unix(); +$guess_os = 1; +$depend_path = ""; +$nodepend = 0; +$output_count = 0; + +$template_name = ""; +$project_name = ""; +$outfile = ""; +@project_extra = (); +@project_files = (); +@eval_expr = (); +$eval_done = 0; + +while ( @ARGV ) { # parse command line args + $_ = shift @ARGV; + if ( s/^-// ) { + if ( /^e(.*)/ ) { + push( @eval_expr, ($1 eq "") ? shift @ARGV : $1); + } elsif ( /^t(.*)/ ) { + $template_name = ($1 eq "") ? shift @ARGV : $1; + } elsif ( /^o(.*)/ ) { + $outfile = ($1 eq "") ? shift @ARGV : $1; + ($outfile eq "-") && ($outfile = ""); + } elsif ( /^p(.*)/ ) { + push( @project_files, ($1 eq "") ? shift @ARGV : $1); + } elsif ( /^unix$/ ) { + $guess_os = 0; + $is_unix = 1; + } elsif ( /^win32$/ ) { + $guess_os = 0; + $is_unix = 0; + } elsif ( /^nodepend$/ ) { + $nodepend = 1; # don't generate dependencies + } elsif ( /^v$/ ) { + $verbose = 1; + } else { + &tmake_usage(); + } + } elsif ( /^\s*(?:[\w\-]+:)?\w+\s*[\+\-\*\/]?=/ ) { # project override + push( @project_extra, $_ ); + } else { + $project_name && + &tmake_error("You can only specify one project file"); + $project_name = $_; + } +} + +($project_name ne "") || &tmake_usage(); + +if ( $guess_os && ! check_unix() ) { # probably non-Unix, + $is_unix = 0; + &tmake_verb("Win32 detected"); +} +if ( ! $is_unix ) { + $obj_ext = "obj"; + $dir_sep = "\\"; +} +$outfile eq "" || open(STDOUT,">" . fix_path($outfile)) || + &tmake_error("Can't create \"$outfile\""); + +%project = (); +&ScanProject( &find_template("tmake.conf") ); +&tmake_verb("Reading the project file $project_name"); +if ( ! ($project_name =~ /\.pro$/i) && -f fix_path($project_name . ".pro") ) { + $project_name .= ".pro"; +} +$project{"PROJECT"} = $project_name; +$project{"PROJECT"} =~ s/\.pro$//i; +$project{"TARGET"} = $project{"PROJECT"}; + +unshift(@project_files,$project_name); +foreach ( @project_files ) { + if ( ! ($_ =~ /\.pro$/i) && -f fix_path($_ . ".pro") ) { + $_ .= ".pro"; + } + if ( !&ScanProject($_) ) { + &tmake_error("Can't open project file \"$_\""); + } +} +&Project( @project_extra ); + +if ( $template_name eq "" ) { + $template_name = $project{"TEMPLATE"} ? + $project{"TEMPLATE"} : "default.t"; +} + +foreach ( @eval_expr ) { + $text = ""; + eval( $_ ); + die $@ if $@; + print $text . "\n" if ($text ne ""); + $eval_done = 1; +} +if ( $eval_done ) { + &tmake_verb("Done!"); + exit 0; +} + +$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-file\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 " -p project Load additional project 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_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" || -f "/usr/bin/uname" ) { + $r = 1; + (-f "\\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,@dirs); + if ( !defined($template_base) || ($template_base eq "") ) { + $tb = ""; + } else { + $tb = $template_base . ";"; + } + $d = ";" . $tb . $ENV{"TMAKEPATH"} . ";" . $ENV{"HOME"} . "/.tmake/"; + @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"}); + } + if ( defined($project{"MOC_DIR"}) ) { + $project{"MOC_DIR"} = FixPath($project{"MOC_DIR"}); + } + $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_val(tag) +# +# Internal function for Project(). +# Expands a project value string. +# + +sub expand_project_val { + my($v) = @_; + my($c); + return "" if !defined($v); + $v =~ s/^\s+//; # trim white space + $v =~ s/\s+$//; + $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_tag,$t,$s,$v,$p,$c); + $r = ""; + foreach ( @settings ) { + $v = $_; + if ( $v =~ s/^\s*((?:[^:]*?:)?)(\w+)\s*(\+=|\*=|\-=|\/=|=)\s*// ) { + $if_tag = $1; + if ( $if_tag ne "" ) { + chop $if_tag; + if ( $if_tag eq "unix" ) { + return "" if !$is_unix; + } elsif ( $if_tag eq "win32" ) { + return "" if $is_unix; + } elsif ( ($if_tag ne $tmake_platform) && !Config($if_tag) ) { + return ""; + } + } + $t = $2; + $s = $3; + $v = expand_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} = expand_project_val($p); + } else { + $p = expand_project_val($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_val($subst); + return $text; +} + + +# +# ScanProject(file) +# +# Scans a project file. Inserts project variables into the global +# associative project array. +# + +sub ScanProject { + my($file) = @_; + my($tag,$var,@v,$more,$line); + + $tag = ""; + $line = 0; + open(TMP,fix_path($file)) || return 0; + + while ( <TMP> ) { + $line++; + s/\#.*//; # strip comment + s/^\s+//; # strip white space + s/\s+$//; + if ( /^\s*((?:(?:[^:]*?:)?)\w+\s*(\+|\-|\*|\/)?=)/ ) { + $tag = $1; # tag also contains the ".=" + s/^.*?=\s*//; + } + if ( $tag ne "" ) { + $more = ( $_ =~ s/\s*\\\s*$// ); # more if \ at end of line + push( @v, split( /\s+/, $_ ) ); + if ( ! $more ) { + $var = join(" ",@v); + Project( $tag . $var ); + $tag = ""; + @v = (); + } + } elsif ( $_ ne "" ) { + tmake_error("$file:$line: Syntax error"); + } + } + close(TMP); + 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(tag) - appends to $text +# +# Expands a list of $project{} variables with a space character between them. +# + +sub Expand { + my @tags = @_; + my($t); + $t = Project(@tags); + if ( $text eq "" ) { + $text = $t; + } elsif ( $t ne "" ) { + $text .= " " . $t; + } + return $text; +} + + +# +# ExpandGlue(tag,prepend,glue,append) - appends to $text +# +# Expands a $project{} tag, 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 +# tag 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($tag,$prepend,$glue,$append) = @_; + my($t,$v); + $v = Project($tag); + 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(tag) - sets $text. +# +# Suitable for expanding HEADERS = ... etc. in a Makefile +# + +sub ExpandList { + my($tag) = @_; + return ExpandGlue($tag,""," ${linebreak}\n\t\t",""); +} + + +# +# 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(" ",@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,@m,@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(" ",@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"}); + $p = $project{"INCLUDEPATH"}; + $p = ($p && $path) ? ($p . ";" . $path) : ($p . $path); + $project{"INCLUDEPATH"} = $p; + $p = join(" ",&split_path($p)); + $p =~ s=[\\/](\s|$)= =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/ ) { + $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,@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; + splice( @cur_dep_path, 0, 0, $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(" ",@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,@allincs,@includes,%incs); + $path = ($file eq $dep_file) ? $file : $dep_curdir . $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/,@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) = @_; + return "" if !defined($p); + $p =~ s=:=;=g if $is_unix; + $p =~ s=[/\\]+=/=g; + $p =~ s=([^/:]);=$1/;=g; + $p =~ s=([^:;/])$=$1/=; + $p =~ s=/=$dir_sep=g unless $is_unix; + return split(/;/,$p); +} + + +# +# 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; +} diff --git a/tmake/bin/tmake.bat b/tmake/bin/tmake.bat new file mode 100644 index 0000000..6fbd6b2 --- /dev/null +++ b/tmake/bin/tmake.bat @@ -0,0 +1,1093 @@ +@rem = '--*-PERL-*--'; +@rem = ' +@echo off +rem setlocal +set ARGS= +:loop +if .%1==. goto endloop +set ARGS=%ARGS% %1 +shift +goto loop +:endloop +rem ***** This assumes PERL is in the PATH ***** +perl.exe -S tmake.bat %ARGS% +goto endofperl +@rem '; +#!/usr/bin/perl +############################################################################ +# $Id$ +# +# 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. +# +############################################################################ + +if ($] < 5.0) { + &tmake_error("This program requires perl version 5 or newer"); +} + +$cpp_ext = "cpp"; +$obj_ext = "o"; +$moc_aware = 0; +$moc_pre = "moc_"; +$moc_ext = "moc"; +$moc_cmd = '$(MOC)'; +$linebreak = "\\"; +$dir_sep = "/"; +$is_unix = 1; +$really_unix = &check_unix(); +$guess_os = 1; +$depend_path = ""; +$nodepend = 0; +$output_count = 0; + +$template_name = ""; +$project_name = ""; +$outfile = ""; +@project_extra = (); +@project_files = (); +@eval_expr = (); +$eval_done = 0; + +while ( @ARGV ) { # parse command line args + $_ = shift @ARGV; + if ( s/^-// ) { + if ( /^e(.*)/ ) { + push( @eval_expr, ($1 eq "") ? shift @ARGV : $1); + } elsif ( /^t(.*)/ ) { + $template_name = ($1 eq "") ? shift @ARGV : $1; + } elsif ( /^o(.*)/ ) { + $outfile = ($1 eq "") ? shift @ARGV : $1; + ($outfile eq "-") && ($outfile = ""); + } elsif ( /^p(.*)/ ) { + push( @project_files, ($1 eq "") ? shift @ARGV : $1); + } elsif ( /^unix$/ ) { + $guess_os = 0; + $is_unix = 1; + } elsif ( /^win32$/ ) { + $guess_os = 0; + $is_unix = 0; + } elsif ( /^nodepend$/ ) { + $nodepend = 1; # don't generate dependencies + } elsif ( /^v$/ ) { + $verbose = 1; + } else { + &tmake_usage(); + } + } elsif ( /^\s*(?:[\w\-]+:)?\w+\s*[\+\-\*\/]?=/ ) { # project override + push( @project_extra, $_ ); + } else { + $project_name && + &tmake_error("You can only specify one project file"); + $project_name = $_; + } +} + +($project_name ne "") || &tmake_usage(); + +if ( $guess_os && ! check_unix() ) { # probably non-Unix, + $is_unix = 0; + &tmake_verb("Win32 detected"); +} +if ( ! $is_unix ) { + $obj_ext = "obj"; + $dir_sep = "\\"; +} +$outfile eq "" || open(STDOUT,">" . fix_path($outfile)) || + &tmake_error("Can't create \"$outfile\""); + +%project = (); +&ScanProject( &find_template("tmake.conf") ); +&tmake_verb("Reading the project file $project_name"); +if ( ! ($project_name =~ /\.pro$/i) && -f fix_path($project_name . ".pro") ) { + $project_name .= ".pro"; +} +$project{"PROJECT"} = $project_name; +$project{"PROJECT"} =~ s/\.pro$//i; +$project{"TARGET"} = $project{"PROJECT"}; + +unshift(@project_files,$project_name); +foreach ( @project_files ) { + if ( ! ($_ =~ /\.pro$/i) && -f fix_path($_ . ".pro") ) { + $_ .= ".pro"; + } + if ( !&ScanProject($_) ) { + &tmake_error("Can't open project file \"$_\""); + } +} +&Project( @project_extra ); + +if ( $template_name eq "" ) { + $template_name = $project{"TEMPLATE"} ? + $project{"TEMPLATE"} : "default.t"; +} + +foreach ( @eval_expr ) { + $text = ""; + eval( $_ ); + die $@ if $@; + print $text . "\n" if ($text ne ""); + $eval_done = 1; +} +if ( $eval_done ) { + &tmake_verb("Done!"); + exit 0; +} + +$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-file\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 " -p project Load additional project 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_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); + } + 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,@dirs); + $tb = ($template_base eq "") ? "" : $template_base . ";"; + $d = ";" . $tb . $ENV{"TMAKEPATH"} . ";" . $ENV{"HOME"} . "/.tmake/"; + @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"}); + } + if ( defined($project{"MOC_DIR"}) ) { + $project{"MOC_DIR"} = FixPath($project{"MOC_DIR"}); + } + $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 ( $p eq "." ) { $p = ""; } + elsif ( length($p) > 0 ) { + $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$name\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_val(tag) +# +# Internal function for Project(). +# Expands a project value string. +# + +sub expand_project_val { + my($v) = @_; + my($c); + $v =~ s/^\s+//; # trim white space + $v =~ s/\s+$//; + $c = 0; + while ( $c < 100 ) { # expand $$ + if ( $v =~ s/(\$\$\w+)/\035/ ) { + $_ = $1; + s/\$\$//g; + $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_tag,$t,$s,$v,$p,$c); + $r = ""; + foreach ( @settings ) { + $v = $_; + if ( $v =~ s/^\s*([\w\-]+:)?(\w+)\s*(\+=|\*=|\-=|\/=|=)\s*// ) { + $if_tag = $1; + if ( $if_tag ne "" ) { + chop $if_tag; + if ( $if_tag eq "unix" ) { + return "" if !$is_unix; + } elsif ( $if_tag eq "win32" ) { + return "" if $is_unix; + } elsif ( ($if_tag ne $tmake_platform) && !Config($if_tag) ) { + return ""; + } + } + $t = $2; + $s = $3; + $v = expand_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} = expand_project_val($p); + } else { + $p = expand_project_val($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_val($subst); + return $text; +} + + +# +# ScanProject(file) +# +# Scans a project file. Inserts project variables into the global +# associative project array. +# + +sub ScanProject { + my($file) = @_; + my($tag,$var,@v,$more,$line); + + $tag = ""; + $line = 0; + open(TMP,fix_path($file)) || return 0; + + while ( <TMP> ) { + $line++; + s/\#.*//; # strip comment + s/^\s+//; # strip white space + s/\s+$//; + if ( /^\s*((?:[\w\-]+:)?\w+\s*(\+|\-|\*|\/)?=)/ ) { + $tag = $1; # tag also contains the ".=" + s/^.*?=\s*//; + } + if ( $tag ne "" ) { + $more = ( $_ =~ s/\s*\\\s*$// ); # more if \ at end of line + push( @v, split( /\s+/, $_ ) ); + if ( ! $more ) { + $var = join(" ",@v); + Project( $tag . $var ); + $tag = ""; + @v = (); + } + } elsif ( $_ ne "" ) { + tmake_error("$file:$line: Syntax error"); + } + } + close(TMP); + 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 = ($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(tag) - appends to $text +# +# Expands a list of $project{} variables with a space character between them. +# + +sub Expand { + my @tags = @_; + my($t); + $t = Project(@tags); + if ( $text eq "" ) { + $text = $t; + } elsif ( $t ne "" ) { + $text .= " " . $t; + } + return $text; +} + + +# +# ExpandGlue(tag,prepend,glue,append) - appends to $text +# +# Expands a $project{} tag, 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 +# tag 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($tag,$prepend,$glue,$append) = @_; + my($t,$v); + $v = Project($tag); + 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(tag) - sets $text. +# +# Suitable for expanding HEADERS = ... etc. in a Makefile +# + +sub ExpandList { + my($tag) = @_; + return ExpandGlue($tag,""," ${linebreak}\n\t\t",""); +} + + +# +# 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(" ",@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,@m,@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(" ",@m); +} + + +# +# BuildObj(objects,sources) +# +# Builds the object files. +# + +sub BuildObj { + my($obj,$src) = @_; + 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; + 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 ""; + if ( defined($project{"OBJECTS_DIR"}) || + !defined($project{"TMAKE_COMPILE_IMP"}) ) { + $c = $project{"TMAKE_COMPILE"}; + $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_COMPILE_IMP"}) ) { + $c = $project{"TMAKE_COMPILE"}; + $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 ( $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; + } + $p = $project{"INCLUDEPATH"}; + $p = ($p && $path) ? ($p . ";" . $path) : ($p . $path); + $project{"INCLUDEPATH"} = $p; + $p = join(" ",&split_path($p)); + $p =~ s=[\\/](\s|$)= =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/ ) { + $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,@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; + $depend_path = $project{"DEPENDPATH"}; + $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; + splice( @cur_dep_path, 0, 0, $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 $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(" ",@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,@allincs,@includes,%incs); + $path = ($file eq $dep_file) ? $file : $dep_curdir . $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/,@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) = @_; + $p =~ s=:=;=g if $is_unix; + $p =~ s=[/\\]+=/=g; + $p =~ s=([^/:]);=$1/;=g; + $p =~ s=([^:;/])$=$1/=; + $p =~ s=/=$dir_sep=g unless $is_unix; + return split(/;/,$p); +} + + +# +# 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; +} +__END__ +:endofperl 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..b19af51 --- /dev/null +++ b/tmake/doc/tmake.html @@ -0,0 +1,638 @@ +<!doctype HTML public "-//W3C//DTD HTML 3.2//EN"> +<html><head><title> +tmake User's Guide +</title></head><body bgcolor="#ffffff"> +<p><h1 align=center>tmake User's Guide</h1> + + +<hr> +<h2>License Statement</h2> + +Copyright (C) 1996-1998 by Troll Tech AS. All rights reserved.<p> + +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. + + +<hr> +<h2>Introduction</h2> + +tmake is an easy-to-use tool for creating and maintaining makefiles across +many platforms and compilers. The idea is that you should spend your time +writing code, not makefiles. + +<p> +We wrote tmake because we spent too much time maintaining makefiles for +Windows and Unix compilers. Being the developer of the multi-platform GUI +toolkit <a href="http://www.troll.no/qt">Qt</a>, Troll Tech must provide +Qt makefiles for more than 30 different OS/compiler combinations. + +<p> +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 work to +add makefile rules for the moc and wanted to automate this task. + +<p> +The tmake project was started around mid 1996 and version 1.0 was released +in September 1997. It soon became a success and is now widely used among +Qt programmers. + +<p> +tmake is written in Perl and requires perl version 5 or newer. You do not +need to be familiar with Perl programming to use tmake, but you should +learn Perl if you want to 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> +Feedback is highly appreciated. Contact the author hanord@troll.no 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 or zip archive. +<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>Windows NT and Windows 95:</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>. +Each template directory contains template files and a configuration file. + +<p> +Supported platforms: AIX, Data General, FreeBSD, HPUX, SGI Irix, Linux, +NetBSD, OpenBSD, OSF1/DEC, SCO, Solaris, SunOS, Ultrix, Unixware and +Win32. + +<p> +Have a look at the tmake/lib directory to see if your platform-compiler +combination is supported. If it's not there, please tell us. + +<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 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> tag. 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> tag 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 (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> + +<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 tags 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 tags. +<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 tags 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 Unix shared +libraries, but ignored on Windows. + + + +<h4>The Subdirs Template</h4> + +The subdirs template, subdirs.t, lets you invoke make in subdirectories. + +<p>The <code>SUBDIRS</code> tag 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><a name="usage"></a>Program Usage: tmake</h2> + +Usage:<pre> + tmake [options] <em>project-file</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. + -p <em>file</em> Load an additional project file. + -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> tag 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> + + +<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:INCLUDE_PATH = c:\myinclude + win32-borland:DEFINES = NO_BOOL +</pre> + +You can prefix a project tag with unix: or win32: to make it specific for +either Unix or Windows. You can also prefix tags 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 tags it +finds, e.g. <code>HEADERS</code>, <code>SOURCES</code> etc. + +All tags 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..0b89b28 --- /dev/null +++ b/tmake/doc/tmake_ref.html @@ -0,0 +1,508 @@ +<!doctype HTML public "-//W3C//DTD HTML 3.2//EN"> +<html><head><title> +tmake Reference Manual +</title></head><body bgcolor="#ffffff"> +<p><h1 align=center>tmake Reference Manual</h1> + +<hr> +<h2>Project Settings</h2> + +tmake recognizes several project tags. The syntax for setting a +project variable is:<pre> + TAG = value +</pre> +You can also do tag expansion using $$:<pre> + ALLFILES = Project files: $$HEADERS $$SOURCES +</pre> +Normally you assign to a tag, but you can also add to a tag, subtract +from a tag or replace parts of the tag.<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 tag does not already contain it. +The /= operation performs regular expression substitution. + +<p> +You can also set tags from the command line when running the tmake program. +For instance, if you want to generate a makefile with debug information:<pre> + tmake hello.pro "CONFIG+=debug" +</pre> + +<p> +Use the <tt>unix:</tt> or <tt>win32:</tt> qualifier if you want a +platform-specific tag:<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 tag in <a +href="#CONFIG">CONFIG</a> setting:<pre> + debug:SOURCES += dbgstuff.cpp # additional source for debugging +</pre> + +Finally, you can set platform and compiler-dependent tags:<pre> + linux-g++:TMAKE_CFLAGS = -fno-rtti +</pre> + +<p> +You may define your own project tags to be used by custom templates. A +project tag is stored in <code>%project</code>, which is an associative +Perl array. Access it like this: <code>$project{"tag"}</code> or via the +function <code>Project('tag')</code>. For example, after reading +"hello.pro", <code>$project{"SOURCES"}</code> contains "hello.cpp +main.cpp". One limitation of tmake is that it cannot handle file names +with white space.<p> + + +<hr> +<h2>Project Tag 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="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 tag 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 tag 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 tag 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 tag 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 +tag. + + +<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 tag 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_FILETAGS"></a>TMAKE_FILETAGS</h4> +Tells tmake which tags 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> tag 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(tag)</h3> +Expands a project tag. Equivalent to <code>$text = $project{$tag}</code>. +<p>Example:<pre> + VERSION = #$ Expand("VERSION"); +</pre>Output:<pre> + VERSION = 1.1 +</pre> + +<h3>ExpandGlue(tag,prepend,glue,append)</h3> +Expands a $project{} tag, 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 tag 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(tag)</h3> +This function is suitable for expanding lists of files. +Equivalent with <code>ExpandGlue($tag,""," \\\n\t\t","")</code>.<p> +Example:<pre> + OBJECTS = #$ ExpandList("OBJECTS"); +</pre>Output:<pre> + OBJECTS = hello.o \ + main.o +</pre> + + +<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 tags 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 tags:<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 tags are created only if <code>CONFIG</code> contains "qt" + + +<h3>Substitute(string)</h3> +This function takes a string and substitutes any occurrence of $$tag +with the actual content of the tag. Returns the substituted string. +Also sets $text. +<p> +Important: Use single quotes around the string, otherwise perl will expand +any $tags 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..dc6ff77 --- /dev/null +++ b/tmake/example/hello.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** $Id$ +** +** 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..16e0871 --- /dev/null +++ b/tmake/example/hello.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** $Id$ +** +** 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 100755 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 100755 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 100755 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 100755 index 0000000..f2fe571 --- /dev/null +++ b/tmake/lib/aix-g++/tmake.conf @@ -0,0 +1,57 @@ +# +# $Id$ +# +# 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 -fno-strength-reduce +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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm + +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 100755 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 100755 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 100755 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 100755 index 0000000..401e390 --- /dev/null +++ b/tmake/lib/aix-xlc/tmake.conf @@ -0,0 +1,63 @@ +# +# $Id$ +# +# tmake configuration for aix-xlc +# + +TEMPLATE = app +CONFIG = qt warn_on release + +TMAKE_CC = xlC +TMAKE_CFLAGS = -+ -qstrict -D_BSD +TMAKE_CFLAGS_WARN_ON = +TMAKE_CFLAGS_WARN_OFF = +TMAKE_CFLAGS_RELEASE = -O3 +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) \ + -lX11 -lXext $(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 = +TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +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/dgux-g++/app.t b/tmake/lib/dgux-g++/app.t new file mode 100755 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 100755 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 100755 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 100755 index 0000000..54e4ac3 --- /dev/null +++ b/tmake/lib/dgux-g++/tmake.conf @@ -0,0 +1,58 @@ +# +# $Id$ +# +# 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 -fno-strength-reduce +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@infp.fzk.de> suggests -h not -soname +TMAKE_LFLAGS_SONAME = -Wl,-h, + +TMAKE_LIBS = +TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm + +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 100755 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 100755 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 100755 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 100755 index 0000000..d7dbb21 --- /dev/null +++ b/tmake/lib/freebsd-g++/tmake.conf @@ -0,0 +1,59 @@ +# +# $Id$ +# +# 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 -fno-strength-reduce +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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm + +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 100755 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 100755 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 100755 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 100755 index 0000000..eed7c32 --- /dev/null +++ b/tmake/lib/gnu-g++/tmake.conf @@ -0,0 +1,57 @@ +# +# $Id$ +# +# 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 -fno-strength-reduce +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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm + +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 100755 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 100755 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 100755 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 100755 index 0000000..381fa97 --- /dev/null +++ b/tmake/lib/hpux-acc/tmake.conf @@ -0,0 +1,59 @@ +# +# $Id$ +# +# tmake configuration for hpux-acc +# + +TEMPLATE = app +CONFIG = qt warn_on release + +TMAKE_CC = aCC +TMAKE_CFLAGS = -w -D__STRICT_ANSI__ +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 = +TMAKE_LIBDIR_X11 = +TMAKE_INCDIR_QT = $(QTDIR)/include +TMAKE_LIBDIR_QT = $(QTDIR)/lib +TMAKE_INCDIR_OPENGL = +TMAKE_LIBDIR_OPENGL = + +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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +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 100755 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 100755 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 100755 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 100755 index 0000000..851cb67 --- /dev/null +++ b/tmake/lib/hpux-cc/tmake.conf @@ -0,0 +1,58 @@ +# +# $Id$ +# +# tmake configuration for hpux-cc +# + +TEMPLATE = app +CONFIG = qt warn_on release + +TMAKE_CC = cc +TMAKE_CFLAGS = -w +a1 +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 = +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 = +TMAKE_LFLAGS_RELEASE = +TMAKE_LFLAGS_DEBUG = +TMAKE_LFLAGS_SHLIB = -b +TMAKE_LFLAGS_SONAME = +TMAKE_HPUX_SHLIB = 1 + +TMAKE_LIBS = +TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +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 100755 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 100755 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 100755 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 100755 index 0000000..f9b47d4 --- /dev/null +++ b/tmake/lib/hpux-g++/tmake.conf @@ -0,0 +1,59 @@ +# +# $Id$ +# +# 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 = -O2 -fno-strength-reduce +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 = -fPIC -shared +TMAKE_LFLAGS_SONAME = +TMAKE_HPUX_SHLIB = 1 + +TMAKE_LIBS = +TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +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 100755 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 100755 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 100755 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 100755 index 0000000..2d20f07 --- /dev/null +++ b/tmake/lib/irix-64/tmake.conf @@ -0,0 +1,59 @@ +# +# $Id$ +# +# 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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +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-dcc/app.t b/tmake/lib/irix-dcc/app.t new file mode 100755 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 100755 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 100755 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 100755 index 0000000..5f69690 --- /dev/null +++ b/tmake/lib/irix-dcc/tmake.conf @@ -0,0 +1,59 @@ +# +# $Id$ +# +# 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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +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 100755 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 100755 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 100755 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 100755 index 0000000..f6fea61 --- /dev/null +++ b/tmake/lib/irix-g++/tmake.conf @@ -0,0 +1,59 @@ +# +# $Id$ +# +# 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 = -O2 -fno-strength-reduce +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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +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 100755 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 100755 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 100755 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 100755 index 0000000..52a6a38 --- /dev/null +++ b/tmake/lib/irix-n32/tmake.conf @@ -0,0 +1,59 @@ +# +# $Id$ +# +# tmake configuration for irix-n32 +# + +TEMPLATE = app +CONFIG = qt warn_on release + +TMAKE_CC = CC +TMAKE_CFLAGS = -n32 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 = -n32 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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +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/linux-g++/app.t b/tmake/lib/linux-g++/app.t new file mode 100755 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 100755 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 100755 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 100755 index 0000000..01b0d82 --- /dev/null +++ b/tmake/lib/linux-g++/tmake.conf @@ -0,0 +1,57 @@ +# +# $Id$ +# +# 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 -fno-strength-reduce +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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm + +TMAKE_MOC = moc + +TMAKE_AR = ar cqs +TMAKE_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 100755 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 100755 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 100755 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 100755 index 0000000..53bbadc --- /dev/null +++ b/tmake/lib/netbsd-g++/tmake.conf @@ -0,0 +1,60 @@ +# +# $Id$ +# +# 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 -fno-strength-reduce +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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm + +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 100755 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 100755 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 100755 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 100755 index 0000000..e45b6d7 --- /dev/null +++ b/tmake/lib/openbsd-g++/tmake.conf @@ -0,0 +1,60 @@ +# +# $Id$ +# +# 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 -fno-strength-reduce +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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm + +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 100755 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 100755 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 100755 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 100755 index 0000000..7e4200e --- /dev/null +++ b/tmake/lib/osf1-cxx/tmake.conf @@ -0,0 +1,57 @@ +# +# $Id$ +# +# tmake configuration for osf1-cxx (a.k.a. DEC Unix) +# + +TEMPLATE = app +CONFIG = qt warn_on release + +TMAKE_CC = cxx +TMAKE_CFLAGS = -x cxx -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 = + +TMAKE_LIBS = +TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm + +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 100755 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 100755 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 100755 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 100755 index 0000000..54aa2c1 --- /dev/null +++ b/tmake/lib/osf1-g++/tmake.conf @@ -0,0 +1,57 @@ +# +# $Id$ +# +# 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 -fno-strength-reduce +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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm + +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 100755 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 100755 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 100755 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 100755 index 0000000..0bb70ae --- /dev/null +++ b/tmake/lib/qnx-g++/tmake.conf @@ -0,0 +1,57 @@ +# +# $Id$ +# +# 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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm + +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 100755 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 100755 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 100755 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 100755 index 0000000..8ee470c --- /dev/null +++ b/tmake/lib/sco-g++/tmake.conf @@ -0,0 +1,57 @@ +# +# $Id$ +# +# 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 -fno-strength-reduce +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 = -lX11 -lXext -lsocket +TMAKE_LIBS_QT = -lqt -lsocket +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm + +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/app.t b/tmake/lib/solaris-cc/app.t new file mode 100755 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 100755 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 100755 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 100755 index 0000000..dd8801b --- /dev/null +++ b/tmake/lib/solaris-cc/tmake.conf @@ -0,0 +1,60 @@ +# +# $Id$ +# +# tmake configuration for solaris-cc +# + +TEMPLATE = app +CONFIG = qt warn_on release + +TMAKE_CC = cc +TMAKE_CFLAGS = -pto +TMAKE_CFLAGS_WARN_ON = +TMAKE_CFLAGS_WARN_OFF = -w +TMAKE_CFLAGS_RELEASE = -O2 +TMAKE_CFLAGS_DEBUG = -g +TMAKE_CFLAGS_SHLIB = -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 = /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@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 +TMAKE_LFLAGS_SONAME = + +TMAKE_LIBS = +TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +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-g++/app.t b/tmake/lib/solaris-g++/app.t new file mode 100755 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 100755 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 100755 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 100755 index 0000000..c23c9b4 --- /dev/null +++ b/tmake/lib/solaris-g++/tmake.conf @@ -0,0 +1,57 @@ +# +# $Id$ +# +# 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 -fno-strength-reduce +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 = -B dynamic -h lib$(TARGET).so.$(VER_MAJ) -shared +TMAKE_LFLAGS_SONAME = + +TMAKE_LIBS = +TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +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 100755 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 100755 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 100755 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 100755 index 0000000..43115f8 --- /dev/null +++ b/tmake/lib/sunos-g++/tmake.conf @@ -0,0 +1,57 @@ +# +# $Id$ +# +# 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 -fno-strength-reduce +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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +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 100755 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 100755 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 100755 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 100755 index 0000000..59147d7 --- /dev/null +++ b/tmake/lib/ultrix-g++/tmake.conf @@ -0,0 +1,57 @@ +# +# $Id$ +# +# 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 -fno-strength-reduce +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 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm + +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 100755 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 100755 index 0000000..d9dc6ea --- /dev/null +++ b/tmake/lib/unix/generic.t @@ -0,0 +1,268 @@ +#! +#! 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") ) { + $moc_aware = 1; + AddIncludePath(Project("TMAKE_INCDIR_QT")); + 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'); + 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'); + } + Project('TMAKE_LIBS += $$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{"DESTDIR"} = FixPath($project{"DESTDIR"}); + $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_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' ); + 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 = #$ ExpandGlue("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): $(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 100755 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 100755 index 0000000..8f20097 --- /dev/null +++ b/tmake/lib/unix/subdirs.t @@ -0,0 +1,36 @@ +############################################################################# +#! +#! 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) + +tmake: +#${ + $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 100755 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 100755 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 100755 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 100755 index 0000000..24300a9 --- /dev/null +++ b/tmake/lib/unixware-g++/tmake.conf @@ -0,0 +1,57 @@ +# +# $Id$ +# +# tmake configuration for sco-g++ +# + +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 -fno-strength-reduce +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 = -lsocket -lnsl -lc +TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXt -lXext -lm + +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 100755 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 100755 index 0000000..88190d8 --- /dev/null +++ b/tmake/lib/win32-borland/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") ) { + $moc_aware = 1; + AddIncludePath(Project("TMAKE_INCDIR_QT")); + 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'); + } + } 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/"); + 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(); + $project{"DESTDIR"} = FixPath($project{"DESTDIR"}); + 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 = #$ 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_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): $(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 100755 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 100755 index 0000000..8e70c0e --- /dev/null +++ b/tmake/lib/win32-borland/subdirs.t @@ -0,0 +1,33 @@ +############################################################################# +#! +#! This is a tmake template for creating a makefile that invokes make in +#! sub directories - for Win32/Borland C++. +#! +#${ + StdInit(); + $m = ""; + foreach ( split(/\s+/,$project{"SUBDIRS"}) ) { + $m = $m . "\tcd $_\n\tDOMAKE\n\t\@cd ..\n"; + } + $project{"SUBMAKE"} = $m; +#$} +#! +# Makefile for building targets in sub directories. +# Generated by tmake at #$ Now(); +# Project: #$ Expand("PROJECT"); +# Template: #$ Expand("TEMPLATE"); +############################################################################# + +SUBDIRS = #$ ExpandList("SUBDIRS"); + +all: $(SUBDIRS) + +#${ + foreach ( split(/\s+/,$project{"SUBDIRS"}) ) { + $text = $text . $_ . ":\n\t" . + "cd $_\n\t\$(MAKE\)\n\t\@cd ..\n\n"; + } +#$} + +clean: +#$ $text = $project{"SUBMAKE"}; $text =~ s/DOMAKE/\$(MAKE\) clean/g; diff --git a/tmake/lib/win32-borland/tmake.conf b/tmake/lib/win32-borland/tmake.conf new file mode 100755 index 0000000..4dd3636 --- /dev/null +++ b/tmake/lib/win32-borland/tmake.conf @@ -0,0 +1,56 @@ +# +# $Id$ +# +# 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 = rc + +TMAKE_ZIP = zip -r -9 diff --git a/tmake/lib/win32-g++/app.t b/tmake/lib/win32-g++/app.t new file mode 100755 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 100755 index 0000000..253c401 --- /dev/null +++ b/tmake/lib/win32-g++/generic.t @@ -0,0 +1,226 @@ +#! +#! 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"} = ".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'); + } + 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; + } + $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; + } + 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_LFLAGS *= $$RES_FILE'); + } + StdInit(); + $project{"DESTDIR"} = FixPath($project{"DESTDIR"}); + 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"} = $project{"DESTDIR"} . "lib" . $project{"TARGET"} . + $project{"TARGET_EXT"}; + } else { + $project{"TARGET"} = $project{"DESTDIR"} . $project{"TARGET"} . + $project{"TARGET_EXT"}; + } +#$} +#! +# 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(); +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_COMPILE_IMP"); + +.cxx.o: + #$ Expand("TMAKE_COMPILE_IMP"); + +.cc.o: + #$ Expand("TMAKE_COMPILE_IMP"); + +.c.o: + #$ Expand("TMAKE_COMPILE_IMP"); + +####### Build rules + +all: #$ ExpandGlue("ALL_DEPS",""," "," "); $text .= '$(TARGET)'; + +$(TARGET): $(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 100755 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 100755 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 100755 index 0000000..59667bd --- /dev/null +++ b/tmake/lib/win32-g++/tmake.conf @@ -0,0 +1,56 @@ +# +# $Id$ +# +# tmake configuration for Win32/g++ (Cygnus gnu-win32) +# + +TEMPLATE = app +CONFIG = qt warn_on release + +TMAKE_CC = g++ +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 = $$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 = 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 -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 100755 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 100755 index 0000000..e57180d --- /dev/null +++ b/tmake/lib/win32-msvc/generic.t @@ -0,0 +1,221 @@ +#! +#! 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") ) { + $moc_aware = 1; + AddIncludePath(Project("TMAKE_INCDIR_QT")); + 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'); + } + } 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/"); + 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(); + $project{"DESTDIR"} = FixPath($project{"DESTDIR"}); + 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 = #$ 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_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): $(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 100755 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 100755 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 100755 index 0000000..cb64ac9 --- /dev/null +++ b/tmake/lib/win32-msvc/tmake.conf @@ -0,0 +1,64 @@ +# +# $Id$ +# +# 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_LIBS = +TMAKE_LIBS_CONSOLE = +TMAKE_LIBS_WINDOWS = user32.lib gdi32.lib comdlg32.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 100755 index 0000000..02e15e4 --- /dev/null +++ b/tmake/lib/win32-msvc/vcapp.t @@ -0,0 +1,226 @@ +#! +#! This TMAKE template - Microsoft Visual C++ 5.0 applications +#! +#${ + 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'); + } + Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT'); + } + if ( Config("opengl") ) { + Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL'); + } + Project('TMAKE_LIBS += $$LIBS'); + + if ( Config("windows") ) { + $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" '; + } else { + $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" '; + } + $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; + ExpandGlue("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 100755 index 0000000..e56409e --- /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; + ExpandGlue("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 100755 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 100755 index 0000000..e22d9c1 --- /dev/null +++ b/tmake/lib/win32-symantec/generic.t @@ -0,0 +1,212 @@ +#! +#! 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(); + $project{"DESTDIR"} = FixPath($project{"DESTDIR"}); + 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): $(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 100755 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 100755 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 100755 index 0000000..c2b7e68 --- /dev/null +++ b/tmake/lib/win32-symantec/tmake.conf @@ -0,0 +1,56 @@ +# +# $Id$ +# +# 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 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 100755 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 100755 index 0000000..fd928ad --- /dev/null +++ b/tmake/lib/win32-visage/generic.t @@ -0,0 +1,208 @@ +#! +#! 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(); + $project{"DESTDIR"} = FixPath($project{"DESTDIR"}); + 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): $(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 100755 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 100755 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 100755 index 0000000..3e20294 --- /dev/null +++ b/tmake/lib/win32-visage/tmake.conf @@ -0,0 +1,56 @@ +# +# $Id$ +# +# 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 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 100755 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 100755 index 0000000..a8c3990 --- /dev/null +++ b/tmake/lib/win32-watcom/generic.t @@ -0,0 +1,202 @@ +#! +#! 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(); + $project{"DESTDIR"} = FixPath($project{"DESTDIR"}); + 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 = #$ 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"}); +TMPLIST = #$ ExpandGlue("TARGET","","",".lst"); +####### Build rules + +all: #$ ExpandGlue("ALL_DEPS",""," "," "); $text .= '$(TARGET)'; + +$(TARGET): $(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 100755 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 100755 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 100755 index 0000000..3a3e0bf --- /dev/null +++ b/tmake/lib/win32-watcom/tmake.conf @@ -0,0 +1,54 @@ +# +# $Id$ +# +# 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 100755 index 0000000..57464c6 --- /dev/null +++ b/tmake/lib/win32/subdirs.t @@ -0,0 +1,35 @@ +############################################################################# +#! +#! 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; +#$} +#! +# Makefile for building targets in sub directories. +# Generated by tmake at #$ Now(); +# Project: #$ Expand("PROJECT"); +# Template: #$ Expand("TEMPLATE"); +############################################################################# + +SUBDIRS = #$ ExpandList("SUBDIRS"); + +all: $(SUBDIRS) + +#${ + foreach ( split(/\s+/,$project{"SUBDIRS"}) ) { + $text = $text . $_ . ": FORCE\n\t" . + "cd $_\n\t\$(MAKE\)\n\t\@cd ..\n\n"; + } +#$} + +clean: +#$ $text = $project{"SUBMAKE"}; $text =~ s/DOMAKE/\$(MAKE\) clean/g; + +FORCE: |