Commit ee8333a5 authored by Dimitri van Heesch's avatar Dimitri van Heesch

mods for doxygen-0.49-990829

parent 6aa7383e
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 <location_of_the_qt_includes> include
ln -s <location_of_the_qt_libs> lib
2. Run the configure script:
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.
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:
3. Compile the program by running make:
make
You'll see a list of all supported platforms/compiler combinations.
To build for the Linux platform with g++ as the compiler for example, type:
make linux-g++
The program should compile without problems and three binaries (doxygen,
doxytag, and doxysearch) should be available in the bin directory of the
distribution.
5. Generate the user manual.
type:
make docs
to let doxygen generate the HTML and LaTeX documentation.
(you will need the stream editor `sed' for this)
type:
make ps
to generate a postscript version of the manual.
......@@ -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
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++ version 5.0, use the vcvars32.bat to set the environment
variables.
- 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)
# 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:
# 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
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:
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:
# 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:
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++
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)
0.49-990829
#! /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 <<EOF
Usage: $0 [--help] [--shared] [--static] [--release] [--debug]
[--perl name] [--make name] [--qt-includes name] [--qt-libs name]
[--platform target]
Options:
--help Print this message
--shared | --static Build using shared or static linking
[default: shared]
--release | --debug Build for release or debug
[default: release]
--perl name Use \`name' as the name of the perl interpreter
[default: autodetect]
--make name Use \`name' as the name of the make tool
[default: autodetect]
--qt-includes path Use \`path' as the path to the qt include directory
[default: autodetect]
--qt-libs path Use \`path' as the path to the qt library directory
[default: autodetect]
--platform target Do not detect platform but use \`target' instead.
See PLATFORMS for a list of possibilities
EOF
test "$f_error" = y && exit 1
exit 0;
fi
u_release=`(uname -r) 2>/dev/null` || u_release=unknown
u_system=`(uname -s) 2>/dev/null` || u_system=unknown
if test -z "$f_platform"; then
f_platforms="`cat PLATFORMS`"
case "$u_system:$u_release" in
AIX*)
f_platform=aix-xlc
;;
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 <<EOF
DOXYGEN = $PWD
TMAKEPATH = $PWD/tmake/lib/$f_platform
TMAKE = $PWD/tmake/bin/tmake
MAKE = $f_make
PERL = $f_perl
RM = rm -f
VERSION = `cat VERSION`
EOF
touch .tmakeconfig
if test "$f_shared" = NO; then
cat > .tmakeconfig <<EOF
TMAKE_LFLAGS = -static
EOF
fi
for i in Makefile.in src/Makefile.in examples/Makefile.in doc/Makefile.in ; do
SRC=$i
DST=`echo $i|sed 's%\(.*\).in$%\1%'`
TIME=`date`
cat > $DST <<EOF
#
# This file was generated from `basename $i` on $TIME
#
EOF
cat .makeconfig $SRC >> $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 <<EOF
#
# This file was generated from `basename $i` on $TIME
#
EOF
if test "$f_debug" = NO; then
cat $SRC .tmakeconfig | sed -e "s/\$extraopts/release/g" >> $DST
else
cat $SRC .tmakeconfig | sed -e "s/\$extraopts/debug/g" >> $DST
fi
echo " Created $DST from $SRC..."
done
include ../Makefile.config
DOXYDIR=../bin
DOXYGEN_DOCDIR=..
all: FORCE
DOXYGEN_DOCDIR=$(DOXYGEN_DOCDIR); \
DOXYGEN_DOCDIR=$(DOXYGEN); \
export DOXYGEN_DOCDIR; \
VERSION=$(VERSION) ; \
export VERSION; \
$(DOXYDIR)/doxygen
$(DOXYGEN)/bin/doxygen
@rm -f ../latex/refman.tex
@cp doxygen_logo*.gif ../html
@cp Makefile.latex ../latex/Makefile
......
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:
......@@ -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 (&quot;...&quot;).
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.
<dt>\c CLASS_DIAGRAMS <dd>
......@@ -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.
<dt>\c SOURCE_BROWSER <dd>
\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.
<dt>\c CASE_SENSE_NAMES <dd>
\addindex CASE_SENSE_NAMES
If the \c CASE_SENSE_NAMES tag is set to \c NO (the default) then Doxygen
......@@ -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".
<dt>\c JAVADOC_AUTOBRIEF <dd>
\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.
</dl>
\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").
<dt>\c INCLUDE_PATH <dd>
\addindex INCLUDE_PATH
The INCLUDE_PATH tag can be used to specify one or more directories that
contain include files that are not input files but should be processed by
the preprocessor.
<dt>\c INPUT_FILTER <dd>
\addindex INPUT_FILTER
The \c INPUT_FILTER tag can be used to specify a program that doxygen should
......@@ -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.
<dt>\c HTML_ALIGN_MEMBERS <dd>
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.
<dt>\c GENERATE_HTMLHELP <dd>
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
<a href="http://msdn.microsoft.com/workshop/author/htmlhelp">
Microsoft HTML help workshop</a>
\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.
<dt>\c ALPHABETICAL_INDEX <dd>
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.
</dl>
\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 \
......
......@@ -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.
<li>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.
<li>Allows documentation of files, classes, templates, variables, functions,
typedefs, enums and defines.
<li>Allows documentation of files, namespaces, classes, structs, unions,
templates, variables, functions, typedefs, enums and defines.
<li>Includes a full C preprocessor to allow proper parsing of conditional
code fragments and to allow expansion of all or part of the define macros.
<li>Automatically detects public, protected and private sections, as well as
......@@ -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.
<li>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.
<li>Allows references to documentation generated for other projects
(or another part of the same project) in a location independent way.
<li>Allows inclusion of source code examples that are automatically
......@@ -58,6 +58,8 @@
file.
<li>Documentation and search engine can be transferred to another
location or machine without regenerating the documentation.
<li>Doxygen can generate index and project files that can
be converted into compressed HTML by MicroSoft's HTML help workshop.
<li>Can cope with large projects easily.
</UL>
......
......@@ -116,6 +116,7 @@ Thanks go to:
(which is even useful for GUI-less applications like doxygen :-)
<li>My brother <a href="http://www.stack.nl/~fidget/index.html">Frank</a>
for rendering the logos.
<li>Harm van der Heijden for adding HTML help support.
<li>
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.
</ul>
*/
......@@ -79,15 +79,15 @@ The following binaries should now be available:
Doxygen was developed and tested under Linux using the following tools:
<ul>
<li>GCC version 2.8.1
<li>EGCS version 2.91.66
<li>GNU flex version 2.5.4
<li>GNU bison version 1.25
<li>GNU make version 3.77
<li>Perl version 5.001 (patch level 1m)
<li>VIM version 5.3
<li>GNU make version 3.76.1
<li>Perl version 5.005_02
<li>VIM version 5.4
<li>Netscape 4.04 & 4.5
<li>Troll Tech's tmake version 1.2 (included in the distribution)
<li>teTeX version 0.4
<li>teTeX version 0.9
</ul>
\htmlonly
......
......@@ -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 <code>formula.repository</code> 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 <code>:=</code> operator instead of
<code>=</code>
As an example suppose we have the following piece of code:
\verbatim
#define QList QListT
class QListT
{
};
\endverbatim
Then the only way to get doxygen interpret this as a class definition
for class 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.
......
......@@ -48,6 +48,13 @@
int *(a[20]);
\endverbatim
then doxygen will remove the braces and correctly parse the result.
<li>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.
</ul>
......@@ -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 <code>-s</code> flag while generating it.
My email address: <a href="mailto:dimitri@stack.nl">dimitri@stack.nl</a>
My e-mail address: <a href="mailto:dimitri@stack.nl">dimitri@stack.nl</a>
*/
include ../Makefile.config
DOXYDIR = ../bin
all: class/html/index.html \
......
......@@ -17,7 +17,6 @@ all: class/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
......@@ -83,9 +82,6 @@ tag/html/index.html: tag.cpp tag.cfg
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
......
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
#
# $Id$
#
......@@ -12,8 +13,6 @@
# 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 $@
......@@ -37,7 +36,7 @@ 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 \
-$(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
......
......@@ -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))
{
......@@ -227,7 +228,7 @@ void ClassDef::writeDocumentation(OutputList &ol)
case Class: pageType=" Class"; break;
case Struct: pageType=" Struct"; break;
case Union: pageType=" Union"; break;
default: pageType+=compType; break; // an error
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,15 +555,19 @@ 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() +
......@@ -572,24 +576,27 @@ void ClassDef::writeDocumentation(OutputList &ol)
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);
}
......@@ -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)!='@' &&
/*! 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();
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)!='@' &&
/*! 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) &&
(hasDocumentation() || !Config::hideClassFlag ||
!reference.isNull());
// 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;
......
......@@ -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(),
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);
}
......
......@@ -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
......@@ -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)
<Start>"INPUT_FILTER"[ \t]*"=" { BEGIN(GetString); s=&Config::inputFilter; }
<Start>"PAPER_TYPE"[ \t]*"=" { BEGIN(GetString); s=&Config::paperType; }
<Start>"OUTPUT_LANGUAGE"[ \t]*"=" { BEGIN(GetString); s=&Config::outputLanguage; }
<Start>"STRIP_FROM_PATH"[ \t]*"=" { BEGIN(GetString); s=&Config::stripFromPath; }
<Start>"MAN_EXTENSION"[ \t]*"=" { BEGIN(GetString); s=&Config::manExtension; }
<Start>"INCLUDE_PATH"[ \t]*"=" { BEGIN(GetStrList); l=&Config::includePath; elemStr=""; }
<Start>"EXAMPLE_PATH"[ \t]*"=" { BEGIN(GetStrList); l=&Config::examplePath; elemStr=""; }
......@@ -200,6 +201,7 @@ static int yyread(char *buf,int max_size)
<Start>"EXT_DOC_PATHS"[ \t]*"=" { BEGIN(GetStrList); l=&Config::extDocPathList; elemStr=""; }
<Start>"PREDEFINED"[ \t]*"=" { BEGIN(GetStrList); l=&Config::predefined; elemStr=""; }
<Start>"EXTRA_PACKAGES"[ \t]*"=" { BEGIN(GetStrList); l=&Config::extraPackageList; elemStr=""; }
<Start>"STRIP_FROM_PATH"[ \t]*"=" { BEGIN(GetStrList); l=&Config::stripFromPath; elemStr=""; }
<Start>"QUIET"[ \t]*"=" { BEGIN(GetBool); b=&Config::quietFlag; }
<Start>"WARNINGS"[ \t]*"=" { BEGIN(GetBool); b=&Config::warningFlag; }
<Start>"RECURSIVE"[ \t]*"=" { BEGIN(GetBool); b=&Config::recursiveFlag; }
......@@ -228,6 +230,8 @@ static int yyread(char *buf,int max_size)
<Start>"HTML_ALIGN_MEMBERS"[ \t]*"=" { BEGIN(GetBool); b=&Config::htmlAlignMemberFlag; }
<Start>"SOURCE_BROWSER"[ \t]*"=" { BEGIN(GetBool); b=&Config::includeSourceFlag; }
<Start>"JAVADOC_AUTOBRIEF"[ \t]*"=" { BEGIN(GetBool); b=&Config::autoBriefFlag; }
<Start>"GENERATE_HTMLHELP"[ \t]*"=" { BEGIN(GetBool); b=&Config::htmlHelpFlag; }
<Start>"ALPHABETICAL_INDEX"[ \t]*"=" { BEGIN(GetBool); b=&Config::alphaIndexFlag; }
<Start>[a-z_A-Z0-9]+ { err("Warning: ignoring unknown tag `%s' at line %d\n",yytext,yyLineNr); }
<GetString,GetBool>\n { yyLineNr++; BEGIN(Start); }
<GetStrList>\n {
......@@ -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";
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";
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";
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 << "# 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";
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";
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";
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";
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";
......
......@@ -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<< <T>"
{
ftl=removeRedundantWhiteSpace(n.right(n.length()-il));
n=n.left(il);
......
......@@ -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]*
<ReadFuncArgType>{B}* {
curArgTypeName+=" ";
}
<ReadFuncArgType>"["[^\]]*"]" {
if (curArgTypeName.stripWhiteSpace().isEmpty())
curArgAttrib=yytext;
else
curArgTypeName+=yytext;
}
<ReadFuncArgDef>"'"\\[0-7]{1,3}"'" { curArgDefValue+=yytext; }
<ReadFuncArgDef>"'"\\."'" { curArgDefValue+=yytext; }
<ReadFuncArgDef>"'"."'" { 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==')')
......
......@@ -21,6 +21,8 @@ Define::Define()
{
undef=FALSE;
fileDef=0;
isPredefined=FALSE;
nonRecursive=FALSE;
}
Define::Define(const Define &d)
......
......@@ -42,6 +42,8 @@ class Define
int nargs;
bool undef;
bool varArgs;
bool isPredefined;
bool nonRecursive;
};
class DefineList : public QList<Define>
......
......@@ -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<QCString> *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
};
......
......@@ -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 << "<area ";
if (cd->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);
}
......
......@@ -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,6 +299,7 @@ void addIncludeFile(ClassDef *cd,FileDef *ifd,Entry *root)
cd->setIncludeFile(fd);
// set include supplied name
cd->setIncludeName(root->includeName);
if (cd->name().find('@')==-1)
fd->setIncludeName(cd->getOutputFileBase()+"-include");
if (includeDict[fd->absFilePath()]==0) // include not inserted earlier
{
......@@ -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;
}
// scope annonymous scope name at the end to determine the scope
// where we can put this variable
//printf("scope=%s\n",scope.data());
//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
{
// 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)
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)
{
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<BaseInfo> *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
if (!scopeName.isEmpty() &&
scopeName.find('<')==-1 &&
classTempList.length()==0
)
{
ClassDef *cd=getClass(scopeName);
if (cd) // class exists
// class is a template, but no template name list found
if (root->tArgList && cd && cd->templateArguments())
{
classTempList = cd->getTemplateNameString();
classTempList = tempArgListToString(root->tArgList);
}
}
......@@ -1840,7 +1967,9 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
extractNamespaceName(scopeName,className,namespaceName);
QCString tempScopeName=scopeName.copy();
int ti;
int ti=tempScopeName.find('<');
if (ti==-1)
{
int spi = namespaceName.isEmpty() ? 0 : namespaceName.length()+2;
if ((ti=tempScopeName.find("::",spi))!=-1 && !classTempList.isEmpty())
{
......@@ -1852,6 +1981,7 @@ void findMember(Entry *root,QCString funcDecl,QCString related,bool overloaded,
{
tempScopeName+=classTempList;
}
}
if (root->tArgList==0 && !classTempList.isEmpty())
......@@ -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)
{
//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->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);
}
//----------------------------------------------------------------------------
......@@ -3193,6 +3409,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
......@@ -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;
}
......@@ -123,5 +123,6 @@ extern int documentedFiles;
extern int documentedGroups;
extern int documentedNamespaces;
extern int documentedNamespaceMembers;
extern int documentedIncludeFiles;
#endif
......@@ -14,7 +14,7 @@
# TMake project file for doxygen
TEMPLATE = doxygen.t
CONFIG = console qt warn_on release #debug
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 \
......@@ -23,7 +23,7 @@ HEADERS = doxygen.h scanner.h classdef.h classlist.h memberdef.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
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 \
......@@ -32,7 +32,8 @@ SOURCES = doxygen.cpp scanner.cpp classdef.cpp classlist.cpp memberdef.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
version.cpp language.cpp definition.cpp formula.cpp debug.cpp \
membergroup.cpp htmlhelp.cpp
win32:INCLUDEPATH += .
TARGET = ../bin/doxygen
OBJECTS_DIR = ../objects
......@@ -12,7 +12,7 @@
# All output generated with Doxygen is not covered by this license.
TEMPLATE = app.t
CONFIG = console warn_on release
CONFIG = console warn_on $extraopts
SOURCES = doxysearch.cpp
TARGET = ../bin/doxysearch
OBJECTS_DIR = ../objects
......@@ -324,14 +324,18 @@ QCString unhtmlify(const char *str)
classFile=yytext;
BEGIN( SearchMemberRef );
}
<SearchMemberRef>"#" {
<SearchMemberRef,ReadClassFile>"#" {
if (YY_START==ReadClassFile)
{
classFile=yyFileName;
}
BEGIN( ReadMemberRef );
}
<ReadMemberRef>[a-z_A-Z0-9]+ {
memberRef=yytext;
BEGIN( SearchMemberName );
}
<SearchMemberName>"<strong>" {
<SearchMemberName>"<strong>"|"<b>" { // <strong> is for qt-1.44, <b> is for qt-2.00
BEGIN( ReadMemberName );
}
<SearchMemberName>[a-z_A-Z~] {
......
......@@ -14,7 +14,7 @@
# TMake project file for doxytag
TEMPLATE = doxytag.t
CONFIG = console warn_on qt release
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
......
......@@ -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<Entry> 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<Argument> 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;
}
......@@ -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<Entry> *sublist; // entries that are children of this one
QList<BaseInfo> *extends; // list of base classes
QList<QCString> *groups; // list of groups this entry belongs to
......
......@@ -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,10 +118,10 @@ 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(),
......@@ -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,16 +157,17 @@ 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(),
......@@ -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();
}
}
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)
{
if (!nd->name().isEmpty() && namespaceDict->find(nd->name())==0)
{
namespaceList->append(nd);
namespaceDict->insert(nd->name(),nd);
}
}
//-----------------------------------------------------------------------------
......
......@@ -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;
......
......@@ -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");
......
......@@ -125,6 +125,7 @@ void GroupDef::writeDocumentation(OutputList &ol)
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());
......
......@@ -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
......
......@@ -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 << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\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 << "</b>";
}
//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 << "<a class=\"el\" href=\"" << f << ".html\">";
docify(name);
t << "</a> ";
//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 << "</a>";
//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 << "<tr><td align=right valign=top>";
t << "<tr>";
if (inGroup)
t << "<td bgcolor=\"" << GROUP_COLOR << "\">";
else
t << "<td>";
t << "<img src=\"null.gif\"></td><td><img src=\"null.gif\"></td>";
switch(annoType)
{
case 0: t << "<td nowrap align=right valign=top>"; break;
case 1: t << "<td nowrap>"; break;
default: t << "<td nowrap valign=top>"; 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 << "&nbsp;</td><td valign=top>";
if (inGroup)
{
t << "&nbsp;</td><td";
if (headerName)
{
t << " align=right valign=top><a class=\"gl\" href=\""
<< fileName << ".html\">&nbsp;" << headerName << "&nbsp;</a>";
}
else
{
t << ">";
}
t << "</td><td bgcolor=\"" << GROUP_COLOR
<< "\"><img src=\"null.gif\">";
}
t << "</td></tr>";
}
t << endl;
}
void HtmlGenerator::endMemberItem()
void HtmlGenerator::insertMemberAlign()
{
if (Config::htmlAlignMemberFlag)
{
t << "</td></tr>";
t << "&nbsp;</td><td valign=top>";
}
t << endl;
}
void HtmlGenerator::startMemberDescription()
{
if (Config::htmlAlignMemberFlag)
{
t << "<tr><td></td><td><font size=-1><em>";
t << "<tr><td><img src=null.gif></td><td><img src=null.gif></td>"
"<td></td><td><font size=-1><em>";
}
else
{
......@@ -458,7 +510,7 @@ void HtmlGenerator::startMemberSections()
{
if (Config::htmlAlignMemberFlag)
{
t << "<table border=0 cellpadding=0 cellspacing=1>" << endl;
t << "<table border=0 cellpadding=0 cellspacing=0>" << endl;
}
}
......@@ -474,7 +526,7 @@ void HtmlGenerator::startMemberHeader()
{
if (Config::htmlAlignMemberFlag)
{
t << "<tr><td colspan=2><br><h2>";
t << "<tr><td colspan=4><br><h2>";
}
else
{
......@@ -494,9 +546,35 @@ void HtmlGenerator::endMemberHeader()
}
}
void HtmlGenerator::memberGroupSpacing(bool inGroup)
{
t << "<tr><td";
if (inGroup)
{
// left vertical table line
t << " bgcolor=\"" << GROUP_COLOR << "\" height=1><img src=\"null.gif\">"
// white space
"</td><td colspan=4></td>"
// right vertical table line
"<td bgcolor=\"" << GROUP_COLOR << "\"><img src=\"null.gif\">";
}
else
{
// one pixel height of whitespace
t << " height=1>";
}
t << "</td></tr>" << endl;
}
void HtmlGenerator::memberGroupSeparator()
{
t << "<tr><td colspan=6 height=1 bgcolor=\"" << GROUP_COLOR
<< "\"><img src=\"null.gif\"></td></tr>" << endl;
}
void HtmlGenerator::startMemberSubtitle()
{
if (Config::htmlAlignMemberFlag) t << "<tr><td colspan=2>";
if (Config::htmlAlignMemberFlag) t << "<tr><td colspan=4>";
}
void HtmlGenerator::endMemberSubtitle()
......@@ -504,3 +582,36 @@ void HtmlGenerator::endMemberSubtitle()
if (Config::htmlAlignMemberFlag) t << "<br><br></td></tr>" << endl;
}
void HtmlGenerator::startIndexList()
{
t << "<ul>" << endl;
//if (Config::htmlHelpFlag)
//{
// if (htmlHelp->depth()==0) htmlHelp->addItem(lastTitle,lastFile);
// htmlHelp->incDepth();
//}
}
void HtmlGenerator::endIndexList()
{
t << "</ul>" << endl;
//if (Config::htmlHelpFlag)
//{
// htmlHelp->decDepth();
//}
}
void HtmlGenerator::startAlfabeticalIndexList()
{
t << "<multicol cols=5><dl compact>" << endl;
}
void HtmlGenerator::endAlfabeticalIndexList()
{
t << "</dl></multicol>" << endl;
}
void HtmlGenerator::writeIndexHeading(const char *s)
{
t << "<dt><b><big>" << s << "</big></b><dd>" << endl;
}
......@@ -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 << "<ul>" << endl; }
void endIndexList() { t << "</ul>" << endl; }
void startIndexList();
void endIndexList();
void startItemList() { t << "<ul>" << endl; }
void endItemList() { t << "</ul>" << endl; }
void startEnumList() { t << "<ol>" << endl; }
void endEnumList() { t << "</ol>" << 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();
......@@ -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 << "&nbsp;&nbsp;&nbsp;"; }
//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
/******************************************************************************
*
* $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 <H.v.d.Heijden@phys.tue.nl>
* Please send thanks to him and bug reports to me :-)
*/
#include <stdio.h>
#include <stdlib.h>
#include <qlist.h>
#include <qdict.h>
#include "htmlhelp.h"
#include "config.h"
#include "message.h"
//----------------------------------------------------------------------------
struct IndexField
{
QCString name;
QCString url;
QCString anchor;
bool link;
};
class IndexFieldList : public QList<IndexField>
{
public:
int compareItems(GCI item1, GCI item2)
{
return stricmp(((IndexField *)item1)->name,((IndexField *)item2)->name);
}
};
class IndexFieldListIterator : public QListIterator<IndexField>
{
public:
IndexFieldListIterator( const IndexFieldList &list) :
QListIterator<IndexField>(list) {}
};
class IndexFieldDict : public QDict<IndexField>
{
public:
IndexFieldDict(int size) : QDict<IndexField>(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 <code>name = level1,level2</code> as follows:
* <pre>
* a1,b1
* a1,b2
* a2,b1
* a2,b2
* a3
* a4,b1
* </pre>
*
* Will result in the following list:
*
* <pre>
* a1 -> link to url if hasLink==TRUE
* b1 -> link to url#anchor
* b2 -> link to url#anchor
* a2 -> link to url if hasLink==TRUE
* b1 -> link to url#anchor
* b2 -> link to url#anchor
* a3 -> link to url if hasLink==TRUE
* a4 -> link to url if hasLink==TRUE
* b1 -> link to url#anchor
* </pre>
*/
void HtmlHelpIndex::writeFields(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 << " </UL>" << endl;
level2Started=FALSE;
if (level2.isEmpty())
{
t << " <LI><OBJECT type=\"text/sitemap\">";
t << "<param name=\"Local\" value=\"" << f->url << ".html";
if (!f->anchor.isEmpty()) t << "#" << f->anchor;
t << "\">";
t << "<param name=\"Name\" value=\"" << level1 << "\">"
"</OBJECT>\n";
}
else
{
if (f->link)
{
t << " <LI><OBJECT type=\"text/sitemap\">";
t << "<param name=\"Local\" value=\"" << f->url << ".html\">";
t << "<param name=\"Name\" value=\"" << level1 << "\">"
"</OBJECT>\n";
}
else
{
t << " <LI><OBJECT type=\"text/sitemap\">";
t << "<param name=\"See Also\" value=\"" << level1 << "\">";
t << "<param name=\"Name\" value=\"" << level1 << "\">"
"</OBJECT>\n";
}
}
}
if (!level2Started && !level2.isEmpty())
{ // start new list at level 2
t << " <UL>" << endl;
level2Started=TRUE;
}
else if (level2Started && level2.isEmpty())
{ // end list at level 2
t << " </UL>" << endl;
level2Started=FALSE;
}
if (level2Started)
{
t << " <LI><OBJECT type=\"text/sitemap\">";
t << "<param name=\"Local\" value=\"" << f->url << ".html";
if (!f->anchor.isEmpty()) t << "#" << f->anchor;
t << "\">";
t << "<param name=\"Name\" value=\"" << level2 << "\">"
"</OBJECT>\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 << "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"
"<HTML><HEAD></HEAD><BODY>\n"
"<OBJECT type=\"text/site properties\">\n"
"<param name=\"ImageType\" value=\"Folder\">\n"
"</OBJECT>\n"
"<UL>\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 << "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"
"<HTML><HEAD></HEAD><BODY>\n"
"<OBJECT type=\"text/site properties\">\n"
"<param name=\"ImageType\" value=\"Folder\">\n"
"</OBJECT>\n"
"<UL>\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 << "</UL>\n";
cts.unsetDevice();
cf->close();
delete cf;
index->writeFields(kts);
// end the index file
kts << "</UL>\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<dc+1;i++) cts << " ";
cts << "<UL>\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<dc;i++) cts << " ";
cts << "</UL>\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<dc;i++) cts << " ";
cts << "<LI><OBJECT type=\"text/sitemap\">";
cts << "<param name=\"Local\" value=\"" << ref << ".html";
if (anchor) cts << "#" << anchor;
cts << "\">";
cts << "<param name=\"Name\" value=\"" << name << "\">"
"</OBJECT>\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);
}
/******************************************************************************
*
* $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 <H.v.d.Heijden@phys.tue.nl>
* Please send thanks to him and bug reports to me :-)
*/
#ifndef HTMLHELP_H
#define HTMLHELP_H
#include "qtbc.h"
#include <qtstream.h>
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 */
......@@ -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,12 +495,7 @@ 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())
......@@ -430,7 +503,7 @@ void writeAnnotatedClassList(OutputList &ol)
case ClassDef::Class: type="class"; break;
case ClassDef::Struct: type="struct"; break;
case ClassDef::Union: type="union"; break;
default: type="unknown"; break; // an error
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,15 +687,31 @@ 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())
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->isFriend() || md->protection()!=Private || Config::extractPrivateFlag) &&
!md->isReference() && md->isRelated() && md->hasDocumentation() &&
md->name()[0]!='@' && (cd=md->memberClass()) && cd->isVisible())
if (md->isRelated())
found=TRUE;
else
}
// 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++;
......@@ -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)
//----------------------------------------------------------------------------
void writeHeaderFileList(OutputList &ol)
int countIncludeFiles()
{
if (includeFiles.count()>0)
int count=0;
FileDef *fd=includeFiles.first();
while (fd)
{
ol.startItemList();
if (fd->isLinkableInProject())
{
count++;
}
fd=includeFiles.next();
}
return count;
}
void writeHeaderFileList(OutputList &ol)
{
bool started=FALSE;
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();
if (Config::generateHtml && Config::htmlHelpFlag)
{
HtmlHelp::getInstance()->addContentsItem(
fd->name(),fd->includeName());
}
ol.endItemList();
}
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);
}
......
......@@ -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
......@@ -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;
}
......@@ -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
......@@ -19,6 +19,15 @@
#include "qtbc.h"
#include <qfile.h>
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)
{
......
......@@ -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
......@@ -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;
}
}
......@@ -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);
......
......@@ -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)
{
scopeTAL->append(new Argument(*a));
membTAL = new ArgumentList;
membTAL->setAutoDelete(TRUE);
copyArgumentList(tal,membTAL);
}
scopeTAL->constSpecifier = tal->constSpecifier;
scopeTAL->volatileSpecifier = tal->volatileSpecifier;
scopeTAL->pureSpecifier = tal->pureSpecifier;
}
void MemberDef::setGroupId(int groupId)
{
grpId=groupId;
if (grpId!=-1)
{
memberGroup=memberGroupDict[grpId];
memberGroup->insertMember(this);
}
}
QCString MemberDef::getScopeTemplateNameString()
void MemberDef::writeLink(OutputList &ol,ClassDef *cd,NamespaceDef *nd,
FileDef *fd,MemberGroup *mg)
{
QCString result;
if (!scopeTAL || scopeTAL->count()==0) return result;
result="<";
Argument *a=scopeTAL->first();
while (a)
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)
{
if (a->name.length()>0) // add template argument name
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)
{
result+=a->name;
gHeader=mg->header();
gFile=mg->getOutputFileBase();
}
else // extract name from type
if (!inGroup)
{
if (prevGroupId==-1 && gId!=-1)
{
int i=a->type.length()-1;
while (i>=0 && isId(a->type.at(i))) i--;
if (i>0)
ol.memberGroupSpacing(FALSE);
ol.memberGroupSeparator();
}
else if (prevGroupId!=-1 && gId==-1)
{
result+=a->type.right(a->type.length()-i-1);
ol.memberGroupSpacing(TRUE);
ol.memberGroupSeparator();
}
else if (prevGroupId!=-1 && gId!=-1 && prevGroupId!=gId)
{
ol.memberGroupSpacing(TRUE);
ol.memberGroupSeparator();
}
a=scopeTAL->next();
if (a) result+=", ";
}
result+=">";
return result;
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;j<indDepth;j++)
{
ol.writeNonBreakableSpace();
}
}
if (i!=-1)
{
//printf("scopeName=`%s' annonymous=`%s'\n",
// cname.data(),type.mid(i,l).data());
if (annoClassDef)
{
//printf("class found!\n");
annoClassDef->writeDeclaration(ol);
ol.startMemberItem(gId!=-1,2);
int j;
for (j=0;j<indDepth;j++)
{
ol.writeNonBreakableSpace();
}
ol.docify("}");
ol.docify(type.right(type.length()-i-l).stripWhiteSpace());
}
else
{
type = type.left(i) + " { ... } " + type.right(type.length()-i-l);
linkifyText(ol,cname,name(),type);
}
}
else
{
linkifyText(ol,cname,name(),type);
}
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);
}
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.
{
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();
}
}
warnIfUndocumented();
}
void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,const char *scopeName,
MemberType m)
{
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)
)
{
//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)
{
// 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
{
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
{
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(".");
}
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);
}
}
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();
}
......@@ -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,13 +56,21 @@ 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; }
const char *anchor() const { return anc; }
QCString bodyCode() const { return body; }
ClassDef *memberClass() { return classDef; }
Protection protection() const { return prot; }
......@@ -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,11 +91,10 @@ 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() ||
......@@ -142,8 +150,8 @@ 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; }
......@@ -152,14 +160,29 @@ 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
FileDef *fileDef; // member of file definition
......@@ -184,24 +207,30 @@ class MemberDef : public Definition
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
/******************************************************************************
*
* $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());
}
/******************************************************************************
*
* $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 <qlist.h>
#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<MemberGroup>
{
};
class MemberGroupListIterator : public QListIterator<MemberGroup>
{
public:
MemberGroupListIterator(const MemberGroupList &l) :
QListIterator<MemberGroup>(l) {}
};
#endif
......@@ -18,6 +18,9 @@
#include "classdef.h"
#include "message.h"
#include <qregexp.h>
#include "util.h"
#include "language.h"
#include "doxygen.h"
MemberList::MemberList() : QList<MemberDef>()
{
......@@ -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<MemberDef> &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<MemberDef> *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);
}
}
......@@ -38,10 +38,16 @@ class MemberList : public QList<MemberDef>
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;
......
......@@ -50,10 +50,6 @@ MemberNameInfo::MemberNameInfo(const char *n) : QList<MemberInfo>()
setAutoDelete(TRUE);
}
MemberNameInfo::~MemberNameInfo()
{
}
int MemberNameInfo::compareItems(GCI item1, GCI item2)
{
MemberInfo *m1=(MemberInfo *)item1;
......
......@@ -70,7 +70,6 @@ class MemberNameInfo : public QList<MemberInfo>
{
public:
MemberNameInfo(const char *name);
~MemberNameInfo();
const char *memberName() const { return name; }
int compareItems(GCI item1,GCI item2);
private:
......
......@@ -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::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)
......
......@@ -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<NamespaceDef>
QListIterator<NamespaceDef>(l) {}
};
typedef QDict<NamespaceDef> NamespaceDict;
class NamespaceDict : public QDict<NamespaceDef>
{
public:
NamespaceDict(int size) : QDict<NamespaceDef>(size) {}
};
#endif
......@@ -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); }
......
......@@ -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)
//--------------------------------------------------------------------------
......@@ -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<OutputGenerator> *outputs;
......
......@@ -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 ((argCount<def->nargs || def->varArgs) &&
((cc=getNextChar(expr,rest,j))!=EOF) && !done
while (!done && (argCount<def->nargs || 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);
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);
}
<ReadString>"//"|"/*" {
defArgsStr+=yytext;
}
<ReadString>. {
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]
}
<DefineArg>","{B}* { defArgsStr+=yytext; }
<DefineArg>"("{B}* { defArgsStr+=yytext; }
<DefineArg>")"{B}* {
<DefineArg>{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);
}
<SkipSingleQuote,SkipDoubleQuote>\\. {
defText += yytext;
}
<SkipSingleQuote>\' {
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",
......
......@@ -20,11 +20,15 @@
#include "qtbc.h"
#include <stdio.h>
#include <qlist.h>
#include <qintdict.h>
#include "entry.h"
#include "code.h"
#include "membergroup.h"
class OutputList;
typedef QIntDict<MemberGroup> MemberGroupDict;
typedef QIntDictIterator<MemberGroup> 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
......@@ -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 <PRE> or \\code "
"in the documentation of %s\n",refName.data());
}
<DocScan>{SCOPEMASK}"("[a-z_A-Z,\<\> \t\*\&]+")" {
<DocScan>{SCOPEMASK}"("[a-z_A-Z,:\<\> \t\*\&]+")" {
generateRef(*outDoc,className,yytext,inSeeBlock);
}
<DocScan>{SCOPEMASK}(("()")?) {
......@@ -1690,9 +1726,28 @@ VAR [vV][aA][rR]
lineCount();
BEGIN( ClassName );
}
<FindMembers>{B}*"module"{BN}+ {
isTypedef=FALSE;
current->section = Entry::NAMESPACE_SEC;
current->type = "module" ;
current->fileName = yyFileName;
current->startLine = yyLineNr;
lineCount();
BEGIN( ClassName );
}
<FindMembers>{B}*"interface"{BN}+ {
isTypedef=FALSE;
current->section = Entry::INTERFACE_SEC;
addType( current ) ;
current->type += " interface" ;
current->fileName = yyFileName;
current->startLine = yyLineNr;
lineCount();
BEGIN( ClassName );
}
<FindMembers>{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]
}
<FindMembers>"template"({BN}*)"<"/[>]? {
lineCount();
// class template specifier already found => member template specifier
// already inside class => member template specifier
if (current->tArgList || (current_root->section&Entry::COMPOUND_MASK))
{
//printf("-------> member template\n");
if (current->mtArgList)
{
current->mtArgList->clear();
}
else
{
current->mtArgList = new ArgumentList;
current->mtArgList->setAutoDelete(TRUE);
}
currentArgumentList = current->mtArgList;
}
else // class template specifier
{
//printf("-------> class template\n");
if (current->tArgList)
{
//printf("scanner.l current->tArgList->clear() %p\n",current->tArgList);
current->tArgList->clear();
}
else
{
current->tArgList = new ArgumentList;
current->tArgList->setAutoDelete(TRUE);
//printf("scanner.l new tArgList %p\n",current->tArgList);
}
currentArgumentList = current->tArgList;
}
templateStr="<";
copyArgString=&templateStr;
......@@ -1764,28 +1838,7 @@ VAR [vV][aA][rR]
//printf("Start template list\n");
BEGIN( ReadTempArgs );
}
/*
<FindMembers>({ID}{BN}*"::")*{BN}*"operator"{BN}*[<=]+ {
lineCount();
addType( current );
current->name = yytext;
}
<FindMembers>"operator"{BN}*"/"[=]?/[^/ *] { space added!
lineCount();
addType( current );
current->name = yytext;
}
<FindMembers>"operator"{BN}*"({B}*)"{BN}* /"(" { space added!
lineCount();
addType( current );
current->name = yytext;
}
<FindMembers>"operator"{BN}*[^(/]+ {
lineCount();
addType( current ) ;
current->name = yytext ;
}
*/
/* for now the using statement is completely ignored */
<FindMembers>"using"{BN}+ { lineCount(); BEGIN(Using); }
<Using>";" { BEGIN(FindMembers); }
<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 = &current->scopeSpec;
if (nameIsOperator(current->name))
BEGIN( Operator );
else
BEGIN( EndTemplate );
}
<FindMemberName>{SCOPENAME}{BN}*/"<" {
sharpCount=0;
lineCount();
current->name+=((QCString)yytext).stripWhiteSpace();
current->memberSpec.resize(0);
currentTemplateSpec = &current->memberSpec;
if (nameIsOperator(current->name))
BEGIN( Operator );
else
BEGIN( EndTemplate );
}
/*
<SkipTemplate>"<" {
sharpCount++;
}
<SkipTemplate>">" {
if (--sharpCount<=0)
{
BEGIN(FindMembers);
}
}
<SkipTemplate>.
*/
<EndTemplate>"<" {
current->name+='<';
*currentTemplateSpec+='<';
sharpCount++;
}
/*
<EndTemplate>">"({BN}*"::"{SCOPENAME})? {
*/
<EndTemplate>">" {
current->name+=*yytext;
current->name+='>';
*currentTemplateSpec+='>';
if (--sharpCount<=0)
{
//printf("Found %s\n",current->name.data());
......@@ -1822,6 +1900,7 @@ VAR [vV][aA][rR]
<EndTemplate>">"{BN}*"(" {
lineCount();
current->name+='>';
*currentTemplateSpec+='>';
if (--sharpCount<=0)
{
current->args = "(";
......@@ -1834,12 +1913,16 @@ VAR [vV][aA][rR]
<EndTemplate>">"{BN}*/"::" {
lineCount();
current->name+='>';
*currentTemplateSpec+='>';
if (--sharpCount<=0)
{
BEGIN(FindMemberName);
}
}
<EndTemplate>. { current->name+=*yytext; }
<EndTemplate>. {
current->name+=*yytext;
*currentTemplateSpec+=*yytext;
}
<FindMembers,FindMemberName>{SCOPENAME} {
lineCount();
if (YY_START==FindMembers)
......@@ -1857,10 +1940,10 @@ VAR [vV][aA][rR]
else
BEGIN(FindMembers);
}
<FindMembers>^{B}*"#" { lastCPPContext = YY_START;
<FindMembers>{B}*"#" { lastCPPContext = YY_START;
BEGIN( SkipCPP ) ;
}
<FindMembers>^{B}*"#define" {
<FindMembers>{B}*"#"{B}*"define" {
BEGIN( Define );
}
<SkipCPP>.
......@@ -1908,46 +1991,67 @@ VAR [vV][aA][rR]
<FindMembers>[*&]+ { current->name += yytext ; }
<FindMembers,MemberSpec,Function,NextSemi>";"{BN}*("/**"|"//!"|"/*!"|"///")"<" {
lineCount();
current->doc.resize(0);
current->brief.resize(0);
lastAfterDocContext = YY_START;
afterDocTerminator = ';';
if (yytext[yyleng-3]=='/')
{
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);
}
}
<MemberSpec,FindFields,FindMembers,NextSemi>","{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);
}
}
<DefineEnd,FindFields,FindFieldArg>{BN}*("/**"|"//!"|"/*!"|"///")"<" {
lineCount();
current->doc.resize(0);
current->brief.resize(0);
lastAfterDocContext = YY_START;
if (YY_START==DefineEnd)
afterDocTerminator = '\n';
else
afterDocTerminator = 0;
if (yytext[yyleng-3]=='/')
{
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);
}
}
<FindMembers>"=" {
BEGIN(NextSemi);
}
......@@ -2326,7 +2430,7 @@ VAR [vV][aA][rR]
<ReadTempArgs>">" {
*copyArgString+=*yytext;
//printf("end template list %s\n",copyArgString->data());
stringToArgumentList(*copyArgString,current->tArgList);
stringToArgumentList(*copyArgString,currentArgumentList);
BEGIN( currentArgumentContext );
}
<CopyArgRound>"(" {
......@@ -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,13 +2766,16 @@ VAR [vV][aA][rR]
current->name = yytext ;
//BEGIN( FindMembers );
}
<ClassVar>"(" {
roundCount=1;
lastSkipRoundContext=YY_START;
BEGIN(SkipRound);
<ClassVar>[(\[] {
// probably a function anyway
unput('(');
BEGIN( FindMembers );
}
<ClassVar>":" {
current->type.resize(0);
if (current->section == Entry::INTERFACE_SEC)
baseProt=Public;
else
baseProt=Private;
baseVirt=Normal;
baseName.resize(0);
......@@ -2676,6 +2787,7 @@ VAR [vV][aA][rR]
}
<ClassName,ClassVar>{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 );
}
<Bases>"," { 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]
}
<Bases>{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 );
}
<Doc,JavaDoc>{B}*("\\"|"@")"interface"{B}* {
current->section = Entry::INTERFACEDOC_SEC;
current->fileName = yyFileName;
current->startLine = yyLineNr;
BEGIN( ClassDocArg1 );
}
<Doc,JavaDoc>{B}*("\\"|"@")"page"{B}* {
current->section = Entry::PAGEDOC_SEC;
current->fileName = yyFileName;
......@@ -3076,6 +3196,35 @@ VAR [vV][aA][rR]
sectionType=SectionInfo::Subsection;
BEGIN(SectionLabel);
}
<Doc,PageDoc,JavaDoc,ClassDoc>("\\"|"@")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);
}
<Doc,PageDoc,JavaDoc,ClassDoc>("\\"|"@")endmgroup/[^a-z_A-Z0-9] {
//printf("--> endmgroup found!\n");
memberGroupId = -1;
current->mGrpId = -1;
}
<GroupHeader>[^\n]*/"\n" {
QCString header = ((QCString)yytext).stripWhiteSpace();
memberGroupDict.insert(memberGroupId,
new MemberGroup(memberGroupId,header)
);
BEGIN(lastMemberGroupContext);
}
<Doc,PageDoc,JavaDoc,ClassDoc>("\\"|"@")anchor{B}+ {
lastAnchorContext = YY_START;
sectionType=SectionInfo::Anchor;
......@@ -3216,6 +3365,7 @@ VAR [vV][aA][rR]
}
<ReadFormulaLong,ReadFormulaShort>. { formulaText+=*yytext; }
<ExampleDoc,PageDoc,ClassDocBrief,ClassDoc>"*/" {
checkDocs();
if (YY_START==ClassDocBrief &&
lastBriefContext==Doc)
{
......@@ -3432,6 +3582,7 @@ VAR [vV][aA][rR]
BEGIN( lastDocContext );
}
<Doc>"*/" {
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); }
}
......@@ -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}
......
......@@ -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,89 +420,105 @@ 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)
......@@ -434,26 +526,31 @@ class 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+=" 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
......@@ -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;
......
......@@ -286,6 +286,7 @@ class TranslatorSpanish : public Translator
case ClassDef::Class: result+=" Clase"; break;
case ClassDef::Struct: result+=" Estructura"; break;
case ClassDef::Union: result+=" Unin"; break;
case ClassDef::Interface: result+=" Interface"; break;
}
result+=" Referencia";
return result;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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:<>]+");
......@@ -222,11 +204,12 @@ static void linkifyText(OutputList &ol,const char *scName,const char *name,const
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
Definition *d=0;
if (cd) d=cd; else if (nd) d=nd; else d=fd;
if (d && d->isLinkable())
{
result.writeObjectLink(cd->getReference(),
cd->getOutputFileBase(),md->anchor(),word);
found=TRUE;
}
else if (nd && nd->hasDocumentation())
{
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)
{
......@@ -410,36 +319,52 @@ QCString argListToString(ArgumentList *al)
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);
}
//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;
//}
static void warnForUndocumentedMember(MemberDef *md)
QCString tempArgListToString(ArgumentList *al)
{
ClassDef *cd=md->memberClass();
FileDef *fd=md->getFileDef();
if (cd)
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 class %s is not documented\n",
md->name().data(),cd->name().data());
if (a->name.length()>0) // add template argument name
{
result+=a->name;
}
else if (fd)
else // extract name from type
{
int i=a->type.length()-1;
while (i>=0 && isId(a->type.at(i))) i--;
if (i>0)
{
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());
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<MemberDef> *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 (m<mdist && mcd->isVisible())
if (m<mdist && mcd->isLinkable())
{
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()
if (//(mmd->protection()!=Private || Config::extractPrivateFlag) &&
//(
//mmd->hasDocumentation()
/*mmd->detailsAreVisible()*/
|| mmd->isReference()
)
//|| mmd->isReference()
//)
mmd->isLinkable()
)
{
ClassDef *mcd=mmd->memberClass();
//printf(" >Class %s found\n",mcd->name().data());
int m=minClassDistance(fcd,mcd);
if (m<mdist && mcd->isVisible())
if (m<mdist && mcd->isLinkable())
{
//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
......
......@@ -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<QCString> *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
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++
......
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
......
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: <ftp://ftp.troll.no/freebies/tmake>
@rem = '--*-PERL-*--';
@rem = '
@echo off
rem setlocal
set ARGS=
:loop
if .%1==. goto endloop
set ARGS=%ARGS% %1
shift
goto loop
:endloop
rem ***** This assumes PERL is in the PATH *****
perl.exe -S progen.bat %ARGS%
goto endofperl
@rem ';
#!/usr/bin/perl
############################################################################
# $Id$
#
# Generates a tmake project file.
#
# Copyright (C) 1996-1998 by Troll Tech AS. All rights reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted, provided
# that this copyright notice appears in all copies.
# No representations are made about the suitability of this software for any
# purpose. It is provided "as is" without express or implied warranty.
#
############################################################################
# Default project settings
$project{"TEMPLATE"} = "app";
$project{"CONFIG"} = "qt warn_on release";
@project_extra = ();
while ( @ARGV ) { # parse command line args
$_ = shift @ARGV;
if ( s/^-// ) {
if ( /^o(.*)/ ) {
$outfile = ($1 eq "") ? shift @ARGV : $1;
($outfile eq "-") && ($outfile = "");
} elsif ( /^n(.*)/ ) {
$project{"TARGET"} = ($1 eq "") ? shift @ARGV : $1;
} elsif ( /^t(.*)/ ) {
$project{"TEMPLATE"} = ($1 eq "") ? shift @ARGV : $1;
$project{"TEMPLATE"} =~ s/\.t$//i;
} elsif ( /lower/ ) {
$tolower = 1;
} else {
&progen_usage;
}
} elsif ( /^\s*(?:[\w\-]+:)?\w+\s*[\+\-\*\/]?=/ ) { # project override
push( @project_extra, $_ );
} else {
push (@files, $_ );
}
}
$outfile eq "" || open(STDOUT,">" . $outfile) ||
&progen_error("Can't create \"$outfile\"");
if ( ! @files ) {
@files = &find_files(".",".*",1);
}
if ( $tolower ) {
foreach $f ( @files ) {
$f =~ tr/A-Z/a-z/;
}
}
@hdr = sort grep(/\.(h|hh|hpp|hxx)$/i,@files);
@src = sort grep(/\.(c|cpp|cc|cxx)$/i && ! /moc_/i,@files);
# Remove source files that are included by other source files
foreach $f ( @src ) {
$srcdict{$f} = 1;
}
foreach $f ( @src ) {
if ( open(F,"< $f") ) {
while ( <F> ) {
if ( /^\s*#\s*include\s+\"([^\"]*)\"/ ) {
$srcdict{$1} = 0;
}
}
}
}
foreach $f( @src ) {
$srcdict{$f} && (push(@src2,$f));
}
@src = @src2;
$project{"HEADERS"} = join(" ",sort @hdr);
$project{"SOURCES"} = join(" ",sort @src);
foreach $p ( @project_extra ) {
if ( $p =~ /^\s*((?:[\w\-]+:)?\w+)\s*([\+\-\*\/])?=\s*(.*)/ ) {
if ( $project{$1} ne "" ) {
Project($p);
}
}
}
$project{"HEADERS"} =~ s/\s+/ \\\n\t\t /g;
$project{"SOURCES"} =~ s/\s+/ \\\n\t\t /g;
print "TEMPLATE\t= " . $project{"TEMPLATE"} . "\n";
print "CONFIG\t\t= " . $project{"CONFIG"} . "\n";
print "HEADERS\t\t= " . $project{"HEADERS"} . "\n";
print "SOURCES\t\t= " . $project{"SOURCES"} . "\n";
if ( $project{"TARGET"} ne "" ) {
print "TARGET\t\t= " . $project{"TARGET"} . "\n";
}
foreach ( @project_extra ) {
if ( /^\s*((?:[\w\-]+:)?\w+)\s*([\+\-\*\/])?=\s*(.*)/ ) {
if ( $project{$1} eq "" ) {
$t = $1;
if ( length($t) < 8 ) {
$t .= "\t\t";
} elsif ( length($t) < 16 ) {
$t .= "\t";
} else {
$t .= " ";
}
print "$t$2= $3\n";
}
}
}
exit 0;
#
# progen_usage()
#
# Prints a message about program usage and exits
#
sub progen_usage {
print STDERR "Usage:\n progen [options] [files]\n";
print STDERR "Options:\n";
print STDERR " -lower Lower-case letters filenames (useful for non-Unix)\n";
print STDERR " -n name Specify a project name (= TARGET)\n";
print STDERR " -o file Write output to \"file\"\n";
print STDERR " -t file Specify a template file other than qtapp\n";
exit 1;
}
#
# progen_error(msg)
#
# Prints the message and exits
#
sub progen_error {
my($msg) = @_;
print STDERR "progen error: " . $msg . "\n";
exit 1;
}
#
# Finds files.
#
# Examples:
# find_files("/usr","\.cpp$",1) - finds .cpp files in /usr and below
# find_files("/tmp","^#",0) - finds #* files in /tmp
#
sub find_files {
my($dir,$match,$descend) = @_;
my($file,$p,@files);
local(*D);
$dir =~ s=\\=/=g;
($dir eq "") && ($dir = ".");
if ( opendir(D,$dir) ) {
if ( $dir eq "." ) {
$dir = "";
} else {
($dir =~ /\/$/) || ($dir .= "/");
}
foreach $file ( readdir(D) ) {
next if ( $file =~ /^\.\.?$/ );
$p = $dir . $file;
($file =~ /$match/i) && (push @files, $p);
if ( $descend && -d $p && ! -l $p ) {
push @files, &find_files($p,$match,$descend);
}
}
closedir(D);
}
return @files;
}
#
# strip_project_val(tag)
#
# Strips white space from project value strings.
#
sub strip_project_val {
my($v) = @_;
$v =~ s/^\s+//; # trim white space
$v =~ s/\s+$//;
return $v;
}
#
# Project(strings)
#
# This is a powerful function for setting or reading project variables.
# Returns the resulting project variables (joined with space between).
#
# This is a slightly modified version of the Project function in tmake.
sub Project {
my @settings = @_;
my($r,$t,$s,$v,$p,$c);
$r = "";
foreach ( @settings ) {
$v = $_;
if ( $v =~ s/^\s*((?:[\w\-]+:)?\w+)\s*(\+=|\*=|\-=|\/=|=)\s*// ) {
$t = $1;
$s = $2;
$v = strip_project_val($v);
$p = $project{$t};
if ( $s eq "=" ) { # set variable
$p = $v;
} elsif ( $s eq "+=" ) { # append
if ( $p eq "" ) {
$p = $v;
} else {
$p .= " " . $v;
}
} elsif ( $s eq "*=" ) { # append if not contained
if ( !($p =~ /(?:^|\s)\Q$v\E(?:\s|$)/) ) {
if ( $p eq "" ) {
$p = $v;
} else {
$p .= " " . $v;
}
}
} elsif ( $s eq "-=" ) { # subtract
$p =~ s/$v//g;
} elsif ( $s eq "/=" ) { # sed
$cmd = '$p =~ ' . $v;
eval $cmd;
}
$project{$t} = strip_project_val($p);
} else {
$p = strip_project_val($project{$v});
}
if ( $p ne "" ) {
$r = ($r eq "") ? $p : ($r . " " . $p);
}
}
return $r;
}
__END__
:endofperl
......@@ -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;
$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_extra = ();
@project_files = ();
@eval_expr = ();
$eval_done = 0;
%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") );
}
}
($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 ( ! ($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\"");
}
if ( !&ScanProject($_) ) {
&tmake_error("Can't open project file \"$_\"");
}
}
&Project( @project_extra );
if ( $template_name eq "" ) {
$template_name = $project{"TEMPLATE"} ?
$project{"TEMPLATE"} : "default.t";
}
&tmake_verb("Version $TMAKE_VERSION (runtime environment: " .
($really_unix ? "Unix" : "Win32") . ")\n" );
foreach ( @eval_expr ) {
$text = "";
eval( $_ );
die $@ if $@;
print $text . "\n" if ($text ne "");
$eval_done = 1;
}
if ( $eval_done ) {
if ( $eval_quit ) {
&tmake_verb("Done!");
exit 0;
}
($project_name eq "") && &tmake_usage();
if ( $template_name eq "" ) {
$template_name = $project{"TEMPLATE"} ?
$project{"TEMPLATE"} : "default.t";
}
$template_name = &find_template($template_name);
&IncludeTemplate($template_name);
&tmake_verb("Done!");
......@@ -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";
......@@ -186,6 +203,18 @@ sub tmake_error {
}
#
# tmake_warning(msg)
#
# Prints the warning message
#
sub tmake_warning {
my($msg) = @_;
print STDERR "tmake warning: " . $msg . "\n";
}
#
# tmake_verb()
#
......@@ -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 ( <TMP> ) {
$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 ( <TMP> ) {
$line++;
if ( /^\Q$endmark\E$/ ) {
$endmark = "";
last;
}
$val .= $_;
}
if ( $endmark ne "" ) {
tmake_error("$file:$line: End marker $endmark not found");
}
chop $val if ( $val ne "" );
$notrim_whitespace++;
Project( $var . $val );
$notrim_whitespace--;
$var = "";
$_ = "";
}
}
if ( $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);
}
@rem = '--*-PERL-*--';
@rem = '
@echo off
rem setlocal
set ARGS=
:loop
if .%1==. goto endloop
set ARGS=%ARGS% %1
shift
goto loop
:endloop
rem ***** This assumes PERL is in the PATH *****
perl.exe -S tmake.bat %ARGS%
goto endofperl
@rem ';
#!/usr/bin/perl
############################################################################
# $Id$
#
# Creates a Makefile from a template and a project file.
#
# Copyright (C) 1996-1998 by Troll Tech AS. All rights reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted, provided
# that this copyright notice appears in all copies.
# No representations are made about the suitability of this software for any
# purpose. It is provided "as is" without express or implied warranty.
#
#
# Some important, global variables in tmake:
# cpp_ext C++ extension added to moc output (.cpp)
# obj_ext Object file extension (.o on Unix, .obj otherwise)
# moc_aware Will scan for files containing Qt signals/slots
# moc_pre Moc prefix for generated moc file: x.h -> moc_x.cpp
# moc_ext Moc extension for generated moc file: x.cpp -> x.moc
# moc_cmd The moc command in your makefile, $(MOC)
# linebreak Line break character (\)
# dir_sep Directory separator (/ on Unix, \ on Windows)
# is_unix Autodetected. If not Unix, assume Windows (Win32).
#
# If you need to customize any of these settings, do it before
# calling StdInit() in the template file.
#
############################################################################
if ($] < 5.0) {
&tmake_error("This program requires perl version 5 or newer");
}
$cpp_ext = "cpp";
$obj_ext = "o";
$moc_aware = 0;
$moc_pre = "moc_";
$moc_ext = "moc";
$moc_cmd = '$(MOC)';
$linebreak = "\\";
$dir_sep = "/";
$is_unix = 1;
$really_unix = &check_unix();
$guess_os = 1;
$depend_path = "";
$nodepend = 0;
$output_count = 0;
$template_name = "";
$project_name = "";
$outfile = "";
@project_extra = ();
@project_files = ();
@eval_expr = ();
$eval_done = 0;
while ( @ARGV ) { # parse command line args
$_ = shift @ARGV;
if ( s/^-// ) {
if ( /^e(.*)/ ) {
push( @eval_expr, ($1 eq "") ? shift @ARGV : $1);
} elsif ( /^t(.*)/ ) {
$template_name = ($1 eq "") ? shift @ARGV : $1;
} elsif ( /^o(.*)/ ) {
$outfile = ($1 eq "") ? shift @ARGV : $1;
($outfile eq "-") && ($outfile = "");
} elsif ( /^p(.*)/ ) {
push( @project_files, ($1 eq "") ? shift @ARGV : $1);
} elsif ( /^unix$/ ) {
$guess_os = 0;
$is_unix = 1;
} elsif ( /^win32$/ ) {
$guess_os = 0;
$is_unix = 0;
} elsif ( /^nodepend$/ ) {
$nodepend = 1; # don't generate dependencies
} elsif ( /^v$/ ) {
$verbose = 1;
} else {
&tmake_usage();
}
} elsif ( /^\s*(?:[\w\-]+:)?\w+\s*[\+\-\*\/]?=/ ) { # project override
push( @project_extra, $_ );
} else {
$project_name &&
&tmake_error("You can only specify one project file");
$project_name = $_;
}
}
($project_name ne "") || &tmake_usage();
if ( $guess_os && ! check_unix() ) { # probably non-Unix,
$is_unix = 0;
&tmake_verb("Win32 detected");
}
if ( ! $is_unix ) {
$obj_ext = "obj";
$dir_sep = "\\";
}
$outfile eq "" || open(STDOUT,">" . fix_path($outfile)) ||
&tmake_error("Can't create \"$outfile\"");
%project = ();
&ScanProject( &find_template("tmake.conf") );
&tmake_verb("Reading the project file $project_name");
if ( ! ($project_name =~ /\.pro$/i) && -f fix_path($project_name . ".pro") ) {
$project_name .= ".pro";
}
$project{"PROJECT"} = $project_name;
$project{"PROJECT"} =~ s/\.pro$//i;
$project{"TARGET"} = $project{"PROJECT"};
unshift(@project_files,$project_name);
foreach ( @project_files ) {
if ( ! ($_ =~ /\.pro$/i) && -f fix_path($_ . ".pro") ) {
$_ .= ".pro";
}
if ( !&ScanProject($_) ) {
&tmake_error("Can't open project file \"$_\"");
}
}
&Project( @project_extra );
if ( $template_name eq "" ) {
$template_name = $project{"TEMPLATE"} ?
$project{"TEMPLATE"} : "default.t";
}
foreach ( @eval_expr ) {
$text = "";
eval( $_ );
die $@ if $@;
print $text . "\n" if ($text ne "");
$eval_done = 1;
}
if ( $eval_done ) {
&tmake_verb("Done!");
exit 0;
}
$template_name = &find_template($template_name);
&IncludeTemplate($template_name);
&tmake_verb("Done!");
exit 0; # finished!
##############################################################################
# Subroutines from here
##############################################################################
#
# tmake_usage()
#
# Prints a message about program usage and exits
#
sub tmake_usage {
print STDERR "Usage:\n tmake [options] project-file\n";
print STDERR "Options:\n";
print STDERR " -e expr Evaluate expression, ignore template file\n";
print STDERR " -nodepend Don't generate dependency information\n";
print STDERR " -o file Write output to file\n";
print STDERR " -p project Load additional project file\n";
print STDERR " -t file Specify a template file\n";
print STDERR " -unix Create output for Unix (auto detects)\n";
print STDERR " -v Verbose/debug mode\n";
print STDERR " -win32 Create output for Win32 (auto detects)\n";
exit 1;
}
#
# tmake_error(msg)
#
# Prints the message and exits
#
sub tmake_error {
my($msg) = @_;
print STDERR "tmake error: " . $msg . "\n";
exit 1;
}
#
# tmake_verb()
#
# Prints a verbose message
#
sub tmake_verb {
my($msg) = @_;
$verbose && print STDERR "tmake: " . $msg . "\n";
}
#
# check_unix()
#
# Returns 1 if this is a Unix, 0 otherwise.
#
sub check_unix {
my($r);
$r = 0;
if ( -f "/bin/uname" ) {
$r = 1;
(-f "\\bin\\uname") && ($r = 0);
}
return $r;
}
#
# find_template(filename)
#
# Looks for the template file.
# 1. search the current directory
# 2. search the directories in TMAKEPATH
# 3. search in $HOME/.tmake
#
sub find_template {
my($filename) = @_;
my($tb,$d,$p,@dirs);
$tb = ($template_base eq "") ? "" : $template_base . ";";
$d = ";" . $tb . $ENV{"TMAKEPATH"} . ";" . $ENV{"HOME"} . "/.tmake/";
@dirs = &split_path( $d );
$filename .= ".t" unless ($filename =~ /\.\w+$/);
for $d ( @dirs ) {
$p = $d . $filename;
if ( -f fix_path($p) ) {
if ( $filename eq "tmake.conf" ) {
$tmake_platform = $d;
$tmake_platform =~ s-.*[/\\]([^/\\]*)[/\\]-$1-;
&tmake_verb("Detected platform $tmake_platform");
}
return $p;
}
return ($d . $filename) if ( -f fix_path($d . $filename) );
}
&tmake_error("Template file " . $filename . " not found");
}
##############################################################################
# User functions
##############################################################################
#
# StdInit()
#
# Standard initialization
#
sub StdInit {
my($p);
return if $stdinit_done;
$stdinit_done = 1;
if ( defined($project{"OBJECTS_DIR"}) ) {
$project{"OBJECTS_DIR"} = FixPath($project{"OBJECTS_DIR"});
}
if ( defined($project{"MOC_DIR"}) ) {
$project{"MOC_DIR"} = FixPath($project{"MOC_DIR"});
}
$project{"OBJECTS"} = &Objects($project{"SOURCES"});
if ( $moc_aware ) {
$project{"_HDRMOC"} = &list_moc($project{"HEADERS"},$moc_pre,$cpp_ext);
$project{"_SRCMOC"} = &list_moc($project{"SOURCES"},"",$moc_ext);
$project{"OBJMOC"} = &Objects($project{"_HDRMOC"});
$p = $project{"_HDRMOC"} . " " . $project{"_SRCMOC"};
$p =~ s/(^\s+|\s+$)//g;
$project{"SRCMOC"} = $p;
}
&AddIncludePath("");
}
sub FixPath {
my($p) = @_;
if ( $p eq "." ) { $p = ""; }
elsif ( length($p) > 0 ) {
$p .= $dir_sep;
$p =~ s-[\\/]+-${dir_sep}-g;
}
return $p;
}
#
# Config(name)
#
# Returns true if the project variable CONFIG contains the
# configuration name.
#
sub Config {
my($name) = @_;
return $project{"CONFIG"} =~ /\b$name\b/;
}
#
# DisableOutput()
#
# Disables tmake output. Must be restored by calling a corresponding
# EnableOutput().
#
sub DisableOutput {
$output_count++;
}
#
# EnableOutput()
#
# Enables tmake output again after DisableOutput() has been called.
#
sub EnableOutput {
$output_count--;
}
#
# Now() - sets $text
#
# Sets $text to the current date and time.
#
sub Now {
my($sec,$min,$hour,$mday,$mon,$year);
($sec,$min,$hour,$mday,$mon,$year) = localtime(time());
$text = sprintf("%02d:%02d, %4d/%02d/%02d",
$hour, $min, 1900+$year, 1+$mon, $mday);
}
#
# expand_project_val(tag)
#
# Internal function for Project().
# Expands a project value string.
#
sub expand_project_val {
my($v) = @_;
my($c);
$v =~ s/^\s+//; # trim white space
$v =~ s/\s+$//;
$c = 0;
while ( $c < 100 ) { # expand $$
if ( $v =~ s/(\$\$\w+)/\035/ ) {
$_ = $1;
s/\$\$//g;
$v =~ s/\035/$project{$_}/g;
$c++;
} else {
$c = 100;
}
}
return $v;
}
#
# Project(strings)
#
# This is a powerful function for setting or reading project variables.
# Returns the resulting project variables (joined with space between).
#
# Get a project variable:
# $s = Project("TEMPLATE"); -> $s = "TEMPLATE"
#
# Set a project variable:
# Project("TEMPLATE = lib"); -> TEMPLATE = lib
# Project("CONFIG =";) -> CONFIG empty
#
# Append to a project variable:
# Project("CONFIG = qt"); -> CONFIG = qt
# Project("CONFIG += debug"); -> CONFIG = qt debug
#
# Append to a project variable if it does not contain the value already:
# Project("CONFIG = qt release"); -> CONFIG = qt release
# Project("CONFIG *= qt"); -> CONFIG = qt release
# Project("CONFIG *= opengl"); -> CONFIG = qt release opengl
#
# Subtract from a project variable:
# Project("THINGS = abc xyz"); -> THINGS = abc xyz
# Project("THINGS -= abc"); -> THINGS = xyz
#
# Search/replace on a project variable:
# Project("CONFIG = tq opengl"); -> CONFIG = tq opengl
# Project("CONFIG /= s/tq/qt/"); -> CONFIG = qt opengl
#
# The operations can be performed on several project variables at a time.
#
# Project("TEMPLATE = app", "CONFIG *= opengl", "THINGS += klm");
#
sub Project {
my @settings = @_;
my($r,$if_tag,$t,$s,$v,$p,$c);
$r = "";
foreach ( @settings ) {
$v = $_;
if ( $v =~ s/^\s*([\w\-]+:)?(\w+)\s*(\+=|\*=|\-=|\/=|=)\s*// ) {
$if_tag = $1;
if ( $if_tag ne "" ) {
chop $if_tag;
if ( $if_tag eq "unix" ) {
return "" if !$is_unix;
} elsif ( $if_tag eq "win32" ) {
return "" if $is_unix;
} elsif ( ($if_tag ne $tmake_platform) && !Config($if_tag) ) {
return "";
}
}
$t = $2;
$s = $3;
$v = expand_project_val($v);
$p = $project{$t};
if ( $s eq "=" ) { # set variable
$p = $v;
} elsif ( $s eq "+=" ) { # append
if ( $p eq "" ) {
$p = $v;
} else {
$p .= " " . $v;
}
} elsif ( $s eq "*=" ) { # append if not contained
if ( !($p =~ /(?:^|\s)\Q$v\E(?:\s|$)/) ) {
if ( $p eq "" ) {
$p = $v;
} else {
$p .= " " . $v;
}
}
} elsif ( $s eq "-=" ) { # subtract
$p =~ s/$v//g;
} elsif ( $s eq "/=" ) { # sed
$cmd = '$p =~ ' . $v;
eval $cmd;
}
$project{$t} = expand_project_val($p);
} else {
$p = expand_project_val($project{$v});
}
if ( $p ne "" ) {
$r = ($r eq "") ? $p : ($r . " " . $p);
}
}
return $r;
}
#
# Substitute(string)
#
# This function substitutes project variables in a text.
#
# Example:
# Substitute('The project name is "$$PROJECT"')
#
sub Substitute {
my($subst) = @_;
$text = expand_project_val($subst);
return $text;
}
#
# ScanProject(file)
#
# Scans a project file. Inserts project variables into the global
# associative project array.
#
sub ScanProject {
my($file) = @_;
my($tag,$var,@v,$more,$line);
$tag = "";
$line = 0;
open(TMP,fix_path($file)) || return 0;
while ( <TMP> ) {
$line++;
s/\#.*//; # strip comment
s/^\s+//; # strip white space
s/\s+$//;
if ( /^\s*((?:[\w\-]+:)?\w+\s*(\+|\-|\*|\/)?=)/ ) {
$tag = $1; # tag also contains the ".="
s/^.*?=\s*//;
}
if ( $tag ne "" ) {
$more = ( $_ =~ s/\s*\\\s*$// ); # more if \ at end of line
push( @v, split( /\s+/, $_ ) );
if ( ! $more ) {
$var = join(" ",@v);
Project( $tag . $var );
$tag = "";
@v = ();
}
} elsif ( $_ ne "" ) {
tmake_error("$file:$line: Syntax error");
}
}
close(TMP);
return 1;
}
#
# IncludeTemplate(template_name)
#
# Includes and processes a template file.
#
# Below, we read the template file and executes any perl code found.
# Perl code comes after "#$". The variable $text contains the text
# to replace the perl code that was executed.
# Template comments begin with "#!".
#
sub IncludeTemplate {
my($t_name) = @_;
my($cmd,$cmd_block,$cmd_end,$is_cmd_block,$saveline,$spaceonly);
local($text);
local(*T);
$t_name = &find_template($t_name);
if ( $tmake_template_dict{$t_name} ) {
&tmake_error("Cyclic template inclusion for $t_name");
} else {
$tmake_template_dict{$t_name} = 1;
}
$template_base = $t_name;
$template_base =~ s-(.*[/\\]).*-$1-;
&tmake_verb("Reading the template $t_name");
open(T,fix_path($t_name)) ||
&tmake_error("Can't open template file \"$t_name\"");
while ( <T> ) {
if ( /\#\!/ ) { # tmake comment
s/\s*\#\!.*//;
next if /^$/;
}
if ( /\#\$(\{)?\s*(.*)\n/ ) { # code
$cmd = $2;
$is_cmd_block = ($1 eq "{");
s/\#\$.*\n//;
if ( $is_cmd_block ) { # code block #${ ...
$saveline = $_;
$cmd_block = $cmd;
$cmd_end = 0;
while ( <T> ) {
$cmd = $_;
$cmd =~ s/\s*\#\!.*//; # tmake comment
if ( $cmd =~ /^\s*\#\$\}/ ) {
$_ = "";
$cmd_end = 1;
last;
}
$cmd =~ s/^\s*\#(\$)?\s*//;
$cmd_block .= $cmd;
}
$cmd_end || &tmake_error('#$} expected but not found');
$cmd = $cmd_block;
$_ = $saveline;
}
$spaceonly = /^\s*$/;
$saveline = $_;
&tmake_verb("Evaluate: $cmd");
$text = "";
eval $cmd;
die $@ if $@;
next if $spaceonly && ($text =~ /^\s*$/);
print $saveline . $text . "\n" if $output_count <= 0;
} else { # something else
print if $output_count <= 0;
}
}
close( T );
}
#
# Expand(tag) - appends to $text
#
# Expands a list of $project{} variables with a space character between them.
#
sub Expand {
my @tags = @_;
my($t);
$t = Project(@tags);
if ( $text eq "" ) {
$text = $t;
} elsif ( $t ne "" ) {
$text .= " " . $t;
}
return $text;
}
#
# ExpandGlue(tag,prepend,glue,append) - appends to $text
#
# Expands a $project{} tag, splits on whitespace
# and joins with $glue. $prepend is put at the start
# of the string and $append is put at the end of the
# string. The resulting string becomes "" if the project
# tag is empty or not defined.
#
# Example:
#
# The project file defines:
# SOURCES = a b c
#
# ExpandGlue("SOURCES","<","-",">")
#
# The result:
# $text = "<a-b-c>"
#
sub ExpandGlue {
my($tag,$prepend,$glue,$append) = @_;
my($t,$v);
$v = Project($tag);
if ( $v eq "" ) {
$t = "";
} else {
$t = $prepend . join($glue,split(/\s+/,$v)) . $append;
}
if ( $text eq "" ) {
$text = $t;
} elsif ( $t ne "" ) {
$text .= " " . $t;
}
return $text;
}
#
# ExpandList(tag) - sets $text.
#
# Suitable for expanding HEADERS = ... etc. in a Makefile
#
sub ExpandList {
my($tag) = @_;
return ExpandGlue($tag,""," ${linebreak}\n\t\t","");
}
#
# TmakeSelf()
#
# Generates makefile rule to regenerate the makefile using tmake.
#
sub TmakeSelf {
my $a = "tmake $project_name";
if ( $nodepend ) {
$a .= " -nodepend";
}
if ( $outfile ) {
$text = "tmake: $outfile\n\n$outfile: $project_name\n\t";
$a .= " -o $outfile";
} else {
$text = "tmake:\n\t";
}
$text .= $a
}
#
# Objects(files)
#
# Replaces any extension with .o ($obj_ext).
#
sub Objects {
local($_) = @_;
my(@a);
@a = split(/\s+/,$_);
foreach ( @a ) {
s-\.\w+$-.${obj_ext}-;
if ( defined($project{"OBJECTS_DIR"}) ) {
s-^.*[\\/]--;
$_ = $project{"OBJECTS_DIR"} . $_;
}
}
return join(" ",@a);
}
#
# list_moc(files,prefix,extension)
#
# Scans all files and selects all files that contain Q_OBJECT.
# Insert a prefix before the filename and replaces the filename extention.
#
sub list_moc {
my($files,$pre,$ext) = @_;
my(@v,@m,@lines,$contents,$n,$f,$t);
@v = split(/\s+/,$files);
undef $/;
foreach $f ( @v ) {
if ( open(TMP,fix_path($f)) ) {
$contents = <TMP>;
close(TMP);
$n = 0;
@lines = split(/\n/,$contents);
grep( /tmake\s+ignore\s+Q_OBJECT/ && $n--, @lines );
$contents =~ s-/\*.*?\*/--gs; # strip C/C++ comments
$contents =~ s-//.*\n--g;
@lines = split(/\n/,$contents);
grep( /(^|\W)Q_OBJECT(\W|$)/ && $n++, @lines );
if ( $n > 0 ) {
$t = $f;
$t =~ s-^(.*[/\\])?([^/\\]*?)\.(\w+)$-$1${pre}$2.${ext}-;
if ( defined($project{"MOC_DIR"}) ) {
$t =~ s-^.*[\\/]--;
$t = $project{"MOC_DIR"} . $t;
}
$moc_output{$f} = $t;
$moc_input{$t} = $f;
push(@m,$t);
}
$contents = "";
}
}
$/ = "\n";
return join(" ",@m);
}
#
# BuildObj(objects,sources)
#
# Builds the object files.
#
sub BuildObj {
my($obj,$src) = @_;
my(@objv,$srcv,$i,$s,$o,$d,$c);
@objv = split(/\s+/,$obj);
@srcv = split(/\s+/,$src);
for $i ( 0..$#objv ) {
$s = $srcv[$i];
$o = $objv[$i];
next if $s eq "";
$text .= $o . ": " . $s;
if ( $moc_output{$s} ne "" ) {
$text .= " ${linebreak}\n\t\t" . $moc_output{$s};
}
$d = &make_depend($s);
$text .= " ${linebreak}\n\t\t" . $d if $d ne "";
if ( defined($project{"OBJECTS_DIR"}) ||
!defined($project{"TMAKE_COMPILE_IMP"}) ) {
$c = $project{"TMAKE_COMPILE"};
$c =~ s/\$src/$s/;
$c =~ s/\$obj/$o/;
$text .= "\n\t$c";
}
$text .= "\n\n";
}
chop $text;
}
#
# BuildMocObj(objects,sources)
#
# Builds the moc object files.
#
sub BuildMocObj {
my($obj,$src) = @_;
my(@objv,$srcv,$i,$s,$o,$hdr,$d);
@objv = split(/\s+/,$obj);
@srcv = split(/\s+/,$src);
for $i ( 0..$#objv ) {
$s = $srcv[$i];
$o = $objv[$i];
$hdr = $moc_input{$srcv[$i]};
$text .= $o . ": " . $s . " ${linebreak}\n\t\t" . $hdr;
$d = &make_depend($hdr);
$text .= " ${linebreak}\n\t\t" . $d if $d ne "";
if ( defined($project{"OBJECTS_DIR"}) || defined($project{"MOC_DIR"})||
!defined($project{"TMAKE_COMPILE_IMP"}) ) {
$c = $project{"TMAKE_COMPILE"};
$c =~ s/\$src/$s/;
$c =~ s/\$obj/$o/;
$text .= "\n\t$c";
}
$text .= "\n\n";
}
chop $text;
}
#
# BuildMocSrc(files)
#
# Builds the moc source files from headers and sources.
#
sub BuildMocSrc {
my($f) = @_;
my(@v,$m,$o);
@v = split(/\s+/,$f);
foreach $m ( @v ) {
$o = $moc_output{$m};
if ( $o ne "" ) {
$text .= "$o: $m\n\t$moc_cmd $m -o $o\n\n";
}
}
chop $text;
}
#
# AddIncludePath(path)
#
# Adds path to the current include path, $project{"INCLUDEPATH"}.
#
sub AddIncludePath {
my($path) = @_;
my($p);
if ( $project{"INCPATH"} &&
($project{"INCPATH"} =~ /(?:^|\s)\Q$path\E(?:\s|$)/) ) {
return;
}
$p = $project{"INCLUDEPATH"};
$p = ($p && $path) ? ($p . ";" . $path) : ($p . $path);
$project{"INCLUDEPATH"} = $p;
$p = join(" ",&split_path($p));
$p =~ s=[\\/](\s|$)= =g;
$project{"INCPATH"} = $p;
}
#
# FindHighestLibVersion(dir,name)
#
# Returns the newest library version. Scans all the files in the specifies
# directory and returns the highest version number.
#
# Used on Windows only.
#
# Example:
# FindHighestLibVersion("c:\qt\lib","qt") returns "200" if
# the c:\qt\lib directory contains qt141.lib and qt200.lib.
#
sub FindHighestLibVersion {
my($dir,$name) = @_;
my(@files,$f,$v,$highest);
$highest = "";
@files = find_files($dir,"${name}.*\.lib");
for $f ( @files ) {
if ( $f =~ /(\d+)\.lib/ ) {
$v = $1;
if ( $highest eq "" || $v > $highest ) {
$highest = $v;
}
}
}
return $highest;
}
#
# Finds files.
#
# Examples:
# find_files("/usr","\.cpp$",1) - finds .cpp files in /usr and below
# find_files("/tmp","^#",0) - finds #* files in /tmp
#
sub find_files {
my($dir,$match,$descend) = @_;
my($file,$p,@files);
local(*D);
$dir =~ s=\\=/=g;
($dir eq "") && ($dir = ".");
if ( opendir(D,fix_path($dir)) ) {
if ( $dir eq "." ) {
$dir = "";
} else {
($dir =~ /\/$/) || ($dir .= "/");
}
foreach $file ( readdir(D) ) {
next if ( $file =~ /^\.\.?$/ );
$p = $dir . $file;
if ( $is_unix ) {
($file =~ /$match/) && (push @files, $p);
} else {
($file =~ /$match/i) && (push @files, $p);
}
if ( $descend && -d $p && ! -l $p ) {
push @files, &find_files($p,$match,$descend);
}
}
closedir(D);
}
return @files;
}
#
# make_depend(file)
#
# Returns a list of included files.
# Uses the global $depend_path variable.
#
sub make_depend {
my($file) = @_;
my($i,$count);
if ( $nodepend ) {
return "";
}
if ( ! $depend_path_fixed ) {
$depend_path_fixed = 1;
$depend_path = $project{"DEPENDPATH"};
$count = 0;
while ( $count < 100 ) {
if ( $depend_path =~ s/(\$[\{\(]?\w+[\}\)]?)/035/ ) {
$_ = $1;
s/[\$\{\}\(\)]//g;
$depend_path =~ s/035/$ENV{$_}/g;
} else {
$count = 100;
}
}
@dep_path = &split_path($depend_path);
}
@cur_dep_path = @dep_path;
if ( $file =~ /(.*[\/\\])/ ) {
$dep_curdir = $1;
splice( @cur_dep_path, 0, 0, $dep_curdir );
} else {
$dep_curdir = "";
}
$dep_file = $file;
&canonical_dep($file);
%dep_dict = ();
$i = &build_dep($file);
chop $i;
$i =~ s=/=$dir_sep=g unless $is_unix;
$i =~ s=([a-zA-Z]):/=//$1/=g if $gnuwin32;
return join(" ${linebreak}\n\t\t",split(/ /,$i) );
}
#
# build_dep() - Internal for make_depend()
#
sub build_dep {
my($file) = @_;
my(@i,$a,$n);
$a = "";
return $a if !(defined $depend_dict{$file});
@i = split(/ /,$depend_dict{$file});
for $n ( @i ) {
if ( !defined($dep_dict{$n}) && defined($full_path{$n}) ) {
$dep_dict{$n} = 1;
$a .= $full_path{$n} . " " . &build_dep($n);
}
}
return $a;
}
#
# canonical_dep(file) - Internal for make_depend()
#
# Reads the file and all included files recursively.
# %depend_dict associates a file name to a list of included files.
#
sub canonical_dep {
my($file) = @_;
my(@inc,$i);
@inc = &scan_dep($file);
if ( @inc ) {
$depend_dict{$file} = join(" ",@inc);
for $i ( @inc ) {
&canonical_dep($i) if !defined($depend_dict{$i});
}
}
}
#
# scan_dep(file) - Internal for make_depend()
#
# Returns an array of included files.
#
sub scan_dep {
my($file) = @_;
my($dir,$path,$found,@allincs,@includes,%incs);
$path = ($file eq $dep_file) ? $file : $dep_curdir . $file;
@includes = ();
return @includes if $file =~ /\.$moc_ext$/; # avoid .moc files
if ( ! (-f fix_path($path)) ) {
$found = 0;
for $dir ( @cur_dep_path ) {
$path = $dir . $file;
last if ( $found = (-f fix_path($path)) );
}
return @includes if ! $found;
}
undef $/;
if ( open(TMP,fix_path($path)) ) {
$full_path{$file} = $path;
$_ = <TMP>;
s-/\*.*?\*/--gs; # strip C/C++ comments
s-//.*\n-\n-g;
@allincs = split(/\n/,$_);
@allincs = grep(/^\s*#\s*include/,@allincs);
foreach ( @allincs ) { # all #include lines
next if !(/^\s*#\s*include\s+[<"]([^>"]*)[>"]/) || defined($incs{$1});
push(@includes,$1);
$incs{$1} = "1";
}
close(TMP);
}
$/ = "\n";
return @includes;
}
#
# split_path(path)
#
# Splits a path containing : (Unix) or ; (MSDOS, NT etc.) separators.
# Returns an array.
#
sub split_path {
my($p) = @_;
$p =~ s=:=;=g if $is_unix;
$p =~ s=[/\\]+=/=g;
$p =~ s=([^/:]);=$1/;=g;
$p =~ s=([^:;/])$=$1/=;
$p =~ s=/=$dir_sep=g unless $is_unix;
return split(/;/,$p);
}
#
# fix_path(path)
#
# Converts all '\' to '/' if this really seems to be a Unix box.
#
sub fix_path {
my($p) = @_;
if ( $really_unix ) {
$p =~ s-\\-/-g;
} else {
$p =~ s-/-\\-g;
}
return $p;
}
__END__
:endofperl
<!doctype HTML public "-//W3C//DTD HTML 3.2//EN">
<html><head><title>
tmake User's Guide
User's Guide - tmake
</title></head><body bgcolor="#ffffff">
<p><h1 align=center>tmake User's Guide</h1>
<hr>
<h2>License Statement</h2>
Copyright (C) 1996-1998 by Troll Tech AS. All rights reserved.<p>
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided
that this copyright notice appears in all copies.
No representations are made about the suitability of this software for any
purpose. It is provided "as is" without express or implied warranty.
<p><h1 align=center>User's Guide - tmake</h1>
<hr>
<h2>Introduction</h2>
tmake is an easy-to-use tool for creating and maintaining makefiles across
many platforms and compilers. The idea is that you should spend your time
writing code, not makefiles.
<p>
We wrote tmake because we spent too much time maintaining makefiles for
Windows and Unix compilers. Being the developer of the multi-platform GUI
toolkit <a href="http://www.troll.no/qt">Qt</a>, Troll Tech must provide
Qt makefiles for more than 30 different OS/compiler combinations.
tmake is an easy-to-use tool from Troll Tech to create and maintain
makefiles for software projects. It can be a painful task to manage
makefiles manually, especially if you develop for more than one platform
or use more than one compiler. tmake automates and streamlines this
process and lets you spend your valuable time on writing code, not
makefiles.
<p>
We looked at GNU autoconf, but it was Unix-specific and not flexible
enough in our opinion. Our makefile system also had to deal with Qt
<a href="http://www.troll.no/qt/metaobjects.html">meta object
compiler</a> (moc) issues. The moc program extracts meta information from
C++ files and generates a C++ file with data tables etc. It takes work to
add makefile rules for the moc and wanted to automate this task.
Our main motivation for developing tmake was that we spent far too much
time maintaining makefiles for <a href="http://www.troll.no/qt">Qt</a>,
our cross-platform GUI toolkit. Qt supports around 15 flavors of Unix,
Microsoft Windows, and around 15 different C++ compilers. We looked at
GNU autoconf, but it was Unix-specific and not flexible enough in our
opinion. Our makefile system also had to deal with Qt <a
href="http://www.troll.no/qt/metaobjects.html">meta object compiler</a>
(moc) issues. The moc program extracts meta information from C++ files and
generates a C++ file with data tables etc. It takes extra work to add
makefile rules for the moc and wanted to automate this task.
<p>
The tmake project was started around mid 1996 and version 1.0 was released
in September 1997. It soon became a success and is now widely used among
Qt programmers.
<p>
tmake is written in Perl and requires perl version 5 or newer. You do not
need to be familiar with Perl programming to use tmake, but you should
learn Perl if you want to write your own makefile templates.
tmake is written in Perl and requires that you have installed perl version
5 or newer. Basic use of tmake requires no perl knowledge, but if you know
perl you can extend tmake and write your own makefile templates.
<p>
<b>Windows users:</b> The tmake distribution for Win32 includes tmake.exe
......@@ -56,9 +40,14 @@ perl scripts. You can download perl for Win32 (Windows NT and 95) from <a
href="http://www.activestate.com">www.activestate.com</a>
<p>
Feedback is highly appreciated. Contact the author hanord@troll.no if you
have ideas, patches etc. for tmake.
tmake is free software and you may use, copy, modify and distribute tmake
and its documentation for any purpose and without any fee. See the
LICENSE file for details.
<p>
Feedback is highly appreciated. Contact the author, Haavard Nord <a
href="mailto:hanord@troll.no">(hanord@troll.no)</a>, if you have ideas,
patches etc. for tmake.
<hr>
<h2>Installation</h2>
......@@ -66,7 +55,7 @@ have ideas, patches etc. for tmake.
<ol>
<li>Make sure you have perl version 5 or later installed (optional
for Windows users).
<li>Unpack the tmake tar.gz or zip archive.
<li>Unpack the tmake tar.gz archive for Unix or the tmake .zip file for Windows.
<li>Set the TMAKEPATH environment variable to the directories
containing the template files (see below).
<li>Add the tmake/bin directory to your PATH.
......@@ -84,14 +73,15 @@ Here are some examples:<p>
setenv PATH $PATH:/local/tmake/bin
</pre>
<strong>Windows NT and Windows 95:</strong><pre>
<strong>Microsoft Windows:</strong><pre>
set TMAKEPATH=c:\tmake\lib\win32-msvc
set PATH=%PATH%;c:\tmake\bin
</pre>
<p>
The template directory name has the form <em>platform</em>-<em>compiler</em>.
Each template directory contains template files and a configuration file.
The template directory name has the form <em>platform</em>-<em>compiler</em>
and contains a platform configuration file (tmake.conf) and tmake template
files.
<p>
Supported platforms: AIX, Data General, FreeBSD, HPUX, SGI Irix, Linux,
......@@ -99,8 +89,7 @@ NetBSD, OpenBSD, OSF1/DEC, SCO, Solaris, SunOS, Ultrix, Unixware and
Win32.
<p>
Have a look at the tmake/lib directory to see if your platform-compiler
combination is supported. If it's not there, please tell us.
You can find your platform-compiler combination in the <tt>tmake/lib</tt>.
<p>
<b>Unix users:</b> tmake requires that perl is in /usr/bin. If your
......@@ -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:<pre>
First you need to create a tmake project file, e.g. hello.pro:<pre>
HEADERS = hello.h
SOURCES = hello.cpp main.cpp
TARGET = hello
......@@ -173,7 +162,7 @@ these files:
<p>
The hello.pro project file above does not have a <code>TEMPLATE</code> or
a <code>CONFIG</code> tag. The default template is <tt>app</tt> (the .t
a <code>CONFIG</code> variable. The default template is <tt>app</tt> (the .t
extension is optional) and the default configuration is <tt>qt warn_on
release</tt>.
......@@ -191,7 +180,7 @@ above:<pre>
<h4>Makefile Configuration</h4>
<p>
The <code>CONFIG</code> tag is recognized by both the app.t and lib.t
The <code>CONFIG</code> variable is recognized by both the app.t and lib.t
templates and specifies what compiler options to use and which extra
libraries to link in.
......@@ -247,7 +236,7 @@ These options defines the application/library type:
<td>&nbsp;</td>
<td>x11</td>
<td>&nbsp;</td>
<td>The target is a X11 application (app.t only).</td>
<td>The target is a X11 application or library.</td>
</tr>
<tr>
<td>&nbsp;</td>
......@@ -265,7 +254,7 @@ These options defines the application/library type:
<td>&nbsp;</td>
<td>dll</td>
<td>&nbsp;</td>
<td>The target is a shared object/DLL (app.t only).</td>
<td>The target is a shared object/DLL.</td>
</tr>
<tr>
<td>&nbsp;</td>
......@@ -283,7 +272,7 @@ read:<pre>
</pre>
<p>
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 <a href="tmake_ref.html">reference manual</a> for
details.<p>
......@@ -294,7 +283,7 @@ details.<p>
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.
<p>
<table border="0">
<tr>
......@@ -372,10 +361,9 @@ The library template, lib.t, lets you compile and create static or shared
libraries.
<p>
The lib.t template supports the same project tags as app.t, but also
The lib.t template supports the same project variables as app.t, but also
<code>VERSION</code>. <code>VERSION</code> is the version number of the
target library, e.g. 1.40. The version is important for 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.
<p>The <code>SUBDIRS</code> tag contains the name of all subdirectories to
<p>The <code>SUBDIRS</code> variable contains the name of all subdirectories to
be processed.
......@@ -418,29 +406,130 @@ template):<pre>
<hr>
<h2><a name="usage"></a>Program Usage: tmake</h2>
<h2>Project File Syntax</h2>
The tmake project file has a very simple syntax. You may set
project variables, append to project variables, remove from
project variable and substitute project variables.
To set a project variable:<pre>
HEADERS = gui.h xml.h url.h
</pre>
If you cannot fit everything on one line, use '\' to split it up:<pre>
HEADERS = gui.h \
xml.h \
url.h
</pre>
<p>
Project variables contains lists of items (such as header files,
compiler options etc.) and use whitespace to separate the items.
This means that tmake cannot deal with items containing whitespace.
The INCLUDEPATH variable is an exception. If INCLUDEPATH contains
one or more semicolons (;), tmake uses the semicolon to separate
the include directories, hence you can have include directories
containing whitespace (this is quite common on Windows).
<p>
Here is an example:<pre>
INCLUDEPATH = C:\Program Files\DBLib\Include;C:\qt\include
</pre>
<p>
tmake supports <em>project variable expension</em>. Use $$ to expand
any project variable:<pre>
ALLFILES = $$HEADERS $$SOURCES
</pre>
<p>
Most often you assign some value to a project variable, but you can
also add to, remove from or replace parts of a project variable.<pre>
A = abc
X = xyz
A += def # A = abc def
X *= xyz # X = xyz
B = $$A # B = abc def
B -= abc # B = def
X /= s/y/Y/ # X = xYz
</pre>
The *= operation adds the value if the variable does not already contain it.
The /= operation performs regular expression substitution.
<p>
You can also set variables from the command line when running the tmake
program. For instance, if you want to generate a makefile with debug
information:<pre>
tmake "CONFIG+=debug" hello.pro
</pre>
<p>
Use the <tt>unix:</tt> or <tt>win32:</tt> (conditional) qualifier if you want a
platform-specific variable:<pre>
SOURCES = common.cpp # common for all platforms
unix:SOURCES += unix.cpp # additional sources for Unix
win32:SOURCES += win32.cpp # additional sources for Windows
unix:LIBS += -lm # on Unix we need the math lib
</pre>
If none of the platforms match, tmake looks for the variable in CONFIG
variable:<pre>
debug:SOURCES += dbgstuff.cpp # additional source for debugging
</pre>
Finally, you can set platform and compiler-dependent variables:<pre>
linux-g++:TMAKE_CFLAGS = -fno-rtti
</pre>
<p>
You may define your own project variables to be used by custom templates. A
project variable is stored in <code>%project</code>, which is an associative
Perl array. Access it like this: <code>$project{"var"}</code> or via the
function <code>Project("var")</code>. For example, after reading
"hello.pro", <code>$project{"SOURCES"}</code> contains "hello.cpp
main.cpp".<p>
<hr>
<h2><a name="usage"></a>Running tmake</h2>
Usage:<pre>
tmake [options] <em>project-file</em>
tmake [options] <em>project files or project settings</em>
</pre>
Options:<pre>
-e expr Evaluate the Perl expression. Ignores the template file.
-nodepend Don't generate dependency information.
-o <em>file</em> Write output to <em>file</em> instead of stdout.
-p <em>file</em> Load an additional project file.
-t <em>file</em> Specify a template <em>file</em>.
-unix Force tmake into Unix mode.
-v Verbose/debugging on.
-win32 Force tmake into Win32 mode.
</pre>
The -t option overrides any <code>TEMPLATE</code> tag in the project file.
The -t option overrides any <code>TEMPLATE</code> variable in the project file.
<p>
The default project file extension is ".pro". The default template file
extension is ".t". If you do not specify these extension tmake will
automatically add them for you.
<p>
Example of basic use:<pre>
tmake hello -o Makefile
</pre>
<p>
Example of how to create a makefile with debugging information:<pre>
tmake "CONFIG+=debug" hello -o Makefile
</pre>
<p>
Exmaple of how to specify a TMAKEPATH:<pre>
tmake "TMAKEPATH=/local/tmake/lib/hpux-g++" hello.pro -o Makefile
</pre>
Example of how to evaluate a perl expression (print names of headers
and source files):<pre>
tmake hello -e 'Expand("HEADERS","SOURCES")'
</pre>
<hr>
<h2><a name="progen"></a>The progen Utility</h2>
......@@ -478,12 +567,12 @@ settings in your project file:<pre>
solaris-cc:TMAKE_CC = /opt/bin/CC_5.0
solaris-cc:TMAKE_CFLAGS = -pts
unix:TMAKE_LIBS = -lXext
win32:INCLUDE_PATH = c:\myinclude
win32:INCLUDEPATH = c:\myinclude
win32-borland:DEFINES = NO_BOOL
</pre>
You can prefix a project tag with unix: or win32: to make it specific for
either Unix or Windows. You can also prefix tags with
You can prefix a project variable with unix: or win32: to make it specific for
either Unix or Windows. You can also prefix a variable with
<em>platform-compiler</em>
<h4>Your Own Templates</h4>
......@@ -496,10 +585,10 @@ can do with tmake. First you need to know how tmake works.
When you run tmake, it first reads the <tt>tmake.conf</tt> file.
This configuration file has the same syntax as the project file.
tmake then reads the project file and sets the project tags it
tmake then reads the project file and sets the project variables it
finds, e.g. <code>HEADERS</code>, <code>SOURCES</code> 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 <code>project</code>. For example,
<code>$project{"SOURCES"}</code> contains "hello.cpp main.cpp"
after processing hello.pro.
......
<!doctype HTML public "-//W3C//DTD HTML 3.2//EN">
<html><head><title>
tmake Reference Manual
Reference Manual - tmake
</title></head><body bgcolor="#ffffff">
<p><h1 align=center>tmake Reference Manual</h1>
<p><h1 align=center>Reference Manual - tmake</h1>
<hr>
<h2>Project Settings</h2>
tmake recognizes several project tags. The syntax for setting a
project variable is:<pre>
TAG = value
</pre>
You can also do tag expansion using $$:<pre>
ALLFILES = Project files: $$HEADERS $$SOURCES
</pre>
Normally you assign to a tag, but you can also add to a tag, subtract
from a tag or replace parts of the tag.<pre>
A = abc
X = xyz
A += def # A = abc def
X *= xyz # X = xyz
B = $$A # B = abc def
B -= abc # B = def
X /= s/y/Y/ # X = xYz
</pre>
The *= operation adds the value if the tag does not already contain it.
The /= operation performs regular expression substitution.
<p>
You can also set tags from the command line when running the tmake program.
For instance, if you want to generate a makefile with debug information:<pre>
tmake hello.pro "CONFIG+=debug"
</pre>
<p>
Use the <tt>unix:</tt> or <tt>win32:</tt> qualifier if you want a
platform-specific tag:<pre>
SOURCES = common.cpp # common for all platforms
unix:SOURCES += unix.cpp # additional sources for Unix
win32:SOURCES += win32.cpp # additional sources for Windows
unix:LIBS += -lm # on Unix we need the math lib
</pre>
If none of the platforms match, tmake looks for the tag in <a
href="#CONFIG">CONFIG</a> setting:<pre>
debug:SOURCES += dbgstuff.cpp # additional source for debugging
</pre>
Finally, you can set platform and compiler-dependent tags:<pre>
linux-g++:TMAKE_CFLAGS = -fno-rtti
</pre>
<p>
You may define your own project tags to be used by custom templates. A
project tag is stored in <code>%project</code>, which is an associative
Perl array. Access it like this: <code>$project{"tag"}</code> or via the
function <code>Project('tag')</code>. For example, after reading
"hello.pro", <code>$project{"SOURCES"}</code> contains "hello.cpp
main.cpp". One limitation of tmake is that it cannot handle file names
with white space.<p>
<hr>
<h2>Project Tag Reference</h2>
<h2>Project Variable Reference</h2>
<h4><a name="ALL_DEPS"></a>ALL_DEPS</h4>
Specifies additional dependencies for the makefile target "all:".<p>
......@@ -158,6 +102,12 @@ These options defines the application/library type:
</table>
<h4><a name="DEFINES"></a>DEFINES</h4>
Specifies C/C++ macros (-D compiler option). On Windows you need
to let DEFINES contain "QT_DLL" if you are building a Qt program
which should link with the Qt DLL.
<h4><a name="DEF_FILE"></a>DEF_FILE</h4>
Win32/app.t only: Specifies a .def file.
......@@ -175,14 +125,14 @@ Defines the header files of the project.
<h4><a name="INCPATH"></a>INCPATH</h4>
This tag is generated from <code>INCLUDEPATH</code>. The ';' or ':'
This variable is generated from <code>INCLUDEPATH</code>. The ';' or ':'
separators have been replaced by ' ' (single space). This makes it
easier to split. qtapp.t and other templates expand
<code>INCPATH</code> to set -I options for the C++ compiler.
<h4><a name="INCLUDEPATH"></a>INCLUDEPATH</h4>
This 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 <a href="#AddIncludePath">AddIncludePath()</a>
function.<p>
Example:<pre>
......@@ -214,7 +164,7 @@ See also: <a href="#OBJECTS_DIR">OBJECTS_DIR</a>.
<h4><a name="OBJECTS"></a>OBJECTS</h4>
This tag is generated from <code>SOURCES</code> by the StdInit() function.
This varialble is generated from <code>SOURCES</code> by the StdInit() function.
The extension of each source file has been replaced by .o (Unix) or .obj
(Win32).<p>
Example:<pre>
......@@ -236,7 +186,7 @@ See also: <a href="#MOC_DIR">MOC_DIR</a>.
<h4><a name="OBJMOC"></a>OBJMOC</h4>
This tag is generated by the <a href="#StdInit">StdInit()</a> function if
This variable is generated by the <a href="#StdInit">StdInit()</a> function if
<code>$moc_aware</code> is true. <code>OBJMOC</code> contains the name of
all intermediate moc object files.<p>
Example:<pre>
......@@ -258,7 +208,7 @@ file, excluding the .pro extension.
<h4><a name="RC_FILE"></a>RC_FILE</h4>
Win32/app.t only: Specifies a .rc file. Cannot be used with the RES_FILE
tag.
variable.
<h4><a name="RES_FILE"></a>RES_FILE</h4>
......@@ -271,7 +221,7 @@ Defines the source files of the project.
<h4><a name="SRCMOC"></a>SRCMOC</h4>
This tag is generated by the <a href="#StdInit">StdInit()</a> function if
This variable is generated by the <a href="#StdInit">StdInit()</a> function if
<code>CONFIG</code> contains "qt". <code>SRCMOC</code> contains the name of
all intermediate moc files.<p>
Example:<pre>
......@@ -303,8 +253,8 @@ Contains the name of the compiler.
Contains the default compiler flags.
<h4><a name="TMAKE_FILETAGS"></a>TMAKE_FILETAGS</h4>
Tells tmake which tags contain file names. This is because tmake
<h4><a name="TMAKE_FILEVARS"></a>TMAKE_FILEVARS</h4>
Tells tmake which variables contain file names. This is because tmake
on Windows replace the directory separator / with \.
......@@ -370,7 +320,7 @@ Example:<pre>
<h3>Config(string)</h3>
Returns true if the <code>CONFIG</code> tag contains the given string.
Returns true if the <code>CONFIG</code> variable contains the given string.
<p>Example:<pre>
#$ if ( Config("release") { }
</pre>
......@@ -390,20 +340,20 @@ EnableOutput() is called.
Enables tmake output after DisableOutput() was called.
<h3>Expand(tag)</h3>
Expands a project tag. Equivalent to <code>$text = $project{$tag}</code>.
<h3>Expand(var)</h3>
Expands a project variable. Equivalent to <code>$text = $project{$var}</code>.
<p>Example:<pre>
VERSION = #$ Expand("VERSION");
</pre>Output:<pre>
VERSION = 1.1
</pre>
<h3>ExpandGlue(tag,prepend,glue,append)</h3>
Expands a $project{} tag, splits on whitespace
<h3>ExpandGlue(var,prepend,glue,append)</h3>
Expands a $project{} variable, splits on whitespace
and joins with $glue. $prepend is put at the start
of the string and $append is put at the end of the
string. The resulting string ($text) becomes "" if
the project tag is empty or not defined.<p>
the project variable is empty or not defined.<p>
Example:<pre>
clear:
#$ ExpandGlue("OBJECTS","-del","\n\t-del ","");
......@@ -414,9 +364,9 @@ Example:<pre>
</pre>
<h3>ExpandList(tag)</h3>
<h3>ExpandList(var)</h3>
This function is suitable for expanding lists of files.
Equivalent with <code>ExpandGlue($tag,""," \\\n\t\t","")</code>.<p>
Equivalent with <code>ExpandGlue($var,""," \\\n\t\t","")</code>.<p>
Example:<pre>
OBJECTS = #$ ExpandList("OBJECTS");
</pre>Output:<pre>
......@@ -425,6 +375,11 @@ Example:<pre>
</pre>
<h3>ExpandPath(var,prepend,glue,append)</h3>
Similar to ExpandGlue, except that it splits the items on a semicolon
instead of space (if the variable contains at least one semicolon).
<h3>IncludeTemplate(file)</h3>
Includes a template file. The ".t" extension is optional.<p>
Example:<pre>
......@@ -477,7 +432,7 @@ between).
<h3><a name="ScanProject"></a>ScanProject(file)</h3>
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 <code>%project</code> array.
......@@ -485,7 +440,7 @@ global associative <code>%project</code> array.
Standard initialization of tmake. StdInit() should be
called from one of the first lines in the template.<p>
This function creates some new project tags:<ul>
This function creates some new project variables:<ul>
<li><code><a href="#OBJECTS">OBJECTS</a></code>
- Object files corresponding to
<code><a href="#SOURCES">SOURCES</a></code>.
......@@ -493,16 +448,16 @@ This function creates some new project tags:<ul>
<li><code><a href="#OBJMOC">OBJMOC</a></code> - moc object files.
</ul>
The moc-related tags are created only if <code>CONFIG</code> contains "qt"
The moc-related variables are created only if <code>CONFIG</code> contains "qt"
<h3>Substitute(string)</h3>
This function takes a string and substitutes any occurrence of $$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.
<p>
Important: Use single quotes around the string, otherwise perl will expand
any $tags it finds.
any $vars it finds.
<p>Example:<pre>
Substitute('Project name: $$PROJECT, uses template $$TEMPLATE');
</pre>
......@@ -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_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
......
......@@ -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
......
#! Use the common Unix template
#$ IncludeTemplate("../unix/app.t");
#! Use the common Unix template
#$ IncludeTemplate("../unix/lib.t");
#! Use the common Unix template
#$ IncludeTemplate("../unix/subdirs.t");
#
# $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
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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 =
......
......@@ -7,7 +7,7 @@
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 =
......@@ -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
......@@ -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
......
......@@ -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
......
......@@ -7,8 +7,8 @@
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_RELEASE = -O2 -OPT:Olimit=3000
......@@ -17,7 +17,7 @@ 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
#! Use the common Unix template
#$ IncludeTemplate("../unix/app.t");
#! Use the common Unix template
#$ IncludeTemplate("../unix/lib.t");
#! Use the common Unix template
#$ IncludeTemplate("../unix/subdirs.t");
#
# $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
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -40,13 +40,15 @@ TMAKE_LFLAGS =
TMAKE_LFLAGS_RELEASE =
TMAKE_LFLAGS_DEBUG =
TMAKE_LFLAGS_SHLIB = -shared
TMAKE_LFLAGS_SONAME =
TMAKE_LFLAGS_SONAME = <<END
-soname
END
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
......
......@@ -11,7 +11,7 @@ TMAKE_CC = gcc
TMAKE_CFLAGS = -D_POSIX_SOURCE -D_OSF_SOURCE -D_AES_SOURCE
TMAKE_CFLAGS_WARN_ON = -Wall -W
TMAKE_CFLAGS_WARN_OFF =
TMAKE_CFLAGS_RELEASE = -O2 -fno-strength-reduce
TMAKE_CFLAGS_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
......
......@@ -43,10 +43,10 @@ TMAKE_LFLAGS_SHLIB =
TMAKE_LFLAGS_SONAME =
TMAKE_LIBS = -lunix
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
......
......@@ -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 =
TMAKE_LIBS =
TMAKE_LIBS_X11 = -lX11 -lXext -lsocket
TMAKE_LIBS_QT = -lqt -lsocket
TMAKE_LIBS_X11 = -lXext -lX11 -lsocket -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
......
#! Use the common Unix template
#$ IncludeTemplate("../unix/app.t");
#! Use the common Unix template
#$ IncludeTemplate("../unix/lib.t");
#! Use the common Unix template
#$ IncludeTemplate("../unix/subdirs.t");
#
# $Id$
#
# tmake configuration for solaris-cc-gcc
# (Using SunPro CC for C++ code and gcc for C code.)
#
TEMPLATE = app
CONFIG = qt warn_on release
TMAKE_CC = gcc
TMAKE_CFLAGS =
TMAKE_CFLAGS_WARN_ON = -Wall -W
TMAKE_CFLAGS_WARN_OFF =
TMAKE_CFLAGS_RELEASE = -O2
TMAKE_CFLAGS_DEBUG = -g
TMAKE_CFLAGS_SHLIB = -fPIC
TMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
TMAKE_CXX = CC
TMAKE_CXXFLAGS =
TMAKE_CXXFLAGS_WARN_ON =
TMAKE_CXXFLAGS_WARN_OFF = -w
TMAKE_CXXFLAGS_RELEASE = $$TMAKE_CFLAGS_RELEASE
TMAKE_CXXFLAGS_DEBUG = $$TMAKE_CFLAGS_DEBUG
TMAKE_CXXFLAGS_SHLIB = -PIC
TMAKE_CXXFLAGS_YACC =
TMAKE_INCDIR =
TMAKE_LIBDIR =
TMAKE_INCDIR_X11 = /usr/openwin/include
TMAKE_LIBDIR_X11 = /usr/openwin/lib
TMAKE_INCDIR_QT = $(QTDIR)/include
TMAKE_LIBDIR_QT = $(QTDIR)/lib
TMAKE_INCDIR_OPENGL =
TMAKE_LIBDIR_OPENGL =
TMAKE_LINK = CC
# Jan Wortelboer <janw@wins.uva.nl> suggests avoiding $LD_LIBRARY_PATH:
TMAKE_LINK_SHLIB = CC -R$(QTDIR)/lib:/usr/openwin/lib
TMAKE_LFLAGS =
TMAKE_LFLAGS_RELEASE =
TMAKE_LFLAGS_DEBUG =
TMAKE_LFLAGS_SHLIB = -G -h $(TARGET1)
TMAKE_LFLAGS_SONAME =
TMAKE_LIBS = -lC
TMAKE_LIBS_X11 = -lXext -lX11 -lm
TMAKE_LIBS_QT = -lqt
TMAKE_LIBS_QT_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
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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,8 +134,12 @@
if ( Config("dll") ) {
Project('TMAKE_CFLAGS *= $$TMAKE_CFLAGS_SHLIB' );
Project('TMAKE_CXXFLAGS *= $$TMAKE_CXXFLAGS_SHLIB' );
if ( Project("TMAKE_APP_FLAG") ) {
Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_SHAPP');
} else {
Project('TMAKE_LFLAGS *= $$TMAKE_LFLAGS_SHLIB $$TMAKE_LFLAGS_SONAME');
}
}
#$}
#!
# Makefile for building #$ Expand("TARGET")
......@@ -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");
......
......@@ -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';
#$}
......
......@@ -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
......
#! Use the common Unix template
#$ IncludeTemplate("../unix/app.t");
#! Use the common Unix template
#$ IncludeTemplate("../unix/lib.t");
#! Use the common Unix template
#$ IncludeTemplate("../unix/subdirs.t");
#
# $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
#! Use the common Unix template
#$ IncludeTemplate("../unix/app.t");
#! Use the common Unix template
#$ IncludeTemplate("../unix/lib.t");
#! Use the common Unix template
#$ IncludeTemplate("../unix/subdirs.t");
#
# $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
......@@ -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,10 +60,12 @@
if ( Project("TMAKE_QT_DLL") ) {
my $qtver =FindHighestLibVersion($ENV{"QTDIR"} . "/lib", "qt");
Project("TMAKE_LIBS /= s/qt.lib/qt${qtver}.lib/");
if ( !Config("dll") ) {
Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL');
}
}
}
}
if ( Config("opengl") ) {
Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL');
}
......@@ -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");
......
#############################################################################
#!
#! 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");
......@@ -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
......@@ -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,41 +20,52 @@
}
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/");
if ( !Config("dll") ) {
Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL');
}
}
}
}
if ( Config("opengl") ) {
Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL');
}
......@@ -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
......
......@@ -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
......
......@@ -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,10 +60,12 @@
if ( Project("TMAKE_QT_DLL") ) {
my $qtver =FindHighestLibVersion($ENV{"QTDIR"} . "/lib", "qt");
Project("TMAKE_LIBS /= s/qt.lib/qt${qtver}.lib/");
if ( !Config("dll") ) {
Project('TMAKE_LIBS *= $$TMAKE_LIBS_QT_DLL');
}
}
}
}
if ( Config("opengl") ) {
Project('TMAKE_LIBS *= $$TMAKE_LIBS_OPENGL');
}
......@@ -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");
......
......@@ -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
......
......@@ -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 = ""; }
......
......@@ -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 = ""; }
......
......@@ -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");
......
......@@ -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
......
......@@ -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");
......
......@@ -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
......
......@@ -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");
......
......@@ -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"}) ) {
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();
# 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,"<VERSION") || die "Cannot open file VERSION for reading!";
while (<VERFILE>) {
print FILE $_;
}
close VERFILE;
close FILE;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment