From f18128845407f8612668950e112c2d5c3e0ff5be Mon Sep 17 00:00:00 2001 From: mueller Date: Wed, 15 Dec 1999 19:34:06 +0000 Subject: mods for doxygen-0.49-990829 --- INSTALL | 115 ++-- Makefile | 183 ------ Makefile.config | 12 - Makefile.in | 34 ++ Makefile.win.in | 42 ++ Makefile.windows | 57 -- PLATFORMS | 24 + README | 4 +- VERSION | 1 + configure | 355 +++++++++++ doc/Makefile | 22 - doc/Makefile.in | 18 + doc/Makefile.win.in | 15 + doc/config.doc | 93 ++- doc/features.doc | 10 +- doc/index.doc | 7 +- doc/install.doc | 10 +- doc/starting.doc | 23 +- doc/trouble.doc | 9 +- examples/Makefile | 90 --- examples/Makefile.in | 89 +++ examples/Makefile.win.in | 89 +++ examples/Makefile.windows | 93 --- make.bat | 14 +- src/Makefile | 44 -- src/Makefile.in | 43 ++ src/classdef.cpp | 245 +++++--- src/classdef.h | 53 +- src/code.l | 50 +- src/config.h | 4 +- src/config.l | 124 ++-- src/declinfo.l | 10 +- src/defargs.l | 9 + src/define.cpp | 2 + src/define.h | 2 + src/definition.h | 56 +- src/diagram.cpp | 18 +- src/doxygen.cpp | 630 +++++++++++++------ src/doxygen.h | 5 +- src/doxygen.pro | 38 -- src/doxygen.pro.in | 39 ++ src/doxysearch.pro | 18 - src/doxysearch.pro.in | 18 + src/doxytag.l | 8 +- src/doxytag.pro | 24 - src/doxytag.pro.in | 24 + src/entry.cpp | 32 + src/entry.h | 13 +- src/filedef.cpp | 69 ++- src/filedef.h | 19 +- src/formula.cpp | 8 + src/groupdef.cpp | 7 +- src/groupdef.h | 8 + src/htmlgen.cpp | 147 ++++- src/htmlgen.h | 21 +- src/htmlhelp.cpp | 381 ++++++++++++ src/htmlhelp.h | 56 ++ src/index.cpp | 403 +++++++++--- src/index.h | 2 + src/latexgen.cpp | 95 ++- src/latexgen.h | 15 +- src/logos.cpp | 21 + src/logos.h | 1 + src/mangen.cpp | 36 ++ src/mangen.h | 18 +- src/memberdef.cpp | 934 +++++++++++++++++++++++++++- src/memberdef.h | 81 ++- src/membergroup.cpp | 251 ++++++++ src/membergroup.h | 62 ++ src/memberlist.cpp | 366 ++++++++++- src/memberlist.h | 8 +- src/membername.cpp | 4 - src/membername.h | 1 - src/namespacedef.cpp | 36 +- src/namespacedef.h | 34 +- src/outputgen.h | 10 +- src/outputlist.cpp | 4 + src/outputlist.h | 24 +- src/pre.l | 47 +- src/scanner.h | 7 + src/scanner.l | 267 ++++++-- src/tag.l | 7 +- src/translator.h | 441 ++++++++----- src/translator_de.h | 1 + src/translator_es.h | 1 + src/translator_it.h | 1 + src/translator_nl.h | 1 + src/translator_se.h | 1 + src/util.cpp | 1156 +++++------------------------------ src/util.h | 23 +- tmake/CHANGES | 10 + tmake/LICENSE | 2 +- tmake/README | 9 +- tmake/bin/progen.bat | 266 -------- tmake/bin/tmake | 415 +++++++++---- tmake/bin/tmake.bat | 1093 --------------------------------- tmake/doc/tmake.html | 219 +++++-- tmake/doc/tmake_ref.html | 117 ++-- tmake/lib/aix-g++/tmake.conf | 8 +- tmake/lib/aix-xlc/tmake.conf | 4 +- tmake/lib/bsdi-g++/app.t | 2 + tmake/lib/bsdi-g++/lib.t | 2 + tmake/lib/bsdi-g++/subdirs.t | 2 + tmake/lib/bsdi-g++/tmake.conf | 60 ++ tmake/lib/dgux-g++/tmake.conf | 6 +- tmake/lib/freebsd-g++/tmake.conf | 6 +- tmake/lib/gnu-g++/tmake.conf | 6 +- tmake/lib/hpux-acc/tmake.conf | 6 +- tmake/lib/hpux-cc/tmake.conf | 6 +- tmake/lib/hpux-g++/tmake.conf | 8 +- tmake/lib/irix-64/tmake.conf | 8 +- tmake/lib/irix-dcc/tmake.conf | 2 +- tmake/lib/irix-g++/tmake.conf | 4 +- tmake/lib/irix-n32/tmake.conf | 12 +- tmake/lib/irix-o32/app.t | 2 + tmake/lib/irix-o32/lib.t | 2 + tmake/lib/irix-o32/subdirs.t | 2 + tmake/lib/irix-o32/tmake.conf | 59 ++ tmake/lib/linux-g++/tmake.conf | 7 +- tmake/lib/netbsd-g++/tmake.conf | 6 +- tmake/lib/openbsd-g++/tmake.conf | 6 +- tmake/lib/osf1-cxx/tmake.conf | 14 +- tmake/lib/osf1-g++/tmake.conf | 6 +- tmake/lib/qnx-g++/tmake.conf | 4 +- tmake/lib/sco-g++/tmake.conf | 8 +- tmake/lib/solaris-cc-gcc/app.t | 2 + tmake/lib/solaris-cc-gcc/lib.t | 2 + tmake/lib/solaris-cc-gcc/subdirs.t | 2 + tmake/lib/solaris-cc-gcc/tmake.conf | 61 ++ tmake/lib/solaris-cc/tmake.conf | 16 +- tmake/lib/solaris-g++/tmake.conf | 7 +- tmake/lib/sunos-g++/tmake.conf | 4 +- tmake/lib/ultrix-g++/tmake.conf | 6 +- tmake/lib/unix/generic.t | 19 +- tmake/lib/unix/subdirs.t | 4 +- tmake/lib/unixware-g++/tmake.conf | 10 +- tmake/lib/unixware7-cc/app.t | 2 + tmake/lib/unixware7-cc/lib.t | 2 + tmake/lib/unixware7-cc/subdirs.t | 2 + tmake/lib/unixware7-cc/tmake.conf | 59 ++ tmake/lib/unixware7-g++/app.t | 2 + tmake/lib/unixware7-g++/lib.t | 2 + tmake/lib/unixware7-g++/subdirs.t | 2 + tmake/lib/unixware7-g++/tmake.conf | 59 ++ tmake/lib/win32-borland/generic.t | 16 +- tmake/lib/win32-borland/subdirs.t | 36 +- tmake/lib/win32-borland/tmake.conf | 2 +- tmake/lib/win32-g++/generic.t | 83 ++- tmake/lib/win32-g++/tmake.conf | 6 +- tmake/lib/win32-msvc/generic.t | 16 +- tmake/lib/win32-msvc/tmake.conf | 5 +- tmake/lib/win32-msvc/vcapp.t | 44 +- tmake/lib/win32-msvc/vclib.t | 2 +- tmake/lib/win32-symantec/generic.t | 3 +- tmake/lib/win32-symantec/tmake.conf | 2 +- tmake/lib/win32-visage/generic.t | 3 +- tmake/lib/win32-visage/tmake.conf | 2 +- tmake/lib/win32-watcom/generic.t | 3 +- tmake/lib/win32/subdirs.t | 23 +- wintools/make.pl | 25 + 160 files changed, 6520 insertions(+), 4396 deletions(-) delete mode 100644 Makefile delete mode 100644 Makefile.config create mode 100644 Makefile.in create mode 100644 Makefile.win.in delete mode 100644 Makefile.windows create mode 100644 PLATFORMS create mode 100644 VERSION create mode 100755 configure delete mode 100644 doc/Makefile create mode 100644 doc/Makefile.in create mode 100644 doc/Makefile.win.in delete mode 100644 examples/Makefile create mode 100644 examples/Makefile.in create mode 100644 examples/Makefile.win.in delete mode 100644 examples/Makefile.windows delete mode 100644 src/Makefile create mode 100644 src/Makefile.in delete mode 100644 src/doxygen.pro create mode 100644 src/doxygen.pro.in delete mode 100644 src/doxysearch.pro create mode 100644 src/doxysearch.pro.in delete mode 100644 src/doxytag.pro create mode 100644 src/doxytag.pro.in create mode 100644 src/htmlhelp.cpp create mode 100644 src/htmlhelp.h create mode 100644 src/membergroup.cpp create mode 100644 src/membergroup.h delete mode 100644 tmake/bin/progen.bat delete mode 100644 tmake/bin/tmake.bat create mode 100755 tmake/lib/bsdi-g++/app.t create mode 100755 tmake/lib/bsdi-g++/lib.t create mode 100755 tmake/lib/bsdi-g++/subdirs.t create mode 100755 tmake/lib/bsdi-g++/tmake.conf create mode 100755 tmake/lib/irix-o32/app.t create mode 100755 tmake/lib/irix-o32/lib.t create mode 100755 tmake/lib/irix-o32/subdirs.t create mode 100755 tmake/lib/irix-o32/tmake.conf create mode 100755 tmake/lib/solaris-cc-gcc/app.t create mode 100755 tmake/lib/solaris-cc-gcc/lib.t create mode 100755 tmake/lib/solaris-cc-gcc/subdirs.t create mode 100755 tmake/lib/solaris-cc-gcc/tmake.conf create mode 100755 tmake/lib/unixware7-cc/app.t create mode 100755 tmake/lib/unixware7-cc/lib.t create mode 100755 tmake/lib/unixware7-cc/subdirs.t create mode 100755 tmake/lib/unixware7-cc/tmake.conf create mode 100755 tmake/lib/unixware7-g++/app.t create mode 100755 tmake/lib/unixware7-g++/lib.t create mode 100755 tmake/lib/unixware7-g++/subdirs.t create mode 100755 tmake/lib/unixware7-g++/tmake.conf create mode 100755 wintools/make.pl diff --git a/INSTALL b/INSTALL index c62f167..4a679e9 100644 --- a/INSTALL +++ b/INSTALL @@ -1,38 +1,34 @@ -DOXYGEN Version 0.49-990728 +DOXYGEN Version 0.49-990829 + +CONTENTS +-------- + - Installation instructions for UNIX + - Installation instructions for Windows + - Known configuration problems: + * HTML related problems + * LaTeX related problems + * HP-UX / Digital UNIX problems INSTALLATION INSTRUCTIONS FOR UNIX: ----------------------------------- 1. Unpack the archive, unless you already have: - gunzip doxygen-0.49-990728.src.tar.gz # uncompress the archive - tar xf doxygen-0.49-990728.src.tar # unpack it - -2. Make sure Qt is installed properly (check the environment variable $QTDIR) + gunzip doxygen-0.49-990829.src.tar.gz # uncompress the archive + tar xf doxygen-0.49-990829.src.tar # unpack it - 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 include - ln -s 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. +2. Run the configure script: + + sh ./configure -4. Compile the program. + The script tries to determine the platform you use, the location + of the Qt library, the make tool and the perl interpreter. + It will report what it finds. Use configure --help + to see how to override or change the default settings. - Type: - - make +3. Compile the program by running 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++ + make The program should compile without problems and three binaries (doxygen, doxytag, and doxysearch) should be available in the bin directory of the @@ -40,16 +36,12 @@ INSTALLATION INSTRUCTIONS FOR UNIX: 5. Generate the user manual. - type: - - make docs + make docs to let doxygen generate the HTML and LaTeX documentation. (you will need the stream editor `sed' for this) - type: - - make ps + make ps to generate a postscript version of the manual. (you will need latex and dvips for this) @@ -65,27 +57,40 @@ INSTALLATION INSTRUCTIONS FOR UNIX: 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. +Currently, only Microsoft Visual C++ (version 5.0) is supported. +(For other platforms you may need to edit the perl script in wintools/make.pl +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. + You can download it at: http://www.ActiveState.com/pw32/ +- the GNU tools flex, bison and sed. + To get these working on Windows you can install the cygwin tools. + You can download them at: http://sourceware.cygnus.com/cygwin/ + Make sure the BISONLIB environment variable points to the + location where bison.simple and bison.hairy are located. +- Qt-1.xx (Qt-2.xx should also work, but I didn't test it for Windows) + (Hint: only the tools section is required, so you can use the free + X-windows version as well!) +- Microsoft Visual C++ (I only tested with version 5.0). + Use the vcvars32.bat to set the environment variables + (if not selected to do this automatically during installation). +- To generate LaTeX documentation or formulas in HTML you need the tools: + latex, dvips and gswin32 + To get these working under Windows install the fpTeX distribution + You can download it at: + ftp://ctan.tug.org/tex-archive/systems/win32/web2c/fptex-0.3/ +- If you want to generate compressed HTML help (see GENERATE_HTMLHELP in the + config file), then you need the Microsoft HTML help workshop. + You can download it at: http://msdn.microsoft.com/workshop/author/htmlhelp - If you used WinZip to extract the tar archive it will (apparently) not create empty folders, so you have to add the folders `objects' and `bin' manually in the root of the distribution before compiling. -Make sure all tools are accessible from the command-line. +Make sure all tools are accessible from the command-line (add them to the +PATH environment if needed). Open a dos box, goto the doxygen root dir and type: @@ -96,23 +101,37 @@ This should build the executables doxygen.exe, doxytag.exe, and doxysearch.exe To build the examples type: -nmake -f Makefile.windows examples +nmake examples + +To generate the HTML documentation type: + +nmake docs + +The generated docs are located in the html directory. +To generate the postscript manual type: + +nmake ps + +The manual should now be here latex/doxygen_manual.ps ----------------------------------------------------------------------------- KNOWN CONFIGURATION PROBLEMS +QT RELATED PROBLEMS: +- Qt-2.01 contains a bug that + + HTML RELATED PROBLEMS: - the indent continuously increases. This seems to be a problem that can be observed with Netscape 4.01. It is not present in many later and earlier versions I tested. 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) + in the config file (see the PAPER_TYPE tag in the config file) - the file fancyheader.sty is known as fancyhdr.sty on some systems. Please change that in src/latexgen.cpp @@ -154,4 +173,4 @@ The latest version of doxygen can be obtained at Enjoy, -Dimitri van Heesch (30 July 1999) +Dimitri van Heesch (29 August 1999) diff --git a/Makefile b/Makefile deleted file mode 100644 index 7fb6010..0000000 --- a/Makefile +++ /dev/null @@ -1,183 +0,0 @@ -# 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) - -gnu-g++: src/version.cpp - cd src; \ - TMAKEPATH=../tmake/lib/gnu-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 LICENSE - -src/version.cpp: FORCE - echo "char versionString[]=\"$(VERSION)\";" > src/version.cpp - -FORCE: diff --git a/Makefile.config b/Makefile.config deleted file mode 100644 index 9dc23f3..0000000 --- a/Makefile.config +++ /dev/null @@ -1,12 +0,0 @@ -# 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-990728 diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..21afe27 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,34 @@ +all: src/version.cpp + cd src ; $(MAKE) + +clean: FORCE + cd examples ; $(MAKE) clean + cd doc ; $(MAKE) clean + cd src ; $(MAKE) clean + -rm -f bin/doxy* + -rm -f objects/*.o + +distclean: clean + -rm -f src/Makefile.doxygen \ + src/Makefile.doxytag \ + src/Makefile.doxysearch + -rm -f Makefile src/Makefile examples/Makefile doc/Makefile + -rm -f src/doxygen.pro src/doxytag.pro src/doxysearch.pro + -rm -f src/version.cpp + +docs: FORCE + cd examples ; $(MAKE) + cd doc ; $(MAKE) + +ps: docs + cd latex ; $(MAKE) + +archive: distclean + tar zcvf dx`date +%y%m%d`.tgz tmake doc wintools examples bin objects \ + src configure Makefile.in Makefile.win.in INSTALL make.bat \ + LANGUAGE.HOWTO LICENSE PLATFORMS VERSION + +src/version.cpp: Makefile + echo "char versionString[]=\"$(VERSION)\";" > src/version.cpp + +FORCE: diff --git a/Makefile.win.in b/Makefile.win.in new file mode 100644 index 0000000..add71f6 --- /dev/null +++ b/Makefile.win.in @@ -0,0 +1,42 @@ +all: src\version.cpp + set TMAKEPATH=$(TMAKEPATH) + cd src + $(MAKE) + +clean: FORCE + cd examples + $(MAKE) clean + cd .. + cd doc + $(MAKE) clean + cd .. + cd src + $(MAKE) clean + cd .. + -del bin\doxy*.* + -del objects\*.o + +distclean: clean + -del src\Makefile.doxygen \ + src\Makefile.doxytag \ + src\Makefile.doxysearch + -del Makefile src\Makefile examples\Makefile doc\Makefile + -del src\doxygen.pro src\doxytag.pro src\doxysearch.pro + -del src\version.cpp + +docs: FORCE + cd examples + $(MAKE) + cd .. + cd doc + $(MAKE) + cd .. + +ps: docs + cd latex + $(MAKE) + +src\version.cpp: Makefile + echo char versionString[]="$(VERSION)"; > src\version.cpp + +FORCE: diff --git a/Makefile.windows b/Makefile.windows deleted file mode 100644 index a662b2e..0000000 --- a/Makefile.windows +++ /dev/null @@ -1,57 +0,0 @@ -# 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: diff --git a/PLATFORMS b/PLATFORMS new file mode 100644 index 0000000..0ce4249 --- /dev/null +++ b/PLATFORMS @@ -0,0 +1,24 @@ +aix-g++ +aix-xlc +dgux-g++ +freebsd-g++ +gnu-g++ +hpux-acc +hpux-cc +hpux-g++ +irix-64 +irix-dcc +irix-g++ +irix-n32 +linux-g++ +netbsd-g++ +openbsd-g++ +osf1-cxx +osf1-g++ +qnx-g++ +sco-g++ +solaris-cc +solaris-g++ +sunos-g++ +ultrix-g++ +unixware-g++ diff --git a/README b/README index d79e9b8..a3de3a4 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOXYGEN Version 0.49-990728 +DOXYGEN Version 0.49-990829 Please read INSTALL for compilation instructions. @@ -7,4 +7,4 @@ The latest version of doxygen can be obtained at Enjoy, -Dimitri van Heesch (30 July 1999) +Dimitri van Heesch (29 August 1999) diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..1eedcd4 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.49-990829 diff --git a/configure b/configure new file mode 100755 index 0000000..da03458 --- /dev/null +++ b/configure @@ -0,0 +1,355 @@ +#! /bin/sh +# +# $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. +# +# shell script to configure doxygen + +bin_dirs=`echo $PATH | sed -e "s/:/ /g"` + +f_debug=NO +f_shared=YES +f_make=NO +f_perl=NO +f_qt_include=NO +f_qt_library=NO +f_plf_auto=NO + +while test -n "$1"; do + case $1 in + --shared) + f_shared=YES + ;; + --static) + f_shared=NO + ;; + --release) + f_debug=NO + ;; + --debug) + f_debug=YES + ;; + --qt-includes) + shift; f_qt_include=$1 + ;; + --qt-libs) + shift; f_qt_library=$1 + ;; + --platform) + shift; f_platform=$1 + ;; + --make) + shift; f_make=$1 + ;; + --perl) + shift; f_perl=$1 + ;; + -h | -help | --help) + f_help=y + ;; + *) + echo $1: unknown argument + f_help=y + f_error=y + ;; + esac + shift +done + +if test "$f_help" = y; then + cat </dev/null` || u_release=unknown +u_system=`(uname -s) 2>/dev/null` || u_system=unknown + +if test -z "$f_platform"; then + f_platforms="`cat PLATFORMS`" + + case "$u_system:$u_release" in + AIX*) + f_platform=aix-xlc + ;; + dgux:*) + f_platform=dgux-g++ + ;; + FreeBSD:*) + f_platform=freebsd-g++ + ;; + GNU:*) + f_platform=gnu-g++ + ;; + HP-UX:*) + f_platform=hpux-g++ + ;; + IRIX64:*) + f_platform=irix-64 + ;; + IRIX:*) + f_platform=irix-n32 + ;; + Linux:*) + f_platform=linux-g++ + ;; + NetBSD:*) + f_platform=netbsd-g++ + ;; + OpenBSD:*) + f_platform=openbsd-g++ + ;; + OSF1:*) + f_platform=osf1-g++ + ;; + QNX:*) + f_platform=qnx-g++ + ;; + *:3.2) + f_platform=sco-g++ + ;; + SunOS:4*) + f_platform=sunos-g++ + ;; + SunOS:5*) + f_platform=solaris-cc + ;; + ULTRIX:*) + f_platform=ultrix-g++ + ;; + UNIX_SV:4.2*) + f_platform=unixware-g++ + ;; + *) + echo + echo "Your platform was not recognised by this configure script" + echo "Please use the -platform option to specify one of platforms" + echo "in this list:" + echo + for p in $f_platforms + do + echo " $0 $* -platform $p" + done + echo + exit 2 + esac + echo " Autodetected platform $f_platform... " + f_plf_auto=YES +fi + +if test "$f_plf_auto" = NO; then + echo -n " Checking for platform $f_platform... " + if test '!' -d tmake/lib/$f_platform; then + echo "not supported!" + echo + exit 2 + fi + echo "supported" +fi + +#- check for qt -------------------------------------------------------------- + +echo -n " Checking for Qt..." +if test "$f_qt_include" = NO; then + qt_incdirs="/usr/lib/qt/include /usr/local/qt/include /usr/include/qt /usr/include /usr/X11R6/include/X11/qt" + test -n "$QTDIR" && qt_incdirs="$QTDIR/include $QTDIR $qt_incdirs" + + qt_incdir=NO + for i in $qt_incdirs; do + if test -r "$i/qlist.h"; then + qt_incdir=$i + break + else + echo "Tried include directory $i..." + fi + done + f_qt_include="$qt_incdir" +fi + +if test "$f_qt_library" = NO; then + qt_libdirs="/usr/lib/qt/lib /usr/X11R6/lib /usr/lib /usr/local/qt/lib /usr/lib/qt" + if test -n "$LD_LIBRARY_PATH"; then + qt_ldpaths=`echo $LD_LIBRARY_PATH | sed 's%:% %'` + qt_libdirs="$qt_ldpaths $qt_libdirs" + fi + test -n "$QTDIR" && qt_libdirs="$QTDIR/lib $QTDIR $qt_libdirs" + + qt_libdir=NO + for i in $qt_libdirs; do + try="ls -1 $i/libqt*" + if test=`eval $try 2>/dev/null`; then + qt_libdir=$i; + break + else + echo "Tried library directory $i..." + fi + done + f_qt_library="$qt_libdir" +fi + +if test "$f_qt_include" = NO || test "$f_qt_library" = NO; then + if test "$f_qt_include" = NO && test "$f_qt_library" = NO; then + echo "not found!" + echo + elif test "$f_qt_include" = NO; then + echo "include files not found!" + else + echo "libraries not found!" + fi + exit 2 +fi + +echo "libraries: $f_qt_library" +echo " headers: $f_qt_include" + +# - check for make ------------------------------------------------------------ + +echo -n " Checking for make tool... " +if test "$f_make" = NO; then + make_names="make gmake pmake" + make_dirs="/usr/bin /usr/local/bin /bin /sbin $bin_dirs" + make_prog=NO + for i in $make_names; do + for j in $make_dirs; do + if test -x "$j/$i"; then + make_prog="$j/$i" + break 2 + fi + done + done + f_make="$make_prog" +fi + +if test "$f_make" = NO; then + echo "not found!"; + echo + exit 2 +fi +echo "using $f_make" + +# - check for perl ------------------------------------------------------------ + +echo -n " Checking for perl... " +if test "$f_perl" = NO; then + perl_names="perl perl5" + perl_dirs="/usr/bin /usr/local/bin /bin /sbin $bin_dirs" + perl_prog=NO + perl_found=NO + for i in $perl_names; do + for j in $perl_dirs; do + if test -x "$j/$i"; then + perl_found=YES + if $j/$i -e 'require 5.000;' 2>/dev/null ; then + perl_prog="$j/$i" + break 2 + fi + fi + done + done + f_perl="$perl_prog" +fi + +if test "$f_perl" = NO; then + if test "$perl_found" = YES; then + echo "version is too old (5.000 or higher is required)." + else + echo "not found!"; + fi + echo + exit 2 +fi +echo "using $f_perl"; + +# ----------------------------------------------------------------------------- + +test -f .makeconfig && rm .makeconfig +test -f .tmakeconfig && rm .tmakeconfig + +cat > .makeconfig < .tmakeconfig < $DST <> $DST + echo " Created $DST from $SRC..." +done + +for i in src/doxygen.pro.in src/doxytag.pro.in src/doxysearch.pro.in ; do + SRC=$i + DST=`echo $i|sed 's%\(.*\).in$%\1%'` + TIME=`date` + cat > $DST <> $DST + else + cat $SRC .tmakeconfig | sed -e "s/\$extraopts/debug/g" >> $DST + fi + echo " Created $DST from $SRC..." +done + diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 953517a..0000000 --- a/doc/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -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.in b/doc/Makefile.in new file mode 100644 index 0000000..f2de956 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,18 @@ + +all: FORCE + DOXYGEN_DOCDIR=$(DOXYGEN); \ + export DOXYGEN_DOCDIR; \ + VERSION=$(VERSION) ; \ + export VERSION; \ + $(DOXYGEN)/bin/doxygen + @rm -f ../latex/refman.tex + @cp doxygen_logo*.gif ../html + @cp Makefile.latex ../latex/Makefile + @sed -e "s/\$$VERSION/$(VERSION)/g" doxygen_manual.tex >../latex/doxygen_manual.tex + @sed -e "s/\$$VERSION/$(VERSION)/g" doxygen.sty >../latex/doxygen.sty + @cp doxygen_logo.eps ../latex + +clean: + rm -rf ../html ../latex + +FORCE: diff --git a/doc/Makefile.win.in b/doc/Makefile.win.in new file mode 100644 index 0000000..e870a81 --- /dev/null +++ b/doc/Makefile.win.in @@ -0,0 +1,15 @@ +all: FORCE + set DOXYGEN_DOCDIR=file:///$(DOXYGEN) + set VERSION=$(VERSION) + $(DOXYGEN)\bin\doxygen + @del ..\latex\refman.tex + @copy doxygen_logo*.gif ..\html + @copy Makefile.latex ..\latex\Makefile + @sed -e "s/\$$VERSION/$(VERSION)/g" doxygen_manual.tex >..\latex\doxygen_manual.tex + @sed -e "s/\$$VERSION/$(VERSION)/g" doxygen.sty >..\latex\doxygen.sty + @copy doxygen_logo.eps ..\latex + +clean: + del /s /q ..\html ..\latex + +FORCE: diff --git a/doc/config.doc b/doc/config.doc index 2bf3dc7..f238ad1 100644 --- a/doc/config.doc +++ b/doc/config.doc @@ -35,7 +35,7 @@ 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). +Environment variables can expanded using the pattern \c $(ENV_VARIABLE_NAME). The configuration options can be divided into several categories. Below is a list of tags that are recognized for each category. @@ -155,7 +155,7 @@ Below is a list of tags that are recognized for each category. \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 + only done if one of the specified strings matches the left-hand part of the path.
\c CLASS_DIAGRAMS
@@ -164,6 +164,12 @@ Below is a list of tags that are recognized for each category. 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. +
\c SOURCE_BROWSER
+ \addindex SOURCE_BROWSER + If the \c SOURCE_BROWSER tag is set to \c YES than the body of a member or + function will be appended as a block of code to the documentation of. + that member or function. +
\c CASE_SENSE_NAMES
\addindex CASE_SENSE_NAMES If the \c CASE_SENSE_NAMES tag is set to \c NO (the default) then Doxygen @@ -179,6 +185,13 @@ Below is a list of tags that are recognized for each category. which an include is specified. Set to NO to disable this.\n"; \sa Section \ref cmdclass "\\class". +
\c JAVADOC_AUTOBRIEF
+ \addinex JAVADOC_AUTOBRIEF + If the JAVADOC_NO_AUTOBRIEF is set to YES (the default) then Doxygen + will interpret the first line (until the first dot) of a JavaDoc-style + comment as the brief description. If set to NO, the Javadoc-style will + behave just like the Qt-style comments. + \subsection config_input Input related options @@ -226,12 +239,6 @@ Below is a list of tags that are recognized for each category. directories that contain example code fragments that are included (see the \\include command in section \ref cmdinclude "\\include"). -
\c INCLUDE_PATH
- \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. -
\c INPUT_FILTER
\addindex INPUT_FILTER The \c INPUT_FILTER tag can be used to specify a program that doxygen should @@ -298,6 +305,44 @@ Below is a list of tags that are recognized for each category. Doxygen will replace them by respectively the title of the page, the current date and time, or only the current date. +
\c HTML_ALIGN_MEMBERS
+ +If the \c HTML_ALIGN_MEMBERS tag is set to \c YES, the members of classes, +files or namespaces will be aligned in HTML using tables. If set to +NO a bullet list will be used. + +\par Notice +Setting this tag to NO will become obsolete in the future, since I only +intent to support and test the aligned representation. + +
\c GENERATE_HTMLHELP
+ +If the \c GENERATE_HTMLHELP tag is set to \c YES, +doxygen generates three additional HTML index files: +\c index.hhp, \c index.hhc, and \c index.hhk. The \c index.hhp is a +project file that can be read by + +Microsoft HTML help workshop +\latexonly +(see http://msdn.microsoft.com/workshop/author/htmlhelp) +\endlatexonly +on Windows. + +The HTML workshop contains a compiler that can convert all HTML output +generated by doxygen into a single compressed HTML file (.chm). Compressed +HTML files are now used as the Windows 98 help format, and will replace +the old windows help format (.hlp) on all Windows platforms in the future. +Compressed HTML files also contain an index, a table of contents, +and you can search for words in the documentation +(which basically renders \c doxysearch obsolete on Windows). +The HTML workshop also contains a viewer for compressed HTML files. + +
\c ALPHABETICAL_INDEX
+ +If the \c ALPHABETICAL_INDEX tag is set to \c YES, an alphabetical index +of all compounds will be generated. Enable this if the project contains +a lot of classes, structs, unions or interfaces. + \subsection latex_output LaTeX related options @@ -542,22 +587,22 @@ 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 + 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 \ diff --git a/doc/features.doc b/doc/features.doc index 2f34e18..7159124 100644 --- a/doc/features.doc +++ b/doc/features.doc @@ -23,10 +23,10 @@ Plain text will do, but for more fancy or structured output HTML tags and/or some of doxygen's special commands can be used.
  • Outputs documentation in on-line format (HTML and man page) and off-line - format (LaTeX) simulatiously (one can be disabled if desired). + format (LaTeX) simulatiously (any one can be disabled if desired). Both formats are optimized for ease of reading. -
  • Allows documentation of files, classes, templates, variables, functions, - typedefs, enums and defines. +
  • Allows documentation of files, namespaces, classes, structs, unions, + templates, variables, functions, typedefs, enums and defines.
  • 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.
  • Automatically detects public, protected and private sections, as well as @@ -46,7 +46,7 @@ of a member function or class. Most documentation systems (such as Javadoc) only support the former, others (such as Qt) only the latter.
  • You can type normal HTML tags in your documentation. Doxygen will convert - them to Latex automatically. + them to their equivalent Latex and man-page counterparts automatically.
  • Allows references to documentation generated for other projects (or another part of the same project) in a location independent way.
  • Allows inclusion of source code examples that are automatically @@ -58,6 +58,8 @@ file.
  • Documentation and search engine can be transferred to another location or machine without regenerating the documentation. +
  • Doxygen can generate index and project files that can + be converted into compressed HTML by MicroSoft's HTML help workshop.
  • Can cope with large projects easily. diff --git a/doc/index.doc b/doc/index.doc index 7db1d27..7a321db 100644 --- a/doc/index.doc +++ b/doc/index.doc @@ -116,6 +116,7 @@ Thanks go to: (which is even useful for GUI-less applications like doxygen :-)
  • My brother Frank for rendering the logos. +
  • Harm van der Heijden for adding HTML help support.
  • Arnt Gulbrandsen, Adam P. Jenkins, @@ -174,9 +175,9 @@ Feiyi Wang, Robert J. Clark, Matthias Baas, Walter Mueller, -William van Dieten, and -Joshua Jensen and -many others for suggestions, patches and bug reports. +William van Dieten, +Joshua Jensen, +and many others for suggestions, patches and bug reports. */ diff --git a/doc/install.doc b/doc/install.doc index 2c5f0ac..b17be97 100644 --- a/doc/install.doc +++ b/doc/install.doc @@ -79,15 +79,15 @@ The following binaries should now be available: Doxygen was developed and tested under Linux using the following tools:
      -
    • GCC version 2.8.1 +
    • EGCS version 2.91.66
    • GNU flex version 2.5.4
    • GNU bison version 1.25 -
    • GNU make version 3.77 -
    • Perl version 5.001 (patch level 1m) -
    • VIM version 5.3 +
    • GNU make version 3.76.1 +
    • Perl version 5.005_02 +
    • VIM version 5.4
    • Netscape 4.04 & 4.5
    • Troll Tech's tmake version 1.2 (included in the distribution) -
    • teTeX version 0.4 +
    • teTeX version 0.9
    \htmlonly diff --git a/doc/starting.doc b/doc/starting.doc index 78f9309..bbb23bd 100644 --- a/doc/starting.doc +++ b/doc/starting.doc @@ -394,7 +394,7 @@ 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 +file formula.repository that is written in the html directory to a rid of an incorrect formula \subsection preprocessing Preprocessing @@ -404,7 +404,7 @@ build-in C-preprocessor. By default doxygen does only partial preprocessing. That is, it evaluates conditional compilation statements (like \#if) and -evaluates macro definitions, but is does not perform macro expansion. +evaluates macro definitions, but it does not perform macro expansion. So if you have the following code fragment \verbatim @@ -509,6 +509,25 @@ automatically by the preprocessor (like \c __cplusplus), have to be defined by hand with doxygen's parser (this is done because these defines are often platform/compiler specific). +In some cases you may want to substitute a macro name or function by +something else without exposing the result to further macro substitution. +You can do this but using the := operator instead of += + +As an example suppose we have the following piece of code: +\verbatim +#define QList QListT +class QListT +{ +}; +\endverbatim + +Then the only way to get doxygen interpret this as a class definition +for class QList is to define: +\verbatim +PREDEFINED = QListT:=QList +\endverbatim + As you can see doxygen's preprocessor is quite powerful, but if you want even more flexibility you can always write an input filter and specify it on the \c INPUT_FILTER flag. diff --git a/doc/trouble.doc b/doc/trouble.doc index 72013d3..5f130ec 100644 --- a/doc/trouble.doc +++ b/doc/trouble.doc @@ -48,6 +48,13 @@ int *(a[20]); \endverbatim then doxygen will remove the braces and correctly parse the result. +
  • Not all names in code fragments that are include in the documentation + are replaced by links (for instance when using SOURCE_BROWSER = YES). + For a part this is because the code parser isn't smart enough at the + moment. I'll try to improve this in the future. But even with these + improvements not everthing can be properly linked to the corresponding + documentation, because of possible ambiguities or lack of + information about the context in which the code fragment is found. @@ -67,6 +74,6 @@ demonstrating the problem you have (make sure the example compiles!). It is usually a good idea to send along the configuation file as well, but please use doxygen with the -s flag while generating it. -My email address: dimitri@stack.nl +My e-mail address: dimitri@stack.nl */ diff --git a/examples/Makefile b/examples/Makefile deleted file mode 100644 index 1bbc2c1..0000000 --- a/examples/Makefile +++ /dev/null @@ -1,90 +0,0 @@ -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 \ - 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 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 - -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.in b/examples/Makefile.in new file mode 100644 index 0000000..f37e22d --- /dev/null +++ b/examples/Makefile.in @@ -0,0 +1,89 @@ +DOXYDIR = ../bin + +all: class/html/index.html \ + define/html/index.html \ + enum/html/index.html \ + file/html/index.html \ + func/html/index.html \ + page/html/index.html \ + relates/html/index.html \ + author/html/index.html \ + par/html/index.html \ + overload/html/index.html \ + example/html/index.html \ + include/html/index.html \ + qtstyle/html/index.html \ + jdstyle/html/index.html \ + structcmd/html/index.html \ + autolink/html/index.html \ + restypedef/html/index.html \ + afterdoc/html/index.html \ + template/html/index.html \ + tag/html/index.html + +clean: + rm -rf class define enum file func page relates author \ + par overload example include qtstyle jdstyle structcmd \ + autolink tag 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 + +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.win.in b/examples/Makefile.win.in new file mode 100644 index 0000000..0b77836 --- /dev/null +++ b/examples/Makefile.win.in @@ -0,0 +1,89 @@ +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 \ + 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 ..\.. + +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/Makefile.windows b/examples/Makefile.windows deleted file mode 100644 index da7cd09..0000000 --- a/examples/Makefile.windows +++ /dev/null @@ -1,93 +0,0 @@ -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/make.bat b/make.bat index a8a2f4e..3105d14 100644 --- a/make.bat +++ b/make.bat @@ -1,4 +1,14 @@ REM make script for Microsoft Visual C++ -set TMAKEPATH=..\tmake\lib\win32-msvc -nmake /NOLOGO -f Makefile.windows win32-msvc +REM use perl to create the config file +perl wintools\make.pl + +type makeconfig Makefile.win.in >Makefile +type makeconfig src\Makefile.in >src\Makefile +type makeconfig examples\Makefile.win.in >examples\Makefile +type makeconfig doc\Makefile.win.in >doc\Makefile +copy src\doxygen.pro.in src\doxygen.pro +copy src\doxytag.pro.in src\doxytag.pro +copy src\doxysearch.pro.in src\doxysearch.pro + +nmake diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index 9812d37..0000000 --- a/src/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -# -# $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 - -FORCE: diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..66ff412 --- /dev/null +++ b/src/Makefile.in @@ -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. +# + +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) 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 + +FORCE: diff --git a/src/classdef.cpp b/src/classdef.cpp index 005a397..5d7c980 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -28,6 +28,7 @@ #include "util.h" #include "diagram.h" #include "language.h" +#include "htmlhelp.h" static QCString stripExtension(const char *fName) { @@ -66,7 +67,7 @@ ClassDef::ClassDef(const char *nm,CompoundType ct,const char *ref,const char *fN allMemberNameInfoList->setAutoDelete(TRUE); allMemberNameInfoDict = new MemberNameInfoDict(1009); visited=FALSE; - reference=ref; + setReference(ref); compType=ct; incFile=0; tempArgs=0; @@ -103,7 +104,7 @@ void ClassDef::insertSuperClass(ClassDef *cd,Protection p, void ClassDef::insertMember(const MemberDef *md) { //printf("adding %s::%s\n",name(),md->name()); - if (!reference) + if (!isReference()) { if (md->isRelated() && (Config::extractPrivateFlag || md->protection()!=Private)) { @@ -224,10 +225,10 @@ void ClassDef::writeDocumentation(OutputList &ol) QCString pageType; switch(compType) { - case Class: pageType=" Class"; break; - case Struct: pageType=" Struct"; break; - case Union: pageType=" Union"; break; - default: pageType+=compType; break; // an error + case Class: pageType=" Class"; break; + case Struct: pageType=" Struct"; break; + case Union: pageType=" Union"; break; + default: pageType=" Interface"; break; } pageTitle+=pageType+" Reference"; startFile(ol,fileName,pageTitle); @@ -302,7 +303,7 @@ void ClassDef::writeDocumentation(OutputList &ol) if (ok && bcd) { ClassDef *cd=bcd->classDef; - if (cd->hasDocumentation() || cd->isReference()) + if (cd->isLinkable()) { if (Config::genTagFile.length()>0) tagFile << cd->getOutputFileBase() << "?"; ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->name()+bcd->templSpecifiers); @@ -340,7 +341,7 @@ void ClassDef::writeDocumentation(OutputList &ol) if (ok && bcd) { ClassDef *cd=bcd->classDef; - if (cd->hasDocumentation() || cd->isReference()) + if (cd->isLinkable()) { ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->name()); } @@ -364,14 +365,14 @@ void ClassDef::writeDocumentation(OutputList &ol) while (ibcd) { ClassDef *icd=ibcd->classDef; - if ( icd->isVisibleExt()) count++; + if ( icd->isVisibleInHierarchy()) count++; ibcd=inheritedBy->next(); } ibcd=inherits->first(); while (ibcd) { ClassDef *icd=ibcd->classDef; - if ( icd->isVisibleExt()) count++; + if ( icd->isVisibleInHierarchy()) count++; ibcd=inherits->next(); } if (Config::classDiagramFlag && count>0) @@ -386,7 +387,7 @@ void ClassDef::writeDocumentation(OutputList &ol) } // write link to list of all members (HTML only) - if (allMemberNameInfoList->count()>0 && compType==Class) + if (allMemberNameInfoList->count()>0 /*&& compType==Class*/) { ol.disableAllBut(OutputGenerator::Html); ol.startTextLink(memListFileName,0); @@ -397,24 +398,23 @@ void ClassDef::writeDocumentation(OutputList &ol) // write member groups ol.startMemberSections(); - writeMemberDecs(ol,this,0,0,theTranslator->trPublicMembers(),0,&pubMembers); - writeMemberDecs(ol,this,0,0,theTranslator->trPublicSlots(),0,&pubSlots); - writeMemberDecs(ol,this,0,0,theTranslator->trSignals(),0,&signals); - writeMemberDecs(ol,this,0,0,theTranslator->trStaticPublicMembers(),0,&pubStaticMembers); - writeMemberDecs(ol,this,0,0,theTranslator->trProtectedMembers(),0,&proMembers); - writeMemberDecs(ol,this,0,0,theTranslator->trProtectedSlots(),0,&proSlots); - writeMemberDecs(ol,this,0,0,theTranslator->trStaticProtectedMembers(),0,&proStaticMembers); + pubMembers.writeDeclarations(ol,this,0,0,theTranslator->trPublicMembers(),0); + pubSlots.writeDeclarations(ol,this,0,0,theTranslator->trPublicSlots(),0); + signals.writeDeclarations(ol,this,0,0,theTranslator->trSignals(),0); + pubStaticMembers.writeDeclarations(ol,this,0,0,theTranslator->trStaticPublicMembers(),0); + proMembers.writeDeclarations(ol,this,0,0,theTranslator->trProtectedMembers(),0); + proSlots.writeDeclarations(ol,this,0,0,theTranslator->trProtectedSlots(),0); + proStaticMembers.writeDeclarations(ol,this,0,0,theTranslator->trStaticProtectedMembers(),0); if (Config::extractPrivateFlag) { - writeMemberDecs(ol,this,0,0,theTranslator->trPrivateMembers(),0,&priMembers); - writeMemberDecs(ol,this,0,0,theTranslator->trPrivateSlots(),0,&priSlots); - writeMemberDecs(ol,this,0,0,theTranslator->trStaticPrivateMembers(),0,&priStaticMembers); + priMembers.writeDeclarations(ol,this,0,0,theTranslator->trPrivateMembers(),0); + priSlots.writeDeclarations(ol,this,0,0,theTranslator->trPrivateSlots(),0); + priStaticMembers.writeDeclarations(ol,this,0,0,theTranslator->trStaticPrivateMembers(),0); } - writeMemberDecs(ol,this,0,0,theTranslator->trFriends(),0,&friends); - writeMemberDecs(ol,this,0,0, + friends.writeDeclarations(ol,this,0,0,theTranslator->trFriends(),0); + related.writeDeclarations(ol,this,0,0, theTranslator->trRelatedFunctions(), - theTranslator->trRelatedSubscript(), - &related + theTranslator->trRelatedSubscript() ); ol.endMemberSections(); @@ -519,11 +519,11 @@ void ClassDef::writeDocumentation(OutputList &ol) parseText(ol,theTranslator->trMemberTypedefDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,&pubMembers,name(),MemberDef::Typedef); - writeMemberDocs(ol,&proMembers,name(),MemberDef::Typedef); + pubMembers.writeDocumentation(ol,name(),MemberDef::Typedef); + proMembers.writeDocumentation(ol,name(),MemberDef::Typedef); if (Config::extractPrivateFlag) { - writeMemberDocs(ol,&priMembers,name(),MemberDef::Typedef); + priMembers.writeDocumentation(ol,name(),MemberDef::Typedef); } } @@ -537,11 +537,11 @@ void ClassDef::writeDocumentation(OutputList &ol) parseText(ol,theTranslator->trMemberEnumerationDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,&pubMembers,name(),MemberDef::Enumeration); - writeMemberDocs(ol,&proMembers,name(),MemberDef::Enumeration); + pubMembers.writeDocumentation(ol,name(),MemberDef::Enumeration); + proMembers.writeDocumentation(ol,name(),MemberDef::Enumeration); if (Config::extractPrivateFlag) { - writeMemberDocs(ol,&priMembers,name(),MemberDef::Enumeration); + priMembers.writeDocumentation(ol,name(),MemberDef::Enumeration); } } @@ -555,41 +555,48 @@ void ClassDef::writeDocumentation(OutputList &ol) parseText(ol,theTranslator->trEnumerationValueDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,&pubMembers,name(),MemberDef::EnumValue); - writeMemberDocs(ol,&proMembers,name(),MemberDef::EnumValue); + pubMembers.writeDocumentation(ol,name(),MemberDef::EnumValue); + proMembers.writeDocumentation(ol,name(),MemberDef::EnumValue); if (Config::extractPrivateFlag) { - writeMemberDocs(ol,&priMembers,name(),MemberDef::EnumValue); + priMembers.writeDocumentation(ol,name(),MemberDef::EnumValue); } } - if ( pubMembers.funcCount() + pubSlots.funcCount() + + int func_count=0; + if ( + ( + func_count = + pubMembers.funcCount() + pubSlots.funcCount() + pubStaticMembers.funcCount() + proMembers.funcCount() + proSlots.funcCount() + proStaticMembers.funcCount() + (Config::extractPrivateFlag ? priMembers.funcCount() + priSlots.funcCount() + priStaticMembers.funcCount() : 0 - ) + ) + ) ) { ol.writeRuler(); ol.startGroupHeader(); - parseText(ol,theTranslator->trMemberFunctionDocumentation()); + QCString countStr; + //countStr.sprintf(" (%d)",func_count); + parseText(ol,theTranslator->trMemberFunctionDocumentation()+countStr); 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); + pubMembers.writeDocumentation(ol,name(),MemberDef::Function); + pubSlots.writeDocumentation(ol,name(),MemberDef::Slot); + signals.writeDocumentation(ol,name(),MemberDef::Signal); + pubStaticMembers.writeDocumentation(ol,name(),MemberDef::Function); + proMembers.writeDocumentation(ol,name(),MemberDef::Function); + proSlots.writeDocumentation(ol,name(),MemberDef::Slot); + proStaticMembers.writeDocumentation(ol,name(),MemberDef::Function); if (Config::extractPrivateFlag) { - writeMemberDocs(ol,&priMembers,name(),MemberDef::Function); - writeMemberDocs(ol,&priSlots,name(),MemberDef::Slot); - writeMemberDocs(ol,&priStaticMembers,name(),MemberDef::Function); + priMembers.writeDocumentation(ol,name(),MemberDef::Function); + priSlots.writeDocumentation(ol,name(),MemberDef::Slot); + priStaticMembers.writeDocumentation(ol,name(),MemberDef::Function); } } @@ -599,8 +606,8 @@ void ClassDef::writeDocumentation(OutputList &ol) ol.startGroupHeader(); parseText(ol,theTranslator->trRelatedFunctionDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,&friends,name(),MemberDef::Friend); - writeMemberDocs(ol,&related,name(),MemberDef::Function); + friends.writeDocumentation(ol,name(),MemberDef::Friend); + related.writeDocumentation(ol,name(),MemberDef::Function); } @@ -616,22 +623,21 @@ void ClassDef::writeDocumentation(OutputList &ol) parseText(ol,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); + pubMembers.writeDocumentation(ol,name(),MemberDef::Variable); + pubStaticMembers.writeDocumentation(ol,name(),MemberDef::Variable); + proMembers.writeDocumentation(ol,name(),MemberDef::Variable); + proStaticMembers.writeDocumentation(ol,name(),MemberDef::Variable); if (Config::extractPrivateFlag) { - writeMemberDocs(ol,&priMembers,name(),MemberDef::Variable); - writeMemberDocs(ol,&priStaticMembers,name(),MemberDef::Variable); + priMembers.writeDocumentation(ol,name(),MemberDef::Variable); + priStaticMembers.writeDocumentation(ol,name(),MemberDef::Variable); } } // write the list of used files (Html and LaTeX only) ol.disable(OutputGenerator::Man); ol.writeRuler(); - parseText(ol,theTranslator->trGeneratedFrom(pageType.lower(), - files.count()==1)); + parseText(ol,theTranslator->trGeneratedFromFiles(compType,files.count()==1)); bool first=TRUE; const char *file = files.first(); @@ -651,15 +657,10 @@ void ClassDef::writeDocumentation(OutputList &ol) QCString path=fd->getPath().copy(); if (Config::fullPathNameFlag) { - // strip part of the path - if (path.left(Config::stripFromPath.length())==Config::stripFromPath) - { - path=path.right(path.length()-Config::stripFromPath.length()); - } - ol.docify(path); + ol.docify(stripFromPath(path)); } - if (fd->hasDocumentation()) + if (fd->isLinkable()) { ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0, fd->name()); @@ -697,7 +698,7 @@ void ClassDef::writeMemberList(OutputList &ol) parseText(ol,name()+" "+theTranslator->trMemberList()); endTitle(ol,0); parseText(ol,theTranslator->trThisIsTheListOfAllMembers()); - ol.writeObjectLink(reference,fileName,0,name()); + ol.writeObjectLink(getReference(),fileName,0,name()); parseText(ol,theTranslator->trIncludingInheritedMembers()); ol.startItemList(); @@ -738,7 +739,7 @@ void ClassDef::writeMemberList(OutputList &ol) ) { bool memberWritten=FALSE; - if (cd->isVisible() && (md->hasDocumentation() || md->isReference())) + if (cd->isLinkable() && md->isLinkable()) // create a link to the documentation { QCString name=mi->ambiguityResolutionScope+md->name(); @@ -773,7 +774,7 @@ void ClassDef::writeMemberList(OutputList &ol) ol.docify(" typedef"); ol.writeString(" ("); parseText(ol,theTranslator->trDefinedIn()+" "); - if (cd->isVisible()) + if (cd->isLinkable()) { ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->name()); } @@ -927,33 +928,33 @@ void ClassDef::setTemplateArguments(ArgumentList *al) } } -QCString ClassDef::getTemplateNameString() -{ - QCString 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; -} +//QCString ClassDef::getTemplateNameString() +//{ +// QCString 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() { @@ -963,3 +964,59 @@ bool ClassDef::hasNonReferenceSuperClass() found=found || bcli.current()->classDef->hasNonReferenceSuperClass(); return found; } + +//void ClassDef::writeMembersToContents() +//{ +// HtmlHelp *htmlHelp = HtmlHelp::getInstance(); +// +// htmlHelp->incContentsDepth(); +// +// MemberNameInfoListIterator mnili(*allMemberNameInfoList); +// MemberNameInfo *mni; +// for (;(mni=mnili.current());++mnili) +// { +// MemberNameInfoIterator mnii(*mni); +// MemberInfo *mi; +// for (mnii.toLast();(mi=mnii.current());--mnii) +// { +// MemberDef *md=mi->memberDef; +// ClassDef *cd=md->memberClass(); +// if (md->isLinkable() && cd==this) // member is not inherited +// { +// htmlHelp->addContentsItem(md->name()+md->argsString(), +// cd->getOutputFileBase(), +// md->anchor()); +// } +// } +// } +// htmlHelp->decContentsDepth(); +//} + +void ClassDef::writeDeclaration(OutputList &ol) +{ + //ol.insertMemberAlign(); + switch(compType) + { + case Class: ol.docify("class {"); break; + case Struct: ol.docify("struct {"); break; + default: ol.docify("union {"); break; + } + ol.endMemberItem(FALSE,0,0,FALSE); // TODO: pass correct group parameters + + // insert members of this class + pubMembers.writePlainDeclarations(ol,this,0,0); + pubSlots.writePlainDeclarations(ol,this,0,0); + signals.writePlainDeclarations(ol,this,0,0); + pubStaticMembers.writePlainDeclarations(ol,this,0,0); + proMembers.writePlainDeclarations(ol,this,0,0); + proSlots.writePlainDeclarations(ol,this,0,0); + proStaticMembers.writePlainDeclarations(ol,this,0,0); + if (Config::extractPrivateFlag) + { + priMembers.writePlainDeclarations(ol,this,0,0); + priSlots.writePlainDeclarations(ol,this,0,0); + priStaticMembers.writePlainDeclarations(ol,this,0,0); + } + friends.writePlainDeclarations(ol,this,0,0); + related.writePlainDeclarations(ol,this,0,0); +} diff --git a/src/classdef.h b/src/classdef.h index dd24b69..ed2aa9d 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -46,7 +46,8 @@ class ClassDef : public Definition enum CompoundType { Class=Entry::CLASS_SEC, Struct=Entry::STRUCT_SEC, - Union=Entry::UNION_SEC + Union=Entry::UNION_SEC, + Interface=Entry::INTERFACE_SEC }; ClassDef(const char *name,CompoundType ct,const char *ref=0,const char *fName=0); @@ -54,7 +55,7 @@ class ClassDef : public Definition //QCString classFile() const { return fileName; } QCString getOutputFileBase() const { return fileName; } CompoundType compoundType() const { return compType; } - const char *memberListFileName() const { return memListFileName; } + //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); @@ -64,8 +65,8 @@ class ClassDef : public Definition 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; } + //bool isReference() { return !reference.isNull(); } + //const char *getReference() const { return reference; } void insertMember(const MemberDef *); void insertUsedFile(const char *); void computeAnchors(); @@ -74,29 +75,45 @@ class ClassDef : public Definition void writeDocumentation(OutputList &ol); void writeMemberList(OutputList &ol); void writeIncludeFile(OutputList &ol); + //void writeMembersToContents(); + void writeDeclaration(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 || Config::extractPrivateFlag) && - hasDocumentation(); - } + /*! a link to this class is possible within this project */ + bool isLinkableInProject() + { int i = name().findRev("::"); + if (i==-1) i=0; else i+=2; + return !name().isEmpty() && name().at(i)!='@' && + (prot!=Private || Config::extractPrivateFlag) && + hasDocumentation() && !isReference(); + } + /*! a link to this class is possible (either within this project, + * or as a cross-reference to another project + */ + bool isLinkable() + { + return isLinkableInProject() || isReference(); + } bool hasNonReferenceSuperClass(); - bool isVisibleExt() - { return (Config::allExtFlag || hasNonReferenceSuperClass()) && - !name().isEmpty() && name().at(0)!='@' && - (prot!=Private || Config::extractPrivateFlag) && - (hasDocumentation() || !Config::hideClassFlag || - !reference.isNull()); - } + /*! the class is visible in a class diagram, or class hierarchy */ + bool isVisibleInHierarchy() + { return // show all classes or a superclass is visible + (Config::allExtFlag || hasNonReferenceSuperClass()) && + // and not an annonymous compound + name().find('@')==-1 && + // and not privately inherited + (prot!=Private || Config::extractPrivateFlag) && + // documented or show anyway or documentation is external + (hasDocumentation() || !Config::hideClassFlag || isReference()); + } // template argument functions ArgumentList *templateArguments() const { return tempArgs; } void setTemplateArguments(ArgumentList *al); - QCString getTemplateNameString(); + //QCString getTemplateNameString(); void setNamespace(NamespaceDef *nd) { nspace = nd; } NamespaceDef *getNamespace() { return nspace; } @@ -129,7 +146,7 @@ class ClassDef : public Definition MemberNameInfoDict *allMemberNameInfoDict; ArgumentList *tempArgs; QStrList files; - QCString reference; + //QCString reference; ExampleList *exampleList; ExampleDict *exampleDict; CompoundType compType; diff --git a/src/code.l b/src/code.l index beafeca..962b328 100644 --- a/src/code.l +++ b/src/code.l @@ -167,7 +167,7 @@ static void generateClassLink(OutputList &ol,const char *clName) QCString className=clName; if (className.length()==0) return; ClassDef *cd; - if ((cd=getClass(className)) && cd->isVisible()) + if ((cd=getClass(className)) && cd->isLinkable()) { if (exampleBlock) { @@ -202,8 +202,7 @@ static bool getLink(const char *className, QCString m=memberName; QCString c=className; //printf("Trying `%s'::`%s'\n",c.data(),m.data()); - if (getDefs(c,m,"()",md,cd,fd,nd) && - (md->hasDocumentation() || md->isReference())) + if (getDefs(c,m,"()",md,cd,fd,nd) && md->isLinkable()) { //printf("Found!\n"); if (exampleBlock) @@ -218,24 +217,35 @@ static bool getLink(const char *className, anchorCount++; } } - if (cd) - { - result.writeCodeLink(cd->getReference(),cd->getOutputFileBase(), - md->anchor(),memberName); - return TRUE; - } - else if (nd) - { - result.writeCodeLink(nd->getReference(),nd->getOutputFileBase(), - md->anchor(),memberName); - return TRUE; - } - else if (fd) + Definition *d=0; + if (cd) d=cd; else if (cd) d=nd; else d=fd; + + if (d) { - result.writeCodeLink(fd->getReference(),fd->getOutputFileBase(), - md->anchor(),memberName); + result.writeCodeLink(d->getReference(),d->getOutputFileBase(), + md->anchor(),memberName); return TRUE; - } + + } + +// if (cd) +// { +// result.writeCodeLink(cd->getReference(),cd->getOutputFileBase(), +// md->anchor(),memberName); +// return TRUE; +// } +// else if (nd) +// { +// result.writeCodeLink(nd->getReference(),nd->getOutputFileBase(), +// md->anchor(),memberName); +// return TRUE; +// } +// else if (fd) +// { +// result.writeCodeLink(fd->getReference(),fd->getOutputFileBase(), +// md->anchor(),memberName); +// return TRUE; +// } } return FALSE; @@ -372,7 +382,7 @@ ID [a-z_A-Z][a-z_A-Z0-9]* bool ambig; FileDef *fd; if ((fd=findFileDef(&inputNameDict,yytext,ambig)) && - fd->hasDocumentation()) + fd->isLinkable()) { code->writeCodeLink(0,fd->getOutputFileBase(),0,yytext); } diff --git a/src/config.h b/src/config.h index d2bec11..9d04582 100644 --- a/src/config.h +++ b/src/config.h @@ -49,7 +49,6 @@ struct Config static QCString genTagFile; // the tag file to generate static QCString inputFilter; // a filter command that is applied to input files static QCString paperType; // the page type to generate docs for - static QCString stripFromPath; // the string to strip from the file path static QCString manExtension; // extension the man page files static QStrList includePath; // list of include paths static QStrList examplePath; // list of example paths @@ -61,6 +60,7 @@ struct Config static QStrList extDocPathList; // list of external doc. directories. static QStrList predefined; // list of predefined macro names. static QStrList extraPackageList; // list of extra LaTeX packages. + static QStrList stripFromPath; // list of candidates to strip from the file path static bool quietFlag; // generate progress messages flag static bool warningFlag; // generate warnings flag static bool recursiveFlag; // scan directories recursively @@ -89,6 +89,8 @@ struct Config static bool htmlAlignMemberFlag; // align members in HTML using tables. static bool includeSourceFlag; // include source code in documentation. static bool autoBriefFlag; // javadoc comments behaves as Qt comments. + static bool htmlHelpFlag; // should html help files be generated? + static bool alphaIndexFlag; // should an alphabetical index be generated? }; #endif diff --git a/src/config.l b/src/config.l index 57897e9..515de4d 100644 --- a/src/config.l +++ b/src/config.l @@ -81,7 +81,6 @@ QCString Config::perlPath; QCString Config::genTagFile; QCString Config::inputFilter; QCString Config::paperType; -QCString Config::stripFromPath; QCString Config::manExtension; QStrList Config::includePath; QStrList Config::examplePath; @@ -93,6 +92,7 @@ QStrList Config::tagFileList; QStrList Config::extDocPathList; QStrList Config::predefined; QStrList Config::extraPackageList; +QStrList Config::stripFromPath; bool Config::quietFlag = FALSE; bool Config::recursiveFlag = FALSE; bool Config::allExtFlag = FALSE; @@ -109,6 +109,8 @@ bool Config::compactLatexFlag = FALSE; bool Config::internalDocsFlag = FALSE; bool Config::caseSensitiveNames = FALSE; bool Config::includeSourceFlag = FALSE; +bool Config::htmlHelpFlag = FALSE; +bool Config::alphaIndexFlag = FALSE; bool Config::autoBriefFlag = TRUE; bool Config::warningFlag = TRUE; bool Config::generateHtml = TRUE; @@ -188,7 +190,6 @@ static int yyread(char *buf,int max_size) "INPUT_FILTER"[ \t]*"=" { BEGIN(GetString); s=&Config::inputFilter; } "PAPER_TYPE"[ \t]*"=" { BEGIN(GetString); s=&Config::paperType; } "OUTPUT_LANGUAGE"[ \t]*"=" { BEGIN(GetString); s=&Config::outputLanguage; } -"STRIP_FROM_PATH"[ \t]*"=" { BEGIN(GetString); s=&Config::stripFromPath; } "MAN_EXTENSION"[ \t]*"=" { BEGIN(GetString); s=&Config::manExtension; } "INCLUDE_PATH"[ \t]*"=" { BEGIN(GetStrList); l=&Config::includePath; elemStr=""; } "EXAMPLE_PATH"[ \t]*"=" { BEGIN(GetStrList); l=&Config::examplePath; elemStr=""; } @@ -200,6 +201,7 @@ static int yyread(char *buf,int max_size) "EXT_DOC_PATHS"[ \t]*"=" { BEGIN(GetStrList); l=&Config::extDocPathList; elemStr=""; } "PREDEFINED"[ \t]*"=" { BEGIN(GetStrList); l=&Config::predefined; elemStr=""; } "EXTRA_PACKAGES"[ \t]*"=" { BEGIN(GetStrList); l=&Config::extraPackageList; elemStr=""; } +"STRIP_FROM_PATH"[ \t]*"=" { BEGIN(GetStrList); l=&Config::stripFromPath; elemStr=""; } "QUIET"[ \t]*"=" { BEGIN(GetBool); b=&Config::quietFlag; } "WARNINGS"[ \t]*"=" { BEGIN(GetBool); b=&Config::warningFlag; } "RECURSIVE"[ \t]*"=" { BEGIN(GetBool); b=&Config::recursiveFlag; } @@ -228,6 +230,8 @@ static int yyread(char *buf,int max_size) "HTML_ALIGN_MEMBERS"[ \t]*"=" { BEGIN(GetBool); b=&Config::htmlAlignMemberFlag; } "SOURCE_BROWSER"[ \t]*"=" { BEGIN(GetBool); b=&Config::includeSourceFlag; } "JAVADOC_AUTOBRIEF"[ \t]*"=" { BEGIN(GetBool); b=&Config::autoBriefFlag; } +"GENERATE_HTMLHELP"[ \t]*"=" { BEGIN(GetBool); b=&Config::htmlHelpFlag; } +"ALPHABETICAL_INDEX"[ \t]*"=" { BEGIN(GetBool); b=&Config::alphaIndexFlag; } [a-z_A-Z0-9]+ { err("Warning: ignoring unknown tag `%s' at line %d\n",yytext,yyLineNr); } \n { yyLineNr++; BEGIN(Start); } \n { @@ -381,7 +385,6 @@ void Config::init() Config::genTagFile.resize(0); Config::inputFilter.resize(0); Config::paperType = "a4wide"; - Config::stripFromPath.resize(0); Config::manExtension = ".3"; Config::includePath.clear(); Config::examplePath.clear(); @@ -393,6 +396,7 @@ void Config::init() Config::extDocPathList.clear(); Config::predefined.clear(); Config::extraPackageList.clear(); + Config::stripFromPath.clear(); Config::quietFlag = FALSE; Config::recursiveFlag = FALSE; Config::allExtFlag = FALSE; @@ -409,6 +413,8 @@ void Config::init() Config::internalDocsFlag = FALSE; Config::caseSensitiveNames = FALSE; Config::includeSourceFlag = FALSE; + Config::htmlHelpFlag = FALSE; + Config::alphaIndexFlag = FALSE; Config::warningFlag = TRUE; Config::generateHtml = TRUE; Config::generateLatex = TRUE; @@ -429,7 +435,7 @@ void writeTemplateConfig(QFile *f,bool sl) #ifdef DOXYWIZARD t << "# Doxygen configuration generated by Doxywizard version " << versionString << endl; #else - t << "# Doxyfile " << versionString << endl; + t << "# Doxyfile " << versionString << endl << endl; #endif if (!sl) { @@ -440,9 +446,12 @@ void writeTemplateConfig(QFile *f,bool sl) 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 << "# General configuration options\n"; + t << "#---------------------------------------------------------------------------\n"; + if (!sl) + { 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"; @@ -581,7 +590,8 @@ void writeTemplateConfig(QFile *f,bool 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 << "# only done if one of the specified strings matches the left-hand part of\n"; + t << "# the path.\n"; t << "\n"; } t << "STRIP_FROM_PATH =\n"; @@ -597,20 +607,20 @@ void writeTemplateConfig(QFile *f,bool sl) 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 << "# If the SOURCE_BROWSER tag is set to YES than the body of a member or\n"; + t << "# function will be appended as a block of code to the documentation of.\n"; + t << "# that member or function.\n"; t << "\n"; } t << "SOURCE_BROWSER = NO\n"; if (!sl) { t << "\n"; - t << "# If the SOURCE_BROWSER tag is set to YES than the body of a member or\n"; - t << "# function will be appended as a block of code to the documentation of.\n"; - t << "# that member or function.\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"; @@ -636,9 +646,12 @@ void writeTemplateConfig(QFile *f,bool sl) if (!sl) { t << "\n"; - t << "#---------------------------------------------------------------------------\n"; - t << "# configuration options related to the input files\n"; - t << "#---------------------------------------------------------------------------\n"; + } + t << "#---------------------------------------------------------------------------\n"; + t << "# configuration options related to the input files\n"; + t << "#---------------------------------------------------------------------------\n"; + if (!sl) + { 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"; @@ -708,9 +721,12 @@ void writeTemplateConfig(QFile *f,bool sl) if (!sl) { t << "\n"; - t << "#---------------------------------------------------------------------------\n"; - t << "# configuration options related to the HTML output\n"; - t << "#---------------------------------------------------------------------------\n"; + } + t << "#---------------------------------------------------------------------------\n"; + t << "# configuration options related to the HTML output\n"; + t << "#---------------------------------------------------------------------------\n"; + if (!sl) + { t << "\n"; t << "# If the GENERATE_HTML tag is set to YES (the default) Doxygen will\n"; t << "# generate HTML output\n"; @@ -756,9 +772,31 @@ void writeTemplateConfig(QFile *f,bool sl) if (!sl) { t << "\n"; - t << "#---------------------------------------------------------------------------\n"; - t << "# configuration options related to the LaTeX output\n"; - t << "#---------------------------------------------------------------------------\n"; + t << "# If the GENERATE_HTMLHELP tag is set to YES, additional index files\n"; + t << "# will be generated that can be used as input for tools like the\n"; + t << "# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)\n"; + t << "# of the generated HTML documentation.\n"; + t << "\n"; + } + t << "GENERATE_HTMLHELP = NO\n"; + if (!sl) + { + t << "\n"; + t << "# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index\n"; + t << "# of all compounds will be generated. Enable this if the project\n"; + t << "# contains a lot of classes, structs, unions or interfaces.\n"; + t << "\n"; + } + t << "ALPHABETICAL_INDEX = NO\n"; + if (!sl) + { + t << "\n"; + } + t << "#---------------------------------------------------------------------------\n"; + t << "# configuration options related to the LaTeX output\n"; + t << "#---------------------------------------------------------------------------\n"; + if (!sl) + { t << "\n"; t << "# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will\n"; t << "# generate Latex output.\n"; @@ -803,9 +841,12 @@ void writeTemplateConfig(QFile *f,bool sl) if (!sl) { t << "\n"; - t << "#---------------------------------------------------------------------------\n"; - t << "# configuration options related to the man page output\n"; - t << "#---------------------------------------------------------------------------\n"; + } + t << "#---------------------------------------------------------------------------\n"; + t << "# configuration options related to the man page output\n"; + t << "#---------------------------------------------------------------------------\n"; + if (!sl) + { t << "\n"; t << "# If the GENERATE_MAN tag is set to YES (the default) Doxygen will\n"; t << "# generate man pages\n"; @@ -833,9 +874,12 @@ void writeTemplateConfig(QFile *f,bool sl) if (!sl) { t << "\n"; - t << "#---------------------------------------------------------------------------\n"; - t << "# Configuration options related to the preprocessor \n"; - t << "#---------------------------------------------------------------------------\n"; + } + t << "#---------------------------------------------------------------------------\n"; + t << "# Configuration options related to the preprocessor \n"; + t << "#---------------------------------------------------------------------------\n"; + if (!sl) + { 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"; @@ -892,9 +936,12 @@ void writeTemplateConfig(QFile *f,bool sl) if (!sl) { t << "\n"; - t << "#---------------------------------------------------------------------------\n"; - t << "# Configuration options related to external references \n"; - t << "#---------------------------------------------------------------------------\n"; + } + t << "#---------------------------------------------------------------------------\n"; + t << "# Configuration options related to external references \n"; + t << "#---------------------------------------------------------------------------\n"; + if (!sl) + { t << "\n"; t << "# The TAGFILES tag can be used to specify one or more tagfiles. \n"; t << "\n"; @@ -928,9 +975,12 @@ void writeTemplateConfig(QFile *f,bool sl) if (!sl) { t << "\n"; - t << "#---------------------------------------------------------------------------\n"; - t << "# Configuration options related to the search engine \n"; - t << "#---------------------------------------------------------------------------\n"; + } + t << "#---------------------------------------------------------------------------\n"; + t << "# Configuration options related to the search engine \n"; + t << "#---------------------------------------------------------------------------\n"; + if (!sl) + { 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"; diff --git a/src/declinfo.l b/src/declinfo.l index dfa3e47..3737a67 100644 --- a/src/declinfo.l +++ b/src/declinfo.l @@ -223,15 +223,17 @@ void parseFuncDecl(const QCString &decl,QCString &cl,QCString &ctl,QCString &t, declinfoYYlex(); cl=scope.copy(); + //printf("scope=`%s'\n",scope.data()); int il,ir; if ((il=cl.find('<'))!=-1 && (ir=cl.findRev('>'))!=-1) // split up scope and template arguments { - if (ir==-1) ir=cl.length(); else ir++; - ctl=removeRedundantWhiteSpace(cl.mid(il,ir-il)); - cl=cl.left(il)+cl.right(cl.length()-ir); + ctl=removeRedundantWhiteSpace(cl.mid(il,ir-il+1)); + cl=cl.left(il)+cl.right(cl.length()-ir-1); } + //printf("cl=`%s' ctl=`%s'\n",cl.data(),ctl.data()); n=removeRedundantWhiteSpace(name); - if ((il=n.find('<'))!=-1 && n.left(8)!="operator") + if ((il=n.find('<'))!=-1 && (ir=n.findRev('>'))!=-1) + // TODO: handle cases like where n="operator<< " { ftl=removeRedundantWhiteSpace(n.right(n.length()-il)); n=n.left(il); diff --git a/src/defargs.l b/src/defargs.l index d82c2fe..f214404 100644 --- a/src/defargs.l +++ b/src/defargs.l @@ -45,6 +45,7 @@ static QCString *copyArgValue; static QCString curArgTypeName; static QCString curArgDefValue; static QCString curArgName; +static QCString curArgAttrib; static int argRoundCount; static int argSharpCount; static int argCurlyCount; @@ -94,6 +95,12 @@ ID [a-z_A-Z][a-z_A-Z0-9]* {B}* { curArgTypeName+=" "; } +"["[^\]]*"]" { + if (curArgTypeName.stripWhiteSpace().isEmpty()) + curArgAttrib=yytext; + else + curArgTypeName+=yytext; + } "'"\\[0-7]{1,3}"'" { curArgDefValue+=yytext; } "'"\\."'" { curArgDefValue+=yytext; } "'"."'" { curArgDefValue+=yytext; } @@ -216,6 +223,7 @@ ID [a-z_A-Z][a-z_A-Z0-9]* ) ) i--; Argument *a = new Argument; + a->attrib = curArgAttrib.copy(); if (i>=0 && curArgTypeName.at(i)!=':') { // type contains a name a->type = curArgTypeName.left(i+1).stripWhiteSpace(); @@ -229,6 +237,7 @@ ID [a-z_A-Z][a-z_A-Z0-9]* //printf("----> Adding argument `%s' `%s' `%s'\n",a->type.data(),a->name.data(),a->defval.data()); argList->append(a); } + curArgAttrib.resize(0); curArgTypeName.resize(0); curArgDefValue.resize(0); if (*yytext==')') diff --git a/src/define.cpp b/src/define.cpp index 336d6da..343ac00 100644 --- a/src/define.cpp +++ b/src/define.cpp @@ -21,6 +21,8 @@ Define::Define() { undef=FALSE; fileDef=0; + isPredefined=FALSE; + nonRecursive=FALSE; } Define::Define(const Define &d) diff --git a/src/define.h b/src/define.h index 92027af..8577b55 100644 --- a/src/define.h +++ b/src/define.h @@ -42,6 +42,8 @@ class Define int nargs; bool undef; bool varArgs; + bool isPredefined; + bool nonRecursive; }; class DefineList : public QList diff --git a/src/definition.h b/src/definition.h index 282ecdc..40e8316 100644 --- a/src/definition.h +++ b/src/definition.h @@ -26,44 +26,72 @@ class Definition { public: - //! create a new definition + /*! create a new definition */ Definition(const char *name,const char *b=0,const char *d=0); - //! destroys the definition + /*! destroys the definition */ virtual ~Definition(); - //! returns the name of the definition + /*! returns the name of the definition */ QCString name() const { return n; } - //! returns the base name of the output file that contains this definition. + /*! returns the base name of the output file that contains this + * definition. + */ virtual QCString getOutputFileBase() const = 0; - //! returns the detailed description of this definition + /*! returns the detailed description of this definition */ QCString documentation() const { return doc; } - //! returns the brief description of this definition + /*! returns the brief description of this definition */ QCString briefDescription() const { return brief; } - //! sets a new name for the definition + /*! sets a new \a name for the definition */ void setName(const char *name) { n=name; } - //! sets the documentation of this definition + /*! sets the documentation of this definition to \a d. */ void setDocumentation(const char *d) { - doc=d; doc=doc.stripWhiteSpace(); + doc=((QCString)d).stripWhiteSpace(); } - //! sets the brief description of this definition + /*! sets the brief description of this definition to \a b. + * A dot is added to the sentence if not available. + */ void setBriefDescription(const char *b) { - brief=b; brief=brief.stripWhiteSpace(); + brief=((QCString) b).stripWhiteSpace(); int bl=brief.length(); - if (bl>0 && brief.at(bl-1)!='.' && brief.at(bl-1)!='!' && - brief.at(bl-1)!='?') brief+='.'; + if (bl>0) // add puntuation if needed + { + switch(brief.at(bl-1)) + { + case '.': case '!': case '?': break; + default: brief+='.'; break; + } + } } - //! returns TRUE iff the definition is documented + /*! returns TRUE iff the definition is documented */ virtual bool hasDocumentation() { return !doc.isNull() || !brief.isNull() || Config::extractAllFlag; } + + virtual bool isLinkableInProject() = 0; + virtual bool isLinkable() = 0; + + bool isReference() { return !ref.isEmpty(); } + void setReference(const char *r) { ref=r; } + QCString getReference() { return ref; } + + /*! returns the base file name that corresponds with the \a name of this + * definition. This replaces a number of special characters in the + * name by string that are more suitable to use in file names. + * The function getOutputFileBase() also uses this function in most cases. + * \sa setName(),Definition() + */ QCString nameToFile(const char *name); + /*! Add the list of anchors that mark the sections that are found in the + * documentation. + */ void addSectionsToDefinition(QList *anchorList); private: QCString n; // name of the definition QCString brief; // brief description QCString doc; // detailed description + QCString ref; // reference to external documentation SectionList *sectionList; // list of all sections }; diff --git a/src/diagram.cpp b/src/diagram.cpp index 8cbe128..d25b334 100644 --- a/src/diagram.cpp +++ b/src/diagram.cpp @@ -148,7 +148,7 @@ static void writeVectorBox(QTextStream &t,DiagramItem *di, static void writeMapArea(QTextStream &t,ClassDef *cd,int x,int y,int w,int h) { - if (cd->hasDocumentation() || cd->isReference()) + if (cd->isLinkable()) { t << "getReference()) t << "doxygen=\"" << cd->getReference() << ":\" "; @@ -229,10 +229,7 @@ void DiagramRow::insertClass(DiagramItem *parent,ClassDef *cd,bool doBases, while (bcd) { ClassDef *ccd=bcd->classDef; - if (ccd && ccd->isVisibleExt() - //(ccd->protection()!=Private || extractPrivateFlag) && - //(ccd->hasDocumentation() || !hideClassFlag) - ) count++; + if (ccd && ccd->isVisibleInHierarchy()) count++; bcd=bcl->next(); } if (count>0 && (prot!=Private || !doBases)) @@ -252,10 +249,7 @@ void DiagramRow::insertClass(DiagramItem *parent,ClassDef *cd,bool doBases, while (bcd) { ClassDef *ccd=bcd->classDef; - if (ccd && ccd->isVisibleExt() - //(ccd->protection()!=Private || extractPrivateFlag) && - //(ccd->hasDocumentation() || !hideClassFlag) - ) + if (ccd && ccd->isVisibleInHierarchy()) { row->insertClass(di,ccd,doBases,bcd->prot, doBases?bcd->virt:Normal, @@ -519,8 +513,7 @@ void TreeDiagram::drawBoxes(QTextStream &t,Image *image, if (bitmap) { - bool hasDocs=di->getClassDef()->hasDocumentation() || - di->getClassDef()->isReference(); + bool hasDocs=di->getClassDef()->isLinkable(); writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow, hasDocs,di->getChildren()->count()>0); if (!firstRow) writeMapArea(t,di->getClassDef(),x,y,cellWidth,cellHeight); @@ -553,8 +546,7 @@ void TreeDiagram::drawBoxes(QTextStream &t,Image *image, y = (baseRows-1)*(cellHeight+labelVertSpacing)+ di->yPos()*(cellHeight+labelVertSpacing)/gridHeight; } - bool hasDocs=di->getClassDef()->hasDocumentation() || - di->getClassDef()->isReference(); + bool hasDocs=di->getClassDef()->isLinkable(); writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,hasDocs); if (!firstRow) writeMapArea(t,di->getClassDef(),x,y,cellWidth,cellHeight); } diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 76518ba..01ac9b6 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -47,6 +47,8 @@ #include "mangen.h" #include "language.h" #include "debug.h" +#include "htmlhelp.h" +#include "defargs.h" #if defined(_MSC_VER) #define popen _popen @@ -60,7 +62,6 @@ 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 -//MemberNameList namespaceNameList; // list of namespace members; FileNameList inputNameList; // list of all input files StringList inputFiles; FileList includeFiles; @@ -74,7 +75,6 @@ ClassDict classDict(1009); // dictionary of all documented classes NamespaceDict namespaceDict(257); // dictionary of all documented namespaces MemberNameDict memberNameDict(10007); // dictionary of all class member names MemberNameDict functionNameDict(10007); // dictionary of all functions -//MemberNameDict namespaceNameDict(10007);// dictionaty of all namespace member names StringDict substituteDict(1009); // dictionary of class name substitutes SectionDict sectionDict(257); // dictionary of all page sections FileNameDict inputNameDict(1009); // dictionary of sections @@ -87,6 +87,7 @@ 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 + // a member group OutputList *outputList; // list of output generating objects @@ -103,6 +104,7 @@ int documentedFiles; int documentedGroups; int documentedNamespaces; int documentedNamespaceMembers; +int documentedIncludeFiles; QTextStream tagFile; @@ -260,6 +262,7 @@ void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root) bool ambig; FileDef *fd=0; // see if we need to include a verbatim copy of the header file + //printf("root->includeFile=%s\n",root->includeFile.data()); if (!root->includeFile.isNull() && (fd=findFileDef(&inputNameDict,root->includeFile,ambig))==0 ) @@ -280,9 +283,9 @@ void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root) else // name is not an input file warn("is not an input file\n"); } - else if (root->includeFile.length()==0 && + else if (root->includeFile.isEmpty() && ifd && // see if the file extension makes sense - guessSection(root->includeFile)==Entry::HEADER_SEC) + guessSection(ifd->name())==Entry::HEADER_SEC) { // implicit assumption fd=ifd; } @@ -296,7 +299,8 @@ void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root) cd->setIncludeFile(fd); // set include supplied name cd->setIncludeName(root->includeName); - fd->setIncludeName(cd->getOutputFileBase()+"-include"); + if (cd->name().find('@')==-1) + fd->setIncludeName(cd->getOutputFileBase()+"-include"); if (includeDict[fd->absFilePath()]==0) // include not inserted earlier { includeFiles.inSort(fd); @@ -317,6 +321,8 @@ void extractNamespaceName(const QCString &scopeName, { // the whole name is a namespace namespaceName=clName.copy(); className.resize(0); + //printf("extractNamespace `%s' => `%s|%s'\n",scopeName.data(), + // className.data(),namespaceName.data()); return; } int i,p=clName.length()-2; @@ -327,12 +333,16 @@ void extractNamespaceName(const QCString &scopeName, { namespaceName=clName.left(i); className=clName.right(clName.length()-i-2); + //printf("extractNamespace `%s' => `%s|%s'\n",scopeName.data(), + // className.data(),namespaceName.data()); return; } p=i-2; // try a smaller piece of the scope } className=scopeName.copy(); namespaceName.resize(0); + //printf("extractNamespace `%s' => `%s|%s'\n",scopeName.data(), + // className.data(),namespaceName.data()); return; } @@ -384,6 +394,7 @@ void buildClassList(Entry *root) else { fullName=stripAnnonymousScope(fullName); + //printf("new class with name %s\n",fullName.data()); bool ambig; ClassDef *cd; @@ -391,7 +402,7 @@ void buildClassList(Entry *root) { if (cd->templateArguments()==0) { - //printf("existing ClassDef tempArgList=%p\n",root->tArgList); + //printf("existing ClassDef tempArgList=%p specScope=%s\n",root->tArgList,root->scopeSpec.data()); cd->setTemplateArguments(root->tArgList); } if (root->doc.length()>0 || root->brief.length()>0) // block contains docs @@ -430,10 +441,14 @@ void buildClassList(Entry *root) case Entry::STRUCT_SEC: case Entry::STRUCTDOC_SEC: sec=ClassDef::Struct; break; + case Entry::INTERFACE_SEC: + case Entry::INTERFACEDOC_SEC: + sec=ClassDef::Interface; break; } ClassDef *cd=new ClassDef(fullName,sec); cd->setDocumentation(root->doc); // copy docs to definition cd->setBriefDescription(root->brief); + //printf("new ClassDef tempArgList=%p specScope=%s\n",root->tArgList,root->scopeSpec.data()); cd->setTemplateArguments(root->tArgList); cd->setProtection(root->protection); cd->addSectionsToDefinition(root->anchors); @@ -531,6 +546,12 @@ void buildNamespaceList(Entry *root) fullName.data(),root->fileName.data(),root->startLine); } } + + bool ambig; + // file definition containing the namespace nd + FileDef *fd=findFileDef(&inputNameDict,root->fileName,ambig); + // insert the namespace in the file definition + if (fd) fd->insertNamespace(nd); } else /* if (root->doc.length()>0 || root->brief.length()>0 || @@ -553,7 +574,7 @@ void buildNamespaceList(Entry *root) } bool ambig; - // file definition containing the class cd + // file definition containing the namespace nd FileDef *fd=findFileDef(&inputNameDict,root->fileName,ambig); // insert the namespace in the file definition if (fd) fd->insertNamespace(nd); @@ -575,6 +596,98 @@ void buildNamespaceList(Entry *root) } } +static MemberDef *addVariableToClass(Entry *root,ClassDef *cd, + MemberDef::MemberType mtype,const QCString &scope,const QCString &name, + bool fromAnnScope,int indentDepth,MemberDef *fromAnnMemb) +{ + 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. + QCString 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) + 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); + return md; + } + md=mn->next(); + } + } + // new member variable, typedef or enum value + MemberDef *md=new MemberDef(root->type,name,root->args,0, + root->protection,Normal,root->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); + md->addSectionsToDefinition(root->anchors); + md->setFromAnnonymousScope(fromAnnScope); + md->setFromAnnonymousMember(fromAnnMemb); + md->setIndentDepth(indentDepth); + + // 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); + return md; +} //---------------------------------------------------------------------- // Searches the Entry tree for Variable documentation sections. @@ -611,7 +724,7 @@ void buildVarList(Entry *root) // 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; + int l; i=re.match(root->args,0,&l); root->name=root->args.mid(i,l); root->args=root->args.mid(i+l, @@ -621,7 +734,7 @@ void buildVarList(Entry *root) } else { - QRegExp re("([^)]*)"); + //QRegExp re("([^)]*)"); i=root->type.find(re,0); if (i!=-1) // function variable { @@ -631,7 +744,10 @@ void buildVarList(Entry *root) } QCString scope,name=root->name.copy(); - bool stat=root->stat; + //bool stat=root->stat; + + // find the scope of this variable (stripping the annonymous part + // at the beginning Entry *p = root->parent; while ((p->section & Entry::SCOPE_MASK)) { @@ -641,16 +757,17 @@ void buildVarList(Entry *root) scope.prepend(scopeName); break; } - //if (p->name.length()>0 && p->name[0]!='@') - //{ - // if (!scope.isEmpty()) scope.prepend("::"); - // scope.prepend(p->name); - // break; - //} p=p->parent; } - - //printf("scope=%s\n",scope.data()); + // scope annonymous scope name at the end to determine the scope + // where we can put this variable + + //while ((i=scope.findRev("::"))!=-1 && (int)scope.length()>i+2 && + // scope.at(i+2)=='@' + // ) + //{ + // scope=scope.left(i); + //} int ni; if ((ni=root->name.findRev("::"))!=-1) goto nextMember; @@ -676,94 +793,28 @@ void buildVarList(Entry *root) ClassDef *cd=0; 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. - QCString 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 && !found) - { - 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 + MemberDef *md=0; + // if cd is an annonymous scope we insert the member + // into a non-annonymous scope as well. + int indentDepth=0; + if (scope.find('@')!=-1) { - // 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); - md->addSectionsToDefinition(root->anchors); - - // add the member to the global list - if (mn) + QCString pScope = scope.copy(); + ClassDef *pcd=0; + while ((i=pScope.findRev("::"))!=-1 && (int)pScope.length()>i+2 && + pScope.at(i+2)=='@' + ) { - //printf("Member already found! %s\n",md->name()); - //addMemberDocs(root,mn->first(),def,FALSE); - //delete md; - mn->inSort(md); + pScope=pScope.left(i); + indentDepth++; } - else // new variable name + if ((pcd=getClass(pScope))) { - 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 + //printf("Inserting member in parent scope!\n"); + md=addVariableToClass(root,pcd,mtype,pScope,name,TRUE,indentDepth,0); } - cd->insertMember(md); - - //TODO: insert FileDef instead of filename strings. - cd->insertUsedFile(root->fileName); - } + } + addVariableToClass(root,cd,mtype,scope,name,FALSE,indentDepth,md); } else if (name.length()>0) // global variable { @@ -874,7 +925,7 @@ void buildMemberList(Entry *root) { Debug::print(Debug::Functions,0, "FUNCTION_SEC:\n" - " `%s' `%s'::`%s' `%s' relates=`%s' file=`%s' #targs=%d docs=`%s'\n", + " `%s' `%s'::`%s' `%s' relates=`%s' file=`%s' #targs=%d #mtargs=%d mGrpId=%d\n", root->type.data(), root->parent->name.data(), root->name.data(), @@ -882,7 +933,8 @@ void buildMemberList(Entry *root) root->relates.data(), root->fileName.data(), root->tArgList ? (int)root->tArgList->count() : -1, - root->doc.data() + root->mtArgList ? (int)root->mtArgList->count() : -1, + root->mGrpId ); bool isFriend=root->type.find("friend ")!=-1; @@ -924,6 +976,13 @@ void buildMemberList(Entry *root) else if (root->slot) mtype=MemberDef::Slot; else mtype=MemberDef::Function; + // strip redundant template specifier for constructors + if ((i=name.find('<'))!=-1 && name.find('>')!=-1) + { + name=name.left(i); + } + + //if (Config::includeSourceFlag && !root->body.isEmpty()) //{ // printf("Function: %s\n-----------------\n%s\n------------------\n", @@ -935,14 +994,15 @@ void buildMemberList(Entry *root) // root->args.data(),argListToString(cd->templateArguments()).data()); 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); + mtype,root->mtArgList,root->argList); md->setMemberClass(cd); md->setDefFile(root->fileName); md->setDefLine(root->startLine); md->setDocumentation(root->doc); md->setBriefDescription(root->brief); md->setBody(root->body); - //md->setScopeTemplateArguments(cd->templateArguments()); + md->setGroupId(root->mGrpId); + //md->setScopeTemplateArguments(root->tArgList); md->addSectionsToDefinition(root->anchors); QCString def; if (root->relates.length()>0 || isFriend) @@ -1090,6 +1150,7 @@ void buildMemberList(Entry *root) md->setPrototype(root->proto); md->setBody(root->body); md->addSectionsToDefinition(root->anchors); + md->setGroupId(root->mGrpId); QCString def; if (root->type.length()>0) { @@ -1323,14 +1384,14 @@ void computeClassRelations(Entry *root) // 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 && !found) + while (p->section&Entry::SCOPE_MASK && !found) { scopePrefix=p->name+"::"; QList *baseList=root->extends; BaseInfo *bi=baseList->first(); while (bi && !found) // for each base class { - QCString cName=scopePrefix+bi->name; + QCString cName=removeRedundantWhiteSpace(scopePrefix+bi->name); //printf("Base class %s\n",cName.data()); ClassDef *baseClass=getClass(cName); if (baseClass) // base class is documented @@ -1358,21 +1419,22 @@ void computeClassRelations(Entry *root) BaseInfo *bi=baseList->first(); while (bi) // for each base class { - ClassDef *baseClass=getClass(bi->name); + QCString baseClassName=removeRedundantWhiteSpace(bi->name); + ClassDef *baseClass=getClass(baseClassName); //printf("baseClass %s of %s found (%s and %s)\n", - // bi->name.data(), + // baseClassName.data(), // root->name.data(), // (bi->prot==Private)?"private":((bi->prot==Protected)?"protected":"public"), // (bi->virt==Normal)?"normal":"virtual" // ); int i; - QCString templSpec,baseClassName=bi->name.copy(); - if (!baseClass && (i=bi->name.find('<'))!=-1) + QCString templSpec; + if (!baseClass && (i=baseClassName.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); + baseClassName=baseClassName.left(i); baseClass=getClass(baseClassName); templSpec=bi->name.right(bi->name.length()-i); } @@ -1415,27 +1477,8 @@ void computeClassRelations(Entry *root) } bi=baseList->next(); } - } - } -// else // class has no base classes -// { -// QCString 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); -// } -// } -// } + } // class not nested + } // class has no base classes } // else class is already found } else if (root->name.right(2)!="::") @@ -1564,6 +1607,22 @@ void addMemberDocs(Entry *root,MemberDef *md, const char *funcDecl, md->setDefLine(root->startLine); md->addSectionsToDefinition(root->anchors); if (cd) cd->insertUsedFile(root->fileName); + if (root->mGrpId!=-1) + { + if (md->groupId()!=-1) + { + if (md->groupId()!=root->mGrpId) + { + warn("Warning: member %s belongs to two different group. The second " + "one is found at line %d of %s and will be ignored\n", + md->name().data(),root->startLine,root->fileName.data()); + } + } + else // copy group id + { + md->setGroupId(root->mGrpId); + } + } } //---------------------------------------------------------------------- @@ -1656,7 +1715,7 @@ void substituteTemplateArgNames(ArgumentList *src, while ((i=re.match(s,p,&l))!=-1) // for each template name found at the // member definition { - Argument *ta = tempArgs->at(c); + Argument *ta = c<(int)tempArgs->count() ? tempArgs->at(c) : 0; if (ta) // get matching template argument of the class { QCString dstName=s.mid(i,l); @@ -1724,6 +1783,31 @@ void substituteTemplateArgNames(ArgumentList *src, } +QCString insertTemplateSpecifierInScope(const QCString &scope,const QCString &templ) +{ + QCString result=scope.copy(); + if (!templ.isEmpty() && scope.find('<')==-1) + { + int si,pi=0; + while ((si=scope.find("::",pi))!=-1 && !getClass(scope.left(si)+templ) + && !getClass(scope.left(si))) + { //printf("Tried `%s'\n",(scope.left(si)+templ).data()); + pi=si+2; + } + if (si==-1) // not nested => append template specifier + { + result+=templ; + } + else // nested => insert template specifier before after first class name + { + result=scope.left(si) + templ + scope.right(scope.length()-si); + } + } + //printf("insertTemplateSpecifierInScope(`%s',`%s')=%s\n", + // scope.data(),templ.data(),result.data()); + return result; +} + //---------------------------------------------------------------------- // This function tries to find a member (in a documented class/file/namespace) // that corresponds to the function declaration given in `funcDecl'. @@ -1739,8 +1823,10 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded, bool isFunc) { Debug::print(Debug::FindMembers,0, - "findMember(root=%p,funcDecl=`%s',related=`%s',overload=%d,isFunc=%d\n====\ndoc=%s\n====\n)\n", - root,funcDecl.data(),related.data(),overloaded,isFunc,root->doc.data() + "findMember(root=%p,funcDecl=`%s',related=`%s',overload=%d,isFunc=%d mGrpId=%d tArgList=%p=\"%s\" scopeSpec=%s memberSpec=%s\n", + root,funcDecl.data(),related.data(),overloaded,isFunc,root->mGrpId, + root->tArgList,tempArgListToString(root->tArgList).data(), + root->scopeSpec.data(),root->memberSpec.data() ); if (Config::includeSourceFlag && !root->body.isEmpty()) { @@ -1789,6 +1875,31 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded, parseFuncDecl(funcDecl,scopeName,classTempList,funcType,funcName, funcArgs,funcTempList,exceptions ); + //printf("scopeName=`%s'\n",scopeName.data()); + + bool isSpecialization = !root->scopeSpec.isEmpty() && + root->scopeSpec != tempArgListToString(root->tArgList); + + //printf("1. scopeName=`%s' specialization=%d\n", + // scopeName.data(),isSpecialization + // ); + // include template specifier in the scope if needed + if (!scopeName.isEmpty() && !root->scopeSpec.isEmpty() && isSpecialization) + { + //scopeName = insertTemplateSpecifierInScope( + // scopeName,removeRedundantWhiteSpace(root->scopeSpec)); + //printf("2. scopeName=`%s'\n",scopeName.data()); + } + + // if this is a member template inside non template class, the parser puts + // template specifier in scopeSepc, so we copy it to the right location here + if (scopeName.isEmpty() && !root->scopeSpec.isEmpty() && + root->memberSpec.isEmpty() && funcTempList.isEmpty() + ) + // template specifier that was found is for a function + { + funcTempList = root->scopeSpec; + } // 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 @@ -1811,13 +1922,23 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded, Entry *p=root->parent; while (p) // get full scope as class name { - //printf("++++++ scope=`%s'\n",p->name.data()); - if (((p->section & Entry::COMPOUND_MASK) || - p->section == Entry::NAMESPACE_SEC - ) && !p->name.isEmpty() && p->name[0]!='@' + if ((p->section & Entry::SCOPE_MASK) + && !p->name.isEmpty() && p->name[0]!='@' ) { - if (scopeName.left(p->name.length())==p->name) + //printf("p->name=`%s' scopeName=`%s' classTempList=%s\n", + // p->name.data(),scopeName.data(),classTempList.data()); + + QCString tryScope; + + if (scopeName.find('<')==-1 && !classTempList.isEmpty()) + tryScope=insertTemplateSpecifierInScope(scopeName,classTempList); + else + tryScope=scopeName.copy(); + + //printf("tryScope=%s\n",tryScope.data()); + + if (leftScopeMatch(tryScope,p->name)) break; // scope already present, so stop now // prepend name to scope if (!scopeName.isEmpty()) scopeName.prepend("::"); @@ -1825,14 +1946,20 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded, } p=p->parent; } + //printf("3. scopeName=`%s'\n",scopeName.data()); + //printf("result: scope=%s\n",scopeName.data()); } - 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 + if (!scopeName.isEmpty() && + scopeName.find('<')==-1 && + classTempList.length()==0 + ) + { + ClassDef *cd=getClass(scopeName); + // class is a template, but no template name list found + if (root->tArgList && cd && cd->templateArguments()) { - classTempList = cd->getTemplateNameString(); + classTempList = tempArgListToString(root->tArgList); } } @@ -1840,17 +1967,20 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded, extractNamespaceName(scopeName,className,namespaceName); QCString tempScopeName=scopeName.copy(); - int ti; - int spi = namespaceName.isEmpty() ? 0 : namespaceName.length()+2; - if ((ti=tempScopeName.find("::",spi))!=-1 && !classTempList.isEmpty()) - { - // insert template parameters after the first scope name - tempScopeName=tempScopeName.left(ti)+classTempList+ - tempScopeName.right(tempScopeName.length()-ti); - } - else + int ti=tempScopeName.find('<'); + if (ti==-1) { - tempScopeName+=classTempList; + int spi = namespaceName.isEmpty() ? 0 : namespaceName.length()+2; + if ((ti=tempScopeName.find("::",spi))!=-1 && !classTempList.isEmpty()) + { + // insert template parameters after the first scope name + tempScopeName=tempScopeName.left(ti)+classTempList+ + tempScopeName.right(tempScopeName.length()-ti); + } + else + { + tempScopeName+=classTempList; + } } @@ -1958,33 +2088,54 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded, isFunc ); - MemberName *mn; + MemberName *mn=0; if (funcName.length()>0) // function name is valid { - if (!isRelated && (mn=memberNameDict[funcName])) // function name already found + Debug::print(Debug::FindMembers,0, + "1. funcName=`%s'\n",funcName.data()); + //if (funcTempList.length()>0) // try with member specialization + //{ + // mn=memberNameDict[funcName+funcTempList]; + //} + if (mn==0) // try without specialization { + mn=memberNameDict[funcName]; + } + if (!isRelated && mn) // function name already found + { + Debug::print(Debug::FindMembers,0, + "2. member name exists \n"); if (className.length()>0) // class name is valid { int count=0; MemberDef *md=mn->first(); // for each member with that name while (md) { + Debug::print(Debug::FindMembers,0, + "3. member definition found scopeName=`%s'\n",scopeName.data()); ClassDef *cd=md->memberClass(); //printf("Member %s (member scopeName=%s) (this scopeName=%s) classTempList=%s\n",md->name().data(),cd->name().data(),scopeName.data(),classTempList.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 + tcd=getClass( + insertTemplateSpecifierInScope( + scopeName, + classTempList + ) + ); // try specialization } - else + if (tcd==0) { - tcd=getClass(scopeName); + tcd=getClass(scopeName); // try general class } if (cd && tcd==cd) // member's classes match { + Debug::print(Debug::FindMembers,0, + "4. class definition %s found\n",cd->name().data()); int ci; ArgumentList *classTemplArgs = cd->templateArguments(); + ArgumentList *funcTemplArgs = md->templateArguments(); if ((ci=cd->name().find("::"))!=-1) // nested class { ClassDef *parentClass = getClass(cd->name().left(ci)); @@ -1993,8 +2144,13 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded, } //printf("cd->name=%s classTemplArgs=%s\n",cd->name().data(), // argListToString(classTemplArgs).data()); + ArgumentList *argList = 0; bool substDone=FALSE; + + /* substitute the occurrences of class template names in the + * argument list before matching + */ if (!classTempList.isEmpty() && classTemplArgs && md->argumentList() @@ -2019,17 +2175,53 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded, { argList = md->argumentList(); } + + /* substitute the occurrences of member template names in the + * argument list before matching + */ + if (!funcTempList.isEmpty() && + funcTemplArgs && + md->argumentList() + ) + { + ArgumentList *oldArgList = argList; + argList = new ArgumentList; + substituteTemplateArgNames( + oldArgList, /* source argument list */ + funcTempList, /* template names source */ + funcTemplArgs, /* template names dest */ + argList /* dest argument list */ + ); + if (substDone) // delete old argument list + delete oldArgList; + substDone=TRUE; + } + + Debug::print(Debug::FindMembers,0, + "5. matching `%s'<=>`%s' className=%s namespaceName=%s\n", + argListToString(argList).data(),argListToString(root->argList).data(), + className.data(),namespaceName.data() + ); + + // TODO: match loop for all possible scopes bool matching= md->isVariable() || md->isTypedef() || // needed for function pointers (md->argumentList()==0 && root->argList->count()==0) || matchArguments(argList, root->argList,className,namespaceName); + Debug::print(Debug::FindMembers,0, + "6. match results = %d\n",matching); + if (substDone) // found a new argument list { //printf("root->tArgList=`%s'\n",argListToString(root->tArgList).data()); if (matching) // replace member's argument list { - md->setScopeTemplateArguments(root->tArgList); + //printf("Setting scope template argument of member to %s\n", + // argListToString(root->tArgList).data() + // ); + md->setScopeDefTemplateArguments(root->tArgList); + md->setMemberDefTemplateArguments(root->mtArgList); md->setArgumentList(argList); } else // no match -> delete argument list @@ -2265,7 +2457,7 @@ void findMemberDocumentation(Entry *root) else if (root->section==Entry::FUNCTION_SEC && (!root->doc.isEmpty() || !root->brief.isEmpty() || - !root->body.isEmpty() /*|| Config::extractAllFlag*/ + !root->body.isEmpty() || root->mGrpId!=-1 /*|| Config::extractAllFlag*/ ) ) { @@ -2275,15 +2467,37 @@ void findMemberDocumentation(Entry *root) //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); + //if (root->tArgList && root->mtArgList) // add member template specifier + //{ + // findMember(root, + // root->type+" "+ + // root->inside+ + // root->name+ + // tempArgListToString(root->mtArgList)+ + // root->args+ + // root->exception, + // root->relates, + // FALSE,isFunc); + // + //else + // + 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->inside+ + root->name+ + root->args+ + root->exception, root->relates, FALSE,isFunc); } @@ -2586,7 +2800,7 @@ static void findDEV(const MemberNameList &mnl) // for each enum value while (fmd) { - if (fmd->hasDocumentation()) documentedEnumValues++; + if (fmd->isLinkableInProject()) documentedEnumValues++; fmd=fmdl->next(); } } @@ -2661,7 +2875,7 @@ void computeMemberRelations() { //printf(" match found!\n"); if (mcd && bmcd && - mcd->isVisibleExt() && bmcd->isVisibleExt() + mcd->isLinkable() && bmcd->isLinkable() ) { md->setReimplements(bmd); @@ -2866,7 +3080,7 @@ void generateFileDocs() FileDef *fd=fn->first(); while (fd) { - if (!fd->isReference() && fd->hasDocumentation()) + if (fd->isLinkableInProject()) { msg("Generating docs for file %s...\n",fd->name().data()); fd->writeDocumentation(*outputList); @@ -2891,13 +3105,19 @@ void generateClassDocs() msg("Generating index page...\n"); writeIndex(*outputList); - msg("Generating compound index...\n"); + msg("Generating annotated compound index...\n"); writeAnnotatedIndex(*outputList); + if (Config::alphaIndexFlag) + { + msg("Generating alphabetical compound index...\n"); + writeAlphabeticalIndex(*outputList); + } + msg("Generating hierarchical class index...\n"); writeHierarchicalIndex(*outputList); - if (includeFiles.count()>0) + if (documentedIncludeFiles>0) { msg("Generating header index...\n"); writeHeaderIndex(*outputList); @@ -2915,13 +3135,7 @@ void generateClassDocs() for ( ; cli.current() ; ++cli ) { ClassDef *cd=cli.current(); - if (!cd->isReference() && - //!cd->name().isEmpty() && - //cd->name().at(0)!='@' && - //(cd->protection()!=Private || Config::extractPrivateFlag) && - //(cd->hasDocumentation() || !Config::hideClassFlag) - cd->isVisible() - ) + if ( cd->isLinkableInProject() ) // skip external references and anonymous compounds { msg("Generating docs for compound %s...\n",cd->name().data()); @@ -2996,7 +3210,7 @@ void findDefineDocumentation(Entry *root) // root->startLine,root->fileName.data()); } } - else // define not found + else if (root->doc.length()>0 || root->brief.length()>0) // 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()); @@ -3166,6 +3380,7 @@ void buildExampleList(Entry *root) void generateExampleDocs() { + outputList->disable(OutputGenerator::Man); PageInfo *pi=exampleList.first(); while (pi) { @@ -3177,6 +3392,7 @@ void generateExampleDocs() endFile(*outputList); pi=exampleList.next(); } + outputList->enable(OutputGenerator::Man); } //---------------------------------------------------------------------------- @@ -3194,6 +3410,34 @@ void generateGroupDocs() } //---------------------------------------------------------------------------- +// create member group documentation based on the documentation of the +// group's members. + +void computeMemberGroupDocumentation() +{ + MemberGroupDictIterator mgdi(memberGroupDict); + MemberGroup *mg; + for (;(mg=mgdi.current());++mgdi) + { + mg->addDocumentation(); + } +} + +//---------------------------------------------------------------------------- +// generate member group pages + +void generateMemberGroupDocs() +{ + MemberGroupDictIterator mgdi(memberGroupDict); + MemberGroup *mg; + for (;(mg=mgdi.current());++mgdi) + { + mg->writeDocumentation(*outputList); + } +} + + +//---------------------------------------------------------------------------- // generate module pages void generateNamespaceDocs() @@ -3204,8 +3448,7 @@ void generateNamespaceDocs() NamespaceDef *nd; for (;(nd=nli.current());++nli) { - if ((nd->getReference() || nd->hasDocumentation()) && - !nd->name().isEmpty() && nd->name().at(0)!='@') + if (nd->isLinkableInProject()) { msg("Generating docs for namespace %s\n",nd->name().data()); nd->writeDocumentation(*outputList); @@ -3524,9 +3767,10 @@ void readFiles(BufStr &output) } s=inputFiles.next(); + //printf("-------> adding new line\n"); + output.addChar('\n'); /* to prevent problems under Windows ? */ } // *p++='\0'; - output.addChar('\n'); /* to prevent problems under Windows ? */ output.addChar(0); //printf("Output after preprocessing:\n---------\n%s\n----------\n",output.data()); //printf("Final length = %d\n",p-output.data()); @@ -3835,7 +4079,7 @@ int main(int argc,char **argv) } } else - config=fileToString(argv[1]); + config=fileToString(argv[optind]); parseConfig(config); checkConfig(); @@ -3849,6 +4093,7 @@ int main(int argc,char **argv) { outputList->add(new HtmlGenerator); HtmlGenerator::init(); + if (Config::htmlHelpFlag) HtmlHelp::getInstance()->initialize(); } if (Config::generateLatex) { @@ -4016,7 +4261,6 @@ int main(int argc,char **argv) msg("Searching for member function documentation...\n"); findMemberDocumentation(root); // may introduce new members ! - msg("Freeing entry tree\n"); delete root; @@ -4035,6 +4279,9 @@ int main(int argc,char **argv) msg("Building full member lists recursively...\n"); buildCompleteMemberLists(); + msg("Determining member group documentation...\n"); + computeMemberGroupDocumentation(); + //unrelatedFunctionsUsed=hasUnrelatedFunctions(); /************************************************************************** @@ -4053,6 +4300,7 @@ int main(int argc,char **argv) documentedGroups = countGroups(); documentedNamespaces = countNamespaces(); documentedNamespaceMembers = countNamespaceMembers(); + documentedIncludeFiles = countIncludeFiles(); // compute the shortest possible names of all files // without loosing the uniqueness of the file names. @@ -4077,6 +4325,9 @@ int main(int argc,char **argv) msg("Generating group documentation...\n"); generateGroupDocs(); + msg("Generating member group documentation...\n"); + generateMemberGroupDocs(); + msg("Generating namespace index...\n"); generateNamespaceDocs(); @@ -4132,6 +4383,11 @@ int main(int argc,char **argv) Config::htmlOutputDir.data()); } + if (Config::generateHtml && Config::htmlHelpFlag) + { + HtmlHelp::getInstance()->finalize(); + } + delete tag; return 0; } diff --git a/src/doxygen.h b/src/doxygen.h index 17c8cd8..00803c0 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -74,11 +74,11 @@ class BufStr : public QCString const int spareRoom; // 10Kb extra room to avoid frequent resizing }; -typedef QList StringList; +typedef QList StringList; typedef QDict MemberDict; typedef QDict ClassDict; typedef QDict FileDict; -typedef QDict StringDict; +typedef QDict StringDict; typedef QDict PageDict; typedef QDict GroupDict; @@ -123,5 +123,6 @@ extern int documentedFiles; extern int documentedGroups; extern int documentedNamespaces; extern int documentedNamespaceMembers; +extern int documentedIncludeFiles; #endif diff --git a/src/doxygen.pro b/src/doxygen.pro deleted file mode 100644 index e6dd3c0..0000000 --- a/src/doxygen.pro +++ /dev/null @@ -1,38 +0,0 @@ -# -# $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.pro.in b/src/doxygen.pro.in new file mode 100644 index 0000000..e36c7e2 --- /dev/null +++ b/src/doxygen.pro.in @@ -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. +# +# TMake project file for doxygen + +TEMPLATE = doxygen.t +CONFIG = console qt warn_on $extraopts +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 membergroup.h htmlhelp.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 \ + membergroup.cpp htmlhelp.cpp +win32:INCLUDEPATH += . +TARGET = ../bin/doxygen +OBJECTS_DIR = ../objects diff --git a/src/doxysearch.pro b/src/doxysearch.pro deleted file mode 100644 index ab34adc..0000000 --- a/src/doxysearch.pro +++ /dev/null @@ -1,18 +0,0 @@ -# -# $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/doxysearch.pro.in b/src/doxysearch.pro.in new file mode 100644 index 0000000..f96daf9 --- /dev/null +++ b/src/doxysearch.pro.in @@ -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 $extraopts +SOURCES = doxysearch.cpp +TARGET = ../bin/doxysearch +OBJECTS_DIR = ../objects diff --git a/src/doxytag.l b/src/doxytag.l index 4e2debd..e56abed 100644 --- a/src/doxytag.l +++ b/src/doxytag.l @@ -324,14 +324,18 @@ QCString unhtmlify(const char *str) classFile=yytext; BEGIN( SearchMemberRef ); } -"#" { +"#" { + if (YY_START==ReadClassFile) + { + classFile=yyFileName; + } BEGIN( ReadMemberRef ); } [a-z_A-Z0-9]+ { memberRef=yytext; BEGIN( SearchMemberName ); } -"" { +""|"" { // is for qt-1.44, is for qt-2.00 BEGIN( ReadMemberName ); } [a-z_A-Z~] { diff --git a/src/doxytag.pro b/src/doxytag.pro deleted file mode 100644 index 3389c00..0000000 --- a/src/doxytag.pro +++ /dev/null @@ -1,24 +0,0 @@ -# -# $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.pro.in b/src/doxytag.pro.in new file mode 100644 index 0000000..c09cad5 --- /dev/null +++ b/src/doxytag.pro.in @@ -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 $extraopts +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/entry.cpp b/src/entry.cpp index 4e2ca93..c330f8b 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -35,6 +35,7 @@ Entry::Entry() argList->setAutoDelete(TRUE); //printf("Entry::Entry() tArgList=0\n"); tArgList = 0; + mtArgList = 0; mGrpId = -1; reset(); } @@ -76,6 +77,7 @@ Entry::Entry(const Entry &e) argList->setAutoDelete(TRUE); //printf("Entry::Entry(copy) tArgList=0\n"); tArgList = 0; + mtArgList = 0; // deep copy of the child entry list QListIterator eli(*e.sublist); @@ -131,6 +133,20 @@ Entry::Entry(const Entry &e) //printf("appending argument %s %s\n",a->type.data(),a->name.data()); } } + + // deep copy template argument list + if (e.mtArgList) + { + mtArgList = new ArgumentList; + mtArgList->setAutoDelete(TRUE); + //printf("Entry::Entry(copy) new tArgList=%p\n",tArgList); + QListIterator mtali(*e.mtArgList); + for (;(a=mtali.current());++mtali) + { + mtArgList->append(new Argument(*a)); + //printf("appending argument %s %s\n",a->type.data(),a->name.data()); + } + } } Entry::~Entry() @@ -143,6 +159,7 @@ Entry::~Entry() delete anchors; delete argList; delete tArgList; + delete mtArgList; num--; } @@ -181,6 +198,8 @@ void Entry::reset() brief.resize(0); inside.resize(0); fileName.resize(0); + scopeSpec.resize(0); + memberSpec.resize(0); mGrpId = -1; section = EMPTY_SEC; sig = FALSE; @@ -195,6 +214,7 @@ void Entry::reset() anchors->clear(); argList->clear(); if (tArgList) { delete tArgList; tArgList=0; } + if (mtArgList) { delete mtArgList; mtArgList=0; } } @@ -262,5 +282,17 @@ int Entry::getSize() a=tArgList->next(); } } + if (mtArgList) + { + a=mtArgList->first(); + while (e) + { + size+=sizeof(Argument); + size+=a->type.length()+1 + +a->name.length()+1 + +a->defval.length()+1; + a=mtArgList->next(); + } + } return size; } diff --git a/src/entry.h b/src/entry.h index 94cf52b..18ee013 100644 --- a/src/entry.h +++ b/src/entry.h @@ -36,6 +36,7 @@ struct Argument Argument() {} Argument(const Argument &a) { + attrib=a.attrib.copy(); type=a.type.copy(); name=a.name.copy(); defval=a.defval.copy(); @@ -44,6 +45,7 @@ struct Argument { if (this!=&a) { + attrib=a.attrib.copy(); type=a.type.copy(); name=a.name.copy(); defval=a.defval.copy(); @@ -51,6 +53,7 @@ struct Argument return *this; } + QCString attrib; // argument attribute (IDL only) QCString type; // argument type QCString name; // argument name (if any) QCString defval; // argument default value (if any) @@ -101,8 +104,10 @@ class Entry 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, + INTERFACE_SEC = 0x04000000, + INTERFACEDOC_SEC = 0x08000000, + COMPOUND_MASK = CLASS_SEC | STRUCT_SEC | UNION_SEC | INTERFACE_SEC, + COMPOUNDDOC_MASK = CLASSDOC_SEC | STRUCTDOC_SEC | UNIONDOC_SEC | INTERFACEDOC_SEC, SCOPE_MASK = COMPOUND_MASK | NAMESPACE_SEC, FILE_MASK = SOURCE_SEC | HEADER_SEC }; @@ -128,6 +133,9 @@ class Entry QCString args; // member argument string ArgumentList *argList; // member arguments as a list ArgumentList *tArgList; // template argument list + ArgumentList *mtArgList; // member template argument list + QCString scopeSpec; // template specialization of the scope + QCString memberSpec; // template specialization of the member QCString program; // the program text QCString body; // the function body QCString includeFile; // include file (2 arg of \class, must be unique) @@ -138,7 +146,6 @@ class Entry QCString inside; // name of the class in which documents are found QCString exception; // throw specification int mGrpId; // member group id - QCString mGrpHeader; // member group header QList *sublist; // entries that are children of this one QList *extends; // list of base classes QList *groups; // list of groups this entry belongs to diff --git a/src/filedef.cpp b/src/filedef.cpp index 5f62357..f038e2e 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -37,12 +37,13 @@ FileDef::FileDef(const char *p,const char *nm,const char *ref) path=p; filepath=path+nm; filename=nameToFile(nm); - reference=ref; + setReference(ref); memList = new MemberList; classList = new ClassList; includeList = new FileList; defineList = new DefineList; namespaceList = new NamespaceList; + namespaceDict = new NamespaceDict(7); } /*! destroy the file definition */ @@ -52,6 +53,8 @@ FileDef::~FileDef() delete classList; delete includeList; delete defineList; + delete namespaceList; + delete namespaceDict; } /*! Compute the HTML anchor names for all members in the class */ @@ -105,7 +108,7 @@ void FileDef::writeDocumentation(OutputList &ol) bool found=FALSE; while (nd) { - if (nd->isVisibleExt()) + if (nd->name().find('@')==-1) { if (!found) { @@ -115,16 +118,16 @@ void FileDef::writeDocumentation(OutputList &ol) ol.startMemberList(); found=TRUE; } - ol.startMemberItem(); + ol.startMemberItem(FALSE,0); ol.writeString("namespace "); ol.insertMemberAlign(); - if (nd->hasDocumentation()) + if (nd->isLinkable()) { ol.writeObjectLink(nd->getReference(), - nd->getOutputFileBase(), - 0, - nd->name() - ); + nd->getOutputFileBase(), + 0, + nd->name() + ); } else { @@ -132,7 +135,7 @@ void FileDef::writeDocumentation(OutputList &ol) ol.docify(nd->name()); ol.endBold(); } - ol.endMemberItem(); + ol.endMemberItem(FALSE,0,0,FALSE); } nd=namespaceList->next(); } @@ -144,7 +147,7 @@ void FileDef::writeDocumentation(OutputList &ol) bool found=FALSE; while (cd) { - if ( cd->isVisibleExt() ) + if (cd->name().find('@')==-1) { if (!found) { @@ -154,22 +157,23 @@ void FileDef::writeDocumentation(OutputList &ol) ol.startMemberList(); found=TRUE; } - ol.startMemberItem(); + ol.startMemberItem(FALSE,FALSE); switch (cd->compoundType()) { case ClassDef::Class: ol.writeString("class"); break; case ClassDef::Struct: ol.writeString("struct"); break; case ClassDef::Union: ol.writeString("union"); break; + case ClassDef::Interface: ol.writeString("interface"); break; } ol.writeString(" "); ol.insertMemberAlign(); - if (cd->hasDocumentation()) + if (cd->isLinkable()) { ol.writeObjectLink(cd->getReference(), - cd->getOutputFileBase(), - 0, - cd->name() - ); + cd->getOutputFileBase(), + 0, + cd->name() + ); } else { @@ -177,14 +181,14 @@ void FileDef::writeDocumentation(OutputList &ol) ol.docify(cd->name()); ol.endBold(); } - ol.endMemberItem(); + ol.endMemberItem(FALSE,0,0,FALSE); } cd=classList->next(); + if (found) ol.endMemberList(); } - if (found) ol.endMemberList(); } - writeMemberDecs(ol,0,0,this,0,0,memList); + memList->writeDeclarations(ol,0,0,this,0,0); ol.endMemberSections(); //doc=doc.stripWhiteSpace(); @@ -222,7 +226,7 @@ void FileDef::writeDocumentation(OutputList &ol) ol.startGroupHeader(); parseText(ol,theTranslator->trDefineDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,memList,name(),MemberDef::Define); + memList->writeDocumentation(ol,name(),MemberDef::Define); } if ( memList->protoCount()>0 ) @@ -231,7 +235,7 @@ void FileDef::writeDocumentation(OutputList &ol) ol.startGroupHeader(); parseText(ol,theTranslator->trFunctionPrototypeDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,memList,name(),MemberDef::Prototype); + memList->writeDocumentation(ol,name(),MemberDef::Prototype); } if ( memList->typedefCount()>0 ) @@ -240,7 +244,7 @@ void FileDef::writeDocumentation(OutputList &ol) ol.startGroupHeader(); parseText(ol,theTranslator->trTypedefDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,memList,name(),MemberDef::Typedef); + memList->writeDocumentation(ol,name(),MemberDef::Typedef); } if ( memList->enumCount()>0 ) @@ -249,7 +253,7 @@ void FileDef::writeDocumentation(OutputList &ol) ol.startGroupHeader(); parseText(ol,theTranslator->trEnumerationTypeDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,memList,name(),MemberDef::Enumeration); + memList->writeDocumentation(ol,name(),MemberDef::Enumeration); } if ( memList->enumValueCount()>0 ) @@ -258,16 +262,19 @@ void FileDef::writeDocumentation(OutputList &ol) ol.startGroupHeader(); parseText(ol,theTranslator->trEnumerationValueDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,memList,name(),MemberDef::EnumValue); + memList->writeDocumentation(ol,name(),MemberDef::EnumValue); } - if ( memList->funcCount()>0 ) + int cnt; + if ( (cnt=memList->funcCount()>0) ) { ol.writeRuler(); ol.startGroupHeader(); - parseText(ol,theTranslator->trFunctionDocumentation()); + QCString cntString; + cntString.sprintf(" (%d)",cnt); + parseText(ol,theTranslator->trFunctionDocumentation()+cntString); ol.endGroupHeader(); - writeMemberDocs(ol,memList,name(),MemberDef::Function); + memList->writeDocumentation(ol,name(),MemberDef::Function); } if ( memList->varCount()>0 ) @@ -276,7 +283,7 @@ void FileDef::writeDocumentation(OutputList &ol) ol.startGroupHeader(); parseText(ol,theTranslator->trVariableDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,memList,name(),MemberDef::Variable); + memList->writeDocumentation(ol,name(),MemberDef::Variable); } // write Author section (Man only) @@ -304,7 +311,11 @@ void FileDef::insertClass(ClassDef *cd) /*! Adds namespace definition \a nd to the list of all compounds of this file */ void FileDef::insertNamespace(NamespaceDef *nd) { - namespaceList->append(nd); + if (!nd->name().isEmpty() && namespaceDict->find(nd->name())==0) + { + namespaceList->append(nd); + namespaceDict->insert(nd->name(),nd); + } } //----------------------------------------------------------------------------- diff --git a/src/filedef.h b/src/filedef.h index b5c9585..6f39be2 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -31,6 +31,7 @@ class OutputList; class DefineList; class NamespaceDef; class NamespaceList; +class NamespaceDict; /*! \class FileDef filedef.h \brief A File definition. @@ -95,15 +96,26 @@ class FileDef : public Definition /*! Returns true iff this file was externally defined (i.e. read from a tag file) */ - bool isReference() { return !reference.isNull(); } + //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; } + //const char *getReference() { return reference; } //void setFileType(FileType ft) { ftype = ft; } //FileType fileType() const { return ftype; } + bool isLinkableInProject() + { + return hasDocumentation() && !isReference(); + } + + bool isLinkable() + { + return isLinkableInProject() || isReference(); + } + + void writeDocumentation(OutputList &ol); friend void generatedFileNames(); void insertMember(MemberDef *fd); @@ -115,12 +127,13 @@ class FileDef : public Definition MemberList *memList; ClassList *classList; FileList *includeList; + NamespaceDict *namespaceDict; NamespaceList *namespaceList; DefineList *defineList; //QCString n; //QCString doc; //QCString brief; - QCString reference; + //QCString reference; QCString path; QCString filepath; QCString diskname; diff --git a/src/formula.cpp b/src/formula.cpp index 0a961ca..68e74f8 100644 --- a/src/formula.cpp +++ b/src/formula.cpp @@ -150,11 +150,19 @@ void FormulaList::generateBitmaps(const char *path) // Then we run ghostscript to convert the postscript to a pixmap // The pixmap is a truecolor image, where only black and white are // used. +#ifdef _WIN32 + sprintf(gsCmd,"gswin32 -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() + ); +#else 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() ); +#endif //printf("Running ghostscript...\n"); system(gsCmd); f.setName(formBase+".pnm"); diff --git a/src/groupdef.cpp b/src/groupdef.cpp index e1e28ab..6f0133a 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -122,9 +122,10 @@ void GroupDef::writeDocumentation(OutputList &ol) QCString type; switch (cd->compoundType()) { - case ClassDef::Class: type="class"; break; - case ClassDef::Struct: type="struct"; break; - case ClassDef::Union: type="union"; break; + case ClassDef::Class: type="class"; break; + case ClassDef::Struct: type="struct"; break; + case ClassDef::Union: type="union"; break; + case ClassDef::Interface: type="interface"; break; } ol.writeStartAnnoItem(type,cd->getOutputFileBase(),0,cd->name()); ol.writeEndAnnoItem(cd->name()); diff --git a/src/groupdef.h b/src/groupdef.h index ab54ea6..7b774d3 100644 --- a/src/groupdef.h +++ b/src/groupdef.h @@ -43,6 +43,14 @@ class GroupDef : public Definition void addNamespace(const NamespaceDef *def); void writeDocumentation(OutputList &ol); int countMembers() const; + bool isLinkableInProject() + { + return hasDocumentation() && !isReference(); + } + bool isLinkable() + { + return isLinkableInProject() || isReference(); + } private: QCString title; // title of the group diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index 1a44646..53b20b9 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -26,6 +26,10 @@ #include "logos.h" #include "diagram.h" +#define GROUP_COLOR "#ff8080" + +HtmlHelp *HtmlGenerator::htmlHelp = 0; + HtmlGenerator::HtmlGenerator() : OutputGenerator() { if (Config::headerFile.length()>0) header=fileToString(Config::headerFile); @@ -51,6 +55,7 @@ void HtmlGenerator::init() exit(1); } writeLogo(Config::htmlOutputDir); + writeNullImage(Config::htmlOutputDir); } void HtmlGenerator::startFile(const char *name,const char *title,bool external) @@ -59,6 +64,7 @@ void HtmlGenerator::startFile(const char *name,const char *title,bool external) lastTitle=title; if (fileName.right(5)!=".html") fileName+=".html"; startPlainFile(fileName); + lastFile = fileName; if (header.length()==0) { t << "\n" @@ -158,14 +164,16 @@ void HtmlGenerator::writeStyleInfo(int part) if (part==0) { startPlainFile("doxygen.css"); - t //<< "H1 { border-width: thin; border: solid; text-align: center }" << endl - << "H1 { 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; + t << "H1 { text-align: center }" << endl; + t << "A.el { text-decoration: none; font-weight: bold }" << endl; + t << "DL.el { margin-left: -1cm }" << endl; + t << "DIV.fragment { width: 100%; border: none; background-color: #eeeeee }" << endl; + t << "DIV.in { margin-left: 16 }" << endl; + t << "A.gl:link { color: #ffffff }" << endl; + t << "A.gl:visited { color: #ffffff }" << endl; + t << "A.gl { text-decoration: none; font-weight: bold; background-color: " << GROUP_COLOR << " }" << endl; + t << endl; endPlainFile(); } } @@ -209,6 +217,10 @@ void HtmlGenerator::writeIndexItem(const char *ref,const char *f, { t << ""; } + //if (Config::htmlHelpFlag && f) + //{ + // htmlHelp->addItem(name,((QCString)f)+".html"); + //} } void HtmlGenerator::writeStartAnnoItem(const char *,const char *f, @@ -219,6 +231,10 @@ void HtmlGenerator::writeStartAnnoItem(const char *,const char *f, t << ""; docify(name); t << " "; + //if (Config::htmlHelpFlag && f) + //{ + // htmlHelp->addItem(name, ((QCString)f)+".html"); + //} } void HtmlGenerator::writeObjectLink(const char *ref,const char *f, @@ -232,6 +248,10 @@ void HtmlGenerator::writeObjectLink(const char *ref,const char *f, t << "\">"; docify(name); t << ""; + //if (Config::htmlHelpFlag && f && htmlHelp->depth()>0) + //{ + // htmlHelp->addItem(name,((QCString)f)+".html"); + //} } void HtmlGenerator::startTextLink(const char *f,const char *anchor) @@ -401,11 +421,26 @@ void HtmlGenerator::endMemberList() } } -void HtmlGenerator::startMemberItem() +// annonymous type: +// 0 = single column right aligned +// 1 = double column left aligned +// 2 = single column left aligned +void HtmlGenerator::startMemberItem(bool inGroup,int annoType) { if (Config::htmlAlignMemberFlag) { - t << ""; + t << ""; + if (inGroup) + t << ""; + else + t << ""; + t << ""; + switch(annoType) + { + case 0: t << ""; break; + case 1: t << ""; break; + default: t << ""; break; + } } else { @@ -413,28 +448,45 @@ void HtmlGenerator::startMemberItem() } } -void HtmlGenerator::insertMemberAlign() +void HtmlGenerator::endMemberItem(bool inGroup, + const char *fileName,const char *headerName,bool) { if (Config::htmlAlignMemberFlag) { - t << " "; + if (inGroup) + { + t << "  " << headerName << " "; + } + else + { + t << ">"; + } + t << ""; + } + t << ""; } + t << endl; } -void HtmlGenerator::endMemberItem() +void HtmlGenerator::insertMemberAlign() { if (Config::htmlAlignMemberFlag) { - t << ""; + t << " "; } - t << endl; } void HtmlGenerator::startMemberDescription() { if (Config::htmlAlignMemberFlag) { - t << ""; + t << "" + ""; } else { @@ -458,7 +510,7 @@ void HtmlGenerator::startMemberSections() { if (Config::htmlAlignMemberFlag) { - t << "" << endl; + t << "
    " << endl; } } @@ -474,7 +526,7 @@ void HtmlGenerator::startMemberHeader() { if (Config::htmlAlignMemberFlag) { - t << "" + // white space + "" + // right vertical table line + "" << endl; +} + +void HtmlGenerator::memberGroupSeparator() +{ + t << "" << endl; +} + void HtmlGenerator::startMemberSubtitle() { - if (Config::htmlAlignMemberFlag) t << "" << endl; } +void HtmlGenerator::startIndexList() +{ + t << "
      " << endl; + //if (Config::htmlHelpFlag) + //{ + // if (htmlHelp->depth()==0) htmlHelp->addItem(lastTitle,lastFile); + // htmlHelp->incDepth(); + //} +} + +void HtmlGenerator::endIndexList() +{ + t << "
    " << endl; + //if (Config::htmlHelpFlag) + //{ + // htmlHelp->decDepth(); + //} +} + +void HtmlGenerator::startAlfabeticalIndexList() +{ + t << "
    " << endl; +} + +void HtmlGenerator::endAlfabeticalIndexList() +{ + t << "
    " << endl; +} + +void HtmlGenerator::writeIndexHeading(const char *s) +{ + t << "
    " << s << "
    " << endl; +} diff --git a/src/htmlgen.h b/src/htmlgen.h index 5eb4484..f742761 100644 --- a/src/htmlgen.h +++ b/src/htmlgen.h @@ -21,6 +21,7 @@ #include "outputgen.h" class QFile; +class HtmlHelp; class HtmlGenerator : public OutputGenerator { @@ -40,6 +41,7 @@ class HtmlGenerator : public OutputGenerator 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); @@ -59,12 +61,15 @@ class HtmlGenerator : public OutputGenerator void newParagraph(); void writeString(const char *text); - void startIndexList() { t << "
      " << endl; } - void endIndexList() { t << "
    " << endl; } + void startIndexList(); + void endIndexList(); void startItemList() { t << "
      " << endl; } void endItemList() { t << "
    " << endl; } void startEnumList() { t << "
      " << endl; } void endEnumList() { t << "
    " << endl; } + void startAlfabeticalIndexList(); + void endAlfabeticalIndexList(); + void writeIndexHeading(const char *s); void writeIndexItem(const char *ref,const char *file,const char *name); void docify(const char *text); void codify(const char *text); @@ -90,9 +95,11 @@ class HtmlGenerator : public OutputGenerator void endMemberSubtitle(); void startMemberList(); void endMemberList(); - void startMemberItem(); + void startMemberItem(bool,int); + void memberGroupSpacing(bool inGroup); + void memberGroupSeparator(); void insertMemberAlign(); - void endMemberItem(); + void endMemberItem(bool,const char *,const char *,bool); void startMemberDescription(); void endMemberDescription(); @@ -115,7 +122,7 @@ class HtmlGenerator : public OutputGenerator void writeChar(char c); void startMemberDoc(const char *,const char *,const char *) { t << endl << "

    "; } - void endMemberDoc() { t << "

    " << endl; } + void endMemberDoc() { t << "" << endl; } void writeDoxyAnchor(const char *clName,const char *anchor, const char *name); void writeLatexSpacing() {} @@ -168,6 +175,7 @@ class HtmlGenerator : public OutputGenerator void startQuickIndexItem(const char *,const char *); void endQuickIndexItem(); void writeFormula(const char *,const char *); + void writeNonBreakableSpace() { t << "   "; } //static void docifyStatic(QTextStream &t,const char *str); @@ -175,9 +183,12 @@ class HtmlGenerator : public OutputGenerator QCString header; QCString footer; QCString lastTitle; + QCString lastFile; HtmlGenerator &operator=(const HtmlGenerator &g); HtmlGenerator(const HtmlGenerator &g); + + static HtmlHelp *htmlHelp; }; #endif diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp new file mode 100644 index 0000000..b1aed98 --- /dev/null +++ b/src/htmlhelp.cpp @@ -0,0 +1,381 @@ +/****************************************************************************** + * + * $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 code is this file is largely based on a contribution from + * Harm van der Heijden + * Please send thanks to him and bug reports to me :-) + */ + +#include +#include +#include +#include + +#include "htmlhelp.h" +#include "config.h" +#include "message.h" + +//---------------------------------------------------------------------------- + +struct IndexField +{ + QCString name; + QCString url; + QCString anchor; + bool link; +}; + +class IndexFieldList : public QList +{ + public: + int compareItems(GCI item1, GCI item2) + { + return stricmp(((IndexField *)item1)->name,((IndexField *)item2)->name); + } +}; + +class IndexFieldListIterator : public QListIterator +{ + public: + IndexFieldListIterator( const IndexFieldList &list) : + QListIterator(list) {} +}; + +class IndexFieldDict : public QDict +{ + public: + IndexFieldDict(int size) : QDict(size) {} +}; + +/*! A helper class for HtmlHelp that manages a two level index in + * alphabetical order + */ +class HtmlHelpIndex +{ + public: + HtmlHelpIndex(); + ~HtmlHelpIndex(); + void addItem(const char *first,const char *second, + const char *url, const char *anchor,bool hasLink); + void writeFields(QTextStream &t); + private: + IndexFieldList *list; + IndexFieldDict *dict; +}; + +/*! Constructs a new HtmlHelp index */ +HtmlHelpIndex::HtmlHelpIndex() +{ + list = new IndexFieldList; + dict = new IndexFieldDict(10007); + list->setAutoDelete(TRUE); +} + +/*! Destroys the HtmlHelp index */ +HtmlHelpIndex::~HtmlHelpIndex() +{ + delete list; + delete dict; +} + +/*! Stores an item in the index if it is not already present. + * Items are stored in alphetical order, by sorting on the + * concatenation of \a level1 and \a level2 (if present). + * + * \param level1 the string at level 1 in the index. + * \param level2 the string at level 2 in the index (or 0 if not applicable). + * \param url the url of the documentation (without .html extension). + * \param anchor the anchor of the documentation within the page. + * \param hasLink if true, the url (without anchor) can be used in the + * level1 item, when writing the header of a list of level2 items. + */ +void HtmlHelpIndex::addItem(const char *level1,const char *level2, + const char *url,const char *anchor,bool hasLink) +{ + QCString key = level1; + if (level2) key+= (QCString)"?" + level2; + if (dict->find(key)==0) // new key + { + //printf(">>>>>>>>> HtmlHelpIndex::addItem(%s,%s,%s,%s)\n", + // level1,level2,url,anchor); + IndexField *f = new IndexField; + f->name = key; + f->url = url; + f->anchor = anchor; + f->link = hasLink; + list->inSort(f); + dict->insert(key,f); + } +} + +/*! Writes the sorted list of index items into a html like list. + * + * An list of calls with name = level1,level2 as follows: + *
    + *    a1,b1
    + *    a1,b2
    + *    a2,b1
    + *    a2,b2
    + *    a3
    + *    a4,b1
    + *  
    + * + * Will result in the following list: + * + *
    + *    a1       -> link to url if hasLink==TRUE
    + *      b1     -> link to url#anchor
    + *      b2     -> link to url#anchor
    + *    a2       -> link to url if hasLink==TRUE
    + *      b1     -> link to url#anchor
    + *      b2     -> link to url#anchor
    + *    a3       -> link to url if hasLink==TRUE
    + *    a4       -> link to url if hasLink==TRUE
    + *      b1     -> link to url#anchor 
    + *  
    + */ +void HtmlHelpIndex::writeFields(QTextStream &t) +{ + IndexFieldListIterator ifli(*list); + IndexField *f; + QCString lastLevel1; + bool level2Started=FALSE; + for (;(f=ifli.current());++ifli) + { + QCString level1,level2; + int i; + if ((i=f->name.find('?'))!=-1) + { + level1 = f->name.left(i); + level2 = f->name.right(f->name.length()-i-1); + } + else + { + level1 = f->name.copy(); + } + + if (level1!=lastLevel1) + { // finish old list at level 2 + if (level2Started) t << " " << endl; + level2Started=FALSE; + + if (level2.isEmpty()) + { + t << "
  • "; + t << "url << ".html"; + if (!f->anchor.isEmpty()) t << "#" << f->anchor; + t << "\">"; + t << "" + "\n"; + } + else + { + if (f->link) + { + t << "
  • "; + t << "url << ".html\">"; + t << "" + "\n"; + } + else + { + t << "
  • "; + t << ""; + t << "" + "\n"; + } + } + } + if (!level2Started && !level2.isEmpty()) + { // start new list at level 2 + t << "
      " << endl; + level2Started=TRUE; + } + else if (level2Started && level2.isEmpty()) + { // end list at level 2 + t << "
    " << endl; + level2Started=FALSE; + } + if (level2Started) + { + t << "
  • "; + t << "url << ".html"; + if (!f->anchor.isEmpty()) t << "#" << f->anchor; + t << "\">"; + t << "" + "\n"; + } + lastLevel1 = level1.copy(); + } +} + +//---------------------------------------------------------------------------- + +HtmlHelp *HtmlHelp::theInstance = 0; + +/*! Constructs an html object. + * The object has to be \link initialize() initialized\endlink before it can + * be used. + */ +HtmlHelp::HtmlHelp() +{ + /* initial depth */ + dc = 0; + cf = kf = 0; + index = new HtmlHelpIndex; +} + +/*! return a reference to the one and only instance of this class. + */ +HtmlHelp *HtmlHelp::getInstance() +{ + if (theInstance==0) theInstance = new HtmlHelp; + return theInstance; +} + +/*! This will create a contents file (index.hhc) and a index file (index.hhk) + * and write the header of those files. + * It also creates a project file (index.hhp) + * \sa finalize() + */ +void HtmlHelp::initialize() +{ + /* open the contents file */ + QCString fName = Config::htmlOutputDir + "/index.hhc"; + cf = new QFile(fName); + if (!cf->open(IO_WriteOnly)) + { + err("Could not open file %s for writing\n",fName.data()); + exit(1); + } + /* Write the header of the contents file */ + cts.setDevice(cf); + cts << "\n" + "\n" + "\n" + "\n" + "\n" + "
      \n"; + + /* open the contents file */ + fName = Config::htmlOutputDir + "/index.hhk"; + kf = new QFile(fName); + if (!kf->open(IO_WriteOnly)) + { + err("Could not open file %s for writing\n",fName.data()); + exit(1); + } + /* Write the header of the contents file */ + kts.setDevice(kf); + kts << "\n" + "\n" + "\n" + "\n" + "\n" + "
        \n"; + + /* Write the project file */ + fName = Config::htmlOutputDir + "/index.hhp"; + QFile f(fName); + if (f.open(IO_WriteOnly)) + { + QTextStream t(&f); + t << "[OPTIONS]\n" + "Compatibility=1.1\n" + "Full-text search=Yes\n" + "Contents file=index.hhc\n" + "Default Window=indexHelp\n" + "Default topic=index.html\n" + "Index file=index.hhk\n" + "Title=" << Config::projectName << endl << endl + << "[FILES]\n" + "index.html"; + f.close(); + } + else + { + err("Could not open file %s for writing\n",fName.data()); + } +} + +/*! Finalizes the HTML help. This will finish and close the + * contents file (index.hhc) and the index file (index.hhk). + * \sa initialize() + */ +void HtmlHelp::finalize() +{ + // end the contents file + cts << "
      \n"; + cts.unsetDevice(); + cf->close(); + delete cf; + + index->writeFields(kts); + + // end the index file + kts << "
    \n"; + kts.unsetDevice(); + kf->close(); + delete kf; +} + +/*! Increase the level of the contents hierarchy. + * This will start a new unnumbered HTML list in contents file. + * \sa decContentsDepth() + */ +int HtmlHelp::incContentsDepth() +{ + int i; for (i=0;i\n"; + return ++dc; +} + +/*! Decrease the level of the contents hierarchy. + * This will end the unnumber HTML list. + * \sa incContentsDepth() + */ +int HtmlHelp::decContentsDepth() +{ + int i; for (i=0;i\n"; + return --dc; +} + +/*! Add an list item to the contents file. + * \param name the name of the item. + * \param ref the URL of to the item. + */ +void HtmlHelp::addContentsItem(const char *name,const char *ref, + const char *anchor) +{ + int i; for (i=0;i"; + cts << ""; + cts << "" + "\n"; +} + +/*! Add an list item to the index file. + * \param name the name of the item. + * \param ref the URL of to the item. + * \sa HtmlHelpIndex + */ +void HtmlHelp::addIndexItem(const char *level1, const char *level2, + const char *ref, const char *anchor) +{ + index->addItem(level1,level2,ref,anchor,TRUE); + index->addItem(level2,level1,ref,anchor,FALSE); +} diff --git a/src/htmlhelp.h b/src/htmlhelp.h new file mode 100644 index 0000000..5856f3c --- /dev/null +++ b/src/htmlhelp.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. + * + * The code is this file is largely based on a contribution from + * Harm van der Heijden + * Please send thanks to him and bug reports to me :-) + */ + +#ifndef HTMLHELP_H +#define HTMLHELP_H + +#include "qtbc.h" +#include + +class QFile; +class HtmlHelpIndex; + +/*! A class that generated the HTML Help specific files. + * These files can be used with the Microsoft HTML Help workshop + * to generate compressed HTML files (.chm). + */ +class HtmlHelp +{ + public: + static HtmlHelp *getInstance(); + void initialize(); + void finalize(); + int incContentsDepth(); + int decContentsDepth(); + /*! return the current depth of the contents tree */ + int contentsDepth() { return dc; } + void addContentsItem(const char *name, const char *ref, + const char *anchor = 0); + void addIndexItem(const char *level1, const char *level2, + const char *ref, const char *anchor); + private: + HtmlHelp(); + QFile *cf,*kf; + QTextStream cts,kts; + HtmlHelpIndex *index; + int dc; + static HtmlHelp *theInstance; +}; + +#endif /* HTMLHELP_H */ diff --git a/src/index.cpp b/src/index.cpp index d8bd56c..3ad97d9 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -30,6 +30,7 @@ #include "util.h" #include "groupdef.h" #include "language.h" +#include "htmlhelp.h" //---------------------------------------------------------------------------- @@ -122,7 +123,7 @@ bool hasVisibleRoot(BaseClassList *bcl) for ( ; bcli.current(); ++bcli) { ClassDef *cd=bcli.current()->classDef; - if (cd->isVisibleExt()) return TRUE; + if (cd->isVisibleInHierarchy()) return TRUE; hasVisibleRoot(cd->baseClasses()); } return FALSE; @@ -132,20 +133,27 @@ bool hasVisibleRoot(BaseClassList *bcl) void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper) { + HtmlHelp *htmlHelp=0; + bool hasHtmlHelp = Config::generateHtml && Config::htmlHelpFlag; + if (Config::generateHtml && Config::htmlHelpFlag) + { + htmlHelp = HtmlHelp::getInstance(); + } BaseClassListIterator bcli(*bcl); bool started=FALSE; for ( ; bcli.current() ; ++bcli) { ClassDef *cd=bcli.current()->classDef; - if (cd->isVisibleExt() && hasVisibleRoot(cd->baseClasses())) + if (cd->isVisibleInHierarchy() && hasVisibleRoot(cd->baseClasses())) { if (!started) { ol.startIndexList(); + if (hasHtmlHelp) htmlHelp->incContentsDepth(); started=TRUE; } //printf("Passed...\n"); - if (cd->hasDocumentation() || cd->isReference()) + if (cd->isLinkable()) { ol.writeIndexItem(cd->getReference(),cd->getOutputFileBase(),cd->name()); if (cd->isReference()) @@ -154,10 +162,19 @@ void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper) ol.docify(" [external]"); ol.endTypewriter(); } + if (hasHtmlHelp) + { + htmlHelp->addContentsItem(cd->name(),cd->getOutputFileBase()); + //cd->writeMembersToContents(); + } } else { ol.writeIndexItem(0,0,cd->name()); + if (hasHtmlHelp) + { + htmlHelp->addContentsItem(cd->name(),"nodoc"); + } } if (!cd->visited && !hideSuper && cd->superClasses()->count()>0) { @@ -166,7 +183,11 @@ void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper) } } } - if (started) ol.endIndexList(); + if (started) + { + ol.endIndexList(); + if (hasHtmlHelp) htmlHelp->decContentsDepth(); + } } //---------------------------------------------------------------------------- @@ -175,6 +196,13 @@ void writeClassHierarchy(OutputList &ol) { initClassHierarchy(&classList); + HtmlHelp *htmlHelp=0; + bool hasHtmlHelp = Config::generateHtml && Config::htmlHelpFlag; + if (Config::generateHtml && Config::htmlHelpFlag) + { + htmlHelp = HtmlHelp::getInstance(); + } + bool started=FALSE; ClassListIterator cli(classList); for (;cli.current(); ++cli) @@ -182,14 +210,15 @@ void writeClassHierarchy(OutputList &ol) ClassDef *cd=cli.current(); if (!hasVisibleRoot(cd->baseClasses())) { - if (cd->isVisibleExt()) + if (cd->isVisibleInHierarchy()) // WAS: isVisible()! { if (!started) { ol.startIndexList(); + if (hasHtmlHelp) htmlHelp->incContentsDepth(); started=TRUE; } - if (cd->hasDocumentation() || cd->isReference()) + if (cd->isLinkable()) { ol.writeIndexItem(cd->getReference(),cd->getOutputFileBase(),cd->name()); if (cd->isReference()) @@ -198,10 +227,16 @@ void writeClassHierarchy(OutputList &ol) ol.docify(" [external]"); ol.endTypewriter(); } + if (hasHtmlHelp) + { + htmlHelp->addContentsItem(cd->name(),cd->getOutputFileBase()); + //cd->writeMembersToContents(); + } } else { ol.writeIndexItem(0,0,cd->name()); + if (hasHtmlHelp) htmlHelp->addContentsItem(cd->name(),"nodoc"); } } if (!cd->visited && cd->superClasses()->count()>0) @@ -211,11 +246,16 @@ void writeClassHierarchy(OutputList &ol) } } } - if (started) ol.endIndexList(); + if (started) + { + ol.endIndexList(); + if (hasHtmlHelp) htmlHelp->decContentsDepth(); + } } //---------------------------------------------------------------------------- +// TODO: let this function return the real number of items in the hierarchy. int countClassHierarchy() { initClassHierarchy(&classList); @@ -236,8 +276,15 @@ void writeHierarchicalIndex(OutputList &ol) ol.disable(OutputGenerator::Man); startFile(ol,"hierarchy","Hierarchical Index"); startTitle(ol); - parseText(ol,Config::projectName+" "+theTranslator->trClassHierarchy()); + QCString title = Config::projectName+" "+theTranslator->trClassHierarchy(); + parseText(ol,title); endTitle(ol,0); + HtmlHelp *htmlHelp = 0; + if (Config::generateHtml && Config::htmlHelpFlag) + { + htmlHelp = HtmlHelp::getInstance(); + htmlHelp->addContentsItem(title,"hierarchy"); + } parseText(ol,theTranslator->trClassHierarchyDescription()); ol.newParagraph(); writeClassHierarchy(ol); @@ -258,7 +305,7 @@ int countFiles() FileDef *fd; for (;(fd=fni.current());++fni) { - if (fd->hasDocumentation()) count++; + if (fd->isLinkable()) count++; } } return count; @@ -272,8 +319,17 @@ void writeFileIndex(OutputList &ol) ol.disable(OutputGenerator::Man); startFile(ol,"files","File Index"); startTitle(ol); - parseText(ol,Config::projectName+" "+theTranslator->trFileList()); + QCString title = Config::projectName+" "+theTranslator->trFileList(); + parseText(ol,title); endTitle(ol,0); + HtmlHelp *htmlHelp = 0; + bool hasHtmlHelp = Config::generateHtml && Config::htmlHelpFlag; + if (hasHtmlHelp) + { + htmlHelp = HtmlHelp::getInstance(); + htmlHelp->addContentsItem(title,"files"); + htmlHelp->incContentsDepth(); + } ol.newParagraph(); parseText(ol,theTranslator->trFileListDescription(Config::extractAllFlag)); ol.newParagraph(); @@ -285,17 +341,14 @@ void writeFileIndex(OutputList &ol) FileDef *fd=fn->first(); while (fd) { - if (fd->hasDocumentation() && !fd->isReference()) + if (fd->isLinkableInProject()) { //ol.writeIndexItem(fd->getReference(),fd->diskName(), // fd->name()); QCString path; if (Config::fullPathNameFlag) { - path=fd->getPath().copy(); - // strip part of the path - if (path.left(Config::stripFromPath.length())==Config::stripFromPath) - path=path.right(path.length()-Config::stripFromPath.length()); + path=stripFromPath(fd->getPath().copy()); } ol.writeStartAnnoItem("file", @@ -319,12 +372,20 @@ void writeFileIndex(OutputList &ol) } ol.docify(")"); ol.writeEndAnnoItem(fd->name()); + if (hasHtmlHelp) + { + htmlHelp->addContentsItem(fd->name(),fd->getOutputFileBase()); + } } fd=fn->next(); } fn=inputNameList.next(); } ol.endIndexList(); + if (hasHtmlHelp) + { + htmlHelp->decContentsDepth(); + } endFile(ol); ol.enable(OutputGenerator::Man); } @@ -337,7 +398,7 @@ int countNamespaces() NamespaceDef *nd; for (;(nd=nli.current());++nli) { - if (nd->isVisible()) count++; + if (nd->isLinkableInProject()) count++; } return count; } @@ -350,8 +411,17 @@ void writeNamespaceIndex(OutputList &ol) ol.disable(OutputGenerator::Man); startFile(ol,"namespaces","Namespace Index"); startTitle(ol); - parseText(ol,Config::projectName+" "+theTranslator->trNamespaceList()); + QCString title = Config::projectName+" "+theTranslator->trNamespaceList(); + parseText(ol,title); endTitle(ol,0); + HtmlHelp *htmlHelp = 0; + bool hasHtmlHelp = Config::generateHtml && Config::htmlHelpFlag; + if (hasHtmlHelp) + { + htmlHelp = HtmlHelp::getInstance(); + htmlHelp->addContentsItem(title,"namespaces"); + htmlHelp->incContentsDepth(); + } ol.newParagraph(); parseText(ol,theTranslator->trNamespaceListDescription(Config::extractAllFlag)); ol.newParagraph(); @@ -360,7 +430,7 @@ void writeNamespaceIndex(OutputList &ol) NamespaceDef *nd=namespaceList.first(); while (nd) { - if (nd->isVisible()) + if (nd->isLinkableInProject()) { ol.writeStartAnnoItem("namespace",nd->getOutputFileBase(),0,nd->name()); ol.docify(" ("); @@ -379,10 +449,18 @@ void writeNamespaceIndex(OutputList &ol) } ol.docify(")"); ol.writeEndAnnoItem(nd->name()); + if (hasHtmlHelp) + { + htmlHelp->addContentsItem(nd->name(),nd->getOutputFileBase()); + } } nd=namespaceList.next(); } ol.endIndexList(); + if (hasHtmlHelp) + { + htmlHelp->decContentsDepth(); + } endFile(ol); ol.enable(OutputGenerator::Man); } @@ -397,7 +475,7 @@ int countAnnotatedClasses() ClassDef *cd; for (;(cd=cli.current());++cli) { - if (!cd->isReference() && cd->isVisible()) + if (cd->isLinkableInProject()) { //printf("Annotated class %s\n",cd->name().data()); count++; @@ -417,20 +495,15 @@ void writeAnnotatedClassList(OutputList &ol) ClassDef *cd; for (;(cd=cli.current());++cli) { - if (!cd->isReference() && - //!cd->name().isEmpty() && cd->name()[0]!='@' && - //(cd->protection()!=Private || Config::extractPrivateFlag) && - //(cd->hasDocumentation() || !hideClassFlag) - cd->isVisible() - ) + if (cd->isLinkableInProject()) { QCString 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 + case ClassDef::Class: type="class"; break; + case ClassDef::Struct: type="struct"; break; + case ClassDef::Union: type="union"; break; + default: type="interface"; break; } ol.writeStartAnnoItem(type,cd->getOutputFileBase(),0,cd->name()); ol.docify(" ("); @@ -449,6 +522,12 @@ void writeAnnotatedClassList(OutputList &ol) } ol.docify(")"); ol.writeEndAnnoItem(cd->name()); + if (Config::generateHtml && Config::htmlHelpFlag) + { + HtmlHelp::getInstance()->addContentsItem( + cd->name(),cd->getOutputFileBase()); + //cd->writeMembersToContents(); + } } cd=classList.next(); } @@ -457,6 +536,50 @@ void writeAnnotatedClassList(OutputList &ol) //---------------------------------------------------------------------------- +void writeAlfabeticalClassList(OutputList &ol) +{ + ol.startAlfabeticalIndexList(); + //ClassDef *cd=classList.first(); + //while (cd) + ClassListIterator cli(classList); + ClassDef *cd; + char startLetter=0; + for (;(cd=cli.current());++cli) + { + if (cd->isLinkableInProject()) + { + if (cd->name().at(0)!=startLetter) + { + startLetter=cd->name().at(0); + char s[2]; s[0]=startLetter; s[1]=0; + ol.writeIndexHeading(s); + } + ol.writeObjectLink(cd->getReference(), + cd->getOutputFileBase(),0,cd->name()); + ol.lineBreak(); + } + cd=classList.next(); + } + ol.endAlfabeticalIndexList(); +} + +//---------------------------------------------------------------------------- + +void writeAlphabeticalIndex(OutputList &ol) +{ + ol.disableAllBut(OutputGenerator::Html); + if (annotatedClasses==0) return; + startFile(ol,"classes.html","Alfabetical index"); + startTitle(ol); + parseText(ol,Config::projectName+" "+theTranslator->trCompoundIndex()); + endTitle(ol,0); + writeAlfabeticalClassList(ol); + endFile(ol); + ol.enableAll(); +} + +//---------------------------------------------------------------------------- + void writeAnnotatedIndex(OutputList &ol) { if (annotatedClasses==0) return; @@ -465,10 +588,23 @@ void writeAnnotatedIndex(OutputList &ol) ol.disable(OutputGenerator::Man); startFile(ol,"annotated","Annotated Index"); startTitle(ol); - parseText(ol,Config::projectName+" "+theTranslator->trCompoundList()); + QCString title = Config::projectName+" "+theTranslator->trCompoundList(); + parseText(ol,title); endTitle(ol,0); + HtmlHelp *htmlHelp = 0; + if (Config::generateHtml && Config::htmlHelpFlag) + { + htmlHelp = HtmlHelp::getInstance(); + htmlHelp->addContentsItem(title,"annotated"); + htmlHelp->incContentsDepth(); + } parseText(ol,theTranslator->trCompoundListDescription()); writeAnnotatedClassList(ol); + if (Config::generateHtml && Config::htmlHelpFlag) + { + htmlHelp->decContentsDepth(); + } + endFile(ol); ol.enable(OutputGenerator::Man); } @@ -487,10 +623,12 @@ void writeMemberList(OutputList &ol) while (md && !found) { ClassDef *cd; - if ((md->isFriend() || md->protection()!=Private || Config::extractPrivateFlag) && - !md->isReference() && md->hasDocumentation() && - md->name()[0]!='@' && (cd=md->memberClass()) && - cd->isVisible() + if (//(md->isFriend() || md->protection()!=Private || Config::extractPrivateFlag) && + //!md->isReference() && md->hasDocumentation() && + // md->name()[0]!='@' && + md->isLinkableInProject() && + (cd=md->memberClass()) && + cd->isLinkableInProject() ) { found=TRUE; @@ -511,10 +649,11 @@ void writeMemberList(OutputList &ol) while (md) { ClassDef *cd=md->memberClass(); - if (cd && (md->isFriend() || md->protection()!=Private || Config::extractPrivateFlag) && - !md->isReference() && md->hasDocumentation() && + if (//cd && (md->isFriend() || md->protection()!=Private || Config::extractPrivateFlag) && + //!md->isReference() && md->hasDocumentation() && + md->isLinkableInProject() && prevName!=cd->name() && - cd->isVisible() + cd->isLinkableInProject() ) { if (count==0) @@ -548,16 +687,32 @@ int countClassMembers() ClassDef *cd; while (md && !found) { - if ((md->isFriend() || md->protection()!=Private || Config::extractPrivateFlag) && - !md->isReference() && !md->isRelated() && md->hasDocumentation() && - md->name()[0]!='@' && (cd=md->memberClass()) && cd->isVisible()) - otherMd=md; - if ((md->isFriend() || md->protection()!=Private || Config::extractPrivateFlag) && - !md->isReference() && md->isRelated() && md->hasDocumentation() && - md->name()[0]!='@' && (cd=md->memberClass()) && cd->isVisible()) - found=TRUE; - else - md=mn->next(); + if (//(md->isFriend() || md->protection()!=Private || Config::extractPrivateFlag) && + //!md->isReference() && !md->isRelated() && md->hasDocumentation() && + //md->name()[0]!='@' && (cd=md->memberClass()) && cd->isLinkable()) + md->isLinkableInProject() && + !md->isRelated() && + (cd=md->memberClass()) && + cd->isLinkableInProject() + ) + { + if (!md->isRelated()) + otherMd=md; + if (md->isRelated()) + found=TRUE; + } + + // otherMd=md; + //if (//(md->isFriend() || md->protection()!=Private || Config::extractPrivateFlag) && + // //!md->isReference() && md->isRelated() && md->hasDocumentation() && + // //md->name()[0]!='@' && (cd=md->memberClass()) && cd->isLinkable() + // md->isLinkableInProject() && + // md->isRelated() && + // (cd=md->memberClass()) && + // cd->isLinkableInProject() + // ) + // found=TRUE; + md=mn->next(); } if (found || otherMd) count++; mn=memberNameList.next(); @@ -597,13 +752,15 @@ void writeFileMemberList(OutputList &ol) { FileDef *fd=md->getFileDef() ? md->getFileDef() : md->getFileDec(); bool hasDocs = - (md->getFileDef() && md->getFileDef()->hasDocumentation()) || - (md->getFileDec() && md->getFileDec()->hasDocumentation()); + (md->getFileDef() && md->getFileDef()->isLinkableInProject()) || + (md->getFileDec() && md->getFileDec()->isLinkableInProject()); if (fd && hasDocs && - !md->isReference() && - md->hasDocumentation() && - md->name()[0]!='@') found=TRUE; + md->isLinkableInProject() + //!md->isReference() && + //md->hasDocumentation() && + //md->name()[0]!='@' + ) found=TRUE; else md=mn->next(); } @@ -621,12 +778,13 @@ void writeFileMemberList(OutputList &ol) { FileDef *fd=md->getFileDef() ? md->getFileDef() : md->getFileDec(); bool hasDocs = - (md->getFileDef() && md->getFileDef()->hasDocumentation()) || - (md->getFileDec() && md->getFileDec()->hasDocumentation()); + (md->getFileDef() && md->getFileDef()->isLinkableInProject()) || + (md->getFileDec() && md->getFileDec()->isLinkableInProject()); if (fd && hasDocs && - !md->isReference() && - md->hasDocumentation() && - md->name()[0]!='@' && + md->isLinkableInProject() && + //!md->isReference() && + //md->hasDocumentation() && + //md->name()[0]!='@' && prevName!=fd->name()) { if (count==0) @@ -663,9 +821,8 @@ void writeNamespaceMemberList(OutputList &ol) while (md && !found) { NamespaceDef *nd=md->getNamespace(); - if (nd && nd->isVisible() && - !md->isReference() && md->hasDocumentation() && - !md->name().isEmpty() && md->name().at(0)!='@') found=TRUE; + if (nd && nd->isLinkableInProject() && md->isLinkableInProject()) + found=TRUE; else md=mn->next(); } @@ -682,9 +839,7 @@ void writeNamespaceMemberList(OutputList &ol) while (md) { NamespaceDef *nd=md->getNamespace(); - if (nd && nd->isVisible() && - !md->isReference() && md->hasDocumentation() && - !md->name().isEmpty() && md->name().at(0)!='@' && + if (nd && nd->isLinkableInProject() && md->isLinkableInProject() && prevName!=nd->name() ) { @@ -718,10 +873,7 @@ int countNamespaceMembers() while (md && !found) { NamespaceDef *nd=md->getNamespace(); - if (nd && nd->isVisible() && - !md->isReference() && md->hasDocumentation() && - !md->name().isEmpty() && md->name().at(0)!='@' - ) + if (nd && nd->isLinkableInProject() && md->isLinkableInProject()) found=TRUE; else md=mn->next(); @@ -745,11 +897,10 @@ int countFileMembers() bool found=FALSE; while (md && !found) { - if (!md->isReference() && md->hasDocumentation() && - !md->name().isEmpty() && md->name()[0]!='@' && - (((fd=md->getFileDef()) && fd->hasDocumentation()) + if (md->isLinkableInProject() && + (((fd=md->getFileDef()) && fd->isLinkableInProject()) || - ((fd=md->getFileDec()) && fd->hasDocumentation()) + ((fd=md->getFileDec()) && fd->isLinkableInProject()) ) ) found=TRUE; @@ -800,45 +951,79 @@ void writeNamespaceMemberIndex(OutputList &ol) //---------------------------------------------------------------------------- +int countIncludeFiles() +{ + int count=0; + FileDef *fd=includeFiles.first(); + while (fd) + { + if (fd->isLinkableInProject()) + { + count++; + } + fd=includeFiles.next(); + } + return count; +} + void writeHeaderFileList(OutputList &ol) { - if (includeFiles.count()>0) + bool started=FALSE; + FileDef *fd=includeFiles.first(); + while (fd) { - ol.startItemList(); - FileDef *fd=includeFiles.first(); - while (fd) + if (fd->isLinkableInProject()) { + if (!started) + { + started=TRUE; + ol.startItemList(); + } ol.writeListItem(); QCString path; if (Config::fullPathNameFlag) { - path=fd->getPath().copy(); - // strip part of the path - if (path.left(Config::stripFromPath.length())==Config::stripFromPath) - path=path.right(path.length()-Config::stripFromPath.length()); + path=stripFromPath(fd->getPath().copy()); } if (!path.isEmpty()) ol.docify(path); ol.writeObjectLink(0,fd->includeName(),0,fd->name()); ol.writeString("\n"); - fd=includeFiles.next(); - } - ol.endItemList(); - } + if (Config::generateHtml && Config::htmlHelpFlag) + { + HtmlHelp::getInstance()->addContentsItem( + fd->name(),fd->includeName()); + } + } + fd=includeFiles.next(); + } + if (started) ol.endItemList(); } //---------------------------------------------------------------------------- void writeHeaderIndex(OutputList &ol) { - if (includeFiles.count()==0) return; + if (documentedIncludeFiles==0) return; ol.disable(OutputGenerator::Man); ol.disable(OutputGenerator::Latex); startFile(ol,"headers","Header File Index"); startTitle(ol); - parseText(ol,Config::projectName+" "+theTranslator->trHeaderFiles()); + QCString title = Config::projectName+" "+theTranslator->trHeaderFiles(); + parseText(ol,title); endTitle(ol,0); + HtmlHelp *htmlHelp = 0; + if (Config::generateHtml && Config::htmlHelpFlag) + { + htmlHelp = HtmlHelp::getInstance(); + htmlHelp->addContentsItem(title,"headers"); + htmlHelp->incContentsDepth(); + } parseText(ol,theTranslator->trHeaderFilesDescription()); writeHeaderFileList(ol); + if (Config::generateHtml && Config::htmlHelpFlag) + { + htmlHelp->decContentsDepth(); + } endFile(ol); ol.enable(OutputGenerator::Latex); ol.enable(OutputGenerator::Man); @@ -852,8 +1037,17 @@ void writeExampleIndex(OutputList &ol) ol.disable(OutputGenerator::Man); startFile(ol,"examples","Example Index"); startTitle(ol); - parseText(ol,Config::projectName+" "+theTranslator->trExamples()); + QCString title = Config::projectName+" "+theTranslator->trExamples(); + parseText(ol,title); endTitle(ol,0); + HtmlHelp *htmlHelp = 0; + bool hasHtmlHelp = Config::generateHtml && Config::htmlHelpFlag; + if (hasHtmlHelp) + { + htmlHelp = HtmlHelp::getInstance(); + htmlHelp->addContentsItem(title,"examples"); + htmlHelp->incContentsDepth(); + } parseText(ol,theTranslator->trExamplesDescription()); ol.startIndexList(); PageInfo *pi=exampleList.first(); @@ -864,15 +1058,21 @@ void writeExampleIndex(OutputList &ol) if (!pi->title.isEmpty()) { ol.writeObjectLink(0,n,0,pi->title); + if (hasHtmlHelp) htmlHelp->addContentsItem(pi->title,n); } else { ol.writeObjectLink(0,n,0,pi->name); + if (hasHtmlHelp) htmlHelp->addContentsItem(pi->name,n); } ol.writeString("\n"); pi=exampleList.next(); } ol.endIndexList(); + if (hasHtmlHelp) + { + htmlHelp->decContentsDepth(); + } endFile(ol); ol.enable(OutputGenerator::Man); } @@ -885,8 +1085,17 @@ void writePageIndex(OutputList &ol) ol.disable(OutputGenerator::Man); startFile(ol,"pages","Page Index"); startTitle(ol); - ol.docify(Config::projectName+" "+theTranslator->trRelatedPages()); + QCString title = Config::projectName+" "+theTranslator->trRelatedPages(); + ol.docify(title); endTitle(ol,0); + HtmlHelp *htmlHelp = 0; + bool hasHtmlHelp = Config::generateHtml && Config::htmlHelpFlag; + if (hasHtmlHelp) + { + htmlHelp = HtmlHelp::getInstance(); + htmlHelp->addContentsItem(title,"pages"); + htmlHelp->incContentsDepth(); + } parseText(ol,theTranslator->trRelatedPagesDescription()); ol.startIndexList(); PageInfo *pi=pageList.first(); @@ -907,9 +1116,14 @@ void writePageIndex(OutputList &ol) ol.writeListItem(); ol.writeObjectLink(0,pageName,0,pageTitle); ol.writeString("\n"); + if (hasHtmlHelp) htmlHelp->addContentsItem(pageTitle,pageName); pi=pageList.next(); } ol.endIndexList(); + if (hasHtmlHelp) + { + htmlHelp->decContentsDepth(); + } endFile(ol); ol.enable(OutputGenerator::Man); } @@ -960,10 +1174,23 @@ void writeGroupIndex(OutputList &ol) ol.disable(OutputGenerator::Man); startFile(ol,"modules","Module Index"); startTitle(ol); - parseText(ol,Config::projectName+" "+theTranslator->trModules()); + QCString title = Config::projectName+" "+theTranslator->trModules(); + parseText(ol,title); endTitle(ol,0); + HtmlHelp *htmlHelp = 0; + bool hasHtmlHelp = Config::generateHtml && Config::htmlHelpFlag; + if (hasHtmlHelp) + { + htmlHelp = HtmlHelp::getInstance(); + htmlHelp->addContentsItem(title,"modules"); + htmlHelp->incContentsDepth(); + } parseText(ol,theTranslator->trModulesDescription()); writeGroupList(ol); + if (hasHtmlHelp) + { + htmlHelp->decContentsDepth(); + } endFile(ol); ol.enable(OutputGenerator::Man); } diff --git a/src/index.h b/src/index.h index a472a7a..ad17339 100644 --- a/src/index.h +++ b/src/index.h @@ -43,6 +43,7 @@ class OutputList; void writeIndex(OutputList &ol); void writeHierarchicalIndex(OutputList &ol); +void writeAlphabeticalIndex(OutputList &ol); void writeClassHierarchy(OutputList &ol); void writeFileIndex(OutputList &ol); void writeAnnotatedIndex(OutputList &ol); @@ -66,5 +67,6 @@ int countGroups(); int countNamespaces(); int countAnnotatedClasses(); int countNamespaceMembers(); +int countIncludeFiles(); #endif diff --git a/src/latexgen.cpp b/src/latexgen.cpp index 2f49efa..3834871 100644 --- a/src/latexgen.cpp +++ b/src/latexgen.cpp @@ -49,6 +49,7 @@ LatexGenerator::LatexGenerator() { dir=Config::latexOutputDir; col=0; + insideTabbing=FALSE; } LatexGenerator::~LatexGenerator() @@ -196,7 +197,7 @@ void LatexGenerator::startIndexSection(IndexSections is) bool found=FALSE; while (gd && !found) { - if (gd->hasDocumentation() || gd->countMembers()>0) + if (gd->isLinkableInProject() || gd->countMembers()>0) { if (Config::compactLatexFlag) t << "\\section"; else t << "\\chapter"; t << "{"; //Module Documentation}\n"; @@ -212,7 +213,7 @@ void LatexGenerator::startIndexSection(IndexSections is) bool found=FALSE; while (nd && !found) { - if (nd->hasDocumentation()) + if (nd->isLinkableInProject()) { if (Config::compactLatexFlag) t << "\\section"; else t << "\\chapter"; t << "{"; // Namespace Documentation}\n": @@ -228,7 +229,7 @@ void LatexGenerator::startIndexSection(IndexSections is) bool found=FALSE; while (cd && !found) { - if (!cd->isReference() && cd->isVisible()) + if (cd->isLinkableInProject()) { if (Config::compactLatexFlag) t << "\\section"; else t << "\\chapter"; t << "{"; //Compound Documentation}\n"; @@ -247,7 +248,7 @@ void LatexGenerator::startIndexSection(IndexSections is) FileDef *fd=fn->first(); while (fd) { - if (fd->hasDocumentation() && !fd->isReference()) + if (fd->isLinkableInProject()) { if (isFirst) { @@ -317,7 +318,7 @@ void LatexGenerator::endIndexSection(IndexSections is) bool found=FALSE; while (gd && !found) { - if (gd->hasDocumentation() || gd->countMembers()>0) + if (gd->isLinkableInProject() || gd->countMembers()>0) { t << "}\n\\input{" << gd->getOutputFileBase() << "}\n"; found=TRUE; @@ -326,7 +327,7 @@ void LatexGenerator::endIndexSection(IndexSections is) } while (gd) { - if (gd->hasDocumentation() || gd->countMembers()>0) + if (gd->isLinkableInProject() || gd->countMembers()>0) { if (Config::compactLatexFlag) t << "\\input"; else t << "\\include"; t << "{" << gd->getOutputFileBase() << "}\n"; @@ -341,7 +342,7 @@ void LatexGenerator::endIndexSection(IndexSections is) bool found=FALSE; while (nd && !found) { - if (nd->hasDocumentation() || nd->countMembers()>0) + if (nd->isLinkableInProject() || nd->countMembers()>0) { t << "}\n\\input{" << nd->getOutputFileBase() << "}\n"; found=TRUE; @@ -350,7 +351,7 @@ void LatexGenerator::endIndexSection(IndexSections is) } while (nd) { - if (nd->hasDocumentation() || nd->countMembers()>0) + if (nd->isLinkableInProject() || nd->countMembers()>0) { if (Config::compactLatexFlag) t << "\\input"; else t << "\\include"; t << "{" << nd->getOutputFileBase() << "}\n"; @@ -365,11 +366,7 @@ void LatexGenerator::endIndexSection(IndexSections is) 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 (cd->isLinkableInProject()) { t << "}\n\\input{" << cd->getOutputFileBase() << "}\n"; found=TRUE; @@ -378,11 +375,7 @@ void LatexGenerator::endIndexSection(IndexSections is) } while (cd) { - //if (cd->classFile()[0]!='@' && !cd->getReference() && - // (cd->hasDocumentation() || !hideClassFlag) && - // (cd->protection()!=Private || extractPrivateFlag) - // ) - if (!cd->isReference() && cd->isVisible()) + if (cd->isLinkableInProject()) { if (Config::compactLatexFlag) t << "\\input"; else t << "\\include"; t << "{" << cd->getOutputFileBase() << "}\n"; @@ -400,7 +393,7 @@ void LatexGenerator::endIndexSection(IndexSections is) FileDef *fd=fn->first(); while (fd) { - if (fd->hasDocumentation() && !fd->isReference()) + if (fd->isLinkableInProject()) { if (isFirst) { @@ -791,13 +784,18 @@ void LatexGenerator::docify(const char *str) case '^': t << "$^\\wedge$"; break; case '&': t << "\\&"; break; case '*': t << "$\\ast$"; break; - case '_': t << "\\_\\-"; break; + case '_': t << "\\_"; + if (!insideTabbing) t << "\\-"; + break; case '{': t << "\\{"; break; case '}': t << "\\}"; break; case '<': t << "$<$"; break; case '>': t << "$>$"; break; case '|': t << "$|$"; break; case '~': t << "$\\sim$"; break; + case ']': if (pc=='[') t << "$\\,$"; + t << "]"; + break; case '-': if (*p=='>') { t << " $\\rightarrow$ "; p++; } else @@ -824,7 +822,7 @@ void LatexGenerator::docify(const char *str) } else // ascii char => see if we can insert hypenation hint { - if (isupper(c) && islower(pc)) t << "\\-"; + if (isupper(c) && islower(pc) && !insideTabbing) t << "\\-"; t << (char)c; } } @@ -900,7 +898,7 @@ void LatexGenerator::docify(const char *str) default: // normal ascii char { // see if we can insert an hyphenation hint - if (isupper(c) && islower(pc)) t << "\\-"; + if (isupper(c) && islower(pc) && !insideTabbing) t << "\\-"; t << (char)c; } } @@ -955,3 +953,56 @@ void LatexGenerator::writeFormula(const char *,const char *text) { t << text; } + +void LatexGenerator::startMemberItem(bool,int annType) +{ + if (!insideTabbing) + { + t << "\\item " << endl; + switch(annType) + { + case 0: break; + case 1: + default: + t << "\\begin{tabbing}" << endl; + t << "xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=xx\\=\\kill" << endl; + insideTabbing=TRUE; + break; + } + } +} + +void LatexGenerator::endMemberItem(bool,const char *,const char *,bool endItem) +{ + if (endItem) + { + t << endl << "\\end{tabbing}"; + insideTabbing=FALSE; + } + if (insideTabbing) + { + t << "\\\\"; + } + t << endl; +} + +void LatexGenerator::writeNonBreakableSpace() +{ + if (insideTabbing) + t << "\\>"; + else + t << "\\ "; +} + +void LatexGenerator::startMemberList() +{ + if (!insideTabbing) + t << "\\begin{CompactItemize}" << endl; +} + +void LatexGenerator::endMemberList() +{ + if (!insideTabbing) + t << "\\end{CompactItemize}" << endl; +} + diff --git a/src/latexgen.h b/src/latexgen.h index cfd8230..06f8ea8 100644 --- a/src/latexgen.h +++ b/src/latexgen.h @@ -63,6 +63,9 @@ class LatexGenerator : public OutputGenerator void endItemList() { t << "\\end{CompactItemize}" << endl; } void startEnumList() { t << "\\begin{enumerate}" << endl; } void endEnumList() { t << "\\end{enumerate}" << endl; } + void startAlfabeticalIndexList() {} + void endAlfabeticalIndexList() {} + void writeIndexHeading(const char *) {} void writeIndexItem(const char *ref,const char *file,const char *name); void docify(const char *text); void codify(const char *text); @@ -85,10 +88,12 @@ class LatexGenerator : public OutputGenerator void endMemberHeader() { endGroupHeader(); } void startMemberSubtitle() {} void endMemberSubtitle() {} - void startMemberList() { t << "\\begin{CompactItemize}" << endl; } - void endMemberList() { t << "\\end{CompactItemize}" << endl; } - void startMemberItem() { t << "\\item " << endl; } - void endMemberItem() { t << endl; } + void startMemberList(); + void endMemberList(); + void startMemberItem(bool,int); + void endMemberItem(bool,const char *,const char *,bool); + void memberGroupSpacing(bool) {} + void memberGroupSeparator() {} void insertMemberAlign() {} void writeRuler() { t << "\\vspace{0.4cm}\\hrule\\vspace{0.2cm}"; } @@ -173,6 +178,7 @@ class LatexGenerator : public OutputGenerator void startQuickIndexItem(const char *,const char *) {} void endQuickIndexItem() {} void writeFormula(const char *,const char *); + void writeNonBreakableSpace(); //static void docifyStatic(QTextStream &t,const char *str); @@ -180,6 +186,7 @@ class LatexGenerator : public OutputGenerator LatexGenerator(const LatexGenerator &); LatexGenerator &operator=(const LatexGenerator &); int col; + bool insideTabbing; }; #endif diff --git a/src/logos.cpp b/src/logos.cpp index ac6e782..dbc47ff 100644 --- a/src/logos.cpp +++ b/src/logos.cpp @@ -19,6 +19,15 @@ #include "qtbc.h" #include + +unsigned char null_data[] = { + 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0x80, 0xff, + 0x00, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3b +}; +unsigned int null_len = 43; + 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, @@ -490,6 +499,18 @@ unsigned char search_data[] = { }; unsigned int search_len = 2010; +void writeNullImage(const char *dir) +{ + QCString fileName=(QCString)dir+"/null.gif"; + QFile f(fileName); + if (f.open(IO_WriteOnly)) + f.writeBlock((char *)null_data,null_len); + else + { + fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data()); + } + f.close(); +} void writeLogo(const char *dir) { diff --git a/src/logos.h b/src/logos.h index 1054fdb..dc2ec51 100644 --- a/src/logos.h +++ b/src/logos.h @@ -18,6 +18,7 @@ #define LOGOS_H extern void writeLogo(const char *dir); +extern void writeNullImage(const char *dir); extern void writeSearchButton(const char *dir); #endif diff --git a/src/mangen.cpp b/src/mangen.cpp index 056bc90..963460b 100644 --- a/src/mangen.cpp +++ b/src/mangen.cpp @@ -31,6 +31,7 @@ ManGenerator::ManGenerator() : OutputGenerator() paragraph=FALSE; col=0; upperCase=FALSE; + insideTabbing=FALSE; } ManGenerator::~ManGenerator() @@ -342,3 +343,38 @@ void ManGenerator::endDescItem() t << "\" 1c" << endl; firstCol=TRUE; } + +void ManGenerator::startMemberItem(bool,int annType) +{ + if (firstCol && !insideTabbing) t << ".in +1c\n"; + t << "\n.ti -1c\n.RI \""; + firstCol=FALSE; + if (annType!=0) insideTabbing=TRUE; +} + +void ManGenerator::endMemberItem(bool,const char *,const char *,bool endItem) +{ + if (endItem) + { + insideTabbing=FALSE; + t << "\"\n.br\n.RI \""; + } + t << "\"\n.br"; +} + +void ManGenerator::startMemberList() +{ + if (!insideTabbing) + { + t << "\n.in +1c"; firstCol=FALSE; + } +} + +void ManGenerator::endMemberList() +{ + if (!insideTabbing) + { + t << "\n.in -1c"; firstCol=FALSE; + } +} + diff --git a/src/mangen.h b/src/mangen.h index 03a6a39..0df3268 100644 --- a/src/mangen.h +++ b/src/mangen.h @@ -63,6 +63,9 @@ class ManGenerator : public OutputGenerator void endItemList() {} void startEnumList() {} void endEnumList() {} + void startAlfabeticalIndexList() {} + void endAlfabeticalIndexList() {} + void writeIndexHeading(const char *) {} void writeIndexItem(const char *ref,const char *file,const char *name); void docify(const char *text); void codify(const char *text); @@ -85,13 +88,12 @@ class ManGenerator : public OutputGenerator void startMemberSubtitle() {} void endMemberSubtitle() {} 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 startMemberList(); + void endMemberList(); + void startMemberItem(bool,int); + void endMemberItem(bool,const char *,const char *,bool); + void memberGroupSpacing(bool) {} + void memberGroupSeparator() {} void writeRuler() {} void writeAnchor(const char *) {} void startCodeFragment(); @@ -164,12 +166,14 @@ class ManGenerator : public OutputGenerator void startQuickIndexItem(const char *,const char *) {} void endQuickIndexItem() {} void writeFormula(const char *,const char *) {} + void writeNonBreakableSpace() { t << " "; } private: bool firstCol; bool paragraph; int col; bool upperCase; + bool insideTabbing; ManGenerator(const ManGenerator &g); ManGenerator &operator=(const ManGenerator &g); diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 1321692..34061f0 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -21,6 +21,165 @@ #include "doxygen.h" #include "util.h" #include "message.h" +#include "htmlhelp.h" +#include "language.h" + +//----------------------------------------------------------------------------- + +static QCString addTemplateNames(const QCString &s,const QCString &n,const QCString &t) +{ + QCString result; + QCString clRealName=n; + int p=0,i; + if ((i=clRealName.find('<'))!=-1) + { + clRealName=clRealName.left(i); // strip template specialization + } + if ((i=clRealName.findRev("::"))!=-1) + { + clRealName=clRealName.right(clRealName.length()-i-2); + } + while ((i=s.find(clRealName,p))!=-1) + { + result+=s.mid(p,i-p); + uint j=clRealName.length()+i; + if (s.length()==j || (s.at(j)!='<' && !isId(s.at(j)))) + { // add template names + //printf("Adding %s+%s\n",clRealName.data(),t.data()); + result+=clRealName+t; + } + else + { // template names already present + //printf("Adding %s\n",clRealName.data()); + result+=clRealName; + } + p=i+clRealName.length(); + } + result+=s.right(s.length()-p); + //printf("addTemplateNames(%s,%s,%s)=%s\n",s.data(),n.data(),t.data(),result.data()); + return result; +} + +static void writeDefArgumentList(OutputList &ol,ClassDef *cd, + const QCString &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(); + QCString cName; + if (md->scopeDefTemplateArguments()) + { + cName=tempArgListToString(md->scopeDefTemplateArguments()); + } + if (cd) + { + cName=cd->name(); + int il=cName.find('<'); + int ir=cName.findRev('>'); + if (il!=-1 && ir!=-1 && ir>il) + { + cName=cName.mid(il,ir-il+1); + //printf("1. cName=%s\n",cName.data()); + } + else if (cd->templateArguments()) + { + cName=tempArgListToString(cd->templateArguments()); + //printf("2. cName=%s\n",cName.data()); + } + else // no template specifier + { + cName.resize(0); + } + } + //printf("~~~ %s cName=%s\n",md->name().data(),cName.data()); + while (a) + { + QRegExp re(")("); + int vp; + if (!a->attrib.isEmpty()) + { + ol.docify(a->attrib+" "); + } + if ((vp=a->type.find(re))!=-1) // argument type is a function pointer + { + QCString 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 + { + QCString 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 + { + QCString 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"); + } +} + +static void writeTemplatePrefix(OutputList &ol,ArgumentList *al,bool br=TRUE) +{ + 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("> "); + if (br) + { + 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); + } +} + +//----------------------------------------------------------------------------- /*! Creates a new member definition. * Members can be function/variables/enums/etc. inside a class or inside a @@ -59,11 +218,14 @@ MemberDef::MemberDef(const char *t,const char *na,const char *a,const char *e, enumScope=0; enumDeclList=0; scopeTAL=0; + membTAL=0; type=substituteClassNames(t); args=substituteClassNames(a); if (type.isNull()) decl=name()+args; else decl=type+" "+name()+args; declLine=0; defLine=0; + grpId=-1; + memberGroup=0; virt=v; prot=p; related=r; @@ -72,6 +234,10 @@ MemberDef::MemberDef(const char *t,const char *na,const char *a,const char *e, exception=e; eUsed=FALSE; proto=FALSE; + annScope=FALSE; + annMemb=0; + annUsed=FALSE; + indDepth=0; docEnumValues=FALSE; // copy function template arguments (if any) if (tal) @@ -203,49 +369,767 @@ QCString MemberDef::getOutputFileBase() const return "dummy"; } -void MemberDef::setScopeTemplateArguments(ArgumentList *tal) +static void copyArgumentList(const ArgumentList *src,ArgumentList *dst) +{ + ArgumentListIterator tali(*src); + Argument *a; + for (;(a=tali.current());++tali) + { + dst->append(new Argument(*a)); + } + dst->constSpecifier = src->constSpecifier; + dst->volatileSpecifier = src->volatileSpecifier; + dst->pureSpecifier = src->pureSpecifier; +} + +void MemberDef::setScopeDefTemplateArguments(ArgumentList *tal) { // copy function arguments (if any) if (tal) { scopeTAL = new ArgumentList; scopeTAL->setAutoDelete(TRUE); - ArgumentListIterator tali(*tal); - Argument *a; - for (;(a=tali.current());++tali) + copyArgumentList(tal,scopeTAL); + } +} + +void MemberDef::setMemberDefTemplateArguments(ArgumentList *tal) +{ + // copy function arguments (if any) + if (tal) + { + membTAL = new ArgumentList; + membTAL->setAutoDelete(TRUE); + copyArgumentList(tal,membTAL); + } +} + + + +void MemberDef::setGroupId(int groupId) +{ + grpId=groupId; + if (grpId!=-1) + { + memberGroup=memberGroupDict[grpId]; + memberGroup->insertMember(this); + } +} + +void MemberDef::writeLink(OutputList &ol,ClassDef *cd,NamespaceDef *nd, + FileDef *fd,MemberGroup *mg) +{ + if (mg) + ol.writeObjectLink(0,mg->getOutputFileBase(), + anchor(),name()); + else if (nd) + ol.writeObjectLink(nd->getReference(),nd->getOutputFileBase(), + anchor(),name()); + else if (fd) + ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(), + anchor(),name()); + else + ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(), + anchor(),name()); +} + +void MemberDef::writeDeclaration(OutputList &ol,ClassDef *cd,NamespaceDef *nd,FileDef *fd, + int prevGroupId,bool inGroup) +{ + int i,l; + bool hasDocs=hasDocumentation(); + //if (cd) printf("MemberDef: %s in class %s annScope=%d annMemb=%p\n", + // name().data(),cd->name().data(),annScope,annMemb); + if (annScope) return; + if (!hasDocs && Config::hideMemberFlag) return; + if (Config::hideMemberFlag && documentation().isEmpty() && + !Config::briefMemDescFlag && !Config::repeatBriefFlag + ) return; + QCString type=typeString(); + // 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); + QRegExp r("@[0-9]+"); + if ((i=r.match(type,0,&l))==-1 || !enumUsed()) + { + + if (Config::genTagFile.length()>0) + { + tagFile << name() << " " << anchor() << " \"" + << argsString() << "\"\n"; + } + + Definition *d=0; + if (cd) d=cd; else if (nd) d=nd; else d=fd; + QCString cname = d->name(); + QCString cfname = d->getOutputFileBase(); + + int gId = inGroup ? -1 : groupId(); + MemberGroup *mg = (gId!=prevGroupId && gId!=-1) ? memberGroupDict[gId] : 0; + const char *gHeader = 0; + const char *gFile = 0; + if (mg) + { + gHeader=mg->header(); + gFile=mg->getOutputFileBase(); + } + + if (!inGroup) + { + if (prevGroupId==-1 && gId!=-1) + { + ol.memberGroupSpacing(FALSE); + ol.memberGroupSeparator(); + } + else if (prevGroupId!=-1 && gId==-1) + { + ol.memberGroupSpacing(TRUE); + ol.memberGroupSeparator(); + } + else if (prevGroupId!=-1 && gId!=-1 && prevGroupId!=gId) + { + ol.memberGroupSpacing(TRUE); + ol.memberGroupSeparator(); + } + } + + HtmlHelp *htmlHelp=0; + bool hasHtmlHelp = Config::generateHtml && Config::htmlHelpFlag; + if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance(); + + // search for the last annonymous scope in the member type + ClassDef *annoClassDef=0; + while (i!=-1 && cname.find(type.mid(i,l))!=-1) + { + i=r.match(type,i+l,&l); + } + if (i!=-1) + { + // get the definition of the annonymous class that is + // the type of this member + annoClassDef=getClass(cname+"::"+type.mid(i,l)); + } + + // start a new member declaration + ol.startMemberItem(gId!=-1,((i!=-1) || annMemb) ? 1 : 0); + + // If there is no detailed description we need to write the anchor here. + bool detailsVisible = detailsAreVisible(); + if (!detailsVisible && !Config::extractAllFlag && !annMemb) + { + QCString doxyName=name().copy(); + if (!cname.isEmpty()) doxyName.prepend(cname+"::"); + ol.writeDoxyAnchor(cname,anchor(),doxyName); + ol.addToIndex(name(),cname); + ol.addToIndex(cname,name()); + if (hasHtmlHelp) + { + htmlHelp->addIndexItem(cname,name(),cfname,anchor()); + } + ol.docify("\n"); + } + //else if (!detailsVisible) // when extractAll it true we have to write + // // a index reference and label in LaTeX because + // // detailed section not shown in LaTeX + //{ + // ol.addToIndex(name(),cname); + // ol.addToIndex(cname,name()); + // ol.writeLatexLabel(cname,anchor()); + //} + + if (tArgList) + { + writeTemplatePrefix(ol,tArgList,FALSE); + } + + if (i!=-1 || annMemb) + { + int j; + for (j=0;jwriteDeclaration(ol); + ol.startMemberItem(gId!=-1,2); + int j; + for (j=0;j0) + { + ol.disable(OutputGenerator::Html); + } + if (!type.isEmpty()) ol.docify(" "); + if (htmlOn) + { + ol.enable(OutputGenerator::Html); + } + + if (annMemb) + { + bool latexOn = ol.isEnabled(OutputGenerator::Latex); + bool manOn = ol.isEnabled(OutputGenerator::Latex); + if (latexOn) ol.disable(OutputGenerator::Latex); + if (manOn) ol.disable(OutputGenerator::Man); + ol.writeNonBreakableSpace(); + if (latexOn) ol.enable(OutputGenerator::Latex); + if (manOn) ol.enable(OutputGenerator::Man); + } + else + ol.insertMemberAlign(); + + // write name + if (grpId!=-1) + { + if (annMemb) + { + //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor()); + annMemb->writeLink(ol,cd,nd,fd,inGroup ? memberGroup : 0); + annMemb->annUsed=annUsed=TRUE; + } + else + writeLink(ol,0,0,0,memberGroup); + //ol.writeBoldString(name()); + } + else if (isLinkable()) + { + if (annMemb) + { + //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor()); + annMemb->writeLink(ol,annMemb->memberClass(),nd,fd,inGroup ? memberGroup : 0); + annMemb->annUsed=annUsed=TRUE; + } + else + //printf("writeLink %s->%d\n",name.data(),hasDocumentation()); + writeLink(ol,cd,nd,fd,inGroup ? memberGroup : 0); + } + else // there is a brief member description and brief member + // descriptions are enabled or there is no detailed description. { - scopeTAL->append(new Argument(*a)); + if (annMemb) annMemb->annUsed=annUsed=TRUE; + ol.writeBoldString(name()); + } + + // if member template specifiers are not part of the name, but they are + // present, we add them + if (tArgList && !(name().find('<')!=-1 && name().find('>')!=-1) + && cd && cd->templateArguments()) + { + ol.docify(tempArgListToString(tArgList)); + } + + if (argsString()) + { + ol.writeString(" "); + //ol.docify(argsString()); + linkifyText(ol,cname,name(),argsString()); + } + + if (excpString()) + { + ol.writeString(" "); + ol.docify(excpString()); + } + + ol.endMemberItem(gId!=-1,gFile,gHeader,annoClassDef!=0 && indDepth==0); + + // write brief description + if (!briefDescription().isEmpty() && Config::briefMemDescFlag && + gId==-1 && !inGroup && !annMemb) + { + ol.startMemberDescription(); + parseDoc(ol,cname,name(),briefDescription()); + if (!documentation().isEmpty()) + { + ol.disableAllBut(OutputGenerator::Html); + ol.endEmphasis(); + ol.docify(" "); + ol.startTextLink(0,anchor()); + parseText(ol,theTranslator->trMore()); + ol.endTextLink(); + ol.startEmphasis(); + ol.enableAll(); + } + ol.endMemberDescription(); + ol.newParagraph(); } - scopeTAL->constSpecifier = tal->constSpecifier; - scopeTAL->volatileSpecifier = tal->volatileSpecifier; - scopeTAL->pureSpecifier = tal->pureSpecifier; } + warnIfUndocumented(); } -QCString MemberDef::getScopeTemplateNameString() + +void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,const char *scopeName, + MemberType m) { - QCString result; - if (!scopeTAL || scopeTAL->count()==0) return result; - result="<"; - Argument *a=scopeTAL->first(); - while (a) + bool hasDocs = detailsAreVisible(); + if ( + (memberType()==m && // filter member type + (Config::extractAllFlag || hasDocs) && + groupId()==-1 + ) || /* member is part of an annonymous scope that is the type of + * another member in the list. + */ + (!hasDocs && !briefDescription().isEmpty() && annUsed) + ) { - if (a->name.length()>0) // add template argument name + //printf("************* Writing docs for member %s\n",name().data()); + //if (Config::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 Config::extractAllFlag is enabled + //} + NamespaceDef *nd=getNamespace(); + ClassDef *cd=memberClass(); + FileDef *fd=getFileDef(); + Definition *d = 0; + if (cd) d=cd; else if (nd) d=nd; else d=fd; + QCString cname = d->name(); + QCString cfname = d->getOutputFileBase(); + + // get member name + QCString doxyName=name().copy(); + // prepend scope if there is any + if (scopeName) doxyName.prepend((QCString)scopeName+"::"); + + QCString def = definition(); + if (isEnumerate()) def.prepend("enum "); + MemberDef *smd; + if (isEnumValue() && def[0]=='@') def = def.right(def.length()-2); + int i=0,l,dummy; + QRegExp r("@[0-9]+"); + if (isEnumerate() && r.match(def,0,&l)!=-1) return; + if (isEnumValue() && (smd = getEnumScope()) + && r.match(smd->name(),0,&dummy)==-1) return; + + bool hasHtmlHelp = Config::generateHtml && Config::htmlHelpFlag; + HtmlHelp *htmlHelp = 0; + if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance(); + + if ((isVariable() || isTypedef()) && (i=r.match(def,0,&l))!=-1) { - result+=a->name; + // 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,name(),anchor()); + if (hasHtmlHelp) + { + htmlHelp->addIndexItem(cname,name(),cfname,anchor()); + } + ol.writeDoxyAnchor(cname,anchor(),doxyName); + linkifyText(ol,scopeName,name(),def.left(i)); + ol+=*vmd->enumDecl(); + linkifyText(ol,scopeName,name(),def.right(def.length()-i-l)); + found=TRUE; + } + } + if (!found) // anonymous compound + { + //printf("Annonymous compound `%s'\n",cname.data()); + ol.startMemberDoc(cname,name(),anchor()); + if (hasHtmlHelp) + { + htmlHelp->addIndexItem(cname,name(),cfname,anchor()); + } + ol.writeDoxyAnchor(cname,anchor(),doxyName); + // strip annonymous compound names from definition + int si=def.find(' '),pi,ei=i+l; + if (si==-1) si=0; + while ((pi=r.match(def,i+l,&l))!=-1) ei=i=pi+l; + // first si characters of def contain compound type name + ol.docify(def.left(si)); + ol.docify(" { ... } "); + // last ei characters of def contain pointer/reference specifiers + linkifyText(ol,scopeName,name(),def.right(def.length()-ei)); + } } - else // extract name from type + else { - int i=a->type.length()-1; - while (i>=0 && isId(a->type.at(i))) i--; - if (i>0) + ol.startMemberDoc(cname,name(),anchor()); + if (hasHtmlHelp) + { + htmlHelp->addIndexItem(cname,name(),cfname,anchor()); + } + ol.writeDoxyAnchor(cname,anchor(),doxyName); + + ArgumentList *scopeAl=scopeDefTemplateArguments(); + if (scopeAl==0 && cd) scopeAl=cd->templateArguments(); + + ArgumentList *membAl=memberDefTemplateArguments(); + if (membAl==0) membAl=templateArguments(); + + //if (cd && (!isRelated() || templateArguments()!=0) && + // ((al=scopeDefTemplateArguments()) || (al=cd->templateArguments())) + // ) + if (scopeAl) // class template prefix + { + writeTemplatePrefix(ol,scopeAl); + } + if (scopeAl && membAl) ol.docify(" "); + + if (membAl) // function template prefix { - result+=a->type.right(a->type.length()-i-1); + writeTemplatePrefix(ol,membAl); } + if (cd) + { + QCString cName=cd->name(); + //printf("cName=%s\n",cName.data()); + int il=cName.find('<'); + int ir=cName.findRev('>'); + if (il!=-1 && ir!=-1 && ir>il) + { + def=addTemplateNames(def, + cName.left(il), /* class without template spec */ + cName.mid(il,ir-il+1) /* templ spec */ + ); + } + else if (scopeAl) + { + def=addTemplateNames(def,cName,tempArgListToString(scopeAl)); + } + } + linkifyText(ol,scopeName,name(),def); + writeDefArgumentList(ol,cd,scopeName,this); + if (excpString()) + { + ol.docify(" "); + linkifyText(ol,scopeName,name(),excpString()); + } + } + + Specifier virt=virtualness(); + MemberDef *rmd=reimplements(); + while (rmd && virt==Normal) + { + virt = rmd->virtualness()==Normal ? Normal : Virtual; + rmd = rmd->reimplements(); + } + + if (isStatic() || protection()!=Public || + virt!=Normal || isSignal() || isFriend() || + isRelated() || isSlot() + ) + { + // write the member specifier list + ol.writeLatexSpacing(); + ol.startTypewriter(); + ol.docify(" ["); + QStrList sl; + if (isFriend()) sl.append("friend"); + else if (isRelated()) sl.append("related"); + else + { + if (isStatic()) sl.append("static"); + if (protection()==Protected) sl.append("protected"); + else if (protection()==Private) sl.append("private"); + if (virt==Virtual) sl.append("virtual"); + else if (virt==Pure) sl.append("pure virtual"); + if (isSignal()) sl.append("signal"); + if (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 (!briefDescription().isEmpty() && + (Config::repeatBriefFlag || + (!Config::briefMemDescFlag && documentation().isEmpty()) + ) || !annMemb + ) + { + parseDoc(ol,scopeName,name(),briefDescription()); + ol.newParagraph(); + } + if (!documentation().isEmpty()) + { + parseDoc(ol,scopeName,name(),documentation()+"\n"); + } + if (!bodyCode().isEmpty()) + { + ol.startCodeFragment(); + parseCode(ol,scopeName,bodyCode(),FALSE,0); + ol.endCodeFragment(); + } + + if (isEnumerate()) + { + bool first=TRUE; + MemberList *fmdl=enumFieldList(); + if (fmdl) + { + MemberDef *fmd=fmdl->first(); + while (fmd) + { + if (fmd->isLinkable()) + { + if (first) + { + ol.newParagraph(); + ol.startBold(); + parseText(ol,theTranslator->trEnumerationValues()); + //ol.writeBoldString("Enumeration values:"); + ol.docify(":"); + ol.endBold(); + ol.startItemList(); + } + ol.writeDoxyAnchor(cname,fmd->anchor(),fmd->name()); + ol.addToIndex(fmd->name(),cname); + ol.addToIndex(cname,fmd->name()); + if (Config::generateHtml && Config::htmlHelpFlag) + { + HtmlHelp::getInstance()->addIndexItem(cname,fmd->name(),cfname,fmd->anchor()); + } + 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.endItemList(); ol.writeChar('\n'); } + } + + MemberDef *bmd=reimplements(); + ClassDef *bcd=0; + if (bmd && (bcd=bmd->memberClass())) + { + if (virt!=Normal) // search for virtual member of the deepest base class + { + MemberDef *lastBmd=bmd; + while (lastBmd) + { + ClassDef *lastBcd = lastBmd->memberClass(); + if (lastBmd->virtualness()!=Normal && + lastBmd->isLinkable() && + lastBcd->isLinkable() + ) { bmd=lastBmd; bcd=lastBcd; } + lastBmd=lastBmd->reimplements(); + } + } + // write class that contains a member that is reimplemented by this one + if (bcd->isLinkable()) + { + ol.newParagraph(); + + QCString reimplFromLine = theTranslator->trReimplementedFromList(1); + int markerPos = reimplFromLine.find("@0"); + if (markerPos!=-1) // should always pass this. + { + parseText(ol,reimplFromLine.left(markerPos)); //text left from marker + if (bmd->isLinkable()) // replace marker with link + { + ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(), + bmd->anchor(),bcd->name()); + if ( bcd->isLinkableInProject()) + { + ol.writePageRef(bcd->name(),bmd->anchor()); + } + } + else + { + ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(), + 0,bcd->name()); + if (bcd->isLinkableInProject()) + { + ol.writePageRef(bcd->name(),0); + } + } + parseText(ol,reimplFromLine.right( + reimplFromLine.length()-markerPos-2)); // text right from marker + + } + else + { + err("Error: translation error: no marker in trReimplementsFromList()\n"); + } + } + + //ol.writeString("."); } - a=scopeTAL->next(); - if (a) result+=", "; + MemberList *bml=reimplementedBy(); + if (bml) + { + MemberListIterator mli(*bml); + MemberDef *bmd=0; + uint count=0; + ClassDef *bcd=0; + for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->memberClass());++mli) + { + // count the members that directly inherit from md and for + // which the member and class are visible in the docs. + if ( bmd->isLinkable() && bcd->isLinkable() ) count++; + } + if (count>0) + { + mli.toFirst(); + // write the list of classes that overwrite this member + ol.newParagraph(); + //parseText(ol,theTranslator->trReimplementedIn()); + //ol.writeString("Reimplemented in "); + //ol.docify(" "); + + QCString reimplInLine = + theTranslator->trReimplementedInList(count); + QRegExp marker("@[0-9]+"); + int index=0,newIndex,matchLen; + // now replace all markers in reimplInLine with links to the classes + while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1) + { + parseText(ol,reimplInLine.mid(index,newIndex-index)); + bool ok; + uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok); + //bmd=bml->at(entryIndex); + + count=0; + // find the entryIndex-th documented entry in the inheritance list. + for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->memberClass());++mli) + { + if ( bmd->isLinkable() && bcd->isLinkable()) + { + if (count==entryIndex) break; + count++; + } + } + + if (ok && bcd && bmd) // write link for marker + { + //if (bmd->hasDocumentation() && + // (bmd->protection()!=Private || Config::extractPrivateFlag) + // ) + //{ + ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(), + bmd->anchor(),bcd->name()); + if (bcd->isLinkableInProject()) + { + ol.writePageRef(bcd->name(),bmd->anchor()); + } + //} + //else + //{ + // ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(), + // 0,bcd->name()); + // if (!bcd->isReference() && bcd->isVisible()) + // ol.writePageRef(bcd->name(),0); + //} + } + ++mli; + index=newIndex+matchLen; + } + parseText(ol,reimplInLine.right(reimplInLine.length()-index)); + + } + } + // write the list of examples that use this member + if (hasExamples()) + { + ol.startDescList(); + ol.startBold(); + parseText(ol,theTranslator->trExamples()+": "); + //ol.writeBoldString("Examples: "); + ol.endBold(); + ol.endDescTitle(); + ol.writeDescItem(); + writeExample(ol,getExampleList()); + //ol.endDescItem(); + ol.endDescList(); + } + ol.endIndent(); + // enable LaTeX again + //if (Config::extractAllFlag && !hasDocs) ol.enable(OutputGenerator::Latex); + } - result+=">"; - return result; +} + +void MemberDef::warnIfUndocumented() +{ + if (memberGroup) return; + ClassDef *cd = memberClass(); + NamespaceDef *nd = getNamespace(); + FileDef *fd = getFileDef(); + Definition *d=0; + const char *t=0; + if (cd) + t="class", d=cd; + else if (nd) + t="namespace", d=nd; + else + t="file", d=fd; + + if (d && d->isLinkable() && !isLinkable() && name().find('@')==-1) + warn("Warning: Member %s of %s %s is not documented\n", + name().data(),t,d->name().data()); +} + + +bool MemberDef::isLinkableInProject() +{ + return !name().isEmpty() && name().at(0)!='@' && + ((hasDocumentation() && !isReference()) || + (memberGroup && memberGroup->isLinkableInProject()) + ) && + (prot!=Private || Config::extractPrivateFlag || isFriend()); +} + +bool MemberDef::isLinkable() +{ + return isLinkableInProject() || isReference(); } diff --git a/src/memberdef.h b/src/memberdef.h index 4c1893f..68d9ad8 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -26,12 +26,13 @@ #include "config.h" #include "outputlist.h" #include "definition.h" -#include "config.h" +#include "scanner.h" class FileDef; class MemberList; class NamespaceDef; + class MemberDef : public Definition { public: @@ -55,14 +56,22 @@ class MemberDef : public Definition const ArgumentList *al); ~MemberDef(); + void writeLink(OutputList &ol,ClassDef *cd,NamespaceDef *nd, + FileDef *fd,MemberGroup *mg); + void writeDeclaration(OutputList &ol,ClassDef *cd,NamespaceDef *nd,FileDef *fd, + int prevGroupId,bool inGroup); + void writeDocumentation(MemberList *ml,OutputList &ol, + const char *scopeName,MemberType m); + void warnIfUndocumented(); + QCString getOutputFileBase() const; 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; } - QCString bodyCode() const { return body; } + const char *anchor() const { return anc; } + QCString bodyCode() const { return body; } ClassDef *memberClass() { return classDef; } Protection protection() const { return prot; } Specifier virtualness() const { return virt; } @@ -73,7 +82,7 @@ class MemberDef : public Definition 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; } + void setAnchor(const char *a) { anc=a; } void setProtection(Protection p) { prot=p; } void setBody(const QCString &b) { body=b; } FileDef *getFileDef() { return fileDef; } @@ -82,12 +91,11 @@ class MemberDef : public Definition bool isRelated() const { return related; } bool isStatic() const { return stat; } bool hasDocumentation() // overrides hasDocumentation in definition.h - { return !documentation().isNull() || - !briefDescription().isNull() || - !body.isEmpty() || - Config::extractAllFlag; - } + { return Definition::hasDocumentation() || !body.isEmpty(); } + bool isLinkableInProject(); + bool isLinkable(); + bool detailsAreVisible() const { return !documentation().isEmpty() || !body.isEmpty() || (mtype==Enumeration && docEnumValues) || @@ -142,9 +150,9 @@ class MemberDef : public Definition bool isPrototype() const { return proto; } // tag file related members - void setReference(const char *r) { external=r; } - bool isReference() { return !external.isNull(); } - + //void setReference(const char *r) { external=r; } + //bool isReference() { return !external.isNull(); } + // argument related members ArgumentList *argumentList() const { return argList; } void setArgumentList(ArgumentList *al) @@ -152,13 +160,28 @@ class MemberDef : public Definition argList = al; } ArgumentList *templateArguments() const { return tArgList; } - void setScopeTemplateArguments(ArgumentList *t); - ArgumentList *scopeTemplateArguments() const { return scopeTAL; } - QCString getScopeTemplateNameString(); + void setScopeDefTemplateArguments(ArgumentList *t); + ArgumentList *scopeDefTemplateArguments() const { return scopeTAL; } + void setMemberDefTemplateArguments(ArgumentList *t); + ArgumentList *memberDefTemplateArguments() const { return membTAL; } + //QCString getScopeTemplateNameString(); // namespace related members NamespaceDef *getNamespace() { return nspace; } void setNamespace(NamespaceDef *nd) { nspace=nd; } + + // grouping related members + void setGroupId(int groupId); + int groupId() const { return grpId; } + QCString groupHeader() const { return grpHeader; } + MemberGroup *getMemberGroup() const { return memberGroup; } + + void setFromAnnonymousScope(bool b) { annScope=b; } + void setFromAnnonymousMember(MemberDef *m) { annMemb=m; } + bool fromAnnonymousScope() { return annScope; } + bool annonymousDeclShown() { return annUsed; } + void setIndentDepth( int i) { indDepth=i; } + int indentDepth() { return indDepth; } private: ClassDef *classDef; // member of or related to @@ -174,34 +197,40 @@ class MemberDef : public Definition MemberList *enumFields; // enumeration fields OutputList *enumDeclList; // stored piece of documentation for enumeration. NamespaceDef *nspace; // the namespace this member is in. - QCString type; // return type - QCString args; // function arguments/variable array specifiers - QCString exception; // exceptions that can be thrown - QCString body; // function body code - QCString decl; // member declaration in class - QCString declFile; // file where the declaration was found + QCString type; // return type + QCString args; // function arguments/variable array specifiers + QCString exception; // exceptions that can be thrown + QCString body; // function body code + QCString decl; // member declaration in class + QCString declFile; // file where the declaration was found int declLine; // line where the declaration was found - QCString def; // member definition in code (fully qualified name) - QCString defFile; // file where the definition was found + QCString def; // member definition in code (fully qualified name) + QCString defFile; // file where the definition was found int defLine; // line where the definition was found - QCString ref; // HTML anchor name + QCString anc; // 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 - QCString 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. + bool annScope; + bool annUsed; + int indDepth; + MemberDef *annMemb; ArgumentList *argList; // argument list of this member ArgumentList *tArgList; // template argument list of function template ArgumentList *scopeTAL; // template argument list of class template + ArgumentList *membTAL; // template argument list of class template + int grpId; // group id + QCString grpHeader; // group header + MemberGroup *memberGroup; // group's member definition // disable copying of member defs MemberDef(const MemberDef &); MemberDef &operator=(const MemberDef &); }; - #endif diff --git a/src/membergroup.cpp b/src/membergroup.cpp new file mode 100644 index 0000000..883bfe2 --- /dev/null +++ b/src/membergroup.cpp @@ -0,0 +1,251 @@ +/****************************************************************************** + * + * $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 "qtbc.h" +#include "membergroup.h" +#include "memberlist.h" +#include "outputlist.h" +#include "util.h" +#include "classdef.h" +#include "namespacedef.h" +#include "filedef.h" +#include "language.h" + +static QCString idToName(int id) +{ + QCString result; + result.sprintf("mgroup_%d",id); + return result; +} + +MemberGroup::MemberGroup(int id,const char *hdr) : Definition(idToName(id)) +{ + memberList = new MemberList; + grpId = id; + grpHeader = hdr; + fileName = name(); +} + +MemberGroup::~MemberGroup() +{ + delete memberList; +} + +void MemberGroup::insertMember(MemberDef *m) +{ + memberList->append(m); +} + +void MemberGroup::writeDocumentation(OutputList &ol) +{ + //printf("Writing documentation for group %s\n",fileName.data()); + + if (memberList->count()==0) return; // no member in this group! + + QCString title = grpHeader.copy(); + if (title.isEmpty()) + { + title = "Member Group"; // TODO: make translatable. + } + ol.disable(OutputGenerator::Man); + startFile(ol,fileName,title); + startTitle(ol); + ol.docify(title); + endTitle(ol,name()); + + + OutputList briefOutput(&ol); + if (!briefDescription().isEmpty()) + { + parseDoc(briefOutput,0,0,briefDescription()); + ol+=briefOutput; + ol.writeString(" \n"); + if (!documentation().isEmpty() || Config::repeatBriefFlag) + { + bool htmlEnabled = ol.isEnabled(OutputGenerator::Html); + bool latexEnabled = ol.isEnabled(OutputGenerator::Html); + if (htmlEnabled) ol.disableAllBut(OutputGenerator::Html); + if (latexEnabled) ol.disableAllBut(OutputGenerator::Html); + ol.startTextLink(0,"_details"); + parseText(ol,theTranslator->trMore()); + ol.endTextLink(); + if (htmlEnabled) ol.enable(OutputGenerator::Html); + if (latexEnabled) ol.enable(OutputGenerator::Latex); + } + } + // TODO: man page synopsis + + //if (memberList->count()>0) + //{ + QCString scopeName; + + MemberDef *md = memberList->first(); + ClassDef *cd = md->memberClass(); + NamespaceDef *nd = md->getNamespace(); + FileDef *fd = md->getFileDef(); + //printf("member %s brief=`%s' docs=`%s'\n", + // md->name().data(), md->briefDescription().data(), + // md->documentation().data()); + if (cd) + { + ol.newParagraph(); + ol.docify("Inside class "); + ol.writeObjectLink(cd->getReference(), + cd->getOutputFileBase(),0, + cd->name() + ); + scopeName=cd->name().copy(); + } + else if (nd) + { + ol.newParagraph(); + ol.docify("Inside namespace "); + ol.writeObjectLink(nd->getReference(), + nd->getOutputFileBase(),0, + nd->name() + ); + scopeName=nd->name().copy(); + } + else if (fd) + { + ol.newParagraph(); + ol.docify("#include <"); + ol.writeObjectLink(fd->getReference(), + fd->getOutputFileBase(),0, + fd->name() + ); + ol.docify(">"); + } + ol.startMemberSections(); + memberList->writeDeclarations(ol,cd,nd,fd,"Synopsis",0,TRUE); + ol.endMemberSections(); + + if ((!briefDescription().isEmpty() && Config::repeatBriefFlag) || + !documentation().isEmpty()) + { + ol.writeRuler(); + bool latexOn = ol.isEnabled(OutputGenerator::Latex); + if (latexOn) ol.disable(OutputGenerator::Latex); + ol.writeAnchor("_details"); + if (latexOn) ol.enable(OutputGenerator::Latex); + ol.startGroupHeader(); + parseText(ol,theTranslator->trDetailedDescription()); + ol.endGroupHeader(); + + // repeat brief description + if (!briefDescription().isEmpty() && Config::repeatBriefFlag) + { + ol+=briefOutput; + ol.newParagraph(); + } + // write documentation + if (!documentation().isEmpty()) + { + parseDoc(ol,scopeName,0,documentation()+"\n"); + } + } + +// memberList->countDocMembers(TRUE); +// +// if ( memberList->defineCount()>0 ) +// { +// ol.writeRuler(); +// ol.startGroupHeader(); +// parseText(ol,theTranslator->trDefineDocumentation()); +// ol.endGroupHeader(); +// writeMemberDocs(ol,memberList,scopeName,MemberDef::Define); +// } +// +// if ( memberList->protoCount()>0 ) +// { +// ol.writeRuler(); +// ol.startGroupHeader(); +// parseText(ol,theTranslator->trFunctionPrototypeDocumentation()); +// ol.endGroupHeader(); +// writeMemberDocs(ol,memberList,scopeName,MemberDef::Prototype); +// } +// +// if ( memberList->typedefCount()>0 ) +// { +// ol.writeRuler(); +// ol.startGroupHeader(); +// parseText(ol,theTranslator->trTypedefDocumentation()); +// ol.endGroupHeader(); +// writeMemberDocs(ol,memberList,scopeName,MemberDef::Typedef); +// } +// +// if ( memberList->enumCount()>0 ) +// { +// ol.writeRuler(); +// ol.startGroupHeader(); +// parseText(ol,theTranslator->trEnumerationTypeDocumentation()); +// ol.endGroupHeader(); +// writeMemberDocs(ol,memberList,scopeName,MemberDef::Enumeration); +// } +// +// if ( memberList->enumValueCount()>0 ) +// { +// ol.writeRuler(); +// ol.startGroupHeader(); +// parseText(ol,theTranslator->trEnumerationValueDocumentation()); +// ol.endGroupHeader(); +// writeMemberDocs(ol,memberList,scopeName,MemberDef::EnumValue); +// } +// +// if ( memberList->funcCount()>0 ) +// { +// ol.writeRuler(); +// ol.startGroupHeader(); +// parseText(ol,theTranslator->trFunctionDocumentation()); +// ol.endGroupHeader(); +// writeMemberDocs(ol,memberList,scopeName,MemberDef::Function); +// } +// +// if ( memberList->varCount()>0 ) +// { +// ol.writeRuler(); +// ol.startGroupHeader(); +// parseText(ol,theTranslator->trVariableDocumentation()); +// ol.endGroupHeader(); +// writeMemberDocs(ol,memberList,scopeName,MemberDef::Variable); +// } + + endFile(ol); + ol.enable(OutputGenerator::Man); +} + +bool MemberGroup::isLinkableInProject() +{ + return hasDocumentation() && !isReference(); +} +bool MemberGroup::isLinkable() +{ + return isLinkableInProject() || isReference(); +} + +void MemberGroup::addDocumentation() +{ + //printf("adding documentation for membergroup %s\n",name().data()); + MemberListIterator mli(*memberList); + MemberDef *md; + for (;(md=mli.current());++mli) + { + //printf("Adding docs `%s' `%s'\n",md->briefDescription().data(),md->documentation().data()); + setBriefDescription(briefDescription()+"\n"+md->briefDescription()); + setDocumentation(documentation()+"\n"+md->documentation()); + } + //printf("isLinkable()=%d\n",isLinkable()); +} diff --git a/src/membergroup.h b/src/membergroup.h new file mode 100644 index 0000000..1db04df --- /dev/null +++ b/src/membergroup.h @@ -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. + * + */ + +#ifndef MEMBERGROUP_H +#define MEMBERGROUP_H + +#include "qtbc.h" +#include + +#include "definition.h" + +class MemberDef; +class MemberList; +class OutputList; + +class MemberGroup : public Definition +{ + public: + MemberGroup(int id,const char *header); + ~MemberGroup(); + QCString header() const { return grpHeader; } + QCString getOutputFileBase() const { return fileName; } + void insertMember(MemberDef *); + void writeDocumentation(OutputList &ol); + MemberList *members() const { return memberList; } + void addDocumentation(); + + bool isLinkableInProject(); + bool isLinkable(); + + private: + MemberList *memberList; // list of all members in the group + int grpId; + QCString grpHeader; + QCString fileName; // base name of the generated file +}; + +class MemberGroupList : public QList +{ +}; + +class MemberGroupListIterator : public QListIterator +{ + public: + MemberGroupListIterator(const MemberGroupList &l) : + QListIterator(l) {} +}; + +#endif diff --git a/src/memberlist.cpp b/src/memberlist.cpp index 99ad00a..4f6bad9 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -18,6 +18,9 @@ #include "classdef.h" #include "message.h" #include +#include "util.h" +#include "language.h" +#include "doxygen.h" MemberList::MemberList() : QList() { @@ -71,13 +74,14 @@ void MemberList::countDecMembers() } } -void MemberList::countDocMembers() +void MemberList::countDocMembers(bool inGroup) { varCnt=funcCnt=enumCnt=enumValCnt=typeCnt=protoCnt=defCnt=friendCnt=0; MemberDef *md=first(); while (md) { - if (Config::extractAllFlag || md->detailsAreVisible()) + if ((Config::extractAllFlag || md->detailsAreVisible()) && + (md->groupId()==-1 || inGroup)) { QRegExp r("@[0-9]+"); int dummy; @@ -142,3 +146,361 @@ MemberListIterator::MemberListIterator(const QList &l) : { } +void MemberList::writePlainDeclarations(OutputList &ol,ClassDef *cd, + NamespaceDef *nd,FileDef *fd,bool inGroup) +{ + countDecMembers(); + if (totalCount()==0) return; // no members in this list + + int prevGroupId = -1; + if (!fd && !nd) ol.startMemberList(); + MemberDef *md; + + if (fd && defineCount()>0) + { + ol.startMemberHeader(); + parseText(ol,theTranslator->trDefines()); + ol.endMemberHeader(); + ol.startMemberList(); + MemberListIterator mli(*this); + for ( ; (md=mli.current()); ++mli ) + { + if (md->isDefine() && + (md->argsString() || md->hasDocumentation() || Config::extractAllFlag) + ) + { + md->writeDeclaration(ol,cd,nd,fd,prevGroupId,inGroup); + prevGroupId = md->groupId(); + } + } + ol.endMemberList(); + } + + if ((fd || nd) && protoCount()>0) + { + ol.startMemberHeader(); + parseText(ol,theTranslator->trFuncProtos()); + ol.endMemberHeader(); + ol.startMemberList(); + MemberListIterator mli(*this); + for ( ; (md=mli.current()); ++mli ) + { + if (md->isPrototype()) + { + md->writeDeclaration(ol,cd,nd,fd,prevGroupId,inGroup); + prevGroupId = md->groupId(); + } + } + ol.endMemberList(); + } + + if (typedefCount()>0) + { + if (fd || nd) + { + ol.startMemberHeader(); + parseText(ol,theTranslator->trTypedefs()); + ol.endMemberHeader(); + //ol.writeMemberHeader("Typedefs"); + ol.startMemberList(); + } + MemberListIterator mli(*this); + for ( ; (md=mli.current()) ; ++mli ) + { + if (md->isTypedef()) + { + md->writeDeclaration(ol,cd,nd,fd,prevGroupId,inGroup); + prevGroupId = md->groupId(); + } + } + if (fd || nd) ol.endMemberList(); + } + + // write enums + if (enumCount()>0) + { + if (fd || nd) + { + ol.startMemberHeader(); + parseText(ol,theTranslator->trEnumerations()); + ol.endMemberHeader(); + ol.startMemberList(); + } + MemberListIterator mli(*this); + for ( ; (md=mli.current()) ; ++mli ) + { + /*bool hasDocs=md->hasDocumentation();*/ + QCString type=md->typeString(); + type=type.stripWhiteSpace(); + if (md->isEnumerate() /*&& (hasDocs || !Config::hideMemberFlag)*/) + { + if (!Config::hideMemberFlag || // do not hide undocumented members or + !md->documentation().isEmpty() || // member has detailed descr. or + md->hasDocumentedEnumValues() || // member has documented enum vales. + Config::briefMemDescFlag || // brief descr. is shown or + Config::repeatBriefFlag // brief descr. is repeated. + ) + { + OutputList typeDecl(&ol); + QCString 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 (Config::extractAllFlag || + // (md->briefDescription().isEmpty() || !Config::briefMemDescFlag) && + // (!md->documentation().isEmpty() || md->hasDocumentedEnumValues() || + // (!md->briefDescription().isEmpty() && + // !Config::briefMemDescFlag && + // Config::repeatBriefFlag + // ) + // ) + // ) + if (md->hasDocumentation() || md->hasDocumentedEnumValues()) + { + if (Config::genTagFile.length()>0) + tagFile << md->name() << " " << md->anchor() + << " \"" << md->argsString() << "\""; + md->writeLink(typeDecl,cd,nd,fd,0); + } + else + { + typeDecl.writeBoldString(name); + } + typeDecl.writeChar(' '); + } + + typeDecl.docify("{ "); + QList *fmdl=md->enumFieldList(); + if (fmdl) + { + MemberDef *fmd=fmdl->first(); + while (fmd) + { + if (fmd->hasDocumentation()) + { + if (Config::genTagFile.length()>0) + tagFile << fmd->name() << " " << fmd->anchor() + << " \"" << fmd->argsString() << "\""; + fmd->writeLink(typeDecl,cd,nd,fd,0); + } + 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(*this); + MemberDef *vmd; + if (name[0]=='@') // anonymous enum => append variables + { + for ( ; (vmd=vmli.current()) ; ++vmli) + { + QCString vtype=vmd->typeString(); + if ((vtype.find(name))!=-1) enumVars++; + } + } + if (enumVars==0) // no variable of this enum type + { + int gId = md->groupId(); + const char *gHeader = (gId!=prevGroupId && gId!=-1) ? + memberGroupDict[gId]->header().data() : 0; + ol.startMemberItem(gId!=-1,0); + ol.writeString("enum "); + ol.insertMemberAlign(); + ol+=typeDecl; + ol.endMemberItem(gId!=-1,md->anchor(),gHeader,FALSE); + //QCString brief=md->briefDescription(); + //brief=brief.stripWhiteSpace(); + if (!md->briefDescription().isEmpty() && Config::briefMemDescFlag + && gId==-1 && !inGroup) + { + ol.startMemberDescription(); + parseDoc(ol,cd?cd->name().data():0, + md->name().data(),md->briefDescription()); + if (!md->documentation().isEmpty() || md->hasDocumentedEnumValues()) + { + ol.disableAllBut(OutputGenerator::Html); + ol.endEmphasis(); + ol.docify(" "); + ol.startTextLink(0,md->anchor()); + parseText(ol,theTranslator->trMore()); + ol.endTextLink(); + ol.startEmphasis(); + ol.enableAll(); + } + ol.endMemberDescription(); + ol.disable(OutputGenerator::Man); + ol.newParagraph(); + ol.enable(OutputGenerator::Man); + } + } + md->warnIfUndocumented(); + prevGroupId = md->groupId(); + } + } // md->isEnumerate() + } // enum loop + if (fd || nd) ol.endMemberList(); + } // write enums + + // write functions + if (funcCount()>0) + { + if (fd || nd) + { + ol.startMemberHeader(); + parseText(ol,theTranslator->trFunctions()); + ol.endMemberHeader(); + ol.startMemberList(); + } + MemberListIterator mli(*this); + for ( ; (md=mli.current()) ; ++mli ) + { + if ( md->isFunction() || md->isSignal() || + md->isSlot()) + { + md->writeDeclaration(ol,cd,nd,fd,prevGroupId,inGroup); + prevGroupId = md->groupId(); + } + } + if (fd || nd) ol.endMemberList(); + } + + if (friendCount()>0) + { + MemberListIterator mli(*this); + for ( ; (md=mli.current()) ; ++mli ) + { + if ( md->isFriend()) + { + QCString type=md->typeString(); + //printf("Friend: type=%s name=%s\n",type.data(),md->name().data()); + if (md->hasDocumentation() && type!="friend class") + { + md->writeDeclaration(ol,cd,nd,fd,prevGroupId,inGroup); + prevGroupId = md->groupId(); + } + else // friend is undocumented as a member but it is a class, + // so generate a link to the class if that is documented. + { + int gId = md->groupId(); + const char *gHeader = (gId!=prevGroupId && gId!=-1) ? + memberGroupDict[gId]->header().data() : 0; + ClassDef *cd=getClass(md->name()); + if (md->hasDocumentation()) // friend is documented + { + ol.startMemberItem(gId!=-1,0); + ol.docify("class "); + ol.insertMemberAlign(); + ol.writeObjectLink(0,0,md->anchor(),md->name()); + ol.endMemberItem(gId!=-1,md->anchor(),gHeader,FALSE); + prevGroupId = md->groupId(); + } + else if (cd && cd->isLinkable()) // class is documented + { + ol.startMemberItem(gId!=-1,0); + ol.docify("class "); + ol.insertMemberAlign(); + ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->name()); + ol.endMemberItem(gId!=-1,md->anchor(),gHeader,FALSE); + prevGroupId = md->groupId(); + } + else if (!Config::hideMemberFlag) // no documentation + { + ol.startMemberItem(gId!=-1,0); + ol.docify("class "); + ol.insertMemberAlign(); + ol.writeBoldString(md->name()); + ol.endMemberItem(gId!=-1,md->anchor(),gHeader,FALSE); + prevGroupId = md->groupId(); + } + } + } + } + } + + // write variables + if (varCount()>0) + { + if (fd || nd) + { + ol.startMemberHeader(); + parseText(ol,theTranslator->trVariables()); + ol.endMemberHeader(); + ol.startMemberList(); + } + MemberListIterator mli(*this); + for ( ; (md=mli.current()) ; ++mli ) + { + if (md->isVariable()) + { + md->writeDeclaration(ol,cd,nd,fd,prevGroupId,inGroup); + prevGroupId = md->groupId(); + } + } + if (fd || nd) ol.endMemberList(); + } + + // handle members that are inside annonymous compounds and for which + // no variables of the annonymous compound type exist. + if (cd) + { + MemberListIterator mli(*this); + for ( ; (md=mli.current()) ; ++mli ) + { + if (md->fromAnnonymousScope() && !md->annonymousDeclShown()) + { + md->setFromAnnonymousScope(FALSE); + md->writeDeclaration(ol,cd,nd,fd,prevGroupId,inGroup); + md->setFromAnnonymousScope(TRUE); + prevGroupId = md->groupId(); + } + } + } + + if (!fd && !nd) { ol.endMemberList(); /*ol.writeChar('\n');*/ } + + if (prevGroupId!=-1 && !inGroup) + { + ol.memberGroupSpacing(TRUE); + ol.memberGroupSeparator(); + } +} + +void MemberList::writeDeclarations(OutputList &ol,ClassDef *cd,NamespaceDef *nd, + FileDef *fd,const char *title,const char *subtitle,bool inGroup) +{ + countDecMembers(); + if (totalCount()==0) return; + if (title) + { + ol.startMemberHeader(); + parseText(ol,title); + ol.endMemberHeader(); + } + if (subtitle) + { + ol.startMemberSubtitle(); + parseText(ol,subtitle); + ol.endMemberSubtitle(); + } + + writePlainDeclarations(ol,cd,nd,fd,inGroup); +} + +void MemberList::writeDocumentation(OutputList &ol, + const char *scopeName, MemberDef::MemberType m) +{ + MemberListIterator mli(*this); + MemberDef *md; + for ( ; (md=mli.current()) ; ++mli) + { + md->writeDocumentation(this,ol,scopeName,m); + } +} diff --git a/src/memberlist.h b/src/memberlist.h index c26f055..abc84f2 100644 --- a/src/memberlist.h +++ b/src/memberlist.h @@ -38,10 +38,16 @@ class MemberList : public QList int defineCount() const { return defCnt; } int friendCount() const { return friendCnt; } void countDecMembers(); - void countDocMembers(); + void countDocMembers(bool inGroup=FALSE); int totalCount() const { return varCnt+funcCnt+enumCnt+enumValCnt+typeCnt+ protoCnt+defCnt+friendCnt; } + void writePlainDeclarations(OutputList &ol,ClassDef *cd, + NamespaceDef *nd,FileDef *fd,bool inGroup=FALSE); + void writeDeclarations(OutputList &ol,ClassDef *cd,NamespaceDef *nd,FileDef *fd, + const char *title,const char *subtitle,bool inGroup=FALSE); + void writeDocumentation(OutputList &ol,const char *scopeName, + MemberDef::MemberType m); private: int varCnt,funcCnt,enumCnt,enumValCnt,typeCnt,protoCnt,defCnt,friendCnt; diff --git a/src/membername.cpp b/src/membername.cpp index 2605f86..eb28091 100644 --- a/src/membername.cpp +++ b/src/membername.cpp @@ -50,10 +50,6 @@ MemberNameInfo::MemberNameInfo(const char *n) : QList() setAutoDelete(TRUE); } -MemberNameInfo::~MemberNameInfo() -{ -} - int MemberNameInfo::compareItems(GCI item1, GCI item2) { MemberInfo *m1=(MemberInfo *)item1; diff --git a/src/membername.h b/src/membername.h index c485dc8..a9454f9 100644 --- a/src/membername.h +++ b/src/membername.h @@ -70,7 +70,6 @@ class MemberNameInfo : public QList { public: MemberNameInfo(const char *name); - ~MemberNameInfo(); const char *memberName() const { return name; } int compareItems(GCI item1,GCI item2); private: diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index 2574563..d8388a0 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -30,7 +30,7 @@ NamespaceDef::NamespaceDef(const char *name,const char *ref) : Definition(name) fileName="namespace_"+nameToFile(name); classList = new ClassList; memList = new MemberList; - reference=ref; + setReference(ref); } NamespaceDef::~NamespaceDef() @@ -94,7 +94,7 @@ void NamespaceDef::writeDocumentation(OutputList &ol) bool found=FALSE; while (cd) { - if (cd->isVisibleExt()) + if (cd->isLinkable()) { if (!found) { @@ -110,12 +110,13 @@ void NamespaceDef::writeDocumentation(OutputList &ol) clName = clName.right(clName.length()-name().length()-2); } - ol.startMemberItem(); + ol.startMemberItem(FALSE,0); switch (cd->compoundType()) { - case ClassDef::Class: ol.writeString("class"); break; - case ClassDef::Struct: ol.writeString("struct"); break; - case ClassDef::Union: ol.writeString("union"); break; + case ClassDef::Class: ol.writeString("class"); break; + case ClassDef::Struct: ol.writeString("struct"); break; + case ClassDef::Union: ol.writeString("union"); break; + case ClassDef::Interface: ol.writeString("interface"); break; } ol.writeString(" "); ol.insertMemberAlign(); @@ -133,14 +134,14 @@ void NamespaceDef::writeDocumentation(OutputList &ol) ol.docify(clName); ol.endBold(); } - ol.endMemberItem(); + ol.endMemberItem(FALSE,0,0,FALSE); } cd=classList->next(); } if (found) ol.endMemberList(); } - writeMemberDecs(ol,0,this,0,0,0,memList); + memList->writeDeclarations(ol,0,this,0,0,0); ol.endMemberSections(); if (!briefDescription().isEmpty() || !documentation().isEmpty()) @@ -173,7 +174,7 @@ void NamespaceDef::writeDocumentation(OutputList &ol) ol.startGroupHeader(); parseText(ol,theTranslator->trFunctionPrototypeDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,memList,name(),MemberDef::Prototype); + memList->writeDocumentation(ol,name(),MemberDef::Prototype); } if ( memList->typedefCount()>0 ) @@ -182,7 +183,7 @@ void NamespaceDef::writeDocumentation(OutputList &ol) ol.startGroupHeader(); parseText(ol,theTranslator->trTypedefDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,memList,name(),MemberDef::Typedef); + memList->writeDocumentation(ol,name(),MemberDef::Typedef); } if ( memList->enumCount()>0 ) @@ -191,7 +192,7 @@ void NamespaceDef::writeDocumentation(OutputList &ol) ol.startGroupHeader(); parseText(ol,theTranslator->trEnumerationTypeDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,memList,name(),MemberDef::Enumeration); + memList->writeDocumentation(ol,name(),MemberDef::Enumeration); } if ( memList->enumValueCount()>0 ) @@ -200,16 +201,19 @@ void NamespaceDef::writeDocumentation(OutputList &ol) ol.startGroupHeader(); parseText(ol,theTranslator->trEnumerationValueDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,memList,name(),MemberDef::EnumValue); + memList->writeDocumentation(ol,name(),MemberDef::EnumValue); } - if ( memList->funcCount()>0 ) + int cnt; + if ( (cnt=memList->funcCount()>0) ) { ol.writeRuler(); ol.startGroupHeader(); - parseText(ol,theTranslator->trFunctionDocumentation()); + QCString cntString; + //cntString.sprintf(" (%d)",cnt); + parseText(ol,theTranslator->trFunctionDocumentation()+cntString); ol.endGroupHeader(); - writeMemberDocs(ol,memList,name(),MemberDef::Function); + memList->writeDocumentation(ol,name(),MemberDef::Function); } if ( memList->varCount()>0 ) @@ -218,7 +222,7 @@ void NamespaceDef::writeDocumentation(OutputList &ol) ol.startGroupHeader(); parseText(ol,theTranslator->trVariableDocumentation()); ol.endGroupHeader(); - writeMemberDocs(ol,memList,name(),MemberDef::Variable); + memList->writeDocumentation(ol,name(),MemberDef::Variable); } // write Author section (Man only) diff --git a/src/namespacedef.h b/src/namespacedef.h index ca25700..e68fa3f 100644 --- a/src/namespacedef.h +++ b/src/namespacedef.h @@ -41,20 +41,32 @@ class NamespaceDef : public Definition void insertMember(MemberDef *md); void computeAnchors(); int countMembers(); - const char *getReference() { return reference; } - bool isVisible() + //const char *getReference() { return reference; } + //bool isVisible() + //{ + // return !getReference() && hasDocumentation() && + // !name().isEmpty() && name().at(0)!='@'; + //} + //bool isVisibleExt() + //{ + // return (getReference() || hasDocumentation()) && + // !name().isEmpty() && name().at(0)!='@'; + //} + + bool isLinkableInProject() { - return !getReference() && hasDocumentation() && - !name().isEmpty() && name().at(0)!='@'; + int i = name().findRev("::"); + if (i==-1) i=0; else i+=2; + return !name().isEmpty() && name().at(i)!='@' && + hasDocumentation() && !isReference(); } - bool isVisibleExt() + bool isLinkable() { - return (getReference() || hasDocumentation()) && - !name().isEmpty() && name().at(0)!='@'; + return isLinkableInProject() || isReference(); } private: - QCString reference; + //QCString reference; QCString fileName; QStrList files; ClassList *classList; @@ -79,6 +91,10 @@ class NamespaceListIterator : public QListIterator QListIterator(l) {} }; -typedef QDict NamespaceDict; +class NamespaceDict : public QDict +{ + public: + NamespaceDict(int size) : QDict(size) {} +}; #endif diff --git a/src/outputgen.h b/src/outputgen.h index 7411d5c..778705c 100644 --- a/src/outputgen.h +++ b/src/outputgen.h @@ -67,6 +67,9 @@ class OutputGenerator virtual void endEnumList() = 0; virtual void startBold() = 0; virtual void endBold() = 0; + virtual void startAlfabeticalIndexList() = 0; + virtual void endAlfabeticalIndexList() = 0; + virtual void writeIndexHeading(const char *s) = 0; virtual void writeIndexItem(const char *ref,const char *file, const char *text) = 0; virtual void docify(const char *s) = 0; @@ -92,8 +95,10 @@ class OutputGenerator virtual void endMemberSubtitle() = 0; virtual void startMemberList() = 0; virtual void endMemberList() = 0; - virtual void startMemberItem() = 0; - virtual void endMemberItem() = 0; + virtual void startMemberItem(bool,int) = 0; + virtual void endMemberItem(bool,const char *,const char *,bool) = 0; + virtual void memberGroupSpacing(bool) = 0; + virtual void memberGroupSeparator() = 0; virtual void insertMemberAlign() = 0; virtual void writeRuler() = 0; @@ -165,6 +170,7 @@ class OutputGenerator virtual void startQuickIndexItem(const char *s,const char *l) = 0; virtual void endQuickIndexItem() = 0; virtual void writeFormula(const char *,const char *) = 0; + virtual void writeNonBreakableSpace() = 0; void clear() { b.close(); a.resize(0); b.setBuffer(a); b.open(IO_WriteOnly); t.setDevice(&b); } diff --git a/src/outputlist.cpp b/src/outputlist.cpp index daa83ed..ae86c89 100644 --- a/src/outputlist.cpp +++ b/src/outputlist.cpp @@ -226,14 +226,18 @@ void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4),a1,a2,a3,a4) FORALL1(const char *a1,a1) FORALL1(char a1,a1) FORALL1(int a1,a1) +FORALL1(bool a1,a1) FORALL1(IndexSections a1,a1) FORALL2(const char *a1,const char *a2,a1,a2) FORALL2(int a1,bool a2,a1,a2) +FORALL2(bool a1,int a2,a1,a2) +FORALL2(bool 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) +FORALL4(bool a1,const char *a2,const char *a3,bool a4,a1,a2,a3,a4) //-------------------------------------------------------------------------- diff --git a/src/outputlist.h b/src/outputlist.h index 8f66f63..79ee93f 100644 --- a/src/outputlist.h +++ b/src/outputlist.h @@ -96,6 +96,12 @@ class OutputList { forall(&OutputGenerator::startEnumList); } void endEnumList() { forall(&OutputGenerator::endEnumList); } + void startAlfabeticalIndexList() + { forall(&OutputGenerator::startAlfabeticalIndexList); } + void endAlfabeticalIndexList() + { forall(&OutputGenerator::endAlfabeticalIndexList); } + void writeIndexHeading(const char *s) + { forall(&OutputGenerator::writeIndexHeading,s); } void writeIndexItem(const char *ref,const char *file,const char *text) { forall(&OutputGenerator::writeIndexItem,ref,file,text); } void docify(const char *s) @@ -145,10 +151,14 @@ class OutputList { forall(&OutputGenerator::startMemberList); } void endMemberList() { forall(&OutputGenerator::endMemberList); } - void startMemberItem() - { forall(&OutputGenerator::startMemberItem); } - void endMemberItem() - { forall(&OutputGenerator::endMemberItem); } + void startMemberItem(bool b1,int i1) + { forall(&OutputGenerator::startMemberItem,b1,i1); } + void endMemberItem(bool b1,const char *n1,const char *n2,bool b2) + { forall(&OutputGenerator::endMemberItem,b1,n1,n2,b2); } + void memberGroupSpacing(bool b) + { forall(&OutputGenerator::memberGroupSpacing,b); } + void memberGroupSeparator() + { forall(&OutputGenerator::memberGroupSeparator); } void insertMemberAlign() { forall(&OutputGenerator::insertMemberAlign); } void writeRuler() @@ -287,6 +297,8 @@ class OutputList { forall(&OutputGenerator::endQuickIndexItem); } void writeFormula(const char *n,const char *t) { forall(&OutputGenerator::writeFormula,n,t); } + void writeNonBreakableSpace() + { forall(&OutputGenerator::writeNonBreakableSpace); } private: void debug(); @@ -296,14 +308,18 @@ class OutputList FORALLPROTO1(const char *); FORALLPROTO1(char); FORALLPROTO1(int); + FORALLPROTO1(bool); FORALLPROTO1(IndexSections); FORALLPROTO2(const char *,const char *); FORALLPROTO2(int,bool); + FORALLPROTO2(bool,int); + FORALLPROTO2(bool,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 *); + FORALLPROTO4(bool,const char *,const char *,bool); OutputList(const OutputList &ol); QList *outputs; diff --git a/src/pre.l b/src/pre.l index 6f5193a..be80487 100644 --- a/src/pre.l +++ b/src/pre.l @@ -294,9 +294,6 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int 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++; @@ -329,8 +326,8 @@ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int } else { - while ((argCountnargs || def->varArgs) && - ((cc=getNextChar(expr,rest,j))!=EOF) && !done + while (!done && (argCountnargs || def->varArgs) && + ((cc=getNextChar(expr,rest,j))!=EOF) ) { char c=(char)cc; @@ -586,13 +583,17 @@ static void expandExpression(QCString &expr,QCString *rest,int pos) if (replaced) // expand the macro and rescan the expression { + //printf("replacing `%s'->`%s'\n",expr.mid(p,len).data(),expMacro.data()); QCString resultExpr=expMacro; QCString restExpr=expr.right(expr.length()-len-p); processConcatOperators(resultExpr); - expandedDict->insert(macroName,def); - expandExpression(resultExpr,&restExpr,0); - expandedDict->remove(macroName); + if (!def->nonRecursive) + { + 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()); @@ -708,7 +709,6 @@ bool computeExpression(const QCString &expr) expandExpression(e,0,0); e = removeIdsAndMarkers(e); if (e.length()==0) return FALSE; - //printf("computeExpession(%s)\n",e.data()); return parseCppExpression(e); } @@ -890,7 +890,8 @@ BN [ \t\r\n] if (includeStack.isEmpty() && Config::macroExpansionFlag && /* (expandDefine=fileDefineCache->findDefine(yyFileName,yytext)) */ - (def=fileDefineDict->find(yytext)) + (def=fileDefineDict->find(yytext)) && + (!Config::onlyPredefinedFlag || def->isPredefined) ) { //printf("Found it!\n"); @@ -899,6 +900,7 @@ BN [ \t\r\n] if (def->nargs==-1) // no function macro { QCString result = expandMacro(defArgsStr); + //printf("result=`%s'\n",result.data()); outputArray(result,result.length()); } else // zero or more arguments @@ -918,12 +920,14 @@ BN [ \t\r\n] if (includeStack.isEmpty() && Config::macroExpansionFlag && (def=fileDefineDict->find(yytext)) && - def->nargs==-1 + def->nargs==-1 && + (!Config::onlyPredefinedFlag || def->isPredefined) ) { //printf("Found it!\n"); QCString name=yytext; QCString result=expandMacro(name); + //printf("result=`%s'\n",result.data()); outputArray(result,result.length()); } else @@ -948,6 +952,7 @@ BN [ \t\r\n] roundCount--; if (roundCount==0) { + //printf("defArgsStr=`%s'\n",defArgsStr.data()); QCString result=expandMacro(defArgsStr); if (findDefArgContext==CopyLine) { @@ -987,6 +992,9 @@ BN [ \t\r\n] defArgsStr+=*yytext; BEGIN(FindDefineArgs); } +"//"|"/*" { + defArgsStr+=yytext; + } . { defArgsStr+=*yytext; } @@ -1273,7 +1281,7 @@ BN [ \t\r\n] //{ // addDefine(); //} - if (!Config::onlyPredefinedFlag && (def=fileDefineDict->find(defName))==0) + if (/*!Config::onlyPredefinedFlag &&*/ (def=fileDefineDict->find(defName))==0) { fileDefineDict->insert(defName,newDefine()); } @@ -1300,7 +1308,7 @@ BN [ \t\r\n] } ","{B}* { defArgsStr+=yytext; } "("{B}* { defArgsStr+=yytext; } -")"{B}* { +{B}*")"{B}* { defArgsStr+=yytext; QCString tmp=(QCString)"#define "+defName+defArgsStr; outputArray(tmp.data(),tmp.length()); @@ -1421,7 +1429,7 @@ BN [ \t\r\n] { addDefine(); } - if (!Config::onlyPredefinedFlag && (def=fileDefineDict->find(defName))==0) + if (/*!Config::onlyPredefinedFlag &&*/ (def=fileDefineDict->find(defName))==0) { fileDefineDict->insert(defName,newDefine()); } @@ -1460,6 +1468,9 @@ BN [ \t\r\n] defText += *yytext; BEGIN(DefineText); } +\\. { + defText += yytext; + } \' { defText += *yytext; BEGIN(DefineText); @@ -1629,6 +1640,7 @@ void preprocessFile(const char *fileName,BufStr &output) int i_equals=ds.find('='); int i_obrace=ds.find('('); int i_cbrace=ds.find(')'); + bool nonRecursive = i_equals>0 && ds.at(i_equals-1)==':'; if (i_obrace==0) continue; // no define name @@ -1676,6 +1688,8 @@ void preprocessFile(const char *fileName,BufStr &output) def->name = ds.left(i_obrace); def->definition = definition; def->nargs = count; + def->isPredefined = TRUE; + def->nonRecursive = nonRecursive; fileDefineDict->insert(def->name,def); //printf("#define `%s' `%s' #nargs=%d\n", @@ -1694,10 +1708,13 @@ void preprocessFile(const char *fileName,BufStr &output) } else // simple define with argument { - def->name = ds.left(i_equals); + int ine=i_equals - (nonRecursive ? 1 : 0); + def->name = ds.left(ine); def->definition = ds.right(ds.length()-i_equals-1); } def->nargs = -1; + def->isPredefined = TRUE; + def->nonRecursive = nonRecursive; fileDefineDict->insert(def->name,def); //printf("#define `%s' `%s' #nargs=%d\n", diff --git a/src/scanner.h b/src/scanner.h index 1e6bad7..30894cd 100644 --- a/src/scanner.h +++ b/src/scanner.h @@ -20,11 +20,15 @@ #include "qtbc.h" #include #include +#include #include "entry.h" #include "code.h" +#include "membergroup.h" class OutputList; +typedef QIntDict MemberGroupDict; +typedef QIntDictIterator MemberGroupDictIterator; extern void parseMain(Entry *); extern void parseDoc(OutputList &ol,const char *clName, const char *memName, @@ -32,4 +36,7 @@ extern void parseDoc(OutputList &ol,const char *clName, const char *memName, extern void parseExample(OutputList &ol,const QCString &docString, const char *fileName); extern void parseText(OutputList &ol,const QCString &txtString); + +extern MemberGroupDict memberGroupDict; + #endif diff --git a/src/scanner.l b/src/scanner.l index 9c7b477..c3c4ade 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -46,6 +46,9 @@ #define YY_NEVER_INTERACTIVE 1 + +MemberGroupDict memberGroupDict(1009); // dictionary of the member groups heading + /* ----------------------------------------------------------------- * * statics @@ -75,6 +78,7 @@ static int lastCurlyContext; static int lastCodeState; static int lastAfterDocContext; static int lastGroupContext; +static int lastMemberGroupContext; static int lastFormulaContext; static int lastAnchorContext; static int nextDefContext; @@ -93,6 +97,7 @@ static Entry* tempEntry = 0 ; static int yyLineNr = 0 ; static int anonCount = 0 ; static char yyFileName[2048] ; +static int lastMemberGroupLine; static bool sig; static bool slot; static bool gstat; @@ -104,6 +109,7 @@ static QCString exampleName; static QCString htmlUrl,htmlText; static QCString currentIncludeFile; static QCString msType,msName,msArgs; +static int memberGroupId = -1; static int includeFileOffset = 0; static int includeFileLength = 0; static bool firstLine; @@ -141,7 +147,8 @@ static int lastCopyArgStringContext; static int lastCopyArgContext; static QCString *copyArgString; - +static ArgumentList *currentArgumentList; +static QCString *currentTemplateSpec; //----------------------------------------------------------------------------- @@ -168,6 +175,7 @@ static void initParser() sharpCount = 0; roundCount = 0; ifCount = 0; + memberGroupId = -1; sig = FALSE; slot = FALSE; gstat = FALSE; @@ -513,8 +521,15 @@ static void showUntil(OutputList &ol,const char *key) } } +static int newMemberGroupId() +{ + static int curGroupId=0; + return curGroupId++; +} + static void newDocState(); + //----------------------------------------------------------------- static bool inBlock() @@ -578,6 +593,20 @@ static bool nameIsOperator(QCString &name) (name.length()==8 || !isId(name.at(name.length()-9))); } +static void checkDocs() +{ + if ((current->brief.length()>2 && + current->brief.at(0)=='<' && current->brief.at(1)==' ') || + (current->doc.length()>2 && + current->doc.at(0)=='<' && current->doc.at(1)==' ') + ) + { + warn("Warning: Found lonely '<' symbol at the start of the documentation " + "at line %d of %s\n",yyLineNr,yyFileName); + + } +} + /* ----------------------------------------------------------------- */ static void addToBody(const char *text); @@ -715,6 +744,7 @@ VAR [vV][aA][rR] %x GroupDocArg1 %x GroupDocArg2 %x GroupName +%x GroupHeader %x AfterDoc %x AfterDocBrief %x AfterDocLine @@ -775,6 +805,7 @@ VAR [vV][aA][rR] %x DocRefItemName %x SectionLabel %x SectionTitle +%x SkipTemplate %x EndTemplate %x CopyArgString %x CopyArgRound @@ -790,6 +821,11 @@ VAR [vV][aA][rR] %% <*>\x06[^\x06]*\x06 { // new file + if (memberGroupId!=-1) + { + warn("Warning: Missing \\endmgroup in file %s\n",yyFileName); + memberGroupId=-1; + } yyLineNr= 1 ; int i; for( i = 0 ; yytext[i+1] != 6 ; i++ ) @@ -1263,7 +1299,7 @@ VAR [vV][aA][rR] warn("Warning: \\endcode without
     or \\code "
         					       "in the documentation of %s\n",refName.data()); 
     					}
    -{SCOPEMASK}"("[a-z_A-Z,\<\> \t\*\&]+")"	{
    +{SCOPEMASK}"("[a-z_A-Z,:\<\> \t\*\&]+")"	{
       					  generateRef(*outDoc,className,yytext,inSeeBlock);
       					}
     {SCOPEMASK}(("()")?)          	{ 
    @@ -1690,9 +1726,28 @@ VAR	  [vV][aA][rR]
     					  lineCount();
       					  BEGIN( ClassName ); 
     					}
    +{B}*"module"{BN}+		{ 
    +  					  isTypedef=FALSE;
    +					  current->section = Entry::NAMESPACE_SEC;
    +					  current->type = "module" ;
    +					  current->fileName  = yyFileName;
    +					  current->startLine = yyLineNr;
    +					  lineCount();
    +  					  BEGIN( ClassName ); 
    +					}
    +{B}*"interface"{BN}+ 	{
    +  					  isTypedef=FALSE;
    +					  current->section = Entry::INTERFACE_SEC;
    +					  addType( current ) ;
    +					  current->type += " interface" ;
    +					  current->fileName  = yyFileName;
    +					  current->startLine = yyLineNr;
    +					  lineCount();
    +					  BEGIN( ClassName );
    +  					}
     {B}*(("typedef"{BN}+)?)"class"{BN}+ { 
     					  isTypedef=((QCString)yytext).find("typedef")!=-1;
    -  					  current->section = Entry::CLASS_SEC ;
    +  					  current->section = Entry::CLASS_SEC;
     					  addType( current ) ;
     					  current->type += " class" ;
     					  current->fileName  = yyFileName;
    @@ -1747,16 +1802,35 @@ VAR	  [vV][aA][rR]
     					}
     "template"({BN}*)"<"/[>]?	{ 
       					  lineCount();
    -					  if (current->tArgList)
    +					  // class template specifier already found => member template specifier
    +					  // already inside class => member template specifier
    +					  if (current->tArgList || (current_root->section&Entry::COMPOUND_MASK))
     					  {
    -					    //printf("scanner.l current->tArgList->clear() %p\n",current->tArgList);
    -					    current->tArgList->clear();
    +					    //printf("-------> member template\n");
    +					    if (current->mtArgList)
    +					    {
    +					      current->mtArgList->clear();
    +                                            }
    +					    else
    +					    {
    +					      current->mtArgList = new ArgumentList;
    +					      current->mtArgList->setAutoDelete(TRUE);
    +					    }
    +					    currentArgumentList = current->mtArgList;
     					  }
    -					  else
    +					  else // class template specifier
     					  {
    -					    current->tArgList = new ArgumentList;
    -					    current->tArgList->setAutoDelete(TRUE);
    -					    //printf("scanner.l new tArgList %p\n",current->tArgList);
    +					    //printf("-------> class template\n");
    +					    if (current->tArgList)
    +					    {
    +					      current->tArgList->clear();
    +                                            }
    +					    else
    +					    {
    +					      current->tArgList = new ArgumentList;
    +					      current->tArgList->setAutoDelete(TRUE);
    +					    }
    +					    currentArgumentList = current->tArgList;
     					  }
     					  templateStr="<";
     					  copyArgString=&templateStr;
    @@ -1764,28 +1838,7 @@ VAR	  [vV][aA][rR]
     					  //printf("Start template list\n");
     					  BEGIN( ReadTempArgs );
       					}
    -  /*
    -({ID}{BN}*"::")*{BN}*"operator"{BN}*[<=]+ {
    -					  lineCount();
    -					  addType( current );
    -					  current->name = yytext;
    -					}
    -"operator"{BN}*"/"[=]?/[^/ *] {  space added!
    -					  lineCount();
    -					  addType( current );
    -					  current->name = yytext;
    -					}
    -"operator"{BN}*"({B}*)"{BN}* /"(" {  space added!  
    -					  lineCount();
    -					  addType( current );
    -					  current->name = yytext;
    -					}
    -"operator"{BN}*[^(/]+	{ 
    -  					  lineCount();
    -  				          addType( current ) ;
    -					  current->name  = yytext ;
    -					}
    -  */
    +  /* for now the using statement is completely ignored */
     "using"{BN}+		{ lineCount(); BEGIN(Using); }
     ";"				{ BEGIN(FindMembers); }
     {SCOPENAME}{BN}*"<>"	{ // guided template decl
    @@ -1799,20 +1852,45 @@ VAR	  [vV][aA][rR]
     					  addType( current );
       					  current->name=yytext;
     					  current->name=current->name.stripWhiteSpace();
    +					  current->scopeSpec.resize(0);
    +					  currentTemplateSpec = ¤t->scopeSpec;
     					  if (nameIsOperator(current->name))
     					    BEGIN( Operator );
     					  else
     					    BEGIN( EndTemplate );
     					}
    +{SCOPENAME}{BN}*/"<"	{
    +  					  sharpCount=0;
    +					  lineCount();
    +  					  current->name+=((QCString)yytext).stripWhiteSpace();
    +					  current->memberSpec.resize(0);
    +					  currentTemplateSpec = ¤t->memberSpec;
    +					  if (nameIsOperator(current->name))
    +					    BEGIN( Operator );
    +					  else
    +					    BEGIN( EndTemplate );
    +  					}
    +  /*
    +"<"			{
    +					  sharpCount++; 
    +  					}
    +">"			{
    +  					  if (--sharpCount<=0)
    +					  {
    +					    BEGIN(FindMembers);
    +					  }
    +  					}
    +.
    +  */
    +
     "<"			{ 
    -  					  current->name+='<'; 
    +  					  current->name+='<';
    +  					  *currentTemplateSpec+='<'; 
     					  sharpCount++; 
     					}
    -  /*
    -">"({BN}*"::"{SCOPENAME})?	{
    -  */
     ">"			{
    -					  current->name+=*yytext;
    +  					  current->name+='>';
    +					  *currentTemplateSpec+='>';
     					  if (--sharpCount<=0)
     					  {  
     					    //printf("Found %s\n",current->name.data());
    @@ -1821,7 +1899,8 @@ VAR	  [vV][aA][rR]
     					}
     ">"{BN}*"("		{ 
       					  lineCount();
    -					  current->name+='>';
    +  					  current->name+='>';
    +					  *currentTemplateSpec+='>';
     					  if (--sharpCount<=0)
     					  {
     					    current->args = "(";
    @@ -1834,12 +1913,16 @@ VAR	  [vV][aA][rR]
     ">"{BN}*/"::"		{
       					  lineCount();
       					  current->name+='>';
    +  					  *currentTemplateSpec+='>';
     					  if (--sharpCount<=0)
     					  {
     					    BEGIN(FindMemberName);
     					  }
       					}
    -.				{ current->name+=*yytext; }
    +.				{ 
    +  					  current->name+=*yytext;
    +  					  *currentTemplateSpec+=*yytext; 
    +					}
     {SCOPENAME}	{ 
     					  lineCount();
     					  if (YY_START==FindMembers)
    @@ -1857,10 +1940,10 @@ VAR	  [vV][aA][rR]
     					  else
     					    BEGIN(FindMembers);
     					}
    -^{B}*"#"			{ lastCPPContext = YY_START; 
    +{B}*"#"			{ lastCPPContext = YY_START; 
     					  BEGIN( SkipCPP ) ; 
     					}
    -^{B}*"#define"		{
    +{B}*"#"{B}*"define"	{
       					  BEGIN( Define );
       					}
     .
    @@ -1908,45 +1991,66 @@ VAR	  [vV][aA][rR]
     [*&]+			{ current->name += yytext ; }
     ";"{BN}*("/**"|"//!"|"/*!"|"///")"<" {
       					  lineCount();
    -					  current->doc.resize(0);
    -					  current->brief.resize(0);
     					  lastAfterDocContext = YY_START;
     					  afterDocTerminator = ';';
     					  if (yytext[yyleng-3]=='/')
    +					  {
    +					    current->brief.resize(0);
     					    BEGIN(AfterDocLine);
    +					  }
     					  else if (yytext[yyleng-2]=='*' && Config::autoBriefFlag)
    +					  {
    +					    current->brief.resize(0);
     					    BEGIN(AfterDocBrief);
    +					  }
     					  else
    +					  {
    +					    current->doc.resize(0);
     					    BEGIN(AfterDoc);
    +					  }
       					}
     ","{BN}*("/**"|"//!"|"/*!"|"///")"<" {
       					  lineCount();
    -					  current->doc.resize(0);
    -					  current->brief.resize(0);
     					  lastAfterDocContext = YY_START;
     					  afterDocTerminator = ',';
     					  if (yytext[yyleng-3]=='/')
    +					  {
    +					    current->brief.resize(0);
     					    BEGIN(AfterDocLine);
    +					  }
     					  else if (yytext[yyleng-2]=='*' && Config::autoBriefFlag)
    +					  {
    +					    current->brief.resize(0);
     					    BEGIN(AfterDocBrief);
    +					  }
     					  else
    +					  {
    +					    current->doc.resize(0);
     					    BEGIN(AfterDoc);
    +					  }
       					}
     {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]=='/')
    +					  {
    +					    current->brief.resize(0);
     					    BEGIN(AfterDocLine);
    +					  }
     					  else if (yytext[yyleng-2]=='*' && Config::autoBriefFlag)
    +					  {
    +					    current->brief.resize(0);
     					    BEGIN(AfterDocBrief);
    +					  }
     					  else
    +					  {
    +					    current->doc.resize(0);
     					    BEGIN(AfterDoc);
    +					  }
       					}
     "="			{
       					  BEGIN(NextSemi);
    @@ -2326,7 +2430,7 @@ VAR	  [vV][aA][rR]
     ">"			{
     					  *copyArgString+=*yytext;
     					  //printf("end template list %s\n",copyArgString->data());
    -					  stringToArgumentList(*copyArgString,current->tArgList);
    +					  stringToArgumentList(*copyArgString,currentArgumentList);
     					  BEGIN( currentArgumentContext );
     					}
     "("			{
    @@ -2496,6 +2600,9 @@ VAR	  [vV][aA][rR]
     					      current->proto = TRUE;
     					    }
     					  }
    +					  //printf("Adding entry `%s' groupId=%d groupHeader=`%s'\n",
    +					  //    current->name.data(),current->mGrpId,current->mGrpId!=-1 ? 
    +					  //        memberGroupDict[current->mGrpId]->header().data() : "");
     					  previous = current;
     					  current_root->addSubEntry(current);
     					  current = new Entry ;
    @@ -2504,6 +2611,7 @@ VAR	  [vV][aA][rR]
     					  current->virt = virt;
     					  current->stat = gstat;
     					  current->slot = slot;
    +					  current->mGrpId = memberGroupId;
     					  lastCurlyContext = FindMembers;
     					  if( *yytext == '{' )
     					  {
    @@ -2658,14 +2766,17 @@ VAR	  [vV][aA][rR]
     					  current->name = yytext ;
     					  //BEGIN( FindMembers );
       					}
    -"("				{
    -					  roundCount=1;
    -					  lastSkipRoundContext=YY_START;
    -					  BEGIN(SkipRound);
    +[(\[]				{
    +                                          // probably a function anyway
    +                                          unput('(');
    +					  BEGIN( FindMembers );
     					}
     ":"				{ 
       					  current->type.resize(0);
    -                                          baseProt=Private;
    +					  if (current->section == Entry::INTERFACE_SEC)
    +					    baseProt=Public;
    +					  else  
    +					    baseProt=Private;
                                               baseVirt=Normal;
     					  baseName.resize(0);
     					  BEGIN( Bases ) ;
    @@ -2676,6 +2787,7 @@ VAR	  [vV][aA][rR]
         					}
     {B}*"{"{B}*		{ current->fileName = yyFileName ;
     					  current->startLine = yyLineNr ;
    +					  current->name = removeRedundantWhiteSpace(current->name);
     					  if (current->name.length()==0 && !isTypedef) // anonymous compound
     					    current->name.sprintf("@%d",anonCount++);
     					  BEGIN( Curly ) ;
    @@ -2725,6 +2837,7 @@ VAR	  [vV][aA][rR]
     					    BEGIN ( lastSkipRoundContext );
     					}
     ","				{ current->args += ',' ; 
    +					  current->name = removeRedundantWhiteSpace(current->name);
       					  if (baseName.length()>0)
       					    current->extends->append(
     					      new BaseInfo(baseName,baseProt,baseVirt)
    @@ -2735,6 +2848,7 @@ VAR	  [vV][aA][rR]
     					}
     {B}*"{"{B}*			{ current->fileName = yyFileName ;
     					  current->startLine = yyLineNr ;
    +					  current->name = removeRedundantWhiteSpace(current->name);
       					  if (baseName.length()>0)
       					    current->extends->append(
     					      new BaseInfo(baseName,baseProt,baseVirt)
    @@ -2935,6 +3049,12 @@ VAR	  [vV][aA][rR]
     					  current->startLine = yyLineNr;
     					  BEGIN( ClassDocArg1 ); 
     					}
    +{B}*("\\"|"@")"interface"{B}* {
    +  					  current->section = Entry::INTERFACEDOC_SEC;
    +					  current->fileName = yyFileName;
    +					  current->startLine = yyLineNr;
    +					  BEGIN( ClassDocArg1 ); 
    +					}
     {B}*("\\"|"@")"page"{B}*   {
       					  current->section = Entry::PAGEDOC_SEC;
     					  current->fileName = yyFileName;
    @@ -3076,6 +3196,35 @@ VAR	  [vV][aA][rR]
       					  sectionType=SectionInfo::Subsection;
       					  BEGIN(SectionLabel);
       					}
    +("\\"|"@")mgroup{B}+ {
    +  					  //printf("--> mgroup found!\n");
    +  					  lastMemberGroupContext = YY_START;
    +					  if (memberGroupId!=-1)
    +					  {
    +  					    warn("Warning: ignoring nested mgroup command "
    +					         "at line %d of %s. Previous command was found at line %d\n",
    +						 yyLineNr,yyFileName,lastMemberGroupLine);
    +					  }
    +					  else
    +					  {
    +					    memberGroupId   = newMemberGroupId();
    +					    current->mGrpId = memberGroupId;
    +					    lastMemberGroupLine = yyLineNr;
    +					  }
    +					  BEGIN(GroupHeader);
    +  					}
    +("\\"|"@")endmgroup/[^a-z_A-Z0-9] {
    +  					  //printf("--> endmgroup found!\n");
    +  					  memberGroupId = -1;
    +					  current->mGrpId = -1;
    +  					}
    +[^\n]*/"\n"		{
    +					  QCString header = ((QCString)yytext).stripWhiteSpace();
    +  					  memberGroupDict.insert(memberGroupId,
    +					                         new MemberGroup(memberGroupId,header)
    +								);
    +  					  BEGIN(lastMemberGroupContext);
    +  					}
     ("\\"|"@")anchor{B}+ {
       					  lastAnchorContext = YY_START;
       					  sectionType=SectionInfo::Anchor;
    @@ -3216,6 +3365,7 @@ VAR	  [vV][aA][rR]
       							}
     .                     { formulaText+=*yytext; }
     "*/"    	{
    +  					  checkDocs();
       					  if (YY_START==ClassDocBrief &&
     					      lastBriefContext==Doc)
     					  {
    @@ -3432,6 +3582,7 @@ VAR	  [vV][aA][rR]
     					  BEGIN( lastDocContext );
     					}
     "*/"				{ 
    +  				          checkDocs();
       					  current->doc += "\n\n";
       					  BEGIN( lastDocContext ); 
     					}
    @@ -3540,7 +3691,7 @@ void parseCompounds(Entry *rt)
     	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
    +      else // named struct, union, or interface
     	current->protection = protection = Public ;
           sig = FALSE;
           slot = FALSE;
    @@ -3637,6 +3788,11 @@ void parseText(OutputList &ol,const QCString &txtString)
       scanYYrestart( scanYYin ); 
       BEGIN( Text );
       scanYYlex();
    +  if (memberGroupId!=-1)
    +  {
    +    warn("Warning: Missing \\endmgroup in file %s\n",yyFileName);
    +    memberGroupId=-1;
    +  }
       ol+=*outDoc;
       delete outDoc;
       return;
    @@ -3655,3 +3811,6 @@ void parseExample(OutputList &ol,const QCString &docString,
     }
     
     //----------------------------------------------------------------------------
    +extern "C" { // some bogus code to keep the compiler happy
    +  void scannerYYdummy() { yy_flex_realloc(0,0); } 
    +}
    diff --git a/src/tag.l b/src/tag.l
    index 8e02d92..e875f31 100644
    --- a/src/tag.l
    +++ b/src/tag.l
    @@ -101,7 +101,7 @@ static void addNamespace(const char *name)
     
     static void addMember(const char *name,const char *anchor,const char *args)
     {
    -  //printf("adding member %s\n",name);
    +  //printf("adding member `%s' `%s'\n",name,anchor);
       if (cd || fd)
       {
         MemberNameDict *mnd=0;
    @@ -112,7 +112,8 @@ static void addMember(const char *name,const char *anchor,const char *args)
         md=new MemberDef(0,name,args,0,Public,Normal,FALSE,FALSE,
                            MemberDef::Function,0,argList); 
         delete argList;
    -    md->setReference(anchor);
    +    md->setAnchor(anchor);
    +    md->setReference(tagName);
         if (cd) // member of a class
         {
           md->setMemberClass(cd);
    @@ -157,7 +158,7 @@ static void addMember(const char *name,const char *anchor,const char *args)
     
     %}
     
    -ID [a-z_A-Z][a-z_A-Z0-9]*
    +ID [a-z_A-Z0-9]+
     FILE [a-z_A-Z0-9\.\-\+\:\\\/]+
     SCOPE ({ID}"::")*{ID}
     
    diff --git a/src/translator.h b/src/translator.h
    index d5c4f67..e81ff92 100644
    --- a/src/translator.h
    +++ b/src/translator.h
    @@ -42,148 +42,163 @@ class Translator
         { return "Reimplemented in"; }
         virtual QCString trIncludeFile()
         { return "Include File"; }
    +    virtual QCString trGeneratedFrom(const char *s,bool single)
    +    { 
    +      QCString result=(QCString)"The documentation for this"+s+
    +                     " was generated from the following file";
    +      if (single) result+=":"; else result+="s:";
    +      return result;
    +    }
         // end of obsolete functions 
         //--------------------------------------------------------------------
     
    +    /*! returns the name of the package that is included by LaTeX */
         virtual QCString latexBabelPackage() 
    -      // returns the name of the package that is included by LaTeX
         { return ""; }
     
    +    /*! used in the compound documentation before a list of related functions. */
         virtual QCString trRelatedFunctions()
    -      // used in the compound documentation before a list of related functions.
         { return "Related Functions"; }
     
    +    /*! subscript for the related functions. */
         virtual QCString trRelatedSubscript()
    -      // subscript for the related functions.
         { return "(Note that these are not member functions.)"; }
     
    +    /*! header that is put before the detailed description of files, classes and namespaces. */
         virtual QCString trDetailedDescription()
    -      // header that is put before the detailed description of files, classes and namespaces.
         { return "Detailed Description"; }
     
    +    /*! header that is put before the list of typedefs. */
         virtual QCString trMemberTypedefDocumentation()
    -      // header that is put before the list of typedefs.
         { return "Member Typedef Documentation"; }
         
    +    /*! header that is put before the list of enumerations. */
         virtual QCString trMemberEnumerationDocumentation()
    -      // header that is put before the list of enumerations.
         { return "Member Enumeration Documentation"; }
         
    +    /*! header that is put before the list of member functions. */
         virtual QCString trMemberFunctionDocumentation()
    -      // header that is put before the list of member functions.
         { return "Member Function Documentation"; }
         
    +    /*! header that is put before the list of member attributes. */
         virtual QCString trMemberDataDocumentation()
    -      // header that is put before the list of member attributes.
         { return "Member Data Documentation"; }
    -    
    -    virtual QCString trGeneratedFrom(const char *s,bool single)
    -    { // here s is one of " Class", " Struct" or " Union"
    -      // single is true implies a single file
    -      QCString result=(QCString)"The documentation for this"+s+
    -                     " was generated from the following file";
    -      if (single) result+=":"; else result+="s:";
    -      return result;
    -    }
     
    +    /*! this is the text of a link put after brief descriptions. */
         virtual QCString trMore() 
    -      // this is the text of a link put after brief descriptions.
         { return "More..."; }
     
    +    /*! put in the class documentation */
         virtual QCString trListOfAllMembers()
    -      // put in the class documentation
         { return "List of all members."; }
     
    +    /*! used as the title of the "list of all members" page of a class */
         virtual QCString trMemberList()
    -      // used as the title of the "list of all members" page of a class
         { return "Member List"; }
     
    +    /*! this is the first part of a sentence that is followed by a class name */
         virtual QCString trThisIsTheListOfAllMembers()
    -      // this is the first part of a sentence that is followed by a class name
         { return "This is the complete list of members for "; }
    +
    +    /*! this is the remainder of the sentence after the class name */
         virtual QCString trIncludingInheritedMembers()
    -      // this is the remainder of the sentence after the class name
         { return ", including all inherited members."; }
         
    +    /*! this is put at the author sections at the bottom of man pages.
    +     *  parameter s is name of the project name.
    +     */
         virtual QCString trGeneratedAutomatically(const char *s)
    -      // this is put at the author sections at the bottom of man pages.
    -      // parameter s is name of the project name.
         { QCString result="Generated automatically by Doxygen";
           if (s) result+=(QCString)" for "+s;
           result+=" from the source code."; 
           return result;
         }
     
    +    /*! put after an enum name in the list of all members */
         virtual QCString trEnumName()
    -      // put after an enum name in the list of all members
         { return "enum name"; }
         
    +    /*! put after an enum value in the list of all members */
         virtual QCString trEnumValue()
    -      // put after an enum value in the list of all members
         { return "enum value"; }
         
    +    /*! put after an undocumented member in the list of all members */
         virtual QCString trDefinedIn()
    -      // put after an undocumented member in the list of all members
         { return "defined in"; }
     
    +    /*! put as in introduction in the verbatim header file of a class.
    +     *  parameter f is the name of the include file.
    +     */
         virtual QCString trVerbatimText(const char *f)
    -      // put as in introduction in the verbatim header file of a class.
    -      // parameter f is the name of the include file.
         { return (QCString)"This is the verbatim text of the "+f+" include file."; }
         
         // quick reference sections
    +
    +    /*! This is put above each page as a link to the list of all groups of 
    +     *  compounds or files (see the \group command).
    +     */
         virtual QCString trModules()
    -      // This is put above each page as a link to the list of all groups of 
    -      // compounds or files (see the \group command).
         { return "Modules"; }
    +    
    +    /*! This is put above each page as a link to the class hierarchy */
         virtual QCString trClassHierarchy()
    -      // This is put above each page as a link to the class hierarchy 
         { return "Class Hierarchy"; }
    +    
    +    /*! This is put above each page as a link to the list of annotated classes */
         virtual QCString trCompoundList()
    -      // This is put above each page as a link to the list of annotated classes
         { return "Compound List"; }
    +    
    +    /*! This is put above each page as a link to the list of documented files */
         virtual QCString trFileList()
    -      // This is put above each page as a link to the list of documented files
         { return "File List"; }
    +
    +    /*! This is put above each page as a link to the list of all verbatim headers */
         virtual QCString trHeaderFiles()
    -      // This is put above each page as a link to the list of all verbatim headers
         { return "Header Files"; }
    +
    +    /*! This is put above each page as a link to all members of compounds. */
         virtual QCString trCompoundMembers()
    -      // This is put above each page as a link to all members of compounds.
         { return "Compound Members"; }
    +
    +    /*! This is put above each page as a link to all members of files. */
         virtual QCString trFileMembers()
    -      // This is put above each page as a link to all members of files.
         { return "File Members"; }
    +
    +    /*! This is put above each page as a link to all related pages. */
         virtual QCString trRelatedPages()
    -      // This is put above each page as a link to all related pages.
         { return "Related Pages"; }
    +
    +    /*! This is put above each page as a link to all examples. */
         virtual QCString trExamples()
    -      // This is put above each page as a link to all examples.
         { return "Examples"; }
    +
    +    /*! This is put above each page as a link to the search engine. */
         virtual QCString trSearch()
    -      // This is put above each page as a link to the search engine.
         { return "Search"; }
     
    +    /*! This is an introduction to the class hierarchy. */
         virtual QCString trClassHierarchyDescription()
    -      // This is an introduction to the class hierarchy.
         { return "This inheritance list is sorted roughly, "
                  "but not completely, alphabetically:";
         }
    +
    +    /*! This is an introduction to the list with all files. */
         virtual QCString trFileListDescription(bool extractAll)
    -      // This is an introduction to the list with all files.
         {
           QCString result="Here is a list of all ";
           if (!extractAll) result+="documented ";
           result+="files with brief descriptions:";
           return result;
         }
    +
    +    /*! This is an introduction to the annotated compound list. */
         virtual QCString trCompoundListDescription()
    -      // This is an introduction to the annotated compound list
         { return "Here are the classes, structs and "
                  "unions with brief descriptions:"; 
         }
    +
    +    /*! This is an introduction to the page with all class members. */
         virtual QCString trCompoundMembersDescription(bool extractAll)
    -      // This is an introduction to the page with all class members
         {
           QCString result="Here is a list of all ";
           if (!extractAll) result+="documented ";
    @@ -194,8 +209,9 @@ class Translator
             result+="the classes they belong to:";
           return result;
         }
    +
    +    /*! This is an introduction to the page with all file members. */
         virtual QCString trFileMembersDescription(bool extractAll)
    -      // This is an introduction to the page with all file members
         {
           QCString result="Here is a list of all ";
           if (!extractAll) result+="documented ";
    @@ -206,137 +222,197 @@ class Translator
             result+="the files they belong to:";
           return result;
         }
    +
    +    /*! This is an introduction to the page with the list of all header files. */
         virtual QCString trHeaderFilesDescription()
    -      // This is an introduction to the page with the list of all header files
         { return "Here are the header files that make up the API:"; }
    +
    +    /*! This is an introduction to the page with the list of all examples */
         virtual QCString trExamplesDescription()
    -      // This is an introduction to the page with the list of all examples
         { return "Here is a list of all examples:"; }
    +
    +    /*! This is an introduction to the page with the list of related pages */
         virtual QCString trRelatedPagesDescription()
    -      // This is an introduction to the page with the list of related pages
         { return "Here is a list of all related documentation pages:"; }
    +
    +    /*! This is an introduction to the page with the list of class/file groups */
         virtual QCString trModulesDescription()
    -      // This is an introduction to the page with the list of class/file groups
         { return "Here is a list of all modules:"; }
    +
    +    /*! This sentences is used in the annotated class/file lists if no brief
    +     * description is given. 
    +     */
         virtual QCString trNoDescriptionAvailable()
    -      // This sentences is used in the annotated class/file lists if no brief
    -      // description is given.
         { return "No description available"; }
         
         // index titles (the project name is prepended for these) 
    +
    +
    +    /*! This is used in HTML as the title of index.html. */
         virtual QCString trDocumentation()
    -      // This is used in HTML as the title of index.html. 
         { return "Documentation"; }
    +
    +    /*! This is used in LaTeX as the title of the chapter with the 
    +     * index of all groups.
    +     */
         virtual QCString trModuleIndex()
    -      // This is used in LaTeX as the title of the chapter with the 
    -      // index of all groups.
         { return "Module Index"; }
    +
    +    /*! This is used in LaTeX as the title of the chapter with the 
    +     * class hierarchy.
    +     */
         virtual QCString trHierarchicalIndex()
    -      // This is used in LaTeX as the title of the chapter with the 
    -      // class hierarchy.
         { return "Hierarchical Index"; }
    +
    +    /*! This is used in LaTeX as the title of the chapter with the 
    +     * annotated compound index.
    +     */
         virtual QCString trCompoundIndex()
    -      // This is used in LaTeX as the title of the chapter with the 
    -      // annotated compound index
         { return "Compound Index"; }
    +
    +    /*! This is used in LaTeX as the title of the chapter with the
    +     * list of all files.
    +     */
         virtual QCString trFileIndex() 
    -      // This is used in LaTeX as the title of the chapter with the
    -      // list of all files.
         { return "File Index"; }
    +
    +    /*! This is used in LaTeX as the title of the chapter containing
    +     *  the documentation of all groups.
    +     */
         virtual QCString trModuleDocumentation()
    -      // This is used in LaTeX as the title of the chapter containing
    -      // the documentation of all groups.
         { return "Module Documentation"; }
    +
    +    /*! This is used in LaTeX as the title of the chapter containing
    +     *  the documentation of all classes, structs and unions.
    +     */
         virtual QCString trClassDocumentation()
    -      // This is used in LaTeX as the title of the chapter containing
    -      // the documentation of all classes, structs and unions.
         { return "Class Documentation"; }
    +
    +    /*! This is used in LaTeX as the title of the chapter containing
    +     *  the documentation of all files.
    +     */
         virtual QCString trFileDocumentation()
    -      // This is used in LaTeX as the title of the chapter containing
    -      // the documentation of all files.
         { return "File Documentation"; }
    +
    +    /*! This is used in LaTeX as the title of the chapter containing
    +     *  the documentation of all examples.
    +     */
         virtual QCString trExampleDocumentation()
    -      // This is used in LaTeX as the title of the chapter containing
    -      // the documentation of all examples.
         { return "Example Documentation"; }
    +
    +    /*! This is used in LaTeX as the title of the chapter containing
    +     *  the documentation of all related pages.
    +     */
         virtual QCString trPageDocumentation()
    -      // This is used in LaTeX as the title of the chapter containing
    -      // the documentation of all related pages.
         { return "Page Documentation"; }
    +
    +    /*! This is used in LaTeX as the title of the document */
         virtual QCString trReferenceManual()
    -      // This is used in LaTeX as the title of the document
         { return "Reference Manual"; }
         
    +    /*! This is used in the documentation of a file as a header before the 
    +     *  list of defines
    +     */
         virtual QCString trDefines()
    -      // This is used in the documentation of a file as a header before the 
    -      // list of defines
         { return "Defines"; }
    +
    +    /*! This is used in the documentation of a file as a header before the 
    +     *  list of function prototypes
    +     */
         virtual QCString trFuncProtos()
    -      // This is used in the documentation of a file as a header before the 
    -      // list of function prototypes
         { return "Function Prototypes"; }
    +
    +    /*! This is used in the documentation of a file as a header before the 
    +     *  list of typedefs
    +     */
         virtual QCString trTypedefs()
    -      // This is used in the documentation of a file as a header before the 
    -      // list of typedefs
         { return "Typedefs"; }
    +
    +    /*! This is used in the documentation of a file as a header before the 
    +     *  list of enumerations
    +     */
         virtual QCString trEnumerations()
    -      // This is used in the documentation of a file as a header before the 
    -      // list of enumerations
         { return "Enumerations"; }
    +
    +    /*! This is used in the documentation of a file as a header before the 
    +     *  list of (global) functions
    +     */
         virtual QCString trFunctions()
    -      // This is used in the documentation of a file as a header before the 
    -      // list of (global) functions
         { return "Functions"; }
    +
    +    /*! This is used in the documentation of a file as a header before the 
    +     *  list of (global) variables
    +     */
         virtual QCString trVariables()
    -      // This is used in the documentation of a file as a header before the 
    -      // list of (global) variables
         { return "Variables"; }
    +
    +    /*! This is used in the documentation of a file as a header before the 
    +     *  list of (global) variables
    +     */
         virtual QCString trEnumerationValues()
    -      // This is used in the documentation of a file as a header before the 
    -      // list of (global) variables
         { return "Enumeration values"; }
         
    +    /*! This is used in man pages as the author section. */
         virtual QCString trAuthor()
    -      // This is used in man pages as the author section.
         { return "Author"; }
     
    +    /*! This is used in the documentation of a file before the list of
    +     *  documentation blocks for defines
    +     */
         virtual QCString trDefineDocumentation()
    -      // This is used in the documentation of a file before the list of
    -      // documentation blocks for defines
         { return "Define Documentation"; }
    +
    +    /*! This is used in the documentation of a file/namespace before the list 
    +     *  of documentation blocks for function prototypes
    +     */
         virtual QCString trFunctionPrototypeDocumentation()
    -      // This is used in the documentation of a file/namespace before the list 
    -      // of documentation blocks for function prototypes
         { return "Function Prototype Documentation"; }
    +
    +    /*! This is used in the documentation of a file/namespace before the list 
    +     *  of documentation blocks for typedefs
    +     */
         virtual QCString trTypedefDocumentation()
    -      // This is used in the documentation of a file/namespace before the list 
    -      // of documentation blocks for typedefs
         { return "Typedef Documentation"; }
    +
    +    /*! This is used in the documentation of a file/namespace before the list 
    +     *  of documentation blocks for enumeration types
    +     */
         virtual QCString trEnumerationTypeDocumentation()
    -      // This is used in the documentation of a file/namespace before the list 
    -      // of documentation blocks for enumeration types
         { return "Enumeration Type Documentation"; }
    +
    +    /*! This is used in the documentation of a file/namespace before the list 
    +     *  of documentation blocks for enumeration values
    +     */
         virtual QCString trEnumerationValueDocumentation()
    -      // This is used in the documentation of a file/namespace before the list 
    -      // of documentation blocks for enumeration values
         { return "Enumeration Value Documentation"; }
    +
    +    /*! This is used in the documentation of a file/namespace before the list 
    +     *  of documentation blocks for functions
    +     */
         virtual QCString trFunctionDocumentation()
    -      // This is used in the documentation of a file/namespace before the list 
    -      // of documentation blocks for functions
         { return "Function Documentation"; }
    +
    +    /*! This is used in the documentation of a file/namespace before the list 
    +     *  of documentation blocks for variables
    +     */
         virtual QCString trVariableDocumentation()
    -      // This is used in the documentation of a file/namespace before the list 
    -      // of documentation blocks for variables
         { return "Variable Documentation"; }
    +
    +    /*! This is used in the documentation of a file/namespace/group before 
    +     *  the list of links to documented compounds
    +     */
         virtual QCString trCompounds()
    -      // This is used in the documentation of a file/namespace/group before 
    -      // the list of links to documented compounds
         { return "Compounds"; }
    +
    +    /*! This is used in the documentation of a group before the list of 
    +     *  links to documented files
    +     */
         virtual QCString trFiles()
    -      // This is used in the documentation of a group before the list of 
    -      // links to documented files
         { return "Files"; }
     
    +    /*! This is used in the standard footer of each page and indicates when 
    +     *  the page was generated 
    +     */
         virtual QCString trGeneratedAt(const char *date,const char *projName)
         { 
           QCString result=(QCString)"Generated at "+date;
    @@ -344,116 +420,137 @@ class Translator
           result+=(QCString)" by";
           return result;
         }
    +    /*! This is part of the sentence used in the standard footer of each page.
    +     */
         virtual QCString trWrittenBy()
         {
           return "written by";
         }
     
    +    /*! this text is put before a class diagram */
         virtual QCString trClassDiagram(const char *clName)
    -      // this text is put before a class diagram
         {
           return (QCString)"Class diagram for "+clName;
         }
         
    +    /*! this text is generated when the \internal command is used. */
         virtual QCString trForInternalUseOnly()
    -      // this text is generated when the \internal command is used.
         { return "For internal use only."; }
    +
    +    /*! this text is generated when the \reimp command is used. */
         virtual QCString trReimplementedForInternalReasons()
    -      // this text is generated when the \reimp command is used.
         { return "Reimplemented for internal reasons; the API is not affected."; }
    +
    +    /*! this text is generated when the \warning command is used. */
         virtual QCString trWarning()
    -      // this text is generated when the \warning command is used.
         { return "Warning"; }
    +
    +    /*! this text is generated when the \bug command is used. */
         virtual QCString trBugsAndLimitations()
    -      // this text is generated when the \bug command is used.
         { return "Bugs and limitations"; }
    +
    +    /*! this text is generated when the \version command is used. */
         virtual QCString trVersion()
    -      // this text is generated when the \version command is used.
         { return "Version"; }
    +
    +    /*! this text is generated when the \date command is used. */
         virtual QCString trDate()
    -      // this text is generated when the \date command is used.
         { return "Date"; }
    +
    +    /*! this text is generated when the \author command is used. */
         virtual QCString trAuthors()
    -      // this text is generated when the \author command is used.
         { return "Author(s)"; }
    +
    +    /*! this text is generated when the \return command is used. */
         virtual QCString trReturns()
    -      // this text is generated when the \return command is used.
         { return "Returns"; }
    +
    +    /*! this text is generated when the \sa command is used. */
         virtual QCString trSeeAlso()
    -      // this text is generated when the \sa command is used.
         { return "See also"; }
    +
    +    /*! this text is generated when the \param command is used. */
         virtual QCString trParameters()
    -      // this text is generated when the \param command is used.
         { return "Parameters"; }
    +
    +    /*! this text is generated when the \exception command is used. */
         virtual QCString trExceptions()
    -      // this text is generated when the \exception command is used.
         { return "Exceptions"; }
         
    +    /*! this text is used in the title page of a LaTeX document. */
         virtual QCString trGeneratedBy()
    -      // this text is used in the title page of a LaTeX document.
         { return "Generated by"; }
     
         // new since 0.49-990307
         
    +    /*! used as the title of page containing all the index of all namespaces. */
         virtual QCString trNamespaceList()
    -      // used as the title of page containing all the index of all namespaces.
         { return "Namespace List"; }
    +
    +    /*! used as an introduction to the namespace list */
         virtual QCString trNamespaceListDescription(bool extractAll)
    -      // used as an introduction to the namespace list
         {
           QCString result="Here is a list of all ";
           if (!extractAll) result+="documented ";
           result+="namespaces with brief descriptions:";
           return result;
         }
    +
    +    /*! used in the class documentation as a header before the list of all
    +     *  friends of a class
    +     */
         virtual QCString trFriends()
    -      // used in the class documentation as a header before the list of all
    -      // friends of a class
         { return "Friends"; }
         
     //////////////////////////////////////////////////////////////////////////
     // new since 0.49-990405
     //////////////////////////////////////////////////////////////////////////
         
    +    /*! used in the class documentation as a header before the list of all
    +     * related classes 
    +     */
         virtual QCString trRelatedFunctionDocumentation()
    -      // used in the class documentation as a header before the list of all
    -      // related classes
         { return "Friends And Related Function Documentation"; }
         
     //////////////////////////////////////////////////////////////////////////
     // new since 0.49-990425
     //////////////////////////////////////////////////////////////////////////
     
    +    /*! used as the title of the HTML page of a class/struct/union */
         virtual QCString trCompoundReference(const char *clName,
                                         ClassDef::CompoundType compType)
    -      // used as the title of the HTML page of a class/struct/union
         {
           QCString result=(QCString)clName+" ";
           switch(compType)
           {
    -        case ClassDef::Class:  result+=" Class"; break;
    -        case ClassDef::Struct: result+=" Struct"; break;
    -        case ClassDef::Union:  result+=" Union"; break;
    +        case ClassDef::Class:      result+=" Class"; break;
    +        case ClassDef::Struct:     result+=" Struct"; break;
    +        case ClassDef::Union:      result+=" Union"; break;
    +        case ClassDef::Interface:  result+=" Interface"; break;
           }
           result+=" Reference";
           return result;
         }
    +
    +    /*! used as the title of the HTML page of a file */
         virtual QCString trFileReference(const char *fileName)
    -      // used as the title of the HTML page of a file
         {
           QCString result=fileName;
           result+=" File Reference"; 
           return result;
         }
    +
    +    /*! used as the title of the HTML page of a namespace */
         virtual QCString trNamespaceReference(const char *namespaceName)
    -      // used as the title of the HTML page of a namespace
         {
           QCString result=namespaceName;
           result+=" Namespace Reference";
           return result;
         }
         
    -    // these are for the member sections of a class, struct or union 
    +    /*! \mgroup Class sections
    +     *  these are for the member sections of a class, struct or union 
    +     */
         virtual QCString trPublicMembers()
         { return "Public Members"; }
         virtual QCString trPublicSlots()
    @@ -474,12 +571,13 @@ class Translator
         { return "Private Slots"; }
         virtual QCString trStaticPrivateMembers()
         { return "Static Private Members"; }
    -    // end of member sections 
    +    /*! \endmgroup */ 
         
    +    /*! this function is used to produce a comma-separated list of items.
    +     *  use generateMarker(i) to indicate where item i should be put.
    +     */
         virtual QCString trWriteList(int numEntries)
         {
    -      // this function is used to produce a comma-separated list of items.
    -      // use generateMarker(i) to indicate where item i should be put.
           QCString result;
           int i;
           // the inherits list contain `numEntries' classes
    @@ -500,36 +598,44 @@ class Translator
           return result; 
         }
         
    +    /*! used in class documentation to produce a list of base classes,
    +     *  if class diagrams are disabled.
    +     */
         virtual QCString trInheritsList(int numEntries)
    -      // used in class documentation to produce a list of base classes,
    -      // if class diagrams are disabled.
         {
           return "Inherits "+trWriteList(numEntries)+".";
         }
    +
    +    /*! used in class documentation to produce a list of super classes,
    +     *  if class diagrams are disabled.
    +     */
         virtual QCString trInheritedByList(int numEntries)
    -      // used in class documentation to produce a list of super classes,
    -      // if class diagrams are disabled.
         {
           return "Inherited by "+trWriteList(numEntries)+".";
         }
    +
    +    /*! used in member documentation blocks to produce a list of 
    +     *  members that are hidden by this one.
    +     */
         virtual QCString trReimplementedFromList(int numEntries)
    -      // used in member documentation blocks to produce a list of 
    -      // members that are hidden by this one.
         {
           return "Reimplemented from "+trWriteList(numEntries)+".";
         }
    +
    +    /*! used in member documentation blocks to produce a list of
    +     *  all member that overwrite the implementation of this member.
    +     */
         virtual QCString trReimplementedInList(int numEntries)
         {
    -      // used in member documentation blocks to produce a list of
    -      // all member that overwrite the implementation of this member.
           return "Reimplemented in "+trWriteList(numEntries)+".";
         }
     
    +    /*! This is put above each page as a link to all members of namespaces. */
         virtual QCString trNamespaceMembers()
    -      // This is put above each page as a link to all members of namespaces.
         { return "Namespace Members"; }
    +
    +    /*! This is an introduction to the page with all namespace members */
         virtual QCString trNamespaceMemberDescription(bool extractAll)
    -      // This is an introduction to the page with all namespace members
         { 
           QCString result="Here is a list of all ";
           if (!extractAll) result+="documented ";
    @@ -540,23 +646,60 @@ class Translator
             result+="the namespaces they belong to:";
           return result;
         }
    +    /*! This is used in LaTeX as the title of the chapter with the 
    +     *  index of all namespaces.
    +     */
         virtual QCString trNamespaceIndex()
    -      // This is used in LaTeX as the title of the chapter with the 
    -      // index of all namespaces.
         { return "Namespace Index"; }
    +
    +    /*! This is used in LaTeX as the title of the chapter containing
    +     *  the documentation of all namespaces.
    +     */
         virtual QCString trNamespaceDocumentation()
    -      // This is used in LaTeX as the title of the chapter containing
    -      // the documentation of all namespaces.
         { return "Namespace Documentation"; }
     
     //////////////////////////////////////////////////////////////////////////
     // new since 0.49-990522
     //////////////////////////////////////////////////////////////////////////
     
    -      // This is used in the documentation before the list of all
    -      // namespaces in a file.
    +    /*! This is used in the documentation before the list of all
    +     *  namespaces in a file.
    +     */
         virtual QCString trNamespaces()
         { return "Namespaces"; }
    +
    +//////////////////////////////////////////////////////////////////////////
    +// new since 0.49-990728
    +//////////////////////////////////////////////////////////////////////////
    +
    +    /*! This is put at the bottom of a class documentation page and is
    +     *  followed by a list of files that were used to generate the page.
    +     */
    +    virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType,
    +        bool single)
    +    { // here s is one of " Class", " Struct" or " Union"
    +      // single is true implies a single file
    +      QCString result=(QCString)"The documentation for this ";
    +      switch(compType)
    +      {
    +        case ClassDef::Class:      result+="class"; break;
    +        case ClassDef::Struct:     result+="struct"; break;
    +        case ClassDef::Union:      result+="union"; break;
    +        case ClassDef::Interface:  result+="interface"; break;
    +      }
    +      result+="was generated from the following file";
    +      if (single) result+=":"; else result+="s:";
    +      return result;
    +    }
    +
    +    /*! This is in the (quick) index as a link to the alphabetical compound
    +     * list.
    +     */
    +    virtual QCString trAlphabeticalList()
    +    {
    +      return "Alphabetical List";
    +    }
     };
     
    +
     #endif
    diff --git a/src/translator_de.h b/src/translator_de.h
    index 8cf43b6..8f17437 100644
    --- a/src/translator_de.h
    +++ b/src/translator_de.h
    @@ -439,6 +439,7 @@ class TranslatorGerman : public Translator
             case ClassDef::Class:  result+=" Klassen"; break;
             case ClassDef::Struct: result+=" Strukturen"; break;
             case ClassDef::Union:  result+=" Varianten"; break;
    +        case ClassDef::Interface:  result+=" Interface"; break;
           }
           result+="referenz";
           return result;
    diff --git a/src/translator_es.h b/src/translator_es.h
    index 9fcda7b..0aba0a8 100644
    --- a/src/translator_es.h
    +++ b/src/translator_es.h
    @@ -286,6 +286,7 @@ class TranslatorSpanish : public Translator
             case ClassDef::Class:  result+=" Clase"; break;
             case ClassDef::Struct: result+=" Estructura"; break;
             case ClassDef::Union:  result+=" Unión"; break;
    +        case ClassDef::Interface:  result+=" Interface"; break;
           }
           result+=" Referencia";
           return result;
    diff --git a/src/translator_it.h b/src/translator_it.h
    index e2f76dc..34d5660 100644
    --- a/src/translator_it.h
    +++ b/src/translator_it.h
    @@ -299,6 +299,7 @@ class TranslatorItalian : public Translator
             case ClassDef::Class:  result+=" classe"; break;
             case ClassDef::Struct: result+=" struct"; break;
             case ClassDef::Union:  result+=" union"; break;
    +        case ClassDef::Interface:  result+=" interface"; break;
           }
           result+=" "+(QCString)clName;
           return result;
    diff --git a/src/translator_nl.h b/src/translator_nl.h
    index f5ceea9..4c105f1 100644
    --- a/src/translator_nl.h
    +++ b/src/translator_nl.h
    @@ -269,6 +269,7 @@ class TranslatorDutch : public Translator
             case ClassDef::Class:  result+=" Class"; break;
             case ClassDef::Struct: result+=" Struct"; break;
             case ClassDef::Union:  result+=" Union"; break;
    +        case ClassDef::Interface:  result+=" Interface"; break;
           }
           result+=" Referentie";
           return result;
    diff --git a/src/translator_se.h b/src/translator_se.h
    index 761d81d..2a04ff3 100644
    --- a/src/translator_se.h
    +++ b/src/translator_se.h
    @@ -382,6 +382,7 @@ class TranslatorSwedish : public Translator
             case ClassDef::Class:  result+=" Klass"; break;
             case ClassDef::Struct: result+=" Strukt"; break;
             case ClassDef::Union:  result+=" Union"; break;
    +        case ClassDef::Interface:  result+=" Interface"; break;
           }
           result+="referens";
           return result;
    diff --git a/src/util.cpp b/src/util.cpp
    index 49fdee5..d8a4772 100644
    --- a/src/util.cpp
    +++ b/src/util.cpp
    @@ -29,6 +29,7 @@
     #include "defargs.h"
     #include "language.h"
     #include "config.h"
    +#include "htmlhelp.h"
     
     // an inheritance tree of depth of 100000 should be enough for everyone :-)
     const int maxInheritanceDepth = 100000; 
    @@ -58,6 +59,23 @@ QCString generateMarker(int id)
       return result;
     }
     
    +// strip part of the path if it matches
    +// one of the paths in the stripFromPath list
    +QCString stripFromPath(const QCString &path)
    +{
    +  const char *s=Config::stripFromPath.first();
    +  while (s)
    +  {
    +    QCString prefix = s;
    +    if (path.left(prefix.length())==prefix)
    +    {
    +      return path.right(path.length()-prefix.length());
    +    }
    +    s = Config::stripFromPath.next();
    +  }
    +  return path;
    +}
    +
     // 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 :-)
    @@ -74,7 +92,8 @@ int guessSection(const char *name)
           n.right(3)==".hh"  ||
           n.right(4)==".hxx" ||
           n.right(4)==".hpp" ||
    -      n.right(4)==".h++"
    +      n.right(4)==".h++" ||
    +      n.right(4)==".idl"
          ) return Entry::HEADER_SEC;
       return 0;
     }
    @@ -140,64 +159,27 @@ QCString removeRedundantWhiteSpace(const QCString &s)
       return result;
     }  
     
    -void writeTemplatePrefix(OutputList &ol,ArgumentList *al)
    +
    +
    +bool rightScopeMatch(const QCString &scope, const QCString &name)
     {
    -  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);
    +  return (name==scope || // equal 
    +           (scope.right(name.length())==name && // substring 
    +           scope.at(scope.length()-name.length()-1)==':' // scope
    +           ) 
    +     );
     }
     
    -QCString addTemplateNames(const QCString &s,const QCString &n,const QCString &t)
    +bool leftScopeMatch(const QCString &scope, const QCString &name)
     {
    -  //printf("addTemplateNames(%s)\n",s.data());
    -  QCString result;
    -  QCString 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;
    +  return (name==scope || // equal 
    +           (scope.left(name.length())==name && // substring 
    +           scope.at(name.length())==':' // scope
    +           ) 
    +     );
     }
     
    -static void linkifyText(OutputList &ol,const char *scName,const char *name,const char *text)
    +void linkifyText(OutputList &ol,const char *scName,const char *name,const char *text)
     {
       //printf("scope=`%s' name=`%s' Text: `%s'\n",scName,name,text);
       QRegExp regExp("[a-z_A-Z0-9:<>]+");
    @@ -214,19 +196,20 @@ static void linkifyText(OutputList &ol,const char *scName,const char *name,const
         result.docify(txtStr.mid(skipIndex,newIndex-skipIndex)); 
         // get word from string
         QCString word=txtStr.mid(newIndex,matchLen);
    -    ClassDef *cd=0;
    -    FileDef *fd=0;
    -    MemberDef *md=0;
    +    ClassDef     *cd=0;
    +    FileDef      *fd=0;
    +    MemberDef    *md=0;
         NamespaceDef *nd=0;
     
         QCString scopeName=scName;
         QCString searchName=name;
         //printf("word=`%s' scopeName=`%s' searchName=`%s'\n",
    -    //        word.data(),scopeName.data(),searchName.data());
    +    //        word.data(),scopeName.data(),searchName.data()
    +    //      );
         // check if `word' is a documented class name
         if (word.length()>0 && 
    -        word.right(searchName.length())!=searchName && 
    -        word!=scopeName.right(word.length())
    +        !rightScopeMatch(word,searchName) && 
    +        !rightScopeMatch(scopeName,word)
            )
         {
           //printf("Searching...\n");
    @@ -244,7 +227,7 @@ static void linkifyText(OutputList &ol,const char *scName,const char *name,const
             if ((cd=getClass(fullName)))
             {
               // add link to the result
    -          if (cd->isVisible())
    +          if (cd->isLinkable())
               {
                 result.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,word);
                 found=TRUE;
    @@ -264,25 +247,15 @@ static void linkifyText(OutputList &ol,const char *scName,const char *name,const
           if (!found && 
               getDefs(scName,word,0,md,cd,fd,nd) && 
               (md->isTypedef() || md->isEnumerate()) &&
    -          md->hasDocumentation() 
    +          md->isLinkable() 
              )
           {
    -        if (cd && cd->isVisible()) // fullName is a member of cd
    -        {
    -          result.writeObjectLink(cd->getReference(),
    -              cd->getOutputFileBase(),md->anchor(),word);
    -          found=TRUE;
    -        }
    -        else if (nd && nd->hasDocumentation())
    +        Definition *d=0;
    +        if (cd) d=cd; else if (nd) d=nd; else d=fd;
    +        if (d && d->isLinkable())
             {
    -          result.writeObjectLink(nd->getReference(),
    -              nd->getOutputFileBase(),md->anchor(),word);
    -          found=TRUE;
    -        }
    -        else if (fd && fd->hasDocumentation()) // fullName is a global in file fd
    -        {
    -          result.writeObjectLink(fd->getReference(),
    -              fd->getOutputFileBase(),md->anchor(),word);
    +          result.writeObjectLink(d->getReference(),d->getOutputFileBase(),
    +                                 md->anchor(),word);
               found=TRUE;
             }
           }
    @@ -305,70 +278,6 @@ static void linkifyText(OutputList &ol,const char *scName,const char *name,const
       ol+=result; 
     }
     
    -static void writeDefArgumentList(OutputList &ol,ClassDef *cd,
    -                                 const QCString &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();
    -  QCString 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
    -    {
    -      QCString 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
    -    {
    -      QCString 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
    -    {
    -      QCString 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");
    -  }
    -}
     
     void writeExample(OutputList &ol,ExampleList *el)
     {
    @@ -409,37 +318,53 @@ QCString argListToString(ArgumentList *al)
       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(nd->getReference(),nd->getOutputFileBase(),
    -                       md->anchor(),name);
    -  else if (fd) 
    -    ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),
    -                       md->anchor(),name);
    -  else    
    -    ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),
    -                       md->anchor(),name);
    -}
     
    -static void warnForUndocumentedMember(MemberDef *md)
    +//QCString tempArgListToString(ArgumentList *al)
    +//{
    +//  QCString result;
    +//  if (al==0) return result;
    +//  Argument *a=al->first();
    +//  result+="<";
    +//  while (a)
    +//  {
    +//    int ni=a->type.findRev(' ');
    +//    if (ni!=-1) 
    +//      result+=a->type.right(a->type.length()-ni-1);
    +//    else
    +//      result+=a->type;
    +//    a = al->next();
    +//    if (a) result+=",";
    +//  }
    +//  result+=">";
    +//  return result;
    +//}
    +
    +QCString tempArgListToString(ArgumentList *al)
     {
    -  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)
    +  QCString result;
    +  if (!al || al->count()==0) return result;
    +  result="<";
    +  Argument *a=al->first();
    +  while (a)
       {
    -    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());
    +    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=al->next();
    +    if (a) result+=", ";
       }
    +  result+=">";
    +  return result;
     }
     
     static bool manIsEnabled;
    @@ -489,6 +414,13 @@ void writeQuickLinks(OutputList &ol,bool compact,bool ext)
       } 
       if (annotatedClasses>0)
       {
    +    if (Config::alphaIndexFlag)
    +    {
    +      if (!compact) ol.writeListItem();
    +      ol.startQuickIndexItem(extLink,absPath+"classes.html");
    +      parseText(ol,theTranslator->trAlphabeticalList());
    +      ol.endQuickIndexItem();
    +    }
         if (!compact) ol.writeListItem();
         ol.startQuickIndexItem(extLink,absPath+"annotated.html");
         parseText(ol,theTranslator->trCompoundList());
    @@ -501,7 +433,7 @@ void writeQuickLinks(OutputList &ol,bool compact,bool ext)
         parseText(ol,theTranslator->trFileList());
         ol.endQuickIndexItem();
       } 
    -  if (includeFiles.count()>0 && Config::verbatimHeaderFlag)
    +  if (documentedIncludeFiles>0 && Config::verbatimHeaderFlag)
       {
         if (!compact) ol.writeListItem();
         ol.startQuickIndexItem(extLink,absPath+"headers.html");
    @@ -594,427 +526,6 @@ void endFile(OutputList &ol,bool external)
       ol.endFile();
     }
     
    -
    -static void writeMemberDef(OutputList &ol, ClassDef *cd, NamespaceDef *nd,
    -                           FileDef *fd, MemberDef *md)
    -{
    -  int i,l;
    -  bool hasDocs=md->hasDocumentation();
    -  if ((!hasDocs && Config::hideMemberFlag) || 
    -      (Config::hideMemberFlag && 
    -       md->documentation().isEmpty() && 
    -       !Config::briefMemDescFlag && 
    -       !Config::repeatBriefFlag
    -      ) 
    -     ) return;
    -  QCString 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 (Config::genTagFile.length()>0)
    -    {
    -      tagFile << md->name() << " " << md->anchor() << " \""
    -              << md->argsString() << "\"\n";
    -    }
    -      
    -    QCString cname;
    -    if (cd)      cname=cd->name(); 
    -    else if (nd) cname=nd->name();
    -    else if (fd) cname=fd->name();
    -
    -    ol.startMemberItem();
    -    // If there is no detailed description we need to write the anchor here.
    -    bool detailsVisible = md->detailsAreVisible();
    -    if (!detailsVisible && !Config::extractAllFlag)
    -    {
    -      QCString doxyName=md->name().copy();
    -      if (!cname.isEmpty()) doxyName.prepend(cname+"::");
    -      ol.writeDoxyAnchor(cname,md->anchor(),doxyName);
    -      ol.addToIndex(md->name(),cname);
    -      ol.addToIndex(cname,md->name());
    -      ol.docify("\n");
    -    }
    -    else if (!detailsVisible) // when extractAll it true we have to write
    -                              // a index reference and label in LaTeX because
    -                              // detailed section not shown in LaTeX
    -    {
    -      ol.addToIndex(md->name(),cname);
    -      ol.addToIndex(cname,md->name());
    -      ol.writeLatexLabel(cname,md->anchor());
    -    }
    -
    -    // write type
    -    if (i!=-1)
    -    {
    -      QCString newType = type.left(i) + " { ... } " +
    -        type.right(type.length()-i-l);
    -      type = newType;
    -      //ol.docify(type);
    -      linkifyText(ol,cname,md->name(),type); 
    -    }
    -    else
    -    {
    -      //ol.docify(type);
    -      linkifyText(ol,cname,md->name(),type); 
    -    }
    -    QCString name=md->name().copy();
    -    bool htmlOn = ol.isEnabled(OutputGenerator::Html);
    -    if (htmlOn && Config::htmlAlignMemberFlag && type.length()>0)
    -    {
    -      ol.disable(OutputGenerator::Html);
    -    }
    -    if (!type.isEmpty()) ol.docify(" ");
    -    if (htmlOn) 
    -    {
    -      ol.enable(OutputGenerator::Html);
    -    }
    -
    -    ol.insertMemberAlign();
    -    
    -    // write name
    -    if (md->hasDocumentation())
    -    {
    -      //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());
    -      linkifyText(ol,cname,md->name(),md->argsString()); 
    -    }
    -    
    -    if (md->excpString())
    -    {
    -      ol.writeString(" ");
    -      ol.docify(md->excpString());
    -    }
    -
    -    ol.endMemberItem();
    -
    -    // write brief description
    -    if (!md->briefDescription().isEmpty() && Config::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());
    -      //  parseText(ol,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();
    -    parseText(ol,title);
    -    ol.endMemberHeader();
    -  }
    -  if (subtitle) 
    -  {
    -    ol.startMemberSubtitle();
    -    parseText(ol,subtitle);
    -    ol.endMemberSubtitle();
    -  }
    -
    -  if (!fd && !nd) ol.startMemberList();
    -  MemberDef *md;
    -
    -  if (fd && ml->defineCount()>0)
    -  {
    -    ol.startMemberHeader();
    -    parseText(ol,theTranslator->trDefines());
    -    ol.endMemberHeader();
    -    ol.startMemberList();
    -    MemberListIterator mli(*ml);
    -    for ( ; (md=mli.current()); ++mli )
    -    {
    -      if (md->isDefine() && 
    -          (md->argsString() || md->hasDocumentation() || Config::extractAllFlag)
    -         ) 
    -        writeMemberDef(ol,cd,nd,fd,md);
    -    }
    -    ol.endMemberList();
    -  }
    -  
    -  if ((fd || nd) && ml->protoCount()>0)
    -  {
    -    ol.startMemberHeader();
    -    parseText(ol,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();
    -      parseText(ol,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();
    -      parseText(ol,theTranslator->trEnumerations());
    -      ol.endMemberHeader();
    -      ol.startMemberList();
    -    }
    -    MemberListIterator mli(*ml);
    -    for ( ; (md=mli.current()) ; ++mli )
    -    {
    -      /*bool hasDocs=md->hasDocumentation();*/
    -      QCString type=md->typeString();
    -      type=type.stripWhiteSpace();
    -      if (md->isEnumerate() /*&& (hasDocs || !Config::hideMemberFlag)*/) 
    -      {
    -        if (!Config::hideMemberFlag ||                // do not hide undocumented members or
    -            !md->documentation().isEmpty() || // member has detailed descr. or
    -            md->hasDocumentedEnumValues() ||  // member has documented enum vales.
    -            Config::briefMemDescFlag ||               // brief descr. is shown or
    -            Config::repeatBriefFlag                   // brief descr. is repeated.
    -           )
    -        {
    -          OutputList typeDecl(&ol);
    -          QCString 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 (Config::extractAllFlag ||
    -            //    (md->briefDescription().isEmpty() || !Config::briefMemDescFlag) &&
    -            //    (!md->documentation().isEmpty() || md->hasDocumentedEnumValues() ||
    -            //     (!md->briefDescription().isEmpty() && 
    -            //      !Config::briefMemDescFlag &&
    -            //      Config::repeatBriefFlag
    -            //     )
    -            //    )
    -            //   )
    -            if (md->hasDocumentation() || md->hasDocumentedEnumValues())
    -            {
    -              if (Config::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("{ ");
    -          QList *fmdl=md->enumFieldList();
    -          if (fmdl)
    -          {
    -            MemberDef *fmd=fmdl->first();
    -            while (fmd)
    -            {
    -              if (fmd->hasDocumentation())
    -              {
    -                if (Config::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)
    -            {
    -              QCString vtype=vmd->typeString();
    -              if ((vtype.find(name))!=-1) enumVars++;
    -            }
    -          }
    -          if (enumVars==0) // no variable of this enum type
    -          {
    -            ol.startMemberItem();
    -            ol.writeString("enum ");
    -            ol.insertMemberAlign();
    -            ol+=typeDecl;
    -            ol.endMemberItem();
    -            //QCString brief=md->briefDescription();
    -            //brief=brief.stripWhiteSpace();
    -            if (!md->briefDescription().isEmpty() && Config::briefMemDescFlag)
    -            {
    -              ol.startMemberDescription();
    -              parseDoc(ol,cd?cd->name().data():0,
    -                  md->name().data(),md->briefDescription());
    -              //if (!md->documentation().isEmpty() || md->hasDocumentedEnumValues())
    -              //{
    -              //  ol.disableAllBut(OutputGenerator::Html);
    -              //  ol.endEmphasis();
    -              //  ol.docify(" ");
    -              //  ol.startTextLink(0,md->anchor());
    -              //  //ol.writeObjectLink(0,0,md->anchor()," More...");
    -              //  parseText(ol,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();
    -      parseText(ol,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()) 
    -      {
    -        QCString 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.insertMemberAlign();
    -            ol.writeObjectLink(0,0,md->anchor(),md->name());
    -            ol.endMemberItem();
    -          }
    -          else if (cd && cd->isVisibleExt()) // class is documented
    -          {
    -            ol.startMemberItem();
    -            ol.docify("class ");
    -            ol.insertMemberAlign();
    -            ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->name());
    -            ol.endMemberItem();
    -          }
    -          else if (!Config::hideMemberFlag) // no documentation
    -          {
    -            ol.startMemberItem();
    -            ol.docify("class ");
    -            ol.insertMemberAlign();
    -            ol.writeBoldString(md->name());
    -            ol.endMemberItem();
    -          }
    -        }
    -      }
    -    }
    -  }
    -
    -  // write variables
    -  if (ml->varCount()>0)
    -  {
    -    if (fd || nd) 
    -    {
    -      ol.startMemberHeader();
    -      parseText(ol,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)
     {
    @@ -1030,397 +541,6 @@ void setAnchors(char id,MemberList *ml)
       }
     }
     
    -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
    -    //      !Config::briefMemDescFlag &&                      // brief description not shown earlier and
    -    //      Config::repeatBriefFlag                           // brief description should be repeated.
    -    //     );
    -    if (md->memberType()==m &&                      // filter member type
    -        (Config::extractAllFlag || hasDocs) 
    -       )
    -    {
    -      if (Config::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 Config::extractAllFlag is enabled
    -      }
    -      QCString 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
    -      QCString doxyName=md->name().copy();
    -      // prepend scope if there is any 
    -      if (scopeName) doxyName.prepend((QCString)scopeName+"::");
    -      
    -      QCString 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=md->scopeTemplateArguments()) || (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 && md->scopeTemplateArguments())
    -        {
    -          def=addTemplateNames(def,cd->name(),md->getScopeTemplateNameString());
    -        }
    -        else 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() && 
    -          (Config::repeatBriefFlag || 
    -             (!Config::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->bodyCode().isEmpty())
    -      {
    -        ol.startCodeFragment();
    -        parseCode(ol,scopeName,md->bodyCode(),FALSE,0);
    -        ol.endCodeFragment();
    -      }
    -      
    -      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();
    -                parseText(ol,theTranslator->trEnumerationValues());
    -                //ol.writeBoldString("Enumeration values:");
    -                ol.docify(":");
    -                ol.endBold();
    -                ol.startItemList();
    -              }
    -              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.endItemList(); ol.writeChar('\n'); }
    -      }
    -      
    -      MemberDef *bmd=md->reimplements();
    -      ClassDef  *bcd=0; 
    -      if (bmd && (bcd=bmd->memberClass()))
    -      {
    -        if (virt!=Normal) // search for virtual member of the deepest base class
    -        {
    -          MemberDef *lastBmd=bmd;
    -          while (lastBmd) 
    -          {
    -            ClassDef *lastBcd = lastBmd->memberClass();
    -            if (lastBmd->virtualness()!=Normal && 
    -                lastBmd->hasDocumentation() &&
    -                (lastBmd->protection()!=Private || Config::extractPrivateFlag) &&
    -                lastBcd->hasDocumentation() &&
    -                (lastBcd->protection()!=Private || Config::extractPrivateFlag)
    -               ) { bmd=lastBmd; bcd=lastBcd; }
    -            lastBmd=lastBmd->reimplements();
    -          }
    -        }
    -        // write class that contains a member that is reimplemented by this one
    -        if (bcd->hasDocumentation() || bcd->isReference())
    -        {
    -          ol.newParagraph();
    -
    -          QCString reimplFromLine = theTranslator->trReimplementedFromList(1);
    -          int markerPos = reimplFromLine.find("@0");
    -          if (markerPos!=-1) // should always pass this.
    -          {
    -            parseText(ol,reimplFromLine.left(markerPos)); //text left from marker
    -            if (bmd->hasDocumentation() && 
    -                (bmd->protection()!=Private || Config::extractPrivateFlag)
    -               ) // replace marker with link
    -            {
    -              ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
    -                  bmd->anchor(),bcd->name());
    -              if (
    -                  !bcd->isReference() &&
    -                  //(bcd->hasDocumentation() || !Config::hideClassFlag) &&
    -                  //(bcd->protection()!=Private || Config::extractPrivateFlag)
    -                  bcd->isVisible() 
    -                  /*&& bmd->detailsAreVisible()*/
    -                 ) ol.writePageRef(bcd->name(),bmd->anchor());
    -            }
    -            else
    -            {
    -              ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
    -                  0,bcd->name());
    -              if (
    -                  !bcd->isReference() &&
    -                  //(bcd->hasDocumentation() || !Config::hideClassFlag) &&
    -                  //(bcd->protection()!=Private || Config::extractPrivateFlag)
    -                  bcd->isVisible()
    -                 ) ol.writePageRef(bcd->name(),0);
    -            }
    -            parseText(ol,reimplFromLine.right(
    -                  reimplFromLine.length()-markerPos-2)); // text right from marker
    -
    -          }
    -          else
    -          {
    -            err("Error: translation error: no marker in trReimplementsFromList()\n");
    -          }
    -        }
    -        
    -        //ol.writeString(".");
    -      }
    -      MemberList *bml=md->reimplementedBy();
    -      if (bml)
    -      {
    -        MemberListIterator mli(*bml);
    -        MemberDef *bmd=0;
    -        uint count=0;
    -        ClassDef *bcd=0;
    -        for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->memberClass());++mli)
    -        {
    -          // count the members that directly inherit from md and for
    -          // which the member and class are visible in the docs.
    -          if (bmd->hasDocumentation() && 
    -              (bmd->protection()!=Private || Config::extractPrivateFlag) &&
    -              bcd->hasDocumentation() &&
    -              (bcd->protection()!=Private || Config::extractPrivateFlag)
    -             ) count++;
    -        }
    -        if (count>0)
    -        {
    -          mli.toFirst();
    -          // write the list of classes that overwrite this member
    -          ol.newParagraph();
    -          //parseText(ol,theTranslator->trReimplementedIn());
    -          //ol.writeString("Reimplemented in ");
    -          //ol.docify(" ");
    -
    -          QCString reimplInLine = 
    -            theTranslator->trReimplementedInList(count);
    -          QRegExp marker("@[0-9]+");
    -          int index=0,newIndex,matchLen;
    -          // now replace all markers in reimplInLine with links to the classes
    -          while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
    -          {
    -            parseText(ol,reimplInLine.mid(index,newIndex-index));
    -            bool ok;
    -            uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
    -            //bmd=bml->at(entryIndex);
    -            
    -            count=0;
    -            // find the entryIndex-th documented entry in the inheritance list.
    -            for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->memberClass());++mli)
    -            {
    -              if (bmd->hasDocumentation() && 
    -                  (bmd->protection()!=Private || Config::extractPrivateFlag) &&
    -                  bcd->hasDocumentation() &&
    -                  (bcd->protection()!=Private || Config::extractPrivateFlag)
    -                 ) 
    -              {
    -                if (count==entryIndex) break;
    -                count++;
    -              }
    -            }
    -            
    -            if (ok && bcd && bmd) // write link for marker
    -            {
    -              //if (bmd->hasDocumentation() &&
    -              //    (bmd->protection()!=Private || Config::extractPrivateFlag)
    -              //   )
    -              //{
    -              ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
    -                  bmd->anchor(),bcd->name());
    -              if (!bcd->isReference() && bcd->isVisible()) 
    -                ol.writePageRef(bcd->name(),bmd->anchor());
    -              //}
    -              //else
    -              //{
    -              //  ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
    -              //      0,bcd->name());
    -              //  if (!bcd->isReference() && bcd->isVisible()) 
    -              //    ol.writePageRef(bcd->name(),0);
    -              //}
    -            }
    -            ++mli;
    -            index=newIndex+matchLen;
    -          } 
    -          parseText(ol,reimplInLine.right(reimplInLine.length()-index));
    -
    -        }
    -      }
    -      // write the list of examples that use this member
    -      if (md->hasExamples())
    -      {
    -        ol.startDescList();
    -        ol.startBold();
    -        parseText(ol,theTranslator->trExamples()+": ");
    -        //ol.writeBoldString("Examples: ");
    -        ol.endBold();
    -        ol.endDescTitle();
    -        ol.writeDescItem();
    -        writeExample(ol,md->getExampleList());
    -        //ol.endDescItem();
    -        ol.endDescList();
    -      }
    -      ol.endIndent();
    -      // enable LaTeX again
    -      if (Config::extractAllFlag && !hasDocs) ol.enable(OutputGenerator::Latex); 
    -                                          
    -    }
    -  }
    -}
    -
     //----------------------------------------------------------------------------
     // read a file with `name' to a string.
     
    @@ -1607,6 +727,13 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
       QCString className=cl;
       QCString namespaceName=ns;
     
    +  // strip template specialization from class name if present
    +  int til=className.find('<'),tir=className.find('>');
    +  if (til!=-1 && tir!=-1 && tir>til) 
    +  {
    +    className=className.left(til)+className.right(className.length()-tir-1);
    +  }
    +
       //printf("matchArguments(%s,%s) className=%s namespaceName=%s\n",
       //    srcAl ? argListToString(srcAl).data() : "",
       //    dstAl ? argListToString(dstAl).data() : "",
    @@ -1616,6 +743,8 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
       {
         return srcAl==dstAl; // at least one of the members is not a function
       }
    +  
    +  // handle special case with void argument
       if ( srcAl->count()==0 && dstAl->count()==1 && 
            dstAl->getFirst()->type=="void" )
       { // special case for finding match between func() and func(void)
    @@ -1632,9 +761,9 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
         dstAl->append(a);
         return TRUE;
       }
    +  
       if (srcAl->count() != dstAl->count())
       {
    -    //printf("Different number of arguments!\n");
         return FALSE; // different number of arguments -> no match
       }
       if (srcAl->constSpecifier != dstAl->constSpecifier) 
    @@ -1683,6 +812,7 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
             srcAType=trimScope(namespaceName,srcAType);
             dstAType=trimScope(namespaceName,dstAType);
           }
    +      //printf("srcAType=%s dstAType=%s\n",srcAType.data(),dstAType.data());
           
           //printf("`%s' <=> `%s'\n",srcAType.data(),dstAType.data());
           uint srcPos=0,dstPos=0; 
    @@ -1796,8 +926,10 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
           else // without scopes the names match exactly
           {
           }
    +      return TRUE;
         }
    -    else if (srcA->name.length()==0 && dstA->name.length()==0) 
    +    //printf("match exactly\n");
    +    if (srcA->name.isEmpty() && dstA->name.isEmpty()) 
                               // arguments match exactly but no name ->
                               // see if we can find the name
         {
    @@ -1812,6 +944,14 @@ bool matchArguments(ArgumentList *srcAl,ArgumentList *dstAl,
             dstA->type=dstAType.left(i+1).stripWhiteSpace();
           } 
         }
    +    else if (!dstA->name.isEmpty())
    +    {
    +      srcA->name=dstA->name.copy();
    +    }
    +    else if (!srcA->name.isEmpty())
    +    {
    +      dstA->name=srcA->name.copy(); 
    +    }
       }
       //printf("Match found!\n");
       return TRUE; // all arguments match 
    @@ -1964,7 +1104,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
     
           ClassDef *fcd=0;
           if ((fcd=getClass(className)) &&  // is it a documented class
    -            fcd->isVisibleExt() 
    +           fcd->isLinkable() 
              )
           {
             //printf("  Found fcd=%p\n",fcd);
    @@ -1972,8 +1112,9 @@ bool getDefs(const QCString &scName,const QCString &memberName,
             int mdist=maxInheritanceDepth; 
             while (mmd)
             {
    -          if ((mmd->protection()!=Private || Config::extractPrivateFlag) &&
    -              mmd->hasDocumentation() 
    +          if (//(mmd->protection()!=Private || Config::extractPrivateFlag) &&
    +              //mmd->hasDocumentation() 
    +              mmd->isLinkable()
                   /*mmd->detailsAreVisible()*/
                   /* && (args==0 || matchArgumentsOld(mmd->argsString(),args)) */
                  )
    @@ -1990,7 +1131,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
                 {
                   ClassDef *mcd=mmd->memberClass();
                   int m=minClassDistance(fcd,mcd);
    -              if (misVisible())
    +              if (misLinkable())
                   {
                     mdist=m;
                     cd=mcd;
    @@ -2011,18 +1152,19 @@ bool getDefs(const QCString &scName,const QCString &memberName,
               mmd=mn->last();
               while (mmd)
               {
    -            if ((mmd->protection()!=Private || Config::extractPrivateFlag) &&
    -                (
    -                 mmd->hasDocumentation() 
    -                 /*mmd->detailsAreVisible()*/
    -                 || mmd->isReference()
    -                )
    +            if (//(mmd->protection()!=Private || Config::extractPrivateFlag) &&
    +                //(
    +                //mmd->hasDocumentation() 
    +                /*mmd->detailsAreVisible()*/
    +                //|| mmd->isReference()
    +                //)
    +                mmd->isLinkable()
                    )
                 {
                   ClassDef *mcd=mmd->memberClass();
                   //printf("  >Class %s found\n",mcd->name().data());
                   int m=minClassDistance(fcd,mcd);
    -              if (misVisible())
    +              if (misLinkable())
                   {
                     //printf("Class distance %d\n",m);
                     mdist=m;
    @@ -2072,7 +1214,7 @@ bool getDefs(const QCString &scName,const QCString &memberName,
             }
             if (namespaceName.length()>0 && 
                 (fnd=namespaceDict[namespaceName]) &&
    -            fnd->isVisibleExt()
    +            fnd->isLinkable()
                )
             {
               //printf("Function inside existing namespace `%s'\n",namespaceName.data());
    @@ -2083,7 +1225,8 @@ bool getDefs(const QCString &scName,const QCString &memberName,
                 //printf("mmd->getNamespace()=%p fnd=%p\n",
                 //    mmd->getNamespace(),fnd);
                 if (mmd->getNamespace()==fnd && 
    -                (mmd->isReference() || mmd->hasDocumentation())
    +                //(mmd->isReference() || mmd->hasDocumentation())
    +                mmd->isLinkable()
                    )
                 { // namespace is found
                   bool match=TRUE;
    @@ -2116,7 +1259,8 @@ bool getDefs(const QCString &scName,const QCString &memberName,
                 while (mmd && !found)
                 {
                   if (mmd->getNamespace()==fnd && 
    -                  (mmd->isReference() || mmd->hasDocumentation())
    +                  //(mmd->isReference() || mmd->hasDocumentation())
    +                  mmd->isLinkable()
                      )
                   {
                     nd=fnd;
    @@ -2134,11 +1278,11 @@ bool getDefs(const QCString &scName,const QCString &memberName,
               md=mn->first();
               while (md)
               {
    -            if (md->isReference() || md->hasDocumentation())
    +            if (md->isLinkable())
                 {
                   //printf("md->name()=`%s'\n",md->name().data());
                   fd=md->getFileDef();
    -              if (fd && (fd->isReference() || fd->hasDocumentation()))
    +              if (fd && fd->isLinkable())
                   {
                     //printf("fd->name()=`%s'\n",fd->name().data());
                     bool match=TRUE;
    @@ -2162,11 +1306,11 @@ bool getDefs(const QCString &scName,const QCString &memberName,
                 md=mn->last();
                 while (md)
                 {
    -              if (md->isReference() || md->hasDocumentation())
    +              if (md->isLinkable())
                   {
                     //printf("md->name()=`%s'\n",md->name().data());
                     fd=md->getFileDef();
    -                if (fd && (fd->isReference() || fd->hasDocumentation()))
    +                if (fd && fd->isLinkable())
                     {
                       return TRUE;
                     }
    @@ -2224,11 +1368,11 @@ bool getScopeDefs(const char *docScope,const char *scope,
         QCString fullName=scopeName.copy();
         if (scopeOffset>0) fullName.prepend(docScopeName.left(scopeOffset)+"::");
         
    -    if ((cd=getClass(fullName)) && cd->isVisibleExt())
    +    if ((cd=getClass(fullName)) && cd->isLinkable())
         {
           return TRUE; // class link written => quit 
         }
    -    else if ((nd=namespaceDict[fullName]) && nd->isVisibleExt())
    +    else if ((nd=namespaceDict[fullName]) && nd->isLinkable())
         {
           return TRUE; // namespace link written => quit 
         }
    @@ -2344,7 +1488,7 @@ void generateRef(OutputList &ol,const char *scName,
       if (getDefs(scopeStr,nameStr,argsStr,md,cd,fd,nd))
       {
         //printf("after getDefs nd=%p\n",nd);
    -    QCString anchor = (md->isReference() || md->hasDocumentation()) ? md->anchor() : 0;
    +    QCString anchor = md->isLinkable() ? md->anchor() : 0;
         QCString cName,aName;
         if (cd) // nameStr is a member of cd
         {
    @@ -2391,7 +1535,7 @@ void generateRef(OutputList &ol,const char *scName,
         if (cName.length()>0 || aName.length()>0)
         {
           if (
    -          (cd && !cd->isReference() && cd->isVisible()) || 
    +          (cd && cd->isLinkableInProject()) || 
               (fd && !fd->isReference()) ||
               (nd /* TODO: && !nd->isReference() */)
              ) 
    @@ -2435,7 +1579,7 @@ void generateLink(OutputList &ol,const char *clName,
       else if ((exampleDict[linkRef])) // link to an example
         ol.writeObjectLink(0,linkRef+"-example",0,lt);
       else if ((fd=findFileDef(&inputNameDict,linkRef,ambig))
    -       && fd->hasDocumentation())
    +       && fd->isLinkable())
             // link to documented input file
         ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,lt);
       else // probably a class or member reference
    @@ -2449,7 +1593,7 @@ void generateFileRef(OutputList &ol,const char *name,const char *text)
       FileDef *fd;
       bool ambig;
       if ((fd=findFileDef(&inputNameDict,name,ambig)) && 
    -      fd->hasDocumentation()) 
    +      fd->isLinkable()) 
         // link to documented input file
         ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,linkText);
       else
    diff --git a/src/util.h b/src/util.h
    index 515a816..f17f5e2 100644
    --- a/src/util.h
    +++ b/src/util.h
    @@ -34,17 +34,17 @@ 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 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 QCString fileToString(const char *name);
     extern QCString dateToString(bool);
    -//extern OutputList linkifyText(const char *clName,const char *name,
    -//                        const char *text);
    +extern void linkifyText(OutputList &ol,const char *clName,const char *name,
    +                        const char *text);
     extern bool getDefs(const QCString &scopeName,const QCString &memberName, 
                         const char *, MemberDef *&md, ClassDef *&cd,FileDef *&fd,
                         NamespaceDef *&nd);
    @@ -79,9 +79,18 @@ void startFile(OutputList &ol,const char *name,
     void endFile(OutputList &ol,bool external=FALSE);
     void writeQuickLinks(OutputList &ol,bool compact,bool external=FALSE);
     QCString argListToString(ArgumentList *al);
    +QCString tempArgListToString(ArgumentList *al);
     QCString generateMarker(int id);
     void writeExample(OutputList &ol,ExampleList *el);
     void setFileNameForSections(QList *anchorList,const char *fileName);
     QCString stripAnnonymousScope(const QCString &s);
     
    +
    +//void writeLink(OutputList &ol,ClassDef *cd,NamespaceDef *nd,
    +//                      FileDef *fd,MemberDef *md,const char *name);
    +//void warnForUndocumentedMember(MemberDef *md);
    +QCString stripFromPath(const QCString &path);
    +bool rightScopeMatch(const QCString &scope, const QCString &name);
    +bool leftScopeMatch(const QCString &scope, const QCString &name);
    +
     #endif
    diff --git a/tmake/CHANGES b/tmake/CHANGES
    index 000ac7d..ce686e9 100644
    --- a/tmake/CHANGES
    +++ b/tmake/CHANGES
    @@ -1,3 +1,13 @@
    +		     Changes from version 1.2 to 1.3
    +
    +* Improved Qt 2.0 support.
    +
    +* INCLUDEPATH can have directories containing whitespace (use semicolon)
    +  as separator.
    +
    +* Many, many code fixes and doc improvements.
    +
    +
     		     Changes from version 1.1 to 1.2
     
     * tmake is no longer restricted to C++ only.  You can now use both C++
    diff --git a/tmake/LICENSE b/tmake/LICENSE
    index 2836b6a..7262d5a 100644
    --- a/tmake/LICENSE
    +++ b/tmake/LICENSE
    @@ -1,6 +1,6 @@
     		       License Statement for tmake
     
    -Copyright (C) 1996-1998 by Troll Tech AS.  All rights reserved.
    +Copyright (C) 1996-1999 by Troll Tech AS.  All rights reserved.
     
     Permission to use, copy, modify, and distribute this software and its
     documentation for any purpose and without fee is hereby granted, provided
    diff --git a/tmake/README b/tmake/README
    index defb697..b049d32 100644
    --- a/tmake/README
    +++ b/tmake/README
    @@ -1,7 +1,10 @@
    -			    tmake version 1.2
    +			    tmake version 1.3
     
     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.
    +many platforms and compilers. For information about installing and using
    +tmake, see:
    +
    +  doc/tmake.html      -- User's Guide
    +  doc/tmake_ref.html  -- Reference Manual
     
     Download the latest version from: 
    diff --git a/tmake/bin/progen.bat b/tmake/bin/progen.bat
    deleted file mode 100644
    index 54475ee..0000000
    --- a/tmake/bin/progen.bat
    +++ /dev/null
    @@ -1,266 +0,0 @@
    -@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 (  ) {
    -	    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
    index 2d7e6a7..457467a 100755
    --- a/tmake/bin/tmake
    +++ b/tmake/bin/tmake
    @@ -29,51 +29,89 @@
     #
     ############################################################################
     
    +$TMAKE_VERSION = "1.3";
    +
     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;
    +$cpp_ext	= "cpp";
    +$moc_aware	= 0;
    +$moc_pre	= "moc_";
    +$moc_ext	= "moc";
    +$moc_cmd	= '$(MOC)';
    +$linebreak	= "\\";
    +$really_unix	= &check_unix();
    +$is_unix	= $really_unix;
    +$dir_sep	= $is_unix ? "/" : "\\";
    +$obj_ext	= $is_unix ? "o" : "obj";
    +$depend_path	= "";
    +$nodepend	= 0;
    +$output_count	= 0;
    +$notrim_whitespace = 0;
    +$read_tmakeconf	= 0;
    +		
    +$template_name	= "";
    +$project_name	= "";
    +$outfile	= "";
    +%project	= ();
    +$eval_quit	= 0;
    +
    +$project{"TMAKEPATH"} = $ENV{"TMAKEPATH"} . ";" . $ENV{"HOME"} . "/.tmake/";
     
     while ( @ARGV ) {				# parse command line args
         $_ = shift @ARGV;
         if ( s/^-// ) {
     	if ( /^e(.*)/ ) {
    -	    push( @eval_expr, ($1 eq "") ? shift @ARGV : $1);
    +	    if ( ! $read_tmakeconf ) {
    +		$read_tmakeconf = 1;
    +		&ScanProject( &find_template("tmake.conf") );
    +	    }
    +	    $text = "";
    +	    eval(  ($1 eq "") ? shift @ARGV : $1 );
    +	    die $@ if $@;
    +	    print $text . "\n" if ($text ne "");
    +	    $eval_quit = 1;
     	} elsif ( /^t(.*)/ ) {
     	    $template_name = ($1 eq "") ? shift @ARGV : $1;
     	} elsif ( /^o(.*)/ ) {
     	    $outfile = ($1 eq "") ? shift @ARGV : $1;
     	    ($outfile eq "-") && ($outfile = "");
    +	    if ( $outfile ne "" ) {
    +		open(STDOUT,">" . fix_path($outfile)) ||
    +		  &tmake_error("Can't create \"$outfile\"");
    +	    }
     	} elsif ( /^p(.*)/ ) {
    -	    push( @project_files, ($1 eq "") ? shift @ARGV : $1);
    +	    #
    +	    # The -p option is obsolete and will be removed in the next	    
    +	    # tmake release.
    +	    #
    +	    &tmake_warning( "-p option obsolete, instead use \"tmake file1.pro file2.pro ...\"");
    +	    my($pf) = ($1 eq "") ? shift @ARGV : $1;
    +	    if ( ! $read_tmakeconf ) {
    +		$read_tmakeconf = 1;
    +		&ScanProject( &find_template("tmake.conf") );
    +	    }
    +	    if ( ! ($pf =~ /\.pro$/i) && -f fix_path($pf . ".pro") ) {
    +		$pf .= ".pro";
    +	    }	
    +	    if ( $project_name eq "" ) {
    +		$project_name = $pf;
    +		$project{"PROJECT"} = $project_name;
    +		$project{"PROJECT"} =~ s/\.pro$//i;
    +		$project{"TARGET"} = $project{"PROJECT"};
    +	    }
    +	    if ( !&ScanProject($pf) ) {
    +		&tmake_error("Can't open project file \"$pf\"");
    +	    }
     	} elsif ( /^unix$/ ) {
    -	    $guess_os = 0;
     	    $is_unix = 1;
    +	    $dir_sep = "/";
    +	    $obj_ext = "o";
     	} elsif ( /^win32$/ ) {
    -	    $guess_os = 0;
     	    $is_unix = 0;
    +	    $dir_sep = "\\";
    +	    $obj_ext = "obj";
     	} elsif ( /^nodepend$/ ) {
     	    $nodepend = 1;			# don't generate dependencies
     	} elsif ( /^v$/ ) {
    @@ -81,66 +119,46 @@ while ( @ARGV ) {				# parse command line args
     	} else {
     	    &tmake_usage();
     	}
    -    } elsif ( /^\s*(?:[\w\-]+:)?\w+\s*[\+\-\*\/]?=/ ) { # project override
    -	push( @project_extra, $_ );
    +    } elsif ( /^\s*((?:[^:\s]*?:)?)(\w+)\s*(\+=|\*=|\-=|\/=|=)/ ) {
    +	if ( ! $read_tmakeconf && ! (/^\s*TMAKEPATH/) ) {
    +	    $read_tmakeconf = 1;
    +	    &ScanProject( &find_template("tmake.conf") );
    +	}
    +	Project( $_ );				# manual project setting
         } else {
    -	$project_name &&
    -	    &tmake_error("You can only specify one project file");
    -	$project_name = $_;
    +	my($pf) = $_;
    +	if ( ! $read_tmakeconf ) {
    +	    $read_tmakeconf = 1;
    +	    &ScanProject( &find_template("tmake.conf") );
    +	}
    +	if ( ! ($pf =~ /\.pro$/i) && -f fix_path($pf . ".pro") ) {
    +	    $pf .= ".pro";
    +	}	
    +	if ( $project_name eq "" ) {
    +	    $project_name = $pf;
    +	    $project{"PROJECT"} = $project_name;
    +	    $project{"PROJECT"} =~ s/\.pro$//i;
    +	    $project{"TARGET"} = $project{"PROJECT"};
    +	}
    +	if ( !&ScanProject($pf) ) {
    +	    &tmake_error("Can't open project file \"$pf\"");
    +	}
         }
     }
     
    -($project_name ne "") || &tmake_usage();
    +&tmake_verb("Version $TMAKE_VERSION (runtime environment: " .
    +	    ($really_unix ? "Unix" : "Win32") . ")\n" );
     
    -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 \"$_\"");
    -    }
    +if ( $eval_quit ) {
    +    &tmake_verb("Done!");
    +    exit 0;
     }
    -&Project( @project_extra );
    +($project_name eq "") && &tmake_usage();
     
     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!");
    @@ -159,12 +177,11 @@ exit 0;						# finished!
     #
     
     sub tmake_usage {
    -    print STDERR "Usage:\n    tmake [options] project-file\n";
    +    print STDERR "Usage:\n    tmake [options] project-files\n";
         print STDERR "Options:\n";
         print STDERR "    -e expr    Evaluate expression, ignore template file\n";
         print STDERR "    -nodepend  Don't generate dependency information\n";
         print STDERR "    -o file    Write output to file\n";
    -    print STDERR "    -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";
    @@ -187,6 +204,18 @@ sub tmake_error {
     
     
     #
    +# tmake_warning(msg)
    +#
    +# Prints the warning message
    +#
    +
    +sub tmake_warning {
    +    my($msg) = @_;
    +    print STDERR "tmake warning: " . $msg . "\n";
    +}
    +
    +
    +#
     # tmake_verb()
     #
     # Prints a verbose message
    @@ -207,10 +236,14 @@ sub tmake_verb {
     sub check_unix {
         my($r);
         $r = 0;
    -    if ( -f "/bin/uname" || -f "/usr/bin/uname" ) {
    +    if ( -f "/bin/uname" ) {
     	$r = 1;
     	(-f "\\bin\\uname") && ($r = 0);
         }
    +    if ( -f "/usr/bin/uname" ) {
    +	$r = 1;
    +	(-f "\\usr\\bin\\uname") && ($r = 0);
    +    }
         return $r;
     }
     
    @@ -232,8 +265,9 @@ sub find_template {
         } else {
     	$tb = $template_base . ";";
         }
    -    $d = ";" . $tb . $ENV{"TMAKEPATH"} . ";" . $ENV{"HOME"} . "/.tmake/";
    -    @dirs = &split_path( $d );
    +    $d = $tb . $project{"TMAKEPATH"};
    +    @dirs = ("");
    +    push @dirs, &split_path( $d );
         $filename .= ".t" unless ($filename =~ /\.\w+$/);
         for $d ( @dirs ) {
     	$p = $d . $filename;
    @@ -267,9 +301,15 @@ sub StdInit {
         $stdinit_done = 1;
         if ( defined($project{"OBJECTS_DIR"}) ) {
     	$project{"OBJECTS_DIR"} = FixPath($project{"OBJECTS_DIR"});
    +	&mkdirp($project{"OBJECTS_DIR"},0777);
         }
         if ( defined($project{"MOC_DIR"}) ) {
     	$project{"MOC_DIR"} = FixPath($project{"MOC_DIR"});
    +	&mkdirp($project{"MOC_DIR"},0777);
    +    }
    +    if ( defined($project{"DESTDIR"}) ) {
    +	$project{"DESTDIR"} = FixPath($project{"DESTDIR"});
    +	&mkdirp($project{"DESTDIR"},0777);
         }
         $project{"OBJECTS"} = &Objects($project{"SOURCES"});
         if ( $moc_aware ) {
    @@ -347,18 +387,16 @@ sub Now {
     
     
     #
    -# expand_project_val(tag)
    +# expand_project_var(var)
     #
     # Internal function for Project().
     # Expands a project value string.
     #
     
    -sub expand_project_val {
    +sub expand_project_var {
         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/ ) {
    @@ -415,27 +453,33 @@ sub expand_project_val {
     
     sub Project {
         my @settings = @_;
    -    my($r,$if_tag,$t,$s,$v,$p,$c);
    +    my($r,$if_var,$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" ) {
    +	if ( $v =~ s/^\s*((?:[^:\s]*?:)?)(\w+)\s*(\+=|\*=|\-=|\/=|=)// ) {
    +	    $if_var = $1;
    +	    if ( $if_var ne "" ) {		
    +		chop $if_var;
    +		if ( $if_var eq "unix" ) {
     		    return "" if !$is_unix;
    -		} elsif ( $if_tag eq "win32" ) {
    +		} elsif ( $if_var eq "win32" ) {
     		    return "" if $is_unix;
    -		} elsif ( ($if_tag ne $tmake_platform) && !Config($if_tag) ) {
    +		} elsif ( ($if_var ne $tmake_platform) && !Config($if_var) ) {
     		    return "";
     		}
     	    }
     	    $t = $2;
     	    $s = $3;
    -	    $v = expand_project_val($v);
    +	    if ( ! $notrim_whitespace ) {	
    +		$v =~ s/^\s+//;			# trim white space
    +		$v =~ s/\s+$//;
    +	    }
    +	    $v = expand_project_var($v);
     	    $p = $project{$t};
    -	    if ( $s eq "=" ) {			# set variable
    +	    if ( $s ne "=" && $v eq "" ) {
    +		# nothing to append, subtract or sed
    +	    } elsif ( $s eq "=" ) {		# set variable
     		$p = $v;
     	    } elsif ( $s eq "+=" ) {		# append
     		if ( $p eq "" ) {
    @@ -457,9 +501,9 @@ sub Project {
     		$cmd = '$p =~ ' . $v;
     		eval $cmd;
     	    }
    -	    $project{$t} = expand_project_val($p);
    +	    $project{$t} = expand_project_var($p);
     	} else {
    -	    $p = expand_project_val($project{$v});
    +	    $p = expand_project_var($project{$v});
     	}
     	if ( $p ne "" ) {
     	    $r = ($r eq "") ? $p : ($r . " " . $p);
    @@ -480,7 +524,7 @@ sub Project {
     
     sub Substitute {
         my($subst) = @_;
    -    $text = expand_project_val($subst);
    +    $text = expand_project_var($subst);
         return $text;
     }
     
    @@ -494,28 +538,50 @@ sub Substitute {
     
     sub ScanProject {
         my($file) = @_;
    -    my($tag,$var,@v,$more,$line);
    +    my($var,$val,@v,$more,$line,$endmark);
     
    -    $tag = "";
    +    $var = "";
         $line = 0;
         open(TMP,fix_path($file)) || return 0;
     
    +    &tmake_verb("Reading the project file $file");
         while (  ) {
     	$line++;
     	s/\#.*//;				# strip comment
     	s/^\s+//;				# strip white space
     	s/\s+$//;
    -	if ( /^\s*((?:(?:[^:]*?:)?)\w+\s*(\+|\-|\*|\/)?=)/ ) {
    -	    $tag = $1;				# tag also contains the ".="
    +	if ( /^\s*((?:(?:[^:\s]*?:)?)\w+\s*(\+|\-|\*|\/)?=)/ ) {
    +	    $var = $1;				# var also contains the ".="
     	    s/^.*?=\s*//;
    +	    if ( /^\<\<(.*)$/ ) {
    +		$endmark = $1;		
    +		$val = "";
    +		while (  ) {
    +		    $line++;
    +		    if ( /^\Q$endmark\E$/ ) {
    +			$endmark = "";
    +			last;
    +		    }
    +		    $val .= $_;
    +		}
    +		if ( $endmark ne "" ) {
    +		    tmake_error("$file:$line: End marker $endmark not found");
    +		}
    +		chop $val if ( $val ne "" );
    +		$notrim_whitespace++;
    +		Project( $var . $val );
    +		$notrim_whitespace--;
    +		$var = "";
    +		$_ = "";
    +	    }
     	}
    -	if ( $tag ne "" ) {
    +	if ( $var ne "" ) {
     	    $more = ( $_ =~ s/\s*\\\s*$// );	# more if \ at end of line
     	    push( @v, split( /\s+/, $_ ) );
     	    if ( ! $more ) {
    -		$var = join(" ",@v);
    -		Project( $tag . $var );
    -		$tag = "";
    +		$val = join(" ",@v);
    +		Project( $var . $val );
    +		$var = "";
     		@v = ();
     	    }
     	} elsif ( $_ ne "" ) {
    @@ -523,6 +589,7 @@ sub ScanProject {
     	}
         }
         close(TMP);
    +    &tmake_verb("Done reading the project file $file");
         return 1;
     }
     
    @@ -601,15 +668,15 @@ sub IncludeTemplate {
     
     
     #
    -# Expand(tag) - appends to $text
    +# Expand(var) - appends to $text
     #
     # Expands a list of $project{} variables with a space character between them.
     #
     
     sub Expand {
    -    my @tags = @_;
    +    my @vars = @_;
         my($t);
    -    $t = Project(@tags);
    +    $t = Project(@vars);
         if ( $text eq "" ) {
     	$text = $t;
         } elsif ( $t ne "" ) {
    @@ -620,13 +687,13 @@ sub Expand {
     
     
     #
    -# ExpandGlue(tag,prepend,glue,append) - appends to $text
    +# ExpandGlue(var,prepend,glue,append) - appends to $text
     #
    -# Expands a $project{} tag, splits on whitespace
    +# Expands a $project{} variable, splits on whitespace
     # and joins with $glue. $prepend is put at the start
     # of the string and $append is put at the end of the
     # string. The resulting string becomes "" if the project
    -# tag is empty or not defined.
    +# var is empty or not defined.
     #
     # Example:
     #
    @@ -640,9 +707,9 @@ sub Expand {
     #
     
     sub ExpandGlue {
    -    my($tag,$prepend,$glue,$append) = @_;
    +    my($var,$prepend,$glue,$append) = @_;
         my($t,$v);
    -    $v = Project($tag);
    +    $v = Project($var);
         if ( $v eq "" ) {
     	$t = "";
         } else {
    @@ -658,14 +725,67 @@ sub ExpandGlue {
     
     
     #
    -# ExpandList(tag) - sets $text.
    +# ExpandList(var) - sets $text.
     #
     # Suitable for expanding HEADERS = ... etc. in a Makefile
     #
     
     sub ExpandList {
    -    my($tag) = @_;
    -    return ExpandGlue($tag,""," ${linebreak}\n\t\t","");
    +    my($var) = @_;
    +    return ExpandGlue($var,""," ${linebreak}\n\t\t","");
    +}
    +
    +
    +#
    +# ExpandPath(var,prepend,glue,append) - appends to $text
    +#
    +# Expands a $project{} variable, splits on either ';' or
    +# whitespace and joins with $glue. $prepend is put at the
    +# start of the string and $append is put at the end of the
    +# string. The resulting string becomes "" if the project
    +# variable is empty or not defined.
    +#
    +# If the variable contains at least one semicolon or tmake
    +# is running on Windows, the resulting items are put in
    +# double-quotes.
    +#
    +# Example:
    +#
    +#   The project file defines:
    +#	INCLUDEPATH = "C:\qt\include;c:\program files\msdev\include
    +#
    +#   ExpandGlue("INCLUDEPATH","-I","-I","")
    +#
    +#   The result:
    +#	$text = -I"c:\qt\include" -I"c:\program files\msdev\include"
    +#
    +
    +sub ExpandPath {
    +    my($var,$prepend,$glue,$append) = @_;
    +    my($t,$v);
    +    my($s);
    +    $v = Project($var);
    +    if ( $v eq "" ) {
    +	$t = "";
    +    } else {
    +	if ( $v =~ /;/ || !$is_unix ) {
    +	    $prepend .= '"';
    +	    $glue = '"' . $glue . '"';
    +	    $append = '"' . $append;
    +	}
    +
    +	if ( $v =~ /;/ ) {    
    +	    $t = $prepend . join($glue,split(/;+/,$v)) . $append;
    +	} else {
    +	    $t = $prepend . join($glue,split(/\s+/,$v)) . $append;
    +	}
    +    }
    +    if ( $text eq "" ) {
    +	$text = $t;
    +    } elsif ( $t ne "" ) {
    +	$text .= " " . $t;
    +    }
    +    return $text;
     }
     
     
    @@ -859,11 +979,18 @@ sub AddIncludePath {
     	return;
         }
         $project{"INCLUDEPATH"} = "" if !defined($project{"INCLUDEPATH"});
    +    if ( !defined($project{"INCPATH_SEP"}) ) {
    +	if ( $project{"INCLUDEPATH"} =~ /;/ ) {
    +	    $project{"INCPATH_SEP"} = ";";
    +	} else {
    +	    $project{"INCPATH_SEP"} = " ";
    +	}
    +    }
         $p = $project{"INCLUDEPATH"};
         $p = ($p && $path) ? ($p . ";" . $path) : ($p . $path);
         $project{"INCLUDEPATH"} = $p;
    -    $p = join(" ",&split_path($p));
    -    $p =~ s=[\\/](\s|$)= =g;
    +    $p = join($project{"INCPATH_SEP"},&split_path($p));
    +    $p =~ s=[\\/]($project{"INCPATH_SEP"}|$)=$project{"INCPATH_SEP"}=g;
         $project{"INCPATH"} = $p;
     }
     
    @@ -887,7 +1014,7 @@ sub FindHighestLibVersion {
         $highest = "";
         @files = find_files($dir,"${name}.*\.lib");
         for $f ( @files ) {
    -	if ( $f =~ /(\d+)\.lib/ ) {
    +	if ( $f =~ /(\d+)\.lib/i ) {
     	    $v = $1;
     	    if ( $highest eq "" || $v > $highest ) {
     		$highest = $v;
    @@ -971,7 +1098,7 @@ sub make_depend {
         @cur_dep_path = @dep_path;
         if ( $file =~ /(.*[\/\\])/ ) {
     	$dep_curdir = $1;
    -	splice( @cur_dep_path, 0, 0, $dep_curdir );
    +	push @cur_dep_path, $dep_curdir;
         } else {
     	$dep_curdir = "";
         }
    @@ -1032,7 +1159,7 @@ sub canonical_dep {
     sub scan_dep {
         my($file) = @_;
         my($dir,$path,$found,@allincs,@includes,%incs);
    -    $path = ($file eq $dep_file) ? $file : $dep_curdir . $file;
    +    $path = $file;
         @includes = ();
         return @includes if $file =~ /\.$moc_ext$/; # avoid .moc files
         if ( ! (-f fix_path($path)) ) {
    @@ -1072,13 +1199,24 @@ sub scan_dep {
     
     sub split_path {
         my($p) = @_;
    -    return ""  if !defined($p);
    +    my($s,@d);
    +    @d = ();
    +    return @d if !defined($p) || $p eq "";
         $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);
    +    if ( !($p =~ /;/) ) {
    +	$p =~ s/\s+/;/g;
    +    }
    +    $p =~ s/\s*;\s*/;/g;
    +    while( $p =~ /(?:(?:[^\"\;][^\;]*;*)|(?:\"[^\"]*\";*))/g ) {
    +	$s = $&;
    +	$s =~ s=\"==g;
    +	$s =~ s=[\s\;]+$==g;
    +	$s =~ s=([^/:])$=$1/=g;
    +	$s =~ s=/=$dir_sep=g unless $is_unix;
    +	push @d, $s;
    +    }
    +    return @d;
     }
     
     
    @@ -1097,3 +1235,28 @@ sub fix_path {
         }
         return $p;
     }
    +
    +
    +#
    +# mkdirp(filename,mode) - Internal for StdInit()
    +#
    +# Creates the directory specified by $filename, with permissions
    +# specified by mode (as modified by umask). Recursively calls
    +# mkdir, similar to 'mkdir -p'.
    +#
    +
    +sub mkdirp {
    +    my($filename,$mode) = @_;
    +    if ( $filename =~ /\$\(\w+\)/ ) {  # ignore "$(something)"
    +	return 0;
    +    }
    +    $filename =~ s-[\\:/]+-/-g;
    +    if ( -d $filename ) {
    +	return 1;
    +    }
    +    $filename =~ m-^((.*)/)?(.*)-;
    +    if ( defined($2) && ! mkdirp($2,$mode) ) {
    +	return 0;
    +    }
    +    return mkdir($filename,$mode);
    +}
    diff --git a/tmake/bin/tmake.bat b/tmake/bin/tmake.bat
    deleted file mode 100644
    index 6fbd6b2..0000000
    --- a/tmake/bin/tmake.bat
    +++ /dev/null
    @@ -1,1093 +0,0 @@
    -@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 (  ) {
    -	$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 (  ) {
    -	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 (  ) {
    -		    $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 = ""
    -#
    -
    -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 = ;
    -	    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;
    -	$_ = ;
    -	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/tmake.html b/tmake/doc/tmake.html
    index b19af51..1b14809 100644
    --- a/tmake/doc/tmake.html
    +++ b/tmake/doc/tmake.html
    @@ -1,52 +1,36 @@
     
     
    -tmake User's Guide
    +User's Guide - tmake
     
    -

    tmake User's Guide

    - - -
    -

    License Statement

    - -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. +

    User's Guide - tmake


    Introduction

    -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. - -

    -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 Qt, Troll Tech must provide -Qt makefiles for more than 30 different OS/compiler combinations. +tmake is an easy-to-use tool from Troll Tech to create and maintain +makefiles for software projects. It can be a painful task to manage +makefiles manually, especially if you develop for more than one platform +or use more than one compiler. tmake automates and streamlines this +process and lets you spend your valuable time on writing code, not +makefiles.

    -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 -meta object -compiler (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. +Our main motivation for developing tmake was that we spent far too much +time maintaining makefiles for Qt, +our cross-platform GUI toolkit. Qt supports around 15 flavors of Unix, +Microsoft Windows, and around 15 different C++ compilers. We looked at +GNU autoconf, but it was Unix-specific and not flexible enough in our +opinion. Our makefile system also had to deal with Qt meta object compiler +(moc) issues. The moc program extracts meta information from C++ files and +generates a C++ file with data tables etc. It takes extra work to add +makefile rules for the moc and wanted to automate this task.

    -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. - -

    -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. +tmake is written in Perl and requires that you have installed perl version +5 or newer. Basic use of tmake requires no perl knowledge, but if you know +perl you can extend tmake and write your own makefile templates.

    Windows users: The tmake distribution for Win32 includes tmake.exe @@ -56,9 +40,14 @@ perl scripts. You can download perl for Win32 (Windows NT and 95) from www.activestate.com

    -Feedback is highly appreciated. Contact the author hanord@troll.no if you -have ideas, patches etc. for tmake. +tmake is free software and you may use, copy, modify and distribute tmake +and its documentation for any purpose and without any fee. See the +LICENSE file for details. +

    +Feedback is highly appreciated. Contact the author, Haavard Nord (hanord@troll.no), if you have ideas, +patches etc. for tmake.


    Installation

    @@ -66,7 +55,7 @@ have ideas, patches etc. for tmake.
    1. Make sure you have perl version 5 or later installed (optional for Windows users). -
    2. Unpack the tmake tar.gz or zip archive. +
    3. Unpack the tmake tar.gz archive for Unix or the tmake .zip file for Windows.
    4. Set the TMAKEPATH environment variable to the directories containing the template files (see below).
    5. Add the tmake/bin directory to your PATH. @@ -84,14 +73,15 @@ Here are some examples:

      setenv PATH $PATH:/local/tmake/bin

    -Windows NT and Windows 95:
    +Microsoft Windows:
         set TMAKEPATH=c:\tmake\lib\win32-msvc
         set PATH=%PATH%;c:\tmake\bin
     

    -The template directory name has the form platform-compiler. -Each template directory contains template files and a configuration file. +The template directory name has the form platform-compiler +and contains a platform configuration file (tmake.conf) and tmake template +files.

    Supported platforms: AIX, Data General, FreeBSD, HPUX, SGI Irix, Linux, @@ -99,8 +89,7 @@ NetBSD, OpenBSD, OSF1/DEC, SCO, Solaris, SunOS, Ultrix, Unixware and Win32.

    -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. +You can find your platform-compiler combination in the tmake/lib.

    Unix users: tmake requires that perl is in /usr/bin. If your @@ -114,7 +103,7 @@ make a small shell script which invokes tmake with the correct perl. 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:

    +First you need to create a tmake project file, e.g. hello.pro:
       HEADERS   =  hello.h
       SOURCES   =  hello.cpp main.cpp
       TARGET    =  hello
    @@ -173,7 +162,7 @@ these files:
     
     

    The hello.pro project file above does not have a TEMPLATE or -a CONFIG tag. The default template is app (the .t +a CONFIG variable. The default template is app (the .t extension is optional) and the default configuration is qt warn_on release. @@ -191,7 +180,7 @@ above:

     

    Makefile Configuration

    -The CONFIG tag is recognized by both the app.t and lib.t +The CONFIG variable is recognized by both the app.t and lib.t templates and specifies what compiler options to use and which extra libraries to link in. @@ -247,7 +236,7 @@ These options defines the application/library type:

  • - + @@ -265,7 +254,7 @@ These options defines the application/library type: - + @@ -283,7 +272,7 @@ read:
     

    -The most common tmake options and project tags are described here. +The most common tmake options and project variables are described here. See the tmake reference manual for details.

    @@ -294,7 +283,7 @@ details.

    The application template, app.t, lets you compile and link executable programs or shared objects (DLLs). -This template recognizes several tags. +This template recognizes several variabless.


    "; + t << "


    "; } else { @@ -494,9 +546,35 @@ void HtmlGenerator::endMemberHeader() } } +void HtmlGenerator::memberGroupSpacing(bool inGroup) +{ + t << "

    "; + } + else + { + // one pixel height of whitespace + t << " height=1>"; + } + t << "
    "; + if (Config::htmlAlignMemberFlag) t << "
    "; } void HtmlGenerator::endMemberSubtitle() @@ -504,3 +582,36 @@ void HtmlGenerator::endMemberSubtitle() if (Config::htmlAlignMemberFlag) t << "

      x11  The target is a X11 application (app.t only).The target is a X11 application or library.
       dll  The target is a shared object/DLL (app.t only).The target is a shared object/DLL.
     
    @@ -372,10 +361,9 @@ The library template, lib.t, lets you compile and create static or shared libraries.

    -The lib.t template supports the same project tags as app.t, but also +The lib.t template supports the same project variables as app.t, but also VERSION. VERSION is the version number of the -target library, e.g. 1.40. The version is important for Unix shared -libraries, but ignored on Windows. +target library, e.g. 1.40. The version is important for shared libraries. @@ -383,7 +371,7 @@ libraries, but ignored on Windows. The subdirs template, subdirs.t, lets you invoke make in subdirectories. -

    The SUBDIRS tag contains the name of all subdirectories to +

    The SUBDIRS variable contains the name of all subdirectories to be processed. @@ -418,29 +406,130 @@ template):

     
     
     
    -

    Program Usage: tmake

    +

    Project File Syntax

    + +The tmake project file has a very simple syntax. You may set +project variables, append to project variables, remove from +project variable and substitute project variables. + +To set a project variable:
    +    HEADERS = gui.h xml.h url.h
    +
    + +If you cannot fit everything on one line, use '\' to split it up:
    +    HEADERS = gui.h \
    +	      xml.h \
    +	      url.h
    +
    + +

    +Project variables contains lists of items (such as header files, +compiler options etc.) and use whitespace to separate the items. +This means that tmake cannot deal with items containing whitespace. +The INCLUDEPATH variable is an exception. If INCLUDEPATH contains +one or more semicolons (;), tmake uses the semicolon to separate +the include directories, hence you can have include directories +containing whitespace (this is quite common on Windows). + +

    +Here is an example:

    +    INCLUDEPATH = C:\Program Files\DBLib\Include;C:\qt\include
    +
    + +

    +tmake supports project variable expension. Use $$ to expand +any project variable:

    +    ALLFILES = $$HEADERS $$SOURCES
    +
    + +

    +Most often you assign some value to a project variable, but you can +also add to, remove from or replace parts of a project variable.

    +    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
    +
    +The *= operation adds the value if the variable does not already contain it. +The /= operation performs regular expression substitution. + +

    +You can also set variables from the command line when running the tmake +program. For instance, if you want to generate a makefile with debug +information:

    +    tmake "CONFIG+=debug" hello.pro
    +
    + +

    +Use the unix: or win32: (conditional) qualifier if you want a +platform-specific variable:

    +    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
    +
    +If none of the platforms match, tmake looks for the variable in CONFIG +variable:
    +    debug:SOURCES  +=  dbgstuff.cpp # additional source for debugging
    +
    + +Finally, you can set platform and compiler-dependent variables:
    +    linux-g++:TMAKE_CFLAGS = -fno-rtti
    +
    + +

    +You may define your own project variables to be used by custom templates. A +project variable is stored in %project, which is an associative +Perl array. Access it like this: $project{"var"} or via the +function Project("var"). For example, after reading +"hello.pro", $project{"SOURCES"} contains "hello.cpp +main.cpp".

    + + +


    +

    Running tmake

    Usage:
    -  tmake [options] project-file
    +  tmake [options] project files or project settings
     
    Options:
       -e expr    Evaluate the Perl expression.  Ignores the template file.
       -nodepend  Don't generate dependency information.
       -o file    Write output to file instead of stdout.
    -  -p file    Load an additional project file.
       -t file    Specify a template file.
       -unix      Force tmake into Unix mode.
       -v         Verbose/debugging on.
       -win32     Force tmake into Win32 mode.
     
    -The -t option overrides any TEMPLATE tag in the project file. +The -t option overrides any TEMPLATE variable in the project file.

    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. + +

    +Example of basic use:

    +    tmake hello -o Makefile
    +
    + +

    +Example of how to create a makefile with debugging information:

    +    tmake "CONFIG+=debug" hello -o Makefile
    +
    +

    +Exmaple of how to specify a TMAKEPATH:

    +    tmake "TMAKEPATH=/local/tmake/lib/hpux-g++" hello.pro -o Makefile
    +
    +Example of how to evaluate a perl expression (print names of headers +and source files):
    +    tmake hello -e 'Expand("HEADERS","SOURCES")'
    +

    The progen Utility

    @@ -478,12 +567,12 @@ settings in your project file:
       solaris-cc:TMAKE_CC     = /opt/bin/CC_5.0
       solaris-cc:TMAKE_CFLAGS = -pts
       unix:TMAKE_LIBS         = -lXext
    -  win32:INCLUDE_PATH      = c:\myinclude
    +  win32:INCLUDEPATH       = c:\myinclude
       win32-borland:DEFINES   = NO_BOOL
     
    -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 +You can prefix a project variable with unix: or win32: to make it specific for +either Unix or Windows. You can also prefix a variable with platform-compiler

    Your Own Templates

    @@ -496,10 +585,10 @@ can do with tmake. First you need to know how tmake works. When you run tmake, it first reads the tmake.conf file. This configuration file has the same syntax as the project file. -tmake then reads the project file and sets the project tags it +tmake then reads the project file and sets the project variables it finds, e.g. HEADERS, SOURCES etc. -All tags and values are stored in a global associative Perl hash +All variables and values are stored in a global associative Perl hash array called project. For example, $project{"SOURCES"} contains "hello.cpp main.cpp" after processing hello.pro. diff --git a/tmake/doc/tmake_ref.html b/tmake/doc/tmake_ref.html index 0b89b28..c9124c4 100644 --- a/tmake/doc/tmake_ref.html +++ b/tmake/doc/tmake_ref.html @@ -1,67 +1,11 @@ -tmake Reference Manual +Reference Manual - tmake -

    tmake Reference Manual

    +

    Reference Manual - tmake


    -

    Project Settings

    - -tmake recognizes several project tags. The syntax for setting a -project variable is:
    -    TAG = value
    -
    -You can also do tag expansion using $$:
    -    ALLFILES = Project files: $$HEADERS $$SOURCES
    -
    -Normally you assign to a tag, but you can also add to a tag, subtract -from a tag or replace parts of the tag.
    -    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
    -
    -The *= operation adds the value if the tag does not already contain it. -The /= operation performs regular expression substitution. - -

    -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:

    -    tmake hello.pro "CONFIG+=debug"
    -
    - -

    -Use the unix: or win32: qualifier if you want a -platform-specific tag:

    -    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
    -
    -If none of the platforms match, tmake looks for the tag in CONFIG setting:
    -    debug:SOURCES  +=  dbgstuff.cpp # additional source for debugging
    -
    - -Finally, you can set platform and compiler-dependent tags:
    -    linux-g++:TMAKE_CFLAGS = -fno-rtti
    -
    - -

    -You may define your own project tags to be used by custom templates. A -project tag is stored in %project, which is an associative -Perl array. Access it like this: $project{"tag"} or via the -function Project('tag'). For example, after reading -"hello.pro", $project{"SOURCES"} contains "hello.cpp -main.cpp". One limitation of tmake is that it cannot handle file names -with white space.

    - - -


    -

    Project Tag Reference

    +

    Project Variable Reference

    ALL_DEPS

    Specifies additional dependencies for the makefile target "all:".

    @@ -158,6 +102,12 @@ These options defines the application/library type:

    +

    DEFINES

    +Specifies C/C++ macros (-D compiler option). On Windows you need +to let DEFINES contain "QT_DLL" if you are building a Qt program +which should link with the Qt DLL. + +

    DEF_FILE

    Win32/app.t only: Specifies a .def file. @@ -175,14 +125,14 @@ Defines the header files of the project.

    INCPATH

    -This tag is generated from INCLUDEPATH. The ';' or ':' +This variable is generated from INCLUDEPATH. The ';' or ':' separators have been replaced by ' ' (single space). This makes it easier to split. qtapp.t and other templates expand INCPATH to set -I options for the C++ compiler.

    INCLUDEPATH

    -This tag specifies the #include directories. It can be set in the +This variable specifies the #include directories. It can be set in the project file, or by the AddIncludePath() function.

    Example:

    @@ -214,7 +164,7 @@ See also: OBJECTS_DIR.
     
     
     

    OBJECTS

    -This tag is generated from SOURCES by the StdInit() function. +This varialble is generated from SOURCES by the StdInit() function. The extension of each source file has been replaced by .o (Unix) or .obj (Win32).

    Example:

    @@ -236,7 +186,7 @@ See also: MOC_DIR.
     
     
     

    OBJMOC

    -This tag is generated by the StdInit() function if +This variable is generated by the StdInit() function if $moc_aware is true. OBJMOC contains the name of all intermediate moc object files.

    Example:

    @@ -258,7 +208,7 @@ file, excluding the .pro extension.
     
     

    RC_FILE

    Win32/app.t only: Specifies a .rc file. Cannot be used with the RES_FILE -tag. +variable.

    RES_FILE

    @@ -271,7 +221,7 @@ Defines the source files of the project.

    SRCMOC

    -This tag is generated by the StdInit() function if +This variable is generated by the StdInit() function if CONFIG contains "qt". SRCMOC contains the name of all intermediate moc files.

    Example:

    @@ -303,8 +253,8 @@ Contains the name of the compiler.
     Contains the default compiler flags.
     
     
    -

    TMAKE_FILETAGS

    -Tells tmake which tags contain file names. This is because tmake +

    TMAKE_FILEVARS

    +Tells tmake which variables contain file names. This is because tmake on Windows replace the directory separator / with \. @@ -370,7 +320,7 @@ Example:
     
     
     

    Config(string)

    -Returns true if the CONFIG tag contains the given string. +Returns true if the CONFIG variable contains the given string.

    Example:

       #$ if ( Config("release") { }
     
    @@ -390,20 +340,20 @@ EnableOutput() is called. Enables tmake output after DisableOutput() was called. -

    Expand(tag)

    -Expands a project tag. Equivalent to $text = $project{$tag}. +

    Expand(var)

    +Expands a project variable. Equivalent to $text = $project{$var}.

    Example:

       VERSION = #$ Expand("VERSION");
     
    Output:
       VERSION = 1.1
     
    -

    ExpandGlue(tag,prepend,glue,append)

    -Expands a $project{} tag, splits on whitespace +

    ExpandGlue(var,prepend,glue,append)

    +Expands a $project{} variable, splits on whitespace and joins with $glue. $prepend is put at the start of the string and $append is put at the end of the string. The resulting string ($text) becomes "" if -the project tag is empty or not defined.

    +the project variable is empty or not defined.

    Example:

       clear:
               #$ ExpandGlue("OBJECTS","-del","\n\t-del ","");
    @@ -414,9 +364,9 @@ Example:
     
    -

    ExpandList(tag)

    +

    ExpandList(var)

    This function is suitable for expanding lists of files. -Equivalent with ExpandGlue($tag,""," \\\n\t\t","").

    +Equivalent with ExpandGlue($var,""," \\\n\t\t","").

    Example:

       OBJECTS = #$ ExpandList("OBJECTS");
     
    Output:
    @@ -425,6 +375,11 @@ Example:
     
    +

    ExpandPath(var,prepend,glue,append)

    +Similar to ExpandGlue, except that it splits the items on a semicolon +instead of space (if the variable contains at least one semicolon). + +

    IncludeTemplate(file)

    Includes a template file. The ".t" extension is optional.

    Example:

    @@ -477,7 +432,7 @@ between).
     
     
     

    ScanProject(file)

    -Scans a project file and stores the project tags and values in the +Scans a project file and stores the project variables and values in the global associative %project array. @@ -485,7 +440,7 @@ global associative %project array. Standard initialization of tmake. StdInit() should be called from one of the first lines in the template.

    -This function creates some new project tags:

      +This function creates some new project variables:
      • OBJECTS - Object files corresponding to SOURCES. @@ -493,16 +448,16 @@ This function creates some new project tags: -The moc-related tags are created only if CONFIG contains "qt" +The moc-related variables are created only if CONFIG contains "qt"

        Substitute(string)

        -This function takes a string and substitutes any occurrence of $$tag -with the actual content of the tag. Returns the substituted string. +This function takes a string and substitutes any occurrence of $$var +with the actual content of the variable. Returns the substituted string. Also sets $text.

        Important: Use single quotes around the string, otherwise perl will expand -any $tags it finds. +any $vars it finds.

        Example:

             Substitute('Project name: $$PROJECT, uses template $$TEMPLATE');
         
        diff --git a/tmake/lib/aix-g++/tmake.conf b/tmake/lib/aix-g++/tmake.conf index f2fe571..cf8c528 100755 --- a/tmake/lib/aix-g++/tmake.conf +++ b/tmake/lib/aix-g++/tmake.conf @@ -11,9 +11,9 @@ TMAKE_CC = gcc TMAKE_CFLAGS = TMAKE_CFLAGS_WARN_ON = -Wall -W TMAKE_CFLAGS_WARN_OFF = -TMAKE_CFLAGS_RELEASE = -O2 -fno-strength-reduce +TMAKE_CFLAGS_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g -TMAKE_CFLAGS_SHLIB = +TMAKE_CFLAGS_SHLIB = TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses TMAKE_CXX = g++ @@ -43,10 +43,10 @@ TMAKE_LFLAGS_SHLIB = TMAKE_LFLAGS_SONAME = TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl -TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu TMAKE_MOC = moc diff --git a/tmake/lib/aix-xlc/tmake.conf b/tmake/lib/aix-xlc/tmake.conf index 401e390..623f258 100755 --- a/tmake/lib/aix-xlc/tmake.conf +++ b/tmake/lib/aix-xlc/tmake.conf @@ -38,7 +38,7 @@ 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); \ + -lXext -lX11 $(OBJECTS) $(OBJMOC); \ ar q lib$(TARGET).a lib$(TARGET).so.$(VER_MAJ).$(VER_MIN); \ ranlib lib$(TARGET).a; \ mv lib$(TARGET).a $(DESTDIR) @@ -49,7 +49,7 @@ TMAKE_LFLAGS_SHLIB = TMAKE_LFLAGS_SONAME = TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu diff --git a/tmake/lib/bsdi-g++/app.t b/tmake/lib/bsdi-g++/app.t new file mode 100755 index 0000000..867725e --- /dev/null +++ b/tmake/lib/bsdi-g++/app.t @@ -0,0 +1,2 @@ +#! Use the common Unix template +#$ IncludeTemplate("../unix/app.t"); diff --git a/tmake/lib/bsdi-g++/lib.t b/tmake/lib/bsdi-g++/lib.t new file mode 100755 index 0000000..2523b2f --- /dev/null +++ b/tmake/lib/bsdi-g++/lib.t @@ -0,0 +1,2 @@ +#! Use the common Unix template +#$ IncludeTemplate("../unix/lib.t"); diff --git a/tmake/lib/bsdi-g++/subdirs.t b/tmake/lib/bsdi-g++/subdirs.t new file mode 100755 index 0000000..5e888af --- /dev/null +++ b/tmake/lib/bsdi-g++/subdirs.t @@ -0,0 +1,2 @@ +#! Use the common Unix template +#$ IncludeTemplate("../unix/subdirs.t"); diff --git a/tmake/lib/bsdi-g++/tmake.conf b/tmake/lib/bsdi-g++/tmake.conf new file mode 100755 index 0000000..e0bfd42 --- /dev/null +++ b/tmake/lib/bsdi-g++/tmake.conf @@ -0,0 +1,60 @@ +# +# $Id$ +# +# tmake configuration for bsdi-shlicc++, bsdi 4.0 +# +# shlicc/++ is a BSDI wrapper around cc/g++ that enables shared libs +# (info/7367) +# + +TEMPLATE = app +CONFIG = qt warn_on release + +TMAKE_CC = gcc +TMAKE_CFLAGS = +TMAKE_CFLAGS_WARN_ON = -Wall -W +TMAKE_CFLAGS_WARN_OFF = +TMAKE_CFLAGS_RELEASE = -O2 +TMAKE_CFLAGS_DEBUG = -g +TMAKE_CFLAGS_SHLIB = -fPIC +TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses + +TMAKE_CXX = shlicc++ +TMAKE_CXXFLAGS = $$TMAKE_CFLAGS +TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON +TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF +TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE +TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG +TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB +TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC + +TMAKE_INCDIR = +TMAKE_LIBDIR = +TMAKE_INCDIR_X11 = /usr/X11R6/include +TMAKE_LIBDIR_X11 = /usr/X11R6/lib +TMAKE_INCDIR_QT = $(QTDIR)/include +TMAKE_LIBDIR_QT = $(QTDIR)/lib +TMAKE_INCDIR_OPENGL = /usr/X11R6/include +TMAKE_LIBDIR_OPENGL = /usr/X11R6/lib + +TMAKE_LINK = shlicc++ +TMAKE_LINK_SHLIB = shlicc++ +TMAKE_LFLAGS = -Wl,-rpath=/lib:/usr/X11R6/lib:$(QTDIR)/lib +TMAKE_LFLAGS_RELEASE = +TMAKE_LFLAGS_DEBUG = +TMAKE_LFLAGS_SHLIB = -shared +TMAKE_LFLAGS_SONAME = -Wl,-soname, + +TMAKE_LIBS = +TMAKE_LIBS_X11 = -lXext -lX11 -lm +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu + +TMAKE_MOC = moc + +TMAKE_AR = ar cqs +TMAKE_RANLIB = + +TMAKE_TAR = tar -cf +TMAKE_GZIP = gzip -9f diff --git a/tmake/lib/dgux-g++/tmake.conf b/tmake/lib/dgux-g++/tmake.conf index 54e4ac3..ff9c24b 100755 --- a/tmake/lib/dgux-g++/tmake.conf +++ b/tmake/lib/dgux-g++/tmake.conf @@ -11,7 +11,7 @@ TMAKE_CC = gcc TMAKE_CFLAGS = TMAKE_CFLAGS_WARN_ON = -Wall -W TMAKE_CFLAGS_WARN_OFF = -TMAKE_CFLAGS_RELEASE = -O2 -fno-strength-reduce +TMAKE_CFLAGS_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_SHLIB = -fPIC TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses @@ -44,10 +44,10 @@ TMAKE_LFLAGS_SHLIB = -shared TMAKE_LFLAGS_SONAME = -Wl,-h, TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl -TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu TMAKE_MOC = moc diff --git a/tmake/lib/freebsd-g++/tmake.conf b/tmake/lib/freebsd-g++/tmake.conf index d7dbb21..ee3f390 100755 --- a/tmake/lib/freebsd-g++/tmake.conf +++ b/tmake/lib/freebsd-g++/tmake.conf @@ -11,7 +11,7 @@ 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_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_SHLIB = -fPIC TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses @@ -45,10 +45,10 @@ TMAKE_LFLAGS_SHLIB = -shared #TMAKE_LFLAGS_SONAME = -Wl,-soname TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl -TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu TMAKE_MOC = moc diff --git a/tmake/lib/gnu-g++/tmake.conf b/tmake/lib/gnu-g++/tmake.conf index eed7c32..9712914 100755 --- a/tmake/lib/gnu-g++/tmake.conf +++ b/tmake/lib/gnu-g++/tmake.conf @@ -11,7 +11,7 @@ TMAKE_CC = gcc TMAKE_CFLAGS = TMAKE_CFLAGS_WARN_ON = -Wall -W TMAKE_CFLAGS_WARN_OFF = -TMAKE_CFLAGS_RELEASE = -O2 -fno-strength-reduce +TMAKE_CFLAGS_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_SHLIB = -fPIC TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses @@ -43,10 +43,10 @@ TMAKE_LFLAGS_SHLIB = -shared TMAKE_LFLAGS_SONAME = -Wl,-soname, TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl -TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu TMAKE_MOC = moc diff --git a/tmake/lib/hpux-acc/tmake.conf b/tmake/lib/hpux-acc/tmake.conf index 381fa97..6a50ab5 100755 --- a/tmake/lib/hpux-acc/tmake.conf +++ b/tmake/lib/hpux-acc/tmake.conf @@ -27,8 +27,8 @@ TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC TMAKE_INCDIR = TMAKE_LIBDIR = -TMAKE_INCDIR_X11 = -TMAKE_LIBDIR_X11 = +TMAKE_INCDIR_X11 = /usr/include/X11R6 +TMAKE_LIBDIR_X11 = /usr/lib/X11R6 TMAKE_INCDIR_QT = $(QTDIR)/include TMAKE_LIBDIR_QT = $(QTDIR)/lib TMAKE_INCDIR_OPENGL = @@ -44,7 +44,7 @@ TMAKE_LFLAGS_SONAME = TMAKE_HPUX_SHLIB = 1 TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu diff --git a/tmake/lib/hpux-cc/tmake.conf b/tmake/lib/hpux-cc/tmake.conf index 851cb67..91289cf 100755 --- a/tmake/lib/hpux-cc/tmake.conf +++ b/tmake/lib/hpux-cc/tmake.conf @@ -27,8 +27,8 @@ TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC TMAKE_INCDIR = TMAKE_LIBDIR = -TMAKE_INCDIR_X11 = -TMAKE_LIBDIR_X11 = +TMAKE_INCDIR_X11 = /usr/include/X11R6 +TMAKE_LIBDIR_X11 = /usr/lib/X11R6 TMAKE_INCDIR_QT = $(QTDIR)/include TMAKE_LIBDIR_QT = $(QTDIR)/lib TMAKE_INCDIR_OPENGL = @@ -44,7 +44,7 @@ TMAKE_LFLAGS_SONAME = TMAKE_HPUX_SHLIB = 1 TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu diff --git a/tmake/lib/hpux-g++/tmake.conf b/tmake/lib/hpux-g++/tmake.conf index f9b47d4..c39e8f9 100755 --- a/tmake/lib/hpux-g++/tmake.conf +++ b/tmake/lib/hpux-g++/tmake.conf @@ -11,7 +11,7 @@ TMAKE_CC = gcc TMAKE_CFLAGS = TMAKE_CFLAGS_WARN_ON = -Wall -W TMAKE_CFLAGS_WARN_OFF = -TMAKE_CFLAGS_RELEASE = -O2 -fno-strength-reduce +TMAKE_CFLAGS_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_SHLIB = -fPIC TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses @@ -27,8 +27,8 @@ TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC TMAKE_INCDIR = TMAKE_LIBDIR = -TMAKE_INCDIR_X11 = -TMAKE_LIBDIR_X11 = +TMAKE_INCDIR_X11 = /usr/include/X11R6 +TMAKE_LIBDIR_X11 = /usr/lib/X11R6 TMAKE_INCDIR_QT = $(QTDIR)/include TMAKE_LIBDIR_QT = $(QTDIR)/lib TMAKE_INCDIR_OPENGL = @@ -44,7 +44,7 @@ TMAKE_LFLAGS_SONAME = TMAKE_HPUX_SHLIB = 1 TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl TMAKE_LIBS_OPENGL = diff --git a/tmake/lib/irix-64/tmake.conf b/tmake/lib/irix-64/tmake.conf index 2d20f07..3e35176 100755 --- a/tmake/lib/irix-64/tmake.conf +++ b/tmake/lib/irix-64/tmake.conf @@ -7,10 +7,10 @@ TEMPLATE = app CONFIG = qt warn_on release -TMAKE_CC = CC +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_WARN_OFF = TMAKE_CFLAGS_RELEASE = -O2 -OPT:Olimit=3000 TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_SHLIB = @@ -43,7 +43,7 @@ TMAKE_LFLAGS_SHLIB = -shared TMAKE_LFLAGS_SONAME = -Wl,-soname, TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu @@ -53,7 +53,7 @@ TMAKE_MOC = moc TMAKE_AR = ar cq TMAKE_RANLIB = -TMAKE_CLEAN = so_locations +TMAKE_CLEAN = -r so_locations ii_files TMAKE_TAR = tar -cf TMAKE_GZIP = gzip -9f diff --git a/tmake/lib/irix-dcc/tmake.conf b/tmake/lib/irix-dcc/tmake.conf index 5f69690..f0fb7d4 100755 --- a/tmake/lib/irix-dcc/tmake.conf +++ b/tmake/lib/irix-dcc/tmake.conf @@ -43,7 +43,7 @@ TMAKE_LFLAGS_SHLIB = -shared TMAKE_LFLAGS_SONAME = -Wl,-soname, TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu diff --git a/tmake/lib/irix-g++/tmake.conf b/tmake/lib/irix-g++/tmake.conf index f6fea61..3ac1c54 100755 --- a/tmake/lib/irix-g++/tmake.conf +++ b/tmake/lib/irix-g++/tmake.conf @@ -11,7 +11,7 @@ TMAKE_CC = gcc TMAKE_CFLAGS = TMAKE_CFLAGS_WARN_ON = -Wall -W TMAKE_CFLAGS_WARN_OFF = -TMAKE_CFLAGS_RELEASE = -O2 -fno-strength-reduce +TMAKE_CFLAGS_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_SHLIB = -fPIC TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses @@ -43,7 +43,7 @@ TMAKE_LFLAGS_SHLIB = -shared TMAKE_LFLAGS_SONAME = -Wl,-soname, TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu diff --git a/tmake/lib/irix-n32/tmake.conf b/tmake/lib/irix-n32/tmake.conf index 52a6a38..6ca03bb 100755 --- a/tmake/lib/irix-n32/tmake.conf +++ b/tmake/lib/irix-n32/tmake.conf @@ -7,17 +7,17 @@ TEMPLATE = app CONFIG = qt warn_on release -TMAKE_CC = CC -TMAKE_CFLAGS = -n32 LANG:bool=ON -woff 1209,1233,1314,1355,1375,1506 +TMAKE_CC = cc +TMAKE_CFLAGS = -n32 -mips3 LANG:bool=ON -woff 1209,1233,1314,1355,1375,1506 TMAKE_CFLAGS_WARN_ON = -fullwarn -TMAKE_CFLAGS_WARN_OFF = +TMAKE_CFLAGS_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 = -n32 -mips3 LANG:bool=ON -woff 1209,1233,1314,1355,1375,1506 TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE @@ -43,7 +43,7 @@ TMAKE_LFLAGS_SHLIB = -shared TMAKE_LFLAGS_SONAME = -Wl,-soname, TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu @@ -53,7 +53,7 @@ TMAKE_MOC = moc TMAKE_AR = ar cq TMAKE_RANLIB = -TMAKE_CLEAN = so_locations +TMAKE_CLEAN = -r so_locations ii_files TMAKE_TAR = tar -cf TMAKE_GZIP = gzip -9f diff --git a/tmake/lib/irix-o32/app.t b/tmake/lib/irix-o32/app.t new file mode 100755 index 0000000..867725e --- /dev/null +++ b/tmake/lib/irix-o32/app.t @@ -0,0 +1,2 @@ +#! Use the common Unix template +#$ IncludeTemplate("../unix/app.t"); diff --git a/tmake/lib/irix-o32/lib.t b/tmake/lib/irix-o32/lib.t new file mode 100755 index 0000000..2523b2f --- /dev/null +++ b/tmake/lib/irix-o32/lib.t @@ -0,0 +1,2 @@ +#! Use the common Unix template +#$ IncludeTemplate("../unix/lib.t"); diff --git a/tmake/lib/irix-o32/subdirs.t b/tmake/lib/irix-o32/subdirs.t new file mode 100755 index 0000000..5e888af --- /dev/null +++ b/tmake/lib/irix-o32/subdirs.t @@ -0,0 +1,2 @@ +#! Use the common Unix template +#$ IncludeTemplate("../unix/subdirs.t"); diff --git a/tmake/lib/irix-o32/tmake.conf b/tmake/lib/irix-o32/tmake.conf new file mode 100755 index 0000000..66da8ef --- /dev/null +++ b/tmake/lib/irix-o32/tmake.conf @@ -0,0 +1,59 @@ +# +# $Id$ +# +# tmake configuration for irix-o32 +# + +TEMPLATE = app +CONFIG = qt warn_on release + +TMAKE_CC = cc +TMAKE_CFLAGS = -32 LANG:bool=ON -woff 1209,1233,1314,1355,1375,1506 +TMAKE_CFLAGS_WARN_ON = -fullwarn +TMAKE_CFLAGS_WARN_OFF = +TMAKE_CFLAGS_RELEASE = -O2 -OPT:Olimit=3000 +TMAKE_CFLAGS_DEBUG = -g +TMAKE_CFLAGS_SHLIB = +TMAKE_CFLAGS_YACC = -woff 1110,1174,3262 + +TMAKE_CXX = CC +TMAKE_CXXFLAGS = -32 LANG:bool=ON -woff 1209,1233,1314,1355,1375,1506 +TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON +TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF +TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE +TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG +TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB +TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC + +TMAKE_INCDIR = +TMAKE_LIBDIR = +TMAKE_INCDIR_X11 = +TMAKE_LIBDIR_X11 = +TMAKE_INCDIR_QT = $(QTDIR)/include +TMAKE_LIBDIR_QT = $(QTDIR)/lib +TMAKE_INCDIR_OPENGL = +TMAKE_LIBDIR_OPENGL = + +TMAKE_LINK = CC +TMAKE_LINK_SHLIB = CC +TMAKE_LFLAGS = -32 +TMAKE_LFLAGS_RELEASE = +TMAKE_LFLAGS_DEBUG = +TMAKE_LFLAGS_SHLIB = -shared +TMAKE_LFLAGS_SONAME = -Wl,-soname, + +TMAKE_LIBS = +TMAKE_LIBS_X11 = -lXext -lX11 -lm +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu + +TMAKE_MOC = moc + +TMAKE_AR = ar cq +TMAKE_RANLIB = + +TMAKE_CLEAN = -r so_locations ii_files + +TMAKE_TAR = tar -cf +TMAKE_GZIP = gzip -9f diff --git a/tmake/lib/linux-g++/tmake.conf b/tmake/lib/linux-g++/tmake.conf index 01b0d82..bbef2ec 100755 --- a/tmake/lib/linux-g++/tmake.conf +++ b/tmake/lib/linux-g++/tmake.conf @@ -11,7 +11,7 @@ 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_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_SHLIB = -fPIC TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses @@ -43,10 +43,11 @@ TMAKE_LFLAGS_SHLIB = -shared TMAKE_LFLAGS_SONAME = -Wl,-soname, TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm +TMAKE_LIBS_X11SM = -lICE -lSM TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl -TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu TMAKE_MOC = moc diff --git a/tmake/lib/netbsd-g++/tmake.conf b/tmake/lib/netbsd-g++/tmake.conf index 53bbadc..693cb9b 100755 --- a/tmake/lib/netbsd-g++/tmake.conf +++ b/tmake/lib/netbsd-g++/tmake.conf @@ -11,7 +11,7 @@ TMAKE_CC = gcc TMAKE_CFLAGS = TMAKE_CFLAGS_WARN_ON = -Wall -W TMAKE_CFLAGS_WARN_OFF = -TMAKE_CFLAGS_RELEASE = -O2 -fno-strength-reduce +TMAKE_CFLAGS_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_SHLIB = -fPIC TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses @@ -46,10 +46,10 @@ TMAKE_LFLAGS_SHLIB = -Bshareable TMAKE_LFLAGS_SONAME = TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl -TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu TMAKE_MOC = moc diff --git a/tmake/lib/openbsd-g++/tmake.conf b/tmake/lib/openbsd-g++/tmake.conf index e45b6d7..fde8505 100755 --- a/tmake/lib/openbsd-g++/tmake.conf +++ b/tmake/lib/openbsd-g++/tmake.conf @@ -11,7 +11,7 @@ TMAKE_CC = gcc TMAKE_CFLAGS = TMAKE_CFLAGS_WARN_ON = -Wall -W TMAKE_CFLAGS_WARN_OFF = -TMAKE_CFLAGS_RELEASE = -O2 -fno-strength-reduce +TMAKE_CFLAGS_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_SHLIB = -fPIC TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses @@ -46,10 +46,10 @@ TMAKE_LFLAGS_SHLIB = -Bshareable TMAKE_LFLAGS_SONAME = TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl -TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu TMAKE_MOC = moc diff --git a/tmake/lib/osf1-cxx/tmake.conf b/tmake/lib/osf1-cxx/tmake.conf index 7e4200e..53f5be8 100755 --- a/tmake/lib/osf1-cxx/tmake.conf +++ b/tmake/lib/osf1-cxx/tmake.conf @@ -9,11 +9,11 @@ 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_ON = TMAKE_CFLAGS_WARN_OFF = TMAKE_CFLAGS_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g -TMAKE_CFLAGS_SHLIB = +TMAKE_CFLAGS_SHLIB = TMAKE_CFLAGS_YACC = -Olimit 1000 TMAKE_CXX = cxx @@ -40,13 +40,15 @@ TMAKE_LFLAGS = TMAKE_LFLAGS_RELEASE = TMAKE_LFLAGS_DEBUG = TMAKE_LFLAGS_SHLIB = -shared -TMAKE_LFLAGS_SONAME = +TMAKE_LFLAGS_SONAME = < suggests avoiding $LD_LIBRARY_PATH: +TMAKE_LINK_SHLIB = CC -R$(QTDIR)/lib:/usr/openwin/lib +TMAKE_LFLAGS = +TMAKE_LFLAGS_RELEASE = +TMAKE_LFLAGS_DEBUG = +TMAKE_LFLAGS_SHLIB = -G -h $(TARGET1) +TMAKE_LFLAGS_SONAME = + +TMAKE_LIBS = -lC +TMAKE_LIBS_X11 = -lXext -lX11 -lm +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu + +TMAKE_MOC = moc + +TMAKE_AR = CC -xar -o +TMAKE_RANLIB = + +TMAKE_CLEAN = -r Templates.DB + +TMAKE_TAR = tar -cf +TMAKE_GZIP = gzip -9f diff --git a/tmake/lib/solaris-cc/tmake.conf b/tmake/lib/solaris-cc/tmake.conf index dd8801b..7f82383 100755 --- a/tmake/lib/solaris-cc/tmake.conf +++ b/tmake/lib/solaris-cc/tmake.conf @@ -8,21 +8,21 @@ TEMPLATE = app CONFIG = qt warn_on release TMAKE_CC = cc -TMAKE_CFLAGS = -pto +TMAKE_CFLAGS = TMAKE_CFLAGS_WARN_ON = TMAKE_CFLAGS_WARN_OFF = -w -TMAKE_CFLAGS_RELEASE = -O2 +TMAKE_CFLAGS_RELEASE = -O TMAKE_CFLAGS_DEBUG = -g -TMAKE_CFLAGS_SHLIB = -PIC +TMAKE_CFLAGS_SHLIB = -KPIC TMAKE_CFLAGS_YACC = TMAKE_CXX = CC TMAKE_CXXFLAGS = $$TMAKE_CFLAGS TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF -TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE +TMAKE_CXXFLAGS_RELEASE = -O2 TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG -TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB +TMAKE_CXXFLAGS_SHLIB = -PIC TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC TMAKE_INCDIR = @@ -40,11 +40,11 @@ TMAKE_LINK_SHLIB = CC -R$(QTDIR)/lib:/usr/openwin/lib TMAKE_LFLAGS = TMAKE_LFLAGS_RELEASE = TMAKE_LFLAGS_DEBUG = -TMAKE_LFLAGS_SHLIB = -G +TMAKE_LFLAGS_SHLIB = -G -h $(TARGET1) TMAKE_LFLAGS_SONAME = -TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS = -lC +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu diff --git a/tmake/lib/solaris-g++/tmake.conf b/tmake/lib/solaris-g++/tmake.conf index c23c9b4..c4c4104 100755 --- a/tmake/lib/solaris-g++/tmake.conf +++ b/tmake/lib/solaris-g++/tmake.conf @@ -11,7 +11,7 @@ TMAKE_CC = gcc TMAKE_CFLAGS = TMAKE_CFLAGS_WARN_ON = -Wall -W TMAKE_CFLAGS_WARN_OFF = -TMAKE_CFLAGS_RELEASE = -O2 -fno-strength-reduce +TMAKE_CFLAGS_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_SHLIB = -fPIC TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses @@ -39,11 +39,12 @@ 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_SHAPP = -shared +TMAKE_LFLAGS_SHLIB = -shared -h $(TARGET1) TMAKE_LFLAGS_SONAME = TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu diff --git a/tmake/lib/sunos-g++/tmake.conf b/tmake/lib/sunos-g++/tmake.conf index 43115f8..1952f48 100755 --- a/tmake/lib/sunos-g++/tmake.conf +++ b/tmake/lib/sunos-g++/tmake.conf @@ -11,7 +11,7 @@ TMAKE_CC = gcc TMAKE_CFLAGS = TMAKE_CFLAGS_WARN_ON = -Wall -W TMAKE_CFLAGS_WARN_OFF = -TMAKE_CFLAGS_RELEASE = -O2 -fno-strength-reduce +TMAKE_CFLAGS_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_SHLIB = -fPIC TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses @@ -43,7 +43,7 @@ TMAKE_LFLAGS_SHLIB = -fPIC -shared TMAKE_LFLAGS_SONAME = TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl TMAKE_LIBS_OPENGL = -lGL -lGLU -lXmu diff --git a/tmake/lib/ultrix-g++/tmake.conf b/tmake/lib/ultrix-g++/tmake.conf index 59147d7..51b4962 100755 --- a/tmake/lib/ultrix-g++/tmake.conf +++ b/tmake/lib/ultrix-g++/tmake.conf @@ -11,7 +11,7 @@ TMAKE_CC = gcc TMAKE_CFLAGS = TMAKE_CFLAGS_WARN_ON = -Wall -W TMAKE_CFLAGS_WARN_OFF = -TMAKE_CFLAGS_RELEASE = -O2 -fno-strength-reduce +TMAKE_CFLAGS_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_SHLIB = TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses @@ -43,10 +43,10 @@ TMAKE_LFLAGS_DEBUG = #TMAKE_LFLAGS_SONAME = -Wl,-soname, TMAKE_LIBS = -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS_X11 = -lXext -lX11 -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl -TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXext -lm +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu TMAKE_MOC = moc diff --git a/tmake/lib/unix/generic.t b/tmake/lib/unix/generic.t index d9dc6ea..88b731a 100755 --- a/tmake/lib/unix/generic.t +++ b/tmake/lib/unix/generic.t @@ -34,8 +34,11 @@ Project('CONFIG *= x11inc'); } if ( Config("qt") ) { - $moc_aware = 1; + Project('CONFIG *= moc'); AddIncludePath(Project("TMAKE_INCDIR_QT")); + if ( Config("release") ) { + Project('DEFINES += NO_DEBUG'); + } if ( Config("opengl") ) { Project("TMAKE_LIBDIR_QT") && Project('TMAKE_LIBS *= -L$$TMAKE_LIBDIR_QT'); @@ -61,6 +64,9 @@ Project('TMAKE_LIBS *= -L$$TMAKE_LIBDIR_X11'); Project('TMAKE_LIBS *= $$TMAKE_LIBS_X11'); } + if ( Config("moc") ) { + $moc_aware = 1; + } Project('TMAKE_LIBS += $$LIBS'); if ( !Project("TMAKE_RUN_CC") ) { Project('TMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src'); @@ -76,7 +82,6 @@ } 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+$//; @@ -86,6 +91,8 @@ if ( Project("TMAKE_APP_FLAG") ) { if ( Config("dll") ) { Project('TARGET = $$TARGET.so'); + Project("TMAKE_LFLAGS_SHAPP") || + ($project{"TMAKE_LFLAGS_SHAPP"} = $project{"TMAKE_LFLAGS_SHLIB"}); Project("TMAKE_LFLAGS_SONAME") && ($project{"TMAKE_LFLAGS_SONAME"} .= $project{"TARGET"}); } @@ -127,7 +134,11 @@ if ( Config("dll") ) { Project('TMAKE_CFLAGS *= $$TMAKE_CFLAGS_SHLIB' ); Project('TMAKE_CXXFLAGS *= $$TMAKE_CXXFLAGS_SHLIB' ); - Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_SHLIB $$TMAKE_LFLAGS_SONAME'); + if ( Project("TMAKE_APP_FLAG") ) { + Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_SHAPP'); + } else { + Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_SHLIB $$TMAKE_LFLAGS_SONAME'); + } } #$} #! @@ -143,7 +154,7 @@ 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",""); +INCPATH = #$ ExpandPath("INCPATH","-I"," -I",""); #$ Config("staticlib") && DisableOutput(); LINK = #$ Expand("TMAKE_LINK"); LFLAGS = #$ Expand("TMAKE_LFLAGS"); diff --git a/tmake/lib/unix/subdirs.t b/tmake/lib/unix/subdirs.t index 8f20097..e2b58a7 100755 --- a/tmake/lib/unix/subdirs.t +++ b/tmake/lib/unix/subdirs.t @@ -25,7 +25,9 @@ all: $(SUBDIRS) $(SUBDIRS): FORCE cd $@; $(MAKE) -tmake: +#$ TmakeSelf(); + +tmake_all: #${ $text = "\t" . 'for i in $(SUBDIRS); do ( cd $$i ; $(TMAKE) $$i.pro -o $(MAKEFILE); grep "TEMPLATE.*subdirs" $$i.pro 2>/dev/null >/dev/null && $(MAKE) -f $(MAKEFILE) tmake ) ; done'; #$} diff --git a/tmake/lib/unixware-g++/tmake.conf b/tmake/lib/unixware-g++/tmake.conf index 24300a9..c01a359 100755 --- a/tmake/lib/unixware-g++/tmake.conf +++ b/tmake/lib/unixware-g++/tmake.conf @@ -3,6 +3,8 @@ # # tmake configuration for sco-g++ # +# incl. UnixWare 7 +# TEMPLATE = app CONFIG = qt warn_on release @@ -11,7 +13,7 @@ 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_RELEASE = -O2 TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_SHLIB = -fPIC TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses @@ -42,11 +44,11 @@ TMAKE_LFLAGS_DEBUG = TMAKE_LFLAGS_SHLIB = -shared TMAKE_LFLAGS_SONAME = -TMAKE_LIBS = -lsocket -lnsl -lc -TMAKE_LIBS_X11 = -lX11 -lXext +TMAKE_LIBS = -lc +TMAKE_LIBS_X11 = -lXext -lX11 -lsocket -lnsl -lm TMAKE_LIBS_QT = -lqt TMAKE_LIBS_QT_OPENGL = -lqgl -TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXt -lXext -lm +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXt TMAKE_MOC = moc diff --git a/tmake/lib/unixware7-cc/app.t b/tmake/lib/unixware7-cc/app.t new file mode 100755 index 0000000..867725e --- /dev/null +++ b/tmake/lib/unixware7-cc/app.t @@ -0,0 +1,2 @@ +#! Use the common Unix template +#$ IncludeTemplate("../unix/app.t"); diff --git a/tmake/lib/unixware7-cc/lib.t b/tmake/lib/unixware7-cc/lib.t new file mode 100755 index 0000000..2523b2f --- /dev/null +++ b/tmake/lib/unixware7-cc/lib.t @@ -0,0 +1,2 @@ +#! Use the common Unix template +#$ IncludeTemplate("../unix/lib.t"); diff --git a/tmake/lib/unixware7-cc/subdirs.t b/tmake/lib/unixware7-cc/subdirs.t new file mode 100755 index 0000000..5e888af --- /dev/null +++ b/tmake/lib/unixware7-cc/subdirs.t @@ -0,0 +1,2 @@ +#! Use the common Unix template +#$ IncludeTemplate("../unix/subdirs.t"); diff --git a/tmake/lib/unixware7-cc/tmake.conf b/tmake/lib/unixware7-cc/tmake.conf new file mode 100755 index 0000000..af04187 --- /dev/null +++ b/tmake/lib/unixware7-cc/tmake.conf @@ -0,0 +1,59 @@ +# +# $Id$ +# +# tmake configuration for sco-g++ +# +# (UnixWare file, with different -D) +# + +TEMPLATE = app +CONFIG = qt warn_on release + +TMAKE_CC = cc +TMAKE_CFLAGS = +TMAKE_CFLAGS_WARN_ON = -Wall -W +TMAKE_CFLAGS_WARN_OFF = +TMAKE_CFLAGS_RELEASE = -O -T used +TMAKE_CFLAGS_DEBUG = -g +TMAKE_CFLAGS_SHLIB = -K PIC +TMAKE_CFLAGS_YACC = + +TMAKE_CXX = CC +TMAKE_CXXFLAGS = $$TMAKE_CFLAGS +TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON +TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF +TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE +TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG +TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB +TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC + +TMAKE_INCDIR = +TMAKE_LIBDIR = +TMAKE_INCDIR_X11 = +TMAKE_LIBDIR_X11 = /usr/X/lib +TMAKE_INCDIR_QT = $(QTDIR)/include +TMAKE_LIBDIR_QT = $(QTDIR)/lib +TMAKE_INCDIR_OPENGL = +TMAKE_LIBDIR_OPENGL = + +TMAKE_LINK = CC +TMAKE_LINK_SHLIB = CC +TMAKE_LFLAGS = +TMAKE_LFLAGS_RELEASE = +TMAKE_LFLAGS_DEBUG = +TMAKE_LFLAGS_SHLIB = -G +TMAKE_LFLAGS_SONAME = + +TMAKE_LIBS = +TMAKE_LIBS_X11 = -lXext -lX11 -lsocket -lnsl -lm +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXt + +TMAKE_MOC = moc + +TMAKE_AR = ar cq +TMAKE_RANLIB = + +TMAKE_TAR = tar -cf +TMAKE_GZIP = gzip -9f diff --git a/tmake/lib/unixware7-g++/app.t b/tmake/lib/unixware7-g++/app.t new file mode 100755 index 0000000..867725e --- /dev/null +++ b/tmake/lib/unixware7-g++/app.t @@ -0,0 +1,2 @@ +#! Use the common Unix template +#$ IncludeTemplate("../unix/app.t"); diff --git a/tmake/lib/unixware7-g++/lib.t b/tmake/lib/unixware7-g++/lib.t new file mode 100755 index 0000000..2523b2f --- /dev/null +++ b/tmake/lib/unixware7-g++/lib.t @@ -0,0 +1,2 @@ +#! Use the common Unix template +#$ IncludeTemplate("../unix/lib.t"); diff --git a/tmake/lib/unixware7-g++/subdirs.t b/tmake/lib/unixware7-g++/subdirs.t new file mode 100755 index 0000000..5e888af --- /dev/null +++ b/tmake/lib/unixware7-g++/subdirs.t @@ -0,0 +1,2 @@ +#! Use the common Unix template +#$ IncludeTemplate("../unix/subdirs.t"); diff --git a/tmake/lib/unixware7-g++/tmake.conf b/tmake/lib/unixware7-g++/tmake.conf new file mode 100755 index 0000000..3f35784 --- /dev/null +++ b/tmake/lib/unixware7-g++/tmake.conf @@ -0,0 +1,59 @@ +# +# $Id$ +# +# tmake configuration for sco-g++ +# +# (UnixWare file, with different -D) +# + +TEMPLATE = app +CONFIG = qt warn_on release + +TMAKE_CC = gcc +TMAKE_CFLAGS = -D_UNIXWARE7 +TMAKE_CFLAGS_WARN_ON = -Wall -W +TMAKE_CFLAGS_WARN_OFF = +TMAKE_CFLAGS_RELEASE = -O2 +TMAKE_CFLAGS_DEBUG = -g +TMAKE_CFLAGS_SHLIB = -fPIC +TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses + +TMAKE_CXX = g++ +TMAKE_CXXFLAGS = $$TMAKE_CFLAGS +TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON +TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF +TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE +TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG +TMAKE_CXXFLAGS_SHLIB = $$TMAKE_CFLAGS_SHLIB +TMAKE_CXXFLAGS_YACC = $$TMAKE_CFLAGS_YACC + +TMAKE_INCDIR = +TMAKE_LIBDIR = +TMAKE_INCDIR_X11 = +TMAKE_LIBDIR_X11 = /usr/X/lib +TMAKE_INCDIR_QT = $(QTDIR)/include +TMAKE_LIBDIR_QT = $(QTDIR)/lib +TMAKE_INCDIR_OPENGL = +TMAKE_LIBDIR_OPENGL = + +TMAKE_LINK = g++ +TMAKE_LINK_SHLIB = g++ +TMAKE_LFLAGS = +TMAKE_LFLAGS_RELEASE = +TMAKE_LFLAGS_DEBUG = +TMAKE_LFLAGS_SHLIB = -shared +TMAKE_LFLAGS_SONAME = + +TMAKE_LIBS = -lc +TMAKE_LIBS_X11 = -lXext -lX11 -lsocket -lnsl -lm +TMAKE_LIBS_QT = -lqt +TMAKE_LIBS_QT_OPENGL = -lqgl +TMAKE_LIBS_OPENGL = -lMesaGL -lMesaGLU -lXmu -lXt + +TMAKE_MOC = moc + +TMAKE_AR = ar cq +TMAKE_RANLIB = + +TMAKE_TAR = tar -cf +TMAKE_GZIP = gzip -9f diff --git a/tmake/lib/win32-borland/generic.t b/tmake/lib/win32-borland/generic.t index 88190d8..0cf8711 100755 --- a/tmake/lib/win32-borland/generic.t +++ b/tmake/lib/win32-borland/generic.t @@ -38,8 +38,11 @@ Project('CONFIG += windows' ); } if ( Config("qt") ) { - $moc_aware = 1; + Project('CONFIG *= moc'); AddIncludePath(Project("TMAKE_INCDIR_QT")); + if ( Config("release") ) { + Project('DEFINES += NO_DEBUG'); + } if ( Config("opengl") ) { Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_OPENGL'); } @@ -47,6 +50,7 @@ if ( Project("TMAKE_QT_DLL") ) { Project('DEFINES -= QT_DLL'); Project('DEFINES *= QT_MAKEDLL'); + Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_QT_DLL'); } } else { if ( Project("TMAKE_QT_DLL") ) { @@ -56,7 +60,9 @@ 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("dll") ) { + Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL'); + } } } } @@ -94,6 +100,9 @@ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY'); Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE'); } + if ( Config("moc") ) { + $moc_aware = 1; + } Project('TMAKE_LIBS += $$LIBS'); Project('TMAKE_FILETAGS = HEADERS SOURCES DEF_FILE RC_FILE TARGET TMAKE_LIBS DESTDIR DLLDESTDIR $$FILETAGS'); foreach ( split(/\s/,Project("TMAKE_FILETAGS")) ) { @@ -115,7 +124,6 @@ Project('TMAKE_LIBS *= $$RES_FILE'); } StdInit(); - $project{"DESTDIR"} = FixPath($project{"DESTDIR"}); if ( Project("VERSION") ) { $project{"VER_MAJ"} = $project{"VERSION"}; $project{"VER_MAJ"} =~ s/\.\d+$//; @@ -141,7 +149,7 @@ 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"','"'); +INCPATH = #$ ExpandPath("INCPATH",'-I',' -I',''); #$ !Project("TMAKE_APP_OR_DLL") && DisableOutput(); LINK = #$ Expand("TMAKE_LINK"); LFLAGS = #$ Expand("TMAKE_LFLAGS"); diff --git a/tmake/lib/win32-borland/subdirs.t b/tmake/lib/win32-borland/subdirs.t index 8e70c0e..f08e41f 100755 --- a/tmake/lib/win32-borland/subdirs.t +++ b/tmake/lib/win32-borland/subdirs.t @@ -1,33 +1,3 @@ -############################################################################# -#! -#! 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; +#! Use the common Win32 template +#$ Project("TMAKE_NOFORCE = 1"); +#$ IncludeTemplate("../win32/subdirs.t"); diff --git a/tmake/lib/win32-borland/tmake.conf b/tmake/lib/win32-borland/tmake.conf index 4dd3636..0f41370 100755 --- a/tmake/lib/win32-borland/tmake.conf +++ b/tmake/lib/win32-borland/tmake.conf @@ -51,6 +51,6 @@ TMAKE_LIBS_OPENGL = TMAKE_MOC = moc TMAKE_LIB = tlib /C /P256 -TMAKE_RC = rc +TMAKE_RC = brc32 TMAKE_ZIP = zip -r -9 diff --git a/tmake/lib/win32-g++/generic.t b/tmake/lib/win32-g++/generic.t index 253c401..060d5c3 100755 --- a/tmake/lib/win32-g++/generic.t +++ b/tmake/lib/win32-g++/generic.t @@ -3,9 +3,11 @@ #! #${ if ( Config("qt") ) { - if ( $ENV{"QT_DLL"} && !$ENV{"QT_NODLL"} ) { + 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" ) { + if ( (Project("TARGET") eq "qt") && Project("TMAKE_LIB_FLAG") ) { Project('CONFIG += dll'); } } @@ -18,38 +20,49 @@ } 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')); + Project('CONFIG *= moc'); + AddIncludePath(Project("TMAKE_INCDIR_QT")); + if ( Config("release") ) { + Project('DEFINES += NO_DEBUG'); + } if ( Config("opengl") ) { Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_OPENGL'); } - if ( Project("TARGET") eq "qt" ) { - if ( Project("TMAKE_QT_DLL") && !(Project("DEFINES") =~ /QT_NODLL/) ) { + if ( (Project("TARGET") eq "qt") && Project("TMAKE_LIB_FLAG") ) { + if ( Project("TMAKE_QT_DLL") ) { + Project('DEFINES -= QT_DLL'); Project('DEFINES *= QT_MAKEDLL'); + Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_QT_DLL'); } } else { - if ( Project("TMAKE_QT_DLL") && !(Project("DEFINES") =~ /QT_NODLL/) ) { + if ( Project("TMAKE_QT_DLL") ) { Project('DEFINES *= QT_DLL'); } Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT'); - if ( (Project("DEFINES") =~ /QT_DLL/) ) { + 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("dll") ) { + Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL'); + } } } } @@ -69,10 +82,10 @@ } else { Project('TMAKE_LFLAGS_CONSOLE_ANY = $$TMAKE_LFLAGS_CONSOLE'); Project('TMAKE_LFLAGS_WINDOWS_ANY = $$TMAKE_LFLAGS_WINDOWS'); - if ( Project('TMAKE_APP_FLAG') ) { + if ( Project("TMAKE_APP_FLAG") ) { $project{"TARGET_EXT"} = ".exe"; } else { - $project{"TARGET_EXT"} = ".a"; + $project{"TARGET_EXT"} = ".lib"; } } if ( Config("windows") ) { @@ -87,26 +100,19 @@ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY'); Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE'); } + if ( Config("moc") ) { + $moc_aware = 1; + } Project('TMAKE_LIBS += $$LIBS'); Project('TMAKE_FILETAGS = HEADERS SOURCES DEF_FILE RC_FILE TARGET TMAKE_LIBS DESTDIR DLLDESTDIR $$FILETAGS'); - foreach ( split(/\s/,Project('TMAKE_FILETAGS')) ) { + 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') ) { + if ( Project("DEF_FILE") ) { Project('TMAKE_LFLAGS *= $$DEF_FILE'); } - if ( Project('RC_FILE') ) { - if ( Project('RES_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."); } @@ -114,11 +120,20 @@ $project{"RES_FILE"} =~ s/\.rc$/.res/i; Project('TARGETDEPS += $$RES_FILE'); } - if ( Project('RES_FILE') ) { - Project('TMAKE_LFLAGS *= $$RES_FILE'); + if ( Project("RES_FILE") ) { + Project('TMAKE_LIBS *= $$RES_FILE'); + } + $obj_ext = "o"; + $dir_sep = "/"; + $gnuwin32 = 1; + if ( Config("qt") ) { + $qtdir = $ENV{"QTDIR"}; + $project{"INCPATH"} =~ s/\$\(QTDIR\)/$qtdir/; + $project{"INCPATH"} =~ s/\\/\//g; + $project{"TMAKE_LIBS"} =~ s/\$\(QTDIR\)/$qtdir/; + $project{"TMAKE_LIBS"} =~ s/\\/\//g; } StdInit(); - $project{"DESTDIR"} = FixPath($project{"DESTDIR"}); if ( Project("VERSION") ) { $project{"VER_MAJ"} = $project{"VERSION"}; $project{"VER_MAJ"} =~ s/\.\d+$//; @@ -143,8 +158,10 @@ ####### Compiler, tools and options CC = #$ Expand("TMAKE_CC"); +CXX = #$ Expand("TMAKE_CXX"); CFLAGS = #$ Expand("TMAKE_CFLAGS"); ExpandGlue("DEFINES","-D"," -D",""); -INCPATH = #$ ExpandGlue("INCPATH","-I"," -I",""); +CXXFLAGS= #$ Expand("TMAKE_CXXFLAGS"); ExpandGlue("DEFINES","-D"," -D",""); +INCPATH = #$ ExpandPath("INCPATH",'-I',' -I',''); #$ !Project("TMAKE_APP_OR_DLL") && DisableOutput(); LINK = #$ Expand("TMAKE_LINK"); LFLAGS = #$ Expand("TMAKE_LFLAGS"); @@ -173,16 +190,16 @@ TARGET = #$ ExpandGlue("TARGET",$project{"DESTDIR"},"",$project{"TARGET_EXT"}); .SUFFIXES: .cpp .cxx .cc .c .cpp.o: - #$ Expand("TMAKE_COMPILE_IMP"); + #$ Expand("TMAKE_RUN_CXX_IMP"); .cxx.o: - #$ Expand("TMAKE_COMPILE_IMP"); + #$ Expand("TMAKE_RUN_CXX_IMP"); .cc.o: - #$ Expand("TMAKE_COMPILE_IMP"); + #$ Expand("TMAKE_RUN_CXX_IMP"); .c.o: - #$ Expand("TMAKE_COMPILE_IMP"); + #$ Expand("TMAKE_RUN_CC_IMP"); ####### Build rules diff --git a/tmake/lib/win32-g++/tmake.conf b/tmake/lib/win32-g++/tmake.conf index 59667bd..2e8b316 100755 --- a/tmake/lib/win32-g++/tmake.conf +++ b/tmake/lib/win32-g++/tmake.conf @@ -7,7 +7,7 @@ TEMPLATE = app CONFIG = qt warn_on release -TMAKE_CC = g++ +TMAKE_CC = gcc TMAKE_CFLAGS = TMAKE_CFLAGS_WARN_ON = TMAKE_CFLAGS_WARN_OFF = @@ -15,7 +15,7 @@ TMAKE_CFLAGS_RELEASE = -O TMAKE_CFLAGS_DEBUG = -g TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses -TMAKE_CXX = $$TMAKE_CC +TMAKE_CXX = g++ TMAKE_CXXFLAGS = $$TMAKE_CFLAGS TMAKE_CXXFLAGS_WARN_ON = $$TMAKE_CFLAGS_WARN_ON TMAKE_CXXFLAGS_WARN_OFF = $$TMAKE_CFLAGS_WARN_OFF @@ -42,7 +42,7 @@ TMAKE_LFLAGS_WINDOWS_DLL= -Wl,-subsystem,windows TMAKE_LIBS = TMAKE_LIBS_CONSOLE = -TMAKE_LIBS_WINDOWS = -luser32 -lgdi32 -lcomdlg32 -lole32 -luuid -lwsock32 +TMAKE_LIBS_WINDOWS = -luser32 -lgdi32 -lcomdlg32 -limm32 -lole32 -luuid -lwsock32 TMAKE_LIBS_QT = -L$(QTDIR)/lib -lqt TMAKE_LIBS_QT_DLL = -lqtmain TMAKE_LIBS_QT_OPENGL = -lqgl diff --git a/tmake/lib/win32-msvc/generic.t b/tmake/lib/win32-msvc/generic.t index e57180d..388db4b 100755 --- a/tmake/lib/win32-msvc/generic.t +++ b/tmake/lib/win32-msvc/generic.t @@ -38,8 +38,11 @@ Project('CONFIG += windows' ); } if ( Config("qt") ) { - $moc_aware = 1; + Project('CONFIG *= moc'); AddIncludePath(Project("TMAKE_INCDIR_QT")); + if ( Config("release") ) { + Project('DEFINES += NO_DEBUG'); + } if ( Config("opengl") ) { Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_OPENGL'); } @@ -47,6 +50,7 @@ if ( Project("TMAKE_QT_DLL") ) { Project('DEFINES -= QT_DLL'); Project('DEFINES *= QT_MAKEDLL'); + Project('TMAKE_LFLAGS += $$TMAKE_LFLAGS_QT_DLL'); } } else { if ( Project("TMAKE_QT_DLL") ) { @@ -56,7 +60,9 @@ 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("dll") ) { + Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL'); + } } } } @@ -94,6 +100,9 @@ Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_CONSOLE_ANY'); Project('TMAKE_LIBS *= $$TMAKE_LIBS_CONSOLE'); } + if ( Config("moc") ) { + $moc_aware = 1; + } Project('TMAKE_LIBS += $$LIBS'); Project('TMAKE_FILETAGS = HEADERS SOURCES DEF_FILE RC_FILE TARGET TMAKE_LIBS DESTDIR DLLDESTDIR $$FILETAGS'); foreach ( split(/\s/,Project("TMAKE_FILETAGS")) ) { @@ -115,7 +124,6 @@ Project('TMAKE_LIBS *= $$RES_FILE'); } StdInit(); - $project{"DESTDIR"} = FixPath($project{"DESTDIR"}); if ( Project("VERSION") ) { $project{"VER_MAJ"} = $project{"VERSION"}; $project{"VER_MAJ"} =~ s/\.\d+$//; @@ -137,7 +145,7 @@ 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"','"'); +INCPATH = #$ ExpandPath("INCPATH",'-I',' -I',''); #$ !Project("TMAKE_APP_OR_DLL") && DisableOutput(); LINK = #$ Expand("TMAKE_LINK"); LFLAGS = #$ Expand("TMAKE_LFLAGS"); diff --git a/tmake/lib/win32-msvc/tmake.conf b/tmake/lib/win32-msvc/tmake.conf index cb64ac9..0f92f29 100755 --- a/tmake/lib/win32-msvc/tmake.conf +++ b/tmake/lib/win32-msvc/tmake.conf @@ -11,7 +11,7 @@ TMAKE_CC = cl TMAKE_CFLAGS = -nologo TMAKE_CFLAGS_WARN_ON = -W3 TMAKE_CFLAGS_WARN_OFF = -W0 -TMAKE_CFLAGS_RELEASE = -O2 +TMAKE_CFLAGS_RELEASE = -O1 TMAKE_CFLAGS_DEBUG = -Zi TMAKE_CFLAGS_MT = -MT TMAKE_CFLAGS_MT_DBG = -MTd @@ -47,10 +47,11 @@ TMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:console TMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:windows TMAKE_LFLAGS_CONSOLE_DLL= /SUBSYSTEM:console /DLL TMAKE_LFLAGS_WINDOWS_DLL= /SUBSYSTEM:windows /DLL +TMAKE_LFLAGS_QT_DLL = /BASE:0x39D00000 TMAKE_LIBS = TMAKE_LIBS_CONSOLE = -TMAKE_LIBS_WINDOWS = user32.lib gdi32.lib comdlg32.lib ole32.lib uuid.lib wsock32.lib +TMAKE_LIBS_WINDOWS = user32.lib gdi32.lib comdlg32.lib imm32.lib ole32.lib uuid.lib wsock32.lib TMAKE_LIBS_QT = $(QTDIR)\lib\qt.lib TMAKE_LIBS_QT_DLL = $(QTDIR)\lib\qtmain.lib TMAKE_LIBS_QT_OPENGL = $(QTDIR)\lib\qgl.lib diff --git a/tmake/lib/win32-msvc/vcapp.t b/tmake/lib/win32-msvc/vcapp.t index 02e15e4..ac7ae23 100755 --- a/tmake/lib/win32-msvc/vcapp.t +++ b/tmake/lib/win32-msvc/vcapp.t @@ -2,6 +2,16 @@ #! This TMAKE template - Microsoft Visual C++ 5.0 applications #! #${ + if ( Config("qt") ) { + if ( !(Project("DEFINES") =~ /QT_NODLL/) && + ((Project("DEFINES") =~ /QT_(?:MAKE)?DLL/) || + ($ENV{"QT_DLL"} && !$ENV{"QT_NODLL"})) ) { + Project('TMAKE_QT_DLL = 1'); + if ( (Project("TARGET") eq "qt") && Project("TMAKE_LIB_FLAG") ) { + Project('CONFIG += dll'); + } + } + } if ( Config("qt") || Config("opengl") ) { Project('CONFIG += windows'); } @@ -11,25 +21,22 @@ if ( Config("opengl") ) { Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_OPENGL'); } + if ( Project("TMAKE_QT_DLL") ) { + Project('DEFINES *= QT_DLL'); + } Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT'); + if ( Project("TMAKE_QT_DLL") ) { + my $qtver =FindHighestLibVersion($ENV{"QTDIR"} . "/lib", "qt"); + Project("TMAKE_LIBS /= s/qt.lib/qt${qtver}.lib/"); + Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL'); + } } if ( Config("opengl") ) { Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL'); } Project('TMAKE_LIBS += $$LIBS'); - if ( Config("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 { + if ( Config("console") ) { $project{"VC_PROJ_TYPE"} = 'Win32 (x86) Console Application'; $project{"VC_PROJ_CODE"} = '0x0103'; $vc_base_libs = 'kernel32.lib user32.lib gdi32.lib winspool.lib ' . @@ -40,6 +47,17 @@ $vc_link_debug = '/nologo /subsystem:console /debug /machine:I386 /pdbtype:sept'; $vc_cpp_def_release = '/D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" '; $vc_cpp_def_debug = '/D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" '; + } else { + $project{"VC_PROJ_TYPE"} = 'Win32 (x86) Application'; + $project{"VC_PROJ_CODE"} = '0x0101'; + $vc_base_libs = 'kernel32.lib user32.lib gdi32.lib winspool.lib ' . + 'comdlg32.lib advapi32.lib shell32.lib ole32.lib ' . + 'oleaut32.lib uuid.lib odbc32.lib odbccp32.lib '; + $vc_libs = $vc_base_libs . 'wsock32.lib '; + $vc_link_release = '/nologo /subsystem:windows /machine:I386'; + $vc_link_debug = '/nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept'; + $vc_cpp_def_release = '/D "NDEBUG" /D "WIN32" /D "_WINDOWS" '; + $vc_cpp_def_debug = '/D "_DEBUG" /D "WIN32" /D "_WINDOWS" '; } $project{"VC_BASE_LINK_RELEASE"} = $vc_base_libs . $vc_link_release; $project{"VC_BASE_LINK_DEBUG"} = $vc_base_libs . $vc_link_debug; @@ -52,7 +70,7 @@ $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 "','"'); + ExpandPath("INCPATH",'/I ',' /I ',''); if ( $text ne "" ) { $vc_inc = $text . " "; $text = ""; } else { $vc_inc = ""; } ExpandGlue("DEFINES",'/D "','" /D "','"'); if ( $text ne "" ) { $vc_def = $text . " "; $text = ""; } else { $vc_def = ""; } diff --git a/tmake/lib/win32-msvc/vclib.t b/tmake/lib/win32-msvc/vclib.t index e56409e..11cd1d7 100755 --- a/tmake/lib/win32-msvc/vclib.t +++ b/tmake/lib/win32-msvc/vclib.t @@ -20,7 +20,7 @@ $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 "','"'); + ExpandPath("INCPATH",'/I ',' /I ',''); if ( $text ne "" ) { $vc_inc = $text . " "; $text = ""; } else { $vc_inc = ""; } ExpandGlue("DEFINES",'/D "','" /D "','"'); if ( $text ne "" ) { $vc_def = $text . " "; $text = ""; } else { $vc_def = ""; } diff --git a/tmake/lib/win32-symantec/generic.t b/tmake/lib/win32-symantec/generic.t index e22d9c1..78e1d77 100755 --- a/tmake/lib/win32-symantec/generic.t +++ b/tmake/lib/win32-symantec/generic.t @@ -108,7 +108,6 @@ Project('TMAKE_LIBS *= $$RES_FILE'); } StdInit(); - $project{"DESTDIR"} = FixPath($project{"DESTDIR"}); if ( Project("VERSION") ) { $project{"VER_MAJ"} = $project{"VERSION"}; $project{"VER_MAJ"} =~ s/\.\d+$//; @@ -127,7 +126,7 @@ CC = #$ Expand("TMAKE_CC"); CFLAGS = #$ Expand("TMAKE_CFLAGS"); ExpandGlue("DEFINES","-D"," -D",""); -INCPATH = #$ ExpandGlue("INCPATH",'-I"','" -I"','"'); +INCPATH = #$ ExpandPath("INCPATH",'-I',' -I',''); #$ !Project("TMAKE_APP_OR_DLL") && DisableOutput(); LINK = #$ Expand("TMAKE_LINK"); LFLAGS = #$ Expand("TMAKE_LFLAGS"); diff --git a/tmake/lib/win32-symantec/tmake.conf b/tmake/lib/win32-symantec/tmake.conf index c2b7e68..02a0a8f 100755 --- a/tmake/lib/win32-symantec/tmake.conf +++ b/tmake/lib/win32-symantec/tmake.conf @@ -42,7 +42,7 @@ 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_WINDOWS = user32.lib gdi32.lib comdlg32.lib imm32.lib ole32.lib uuid.lib wsock32.lib TMAKE_LIBS_QT = $(QTDIR)\lib\qt.lib TMAKE_LIBS_QT_DLL = $(QTDIR)\lib\qtmain.lib TMAKE_LIBS_QT_OPENGL = $(QTDIR)\lib\qgl.lib diff --git a/tmake/lib/win32-visage/generic.t b/tmake/lib/win32-visage/generic.t index fd928ad..aeec8db 100755 --- a/tmake/lib/win32-visage/generic.t +++ b/tmake/lib/win32-visage/generic.t @@ -108,7 +108,6 @@ Project('TMAKE_LIBS *= $$RES_FILE'); } StdInit(); - $project{"DESTDIR"} = FixPath($project{"DESTDIR"}); if ( Project("VERSION") ) { $project{"VER_MAJ"} = $project{"VERSION"}; $project{"VER_MAJ"} =~ s/\.\d+$//; @@ -127,7 +126,7 @@ CC = #$ Expand("TMAKE_CC"); CFLAGS = #$ Expand("TMAKE_CFLAGS"); ExpandGlue("DEFINES","-D"," -D",""); -INCPATH = #$ ExpandGlue("INCPATH",'-I"','" -I"','"'); +INCPATH = #$ ExpandGlue("INCPATH",'-I',' -I',''); #$ !Project("TMAKE_APP_OR_DLL") && DisableOutput(); LINK = #$ Expand("TMAKE_LINK"); LFLAGS = #$ Expand("TMAKE_LFLAGS"); diff --git a/tmake/lib/win32-visage/tmake.conf b/tmake/lib/win32-visage/tmake.conf index 3e20294..c909baf 100755 --- a/tmake/lib/win32-visage/tmake.conf +++ b/tmake/lib/win32-visage/tmake.conf @@ -42,7 +42,7 @@ 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_WINDOWS = user32.lib gdi32.lib comdlg32.lib imm32.lib ole32.lib uuid.lib wsock32.lib TMAKE_LIBS_QT = $(QTDIR)\lib\qt.lib TMAKE_LIBS_QT_DLL = $(QTDIR)\lib\qtmain.lib TMAKE_LIBS_QT_OPENGL = $(QTDIR)\lib\qgl.lib diff --git a/tmake/lib/win32-watcom/generic.t b/tmake/lib/win32-watcom/generic.t index a8c3990..0cc47bb 100755 --- a/tmake/lib/win32-watcom/generic.t +++ b/tmake/lib/win32-watcom/generic.t @@ -109,7 +109,6 @@ } $linebreak = '&'; StdInit(); - $project{"DESTDIR"} = FixPath($project{"DESTDIR"}); if ( Project("VERSION") ) { $project{"VER_MAJ"} = $project{"VERSION"}; $project{"VER_MAJ"} =~ s/\.\d+$//; @@ -131,7 +130,7 @@ QTDIR = #$ $text = $ENV{"QTDIR"}; #$ Config("qt") || EnableOutput(); CC = #$ Expand("TMAKE_CC"); CFLAGS = #$ Expand("TMAKE_CFLAGS"); ExpandGlue("DEFINES","-d="," -d=",""); -INCPATH = #$ ExpandGlue("INCPATH","-i="," -i=",""); +INCPATH = #$ ExpandPath("INCPATH",'-i=',' -i=',''); #$ !Project("TMAKE_APP_OR_DLL") && DisableOutput(); LINK = #$ Expand("TMAKE_LINK"); LFLAGS = #$ Expand("TMAKE_LFLAGS"); diff --git a/tmake/lib/win32/subdirs.t b/tmake/lib/win32/subdirs.t index 57464c6..4c857fd 100755 --- a/tmake/lib/win32/subdirs.t +++ b/tmake/lib/win32/subdirs.t @@ -10,6 +10,8 @@ $m = $m . "\tcd $_\n\tDOMAKE\n\t\@cd ..\n"; } $project{"SUBMAKE"} = $m; + Project('MAKEFILE') || Project('MAKEFILE = Makefile'); + Project('TMAKE') || Project('TMAKE = tmake'); #$} #! # Makefile for building targets in sub directories. @@ -18,18 +20,35 @@ # Template: #$ Expand("TEMPLATE"); ############################################################################# +MAKEFILE= #$ Expand("MAKEFILE"); +TMAKE = #$ Expand("TMAKE"); + SUBDIRS = #$ ExpandList("SUBDIRS"); all: $(SUBDIRS) #${ foreach ( split(/\s+/,$project{"SUBDIRS"}) ) { - $text = $text . $_ . ": FORCE\n\t" . + if ( Project("TMAKE_NOFORCE") ) { + $text = $text . $_ . ":\n\t" . + "cd $_\n\t\$(MAKE\)\n\t\@cd ..\n\n"; + } else { + $text = $text . $_ . ": FORCE\n\t" . "cd $_\n\t\$(MAKE\)\n\t\@cd ..\n\n"; + } + } +#$} +#$ TmakeSelf(); + +tmake_all: +#${ + foreach ( split(/\s+/,$project{"SUBDIRS"}) ) { + $text .= "\tcd $_\n\t\$(TMAKE\) $_.pro -o \$(MAKEFILE)\n\t\@cd ..\n"; } #$} clean: #$ $text = $project{"SUBMAKE"}; $text =~ s/DOMAKE/\$(MAKE\) clean/g; - +#$ Project("TMAKE_NOFORCE") && DisableOutput(); FORCE: +#$ Project("TMAKE_NOFORCE") && EnableOutput(); diff --git a/wintools/make.pl b/wintools/make.pl new file mode 100755 index 0000000..ae1eff3 --- /dev/null +++ b/wintools/make.pl @@ -0,0 +1,25 @@ +# make script used to create a config file for windows + +use Cwd; + +# get current working directory +$pwd=cwd(); + +# create config file +open(FILE,">makeconfig") || die "Cannot create file makeconfig!"; + +print FILE "DOXYGEN = $pwd\n"; +print FILE "TMAKEPATH = $pwd\\tmake\\lib\\win32-msvc\n"; +print FILE "TMAKE = $pwd\\tmake\\bin\\tmake\n"; +print FILE "MAKE = nmake\n"; +print FILE "PERL = perl\n"; +print FILE "RM = del /s /q\n"; +print FILE "VERSION = "; + +# copy contents of VERSION file to FILE +open(VERFILE,") { + print FILE $_; +} +close VERFILE; +close FILE; -- cgit v0.12