From cf5706eb5adbe5858d87118d200e233abfa1271f Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 1 Jan 2012 19:19:07 -0600 Subject: [PATCH] Update embedded kalyptus installation --- kalyptus/ChangeLog | 307 +- kalyptus/Makefile.cvs | 5 + kalyptus/Makefile.in | 53 + kalyptus/README | 8 +- kalyptus/configure.in | 28 + kalyptus/dcopidlng | 12 + kalyptus/findperl | 17 + kalyptus/install-sh | 251 ++ kalyptus/kalyptus | 345 +- kalyptus/kalyptus.spec.in | 62 + kalyptus/kalyptusCxxToCSharp.pm | 764 ++++ kalyptus/kalyptusCxxToDcopIDL.pm | 1126 ++++++ kalyptus/kalyptusCxxToECMA.pm | 570 +++ kalyptus/kalyptusCxxToJNI.pm | 5595 ++++++++++++++++++++++++++++++ kalyptus/kalyptusCxxToJava.pm | 3434 ++++++++++++++++++ kalyptus/kalyptusCxxToKimono.pm | 3633 +++++++++++++++++++ kalyptus/kalyptusCxxToSmoke.pm | 746 +++- kalyptus/kalyptusCxxToSwig.pm | 996 ++++++ kalyptus/kalyptusDataDict.pm | 1769 +++++----- kalyptus/kdocAstUtil.pm | 27 + kalyptus/kdocLib.pm | 2 +- kalyptus/kdocParseDoc.pm | 3 + kalyptus/kdocUtil.pm | 35 +- kalyptus/perlbin | 1 + 24 files changed, 18671 insertions(+), 1118 deletions(-) create mode 100644 kalyptus/Makefile.cvs create mode 100644 kalyptus/Makefile.in create mode 100644 kalyptus/configure.in create mode 100755 kalyptus/dcopidlng create mode 100755 kalyptus/findperl create mode 100644 kalyptus/install-sh create mode 100644 kalyptus/kalyptus.spec.in create mode 100644 kalyptus/kalyptusCxxToCSharp.pm create mode 100644 kalyptus/kalyptusCxxToDcopIDL.pm create mode 100644 kalyptus/kalyptusCxxToECMA.pm create mode 100644 kalyptus/kalyptusCxxToJNI.pm create mode 100644 kalyptus/kalyptusCxxToJava.pm create mode 100644 kalyptus/kalyptusCxxToKimono.pm create mode 100644 kalyptus/kalyptusCxxToSwig.pm create mode 100644 kalyptus/perlbin diff --git a/kalyptus/ChangeLog b/kalyptus/ChangeLog index 6158567..fd2235b 100644 --- a/kalyptus/ChangeLog +++ b/kalyptus/ChangeLog @@ -1,3 +1,306 @@ +2005-09-26 Richard Dale + + * Some fixes/enhancements from the trunk version. Most + importantly generating accessor methods to get and set + public instance variables. + +2005-02-17 Richard Dale + + * Added a '--qt4' option to parse Qt 4 headers + +2005-02-06 Richard Dale + + * The KWin class was bracketed with '#ifdef Q_OS_UNIX.. #endif', and was being skipped + by kalyptus. Fixes a problem reported by Ian Monroe. + + CCMAIL: ian.monroe@gmail.com + +2004-10-02 Richard Dale + + * Fixed problem where a call to super in java TQWidet.polish() caused a loop + * DCOPArg and DCOPReply are ignored for java bindings generation + +2004-09-10 Richard Dale + + * Fixed Smoke library generation for KDE 3.1 + +2004-09-05 Richard Dale + + * Removed forward declarations for classes embedded in method return types. + For instance: + virtual class View *createView ( TQWidget *parent, const char *name = 0 ) = 0; + virtual TQPtrList views () const = 0; + * Added kate as a KDE include header subdirectory + + +2004-09-05 Richard Dale + + * Added kontact to the expected KDE header subdirectory names + * Fixed a bug in the code generation for this method: + + virtual TQValueList pluginList() const = 0; + + It was being incorrectly treated as a pointer type, because it contained as asterisk. + +2004-08-19 Richard Dale + + * A namespace such as KIO:: can be spread over several header files, the source + names are now kept in a property list so that all the includes can be generated. + +2004-07-26 Richard Dale + + * TQMap and TQPair template types such as 'TQMap' with an + embedded comma, were not being correctly normalised. A space was left in + the smoke type. + +2004-07-25 Richard Dale + + * When the Smoke code for accessing an enum was generated, it was assuming + that the enum was in the same source file as the class. This doesn't work + for namespaces like KIO:: where enums can be spread over several source + files. + * The solution is to add a source file property to each enum, and when the + accessor code for the enum is generated a suitable include can be added. + * Fixes problem reported by Luca Perossa + + CCMAIL: kde-bindings@kde.org + +2004-07-07 Richard Dale + + * After discussion with Germain Garand, TQChars have been returned to + the Smoke runtime as first class members. + +2004-07-07 Richard Dale + + * The TQChar class is now treated as a primitive type just like TQString. + +2004-06-30 Richard Dale + + * Added DCOPRef to the Smoke runtime. But the various template methods for send(), call() and callExt() + need to be reimplemented in the scripting language. + +2004-06-29 Richard Dale + + * Java methods now generated for qCompress and qUncompress methods - Michal Ceresna + reported that the methods missing from the QtJava api. + +2004-06-25 Richard Dale + + * Reinstated the KMultiTabBarTab and KMultiTabBarButton classes in the Smoke runtime + * It makes more sense to fix the parser to handle arg types starting with + 'class '. They are now stripped off and ignored. + +2004-06-24 Richard Dale + + * Removed KMultiTabBarTab and KMultiTabBarButton from the Smoke runtime + * Added an instance variable '_smokeObject' to generated C# Kimono classes + +2004-06-09 Richard Dale + + * New flags were added for Smoke methods - mf_internal and mf_copyctor. + This allows copy constructors which are only used internally by the ruby + or perl runtime, to be excluded from the standard api. + +2004-06-07 Richard Dale + + * Added patch from Michal Ceresna to fix code generation for TQImage.bits() and + TQImage.colorTable() + * Fixed bug reported by Maik Schulz caused by unwanted KListViewItem copy constructor. + An 'enhancement' was added for KDE 3.2 - for any class which didn't have a copy + constructor, but which could still be copied, a copy constructor was generated. + Unfortunately this had unforseen consequences, such as messing up KListView logic, + hence they're no longer generated. + +2004-05-27 Richard Dale + + * The methods TQPainter::pos() and TQFontInfo::font() are skipped for + Qt2 embedded as they don't link to the ARM version of Qt/E + * Thanks to Fabien Renaud for testing QtJava/E on an ARM box + +2004-05-25 Richard Dale + + * Added the correct macro expansion for Q_OBJECT with Qt/E 2.3.x + * kalyptus can now generate the SMOKE library for Qt Embedded + +2004-05-22 Richard Dale + + * More tweaks to the QtJava Embedded code generation. + The code now compiles without error, links and runs.. + * However, the Qt framebuffer emulator plasters the KDE desktop in + lurid green and doesn't seem to have a way of accepting mouse + input. How do you get mouse events into a named pipe that it reads? + +2004-05-21 Richard Dale + + * Added code generation for Qt/Embedded 2.3.4 with a '--qte' option to + be used in conjunction with the '-fjni' option. + * Example usage - this command will parse the Qt embedded headers in + directory 'test', and generate the .java and .cpp files in the same dir: + $ kalyptus -fjni -dtest --globspace --qte test/*.h + +2004-05-20 Richard Dale + + * The java '-fjni' option now generates correct java code with Qt/E 2.3.4 + * KMainWindow.toolBar() and KMainWindow.menuBar() rename ktoolBar() and + kmenuBar(). This is because java doesn't have covariant return types + and the methods with the same names in TQMainWindow return a TQToolBar + and TQMenuBar, rather than their KDE equivalent subclasses. + +2004-05-19 Richard Dale + + * Namespaces were being omitted from the SMOKE runtime, and so methods + such as the ones in KStdAction were missing. They are now included and + appear to be ordinary classes containing static methods. + For example, in ruby: + quit = KDE::StdAction.quit( self, SLOT("quit()"), actionCollection() ) + +2004-04-26 Richard Dale + + * Now only 55 Qt C# warnings, too much use of the 'new' inheritance directive + though. + +2004-04-26 Richard Dale + + * Reduced the number of compiler warnings for C# Dispose() methods. Now down to + 'only' 130 warnings for the Qt classes + +2004-04-13 Richard Dale + + * When a class includes equality operator overloading, an implementation of + GetHashCode() is generated (along with Equals() too) to avoid compiler warnings. + * If a method was originally inherited via C++ MI, but is now copied from the superclass + to the current class in C# instead, then it isn't labelled with a 'new' modifier + +2004-04-12 Richard Dale + + * Kimono C# code generation improvements + - Added the 'out' modifier for args which are references to mutable primitive types + - Improved doc comment to C# xml comment translation, with tags bracketing + the body of the comment + - Enum types are only given a 'E_' prefix if they clash with a C# method name after + the first character has been uppercased + +2004-03-26 Richard Dale + + * Removed quite a few compiler warnings from the C# code generated by -fkimono + - A lot of warnings about virtual methods not needing the 'new' keyword fixed + - If you define operator==, but not operator!= you get a warning. + A smarter compiler might be able to work one out from the other? + But added a corresponding 'operator!=' always. + - If you define operator== or operator!=, you get a warning for not defining + GetHashCode(). There must be some sort of logic in that, but not fixed yet. + +2004-03-25 Richard Dale + + * Removed obsolete C and Objective-C code generation options + +2004-03-19 Richard Dale + + * 'KDE Integrates Mono'; added -fkimono option to generate C# bindings + * It doens't use the Qt C bindings, like Qt# but the Smoke lib instead + * To generate the code and review the api, edit tdebindings/smoke/kde/generate.pl.in + and change '-fsmoke' to '-fkimono'. Then configure tdebindings with the + '--with-smoke=kde' option. The sources will be generated in smoke/kde. + * It uses custom real proxies as AOP style interceptors, one per instance + and a static interceptor per class. + - Every method call in the api is forwarded to SmokeInvocation.Invoke() + via the proxies, and is effectively a pointcut. + - In Invoke() the method call will be looked up dynamically from the Smoke runtime + - The arguments are marsalled from C# to C++ on the Smoke::Stack, and the method + invoked. + * The KDE doc comments are converted to C# xml style tags (eg KApplication.cs) + * Problems + - A small fix was need for RealProxies with Mono 0.30. DotGnu doesn't have + RealProxies/remoting yet. + - It should be possible to use ContextBoundObjects and custom ContextAttributes + as described here, but they aren't implemented in Mono yet. + http://msdn.microsoft.com/msdnmag/issues/03/03/ContextsinNET/ + - In interfaces the 'ref' keyword can't be used + - Doesn't use event handlers as delegates like Qt#, they are just overriden + like normal virtual methods + - Many compiler warnings about 'new virtual' not being needed. Some work needed + to only add new to overriden ones. + +2004-02-17 Richard Dale + + * Aligned the forthcoming KDE 3.3 dynamic proxy/SMOKE library based java + code generation with the current 3.2 JNI based ones (-fjava vs. -fjni). + +2004-01-28 Richard Dale + + * When two methods differed only in 'constness', it wasn't possible to + resolve which to call from ruby. For example: + KProgress* progressBar(); + const KProgress* progressBar() const; + So only the const variant is generated in the Smoke runtime. + +2004-01-05 Richard Dale + + * When a java method needed to be renamed, because in the type signature + only the return type differed in C++, when that isn't allowed in java, + the JNI function name was not using the new name. + * Fixed error in JNI function names when the C++ method had an underscore. + + +2003-12-29 Richard Dale + + * Fixed a problem with parsing one line namespace declarations + * Added support for the QT_WORKSPACE_WINDOWMODE macro, to solve build problem + * Added some more primitive type definitions such as KIO::filesize_t + +2003-12-23 Richard Dale + + * Added a '-fjni' option to generate code for the current KDE 3.2 JNI based java + bindings The '-fjava' option generates code for the forthcoming Dynamic + Proxy/Smoke library based java bindings in KDE 3.3. + * The Qt and KDE bindings just checked in were generated by changing the kalyptus + option '-fsmoke' to '-fjni' in tdebindings/smoke/kde/generate.pl.in. Then + configure tdebindings with '--enable-smoke=kde' option to generate the .cpp + and .java sources. The .h files are generated by using javah on the compiled + java .class files. + +2003-11-29 Richard Dale + + * Fixed parsing of casts inside enums in kfileitem.h: + enum { Unknown = (mode_t) - 1 }; + Hmm, not sure what that's up to anyway.. + * Added a special Source property to method nodes in TQGlobalSpace. + In java, this allows Qt friend methods to be grouped under the + Qt.java class, and KDE ones under KDE.java according to which + source file they originated from. + +2003-11-05 Richard Dale + + * Fixed parsing default argument values cast to a numeric literal, eg: + mode_t mode = (mode_t)-1 + * Excluded a couple of structs from kparts/browserextension + +2003-11-04 Richard Dale + + * KDE MI has some diamond shaped cycles, such as for the children of + KXMLGUIClient. When the code for casts to all the parents of a class + was generated in the Smoke runtime, this meant there were some + duplicate entries in the switch statement. Duplicates now removed. + + +2003-10-11 Richard Dale + + * Avoid generating wrappers for private classes with 'Private', + 'Impl' or 'Internal' in the name. Other unneeded classes also + dropped. + +2003-10-08 Richard Dale + + * Added SmokeKDE namespace class code generation + - Fixed bug in kalyptus where it couldn't detect the end of a namespace + - resolveType() in kalyptusDataDict.pm now looks in parent namespace for symbols + - Namespace enclosed class code generation added to kalyptusCxxToSmoke.pm + +2003-09-16 Richard Dale + + * Added various parser and code generation fixes so that a libsmokekde.so + can be generated from the tdelibs headers. + 2003-08-30 Richard Dale * Applied Germain Garand's patch to no longer rename operator methods @@ -16,7 +319,7 @@ 2003-08-21 Richard Dale - * Rewritten java code generation for a Dynamic Proxy based SMOKE adaptor version of TQtJava. + * Rewritten java code generation for a Dynamic Proxy based SMOKE adaptor version of QtJava. * Based on David Faure's SMOKE generation code in the '-fsmoke' option. 2003-08-11 Richard Dale @@ -56,7 +359,7 @@ * Perl .pig generation improved 2002-01-25 Richard Dale * Added '-fperl' option to autogenerate .pig (Perl Interface - Generator) files, suitable for generating Ashley Winters' PerlTQt/KDETQt + Generator) files, suitable for generating Ashley Winters' PerlQt/KDEQt bindings 2002-01-23 Richard Dale * Made dispose() public, added isDisposed() after SWT. diff --git a/kalyptus/Makefile.cvs b/kalyptus/Makefile.cvs new file mode 100644 index 0000000..3c0d806 --- /dev/null +++ b/kalyptus/Makefile.cvs @@ -0,0 +1,5 @@ + +all: configure + +configure: configure.in + autoconf diff --git a/kalyptus/Makefile.in b/kalyptus/Makefile.in new file mode 100644 index 0000000..8606120 --- /dev/null +++ b/kalyptus/Makefile.in @@ -0,0 +1,53 @@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +perl = @perl@ +install = @INSTALL@ +bin = kalyptus +pm = kdocUtil.pm kdocAstUtil.pm kdocParseDoc.pm kdocLib.pm \ + Ast.pm kalyptusDataDict.pm kalyptusCxxToC.pm \ + kalyptusCxxToObjc.pm kalyptusCxxToJava.pm \ + kalyptusCxxToSmoke.pm kalyptusCxxToCSharp.pm \ + Iter.pm +pmextra = +bindir = ${exec_prefix}/bin +pmdir = ${prefix}/share/kalyptus +srcdocdir= . +VERSION=@Version@ + +all: kalyptus.local + +kalyptus.local: @srcdir@/kalyptus + cp @srcdir@/kalyptus kalyptus.local + perl -npi -e 's%^#\!.*$$%#!'${perl}' -I'${pmdir}'%g;' kalyptus.local + perl -npi -e 's#\$$Version\\\$$#'"${VERSION}"'#g;' kalyptus.local + +install: all + ${install} -d $(DESTDIR)${bindir} + ${install} -m 755 kalyptus.local $(DESTDIR)${bindir}/kalyptus + ${install} -d $(DESTDIR)${pmdir} + for file in ${pm} ${pmextra}; do \ + ${install} -m 644 @srcdir@/$$file $(DESTDIR)${pmdir}; \ + done + +uninstall: + (cd $(DESTDIR)${bindir} && rm -f ${bin}) + (cd $(DESTDIR)${pmdir} && rm -f ${pm}) + -rmdir $(DESTDIR)${bindir} + -rmdir $(DESTDIR)${pmdir} + +clean: + rm -f kalyptus.local + +distclean: clean + rm -f Makefile config.status config.log config.cache perlbin + +srcdoc: + pod2html --flush --title KALYPTUS $(bin) $(pm) \ + --outfile $(srcdocdir)/kalyptus-doc.html +tags: + perltags kalyptus *.pm + +check: + @for dir in $(bin) $(pm); do \ + echo "** Checking: $$dir"; \ + perl -wc $$dir; done diff --git a/kalyptus/README b/kalyptus/README index 362027e..a966384 100644 --- a/kalyptus/README +++ b/kalyptus/README @@ -3,7 +3,7 @@ KALYPTUS -- C, Objective-C and Java bindings generator Version 0.9 -KALYPTUS creates language bindings for TQt and KDE C++ libraries +KALYPTUS creates language bindings for Qt and KDE C++ libraries directly from the headers. Documentation embedded in special doc comments in the source is translated to an appropriate format for the target language. @@ -47,12 +47,12 @@ JAVA Here are some of the shell commands that were used in the conversion process: -Remove any TTQ_OVERRIDE macros from the TQt headers, and remove EXPORT_DOCKCLASS from the +Remove any Q_OVERRIDE macros from the Qt headers, and remove EXPORT_DOCKCLASS from the KDE headers # Generate Java and C++ sources. Copy all the target headers to directory 'test/tmp' -kalyptus -fjava test/tmp/*.h test/tmp/dom/*.h test/tmp/kio/*.h test/tmp/kdeprint/*.h \ - test/tmp/kjs/*.h test/tmp/kparts/*.h test/tmp/kdesu/*.h test/ktextedit/*.h test/tmp/libkmid/*.h +kalyptus -fjava test/tmp/*.h test/tmp/dom/*.h test/tmp/kio/*.h test/tmp/tdeprint/*.h \ + test/tmp/kjs/*.h test/tmp/kparts/*.h test/tmp/tdesu/*.h test/ktextedit/*.h test/tmp/libkmid/*.h # Shorten generated filenames mv DOM__Node.cpp DOMNode.cpp diff --git a/kalyptus/configure.in b/kalyptus/configure.in new file mode 100644 index 0000000..8d19b4c --- /dev/null +++ b/kalyptus/configure.in @@ -0,0 +1,28 @@ +AC_INIT(kalyptus) + +AC_DEFUN(AC_FIND_PERL, +[ +AC_MSG_CHECKING(for perl 5 or greater) +if $srcdir/findperl; then + $1=`cat perlbin` + echo $$1 +else + echo "Couldn't find perl 5 or later. kdoc will not run." + exit 1 +fi +]) + +AC_DEFUN(AC_KALYPTUS_VERSION, +[ +AC_MSG_CHECKING(kalyptus version) +$1=`cat $srcdir/Version | sed 's#Revision##g' | tr -d '\$:'` +echo $$1 +]) + +AC_PROG_INSTALL +AC_FIND_PERL(perl) +AC_SUBST(perl) +AC_KALYPTUS_VERSION(Version) +AC_SUBST(Version) + +AC_OUTPUT(Makefile) diff --git a/kalyptus/dcopidlng b/kalyptus/dcopidlng new file mode 100755 index 0000000..a9add53 --- /dev/null +++ b/kalyptus/dcopidlng @@ -0,0 +1,12 @@ +#!/bin/sh +if [[ -z $KALYPTUS || ! -d $KALYPTUS ]] +then + echo "Please set enviroment variable KALYPTUS to point to your tdebindings/kaltyptus checkout directory" + exit +fi +perl -I$KALYPTUS $KALYPTUS/kalyptus $2 --allow_k_dcop_accessors -f dcopidl $1 2>/tmp/dcopidlng.stderr.$$ +if [[ $? -ne 0 ]] +then + cat /tmp/dcopidlng.stderr.$$ +fi +rm /tmp/dcopidlng.stderr.$$ diff --git a/kalyptus/findperl b/kalyptus/findperl new file mode 100755 index 0000000..451758d --- /dev/null +++ b/kalyptus/findperl @@ -0,0 +1,17 @@ +#!/bin/sh + +test -f perlbin && rm perlbin + +for p in `echo $PATH | tr ":" " "` +do + if [ -x $p/perl ] + then + if $p/perl -e 'require 5.000;' + then + echo $p/perl > perlbin + exit 0 + fi + fi + +done +exit 1 diff --git a/kalyptus/install-sh b/kalyptus/install-sh new file mode 100644 index 0000000..e9de238 --- /dev/null +++ b/kalyptus/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/kalyptus/kalyptus b/kalyptus/kalyptus index 6cdc12d..15e7a27 100644 --- a/kalyptus/kalyptus +++ b/kalyptus/kalyptus @@ -1,8 +1,8 @@ -#!/usr/bin/perl -I/Users/duke/src/kde/kdebindings/kalyptus +#!/usr/bin/perl # KDOC -- C++ and CORBA IDL interface documentation tool. # Sirtaj Singh Kang , Jan 1999. -# $Id: kalyptus,v 1.9 2003/08/31 15:35:11 germaingarand Exp $ +# $Id$ # All files in this project are distributed under the GNU General # Public License. This is Free Software. @@ -22,12 +22,12 @@ use kdocParseDoc; use vars qw/ %rootNodes $declNodeType @includes_list %options @formats_wanted $allow_k_dcop_accessors @includeclasses $includeclasses $skipInternal %defines $defines $match_qt_defines - $libdir $libname $outputdir @libs $parse_global_space $striphpath $doPrivate $readstdin - $Version $quiet $debug $debuggen $parseonly $currentfile $cSourceNode $exe + $libdir $libname $outputdir @libs $parse_global_space $qt_embedded $qt4 $striphpath $doPrivate $readstdin + $Version $tquiet $debug $debuggen $parseonly $currentfile $cSourceNode $exe %formats %flagnames @allowed_k_dcop_accesors $allowed_k_dcop_accesors_re $rootNode @classStack $cNode $globalSpaceClassName $lastLine $docNode @includes $cpp $defcppcmd $cppcmd $docincluded - $inExtern %stats %definitions @inputqueue @codeqobject /; + $inExtern $inNamespace %stats %definitions @inputqueue @codeqobject @qt4_codeqobject @qte_codeqobject /; ## globals @@ -52,7 +52,7 @@ $includeclasses = ""; $doPrivate = 0; $Version = "0.9"; -$quiet = 0; +$tquiet = 0; $debug = 0; $debuggen = 0; $parseonly = 0; @@ -82,11 +82,36 @@ public: private: CODE +@qt4_codeqobject = split "\n", < "kalyptusCxxToJava", "c" => "kalyptusCxxToC", - "objc" => "kalyptusCxxToObjc", "dcopidl" => "kalyptusCxxToDcopIDL", - "smoke" => "kalyptusCxxToSmoke", "csharp" => "kalyptusCxxToCSharp", - "ECMA" => "kalyptusCxxToECMA", "swig" => "kalyptusCxxToSwig" ); +%formats = ( "java" => "kalyptusCxxToJava", "jni" => "kalyptusCxxToJNI", + "dcopidl" => "kalyptusCxxToDcopIDL", + "smoke" => "kalyptusCxxToSmoke", "csharp" => "kalyptusCxxToCSharp", "kimono" => "kalyptusCxxToKimono", + "ECMA" => "kalyptusCxxToECMA", "swig" => "kalyptusCxxToSwig", + "KDOMECMA" => "kalyptusKDOMEcma"); # these are for expansion of method flags %flagnames = ( v => 'virtual', 's' => 'static', p => 'pure', @@ -104,22 +129,23 @@ $allowed_k_dcop_accesors_re = join("|", @allowed_k_dcop_accesors); _STYLE_PLATINUM => '', _STYLE_SGI => '', _STYLE_WINDOWS => '', - TQT_STATIC_CONST => 'static const', - TTQ_EXPORT => '', - TTQ_REFCOUNT => '', + QT_STATIC_CONST => 'static const', + Q_EXPORT => '', + Q_EXPORT_CODECS_BIG5 => '', + Q_REFCOUNT => '', TQM_EXPORT_CANVAS => '', TQM_EXPORT_DNS => '', TQM_EXPORT_ICONVIEW => '', TQM_EXPORT_NETWORK => '', TQM_EXPORT_SQL => '', TQM_EXPORT_WORKSPACE => '', - TQT_NO_REMOTE => 'TQT_NO_REMOTE', - TQT_ACCESSIBILITY_SUPPORT => 'TQT_ACCESSIBILITY_SUPPORT', - TTQ_WS_X11 => 'TTQ_WS_X11', - TTQ_DISABLE_COPY => 'TTQ_DISABLE_COPY', - TTQ_WS_TQWS => 'undef', - TTQ_WS_MAC => 'undef', - TTQ_OBJECT => <<'CODE', + QT_NO_REMOTE => 'QT_NO_REMOTE', + QT_ACCESSIBILITY_SUPPORT => 'QT_ACCESSIBILITY_SUPPORT', + Q_WS_X11 => 'Q_WS_X11', + Q_DISABLE_COPY => 'Q_DISABLE_COPY', + Q_WS_QWS => 'undef', + Q_WS_MAC => 'undef', + Q_OBJECT => <<'CODE', public: virtual TQMetaObject *metaObject() const; virtual const char *className() const; @@ -164,6 +190,8 @@ GetOptions( \%options, "xref|l=s", \@libs, "classes|c=s", \@includeclasses, "globspace", \$parse_global_space, + "qte", \$qt_embedded, + "qt4", \$qt4, "allow_k_dcop_accessors", \$allow_k_dcop_accessors, "cpp|P", \$cpp, @@ -173,7 +201,7 @@ GetOptions( \%options, "define=s", \%defines, # define a single preprocessing symbol "defines=s", \$defines, # file containing preprocessing symbols, one per line - "quiet|q", \$quiet, + "tquiet|q", \$tquiet, "debug|D", \$debug, # debug the parsing "debuggen", \$debuggen, # debug the file generation "parse-only", \$parseonly ) @@ -193,7 +221,7 @@ else { if ($#includeclasses>=0) { $includeclasses = join (" ", @includeclasses); - print "Using Classes: $includeclasses\n" unless $quiet; + print "Using Classes: $includeclasses\n" unless $tquiet; } if ( $#includes >= 0 && !$cpp ) { @@ -222,13 +250,13 @@ if( $defines ) } } -# Check the %defines hash for TQT_* symbols and compile the corresponding RE +# Check the %defines hash for QT_* symbols and compile the corresponding RE # Otherwise, compile the default ones. Used for filtering in readCxxLine. -if ( my @qt_defines = map { ($_=~m/^TQT_(.*)/)[0] } keys %defines) +if ( my @qt_defines = map { ($_=~m/^QT_(.*)/)[0] } keys %defines) { - my $regexp = "m/^#\\s*ifn?def\\s+TQT_(?:" . join('|', map { "\$qt_defines[$_]" } 0..$#qt_defines).")/o"; + my $regexp = "m/^#\\s*ifn?def\\s+QT_(?:" . join('|', map { "\$qt_defines[$_]" } 0..$#qt_defines).")/o"; $match_qt_defines = eval "sub { my \$s=shift; - \$s=~/^#\\s*if(n)?def/ || return 0; + \$s=~/^#\\s*if(n)?def\\s+QT_/ || return 0; if(!\$1) { return \$s=~$regexp ? 0:1 } else { return \$s=~$regexp ? 1:0 } }"; @@ -236,18 +264,18 @@ if ( my @qt_defines = map { ($_=~m/^TQT_(.*)/)[0] } keys %defines) } else { - $match_qt_defines = eval q£ + $match_qt_defines = eval q{ sub { my $s = shift; - $s =~ m/^\#\s*ifndef\s+TQT_NO_(?:REMOTE| # not in the default compile options + $s =~ m/^\#\s*ifndef\s+QT_NO_(?:REMOTE| # not in the default compile options NIS| # ... XINERAMA| IMAGEIO_(?:MNG|JPEG)| STYLE_(?:MAC|INTERLACE|COMPACT) )/x; } - £; + }; die if $@; } # Check if there any files to process. @@ -302,7 +330,7 @@ sub readLibraries require kdocLib; foreach my $lib ( @libs ) { - print "$exe: reading lib: $lib\n" unless $quiet; + print "$exe: reading lib: $lib\n" unless $tquiet; my $relpath = exists $options{url} ? $options{url} : $outputdir; @@ -334,11 +362,11 @@ sub parseFiles || croak "Can't preprocess $currentfile"; } else { - open( INPUT, "$currentfile" ) + open( INPUT, "tqt-replace-stream $currentfile |" ) || croak "Can't read from $currentfile"; } - print STDERR "$exe: processing $currentfile\n" unless $quiet; + print STDERR "$exe: processing $currentfile\n" unless $tquiet; # reset vars $rootNode = getRoot( $lang ); @@ -356,6 +384,7 @@ sub parseFiles @classStack = (); $cNode = $rootNode; $inExtern = 0; + $inNamespace = 0; # parse my $k = undef; @@ -386,7 +415,7 @@ sub writeDocumentation require $pack.".pm"; print STDERR "Generating bindings for $format ", - "language...\n" unless $quiet; + "language...\n" unless $tquiet; my $f = "$pack\::writeDoc"; &$f( $libname, $node, $outputdir, \%options ); @@ -425,7 +454,7 @@ sub readSourceLine =head2 readCxxLine Reads a C++ source line, skipping comments, blank lines, - preprocessor tokens and the TTQ_OBJECT macro + preprocessor tokens and the Q_OBJECT macro =cut @@ -453,12 +482,31 @@ LOOP: } } - if ( $p =~ /^\s*TTQ_OBJECT/ ) { - push @inputqueue, @codeqobject; + if ( $p =~ /^\s*Q_OBJECT/ ) { + if ($qt_embedded) { + push @inputqueue, @qte_codeqobject; + } elsif ($qt4) { + push @inputqueue, @qt4_codeqobject; + } else { + push @inputqueue, @codeqobject; + } next; } # Hack, waiting for real handling of preprocessor defines - $p =~ s/TQT_STATIC_CONST/static const/; + $p =~ s/QT_MODULE\(\w+\)//; + $p =~ s/QT_STATIC_CONST/static const/; + $p =~ s/QT_WEAK_SYMBOL//; + $p =~ s/QT_MOC_COMPAT//; + $p =~ s/Q_EXPORT_CODECS_BIG5//; + $p =~ s/QT_COMPAT / /; + $p =~ s/Q_DISABLE_COPY\((\w+)\)/$1(const $1 &);\n$1 &operator=(const $1 &);/; + $p =~ s/TQWIDGETSIZE_MAX/32767/; # Qt/E uses this #define as an enum value - yuck! + $p =~ s/Q_SIGNALS/signals/; + $p =~ s/ASYNC/void/; + $p =~ s/[A-Z_]*_EXPORT_DEPRECATED//; + $p =~ s/[A-Z_]*_EXPORT\s/ /; + $p =~ s/EXPORT_DOCKCLASS//; + $p =~ s/DLL_IMP_EXP_KMDICLASS//; $p =~ s/KSVG_GET/KJS::Value get();/; $p =~ s/KSVG_BASECLASS_GET/KJS::Value get();/; $p =~ s/KSVG_BRIDGE/KJS::ObjectImp *bridge();/; @@ -469,20 +517,44 @@ LOOP: if ( $p =~ m/KSVG_DEFINE_PROTOTYPE\((\w+)\)/ ) { push @inputqueue, split('\n',"namespace KSVG {\nclass $1 {\n};\n};"); } + # Bother the same again for KDOM :/ + $p =~ s/KDOM_GET/KJS::Value get();/; + $p =~ s/KDOM_BASECLASS_GET/KJS::Value get();/; + $p =~ s/KDOM_FORWARDGET/KJS::Value getforward();/; + $p =~ s/KDOM_PUT/bool put();/; + $p =~ s/KDOM_FORWARDPUT/bool putforward();/; + $p =~ s/KDOM_BASECLASS/virtual KJS::Value cache();/; + $p =~ s/KDOM_CAST/KJS::Value cast();/; + if ( $p =~ m/KDOM_DEFINE_PROTOTYPE\((\w+)\)/ ) { + push @inputqueue, split('\n',"namespace KDOM {\nclass $1 {\n};\n};"); + } + next if ( $p =~ /^\s*$/s ); # blank lines -# || $p =~ /^\s*TTQ_OBJECT/ # TQObject macro +# || $p =~ /^\s*Q_OBJECT/ # TQObject macro # ); # - next if ( $p =~ /^\s*TTQ_ENUMS/ # ignore TTQ_ENUMS - || $p =~ /^\s*TTQ_PROPERTY/ # and TTQ_PROPERTY - || $p =~ /^\s*TTQ_OVERRIDE/ # and TTQ_OVERRIDE - || $p =~ /^\s*TTQ_SETS/ - || $p =~ /^\s*TTQ_DUMMY_COMPARISON_OPERATOR/ + next if ( $p =~ /^\s*Q_ENUMS/ # ignore Q_ENUMS + || $p =~ /^\s*TQ_OBJECT/ # and TQ_OBJECT + || $p =~ /^\s*Q_FLAGS/ # and Q_FLAGS + || $p =~ /^\s*Q_DECLARE_FLAGS/ # and Q_DECLARE_FLAGS + || ( !$qt4 && $p =~ /^\s*Q_PROPERTY/ ) # and Q_PROPERTY + || $p =~ /^\s*TQDOC_PROPERTY/ + || $p =~ /^\s*Q_GADGET/ + || $p =~ /^\s*Q_OVERRIDE/ # and Q_OVERRIDE + || $p =~ /^\s*Q_SETS/ + || $p =~ /^\s*Q_DUMMY_COMPARISON_OPERATOR/ || $p =~ /^\s*K_SYCOCATYPE/ # and K_SYCOCA stuff || $p =~ /^\s*K_SYCOCAFACTORY/ # || $p =~ /^\s*KSVG_/ # and KSVG stuff ;) + || $p =~ /^\s*KDOM_/ # and KDOM stuff :( + || $p =~ /^\s*Q_DECLARE_FLAGS/ + || $p =~ /^\s*Q_DECLARE_OPERATORS_FOR_FLAGS/ + || $p =~ /^\s*Q_DECLARE_PRIVATE/ + || $p =~ /^\s*Q_DECLARE_TYPEINFO/ + || $p =~ /^\s*Q_PRIVATE_SLOT/ + || $p =~ /^\s*Q_DECLARE_SHARED/ ); push @includes_list, $1 if $p =~ /^#include\s+?\s*$/; @@ -503,14 +575,31 @@ LOOP: else { # Skip platform-specific stuff, or #if 0 stuff # or #else of something we parsed (e.g. for TQKeySequence) - if ( $p =~ m/^#\s*ifdef\s*TTQ_WS_/ or - $p =~ m/^#\s*if\s+defined\(TTQ_WS_/ or - $p =~ m/^#\s*if\s+defined\(TTQ_OS_/ or - $p =~ m/^#\s*if\s+defined\(TTQ_CC_/ or - $p =~ m/^#\s*if\s+defined\(TQT_THREAD_SUPPORT/ or + if ( $p =~ m/^#\s*ifdef\s*Q_WS_/ or + $p =~ m/^#\s*if\s+defined\(Q_WS_/ or + ($p =~ m/^#\s*ifdef\s+_WS_QWS_/ and $qt_embedded) or + ($p =~ m/^#\s*ifndef\s+QT_NO_MIMECLIPBOARD/ and $qt_embedded) or + ($p =~ m/^#\s*if\s+defined\(_WS_X11_/ and $qt_embedded) or + ($p =~ m/^#\s*if\s+defined\(Q_WS_X11_/ and $qt_embedded) or + ($p =~ m/^#\s*if\s+defined\(Q_WS_WIN_/ and $qt_embedded) or + ($p =~ m/^#\s*if\s+defined\(_WS_MAC_/ and $qt_embedded) or + ($p =~ m/^#\s*if\s+defined\(Q_INCOMPATIBLE_3_0_ADDONS/ and $qt_embedded) or + $p =~ m/^#\s*ifndef\s+QT_NO_STL/ or + $p =~ m/^#\s*if\s+defined\s*\(Q_OS_/ or + $p =~ m/^#\s*if\s+defined\(Q_CC_/ or + $p =~ m/^#\s*if\s+defined\(QT_THREAD_SUPPORT/ or $p =~ m/^#\s*else/ or - $p =~ m/^#\s*if\s+defined\(TTQ_FULL_TEMPLATE_INSTANTIATION/ or + $p =~ m/^#\s*if\s+defined\(Q_FULL_TEMPLATE_INSTANTIATION/ or + $p =~ m/^#\s*ifdef\s+QT_WORKSPACE_WINDOWMODE/ or + $p =~ m/^#\s*ifdef\s+QT_COMPAT/ or + $p =~ m/^#\s*if\s+defined\s*\(?QT_COMPAT/ or $p =~ m/^#\s*ifdef\s+CONTAINER_CUSTOM_WIDGETS/ or + $p =~ m/^#\s*ifdef\s+QT3_SUPPORT/ or + $p =~ m/^#\s*ifdef\s+Q_MOC_RUN/ or + $p =~ m/^#\s*if\s+defined\s*\(QT3_SUPPORT/ or + $p =~ m/^#\s*if\s+defined\s*\(qdoc/ or + $p =~ m/^#\s*ifndef\s+QT_NO_MEMBER_TEMPLATES/ or + $p =~ m/^#if\s*!defined\(Q_NO_USING_KEYWORD\)/ or &$match_qt_defines( $p ) or $p =~ m/^#\s*if\s+0\s+/ ) { my $if_depth = 1; @@ -519,7 +608,7 @@ LOOP: last if !defined $p; $if_depth++ if $p =~ m/^#\s*if/; $if_depth-- if $p =~ m/^#\s*endif/; - # Exit at #else in the #ifdef TQT_NO_ACCEL/#else/#endif case + # Exit at #else in the #ifdef QT_NO_ACCEL/#else/#endif case last if $if_depth == 1 && $p =~ m/^#\s*else\s/; #ignore elif for now print "Skipping ifdef'ed line: $p" if $debug; @@ -638,6 +727,9 @@ sub readDecl $declNodeType = "c"; return $l; } + elsif ( $l =~ /Q_PROPERTY/ ) { # property + return $l; + } do { $decl .= $l; @@ -694,7 +786,11 @@ sub identifyDecl my $newNode = undef; my $skipBlock = 0; - + my $isDeprecated = 0; + + if ( $decl =~ s/KDE_DEPRECATED// ) { + $isDeprecated = 1; + } # Doc comment if ( $declNodeType eq "c" ) { $docNode = kdocParseDoc::newDocComment( $decl ); @@ -713,7 +809,12 @@ sub identifyDecl elsif ( $declNodeType eq "k" ) { $cNode->AddProp( "DcopExported", 1 ); } + # properties + elsif ( $decl =~ s/Q_PROPERTY// ) { + print "Property: <$1>\n" if $debug; + $newNode = newProperty( $decl ); + } # Typedef struct/class elsif ( $decl =~ /^\s*typedef \s+(struct|union|class|enum) @@ -737,8 +838,8 @@ sub identifyDecl # Typedef elsif ( $decl =~ /^\s*typedef\s+ (?:typename\s+)? # `typename' keyword - (.*?\s*[\*&]?) # type - \s+([-\w_\:]+) # name + (.*?\s*[\*&>]?) # type + \s*([-\w_\:]+) # name \s*((?:\[[-\w_\:<>\s]*\])*) # array \s*[{;]\s*$/xs ) { @@ -758,15 +859,16 @@ sub identifyDecl # Class/Struct elsif ( $decl =~ /^\s*((?:template\s*<.*>)?) # 1 template \s*(class|struct|union|namespace) # 2 struct type + (?:\s*TQ[A-Z_]*EXPORT[A-Z_]*)? (?:\s*Q[A-Z_]*EXPORT[A-Z_]*)? - (?:\s*TTQ_PACKED)? - (?:\s*TTQ_REFCOUNT)? + (?:\s*Q_PACKED)? + (?:\s*Q_REFCOUNT)? \s+([\w_]+ # 3 name (?:<[\w_ :,]+?>)? # maybe explicit template # (eat chars between <> non-hungry) (?:::[\w_]+)* # maybe nested ) - (.*?) # 4 inheritance + ([^\(]*?) # 4 inheritance ([;{])/xs ) { # 5 rest print "Class: [$1]\n\t[$2]\n\t[$3]\n\t[$4]\n\t[$5]\n" if $debug; @@ -781,7 +883,14 @@ sub identifyDecl } } - + if ($ntype eq 'namespace') { + if ($decl =~ /}/) { + return 0; + } + # Set a flag to indicate we're in a multi-line namespace declaration + $inNamespace = 1; + } + my @inherits = (); $tmpl =~ s/<(.*)>/$1/ if $tmpl ne ""; @@ -793,7 +902,15 @@ sub identifyDecl } $newNode = newClass( $tmpl, $ntype, - $name, $endtag, @inherits ); + $name, $endtag, $isDeprecated, @inherits ); + + if ($decl =~ /};/) { + # If the declaration was all on one line ending with a '};', + # then pop the new node + $cNode = pop @classStack; + print "end decl: popped $cNode->{astNodeName}\n" + if $debug; + } } # IDL compound node elsif( $decl =~ /^\s*(module|interface|exception) # struct type @@ -819,9 +936,10 @@ sub identifyDecl $newNode = newIDLstruct( $type, $name, $fwd, $complete, @in ); } # Method - elsif ( $decl =~ /^\s*([^=]+?(?:operator\s*(?:\(\)|.?=)\s*)?) # ret+nm + elsif ( $decl =~ /^\s*(?:(?:class|struct)\s*)?([^=]+?(?:operator\s*(?:\(\)|.?=)\s*)?) # ret+nm \( (.*?) \) # parameters \s*((?:const)?)\s* + (?:throw\s*\(.*?\))? \s*((?:=\s*0(?:L?))?)\s* # Pureness. is "0L" allowed? \s*[;{]+/xs ) { # rest @@ -836,16 +954,17 @@ sub identifyDecl my $const = $3 eq "" ? 0 : 1; my $pure = $4 eq "" ? 0 : 1; $tpn =~ s/\s+/ /g; + $tpn =~ s/operator\s+([^\w])/operator$1/g; $params =~ s/\s+/ /g; print "Method: R+N:[$tpn]\n\tP:[$params]\n\t[$const]\n" if $debug; if ( $tpn =~ /((?:\w+\s*::\s*)?operator.*?)\s*$/ # operator - || $tpn =~ /((?:\w*\s*::\s*~?)?[-\w:]+)\s*$/ ) { # normal + || $tpn =~ /((?:\w*\s*::\s*~?)?[-\w:]+)\s*$/ ) { # normal my $name = $1; $tpn = $`; $newNode = newMethod( $tpn, $name, - $params, $const, $pure ); + $params, $const, $pure, $isDeprecated ); } $skipBlock = 1; # FIXME check end token before doing this! @@ -877,8 +996,10 @@ sub identifyDecl my $val = $4; my $end = $5; - if ( $type !~ /^friend\s+class\s*/ ) { - print "Var: [$name] type: [$type$arr] val: [$val]\n" + $type =~ s/\s+/ /g; + + if ( $type !~ /^friend\s+class\s*/ && $type.$name ne "struct" ) { + print "Var: [$name] type: [$type$arr] val: [$val]\n" if $debug; $newNode = newVar( $type.$arr, $name, $val ); @@ -931,12 +1052,11 @@ sub identifyDecl $skipBlock = 1 if $end eq '{'; } # end of an "extern" block - elsif ( $decl =~ /^\s*}\s*$/ ) { + elsif ( $decl =~ /^\s*}\s*$/ && $inExtern ) { $inExtern = 0; } # end of an in-block declaration - elsif ( $decl =~ /^\s*}\s*(.*?)\s*;\s*$/ ) { - + elsif ( $decl =~ /^\s*}\s*(.*?)\s*;\s*$/ || ($decl =~ /^\s*}\s*$/ && $inNamespace) ) { if ( $cNode->{astNodeName} eq "--" ) { # structure typedefs should have no name preassigned. # If they do, then the name in @@ -950,6 +1070,11 @@ sub identifyDecl $siblings->{ $1 } = $cNode; } + # C++ namespaces end with a '}', and not '};' like classes + if ($decl =~ /^\s*}\s*$/ ) { + $inNamespace = 0; + } + if ( $#classStack < 0 ) { confess "close decl found, but no class in stack!" ; $cNode = $rootNode; @@ -966,9 +1091,13 @@ sub identifyDecl $skipBlock = 1; } # explicit template instantiation, or friend template - elsif ( $decl =~ /(template|friend)\s+class\s+(?:Q[A-Z_]*EXPORT[A-Z_]*\s*)?\w+\s*<.*>\s*;/x ) { + elsif ( $decl =~ /(template|friend)\s+class\s+(?:TQ[A-Z_]*EXPORT[A-Z_]*\s*)?\w+\s*<.*>\s*;/x ) { # Nothing to be done with those. } + # explicit template instantiation, or friend template + elsif ( $decl =~ /(template|friend)\s+class\s+(?:Q[A-Z_]*EXPORT[A-Z_]*\s*)?\w+\s*<.*>\s*;/x ) { + # Nothing to be done with those (same as above, but for QT not TQT). + } else { ## decl is unidentified. @@ -1060,13 +1189,15 @@ sub initEnum ($name = $end) if $name eq "" && $end ne ""; $params =~ s#\s+# #sg; # no newlines + $params =~ s#\s*/\*([^\*]/|\*[^/]|[^\*/])*\*/##g; # strip out comments $params = $1 if $params =~ /^\s*{?(.*)}/; + $params =~ s/,\s*$/ /; print "$name params: [$params]\n" if $debug; - my ( $node ) = Ast::New( $name ); $node->AddProp( "NodeType", "enum" ); $node->AddProp( "Params", $params ); + $node->AddProp( "Source", $cSourceNode ); makeParamList( $node, $params, 1 ); # Adds the ParamList property containing the list of param nodes kdocAstUtil::attachChild( $cNode, $node ); @@ -1125,7 +1256,7 @@ sub newIDLstruct =head2 newClass - Parameters: tmplArgs, cNodeType, name, endTag, @inheritlist + Parameters: tmplArgs, cNodeType, name, endTag, isDeprecated, @inheritlist Handles a class declaration (also fwd decls). @@ -1133,7 +1264,7 @@ sub newIDLstruct sub newClass { - my( $tmplArgs, $cNodeType, $name, $endTag ) = @_; + my( $tmplArgs, $cNodeType, $name, $endTag, $isDeprecated ) = @_; my $access = "private"; $access = "public" if $cNodeType ne "class"; @@ -1150,6 +1281,8 @@ sub newClass $node->AddProp( "KidAccess", $access ); kdocAstUtil::attachChild( $cNode, $node ); } + # Discard any doc comment against a forward decl + undef $docNode; return $node; } @@ -1160,17 +1293,23 @@ sub newClass $node->AddProp( "NodeType", $cNodeType ); $node->AddProp( "Compound", 1 ); $node->AddProp( "Source", $cSourceNode ); + + if ($cNodeType eq 'namespace') { + $node->AddPropList( "Sources", $cSourceNode ); + } $node->AddProp( "KidAccess", $access ); $node->AddProp( "Tmpl", $tmplArgs ) unless $tmplArgs eq ""; + $node->AddProp( "Deprecated", $isDeprecated ); + if ( !defined $oldnode ) { kdocAstUtil::attachChild( $cNode, $node ); } # inheritance - foreach my $ances ( splice (@_, 4) ) { + foreach my $ances ( splice (@_, 5) ) { my $type = ""; my $name = $ances; my $intmpl = undef; @@ -1323,7 +1462,7 @@ sub newTypedefComp =head2 newMethod - Parameters: retType, name, params, const, pure? + Parameters: retType, name, params, const, pure?, deprecated? Handles a new method declaration or definition. @@ -1334,7 +1473,7 @@ my $theSourceNode = $cSourceNode; sub newMethod { - my ( $retType, $name, $params, $const, $pure ) = @_; + my ( $retType, $name, $params, $const, $pure, $deprecated ) = @_; my $parent = $cNode; my $class; @@ -1405,9 +1544,12 @@ sub newMethod $opsNode->AddProp( "KidAccess", "public" ); kdocAstUtil::attachChild( $cNode, $opsNode ); } + # Add a special 'Source' property for methods in global space + $cNode->AddProp( "Source", $theSourceNode ); + unless( $theSourceNode == $cSourceNode ) { $theSourceNode = $cSourceNode; - $opsNode->AddPropList( "Sources", $theSourceNode ); # sources are scattered across TQt + $opsNode->AddPropList( "Sources", $theSourceNode ); # sources are scattered across Qt } $parent = $opsNode; } @@ -1434,6 +1576,11 @@ sub newMethod $retType =~ s/virtual//g; } + if( $retType =~ /explicit\s*/ ) { + $flags .= "t"; + $retType =~ s/explicit\s*//g; + } + print "\n" if $flags ne "" && $debug; if ( !defined $parent->{KidAccess} ) { @@ -1458,11 +1605,14 @@ sub newMethod $flags .= "n"; } + $retType =~ s/TQM?_EXPORT[_A-Z]*\s*//; $retType =~ s/QM?_EXPORT[_A-Z]*\s*//; $retType =~ s/inline\s+//; $retType =~ s/extern\s+//; $retType =~ s/^\s*//g; $retType =~ s/\s*$//g; + $retType =~ s/^class\s/ /; # Remove redundant class forward decln's + $retType =~ s/AddProp( "ReturnType", $retType ); $node->AddProp( "Params", $params ); # The raw string with the whole param list makeParamList( $node, $params, 0 ); # Adds the ParamList property containing the list of param nodes + + $node->AddProp( "Deprecated", $deprecated ); $parent->AddProp( "Pure", 1 ) if $pure; kdocAstUtil::attachChild( $parent, $node ); + return $node; } @@ -1505,7 +1658,8 @@ sub makeParamList($$$) { my ( $methodNode, $params, $isEnum ) = @_; $params =~ s/\s+/ /g; # normalize multiple spaces/tabs into a single one - $params =~ s/\s*([,\*\&])\s*/$1 /g; # normalize spaces before and after *, & and ',' + $params =~ s/\s*([\*\&])\s*/$1 /g; # normalize spaces before and after *, & + $params =~ s/\s*(,)([^'\s])\s*/$1 $2/g; # And after ',', but not if inside single quotes $params =~ s/^\s*void\s*$//; # foo(void) ==> foo() $params =~ s/^\s*$//; # Make sure the property always exists, makes iteration over it easier @@ -1520,12 +1674,19 @@ sub makeParamList($$$) my $defaultparam; $arg =~ s/\s*([^\s].*[^\s])\s*/$1/; # stripWhiteSpace $arg =~ s/(\w+)\[\]/\* $1/; # Turn [] array into * + $arg =~ s/^class //; # Remove any redundant 'class' forward decln's - # The RE below reads as: = ( string constant or char + # The RE below reads as: = ( string constant or char or cast to numeric literal # or some word/number, with optional bitwise shifts, OR'ed or +'ed flags, and/or function call ). - if ( $arg =~ s/\s*=\s*(("[^\"]*")|(\'.\')|(([-\w:~]*)\s*([<>\|\+-]*\s*\w*\s*)*(\([^(]*\))?))// ) { + if ( $arg =~ s/\s*=\s*(("[^\"]*")|\([^)]*\)\s*[\+-]?\s*[0-9]+|(\'.\')|(([-\w:~]*)\s*([<>\|\+-]*\s*[\w:._]*\s*)*(\([^(]*\))?))// ) { $defaultparam = $1; } + + if (defined $defaultparam && $isEnum) { + # Remove any casts in enum values, for example this in kfileitem.h: + # 'enum { Unknown = (mode_t) - 1 };' + $defaultparam =~ s/\([^\)]+\)(.*[0-9].*)/$1/; + } # Separate arg type from arg name, if the latter is specified if ( $arg =~ /(.*)\s+([\w_]+)\s*$/ || $arg =~ /(.*)\(\s*\*\s([\w_]+)\)\s*\((.*)\)\s*$/ ) { @@ -1611,6 +1772,36 @@ sub newVar return $node; } +=head2 newProperty + + Parameters: property + + Handles a property + +=cut + +sub newProperty +{ + my ( $property ) = @_; + + $property =~ s/^\s+|\s+$//g; + my @items = split(/ /,$property); + + do { + my ( $node ) = Ast::New( $items[1] ); + + $node->AddProp( "NodeType", "property" ); + $node->AddProp( "type", $items[0] ); + $node->AddProp( "READ", $items[3] ); + $node->AddProp( "WRITE", $items[5] ); + $node->AddProp( "NOTIFY", $items[7] ); + + $cNode->{KidAccess} = "public"; + kdocAstUtil::attachChild( $cNode, $node ); + return $node; + + } if defined $items[1]; +} =head2 show_usage diff --git a/kalyptus/kalyptus.spec.in b/kalyptus/kalyptus.spec.in new file mode 100644 index 0000000..6548131 --- /dev/null +++ b/kalyptus/kalyptus.spec.in @@ -0,0 +1,62 @@ +# You might want to change the next 2 lines, the rest should be ok +%define qtdir /usr/lib/qt-3.0.0 +Prefix: /opt/trinity + +Name: kalyptus +Icon: kde-icon.xpm +Summary: Bindings generation tools for the K Desktop Environment (KDE) 3.0. +Version: @VERSION@ +Release: 1 +Epoch: 1 +#Source: ftp://ftp.kde.org/pub/kde/stable/%{version}/distribution/tar/generic/source/kdoc-%{version}.tar.bz2 +Group: Bindings +BuildRoot: /var/tmp/%{name}-buildroot +Copyright: GPL +BuildArch: noarch + +%description +Bindings generation tools for the K Desktop Environment 3.0. + +%prep +rm -rf $RPM_BUILD_ROOT + +%setup -q -n %{name} +make -f Makefile.cvs + +%build +export TDEDIR=%{prefix} QTDIR=%{qtdir} +CXXFLAGS="$RPM_OPT_FLAGS -I%{prefix}/include/kde" ./configure \ + --prefix=%{prefix} +make CXXFLAGS="$RPM_OPT_FLAGS -DNO_DEBUG -DNDEBUG" + +%install +make install DESTDIR=$RPM_BUILD_ROOT + +cd $RPM_BUILD_ROOT +find . -type d | sed '1,3d;s,^\.,\%attr(-\,root\,root) \%dir ,' > \ + $RPM_BUILD_DIR/file.list.%{name} +perl -pi -e "s|\%attr\(-,root,root\) \%dir %{prefix}/man/man1||" $RPM_BUILD_DIR/file.list.%{name} +perl -pi -e "s|\%attr\(-,root,root\) \%dir %{prefix}/man||" $RPM_BUILD_DIR/file.list.%{name} +perl -pi -e "s|\%attr\(-,root,root\) \%dir %{prefix}/bin||" $RPM_BUILD_DIR/file.list.%{name} +perl -pi -e "s|\%attr\(-,root,root\) \%dir %{prefix}/lib$||" $RPM_BUILD_DIR/file.list.%{name} + +find . -type f | sed -e 's,^\.,\%attr(-\,root\,root) ,' \ + -e '/\/config\//s|^|%config|' >> \ + $RPM_BUILD_DIR/file.list.%{name} + +find . -type l | sed 's,^\.,\%attr(-\,root\,root) ,' >> \ + $RPM_BUILD_DIR/file.list.%{name} + +sed -e "s,%{prefix}/man/.*,&*,g" $RPM_BUILD_DIR/file.list.%{name} >$RPM_BUILD_DIR/file.list.%{name}.new +mv -f $RPM_BUILD_DIR/file.list.%{name}.new $RPM_BUILD_DIR/file.list.%{name} + +echo "%docdir %{prefix}/doc/kde" >> $RPM_BUILD_DIR/file.list.%{name} + +%clean +rm -rf $RPM_BUILD_ROOT $RPM_BUILD_DIR/file.list.%{name} + +%files -f ../file.list.%{name} + +%changelog +* Thu May 11 2000 Bernhard Rosenkraenzer +- initial diff --git a/kalyptus/kalyptusCxxToCSharp.pm b/kalyptus/kalyptusCxxToCSharp.pm new file mode 100644 index 0000000..400611e --- /dev/null +++ b/kalyptus/kalyptusCxxToCSharp.pm @@ -0,0 +1,764 @@ +#*************************************************************************** +# copyright : (C) 2000-2001 Lost Highway Ltd. All Rights Reserved. +# (C) 2002 Adam Treat. All Rights Reserved. +# email : manyoso@yahoo.com +# author : Adam Treat & Richard Dale. +#***************************************************************************/ + +#/*************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation; either version 2 of the License, or * +# * (at your option) any later version. * +# * * +#***************************************************************************/ + +package kalyptusCxxToCSharp; + +use File::Path; +use File::Basename; + +use Carp; +use Ast; +use kdocAstUtil; +use kdocUtil; +use Iter; +use kalyptusDataDict; + +use strict; +no strict "subs"; + +use vars qw/ @clist $host $who $now $gentext %functionId $docTop + $lib $rootnode $outputdir $opt $debug $typeprefix $eventHandlerCount + $pastaccess $pastname $pastreturn $pastparams $nullctor $constructorCount *CLASS *HEADER *TQTCTYPES *KDETYPES /; + +BEGIN +{ + @clist = (); + + + # Page footer + + $who = kdocUtil::userName(); + $host = kdocUtil::hostName(); + $now = localtime; + $gentext = "$who using kalyptus $main::Version."; + + $docTop =<{astNodeName}\n" if $debug; + if( exists $node->{ExtSource} ) { + warn "Trying to write doc for ".$node->{AstNodeName}. + " from ".$node->{ExtSource}."\n"; + return; + } + + my $typeName = $node->{astNodeName}."*"; + + if ( kalyptusDataDict::ctypemap($typeName) eq "" ) { + $typeprefix = ($typeName =~ /^Q/ ? "qt_" : "kde_"); + kalyptusDataDict::setctypemap($typeName, $typeprefix.$node->{astNodeName}."*"); + print "'$typeName' => '$typeprefix$typeName',\n"; + } elsif ( kalyptusDataDict::ctypemap($typeName) =~ /^qt_/ ) { + $typeprefix = "qt_"; + } elsif ( kalyptusDataDict::ctypemap($typeName) =~ /^kde_/ ) { + $typeprefix = "kde_"; + } else { + $typeprefix = "kde_"; + } + + my $file = "$outputdir/".join("__", kdocAstUtil::heritage($node)).".cs"; + my $docnode = $node->{DocNode}; + my @list = (); + my $version = undef; + my $author = undef; + + if( $#{$node->{Kids}} < 0 || $node->{Access} eq "private") { + return; + } + + open( CLASS, ">$file" ) || die "Couldn't create $file\n"; + $file =~ s/\.h/.cpp/; + + my $short = ""; + my $extra = ""; + + print CLASS "// ", $node->{astNodeName}, ".cs - ", $node->{astNodeName}, " c-sharp implementation."; + print CLASS $docTop; + + print CLASS "\nnamespace Qt {"; + print CLASS "\n\n\tusing Qt;"; + print CLASS "\n\tusing System;"; + print CLASS "\n\tusing System.Runtime.InteropServices;"; + + # ancestors + my @ancestors = (); + Iter::Ancestors( $node, $rootnode, undef, undef, + sub { # print + my ( $ances, $name, $type, $template ) = @_; + push @ancestors, $name; + }, + undef + ); + + if ( $#ancestors < 0 ) { + print CLASS "\n\n\tpublic class ", $node->{astNodeName}, " : QtSupport {"; + + if ( kalyptusDataDict::interfacemap($node->{astNodeName}) ne () ) { + $file = "$outputdir/".join("__", kdocAstUtil::heritage($node)).".cs"; + my $interfaceName = kalyptusDataDict::interfacemap($node->{astNodeName}); + $file =~ s/$node->{astNodeName}/$interfaceName/; + open( INTERFACE, ">$file" ) || die "Couldn't create $file\n"; + print INTERFACE "// ", kalyptusDataDict::interfacemap($node->{astNodeName}), ".cs - ", kalyptusDataDict::interfacemap($node->{astNodeName}), " c-sharp implementation."; + print INTERFACE $docTop; + print INTERFACE "\nnamespace Qt {"; + print INTERFACE "\n\n\tusing Qt;"; + print INTERFACE "\n\n\tpublic interface ", kalyptusDataDict::interfacemap($node->{astNodeName}), " {"; + } + + } else { + my $ancestor; + foreach $ancestor ( @ancestors ) { + if ( kalyptusDataDict::interfacemap($ancestor) eq () ) { + if ( $ancestor eq ("Qt") ){ + print CLASS "\n\n\tpublic class ", $node->{astNodeName}, " : TQNameSpace "; + } else { + print CLASS "\n\n\tpublic class ", $node->{astNodeName}, " : $ancestor"; + } + last; + } elsif ($ancestor eq @ancestors[$#ancestors] ) { + if ( $ancestor eq ("Qt") ){ + print CLASS "\n\n\tpublic class ", $node->{astNodeName}, " : TQNameSpace "; + } else { + print CLASS "\n\n\tpublic class ", $node->{astNodeName}, " : "; + } + print CLASS @ancestors[$#ancestors], ""; + } + } + + if ( $#ancestors >= 1 ) { + foreach $ancestor ( @ancestors ) { + if ( kalyptusDataDict::interfacemap($ancestor) ne () ) { + print CLASS ", ".kalyptusDataDict::interfacemap($ancestor); + } + } + } + + if ( kalyptusDataDict::interfacemap($node->{astNodeName}) ne () ) { + print CLASS ",".kalyptusDataDict::interfacemap($node->{astNodeName}); + } + + print CLASS " {"; + } + + Iter::MembersByType ( $node, + sub { print CLASS "", $_[0], ""; print JNISOURCE "", $_[0], ""; }, + sub { my ($node, $kid ) = @_; + generateClassMethodForEnum( $node, $kid ); + }, + sub { print CLASS ""; print JNISOURCE ""; } + ); + + %functionId = (); + $eventHandlerCount = 0; + + Iter::MembersByType ( $node, + sub { print CLASS "", $_[0], ""; print CLASS "", $_[0], ""; }, + sub { my ($node, $kid ) = @_; + listMember( $node, $kid ); + }, + sub { print CLASS ""; print CLASS ""; } + ); + + if ($nullctor ne (1) ) { + if ( $#ancestors >= 0 ) { + print CLASS "\n\n\t\tpublic ", $node->{astNodeName}, "() : base() {"; + print CLASS "\n\n\t\t\t// Dummy constructor for inherited classes."; + print CLASS "\n\t\t}"; + #print CLASS "\n\n\t\t// This is a convenience constructor for instantiating by passing a RawObject."; + #print CLASS "\n\t\tpublic ", $node->{astNodeName}, "(IntPtr raw) : base((Class) null) {"; + #print CLASS "\n\n\t\t\tRawObject = raw;"; + #print CLASS "\n\t\t}"; + } else { + print CLASS "\n\n\t\tpublic ", $node->{astNodeName}, "() : base() {"; + print CLASS "\n\n\t\t\t// Dummy constructor for inherited classes."; + print CLASS "\n\t\t}"; + #print CLASS "\n\n\t\t// This is a convenience constructor for instantiating by passing a RawObject."; + #print CLASS "\n\t\tpublic ", $node->{astNodeName}, "(IntPtr raw) {"; + #print CLASS "\n\n\t\t\tRawObject = raw;"; + #print CLASS "\n\t\t}"; + } + } + + print CLASS "\n\t}\n}\n"; + close CLASS; + $nullctor = 0; + + if ( kalyptusDataDict::interfacemap($node->{astNodeName}) ne () ) { + print INTERFACE "\n\t}\n}\n"; + close INTERFACE; + } +} + +sub listMember +{ + my( $class, $m, $ancestorCount) = @_; + my $name; + my $function; + my $csharpaccess; + my $csharpparams; + my $returnType; + + $name = $m->{astNodeName} ; + my $type = $m->{NodeType}; + my $docnode = $m->{DocNode}; + + if ( $m->{ReturnType} =~ /~/ ) { + $name = "~".$name; + } + + if ( $functionId{$name} eq "" ) { + $functionId{$name} = 0; + $function = $name; + } else { + $functionId{$name}++; + $function = $name.$functionId{$name}; + } + + $function =~ s/~//; + + if( $type eq "method" && $m->{Access} ne "private" && $m->{Access} ne "private_slots" && $m->{Access} ne "signals" ) { + if ( $m->{ReturnType} =~ /[<>]/ || $m->{Params} =~ /[<>]/ || $m->{Params} =~ /\.\.\./ || $m->{Params} =~ /Impl/ + || $m->{ReturnType} =~ /TQAuBucket/ || $m->{Params} =~ /TQAuBucket/ + || $m->{ReturnType} =~ /TQMember/ || $m->{Params} =~ /TQMember/ ) { + return; + } + + $returnType = $m->{ReturnType}; + $returnType =~ s/const\s*//; + $returnType =~ s/inline\s*//; + $returnType =~ s/\s*([,\*\&])\s*/$1/; + $returnType =~ s/^\s*//; + $returnType =~ s/\s*$//; + + if ( $returnType ne "" && cplusplusToPInvoke($returnType) eq () ) { + $returnType =~ s/^.*::.*$/int/; + } else { + $returnType = cplusplusToPInvoke($returnType); + } + + if ( $returnType eq "RawObject") { + $returnType = "IntPtr"; + } + + my $cparams = $m->{Params}; + my $cplusplusparams; + my $pinvokeparams; + my $pinvokeargs; + + # TODO port to $m->{ParamList} + $cparams =~ s/\s+/ /g; + $cparams =~ s/\s*([,\*\&])\s*/$1 /g; + $cparams =~ s/^\s*void\s*$//; + my $argId = 0; + my @cargs = kdocUtil::splitUnnested(",", $cparams); + $cparams = ""; + foreach my $arg ( @cargs ) { + my $argType; + my $cargType; + my $csharpargType; + my $pinvokeargType; + if ( $arg =~ /^\s*$/ ) { + next; + } + + # A ' = ' default parameter + $arg =~ s/\s*([^\s].*[^\s])\s*/$1/; + $arg =~ s/(\w+)\[\]/\* $1/; + $arg =~ s/=\s*(("[^\"]*")|(\'.\')|(([-\w:.]*)\s*(\|\s*[-\w]*)*(\(\w*\))?))//; + + if ( $arg =~ /^(.*)\s+(\w+)\s*$/ ) { + $argType = $1; + $arg = $2; + } else { + $argType = $arg; + $argId++; + $arg = "arg".$argId; + } + $arg =~ s/^id$/identifier/; + $argType =~ s/\s*([^\s].*[^\s])\s*/$1/; + $argType =~ s/\s*const//g; + $argType =~ s/^\s*//; + $argType =~ s/([\*\&])\s*([\*\&])/$1$2/; + $cargType = kalyptusDataDict::ctypemap($argType); + $csharpargType = cplusplusToCSharp($argType); + $pinvokeargType = cplusplusToPInvoke($argType); + + if ( $csharpargType eq "" ) { + $csharpargType = $argType; + $csharpargType =~ s/\&/\*/; + $csharpargType =~ s/^.*::.*$/int/; + } + if ( $pinvokeargType eq "" ) { + $pinvokeargType = $argType; + $pinvokeargType =~ s/\&/\*/; + $pinvokeargType =~ s/^.*::.*$/int/; + } + + $arg = checkReserved($arg); + if ( $pinvokeargType =~ /IntPtr/ ) { + $pinvokeargs .= "$arg.Ptr, "; + } elsif ( $csharpargType =~ /\./ ) { + $pinvokeargs .= "($pinvokeargType)$arg, "; + } else { + $pinvokeargs .= "$arg, "; + } + + if ( $pinvokeargType =~ /RawObject/ ) { + $pinvokeargType =~ s/RawObject/IntPtr/; + } + $csharpparams .= "$csharpargType $arg, "; + $pinvokeparams .= "$pinvokeargType $arg, "; + } + $cparams =~ s/, $//; + $cplusplusparams =~ s/, $//; + $csharpparams =~ s/, $//; + $pinvokeparams =~ s/, $//; + $pinvokeargs =~ s/, $//; + + my $flags = $m->{Flags}; + + if ( !defined $flags ) { + warn "Method ".$m->{astNodeName}. " has no flags\n"; + } + + + my $extra = ""; + $extra .= "static " if $flags =~ "s"; + + if ( $name =~ /operator/ ) { + return; + } + + if ( $m->{Access} =~ /protected/ && $name ne $class->{astNodeName} ) { + if ( $class->{Pure} ) { + return; + } + + $name = "protected_".$name; + } + + $m->{Access} =~ /([^_]*)(.*)?\s*/; + $csharpaccess = $1; + if ( $extra =~ /static/ ) { + $csharpaccess .= " static"; + } + + if ( $name eq $class->{astNodeName} && $class->{Pure} ) { + return; + } + + if ( defined $docnode ) { + if ( defined $docnode->{Text} ) { + print CLASS "\n/** "; + my $node; + my $line; + foreach $node ( @{$docnode->{Text}} ) { + next if $node->{NodeType} ne "DocText"; + $line = $node->{astNodeName}; + print CLASS $line, "\n"; + } + print CLASS "*/\n"; + } + } + + #This is to make sure we have no duplicate methods... + my $currentmethod .= "$name $returnType $csharpparams"; + my $pastmethod .= "$pastname $pastreturn $pastparams"; + if($currentmethod ne $pastmethod) { + + if ( $name eq $class->{astNodeName} ) { + #All the constructors are generated here except the dummy constructor + #print CLASS "\n// DLLImport goes here..."; + print CLASS "\n\n\t\t[DllImport(\"libqtc.so\", CharSet=CharSet.Ansi)]"; + print CLASS "\n\t\tprivate static extern IntPtr ", $typeprefix, "new_", $function, "(", $pinvokeparams, ");"; + print CLASS "\n\t\t", $csharpaccess, " ", $class->{astNodeName}, "(", $csharpparams, ") "; + if ($ancestorCount >= 0) { + print CLASS ": base() {"; + } + else { + print CLASS "{"; + } + print CLASS "\n\n\t\t\tRawObject = ", $typeprefix, "new_", $function, "(", $pinvokeargs, ");"; + print CLASS "\n\t\t}"; + if ($csharpparams eq () ) { + $nullctor = 1; + } + } elsif ( $returnType =~ /~/ ) { + #The deconstructor is here + print CLASS "\n\n\t\t// Deconstructor goes here..."; + print CLASS "\n\t\t", $csharpaccess, " void ", "del_", $function, "( ", $class->{astNodeName}, " p ){}"; + } else { + if ( $name =~ /.*Event$/ ) { + return; + } + + # Class or instance method + my $selfstring; + if ( $extra =~ /static/ ) { + if ( exists $class->{Pure} || $constructorCount == 0 ) { + $selfstring = kalyptusDataDict::addNamespace($class->{astNodeName})."::"; + } else { + $selfstring = $class->{astNodeName}."Bridge::"; + } + #Static Methods are generated here + #print CLASS "\n\n\t\t// DLLImport method goes here..."; + print CLASS "\n\n\t\t[DllImport(\"libqtc.so\", CharSet=CharSet.Ansi)]"; + print CLASS "\n\t\tprivate static extern", " ", $returnType, " ", $typeprefix, $class->{astNodeName}, "_", $function, "(", $pinvokeparams, ");"; + print CLASS "\n\t\t", $csharpaccess, " ", $returnType, " ", $name, "(", $csharpparams, ") {"; + if ($returnType =~ /void/ ) { + print CLASS "\n\n\t\t\t",$typeprefix, $class->{astNodeName}, "_", $function, "(", $pinvokeargs, ");"; + } else { + print CLASS "\n\n\t\t\treturn ", $typeprefix, $class->{astNodeName}, "_", $function, "(", $pinvokeargs, ");"; + } + print CLASS "\n\t\t}"; + } else { + if ( exists $class->{Pure} || $constructorCount == 0 ) { + $selfstring = "((".kalyptusDataDict::addNamespace($class->{astNodeName})."*)instPointer)->"; + } else { + $selfstring = "((".$class->{astNodeName}."Bridge*)instPointer)->"; + } + #Methods are generated here + #print CLASS "\n\n\t\t// DLLImport method goes here..."; + print CLASS "\n\n\t\t[DllImport(\"libqtc.so\", CharSet=CharSet.Ansi)]"; + print CLASS "\n\t\tprivate static extern", " ", $returnType, " ", $typeprefix, $class->{astNodeName}, "_", $function, "(", "IntPtr raw", ($pinvokeparams eq "" ? "" : ", "), $pinvokeparams, ");"; + print CLASS "\n\t\t", $csharpaccess, " ", $returnType, " ", checkReserved($name), "(", $csharpparams, ") {"; + if ($returnType =~ /void/ ) { + print CLASS "\n\n\t\t\t",$typeprefix, $class->{astNodeName}, "_", $function, "(", "RawObject", ($pinvokeargs eq "" ? "" : ", "), $pinvokeargs, ");"; + } else { + print CLASS "\n\n\t\t\treturn ", $typeprefix, $class->{astNodeName}, "_", $function, "(", "RawObject", ($pinvokeargs eq "" ? "" : ", "), $pinvokeargs, ");"; + } + print CLASS "\n\t\t}"; + } + } + } + } + #Part of the duplicate methods check. + $pastname = $name; + $pastreturn = $returnType; + $pastparams = $csharpparams; + $csharpparams = ""; +} + +sub generateClassMethodForEnum +{ + my( $class, $m ) = @_; + my $enum = $m->{astNodeName}; + my $csharpaccess; + + $m->{Access} =~ /([^_]*)(.*)?\s*/; + $csharpaccess = $1; + + if( $m->{NodeType} eq "enum" ) { + my $enum = $m->{astNodeName}; + my @enums = split(",", $m->{Params}); + my $enumCount = 0; + + if($enum ne " ") { + print CLASS "\n\n\t\t$csharpaccess enum", $enum,":long {"; + + foreach my $enum ( @enums ) { + $enum =~ s/\s//g; + $enum =~ s/::/./g; + if($#enums == $enumCount){ + + if ( $enum =~ /(.*)=(.*)/ ) { + print CLASS "\n\t\t\t$1 = $2"; + } else { + print CLASS "\n\t\t\t$enum = $enumCount"; + } + + } else { + + if ( $enum =~ /(.*)=(.*)/ ) { + print CLASS "\n\t\t\t$1 = $2,"; + } else { + print CLASS "\n\t\t\t$enum = $enumCount,"; + } + + } + $enumCount++; + + } + + print CLASS "\n\t\t}"; + } + } +} + +1; + diff --git a/kalyptus/kalyptusCxxToDcopIDL.pm b/kalyptus/kalyptusCxxToDcopIDL.pm new file mode 100644 index 0000000..ad7e3ee --- /dev/null +++ b/kalyptus/kalyptusCxxToDcopIDL.pm @@ -0,0 +1,1126 @@ +#*************************************************************************** +# kalyptusCxxToDcopIDL.pm - Generates idl from dcop headers +# ------------------- +# begin : Fri Jan 25 12:00:00 2000 +# copyright : (C) 2003 Alexander Kellett +# email : lypanov@kde.org +# author : Alexander Kellett +#***************************************************************************/ + +#/*************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation; either version 2 of the License, or * +# * (at your option) any later version. * +# * * +#***************************************************************************/ + +package kalyptusCxxToDcopIDL; + +use File::Path; +use File::Basename; +use Carp; +use Ast; +use kdocAstUtil; +use kdocUtil; +use Iter; +use kalyptusDataDict; +use Data::Dumper; + +use strict; +no strict "subs"; + +use vars qw/ + $libname $rootnode $outputdir $opt $debug + $methodNumber + %builtins %typeunion %allMethods %allTypes %enumValueToType %typedeflist %mungedTypeMap + %skippedClasses /; + +BEGIN +{ + +# Types supported by the StackItem union +# Key: C++ type Value: Union field of that type +%typeunion = ( + 'void*' => 's_voidp', + 'bool' => 's_bool', + 'char' => 's_char', + 'uchar' => 's_uchar', + 'short' => 's_short', + 'ushort' => 's_ushort', + 'int' => 's_int', + 'uint' => 's_uint', + 'long' => 's_long', + 'ulong' => 's_ulong', + 'float' => 's_float', + 'double' => 's_double', + 'enum' => 's_enum', + 'class' => 's_class' +); + +# Mapping for iterproto, when making up the munged method names +%mungedTypeMap = ( + 'TQString' => '$', + 'TQString*' => '$', + 'TQString&' => '$', + 'TQCString' => '$', + 'TQCString*' => '$', + 'TQCString&' => '$', + 'TQByteArray' => '$', + 'TQByteArray&' => '$', + 'TQByteArray*' => '$', + 'char*' => '$', + 'TQCOORD*' => '?', + 'TQRgb*' => '?', +); + +# Yes some of this is in kalyptusDataDict's ctypemap +# but that one would need to be separated (builtins vs normal classes) +%typedeflist = +( + 'signed char' => 'char', + 'unsigned char' => 'uchar', + 'signed short' => 'short', + 'unsigned short' => 'ushort', + 'signed' => 'int', + 'signed int' => 'int', + 'unsigned' => 'uint', + 'unsigned int' => 'uint', + 'signed long' => 'long', + 'unsigned long' => 'ulong', + +# Anything that is not known is mapped to void*, so no need for those here anymore +# 'TQWSEvent*' => 'void*', +# 'TQDiskFont*' => 'void*', +# 'XEvent*' => 'void*', +# 'TQStyleHintReturn*' => 'void*', +# 'FILE*' => 'void*', +# 'TQUnknownInterface*' => 'void*', +# 'GDHandle' => 'void*', +# '_NPStream*' => 'void*', +# 'TQTextFormat*' => 'void*', +# 'TQTextDocument*' => 'void*', +# 'TQTextCursor*' => 'void*', +# 'TQTextParag**' => 'void*', +# 'TQTextParag*' => 'void*', +# 'TQRemoteInterface*' => 'void*', +# 'TQSqlRecordPrivate*' => 'void*', +# 'TQTSMFI' => 'void*', # TQTextStream's TQTSManip +# 'const GUID&' => 'void*', +# 'TQWidgetMapper*' => 'void*', +# 'MSG*' => 'void*', +# 'const TQSqlFieldInfoList&' => 'void*', # TQSqlRecordInfo - TODO (templates) + + 'TQPtrCollection::Item' => 'void*', # to avoid a warning + + 'mode_t' => 'long', + 'TQProcess::PID' => 'long', + 'size_type' => 'int', # TQSqlRecordInfo + 'TQt::ComparisonFlags' => 'uint', + 'TQt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it + 'TQIODevice::Offset' => 'ulong', + 'WState' => 'int', + 'WId' => 'ulong', + 'TQRgb' => 'uint', + 'TQCOORD' => 'int', + 'TQTSMFI' => 'int', + 'TQt::WState' => 'int', + 'TQt::WFlags' => 'int', + 'TQt::HANDLE' => 'uint', + 'TQEventLoop::ProcessEventsFlags' => 'uint', + 'TQStyle::SCFlags' => 'int', + 'TQStyle::SFlags' => 'int', + 'Q_INT16' => 'short', + 'Q_INT32' => 'int', + 'Q_INT8' => 'char', + 'Q_LONG' => 'long', + 'Q_UINT16' => 'ushort', + 'Q_UINT32' => 'uint', + 'Q_UINT8' => 'uchar', + 'Q_ULONG' => 'long', +); + +} + +sub writeDoc +{ + ( $libname, $rootnode, $outputdir, $opt ) = @_; + + print STDERR "Starting writeDoc for $libname...\n"; + + $debug = $main::debuggen; + + # Define TQPtrCollection::Item, for resolveType + unless ( kdocAstUtil::findRef( $rootnode, "TQPtrCollection::Item" ) ) { + my $cNode = kdocAstUtil::findRef( $rootnode, "TQPtrCollection" ); + warn "TQPtrCollection not found" if (!$cNode); + my $node = Ast::New( 'Item' ); + $node->AddProp( "NodeType", "Forward" ); + $node->AddProp( "Source", $cNode->{Source} ) if ($cNode); + kdocAstUtil::attachChild( $cNode, $node ) if ($cNode); + $node->AddProp( "Access", "public" ); + } + + print STDERR "Preparsing...\n"; + + # Preparse everything, to prepare some additional data in the classes and methods + Iter::LocalCompounds( $rootnode, sub { preParseClass( shift ); } ); + + print STDERR "Writing smokedata.cpp...\n"; + + # Write out smokedata.cpp + writeSmokeDataFile($rootnode); + + print STDERR "Writing dcopidl...\n"; + + print STDOUT "\n"; + + print STDOUT "".@{$rootnode->{Sources}}[0]->{astNodeName}."\n"; + + print STDOUT map { "$_\n" } reverse @main::includes_list; + + Iter::LocalCompounds( $rootnode, sub { + my ($node) = @_; + + my ($methodCode, $switchCode, $incl) = generateAllMethods( $node ); + my $className = join "::", kdocAstUtil::heritage($node); + + if ($node->{DcopExported}) { + print STDOUT "\n"; + my @docs; + if ($node->{DocNode}->{Text}) { + for my $blah ($node->{DocNode}->{Text}) { + for my $blah2 (@{$blah}) { + push @docs, $blah2->{astNodeName} if $blah2->{NodeType} eq "DocText"; + } + } + } + if (scalar(@docs) != 0) { + my $doc = join "", map { "$_" } @docs; + print STDOUT " $doc\n"; + } + print STDOUT " $className\n"; + print STDOUT join("\n", map { " $_"; } grep { $_ ne "Global"; } + map { + my $name = $_->{astNodeName}; + $name =~ s//>/; + my $tmpl = $_->{TmplType}; + $tmpl =~ s//>/; + $tmpl ? "$name<$tmpl>" : $name; + } @{$node->{InList}}) . "\n"; + print STDOUT $methodCode; + + print STDOUT "\n"; + } + }); + + print STDOUT "\n"; + + print STDERR "Done.\n"; +} + +=head2 preParseClass + Called for each class +=cut +sub preParseClass +{ + my( $classNode ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + if( $#{$classNode->{Kids}} < 0 || + $classNode->{Access} eq "private" || + $classNode->{Access} eq "protected" || # e.g. TQPixmap::TQPixmapData + exists $classNode->{Tmpl} || + # Don't generate standard bindings for TQString, this class is handled as a native type + $className eq 'TQString' || + $className eq 'TQConstString' || + $className eq 'TQCString' || + # Don't map classes which are really arrays + $className eq 'TQStringList' || + $className eq 'TQCanvasItemList' || + $className eq 'TQWidgetList' || + $className eq 'TQObjectList' || + $className eq 'TQStrList' || + # Those are template related + $className eq 'TQTSManip' || # cause compiler errors with several gcc versions + $className eq 'TQGDict' || + $className eq 'TQGList' || + $className eq 'TQGVector' || + $className eq 'TQStrIList' || + $className eq 'TQStrIVec' || + $className eq 'TQByteArray' || + $className eq 'TQBitArray' || + $classNode->{NodeType} eq 'union' # Skip unions for now, e.g. TQPDevCmdParam + ) { + print STDERR "Skipping $className\n" if ($debug); + print STDERR "Skipping union $className\n" if ( $classNode->{NodeType} eq 'union'); + $skippedClasses{$className} = 1; + delete $classNode->{Compound}; # Cheat, to get it excluded from Iter::LocalCompounds + return; + } + + my $signalCount = 0; + my $eventHandlerCount = 0; + my $defaultConstructor = 'none'; # none, public, protected or private. 'none' will become 'public'. + my $constructorCount = 0; # total count of _all_ ctors + # If there are ctors, we need at least one public/protected one to instanciate the class + my $hasPublicProtectedConstructor = 0; + # We need a public dtor to destroy the object --- ### aren't protected dtors ok too ?? + my $hasPublicDestructor = 1; # by default all classes have a public dtor! + my $hasDestructor = 0; + my $hasPrivatePureVirtual = 0; + my $hasCopyConstructor = 0; + my $hasPrivateCopyConstructor = 0; + # Note: no need for hasPureVirtuals. $classNode{Pure} has that. + + my $doPrivate = $main::doPrivate; + $main::doPrivate = 1; + # Look at each class member (looking for methods and enums in particular) + Iter::MembersByType ( $classNode, undef, + sub { + + my( $classNode, $m ) = @_; + my $name = $m->{astNodeName}; + + if( $m->{NodeType} eq "method" ) { + if ( $m->{ReturnType} eq 'typedef' # TQFile's EncoderFn/DecoderFn callback, very badly parsed + ) { + $m->{NodeType} = 'deleted'; + next; + } + + print STDERR "preParseClass: looking at $className\::$name $m->{Params}\n" if ($debug); + + if ( $name eq $classNode->{astNodeName} ) { + if ( $m->{ReturnType} =~ /~/ ) { + # A destructor + $hasPublicDestructor = 0 if $m->{Access} ne 'public'; + $hasDestructor = 1; + } else { + # A constructor + $constructorCount++; + $defaultConstructor = $m->{Access} if ( $m->{Params} eq '' ); + $hasPublicProtectedConstructor = 1 if ( $m->{Access} ne 'private' ); + + # Copy constructor? + if ( $#{$m->{ParamList}} == 0 ) { + my $theArgType = @{$m->{ParamList}}[0]->{ArgType}; + if ($theArgType =~ /$className\s*\&/) { + $hasCopyConstructor = 1; + $hasPrivateCopyConstructor = 1 if ( $m->{Access} eq 'private' ); + } + } + # Hack the return type for constructors, since constructors return an object pointer + $m->{ReturnType} = $className."*"; + } + } + + if ( $name =~ /~$classNode->{astNodeName}/ && $m->{Access} ne "private" ) { # not used + $hasPublicDestructor = 0 if $m->{Access} ne 'public'; + $hasDestructor = 1; + } + + if ( $m->{Flags} =~ "p" && $m->{Access} =~ /private/ ) { + $hasPrivatePureVirtual = 1; # ouch, can't inherit from that one + } + + # All we want from private methods is to check for virtuals, nothing else + next if ( $m->{Access} =~ /private/ ); + + my $argId = 0; + my $firstDefaultParam; + foreach my $arg ( @{$m->{ParamList}} ) { + # Look for first param with a default value + if ( defined $arg->{DefaultValue} && !defined $firstDefaultParam ) { + $firstDefaultParam = $argId; + } + + if ( $arg->{ArgType} eq '...' # refuse a method with variable arguments + or $arg->{ArgType} eq 'image_io_handler' # TQImage's callback + or $arg->{ArgType} eq 'DecoderFn' # TQFile's callback + or $arg->{ArgType} eq 'EncoderFn' # TQFile's callback + or $arg->{ArgType} =~ /bool \(\*\)\(TQObject/ # TQMetaObject's ctor + or $arg->{ArgType} eq 'QtStaticMetaObjectFunction' # TQMetaObjectCleanUp's ctor with func pointer + or $arg->{ArgType} eq 'const TQTextItem&' # ref to a private class in 3.2.0b1 + or $arg->{ArgType} eq 'FILE*' # won't be able to handle that I think + ) { + $m->{NodeType} = 'deleted'; + } + else + { + # Resolve type in full, e.g. for TQSessionManager::RestartHint + # (x_QSessionManager doesn't inherit TQSessionManager) + $arg->{ArgType} = kalyptusDataDict::resolveType($arg->{ArgType}, $classNode, $rootnode); + registerType( $arg->{ArgType} ); + $argId++; + } + } + $m->AddProp( "FirstDefaultParam", $firstDefaultParam ); + $m->{ReturnType} = kalyptusDataDict::resolveType($m->{ReturnType}, $classNode, $rootnode) if ($m->{ReturnType}); + registerType( $m->{ReturnType} ); + } + elsif( $m->{NodeType} eq "enum" ) { + my $fullEnumName = $className."::".$m->{astNodeName}; + $classNode->{enumerations}{$m->{astNodeName}} = $fullEnumName + if $m->{astNodeName} and $m->{Access} ne 'private'; + + # Define a type for this enum + registerType( $fullEnumName ); + + # Remember that it's an enum + findTypeEntry( $fullEnumName )->{isEnum} = 1; + + #print STDERR "$fullEnumName is an enum\n"; + } + elsif( $m->{NodeType} eq 'var' ) { + my $varType = $m->{Type}; + # We are interested in public static vars, like TQColor::blue + if ( $varType =~ s/static\s+// && $m->{Access} ne 'private' ) + { + $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/\s*$//; + print STDERR "var: $m->{astNodeName} '$varType'\n" if ($debug); + + # Register the type + registerType( $varType ); + + } else { + # To avoid duplicating the above test, we just get rid of any other var + $m->{NodeType} = 'deleted'; + } + } + }, + undef + ); + $main::doPrivate = $doPrivate; + + print STDERR "$className: ctor count: $constructorCount, hasPublicProtectedConstructor: $hasPublicProtectedConstructor, hasCopyConstructor: $hasCopyConstructor:, defaultConstructor: $defaultConstructor, hasPublicDestructor: $hasPublicDestructor, hasPrivatePureVirtual:$hasPrivatePureVirtual\n" if ($debug); + + # We will derive from the class only if it has public or protected constructors. + # (_Even_ if it has pure virtuals. But in that case the x_ class can't be instantiated either.) + $classNode->AddProp( "BindingDerives", $hasPublicProtectedConstructor ); +} + + +=head2 writeClassDoc + + Called by writeDoc for each series of classes to be written out + +=cut + + sub writeClassDoc + { + } + +# Generate the prototypes for a method (one per arg with a default value) +# Helper for makeprotos +sub iterproto($$$$$) { + my $classidx = shift; # to check if a class exists + my $method = shift; + my $proto = shift; + my $idx = shift; + my $protolist = shift; + + my $argcnt = scalar @{ $method->{ParamList} } - 1; + if($idx > $argcnt) { + push @$protolist, $proto; + return; + } + if(defined $method->{FirstDefaultParam} and $method->{FirstDefaultParam} <= $idx) { + push @$protolist, $proto; + } + + my $arg = $method->{ParamList}[$idx]->{ArgType}; + + my $typeEntry = findTypeEntry( $arg ); + my $realType = $typeEntry->{realType}; + + # A scalar ? + $arg =~ s/\bconst\b//g; + $arg =~ s/\s+//g; + if($typeEntry->{isEnum} || $allTypes{$realType}{isEnum} || exists $typeunion{$realType} || exists $mungedTypeMap{$arg}) + { + my $id = '$'; # a 'scalar + $id = '?' if $arg =~ /[*&]{2}/; + $id = $mungedTypeMap{$arg} if exists $mungedTypeMap{$arg}; + iterproto($classidx, $method, $proto . $id, $idx + 1, $protolist); + return; + } + + # A class ? + if(exists $classidx->{$realType}) { + iterproto($classidx, $method, $proto . '#', $idx + 1, $protolist); + return; + } + + # A non-scalar (reference to array or hash, undef) + iterproto($classidx, $method, $proto . '?', $idx + 1, $protolist); + return; +} + +# Generate the prototypes for a method (one per arg with a default value) +sub makeprotos($$$) { + my $classidx = shift; + my $method = shift; + my $protolist = shift; + iterproto($classidx, $method, $method->{astNodeName}, 0, $protolist); +} + +# Return the string containing the signature for this method (without return type). +# If the 2nd arg is not the size of $m->{ParamList}, this method returns a +# partial signature (this is used to handle default values). +sub methodSignature($$) { + my $method = shift; + my $last = shift; + my $sig = $method->{astNodeName}; + my @argTypeList; + my $argId = 0; + foreach my $arg ( @{$method->{ParamList}} ) { + last if $argId > $last; + push @argTypeList, $arg->{ArgType}; + $argId++; + } + $sig .= "(". join(", ",@argTypeList) .")"; + $sig .= " const" if $method->{Flags} =~ "c"; + return $sig; +} + +sub coerce_type($$$$) { + #my $m = shift; + my $union = shift; + my $var = shift; + my $type = shift; + my $new = shift; # 1 if this is a return value, 0 for a normal param + + my $typeEntry = findTypeEntry( $type ); + my $realType = $typeEntry->{realType}; + + my $unionfield = $typeEntry->{typeId}; + die "$type" unless defined( $unionfield ); + $unionfield =~ s/t_/s_/; + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + my $code = "$union.$unionfield = "; + if($type =~ /&$/) { + $code .= "(void*)&$var;\n"; + } elsif($type =~ /\*$/) { + $code .= "(void*)$var;\n"; + } else { + if ( $unionfield eq 's_class' + or ( $unionfield eq 's_voidp' and $type ne 'void*' ) + or $type eq 'TQString' ) { # hack + $type =~ s/^const\s+//; + if($new) { + $code .= "(void*)new $type($var);\n"; + } else { + $code .= "(void*)&$var;\n"; + } + } else { + $code .= "$var;\n"; + } + } + + return $code; +} + +# Generate the list of args casted to their real type, e.g. +# (TQObject*)x[1].s_class,(TQEvent*)x[2].s_class,x[3].s_int +sub makeCastedArgList +{ + my @castedList; + my $i = 1; # The args start at x[1]. x[0] is the return value + my $arg; + foreach $arg (@_) { + my $type = $arg; + my $cast; + + my $typeEntry = findTypeEntry( $type ); + my $unionfield = $typeEntry->{typeId}; + die "$type" unless defined( $unionfield ); + $unionfield =~ s/t_/s_/; + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + my $v .= "$unionfield"; + if($type =~ s/&$//) { + $cast = "{($type *)}"; + } elsif($type =~ /\*$/) { + $cast = "$type"; + } elsif($type =~ /\(\*\)\s*\(/) { # function pointer ... (*)(...) + $cast = "$type"; + } else { + if ( $unionfield eq 's_class' + or ( $unionfield eq 's_voidp' and $type ne 'void*' ) + or $type eq 'TQString' ) { # hack + $cast = "{*($type *)}"; + } else { + $cast = "$type"; + } + } + push @castedList, "$cast$v"; + $i++; + } + return @castedList; +} + +# Adds the header for node $1 to be included in $2 if not already there +# Prints out debug stuff if $3 +sub addIncludeForClass($$$) +{ + my ( $node, $addInclude, $debugMe ) = @_; + my $sourcename = $node->{Source}->{astNodeName}; + $sourcename =~ s!.*/(.*)!$1!m; + die "Empty source name for $node->{astNodeName}" if ( $sourcename eq '' ); + unless ( defined $addInclude->{$sourcename} ) { + print " Including $sourcename\n" if ($debugMe); + $addInclude->{$sourcename} = 1; + } + else { print " $sourcename already included.\n" if ($debugMe); } +} + +sub checkIncludesForObject($$) +{ + my $type = shift; + my $addInclude = shift; + + my $debugCI = 0; #$debug + #print "checkIncludesForObject $type\n"; + $type =~ s/const\s+//; + my $it = $type; + if (!($it and exists $typeunion{$it}) and $type !~ /\*/ + #and $type !~ /&/ # in fact we also want refs, due to the generated code + ) { + $type =~ s/&//; + print " Detecting an object by value/ref: $type\n" if ($debugCI); + my $node = kdocAstUtil::findRef( $rootnode, $type ); + if ($node) { + addIncludeForClass( $node, $addInclude, $debugCI ); + } + else { print " No header found for $type\n" if ($debugCI); } + } +} + +sub generateMethod($$$) +{ + my( $classNode, $m, $addInclude ) = @_; # input + my $methodCode = ''; # output + + my $name = $m->{astNodeName}; # method name + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + my $xClassName = "x_" . join( "__", @heritage ); + + # Check some method flags: constructor, destructor etc. + my $flags = $m->{Flags}; + + if ( !defined $flags ) { + warn "Method ".$name. " has no flags\n"; + } + + my $returnType = $m->{ReturnType}; + $returnType = undef if ($returnType eq 'void'); + + # Don't use $className here, it's never the fully qualified (A::B) name for a ctor. + my $isConstructor = ($name eq $classNode->{astNodeName} ); + my $isDestructor = ($returnType eq '~'); + + if ($debug) { + print STDERR " Method $name"; + print STDERR ", is DTOR" if $isDestructor; + print STDERR ", returns $returnType" if $returnType; + #print STDERR " ($m->{Access})"; + print STDERR "\n"; + } + + # Don't generate anything for destructors + return if $isDestructor; + + return if ( $m->{SkipFromSwitch} ); # pure virtuals, etc. + +# # Skip internal methods, which return unknown types +# # Hmm, the C# bindings have a list of those too. +# return if ( $returnType =~ m/TQGfx\s*\*/ ); +# return if ( $returnType eq 'CGContextRef' ); +# return if ( $returnType eq 'TQWSDisplay *' ); +# # This stuff needs callback, or ** +# return if ( $name eq 'defineIOHandler' or $name eq 'qt_init_internal' ); +# # Skip casting operators, but not == < etc. +# return if ( $name =~ /operator \w+/ ); +# # TQFile's EncoderFn/DecoderFn +# return if ( $name =~ /set[ED][ne]codingFunction/ ); +# # How to implement this? (TQXmlDefaultHandler/TQXmlEntityResolver::resolveEntity, needs A*&) +# return if ( $name eq 'resolveEntity' and $className =~ /^TQXml/ ); +# return if ( $className eq 'TQBitArray' && $m->{Access} eq 'protected' ); + + #print STDERR "Tests passed, generating.\n"; + + # Detect objects returned by value + checkIncludesForObject( $returnType, $addInclude ) if ($returnType); + + my $argId = 0; + + my @argTypeList=(); + + my $args = ""; + + foreach my $arg ( @{$m->{ParamList}} ) { + + print STDERR " Param ".$arg->{astNodeName}." type: ".$arg->{ArgType}." name:".$arg->{ArgName}." default: ".$arg->{DefaultValue}."\n" if ($debug); + + my $argType = $arg->{ArgType}; + + my $x_isConst = ($argType =~ s/const//); + my $x_isRef = ($argType =~ s/&//); + + my $typeAttrs = ""; + $typeAttrs .= " qleft=\"const\"" if $x_isConst; + $typeAttrs .= " qright=\"&\"" if $x_isRef; + + $argType =~ s/^\s*(.*?)\s*$/$1/; + $argType =~ s//>/g; + + $args .= " $argType$arg->{ArgName}\n"; + + push @argTypeList, $argType; + + # Detect objects passed by value + checkIncludesForObject( $argType, $addInclude ); + } + +# my @castedArgList = makeCastedArgList( @argTypeList ); + + my $isStatic = ($flags =~ "s"); + my $extra = ""; + $extra .= "static " if $isStatic || $isConstructor; + + my $qual = ""; + $qual .= " qual=\"const\"" if $flags =~ "c"; + + my $this = $classNode->{BindingDerives} > 0 ? "this" : "xthis"; + + # We iterate as many times as we have default params + my $firstDefaultParam = $m->{FirstDefaultParam}; + $firstDefaultParam = scalar(@argTypeList) unless defined $firstDefaultParam; + + my $xretCode = ''; + if($returnType) { + $xretCode .= coerce_type('x[0]', 'xret', $returnType, 1); } + + $returnType = "void" unless $returnType; + $returnType =~ s//>/g; + + my $methodCode = ""; + + my $tagType = ($flags !~ /z/) ? "FUNC" : "SIGNAL"; + my $tagAttr = ""; + $tagAttr .= " hidden=\"yes\"" if $flags =~ /y/; + + if (!$isConstructor) { + $methodCode .= " <$tagType$tagAttr$qual>\n"; + + my @docs; + if ($m->{DocNode}->{Text}) { + for my $blah ($m->{DocNode}->{Text}) { + for my $blah2 (@{$blah}) { + push @docs, $blah2->{astNodeName} if $blah2->{NodeType} eq "DocText"; + } + } + } + if (scalar(@docs) != 0) { + my $doc = join "", map { "$_" } @docs; + $methodCode .= " $doc\n"; + } + + $methodCode .= " $returnType\n"; + $methodCode .= " $name\n"; + $methodCode .= "$args"; + $methodCode .= " \n"; + } + + $methodNumber++; + + return ( $methodCode, "" ); +} + +## Called by writeClassDoc +sub generateAllMethods +{ + my ($classNode) = @_; + my $methodCode = ''; + + my $sourcename = $classNode->{Source}->{astNodeName}; + $sourcename =~ s!.*/(.*)!$1!m; + die "Empty source name for $classNode->{astNodeName}" if ( $sourcename eq '' ); + + my %addInclude = ( $sourcename => 1 ); + + # Then all methods + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'method' ) { + next unless $methodNode->{Flags} =~ /(d|z|y)/; + my ($meth, $swit) = generateMethod( $classNode, $methodNode, \%addInclude ); + $methodCode .= $meth; + } + }, undef ); + + return ( $methodCode, "", \%addInclude ); +} + +# Known typedef? If so, apply it. +sub applyTypeDef($) +{ + my $type = shift; + # Parse 'const' in front of it, and '*' or '&' after it + my $prefix = $type =~ s/^const\s+// ? 'const ' : ''; + my $suffix = $type =~ s/\s*([\&\*]+)$// ? $1 : ''; + + if (exists $typedeflist{$type}) { + return $prefix.$typedeflist{$type}.$suffix; + } + return $prefix.$type.$suffix; +} + +# Register type ($1) into %allTypes if not already there +sub registerType($$) { + my $type = shift; + #print "registerType: $type\n" if ($debug); + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + return if ( $type eq 'void' or $type eq '' or $type eq '~' ); + die if ( $type eq '...' ); # ouch + + # Let's register the real type, not its known equivalent + #$type = applyTypeDef($type); + + # Enum _value_ -> get corresponding type + if (exists $enumValueToType{$type}) { + $type = $enumValueToType{$type}; + } + + # Already in allTypes + if(exists $allTypes{$type}) { + return; + } + + die if $type eq 'TQTextEdit::UndoRedoInfo::Type'; + die if $type eq ''; + + my $realType = $type; + + # Look for references (&) and pointers (* or **) - this will not handle *& correctly. + # We do this parsing here because both the type list and iterproto need it + if($realType =~ s/&$//) { + $allTypes{$type}{typeFlags} = 'Smoke::tf_ref'; + } + elsif($realType ne 'void*' && $realType =~ s/\*$//) { + $allTypes{$type}{typeFlags} = 'Smoke::tf_ptr'; + } + else { + $allTypes{$type}{typeFlags} = 'Smoke::tf_stack'; + } + + if ( $realType =~ s/^const\s+// ) { # Remove 'const' + $allTypes{$type}{typeFlags} .= ' | Smoke::tf_const'; + } + + # Apply typedefs, and store the resulting type. + # For instance, if $type was Q_UINT16&, realType will be ushort + $allTypes{$type}{realType} = applyTypeDef( $realType ); + + # In the first phase we only create entries into allTypes. + # The values (indexes) are calculated afterwards, once the list is full. + $allTypes{$type}{index} = -1; + #print STDERR "Register $type. Realtype: $realType\n" if($debug); +} + +# Get type from %allTypes +# This returns a hash with {index}, {isEnum}, {typeFlags}, {realType} +# (and {typeId} after the types array is written by writeSmokeDataFile) +sub findTypeEntry($) { + my $type = shift; + my $typeIndex = -1; + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + return undef if ( $type =~ '~' or $type eq 'void' or $type eq '' ); + + # Enum _value_ -> get corresponding type + if (exists $enumValueToType{$type}) { + $type = $enumValueToType{$type}; + } + + die "type not known: $type" unless defined $allTypes{$type}; + return $allTypes{ $type }; +} + +# List of all super-classes for a given class +sub superclass_list($) +{ + my $classNode = shift; + my @super; + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + push @super, @_[0]; + push @super, superclass_list( @_[0] ); + }, undef ); + return @super; +} + +=head2 + Write out the smokedata.cpp file containing all the arrays. +=cut + +sub writeSmokeDataFile($) { + my $rootnode = shift; + + # Make list of classes + my %allIncludes; # list of all header files for all classes + my @classlist; + push @classlist, ""; # Prepend empty item for "no class" + my %enumclasslist; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = $_[0]; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + push @classlist, $className; + $enumclasslist{$className}++ if keys %{$classNode->{enumerations}}; + $classNode->{ClassIndex} = $#classlist; + addIncludeForClass( $classNode, \%allIncludes, undef ); + } ); + + kdocAstUtil::dumpAst($rootnode) if ($debug); + + my %classidx = do { my $i = 0; map { $_ => $i++ } @classlist }; + + my $file = "$outputdir/smokedata.cpp"; + open OUT, ">$file" or die "Couldn't create $file\n"; + + # Prepare descendants information for each class + my %descendants; # classname -> list of descendant nodes + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + # Get _all_ superclasses (up any number of levels) + # and store that $classNode is a descendant of $s + my @super = superclass_list($classNode); + for my $s (@super) { + my $superClassName = join( "::", kdocAstUtil::heritage($s) ); + Ast::AddPropList( \%descendants, $superClassName, $classNode ); + } + } ); + + # Iterate over all classes, to write the xtypecast function + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + # @super will contain superclasses, the class itself, and all descendants + my @super = superclass_list($classNode); + push @super, $classNode; + if ( defined $descendants{$className} ) { + push @super, @{$descendants{$className}}; + } + my $cur = $classidx{$className}; + print OUT " case $cur:\t//$className\n"; + print OUT "\tswitch(to) {\n"; + $cur = -1; + for my $s (@super) { + my $superClassName = join( "::", kdocAstUtil::heritage($s) ); + next if !defined $classidx{$superClassName}; # inherits from unknown class, see below + next if $classidx{$superClassName} == $cur; # shouldn't happen in Qt + $cur = $classidx{$superClassName}; + print OUT "\t case $cur: return (void*)($superClassName*)($className*)xptr;\n"; + } + print OUT "\t default: return xptr;\n"; + print OUT "\t}\n"; + } ); + print OUT " default: return xptr;\n"; + print OUT " }\n"; + print OUT "}\n\n"; + + + # Write inheritance array + # Imagine you have "Class : public super1, super2" + # The inheritlist array will get 3 new items: super1, super2, 0 + my %inheritfinder; # key = (super1, super2) -> data = (index in @inheritlist). This one allows reuse. + my %classinherit; # we store that index in %classinherit{className} + # We don't actually need to store inheritlist in memory, we write it + # directly to the file. We only need to remember its current size. + my $inheritlistsize = 1; + + print OUT "// Group of class IDs (0 separated) used as super class lists.\n"; + print OUT "// Classes with super classes have an index into this array.\n"; + print OUT "static short ${libname}_inheritanceList[] = {\n"; + print OUT "\t0,\t// 0: (no super class)\n"; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "__", kdocAstUtil::heritage($classNode) ); + print STDERR "inheritanceList: looking at $className\n" if ($debug); + + # Make list of direct ancestors + my @super; + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + my $superClassName = join( "::", kdocAstUtil::heritage($_[0]) ); + push @super, $superClassName; + }, undef ); + # Turn that into a list of class indexes + my $key = ''; + foreach my $superClass( @super ) { + if (defined $classidx{$superClass}) { + $key .= ', ' if ( length $key > 0 ); + $key .= $classidx{$superClass}; + } + } + if ( $key ne '' ) { + if ( !defined $inheritfinder{$key} ) { + print OUT "\t"; + my $index = $inheritlistsize; # Index of first entry (for this group) in inheritlist + foreach my $superClass( @super ) { + if (defined $classidx{$superClass}) { + print OUT "$classidx{$superClass}, "; + $inheritlistsize++; + } + } + $inheritlistsize++; + my $comment = join( ", ", @super ); + print OUT "0,\t// $index: $comment\n"; + $inheritfinder{$key} = $index; + } + $classinherit{$className} = $inheritfinder{$key}; + } else { # No superclass + $classinherit{$className} = 0; + } + } ); + print OUT "};\n\n"; + + + print OUT "// These are the xenum functions for manipulating enum pointers\n"; + for my $className (keys %enumclasslist) { + my $c = $className; + $c =~ s/::/__/g; + print OUT "void xenum_$c\(Smoke::EnumOperation, Smoke::Index, void*&, long&);\n"; + } + print OUT "\n"; + print OUT "// Those are the xcall functions defined in each x_*.cpp file, for dispatching method calls\n"; + my $firstClass = 1; + for my $className (@classlist) { + if ($firstClass) { + $firstClass = 0; + next; + } + my $c = $className; # make a copy + $c =~ s/::/__/g; + print OUT "void xcall_$c\(Smoke::Index, void*, Smoke::Stack);\n"; + } + print OUT "\n"; + + # Write class list afterwards because it needs offsets to the inheritance array. + print OUT "// List of all classes\n"; + print OUT "// Name, index into inheritanceList, method dispatcher, enum dispatcher, class flags\n"; + print OUT "static Smoke::Class ${libname}_classes[] = {\n"; + my $firstClass = 1; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "__", kdocAstUtil::heritage($classNode) ); + + if ($firstClass) { + $firstClass = 0; + print OUT "\t{ 0L, 0, 0, 0, 0 }, \t// 0 (no class)\n"; + } + my $c = $className; + $c =~ s/::/__/g; + my $xcallFunc = "xcall_$c"; + my $xenumFunc = "0"; + $xenumFunc = "xenum_$c" if exists $enumclasslist{$className}; + # %classinherit needs Foo__Bar, not Foo::Bar? + die "problem with $className" unless defined $classinherit{$c}; + + my $xClassFlags = 0; + $xClassFlags =~ s/0\|//; # beautify + print OUT "\t{ \"$className\", $classinherit{$c}, $xcallFunc, $xenumFunc, $xClassFlags }, \t//$classidx{$className}\n"; + } ); + print OUT "};\n\n"; + + + print OUT "// List of all types needed by the methods (arguments and return values)\n"; + print OUT "// Name, class ID if arg is a class, and TypeId\n"; + print OUT "static Smoke::Type ${libname}_types[] = {\n"; + my $typeCount = 0; + $allTypes{''}{index} = 0; # We need an "item 0" + for my $type (sort keys %allTypes) { + $allTypes{$type}{index} = $typeCount; # Register proper index in allTypes + if ( $typeCount == 0 ) { + print OUT "\t{ 0, 0, 0 },\t//0 (no type)\n"; + $typeCount++; + next; + } + my $isEnum = $allTypes{$type}{isEnum}; + my $typeId; + my $typeFlags = $allTypes{$type}{typeFlags}; + my $realType = $allTypes{$type}{realType}; + die "$type" if !defined $typeFlags; + die "$realType" if $realType =~ /\(/; + # First write the name + print OUT "\t{ \"$type\", "; + # Then write the classId (and find out the typeid at the same time) + if(exists $classidx{$realType}) { # this one first, we want t_class for TQBlah* + $typeId = 't_class'; + print OUT "$classidx{$realType}, "; + } + elsif($type =~ /&$/ || $type =~ /\*$/) { + $typeId = 't_voidp'; + print OUT "0, "; # no classId + } + elsif($isEnum || $allTypes{$realType}{isEnum}) { + $typeId = 't_enum'; + if($realType =~ /(.*)::/) { + my $c = $1; + if($classidx{$c}) { + print OUT "$classidx{$c}, "; + } else { + print OUT "0 /* unknown class $c */, "; + } + } else { + print OUT "0 /* unknown $realType */, "; # no classId + } + } + else { + $typeId = $typeunion{$realType}; + if (defined $typeId) { + $typeId =~ s/s_/t_/; # from s_short to t_short for instance + } + else { + # Not a known class - ouch, this happens quite a lot + # (private classes, typedefs, template-based types, etc) + if ( $skippedClasses{$realType} ) { +# print STDERR "$realType has been skipped, using t_voidp for it\n"; + } else { + unless( $realType =~ / map to a void * + } + print OUT "0, "; # no classId + } + # Then write the flags + die "$type" if !defined $typeId; + print OUT "Smoke::$typeId | $typeFlags },"; + print OUT "\t//$typeCount\n"; + $typeCount++; + # Remember it for coerce_type + $allTypes{$type}{typeId} = $typeId; + } + + close OUT; +} + +1; diff --git a/kalyptus/kalyptusCxxToECMA.pm b/kalyptus/kalyptusCxxToECMA.pm new file mode 100644 index 0000000..5b41973 --- /dev/null +++ b/kalyptus/kalyptusCxxToECMA.pm @@ -0,0 +1,570 @@ +#*************************************************************************** +# kalyptusCxxToEMA.pm - Generates class info for ECMA bindings in KDE +# ------------------- +# begin : Fri Jan 25 12:00:00 2000 +# copyright : (C) 2002 Lost Highway Ltd. All Rights Reserved. +# email : david@mandrakesoft.com +# author : David Faure. +#***************************************************************************/ + +#/*************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation; either version 2 of the License, or * +# * (at your option) any later version. * +# * * +#***************************************************************************/ + +package kalyptusCxxToECMA; + +use File::Path; +use File::Basename; + +use Carp; +use Ast; +use kdocAstUtil; +use kdocUtil; +use Iter; +use kalyptusDataDict; + +use strict; +no strict "subs"; + +use vars qw/ + $libname $rootnode $outputdir $opt $debug + %skippedClasses %hasHashTable %hasFunctions %hasBridge %hasGet %hasPut/; + +sub writeDoc +{ + ( $libname, $rootnode, $outputdir, $opt ) = @_; + + print STDERR "Starting writeDoc for $libname...\n"; + + $debug = $main::debuggen; + + mkpath( $outputdir ) unless -f $outputdir; + + # Preparse everything, to prepare some additional data in the classes and methods + Iter::LocalCompounds( $rootnode, sub { preParseClass( shift ); } ); + + print STDERR "Writing generateddata.cpp...\n"; + + writeInheritanceFile($rootnode); + + print STDERR "Done.\n"; +} + +=head2 preParseClass + Called for each class +=cut +sub preParseClass +{ + my( $classNode ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + if ( $className =~ /Proto$/ ) { + my $c = $className; + $c =~ s/Proto$//; + #print STDERR "$c -> $className\n"; + $hasFunctions{$c} = $className; # Associate class -> proto + #print STDERR "Found proto $className -> skipping\n"; + $skippedClasses{$className} = 1; # Skip proto + return; + } + + if( $classNode->{Access} eq "private" || + $classNode->{Access} eq "protected" || # e.g. TQPixmap::TQPixmapData + exists $classNode->{Tmpl} || + $className eq 'KJS' || $className eq 'KSVG' || # namespaces + $className =~ /^KSVG::KSVG/ || $className eq 'KSVG::CachedGlyph' || # Not DOM classes + $className eq 'KSVG::ImageStreamMap' || + $className eq 'KSVG::SVGBBoxTarget' || + $className eq 'KSVG::SVGLoader' || + $className eq 'KSVG::SVGElementImpl::MouseEvent' || + $className eq 'KSVG::SVGRegisteredEventListener' || + $classNode->{NodeType} eq 'union' # Skip unions for now, e.g. TQPDevCmdParam + ) { + print STDERR "Skipping $className "; #if ($debug); + + #print STDERR "(nothing in it)\n" if ( $#{$classNode->{Kids}} < 0 ); + if ( exists $classNode->{Tmpl} ) { + print STDERR "(template)\n"; + } elsif ( $classNode->{Access} eq "private" or $classNode->{Access} eq "protected" ) { + print STDERR "(not public)\n"; + } elsif ( $classNode->{NodeType} eq 'union') { + print STDERR "(union)\n"; + } elsif ( $className =~ /^KSVG::KSVG/ || $className eq 'KSVG::CachedGlyph' ) { + print STDERR "(not a DOM class)\n"; + } else { + print STDERR "\n"; + } + $skippedClasses{$className} = 1; + #delete $classNode->{Compound}; # Cheat, to get it excluded from Iter::LocalCompounds + # Can't do that, it's recursive (KSVG::* disappears) + return; + } + + # Iterate over methods + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'method' ) { + if ( $methodNode->{astNodeName} eq 'get' ) { + $hasGet{$className} = '1'; + } elsif ( $methodNode->{astNodeName} eq 'getforward' ) { + $hasGet{$className} = '2'; + } elsif ( $methodNode->{astNodeName} eq 'put' ) { + $hasPut{$className} = '1'; + } elsif ( $methodNode->{astNodeName} eq 'putforward' ) { + $hasPut{$className} = '2'; + } elsif ( $methodNode->{astNodeName} eq 'getValueProperty' ) { + $hasHashTable{$className} = '1'; + } elsif ( $methodNode->{astNodeName} eq 'bridge' ) { + $hasBridge{$className} = '1'; + } + + } + } ); +} + +# List of all super-classes for a given class +sub superclass_list($) +{ + my $classNode = shift; + my @super; + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + push @super, @_[0]; + push @super, superclass_list( @_[0] ); + }, undef ); + return @super; +} + +# Adds the header for node $1 to be included in $2 if not already there +# Prints out debug stuff if $3 +sub addIncludeForClass($$$) +{ + my ( $node, $addInclude, $debugMe ) = @_; + my $sourcename = $node->{Source}->{astNodeName}; + $sourcename =~ s!.*/(.*)!$1!m; + unless ( defined $addInclude->{$sourcename} ) { + print " Including $sourcename\n" if ($debugMe); + $addInclude->{$sourcename} = 1; + } + else { print " $sourcename already included.\n" if ($debugMe); } +} + +=head2 + Write out the smokedata.cpp file containing all the arrays. +=cut + +sub writeInheritanceFile($) { + my $rootnode = shift; + + # Make list of classes + my %allIncludes; # list of all header files for all classes + my @classlist; + push @classlist, ""; # Prepend empty item for "no class" + Iter::LocalCompounds( $rootnode, sub { + my $classNode = $_[0]; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if ( defined $skippedClasses{$className} ); + push @classlist, $className; + $classNode->{ClassIndex} = $#classlist; + addIncludeForClass( $classNode, \%allIncludes, undef ); + } ); + + my %classidx = do { my $i = 0; map { $_ => $i++ } @classlist }; + #foreach my $debugci (keys %classidx) { + # print STDERR "$debugci: $classidx{$debugci}\n"; + #} + + my $file = "$outputdir/generateddata.cpp"; + open OUT, ">$file" or die "Couldn't create $file\n"; + print OUT "#include \n"; + print OUT "#include \n"; + + foreach my $incl (keys %allIncludes) { + die if $incl eq ''; + print OUT "#include <$incl>\n"; + } + + print OUT "\n"; + + # Prepare descendants information for each class + my %descendants; # classname -> list of descendant nodes + #my $SVGElementImplNode; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + # Get _all_ superclasses (up any number of levels) + # and store that $classNode is a descendant of $s + my @super = superclass_list($classNode); + for my $s (@super) { + my $superClassName = join( "::", kdocAstUtil::heritage($s) ); + Ast::AddPropList( \%descendants, $superClassName, $classNode ); + } + # Found SVGElementImpl itself + if ( $className eq 'KSVG::SVGElementImpl' ) { + $classNode->{IsSVGElement} = '1'; + #$SVGElementImplNode = $classNode; + } + } ); + + # Mark all SVGElementImpl descendants as svg elements + if ( defined $descendants{'KSVG::SVGElementImpl'} ) { + my @desc = @{$descendants{'KSVG::SVGElementImpl'}}; + for my $d (@desc) { + $d->{IsSVGElement} = '1' ; + print STDERR $d->{astNodeName}. " is an SVGElement\n" if($debug); + } + } + + # Propagate $hasPut and $hasGet + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + if ( defined $descendants{$className} ) { + my @desc = @{$descendants{$className}}; + for my $d (@desc) { + my $c = join( "::", kdocAstUtil::heritage($d) ); + $hasPut{$c} = '2' if (!$hasPut{$c} && $hasPut{$className}); + $hasGet{$c} = '2' if (!$hasGet{$c} && $hasGet{$className}); + } + } + + # This code prints out the base classes - useful for KSVG_BASECLASS_GET + if ( 0 && defined $descendants{$className} ) { + my $baseClass = 1; + Iter::Ancestors( $classNode, $rootnode, sub { # called if no ancestors + }, undef, sub { # called for each ancestor + my $superClassName = join( "::", kdocAstUtil::heritage($_[0]) ); + $baseClass = 0 if ( $superClassName ne '' ); # happens with unknown parents; + } ); + print STDERR "$className is a base class.\n" if ($baseClass); + } + + } ); + + # Write namespaces + print OUT "using namespace KSVG;\n"; + print OUT "using namespace KJS;\n\n"; + + # Write classInfos + print OUT "// For all classes with generated data: the ClassInfo\n"; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + # We use namespace declartions! + my $printName = $className; + $printName =~ s/KSVG:://; + + # Write tagNames + if ($hasBridge{$className}) { + my $tagName = $printName; + $tagName =~ s/SVG//; + $tagName =~ s/ElementImpl//; + + $tagName = lcfirst($tagName); + + # Special cases, otherwhise they'd be "tRef" / "tSpan" / "sVG" + if($printName eq "SVGTRefElementImpl" or + $printName eq "SVGTSpanElementImpl" or + $printName eq "SVGSVGElementImpl") { + $tagName =~ tr/A-Z/a-z/; + } + + while($tagName =~ /[A-Z]/g) { + # Special case: color-profile instead of ie. animateColor/animateMotion + if($printName eq "SVGColorProfileElementImpl") { + $tagName = substr($tagName, 0, pos($tagName) - 1) . "-" . lc($&) . substr($tagName, pos($tagName)); + } + } + + # Special cases: gradient & poly aren't element! + if($tagName ne "" and $tagName ne "gradient" and $tagName ne "poly") { + print OUT "const DOM::DOMString ${printName}::s_tagName = \"$tagName\";\n"; + } + } + + # Skip classes without KSVG_GENERATEDDATA + if (!$hasGet{$className} && !$skippedClasses{$className}) { + $skippedClasses{$className} = '1' ; + print STDERR "Skipping $className, no get()\n"; + } + + return if ( defined $skippedClasses{$className} ); + + my $ok = $hasHashTable{$className}; + print STDERR "$className has get() but no hashtable - TODO\n" if (!$ok && $hasGet{$className} eq '1'); + + print OUT "const ClassInfo ${printName}::s_classInfo = {\"$className\",0,"; + if ($ok) { + print OUT "\&${printName}::s_hashTable"; + } else { + print OUT "0"; + } + print OUT ",0};\n"; + #die "problem with $className" unless defined $classinherit{$className}; + #print OUT "const short int ${className}::s_inheritanceIndex = $classinherit{$className};\n"; + } ); + + # Generated methods + print OUT "\n"; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if ( defined $skippedClasses{$className} ); + + # We use namespace declartions! + my $printName = $className; + $printName =~ s/KSVG:://; + + my $paramsUsed = 0; + + print OUT "bool ${printName}::hasProperty(ExecState *p1,const Identifier &p2) const\n"; + print OUT "{\n"; + + if ($hasHashTable{$className}) { + print OUT " const HashEntry *e = Lookup::findEntry(\&${printName}::s_hashTable,p2);\n"; + print OUT " if(e) return true;\n"; + $paramsUsed=1; + } + # Now look in prototype, if it exists + if ( defined $hasFunctions{$className} ) { + + # We use namespace declartions! + my $output = $hasFunctions{$className}; + $output =~ s/KSVG:://; + + print OUT " Object proto = " . $output . "::self(p1);\n"; + print OUT " if(proto.hasProperty(p1,p2)) return true;\n"; + } + # For each direct ancestor... + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + my $superClassName = join( "::", kdocAstUtil::heritage($_[0]) ); + + # We use namespace declartions! + my $printSuperClassName = $superClassName; + $printSuperClassName =~ s/KSVG:://; + + if ( $superClassName ne '' ) { # happens with unknown parents + return if ( defined $skippedClasses{$superClassName} ); + print OUT " if(${printSuperClassName}::hasProperty(p1,p2)) return true;\n"; + $paramsUsed=2; + } + }, undef ); + if ($paramsUsed == 1 && !defined $hasFunctions{$className}){ + print OUT " Q_UNUSED(p1);\n"; + } + if ($paramsUsed == 0){ + print OUT " Q_UNUSED(p1); Q_UNUSED(p2);\n"; + } + print OUT " return false;\n"; + print OUT "}\n\n"; + + my @ancestorsWithGet; + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + my $superClassName = join( "::", kdocAstUtil::heritage($_[0]) ); + if ( $superClassName ne '' # happens with unknown parents + && ! defined $skippedClasses{$superClassName} ) { + if ( $hasGet{$superClassName} ) { + push @ancestorsWithGet, $superClassName; + } + } + }, undef ); + + if ($hasHashTable{$className}) { + die unless $hasGet{$className}; + if ( $hasGet{$className} eq '1' ) { + print OUT "Value ${printName}::get(GET_METHOD_ARGS) const\n"; + print OUT "{\n"; + if ( defined $hasFunctions{$className} ) { + + # We use namespace declartions! + my $output = $hasFunctions{$className}; + $output =~ s/KSVG:://; + + print OUT " return lookupGet<${output}Func,${printName}>(p1,p2,&s_hashTable,this,p3);\n"; + } else { + print OUT " return lookupGetValue<${printName}>(p1,p2,&s_hashTable,this,p3);\n"; + } + print OUT "}\n\n"; + + if ( defined $hasFunctions{$className} ) { + + # We use namespace declartions! + my $output = $hasFunctions{$className}; + $output =~ s/KSVG:://; + + my $methodName = "${output}Func::cast"; + my $const = 'const'; + # Special case - we also need that code in toNode() + if ($methodName eq 'SVGDOMNodeBridgeProtoFunc::cast') { + print OUT "${printName} *$methodName(const ObjectImp *p1) const\n"; + $methodName = 'KSVG::toNodeBridge'; + print OUT "{\n"; + print OUT " return $methodName(p1);\n"; + print OUT "}\n\n"; + $const = ''; + } + + # Type resolver for the Func class + print OUT "${printName} *$methodName(const ObjectImp *p1) $const\n"; + print OUT "{\n"; + my @toTry; + push @toTry, $classNode; + if ( defined $descendants{$className} ) { + push @toTry, @{$descendants{$className}}; + } + foreach my $d (@toTry) { + my $c = join( "::", kdocAstUtil::heritage($d) ); + + # We use namespace declartions! + my $d = $c; + $d =~ s/KSVG:://; + + print OUT " { const KSVGBridge<$d> *test = dynamic_cast * >(p1);\n"; + print OUT " if(test) return test->impl(); }\n"; + } + print OUT " return 0;\n"; + print OUT "}\n\n"; + } + } + } + + my $methodName = $hasGet{$className} eq '1' ? 'getInParents' : 'get'; + print OUT "Value ${printName}::$methodName(GET_METHOD_ARGS) const\n"; + print OUT "{\n"; + my $paramsUsed = 0; + # Now look in prototype, if it exists + if ( defined $hasFunctions{$className} ) { + # Prototype exists (because the class has functions) + + # We use namespace declartions! + my $output = $hasFunctions{$className}; + $output =~ s/KSVG:://; + + print OUT " Object proto = " . $output . "::self(p1);\n"; + print OUT " if(proto.hasProperty(p1,p2)) return proto.get(p1,p2);\n"; ## TODO get() directly + $paramsUsed = 1; + } + foreach my $anc (@ancestorsWithGet) { + # We use namespace declartions! + my $printAnc = $anc; + $printAnc =~ s/KSVG:://; + + print OUT " if(${printAnc}::hasProperty(p1,p2)) return ${printAnc}::get(p1,p2,p3);\n"; ## TODO get() directly + $paramsUsed = 2; + } + + if ($paramsUsed == 0 ){ + print OUT " Q_UNUSED(p1); Q_UNUSED(p2); Q_UNUSED(p3);\n"; + } elsif ( $paramsUsed == 1 ) { + print OUT " Q_UNUSED(p3);\n"; + } + print OUT " return Undefined();\n"; + print OUT "}\n\n"; + + if ( $hasPut{$className} ) + { + if ( $hasPut{$className} eq '1' ) { + if ($hasHashTable{$className}) { + print OUT "bool ${printName}::put(PUT_METHOD_ARGS)\n"; + print OUT "{\n"; + print OUT " return lookupPut<${printName}>(p1,p2,p3,p4,&s_hashTable,this);\n"; + print OUT "}\n\n"; + } + print OUT "bool ${printName}::putInParents(PUT_METHOD_ARGS)\n"; + } else { # forward put + print OUT "bool ${printName}::put(PUT_METHOD_ARGS)\n"; + } + print OUT "{\n"; + my $paramsUsed = 0; + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + my $superClassName = join( "::", kdocAstUtil::heritage($_[0]) ); + + # We use namespace declartions! + my $printSuperClassName = $superClassName; + $printSuperClassName =~ s/KSVG:://; + + if ( $superClassName ne '' ) { # happens with unknown parents + if ( $hasPut{$superClassName} ) { + print OUT " if(${printSuperClassName}::hasProperty(p1,p2)) {\n"; + print OUT " ${printSuperClassName}::put(p1,p2,p3,p4);\n"; + print OUT " return true;\n"; + print OUT " }\n"; + $paramsUsed=1; + } + } + }, undef ); + if (!$paramsUsed){ + print OUT " Q_UNUSED(p1); Q_UNUSED(p2); Q_UNUSED(p3); Q_UNUSED(p4);\n"; + } + print OUT " return false;\n"; + print OUT "}\n\n"; + } + + # Write prototype method + print OUT "Object ${printName}::prototype(ExecState *p1) const\n"; + print OUT "{\n"; + if ( defined $hasFunctions{$className} ) { + + # We use namespace declartions! + my $output = $hasFunctions{$className}; + $output =~ s/KSVG:://; + + # Prototype exists (because the class has functions) + print OUT " if(p1) return " . $output . "::self(p1);\n"; + } else { + # Standard Object prototype + print OUT " if(p1) return p1->interpreter()->builtinObjectPrototype();\n"; + } + print OUT " return Object::dynamicCast(Null());\n"; # hmm + + print OUT "}\n\n"; + + # Process classes only with KSVG_BRIDGE + if ($hasBridge{$className}) { + + #print STDERR "Writing bridge() for $className...\n"; + + # Write bridge method + print OUT "ObjectImp *${printName}::bridge(ExecState *p1) const\n"; + print OUT "{\n"; + + if ($hasPut{$className}) + { + print OUT " return new KSVGRWBridge<${printName}>(p1,const_cast<${printName} *>(this));\n"; + } + else + { + print OUT " return new KSVGBridge<${printName}>(p1,const_cast<${printName} *>(this));\n"; + } + + print OUT "}\n\n"; + } + + if ($hasGet{$className}) { + # Write cache method + print OUT "Value ${printName}::cache(ExecState *p1) const\n"; + print OUT "{\n"; + + if ($hasPut{$className}) + { + print OUT " return KJS::Value(cacheDOMObject<${printName},KSVGRWBridge<${printName}> >(p1,const_cast<${printName} *>(this)));\n"; + } + else + { + print OUT " return KJS::Value(cacheDOMObject<${printName},KSVGBridge<${printName}> >(p1,const_cast<${printName} *>(this)));\n"; + } + + print OUT "}\n\n"; + } + + } ); + +} + +1; diff --git a/kalyptus/kalyptusCxxToJNI.pm b/kalyptus/kalyptusCxxToJNI.pm new file mode 100644 index 0000000..2da2cc7 --- /dev/null +++ b/kalyptus/kalyptusCxxToJNI.pm @@ -0,0 +1,5595 @@ +#*************************************************************************** +# kalyptusCxxToJNI.pm - Generates *.java and *.cpp files for a JNI based +# version of Qt/KDE java bindings +# ------------------- +# begin : Sun Nov 16 12:00:00 2003 +# copyright : (C) 2003, Richard Dale. All Rights Reserved. +# email : Richard_Dale@tipitina.demon.co.uk +# author : Richard Dale, based on the SMOKE generation code +# by David Faure. +#***************************************************************************/ + +#/*************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation; either version 2 of the License, or * +# * (at your option) any later version. * +# * * +#***************************************************************************/ + +package kalyptusCxxToJNI; + +use File::Path; +use File::Basename; + +use Carp; +use Ast; +use kdocAstUtil; +use kdocUtil; +use Iter; +use kalyptusDataDict; + +use strict; +no strict "subs"; + +use vars qw/ + $libname $rootnode $outputdir $opt $debug + $qapplicationExtras $qapplicationjniExtras $qbitmapExtras $qbitmapjniExtras + $qlistviewExtras $qlistviewjniExtras $qlistviewitemExtras $qlistviewitemjniExtras + $qpopupmenujniExtras $qmenudatajniExtras $qmenubarjniExtras + $qdragobjectExtras $qdragobjectjniExtras $qdropeventExtras $qdropeventjniExtras $qmimesourceExtras $qmimesourcejniExtras + $qtExtras $qtjniExtras $qobjectExtras $qobjectjniExtras $qimagejniExtras $qwidgetExtras $qwidgetjniExtras + $qpixmapExtras $qpixmapjniExtras $qpaintdeviceExtras $qpaintdevicejniExtras + $qdragobjectExtras $qdragobjectjniExtras $qiodeviceExtras $qpointarrayExtras $qpointarrayjniExtras + $qtextcodecExtras $qtextcodecjniExtras $quridragExtras $quridragjniExtras + $kapplicationExtras $kapplicationjniExtras $kmainwindowExtras $kmainwindowjniExtras + $kcmdlineargsjniExtras $schedulerjniExtras + $methodNumber + %builtins %typeunion %allMethods %allTypes %enumValueToType %typedeflist %mungedTypeMap %javaImports + %skippedClasses %skippedJniMethods %operatorNames /; + +BEGIN +{ + +# Types supported by the StackItem union +# Key: C++ type Value: Union field of that type +%typeunion = ( + 'void*' => 's_voidp', + 'bool' => 's_bool', + 'char' => 's_char', + 'uchar' => 's_uchar', + 'short' => 's_short', + 'ushort' => 's_ushort', + 'int' => 's_int', + 'uint' => 's_uint', + 'long' => 's_long', + 'ulong' => 's_ulong', + 'float' => 's_float', + 'double' => 's_double', + 'enum' => 's_enum', + 'class' => 's_class' +); + +# Mapping for iterproto, when making up the munged method names +%mungedTypeMap = ( + 'TQString' => '$', + 'TQString*' => '$', + 'TQString&' => '$', + 'TQCString' => '$', + 'TQCString*' => '$', + 'TQCString&' => '$', + 'TQByteArray' => '$', + 'TQByteArray&' => '$', + 'TQByteArray*' => '$', + 'char*' => '$', + 'TQCOORD*' => '?', + 'TQRgb*' => '?', +); + +# Yes some of this is in kalyptusDataDict's ctypemap +# but that one would need to be separated (builtins vs normal classes) +%typedeflist = +( + 'signed char' => 'char', + 'unsigned char' => 'uchar', + 'signed short' => 'short', + 'unsigned short' => 'ushort', + 'signed' => 'int', + 'signed int' => 'int', + 'unsigned' => 'uint', + 'unsigned int' => 'uint', + 'KIO::filesize_t' => 'long', + 'signed long' => 'long', + 'unsigned long' => 'ulong', + +# Anything that is not known is mapped to void*, so no need for those here anymore +# 'TQWSEvent*' => 'void*', +# 'TQDiskFont*' => 'void*', +# 'XEvent*' => 'void*', +# 'FILE*' => 'void*', +# 'TQUnknownInterface*' => 'void*', +# 'GDHandle' => 'void*', +# '_NPStream*' => 'void*', +# 'TQTextFormat*' => 'void*', +# 'TQTextDocument*' => 'void*', +# 'TQTextCursor*' => 'void*', +# 'TQTextParag**' => 'void*', +# 'TQTextParag*' => 'void*', +# 'TQRemoteInterface*' => 'void*', +# 'TQSqlRecordPrivate*' => 'void*', +# 'TQTSMFI' => 'void*', # TQTextStream's TQTSManip +# 'const GUID&' => 'void*', +# 'TQWidgetMapper*' => 'void*', +# 'MSG*' => 'void*', +# 'const TQSqlFieldInfoList&' => 'void*', # TQSqlRecordInfo - TODO (templates) + + 'TQStyleHintReturn*' => 'void*', + 'TQPtrCollection::Item' => 'void*', # to avoid a warning + + 'mode_t' => 'long', + 'TQProcess::PID' => 'long', + 'size_type' => 'int', # TQSqlRecordInfo + 'TQt::ComparisonFlags' => 'uint', + 'TQt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it + 'TQIODevice::Offset' => 'ulong', + 'WState' => 'int', + 'WId' => 'ulong', + 'TQRgb' => 'uint', + 'ksocklen_t' => 'uint', + 'TQCOORD' => 'int', + 'TQTSMFI' => 'int', + 'TQt::WState' => 'int', + 'TQt::WFlags' => 'int', + 'TQt::HANDLE' => 'uint', + 'TQEventLoop::ProcessEventsFlags' => 'uint', + 'TQStyle::SCFlags' => 'int', + 'TQStyle::SFlags' => 'int', + 'Q_INT16' => 'short', + 'Q_INT32' => 'int', + 'Q_INT64' => 'long', + 'Q_INT8' => 'char', + 'Q_LONG' => 'long', + 'Q_LLONG' => 'long', + 'Q_ULLONG' => 'long', + 'Q_UINT16' => 'ushort', + 'Q_UINT32' => 'uint', + 'Q_UINT64' => 'long', + 'Q_UINT8' => 'uchar', + 'Q_ULONG' => 'long', + 'pid_t' => 'int', + 'size_t' => 'int', + 'pid_t' => 'int', + 'time_t' => 'int', + 'short int' => 'short', + 'unsigned long long int' => 'ulong', + 'long long int' => 'long', + 'signed long int' => 'long', + 'unsigned long int' => 'ulong', + 'int long' => 'long', + 'unsigned short int' => 'ushort', +); + +%operatorNames = +( + 'operator^' => 'op_xor', + 'operator^=' => 'op_xor_assign', + 'operator<' => 'op_lt', + 'operator<<' => 'op_write', + 'operator<=' => 'op_lte', +# 'operator=' => 'op_assign', + 'operator==' => 'op_equals', + 'operator>' => 'op_gt', + 'operator>=' => 'op_gte', + 'operator>>' => 'op_read', + 'operator|' => 'op_or', + 'operator|=' => 'op_or_assign', + 'operator-' => 'op_minus', + 'operator-=' => 'op_minus_assign', + 'operator--' => 'op_decr', + 'operator!' => 'op_not', + 'operator!=' => 'op_not_equals', + 'operator/' => 'op_div', + 'operator/=' => 'op_div_assign', + 'operator()' => 'op_expr', + 'operator[]' => 'op_at', + 'operator*' => 'op_mult', + 'operator*=' => 'op_mult_assign', + 'operator&' => 'op_and', + 'operator&=' => 'op_and_assign', + 'operator+' => 'op_plus', + 'operator+=' => 'op_plus_assign', + 'operator++' => 'op_incr', +); + +%skippedJniMethods = +( + 'Java_org_kde_qt_QApplication_newTQApplication___3Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QApplication_newTQApplication___3Ljava_lang_String_2Z' => 1, + 'Java_org_kde_qt_QApplication_newTQApplication___3Ljava_lang_String_2I' => 1, + 'Java_org_kde_qt_QApplication_newTQApplication___3I_3Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QApplication_newTQApplication___3I_3Ljava_lang_String_2Z' => 1, + 'Java_org_kde_qt_QApplication_newTQApplication___3I_3Ljava_lang_String_2I' => 1, + 'Java_org_kde_qt_QApplication_newTQApplication__I_3Ljava_lang_String_2I' => 1, + 'Java_org_kde_qt_QApplication_newTQApplication__I_3Ljava_lang_String_2Z' => 1, + 'Java_org_kde_qt_QApplication_newTQApplication__I_3Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QApplication_args__' => 1, + 'Java_org_kde_qt_QBitmap_newTQBitmap__Lorg_kde_qt_QPixmap_2' => 1, + 'Java_org_kde_qt_QBitmap_newTQBitmap__Lorg_kde_qt_QImage_2' => 1, + 'Java_org_kde_qt_QListView_itemList' => 1, + 'Java_org_kde_qt_QListViewItem_itemList' => 1, + 'Java_org_kde_qt_Qt_color0' => 1, + 'Java_org_kde_qt_Qt_color1' => 1, + 'Java_org_kde_qt_Qt_black' => 1, + 'Java_org_kde_qt_Qt_white' => 1, + 'Java_org_kde_qt_Qt_darkGray' => 1, + 'Java_org_kde_qt_Qt_lightGray' => 1, + 'Java_org_kde_qt_Qt_gray' => 1, + 'Java_org_kde_qt_Qt_red' => 1, + 'Java_org_kde_qt_Qt_green' => 1, + 'Java_org_kde_qt_Qt_blue' => 1, + 'Java_org_kde_qt_Qt_cyan' => 1, + 'Java_org_kde_qt_Qt_magenta' => 1, + 'Java_org_kde_qt_Qt_yellow' => 1, + 'Java_org_kde_qt_Qt_darkRed' => 1, + 'Java_org_kde_qt_Qt_darkGreen' => 1, + 'Java_org_kde_qt_Qt_darkBlue' => 1, + 'Java_org_kde_qt_Qt_darkCyan' => 1, + 'Java_org_kde_qt_Qt_darkMagenta' => 1, + 'Java_org_kde_qt_Qt_darkYellow' => 1, + 'Java_org_kde_qt_Qt_arrowCursor' => 1, + 'Java_org_kde_qt_Qt_upArrowCursor' => 1, + 'Java_org_kde_qt_Qt_crossCursor' => 1, + 'Java_org_kde_qt_Qt_waitCursor' => 1, + 'Java_org_kde_qt_Qt_ibeamCursor' => 1, + 'Java_org_kde_qt_Qt_sizeVerCursor' => 1, + 'Java_org_kde_qt_Qt_sizeHorCursor' => 1, + 'Java_org_kde_qt_Qt_sizeBDiagCursor' => 1, + 'Java_org_kde_qt_Qt_sizeFDiagCursor' => 1, + 'Java_org_kde_qt_Qt_sizeAllCursor' => 1, + 'Java_org_kde_qt_Qt_blankCursor' => 1, + 'Java_org_kde_qt_Qt_splitVCursor' => 1, + 'Java_org_kde_qt_Qt_splitHCursor' => 1, + 'Java_org_kde_qt_Qt_pointingHandCursor' => 1, + 'Java_org_kde_qt_Qt_forbiddenCursor' => 1, + 'Java_org_kde_qt_Qt_qApp' => 1, + 'Java_org_kde_qt_Qt_qDebug' => 1, + 'Java_org_kde_qt_Qt_qWarning' => 1, + 'Java_org_kde_qt_Qt_qFatal' => 1, + 'Java_org_kde_qt_QObject_connect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QObject_connect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QObject_disconnect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QObject_disconnect__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QObject_emit' => 1, + 'Java_org_kde_qt_QWidget_paintDevice' => 1, + 'Java_org_kde_qt_QImage_bits__' => 1, + 'Java_org_kde_qt_QImage_colorTable__' => 1, + 'Java_org_kde_qt_QImage_scanLine__I' => 1, + 'Java_org_kde_qt_QPixmap_paintDevice' => 1, + 'Java_org_kde_qt_QPixmap_loadFromData___3C' => 1, + 'Java_org_kde_qt_QPaintDevice_paintDevice' => 1, + 'Java_org_kde_qt_QDragObject_mimeSource' => 1, + 'Java_org_kde_qt_QPointArray_point__I_3I_3I' => 1, + 'Java_org_kde_qt_QPointArray_setPoints__I_3S' => 1, + 'Java_org_kde_qt_QPointArray_putPoints__II_3S' => 1, + 'Java_org_kde_qt_QPointArray_count__' => 1, + 'Java_org_kde_qt_QPointArray_isEmpty__' => 1, + 'Java_org_kde_qt_QPointArray_isNull__' => 1, + 'Java_org_kde_qt_QPointArray_resize__' => 1, + 'Java_org_kde_qt_QPopupMenu_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QKeySequence_2II' => 1, + 'Java_org_kde_qt_QPopupMenu_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QPopupMenu_connectItem__ILorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QPopupMenu_disconnectItem__ILorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuData_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QKeySequence_2II' => 1, + 'Java_org_kde_qt_QMenuData_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuData_connectItem__ILorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuData_disconnectItem__ILorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuBar_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QKeySequence_2II' => 1, + 'Java_org_kde_qt_QMenuBar_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuBar_connectItem__ILorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuBar_disconnectItem__ILorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QUriDrag_decode__Lorg_kde_qt_QMimeSourceInterface_2_3Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QUriDrag_decodeToUnicodeUris__Lorg_kde_qt_QMimeSourceInterface_2_3Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QUriDrag_decodeLocalFiles__Lorg_kde_qt_QMimeSourceInterface_2_3Ljava_lang_String_2' => 1, + 'Java_org_kde_koala_KApplication_setJavaSlotFactory' => 1, + 'Java_org_kde_koala_KMainWindow_memberList' => 1, + 'Java_org_kde_koala_KCmdLineArgs_init__I_3Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2' => 1, + 'Java_org_kde_koala_KCmdLineArgs_init__I_3Ljava_lang_String_2Lorg_kde_koala_KAboutData_2' => 1, + 'Java_org_kde_koala_KCmdLineArgs_init__I_3Ljava_lang_String_2Lorg_kde_koala_KAboutData_2Z' => 1, + 'Java_org_kde_koala_KCmdLineArgs_init__I_3Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Z' => 1, + 'Java_org_kde_koala_Scheduler_connect__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_koala_Scheduler_connect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Ljava_lang_String_2' => 1, + 'Java_org_kde_koala_Scheduler_disconnect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_koala_Scheduler_disconnect' => 1, +); + + $qapplicationExtras = <GetArrayLength(args) + 1; + _args = (jobjectArray) env->NewGlobalRef(args); + if (QtSupport::getQt(env, obj) == 0) { + QtSupport::setQt(env, obj, new TQApplicationJBridge(argc, QtSupport::toArgv(env, args))); + QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj)); + } + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_qt_QApplication_newTQApplication___3Ljava_lang_String_2Z(JNIEnv *env, jobject obj, jobjectArray args, jboolean GUIenabled) +{ + int argc = (int) env->GetArrayLength(args) + 1; + _args = (jobjectArray) env->NewGlobalRef(args); + if (QtSupport::getQt(env, obj) == 0) { + QtSupport::setQt(env, obj, new TQApplicationJBridge(argc, QtSupport::toArgv(env, args), (bool) GUIenabled)); + QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj)); + } + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_qt_QApplication_newTQApplication___3Ljava_lang_String_2I(JNIEnv *env, jobject obj, jobjectArray args, jint arg1) +{ + int argc = (int) env->GetArrayLength(args) + 1; + _args = (jobjectArray) env->NewGlobalRef(args); + if (QtSupport::getQt(env, obj) == 0) { + QtSupport::setQt(env, obj, new TQApplicationJBridge(argc, QtSupport::toArgv(env, args), (TQApplication::Type) arg1)); + QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj)); + } + return; +} + +JNIEXPORT jobjectArray JNICALL +Java_org_kde_qt_QApplication_args(JNIEnv *env, jobject obj) +{ + (void) env; + (void) obj; + return _args; +} + +EOF + + $qbitmapExtras = < +#include +#include + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_color0(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::color0, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_color1(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::color1, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_black(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::black, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_white(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::white, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkGray(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::darkGray, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_lightGray(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::lightGray, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_gray(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::gray, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_red(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::red, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_green(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::green, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_blue(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::blue, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_cyan(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::cyan, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_magenta(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::magenta, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_yellow(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::yellow, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkRed(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::darkRed, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkGreen(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::darkGreen, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkBlue(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::darkBlue, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkCyan(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::darkCyan, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkMagenta(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::darkMagenta, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkYellow(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::darkYellow, "org.kde.qt.TQColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_arrowCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::arrowCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_upArrowCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::upArrowCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_crossCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::crossCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_waitCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::waitCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_ibeamCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::ibeamCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_sizeVerCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::sizeVerCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_sizeHorCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::sizeHorCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_sizeBDiagCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::sizeBDiagCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_sizeFDiagCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::sizeFDiagCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_sizeAllCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::sizeAllCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_blankCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::blankCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_splitVCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::splitVCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_splitHCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::splitHCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_pointingHandCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::pointingHandCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_forbiddenCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::forbiddenCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_whatsThisCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&TQt::whatsThisCursor, "org.kde.qt.TQCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_qApp(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, qApp, "org.kde.qt.TQApplication"); +} + +JNIEXPORT void JNICALL +Java_org_kde_qt_Qt_qDebug(JNIEnv* env, jclass cls, jstring message) +{ +static TQCString * _qstring_message = 0; + (void) cls; + qDebug("%s", (const char *) QtSupport::toCharString(env, message, &_qstring_message)); + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_qt_Qt_qWarning(JNIEnv* env, jclass cls, jstring message) +{ +static TQCString * _qstring_message = 0; + (void) cls; + qWarning("%s", (const char *) QtSupport::toCharString(env, message, &_qstring_message)); + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_qt_Qt_qFatal(JNIEnv* env, jclass cls, jstring message) +{ +static TQCString * _qstring_message = 0; + (void) cls; + qFatal("%s", (const char *) QtSupport::toCharString(env, message, &_qstring_message)); + return; +} + +EOF + + $qobjectExtras = <bits(); + int len = ((TQImageJBridge*) QtSupport::getQt(env, obj))->numBytes(); + jbyteArray result = env->NewByteArray(len); + env->SetByteArrayRegion(result, 0, len, (jbyte *) ptr); + return result; +} + +JNIEXPORT jbyteArray JNICALL +Java_org_kde_qt_QImage_scanLine(JNIEnv *env, jobject obj, jint arg1) +{ +static uchar * ptr = 0; + ptr = ((TQImageJBridge*) QtSupport::getQt(env, obj))->scanLine(arg1); + int len = ((TQImageJBridge*) QtSupport::getQt(env, obj))->numBytes() / ((TQImageJBridge*) QtSupport::getQt(env, obj))->height(); + jbyteArray result = env->NewByteArray(len); + env->SetByteArrayRegion(result, 0, len, (jbyte *) ptr); + return result; +} + +JNIEXPORT jintArray JNICALL +Java_org_kde_qt_QImage_colorTable(JNIEnv *env, jobject obj) +{ +static TQRgb * ptr = 0; + ptr = ((TQImageJBridge*) QtSupport::getQt(env, obj))->colorTable(); + int len = ((TQImageJBridge*) QtSupport::getQt(env, obj))->numColors(); + jintArray result = env->NewIntArray(len); + env->SetIntArrayRegion(result, 0, len, (jint *) ptr); + return result; +} + +EOF + + $qpixmapExtras = <loadFromData((uchar *) QtSupport::toUcharArray(env, data, &_qbyteArray_data), env->GetArrayLength(data), 0, 0); +} + +JNIEXPORT jlong JNICALL +Java_org_kde_qt_QPixmap_paintDevice(JNIEnv* env, jobject obj) +{ + return (jlong) (TQPaintDevice*)(TQPixmap*) QtSupport::getQt(env, obj); +} + +EOF + + $qpaintdeviceExtras = <point((uint) i, &argx, &argy); + env->SetIntArrayRegion(x, 0, 1, (jint *) &argx); + env->SetIntArrayRegion(y, 0, 1, (jint *) &argy); + return; +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPointArray_setPoints(JNIEnv *env, jobject obj, jint nPoints, jshortArray points) +{ + if (!((TQPointArrayJBridge*) QtSupport::getQt(env, obj))->resize((uint)nPoints)) { + return JNI_FALSE; + } + + short * shortArray = QtSupport::toShortPtr(env, points); + for (int index = 0; index < nPoints; index++) { + ((TQPointArrayJBridge*) QtSupport::getQt(env, obj))->setPoint(index, shortArray[index * 2], shortArray[(index * 2) + 1]); + } + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPointArray_putPoints__II_3S(JNIEnv *env, jobject obj, jint index, jint nPoints, jshortArray points) +{ + if ( ((TQPointArrayJBridge*) QtSupport::getQt(env, obj))->size() < (uint) nPoints + && !((TQPointArrayJBridge*) QtSupport::getQt(env, obj))->resize((uint) nPoints) ) + { + return JNI_FALSE; + } + + short * shortArray = QtSupport::toShortPtr(env, points); + for (int i = (int) index; nPoints > 0; i++, nPoints--) { + ((TQPointArrayJBridge*) QtSupport::getQt(env, obj))->setPoint(i, shortArray[i * 2], shortArray[(i * 2) + 1]); + } + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QPointArray_size(JNIEnv* env, jobject obj) +{ + return (jint) ((TQPointArrayJBridge*) QtSupport::getQt(env, obj))->size(); +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QPointArray_count(JNIEnv* env, jobject obj) +{ + return (jint) ((TQPointArrayJBridge*) QtSupport::getQt(env, obj))->count(); +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPointArray_isEmpty(JNIEnv* env, jobject obj) +{ + return (jboolean) ((TQPointArrayJBridge*) QtSupport::getQt(env, obj))->isEmpty(); +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPointArray_isNull(JNIEnv* env, jobject obj) +{ + return (jboolean) ((TQPointArrayJBridge*) QtSupport::getQt(env, obj))->isNull(); +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPointArray_resize(JNIEnv* env, jobject obj, jint size) +{ + return (jboolean) ((TQPointArrayJBridge*) QtSupport::getQt(env, obj))->resize((uint) size); +} +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPointArray_truncate(JNIEnv *env, jobject obj, jint pos) +{ + return (jboolean) ((TQPointArrayJBridge*) QtSupport::getQt(env, obj))->truncate((uint) pos); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_QPointArray_at(JNIEnv * env, jobject obj, jint index) +{ + TQPoint _p= ((TQPointArrayJBridge*) QtSupport::getQt(env, obj))->at((uint) index); + return (jobject) QtSupport::objectForQtKey(env, (void *)new TQPoint(_p.x(),_p.y()), "org.kde.qt.TQPoint", TRUE); +} + +EOF + + $qpopupmenujniExtras = <connectItem( identifier, + javaSlot, + javaSlot->javaToQtSlotName(env, member) ) ) + { + return(jboolean) JNI_TRUE; + } else { + return (jboolean) JNI_FALSE; + } +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPopupMenu_disconnectItem(JNIEnv *env, jobject obj, jint identifier, jobject receiver, jstring member) +{ + JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member); + + if ( ((TQPopupMenuJBridge*) QtSupport::getQt(env, obj))->disconnectItem( identifier, + javaSlot, + javaSlot->javaToQtSlotName(env, member) ) ) + { + return(jboolean) JNI_TRUE; + } else { + return (jboolean) JNI_FALSE; + } +} + +EOF + + $qmenudatajniExtras = <connectItem( identifier, + javaSlot, + javaSlot->javaToQtSlotName(env, member) ) ) + { + return(jboolean) JNI_TRUE; + } else { + return (jboolean) JNI_FALSE; + } +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QMenuData_disconnectItem(JNIEnv *env, jobject obj, jint identifier, jobject receiver, jstring member) +{ + JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member); + + if ( ((TQMenuDataJBridge*) QtSupport::getQt(env, obj))->disconnectItem( identifier, + javaSlot, + javaSlot->javaToQtSlotName(env, member) ) ) + { + return(jboolean) JNI_TRUE; + } else { + return (jboolean) JNI_FALSE; + } +} + +EOF + + $qmenubarjniExtras = <connectItem( identifier, + javaSlot, + javaSlot->javaToQtSlotName(env, member) ) ) + { + return(jboolean) JNI_TRUE; + } else { + return (jboolean) JNI_FALSE; + } +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QMenuBar_disconnectItem(JNIEnv *env, jobject obj, jint identifier, jobject receiver, jstring member) +{ + JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member); + + if ( ((TQMenuBarJBridge*) QtSupport::getQt(env, obj))->disconnectItem( identifier, + javaSlot, + javaSlot->javaToQtSlotName(env, member) ) ) + { + return(jboolean) JNI_TRUE; + } else { + return (jboolean) JNI_FALSE; + } +} + + +EOF + + $quridragExtras = < + +JNIEXPORT void JNICALL +Java_org_kde_koala_KApplication_setJavaSlotFactory(JNIEnv* env, jclass cls) +{ + (void) env; + (void) cls; + JavaSlot::setJavaSlotFactory(new KDEJavaSlotFactory()); + return; +} + +EOF + + $kmainwindowExtras = <GetArrayLength(args); + KCmdLineArgsJBridge::init((int) argc+1, (char**) QtSupport::toArgv(env, args), (const char*) QtSupport::toCharString(env, _appname, &_qstring__appname), (const char*) QtSupport::toCharString(env, programName, &_qstring_programName), (const char*) QtSupport::toCharString(env, _description, &_qstring__description), (const char*) QtSupport::toCharString(env, _version, &_qstring__version)); + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_koala_KCmdLineArgs_init___3Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Z(JNIEnv* env, jclass cls, jobjectArray args, jstring _appname, jstring programName, jstring _description, jstring _version, jboolean noKApp) +{ + (void) cls; +static TQCString* _qstring__appname = 0; +static TQCString* _qstring_programName = 0; +static TQCString* _qstring__description = 0; +static TQCString* _qstring__version = 0; + int argc = (int) env->GetArrayLength(args); + KCmdLineArgsJBridge::init(argc+1, (char**) QtSupport::toArgv(env, args), (const char*) QtSupport::toCharString(env, _appname, &_qstring__appname), (const char*) QtSupport::toCharString(env, programName, &_qstring_programName), (const char*) QtSupport::toCharString(env, _description, &_qstring__description), (const char*) QtSupport::toCharString(env, _version, &_qstring__version), (bool) noKApp); + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_koala_KCmdLineArgs_init___3Ljava_lang_String_2Lorg_kde_koala_KAboutData_2(JNIEnv* env, jclass cls, jobjectArray args, jobject about) +{ + (void) cls; + int argc = (int) env->GetArrayLength(args); + KCmdLineArgsJBridge::init(argc+1, (char**) QtSupport::toArgv(env, args), (const KAboutData*) QtSupport::getQt(env, about)); + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_koala_KCmdLineArgs_init___3Ljava_lang_String_2Lorg_kde_koala_KAboutData_2Z(JNIEnv* env, jclass cls, jobjectArray args, jobject about, jboolean noKApp) +{ + (void) cls; + int argc = (int) env->GetArrayLength(args); + KCmdLineArgsJBridge::init(argc+1, (char**) QtSupport::toArgv(env, args), (const KAboutData*) QtSupport::getQt(env, about), (bool) noKApp); + return; +} + +EOF + + $schedulerjniExtras = <javaToQtSignalName(env, signal, 0)); + jboolean xret = (jboolean) SchedulerJBridge::connect((const char*) qtSignalName, (const TQObject*) javaSlot, javaSlot->javaToQtSlotName(env, member, qtSignalName)); + return xret; +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_koala_Scheduler_connect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject sender, jstring signal, jstring member) +{ + return QtSupport::connect(env, sender, signal, obj, member); +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_koala_Scheduler_disconnect(JNIEnv *env, jclass cls, jobject sender, jstring signal, jobject receiver, jstring member) +{ + (void) cls; + return QtSupport::disconnect(env, sender, signal, receiver, member); +} + +EOF + +} + +sub javaImport($) +{ + my ( $classname ) = @_; + my $classname_ptr = $classname . "*"; + if ( cplusplusToJava($classname_ptr) eq "" or $classname eq $main::globalSpaceClassName ) { + return ""; + } elsif ( cplusplusToJava($classname_ptr) eq "ArrayList" ) { + return "java.util.ArrayList"; + } elsif ( cplusplusToJava($classname_ptr) eq "Calendar" ) { + return "java.util.Calendar"; + } elsif ( cplusplusToJava($classname_ptr) eq "StringBuffer" ) { + return ""; + } elsif ( cplusplusToJava($classname_ptr) eq "String" ) { + return ""; + } elsif ( cplusplusToJava($classname_ptr) eq "String[][]" ) { + return ""; + } elsif ( cplusplusToJava($classname_ptr) eq "String[]" ) { + return ""; + } elsif ( cplusplusToJava($classname_ptr) eq "Date" ) { + return "java.util.Date"; + } elsif ( cplusplusToJava($classname_ptr) =~ /^[a-z]/ ) { + return ""; + } elsif ( $classname =~ /^Q/ ) { + return "org.kde.qt." . $classname; + } else { + return "org.kde.koala." . $classname; + } +} + +sub cplusplusToJava +{ + my ( $cplusplusType ) = @_; + my $isConst = ($cplusplusType =~ /const / or $cplusplusType !~ /[*&]/ ? 1 : 0); + $cplusplusType =~ s/const //; + $cplusplusType =~ s/^signed//; + my $className = $cplusplusType; + $className =~ s/[*&]//; + + if ( $cplusplusType =~ /void\*|DCOPArg|DCOPRef|^MSG\s*\*|TQGfx|^Display\s*\*|KHTMLPart::PageSecurity|TQFileInfoList|TQValueList|TQValueList|TQValueList|TQValueList|TQValueListConstIterator|TQMap|EditMode|TQPtrList|TQPtrList|TQTextFormat|TQTextCursor|TQTextDocument|TQNetworkProtocolFactoryBase|TQDomNodePrivate|TQSqlDriverCreatorBase|TQSqlFieldInfoList|TQObjectUserData|TQUObject|TQTextParag|TQWidgetMapper|TQMemArray|TQBitArray|TQLayoutIterator|TQAuBucket|TQUnknownInterface|TQConnectionList/ ) { + return ""; # Unsupported type + } elsif ( $cplusplusType =~ /TQSignal\s*\*|TQMenuItem|TQWSEvent|TQWSDisplay|TQWSSocket|TQPaintDeviceX11Data|TQWindowsMime|TQDirectPainter|TQMember|TQDiskFont|TQGCache|TQRichText|TQWSDecoration/ && $main::qt_embedded ) { + return ""; # Unsupported Qt/E type + } elsif ( $cplusplusType =~ /bool/ && kalyptusDataDict::ctypemap($cplusplusType) eq "int" ) { + return "boolean"; + } elsif ( $cplusplusType =~ /bool\s*[*&]/ ) { + return "boolean[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^void\s*\*/ ) { + return "int"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^\s*(unsigned )?int\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /^qt_QIntValueList\*/ + || $cplusplusType =~ /^int[*&]$/ ) + { + return "int[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^\s*double\s*\*/ ) { + return "double[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^\s*(unsigned )?short\s*\*/ ) { + return "short[]"; + } elsif ( $cplusplusType =~ /KCmdLineOptions/ ) { + return "String[][]"; + } elsif ( $cplusplusType =~ /char\s*\*\*/ || $cplusplusType =~ /TQStringList/|| $cplusplusType =~ /TQStrList/) { + return "String[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QUrlInfoValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QVariantValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QIconDragItemValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QPixmapValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_QCStringList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QObjectList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QDomNodeList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QWidgetList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KURLList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KMainWindow\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KFileItemList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KFileViewItemList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_DOMNodeList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_StyleSheetList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_MediaList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_OfferList\s*\*/ + || $cplusplusType =~ /TQMemArray/ + || $cplusplusType =~ /TQArray/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QCanvasItemList\s*\*/ ) { + return "ArrayList" + } elsif ( $cplusplusType =~ /uchar\s*\*/ ) { + return "char[]"; + } elsif ( $cplusplusType =~ /QC?String/ and !$isConst ) { + return "StringBuffer" + } elsif ( $cplusplusType =~ /(DOM::)?DOMString/ || $cplusplusType =~ /TQString/ || $cplusplusType =~ /TQCString/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /^(const )?char\s*\*/ ) { + return "String" + } elsif ( $cplusplusType =~ /TQChar\s*[&\*]?/ || $cplusplusType =~ /^char$/ ) { + return "char" + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QTime\s*\*/ ) { + return "Date" + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QDateTime\s*\*/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QDate\s*\*/ ) { + return "Calendar" + } elsif ( $cplusplusType =~ /TQPaintDevice/ ) { + return "TQPaintDeviceInterface" + } elsif ( $cplusplusType =~ /TQByteArray/ ) { + return "byte[]" + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_([^\*\s]*)(.*)$/ and !$skippedClasses{$className}) { + if ( kalyptusDataDict::interfacemap($1) ne () ) { + return $1."Interface"; + } else { + return $1; + } + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_([^\*\s]*)(.*)$/ and !$skippedClasses{$className}) { + if ( kalyptusDataDict::interfacemap($1) ne () ) { + return $1."Interface"; + } else { + return $1; + } + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /unsigned char/ ) { + return "short"; + } elsif ( $typedeflist{$cplusplusType} =~ /ulong|long/ ) { + return "long"; + } elsif ( $typedeflist{$cplusplusType} =~ /uint|int/ or $cplusplusType =~ /^int\&$/ ) { + return "int"; + } elsif ( $typedeflist{$cplusplusType} =~ /ushort|short/ ) { + return "short"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /(unsigned )(.*)/ ) { + return $2; + } else { + my $node; + my $item; + if ($className =~ /^(\w+)::(\w+)$/) { + $node = kdocAstUtil::findRef( $rootnode, $1 ); + $item = kdocAstUtil::findRef( $node, $2 ) if defined $node; + if (defined $item && $item->{NodeType} eq 'enum') { + return "int"; + } elsif (defined $item && ($item->{NodeType} eq 'class' || $item->{NodeType} eq 'struct')) { + return $skippedClasses{$className} ? "" : $2; + } + } + + if ($className =~ /^\w+$/) { + $item = kdocAstUtil::findRef( $rootnode, $className ); + if (defined $item && ($item->{NodeType} eq 'class' || $item->{NodeType} eq 'struct')) { + return $skippedClasses{$className} ? "" : $className; + } + } + return kalyptusDataDict::ctypemap($cplusplusType); + } + +} + +sub cplusplusToJNI +{ + my ( $cplusplusType ) = @_; + my $javaType = cplusplusToJava( $cplusplusType ); + + if ( $cplusplusType =~ /void/ ) { + return "void" + } elsif ( $javaType =~ /^Calendar$/ ) { + return "jobject" + } elsif ( $javaType =~ /^Date$/ ) { + return "jobject" + } elsif ( $javaType =~ /ArrayList/ ) { + return "jobjectArray" + } elsif ( $javaType =~ /String\[\]\[\]/ ) { + return "jobjectArray"; + } elsif ( $javaType =~ /String\[\]/ ) { + return "jobjectArray"; + } elsif ( $javaType =~ /StringBuffer/ ) { + return "jobject"; + } elsif ( $javaType =~ /^String$/ ) { + return "jstring"; + } elsif ( $javaType =~ /boolean\[\]/ ) { + return "jbooleanArray"; + } elsif ( $javaType =~ /char\[\]/ ) { + return "jcharArray"; + } elsif ( $javaType =~ /byte\[\]/ ) { + return "jbyteArray"; + } elsif ( $javaType =~ /short\[\]/ ) { + return "jshortArray"; + } elsif ( $javaType =~ /int\[\]/ ) { + return "jintArray"; + } elsif ( $javaType =~ /double\[\]/ ) { + return "jdoubleArray"; + } elsif ( $javaType =~ /^Q/ ) { + return "jobject"; + } elsif ( $javaType =~ /^[A-Z]/ ) { + return "jobject"; + } elsif ( $javaType =~ /^boolean\s*/ ) { + return "jboolean"; + } elsif ( $javaType =~ /^byte\s*/ ) { + return "jbyte"; + } elsif ( $javaType =~ /^char\s*/ ) { + return "jchar"; + } elsif ( $javaType =~ /^short\s*/ ) { + return "jshort"; + } elsif ( $javaType =~ /^int\s*/ ) { + return "jint"; + } elsif ( $javaType =~ /^long\s*/ ) { + return "jlong"; + } elsif ( $javaType =~ /^float\s*/ ) { + return "jfloat"; + } elsif ( $javaType =~ /^double\s*/ ) { + return "jdouble"; + } else { + return ""; + } + +} + +sub cplusplusToJNISignature +{ + my ( $cplusplusType ) = @_; + my $javaType = cplusplusToJava( $cplusplusType ); + + if ( $javaType =~ /^Calendar$/ ) { + return "Ljava_util_Calendar_2" + } elsif ( $javaType eq 'Date' ) { + return "Ljava_util_Date_2" + } elsif ( $javaType =~ /ArrayList/ ) { + return "Ljava_util_ArrayList_2" + } elsif ( $javaType =~ /String\[\]\[\]/ ) { + return "_3_3Ljava_lang_String_2"; + } elsif ( $javaType =~ /String\[\]/ ) { + return "_3Ljava_lang_String_2"; + } elsif ( $javaType =~ /StringBuffer/ ) { + return "Ljava_lang_StringBuffer_2"; + } elsif ( $javaType eq 'String' ) { + return "Ljava_lang_String_2"; + } elsif ( $javaType =~ /boolean\[\]/ ) { + return "_3Z"; + } elsif ( $javaType =~ /char\[\]/ ) { + return "_3C"; + } elsif ( $javaType =~ /byte\[\]/ ) { + return "_3B"; + } elsif ( $javaType =~ /short\[\]/ ) { + return "_3S"; + } elsif ( $javaType =~ /int\[\]/ ) { + return "_3I"; + } elsif ( $javaType =~ /double\[\]/ ) { + return "_3D"; + } elsif ( $javaType =~ /^Q/ ) { + return "Lorg_kde_qt_$javaType"."_2"; + } elsif ( $javaType =~ /^[A-Z]/ ) { + return "Lorg_kde_koala_$javaType"."_2"; + } elsif ( $javaType =~ /^boolean\s*/ ) { + return "Z"; + } elsif ( $javaType =~ /^byte\s*/ ) { + return "B"; + } elsif ( $javaType =~ /^char\s*/ ) { + return "C"; + } elsif ( $javaType =~ /^short\s*/ ) { + return "S"; + } elsif ( $javaType =~ /^int\s*/ ) { + return "I"; + } elsif ( $javaType =~ /^long\s*/ ) { + return "J"; + } elsif ( $javaType =~ /^float\s*/ ) { + return "F"; + } elsif ( $javaType =~ /^double\s*/ ) { + return "D"; + } else { + return ""; + } + +} + +sub jniArgTocplusplus +{ + my ( $cplusplusType, $argName ) = @_; + my $jniLocal = ''; # output + my $jniArg = ''; # output + my $jniCleanup = ''; # output + + my $javaType = cplusplusToJava( $cplusplusType ); + my $jniType = cplusplusToJNI( $cplusplusType ); + + if ( $javaType =~ /^Calendar$/ ) { + my $dateclass = $cplusplusType =~ /TQDateTime/ ? "TQDateTime" : "TQDate"; + $jniLocal = "static $dateclass* _qdate_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::to$dateclass(env, $argName, &_qdate_$argName)"; + } else { + $jniArg = "($cplusplusType)*($dateclass*) QtSupport::to$dateclass(env, $argName, &_qdate_$argName)"; + } + } elsif ( $javaType =~ /^Date$/ ) { + $jniLocal = "static TQTime* _qtime_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toTQTime(env, $argName, &_qtime_$argName)"; + } else { + $jniArg = "($cplusplusType)*(TQTime*) QtSupport::toTQTime(env, $argName, &_qtime_$argName)"; + } + } elsif ( $javaType =~ /ArrayList/ ) { + if ( $cplusplusType =~ /KFileItemList/ ) { + $jniLocal ="static KFileItemList* _qlist_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) KDESupport::toKFileItemList(env, $argName, &_qlist_$argName)"; + } else { + $jniArg = "($cplusplusType)*(TQStrList*) KDESupport::toKFileItemList(env, $argName, &_qlist_$argName)"; + } + } elsif ( $cplusplusType =~ /QCStringList/ ) { + $jniLocal ="static QCStringList* _qlist_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) KDESupport::toQCStringList(env, $argName, &_qlist_$argName)"; + } else { + $jniArg = "($cplusplusType)*(QCStringList*) KDESupport::toQCStringList(env, $argName, &_qlist_$argName)"; + } + } elsif ( $cplusplusType =~ /KURL::List/ ) { + $jniLocal ="static KURL::List* _qlist_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) KDESupport::toKURLList(env, $argName, &_qlist_$argName)"; + } else { + $jniArg = "($cplusplusType)*(KURL::List*) KDESupport::toKURLList(env, $argName, &_qlist_$argName)"; + } + } + } elsif ( $javaType =~ /String\[\]\[\]/ ) { + if ( $cplusplusType =~ /KCmdLineOptions/ ) { + $jniArg = "(KCmdLineOptions*) KDESupport::toKCmdLineOptions(env, $argName)"; + } + } elsif ( $javaType =~ /String\[\]/ ) { + if ( $cplusplusType =~ /TQStringList/ ) { + $jniLocal ="static TQStringList* _qlist_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toTQStringList(env, $argName, &_qlist_$argName)"; + } else { + $jniArg = "($cplusplusType)*(TQStringList*) QtSupport::toTQStringList(env, $argName, &_qlist_$argName)"; + } + } elsif ( $cplusplusType =~ /TQStrList/ ) { + $jniLocal ="static TQStrList* _qlist_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toTQStrList(env, $argName, &_qlist_$argName)"; + } else { + $jniArg = "($cplusplusType)*(TQStrList*) QtSupport::toTQStrList(env, $argName, &_qlist_$argName)"; + } + } elsif ( $cplusplusType =~ /char\s*\*\*/ ) { + $jniArg = "($cplusplusType) QtSupport::toStringArray(env, $argName)"; + } + } elsif ( $javaType =~ /StringBuffer/ ) { + if ( $cplusplusType =~ /TQCString/ ) { + $jniLocal = "static TQCString* _qcstring_$argName = 0;\n"; + $jniLocal .= "\tif (_qcstring_$argName == 0) {\n"; + $jniLocal .= "\t\t_qcstring_$argName = new TQCString();\n"; + $jniLocal .= "\t}\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) _qcstring_$argName"; + } else { + $jniArg = "($cplusplusType)*(TQCString*) _qcstring_$argName"; + } + $jniCleanup = "\tQtSupport::fromTQCStringToStringBuffer(env, _qcstring_$argName, $argName);\n"; + } else { + $jniLocal ="static TQString* _qstring_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toTQStringFromStringBuffer(env, $argName, &_qstring_$argName)"; + } else { + $jniArg = "($cplusplusType)*(TQString*) QtSupport::toTQStringFromStringBuffer(env, $argName, &_qstring_$argName)"; + } + $jniCleanup = "\tQtSupport::fromTQStringToStringBuffer(env, _qstring_$argName, $argName);\n"; + } + } elsif ( $javaType =~ /^String$/ ) { + if ( $cplusplusType =~ /TQString/ ) { + $jniLocal ="static TQString* _qstring_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toTQString(env, $argName, &_qstring_$argName)"; + } else { + $jniArg = "($cplusplusType)*(TQString*) QtSupport::toTQString(env, $argName, &_qstring_$argName)"; + } + } elsif ( $cplusplusType =~ /TQCString/ ) { + $jniLocal ="static TQCString* _qcstring_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toTQCString(env, $argName, &_qcstring_$argName)"; + } else { + $jniArg = "($cplusplusType)*(TQCString*) QtSupport::toTQCString(env, $argName, &_qcstring_$argName)"; + } + } elsif ( $cplusplusType =~ /DOMString/ ) { + $jniLocal ="static DOM::DOMString* _domstring_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "(DOM::DOMString*) KDESupport::toDOMString(env, $argName, &_domstring_$argName)"; + } else { + $jniArg = "(DOM::DOMString)*(DOM::DOMString*) KDESupport::toDOMString(env, $argName, &_domstring_$argName)"; + } + } else { + $jniLocal ="static TQCString* _qstring_$argName = 0;\n"; + $jniArg = "($cplusplusType) ". ($cplusplusType =~ /[\&]/ ? "*(char*)" : "") . "QtSupport::toCharString(env, $argName, &_qstring_$argName)"; + } + } elsif ( $javaType =~ /boolean\[\]/ ) { + $jniLocal ="\tbool* _bool_$argName = QtSupport::toBooleanPtr(env, $argName);\n"; + $jniArg = " ($cplusplusType) " . ($cplusplusType =~ /[\*]/ ? "" : "*") . "_bool_$argName"; + $jniCleanup = "\tenv->SetBooleanArrayRegion($argName, 0, 1, (jboolean*) _bool_$argName);\n"; + } elsif ( $javaType =~ /char\[\]/ ) { + $jniLocal ="static TQByteArray* _qbytearray_$argName = 0;\n"; + $jniArg = "($cplusplusType) QtSupport::toUcharArray(env, $argName, &_qbytearray_$argName)"; + } elsif ( $javaType =~ /byte\[\]/ ) { + $jniLocal = "static TQByteArray* _qbyteArray_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toTQByteArray(env, $argName, &_qbyteArray_$argName)"; + } else { + $jniArg = "($cplusplusType)*(TQByteArray*) QtSupport::toTQByteArray(env, $argName, &_qbyteArray_$argName)"; + } + } elsif ( $javaType =~ /short\[\]/ ) { + $jniLocal ="\tshort* _short_$argName = QtSupport::toShortPtr(env, $argName);\n"; + $jniArg = " ($cplusplusType) " . ($cplusplusType =~ /[\*]/ ? "" : "*") . "_short_$argName"; + $jniCleanup = "\tenv->SetShortArrayRegion($argName, 0, 1, (jshort*) _short_$argName);\n"; + } elsif ( $javaType =~ /int\[\]/ ) { + if ( $cplusplusType =~ /TQValueList/ ) { + $jniLocal = "static TQValueList* _qlist_$argName = 0;\n"; + $jniArg = "($cplusplusType) QtSupport::toTQIntValueList(env, $argName, &_qlist_$argName)"; + } else { + $jniLocal ="\tint* _int_$argName = QtSupport::toIntPtr(env, $argName);\n"; + $jniArg = " ($cplusplusType) " . ($cplusplusType =~ /[\*]/ ? "" : "*") . "_int_$argName"; + $jniCleanup = "\tenv->SetIntArrayRegion($argName, 0, 1, (jint *) _int_$argName);\n"; + } + } elsif ( $javaType =~ /double\[\]/ ) { + $jniLocal ="\tdouble* _double_$argName = QtSupport::toDoublePtr(env, $argName);\n"; + $jniArg = " ($cplusplusType) " . ($cplusplusType =~ /[\*]/ ? "" : "*") . "_double_$argName"; + $jniCleanup = "\tenv->SetDoubleArrayRegion($argName, 0, 1, (jdouble*) _double_$argName);\n"; + } elsif ( $javaType =~ /^TQPaintDeviceInterface$/ ) { + $jniArg = "($cplusplusType) QtSupport::paintDevice(env, $argName)"; + } elsif ( $javaType =~ /^TQMimeSourceInterface$/ ) { + $jniArg = "($cplusplusType) QtSupport::mimeSource(env, $argName)"; + } elsif ( $javaType =~ /^[A-Z]/ ) { + ( my $className = $cplusplusType ) =~ s/[&*]//g; + $jniArg = (($cplusplusType !~ /[\*]/ or $cplusplusType =~ /\*\&/) ? "($cplusplusType)*" : "") . "($className*) QtSupport::getQt(env, $argName)"; + } elsif ( $javaType =~ /^boolean\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } elsif ( $javaType =~ /^byte\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } elsif ( $javaType =~ /^char\s*/ ) { + if ( $cplusplusType =~ /TQChar/ ) { + $jniLocal = "static TQChar* _qchar_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toTQChar(env, $argName, &_qchar_$argName)"; + } else { + $jniArg = "($cplusplusType)*(TQChar*) QtSupport::toTQChar(env, $argName, &_qchar_$argName)"; + } + } else { + $jniArg = "($cplusplusType) $argName"; + } + } elsif ( $javaType =~ /^short\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } elsif ( $javaType =~ /^int\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } elsif ( $javaType =~ /^long\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } elsif ( $javaType =~ /^float\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } elsif ( $javaType =~ /^double\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } else { + ; + } + + return ($jniLocal, $jniArg, $jniCleanup); +} + +sub jniToReturnValue($$$) +{ + my ( $cplusplusType, $functionCall, $jniCleanups ) = @_; + my $jniLocal = ''; # output + my $returnCall = ''; # output + + my $javaType = cplusplusToJava( $cplusplusType ); + my $const = ($cplusplusType =~ /const / ? "const " : ""); + + if ( $cplusplusType =~ /void/ ) { + $returnCall = "\t$functionCall;\n\treturn;\n"; + $returnCall = "\t$functionCall;\n$jniCleanups\treturn;\n"; + } elsif ( $javaType =~ /^Calendar$/ ) { + $cplusplusType =~ /(TQDateTime|TQDate)\s*(\*)?&?\s*$/; + $jniLocal = "\t$1 $2 _qdate;\n"; + $returnCall = "\t_qdate = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn (jobject) QtSupport::from$1(env, ($1*) " . ($2 eq "\*" ? "" : "&") . "_qdate);\n"; + } elsif ( $javaType =~ /^Date$/ ) { + $cplusplusType =~ /(TQTime)\s*(\*)?&?\s*$/; + $jniLocal = "\t$1 $2 _qtime;\n"; + $returnCall = "\t_qtime = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn (jobject) QtSupport::fromTQTime(env, ($1*) " . ($2 eq "\*" ? "" : "&") . "_qtime);\n"; + } elsif ( $javaType =~ /ArrayList/ || $javaType =~ /String\[\]/ ) { + if ( $cplusplusType !~ /\*/ ) { + $const = ""; + } + $cplusplusType =~ /(const )?([^\&]*)(\*)?&?/; + $jniLocal = "\t$const$2 $3 _qlist;\n"; + $returnCall = "\t_qlist = $functionCall;\n$jniCleanups"; + if ( $cplusplusType =~ /(TQStrList|TQStringList|TQCanvasItemList|TQWidgetList|TQDomNodeList|TQObjectList)\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) QtSupport::arrayWith$1(env, ($1*) " . ($2 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /DOM::(NodeList|StyleSheetList|MediaList)\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) KDESupport::arrayWith$1(env, (DOM::$1 *) " . ($2 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /(QCStringList|KFileItemList|KFileViewItemList)\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) KDESupport::arrayWith$1(env, ($1*) " . ($2 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /(KTrader::OfferList)\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) KDESupport::arrayWithOfferList(env, ($1*) " . ($2 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /(KURL::List)\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) KDESupport::arrayWithKURLList(env, ($1*) " . ($2 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /TQValueList\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) QtSupport::arrayWithTQIconDragItemList(env, (TQValueList*) " . ($1 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /TQMemArray\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) QtSupport::arrayWithTQRectList(env, (TQMemArray*) " . ($1 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /TQArray\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) QtSupport::arrayWithTQRectList(env, (TQArray*) " . ($1 eq "\*" ? "" : "&") . "_qlist);\n"; + } + } elsif ( $javaType =~ /String\[\]/ ) { + ; # Do nothing, string arrays are ArrayLists as return values + } elsif ( $javaType =~ /String/ || $javaType =~ /StringBuffer/ ) { + if ( $cplusplusType =~ /TQString(\s*\*)?/ ) { + $jniLocal = "\tTQString $1 _qstring;\n"; + $returnCall = "\t_qstring = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn QtSupport::fromTQString(env, " . ($cplusplusType =~ /\*/ ? "" : "&") . "_qstring);\n"; + } elsif ($cplusplusType =~ /TQCString(\s*\*)?/) { + $jniLocal = "\tTQCString $1 _qstring;\n"; + $returnCall = "\t_qstring = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn QtSupport::fromTQCString(env, " . ($cplusplusType =~ /\*/ ? "" : "&") . "_qstring);\n"; + } elsif ($cplusplusType =~ /DOM::DOMString(\s*\*)?/) { + $jniLocal = "\tDOM::DOMString $1 _qstring;\n"; + $returnCall = "\t_qstring = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn KDESupport::fromDOMString(env, " . ($cplusplusType =~ /\*/ ? "" : "&") . "_qstring);\n"; + } else { + $jniLocal = "\t$cplusplusType _qstring;\n"; + $returnCall = "\t_qstring = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn QtSupport::fromCharString(env, (char *) _qstring);\n"; + } + } elsif ( $javaType =~ /boolean\[\]/ ) { + ; + } elsif ( $cplusplusType =~ /uchar\s*\*/ ) { + ; + } elsif ( $javaType =~ /char\[\]/ ) { + ; + } elsif ( $javaType =~ /byte\[\]/ ) { + $jniLocal = "\tTQByteArray " . ($cplusplusType =~ /\*/ ? "*" : "") . "_qbyteArray;\n"; + $returnCall = "\t_qbyteArray = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn QtSupport::fromTQByteArray(env, " . ($cplusplusType =~ /\*/ ? "" : "&") . "_qbyteArray);\n"; + } elsif ( $javaType =~ /short\[\]/ ) { + ; + } elsif ( $javaType =~ /int\[\]/ && $cplusplusType !~ /\&/ ) { + if ( $cplusplusType =~ /(int\*|TQRgb\*)/ ) { + $jniLocal = "\t$1 _qint;\n"; + $returnCall = "\t_qint = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn QtSupport::fromIntPtr(env, (int*)_qint);\n"; + } else { + $jniLocal = "\tTQValueList _qintArray;\n"; + $returnCall = "\t_qintArray = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn QtSupport::fromTQIntValueList(env, &_qintArray);\n"; + } + } elsif ( $javaType =~ /double\[\]/ ) { + ; + } elsif ( $javaType =~ /^[A-Z]/ ) { + my $className = $cplusplusType; + $className =~ s/[\*\&]|const //g; + $returnCall = "\tjobject xret = QtSupport::objectForQtKey(env, (void*)"; + my $fullyQualifiedReturnType = ($javaType =~ /^Q/ ? "org.kde.qt.$javaType" : "org.kde.koala.$javaType"); + if ($cplusplusType =~ /\*/) { + $returnCall .= "$functionCall, \"$fullyQualifiedReturnType\");\n"; + } elsif ($cplusplusType =~ /\&/) { + $returnCall .= "($className *) &$functionCall, \"$fullyQualifiedReturnType\");\n"; + } else { + $returnCall .= "new $className($functionCall), \"$fullyQualifiedReturnType\", TRUE);\n"; + } + $returnCall .= "$jniCleanups\treturn xret;\n"; + } elsif ( $javaType =~ /^char\s*/ ) { + if ( $cplusplusType =~ /(TQChar)(\s*\*)?\s*$/ ) { + $jniLocal = "\t$const$1 $2 _qchar;\n"; + $returnCall = "\t_qchar = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn (jchar) QtSupport::fromTQChar(env, (TQChar*) " . ($cplusplusType =~ /\*/ ? "" : "&") . "_qchar);\n"; + } else { + $returnCall = "\tjchar xret = (jchar) $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn xret;\n"; + } + } elsif ( $javaType =~ /int\[\]/ && $cplusplusType =~ /\&/ ) { + $returnCall = "\tjint xret = (jint) $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn xret;\n"; + } elsif ( $javaType =~ /(^boolean|^byte|^short|^int|^long|^float|^double)/ ) { + $returnCall = "\tj$1 xret = (j$1) $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn xret;\n"; + } + + return ($jniLocal, $returnCall); +} + +sub writeDoc +{ + ( $libname, $rootnode, $outputdir, $opt ) = @_; + + print STDERR "Starting writeDoc for $libname...\n"; + + $debug = $main::debuggen; + + mkpath( $outputdir ) unless -f $outputdir; + + # Define TQPtrCollection::Item, for resolveType + unless ( kdocAstUtil::findRef( $rootnode, "TQPtrCollection::Item" ) ) { + my $cNode = kdocAstUtil::findRef( $rootnode, "TQPtrCollection" ); + warn "TQPtrCollection not found" if (!$cNode); + my $node = Ast::New( 'Item' ); + $node->AddProp( "NodeType", "Forward" ); + $node->AddProp( "Source", $cNode->{Source} ) if ($cNode); + kdocAstUtil::attachChild( $cNode, $node ) if ($cNode); + $node->AddProp( "Access", "public" ); + } + + print STDERR "Preparsing...\n"; + + # Preparse everything, to prepare some additional data in the classes and methods + Iter::LocalCompounds( $rootnode, sub { preParseClass( shift ); } ); + + # Have a look at each class again, to propagate CanBeCopied + Iter::LocalCompounds( $rootnode, sub { propagateCanBeCopied( shift ); } ); + + # Write out smokedata.cpp + writeSmokeDataFile($rootnode); + + print STDERR "Writing *.java...\n"; + + # Generate *java file for each class + Iter::LocalCompounds( $rootnode, sub { writeClassDoc( shift ); } ); + + print STDERR "Done.\n"; +} + +=head2 preParseClass + Called for each class +=cut +sub preParseClass +{ + my( $classNode ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + if( $#{$classNode->{Kids}} < 0 || + $classNode->{Access} eq "private" || + $classNode->{Access} eq "protected" || # e.g. TQPixmap::TQPixmapData + exists $classNode->{Tmpl} || + # Don't generate standard bindings for TQString, this class is handled as a native type + $className eq 'TQString' || + $className eq 'TQConstString' || + $className eq 'TQCString' || + # Don't map classes which are really arrays + $className eq 'TQStringList' || + $className eq 'TQCanvasItemList' || + $className eq 'TQWidgetList' || + $className eq 'TQObjectList' || + $className eq 'TQStrList' || + # Those are template related + $className eq 'TQTSManip' || # cause compiler errors with several gcc versions + $className eq 'TQIconFactory' || + $className eq 'TQGDict' || + $className eq 'TQGList' || + $className eq 'TQGVector' || + $className eq 'TQStrIList' || + $className eq 'TQStrIVec' || + $className eq 'TQByteArray' || + $className eq 'TQBitArray' || + $className eq 'TQWExtra' || + $className eq 'TQTLWExtra' || + $className eq 'TQMetaEnum::Item' || + $className eq 'TQWidgetContainerPlugin' || + $className eq 'TQGArray::array_data' || + $className eq 'KBookmarkMenu::DynMenuInfo' || + $className eq 'KCompletionMatches' || + $className eq 'KDEDesktopMimeType::Service' || + $className eq 'KGlobalSettings::KMouseSettings' || + $className eq 'KMimeType::Format' || + $className eq 'KNotifyClient::Instance' || + $className eq 'KParts::Plugin::PluginInfo' || + $className eq 'KProtocolInfo::ExtraField' || + $className eq 'KXMLGUIClient::StateChange' || + $className eq 'KIconTheme' || + $className eq 'KEditListBox::CustomEditor' || + $className eq 'KIO::KBookmarkMenuNSImporter' || + $className eq 'KPerDomainSettings' || + $className eq 'KApplicationPropsPlugin' || + $className eq 'KPrinter' || + $className eq 'KPty' || + $className eq 'KOpenWithHandler' || + $className eq 'KFileOpenWithHandler' || + $className eq 'KBindingPropsPlugin' || + $className eq 'KPropsDlgPlugin' || + $className eq 'KFileSharePropsPlugin' || + $className eq 'KBookmarkMenuNSImporter' || + $className eq 'KDevicePropsPlugin' || + $className eq 'KWin::WindowInfo' || + $className eq 'KDEDModule' || + $className eq 'KFileMetaInfoProvider' || + $className eq 'KFileMimeTypeInfo' || + $className eq 'KExecPropsPlugin' || + $className eq 'KFilePermissionsPropsPlugin' || + $className eq 'KImageFilePreview' || + $className eq 'KBookmarkManager' || + $className eq 'KBookmarkNotifier' || + $className eq 'KOCRDialogFactory' || + $className eq 'KExtendedBookmarkOwner' || + $className eq 'KSharedPixmap' || + $className eq 'KSocket' || + $className eq 'KLibrary' || + $className eq 'KScanDialogFactory' || + $className eq 'KDictSpellingHighlighter' || + $className eq 'KPropertiesDialog' || + $className eq 'ProgressItem' || + $className eq 'KIO::ChmodInfo' || + $className eq 'KIO::MetaData' || + $className eq 'KFileMimeTypeInfo::ItemInfo' || + $className eq 'KIO::UDSAtom' || + $className eq 'khtml::DrawContentsEvent' || # the khtml:: classes build, but don't link + $className eq 'khtml::MouseDoubleClickEvent' || + $className eq 'khtml::MouseMoveEvent' || + $className eq 'khtml::MousePressEvent' || + $className eq 'khtml::MouseReleaseEvent' || + $className eq 'khtml::MouseEvent' || + $className eq 'KURL::List' || + $className eq 'KWin::Info' || + $className eq 'TerminalInterface' || + $className =~ /.*Private$/ || # Ignore any classes which aren't for public consumption + $className =~ /.*Impl$/ || + $className =~ /.*Internal.*/ || +# $classNode->{Deprecated} || + $classNode->{NodeType} eq 'union' # Skip unions for now, e.g. TQPDevCmdParam + ) { + print STDERR "Skipping $className\n" if ($debug); + print STDERR "Skipping union $className\n" if ( $classNode->{NodeType} eq 'union'); + $skippedClasses{$className} = 1; + delete $classNode->{Compound}; # Cheat, to get it excluded from Iter::LocalCompounds + return; + } + + my $signalCount = 0; + my $eventHandlerCount = 0; + my $defaultConstructor = 'none'; # none, public, protected or private. 'none' will become 'public'. + my $constructorCount = 0; # total count of _all_ ctors + # If there are ctors, we need at least one public/protected one to instanciate the class + my $hasPublicProtectedConstructor = 0; + # We need a public dtor to destroy the object --- ### aren't protected dtors ok too ?? + my $hasPublicDestructor = 1; # by default all classes have a public dtor! + #my $hasVirtualDestructor = 0; + my $hasDestructor = 0; + my $hasPrivatePureVirtual = 0; + my $hasCopyConstructor = 0; + my $hasPrivateCopyConstructor = 0; + # Note: no need for hasPureVirtuals. $classNode{Pure} has that. + + my $doPrivate = $main::doPrivate; + $main::doPrivate = 1; + # Look at each class member (looking for methods and enums in particular) + Iter::MembersByType ( $classNode, undef, + sub { + + my( $classNode, $m ) = @_; + my $name = $m->{astNodeName}; + + if( $m->{NodeType} eq "method" ) { + if ( $m->{ReturnType} eq 'typedef' # TQFile's EncoderFn/DecoderFn callback, very badly parsed + ) { + $m->{NodeType} = 'deleted'; + next; + } + + print STDERR "preParseClass: looking at $className\::$name $m->{Params}\n" if ($debug); + + if ( $name eq $classNode->{astNodeName} ) { + if ( $m->{ReturnType} =~ /~/ ) { + # A destructor + $hasPublicDestructor = 0 if $m->{Access} ne 'public'; + #$hasVirtualDestructor = 1 if ( $m->{Flags} =~ "v" && $m->{Access} ne 'private' ); + $hasDestructor = 1; + } else { + # A constructor + $constructorCount++; + $defaultConstructor = $m->{Access} if ( $m->{Params} eq '' ); + $hasPublicProtectedConstructor = 1 if ( $m->{Access} ne 'private' ); + + # Copy constructor? + if ( $#{$m->{ParamList}} == 0 ) { + my $theArgType = @{$m->{ParamList}}[0]->{ArgType}; + if ($theArgType =~ /$className\s*\&/) { + $hasCopyConstructor = 1; + $hasPrivateCopyConstructor = 1 if ( $m->{Access} eq 'private' ); + } + } + # Hack the return type for constructors, since constructors return an object pointer + $m->{ReturnType} = $className."*"; + } + } + + if ( $name =~ /~$classNode->{astNodeName}/ && $m->{Access} ne "private" ) { # not used + $hasPublicDestructor = 0 if $m->{Access} ne 'public'; + #$hasVirtualDestructor = 1 if ( $m->{Flags} =~ "v" ); + $hasDestructor = 1; + } + + if ( $m->{Flags} =~ "p" && $m->{Access} =~ /private/ ) { + $hasPrivatePureVirtual = 1; # ouch, can't inherit from that one + } + + # All we want from private methods is to check for virtuals, nothing else + next if ( $m->{Access} =~ /private/ ); + + # Don't generate code for deprecated methods, + # or where the code won't compile/link for obscure reasons. Or even obvious reasons.. + if ( ($classNode->{astNodeName} eq 'KCharSelectTable' and $name eq 'paintCell') + || ($classNode->{astNodeName} eq 'KAnimWidget' and $name eq 'KAnimWidget' and @{$m->{ParamList}} == 2) + || ($classNode->{astNodeName} eq 'KDCOPActionProxy' and $name eq 'actions') + || ($classNode->{astNodeName} eq 'KFileDialog' and $name eq 'addDirEntry') + || ($classNode->{astNodeName} eq 'KFileDialog' and $name eq 'getDirEntry') + || ($classNode->{astNodeName} eq 'KFileView' and $name eq 'selectionMode') + || ($classNode->{astNodeName} eq 'KFind' and $name eq 'KFind' and @{$m->{ParamList}} == 4) + || ($classNode->{astNodeName} eq 'KGlobalAccel' and $name eq 'setEnabled') + || ($classNode->{astNodeName} eq 'KCharsets' and $name eq 'encodingsForLanguage') + || ($classNode->{astNodeName} eq 'KInputDialog' and $name eq 'getInteger') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'buildHTMLErrorString') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'calculateRemainingSeconds') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'checkCachedAuthentication') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'cacheAuthentication') + || ($classNode->{astNodeName} eq 'KInputDialog' and $name eq 'getDouble') + || ($classNode->{astNodeName} eq 'KToolBar' and $name eq 'enable') + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'insert' and @{$m->{ParamList}} == 2) + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'autoupdate') + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'getAutoUpdate') + || ($classNode->{astNodeName} eq 'KStdAccel' and $name eq 'insert') + || ($classNode->{astNodeName} eq 'KBookmarkMenu' and $name eq 'invalid') + || ($classNode->{astNodeName} eq 'KCharsets' and $name eq 'languages') + || ($classNode->{astNodeName} eq 'KCombiView' and $name eq 'setDropOptions') + || ($classNode->{astNodeName} eq 'KFileMetaInfoItem' and $name eq 'unit') + || ($classNode->{astNodeName} eq 'KInstance' and $name eq 'charsets') + || ($classNode->{astNodeName} eq 'KInstance' and $name eq 'KInstance' and $m->{Access} =~ /protected/) + || ($classNode->{astNodeName} eq 'KKey' and $name eq 'isValidQt') + || ($classNode->{astNodeName} eq 'KKey' and $name eq 'isValidNative') + || ($classNode->{astNodeName} eq 'KKeySequence' and $name eq 'init') + || ($classNode->{astNodeName} eq 'KKeySequence' and $name eq 'setTriggerOnRelease') + || ($classNode->{astNodeName} eq 'KEMailSettings' and $name eq 'getExtendedSetting') + || ($classNode->{astNodeName} eq 'KEMailSettings' and $name eq 'setExtendedSetting') + || ($classNode->{astNodeName} eq 'KHTMLSettings' and $name eq 'fallbackAccessKeysAssignments') + || ($classNode->{astNodeName} eq 'KProtocolManager' and $name eq 'defaultConnectTimeout') + || ($classNode->{astNodeName} eq 'KMD5' and $name eq 'transform') + || ($classNode->{astNodeName} eq 'KSSLCertificate' and $name eq 'operator!=') + || ($classNode->{astNodeName} eq 'KSSLPKCS7' and $name eq 'validate') + || ($classNode->{astNodeName} eq 'KSSLPKCS7' and $name eq 'revalidate') + || ($classNode->{astNodeName} eq 'KSSLSession' and $name eq 'KSSLSession' and @{$m->{ParamList}} == 1) + || ($classNode->{astNodeName} eq 'KSimpleFileFilter' and $name eq 'nameFilters') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'isTabReorderingEnabled') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'hoverCloseButton') + || ($classNode->{astNodeName} eq 'KTar' and $name eq 'writeFile_impl') + + # Various methods to skip in Qt/E (Qt 2.3.x) + || ($main::qt_embedded + && ( ($classNode->{astNodeName} eq 'TQUriDrag' and $name =~ /^decode$|decodeLocalFiles|decodeToUnicodeUris/) + || ($classNode->{astNodeName} eq 'TQApplication' and $name =~ /^qwsSetCustomColors|^setArgs$|^winMouseButtonUp|^winFocus|^winMouseButtonUP$|^winVersion$/) + || ($classNode->{astNodeName} eq 'TQPrinter' and $name =~ /^setIdle$|^setActive$/) + || ($classNode->{astNodeName} eq 'TQDragObject' and $name eq 'dragLink') + || ($classNode->{astNodeName} eq 'TQFont' and $name eq 'qwsRenderToDisk') + || ($classNode->{astNodeName} eq 'TQFontInfo' and $name eq 'font') + || ($classNode->{astNodeName} eq 'TQLineEdit' and $name eq 'getSelection') + || ($classNode->{astNodeName} eq 'TQMainWindow' and $name eq 'toolBars') + || ($classNode->{astNodeName} eq 'TQMovie' and $name eq 'setDisplayWidget') + || ($classNode->{astNodeName} eq 'TQMetaObject' and $name =~ /^new_metaenum_item$|^new_metaaccess$/) + || ($classNode->{astNodeName} eq 'TQPainter' and $name eq 'pos') + || ($classNode->{astNodeName} eq 'TQPixmap' and $name =~ /^allocCell$|^clut$|^freeCell|^hbm|^isMultiCellPixmap|^multiCellPixmap|^multiCellBitmap|^multiCellHandle|^multiCellOffset|^numCols/) + || ($name eq 'handle') + || ($name eq 'resetInputContext') + || ($name eq 'propagateUpdates') + || ($name eq 'bytesPerLine') + || ($name eq 'scanLine') + || ($name eq 'hPal') + || ($name eq 'copyX11Data') + || ($name eq 'getX11Data') + || ($name eq 'setX11Data') + || ($name eq 'realizePal') + || ($name eq 'qwsDisplay') + || ($name eq 'fixport') + || ($name eq 'hack_strrchr') + || ($name eq 'hack_strchr') + || ($name eq 'hack_strstr') ) ) + + || ($name eq 'virtual_hook') + || ($name =~ /_KShared_/) + || ($name eq 'qObject') + || ($name =~ /argv/) + || ($name =~ /argc/) + || ($name eq 'qt_emit') + || ($name eq 'qt_invoke') + || ($name eq 'qt_cast') + || ($name eq 'qt_property') + || ($name eq 'staticMetaObject') + # Assume only Qt classes have tr() and trUtf8() in their Q_OBJECT macro + || ($classNode->{astNodeName} !~ /^Q/ and $name eq 'tr') + || ($classNode->{astNodeName} !~ /^Q/ and $name eq 'trUtf8') + || $name eq 'trUtf8' + || $m->{Deprecated} ) { + $m->{NodeType} = 'deleted'; + next; + } + + my $argId = 0; + my $firstDefaultParam; + foreach my $arg ( @{$m->{ParamList}} ) { + # Look for first param with a default value + if ( defined $arg->{DefaultValue} && !defined $firstDefaultParam ) { + $firstDefaultParam = $argId; + } + + if ( $arg->{ArgType} eq '...' # refuse a method with variable arguments + or $arg->{ArgType} eq 'image_io_handler' # TQImage's callback + or $arg->{ArgType} eq 'DecoderFn' # TQFile's callback + or $arg->{ArgType} eq 'EncoderFn' # TQFile's callback + or $arg->{ArgType} =~ /bool \(\*\)\(TQObject/ # TQMetaObject's ctor + or $arg->{ArgType} eq 'QtStaticMetaObjectFunction' # TQMetaObjectCleanUp's ctor with func pointer + or $arg->{ArgType} eq 'const TQTextItem&' # ref to a private class in 3.2.0b1 + or $arg->{ArgType} eq 'FILE*' # won't be able to handle that I think + or $arg->{ArgType} eq 'const KKeyNative&' # + ) { + $m->{NodeType} = 'deleted'; + } + else + { + # Resolve type in full, e.g. for TQSessionManager::RestartHint + # (TQSessionManagerJBridge doesn't inherit TQSessionManager) + $arg->{ArgType} = kalyptusDataDict::resolveType($arg->{ArgType}, $classNode, $rootnode); + registerType( $arg->{ArgType} ); + $argId++; + } + } + $m->AddProp( "FirstDefaultParam", $firstDefaultParam ); + $m->{ReturnType} = kalyptusDataDict::resolveType($m->{ReturnType}, $classNode, $rootnode) if ($m->{ReturnType}); + registerType( $m->{ReturnType} ); + } + elsif( $m->{NodeType} eq "enum" ) { + if ( ! $m->{astNodeName} ) { + $m->{Access} = 'protected'; + } + my $fullEnumName = $className."::".$m->{astNodeName}; + if ( ($fullEnumName eq 'KMimeType::Format' and $name eq 'compression') + || $m->{Deprecated} ) { + $m->{NodeType} = 'deleted'; + next; + } + + $classNode->{enumerations}{$m->{astNodeName}} = $fullEnumName; +# if $m->{astNodeName} and $m->{Access} ne 'private'; +# if $m->{astNodeName} ; + + # Define a type for this enum + registerType( $fullEnumName ); + + # Remember that it's an enum + findTypeEntry( $fullEnumName )->{isEnum} = 1; + } + elsif( $m->{NodeType} eq 'var' ) { + my $varType = $m->{Type}; + # We are interested in public static vars, like TQColor::blue + if ( $varType =~ s/static\s+// && $m->{Access} ne 'private' + && $className."::".$m->{astNodeName} ne "KSpell::modalListText" ) + { + $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/\s*$//; + print STDERR "var: $m->{astNodeName} '$varType'\n" if ($debug); + + # Register the type + registerType( $varType ); + + } else { + # To avoid duplicating the above test, we just get rid of any other var + $m->{NodeType} = 'deleted'; + } + } + }, + undef + ); + $main::doPrivate = $doPrivate; + + print STDERR "$className: ctor count: $constructorCount, hasPublicProtectedConstructor: $hasPublicProtectedConstructor, hasCopyConstructor: $hasCopyConstructor:, defaultConstructor: $defaultConstructor, hasPublicDestructor: $hasPublicDestructor, hasPrivatePureVirtual:$hasPrivatePureVirtual\n" if ($debug); + + # Note that if the class has _no_ constructor, the default ctor applies. Let's even generate it. + if ( !$constructorCount && $defaultConstructor eq 'none' && !$hasPrivatePureVirtual ) { + # Create a method node for the constructor + my $methodNode = Ast::New( $classNode->{astNodeName} ); + $methodNode->AddProp( "NodeType", "method" ); + $methodNode->AddProp( "Flags", "" ); + $methodNode->AddProp( "Params", "" ); + $methodNode->AddProp( "ParamList", [] ); + kdocAstUtil::attachChild( $classNode, $methodNode ); + + # Hack the return type for constructors, since constructors return an object pointer + $methodNode->AddProp( "ReturnType", $className."*" ); + registerType( $className."*" ); + $methodNode->AddProp( "Access", "public" ); # after attachChild + $defaultConstructor = 'public'; + $hasPublicProtectedConstructor = 1; + } + + # Also, if the class has no explicit destructor, generate a default one. + if ( !$hasDestructor && !$hasPrivatePureVirtual ) { + my $methodNode = Ast::New( "$classNode->{astNodeName}" ); + $methodNode->AddProp( "NodeType", "method" ); + $methodNode->AddProp( "Flags", "" ); + $methodNode->AddProp( "Params", "" ); + $methodNode->AddProp( "ParamList", [] ); + kdocAstUtil::attachChild( $classNode, $methodNode ); + + $methodNode->AddProp( "ReturnType", "~" ); + $methodNode->AddProp( "Access", "public" ); + } + + # If we have a private pure virtual, then the class can't be instanciated (e.g. TQCanvasItem) + # Same if the class has only private constructors (e.g. TQInputDialog) + $classNode->AddProp( "CanBeInstanciated", $hasPublicProtectedConstructor +# && !$hasPrivatePureVirtual + && (!$classNode->{Pure} or $classNode->{astNodeName} eq 'TQValidator') + && !($classNode->{NodeType} eq 'namespace') + && ($classNode->{astNodeName} !~ /^DrawContentsEvent$|^MouseEvent$|^MouseDoubleClickEvent$|^MouseMoveEvent$|^MouseReleaseEvent$|^MousePressEvent$/) + && ($classNode->{astNodeName} !~ /TQMetaObject|TQDragObject|Slave|CopyJob|KMdiChildFrm|KNamedCommand/) ); + + # We will derive from the class only if it has public or protected constructors. + # (_Even_ if it has pure virtuals. But in that case the *.cpp class can't be instantiated either.) + $classNode->AddProp( "BindingDerives", $hasPublicProtectedConstructor ); + + # We need a public dtor to destroy the object --- ### aren't protected dtors ok too ?? + $classNode->AddProp( "HasPublicDestructor", $hasPublicDestructor ); + + # Hack for TQAsyncIO. We don't implement the "if a class has no explicit copy ctor, + # then all of its member variables must be copiable, otherwise the class isn't copiable". + $hasPrivateCopyConstructor = 1 if ( $className eq 'TQAsyncIO' ); + + # Remember if this class can't be copied - it means all its descendants can't either + $classNode->AddProp( "CanBeCopied", !$hasPrivateCopyConstructor ); + $classNode->AddProp( "HasCopyConstructor", $hasCopyConstructor ); +} + +sub propagateCanBeCopied($) +{ + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + my @super = superclass_list($classNode); + # A class can only be copied if none of its ancestors have a private copy ctor. + for my $s (@super) { + if (!$s->{CanBeCopied}) { + $classNode->{CanBeCopied} = 0; + print STDERR "$classNode->{astNodeName} cannot be copied\n" if ($debug); + last; + } + } + + # Prepare the {case} dict for the class + prepareCaseDict( $classNode ); +} + +=head2 writeClassDoc + + Called by writeDoc for each class to be written out + +=cut + +sub writeClassDoc +{ + my( $node ) = @_; + my $className = join( "::", kdocAstUtil::heritage($node) ); + my $javaClassName = $node->{astNodeName}; + # Makefile doesn't like '::' in filenames, so use __ + my $fileName = $node->{astNodeName}; +# my $fileName = join( "__", kdocAstUtil::heritage($node) ); + print "Enter: $className\n" if $debug; + + my $typeprefix = ($className =~ /^Q/ ? "qt_" : "kde_"); + my $packagename = ($typeprefix eq 'qt_' ? "org.kde.qt" : "org.kde.koala"); + + # Write out the *.java file + my $classFile = "$outputdir/$fileName.java"; + open( CLASS, ">$classFile" ) || die "Couldn't create $classFile\n"; + print STDERR "Writing $fileName.java\n" if ($debug); + + print CLASS "//Auto-generated by $0. DO NOT EDIT.\n"; + + print CLASS "package $packagename;\n\n"; + + # And write out the *.cpp file + my $jniFile = "$outputdir/$fileName.cpp"; + open( JNISOURCE, ">$jniFile" ) || die "Couldn't create $jniFile\n"; + print STDERR "Writing $fileName.cpp\n" if ($debug); + + print JNISOURCE "//Auto-generated by $0. DO NOT EDIT.\n"; + + my %javaMethods = (); + my %jniMethods = (); + my $jniCode; + my %addImport = (); + my %addInclude = (); + + my @ancestors = (); + my @ancestor_nodes = (); + Iter::Ancestors( $node, $rootnode, undef, undef, sub { + my ( $ances, $name, $type, $template ) = @_; + if ( $name ne "TQMemArray" and $name ne "TQArray" and $name ne "TQSqlFieldInfoList" ) { + push @ancestor_nodes, $ances; + push @ancestors, $name; + } + }, + undef + ); + + my ($methodCode, $interfaceCode, $signalCode, $jbridgeCode) = generateAllMethods( $node, $#ancestors + 1, + \%javaMethods, \%jniMethods, + $node, + ($node->{NodeType} eq 'namespace' ? 0 : 1), + \%addImport, \%addInclude ); + + my $signalFile = "$outputdir/$fileName" . "Signals.java"; + if ( $signalCode ne '' ) { + open( SIGNALS, ">$signalFile" ) || die "Couldn't create $signalFile\n"; + print SIGNALS "//Auto-generated by $0. DO NOT EDIT.\n"; + print SIGNALS "package $packagename;\n\n"; + } + + my $tempMethodNumber = $methodNumber; + + # Add method calls for the interfaces implemented by the class + foreach my $ancestor_node ( @ancestor_nodes ) { + if ( kalyptusDataDict::interfacemap($ancestor_node->{astNodeName}) ne () && ($#ancestors > 0) ) { + my ($meth, $interf, $sig, $jbridge) = generateAllMethods( $ancestor_node, 0, \%javaMethods, \%jniMethods, $node, 0, \%addImport, \%addInclude ); + $methodCode .= $meth; + $jbridgeCode .= $jbridge; + } + } + + + if ( $className eq 'Qt' or $className eq 'KDE' ) { + my $globalSpace = kdocAstUtil::findRef( $rootnode, $main::globalSpaceClassName ); + my ($meth, $interf, $sig, $jbridge) = generateAllMethods( $globalSpace, 0, \%javaMethods, \%jniMethods, $node, 0, \%addImport, \%addInclude ); + $methodCode .= $meth; + $jbridgeCode .= $jbridge; + } + + + $jbridgeCode .= virtualMethodCallbacks( $node ); + + $methodNumber = $tempMethodNumber; + + if ( $className eq 'Qt' ) { + print CLASS "import java.io.*;\n"; + print CLASS "import java.text.MessageFormat;\n"; + print CLASS "import java.lang.reflect.*;\n"; + } else { + if ( $className eq 'TQListView' or $className eq 'TQListViewItem' or $className eq 'TQUriDrag' ) { + # Special case these two classes as they have methods that use ArrayList added as 'extras' + print CLASS "import java.util.ArrayList;\n"; + } + print CLASS "import org.kde.qt.Qt;\n"; + } + + if ( kalyptusDataDict::interfacemap($javaClassName) ne () ) { + my $interfaceFile = "$outputdir/" . kalyptusDataDict::interfacemap($javaClassName) . ".java"; + open( INTERFACE, ">$interfaceFile" ) || die "Couldn't create $interfaceFile\n"; + print INTERFACE "//Auto-generated by $0. DO NOT EDIT.\n"; + print INTERFACE "package $packagename;\n\n"; + } + + foreach my $imp (keys %addImport) { + die if $imp eq ''; + # Ignore any imports for classes in the same package as the current class + if ($imp !~ /$packagename/) { + print CLASS "import $imp;\n"; + print INTERFACE "import $imp;\n"; + print SIGNALS "import $imp;\n" unless $signalCode eq '';; + } + } + + if ( kalyptusDataDict::interfacemap($javaClassName) ne () ) { + print INTERFACE "\npublic interface " . kalyptusDataDict::interfacemap($javaClassName) . " {\n"; + print INTERFACE $interfaceCode; + print INTERFACE "}\n"; + close INTERFACE; + } + + my $classdec; + if ($node->{NodeType} eq 'namespace') { + $classdec = "public class $javaClassName {\n"; + } elsif ( $#ancestors < 0 ) { + $classdec = "public class $javaClassName implements QtSupport"; + if ( kalyptusDataDict::interfacemap($javaClassName) ne () ) { + $classdec .= ", " . kalyptusDataDict::interfacemap($javaClassName); + } + + $classdec .= " {\n\tprivate long _qt;\n"; + $classdec .= "\tprivate boolean _allocatedInJavaWorld = true;\n"; + $classdec .= "\tprotected $javaClassName(Class dummy){}\n\n"; + } else { + $classdec = "public class $javaClassName extends "; + my $ancestor; + foreach $ancestor ( @ancestors ) { + if ( kalyptusDataDict::interfacemap($ancestor) eq () or $ancestor eq @ancestors[$#ancestors] ) { + $ancestor =~ s/^.*:://; + $classdec .= "$ancestor "; + if ( $typeprefix ne 'qt_' and $ancestor =~ /^Q/ ) { + print CLASS "import org.kde.qt.$ancestor;\n"; + } + last; + } + } + + my @implements = (); + if ( $#ancestors >= 1 ) { + foreach $ancestor ( @ancestors ) { + if ( kalyptusDataDict::interfacemap($ancestor) ne () ) { + push(@implements, kalyptusDataDict::interfacemap($ancestor)); + } + } + } + + if ($#implements >= 0) { + $classdec .= "implements "; + $classdec .= join(", ", @implements); + } + + $classdec .= " {\n"; + $classdec .= "\tprotected $javaClassName(Class dummy){super((Class) null);}\n"; + } + + print CLASS "\n"; + if ( $javaClassName !~ /^Q/ or $signalCode ne '' ) { + my $signalLink = ''; + if ( $signalCode ne '' ) { + print SIGNALS "\npublic interface $javaClassName" . "Signals {\n"; + print SIGNALS $signalCode; + print SIGNALS "}\n"; + close SIGNALS; + + $signalLink = " See {\@link $javaClassName" . "Signals} for signals emitted by $javaClassName\n"; + } + my $docnode = $node->{DocNode}; + print CLASS "/**\n"; + if ( defined $docnode ) { + print CLASS printJavadocComment( $docnode, "", "", $signalLink ) . "\n" + } else { + print CLASS $signalLink; + } + print CLASS "*/\n"; + } + + print CLASS $classdec; + print CLASS $methodCode; + + my %jniNames; + my $name; + foreach my $methodName (keys %jniMethods) { + die if $methodName eq ''; + $name = $methodName; + $name =~ s/(.*[^_])__[^1].*/$1/; + $name =~ s/(.*[^_])__$/$1/; + if (defined $jniNames{$name}) { + $jniNames{$name}++; + } else { + $jniNames{$name} = 1; + } + } + + # Add the JNI functions sorted by name. And with the correct + # signature minus the arg types if name not duplicated + foreach my $methodName (sort keys %jniMethods) { + die if $methodName eq ''; + my $methodCode = $jniMethods{$methodName}; + $methodName =~ s/(.*[^_])__[^1].*/$1/; + $methodName =~ s/(.*[^_])__$/$1/; + if ($jniNames{$methodName} == 1) { + $methodCode =~ s/__\(/\(/; + $methodCode =~ s/__[^1][^\(]*\(/\(/; + } + $jniCode .= $methodCode; + } + + if ( $className eq 'Qt' ) { + if ($main::qt_embedded) { + $qtExtras =~ s/public static native TQCursor whatsThisCursor\(\);//; + $qtjniExtras =~ s/JNIEXPORT jobject JNICALL\nJava_org_kde_qt_Qt_whatsThisCursor[^}]*}//; + } + print CLASS $qtExtras; + $jniCode .= $qtjniExtras; + } elsif ( $className eq 'TQApplication' ) { + print CLASS $qapplicationExtras; + $jniCode .= $qapplicationjniExtras; + } elsif ( $className eq 'TQBitmap' ) { + print CLASS $qbitmapExtras; + $jniCode .= $qbitmapjniExtras; + } elsif ( $className eq 'TQDropEvent' ) { + print CLASS $qdropeventExtras; + $jniCode .= $qdropeventjniExtras; + } elsif ( $className eq 'TQDragObject' ) { + print CLASS $qdragobjectExtras; + $jniCode .= $qdragobjectjniExtras; + } elsif ( $className eq 'TQObject' ) { + print CLASS $qobjectExtras; + $jniCode .= $qobjectjniExtras; + } elsif ( $className eq 'TQImage' ) { + $jniCode .= $qimagejniExtras; + } elsif ( $className eq 'TQListView' ) { + print CLASS $qlistviewExtras; + $jniCode .= $qlistviewjniExtras; + } elsif ( $className eq 'TQListViewItem' ) { + print CLASS $qlistviewitemExtras; + $jniCode .= $qlistviewitemjniExtras; + } elsif ( $className eq 'TQMenuBar' ) { + if ($main::qt_embedded) { + $qmenubarjniExtras =~ s/jobject accel/jlong accel/; + } + $jniCode .= $qmenubarjniExtras; + } elsif ( $className eq 'TQMenuData' ) { + if ($main::qt_embedded) { + $qmenudatajniExtras =~ s/jobject accel/jlong accel/; + } + $jniCode .= $qmenudatajniExtras; + } elsif ( $className eq 'TQMimeSource' ) { + print CLASS $qmimesourceExtras; + $jniCode .= $qmimesourcejniExtras; + } elsif ( $className eq 'TQPopupMenu' ) { + if ($main::qt_embedded) { + $qpopupmenujniExtras =~ s/jobject accel/jlong accel/; + } + $jniCode .= $qpopupmenujniExtras; + } elsif ( $className eq 'TQWidget' ) { + print CLASS $qwidgetExtras; + $jniCode .= $qwidgetjniExtras; + } elsif ( $className eq 'TQPaintDevice' ) { + print CLASS $qpaintdeviceExtras; + $jniCode .= $qpaintdevicejniExtras; + } elsif ( $className eq 'TQPixmap' ) { + print CLASS $qpixmapExtras; + $jniCode .= $qpixmapjniExtras; + } elsif ( $className eq 'TQIODevice' ) { + print CLASS $qiodeviceExtras; + } elsif ( $className eq 'TQPointArray' ) { + print CLASS $qpointarrayExtras; + $jniCode .= $qpointarrayjniExtras; + } elsif ( $className eq 'TQUriDrag' ) { + print CLASS $quridragExtras; + $jniCode .= $quridragjniExtras; + } elsif ( $className eq 'KCmdLineArgs' ) { + $jniCode .= $kcmdlineargsjniExtras; + } elsif ( $className eq 'KIO::Scheduler' ) { + $jniCode .= $schedulerjniExtras; + } elsif ( $className eq 'KApplication' ) { + print CLASS $kapplicationExtras; + $jniCode .= $kapplicationjniExtras; + } elsif ( $className eq 'KMainWindow' ) { + print CLASS $kmainwindowExtras; + $jniCode .= $kmainwindowjniExtras; + } + + print CLASS "}\n"; + close CLASS; + + foreach my $incl (keys %addInclude) { + die if $incl eq ''; + print JNISOURCE "#include <$incl>\n"; + } + + print JNISOURCE "\n"; + print JNISOURCE "#include \n"; + + if ($jniCode =~ /JavaSlot/) { + print JNISOURCE "#include \n"; + } + + if ( $typeprefix eq "qt_" ) { + print JNISOURCE "#include \n"; + } else { + print JNISOURCE "#include \n"; + print JNISOURCE "#include \n"; + } + + if ($javaClassName eq 'KIO') { + # Hack: namespaces can be defined in several source files, which doesn't work, so this.. + print JNISOURCE "#include \n"; + print JNISOURCE "#include \n"; + print JNISOURCE "#include \n"; + print JNISOURCE "#include \n"; + print JNISOURCE "#include \n"; + } + + print JNISOURCE "\n"; + + if ($jbridgeCode ne '' && $node->{CanBeInstanciated}) { + print JNISOURCE "class $javaClassName" . "JBridge : public $className\n"; + print JNISOURCE "{\npublic:\n"; + print JNISOURCE $jbridgeCode; + print JNISOURCE "};\n\n" + } + print JNISOURCE $jniCode; + close JNISOURCE; +} + + +# Generate the prototypes for a method (one per arg with a default value) +# Helper for makeprotos +sub iterproto($$$$$) { + my $classidx = shift; # to check if a class exists + my $method = shift; + my $proto = shift; + my $idx = shift; + my $protolist = shift; + + my $argcnt = scalar @{ $method->{ParamList} } - 1; + if($idx > $argcnt) { + push @$protolist, $proto; + return; + } + if(defined $method->{FirstDefaultParam} and $method->{FirstDefaultParam} <= $idx) { + push @$protolist, $proto; + } + + my $arg = $method->{ParamList}[$idx]->{ArgType}; + + my $typeEntry = findTypeEntry( $arg ); + my $realType = $typeEntry->{realType}; + + # A scalar ? + $arg =~ s/\bconst\b//g; + $arg =~ s/\s+//g; + if($typeEntry->{isEnum} || $allTypes{$realType}{isEnum} || exists $typeunion{$realType} || exists $mungedTypeMap{$arg}) + { + my $id = '$'; # a 'scalar + $id = '?' if $arg =~ /[*&]{2}/; + $id = $mungedTypeMap{$arg} if exists $mungedTypeMap{$arg}; + iterproto($classidx, $method, $proto . $id, $idx + 1, $protolist); + return; + } + + # A class ? + if(exists $classidx->{$realType}) { + iterproto($classidx, $method, $proto . '#', $idx + 1, $protolist); + return; + } + + # A non-scalar (reference to array or hash, undef) + iterproto($classidx, $method, $proto . '?', $idx + 1, $protolist); + return; +} + +# Generate the prototypes for a method (one per arg with a default value) +sub makeprotos($$$) { + my $classidx = shift; + my $method = shift; + my $protolist = shift; + iterproto($classidx, $method, $method->{astNodeName}, 0, $protolist); +} + +# Return the string containing the signature for this method (without return type). +# If the 2nd arg is not the size of $m->{ParamList}, this method returns a +# partial signature (this is used to handle default values). +sub methodSignature($$) { + my $method = shift; + my $last = shift; + my $sig = $method->{astNodeName}; + my @argTypeList; + my $argId = 0; + foreach my $arg ( @{$method->{ParamList}} ) { + last if $argId > $last; + push @argTypeList, $arg->{ArgType}; + $argId++; + } + $sig .= "(". join(", ",@argTypeList) .")"; + $sig .= " const" if $method->{Flags} =~ "c"; + return $sig; +} + +# Return the string containing the java signature for this method (without return type). +# If the 2nd arg is not the size of $m->{ParamList}, this method returns a +# partial signature (this is used to handle default values). +sub javaMethodSignature($$) { + my $method = shift; + my $last = shift; + my $sig = $method->{astNodeName}; + my @argTypeList; + my $argId = 0; + foreach my $arg ( @{$method->{ParamList}} ) { + $argId++; + last if $argId > $last; + push @argTypeList, "arg" . "$argId ". cplusplusToJava( $arg->{ArgType} ); + } + $sig .= "(". join(", ",@argTypeList) .")"; + return $sig; +} + +# Return the string containing the JNI signature for this method (without return type). +# If the 2nd arg is not the size of $m->{ParamList}, this method returns a +# partial signature (this is used to handle default values). +sub jniMethodSignature($$$$$) { + my $method = shift; + my $methodname = shift; + my $last = shift; + my $javaClassName = shift; + my $javaArgList = shift; + + my $sig = ($javaClassName =~ /^Q/ ? "Java_org_kde_qt_" : "Java_org_kde_koala_"); + $sig .= $javaClassName . "_"; + $methodname =~ s/_/_1/g; + $sig .= $methodname . "__"; + my @argTypeList; + my @argList; + my $javaStatic = ($method->{Flags} =~ "s" or $method->{Parent}->{NodeType} eq 'namespace'); + push @argTypeList, "JNIEnv*"; + push @argTypeList, ($javaStatic ? "jclass" : "jobject"); + push @argList, "JNIEnv* env"; + push @argList, ($javaStatic ? "jclass cls" : "jobject obj"); + my $argId = 0; + foreach my $arg ( @{$method->{ParamList}} ) { + $argId++; + last if $argId > $last; + push @argTypeList, cplusplusToJNI( $arg->{ArgType} ); + push @argList, cplusplusToJNI( $arg->{ArgType} ) . " " . $javaArgList->[$argId - 1]; + $sig .= cplusplusToJNISignature( $arg->{ArgType} ); + } + my $call = $sig; + $sig .= "(" . join(", ",@argTypeList) .")"; + $call .= "(" . join(", ",@argList) .")"; + return ( $sig, $call ); +} + +sub coerce_type($$$$) { + #my $m = shift; + my $union = shift; + my $var = shift; + my $type = shift; + my $new = shift; # 1 if this is a return value, 0 for a normal param + + my $typeEntry = findTypeEntry( $type ); + my $realType = $typeEntry->{realType}; + + my $unionfield = $typeEntry->{typeId}; +# die "$type" unless defined( $unionfield ); + if ( ! defined( $unionfield ) ) { + print STDERR "type field not defined: $type\n"; + return ""; + } + + $unionfield =~ s/t_/s_/; + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + my $code = "$union.$unionfield = "; + if($type =~ /&$/) { + $code .= "(void*)&$var;\n"; + } elsif($type =~ /\*$/) { + $code .= "(void*)$var;\n"; + } else { + if ( $unionfield eq 's_class' + or ( $unionfield eq 's_voidp' and $type ne 'void*' ) + or $type eq 'TQString' ) { # hack + $type =~ s/^const\s+//; + if($new) { + $code .= "(void*)new $type($var);\n"; + } else { + $code .= "(void*)&$var;\n"; + } + } else { + $code .= "$var;\n"; + } + } + + return $code; +} + +# Generate the list of args casted to their real type, e.g. +# (TQObject*)x[1].s_class,(TQEvent*)x[2].s_class,x[3].s_int +sub makeCastedArgList +{ + my @castedList; + my $i = 1; # The args start at x[1]. x[0] is the return value + my $arg; + foreach $arg (@_) { + my $type = $arg; + my $cast; + + my $typeEntry = findTypeEntry( $type ); + my $unionfield = $typeEntry->{typeId}; +# die "$type" unless defined( $unionfield ); + if ( ! defined( $unionfield ) ) { + print STDERR "type field not defined: $type\n"; + return ""; + } + $unionfield =~ s/t_/s_/; + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + my $v .= " arg$i"; + if($type =~ /&$/) { + $cast = "*($type *)"; + } elsif($type =~ /\*$/) { + $cast = "($type)"; + } elsif($type =~ /\(\*\)\s*\(/) { # function pointer ... (*)(...) + $cast = "($type)"; + } else { + if ( $unionfield eq 's_class' + or ( $unionfield eq 's_voidp' and $type ne 'void*' ) + or $type eq 'TQString' ) { # hack + $cast = "*($type *)"; + } else { + $cast = "($type)"; + } + } + push @castedList, "$type$v"; + $i++; + } + return @castedList; +} + +# Adds the header for node $1 to be included in $2 if not already there +# Prints out debug stuff if $3 +sub addIncludeForClass($$$) +{ + my ( $node, $addInclude, $debugMe ) = @_; + my $sourcename = $node->{Source}->{astNodeName}; + if ( $sourcename !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|tdeprint/|tdesu/)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } +# die "Empty source name for $node->{astNodeName}" if ( $sourcename eq '' ); + return if ( $sourcename eq '' ); + unless ( defined $addInclude->{$sourcename} ) { + print " Including $sourcename\n" if ($debugMe); + $addInclude->{$sourcename} = 1; + } + else { print " $sourcename already included.\n" if ($debugMe); } +} + +sub checkIncludesForObject($$) +{ + my $type = shift; + my $addInclude = shift; + + my $debugCI = 0; #$debug + #print "checkIncludesForObject $type\n"; + $type =~ s/const\s+//; + my $it = $type; + if (!($it and exists $typeunion{$it}) and $type !~ /\*/ and $type ne "" + #and $type !~ /&/ # in fact we also want refs, due to the generated code + ) { + $type =~ s/&//; + print " Detecting an object by value/ref: $type\n" if ($debugCI); + my $node = kdocAstUtil::findRef( $rootnode, $type ); + if ($node) { + addIncludeForClass( $node, $addInclude, $debugCI ); + } + else { print " No header found for $type\n" if ($debugCI); } + } +} + + + +# Adds the import for node $1 to be imported in $2 if not already there +# Prints out debug stuff if $3 +sub addImportForClass($$$) +{ + my ( $node, $addImport, $debugMe ) = @_; + my $importname = javaImport( $node->{astNodeName} ); +# print " Importing $importname for node name: " . $node->{astNodeName} . "\n"; + # No import needed, so return + return if ( $importname eq '' ); + unless ( defined $addImport->{$importname} ) { + print " Importing $importname\n" if ($debugMe); + $addImport->{$importname} = 1; + if ( kalyptusDataDict::interfacemap($node->{astNodeName}) ) { + $addImport->{$importname . "Interface"} = 1; + } + } + else { print " $importname already imported.\n" if ($debugMe); } +} + +sub checkImportsForObject($$) +{ + my $type = shift; + my $addImport = shift; + + my $debugCI = 0; #$debug + # print "checkImportsForObject $type\n"; + $type =~ s/const\s+//; + my $it = $type; + if (!($it and exists $typeunion{$it}) and $type ne "" + #and $type !~ /&/ # in fact we also want refs, due to the generated code + ) { + $type =~ s/&//; + $type =~ s/[*]//; + print " Detecting an object by value/ref: $type\n" if ($debugCI); + my $node = kdocAstUtil::findRef( $rootnode, $type ); + if ($node and $node->{NodeType} eq "class" ) { + print " NodeType: " . $node->{NodeType} . "\n" if ($debugCI); + addImportForClass( $node, $addImport, $debugCI ); + } + else { + if ( cplusplusToJava($it) eq 'ArrayList' ) { + $addImport->{"java.util.ArrayList"} = 1; + } else { + print " No import found for $type\n" if ($debugCI); + } + } + } +} + +sub generateVirtualMethod($$$$$) +{ + # Generating methods for $class. + # $m: method node. $methodClass: the node of the class in which the method is really declared + # (can be different from $class when the method comes from a super class) + # This is important because of $allMethods, which has no entry for class::method in that case. + + my( $classNode, $signature, $m, $methodClass, $addImport ) = @_; + my $methodCode = ''; # output + my $returnType = $m->{ReturnType}; + return ('', '') if $returnType eq '~'; # skip destructors + + my $className = $classNode->{astNodeName}; + my $flags = $m->{Flags}; + my @argList = @{$m->{ParamList}}; + + print "generateVirtualMethod $className: $signature ($m->{Access})\n" if ($debug); + + # Detect objects returned by value + checkImportsForObject( $returnType, $addImport ) if ($returnType ne 'void'); + + # Generate a matching virtual method in the x_ class + $methodCode .= "\tvirtual $returnType $m->{astNodeName}("; + my $i = 0; + foreach my $arg ( @argList ) { + $methodCode .= ", " if $i++; + $methodCode .= $arg->{ArgType}; + $methodCode .= " x$i"; + + # Detect objects passed by value + checkImportsForObject( $arg->{ArgType}, $addImport ); + } + $methodCode .= ") "; + $methodCode .= "const " if ($flags =~ "c"); + $methodCode .= "\{\n"; + + # Now the code of the method + my $this = $classNode->{BindingDerives} > 0 ? "this" : "xthis"; + + $i++; # Now the number of args + $methodCode .= "\tSmoke::StackItem x[$i];\n"; + $i = 1; + for my $arg (@argList) { + $methodCode .= "\t"; + $methodCode .= coerce_type("x[$i]", "x$i", $arg->{ArgType}, 0); + $i++; + } + + my $sig = $methodClass->{astNodeName} . "::" . $signature; + my $idx = $allMethods{$sig}; +# die "generateVirtualMethod: $className: No method found for $sig\n" if !defined $idx; + if ( !defined $idx ) { + print STDERR "generateVirtualMethod: $className: No method found for $sig\n"; + return ""; + } + + if($flags =~ "p") { # pure virtual + $methodCode .= "\t${libname}_Smoke->binding->callMethod($idx, (void*)$this, x, true /*pure virtual*/);\n"; + } else { + $methodCode .= "\tif(${libname}_Smoke->binding->callMethod($idx, (void*)$this, x)) "; + } + + $returnType = undef if ($returnType eq 'void'); + if($returnType) { + my $arg = $returnType; + my $it = $arg; + my $cast; + my $v = "x[0]"; + my $indent = ($flags =~ "p") ? "\t" : ""; + if($it and exists $typeunion{$it}) { + $v .= ".$typeunion{$it}"; + $cast = "($arg)"; + $methodCode .= "${indent}return $cast$v;\n"; + } else { + $v .= ".s_class"; + if($arg =~ s/&//) { + $cast = "*($arg *)"; + $methodCode .= "${indent}return $cast$v;\n"; + } elsif($arg !~ /\*/) { + unless($flags =~ "p") { + $indent = "\t "; + $methodCode .= "{\n"; + } + # we assume it's a new thing, and handle it + $methodCode .= "${indent}$arg *xptr = ($arg *)$v;\n"; + $methodCode .= "${indent}$arg xret(*xptr);\n"; + $methodCode .= "${indent}delete xptr;\n"; + $methodCode .= "${indent}return xret;\n"; + $methodCode .= "\t}\n" unless $flags =~ "p"; + } else { + $cast = "($arg)"; + $methodCode .= "${indent}return $cast$v;\n"; + } + } + } else { + $methodCode .= "\t" if $flags =~ "p"; + $methodCode .= "return;\n"; + } + if($flags =~ "p") { + $methodCode .= "\t// ABSTRACT\n"; + $methodCode .= " }\n"; + return ( $methodCode ); + } + $methodCode .= "\t"; + if($returnType) { + $methodCode .= "return "; + } + $methodCode .= "$this\->$methodClass->{astNodeName}\::$m->{astNodeName}("; + $i = 0; + for my $arg (@argList) { + $methodCode .= ", " if $i++; + $methodCode .= "x$i"; + } + $methodCode .= ");\n"; + $methodCode .= "\t}\n"; + return ( $methodCode ); +} + +sub generateMethod($$$$$$$$$) +{ + my( $classNode, $m, $addImport, $addInclude, $ancestorCount, $javaMethods, $jniMethods, $mainClassNode, $generateConstructors ) = @_; # input + my $methodCode = ''; # output + my $interfaceCode = ''; # output + my $signalCode = ''; # output + my $jbridgeCode = ''; # output + + my $jniCode; + my $name = $m->{astNodeName}; # method name + + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + + @heritage = kdocAstUtil::heritage($mainClassNode); + my $mainClassName = join( "::", @heritage ); + + # The javaClassName might be 'TQWidget', while currentClassName is 'TQRangeControl' + # and the TQRangeControl methods are being copied into TQWidget. + my $javaClassName = $mainClassNode->{astNodeName}; + my $currentClassName = $classNode->{astNodeName}; + + my $bridgeClassName; + if ($classNode->{astNodeName} eq $main::globalSpaceClassName) { + $bridgeClassName = ""; + } elsif (!$mainClassNode->{CanBeInstanciated}) { + $bridgeClassName = $className; + } else { + $bridgeClassName = $mainClassNode->{astNodeName} . "JBridge"; + } + + my $firstUnknownArgType = 99; + my $returnType = $m->{ReturnType}; + + # Don't use $className here, it's never the fully qualified (A::B) name for a ctor. + my $isConstructor = ($name eq $classNode->{astNodeName} ); + my $isDestructor = ($returnType eq '~'); + + # Don't generate anything for destructors, or constructors for namespaces + return if $isDestructor + or ($classNode->{NodeType} eq 'namespace' and $isConstructor) + or (!$mainClassNode->{CanBeInstanciated} and $m->{Access} =~ /protected/); + + # Rename operator methods 'op_...' + if ( $name =~ /^operator.*/ ) { + $methodNumber++; + $name =~ s/ //; + if (! exists $operatorNames{$name} ) { + return; + } + $name = $operatorNames{$name}; + } + + if ($classNode->{astNodeName} eq $main::globalSpaceClassName) { + my $sourcename = $m->{Source}->{astNodeName}; + # Only put Global methods which came from sources beginning with q into class Qt + # Skip any methods in qstring.h/qcstring.h apart from TQByteArray compress/uncompress + if ($javaClassName eq 'Qt' + and ( $sourcename !~ /\/q[^\/]*$/ or ($sourcename =~ /string.h$/ and $name !~ /[Cc]ompress/) )) { + return; + } + # ..and any other global methods into KDE + if ($javaClassName eq 'KDE' and $m->{Source}->{astNodeName} =~ /\/q[^\/]*$/) { + return; + } + + if ( $sourcename !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|tdeprint/|tdesu/)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } + if ( $sourcename eq '' ) { + return; + } + $addInclude->{$sourcename} = 1; + } + + if ($returnType eq 'void') { + $returnType = undef; + } else { + # Detect objects returned by value + checkImportsForObject( $returnType, $addImport ); + checkIncludesForObject( $returnType, $addInclude ); + } + + my $hasDuplicateSignature = 0; + my $isStatic = $m->{Flags} =~ "s"; + my $isPure = $m->{Flags} =~ "p"; + + return if ( $m->{SkipFromSwitch} && $m->{Flags} !~ "p" ); + +# # Skip internal methods, which return unknown types +# # Hmm, the C# bindings have a list of those too. +# return if ( $returnType =~ m/TQGfx\s*\*/ ); +# return if ( $returnType eq 'CGContextRef' ); +# return if ( $returnType eq 'TQWSDisplay *' ); +# # This stuff needs callback, or ** +# return if ( $name eq 'defineIOHandler' or $name eq 'qt_init_internal' ); +# # Skip casting operators, but not == < etc. +# return if ( $name =~ /operator \w+/ ); +# # TQFile's EncoderFn/DecoderFn +# return if ( $name =~ /set[ED][ne]codingFunction/ ); +# # How to implement this? (TQXmlDefaultHandler/TQXmlEntityResolver::resolveEntity, needs A*&) +# return if ( $name eq 'resolveEntity' and $className =~ /^TQXml/ ); +# return if ( $className eq 'TQBitArray' && $m->{Access} eq 'protected' ); + + #print STDERR "Tests passed, generating.\n"; + + + my $argId = 0; + + my @argTypeList=(); + my @javaArgTypeList=(); + my @javaArgList = (); + my @jniArgList = (); + my @jniArgLocals = (); + my @jniCleanups = (); + my @namedArgTypeList=(); + + foreach my $arg ( @{$m->{ParamList}} ) { + $argId++; + + if ( $arg->{ArgName} =~ /^super$|^int$|^env$|^cls$|^obj$|^byte$/ ) { + $arg->{ArgName} = ""; + } + + if ( $arg->{ArgName} =~ /^short$|^long$/ ) { + # Oops looks like a parser error + $arg->{ArgType} = $arg->{ArgName}; + $arg->{ArgName} = ""; + } + + print STDERR " Param ".$arg->{astNodeName}." type: ".$arg->{ArgType}." name:".$arg->{ArgName}." default: ".$arg->{DefaultValue}." java: ".cplusplusToJava($arg->{ArgType})."\n" if ($debug); + + my $argType = $arg->{ArgType}; + my $namedArgType; + my $javaArgType; + my $javaArg; + my $jniArg; + my $jniLocal; + my $jniCleanup; + my $argName; + + if ( cplusplusToJava($argType) eq "" && $firstUnknownArgType > $argId ) { + $firstUnknownArgType = $argId; + } + + $javaArg = ($arg->{ArgName} eq "" ? "arg" . $argId : $arg->{ArgName}); + $namedArgType = $argType . " " . $javaArg; + $javaArgType = cplusplusToJava($argType) . " " . $javaArg; + ($jniLocal, $jniArg, $jniCleanup) = jniArgTocplusplus($argType, $javaArg); + + push @argTypeList, $argType; + push @javaArgTypeList, $javaArgType; + push @javaArgList, $javaArg; + push @jniArgLocals, $jniLocal; + push @jniCleanups, $jniCleanup; + push @jniArgList, $jniArg; + push @namedArgTypeList, $namedArgType; + + # Detect objects passed by value + checkImportsForObject( $argType, $addImport ); + checkIncludesForObject( $argType, $addInclude ); + } + + if ( $name eq 'TQApplication' or ($javaClassName eq 'KCmdLineArgs' and $name eq 'init' and scalar(@javaArgList) > 1) ) { + # Junk the 'int argc' parameter + shift @javaArgTypeList; + shift @javaArgList; + } + + my @castedArgList = makeCastedArgList( @argTypeList ); + + # We iterate as many times as we have default params + my $firstDefaultParam = $m->{FirstDefaultParam}; + $firstDefaultParam = scalar(@argTypeList) unless defined $firstDefaultParam; + my $iterationCount = scalar(@argTypeList) - $firstDefaultParam; + + my $jniReturnType = cplusplusToJNI($m->{ReturnType}); + # ArrayLists are jobjectArrays in args, but jobjects in return types + $jniReturnType =~ s/jobjectArray/jobject/; + + my $javaReturnType = cplusplusToJava($m->{ReturnType}); + if ( $javaReturnType =~ s/StringBuffer/String/ ) { + $jniReturnType =~ s/jobject/jstring/; + } elsif ( $javaReturnType =~ s/String\[\]/ArrayList/ ) { + $addImport->{"java.util.ArrayList"} = 1; + } + + if ($m->{ReturnType} =~ /^int\&/) { + $javaReturnType = 'int'; + $jniReturnType =~ s/jintArray/jint/; + } + + if ($javaReturnType eq "") { + $firstUnknownArgType = 0; + } + + print STDERR " ". ($iterationCount+1). " iterations for $name\n" if ($debug); + + my $javaSignature = javaMethodSignature( $m, @argTypeList ); + + if ( defined $javaMethods->{$javaSignature} ) { + $hasDuplicateSignature = 1; + } + + my $docnode = $m->{DocNode}; + if ( $firstUnknownArgType >= 0 && $m->{Access} !~ /signals/ && ! $hasDuplicateSignature + && defined $docnode && ($generateConstructors || !$isConstructor) ) + { + my $javadocComment = printJavadocComment( $docnode, "", "\t", "" ); + $methodCode .= "\t/**" . $javadocComment . "*/\n" unless $javadocComment =~ /^\s*$/; + } + + while($iterationCount >= 0) { + + $javaMethods->{$javaSignature} = 1; + + local($") = ","; + + if($firstUnknownArgType <= scalar(@argTypeList) || $hasDuplicateSignature || ($name =~ /^qObject$/) || $m->{Access} =~ /dcop/ ) { + if ( $firstUnknownArgType <= scalar(@argTypeList) || $m->{Access} =~ /dcop/ ) { + my $failedConversion = "\t// " . $m->{ReturnType} . " $name(@castedArgList[0..$#argTypeList]); >>>> NOT CONVERTED\n"; + if ( $m->{Access} =~ /signals/ ) { + $signalCode .= $failedConversion; + } else { + $methodCode .= $failedConversion; + } + } + } else { + +# $jniCode .= "\tcase $methodNumber: "; +# if ($flags =~ "s" || $isConstructor) { # static or constructor +# $jniCode .= "$bridgeClassName\::"; +# } else { +# $jniCode .= "xself->" +# } +# $jniCode .= "x_$methodNumber(args);"; +# $jniCode .= "\tbreak;\n"; + + if ($name eq 'find' and $javaClassName eq 'TQButtonGroup') { + # Can't override a static method find() in TQWidget + $name = "findButton"; + } elsif ( $name eq 'null' ) { + $name = "nil"; + } elsif ( $name eq 'form' and $javaClassName =~ /^HTML/ ) { + $name = "formElement"; + } elsif ( $name eq 'wait' and $javaClassName eq 'KProcess' ) { + $name = "waitThread"; + } elsif ( $name eq 'finalize' and $javaClassName eq 'KMD5' ) { + $name = "finalizeDigest"; + } elsif ( $name eq 'icon' and $javaClassName eq 'TQMessageBox' ) { + $name = "iconId"; + } elsif ( $name eq 'icon' and $javaClassName eq 'KURLBarItemDialog' ) { + $name = "iconName"; + } elsif ( $name eq 'iconText' and $javaClassName eq 'KToolBar' ) { + $name = "iconTextId"; + } elsif ( $name eq 'reset' and $javaClassName eq 'KExtendedSocket' ) { + $name = "resetSocket"; + } elsif ( $name eq 'palette' and $javaClassName eq 'KPaletteTable' ) { + $name = "paletteName"; + } elsif ( $name eq 'size' and $javaClassName eq 'KAnimWidget' ) { + $name = "iconSize"; + } elsif ( $name eq 'size' and $javaClassName eq 'KFontCombo' ) { + $name = "pointSize"; + } elsif ($javaSignature eq "icon()" and $javaClassName eq 'KIconButton') { + $name = "iconName"; + } elsif ($javaSignature eq "close()" and $javaClassName eq 'KDirOperator') { + $name = "closeLoading"; + } elsif ($javaSignature eq "font()" and $javaClassName eq 'KCharSelect') { + $name = "fontName"; + } elsif ($javaSignature eq "layout()" and $javaReturnType eq 'void') { + $name = "updateLayout"; + } elsif ( $name eq 'sorting' and $javaReturnType eq 'boolean' ) { + $name = "sortOnInsert"; + } elsif ($javaSignature eq "statusBar()" and $javaClassName =~ /^K/ ) { + $name = "kstatusBar"; + } elsif ($javaSignature eq "menuBar()" and $javaClassName =~ /^K/ ) { + $name = "kmenuBar"; + } elsif ( $name eq 'addLabel' and $javaClassName eq 'TQTableHeader' ) { + $name = "addHeaderLabel"; + } + + my $javaparams = join( ", ", @javaArgTypeList ); + my ( $jniSignature, $jniCall ) = jniMethodSignature( $m, + ($isConstructor ? "new$name" : $name), + @argTypeList, $javaClassName, \@javaArgList ); + + my $cplusplusparams; + my $i = 0; + for my $arg (@argTypeList) { + $cplusplusparams .= "," if $i++; + $cplusplusparams .= "arg" . $i; + } + + if ($isConstructor) { + if ( $generateConstructors && $mainClassNode->{CanBeInstanciated} ) { + $jbridgeCode .= "\t$bridgeClassName(@castedArgList[0..$#argTypeList]) : $className($cplusplusparams) {};\n"; + + $methodCode .= "\tpublic $javaClassName($javaparams) {\n"; + if ( $ancestorCount > 0 ) { + $methodCode .= "\t\tsuper((Class) null);\n" + } + $methodCode .= "\t\tnew$javaClassName(@javaArgList[0..$#javaArgTypeList]);\n"; + $methodCode .= "\t}\n"; + $methodCode .= "\tprivate native void new$javaClassName($javaparams);\n"; + + $jniCode = "JNIEXPORT void JNICALL\n"; + $jniCode .= "$jniCall\n"; + $jniCode .= "{\n"; + $jniCode .= join( "", @jniArgLocals ); + $jniCode .= "\tif (QtSupport::getQt(env, obj) == 0) {\n"; + $jniCode .= "\t\tQtSupport::setQt(env, obj, new $bridgeClassName(" . join( ", ", @jniArgList ). "));\n"; + $jniCode .= "\t\tQtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj));\n"; + $jniCode .= join( "", @jniCleanups ); + $jniCode .= "\t}\n\treturn;\n}\n\n"; + + # Look for args which are are a TQQbject/slot string pair and replace with a java proxy slot + if ($jniCode =~ s/QtSupport::getQt\(env, (receiver|recvr|pObjSlot)\), \(const char\*\) QtSupport::toCharString\(env, (member|slot|psMethodSlot), \&_qstring_(member|slot|psMethodSlot)\)/QtSupport::slotForReceiver(env, $1, $2), "1invoke()"/) { + $jniCode =~ s/static TQCString\* _qstring_(member|slot|psMethodSlot) = 0;\n//; + } + + $jniSignature =~ /^([^\)]*)\(.*/; + if ($skippedJniMethods{$1}) { + # Don't generate code for jni methods added as 'extras' + $jniMethods->{$jniSignature} = ""; + } else { + $jniMethods->{$jniSignature} = $jniCode; + } + } + } else { + my $access = $m->{Access}; + $access =~ s/_slots//; + + if ( $access eq 'public' or $access eq 'protected' ) { + if ( $name =~ /^takeItem$|^setPixmap$|^clearCell$|^setItem$|^item$|^minimumSize$/ + or $name =~ /^stepUp$|^stepDown$|^sectionFormattedText$|^addNumber$|^removeLastNumber$/ + or $name =~ /^cancel$|^setSource$|^paintCell$|^updateContents$|^sizeHint$|^setFocusSection$/ + or $name =~ /^event$|^eventFilter$|^copy$|^detach$|^showEvent$|^format$|^encodedData$/ + or $name =~ /^styleChange$|^insertItem$|^setStatus$|^setState$|^minimumSizeHint$/ + or $name =~ /^bytesPerLine$|^paintBranches$|^scanLine$|^ensureCursorVisible$|^setCursor$/ + or $name =~ /^updateGeometry$|^setState$|^exec$|^pixmap$|^areaPoints$|^draw$|^writeDir$/ ) { + # These methods are public in some places, but protected in others, + # so make them all public. + $access = "public"; + } + + $methodCode .= "\t" . $access . (($isStatic or $classNode->{NodeType} eq 'namespace') ? " static " : " ") . "native "; +# $methodCode .= ( $m->{Flags} =~ "v" || $isStatic ? "" : "final " ); + + my $altReturnType = undef; + if ($name =~ /^xForm$/ ) { + $javaReturnType = "Object"; + } elsif ($javaSignature eq "layout()" and $javaReturnType ne 'void') { + $altReturnType = "TQLayout"; + } elsif ($javaSignature eq "defaultFactory()" and $javaReturnType eq 'TQSqlEditorFactory') { + $javaReturnType = "TQEditorFactory"; + } elsif ($javaSignature =~ /^bits|^scanLine/) { + $javaReturnType = "byte[]"; + } elsif ($javaSignature eq "at()" and $javaClassName eq 'KFilterDev') { + $javaReturnType = "long"; + } elsif ($javaSignature =~ /copyTo/ and $javaClassName eq "KDesktopFile" ) { + $altReturnType = "KConfig"; + } + + if ( defined $altReturnType ) { + checkImportsForObject( $altReturnType, $addImport ); + $javaReturnType = $altReturnType; + } + $methodCode .= $javaReturnType; + $methodCode .= " $name($javaparams);\n"; + + if ($access eq 'public' and !$isStatic) { + $interfaceCode .= "\t\t$javaReturnType $name($javaparams);\n"; + } + + my $methodName = $m->{astNodeName}; + # Hack to stop calling super for TQWidget::polish() from looping + if ( $m->{Access} =~ /public/ + && $returnType eq '' + && $m->{Flags} =~ "v" + && $cplusplusparams eq '' + && $bridgeClassName ne $className ) + { + $methodName = "public_" . $m->{astNodeName}; + $jbridgeCode .= "\t"; + $jbridgeCode .= "void $methodName() {\n"; + $jbridgeCode .= "\t\t$className" . "::" . $m->{astNodeName} . "();\n"; + $jbridgeCode .= "\t\treturn;\n"; + $jbridgeCode .= "\t}\n"; + } + + if ($m->{Access} =~ /protected/) { + $methodName = "protected_" . $m->{astNodeName}; + $jbridgeCode .= (($isStatic or $classNode->{NodeType} eq 'namespace') ? "\tstatic " : "\t"); + if ( $returnType eq '' ) { + $jbridgeCode .= "void $methodName(@castedArgList[0..$#argTypeList]) {\n"; + $jbridgeCode .= "\t\t$className" . "::" . $m->{astNodeName} . "($cplusplusparams);\n"; + $jbridgeCode .= "\t\treturn;\n"; + } else { + $jbridgeCode .= "$returnType $methodName(@castedArgList[0..$#argTypeList]) {\n"; + $jbridgeCode .= "\t\treturn ($returnType) $className" . "::" . $m->{astNodeName} . "($cplusplusparams);\n"; + } + $jbridgeCode .= "\t}\n"; + + } + + $jniCode = "JNIEXPORT $jniReturnType JNICALL\n"; + $jniCode .= "$jniCall\n"; + $jniCode .= "{\n"; + my $selfstring; + if ( $isStatic or $classNode->{NodeType} eq 'namespace' ) { + $selfstring = $bridgeClassName . "::" . $methodName; + } else { + if ($m->{Access} =~ /protected/ || $methodName =~ /^public_/) { + $selfstring = "(($bridgeClassName*) QtSupport::getQt(env, obj))->$methodName"; + } else { + $selfstring = "(($className*)" . ($mainClassName eq $className ? "" : "($mainClassName*)") . " QtSupport::getQt(env, obj))->" . $m->{astNodeName}; + } + } + my ($locals, $fcall) = jniToReturnValue( $m->{ReturnType}, "$selfstring(" . join( ", ", @jniArgList ). ")", join( "", @jniCleanups ) ); + # Add dummy statements to avoid compiler warnings if needed + $locals .= ($jniSignature =~ /jclass/ ? "\t(void) cls;\n" : ""); + $locals .= ($fcall !~ /env/ ? "\t(void) env;\n" : ""); + + my $slotArgType = ''; + if ($name eq 'insertAnimatedWidget' or $name eq 'connectStatus' or $name eq 'disconnectStatus') { + $slotArgType = 'int'; + } elsif ($name eq 'connectResize' or $name eq 'disconnectResize') { + $slotArgType = 'const TQSize&'; + } elsif ($name eq 'connectUpdate' or $name eq 'disconnectUpdate') { + $slotArgType = 'const TQRect&'; + } + # Look for args which are are a TQQbject/slot string pair and replace with a java proxy slot + + $locals .= join( "", @jniArgLocals ); + + if ($fcall =~ s/QtSupport::getQt\(env, (receiver|recvr|pObjSlot)\), \(const char\*\) QtSupport::toCharString\(env, (member|slot|psMethodSlot), \&_qstring_(member|slot|psMethodSlot)\)/QtSupport::slotForReceiver(env, $1, $2), "1invoke($slotArgType)"/) { + $locals =~ s/static TQCString\* _qstring_(member|slot|psMethodSlot) = 0;\n//; + } + + $jniCode .= $locals; + + if ($name eq 'readBlock') { + $interfaceCode =~ s/String /StringBuffer /; + $methodCode =~ s/String /StringBuffer /; + $jniCode =~ s/jstring/jobject/; + $jniCode =~ /(jlong|jint) (\w+)\)/; + my $arg2 = $2; + $jniCode =~ s/_qstring_(\w+) = 0;\n/_qstring_$1 = 0;\n\tif \(_qstring_$1 == 0\) { _qstring_$1 = new TQCString\(\); }\n\t_qstring_$1->resize\(\(uint\) $arg2\);\n/; + my $arg1 = $1; + $fcall =~ s/QtSupport::toCharString\([^\)]*\)/_qstring_$arg1->data()/; + $fcall =~ s/return xret;/QtSupport::fromTQCStringToStringBuffer(env, _qstring_$arg1, $arg1);\n\treturn xret;/; + } + + $jniCode .= $fcall; + $jniCode .= "}\n\n"; + + if ($isPure && $m->{Access} =~ /protected/) { + # Can't do a lot with implementing these, so give up + $jniCode = ""; + $jbridgeCode = ""; + } + + $jniSignature =~ /^([^\)]*)\(.*/; + if ($skippedJniMethods{$1}) { + # Don't generate code for jni methods added as 'extras' + $jniMethods->{$jniSignature} = ""; + } else { + $jniMethods->{$jniSignature} = $jniCode; + } + } else { + if ( $access =~ /signals/ ) { + my $docnode = $m->{DocNode}; + if ( defined $docnode ) { + my $javadocComment = printJavadocComment( $docnode, "", "\t", "" ); + $signalCode .= "\t/**" . $javadocComment . "*/\n" unless $javadocComment =~ /^\s*$/; + } + $signalCode .= "\tvoid $name($javaparams);\n"; + } + } + } + } + + pop @argTypeList; + pop @javaArgTypeList; + pop @javaArgList; + pop @jniArgList; + pop @jniArgLocals; + pop @jniCleanups; + + $javaSignature = javaMethodSignature( $m, @argTypeList ); + $hasDuplicateSignature = (defined $javaMethods->{$javaSignature} ? 1 : 0); + + $methodNumber++; + $iterationCount--; + } # Iteration loop + + return ( $methodCode, $interfaceCode, $signalCode, $jbridgeCode ); +} + + +sub generateEnum($$$) +{ + my( $classNode, $m, $generateAnonymous ) = @_; # input + my $methodCode = ''; # output + + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + my $javaClassName = $classNode->{astNodeName}; + + if ( ($generateAnonymous and $m->{astNodeName} ) or (! $generateAnonymous and ! $m->{astNodeName}) ) { + return; + } + + if ( defined $m->{DocNode} ) { + my $javadocComment = printJavadocComment( $m->{DocNode}, "", "\t", "" ); + $methodCode .= "\t/**" . $javadocComment . "*/\n" unless $javadocComment =~ /^\s*$/; + } + + my @enums = split(",", $m->{Params}); + my $enumCount = 0; + foreach my $enum ( @enums ) { + $enum =~ s/\s//g; + $enum =~ s/::/./g; + $enum =~ s/\(mode_t\)//; + if ( $enum =~ /(.*)=([-0-9]+)$/ ) { + $methodCode .= "\tpublic static final int $1 = $2;\n"; + $enumCount = $2; + $enumCount++; + } elsif ( $enum =~ /(.*)=(.*)/ ) { + $methodCode .= "\tpublic static final int $1 = $2;\n"; + } else { + $methodCode .= "\tpublic static final int $enum = $enumCount;\n"; + $enumCount++; + } + } + + $methodCode .= "\n"; + $methodNumber++; + + return ( $methodCode ); +} + +sub generateVar($$$) +{ + my( $classNode, $m, $addImport ) = @_; # input + my $methodCode = ''; # output + my $interfaceCode = ''; # output + + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + my $javaClassName = $classNode->{astNodeName}; + + my $name = $m->{astNodeName}; + my $varType = $m->{Type}; + $varType =~ s/static\s//; + $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/\s*$//; + my $fullName = "$className\::$name"; + + checkImportsForObject( $varType, $addImport ); + +# die "Invalid index for $fullName: $classNode->{case}{$fullName} instead of $methodNumber" if $classNode->{case}{$fullName} != $methodNumber; +# $methodCode .= " static void x_$methodNumber(Smoke::Stack x) {\n"; +# $methodCode .= "\tx[0].s_class = (void*)new $varType($fullName);\n"; +# $methodCode .= " }\n"; + +# if ( ($name !~ /^null$/) && (cplusplusToJava($varType) ne "") ) { + if ( ($name !~ /^null$/) && (cplusplusToJava($varType) ne "" ) ) { +# $interfaceCode .= "\t\t". cplusplusToJava($varType) . " $name();\n"; + +# $methodCode .= "\tpublic native static ". cplusplusToJava($varType) . " $name();\n"; + } + + $methodNumber++; + return ( $methodCode, $interfaceCode ); +} + +## Called by writeClassDoc +sub generateAllMethods($$$$$$$$) +{ + my ($classNode, $ancestorCount, $javaMethods, $jniMethods, $mainClassNode, $generateConstructors, $addImport, $addInclude) = @_; + my $methodCode = ''; + my $interfaceCode = ''; + my $signalCode = ''; + my $jbridgeCode = ''; + $methodNumber = 0; + #my $className = $classNode->{astNodeName}; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + my $javaClassName = $mainClassNode->{astNodeName}; + my $jniClassName = ($classNode->{astNodeName} =~ /^Q/ ? "Java_org_kde_qt_" : "Java_org_kde_koala_") . $classNode->{astNodeName}; + # If the C++ class had multiple inheritance, then the code for all but one of the + # parents must be copied into the code for javaClassName. Hence, for TQWidget current + # classname might be TQPaintDevice, as its methods are needed in TQWidget. + my $currentClassName = join( ".", kdocAstUtil::heritage($classNode) ); + + my $sourcename = $classNode->{Source}->{astNodeName}; + + if ( $sourcename !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|tdeprint/|tdesu/)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } +# die "Empty source name for $classNode->{astNodeName} $classNode->{Source}->{astNodeName}" if ( $sourcename eq '' ); + + if ($classNode->{astNodeName} ne $main::globalSpaceClassName && $sourcename ne '') { + $addInclude->{$sourcename} = 1; +# my $s; +# for my $sn( @{$classNode->{Sources}} ) { +# if ( ($s = $sn->{astNodeName}) !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|tdeprint/|tdesu/)(.*)!$1$2!m ) { +# $s =~ s!.*/(.*)!$1!m; +# } +# $addInclude->{$s} = 1; +# } + } + + $addImport->{"org.kde.qt.QtSupport"} = 1; + + # Do all enums first, anonymous ones and then named enums + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'enum' and $currentClassName eq $javaClassName ) { + my ($meth) = generateEnum( $classNode, $methodNode, 1 ); + $methodCode .= $meth; + } + }, undef ); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'enum' and $currentClassName eq $javaClassName ) { + my ($meth) = generateEnum( $classNode, $methodNode, 0 ); + $methodCode .= $meth; + } + }, undef ); + + # Then all static vars + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'var' and $currentClassName eq $javaClassName ) { + my ($meth, $interface) = generateVar( $classNode, $methodNode, $addImport ); + $methodCode .= $meth; +# $interfaceCode .= $interface; + } + }, undef ); + + # Then all methods + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'method' ) { + my ($meth, $interf, $signals, $jbridge) = generateMethod( $classNode, $methodNode, $addImport, $addInclude, $ancestorCount, $javaMethods, $jniMethods, $mainClassNode, $generateConstructors ); + $methodCode .= $meth; + $interfaceCode .= $interf; + $signalCode .= $signals; + $jbridgeCode .= $jbridge; +# $jniCode .= $jni; + } + }, undef ); + + # Virtual methods +# if ($classNode->{BindingDerives}) { +# my %virtualMethods; +# allVirtualMethods( $classNode, \%virtualMethods ); + +# for my $sig (sort keys %virtualMethods) { +# my ($meth) = generateVirtualMethod( $classNode, $sig, $virtualMethods{$sig}{method}, $virtualMethods{$sig}{class}, \%addImport ); +# $methodCode .= $meth; +# } +# } + + # Destructor + # "virtual" is useless, if the base class has a virtual destructor then the x_* class too. + #if($classNode->{HasVirtualDestructor} and $classNode->{HasDestructor}) { + # $methodCode .= " virtual ~$bridgeClassName() {}\n"; + #} + # We generate a dtor though, because we might want to add stuff into it + + if ($currentClassName eq $javaClassName and $classNode->{CanBeInstanciated} and $classNode->{HasPublicDestructor}) { + if ( $generateConstructors ) { + my $jniCode; + my $jniSignature; + + $jbridgeCode .= "\t~$className" . "JBridge() {QtSupport::qtKeyDeleted(this);}\n"; + $methodCode .= "\t/** Deletes the wrapped C++ instance */\n"; + $methodCode .= "\tprotected native void finalize() throws InternalError;\n"; + + $jniSignature = $jniClassName . "_finalize"; + $jniCode = "JNIEXPORT void JNICALL\n$jniSignature(JNIEnv* env, jobject obj)\n{"; + + if ( is_kindof($classNode, 'TQCheckListItem') ) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((TQCheckListItem*)($className*)QtSupport::getQt(env, obj))->parent() == 0 && ((TQCheckListItem*)($className*)QtSupport::getQt(env, obj))->listView() == 0) {\n"; + } elsif ( $classNode->{astNodeName} =~ /^KFileTreeViewToolTip$/ ) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && (($className*)QtSupport::getQt(env, obj))->parentWidget() == 0) {\n"; + } elsif ( is_kindof($classNode, 'TQTableItem')) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((TQTableItem*)($className*)QtSupport::getQt(env, obj))->table() == 0) {\n"; + } elsif ( is_kindof($classNode, 'TQPopupMenu')) { + if ($main::qt_embedded) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((TQPopupMenu*)($className*)QtSupport::getQt(env, obj))->parentWidget() == 0) {\n"; + } else { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((TQPopupMenu*)($className*)QtSupport::getQt(env, obj))->parentWidget(FALSE) == 0) {\n"; + } + } elsif ( is_kindof($classNode, 'TQListViewItem') ) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((TQListViewItem*)($className*)QtSupport::getQt(env, obj))->parent() == 0 && ((TQListViewItem*)($className*)QtSupport::getQt(env, obj))->listView() == 0) {\n"; + } elsif ( is_kindof($classNode, 'TQIconViewItem')) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((TQIconViewItem*)($className*)QtSupport::getQt(env, obj))->iconView() == 0) {\n"; + } elsif ( is_kindof($classNode, 'TQLayoutItem')) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((TQLayoutItem*)($className*)QtSupport::getQt(env, obj))->layout() == 0 && ((TQLayoutItem*)($className*)QtSupport::getQt(env, obj))->widget() == 0 && ((TQLayoutItem*)($className*)QtSupport::getQt(env, obj))->spacerItem() == 0) {\n"; + } elsif ( $classNode->{astNodeName} =~ /^KSpell$|^KReplace$/ ) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj)) {\n"; + } elsif ( $classNode->{astNodeName} =~ /^TQWidget$/ || defined kdocAstUtil::findOverride( $rootnode, $classNode, "parentWidget" ) ) { + if ($main::qt_embedded) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((TQWidget*)($className*)QtSupport::getQt(env, obj))->parentWidget() == 0) {\n"; + } else { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((TQWidget*)($className*)QtSupport::getQt(env, obj))->parentWidget(TRUE) == 0) {\n"; + } + } elsif ( $classNode->{astNodeName} =~ /^TQObject$/ || defined kdocAstUtil::findOverride( $rootnode, $classNode, "parent" ) ) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && (($className*)QtSupport::getQt(env, obj))->parent() == 0) {\n"; + } else { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj)) {\n"; + } + + if ($classNode->{astNodeName} !~ /^Q.*Style$/) { + $jniCode .= "\t\tdelete ($className*)QtSupport::getQt(env, obj);\n"; + } + + $jniCode .= "\t\tQtSupport::setQt(env, obj, 0);\n\t}\n\treturn;\n}\n\n"; + $jniMethods->{$jniSignature} = $jniCode; + +# $interfaceCode .= "\t\tvoid dispose();\n"; + $methodCode .= "\t/** Delete the wrapped C++ instance ahead of finalize() */\n"; + $methodCode .= "\tpublic native void dispose();\n"; + +# $interfaceCode .= "\t\tboolean isDisposed();\n"; + $methodCode .= "\t/** Has the wrapped C++ instance been deleted? */\n"; + $methodCode .= "\tpublic native boolean isDisposed();\n"; + + + $jniSignature = $jniClassName . "_dispose"; + $jniCode = "JNIEXPORT void JNICALL\n$jniSignature(JNIEnv* env, jobject obj)\n{"; + $jniCode .= "\n\t$jniClassName" . "_finalize(env, obj);\n\treturn;\n}\n\n"; + $jniMethods->{$jniSignature} = $jniCode; + + $jniSignature = $jniClassName . "_isDisposed"; + $jniCode = "JNIEXPORT jboolean JNICALL\n$jniSignature(JNIEnv* env, jobject obj)\n{"; + $jniCode .= "\n\treturn (QtSupport::getQt(env, obj) == 0);\n}\n\n"; + $jniMethods->{$jniSignature} = $jniCode; + } +# die "$className destructor: methodNumber=$methodNumber != case entry=".$classNode->{case}{"~$className()"}."\n" +# if $methodNumber != $classNode->{case}{"~$className()"}; + $methodNumber++; + } + + return ( $methodCode, $interfaceCode, $signalCode, $jbridgeCode ); +} + +sub virtualMethodCallbacks +{ + my( $node ) = @_; + my $jbridgeCode = ''; # output + my %allmem = (); + my $key; + + my $m; + my $name; + my $isTQObject = is_kindof($node, 'TQObject'); + + kdocAstUtil::allMembers( \%allmem, $node ); + + foreach $key (keys (%allmem)) { + $m = $allmem{$key}; + $name = $m->{astNodeName} ; + my $type = $m->{NodeType}; + my $docnode = $m->{DocNode}; + my $parent = $m->{Parent}; + + if ( $type eq "method" && ($m->{Flags} =~ "v" || $name =~ /^.*Event$/) && !$m->{SkipFromSwitch} + && $m->{Access} =~ /public|protected/ + && $name !~ /qwsEvent/ && $name !~ /x11Event/ && $name !~ /winEvent/ + && $name !~ /macEvent/ && $name !~ /movableDropEvent/ ) + { + my @argTypeList = (); + my @castedArgList; + my $i = 0; + my $cplusplusparams; + foreach my $arg ( @{$m->{ParamList}} ) { + my $argType = $arg->{ArgType}; + push @argTypeList, $argType; + $cplusplusparams .= "," if $i++; + $cplusplusparams .= "arg" . $i; + } + + my $qobjectType = $node->{astNodeName}; + $qobjectType =~ s/(.*)\*.*$/$1/; + $qobjectType =~ s/^([^Q].*)/org.kde.koala.$1/; + $qobjectType =~ s/^(Q.*)/org.kde.qt.$1/; + if( $m->{ReturnType} eq 'void' && $#argTypeList eq 0 + && cplusplusToJNISignature( @argTypeList[0] ) =~ /Lorg_kde/ + && $isTQObject ) + { + @castedArgList = makeCastedArgList( @argTypeList ); + my $eventType = cplusplusToJava( @argTypeList[0] ); + $eventType =~ s/(.*)\*.*$/$1/; + $eventType =~ s/^([^Q].*)/org.kde.koala.$1/; + $eventType =~ s/^(Q.*)/org.kde.qt.$1/; + $jbridgeCode .= "\tvoid $name(@castedArgList[0..$#argTypeList]) {\n"; + $jbridgeCode .= "\t\tif (!QtSupport::eventDelegate(this,\"$name\",(void*)" . (@argTypeList[0] =~ /\*/ ? "" : "&") . "arg1,\"$eventType\")) {\n"; + $jbridgeCode .= "\t\t\t" . $parent->{astNodeName} . "::" . "$name(arg1);\n"; + $jbridgeCode .= "\t\t}\n"; + $jbridgeCode .= "\t\treturn;\n\t}\n"; + } elsif( $name =~ /eventFilter$/ and $isTQObject and $#argTypeList eq 1) { + $jbridgeCode .= "\tbool eventFilter(TQObject* object,TQEvent* event) {\n"; + $jbridgeCode .= "\t\tif (!QtSupport::eventFilterDelegate(this,\"$qobjectType\",object,event)) {\n"; + $jbridgeCode .= "\t\t\treturn " . $parent->{astNodeName} . "::eventFilter(object,event);\n"; + $jbridgeCode .= "\t\t} else {\n"; + $jbridgeCode .= "\t\t\treturn TRUE;\n"; + $jbridgeCode .= "\t\t}\n\t}\n"; + } elsif( $name =~ /^fixup$/ and $node->{astNodeName} eq 'TQValidator' ) { + $jbridgeCode .= "\tTQValidator::State validate(TQString& input,int& pos) const\n"; + $jbridgeCode .= "\t{\n"; + $jbridgeCode .= "\t\treturn (TQValidator::State) QtSupport::validateDelegate((TQValidator*)this,input,pos);\n"; + $jbridgeCode .= "\t}\n"; + $jbridgeCode .= "\tvoid fixup(TQString& input) const\n"; + $jbridgeCode .= "\t{\n"; + $jbridgeCode .= "\t\tQtSupport::fixupDelegate((TQValidator*) this, input);\n"; + $jbridgeCode .= "\t\treturn;\n\t}\n"; + } elsif( $m->{ReturnType} eq 'void' and $#argTypeList eq -1 and $isTQObject) { + $jbridgeCode .= "\tvoid $name() {\n"; + $jbridgeCode .= "\t\tif (!QtSupport::voidDelegate(this,\"$qobjectType\",\"$name\")) {\n"; + $jbridgeCode .= "\t\t\t" . $parent->{astNodeName} . "::$name();\n"; + $jbridgeCode .= "\t\t}\n"; + $jbridgeCode .= "\t\treturn;\n\t}\n"; + } elsif( cplusplusToJava( $m->{ReturnType} ) eq 'boolean' and $#argTypeList eq -1 and $isTQObject ) { + $jbridgeCode .= "\t" . $m->{ReturnType} . " $name() {\n"; + $jbridgeCode .= "\t\treturn QtSupport::booleanDelegate(this,\"$name\");\n"; + $jbridgeCode .= "\t}\n"; + } + } + } + + return $jbridgeCode; +} + +# Return 0 if the class has no virtual dtor, 1 if it has, 2 if it's private +sub hasVirtualDestructor($) +{ + my ( $classNode ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if ( $skippedClasses{$className} ); + + my $parentHasIt; + # Look at ancestors, and (recursively) call hasVirtualDestructor for each + # It's enough to have one parent with a prot/public virtual dtor + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + my $vd = hasVirtualDestructor( $_[0] ); + $parentHasIt = $vd unless $parentHasIt > $vd; + } ); + return $parentHasIt if $parentHasIt; # 1 or 2 + + # Now look in $classNode - including private methods + my $doPrivate = $main::doPrivate; + $main::doPrivate = 1; + my $result; + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + return unless( $m->{NodeType} eq "method" && $m->{ReturnType} eq '~' ); + + if ( $m->{Flags} =~ /[vp]/ ) { + if ( $m->{Access} =~ /private/ ) { + $result=2; # private virtual + } else { + $result=1; # [protected or public] virtual + } + } + }, + undef + ); + $main::doPrivate = $doPrivate; + $result=0 if (!defined $result); + return $result; +} + +=head2 allVirtualMethods + + Parameters: class node, dict + + Adds to the dict, for all method nodes that are virtual, in this class and in parent classes : + {method} the method node, {class} the class node (the one where the virtual is implemented) + +=cut + +sub allVirtualMethods($$) +{ + my ( $classNode, $virtualMethods ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if ( $skippedClasses{$className} ); + + # Look at ancestors, and (recursively) call allVirtualMethods for each + # This is done first, so that virtual methods that are reimplemented as 'private' + # can be removed from the list afterwards (below) + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + allVirtualMethods( @_[0], $virtualMethods ); + }, undef + ); + + # Now look for virtual methods in $classNode - including private ones + my $doPrivate = $main::doPrivate; + $main::doPrivate = 1; + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + # Only interested in methods, and skip destructors + return unless( $m->{NodeType} eq "method" && $m->{ReturnType} ne '~' ); + + my $signature = methodSignature( $m, $#{$m->{ParamList}} ); + print STDERR $signature . " ($m->{Access})\n" if ($debug); + + # A method is virtual if marked as such (v=virtual p=pure virtual) + # or if a parent method with same signature was virtual + if ( $m->{Flags} =~ /[vp]/ or defined $virtualMethods->{$signature} ) { + if ( $m->{Access} =~ /private/ ) { + if ( defined $virtualMethods->{$signature} ) { # remove previously defined + delete $virtualMethods->{$signature}; + } + # else, nothing, just ignore private virtual method + } else { + $virtualMethods->{$signature}{method} = $m; + $virtualMethods->{$signature}{class} = $classNode; + } + } + }, + undef + ); + $main::doPrivate = $doPrivate; +} + +# Known typedef? If so, apply it. +sub applyTypeDef($) +{ + my $type = shift; + # Parse 'const' in front of it, and '*' or '&' after it + my $prefix = $type =~ s/^const\s+// ? 'const ' : ''; + my $suffix = $type =~ s/\s*([\&\*]+)$// ? $1 : ''; + + if (exists $typedeflist{$type}) { + return $prefix.$typedeflist{$type}.$suffix; + } + return $prefix.$type.$suffix; +} + +# Register type ($1) into %allTypes if not already there +sub registerType($$) { + my $type = shift; + #print "registerType: $type\n" if ($debug); + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + return if ( $type eq 'void' or $type eq '' or $type eq '~' ); + die if ( $type eq '...' ); # ouch + + # Let's register the real type, not its known equivalent + #$type = applyTypeDef($type); + + # Enum _value_ -> get corresponding type + if (exists $enumValueToType{$type}) { + $type = $enumValueToType{$type}; + } + + # Already in allTypes + if(exists $allTypes{$type}) { + return; + } + + die if $type eq 'TQTextEdit::UndoRedoInfo::Type'; + die if $type eq ''; + + my $realType = $type; + + # Look for references (&) and pointers (* or **) - this will not handle *& correctly. + # We do this parsing here because both the type list and iterproto need it + if($realType =~ s/&$//) { + $allTypes{$type}{typeFlags} = 'Smoke::tf_ref'; + } + elsif($realType ne 'void*' && $realType =~ s/\*$//) { + $allTypes{$type}{typeFlags} = 'Smoke::tf_ptr'; + } + else { + $allTypes{$type}{typeFlags} = 'Smoke::tf_stack'; + } + + if ( $realType =~ s/^const\s+// ) { # Remove 'const' + $allTypes{$type}{typeFlags} .= ' | Smoke::tf_const'; + } + + # Apply typedefs, and store the resulting type. + # For instance, if $type was Q_UINT16&, realType will be ushort + $allTypes{$type}{realType} = applyTypeDef( $realType ); + + # In the first phase we only create entries into allTypes. + # The values (indexes) are calculated afterwards, once the list is full. + $allTypes{$type}{index} = -1; + #print STDERR "Register $type. Realtype: $realType\n" if($debug); +} + +# Get type from %allTypes +# This returns a hash with {index}, {isEnum}, {typeFlags}, {realType} +# (and {typeId} after the types array is written by writeSmokeDataFile) +sub findTypeEntry($) { + my $type = shift; + my $typeIndex = -1; + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + return undef if ( $type =~ '~' or $type eq 'void' or $type eq '' ); + + # Enum _value_ -> get corresponding type + if (exists $enumValueToType{$type}) { + $type = $enumValueToType{$type}; + } + + die "type not known: $type" unless defined $allTypes{$type}; + return $allTypes{ $type }; +} + +# List of all java super-classes for a given class, via single inheritance. +# Excluding any which are mapped onto interfaces to avoid multiple inheritance. +sub direct_superclass_list($) +{ + my $classNode = shift; + my @super; + my $has_ancestor = 0; + my $direct_ancestor = undef; + my $name; + + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + ( $direct_ancestor, $name ) = @_; + if ($name =~ /TQMemArray|TQSqlFieldInfoList/) { + # Template classes, give up for now.. + $has_ancestor = 1; + } elsif (kalyptusDataDict::interfacemap($name) eq "") { + push @super, $direct_ancestor; + push @super, direct_superclass_list( $direct_ancestor ); + $has_ancestor = 1; + } + }, undef ); + + if (! $has_ancestor and defined $direct_ancestor) { + push @super, $direct_ancestor; + push @super, direct_superclass_list( $direct_ancestor ); + } + + return @super; +} + +# List of all super-classes for a given class +sub superclass_list($) +{ + my $classNode = shift; + my @super; + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + push @super, @_[0]; + push @super, superclass_list( @_[0] ); + }, undef ); + return @super; +} + +sub is_kindof($$) +{ + my $classNode = shift; + my $className = shift; + + if ($classNode->{astNodeName} eq $className) { + return 1; + } + + my @superclasses = superclass_list($classNode); + foreach my $ancestor (@superclasses) { + if ($ancestor->{astNodeName} eq $className) { + return 1; + } + } + + return 0; +} + +# Store the {case} dict in the class Node (method signature -> index in the "case" switch) +# This also determines which methods should NOT be in the switch, and sets {SkipFromSwitch} for them +sub prepareCaseDict($) { + + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + $classNode->AddProp("case", {}); + my $methodNumber = 0; + + # First look at all enums for this class + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'enum'; + foreach my $val ( @{$m->{ParamList}} ) { + my $fullEnumName = "$className\::".$val->{ArgName}; + print STDERR "Enum: $fullEnumName -> case $methodNumber\n" if ($debug); + $classNode->{case}{$fullEnumName} = $methodNumber; + $enumValueToType{$fullEnumName} = "$className\::$m->{astNodeName}"; + $methodNumber++; + } + }, undef ); + + # Check for static vars + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'var'; + my $name = "$className\::".$m->{astNodeName}; + print STDERR "Var: $name -> case $methodNumber\n" if ($debug); + $classNode->{case}{$name} = $methodNumber; + $methodNumber++; + + }, undef ); + + + # Now look at all methods for this class + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'method'; + my $name = $m->{astNodeName}; + my $isConstructor = ($name eq $classNode->{astNodeName} ); + if ($isConstructor and ($m->{ReturnType} eq '~')) # destructor + { + # Remember whether we'll generate a switch entry for the destructor + $m->{SkipFromSwitch} = 1 unless ($classNode->{CanBeInstanciated} and $classNode->{HasPublicDestructor}); + next; + } + + # Don't generate bindings for protected methods (incl. signals) if + # we're not deriving from the C++ class. Only take public and public_slots + my $ok = ( $classNode->{BindingDerives} or $m->{Access} =~ /public/ ) ? 1 : 0; + + # Don't generate bindings for pure virtuals - we can't call them ;) + $ok = 0 if ( $ok && $m->{Flags} =~ "p" ); + + # Bugfix for Qt-3.0.4: those methods are NOT implemented (report sent). + $ok = 0 if ( $ok && $className eq 'TQLineEdit' && ( $name eq 'setPasswordChar' || $name eq 'passwordChar' ) ); + $ok = 0 if ( $ok && $className eq 'TQWidgetItem' && $name eq 'widgetSizeHint' ); + + if ( !$ok ) + { + #print STDERR "Skipping $className\::$name\n" if ($debug); + $m->{SkipFromSwitch} = 1; + next; + } + + my @args = @{ $m->{ParamList} }; + my $last = $m->{FirstDefaultParam}; + $last = scalar @args unless defined $last; + my $iterationCount = scalar(@args) - $last; + while($iterationCount >= 0) { + my $sig = methodSignature( $m, $#args ); + $classNode->{case}{$sig} = $methodNumber; + #print STDERR "prepareCaseDict: registered case number $methodNumber for $sig in $className()\n" if ($debug); + pop @args; + $iterationCount--; + $methodNumber++; + } + }, undef ); + + # Add the destructor, at the end + if ($classNode->{CanBeInstanciated} and $classNode->{HasPublicDestructor}) { + $classNode->{case}{"~$className()"} = $methodNumber; + # workaround for ~Sub::Class() being seen as Sub::~Class() + $classNode->{case}{"~$classNode->{astNodeName}()"} = $methodNumber; + #print STDERR "prepareCaseDict: registered case number $methodNumber for ~$className()\n" if ($debug); + } +} + +sub writeSmokeDataFile($) { + my $rootnode = shift; + + # Make list of classes + my %allImports; # list of all header files for all classes + my @classlist; + push @classlist, ""; # Prepend empty item for "no class" + my %enumclasslist; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = $_[0]; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + push @classlist, $className; + $enumclasslist{$className}++ if keys %{$classNode->{enumerations}}; + $classNode->{ClassIndex} = $#classlist; + addImportForClass( $classNode, \%allImports, undef ); + } ); + + my %classidx = do { my $i = 0; map { $_ => $i++ } @classlist }; + + my $file = "$outputdir/smokedata.cpp"; +# open OUT, ">$file" or die "Couldn't create $file\n"; + +# foreach my $incl (sort{ +# return 1 if $a=~/qmotif/; # move qmotif* at bottom (they include dirty X11 headers) +# return -1 if $b=~/qmotif/; +# return -1 if substr($a,0,1) eq 'q' and substr($b,0,1) ne 'q'; # move Qt headers on top +# return 1 if substr($a,0,1) ne 'q' and substr($b,0,1) eq 'q'; +# $a cmp $b +# } keys %allIncludes) { +# die if $imp eq ''; +# print OUT "import $imp;\n"; +# } + +# print OUT "\n"; + + print STDERR "Writing ${libname}_cast function\n" if ($debug); + + # Prepare descendants information for each class + my %descendants; # classname -> list of descendant nodes + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + # Get _all_ superclasses (up any number of levels) + # and store that $classNode is a descendant of $s + my @super = superclass_list($classNode); + for my $s (@super) { + my $superClassName = join( "::", kdocAstUtil::heritage($s) ); + Ast::AddPropList( \%descendants, $superClassName, $classNode ); + } + } ); + + # Iterate over all classes, to write the xtypecast function + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + # @super will contain superclasses, the class itself, and all descendants + my @super = superclass_list($classNode); + push @super, $classNode; + if ( defined $descendants{$className} ) { + push @super, @{$descendants{$className}}; + } + my $cur = $classidx{$className}; + + return if $classNode->{NodeType} eq 'namespace'; + +# print OUT " case $cur:\t//$className\n"; +# print OUT "\tswitch(to) {\n"; +# $cur = -1; +# my %casevalues; +# for my $s (@super) { +# my $superClassName = join( "::", kdocAstUtil::heritage($s) ); +# next if !defined $classidx{$superClassName}; # inherits from unknown class, see below +# next if $classidx{$superClassName} == $cur; # shouldn't happen in Qt +# next if $s->kdocAstUtil::inheritsAsVirtual($classNode); # can't cast from a virtual base class +# $cur = $classidx{$superClassName}; # KDE has MI with diamond shaped cycles (cf. KXMLGUIClient) +# next if $casevalues{$cur}; # ..so skip any duplicate parents +# print OUT "\t case $cur: return (void*)($superClassName*)($className*)xptr;\n"; +# $casevalues{$cur} = 1; +# } +# print OUT "\t default: return xptr;\n"; +# print OUT "\t}\n"; + } ); +# print OUT " default: return xptr;\n"; +# print OUT " }\n"; +# print OUT "}\n\n"; + + + # Write inheritance array + # Imagine you have "Class : public super1, super2" + # The inheritlist array will get 3 new items: super1, super2, 0 + my %inheritfinder; # key = (super1, super2) -> data = (index in @inheritlist). This one allows reuse. + my %classinherit; # we store that index in %classinherit{className} + # We don't actually need to store inheritlist in memory, we write it + # directly to the file. We only need to remember its current size. + my $inheritlistsize = 1; + +# print OUT "// Group of class IDs (0 separated) used as super class lists.\n"; +# print OUT "// Classes with super classes have an index into this array.\n"; +# print OUT "static short ${libname}_inheritanceList[] = {\n"; +# print OUT "\t0,\t// 0: (no super class)\n"; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "__", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + print STDERR "inheritanceList: looking at $className\n" if ($debug); + + # Make list of direct ancestors + my @super; + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + my $superClassName = join( "::", kdocAstUtil::heritage($_[0]) ); + push @super, $superClassName; + }, undef ); + # Turn that into a list of class indexes + my $key = ''; + foreach my $superClass( @super ) { + if (defined $classidx{$superClass}) { + $key .= ', ' if ( length $key > 0 ); + $key .= $classidx{$superClass}; + } + } + if ( $key ne '' ) { + if ( !defined $inheritfinder{$key} ) { + print OUT "\t"; + my $index = $inheritlistsize; # Index of first entry (for this group) in inheritlist + foreach my $superClass( @super ) { + if (defined $classidx{$superClass}) { + print OUT "$classidx{$superClass}, "; + $inheritlistsize++; + } + } + $inheritlistsize++; + my $comment = join( ", ", @super ); + print OUT "0,\t// $index: $comment\n"; + $inheritfinder{$key} = $index; + } + $classinherit{$className} = $inheritfinder{$key}; + } else { # No superclass + $classinherit{$className} = 0; + } + } ); +# print OUT "};\n\n"; + + +# print OUT "// These are the xenum functions for manipulating enum pointers\n"; + for my $className (keys %enumclasslist) { + my $c = $className; + $c =~ s/::/__/g; +# print OUT "void xenum_$c\(Smoke::EnumOperation, Smoke::Index, void*&, long&);\n"; + } +# print OUT "\n"; +# print OUT "// Those are the xcall functions defined in each x_*.cpp file, for dispatching method calls\n"; + my $firstClass = 1; + for my $className (@classlist) { + if ($firstClass) { + $firstClass = 0; + next; + } + my $c = $className; # make a copy + $c =~ s/::/__/g; +# print OUT "void xcall_$c\(Smoke::Index, void*, Smoke::Stack);\n"; + } +# print OUT "\n"; + + # Write class list afterwards because it needs offsets to the inheritance array. +# print OUT "// List of all classes\n"; +# print OUT "// Name, index into inheritanceList, method dispatcher, enum dispatcher, class flags\n"; +# print OUT "static Smoke::Class ${libname}_classes[] = {\n"; + my $firstClass = 1; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "__", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + if ($firstClass) { + $firstClass = 0; + print OUT "\t{ 0L, 0, 0, 0, 0 }, \t// 0 (no class)\n"; + } + my $c = $className; + $c =~ s/::/__/g; + my $xcallFunc = "xcall_$c"; + my $xenumFunc = "0"; + $xenumFunc = "xenum_$c" if exists $enumclasslist{$className}; + # %classinherit needs Foo__Bar, not Foo::Bar? + die "problem with $className" unless defined $classinherit{$c}; + + my $xClassFlags = 0; + $xClassFlags .= "|Smoke::cf_constructor" if $classNode->{CanBeInstanciated}; # correct? + $xClassFlags .= "|Smoke::cf_deepcopy" if $classNode->{CanBeCopied}; # HasCopyConstructor would be wrong (when it's private) + $xClassFlags .= "|Smoke::cf_virtual" if hasVirtualDestructor($classNode) == 1; + # $xClassFlags .= "|Smoke::cf_undefined" if ...; + $xClassFlags =~ s/0\|//; # beautify +# print OUT "\t{ \"$className\", $classinherit{$c}, $xcallFunc, $xenumFunc, $xClassFlags }, \t//$classidx{$className}\n"; + } ); +# print OUT "};\n\n"; + + +# print OUT "// List of all types needed by the methods (arguments and return values)\n"; +# print OUT "// Name, class ID if arg is a class, and TypeId\n"; +# print OUT "static Smoke::Type ${libname}_types[] = {\n"; + my $typeCount = 0; + $allTypes{''}{index} = 0; # We need an "item 0" + for my $type (sort keys %allTypes) { + $allTypes{$type}{index} = $typeCount; # Register proper index in allTypes + if ( $typeCount == 0 ) { +# print OUT "\t{ 0, 0, 0 },\t//0 (no type)\n"; + $typeCount++; + next; + } + my $isEnum = $allTypes{$type}{isEnum}; + my $typeId; + my $typeFlags = $allTypes{$type}{typeFlags}; + my $realType = $allTypes{$type}{realType}; + die "$type" if !defined $typeFlags; +# die "$realType" if $realType =~ /\(/; + # First write the name +# print OUT "\t{ \"$type\", "; + # Then write the classId (and find out the typeid at the same time) + if(exists $classidx{$realType}) { # this one first, we want t_class for TQBlah* + $typeId = 't_class'; +# print OUT "$classidx{$realType}, "; + } + elsif($type =~ /&$/ || $type =~ /\*$/) { + $typeId = 't_voidp'; +# print OUT "0, "; # no classId + } + elsif($isEnum || $allTypes{$realType}{isEnum}) { + $typeId = 't_enum'; + if($realType =~ /(.*)::/) { + my $c = $1; + if($classidx{$c}) { +# print OUT "$classidx{$c}, "; + } else { +# print OUT "0 /* unknown class $c */, "; + } + } else { +# print OUT "0 /* unknown $realType */, "; # no classId + } + } + else { + $typeId = $typeunion{$realType}; + if (defined $typeId) { + $typeId =~ s/s_/t_/; # from s_short to t_short for instance + } + else { + # Not a known class - ouch, this happens quite a lot + # (private classes, typedefs, template-based types, etc) + if ( $skippedClasses{$realType} ) { +# print STDERR "$realType has been skipped, using t_voidp for it\n"; + } else { + unless( $realType =~ / map to a void * + } +# print OUT "0, "; # no classId + } + # Then write the flags + die "$type" if !defined $typeId; +# print OUT "Smoke::$typeId | $typeFlags },"; +# print OUT "\t//$typeCount\n"; + $typeCount++; + # Remember it for coerce_type + $allTypes{$type}{typeId} = $typeId; + } +# print OUT "};\n\n"; + + + my %arglist; # registers the needs for argumentList (groups of type ids) + my %methods; + # Look for all methods and all enums, in all classes + # And fill in methods and arglist. This loop writes nothing to OUT. + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + print STDERR "writeSmokeDataFile: arglist: looking at $className\n" if ($debug); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + my $methName = $m->{astNodeName}; + # For destructors, get a proper signature that includes the '~' + if ( $m->{ReturnType} eq '~' ) + { + $methName = '~' . $methName ; + # Let's even store that change, otherwise we have to do it many times + $m->{astNodeName} = $methName; + } + + if( $m->{NodeType} eq "enum" ) { + + foreach my $enum ( @{$m->{ParamList}} ) { + my $enumName = $enum->{ArgName}; + $methods{$enumName}++; + } + + } elsif ( $m->{NodeType} eq 'var' ) { + + $methods{$m->{astNodeName}}++; + + } elsif( $m->{NodeType} eq "method" ) { + + $methods{$methName}++; + my @protos; + makeprotos(\%classidx, $m, \@protos); + + #print "made @protos from $className $methName $m->{Signature})\n" if ($debug); + for my $p (@protos) { + $methods{$p}++; + my $argcnt = 0; + $argcnt = length($1) if $p =~ /([\$\#\?]+)/; + my $sig = methodSignature($m, $argcnt-1); + # Store in a class hash named "proto", a proto+signature => method association + $classNode->{proto}{$p}{$sig} = $m; + #$classNode->{signature}{$sig} = $p; + # There's probably a way to do this better, but this is the fastest way + # to get the old code going: store classname into method + $m->{class} = $className; + } + + my $firstDefaultParam = $m->{FirstDefaultParam}; + $firstDefaultParam = scalar(@{ $m->{ParamList} }) unless defined $firstDefaultParam; + my $argNames = ''; + my $args = ''; + for(my $i = 0; $i < @{ $m->{ParamList} }; $i++) { + $args .= ', ' if $i; + $argNames .= ', ' if $i; + my $argType = $m->{ParamList}[$i]{ArgType}; + my $typeEntry = findTypeEntry( $argType ); + $args .= defined $typeEntry ? $typeEntry->{index} : 0; + $argNames .= $argType; + + if($i >= ($firstDefaultParam - 1)) { + #print "arglist entry: $args\n"; + $arglist{$args} = $argNames; + } + + } + # create an entry for e.g. "arg0,arg1,arg2" where argN is index in allTypes of type for argN + # The value, $argNames, is temporarily stored, to be written out as comment + # It gets replaced with the index in the next loop. + #print "arglist entry : $args\n"; + $arglist{$args} = $argNames; + } + }, # end of sub + undef + ); + }); + + + $arglist{''} = 0; + # Print arguments array +# print OUT "static Smoke::Index ${libname}_argumentList[] = {\n"; + my $argListCount = 0; + for my $args (sort keys %arglist) { + my @dunnohowtoavoidthat = split(',',$args); + my $numTypes = $#dunnohowtoavoidthat; + if ($args eq '') { +# print OUT "\t0,\t//0 (void)\n"; + } else { + # This is a nice trick : args can be written in one go ;) +# print OUT "\t$args, 0,\t//$argListCount $arglist{$args} \n"; + } + $arglist{$args} = $argListCount; # Register proper index in argList + $argListCount += $numTypes + 2; # Move forward by as much as we wrote out + } +# print OUT "};\n\n"; + + $methods{''} = 0; + my @methodlist = sort keys %methods; + my %methodidx = do { my $i = 0; map { $_ => $i++ } @methodlist }; + +# print OUT "// Raw list of all methods, using munged names\n"; +# print OUT "static const char *${libname}_methodNames[] = {\n"; + my $methodNameCount = $#methodlist; + for my $m (@methodlist) { +# print OUT qq( "$m",\t//$methodidx{$m}\n); + } +# print OUT "};\n\n"; + +# print OUT "// (classId, name (index in methodNames), argumentList index, number of args, method flags, return type (index in types), xcall() index)\n"; +# print OUT "static Smoke::Method ${libname}_methods[] = {\n"; + my @methods; + %allMethods = (); + my $methodCount = 0; + # Look at all classes and all enums again + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if $classNode->{NodeType} eq 'namespace'; + + my $classIndex = $classidx{$className}; + print STDERR "writeSmokeDataFile: methods: looking at $className\n" if ($debug); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + if( $m->{NodeType} eq "enum" ) { + + foreach my $enum ( @{$m->{ParamList}} ) { + my $enumName = $enum->{ArgName}; + my $fullEnumName = "$className\::$enumName"; + my $sig = "$className\::$enumName\()"; + my $xmethIndex = $methodidx{$enumName}; + die "'Method index' for enum $sig not found" unless defined $xmethIndex; + my $typeId = findTypeEntry( $fullEnumName )->{index}; + die "enum has no {case} value in $className: $fullEnumName" unless defined $classNode->{case}{$fullEnumName}; +# print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullEnumName}},\t//$methodCount $fullEnumName (enum)\n"; + $allMethods{$sig} = $methodCount; + print STDERR "Added entry for " . $sig . " into \$allMethods\n" if ($debug); + $methods[$methodCount] = { + c => $classIndex, + methIndex => $xmethIndex, + argcnt => '0', + args => 0, + retTypeIndex => 0, + idx => $classNode->{case}{$fullEnumName} + }; + $methodCount++; + } + + } elsif( $m->{NodeType} eq 'var' ) { + + my $name = $m->{astNodeName}; + my $fullName = "$className\::$name"; + my $sig = "$fullName\()"; + my $xmethIndex = $methodidx{$name}; + die "'Method index' for var $sig not found" unless defined $xmethIndex; + my $varType = $m->{Type}; + $varType =~ s/static\s//; + $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/\s*$//; + my $typeId = findTypeEntry( $varType )->{index}; + die "var has no {case} value in $className: $fullName" unless defined $classNode->{case}{$fullName}; +# print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullName}},\t//$methodCount $fullName (static var)\n"; + $allMethods{$sig} = $methodCount; + print STDERR "Added entry for " . $sig . " into \$allMethods\n" if ($debug); + $methods[$methodCount] = { + c => $classIndex, + methIndex => $xmethIndex, + argcnt => '0', + args => 0, + retTypeIndex => 0, + idx => $classNode->{case}{$fullName} + }; + $methodCount++; + + + } elsif( $m->{NodeType} eq "method" ) { + + # We generate a method entry only if the method is in the switch() code + # BUT: for pure virtuals, they need to have a method entry, even though they + # do NOT have a switch code. + return if ( $m->{SkipFromSwitch} && $m->{Flags} !~ "p" ); + + # No switch code for destructors if we didn't derive from the class (e.g. it has private ctors only) + return if ( $m->{ReturnType} eq '~' && ! ( $classNode->{BindingDerives} and $classNode->{HasPublicDestructor}) ); + + # Is this sorting really important? + #for my $m (sort {$a->{name} cmp $b->{name}} @{ $self->{$c}{method} }) { + + my $methName = $m->{astNodeName}; + my $def = $m->{FirstDefaultParam}; + $def = scalar(@{ $m->{ParamList} }) unless defined $def; + my $last = scalar(@{ $m->{ParamList} }) - 1; + #print STDERR "writeSmokeDataFile: methods: generating for method $methName, def=$def last=$last\n" if ($debug); + + while($last >= ($def-1)) { + last if $last < -1; + my $args = [ @{ $m->{ParamList} }[0..$last] ]; + my $sig = methodSignature($m, $last); + #my $methodSig = $classNode->{signature}{$sig}; # Munged signature + #print STDERR "writeSmokeDataFile: methods: sig=$className\::$sig methodSig=$methodSig\n" if ($debug); + #my $methodIndex = $methodidx{$methodSig}; + #die "$methodSig" if !defined $methodIndex; + + my $methodIndex = $methodidx{$methName}; + die "$methName" if !defined $methodIndex; + my $case = $classNode->{case}{$sig}; + my $typeEntry = findTypeEntry( $m->{ReturnType} ); + my $retTypeIndex = defined $typeEntry ? $typeEntry->{index} : 0; + + my $i = 0; + my $t = ''; + for my $arg (@$args) { + $t .= ', ' if $i++; + my $typeEntry = findTypeEntry( $arg->{ArgType} ); + $t .= defined $typeEntry ? $typeEntry->{index} : 0; + } + my $arglist = $t eq '' ? 0 : $arglist{$t}; + die "arglist for $t not found" unless defined $arglist; + if ( $m->{Flags} =~ "p" ) { + # Pure virtuals don't have a {case} number, that's normal + die if defined $case; + $case = -1; # This remains -1, not 0 ! + } else { + ; +# die "$className\::$methName has no case number for sig=$sig" unless defined $case; + } + my $argcnt = $last + 1; + my $methodFlags = '0'; + $methodFlags .= "|Smoke::mf_static" if $m->{Flags} =~ "s"; + $methodFlags .= "|Smoke::mf_const" if $m->{Flags} =~ "c"; # useful?? probably not + $methodFlags =~ s/0\|//; # beautify + +# print OUT "\t{$classIndex, $methodIndex, $arglist, $argcnt, $methodFlags, $retTypeIndex, $case},\t//$methodCount $className\::$sig"; +# print OUT " [pure virtual]" if ( $m->{Flags} =~ "p" ); # explain why $case = -1 ;) +# print OUT "\n"; + + $allMethods{$className . "::" . $sig} = $methodCount; + $methods[$methodCount] = { + c => $classIndex, + methIndex => $methodIndex, + argcnt => $argcnt, + args => $arglist, + retTypeIndex => $retTypeIndex, + idx => $case + }; + $methodCount++; + $last--; + } # while + } # if method + } ); # Method Iter + } ); # Class Iter +# print OUT "};\n\n"; + + my @protos; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + my $classIndex = $classidx{$className}; + print STDERR "writeSmokeDataFile: protos: looking at $className\n" if ($debug); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + if( $m->{NodeType} eq "enum" ) { + foreach my $enum ( @{$m->{ParamList}} ) { + my $enumName = $enum->{ArgName}; + my $sig = "$className\::$enumName\()"; + my $xmeth = $allMethods{$sig}; + die "'Method' for enum $sig not found" unless defined $xmeth; + my $xmethIndex = $methodidx{$enumName}; + die "'Method index' for enum $enumName not found" unless defined $xmethIndex; + push @protos, { + methIndex => $xmethIndex, + c => $classIndex, + over => { + $sig => { + sig => $sig, + } + }, + meth => $xmeth + }; + } + + } elsif( $m->{NodeType} eq 'var' ) { + + my $name = $m->{astNodeName}; + my $fullName = "$className\::$name"; + my $sig = "$fullName\()"; + my $xmeth = $allMethods{$sig}; + die "'Method' for var $sig not found" unless defined $xmeth; + my $xmethIndex = $methodidx{$name}; + die "'Method index' for var $name not found" unless defined $xmethIndex; + push @protos, { + methIndex => $xmethIndex, + c => $classIndex, + over => { + $sig => { + sig => $sig, + } + }, + meth => $xmeth + }; + + } + }); + + for my $p (keys %{ $classNode->{proto} }) { + # For each prototype + my $scratch = { %{ $classNode->{proto}{$p} } }; # sig->method association + # first, grab all the superclass voodoo + for my $supNode (superclass_list($classNode)) { + my $i = $supNode->{proto}{$p}; + next unless $i; + for my $k (keys %$i) { + $scratch->{$k} = $i->{$k} unless exists $scratch->{$k}; + } + } + + # Ok, now we have a full list + #if(scalar keys %$scratch > 1) { + #print STDERR "Overload: $p (@{[keys %$scratch]})\n" if ($debug); + #} + my $xmethIndex = $methodidx{$p}; + my $classIndex = $classidx{$className}; + for my $sig (keys %$scratch) { + #my $xsig = $scratch->{$sig}{class} . "::" . $sig; + my $xsig = $className . "::" . $sig; + $scratch->{$sig}{sig} = $xsig; + delete $scratch->{$sig} + if $scratch->{$sig}{Flags} =~ "p" # pure virtual + or not exists $allMethods{$xsig}; + } + push @protos, { + methIndex => $xmethIndex, + c => $classIndex, + over => $scratch + } if scalar keys %$scratch; + } + }); + + my @protolist = sort { $a->{c} <=> $b->{c} || $a->{methIndex} <=> $b->{methIndex} } @protos; +#for my $abc (@protos) { +#print "$abc->{methIndex}.$abc->{c}\n"; +#} + + print STDERR "Writing methodmap table\n" if ($debug); + my @resolve = (); +# print OUT "// Class ID, munged name ID (index into methodNames), method def (see methods) if >0 or number of overloads if <0\n"; + my $methodMapCount = 1; +# print OUT "static Smoke::MethodMap ${libname}_methodMaps[] = {\n"; +# print OUT "\t{ 0, 0, 0 },\t//0 (no method)\n"; + for my $cur (@protolist) { + if(scalar keys %{ $cur->{over} } > 1) { +# print OUT "\t{$cur->{c}, $cur->{methIndex}, -@{[1+scalar @resolve]}},\t//$methodMapCount $classlist[$cur->{c}]\::$methodlist[$cur->{methIndex}]\n"; + $methodMapCount++; + for my $k (keys %{ $cur->{over} }) { + my $p = $cur->{over}{$k}; + my $xsig = $p->{class} ? "$p->{class}\::$k" : $p->{sig}; + push @resolve, { k => $k, p => $p, cur => $cur, id => $allMethods{$xsig} }; + } + push @resolve, 0; + } else { + for my $k (keys %{ $cur->{over} }) { + my $p = $cur->{over}{$k}; + my $xsig = $p->{class} ? "$p->{class}\::$k" : $p->{sig}; +# print OUT "\t{$cur->{c}, $cur->{methIndex}, $allMethods{$xsig}},\t//$methodMapCount $classlist[$cur->{c}]\::$methodlist[$cur->{methIndex}]\n"; + $methodMapCount++; + } + } + } +# print OUT "};\n\n"; + + + print STDERR "Writing ambiguousMethodList\n" if ($debug); +# print OUT "static Smoke::Index ${libname}_ambiguousMethodList[] = {\n"; +# print OUT " 0,\n"; + for my $r (@resolve) { + unless($r) { +# print OUT " 0,\n"; + next; + } + my $xsig = $r->{p}{class} ? "$r->{p}{class}\::$r->{k}" : $r->{p}{sig}; + die "ambiguousMethodList: no method found for $xsig\n" if !defined $allMethods{$xsig}; +# print OUT " $allMethods{$xsig}, // $xsig\n"; + } +# print OUT "};\n\n"; + +# print OUT "extern \"C\" { // needed?\n"; +# print OUT " void init_${libname}_Smoke();\n"; +# print OUT "}\n"; +# print OUT "\n"; +# print OUT "Smoke* qt_Smoke = 0L;\n"; +# print OUT "\n"; +# print OUT "// Create the Smoke instance encapsulating all the above.\n"; +# print OUT "void init_${libname}_Smoke() {\n"; +# print OUT " qt_Smoke = new Smoke(\n"; +# print OUT " ${libname}_classes, ".$#classlist.",\n"; +# print OUT " ${libname}_methods, $methodCount,\n"; +# print OUT " ${libname}_methodMaps, $methodMapCount,\n"; +# print OUT " ${libname}_methodNames, $methodNameCount,\n"; +# print OUT " ${libname}_types, $typeCount,\n"; +# print OUT " ${libname}_inheritanceList,\n"; +# print OUT " ${libname}_argumentList,\n"; +# print OUT " ${libname}_ambiguousMethodList,\n"; +# print OUT " ${libname}_cast );\n"; +# print OUT "}\n"; +# close OUT; + +#print "@{[keys %allMethods ]}\n"; +} +=head2 printJavadocComment + + Parameters: docnode filehandle + + Converts a kdoc comment to javadoc format. + @ref's are converted to @link's; @p's and @em's are converted + to inline HTML. + +=cut + +sub printJavadocComment($$$$) +{ + my( $docnode, $name, $indent, $signalLink ) = @_; + + my $node; + my $returntext = ''; + foreach $node ( @{$docnode->{Text}} ) { + next if $node->{NodeType} ne "DocText" and $node->{NodeType} ne "ListItem" + and $node->{NodeType} ne "Param"; + my $line = ''; + + if ($node->{NodeType} eq "Param") { + if ($node->{Name} !~ /argc/) { + $line = "\@param " . $node->{Name} . " " . $node->{astNodeName}; + } + } else { + $line = $node->{astNodeName}; + } + $line =~ s/argc, ?argv/args/g; + $line =~ s/int argc, ?char ?\* ?argv(\[\])?/String[] args/g; + $line =~ s/int argc, ?char ?\*\* ?argv/String[] args/g; + if ($node->{NodeType} eq "Param") { + $line =~ s/(const )?QC?StringList(\s*&)?/String[]/g; + } else { + $line =~ s/(const )?QC?StringList(\s*&)?/ArrayList/g; + } + $line =~ s/NodeList|KTrader::OfferList/ArrayList/g; + $line =~ s/(const )?TQDate(Time)?(\s*&)?/Calendar/g; + $line =~ s/(const )?TQTime([^r])/Date$1/g; + $line =~ s/TQString::null/null/g; + $line =~ s/(const )?QC?String(\s*&)?/String/g; + $line =~ s/TQByteArray/byte[]/g; + $line =~ s/(const )?KCmdLineOptions\s*(\w+)\[\]/String[][] $2/; + $line =~ s/KCmdLineLastOption//g; + $line =~ s/virtual //g; + $line =~ s/~\w+\(\)((\s*{\s*})|;)//g; + $line =~ s/0L/null/g; + $line =~ s/(\([^\)]*\))\s*:\s*\w+\([^\)]*\)/$1/g; + $line =~ s/\(void\)//g; + $line =~ s/const char/String/g; + $line =~ s/const (\w+)\&/$1/g; + $line =~ s/bool/boolean/g; + $line =~ s/SLOT\(\s*([^\)]*)\) ?\)/SLOT("$1)")/g; + $line =~ s/SIGNAL\(\s*([^\)]*)\) ?\)/SIGNAL("$1)")/g; + $line =~ s/Q_OBJECT\n//g; + $line =~ s/class\s+([\w]+)\s*:\s*public/public class $1 implements/g; + $line =~ s/public\s*(slots)?:\n/public /g; + $line =~ s/([^0-9"]\s*)\*(\s*[^0-9"-])/$1$2/g; + $line =~ s/^(\s*)\*/$1/g; + $line =~ s/\n \*/\n /g; + $line =~ s/\@ref\s+([\w]+)::([\w]+)\s*(\([^\)]*\))(\.)?/{\@link $1#$2}$4/g; + $line =~ s/\@ref\s+#([\w:]+)(\(\))?/{\@link #$1}/g; + $line =~ s/\@ref\s+([\w]+)\s*(\([^\)]*\))/{\@link #$1}/g; + $line =~ s/\@ref\s+([\w]+)::([\w]+)/{\@link $1#$2}/g; + $line =~ s/\@ref\s+([a-z][\w]+)/{\@link #$1}/g; + $line =~ s/\@ref\s+([\w]+)/{\@link $1}/g; + while ($line =~ /\@c\s+([\w#\\\.<>]+)/ ) { + my $code = $1; + $code =~ s!!>!g; + $code =~ s!\\#!#!g; + $line =~ s!\@c\s+([\w#\\\.<>]+)!$code!; + } + $line =~ s!\@em\s+(\w+)!$1!g; + $line =~ s!\@p\s+([\w\._]*)!$1!g; + $line =~ s!\\paragraph\s+[\w]+\s([\w]+)!
  • $1
  • !g; + $line =~ s!\\b\s+([\w -]+)\\n!
  • $1
  • !g; + $line =~ s!\\c\s+([\w\@&\\?;-]+)!$1!g; + $line =~ s!\\p\s+([\w\@]+)!
    $1
    !g; + $line =~ s!\\li\s+([\w\@]+)!
  • $1
  • !g; + $line =~ s!([\w\t \(\)-]*:?)\\n!
  • $1
  • !g; + $line =~ s!static_cast<\s*([\w\.]*)\s*>!($1)!g; + if ($name ne "") { + $line =~ s/\@link #/\@link $name\#/g; + } + + if ($node->{NodeType} eq "ListItem") { + $line =~ s/^/\n
  • \n/; + $line =~ s!$!\n
  • !; + $line =~ s/\n/\n$indent\t/g; + } else { + $line =~ s/^/$indent/; + $line =~ s/\n/\n$indent/g; + } + + $line =~ s/\n/\n$indent/g; + $returntext .= $line; + } + + $returntext .= $signalLink; + + if ( defined $docnode->{Returns} ) { + my $text = $docnode->{Returns}; + $text =~ s/TQString::null/null/g; + $returntext .= "\t\t\@return $text\n"; + } + + if ( defined $docnode->{Author} ) { + $returntext .= "\t\t\@author " . $docnode->{Author} . "\n" + } + + if ( defined $docnode->{Version} ) { + my $versionStr = $docnode->{Version}; + $versionStr =~ s/\$\s*Id:([^\$]*) Exp \$/$1/; + $returntext .= "\t\t\@version $versionStr\n"; + } + + if ( defined $docnode->{ClassShort} ) { + my $shortText = $docnode->{ClassShort}; + $shortText =~ s![\*\n]! !g; + $returntext .= "\t\t\@short $shortText\n"; + } + + if ( defined $docnode->{See} ) { + foreach my $text ( @{$docnode->{See}} ) { + next if ($text =~ /TQString|^\s*and\s*$|^\s*$|^[^\w]*$/); + $text =~ s/KIO:://g; + $text =~ s/KParts:://g; + $text =~ s/bool/boolean/g; + $text =~ s/::/#/g; + $text =~ s/->/#/g; + $text =~ s/\./#/g; + $text =~ s/\(\)//g; + $text =~ s/^\s*([a-z].*)/#$1/g; + $text =~ s/^\s*Q/org.kde.qt.Q/g; +# $text =~ s/^\s*K/org.kde.koala.K/g; + $returntext .= "\t\t\@see $text\n"; + } + } + + $returntext =~ s/DOM#([A-Z])/$1/g; + $returntext =~ s/KIO#([A-Z])/$1/g; + $returntext =~ s/KParts#([A-Z])/$1/g; + $returntext =~ s/const\s+(\w+)\s*\&/$1/g; + $returntext =~ s/TQChar/char/g; + $returntext =~ s/TQStringList/ArrayList/g; + $returntext =~ s/([Aa]) ArrayList/$1n ArrayList/g; + $returntext =~ s/TQString/String/g; + $returntext =~ s/KCmdLineOptions/String[][]/; + $returntext =~ s!\\note!Note:<\b>!g; + $returntext =~ s!\\(code|verbatim)!
    !g;
    +	$returntext =~ s!\\(endcode|endverbatim)!
    !g; + $returntext =~ s!\\addtogroup\s+[\w]+\s+"([^"\@]+)"\s+\@{!
  • $1
  • !g; + $returntext =~ s![\\\@]relates\s+([a-z][\w]*)!{\@link #$1}!g; + $returntext =~ s![\\\@]relates\s+(\w+)::(\w+)!{\@link $1#$2}!g; + $returntext =~ s![\\\@]relates\s+(#?\w+)!{\@link $1}!g; + $returntext =~ s!\\c\s+([\w\@&\\?";-]+)!$1!g; + $returntext =~ s!\@p\s+([\w\._]*)!$1!g; + $returntext =~ s!\@a\s+([:\w]+)!$1!g; + $returntext =~ s![\@\\]b\s+[:\w]!$1!g; + $returntext =~ s/};/}/g; + $returntext =~ s/::/./g; + $returntext =~ s/->/./g; + + $returntext =~ s/\s*$//; + return $returntext . "\n" . $indent; +} + +1; diff --git a/kalyptus/kalyptusCxxToJava.pm b/kalyptus/kalyptusCxxToJava.pm new file mode 100644 index 0000000..fa518cf --- /dev/null +++ b/kalyptus/kalyptusCxxToJava.pm @@ -0,0 +1,3434 @@ +#*************************************************************************** +# kalyptusCxxToJava.pm - Generates *.java files for a Dynamic Proxy +# based smoke adaptor +# ------------------- +# begin : Fri Jan 25 12:00:00 2003 +# copyright : (C) 2003, Richard Dale. All Rights Reserved. +# email : Richard_Dale@tipitina.demon.co.uk +# author : Richard Dale, based on the SMOKE generation code +# by David Faure. +#***************************************************************************/ + +#/*************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation; either version 2 of the License, or * +# * (at your option) any later version. * +# * * +#***************************************************************************/ + +package kalyptusCxxToJava; + +use File::Path; +use File::Basename; + +use Carp; +use Ast; +use kdocAstUtil; +use kdocUtil; +use Iter; +use kalyptusDataDict; + +use strict; +no strict "subs"; + +use vars qw/ + $libname $rootnode $outputdir $opt $debug + $qapplicationExtras $qbitmapExtras + $qlistviewExtras $qlistviewitemExtras + $qdragobjectExtras $qdropeventExtras $qmimesourceExtras + $qtExtras $qobjectExtras $qwidgetExtras + $qpixmapExtras $qpaintdeviceExtras + $qdragobjectExtras $qiodeviceExtras $qpointarrayExtras + $qtextcodecExtras $quridragExtras + $kapplicationExtras $kmainwindowExtras + $methodNumber + %builtins %typeunion %allMethods %allTypes %enumValueToType %typedeflist %mungedTypeMap %javaImports + %skippedClasses %operatorNames /; + +BEGIN +{ + +# Types supported by the StackItem union +# Key: C++ type Value: Union field of that type +%typeunion = ( + 'void*' => 's_voidp', + 'bool' => 's_bool', + 'char' => 's_char', + 'uchar' => 's_uchar', + 'short' => 's_short', + 'ushort' => 's_ushort', + 'int' => 's_int', + 'uint' => 's_uint', + 'long' => 's_long', + 'ulong' => 's_ulong', + 'float' => 's_float', + 'double' => 's_double', + 'enum' => 's_enum', + 'class' => 's_class' +); + +# Mapping for iterproto, when making up the munged method names +%mungedTypeMap = ( + 'TQString' => '$', + 'TQString*' => '$', + 'TQString&' => '$', + 'TQCString' => '$', + 'TQCString*' => '$', + 'TQCString&' => '$', + 'TQByteArray' => '$', + 'TQByteArray&' => '$', + 'TQByteArray*' => '$', + 'char*' => '$', + 'TQCOORD*' => '?', + 'TQRgb*' => '?', +); + +# Yes some of this is in kalyptusDataDict's ctypemap +# but that one would need to be separated (builtins vs normal classes) +%typedeflist = +( + 'signed char' => 'char', + 'unsigned char' => 'uchar', + 'signed short' => 'short', + 'unsigned short' => 'ushort', + 'signed' => 'int', + 'signed int' => 'int', + 'unsigned' => 'uint', + 'unsigned int' => 'uint', + 'KIO::filesize_t' => 'long', + 'signed long' => 'long', + 'unsigned long' => 'ulong', + +# Anything that is not known is mapped to void*, so no need for those here anymore +# 'TQWSEvent*' => 'void*', +# 'TQDiskFont*' => 'void*', +# 'XEvent*' => 'void*', +# 'FILE*' => 'void*', +# 'TQUnknownInterface*' => 'void*', +# 'GDHandle' => 'void*', +# '_NPStream*' => 'void*', +# 'TQTextFormat*' => 'void*', +# 'TQTextDocument*' => 'void*', +# 'TQTextCursor*' => 'void*', +# 'TQTextParag**' => 'void*', +# 'TQTextParag*' => 'void*', +# 'TQRemoteInterface*' => 'void*', +# 'TQSqlRecordPrivate*' => 'void*', +# 'TQTSMFI' => 'void*', # TQTextStream's TQTSManip +# 'const GUID&' => 'void*', +# 'TQWidgetMapper*' => 'void*', +# 'MSG*' => 'void*', +# 'const TQSqlFieldInfoList&' => 'void*', # TQSqlRecordInfo - TODO (templates) + + 'TQStyleHintReturn*' => 'void*', + 'TQPtrCollection::Item' => 'void*', # to avoid a warning + + 'mode_t' => 'long', + 'TQProcess::PID' => 'long', + 'size_type' => 'int', # TQSqlRecordInfo + 'TQt::ComparisonFlags' => 'uint', + 'TQt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it + 'TQIODevice::Offset' => 'ulong', + 'WState' => 'int', + 'WId' => 'ulong', + 'TQRgb' => 'uint', + 'ksocklen_t' => 'uint', + 'TQCOORD' => 'int', + 'TQTSMFI' => 'int', + 'TQt::WState' => 'int', + 'TQt::WFlags' => 'int', + 'TQt::HANDLE' => 'uint', + 'TQEventLoop::ProcessEventsFlags' => 'uint', + 'TQStyle::SCFlags' => 'int', + 'TQStyle::SFlags' => 'int', + 'Q_INT16' => 'short', + 'Q_INT32' => 'int', + 'Q_INT64' => 'long', + 'Q_INT8' => 'char', + 'Q_LONG' => 'long', + 'Q_LLONG' => 'long', + 'Q_ULLONG' => 'long', + 'Q_UINT16' => 'ushort', + 'Q_UINT32' => 'uint', + 'Q_UINT64' => 'long', + 'Q_UINT8' => 'uchar', + 'Q_ULONG' => 'long', + 'pid_t' => 'int', + 'size_t' => 'int', + 'pid_t' => 'int', + 'time_t' => 'int', + 'short int' => 'short', + 'unsigned long long int' => 'ulong', + 'long long int' => 'long', + 'signed long int' => 'long', + 'unsigned long int' => 'ulong', + 'int long' => 'long', + 'unsigned short int' => 'ushort', +); + +%operatorNames = +( + 'operator^' => 'op_xor', + 'operator^=' => 'op_xor_assign', + 'operator<' => 'op_lt', + 'operator<<' => 'op_write', + 'operator<=' => 'op_lte', +# 'operator=' => 'op_assign', + 'operator==' => 'op_equals', + 'operator>' => 'op_gt', + 'operator>=' => 'op_gte', + 'operator>>' => 'op_read', + 'operator|' => 'op_or', + 'operator|=' => 'op_or_assign', + 'operator-' => 'op_minus', + 'operator-=' => 'op_minus_assign', + 'operator--' => 'op_decr', + 'operator!' => 'op_not', + 'operator!=' => 'op_not_equals', + 'operator/' => 'op_div', + 'operator/=' => 'op_div_assign', + 'operator()' => 'op_expr', + 'operator[]' => 'op_at', + 'operator*' => 'op_mult', + 'operator*=' => 'op_mult_assign', + 'operator&' => 'op_and', + 'operator&=' => 'op_and_assign', + 'operator+' => 'op_plus', + 'operator+=' => 'op_plus_assign', + 'operator++' => 'op_incr', +); + + $qapplicationExtras = <|TQValueList|TQValueList|TQValueList|TQValueListConstIterator|TQMap|EditMode|TQPtrList|TQPtrList|TQTextFormat|TQTextCursor|TQTextDocument|TQNetworkProtocolFactoryBase|TQDomNodePrivate|TQSqlDriverCreatorBase|TQSqlFieldInfoList|TQObjectUserData|TQUObject|TQTextParag|TQWidgetMapper|TQMemArray|TQBitArray|TQLayoutIterator|TQAuBucket|TQUnknownInterface|TQConnectionList/ ) { + return ""; # Unsupported type + } elsif ( $cplusplusType =~ /bool/ && kalyptusDataDict::ctypemap($cplusplusType) eq "int" ) { + return "boolean"; + } elsif ( $cplusplusType =~ /bool\s*[*&]/ ) { + return "boolean[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^void\s*\*/ ) { + return "int"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^\s*(unsigned )?int\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /^qt_QIntValueList\*/ + || $cplusplusType =~ /^int[*&]$/ ) + { + return "int[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^\s*double\s*\*/ ) { + return "double[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^\s*(unsigned )?short\s*\*/ ) { + return "short[]"; + } elsif ( $cplusplusType =~ /KCmdLineOptions/ ) { + return "String[][]"; + } elsif ( $cplusplusType =~ /char\s*\*\*/ || $cplusplusType =~ /TQStringList/|| $cplusplusType =~ /TQStrList/) { + return "String[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QUrlInfoValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QVariantValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QIconDragItemValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QPixmapValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_QCStringList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QObjectList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QDomNodeList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QWidgetList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KURLList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KMainWindow\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KFileItemList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KFileViewItemList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_DOMNodeList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_StyleSheetList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_MediaList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_OfferList\s*\*/ + || $cplusplusType =~ /TQMemArray/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QCanvasItemList\s*\*/ ) { + return "ArrayList" + } elsif ( $cplusplusType =~ /uchar\s*\*/ ) { + return "char[]"; + } elsif ( $cplusplusType =~ /QC?String/ and !$isConst ) { + return "StringBuffer" + } elsif ( $cplusplusType =~ /(DOM::)?DOMString/ || $cplusplusType =~ /TQString/ || $cplusplusType =~ /TQCString/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /^(const )?char\s*\*/ ) { + return "String" + } elsif ( $cplusplusType =~ /TQChar\s*[&\*]?/ || $cplusplusType =~ /^char$/ ) { + return "char" + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QTime\s*\*/ ) { + return "Date" + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QDateTime\s*\*/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QDate\s*\*/ ) { + return "Calendar" + } elsif ( $cplusplusType =~ /TQPaintDevice/ ) { + return "TQPaintDeviceInterface" + } elsif ( $cplusplusType =~ /TQByteArray/ ) { + return "byte[]" + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_([^\*\s]*)(.*)$/ and !$skippedClasses{$className}) { + if ( kalyptusDataDict::interfacemap($1) ne () ) { + return $1."Interface"; + } else { + return $1; + } + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_([^\*\s]*)(.*)$/ and !$skippedClasses{$className}) { + if ( kalyptusDataDict::interfacemap($1) ne () ) { + return $1."Interface"; + } else { + return $1; + } + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /unsigned char/ ) { + return "short"; + } elsif ( $typedeflist{$cplusplusType} =~ /ulong|long/ ) { + return "long"; + } elsif ( $typedeflist{$cplusplusType} =~ /uint|int/ or $cplusplusType =~ /^int\&$/ ) { + return "int"; + } elsif ( $typedeflist{$cplusplusType} =~ /ushort|short/ ) { + return "short"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /(unsigned )(.*)/ ) { + return $2; + } else { + my $node; + my $item; + if ($className =~ /^(\w+)::(\w+)$/) { + $node = kdocAstUtil::findRef( $rootnode, $1 ); + $item = kdocAstUtil::findRef( $node, $2 ) if defined $node; + if (defined $item && $item->{NodeType} eq 'enum') { + return "int"; + } elsif (defined $item && ($item->{NodeType} eq 'class' || $item->{NodeType} eq 'struct')) { + return $skippedClasses{$className} ? "" : $2; + } + } + + if ($className =~ /^\w+$/) { + $item = kdocAstUtil::findRef( $rootnode, $className ); + if (defined $item && ($item->{NodeType} eq 'class' || $item->{NodeType} eq 'struct')) { + return $skippedClasses{$className} ? "" : $className; + } + } + return kalyptusDataDict::ctypemap($cplusplusType); + } + +} + +sub writeDoc +{ + ( $libname, $rootnode, $outputdir, $opt ) = @_; + + print STDERR "Starting writeDoc for $libname...\n"; + + $debug = $main::debuggen; + + mkpath( $outputdir ) unless -f $outputdir; + + # Define TQPtrCollection::Item, for resolveType + unless ( kdocAstUtil::findRef( $rootnode, "TQPtrCollection::Item" ) ) { + my $cNode = kdocAstUtil::findRef( $rootnode, "TQPtrCollection" ); + warn "TQPtrCollection not found" if (!$cNode); + my $node = Ast::New( 'Item' ); + $node->AddProp( "NodeType", "Forward" ); + $node->AddProp( "Source", $cNode->{Source} ) if ($cNode); + kdocAstUtil::attachChild( $cNode, $node ) if ($cNode); + $node->AddProp( "Access", "public" ); + } + + print STDERR "Preparsing...\n"; + + # Preparse everything, to prepare some additional data in the classes and methods + Iter::LocalCompounds( $rootnode, sub { preParseClass( shift ); } ); + + # Have a look at each class again, to propagate CanBeCopied + Iter::LocalCompounds( $rootnode, sub { propagateCanBeCopied( shift ); } ); + + # Write out smokedata.cpp + writeSmokeDataFile($rootnode); + + print STDERR "Writing *.java...\n"; + + # Generate *java file for each class + Iter::LocalCompounds( $rootnode, sub { writeClassDoc( shift ); } ); + + print STDERR "Done.\n"; +} + +=head2 preParseClass + Called for each class +=cut +sub preParseClass +{ + my( $classNode ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + if( $#{$classNode->{Kids}} < 0 || + $classNode->{Access} eq "private" || + $classNode->{Access} eq "protected" || # e.g. TQPixmap::TQPixmapData + exists $classNode->{Tmpl} || + # Don't generate standard bindings for TQString, this class is handled as a native type + $className eq 'TQString' || + $className eq 'TQConstString' || + $className eq 'TQCString' || + # Don't map classes which are really arrays + $className eq 'TQStringList' || + $className eq 'TQCanvasItemList' || + $className eq 'TQWidgetList' || + $className eq 'TQObjectList' || + $className eq 'TQStrList' || + # Those are template related + $className eq 'TQTSManip' || # cause compiler errors with several gcc versions + $className eq 'TQIconFactory' || + $className eq 'TQGDict' || + $className eq 'TQGList' || + $className eq 'TQGVector' || + $className eq 'TQStrIList' || + $className eq 'TQStrIVec' || + $className eq 'TQByteArray' || + $className eq 'TQBitArray' || + $className eq 'TQWExtra' || + $className eq 'TQTLWExtra' || + $className eq 'TQMetaEnum::Item' || + $className eq 'TQWidgetContainerPlugin' || + $className eq 'TQGArray::array_data' || + $className eq 'KBookmarkMenu::DynMenuInfo' || + $className eq 'KCompletionMatches' || + $className eq 'KDEDesktopMimeType::Service' || + $className eq 'KGlobalSettings::KMouseSettings' || + $className eq 'KMimeType::Format' || + $className eq 'KNotifyClient::Instance' || + $className eq 'KParts::Plugin::PluginInfo' || + $className eq 'KProtocolInfo::ExtraField' || + $className eq 'KXMLGUIClient::StateChange' || + $className eq 'KIconTheme' || + $className eq 'KEditListBox::CustomEditor' || + $className eq 'KIO::KBookmarkMenuNSImporter' || + $className eq 'KPerDomainSettings' || + $className eq 'KApplicationPropsPlugin' || + $className eq 'KPrinter' || + $className eq 'KPty' || + $className eq 'KOpenWithHandler' || + $className eq 'KFileOpenWithHandler' || + $className eq 'KBindingPropsPlugin' || + $className eq 'KPropsDlgPlugin' || + $className eq 'KFileSharePropsPlugin' || + $className eq 'KBookmarkMenuNSImporter' || + $className eq 'KDevicePropsPlugin' || + $className eq 'KWin::WindowInfo' || + $className eq 'KDEDModule' || + $className eq 'KFileMetaInfoProvider' || + $className eq 'KFileMimeTypeInfo' || + $className eq 'KExecPropsPlugin' || + $className eq 'KFilePermissionsPropsPlugin' || + $className eq 'KImageFilePreview' || + $className eq 'KBookmarkManager' || + $className eq 'KBookmarkNotifier' || + $className eq 'KOCRDialogFactory' || + $className eq 'KExtendedBookmarkOwner' || + $className eq 'KSharedPixmap' || + $className eq 'KSocket' || + $className eq 'KLibrary' || + $className eq 'KScanDialogFactory' || + $className eq 'KDictSpellingHighlighter' || + $className eq 'KPropertiesDialog' || + $className eq 'ProgressItem' || + $className eq 'KIO::ChmodInfo' || + $className eq 'KIO::MetaData' || + $className eq 'KFileMimeTypeInfo::ItemInfo' || + $className eq 'KIO::UDSAtom' || + $className eq 'khtml::DrawContentsEvent' || # the khtml:: classes build, but don't link + $className eq 'khtml::MouseDoubleClickEvent' || + $className eq 'khtml::MouseMoveEvent' || + $className eq 'khtml::MousePressEvent' || + $className eq 'khtml::MouseReleaseEvent' || + $className eq 'khtml::MouseEvent' || + $className eq 'KURL::List' || + $className eq 'KWin::Info' || + $className eq 'TerminalInterface' || + $className =~ /.*Private$/ || # Ignore any classes which aren't for public consumption + $className =~ /.*Impl$/ || + $className =~ /.*Internal.*/ || +# $classNode->{Deprecated} || + $classNode->{NodeType} eq 'union' # Skip unions for now, e.g. TQPDevCmdParam + ) { + print STDERR "Skipping $className\n" if ($debug); + print STDERR "Skipping union $className\n" if ( $classNode->{NodeType} eq 'union'); + $skippedClasses{$className} = 1; + delete $classNode->{Compound}; # Cheat, to get it excluded from Iter::LocalCompounds + return; + } + + my $signalCount = 0; + my $eventHandlerCount = 0; + my $defaultConstructor = 'none'; # none, public, protected or private. 'none' will become 'public'. + my $constructorCount = 0; # total count of _all_ ctors + # If there are ctors, we need at least one public/protected one to instanciate the class + my $hasPublicProtectedConstructor = 0; + # We need a public dtor to destroy the object --- ### aren't protected dtors ok too ?? + my $hasPublicDestructor = 1; # by default all classes have a public dtor! + #my $hasVirtualDestructor = 0; + my $hasDestructor = 0; + my $hasPrivatePureVirtual = 0; + my $hasCopyConstructor = 0; + my $hasPrivateCopyConstructor = 0; + # Note: no need for hasPureVirtuals. $classNode{Pure} has that. + + my $doPrivate = $main::doPrivate; + $main::doPrivate = 1; + # Look at each class member (looking for methods and enums in particular) + Iter::MembersByType ( $classNode, undef, + sub { + + my( $classNode, $m ) = @_; + my $name = $m->{astNodeName}; + + if( $m->{NodeType} eq "method" ) { + if ( $m->{ReturnType} eq 'typedef' # TQFile's EncoderFn/DecoderFn callback, very badly parsed + ) { + $m->{NodeType} = 'deleted'; + next; + } + + print STDERR "preParseClass: looking at $className\::$name $m->{Params}\n" if ($debug); + + if ( $name eq $classNode->{astNodeName} ) { + if ( $m->{ReturnType} =~ /~/ ) { + # A destructor + $hasPublicDestructor = 0 if $m->{Access} ne 'public'; + #$hasVirtualDestructor = 1 if ( $m->{Flags} =~ "v" && $m->{Access} ne 'private' ); + $hasDestructor = 1; + } else { + # A constructor + $constructorCount++; + $defaultConstructor = $m->{Access} if ( $m->{Params} eq '' ); + $hasPublicProtectedConstructor = 1 if ( $m->{Access} ne 'private' ); + + # Copy constructor? + if ( $#{$m->{ParamList}} == 0 ) { + my $theArgType = @{$m->{ParamList}}[0]->{ArgType}; + if ($theArgType =~ /$className\s*\&/) { + $hasCopyConstructor = 1; + $hasPrivateCopyConstructor = 1 if ( $m->{Access} eq 'private' ); + } + } + # Hack the return type for constructors, since constructors return an object pointer + $m->{ReturnType} = $className."*"; + } + } + + if ( $name =~ /~$classNode->{astNodeName}/ && $m->{Access} ne "private" ) { # not used + $hasPublicDestructor = 0 if $m->{Access} ne 'public'; + #$hasVirtualDestructor = 1 if ( $m->{Flags} =~ "v" ); + $hasDestructor = 1; + } + + if ( $m->{Flags} =~ "p" && $m->{Access} =~ /private/ ) { + $hasPrivatePureVirtual = 1; # ouch, can't inherit from that one + } + + # All we want from private methods is to check for virtuals, nothing else + next if ( $m->{Access} =~ /private/ ); + + # Don't generate code for deprecated methods, + # or where the code won't compile/link for obscure reasons. Or even obvious reasons.. + if ( ($classNode->{astNodeName} eq 'KCharSelectTable' and $name eq 'paintCell') + || ($classNode->{astNodeName} eq 'KAnimWidget' and $name eq 'KAnimWidget' and @{$m->{ParamList}} == 2) + || ($classNode->{astNodeName} eq 'KDCOPActionProxy' and $name eq 'actions') + || ($classNode->{astNodeName} eq 'KFileDialog' and $name eq 'addDirEntry') + || ($classNode->{astNodeName} eq 'KFileDialog' and $name eq 'getDirEntry') + || ($classNode->{astNodeName} eq 'KFileView' and $name eq 'selectionMode') + || ($classNode->{astNodeName} eq 'KFind' and $name eq 'KFind' and @{$m->{ParamList}} == 4) + || ($classNode->{astNodeName} eq 'KGlobalAccel' and $name eq 'setEnabled') + || ($classNode->{astNodeName} eq 'KCharsets' and $name eq 'encodingsForLanguage') + || ($classNode->{astNodeName} eq 'KInputDialog' and $name eq 'getInteger') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'buildHTMLErrorString') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'checkCachedAuthentication') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'cacheAuthentication') + || ($classNode->{astNodeName} eq 'KInputDialog' and $name eq 'getDouble') + || ($classNode->{astNodeName} eq 'KToolBar' and $name eq 'enable') + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'insert' and @{$m->{ParamList}} == 2) + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'autoupdate') + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'getAutoUpdate') + || ($classNode->{astNodeName} eq 'KStdAccel' and $name eq 'insert') + || ($classNode->{astNodeName} eq 'KBookmarkMenu' and $name eq 'invalid') + || ($classNode->{astNodeName} eq 'KCharsets' and $name eq 'languages') + || ($classNode->{astNodeName} eq 'KCombiView' and $name eq 'setDropOptions') + || ($classNode->{astNodeName} eq 'KFileMetaInfoItem' and $name eq 'unit') + || ($classNode->{astNodeName} eq 'KInstance' and $name eq 'charsets') + || ($classNode->{astNodeName} eq 'KInstance' and $name eq 'KInstance' and $m->{Access} =~ /protected/) + || ($classNode->{astNodeName} eq 'KKey' and $name eq 'isValidQt') + || ($classNode->{astNodeName} eq 'KKey' and $name eq 'isValidNative') + || ($classNode->{astNodeName} eq 'KKeySequence' and $name eq 'init') + || ($classNode->{astNodeName} eq 'KKeySequence' and $name eq 'setTriggerOnRelease') + || ($classNode->{astNodeName} eq 'KEMailSettings' and $name eq 'getExtendedSetting') + || ($classNode->{astNodeName} eq 'KEMailSettings' and $name eq 'setExtendedSetting') + || ($classNode->{astNodeName} eq 'KProtocolManager' and $name eq 'defaultConnectTimeout') + || ($classNode->{astNodeName} eq 'KMD5' and $name eq 'transform') + || ($classNode->{astNodeName} eq 'KSSLCertificate' and $name eq 'operator!=') + || ($classNode->{astNodeName} eq 'KSSLPKCS7' and $name eq 'validate') + || ($classNode->{astNodeName} eq 'KSSLPKCS7' and $name eq 'revalidate') + || ($classNode->{astNodeName} eq 'KSSLSession' and $name eq 'KSSLSession' and @{$m->{ParamList}} == 1) + || ($classNode->{astNodeName} eq 'KSimpleFileFilter' and $name eq 'nameFilters') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'isTabReorderingEnabled') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'hoverCloseButton') + || ($classNode->{astNodeName} eq 'TQUriDrag' and $name =~ /^decode$|decodeLocalFiles|decodeToUnicodeUris/) + || ($name eq 'virtual_hook') + || ($name =~ /_KShared_/) + || ($name eq 'qObject') + || ($name =~ /argv/) + || ($name =~ /argc/) + || ($name eq 'qt_emit') + || ($name eq 'qt_invoke') + || ($name eq 'qt_cast') + || ($name eq 'qt_property') + || ($name eq 'staticMetaObject') + || ($classNode->{astNodeName} eq 'KTar' and $name eq 'writeFile_impl') + # Assume only Qt classes have tr() and trUtf8() in their Q_OBJECT macro + || ($classNode->{astNodeName} !~ /^Q/ and $name eq 'tr') + || ($classNode->{astNodeName} !~ /^Q/ and $name eq 'trUtf8') + || $m->{Deprecated} ) { + $m->{NodeType} = 'deleted'; + next; + } + + my $argId = 0; + my $firstDefaultParam; + foreach my $arg ( @{$m->{ParamList}} ) { + # Look for first param with a default value + if ( defined $arg->{DefaultValue} && !defined $firstDefaultParam ) { + $firstDefaultParam = $argId; + } + + if ( $arg->{ArgType} eq '...' # refuse a method with variable arguments + or $arg->{ArgType} eq 'image_io_handler' # TQImage's callback + or $arg->{ArgType} eq 'DecoderFn' # TQFile's callback + or $arg->{ArgType} eq 'EncoderFn' # TQFile's callback + or $arg->{ArgType} =~ /bool \(\*\)\(TQObject/ # TQMetaObject's ctor + or $arg->{ArgType} eq 'QtStaticMetaObjectFunction' # TQMetaObjectCleanUp's ctor with func pointer + or $arg->{ArgType} eq 'const TQTextItem&' # ref to a private class in 3.2.0b1 + or $arg->{ArgType} eq 'FILE*' # won't be able to handle that I think + or $arg->{ArgType} eq 'const KKeyNative&' # + ) { + $m->{NodeType} = 'deleted'; + } + else + { + # Resolve type in full, e.g. for TQSessionManager::RestartHint + # (TQSessionManagerJBridge doesn't inherit TQSessionManager) + $arg->{ArgType} = kalyptusDataDict::resolveType($arg->{ArgType}, $classNode, $rootnode); + registerType( $arg->{ArgType} ); + $argId++; + } + } + $m->AddProp( "FirstDefaultParam", $firstDefaultParam ); + $m->{ReturnType} = kalyptusDataDict::resolveType($m->{ReturnType}, $classNode, $rootnode) if ($m->{ReturnType}); + registerType( $m->{ReturnType} ); + } + elsif( $m->{NodeType} eq "enum" ) { + if ( ! $m->{astNodeName} ) { + $m->{Access} = 'protected'; + } + my $fullEnumName = $className."::".$m->{astNodeName}; + if ( ($fullEnumName eq 'KMimeType::Format' and $name eq 'compression') + || $m->{Deprecated} ) { + $m->{NodeType} = 'deleted'; + next; + } + + $classNode->{enumerations}{$m->{astNodeName}} = $fullEnumName; +# if $m->{astNodeName} and $m->{Access} ne 'private'; +# if $m->{astNodeName} ; + + # Define a type for this enum + registerType( $fullEnumName ); + + # Remember that it's an enum + findTypeEntry( $fullEnumName )->{isEnum} = 1; + } + elsif( $m->{NodeType} eq 'var' ) { + my $varType = $m->{Type}; + # We are interested in public static vars, like TQColor::blue + if ( $varType =~ s/static\s+// && $m->{Access} ne 'private' + && $className."::".$m->{astNodeName} ne "KSpell::modalListText" ) + { + $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/\s*$//; + print STDERR "var: $m->{astNodeName} '$varType'\n" if ($debug); + + # Register the type + registerType( $varType ); + + } else { + # To avoid duplicating the above test, we just get rid of any other var + $m->{NodeType} = 'deleted'; + } + } + }, + undef + ); + $main::doPrivate = $doPrivate; + + print STDERR "$className: ctor count: $constructorCount, hasPublicProtectedConstructor: $hasPublicProtectedConstructor, hasCopyConstructor: $hasCopyConstructor:, defaultConstructor: $defaultConstructor, hasPublicDestructor: $hasPublicDestructor, hasPrivatePureVirtual:$hasPrivatePureVirtual\n" if ($debug); + + # Note that if the class has _no_ constructor, the default ctor applies. Let's even generate it. + if ( !$constructorCount && $defaultConstructor eq 'none' && !$hasPrivatePureVirtual ) { + # Create a method node for the constructor + my $methodNode = Ast::New( $classNode->{astNodeName} ); + $methodNode->AddProp( "NodeType", "method" ); + $methodNode->AddProp( "Flags", "" ); + $methodNode->AddProp( "Params", "" ); + $methodNode->AddProp( "ParamList", [] ); + kdocAstUtil::attachChild( $classNode, $methodNode ); + + # Hack the return type for constructors, since constructors return an object pointer + $methodNode->AddProp( "ReturnType", $className."*" ); + registerType( $className."*" ); + $methodNode->AddProp( "Access", "public" ); # after attachChild + $defaultConstructor = 'public'; + $hasPublicProtectedConstructor = 1; + } + + # Also, if the class has no explicit destructor, generate a default one. + if ( !$hasDestructor && !$hasPrivatePureVirtual ) { + my $methodNode = Ast::New( "$classNode->{astNodeName}" ); + $methodNode->AddProp( "NodeType", "method" ); + $methodNode->AddProp( "Flags", "" ); + $methodNode->AddProp( "Params", "" ); + $methodNode->AddProp( "ParamList", [] ); + kdocAstUtil::attachChild( $classNode, $methodNode ); + + $methodNode->AddProp( "ReturnType", "~" ); + $methodNode->AddProp( "Access", "public" ); + } + + # If we have a private pure virtual, then the class can't be instanciated (e.g. TQCanvasItem) + # Same if the class has only private constructors (e.g. TQInputDialog) + $classNode->AddProp( "CanBeInstanciated", $hasPublicProtectedConstructor +# && !$hasPrivatePureVirtual + && (!$classNode->{Pure} or $classNode->{astNodeName} eq 'TQValidator') + && !($classNode->{NodeType} eq 'namespace') + && ($classNode->{astNodeName} !~ /^DrawContentsEvent$|^MouseEvent$|^MouseDoubleClickEvent$|^MouseMoveEvent$|^MouseReleaseEvent$|^MousePressEvent$/) + && ($classNode->{astNodeName} !~ /TQMetaObject|TQDragObject|Slave|CopyJob|KMdiChildFrm|KNamedCommand/) ); + + # We will derive from the class only if it has public or protected constructors. + # (_Even_ if it has pure virtuals. But in that case the *.cpp class can't be instantiated either.) + $classNode->AddProp( "BindingDerives", $hasPublicProtectedConstructor ); + + # We need a public dtor to destroy the object --- ### aren't protected dtors ok too ?? + $classNode->AddProp( "HasPublicDestructor", $hasPublicDestructor ); + + # Hack for TQAsyncIO. We don't implement the "if a class has no explicit copy ctor, + # then all of its member variables must be copiable, otherwise the class isn't copiable". + $hasPrivateCopyConstructor = 1 if ( $className eq 'TQAsyncIO' ); + + # Remember if this class can't be copied - it means all its descendants can't either + $classNode->AddProp( "CanBeCopied", !$hasPrivateCopyConstructor ); + $classNode->AddProp( "HasCopyConstructor", $hasCopyConstructor ); +} + +sub propagateCanBeCopied($) +{ + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + my @super = superclass_list($classNode); + # A class can only be copied if none of its ancestors have a private copy ctor. + for my $s (@super) { + if (!$s->{CanBeCopied}) { + $classNode->{CanBeCopied} = 0; + print STDERR "$classNode->{astNodeName} cannot be copied\n" if ($debug); + last; + } + } + # If the class has no explicit copy constructor, and it can be copied, + # generate the copy constructor. + if ( !$classNode->{HasCopyConstructor} && $classNode->{CanBeCopied} && $classNode->{CanBeInstanciated} ) { + my $methodNode = Ast::New( "$classNode->{astNodeName}" ); + $methodNode->AddProp( "NodeType", "method" ); + $methodNode->AddProp( "Flags", "" ); + my $argType = "const ".$className."&"; + registerType( $argType ); + $methodNode->AddProp( "Params", $argType ); + # The param node + my $node = Ast::New( 1 ); # let's make the arg index the node "name" + $node->AddProp( "NodeType", "param" ); + $node->AddProp( "ArgType", $argType ); + $methodNode->AddPropList( "ParamList", $node ); + kdocAstUtil::attachChild( $classNode, $methodNode ); + + # Hack the return type for constructors, since constructors return an object pointer + $methodNode->AddProp( "ReturnType", $className."*" ); + registerType( $className."*" ); + $methodNode->AddProp( "Access", "public" ); # after attachChild + } + + # Prepare the {case} dict for the class + prepareCaseDict( $classNode ); +} + +=head2 writeClassDoc + + Called by writeDoc for each class to be written out + +=cut + +sub writeClassDoc +{ + my( $node ) = @_; + my $className = join( "::", kdocAstUtil::heritage($node) ); + my $javaClassName = $node->{astNodeName}; + # Makefile doesn't like '::' in filenames, so use __ + my $fileName = $node->{astNodeName}; +# my $fileName = join( "__", kdocAstUtil::heritage($node) ); + print "Enter: $className\n" if $debug; + + my $typeprefix = ($className =~ /^Q/ ? "qt_" : "kde_"); + my $packagename = ($typeprefix eq 'qt_' ? "org.kde.qt" : "org.kde.koala"); + + # Write out the *.java file + my $classFile = "$outputdir/$fileName.java"; + open( CLASS, ">$classFile" ) || die "Couldn't create $classFile\n"; + print STDERR "Writing $fileName.java\n" if ($debug); + + print CLASS "//Auto-generated by $0. DO NOT EDIT.\n"; + + print CLASS "package $packagename;\n\n"; + + print CLASS "import java.lang.reflect.Proxy;\n"; + print CLASS "import org.kde.qt.SmokeInvocation;\n"; + + my %javaMethods = (); + my %addImport = (); + + my @ancestors = (); + my @ancestor_nodes = (); + Iter::Ancestors( $node, $rootnode, undef, undef, sub { + my ( $ances, $name, $type, $template ) = @_; + if ( $name ne "TQMemArray" and $name ne "TQSqlFieldInfoList" ) { + push @ancestor_nodes, $ances; + push @ancestors, $name; + } + }, + undef + ); + + my ($methodCode, $interfaceCode, $proxyInterfaceCode, $signalCode) = generateAllMethods( $node, $#ancestors + 1, + \%javaMethods, + $node, + 1, + \%addImport ); + + my $signalFile = "$outputdir/$fileName" . "Signals.java"; + if ( $signalCode ne '' ) { + open( SIGNALS, ">$signalFile" ) || die "Couldn't create $signalFile\n"; + print SIGNALS "//Auto-generated by $0. DO NOT EDIT.\n"; + print SIGNALS "package $packagename;\n\n"; + } + + my $tempMethodNumber = $methodNumber; + + # Add method calls for the interfaces implemented by the class + foreach my $ancestor_node ( @ancestor_nodes ) { + if ( kalyptusDataDict::interfacemap($ancestor_node->{astNodeName}) ne () && ($#ancestors > 0) ) { + my ($meth, $interf, $proxyInterf, $sig) = generateAllMethods( $ancestor_node, 0, \%javaMethods, $node, 0, \%addImport ); + $methodCode .= $meth; + $interfaceCode .= $interf; + $proxyInterfaceCode .= $proxyInterf; + } + } + + if ( $className eq 'Qt' or $className eq 'KDE' ) { + my $globalSpace = kdocAstUtil::findRef( $rootnode, $main::globalSpaceClassName ); + my ($meth, $interf, $proxyInterf, $sig) = generateAllMethods( $globalSpace, 0, \%javaMethods, $node, 0, \%addImport ); + $methodCode .= $meth; + $interfaceCode .= $interf; + $proxyInterfaceCode .= $proxyInterf; + } + + $methodNumber = $tempMethodNumber; + + if ( $className eq 'Qt' ) { + print CLASS "import java.io.*;\n"; + print CLASS "import java.text.MessageFormat;\n"; + print CLASS "import java.lang.reflect.*;\n"; + } else { + if ( $className eq 'TQListView' or $className eq 'TQListViewItem' or $className eq 'TQUriDrag' ) { + # Special case these two classes as they have methods that use ArrayList added as 'extras' + print CLASS "import java.util.ArrayList;\n"; + } + print CLASS "import org.kde.qt.Qt;\n"; + } + + if ( kalyptusDataDict::interfacemap($javaClassName) ne () ) { + my $interfaceFile = "$outputdir/" . kalyptusDataDict::interfacemap($javaClassName) . ".java"; + open( INTERFACE, ">$interfaceFile" ) || die "Couldn't create $interfaceFile\n"; + print INTERFACE "//Auto-generated by $0. DO NOT EDIT.\n"; + print INTERFACE "package $packagename;\n\n"; + } + + foreach my $imp (keys %addImport) { + die if $imp eq ''; + # Ignore any imports for classes in the same package as the current class + if ($imp !~ /$packagename/) { + print CLASS "import $imp;\n"; + print INTERFACE "import $imp;\n"; + print SIGNALS "import $imp;\n" unless $signalCode eq '';; + } + } + + if ( kalyptusDataDict::interfacemap($javaClassName) ne () ) { + print INTERFACE "\npublic interface " . kalyptusDataDict::interfacemap($javaClassName) . " {\n"; + print INTERFACE $interfaceCode; + print INTERFACE "}\n"; + close INTERFACE; + } + + my $classdec; + if ($node->{NodeType} eq 'namespace') { + $classdec = "public class $javaClassName {\n"; + $classdec .= "\tprotected Object _proxy = null;\n"; + } elsif ( $#ancestors < 0 ) { + $classdec = "public class $javaClassName implements QtSupport"; + if ( kalyptusDataDict::interfacemap($javaClassName) ne () ) { + $classdec .= ", " . kalyptusDataDict::interfacemap($javaClassName); + } + + $classdec .= " {\n\tprotected Object _proxy = null;\n"; + } else { + $classdec = "public class $javaClassName extends "; + my $ancestor; + foreach $ancestor ( @ancestors ) { + if ( kalyptusDataDict::interfacemap($ancestor) eq () or $ancestor eq @ancestors[$#ancestors] ) { + $ancestor =~ s/^.*:://; + $classdec .= "$ancestor "; + if ( $typeprefix ne 'qt_' and $ancestor =~ /^Q/ ) { + print CLASS "import org.kde.qt.$ancestor;\n"; + } + last; + } + } + + my @implements = (); + if ( $#ancestors >= 1 ) { + foreach $ancestor ( @ancestors ) { + if ( kalyptusDataDict::interfacemap($ancestor) ne () ) { + push(@implements, kalyptusDataDict::interfacemap($ancestor)); + } + } + } + + if ($#implements >= 0) { + $classdec .= "implements "; + $classdec .= join(", ", @implements); + } + + $classdec .= " {\n"; + } + + print CLASS "\n"; + if ( $javaClassName !~ /^Q/ or $signalCode ne '' ) { + my $signalLink = ''; + if ( $signalCode ne '' ) { + print SIGNALS "\npublic interface $javaClassName" . "Signals {\n"; + print SIGNALS $signalCode; + print SIGNALS "}\n"; + close SIGNALS; + + $signalLink = " See {\@link $javaClassName" . "Signals} for signals emitted by $javaClassName\n"; + } + my $docnode = $node->{DocNode}; + print CLASS "/**\n"; + if ( defined $docnode ) { + print CLASS printJavadocComment( $docnode, "", "", $signalLink ) . "\n" + } else { + print CLASS $signalLink; + } + print CLASS "*/\n"; + } + + print CLASS $classdec; + + print CLASS "\tinterface $javaClassName" . "ProxyInterface {\n"; + print CLASS $proxyInterfaceCode; + print CLASS "\t}\n\n"; + + if ( $#ancestors < 0 ) { + print CLASS "\tprotected ", $javaClassName, "(Class[] interfaces, int index) {\n"; + print CLASS "\t\tinterfaces[index] = $javaClassName" . "ProxyInterface.class;\n"; + print CLASS "\t\t_proxy = Proxy.newProxyInstance("; + print CLASS "$javaClassName.class.getClassLoader(),\n"; + print CLASS "\t\t\tinterfaces,\n\t\t\tnew SmokeInvocation(this) );\n\t}\n"; + } else { + print CLASS "\tprivate static Class[] addInterfaces(Class[] interfaces, int index) {\n"; + print CLASS "\t\tinterfaces[index] = $javaClassName" . "ProxyInterface.class;\n"; + print CLASS "\t\treturn interfaces;\n\t}\n"; + + print CLASS "\tprotected ", $javaClassName, "(Class[] interfaces, int index) {\n"; + print CLASS "\t\tsuper(addInterfaces(interfaces, index), index+1);\n\t}\n"; + } + + print CLASS $methodCode; + + if ( $className eq 'Qt' ) { + print CLASS $qtExtras; + } elsif ( $className eq 'TQApplication' ) { + print CLASS $qapplicationExtras; + } elsif ( $className eq 'TQBitmap' ) { + print CLASS $qbitmapExtras; + } elsif ( $className eq 'TQDropEvent' ) { + print CLASS $qdropeventExtras; + } elsif ( $className eq 'TQDragObject' ) { + print CLASS $qdragobjectExtras; + } elsif ( $className eq 'TQObject' ) { + print CLASS $qobjectExtras; + } elsif ( $className eq 'TQListView' ) { + print CLASS $qlistviewExtras; + } elsif ( $className eq 'TQListViewItem' ) { + print CLASS $qlistviewitemExtras; + } elsif ( $className eq 'TQMimeSource' ) { + print CLASS $qmimesourceExtras; + } elsif ( $className eq 'TQWidget' ) { + print CLASS $qwidgetExtras; + } elsif ( $className eq 'TQPaintDevice' ) { + print CLASS $qpaintdeviceExtras; + } elsif ( $className eq 'TQPixmap' ) { + print CLASS $qpixmapExtras; + } elsif ( $className eq 'TQIODevice' ) { + print CLASS $qiodeviceExtras; + } elsif ( $className eq 'TQPointArray' ) { + print CLASS $qpointarrayExtras; + } elsif ( $className eq 'TQUriDrag' ) { + print CLASS $quridragExtras; + } elsif ( $className eq 'KApplication' ) { + print CLASS $kapplicationExtras; + } elsif ( $className eq 'KMainWindow' ) { + print CLASS $kmainwindowExtras; + } + + print CLASS "}\n"; + close CLASS; +} + + +# Generate the prototypes for a method (one per arg with a default value) +# Helper for makeprotos +sub iterproto($$$$$) { + my $classidx = shift; # to check if a class exists + my $method = shift; + my $proto = shift; + my $idx = shift; + my $protolist = shift; + + my $argcnt = scalar @{ $method->{ParamList} } - 1; + if($idx > $argcnt) { + push @$protolist, $proto; + return; + } + if(defined $method->{FirstDefaultParam} and $method->{FirstDefaultParam} <= $idx) { + push @$protolist, $proto; + } + + my $arg = $method->{ParamList}[$idx]->{ArgType}; + + my $typeEntry = findTypeEntry( $arg ); + my $realType = $typeEntry->{realType}; + + # A scalar ? + $arg =~ s/\bconst\b//g; + $arg =~ s/\s+//g; + if($typeEntry->{isEnum} || $allTypes{$realType}{isEnum} || exists $typeunion{$realType} || exists $mungedTypeMap{$arg}) + { + my $id = '$'; # a 'scalar + $id = '?' if $arg =~ /[*&]{2}/; + $id = $mungedTypeMap{$arg} if exists $mungedTypeMap{$arg}; + iterproto($classidx, $method, $proto . $id, $idx + 1, $protolist); + return; + } + + # A class ? + if(exists $classidx->{$realType}) { + iterproto($classidx, $method, $proto . '#', $idx + 1, $protolist); + return; + } + + # A non-scalar (reference to array or hash, undef) + iterproto($classidx, $method, $proto . '?', $idx + 1, $protolist); + return; +} + +# Generate the prototypes for a method (one per arg with a default value) +sub makeprotos($$$) { + my $classidx = shift; + my $method = shift; + my $protolist = shift; + iterproto($classidx, $method, $method->{astNodeName}, 0, $protolist); +} + +# Return the string containing the signature for this method (without return type). +# If the 2nd arg is not the size of $m->{ParamList}, this method returns a +# partial signature (this is used to handle default values). +sub methodSignature($$) { + my $method = shift; + my $last = shift; + my $sig = $method->{astNodeName}; + my @argTypeList; + my $argId = 0; + foreach my $arg ( @{$method->{ParamList}} ) { + last if $argId > $last; + push @argTypeList, $arg->{ArgType}; + $argId++; + } + $sig .= "(". join(", ",@argTypeList) .")"; + $sig .= " const" if $method->{Flags} =~ "c"; + return $sig; +} + +# Return the string containing the java signature for this method (without return type). +# If the 2nd arg is not the size of $m->{ParamList}, this method returns a +# partial signature (this is used to handle default values). +sub javaMethodSignature($$) { + my $method = shift; + my $last = shift; + my $sig = $method->{astNodeName}; + my @argTypeList; + my $argId = 0; + foreach my $arg ( @{$method->{ParamList}} ) { + $argId++; + last if $argId > $last; + push @argTypeList, "arg" . "$argId ". cplusplusToJava( $arg->{ArgType} ); + } + $sig .= "(". join(", ",@argTypeList) .")"; + return $sig; +} + +sub coerce_type($$$$) { + #my $m = shift; + my $union = shift; + my $var = shift; + my $type = shift; + my $new = shift; # 1 if this is a return value, 0 for a normal param + + my $typeEntry = findTypeEntry( $type ); + my $realType = $typeEntry->{realType}; + + my $unionfield = $typeEntry->{typeId}; +# die "$type" unless defined( $unionfield ); + if ( ! defined( $unionfield ) ) { + print STDERR "type field not defined: $type\n"; + return ""; + } + + $unionfield =~ s/t_/s_/; + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + my $code = "$union.$unionfield = "; + if($type =~ /&$/) { + $code .= "(void*)&$var;\n"; + } elsif($type =~ /\*$/) { + $code .= "(void*)$var;\n"; + } else { + if ( $unionfield eq 's_class' + or ( $unionfield eq 's_voidp' and $type ne 'void*' ) + or $type eq 'TQString' ) { # hack + $type =~ s/^const\s+//; + if($new) { + $code .= "(void*)new $type($var);\n"; + } else { + $code .= "(void*)&$var;\n"; + } + } else { + $code .= "$var;\n"; + } + } + + return $code; +} + +# Generate the list of args casted to their real type, e.g. +# (TQObject*)x[1].s_class,(TQEvent*)x[2].s_class,x[3].s_int +sub makeCastedArgList +{ + my @castedList; + my $i = 1; # The args start at x[1]. x[0] is the return value + my $arg; + foreach $arg (@_) { + my $type = $arg; + my $cast; + + my $typeEntry = findTypeEntry( $type ); + my $unionfield = $typeEntry->{typeId}; +# die "$type" unless defined( $unionfield ); + if ( ! defined( $unionfield ) ) { + print STDERR "type field not defined: $type\n"; + return ""; + } + $unionfield =~ s/t_/s_/; + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + my $v .= " arg$i"; + if($type =~ /&$/) { + $cast = "*($type *)"; + } elsif($type =~ /\*$/) { + $cast = "($type)"; + } elsif($type =~ /\(\*\)\s*\(/) { # function pointer ... (*)(...) + $cast = "($type)"; + } else { + if ( $unionfield eq 's_class' + or ( $unionfield eq 's_voidp' and $type ne 'void*' ) + or $type eq 'TQString' ) { # hack + $cast = "*($type *)"; + } else { + $cast = "($type)"; + } + } + push @castedList, "$type$v"; + $i++; + } + return @castedList; +} + + +# Adds the import for node $1 to be imported in $2 if not already there +# Prints out debug stuff if $3 +sub addImportForClass($$$) +{ + my ( $node, $addImport, $debugMe ) = @_; + my $importname = javaImport( $node->{astNodeName} ); +# print " Importing $importname for node name: " . $node->{astNodeName} . "\n"; + # No import needed, so return + return if ( $importname eq '' ); + unless ( defined $addImport->{$importname} ) { + print " Importing $importname\n" if ($debugMe); + $addImport->{$importname} = 1; + if ( kalyptusDataDict::interfacemap($node->{astNodeName}) ) { + $addImport->{$importname . "Interface"} = 1; + } + } + else { print " $importname already imported.\n" if ($debugMe); } +} + +sub checkImportsForObject($$) +{ + my $type = shift; + my $addImport = shift; + + my $debugCI = 0; #$debug + # print "checkImportsForObject $type\n"; + $type =~ s/const\s+//; + my $it = $type; + if (!($it and exists $typeunion{$it}) and $type ne "" + #and $type !~ /&/ # in fact we also want refs, due to the generated code + ) { + $type =~ s/&//; + $type =~ s/[*]//; + print " Detecting an object by value/ref: $type\n" if ($debugCI); + my $node = kdocAstUtil::findRef( $rootnode, $type ); + if ($node and $node->{NodeType} eq "class" ) { + print " NodeType: " . $node->{NodeType} . "\n" if ($debugCI); + addImportForClass( $node, $addImport, $debugCI ); + } + else { + if ( cplusplusToJava($it) eq 'ArrayList' ) { + $addImport->{"java.util.ArrayList"} = 1; + } else { + print " No import found for $type\n" if ($debugCI); + } + } + } +} + +sub generateVirtualMethod($$$$$) +{ + # Generating methods for $class. + # $m: method node. $methodClass: the node of the class in which the method is really declared + # (can be different from $class when the method comes from a super class) + # This is important because of $allMethods, which has no entry for class::method in that case. + + my( $classNode, $signature, $m, $methodClass, $addImport ) = @_; + my $methodCode = ''; # output + my $returnType = $m->{ReturnType}; + return ('', '') if $returnType eq '~'; # skip destructors + + my $className = $classNode->{astNodeName}; + my $flags = $m->{Flags}; + my @argList = @{$m->{ParamList}}; + + print "generateVirtualMethod $className: $signature ($m->{Access})\n" if ($debug); + + # Detect objects returned by value + checkImportsForObject( $returnType, $addImport ) if ($returnType ne 'void'); + + # Generate a matching virtual method in the x_ class + $methodCode .= "\tvirtual $returnType $m->{astNodeName}("; + my $i = 0; + foreach my $arg ( @argList ) { + $methodCode .= ", " if $i++; + $methodCode .= $arg->{ArgType}; + $methodCode .= " x$i"; + + # Detect objects passed by value + checkImportsForObject( $arg->{ArgType}, $addImport ); + } + $methodCode .= ") "; + $methodCode .= "const " if ($flags =~ "c"); + $methodCode .= "\{\n"; + + # Now the code of the method + my $this = $classNode->{BindingDerives} > 0 ? "this" : "xthis"; + + $i++; # Now the number of args + $methodCode .= "\tSmoke::StackItem x[$i];\n"; + $i = 1; + for my $arg (@argList) { + $methodCode .= "\t"; + $methodCode .= coerce_type("x[$i]", "x$i", $arg->{ArgType}, 0); + $i++; + } + + my $sig = $methodClass->{astNodeName} . "::" . $signature; + my $idx = $allMethods{$sig}; +# die "generateVirtualMethod: $className: No method found for $sig\n" if !defined $idx; + if ( !defined $idx ) { + print STDERR "generateVirtualMethod: $className: No method found for $sig\n"; + return ""; + } + + if($flags =~ "p") { # pure virtual + $methodCode .= "\t${libname}_Smoke->binding->callMethod($idx, (void*)$this, x, true /*pure virtual*/);\n"; + } else { + $methodCode .= "\tif(${libname}_Smoke->binding->callMethod($idx, (void*)$this, x)) "; + } + + $returnType = undef if ($returnType eq 'void'); + if($returnType) { + my $arg = $returnType; + my $it = $arg; + my $cast; + my $v = "x[0]"; + my $indent = ($flags =~ "p") ? "\t" : ""; + if($it and exists $typeunion{$it}) { + $v .= ".$typeunion{$it}"; + $cast = "($arg)"; + $methodCode .= "${indent}return $cast$v;\n"; + } else { + $v .= ".s_class"; + if($arg =~ s/&//) { + $cast = "*($arg *)"; + $methodCode .= "${indent}return $cast$v;\n"; + } elsif($arg !~ /\*/) { + unless($flags =~ "p") { + $indent = "\t "; + $methodCode .= "{\n"; + } + # we assume it's a new thing, and handle it + $methodCode .= "${indent}$arg *xptr = ($arg *)$v;\n"; + $methodCode .= "${indent}$arg xret(*xptr);\n"; + $methodCode .= "${indent}delete xptr;\n"; + $methodCode .= "${indent}return xret;\n"; + $methodCode .= "\t}\n" unless $flags =~ "p"; + } else { + $cast = "($arg)"; + $methodCode .= "${indent}return $cast$v;\n"; + } + } + } else { + $methodCode .= "\t" if $flags =~ "p"; + $methodCode .= "return;\n"; + } + if($flags =~ "p") { + $methodCode .= "\t// ABSTRACT\n"; + $methodCode .= " }\n"; + return ( $methodCode ); + } + $methodCode .= "\t"; + if($returnType) { + $methodCode .= "return "; + } + $methodCode .= "$this\->$methodClass->{astNodeName}\::$m->{astNodeName}("; + $i = 0; + for my $arg (@argList) { + $methodCode .= ", " if $i++; + $methodCode .= "x$i"; + } + $methodCode .= ");\n"; + $methodCode .= "\t}\n"; + return ( $methodCode ); +} + +sub generateMethod($$$$$$$) +{ + my( $classNode, $m, $addImport, $ancestorCount, $javaMethods, $mainClassNode, $generateConstructors ) = @_; # input + my $methodCode = ''; # output + my $interfaceCode = ''; # output + my $proxyInterfaceCode = ''; # output + my $signalCode = ''; # output + + my $name = $m->{astNodeName}; # method name + + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + + @heritage = kdocAstUtil::heritage($mainClassNode); + my $mainClassName = join( "::", @heritage ); + + # The javaClassName might be 'TQWidget', while currentClassName is 'TQRangeControl' + # and the TQRangeControl methods are being copied into TQWidget. + my $javaClassName = $mainClassNode->{astNodeName}; + my $currentClassName = $classNode->{astNodeName}; + + my $firstUnknownArgType = 99; + my $returnType = $m->{ReturnType}; + + # Don't use $className here, it's never the fully qualified (A::B) name for a ctor. + my $isConstructor = ($name eq $classNode->{astNodeName} ); + my $isDestructor = ($returnType eq '~'); + + # Don't generate anything for destructors, or constructors for namespaces + return if $isDestructor + or ($classNode->{NodeType} eq 'namespace' and $isConstructor) + or (!$mainClassNode->{CanBeInstanciated} and $m->{Access} =~ /protected/); + + # Rename operator methods 'op_...' + if ( $name =~ /^operator.*/ ) { + $methodNumber++; + $name =~ s/ //; + if (! exists $operatorNames{$name} ) { + return; + } + $name = $operatorNames{$name}; + } + + if ($classNode->{astNodeName} eq $main::globalSpaceClassName) { + my $sourcename = $m->{Source}->{astNodeName}; + # Only put Global methods which came from sources beginning with q into class Qt + if ($javaClassName eq 'Qt' and ( $sourcename !~ /\/q[^\/]*$/ or $sourcename =~ /string.h$/ )) { + return; + } + # ..and any other global methods into KDE + if ($javaClassName eq 'KDE' and $m->{Source}->{astNodeName} =~ /\/q[^\/]*$/) { + return; + } + + if ( $sourcename !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|tdeprint/|tdesu/)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } + if ( $sourcename eq '' ) { + return; + } + } + + if ($returnType eq 'void') { + $returnType = undef; + } else { + # Detect objects returned by value + checkImportsForObject( $returnType, $addImport ); + } + + my $hasDuplicateSignature = 0; + my $isStatic = $m->{Flags} =~ "s"; + my $isPure = $m->{Flags} =~ "p"; + + return if ( $m->{SkipFromSwitch} && $m->{Flags} !~ "p" ); + +# # Skip internal methods, which return unknown types +# # Hmm, the C# bindings have a list of those too. +# return if ( $returnType =~ m/TQGfx\s*\*/ ); +# return if ( $returnType eq 'CGContextRef' ); +# return if ( $returnType eq 'TQWSDisplay *' ); +# # This stuff needs callback, or ** +# return if ( $name eq 'defineIOHandler' or $name eq 'qt_init_internal' ); +# # Skip casting operators, but not == < etc. +# return if ( $name =~ /operator \w+/ ); +# # TQFile's EncoderFn/DecoderFn +# return if ( $name =~ /set[ED][ne]codingFunction/ ); +# # How to implement this? (TQXmlDefaultHandler/TQXmlEntityResolver::resolveEntity, needs A*&) +# return if ( $name eq 'resolveEntity' and $className =~ /^TQXml/ ); +# return if ( $className eq 'TQBitArray' && $m->{Access} eq 'protected' ); + + #print STDERR "Tests passed, generating.\n"; + + + my $argId = 0; + + my @argTypeList=(); + my @javaArgTypeList=(); + my @javaArgList = (); + my @namedArgTypeList=(); + + foreach my $arg ( @{$m->{ParamList}} ) { + $argId++; + + if ( $arg->{ArgName} =~ /^super$|^int$|^env$|^cls$|^obj$|^byte$/ ) { + $arg->{ArgName} = ""; + } + + if ( $arg->{ArgName} =~ /^short$|^long$/ ) { + # Oops looks like a parser error + $arg->{ArgType} = $arg->{ArgName}; + $arg->{ArgName} = ""; + } + + print STDERR " Param ".$arg->{astNodeName}." type: ".$arg->{ArgType}." name:".$arg->{ArgName}." default: ".$arg->{DefaultValue}." java: ".cplusplusToJava($arg->{ArgType})."\n" if ($debug); + + my $argType = $arg->{ArgType}; + my $namedArgType; + my $javaArgType; + my $javaArg; + my $argName; + + if ( cplusplusToJava($argType) eq "" && $firstUnknownArgType > $argId ) { + $firstUnknownArgType = $argId; + } + + $javaArg = ($arg->{ArgName} eq "" ? "arg" . $argId : $arg->{ArgName}); + $namedArgType = $argType . " " . $javaArg; + $javaArgType = cplusplusToJava($argType) . " " . $javaArg; + + push @argTypeList, $argType; + push @javaArgTypeList, $javaArgType; + push @javaArgList, $javaArg; + push @namedArgTypeList, $namedArgType; + + # Detect objects passed by value + checkImportsForObject( $argType, $addImport ); + } + + if ( $name eq 'TQApplication' or ($javaClassName eq 'KCmdLineArgs' and $name eq 'init' and scalar(@javaArgList) > 1) ) { + # Junk the 'int argc' parameter + shift @javaArgTypeList; + shift @javaArgList; + } + + my @castedArgList = makeCastedArgList( @argTypeList ); + + # We iterate as many times as we have default params + my $firstDefaultParam = $m->{FirstDefaultParam}; + $firstDefaultParam = scalar(@argTypeList) unless defined $firstDefaultParam; + my $iterationCount = scalar(@argTypeList) - $firstDefaultParam; + + my $javaReturnType = cplusplusToJava($m->{ReturnType}); + if ( $javaReturnType =~ s/StringBuffer/String/ ) { + ; + } elsif ( $javaReturnType =~ s/String\[\]/ArrayList/ ) { + $addImport->{"java.util.ArrayList"} = 1; + } + + if ($m->{ReturnType} =~ /^int\&/) { + $javaReturnType = 'int'; + } + + if ($javaReturnType eq "") { + $firstUnknownArgType = 0; + } + + print STDERR " ". ($iterationCount+1). " iterations for $name\n" if ($debug); + + my $javaSignature = javaMethodSignature( $m, @argTypeList ); + + if ( defined $javaMethods->{$javaSignature} ) { + $hasDuplicateSignature = 1; + } + + my $docnode = $m->{DocNode}; + if ( $firstUnknownArgType >= 0 && $m->{Access} !~ /signals/ && ! $hasDuplicateSignature + && defined $docnode && ($generateConstructors || !$isConstructor) ) + { + my $javadocComment = printJavadocComment( $docnode, "", "\t", "" ); + $methodCode .= "\t/**" . $javadocComment . "*/\n" unless $javadocComment =~ /^\s*$/; + } + + while($iterationCount >= 0) { + + $javaMethods->{$javaSignature} = 1; + + local($") = ","; + + if($firstUnknownArgType <= scalar(@argTypeList) || $hasDuplicateSignature || ($name =~ /^qObject$/) || $m->{Access} =~ /dcop/ ) { + if ( $firstUnknownArgType <= scalar(@argTypeList) || $m->{Access} =~ /dcop/ ) { + my $failedConversion = "\t// " . $m->{ReturnType} . " $name(@castedArgList[0..$#argTypeList]); >>>> NOT CONVERTED\n"; + if ( $m->{Access} =~ /signals/ ) { + $signalCode .= $failedConversion; + } else { + $methodCode .= $failedConversion; + } + } + } else { + + if ($name eq 'find' and $javaClassName eq 'TQButtonGroup') { + # Can't override a static method find() in TQWidget + $name = "findButton"; + } elsif ( $name eq 'null' ) { + $name = "nil"; + } elsif ( $name eq 'form' and $javaClassName =~ /^HTML/ ) { + $name = "formElement"; + } elsif ( $name eq 'wait' and $javaClassName eq 'KProcess' ) { + $name = "waitThread"; + } elsif ( $name eq 'finalize' and $javaClassName eq 'KMD5' ) { + $name = "finalizeDigest"; + } elsif ( $name eq 'icon' and $javaClassName eq 'TQMessageBox' ) { + $name = "iconId"; + } elsif ( $name eq 'icon' and $javaClassName eq 'KURLBarItemDialog' ) { + $name = "iconName"; + } elsif ( $name eq 'iconText' and $javaClassName eq 'KToolBar' ) { + $name = "iconTextId"; + } elsif ( $name eq 'reset' and $javaClassName eq 'KExtendedSocket' ) { + $name = "resetSocket"; + } elsif ( $name eq 'palette' and $javaClassName eq 'KPaletteTable' ) { + $name = "paletteName"; + } elsif ( $name eq 'size' and $javaClassName eq 'KFontCombo' ) { + $name = "pointSize"; + } elsif ($javaSignature eq "icon()" and $javaClassName eq 'KIconButton') { + $name = "iconName"; + } elsif ($javaSignature eq "close()" and $javaClassName eq 'KDirOperator') { + $name = "closeLoading"; + } elsif ($javaSignature eq "font()" and $javaClassName eq 'KCharSelect') { + $name = "fontName"; + } elsif ($javaSignature eq "layout()" and $javaReturnType eq 'void') { + $name = "updateLayout"; + } elsif ( $name eq 'sorting' and $javaReturnType eq 'boolean' ) { + $name = "sortOnInsert"; + } + + my $javaparams = join( ", ", @javaArgTypeList ); + my $cplusplusparams; + my $i = 0; + for my $arg (@argTypeList) { + $cplusplusparams .= "," if $i++; + $cplusplusparams .= "arg" . $i; + } + + if ($isConstructor) { + if ( $generateConstructors && $mainClassNode->{CanBeInstanciated} ) { + $proxyInterfaceCode .= "\t\tvoid new$javaClassName($javaparams);\n"; + $methodCode .= "\tpublic $javaClassName($javaparams) {\n"; + if ( $ancestorCount > 0 ) { + # $methodCode .= ", $superClassName" . "Interface.class, $superClassName" . "ProtectedInterface.class"; + $methodCode .= "\t\tsuper(new Class[] {$javaClassName" . "ProxyInterface.class"; + my @super = direct_superclass_list($classNode); + for my $s (@super) { + $methodCode .= ", null"; + } + $methodCode .= " }, 1);\n"; + } else { + $methodCode .= "\t\tthis(new Class[] { null }, 0);\n"; + } + + # $methodCode .= " },\n\t\t\tnew SmokeInvocation(this, "; + $methodCode .= "\t\tnew$javaClassName(@javaArgList[0..$#javaArgTypeList]);\n"; + $methodCode .= "\t}\n"; + + $methodCode .= "\tprotected void new$javaClassName($javaparams) {\n"; + $methodCode .= "\t\tproxy$javaClassName().new$javaClassName(@javaArgList[0..$#javaArgTypeList]);\n"; + $methodCode .= "\t}\n"; + } + } else { + my $access = $m->{Access}; + $access =~ s/_slots//; + + if ( $access eq 'public' or $access eq 'protected' ) { + if ( $name =~ /^takeItem$|^setPixmap$|^clearCell$|^setItem$|^item$|^minimumSize$/ + or $name =~ /^stepUp$|^stepDown$|^sectionFormattedText$|^addNumber$|^removeLastNumber$/ + or $name =~ /^cancel$|^setSource$|^paintCell$|^updateContents$|^sizeHint$|^setFocusSection$/ + or $name =~ /^event$|^eventFilter$|^copy$|^detach$|^showEvent$|^format$|^encodedData$/ + or $name =~ /^styleChange$|^insertItem$|^setStatus$|^setState$|^minimumSizeHint$/ + or $name =~ /^updateGeometry$|^setState$|^exec$|^pixmap$|^areaPoints$|^draw$|^writeDir$/ ) { + # These methods are public in some places, but protected in others, + # so make them all public. + $access = "public"; + } + + + $methodCode .= "\t" . $access . (($isStatic or $classNode->{NodeType} eq 'namespace') ? " static " : " "); +# $methodCode .= ( $m->{Flags} =~ "v" || $isStatic ? "" : "final " ); + + my $altReturnType = undef; + if ($name =~ /^xForm$/ ) { + $javaReturnType = "Object"; + } elsif ($javaSignature eq "layout()" and $javaReturnType ne 'void') { + $altReturnType = "TQLayout"; + } elsif ($javaSignature eq "defaultFactory()" and $javaReturnType eq 'TQSqlEditorFactory') { + $javaReturnType = "TQEditorFactory"; + } elsif ($javaSignature eq "statusBar()") { + $altReturnType = "TQStatusBar"; + } elsif ($javaSignature eq "menuBar()") { + $altReturnType = "TQMenuBar"; + } elsif ($javaSignature =~ /^bits|^scanLine/) { + $javaReturnType = "byte[]"; + } elsif ($javaSignature eq "at()" and $javaClassName eq 'KFilterDev') { + $javaReturnType = "long"; + } elsif ($javaSignature =~ /copyTo/ and $javaClassName eq "KDesktopFile" ) { + $altReturnType = "KConfig"; + } + + if ( defined $altReturnType ) { + checkImportsForObject( $altReturnType, $addImport ); + $javaReturnType = $altReturnType; + } + + if ($access eq 'public' && ! $isStatic) { + $interfaceCode .= "\t\t$javaReturnType $name($javaparams);\n"; + } + + $proxyInterfaceCode .= "\t\t$javaReturnType $name($javaparams);\n"; + + $methodCode .= $javaReturnType; + $methodCode .= " $name($javaparams) \{\n"; + + $methodCode .= "\t\t" . ($javaReturnType ne "void" ? "return " : ""); + $methodCode .= (($isStatic or $classNode->{NodeType} eq 'namespace') ? "static" : "proxy") . "$javaClassName().$name(@javaArgList[0..$#javaArgTypeList]);\n"; + $methodCode .= "\t}\n"; + } else { + if ( $access =~ /signals/ ) { + my $docnode = $m->{DocNode}; + if ( defined $docnode ) { + my $javadocComment = printJavadocComment( $docnode, "", "\t", "" ); + $signalCode .= "\t/**" . $javadocComment . "*/\n" unless $javadocComment =~ /^\s*$/; + } + $signalCode .= "\tvoid $name($javaparams);\n"; + } + } + } + } + + pop @argTypeList; + pop @javaArgTypeList; + pop @javaArgList; + + $javaSignature = javaMethodSignature( $m, @argTypeList ); + $hasDuplicateSignature = (defined $javaMethods->{$javaSignature} ? 1 : 0); + + $methodNumber++; + $iterationCount--; + } # Iteration loop + + return ( $methodCode, $interfaceCode, $proxyInterfaceCode, $signalCode ); +} + + +sub generateEnum($$$) +{ + my( $classNode, $m, $generateAnonymous ) = @_; # input + my $methodCode = ''; # output + + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + my $javaClassName = $classNode->{astNodeName}; + + if ( ($generateAnonymous and $m->{astNodeName} ) or (! $generateAnonymous and ! $m->{astNodeName}) ) { + return; + } + + if ( defined $m->{DocNode} ) { + my $javadocComment = printJavadocComment( $m->{DocNode}, "", "\t", "" ); + $methodCode .= "\t/**" . $javadocComment . "*/\n" unless $javadocComment =~ /^\s*$/; + } + + my @enums = split(",", $m->{Params}); + my $enumCount = 0; + foreach my $enum ( @enums ) { + $enum =~ s/\s//g; + $enum =~ s/::/./g; + $enum =~ s/\(mode_t\)//; + if ( $enum =~ /(.*)=([-0-9]+)$/ ) { + $methodCode .= "\tpublic static final int $1 = $2;\n"; + $enumCount = $2; + $enumCount++; + } elsif ( $enum =~ /(.*)=(.*)/ ) { + $methodCode .= "\tpublic static final int $1 = $2;\n"; + } else { + $methodCode .= "\tpublic static final int $enum = $enumCount;\n"; + $enumCount++; + } + } + + $methodCode .= "\n"; + $methodNumber++; + + return ( $methodCode ); +} + +sub generateVar($$$) +{ + my( $classNode, $m, $addImport ) = @_; # input + my $methodCode = ''; # output + my $interfaceCode = ''; # output + + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + my $javaClassName = $classNode->{astNodeName}; + + my $name = $m->{astNodeName}; + my $varType = $m->{Type}; + $varType =~ s/static\s//; + $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/\s*$//; + my $fullName = "$className\::$name"; + + checkImportsForObject( $varType, $addImport ); + +# die "Invalid index for $fullName: $classNode->{case}{$fullName} instead of $methodNumber" if $classNode->{case}{$fullName} != $methodNumber; +# $methodCode .= " static void x_$methodNumber(Smoke::Stack x) {\n"; +# $methodCode .= "\tx[0].s_class = (void*)new $varType($fullName);\n"; +# $methodCode .= " }\n"; + +# if ( ($name !~ /^null$/) && (cplusplusToJava($varType) ne "") ) { + if ( ($name !~ /^null$/) && (cplusplusToJava($varType) ne "" ) ) { +# $interfaceCode .= "\t\t". cplusplusToJava($varType) . " $name();\n"; + +# $methodCode .= "\tpublic native static ". cplusplusToJava($varType) . " $name();\n"; + } + + $methodNumber++; + return ( $methodCode, $interfaceCode ); +} + +## Called by writeClassDoc +sub generateAllMethods($$$$$$) +{ + my ($classNode, $ancestorCount, $javaMethods, $mainClassNode, $generateConstructors, $addImport) = @_; + my $methodCode = ''; + my $interfaceCode = ''; + my $proxyInterfaceCode = ''; + my $signalCode = ''; + $methodNumber = 0; + #my $className = $classNode->{astNodeName}; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + my $javaClassName = $mainClassNode->{astNodeName}; + # If the C++ class had multiple inheritance, then the code for all but one of the + # parents must be copied into the code for javaClassName. Hence, for TQWidget current + # classname might be TQPaintDevice, as its methods are needed in TQWidget. + my $currentClassName = join( ".", kdocAstUtil::heritage($classNode) ); + + my $sourcename = $classNode->{Source}->{astNodeName}; + + if ( $sourcename !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|tdeprint/|tdesu/)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } + die "Empty source name for $classNode->{astNodeName}" if ( $sourcename eq '' ); + + if ($generateConstructors) { + $methodCode .= " \tprivate $javaClassName" . "ProxyInterface proxy$javaClassName() {\n"; + $methodCode .= " \t\treturn ($javaClassName". "ProxyInterface) _proxy;\n\t}\n"; + + $methodCode .= " \tprivate static Object _static_proxy = null;\n"; + $methodCode .= "\tstatic {\n"; + $methodCode .= "\t\t_static_proxy = Proxy.newProxyInstance("; + $methodCode .= "$javaClassName.class.getClassLoader(),\n"; + $methodCode .= "\t\t\tnew Class[] { $javaClassName" . "ProxyInterface.class"; + $methodCode .= " },\n\t\t\tnew SmokeInvocation() );\n"; + $methodCode .= "\t}\n\n"; + + $methodCode .= " \tprivate static $javaClassName" . "ProxyInterface static$javaClassName() {\n"; + $methodCode .= " \t\treturn ($javaClassName". "ProxyInterface) _static_proxy;\n\t}\n"; + } + + if ($classNode->{astNodeName} ne $main::globalSpaceClassName) { +# my $s; +# for my $sn( @{$classNode->{Sources}} ) { +# if ( ($s = $sn->{astNodeName}) !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|tdeprint/|tdesu/)(.*)!$1$2!m ) { +# $s =~ s!.*/(.*)!$1!m; +# } +# $addInclude->{$s} = 1; +# } + } + + $addImport->{"org.kde.qt.QtSupport"} = 1; + + # Do all enums first, anonymous ones and then named enums + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'enum' and $currentClassName eq $javaClassName ) { + my ($meth) = generateEnum( $classNode, $methodNode, 1 ); + $methodCode .= $meth; + } + }, undef ); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'enum' and $currentClassName eq $javaClassName ) { + my ($meth) = generateEnum( $classNode, $methodNode, 0 ); + $methodCode .= $meth; + } + }, undef ); + + # Then all static vars + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'var' and $currentClassName eq $javaClassName ) { + my ($meth, $interface) = generateVar( $classNode, $methodNode, $addImport ); + $methodCode .= $meth; +# $interfaceCode .= $interface; + } + }, undef ); + + # Then all methods + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'method' ) { + my ($meth, $interface, $proxyInterface, $signals) = generateMethod( $classNode, $methodNode, $addImport, $ancestorCount, $javaMethods, $mainClassNode, $generateConstructors ); + $methodCode .= $meth; + $interfaceCode .= $interface; + $proxyInterfaceCode .= $proxyInterface; + $signalCode .= $signals; + } + }, undef ); + + # Virtual methods +# if ($classNode->{BindingDerives}) { +# my %virtualMethods; +# allVirtualMethods( $classNode, \%virtualMethods ); + +# for my $sig (sort keys %virtualMethods) { +# my ($meth) = generateVirtualMethod( $classNode, $sig, $virtualMethods{$sig}{method}, $virtualMethods{$sig}{class}, \%addImport ); +# $methodCode .= $meth; +# } +# } + + # Destructor + # "virtual" is useless, if the base class has a virtual destructor then the x_* class too. + #if($classNode->{HasVirtualDestructor} and $classNode->{HasDestructor}) { + # $methodCode .= " virtual ~$bridgeClassName() {}\n"; + #} + # We generate a dtor though, because we might want to add stuff into it + + if ($currentClassName eq $javaClassName and $classNode->{CanBeInstanciated} and $classNode->{HasPublicDestructor}) { + if ( $generateConstructors ) { + $methodCode .= "\tprotected void finalize() throws InternalError {\n"; + $methodCode .= "\t\tproxy$javaClassName().dispose();\n\t}\n"; + + $proxyInterfaceCode .= "\t\tvoid dispose();\n"; + $methodCode .= "\tpublic void dispose() {\n"; + $methodCode .= "\t\tproxy$javaClassName().dispose();\n\t}\n"; + + $proxyInterfaceCode .= "\t\tboolean isDisposed();\n"; + $methodCode .= "\tpublic boolean isDisposed() {\n"; + $methodCode .= "\t\treturn proxy$javaClassName().isDisposed();\n\t}\n"; + } +# die "$className destructor: methodNumber=$methodNumber != case entry=".$classNode->{case}{"~$className()"}."\n" +# if $methodNumber != $classNode->{case}{"~$className()"}; + $methodNumber++; + } + + return ( $methodCode, $interfaceCode, $proxyInterfaceCode, $signalCode ); +} + +# Return 0 if the class has no virtual dtor, 1 if it has, 2 if it's private +sub hasVirtualDestructor($) +{ + my ( $classNode ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if ( $skippedClasses{$className} ); + + my $parentHasIt; + # Look at ancestors, and (recursively) call hasVirtualDestructor for each + # It's enough to have one parent with a prot/public virtual dtor + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + my $vd = hasVirtualDestructor( $_[0] ); + $parentHasIt = $vd unless $parentHasIt > $vd; + } ); + return $parentHasIt if $parentHasIt; # 1 or 2 + + # Now look in $classNode - including private methods + my $doPrivate = $main::doPrivate; + $main::doPrivate = 1; + my $result; + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + return unless( $m->{NodeType} eq "method" && $m->{ReturnType} eq '~' ); + + if ( $m->{Flags} =~ /[vp]/ ) { + if ( $m->{Access} =~ /private/ ) { + $result=2; # private virtual + } else { + $result=1; # [protected or public] virtual + } + } + }, + undef + ); + $main::doPrivate = $doPrivate; + $result=0 if (!defined $result); + return $result; +} + +=head2 allVirtualMethods + + Parameters: class node, dict + + Adds to the dict, for all method nodes that are virtual, in this class and in parent classes : + {method} the method node, {class} the class node (the one where the virtual is implemented) + +=cut + +sub allVirtualMethods($$) +{ + my ( $classNode, $virtualMethods ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if ( $skippedClasses{$className} ); + + # Look at ancestors, and (recursively) call allVirtualMethods for each + # This is done first, so that virtual methods that are reimplemented as 'private' + # can be removed from the list afterwards (below) + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + allVirtualMethods( @_[0], $virtualMethods ); + }, undef + ); + + # Now look for virtual methods in $classNode - including private ones + my $doPrivate = $main::doPrivate; + $main::doPrivate = 1; + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + # Only interested in methods, and skip destructors + return unless( $m->{NodeType} eq "method" && $m->{ReturnType} ne '~' ); + + my $signature = methodSignature( $m, $#{$m->{ParamList}} ); + print STDERR $signature . " ($m->{Access})\n" if ($debug); + + # A method is virtual if marked as such (v=virtual p=pure virtual) + # or if a parent method with same signature was virtual + if ( $m->{Flags} =~ /[vp]/ or defined $virtualMethods->{$signature} ) { + if ( $m->{Access} =~ /private/ ) { + if ( defined $virtualMethods->{$signature} ) { # remove previously defined + delete $virtualMethods->{$signature}; + } + # else, nothing, just ignore private virtual method + } else { + $virtualMethods->{$signature}{method} = $m; + $virtualMethods->{$signature}{class} = $classNode; + } + } + }, + undef + ); + $main::doPrivate = $doPrivate; +} + +# Known typedef? If so, apply it. +sub applyTypeDef($) +{ + my $type = shift; + # Parse 'const' in front of it, and '*' or '&' after it + my $prefix = $type =~ s/^const\s+// ? 'const ' : ''; + my $suffix = $type =~ s/\s*([\&\*]+)$// ? $1 : ''; + + if (exists $typedeflist{$type}) { + return $prefix.$typedeflist{$type}.$suffix; + } + return $prefix.$type.$suffix; +} + +# Register type ($1) into %allTypes if not already there +sub registerType($$) { + my $type = shift; + #print "registerType: $type\n" if ($debug); + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + return if ( $type eq 'void' or $type eq '' or $type eq '~' ); + die if ( $type eq '...' ); # ouch + + # Let's register the real type, not its known equivalent + #$type = applyTypeDef($type); + + # Enum _value_ -> get corresponding type + if (exists $enumValueToType{$type}) { + $type = $enumValueToType{$type}; + } + + # Already in allTypes + if(exists $allTypes{$type}) { + return; + } + + die if $type eq 'TQTextEdit::UndoRedoInfo::Type'; + die if $type eq ''; + + my $realType = $type; + + # Look for references (&) and pointers (* or **) - this will not handle *& correctly. + # We do this parsing here because both the type list and iterproto need it + if($realType =~ s/&$//) { + $allTypes{$type}{typeFlags} = 'Smoke::tf_ref'; + } + elsif($realType ne 'void*' && $realType =~ s/\*$//) { + $allTypes{$type}{typeFlags} = 'Smoke::tf_ptr'; + } + else { + $allTypes{$type}{typeFlags} = 'Smoke::tf_stack'; + } + + if ( $realType =~ s/^const\s+// ) { # Remove 'const' + $allTypes{$type}{typeFlags} .= ' | Smoke::tf_const'; + } + + # Apply typedefs, and store the resulting type. + # For instance, if $type was Q_UINT16&, realType will be ushort + $allTypes{$type}{realType} = applyTypeDef( $realType ); + + # In the first phase we only create entries into allTypes. + # The values (indexes) are calculated afterwards, once the list is full. + $allTypes{$type}{index} = -1; + #print STDERR "Register $type. Realtype: $realType\n" if($debug); +} + +# Get type from %allTypes +# This returns a hash with {index}, {isEnum}, {typeFlags}, {realType} +# (and {typeId} after the types array is written by writeSmokeDataFile) +sub findTypeEntry($) { + my $type = shift; + my $typeIndex = -1; + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + return undef if ( $type =~ '~' or $type eq 'void' or $type eq '' ); + + # Enum _value_ -> get corresponding type + if (exists $enumValueToType{$type}) { + $type = $enumValueToType{$type}; + } + + die "type not known: $type" unless defined $allTypes{$type}; + return $allTypes{ $type }; +} + +# List of all java super-classes for a given class, via single inheritance. +# Excluding any which are mapped onto interfaces to avoid multiple inheritance. +sub direct_superclass_list($) +{ + my $classNode = shift; + my @super; + my $has_ancestor = 0; + my $direct_ancestor = undef; + my $name; + + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + ( $direct_ancestor, $name ) = @_; + if ($name =~ /TQMemArray|TQSqlFieldInfoList/) { + # Template classes, give up for now.. + $has_ancestor = 1; + } elsif (kalyptusDataDict::interfacemap($name) eq "") { + push @super, $direct_ancestor; + push @super, direct_superclass_list( $direct_ancestor ); + $has_ancestor = 1; + } + }, undef ); + + if (! $has_ancestor and defined $direct_ancestor) { + push @super, $direct_ancestor; + push @super, direct_superclass_list( $direct_ancestor ); + } + + return @super; +} + +# List of all super-classes for a given class +sub superclass_list($) +{ + my $classNode = shift; + my @super; + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + push @super, @_[0]; + push @super, superclass_list( @_[0] ); + }, undef ); + return @super; +} + +sub is_kindof($$) +{ + my $classNode = shift; + my $className = shift; + + if ($classNode->{astNodeName} eq $className) { + return 1; + } + + my @superclasses = superclass_list($classNode); + foreach my $ancestor (@superclasses) { + if ($ancestor->{astNodeName} eq $className) { + return 1; + } + } + + return 0; +} + +# Store the {case} dict in the class Node (method signature -> index in the "case" switch) +# This also determines which methods should NOT be in the switch, and sets {SkipFromSwitch} for them +sub prepareCaseDict($) { + + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + $classNode->AddProp("case", {}); + my $methodNumber = 0; + + # First look at all enums for this class + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'enum'; + foreach my $val ( @{$m->{ParamList}} ) { + my $fullEnumName = "$className\::".$val->{ArgName}; + print STDERR "Enum: $fullEnumName -> case $methodNumber\n" if ($debug); + $classNode->{case}{$fullEnumName} = $methodNumber; + $enumValueToType{$fullEnumName} = "$className\::$m->{astNodeName}"; + $methodNumber++; + } + }, undef ); + + # Check for static vars + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'var'; + my $name = "$className\::".$m->{astNodeName}; + print STDERR "Var: $name -> case $methodNumber\n" if ($debug); + $classNode->{case}{$name} = $methodNumber; + $methodNumber++; + + }, undef ); + + + # Now look at all methods for this class + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'method'; + my $name = $m->{astNodeName}; + my $isConstructor = ($name eq $classNode->{astNodeName} ); + if ($isConstructor and ($m->{ReturnType} eq '~')) # destructor + { + # Remember whether we'll generate a switch entry for the destructor + $m->{SkipFromSwitch} = 1 unless ($classNode->{CanBeInstanciated} and $classNode->{HasPublicDestructor}); + next; + } + + # Don't generate bindings for protected methods (incl. signals) if + # we're not deriving from the C++ class. Only take public and public_slots + my $ok = ( $classNode->{BindingDerives} or $m->{Access} =~ /public/ ) ? 1 : 0; + + # Don't generate bindings for pure virtuals - we can't call them ;) + $ok = 0 if ( $ok && $m->{Flags} =~ "p" ); + + # Bugfix for Qt-3.0.4: those methods are NOT implemented (report sent). + $ok = 0 if ( $ok && $className eq 'TQLineEdit' && ( $name eq 'setPasswordChar' || $name eq 'passwordChar' ) ); + $ok = 0 if ( $ok && $className eq 'TQWidgetItem' && $name eq 'widgetSizeHint' ); + + if ( !$ok ) + { + #print STDERR "Skipping $className\::$name\n" if ($debug); + $m->{SkipFromSwitch} = 1; + next; + } + + my @args = @{ $m->{ParamList} }; + my $last = $m->{FirstDefaultParam}; + $last = scalar @args unless defined $last; + my $iterationCount = scalar(@args) - $last; + while($iterationCount >= 0) { + my $sig = methodSignature( $m, $#args ); + $classNode->{case}{$sig} = $methodNumber; + #print STDERR "prepareCaseDict: registered case number $methodNumber for $sig in $className()\n" if ($debug); + pop @args; + $iterationCount--; + $methodNumber++; + } + }, undef ); + + # Add the destructor, at the end + if ($classNode->{CanBeInstanciated} and $classNode->{HasPublicDestructor}) { + $classNode->{case}{"~$className()"} = $methodNumber; + # workaround for ~Sub::Class() being seen as Sub::~Class() + $classNode->{case}{"~$classNode->{astNodeName}()"} = $methodNumber; + #print STDERR "prepareCaseDict: registered case number $methodNumber for ~$className()\n" if ($debug); + } +} + +sub writeSmokeDataFile($) { + my $rootnode = shift; + + # Make list of classes + my %allImports; # list of all header files for all classes + my @classlist; + push @classlist, ""; # Prepend empty item for "no class" + my %enumclasslist; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = $_[0]; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + push @classlist, $className; + $enumclasslist{$className}++ if keys %{$classNode->{enumerations}}; + $classNode->{ClassIndex} = $#classlist; + addImportForClass( $classNode, \%allImports, undef ); + } ); + + my %classidx = do { my $i = 0; map { $_ => $i++ } @classlist }; + + my $file = "$outputdir/smokedata.cpp"; +# open OUT, ">$file" or die "Couldn't create $file\n"; + +# foreach my $incl (sort{ +# return 1 if $a=~/qmotif/; # move qmotif* at bottom (they include dirty X11 headers) +# return -1 if $b=~/qmotif/; +# return -1 if substr($a,0,1) eq 'q' and substr($b,0,1) ne 'q'; # move Qt headers on top +# return 1 if substr($a,0,1) ne 'q' and substr($b,0,1) eq 'q'; +# $a cmp $b +# } keys %allIncludes) { +# die if $imp eq ''; +# print OUT "import $imp;\n"; +# } + +# print OUT "\n"; + + print STDERR "Writing ${libname}_cast function\n" if ($debug); + + # Prepare descendants information for each class + my %descendants; # classname -> list of descendant nodes + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + # Get _all_ superclasses (up any number of levels) + # and store that $classNode is a descendant of $s + my @super = superclass_list($classNode); + for my $s (@super) { + my $superClassName = join( "::", kdocAstUtil::heritage($s) ); + Ast::AddPropList( \%descendants, $superClassName, $classNode ); + } + } ); + + # Iterate over all classes, to write the xtypecast function + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + # @super will contain superclasses, the class itself, and all descendants + my @super = superclass_list($classNode); + push @super, $classNode; + if ( defined $descendants{$className} ) { + push @super, @{$descendants{$className}}; + } + my $cur = $classidx{$className}; + + return if $classNode->{NodeType} eq 'namespace'; + +# print OUT " case $cur:\t//$className\n"; +# print OUT "\tswitch(to) {\n"; +# $cur = -1; +# my %casevalues; +# for my $s (@super) { +# my $superClassName = join( "::", kdocAstUtil::heritage($s) ); +# next if !defined $classidx{$superClassName}; # inherits from unknown class, see below +# next if $classidx{$superClassName} == $cur; # shouldn't happen in Qt +# next if $s->kdocAstUtil::inheritsAsVirtual($classNode); # can't cast from a virtual base class +# $cur = $classidx{$superClassName}; # KDE has MI with diamond shaped cycles (cf. KXMLGUIClient) +# next if $casevalues{$cur}; # ..so skip any duplicate parents +# print OUT "\t case $cur: return (void*)($superClassName*)($className*)xptr;\n"; +# $casevalues{$cur} = 1; +# } +# print OUT "\t default: return xptr;\n"; +# print OUT "\t}\n"; + } ); +# print OUT " default: return xptr;\n"; +# print OUT " }\n"; +# print OUT "}\n\n"; + + + # Write inheritance array + # Imagine you have "Class : public super1, super2" + # The inheritlist array will get 3 new items: super1, super2, 0 + my %inheritfinder; # key = (super1, super2) -> data = (index in @inheritlist). This one allows reuse. + my %classinherit; # we store that index in %classinherit{className} + # We don't actually need to store inheritlist in memory, we write it + # directly to the file. We only need to remember its current size. + my $inheritlistsize = 1; + +# print OUT "// Group of class IDs (0 separated) used as super class lists.\n"; +# print OUT "// Classes with super classes have an index into this array.\n"; +# print OUT "static short ${libname}_inheritanceList[] = {\n"; +# print OUT "\t0,\t// 0: (no super class)\n"; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "__", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + print STDERR "inheritanceList: looking at $className\n" if ($debug); + + # Make list of direct ancestors + my @super; + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + my $superClassName = join( "::", kdocAstUtil::heritage($_[0]) ); + push @super, $superClassName; + }, undef ); + # Turn that into a list of class indexes + my $key = ''; + foreach my $superClass( @super ) { + if (defined $classidx{$superClass}) { + $key .= ', ' if ( length $key > 0 ); + $key .= $classidx{$superClass}; + } + } + if ( $key ne '' ) { + if ( !defined $inheritfinder{$key} ) { + print OUT "\t"; + my $index = $inheritlistsize; # Index of first entry (for this group) in inheritlist + foreach my $superClass( @super ) { + if (defined $classidx{$superClass}) { + print OUT "$classidx{$superClass}, "; + $inheritlistsize++; + } + } + $inheritlistsize++; + my $comment = join( ", ", @super ); + print OUT "0,\t// $index: $comment\n"; + $inheritfinder{$key} = $index; + } + $classinherit{$className} = $inheritfinder{$key}; + } else { # No superclass + $classinherit{$className} = 0; + } + } ); +# print OUT "};\n\n"; + + +# print OUT "// These are the xenum functions for manipulating enum pointers\n"; + for my $className (keys %enumclasslist) { + my $c = $className; + $c =~ s/::/__/g; +# print OUT "void xenum_$c\(Smoke::EnumOperation, Smoke::Index, void*&, long&);\n"; + } +# print OUT "\n"; +# print OUT "// Those are the xcall functions defined in each x_*.cpp file, for dispatching method calls\n"; + my $firstClass = 1; + for my $className (@classlist) { + if ($firstClass) { + $firstClass = 0; + next; + } + my $c = $className; # make a copy + $c =~ s/::/__/g; +# print OUT "void xcall_$c\(Smoke::Index, void*, Smoke::Stack);\n"; + } +# print OUT "\n"; + + # Write class list afterwards because it needs offsets to the inheritance array. +# print OUT "// List of all classes\n"; +# print OUT "// Name, index into inheritanceList, method dispatcher, enum dispatcher, class flags\n"; +# print OUT "static Smoke::Class ${libname}_classes[] = {\n"; + my $firstClass = 1; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "__", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + if ($firstClass) { + $firstClass = 0; + print OUT "\t{ 0L, 0, 0, 0, 0 }, \t// 0 (no class)\n"; + } + my $c = $className; + $c =~ s/::/__/g; + my $xcallFunc = "xcall_$c"; + my $xenumFunc = "0"; + $xenumFunc = "xenum_$c" if exists $enumclasslist{$className}; + # %classinherit needs Foo__Bar, not Foo::Bar? + die "problem with $className" unless defined $classinherit{$c}; + + my $xClassFlags = 0; + $xClassFlags .= "|Smoke::cf_constructor" if $classNode->{CanBeInstanciated}; # correct? + $xClassFlags .= "|Smoke::cf_deepcopy" if $classNode->{CanBeCopied}; # HasCopyConstructor would be wrong (when it's private) + $xClassFlags .= "|Smoke::cf_virtual" if hasVirtualDestructor($classNode) == 1; + # $xClassFlags .= "|Smoke::cf_undefined" if ...; + $xClassFlags =~ s/0\|//; # beautify +# print OUT "\t{ \"$className\", $classinherit{$c}, $xcallFunc, $xenumFunc, $xClassFlags }, \t//$classidx{$className}\n"; + } ); +# print OUT "};\n\n"; + + +# print OUT "// List of all types needed by the methods (arguments and return values)\n"; +# print OUT "// Name, class ID if arg is a class, and TypeId\n"; +# print OUT "static Smoke::Type ${libname}_types[] = {\n"; + my $typeCount = 0; + $allTypes{''}{index} = 0; # We need an "item 0" + for my $type (sort keys %allTypes) { + $allTypes{$type}{index} = $typeCount; # Register proper index in allTypes + if ( $typeCount == 0 ) { +# print OUT "\t{ 0, 0, 0 },\t//0 (no type)\n"; + $typeCount++; + next; + } + my $isEnum = $allTypes{$type}{isEnum}; + my $typeId; + my $typeFlags = $allTypes{$type}{typeFlags}; + my $realType = $allTypes{$type}{realType}; + die "$type" if !defined $typeFlags; +# die "$realType" if $realType =~ /\(/; + # First write the name +# print OUT "\t{ \"$type\", "; + # Then write the classId (and find out the typeid at the same time) + if(exists $classidx{$realType}) { # this one first, we want t_class for TQBlah* + $typeId = 't_class'; +# print OUT "$classidx{$realType}, "; + } + elsif($type =~ /&$/ || $type =~ /\*$/) { + $typeId = 't_voidp'; +# print OUT "0, "; # no classId + } + elsif($isEnum || $allTypes{$realType}{isEnum}) { + $typeId = 't_enum'; + if($realType =~ /(.*)::/) { + my $c = $1; + if($classidx{$c}) { +# print OUT "$classidx{$c}, "; + } else { +# print OUT "0 /* unknown class $c */, "; + } + } else { +# print OUT "0 /* unknown $realType */, "; # no classId + } + } + else { + $typeId = $typeunion{$realType}; + if (defined $typeId) { + $typeId =~ s/s_/t_/; # from s_short to t_short for instance + } + else { + # Not a known class - ouch, this happens quite a lot + # (private classes, typedefs, template-based types, etc) + if ( $skippedClasses{$realType} ) { +# print STDERR "$realType has been skipped, using t_voidp for it\n"; + } else { + unless( $realType =~ / map to a void * + } +# print OUT "0, "; # no classId + } + # Then write the flags + die "$type" if !defined $typeId; +# print OUT "Smoke::$typeId | $typeFlags },"; +# print OUT "\t//$typeCount\n"; + $typeCount++; + # Remember it for coerce_type + $allTypes{$type}{typeId} = $typeId; + } +# print OUT "};\n\n"; + + + my %arglist; # registers the needs for argumentList (groups of type ids) + my %methods; + # Look for all methods and all enums, in all classes + # And fill in methods and arglist. This loop writes nothing to OUT. + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + print STDERR "writeSmokeDataFile: arglist: looking at $className\n" if ($debug); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + my $methName = $m->{astNodeName}; + # For destructors, get a proper signature that includes the '~' + if ( $m->{ReturnType} eq '~' ) + { + $methName = '~' . $methName ; + # Let's even store that change, otherwise we have to do it many times + $m->{astNodeName} = $methName; + } + + if( $m->{NodeType} eq "enum" ) { + + foreach my $enum ( @{$m->{ParamList}} ) { + my $enumName = $enum->{ArgName}; + $methods{$enumName}++; + } + + } elsif ( $m->{NodeType} eq 'var' ) { + + $methods{$m->{astNodeName}}++; + + } elsif( $m->{NodeType} eq "method" ) { + + $methods{$methName}++; + my @protos; + makeprotos(\%classidx, $m, \@protos); + + #print "made @protos from $className $methName $m->{Signature})\n" if ($debug); + for my $p (@protos) { + $methods{$p}++; + my $argcnt = 0; + $argcnt = length($1) if $p =~ /([\$\#\?]+)/; + my $sig = methodSignature($m, $argcnt-1); + # Store in a class hash named "proto", a proto+signature => method association + $classNode->{proto}{$p}{$sig} = $m; + #$classNode->{signature}{$sig} = $p; + # There's probably a way to do this better, but this is the fastest way + # to get the old code going: store classname into method + $m->{class} = $className; + } + + my $firstDefaultParam = $m->{FirstDefaultParam}; + $firstDefaultParam = scalar(@{ $m->{ParamList} }) unless defined $firstDefaultParam; + my $argNames = ''; + my $args = ''; + for(my $i = 0; $i < @{ $m->{ParamList} }; $i++) { + $args .= ', ' if $i; + $argNames .= ', ' if $i; + my $argType = $m->{ParamList}[$i]{ArgType}; + my $typeEntry = findTypeEntry( $argType ); + $args .= defined $typeEntry ? $typeEntry->{index} : 0; + $argNames .= $argType; + + if($i >= ($firstDefaultParam - 1)) { + #print "arglist entry: $args\n"; + $arglist{$args} = $argNames; + } + + } + # create an entry for e.g. "arg0,arg1,arg2" where argN is index in allTypes of type for argN + # The value, $argNames, is temporarily stored, to be written out as comment + # It gets replaced with the index in the next loop. + #print "arglist entry : $args\n"; + $arglist{$args} = $argNames; + } + }, # end of sub + undef + ); + }); + + + $arglist{''} = 0; + # Print arguments array +# print OUT "static Smoke::Index ${libname}_argumentList[] = {\n"; + my $argListCount = 0; + for my $args (sort keys %arglist) { + my @dunnohowtoavoidthat = split(',',$args); + my $numTypes = $#dunnohowtoavoidthat; + if ($args eq '') { +# print OUT "\t0,\t//0 (void)\n"; + } else { + # This is a nice trick : args can be written in one go ;) +# print OUT "\t$args, 0,\t//$argListCount $arglist{$args} \n"; + } + $arglist{$args} = $argListCount; # Register proper index in argList + $argListCount += $numTypes + 2; # Move forward by as much as we wrote out + } +# print OUT "};\n\n"; + + $methods{''} = 0; + my @methodlist = sort keys %methods; + my %methodidx = do { my $i = 0; map { $_ => $i++ } @methodlist }; + +# print OUT "// Raw list of all methods, using munged names\n"; +# print OUT "static const char *${libname}_methodNames[] = {\n"; + my $methodNameCount = $#methodlist; + for my $m (@methodlist) { +# print OUT qq( "$m",\t//$methodidx{$m}\n); + } +# print OUT "};\n\n"; + +# print OUT "// (classId, name (index in methodNames), argumentList index, number of args, method flags, return type (index in types), xcall() index)\n"; +# print OUT "static Smoke::Method ${libname}_methods[] = {\n"; + my @methods; + %allMethods = (); + my $methodCount = 0; + # Look at all classes and all enums again + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if $classNode->{NodeType} eq 'namespace'; + + my $classIndex = $classidx{$className}; + print STDERR "writeSmokeDataFile: methods: looking at $className\n" if ($debug); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + if( $m->{NodeType} eq "enum" ) { + + foreach my $enum ( @{$m->{ParamList}} ) { + my $enumName = $enum->{ArgName}; + my $fullEnumName = "$className\::$enumName"; + my $sig = "$className\::$enumName\()"; + my $xmethIndex = $methodidx{$enumName}; + die "'Method index' for enum $sig not found" unless defined $xmethIndex; + my $typeId = findTypeEntry( $fullEnumName )->{index}; + die "enum has no {case} value in $className: $fullEnumName" unless defined $classNode->{case}{$fullEnumName}; +# print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullEnumName}},\t//$methodCount $fullEnumName (enum)\n"; + $allMethods{$sig} = $methodCount; + print STDERR "Added entry for " . $sig . " into \$allMethods\n" if ($debug); + $methods[$methodCount] = { + c => $classIndex, + methIndex => $xmethIndex, + argcnt => '0', + args => 0, + retTypeIndex => 0, + idx => $classNode->{case}{$fullEnumName} + }; + $methodCount++; + } + + } elsif( $m->{NodeType} eq 'var' ) { + + my $name = $m->{astNodeName}; + my $fullName = "$className\::$name"; + my $sig = "$fullName\()"; + my $xmethIndex = $methodidx{$name}; + die "'Method index' for var $sig not found" unless defined $xmethIndex; + my $varType = $m->{Type}; + $varType =~ s/static\s//; + $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/\s*$//; + my $typeId = findTypeEntry( $varType )->{index}; + die "var has no {case} value in $className: $fullName" unless defined $classNode->{case}{$fullName}; +# print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullName}},\t//$methodCount $fullName (static var)\n"; + $allMethods{$sig} = $methodCount; + print STDERR "Added entry for " . $sig . " into \$allMethods\n" if ($debug); + $methods[$methodCount] = { + c => $classIndex, + methIndex => $xmethIndex, + argcnt => '0', + args => 0, + retTypeIndex => 0, + idx => $classNode->{case}{$fullName} + }; + $methodCount++; + + + } elsif( $m->{NodeType} eq "method" ) { + + # We generate a method entry only if the method is in the switch() code + # BUT: for pure virtuals, they need to have a method entry, even though they + # do NOT have a switch code. + return if ( $m->{SkipFromSwitch} && $m->{Flags} !~ "p" ); + + # No switch code for destructors if we didn't derive from the class (e.g. it has private ctors only) + return if ( $m->{ReturnType} eq '~' && ! ( $classNode->{BindingDerives} and $classNode->{HasPublicDestructor}) ); + + # Is this sorting really important? + #for my $m (sort {$a->{name} cmp $b->{name}} @{ $self->{$c}{method} }) { + + my $methName = $m->{astNodeName}; + my $def = $m->{FirstDefaultParam}; + $def = scalar(@{ $m->{ParamList} }) unless defined $def; + my $last = scalar(@{ $m->{ParamList} }) - 1; + #print STDERR "writeSmokeDataFile: methods: generating for method $methName, def=$def last=$last\n" if ($debug); + + while($last >= ($def-1)) { + last if $last < -1; + my $args = [ @{ $m->{ParamList} }[0..$last] ]; + my $sig = methodSignature($m, $last); + #my $methodSig = $classNode->{signature}{$sig}; # Munged signature + #print STDERR "writeSmokeDataFile: methods: sig=$className\::$sig methodSig=$methodSig\n" if ($debug); + #my $methodIndex = $methodidx{$methodSig}; + #die "$methodSig" if !defined $methodIndex; + + my $methodIndex = $methodidx{$methName}; + die "$methName" if !defined $methodIndex; + my $case = $classNode->{case}{$sig}; + my $typeEntry = findTypeEntry( $m->{ReturnType} ); + my $retTypeIndex = defined $typeEntry ? $typeEntry->{index} : 0; + + my $i = 0; + my $t = ''; + for my $arg (@$args) { + $t .= ', ' if $i++; + my $typeEntry = findTypeEntry( $arg->{ArgType} ); + $t .= defined $typeEntry ? $typeEntry->{index} : 0; + } + my $arglist = $t eq '' ? 0 : $arglist{$t}; + die "arglist for $t not found" unless defined $arglist; + if ( $m->{Flags} =~ "p" ) { + # Pure virtuals don't have a {case} number, that's normal + die if defined $case; + $case = -1; # This remains -1, not 0 ! + } else { + ; +# die "$className\::$methName has no case number for sig=$sig" unless defined $case; + } + my $argcnt = $last + 1; + my $methodFlags = '0'; + $methodFlags .= "|Smoke::mf_static" if $m->{Flags} =~ "s"; + $methodFlags .= "|Smoke::mf_const" if $m->{Flags} =~ "c"; # useful?? probably not + $methodFlags =~ s/0\|//; # beautify + +# print OUT "\t{$classIndex, $methodIndex, $arglist, $argcnt, $methodFlags, $retTypeIndex, $case},\t//$methodCount $className\::$sig"; +# print OUT " [pure virtual]" if ( $m->{Flags} =~ "p" ); # explain why $case = -1 ;) +# print OUT "\n"; + + $allMethods{$className . "::" . $sig} = $methodCount; + $methods[$methodCount] = { + c => $classIndex, + methIndex => $methodIndex, + argcnt => $argcnt, + args => $arglist, + retTypeIndex => $retTypeIndex, + idx => $case + }; + $methodCount++; + $last--; + } # while + } # if method + } ); # Method Iter + } ); # Class Iter +# print OUT "};\n\n"; + + my @protos; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + my $classIndex = $classidx{$className}; + print STDERR "writeSmokeDataFile: protos: looking at $className\n" if ($debug); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + if( $m->{NodeType} eq "enum" ) { + foreach my $enum ( @{$m->{ParamList}} ) { + my $enumName = $enum->{ArgName}; + my $sig = "$className\::$enumName\()"; + my $xmeth = $allMethods{$sig}; + die "'Method' for enum $sig not found" unless defined $xmeth; + my $xmethIndex = $methodidx{$enumName}; + die "'Method index' for enum $enumName not found" unless defined $xmethIndex; + push @protos, { + methIndex => $xmethIndex, + c => $classIndex, + over => { + $sig => { + sig => $sig, + } + }, + meth => $xmeth + }; + } + + } elsif( $m->{NodeType} eq 'var' ) { + + my $name = $m->{astNodeName}; + my $fullName = "$className\::$name"; + my $sig = "$fullName\()"; + my $xmeth = $allMethods{$sig}; + die "'Method' for var $sig not found" unless defined $xmeth; + my $xmethIndex = $methodidx{$name}; + die "'Method index' for var $name not found" unless defined $xmethIndex; + push @protos, { + methIndex => $xmethIndex, + c => $classIndex, + over => { + $sig => { + sig => $sig, + } + }, + meth => $xmeth + }; + + } + }); + + for my $p (keys %{ $classNode->{proto} }) { + # For each prototype + my $scratch = { %{ $classNode->{proto}{$p} } }; # sig->method association + # first, grab all the superclass voodoo + for my $supNode (superclass_list($classNode)) { + my $i = $supNode->{proto}{$p}; + next unless $i; + for my $k (keys %$i) { + $scratch->{$k} = $i->{$k} unless exists $scratch->{$k}; + } + } + + # Ok, now we have a full list + #if(scalar keys %$scratch > 1) { + #print STDERR "Overload: $p (@{[keys %$scratch]})\n" if ($debug); + #} + my $xmethIndex = $methodidx{$p}; + my $classIndex = $classidx{$className}; + for my $sig (keys %$scratch) { + #my $xsig = $scratch->{$sig}{class} . "::" . $sig; + my $xsig = $className . "::" . $sig; + $scratch->{$sig}{sig} = $xsig; + delete $scratch->{$sig} + if $scratch->{$sig}{Flags} =~ "p" # pure virtual + or not exists $allMethods{$xsig}; + } + push @protos, { + methIndex => $xmethIndex, + c => $classIndex, + over => $scratch + } if scalar keys %$scratch; + } + }); + + my @protolist = sort { $a->{c} <=> $b->{c} || $a->{methIndex} <=> $b->{methIndex} } @protos; +#for my $abc (@protos) { +#print "$abc->{methIndex}.$abc->{c}\n"; +#} + + print STDERR "Writing methodmap table\n" if ($debug); + my @resolve = (); +# print OUT "// Class ID, munged name ID (index into methodNames), method def (see methods) if >0 or number of overloads if <0\n"; + my $methodMapCount = 1; +# print OUT "static Smoke::MethodMap ${libname}_methodMaps[] = {\n"; +# print OUT "\t{ 0, 0, 0 },\t//0 (no method)\n"; + for my $cur (@protolist) { + if(scalar keys %{ $cur->{over} } > 1) { +# print OUT "\t{$cur->{c}, $cur->{methIndex}, -@{[1+scalar @resolve]}},\t//$methodMapCount $classlist[$cur->{c}]\::$methodlist[$cur->{methIndex}]\n"; + $methodMapCount++; + for my $k (keys %{ $cur->{over} }) { + my $p = $cur->{over}{$k}; + my $xsig = $p->{class} ? "$p->{class}\::$k" : $p->{sig}; + push @resolve, { k => $k, p => $p, cur => $cur, id => $allMethods{$xsig} }; + } + push @resolve, 0; + } else { + for my $k (keys %{ $cur->{over} }) { + my $p = $cur->{over}{$k}; + my $xsig = $p->{class} ? "$p->{class}\::$k" : $p->{sig}; +# print OUT "\t{$cur->{c}, $cur->{methIndex}, $allMethods{$xsig}},\t//$methodMapCount $classlist[$cur->{c}]\::$methodlist[$cur->{methIndex}]\n"; + $methodMapCount++; + } + } + } +# print OUT "};\n\n"; + + + print STDERR "Writing ambiguousMethodList\n" if ($debug); +# print OUT "static Smoke::Index ${libname}_ambiguousMethodList[] = {\n"; +# print OUT " 0,\n"; + for my $r (@resolve) { + unless($r) { +# print OUT " 0,\n"; + next; + } + my $xsig = $r->{p}{class} ? "$r->{p}{class}\::$r->{k}" : $r->{p}{sig}; + die "ambiguousMethodList: no method found for $xsig\n" if !defined $allMethods{$xsig}; +# print OUT " $allMethods{$xsig}, // $xsig\n"; + } +# print OUT "};\n\n"; + +# print OUT "extern \"C\" { // needed?\n"; +# print OUT " void init_${libname}_Smoke();\n"; +# print OUT "}\n"; +# print OUT "\n"; +# print OUT "Smoke* qt_Smoke = 0L;\n"; +# print OUT "\n"; +# print OUT "// Create the Smoke instance encapsulating all the above.\n"; +# print OUT "void init_${libname}_Smoke() {\n"; +# print OUT " qt_Smoke = new Smoke(\n"; +# print OUT " ${libname}_classes, ".$#classlist.",\n"; +# print OUT " ${libname}_methods, $methodCount,\n"; +# print OUT " ${libname}_methodMaps, $methodMapCount,\n"; +# print OUT " ${libname}_methodNames, $methodNameCount,\n"; +# print OUT " ${libname}_types, $typeCount,\n"; +# print OUT " ${libname}_inheritanceList,\n"; +# print OUT " ${libname}_argumentList,\n"; +# print OUT " ${libname}_ambiguousMethodList,\n"; +# print OUT " ${libname}_cast );\n"; +# print OUT "}\n"; +# close OUT; + +#print "@{[keys %allMethods ]}\n"; +} +=head2 printJavadocComment + + Parameters: docnode filehandle + + Converts a kdoc comment to javadoc format. + @ref's are converted to @link's; @p's and @em's are converted + to inline HTML. + +=cut + +sub printJavadocComment($$$$) +{ + my( $docnode, $name, $indent, $signalLink ) = @_; + + my $node; + my $returntext = ''; + foreach $node ( @{$docnode->{Text}} ) { + next if $node->{NodeType} ne "DocText" and $node->{NodeType} ne "ListItem" + and $node->{NodeType} ne "Param"; + my $line = ''; + + if ($node->{NodeType} eq "Param") { + if ($node->{Name} !~ /argc/) { + $line = "\@param " . $node->{Name} . " " . $node->{astNodeName}; + } + } else { + $line = $node->{astNodeName}; + } + $line =~ s/argc, ?argv/args/g; + $line =~ s/int argc, ?char ?\* ?argv(\[\])?/String[] args/g; + $line =~ s/int argc, ?char ?\*\* ?argv/String[] args/g; + if ($node->{NodeType} eq "Param") { + $line =~ s/(const )?QC?StringList(\s*&)?/String[]/g; + } else { + $line =~ s/(const )?QC?StringList(\s*&)?/ArrayList/g; + } + $line =~ s/NodeList|KTrader::OfferList/ArrayList/g; + $line =~ s/(const )?TQDate(Time)?(\s*&)?/Calendar/g; + $line =~ s/(const )?TQTime([^r])/Date$1/g; + $line =~ s/TQString::null/null/g; + $line =~ s/(const )?QC?String(\s*&)?/String/g; + $line =~ s/TQByteArray/byte[]/g; + $line =~ s/(const )?KCmdLineOptions\s*(\w+)\[\]/String[][] $2/; + $line =~ s/KCmdLineLastOption//g; + $line =~ s/virtual //g; + $line =~ s/~\w+\(\)((\s*{\s*})|;)//g; + $line =~ s/0L/null/g; + $line =~ s/(\([^\)]*\))\s*:\s*\w+\([^\)]*\)/$1/g; + $line =~ s/\(void\)//g; + $line =~ s/const char/String/g; + $line =~ s/const (\w+)\&/$1/g; + $line =~ s/bool/boolean/g; + $line =~ s/SLOT\(\s*([^\)]*)\) ?\)/SLOT("$1)")/g; + $line =~ s/SIGNAL\(\s*([^\)]*)\) ?\)/SIGNAL("$1)")/g; + $line =~ s/Q_OBJECT\n//g; + $line =~ s/class\s+([\w]+)\s*:\s*public/public class $1 implements/g; + $line =~ s/public\s*(slots)?:\n/public /g; + $line =~ s/([^0-9"]\s*)\*(\s*[^0-9"-])/$1$2/g; + $line =~ s/^(\s*)\*/$1/g; + $line =~ s/\n \*/\n /g; + $line =~ s/\@ref\s+([\w]+)::([\w]+)\s*(\([^\)]*\))(\.)?/{\@link $1#$2}$4/g; + $line =~ s/\@ref\s+#([\w:]+)(\(\))?/{\@link #$1}/g; + $line =~ s/\@ref\s+([\w]+)\s*(\([^\)]*\))/{\@link #$1}/g; + $line =~ s/\@ref\s+([\w]+)::([\w]+)/{\@link $1#$2}/g; + $line =~ s/\@ref\s+([a-z][\w]+)/{\@link #$1}/g; + $line =~ s/\@ref\s+([\w]+)/{\@link $1}/g; + while ($line =~ /\@c\s+([\w#\\\.<>]+)/ ) { + my $code = $1; + $code =~ s!!>!g; + $code =~ s!\\#!#!g; + $line =~ s!\@c\s+([\w#\\\.<>]+)!$code!; + } + $line =~ s!\@em\s+(\w+)!$1!g; + $line =~ s!\@p\s+([\w\._]*)!$1!g; + $line =~ s!\\paragraph\s+[\w]+\s([\w]+)!
  • $1
  • !g; + $line =~ s!\\b\s+([\w -]+)\\n!
  • $1
  • !g; + $line =~ s!\\c\s+([\w\@&\\?;-]+)!$1!g; + $line =~ s!\\p\s+([\w\@]+)!
    $1
    !g; + $line =~ s!\\li\s+([\w\@]+)!
  • $1
  • !g; + $line =~ s!([\w\t \(\)-]*:?)\\n!
  • $1
  • !g; + $line =~ s!static_cast<\s*([\w\.]*)\s*>!($1)!g; + if ($name ne "") { + $line =~ s/\@link #/\@link $name\#/g; + } + + if ($node->{NodeType} eq "ListItem") { + $line =~ s/^/\n
  • \n/; + $line =~ s!$!\n
  • !; + $line =~ s/\n/\n$indent\t/g; + } else { + $line =~ s/^/$indent/; + $line =~ s/\n/\n$indent/g; + } + + $line =~ s/\n/\n$indent/g; + $returntext .= $line; + } + + $returntext .= $signalLink; + + if ( defined $docnode->{Returns} ) { + my $text = $docnode->{Returns}; + $text =~ s/TQString::null/null/g; + $returntext .= "\t\t\@return $text\n"; + } + + if ( defined $docnode->{Author} ) { + $returntext .= "\t\t\@author " . $docnode->{Author} . "\n" + } + + if ( defined $docnode->{Version} ) { + my $versionStr = $docnode->{Version}; + $versionStr =~ s/\$\s*Id:([^\$]*) Exp \$/$1/; + $returntext .= "\t\t\@version $versionStr\n"; + } + + if ( defined $docnode->{ClassShort} ) { + my $shortText = $docnode->{ClassShort}; + $shortText =~ s![\*\n]! !g; + $returntext .= "\t\t\@short $shortText\n"; + } + + if ( defined $docnode->{See} ) { + foreach my $text ( @{$docnode->{See}} ) { + next if ($text =~ /TQString|^\s*and\s*$|^\s*$|^[^\w]*$/); + $text =~ s/KIO:://g; + $text =~ s/KParts:://g; + $text =~ s/bool/boolean/g; + $text =~ s/::/#/g; + $text =~ s/->/#/g; + $text =~ s/\./#/g; + $text =~ s/\(\)//g; + $text =~ s/^\s*([a-z].*)/#$1/g; + $text =~ s/^\s*Q/org.kde.qt.Q/g; +# $text =~ s/^\s*K/org.kde.koala.K/g; + $returntext .= "\t\t\@see $text\n"; + } + } + + $returntext =~ s/DOM#([A-Z])/$1/g; + $returntext =~ s/KIO#([A-Z])/$1/g; + $returntext =~ s/KParts#([A-Z])/$1/g; + $returntext =~ s/const\s+(\w+)\s*\&/$1/g; + $returntext =~ s/TQChar/char/g; + $returntext =~ s/TQStringList/ArrayList/g; + $returntext =~ s/([Aa]) ArrayList/$1n ArrayList/g; + $returntext =~ s/TQString/String/g; + $returntext =~ s/KCmdLineOptions/String[][]/; + $returntext =~ s!\\note!Note:<\b>!g; + $returntext =~ s!\\(code|verbatim)!
    !g;
    +	$returntext =~ s!\\(endcode|endverbatim)!
    !g; + $returntext =~ s!\\addtogroup\s+[\w]+\s+"([^"\@]+)"\s+\@{!
  • $1
  • !g; + $returntext =~ s![\\\@]relates\s+([a-z][\w]*)!{\@link #$1}!g; + $returntext =~ s![\\\@]relates\s+(\w+)::(\w+)!{\@link $1#$2}!g; + $returntext =~ s![\\\@]relates\s+(#?\w+)!{\@link $1}!g; + $returntext =~ s!\\c\s+([\w\@&\\?";-]+)!$1!g; + $returntext =~ s!\@p\s+([\w\._]*)!$1!g; + $returntext =~ s!\@a\s+([:\w]+)!$1!g; + $returntext =~ s![\@\\]b\s+[:\w]!$1!g; + $returntext =~ s/};/}/g; + $returntext =~ s/::/./g; + $returntext =~ s/->/./g; + + $returntext =~ s/\s*$//; + return $returntext . "\n" . $indent; +} + +1; diff --git a/kalyptus/kalyptusCxxToKimono.pm b/kalyptus/kalyptusCxxToKimono.pm new file mode 100644 index 0000000..77e0af8 --- /dev/null +++ b/kalyptus/kalyptusCxxToKimono.pm @@ -0,0 +1,3633 @@ +#*************************************************************************** +# kalyptusCxxToKimono.pm - Generates *.cs files for a Custom RealProxy +# based smoke adaptor +# ------------------- +# begin : Thurs Feb 19 12:00:00 2004 +# copyright : (C) 2004, Richard Dale. All Rights Reserved. +# email : Richard_Dale@tipitina.demon.co.uk +# author : Richard Dale, based on the SMOKE generation code +#***************************************************************************/ + +#/*************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License as published by * +# * the Free Software Foundation; either version 2 of the License, or * +# * (at your option) any later version. * +# * * +#***************************************************************************/ + +package kalyptusCxxToKimono; + +use File::Path; +use File::Basename; + +use Carp; +use Ast; +use kdocAstUtil; +use kdocUtil; +use Iter; +use kalyptusDataDict; + +use strict; +no strict "subs"; + +use vars qw/ + $libname $rootnode $outputdir $opt $debug + $qapplicationExtras $qbitmapExtras $qbytearrayExtras + $qlistviewExtras $qlistviewitemExtras + $qdragobjectExtras $qdropeventExtras $qmimesourceExtras + $qtExtras $qobjectExtras $qwidgetExtras + $qpixmapExtras $qpaintdeviceExtras + $qdragobjectExtras $qiodeviceExtras $qpointarrayExtras + $qtextcodecExtras $qsizepolicyExtras $quridragExtras + $kapplicationExtras $kmainwindowExtras + $methodNumber + %builtins %typeunion %allMethods %allTypes %enumValueToType %typedeflist %mungedTypeMap %csharpImports + %skippedClasses %operatorNames /; + +BEGIN +{ + +# Types supported by the StackItem union +# Key: C++ type Value: Union field of that type +%typeunion = ( + 'void*' => 's_voidp', + 'bool' => 's_bool', + 'char' => 's_char', + 'uchar' => 's_uchar', + 'short' => 's_short', + 'ushort' => 's_ushort', + 'int' => 's_int', + 'uint' => 's_uint', + 'long' => 's_long', + 'ulong' => 's_ulong', + 'float' => 's_float', + 'double' => 's_double', + 'enum' => 's_enum', + 'class' => 's_class' +); + +# Mapping for iterproto, when making up the munged method names +%mungedTypeMap = ( + 'TQString' => '$', + 'TQString*' => '$', + 'TQString&' => '$', + 'TQCString' => '$', + 'TQCString*' => '$', + 'TQCString&' => '$', + 'char*' => '$', + 'TQCOORD*' => '?', + 'TQRgb*' => '?', + 'Q_UINT64' => '$', + 'Q_INT64' => '$', + 'Q_LLONG' => '$', + 'tquint64' => '$', + 'qint64' => '$', + 'long long' => '$', + 'qulonglong' => '$', +); + +# Yes some of this is in kalyptusDataDict's ctypemap +# but that one would need to be separated (builtins vs normal classes) +%typedeflist = +( + 'signed char' => 'char', + 'unsigned char' => 'uchar', + 'signed short' => 'short', + 'unsigned short' => 'ushort', + 'signed' => 'int', + 'signed int' => 'int', + 'unsigned' => 'uint', + 'unsigned int' => 'uint', + 'KIO::filesize_t' => 'long', + 'signed long' => 'long', + 'unsigned long' => 'ulong', + +# Anything that is not known is mapped to void*, so no need for those here anymore +# 'TQWSEvent*' => 'void*', +# 'TQDiskFont*' => 'void*', +# 'XEvent*' => 'void*', +# 'FILE*' => 'void*', +# 'TQUnknownInterface*' => 'void*', +# 'GDHandle' => 'void*', +# '_NPStream*' => 'void*', +# 'TQTextFormat*' => 'void*', +# 'TQTextDocument*' => 'void*', +# 'TQTextCursor*' => 'void*', +# 'TQTextParag**' => 'void*', +# 'TQTextParag*' => 'void*', +# 'TQRemoteInterface*' => 'void*', +# 'TQSqlRecordPrivate*' => 'void*', +# 'TQTSMFI' => 'void*', # TQTextStream's TQTSManip +# 'const GUID&' => 'void*', +# 'TQWidgetMapper*' => 'void*', +# 'MSG*' => 'void*', +# 'const TQSqlFieldInfoList&' => 'void*', # TQSqlRecordInfo - TODO (templates) + + 'TQStyleHintReturn*' => 'void*', + 'TQPtrCollection::Item' => 'void*', # to avoid a warning + + 'mode_t' => 'long', + 'TQProcess::PID' => 'long', + 'size_type' => 'int', # TQSqlRecordInfo + 'TQt::ComparisonFlags' => 'uint', + 'TQt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it + 'TQIODevice::Offset' => 'ulong', + 'WState' => 'int', + 'WId' => 'ulong', + 'TQRgb' => 'uint', + 'ksocklen_t' => 'uint', + 'TQCOORD' => 'int', + 'TQTSMFI' => 'int', + 'TQt::WState' => 'int', + 'TQt::WFlags' => 'int', + 'TQt::HANDLE' => 'uint', + 'TQEventLoop::ProcessEventsFlags' => 'uint', + 'TQStyle::SCFlags' => 'int', + 'TQStyle::SFlags' => 'int', + 'Q_INT16' => 'short', + 'qint16' => 'short', + 'Q_INT32' => 'int', + 'qint32' => 'int', + 'qint32&' => 'int&', + 'Q_INT8' => 'char', + 'qint8' => 'char', + 'Q_LONG' => 'long', + 'Q_UINT16' => 'ushort', + 'tquint16' => 'ushort', + 'Q_UINT32' => 'uint', + 'tquint32' => 'uint', + 'Q_UINT8' => 'uchar', + 'tquint8' => 'uchar', + 'Q_ULONG' => 'long', + 'qreal' => 'double', + 'pid_t' => 'int', + 'size_t' => 'int', + 'pid_t' => 'int', + 'time_t' => 'int', + 'short int' => 'short', + 'signed long int' => 'long', + 'unsigned long int' => 'ulong', + 'unsigned short int' => 'ushort', + 'TQt::Alignment' => 'int', + 'TQt::Orientations' => 'int', + 'TQt::DockWidgetAreas' => 'int', + 'TQt::DropActions' => 'int', + 'TQt::ImageConversionFlags' => 'int', + 'TQt::ItemFlags' => 'int', + 'TQt::KeyboardModifiers' => 'int', + 'TQt::MatchFlags' => 'int', + 'TQt::MouseButtons' => 'int', + 'TQt::ToolBarAreas' => 'int', + 'TQt::WindowFlags' => 'int', + 'TQt::WindowStates' => 'int', + 'AutoFormatting' => 'int', + 'DirtyFlags' => 'int', + 'EditTriggers' => 'int', + 'FindFlags' => 'int', + 'Flags' => 'int', + 'FormattingOptions' => 'int', + 'GLenum' => 'int', + 'GLint' => 'int', + 'GLuint' => 'uint', + 'LoadOperator' => 'int', + 'NumberFlags' => 'int', + 'OpenMode' => 'int', + 'Options' => 'int', + 'PaintEngineFeatures' => 'int', + 'Permissions' => 'int', + 'PrintDialogOptions' => 'int', + 'ProcessEventsFlags' => 'int', + 'TQDir::Filters' => 'int', + 'TQDir::SortFlags' => 'int', + 'TQFile::Permissions' => 'int', + 'TQGL::FormatOptions' => 'int', + 'TQIODevice::OpenMode' => 'int', + 'TQImageReader::ImageReaderError' => 'int', + 'TQItemSelectionModel::SelectionFlags' => 'int', + 'TQPaintEngine::DirtyFlags' => 'int', + 'TQPainter::RenderHints' => 'int', + 'TQSql::ParamType' => 'int', + 'TQTextDocument::FindFlags' => 'int', + 'Q_PID' => 'int', + 'TQt::DropActions' => 'int', + 'TQt::ImageConversionFlags' => 'int', + 'TQt::ItemFlags' => 'int', + 'TQt::KeyboardModifiers' => 'int', + 'TQt::MatchFlags' => 'int', + 'TQt::MouseButtons' => 'int', + 'TQt::ToolBarAreas' => 'int', + 'TQt::WindowFlags' => 'int', + 'TQt::WindowStates' => 'int', + 'RenderFlags' => 'int', + 'RenderHints' => 'int', + 'SortFlags' => 'int', + 'StepEnabled' => 'int', + 'Sections' => 'int', + 'Filters' => 'int', + 'SortFlags' => 'int', + 'TQDir::Filters' => 'int', + 'TQDir::SortFlags' => 'int', + 'TQStyle::State' => 'int', + 'TQValidator::State' => 'int', + 'TQAbstractSpinBox::StepEnabled' => 'int', + 'TQDockWidget::DockWidgetFeatures' => 'int', + 'TQStyle::SubControls' => 'int', + 'TQSocket::State' => 'int', +); + +%operatorNames = +( + 'operator^' => 'op_xor', + 'operator^=' => 'op_xor_assign', + 'operator<' => 'op_lt', + 'operator<<' => 'op_write', + 'operator<=' => 'op_lte', + 'operator=' => 'op_assign', + 'operator==' => 'op_equals', + 'operator>' => 'op_gt', + 'operator>=' => 'op_gte', + 'operator>>' => 'op_read', + 'operator|' => 'op_or', + 'operator|=' => 'op_or_assign', + 'operator-' => 'op_minus', + 'operator-=' => 'op_minus_assign', + 'operator--' => 'op_decr', + 'operator!' => 'op_not', + 'operator!=' => 'op_not_equals', + 'operator/' => 'op_div', + 'operator/=' => 'op_div_assign', + 'operator()' => 'op_expr', + 'operator[]' => 'op_at', + 'operator*' => 'op_mult', + 'operator*=' => 'op_mult_assign', + 'operator&' => 'op_and', + 'operator&=' => 'op_and_assign', + 'operator+' => 'op_plus', + 'operator+=' => 'op_plus_assign', + 'operator++' => 'op_incr', +); + + $qapplicationExtras = <|TQValueList|TQValueList|TQValueList|TQValueListConstIterator|TQMap|EditMode|TQPtrList|TQPtrList|TQTextFormat|TQTextCursor|TQTextDocument|TQNetworkProtocolFactoryBase|TQDomNodePrivate|TQSqlDriverCreatorBase|TQSqlFieldInfoList|TQObjectUserData|TQUObject|TQTextParag|TQWidgetMapper|TQMemArray|TQBitArray|TQLayoutIterator|TQAuBucket|TQUnknownInterface|TQConnectionList/ ) { + return ""; # Unsupported type + } elsif ( $cplusplusType =~ /bool/ && kalyptusDataDict::ctypemap($cplusplusType) eq "int" ) { + return "bool"; + } elsif ( $cplusplusType =~ /bool\s*[*&]/ ) { + return "out bool"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^void\s*\*/ ) { + return "int"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^qt_QIntValueList\*/ ) + { + return "int[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^\s*(unsigned )?int\s*\*/ + || $cplusplusType =~ /^int[*&]$/ ) + { + return "out int"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^\s*double\s*\*/ ) { + return "out double"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^\s*(unsigned )?short\s*\*/ ) { + return "out short"; + } elsif ( $cplusplusType =~ /KCmdLineOptions/ ) { + return "string[][]"; + } elsif ( $cplusplusType =~ /char\s*\*\*/ || $cplusplusType =~ /TQStringList/|| $cplusplusType =~ /TQStrList/) { + return "string[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QUrlInfoValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QVariantValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QIconDragItemValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QPixmapValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_QCStringList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QObjectList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QDomNodeList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QWidgetList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KURLList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KMainWindow\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KFileItemList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KFileViewItemList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_DOMNodeList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_StyleSheetList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_MediaList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_OfferList\s*\*/ + || $cplusplusType =~ /TQMemArray/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QCanvasItemList\s*\*/ ) { + return "ArrayList" + } elsif ( $cplusplusType =~ /uchar\s*\*/ ) { + return "char[]"; + } elsif ( $cplusplusType =~ /QC?String/ and !$isConst ) { + return "StringBuilder" + } elsif ( $cplusplusType =~ /(DOM::)?DOMString/ || $cplusplusType =~ /TQString/ || $cplusplusType =~ /TQCString/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /^(const )?char\s*\*/ ) { + return "string" + } elsif ( $cplusplusType =~ /TQChar\s*[&\*]?/ || $cplusplusType =~ /^char$/ ) { + return "char" + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QTime\s*\*/ ) { + return "DateTime" + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QDateTime\s*\*/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QDate\s*\*/ ) { + return "DateTime" + } elsif ( $cplusplusType =~ /TQPaintDevice/ ) { + return "ITQPaintDevice" + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_([^\*\s]*)(.*)$/ and !$skippedClasses{$className}) { + if ( defined interfaceForClass($1) ) { + return interfaceForClass($1); + } else { + return $1; + } + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_([^\*\s]*)(.*)$/ and !$skippedClasses{$className}) { + if ( defined interfaceForClass($1) ) { + return interfaceForClass($1); + } else { + return $1; + } + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /unsigned char/ ) { + return "ushort"; + } elsif ( $typedeflist{$cplusplusType} =~ /ulong/ ) { + return "ulong"; + } elsif ( $typedeflist{$cplusplusType} =~ /long/ ) { + return "long"; + } elsif ( $typedeflist{$cplusplusType} =~ /uint/ ) { + return "uint"; + } elsif ( $typedeflist{$cplusplusType} =~ /int/ or $cplusplusType =~ /^int\&$/ ) { + return "int"; + } elsif ( $typedeflist{$cplusplusType} =~ /ushort/ ) { + return "ushort"; + } elsif ( $typedeflist{$cplusplusType} =~ /short/ ) { + return "short"; + } elsif ( $typedeflist{$cplusplusType} =~ /float/ ) { + return "float"; + } elsif ( $typedeflist{$cplusplusType} =~ /double/ ) { + return "double"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /(unsigned )(.*)/ ) { + return "u" . $2; + } else { + my $node; + my $item; + if ($className =~ /^(\w+)::(\w+)$/) { + $node = kdocAstUtil::findRef( $rootnode, $1 ); + $item = kdocAstUtil::findRef( $node, $2 ) if defined $node; + if (defined $item && $item->{NodeType} eq 'enum') { + if ($2 eq 'Type') { + return "$1.E_$2"; + } else { + return "$1.$2"; + } + + } elsif (defined $item && ($item->{NodeType} eq 'class' || $item->{NodeType} eq 'struct')) { + return $skippedClasses{$className} ? "" : $2; + } + } + + if ($className =~ /^\w+$/) { + $item = kdocAstUtil::findRef( $rootnode, $className ); + if (defined $item && ($item->{NodeType} eq 'class' || $item->{NodeType} eq 'struct')) { + return $skippedClasses{$className} ? "" : $className; + } + } + return kalyptusDataDict::ctypemap($cplusplusType); + } + +} + +sub writeDoc +{ + ( $libname, $rootnode, $outputdir, $opt ) = @_; + + print STDERR "Starting writeDoc for $libname...\n"; + + $debug = $main::debuggen; + + mkpath( $outputdir ) unless -f $outputdir; + + # Define TQPtrCollection::Item, for resolveType + unless ( kdocAstUtil::findRef( $rootnode, "TQPtrCollection::Item" ) ) { + my $cNode = kdocAstUtil::findRef( $rootnode, "TQPtrCollection" ); + warn "TQPtrCollection not found" if (!$cNode); + my $node = Ast::New( 'Item' ); + $node->AddProp( "NodeType", "Forward" ); + $node->AddProp( "Source", $cNode->{Source} ) if ($cNode); + kdocAstUtil::attachChild( $cNode, $node ) if ($cNode); + $node->AddProp( "Access", "public" ); + } + + print STDERR "Preparsing...\n"; + + # Preparse everything, to prepare some additional data in the classes and methods + Iter::LocalCompounds( $rootnode, sub { preParseClass( shift ); } ); + + # Have a look at each class again, to propagate CanBeCopied + Iter::LocalCompounds( $rootnode, sub { propagateCanBeCopied( shift ); } ); + + # Write out smokedata.cpp + writeSmokeDataFile($rootnode); + + print STDERR "Writing *.cs...\n"; + + # Generate *cs file for each class + Iter::LocalCompounds( $rootnode, sub { writeClassDoc( shift ); } ); + + print STDERR "Done.\n"; +} + +=head2 preParseClass + Called for each class +=cut +sub preParseClass +{ + my( $classNode ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + if( $#{$classNode->{Kids}} < 0 || + $classNode->{Access} eq "private" || + $classNode->{Access} eq "protected" || # e.g. TQPixmap::TQPixmapData + exists $classNode->{Tmpl} || + # Don't generate standard bindings for TQString, this class is handled as a native type + $className eq 'TQString' || + $className eq 'TQConstString' || + $className eq 'TQCString' || + $className eq 'TQLatin1String' || + # Don't map classes which are really arrays + $className eq 'TQStringList' || + $className eq 'TQCanvasItemList' || + $className eq 'TQWidgetList' || + $className eq 'TQObjectList' || + $className eq 'TQStrList' || + # Those are template related + $className eq 'TQTSManip' || # cause compiler errors with several gcc versions + $className eq 'TQIconFactory' || + $className eq 'TQGDict' || + $className eq 'TQGList' || + $className eq 'TQGVector' || + $className eq 'TQStrIList' || + $className eq 'TQStrIVec' || + $className eq 'TQBitArray' || + $className eq 'TQWExtra' || + $className eq 'TQTLWExtra' || + ($className eq 'TQAbstractUndoItem' and $main::qt4) || + ($className eq 'TQDebug' and $main::qt4) || + ($className eq 'TQNoDebug' and $main::qt4) || + ($className eq 'TQObjectData' and $main::qt4) || + ($className eq 'TQSysInfo' and $main::qt4) || + ($className eq 'TQPNGImageWriter' and $main::qt4) || + ($className eq 'TQPNGImagePacker' and $main::qt4) || + ($className eq 'TQTextCodec::ConverterState' and $main::qt4) || + ($className eq 'TQTextLayout::Selection' and $main::qt4) || + ($className eq 'TQTextStreamManipulator' and $main::qt4) || + ($className eq 'iterator' and $main::qt4) || + $className eq 'TQMetaEnum::Item' || + $className eq 'TQWidgetContainerPlugin' || + $className eq 'TQGArray::array_data' || + $className eq 'KBookmarkMenu::DynMenuInfo' || + $className eq 'KCompletionMatches' || + $className eq 'KDEDesktopMimeType::Service' || + $className eq 'KGlobalSettings::KMouseSettings' || + $className eq 'KMimeType::Format' || + $className eq 'KNotifyClient::Instance' || + $className eq 'KParts::Plugin::PluginInfo' || + $className eq 'KProtocolInfo::ExtraField' || + $className eq 'KXMLGUIClient::StateChange' || + $className eq 'KIconTheme' || + $className eq 'KEditListBox::CustomEditor' || + $className eq 'KIO::KBookmarkMenuNSImporter' || + $className eq 'KPerDomainSettings' || + $className eq 'KApplicationPropsPlugin' || + $className eq 'KPrinter' || + $className eq 'KPty' || + $className eq 'KOpenWithHandler' || + $className eq 'KFileOpenWithHandler' || + $className eq 'KBindingPropsPlugin' || + $className eq 'KPropsDlgPlugin' || + $className eq 'KFileSharePropsPlugin' || + $className eq 'KBookmarkMenuNSImporter' || + $className eq 'KDevicePropsPlugin' || + $className eq 'KWin::WindowInfo' || + $className eq 'KDEDModule' || + $className eq 'KFileMetaInfoProvider' || + $className eq 'KFileMimeTypeInfo' || + $className eq 'KExecPropsPlugin' || + $className eq 'KFilePermissionsPropsPlugin' || + $className eq 'KImageFilePreview' || + $className eq 'KBookmarkManager' || + $className eq 'KBookmarkNotifier' || + $className eq 'KOCRDialogFactory' || + $className eq 'KExtendedBookmarkOwner' || + $className eq 'KSharedPixmap' || + $className eq 'KSocket' || + $className eq 'KLibrary' || + $className eq 'KScanDialogFactory' || + $className eq 'KDictSpellingHighlighter' || + $className eq 'KPropertiesDialog' || + $className eq 'ProgressItem' || + $className eq 'KIO::ChmodInfo' || + $className eq 'KIO::MetaData' || + $className eq 'KFileMimeTypeInfo::ItemInfo' || + $className eq 'KIO::UDSAtom' || + $className eq 'khtml::DrawContentsEvent' || # the khtml:: classes build, but don't link + $className eq 'khtml::MouseDoubleClickEvent' || + $className eq 'khtml::MouseMoveEvent' || + $className eq 'khtml::MousePressEvent' || + $className eq 'khtml::MouseReleaseEvent' || + $className eq 'khtml::MouseEvent' || + $className eq 'KURL::List' || + $className eq 'KWin::Info' || + $className eq 'TerminalInterface' || + $className eq 'TQForeachContainerBase' || # Qt4 + $className eq 'TQInputMethodEvent::Attribute' || # Qt4 + $className eq 'TQAbstractTextDocumentLayout::PaintContext' || # Qt4 + $className eq 'TQAbstractTextDocumentLayout::Selection' || # Qt4 + $className eq 'TQBrushData' || # Qt4 + $className eq 'TQIPv6Address' || # Qt4 + $className eq 'TQImageTextKeyLang' || # Qt4 + $className eq 'TQMap' || # Qt4 + $className eq 'TQMap::const_iterator' || # Qt4 + $className eq 'TQMap::iterator' || # Qt4 + $className eq 'TQMapData' || # Qt4 + $className eq 'TQMapData::Node' || # Qt4 + $className eq 'TQSharedData' || # Qt4 + $className eq 'TQPainterPath::Element' || # Qt4 + $className eq 'TQThreadStorageData' || # Qt4 + $className eq 'TQVFbHeader' || # Qt4 + $className eq 'TQStyleOptionQ3DockWindow' || # Qt4 + $className eq 'TQStyleOptionQ3ListView' || # Qt4 + $className eq 'TQStyleOptionQ3ListViewItem' || # Qt4 + $className eq 'TQStyleOptionQ3ListView' || # Qt4 + $className eq 'TQTextLayout::FormatRange' || # Qt4 + $className eq 'TQVFbKeyData' || # Qt4 + $className eq 'TQVariant::Handler' || # Qt4 + $className eq 'TQVariant::PrivateShared' || # Qt4 + $className eq 'TQVectorData' || # Qt4 + $className eq 'TQWidgetData' || # Qt4 + $className =~ /.*Private$/ || # Ignore any classes which aren't for public consumption + $className =~ /.*Impl$/ || + $className =~ /.*Internal.*/ || +# $classNode->{Deprecated} || + $classNode->{NodeType} eq 'union' # Skip unions for now, e.g. TQPDevCmdParam + ) { + print STDERR "Skipping $className\n" if ($debug); + print STDERR "Skipping union $className\n" if ( $classNode->{NodeType} eq 'union'); + $skippedClasses{$className} = 1; + delete $classNode->{Compound}; # Cheat, to get it excluded from Iter::LocalCompounds + return; + } + + my $signalCount = 0; + my $eventHandlerCount = 0; + my $defaultConstructor = 'none'; # none, public, protected or private. 'none' will become 'public'. + my $constructorCount = 0; # total count of _all_ ctors + # If there are ctors, we need at least one public/protected one to instanciate the class + my $hasPublicProtectedConstructor = 0; + # We need a public dtor to destroy the object --- ### aren't protected dtors ok too ?? + my $hasPublicDestructor = 1; # by default all classes have a public dtor! + #my $hasVirtualDestructor = 0; + my $hasDestructor = 0; + my $hasPrivatePureVirtual = 0; + my $hasCopyConstructor = 0; + my $hasPrivateCopyConstructor = 0; + # Note: no need for hasPureVirtuals. $classNode{Pure} has that. + + my $doPrivate = $main::doPrivate; + $main::doPrivate = 1; + # Look at each class member (looking for methods and enums in particular) + Iter::MembersByType ( $classNode, undef, + sub { + + my( $classNode, $m ) = @_; + my $name = $m->{astNodeName}; + + if( $m->{NodeType} eq "method" ) { + if ( $m->{ReturnType} eq 'typedef' # TQFile's EncoderFn/DecoderFn callback, very badly parsed + ) { + $m->{NodeType} = 'deleted'; + next; + } + + print STDERR "preParseClass: looking at $className\::$name $m->{Params}\n" if ($debug); + + if ( $name eq $classNode->{astNodeName} ) { + if ( $m->{ReturnType} =~ /~/ ) { + # A destructor + $hasPublicDestructor = 0 if $m->{Access} ne 'public'; + #$hasVirtualDestructor = 1 if ( $m->{Flags} =~ "v" && $m->{Access} ne 'private' ); + $hasDestructor = 1; + } else { + # A constructor + $constructorCount++; + $defaultConstructor = $m->{Access} if ( $m->{Params} eq '' ); + $hasPublicProtectedConstructor = 1 if ( $m->{Access} ne 'private' ); + + # Copy constructor? + if ( $#{$m->{ParamList}} == 0 ) { + my $theArgType = @{$m->{ParamList}}[0]->{ArgType}; + if ($theArgType =~ /$className\s*\&/) { + $hasCopyConstructor = 1; + $hasPrivateCopyConstructor = 1 if ( $m->{Access} eq 'private' ); + } + } + # Hack the return type for constructors, since constructors return an object pointer + $m->{ReturnType} = $className."*"; + } + } + + if ( $name =~ /~$classNode->{astNodeName}/ && $m->{Access} ne "private" ) { # not used + $hasPublicDestructor = 0 if $m->{Access} ne 'public'; + #$hasVirtualDestructor = 1 if ( $m->{Flags} =~ "v" ); + $hasDestructor = 1; + } + + if ( $m->{Flags} =~ "p" && $m->{Access} =~ /private/ ) { + $hasPrivatePureVirtual = 1; # ouch, can't inherit from that one + } + + # All we want from private methods is to check for virtuals, nothing else + next if ( $m->{Access} =~ /private/ ); + + # Don't generate code for deprecated methods, + # or where the code won't compile/link for obscure reasons. Or even obvious reasons.. + if ( ($classNode->{astNodeName} eq 'KCharSelectTable' and $name eq 'paintCell') + || ($classNode->{astNodeName} eq 'KAnimWidget' and $name eq 'KAnimWidget' and @{$m->{ParamList}} == 2) + || ($classNode->{astNodeName} eq 'KDCOPActionProxy' and $name eq 'actions') + || ($classNode->{astNodeName} eq 'KFileDialog' and $name eq 'addDirEntry') + || ($classNode->{astNodeName} eq 'KFileDialog' and $name eq 'getDirEntry') + || ($classNode->{astNodeName} eq 'KFileView' and $name eq 'selectionMode') + || ($classNode->{astNodeName} eq 'KFind' and $name eq 'KFind' and @{$m->{ParamList}} == 4) + || ($classNode->{astNodeName} eq 'KGlobalAccel' and $name eq 'setEnabled') + || ($classNode->{astNodeName} eq 'KCharsets' and $name eq 'encodingsForLanguage') + || ($classNode->{astNodeName} eq 'KInputDialog' and $name eq 'getInteger') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'buildHTMLErrorString') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'checkCachedAuthentication') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'cacheAuthentication') + || ($classNode->{astNodeName} eq 'KInputDialog' and $name eq 'getDouble') + || ($classNode->{astNodeName} eq 'KToolBar' and $name eq 'enable') + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'insert' and @{$m->{ParamList}} == 2) + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'autoupdate') + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'getAutoUpdate') + || ($classNode->{astNodeName} eq 'KStdAccel' and $name eq 'insert') + || ($classNode->{astNodeName} eq 'KBookmarkMenu' and $name eq 'invalid') + || ($classNode->{astNodeName} eq 'KCharsets' and $name eq 'languages') + || ($classNode->{astNodeName} eq 'KCombiView' and $name eq 'setDropOptions') + || ($classNode->{astNodeName} eq 'KFileMetaInfoItem' and $name eq 'unit') + || ($classNode->{astNodeName} eq 'KInstance' and $name eq 'charsets') + || ($classNode->{astNodeName} eq 'KInstance' and $name eq 'KInstance' and $m->{Access} =~ /protected/) + || ($classNode->{astNodeName} eq 'KKey' and $name eq 'isValidQt') + || ($classNode->{astNodeName} eq 'KKey' and $name eq 'isValidNative') + || ($classNode->{astNodeName} eq 'KKeySequence' and $name eq 'init') + || ($classNode->{astNodeName} eq 'KKeySequence' and $name eq 'setTriggerOnRelease') + || ($classNode->{astNodeName} eq 'KEMailSettings' and $name eq 'getExtendedSetting') + || ($classNode->{astNodeName} eq 'KEMailSettings' and $name eq 'setExtendedSetting') + || ($classNode->{astNodeName} eq 'KProtocolManager' and $name eq 'defaultConnectTimeout') + || ($classNode->{astNodeName} eq 'KMD5' and $name eq 'transform') + || ($classNode->{astNodeName} eq 'KSSLCertificate' and $name eq 'operator!=') + || ($classNode->{astNodeName} eq 'KSSLPKCS7' and $name eq 'validate') + || ($classNode->{astNodeName} eq 'KSSLPKCS7' and $name eq 'revalidate') + || ($classNode->{astNodeName} eq 'KSSLSession' and $name eq 'KSSLSession' and @{$m->{ParamList}} == 1) + || ($classNode->{astNodeName} eq 'KSimpleFileFilter' and $name eq 'nameFilters') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'isTabReorderingEnabled') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'hoverCloseButton') + || ($classNode->{astNodeName} =~ /^TQUrl/ and $name eq 'operator==') + || ($classNode->{astNodeName} eq 'TQUriDrag' and $name =~ /^decode$|decodeLocalFiles|decodeToUnicodeUris/) + || ($name eq 'virtual_hook') + || ($name =~ /_KShared_/) + || ($name eq 'qObject') + || ($name =~ /argv/) + || ($name =~ /argc/) + || ($name eq 'qt_emit') + || ($name eq 'qt_invoke') + || ($name eq 'qt_cast') + || ($name eq 'qt_property') + || ($name eq 'staticMetaObject') + || ($name eq 'type') + || ($classNode->{astNodeName} eq 'KTar' and $name eq 'writeFile_impl') + || ($classNode->{astNodeName} eq 'TQApplication' and $name eq 'TQApplication') + # Assume only Qt classes have tr() and trUtf8() in their Q_OBJECT macro + || ($classNode->{astNodeName} !~ /^Q/ and $name eq 'tr') + || ($classNode->{astNodeName} !~ /^Q/ and $name eq 'trUtf8') + + || ($main::qt4 + && ( ($classNode->{astNodeName} eq 'TQWidgetListItem' and $name eq 'operator=') + || ($classNode->{astNodeName} eq 'TQColormap' and $name eq 'operator=') + || ($classNode->{astNodeName} eq 'TQMatrix' and $name eq 'operator*=') + || ($classNode->{astNodeName} eq 'TQListWidget' and $name eq 'setItemPosition') + || ($classNode->{astNodeName} eq 'TQFontMetricsF' and $name eq 'operator=') + || ($classNode->{astNodeName} eq 'TQFontMetricsF' and $name eq 'TQFontMetricsF' + and $#{$m->{ParamList}} == 0 && $m->{ParamList}[0]->{ArgType} eq 'const TQFontMetrics&') + || ($classNode->{astNodeName} eq 'TQHttp' and $name eq 'supportedOperations') + || ($classNode->{astNodeName} eq 'TQRectF' and $name eq 'setX') + || ($classNode->{astNodeName} eq 'TQRectF' and $name eq 'setY') + || ($classNode->{astNodeName} eq 'TQTextObject' and $name eq 'formatType') + || ($classNode->{astNodeName} eq 'TQUrl' and $name eq 'TQUrl' + and $#{$m->{ParamList}} == 0 && $m->{ParamList}[0]->{ArgType} eq 'TQUrlPrivate&') + || ($classNode->{astNodeName} eq 'TQGlobalSpace' and $name eq 'operator<<' and $m->{ParamList}[0]->{ArgType} =~ /TQDebug/) + || ($classNode->{astNodeName} eq 'TQGlobalSpace' and $#{$m->{ParamList}} > 0 and $name =~ /operator/ and $m->{ParamList}[1]->{ArgType} =~ /TQVariant::Type/) + || ($#{$m->{ParamList}} > 0 and $m->{ParamList}[0]->{ArgType} =~ /Private/) + || ($m->{ReturnType} =~ /iterator/) + || ($m->{ReturnType} =~ /QT3_SUPPORT/) ) ) + + || $m->{Deprecated} ) { + $m->{NodeType} = 'deleted'; + next; + } + + my $argId = 0; + my $firstDefaultParam; + foreach my $arg ( @{$m->{ParamList}} ) { + # Look for first param with a default value + if ( defined $arg->{DefaultValue} && !defined $firstDefaultParam ) { + $firstDefaultParam = $argId; + } + + if ( $arg->{ArgType} eq '...' # refuse a method with variable arguments + or $arg->{ArgType} eq 'image_io_handler' # TQImage's callback + or $arg->{ArgType} eq 'DecoderFn' # TQFile's callback + or $arg->{ArgType} eq 'EncoderFn' # TQFile's callback + or $arg->{ArgType} =~ /bool \(\*\)\(TQObject/ # TQMetaObject's ctor + or $arg->{ArgType} eq 'QtStaticMetaObjectFunction' # TQMetaObjectCleanUp's ctor with func pointer + or $arg->{ArgType} eq 'const TQTextItem&' # ref to a private class in 3.2.0b1 + or $arg->{ArgType} eq 'FILE*' # won't be able to handle that I think + or $arg->{ArgType} eq 'const KKeyNative&' # + ) { + $m->{NodeType} = 'deleted'; + } + else + { + # Resolve type in full, e.g. for TQSessionManager::RestartHint + # (TQSessionManagerJBridge doesn't inherit TQSessionManager) + $arg->{ArgType} = kalyptusDataDict::resolveType($arg->{ArgType}, $classNode, $rootnode); + registerType( $arg->{ArgType} ); + $argId++; + } + } + $m->AddProp( "FirstDefaultParam", $firstDefaultParam ); + $m->{ReturnType} = kalyptusDataDict::resolveType($m->{ReturnType}, $classNode, $rootnode) if ($m->{ReturnType}); + registerType( $m->{ReturnType} ); + } + elsif( $m->{NodeType} eq "enum" ) { + if ( ! $m->{astNodeName} ) { + $m->{Access} = 'protected'; + } + my $fullEnumName = $className."::".$m->{astNodeName}; + if ( ($fullEnumName eq 'KMimeType::Format' and $name eq 'compression') + || $m->{Deprecated} ) { + $m->{NodeType} = 'deleted'; + next; + } + + $classNode->{enumerations}{$m->{astNodeName}} = $fullEnumName; +# if $m->{astNodeName} and $m->{Access} ne 'private'; +# if $m->{astNodeName} ; + + # Define a type for this enum + registerType( $fullEnumName ); + + # Remember that it's an enum + findTypeEntry( $fullEnumName )->{isEnum} = 1; + } + elsif( $m->{NodeType} eq 'var' ) { + my $varType = $m->{Type}; + # We are interested in public static vars, like TQColor::blue + if ( $varType =~ s/static\s+// && $m->{Access} ne 'private' + && $className."::".$m->{astNodeName} ne "KSpell::modalListText" ) + { + $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/\s*$//; + print STDERR "var: $m->{astNodeName} '$varType'\n" if ($debug); + + # Register the type + registerType( $varType ); + + } else { + # To avoid duplicating the above test, we just get rid of any other var + $m->{NodeType} = 'deleted'; + } + } + }, + undef + ); + $main::doPrivate = $doPrivate; + + print STDERR "$className: ctor count: $constructorCount, hasPublicProtectedConstructor: $hasPublicProtectedConstructor, hasCopyConstructor: $hasCopyConstructor:, defaultConstructor: $defaultConstructor, hasPublicDestructor: $hasPublicDestructor, hasPrivatePureVirtual:$hasPrivatePureVirtual\n" if ($debug); + + # Note that if the class has _no_ constructor, the default ctor applies. Let's even generate it. + if ( !$constructorCount && $defaultConstructor eq 'none' && !$hasPrivatePureVirtual ) { + # Create a method node for the constructor + my $methodNode = Ast::New( $classNode->{astNodeName} ); + $methodNode->AddProp( "NodeType", "method" ); + $methodNode->AddProp( "Flags", "" ); + $methodNode->AddProp( "Params", "" ); + $methodNode->AddProp( "ParamList", [] ); + kdocAstUtil::attachChild( $classNode, $methodNode ); + + # Hack the return type for constructors, since constructors return an object pointer + $methodNode->AddProp( "ReturnType", $className."*" ); + registerType( $className."*" ); + $methodNode->AddProp( "Access", "public" ); # after attachChild + $defaultConstructor = 'public'; + $hasPublicProtectedConstructor = 1; + } + + # Also, if the class has no explicit destructor, generate a default one. + if ( !$hasDestructor && !$hasPrivatePureVirtual ) { + my $methodNode = Ast::New( "$classNode->{astNodeName}" ); + $methodNode->AddProp( "NodeType", "method" ); + $methodNode->AddProp( "Flags", "" ); + $methodNode->AddProp( "Params", "" ); + $methodNode->AddProp( "ParamList", [] ); + kdocAstUtil::attachChild( $classNode, $methodNode ); + + $methodNode->AddProp( "ReturnType", "~" ); + $methodNode->AddProp( "Access", "public" ); + } + + # If we have a private pure virtual, then the class can't be instanciated (e.g. TQCanvasItem) + # Same if the class has only private constructors (e.g. TQInputDialog) + $classNode->AddProp( "CanBeInstanciated", $hasPublicProtectedConstructor +# && !$hasPrivatePureVirtual + && (!$classNode->{Pure} or $classNode->{astNodeName} eq 'TQValidator') + && !($classNode->{NodeType} eq 'namespace') + && ($classNode->{astNodeName} !~ /^DrawContentsEvent$|^MouseEvent$|^MouseDoubleClickEvent$|^MouseMoveEvent$|^MouseReleaseEvent$|^MousePressEvent$/) + && ($classNode->{astNodeName} !~ /TQMetaObject|TQDragObject|Slave|CopyJob|KMdiChildFrm|KNamedCommand/) ); + + # We will derive from the class only if it has public or protected constructors. + # (_Even_ if it has pure virtuals. But in that case the *.cpp class can't be instantiated either.) + $classNode->AddProp( "BindingDerives", $hasPublicProtectedConstructor ); + + # We need a public dtor to destroy the object --- ### aren't protected dtors ok too ?? + $classNode->AddProp( "HasPublicDestructor", $hasPublicDestructor ); + + # Hack for TQAsyncIO. We don't implement the "if a class has no explicit copy ctor, + # then all of its member variables must be copiable, otherwise the class isn't copiable". + $hasPrivateCopyConstructor = 1 if ( $className eq 'TQAsyncIO' ); + + # Remember if this class can't be copied - it means all its descendants can't either + $classNode->AddProp( "CanBeCopied", !$hasPrivateCopyConstructor ); + $classNode->AddProp( "HasCopyConstructor", $hasCopyConstructor ); +} + +sub propagateCanBeCopied($) +{ + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + my @super = superclass_list($classNode); + # A class can only be copied if none of its ancestors have a private copy ctor. + for my $s (@super) { + if (!$s->{CanBeCopied}) { + $classNode->{CanBeCopied} = 0; + print STDERR "$classNode->{astNodeName} cannot be copied\n" if ($debug); + last; + } + } + + # Prepare the {case} dict for the class + prepareCaseDict( $classNode ); +} + +=head2 writeClassDoc + + Called by writeDoc for each class to be written out + +=cut + +sub writeClassDoc +{ + my( $node ) = @_; + my $className = join( "::", kdocAstUtil::heritage($node) ); + my $csharpClassName = $node->{astNodeName}; + # Makefile doesn't like '::' in filenames, so use __ + my $fileName = $node->{astNodeName}; +# my $fileName = join( "__", kdocAstUtil::heritage($node) ); + print "Enter: $className\n" if $debug; + + my $typeprefix = ($className =~ /^Q/ ? "qt_" : "kde_"); + my $packagename = ($typeprefix eq 'qt_' ? "Qt" : "KDE"); + + # Write out the *.csharp file + my $classFile = "$outputdir/$fileName.cs"; + open( CLASS, ">$classFile" ) || die "Couldn't create $classFile\n"; + print STDERR "Writing $fileName.csharp\n" if ($debug); + + print CLASS "//Auto-generated by $0. DO NOT EDIT.\n"; + + print CLASS "namespace $packagename {\n\n"; + + print CLASS "\tusing System;\n"; + + my %csharpMethods = (); + my %addImport = (); + + my @ancestors = (); + my @ancestor_nodes = (); + Iter::Ancestors( $node, $rootnode, undef, undef, sub { + my ( $ances, $name, $type, $template ) = @_; + if ( $name ne "TQMemArray" and $name ne "TQSqlFieldInfoList" ) { + push @ancestor_nodes, $ances; + push @ancestors, $name; + } + }, + undef + ); + + my ($methodCode, $interfaceCode, $proxyInterfaceCode, $signalCode) = generateAllMethods( $node, $#ancestors + 1, + \%csharpMethods, + $node, + 1, + \%addImport ); + + my $tempMethodNumber = $methodNumber; + + # Add method calls for the interfaces implemented by the class + foreach my $ancestor_node ( @ancestor_nodes ) { + if ( defined interfaceForClass($ancestor_node->{astNodeName}) && ($#ancestors > 0) ) { + my ($meth, $interf, $proxyInterf, $sig) = generateAllMethods( $ancestor_node, 0, \%csharpMethods, $node, 0, \%addImport ); + $methodCode .= $meth; + $interfaceCode .= $interf; + $proxyInterfaceCode .= $proxyInterf; + } + } + + if ( $className eq 'Qt' or $className eq 'KDE' ) { + my $globalSpace = kdocAstUtil::findRef( $rootnode, $main::globalSpaceClassName ); + my ($meth, $interf, $proxyInterf, $sig) = generateAllMethods( $globalSpace, 0, \%csharpMethods, $node, 0, \%addImport ); + $methodCode .= $meth; + $interfaceCode .= $interf; + $proxyInterfaceCode .= $proxyInterf; + } + + $methodNumber = $tempMethodNumber; + + if ( $className eq 'Qt' ) { + ; + } else { + if ( $className eq 'TQListView' or $className eq 'TQListViewItem' or $className eq 'TQUriDrag' ) { + # Special case these two classes as they have methods that use ArrayList added as 'extras' + print CLASS "using System.Collections;\n"; + } + } + + foreach my $imp (keys %addImport) { + die if $imp eq ''; + # Ignore any imports for classes in the same package as the current class + if ($imp !~ /$packagename/) { + print CLASS "\tusing $imp;\n"; + } + } + + if ( defined interfaceForClass($csharpClassName) ) { + print CLASS "\n\tpublic interface " . interfaceForClass($csharpClassName) . " {\n"; + print CLASS $interfaceCode; + print CLASS "\t}\n"; + } + + my $classdec; + my $parentClassName = ""; + + if ($node->{NodeType} eq 'namespace') { + $classdec = "\tpublic class $csharpClassName {\n"; + $classdec .= "\t\tprotected Object _interceptor = null;\n"; + } elsif ( $#ancestors < 0 ) { + $classdec = "\t[SmokeClass(\"$className\")]\n"; + $classdec .= "\tpublic class $csharpClassName : MarshalByRefObject"; + if ( defined interfaceForClass($csharpClassName) ) { + $classdec .= ", " . interfaceForClass($csharpClassName); + } + + if ($node->{CanBeInstanciated} and $node->{HasPublicDestructor}) { + $classdec .= ", IDisposable"; + } + + $classdec .= " {\n\t\tprotected Object _interceptor = null;\n"; + $classdec .= " \n\t\tprivate IntPtr _smokeObject;\n"; + $classdec .= " \t\tprotected $csharpClassName(Type dummy) {}\n"; + } else { + $classdec = "\t[SmokeClass(\"$className\")]\n"; + $classdec .= "\tpublic class $csharpClassName : "; + my $ancestor; + foreach $ancestor ( @ancestors ) { + if ( !defined interfaceForClass($ancestor) or $ancestor eq @ancestors[$#ancestors] ) { + $ancestor =~ s/^.*:://; + $parentClassName .= "$ancestor"; + $classdec .= "$ancestor"; + last; + } + } + + my @implements = (); + if ( $#ancestors >= 1 ) { + $classdec .= ", "; + foreach $ancestor ( @ancestors ) { + if ( defined interfaceForClass($ancestor) ) { + push(@implements, interfaceForClass($ancestor)); + } + } + } + + if ($#implements >= 0) { + $classdec .= join(", ", @implements); + } + + if ($node->{CanBeInstanciated} and $node->{HasPublicDestructor}) { + $classdec .= ", IDisposable"; + } + + $classdec .= " {\n"; + $classdec .= " \t\tprotected $csharpClassName(Type dummy) : base((Type) null) {}\n"; + } + + print CLASS "\n"; + if ( $csharpClassName !~ /^Q/ or $signalCode ne '' ) { + my $signalLink = ''; + if ( $signalCode ne '' ) { + $signalLink = " See for signals emitted by $csharpClassName\n"; + } + my $docnode = $node->{DocNode}; + if ( defined $docnode ) { + print CLASS printCSharpdocComment( $docnode, "", "\t///", $signalLink ) . "\n" + } else { + print CLASS "\t///$signalLink"; + } + } + + print CLASS $classdec; + + print CLASS "\t\tinterface I$csharpClassName" . "Proxy {\n"; + print CLASS $proxyInterfaceCode; + print CLASS "\t\t}\n\n"; + + print CLASS "\t\tprotected new void CreateProxy() {\n"; + print CLASS "\t\t\tSmokeInvocation realProxy = new SmokeInvocation(typeof($csharpClassName), this);\n"; + print CLASS "\t\t\t_interceptor = ($csharpClassName) realProxy.GetTransparentProxy();\n\t\t}\n"; + + print CLASS $methodCode; + + if ( $className eq 'Qt' and ! $main::qt4 ) { + print CLASS $qtExtras; + } elsif ( $className eq 'TQApplication' and ! $main::qt4 ) { + print CLASS $qapplicationExtras; + } elsif ( $className eq 'TQBitmap' ) { + print CLASS $qbitmapExtras; + } elsif ( $className eq 'TQByteArray' and ! $main::qt4) { + print CLASS $qbytearrayExtras; + } elsif ( $className eq 'TQDropEvent' ) { + print CLASS $qdropeventExtras; + } elsif ( $className eq 'TQDragObject' ) { + print CLASS $qdragobjectExtras; + } elsif ( $className eq 'TQObject' ) { + print CLASS $qobjectExtras; + } elsif ( $className eq 'TQListView' ) { + print CLASS $qlistviewExtras; + } elsif ( $className eq 'TQListViewItem' ) { + print CLASS $qlistviewitemExtras; + } elsif ( $className eq 'TQMimeSource' ) { + print CLASS $qmimesourceExtras; + } elsif ( $className eq 'TQWidget' ) { + print CLASS $qwidgetExtras; + } elsif ( $className eq 'TQPaintDevice' ) { + print CLASS $qpaintdeviceExtras; + } elsif ( $className eq 'TQPixmap' ) { + print CLASS $qpixmapExtras; + } elsif ( $className eq 'TQIODevice' ) { + print CLASS $qiodeviceExtras; + } elsif ( $className eq 'TQPointArray' ) { + print CLASS $qpointarrayExtras; + } elsif ( $className eq 'TQSizePolicy' ) { + print CLASS $qsizepolicyExtras; + } elsif ( $className eq 'TQUriDrag' ) { + print CLASS $quridragExtras; + } elsif ( $className eq 'KApplication' ) { + print CLASS $kapplicationExtras; + } elsif ( $className eq 'KMainWindow' ) { + print CLASS $kmainwindowExtras; + } + + + if ( is_kindof($node, "TQObject") ) { + print CLASS "\t\tprotected new void CreateSignalProxy() {\n"; + print CLASS "\t\t\tSignalInvocation realProxy = new SignalInvocation(typeof(I" . $csharpClassName . "Signals), this);\n"; + print CLASS "\t\t\tQ_EMIT = (I" . $csharpClassName . "Signals) realProxy.GetTransparentProxy();\n"; + print CLASS "\t\t}\n"; + print CLASS "\t\tprotected new I" . $csharpClassName . "Signals Emit() {\n"; + print CLASS "\t\t\treturn (I" . $csharpClassName . "Signals) Q_EMIT;\n"; + print CLASS "\t\t}\n"; + print CLASS "\t}\n"; + + print CLASS "\n\tpublic interface I$csharpClassName" . "Signals"; + print CLASS " : I" . $parentClassName . "Signals" unless $parentClassName eq "Qt"; + print CLASS " {\n"; + print CLASS $signalCode; + print CLASS "\t}\n"; + } else { + print CLASS "\t}\n"; + } + + print CLASS "}\n"; + close CLASS; +} + + +# Generate the prototypes for a method (one per arg with a default value) +# Helper for makeprotos +sub iterproto($$$$$) { + my $classidx = shift; # to check if a class exists + my $method = shift; + my $proto = shift; + my $idx = shift; + my $protolist = shift; + + my $argcnt = scalar @{ $method->{ParamList} } - 1; + if($idx > $argcnt) { + push @$protolist, $proto; + return; + } + if(defined $method->{FirstDefaultParam} and $method->{FirstDefaultParam} <= $idx) { + push @$protolist, $proto; + } + + my $arg = $method->{ParamList}[$idx]->{ArgType}; + + my $typeEntry = findTypeEntry( $arg ); + my $realType = $typeEntry->{realType}; + + # A scalar ? + $arg =~ s/\bconst\b//g; + $arg =~ s/\s+//g; + if($typeEntry->{isEnum} || $allTypes{$realType}{isEnum} || exists $typeunion{$realType} || exists $mungedTypeMap{$arg}) + { + my $id = '$'; # a 'scalar + $id = '?' if $arg =~ /[*&]{2}/; + $id = $mungedTypeMap{$arg} if exists $mungedTypeMap{$arg}; + iterproto($classidx, $method, $proto . $id, $idx + 1, $protolist); + return; + } + + # A class ? + if(exists $classidx->{$realType}) { + iterproto($classidx, $method, $proto . '#', $idx + 1, $protolist); + return; + } + + # A non-scalar (reference to array or hash, undef) + iterproto($classidx, $method, $proto . '?', $idx + 1, $protolist); + return; +} + +# Generate the prototypes for a method (one per arg with a default value) +sub makeprotos($$$) { + my $classidx = shift; + my $method = shift; + my $protolist = shift; + iterproto($classidx, $method, $method->{astNodeName}, 0, $protolist); +} + +# Return the string containing the signature for this method (without return type). +# If the 2nd arg is not the size of $m->{ParamList}, this method returns a +# partial signature (this is used to handle default values). +sub methodSignature($$) { + my $method = shift; + my $last = shift; + my $sig = $method->{astNodeName}; + my @argTypeList; + my $argId = 0; + foreach my $arg ( @{$method->{ParamList}} ) { + last if $argId > $last; + push @argTypeList, $arg->{ArgType}; + $argId++; + } + $sig .= "(". join(", ",@argTypeList) .")"; + $sig .= " const" if $method->{Flags} =~ "c"; + return $sig; +} + +# Return the string containing the csharp signature for this method (without return type). +# If the 2nd arg is not the size of $m->{ParamList}, this method returns a +# partial signature (this is used to handle default values). +sub csharpMethodSignature($$) { + my $method = shift; + my $last = shift; + my $sig = $method->{astNodeName}; + my @argTypeList; + my $argId = 0; + foreach my $arg ( @{$method->{ParamList}} ) { + $argId++; + last if $argId > $last; + push @argTypeList, "arg" . "$argId ". cplusplusToCSharp( $arg->{ArgType} ); + } + $sig .= "(". join(", ",@argTypeList) .")"; + return $sig; +} + +sub coerce_type($$$$) { + #my $m = shift; + my $union = shift; + my $var = shift; + my $type = shift; + my $new = shift; # 1 if this is a return value, 0 for a normal param + + my $typeEntry = findTypeEntry( $type ); + my $realType = $typeEntry->{realType}; + + my $unionfield = $typeEntry->{typeId}; +# die "$type" unless defined( $unionfield ); + if ( ! defined( $unionfield ) ) { + print STDERR "type field not defined: $type\n"; + return ""; + } + + $unionfield =~ s/t_/s_/; + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + my $code = "$union.$unionfield = "; + if($type =~ /&$/) { + $code .= "(void*)&$var;\n"; + } elsif($type =~ /\*$/) { + $code .= "(void*)$var;\n"; + } else { + if ( $unionfield eq 's_class' + or ( $unionfield eq 's_voidp' and $type ne 'void*' ) + or $type eq 'TQString' ) { # hack + $type =~ s/^const\s+//; + if($new) { + $code .= "(void*)new $type($var);\n"; + } else { + $code .= "(void*)&$var;\n"; + } + } else { + $code .= "$var;\n"; + } + } + + return $code; +} + +# Generate the list of args casted to their real type, e.g. +# (TQObject*)x[1].s_class,(TQEvent*)x[2].s_class,x[3].s_int +sub makeCastedArgList +{ + my @castedList; + my $i = 1; # The args start at x[1]. x[0] is the return value + my $arg; + foreach $arg (@_) { + my $type = $arg; + my $cast; + + my $typeEntry = findTypeEntry( $type ); + my $unionfield = $typeEntry->{typeId}; +# die "$type" unless defined( $unionfield ); + if ( ! defined( $unionfield ) ) { + print STDERR "type field not defined: $type\n"; + return ""; + } + $unionfield =~ s/t_/s_/; + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + my $v .= " arg$i"; + if($type =~ /&$/) { + $cast = "*($type *)"; + } elsif($type =~ /\*$/) { + $cast = "($type)"; + } elsif($type =~ /\(\*\)\s*\(/) { # function pointer ... (*)(...) + $cast = "($type)"; + } else { + if ( $unionfield eq 's_class' + or ( $unionfield eq 's_voidp' and $type ne 'void*' ) + or $type eq 'TQString' ) { # hack + $cast = "*($type *)"; + } else { + $cast = "($type)"; + } + } + push @castedList, "$type$v"; + $i++; + } + return @castedList; +} + + +# Adds the import for node $1 to be imported in $2 if not already there +# Prints out debug stuff if $3 +sub addImportForClass($$$) +{ + my ( $node, $addImport, $debugMe ) = @_; + my $importname = csharpImport( $node->{astNodeName} ); +# print " Importing $importname for node name: " . $node->{astNodeName} . "\n"; + # No import needed, so return + return if ( $importname eq '' ); + unless ( defined $addImport->{$importname} ) { + print " Importing $importname\n" if ($debugMe); + $addImport->{$importname} = 1; + } + else { print " $importname already imported.\n" if ($debugMe); } +} + +sub checkImportsForObject($$) +{ + my $type = shift; + my $addImport = shift; + + my $debugCI = 0; #$debug + # print "checkImportsForObject $type\n"; + $type =~ s/const\s+//; + my $it = $type; + if (!($it and exists $typeunion{$it}) and $type ne "" + #and $type !~ /&/ # in fact we also want refs, due to the generated code + ) { + $type =~ s/&//; + $type =~ s/[*]//; + print " Detecting an object by value/ref: $type\n" if ($debugCI); + my $node = kdocAstUtil::findRef( $rootnode, $type ); + if ($node and $node->{NodeType} eq "class" ) { + print " NodeType: " . $node->{NodeType} . "\n" if ($debugCI); + addImportForClass( $node, $addImport, $debugCI ); + } + else { + if ( cplusplusToCSharp($it) eq 'ArrayList' ) { + $addImport->{"System.Collections"} = 1; + } else { + print " No import found for $type\n" if ($debugCI); + } + } + } +} + +sub generateVirtualMethod($$$$$) +{ + # Generating methods for $class. + # $m: method node. $methodClass: the node of the class in which the method is really declared + # (can be different from $class when the method comes from a super class) + # This is important because of $allMethods, which has no entry for class::method in that case. + + my( $classNode, $signature, $m, $methodClass, $addImport ) = @_; + my $methodCode = ''; # output + my $returnType = $m->{ReturnType}; + return ('', '') if $returnType eq '~'; # skip destructors + + my $className = $classNode->{astNodeName}; + my $flags = $m->{Flags}; + my @argList = @{$m->{ParamList}}; + + print "generateVirtualMethod $className: $signature ($m->{Access})\n" if ($debug); + + # Detect objects returned by value + checkImportsForObject( $returnType, $addImport ) if ($returnType ne 'void'); + + # Generate a matching virtual method in the x_ class + $methodCode .= "\t\tvirtual $returnType $m->{astNodeName}("; + my $i = 0; + foreach my $arg ( @argList ) { + $methodCode .= ", " if $i++; + $methodCode .= $arg->{ArgType}; + $methodCode .= " x$i"; + + # Detect objects passed by value + checkImportsForObject( $arg->{ArgType}, $addImport ); + } + $methodCode .= ") "; + $methodCode .= "const " if ($flags =~ "c"); + $methodCode .= "\{\n"; + + # Now the code of the method + my $this = $classNode->{BindingDerives} > 0 ? "this" : "xthis"; + + $i++; # Now the number of args + $methodCode .= "\tSmoke::StackItem x[$i];\n"; + $i = 1; + for my $arg (@argList) { + $methodCode .= "\t"; + $methodCode .= coerce_type("x[$i]", "x$i", $arg->{ArgType}, 0); + $i++; + } + + my $sig = $methodClass->{astNodeName} . "::" . $signature; + my $idx = $allMethods{$sig}; +# die "generateVirtualMethod: $className: No method found for $sig\n" if !defined $idx; + if ( !defined $idx ) { + print STDERR "generateVirtualMethod: $className: No method found for $sig\n"; + return ""; + } + + if($flags =~ "p") { # pure virtual + $methodCode .= "\t${libname}_Smoke->binding->callMethod($idx, (void*)$this, x, true /*pure virtual*/);\n"; + } else { + $methodCode .= "\tif(${libname}_Smoke->binding->callMethod($idx, (void*)$this, x)) "; + } + + $returnType = undef if ($returnType eq 'void'); + if($returnType) { + my $arg = $returnType; + my $it = $arg; + my $cast; + my $v = "x[0]"; + my $indent = ($flags =~ "p") ? "\t" : ""; + if($it and exists $typeunion{$it}) { + $v .= ".$typeunion{$it}"; + $cast = "($arg)"; + $methodCode .= "${indent}return $cast$v;\n"; + } else { + $v .= ".s_class"; + if($arg =~ s/&//) { + $cast = "*($arg *)"; + $methodCode .= "${indent}return $cast$v;\n"; + } elsif($arg !~ /\*/) { + unless($flags =~ "p") { + $indent = "\t "; + $methodCode .= "{\n"; + } + # we assume it's a new thing, and handle it + $methodCode .= "${indent}$arg *xptr = ($arg *)$v;\n"; + $methodCode .= "${indent}$arg xret(*xptr);\n"; + $methodCode .= "${indent}delete xptr;\n"; + $methodCode .= "${indent}return xret;\n"; + $methodCode .= "\t}\n" unless $flags =~ "p"; + } else { + $cast = "($arg)"; + $methodCode .= "${indent}return $cast$v;\n"; + } + } + } else { + $methodCode .= "\t" if $flags =~ "p"; + $methodCode .= "return;\n"; + } + if($flags =~ "p") { + $methodCode .= "\t// ABSTRACT\n"; + $methodCode .= " }\n"; + return ( $methodCode ); + } + $methodCode .= "\t"; + if($returnType) { + $methodCode .= "return "; + } + $methodCode .= "$this\->$methodClass->{astNodeName}\::$m->{astNodeName}("; + $i = 0; + for my $arg (@argList) { + $methodCode .= ", " if $i++; + $methodCode .= "x$i"; + } + $methodCode .= ");\n"; + $methodCode .= "\t}\n"; + return ( $methodCode ); +} + +sub interfaceForClass($) +{ + my ( $ancestor ) = @_; + if ( kalyptusDataDict::interfacemap($ancestor) eq () ) { + return undef; + } else { + return "I". $ancestor; + } +} + +sub generateMethod($$$$$$$) +{ + my( $classNode, $m, $addImport, $ancestorCount, $csharpMethods, $mainClassNode, $generateConstructors ) = @_; # input + my $methodCode = ''; # output + my $interfaceCode = ''; # output + my $proxyInterfaceCode = ''; # output + my $signalCode = ''; # output + + my $name = $m->{astNodeName}; # method name + + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + + @heritage = kdocAstUtil::heritage($mainClassNode); + my $mainClassName = join( "::", @heritage ); + + # The csharpClassName might be 'TQWidget', while currentClassName is 'TQRangeControl' + # and the TQRangeControl methods are being copied into TQWidget. + my $csharpClassName = $mainClassNode->{astNodeName}; + my $currentClassName = $classNode->{astNodeName}; + + my $firstUnknownArgType = 99; + my $returnType = $m->{ReturnType}; + + # Don't use $className here, it's never the fully qualified (A::B) name for a ctor. + my $isConstructor = ($name eq $classNode->{astNodeName} ); + my $isDestructor = ($returnType eq '~'); + + # Don't generate anything for destructors, or constructors for namespaces + return if $isDestructor + or ($classNode->{NodeType} eq 'namespace' and $isConstructor) + or (!$mainClassNode->{CanBeInstanciated} and $m->{Access} =~ /protected/) + or $name =~ /^operator\s*(=|(\[\])|([|&^+-]=)|(!=))\s*$/; + + if ($classNode->{astNodeName} eq $main::globalSpaceClassName) { + my $sourcename = $m->{Source}->{astNodeName}; + # Only put Global methods which came from sources beginning with q into class Qt + if ($csharpClassName eq 'Qt' and ( $sourcename !~ /\/q[^\/]*$/ or $sourcename =~ /string.h$/ )) { + return; + } + # ..and any other global methods into KDE + if ($csharpClassName eq 'KDE' and $m->{Source}->{astNodeName} =~ /\/q[^\/]*$/) { + return; + } + + if ( $sourcename !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|tdeprint/|tdesu/)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } + if ( $sourcename eq '' ) { + return; + } + } + + if ($returnType eq 'void') { + $returnType = undef; + } else { + # Detect objects returned by value + checkImportsForObject( $returnType, $addImport ); + } + + my $hasDuplicateSignature = 0; + my $isStatic = $m->{Flags} =~ "s"; + my $isPure = $m->{Flags} =~ "p"; + + return if ( $m->{SkipFromSwitch} && $m->{Flags} !~ "p" ); + +# # Skip internal methods, which return unknown types +# # Hmm, the C# bindings have a list of those too. +# return if ( $returnType =~ m/TQGfx\s*\*/ ); +# return if ( $returnType eq 'CGContextRef' ); +# return if ( $returnType eq 'TQWSDisplay *' ); +# # This stuff needs callback, or ** +# return if ( $name eq 'defineIOHandler' or $name eq 'qt_init_internal' ); +# # Skip casting operators, but not == < etc. +# return if ( $name =~ /operator \w+/ ); +# # TQFile's EncoderFn/DecoderFn +# return if ( $name =~ /set[ED][ne]codingFunction/ ); +# # How to implement this? (TQXmlDefaultHandler/TQXmlEntityResolver::resolveEntity, needs A*&) +# return if ( $name eq 'resolveEntity' and $className =~ /^TQXml/ ); +# return if ( $className eq 'TQBitArray' && $m->{Access} eq 'protected' ); + + #print STDERR "Tests passed, generating.\n"; + + + my $argId = 0; + + my @argTypeList=(); + my @csharpArgTypeList=(); + my @csharpArgList = (); + my @namedArgTypeList=(); + + foreach my $arg ( @{$m->{ParamList}} ) { + $argId++; + + if ( $arg->{ArgName} =~ /^super$|^int$|^env$|^cls$|^obj$|^byte$|^event$|^base$|^object$|^in$|^out$|^checked$|^delegate$|^string$/ ) { + $arg->{ArgName} = ""; + } + + if ( $arg->{ArgName} =~ /^short$|^long$/ ) { + # Oops looks like a parser error + $arg->{ArgType} = $arg->{ArgName}; + $arg->{ArgName} = ""; + } + + print STDERR " Param ".$arg->{astNodeName}." type: ".$arg->{ArgType}." name:".$arg->{ArgName}." default: ".$arg->{DefaultValue}." csharp: ".cplusplusToCSharp($arg->{ArgType})."\n" if ($debug); + + my $argType = $arg->{ArgType}; + my $namedArgType; + my $csharpArgType; + my $csharpArg; + my $argName; + + if ( cplusplusToCSharp($argType) eq "" && $firstUnknownArgType > $argId ) { + $firstUnknownArgType = $argId; + } + + $csharpArg = ($arg->{ArgName} eq "" ? "arg" . $argId : $arg->{ArgName}); + $namedArgType = $argType . " " . $csharpArg; + $csharpArgType = cplusplusToCSharp($argType) . " " . $csharpArg; + + push @argTypeList, $argType; + push @csharpArgTypeList, $csharpArgType; + if ( $csharpArgType =~ /^((out)|(ref)) / ) { + push @csharpArgList, "$1 " . $csharpArg; + } else { + push @csharpArgList, $csharpArg; + } + push @namedArgTypeList, $namedArgType; + + # Detect objects passed by value + checkImportsForObject( $argType, $addImport ); + } + + if ( $name eq 'TQApplication' or ($csharpClassName eq 'KCmdLineArgs' and $name eq 'init' and scalar(@csharpArgList) > 1) ) { + # Junk the 'int argc' parameter + shift @csharpArgTypeList; + shift @csharpArgList; + } + + my @castedArgList = makeCastedArgList( @argTypeList ); + + # We iterate as many times as we have default params + my $firstDefaultParam = $m->{FirstDefaultParam}; + $firstDefaultParam = scalar(@argTypeList) unless defined $firstDefaultParam; + my $iterationCount = scalar(@argTypeList) - $firstDefaultParam; + + my $csharpReturnType = cplusplusToCSharp($m->{ReturnType}); + $csharpReturnType =~ s/^(out)|(ref) //; + $csharpReturnType =~ s/StringBuilder/string/; + if ( $csharpReturnType =~ s/string\[\]/ArrayList/ ) { + $addImport->{"System.Collections"} = 1; + } + + if ($m->{ReturnType} =~ /^int\&/) { + $csharpReturnType = 'int'; + } + + if ($csharpReturnType eq "") { + $firstUnknownArgType = 0; + } + + print STDERR " ". ($iterationCount+1). " iterations for $name\n" if ($debug); + + my $csharpSignature = csharpMethodSignature( $m, @argTypeList ); + + if ( defined $csharpMethods->{$csharpSignature} ) { + $hasDuplicateSignature = 1; + } + + my $docnode = $m->{DocNode}; + if ( $firstUnknownArgType >= 0 && $m->{Access} !~ /signals/ && ! $hasDuplicateSignature + && defined $docnode && ($generateConstructors || !$isConstructor) ) + { + my $csharpdocComment = printCSharpdocComment( $docnode, "", "\t\t///", "" ); + $methodCode .= $csharpdocComment unless $csharpdocComment =~ /^\s*$/; + } + + while($iterationCount >= 0) { + + $csharpMethods->{$csharpSignature} = 1; + + local($") = ","; + my $signature = methodSignature( $m, $#argTypeList ); + + if($firstUnknownArgType <= scalar(@argTypeList) || $hasDuplicateSignature || ($name =~ /^qObject$/) || $m->{Access} =~ /dcop/ ) { + if ( $firstUnknownArgType <= scalar(@argTypeList) || $m->{Access} =~ /dcop/ ) { + my $failedConversion = "\t\t// " . $m->{ReturnType} . " $name(@castedArgList[0..$#argTypeList]); >>>> NOT CONVERTED\n"; + if ( $m->{Access} =~ /signals/ ) { + $signalCode .= $failedConversion; + } else { + $methodCode .= $failedConversion; + } + } + } else { + + if ($name eq 'find' and $csharpClassName eq 'TQButtonGroup') { + # Can't override a static method find() in TQWidget + $name = "findButton"; + } elsif ( $name eq 'null' ) { + $name = "nil"; + } elsif ( $name eq 'form' and $csharpClassName =~ /^HTML/ ) { + $name = "formElement"; + } elsif ( $name eq 'wait' and $csharpClassName eq 'KProcess' ) { + $name = "waitThread"; + } elsif ( $name eq 'icon' and $csharpClassName eq 'TQMessageBox' ) { + $name = "iconId"; + } elsif ( $name eq 'icon' and $csharpClassName eq 'KURLBarItemDialog' ) { + $name = "iconName"; + } elsif ( $name eq 'iconText' and $csharpClassName eq 'KToolBar' ) { + $name = "iconTextId"; + } elsif ( $name eq 'reset' and $csharpClassName eq 'KExtendedSocket' ) { + $name = "resetSocket"; + } elsif ( $name eq 'palette' and $csharpClassName eq 'KPaletteTable' ) { + $name = "paletteName"; + } elsif ( $name eq 'size' and $csharpClassName eq 'KFontCombo' ) { + $name = "pointSize"; + } elsif ($csharpSignature eq "icon()" and $csharpClassName eq 'KIconButton') { + $name = "iconName"; + } elsif ($csharpSignature eq "close()" and $csharpClassName eq 'KDirOperator') { + $name = "closeLoading"; + } elsif ($csharpSignature eq "font()" and $csharpClassName eq 'KCharSelect') { + $name = "fontName"; + } elsif ($csharpSignature eq "layout()" and $csharpReturnType eq 'void') { + $name = "updateLayout"; + } elsif ( $name eq 'sorting' and $csharpReturnType eq 'bool' ) { + $name = "sortOnInsert"; + } + + my $csharpparams = join( ", ", @csharpArgTypeList ); + my $cplusplusparams; + my $i = 0; + for my $arg (@argTypeList) { + $cplusplusparams .= "," if $i++; + $cplusplusparams .= "arg" . $i; + } + + my $access = $m->{Access}; + $access =~ s/_slots//; + + if ($isConstructor) { + if ( $generateConstructors ) { +# $proxyInterfaceCode .= "\t\t\tvoid new$csharpClassName($csharpparams);\n"; + $methodCode .= "\t\tpublic $csharpClassName($csharpparams) : this((Type) null) {\n"; + $methodCode .= "\t\t\tCreateProxy();\n"; + + if ( is_kindof($classNode, "TQObject") ) { + $methodCode .= "\t\t\tCreateSignalProxy();\n"; + } + + $methodCode .= "\t\t\tNew$csharpClassName(@csharpArgList[0..$#csharpArgTypeList]);\n"; + $methodCode .= "\t\t}\n"; + + $methodCode .= "\t\t[SmokeMethod(\"" . $signature . "\")]\n"; + $methodCode .= "\t\tprivate void New$csharpClassName($csharpparams) {\n"; + $methodCode .= "\t\t\tProxy$csharpClassName().New$csharpClassName(@csharpArgList[0..$#csharpArgTypeList]);\n"; + $methodCode .= "\t\t}\n"; + } + } elsif ($name =~ /^operator.*/) { + $name =~ s/ //; + $name =~ s!([|&*/+^-])=!$1!; + if (!$isStatic) { + # In C# operator methods must be static, so if the C++ version isn't + # static, then add another arg 'lhs', the value of 'this'. + $csharpparams = "$csharpClassName lhs" . ($csharpparams eq "" ? "" : ", ") . $csharpparams; + unshift @csharpArgTypeList, $csharpClassName; + unshift @csharpArgList, "lhs"; + } + + $proxyInterfaceCode .= "\t\t\t$csharpReturnType $operatorNames{$name}($csharpparams);\n"; + + $methodCode .= "\t\t[SmokeMethod(\"" . $signature . "\")]\n"; + $methodCode .= "\t\t" . $access . " static "; + $methodCode .= $csharpReturnType; + + if ($classNode->{astNodeName} eq $main::globalSpaceClassName + || $name eq 'operator<<' + || $name eq 'operator>>' ) + { + # In C# an operator method must be in the same class as its first operand, + # so any operator methods in TQGlobalSpace must be left as ordinary method + # calls. eg op_write() + # 'operator<<' and 'operator>>' can only have int types as the second + # arg in C#, so convert them to op_read() and op_write() calls + $methodCode .= " $operatorNames{$name}($csharpparams) \{\n"; + } else { + $methodCode .= " $name($csharpparams) \{\n"; + } + + $methodCode .= "\t\t\treturn "; + $methodCode .= "Static" . "$csharpClassName().$operatorNames{$name}(@csharpArgList[0..$#csharpArgTypeList]);\n"; + $methodCode .= "\t\t}\n"; + + if ( $name =~ /operator==/ + && $classNode->{astNodeName} ne $main::globalSpaceClassName ) + { + # Add a 'operator!=' method defined in terms of 'operator==' + $methodCode .= "\t\t" . $access . " static bool"; + $methodCode .= " operator!=($csharpparams) \{\n"; + + $methodCode .= "\t\t\treturn "; + $methodCode .= "!Static" . "$csharpClassName().$operatorNames{$name}(@csharpArgList[0..$#csharpArgTypeList]);\n"; + $methodCode .= "\t\t}\n"; + + $methodCode .= "\t\tpublic override bool Equals(object o) \{\n"; + $methodCode .= "\t\t\tif (!(o is $csharpClassName)) { return false; }\n"; + + $methodCode .= "\t\t\treturn this == ($csharpClassName) o;\n"; + $methodCode .= "\t\t}\n"; + + $methodCode .= "\t\tpublic override int GetHashCode() \{\n"; + $methodCode .= "\t\t\treturn Proxy$csharpClassName().GetHashCode();\n"; + $methodCode .= "\t\t}\n"; + } + } else { + if ( $access eq 'public' or $access eq 'protected' ) { + if ( $name =~ /^takeItem$|^setPixmap$|^clearCell$|^setItem$|^item$|^minimumSize$/ + or $name =~ /^stepUp$|^stepDown$|^sectionFormattedText$|^addNumber$|^removeLastNumber$/ + or $name =~ /^cancel$|^setSource$|^paintCell$|^updateContents$|^sizeHint$|^setFocusSection$/ + or $name =~ /^event$|^eventFilter$|^copy$|^detach$|^showEvent$|^format$|^encodedData$/ + or $name =~ /^styleChange$|^insertItem$|^setStatus$|^setState$|^minimumSizeHint$/ + or $name =~ /^updateGeometry$|^setState$|^exec$|^pixmap$|^areaPoints$|^draw$|^writeDir$/ ) { + # These methods are public in some places, but protected in others, + # so make them all public. + $access = "public"; + } + + + my $altReturnType = undef; + if ($name =~ /^xForm$/ ) { + $csharpReturnType = "Object"; + } elsif ($csharpSignature eq "layout()" and $csharpReturnType ne 'void') { + $altReturnType = "TQLayout"; + } elsif ($csharpSignature eq "defaultFactory()" and $csharpReturnType eq 'TQSqlEditorFactory') { + $csharpReturnType = "TQEditorFactory"; + } elsif ($csharpSignature eq "statusBar()") { + $altReturnType = "TQStatusBar"; + } elsif ($csharpSignature eq "menuBar()") { + $altReturnType = "TQMenuBar"; + } elsif ($csharpSignature =~ /^bits|^scanLine/) { + $csharpReturnType = "byte[]"; + } elsif ($csharpSignature eq "at()" and $csharpClassName eq 'KFilterDev') { + $csharpReturnType = "long"; + } elsif ($csharpSignature =~ /copyTo/ and $csharpClassName eq "KDesktopFile" ) { + $altReturnType = "KConfig"; + } + + + if ($name =~ /^([a-z])(.*)/) { + $name = uc($1) . $2; + + # Only change the method name to start with an upper case letter + # if it doesn't clash with an enum with the same name + my $item = kdocAstUtil::findRef( $classNode, $name ); + if ( defined $item && $item->{NodeType} eq 'enum' && $name =~ /^([A-Z])(.*)/) { + $name = lc($1) . $2; + } + + if ($classNode->{astNodeName} eq 'TQIODevice' and $name eq 'State') { + $name = 'state'; + } + } + + if ( defined $altReturnType ) { + checkImportsForObject( $altReturnType, $addImport ); + $csharpReturnType = $altReturnType; + } + + if ($access eq 'public' && ! $isStatic) { + $interfaceCode .= "\t\t\t$csharpReturnType $name($csharpparams);\n"; + } + + if (($isStatic or $classNode->{NodeType} eq 'namespace')) { + $proxyInterfaceCode .= "\t\t\t$csharpReturnType $name($csharpparams);\n"; + } + + if ( $m->{Access} =~ /_slots/ ) { + $methodCode .= "\t\t[Q_SLOT(\"". $m->{ReturnType} . " $signature" . "\")]\n"; + } + + $methodCode .= "\t\t[SmokeMethod(\"" . $signature . "\")]\n"; + $methodCode .= "\t\t" . $access . (($isStatic or $classNode->{NodeType} eq 'namespace') ? " static " : " "); + + my $overrideNode = kdocAstUtil::findOverride( $rootnode, $classNode, $m->{astNodeName} ); + + if ( ( $generateConstructors + && defined $overrideNode + && ( $ancestorCount == 1 + || !defined interfaceForClass($overrideNode->{astNodeName}) ) ) + || $name eq 'ToString' ) + { + $methodCode .= "new "; + } + + if ($m->{Flags} =~ "v") { + $methodCode .= "virtual "; + } + + $methodCode .= $csharpReturnType; + $methodCode .= " $name($csharpparams) \{\n"; + + $methodCode .= "\t\t\t" . ($csharpReturnType ne "void" ? "return " : ""); + $methodCode .= (($isStatic or $classNode->{NodeType} eq 'namespace') ? "Static" : "Proxy") . "$csharpClassName().$name(@csharpArgList[0..$#csharpArgTypeList]);\n"; + $methodCode .= "\t\t}\n"; + } else { + if ( $access =~ /signals/ ) { + if ($name =~ /^([a-z])(.*)/) { + $name = uc($1) . $2; + } + my $docnode = $m->{DocNode}; + if ( defined $docnode ) { + my $csharpdocComment = printCSharpdocComment( $docnode, "", "\t\t///", "" ); + $signalCode .= $csharpdocComment unless $csharpdocComment =~ /^\s*$/; + } + $signalCode .= "\t\t[Q_SIGNAL(\"" . $m->{ReturnType} . " $signature" . "\")]\n"; + $signalCode .= "\t\tvoid $name($csharpparams);\n"; + } + } + } + } + + pop @argTypeList; + pop @csharpArgTypeList; + pop @csharpArgList; + + $csharpSignature = csharpMethodSignature( $m, @argTypeList ); + $hasDuplicateSignature = (defined $csharpMethods->{$csharpSignature} ? 1 : 0); + + $methodNumber++; + $iterationCount--; + } # Iteration loop + + return ( $methodCode, $interfaceCode, $proxyInterfaceCode, $signalCode ); +} + + +sub generateEnum($$$) +{ + my( $classNode, $m, $generateAnonymous ) = @_; # input + my $methodCode = ''; # output + + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + my $csharpClassName = $classNode->{astNodeName}; + + if ( ($generateAnonymous and $m->{astNodeName} ) or (! $generateAnonymous and ! $m->{astNodeName}) ) { + return; + } + + if ( defined $m->{DocNode} ) { + my $csharpdocComment = printCSharpdocComment( $m->{DocNode}, "", "\t\t///", "" ); + $methodCode .= $csharpdocComment unless $csharpdocComment =~ /^\s*$/; + } + + # In C# enums must have names, so anonymous C++ enums become constants + if (! $m->{astNodeName}) { + return generateConst($classNode, $m, $generateAnonymous); + } + + $m->{astNodeName} =~ /(.)(.*)/; + if ($m->{astNodeName} eq 'Type') { + $methodCode .= "\t\tpublic enum E_Type {\n"; + } else { + $methodCode .= "\t\tpublic enum " . $m->{astNodeName} . " {\n"; + } + + my @enums = split(",", $m->{Params}); + my $enumCount = 0; + foreach my $enum ( @enums ) { + $enum =~ s/\s//g; + $enum =~ s/::/./g; + $enum =~ s/::([a-z])/./g; + $enum =~ s/\(mode_t\)//; + $enum =~ s/internal/_internal/; + $enum =~ s/fixed/_fixed/; + if ( $enum =~ /(.*)=([-0-9]+)$/ ) { + $methodCode .= "\t\t\t$1 = $2,\n"; + $enumCount = $2; + $enumCount++; + } elsif ( $enum =~ /(.*)=(.*)/ ) { + $methodCode .= "\t\t\t$1 = $2,\n"; + if ($2 =~ /(0xf0000000)|(0xffffffff)/) { + $methodCode =~ s/enum ((E_)?[^\s]*)/enum $1 : uint/; + } + } else { + $methodCode .= "\t\t\t$enum = $enumCount,\n"; + $enumCount++; + } + } + + $methodCode .= "\t\t}\n"; + $methodNumber++; + + return ( $methodCode ); +} + +sub generateConst($$$) +{ + my( $classNode, $m, $generateAnonymous ) = @_; # input + my $methodCode = ''; # output + + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + my $csharpClassName = $classNode->{astNodeName}; + + my @enums = split(",", $m->{Params}); + my $enumCount = 0; + foreach my $enum ( @enums ) { + $enum =~ s/\s//g; + $enum =~ s/::/./g; + $enum =~ s/\(mode_t\)//; + $enum =~ s/internal/_internal/; + $enum =~ s/fixed/_fixed/; + $enum =~ s/IsActive/_IsActive/; + if ( $enum =~ /(.*)=([-0-9]+)$/ ) { + $methodCode .= "\t\tpublic const int $1 = $2;\n"; + $enumCount = $2; + $enumCount++; + } elsif ( $enum =~ /(.*)=(.*)/ ) { + $methodCode .= "\t\tpublic const int $1 = $2;\n"; + } else { + $methodCode .= "\t\tpublic const int $enum = $enumCount;\n"; + $enumCount++; + } + } + + $methodCode .= "\n"; + $methodNumber++; + + return ( $methodCode ); +} + +sub generateVar($$$) +{ + my( $classNode, $m, $addImport ) = @_; # input + my $methodCode = ''; # output + my $interfaceCode = ''; # output + + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + my $csharpClassName = $classNode->{astNodeName}; + + my $name = $m->{astNodeName}; + my $varType = $m->{Type}; + $varType =~ s/static\s//; + $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/\s*$//; + my $fullName = "$className\::$name"; + + checkImportsForObject( $varType, $addImport ); + +# die "Invalid index for $fullName: $classNode->{case}{$fullName} instead of $methodNumber" if $classNode->{case}{$fullName} != $methodNumber; +# $methodCode .= " static void x_$methodNumber(Smoke::Stack x) {\n"; +# $methodCode .= "\tx[0].s_class = (void*)new $varType($fullName);\n"; +# $methodCode .= " }\n"; + +# if ( ($name !~ /^null$/) && (cplusplusToCSharp($varType) ne "") ) { + if ( ($name !~ /^null$/) && (cplusplusToCSharp($varType) ne "" ) ) { +# $interfaceCode .= "\t\t". cplusplusToCSharp($varType) . " $name();\n"; + +# $methodCode .= "\tpublic native static ". cplusplusToCSharp($varType) . " $name();\n"; + } + + $methodNumber++; + return ( $methodCode, $interfaceCode ); +} + +## Called by writeClassDoc +sub generateAllMethods($$$$$$) +{ + my ($classNode, $ancestorCount, $csharpMethods, $mainClassNode, $generateConstructors, $addImport) = @_; + my $methodCode = ''; + my $interfaceCode = ''; + my $proxyInterfaceCode = ''; + my $signalCode = ''; + $methodNumber = 0; + #my $className = $classNode->{astNodeName}; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + my $csharpClassName = $mainClassNode->{astNodeName}; + # If the C++ class had multiple inheritance, then the code for all but one of the + # parents must be copied into the code for csharpClassName. Hence, for TQWidget current + # classname might be TQPaintDevice, as its methods are needed in TQWidget. + my $currentClassName = join( ".", kdocAstUtil::heritage($classNode) ); + + my $sourcename = $classNode->{Source}->{astNodeName}; + + if ( $sourcename !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|tdeprint/|tdesu/)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } + die "Empty source name for $classNode->{astNodeName}" if ( $sourcename eq '' ); + + if ($generateConstructors) { + $methodCode .= "\t\tprivate $csharpClassName Proxy$csharpClassName() {\n"; + $methodCode .= "\t\t\treturn ($csharpClassName) _interceptor;\n\t\t}\n"; + + $methodCode .= "\t\tprivate static Object _staticInterceptor = null;\n"; + $methodCode .= "\t\tstatic $csharpClassName() {\n"; + $methodCode .= "\t\t\tSmokeInvocation realProxy = new SmokeInvocation(typeof(I$csharpClassName" . "Proxy), null);\n"; + $methodCode .= "\t\t\t_staticInterceptor = (I$csharpClassName" . "Proxy) realProxy.GetTransparentProxy();\n"; + $methodCode .= "\t\t}\n"; + + $methodCode .= "\t\tprivate static I$csharpClassName" . "Proxy Static$csharpClassName() {\n"; + $methodCode .= "\t\t\treturn (I$csharpClassName". "Proxy) _staticInterceptor;\n\t\t}\n\n"; + } + + if ($classNode->{astNodeName} ne $main::globalSpaceClassName) { +# my $s; +# for my $sn( @{$classNode->{Sources}} ) { +# if ( ($s = $sn->{astNodeName}) !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|tdeprint/|tdesu/)(.*)!$1$2!m ) { +# $s =~ s!.*/(.*)!$1!m; +# } +# $addInclude->{$s} = 1; +# } + } + + $addImport->{"Qt"} = 1; + + # Do all enums first, anonymous ones and then named enums + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'enum' and $currentClassName eq $csharpClassName ) { + my ($meth) = generateEnum( $classNode, $methodNode, 1 ); + $methodCode .= $meth; + } + }, undef ); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'enum' and $currentClassName eq $csharpClassName ) { + my ($meth) = generateEnum( $classNode, $methodNode, 0 ); + $methodCode .= $meth; + } + }, undef ); + + # Then all static vars + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'var' and $currentClassName eq $csharpClassName ) { + my ($meth, $interface) = generateVar( $classNode, $methodNode, $addImport ); + $methodCode .= $meth; +# $interfaceCode .= $interface; + } + }, undef ); + + # Then all methods + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'method' ) { + my ($meth, $interface, $proxyInterface, $signals) = generateMethod( $classNode, $methodNode, $addImport, $ancestorCount, $csharpMethods, $mainClassNode, $generateConstructors ); + $methodCode .= $meth; + $interfaceCode .= $interface; + $proxyInterfaceCode .= $proxyInterface; + $signalCode .= $signals; + } + }, undef ); + + # Virtual methods +# if ($classNode->{BindingDerives}) { +# my %virtualMethods; +# allVirtualMethods( $classNode, \%virtualMethods ); + +# for my $sig (sort keys %virtualMethods) { +# my ($meth) = generateVirtualMethod( $classNode, $sig, $virtualMethods{$sig}{method}, $virtualMethods{$sig}{class}, \%addImport ); +# $methodCode .= $meth; +# } +# } + + # Destructor + # "virtual" is useless, if the base class has a virtual destructor then the x_* class too. + #if($classNode->{HasVirtualDestructor} and $classNode->{HasDestructor}) { + # $methodCode .= " virtual ~$bridgeClassName() {}\n"; + #} + # We generate a dtor though, because we might want to add stuff into it + + if ($currentClassName eq $csharpClassName and $classNode->{HasPublicDestructor}) { + if ( $generateConstructors ) { + $methodCode .= "\t\t~$csharpClassName() {\n"; + $methodCode .= "\t\t\tDispose$csharpClassName();\n\t\t}\n"; + + if ( hasVirtualDestructor($classNode, $classNode) == 1 ) { + $methodCode .= "\t\tpublic new "; + } else { + $methodCode .= "\t\tpublic "; + } + $methodCode .= "void Dispose() {\n"; + $methodCode .= "\t\t\tDispose$csharpClassName();\n\t\t}\n"; + + $methodCode .= "\t\tprivate void Dispose$csharpClassName() {\n"; + $methodCode .= "\t\t\tProxy$csharpClassName().Dispose$csharpClassName();\n\t\t}\n"; + } +# die "$className destructor: methodNumber=$methodNumber != case entry=".$classNode->{case}{"~$className()"}."\n" +# if $methodNumber != $classNode->{case}{"~$className()"}; + $methodNumber++; + } + + return ( $methodCode, $interfaceCode, $proxyInterfaceCode, $signalCode ); +} + +# Return 0 if the class has no virtual dtor, 1 if it has, 2 if it's private +sub hasVirtualDestructor($$) +{ + my ( $classNode, $startNode ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if ( $skippedClasses{$className} || defined interfaceForClass($className) ); + + my $parentHasIt; + # Look at ancestors, and (recursively) call hasVirtualDestructor for each + # It's enough to have one parent with a prot/public virtual dtor + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + my $vd = hasVirtualDestructor( $_[0], $_[1] ); + $parentHasIt = $vd unless $parentHasIt > $vd; + } ); + return $parentHasIt if $parentHasIt; # 1 or 2 + + # Now look in $classNode - including private methods + my $doPrivate = $main::doPrivate; + $main::doPrivate = 1; + my $result; + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + return unless( $m->{NodeType} eq "method" && $m->{ReturnType} eq '~' ); + + if ( $m->{Flags} =~ /[vp]/ && $classNode != $startNode) { + if ( $m->{Access} =~ /private/ ) { + $result=2; # private virtual + } else { + $result=1; # [protected or public] virtual + } + } + }, + undef + ); + $main::doPrivate = $doPrivate; + $result=0 if (!defined $result); + return $result; +} + +=head2 allVirtualMethods + + Parameters: class node, dict + + Adds to the dict, for all method nodes that are virtual, in this class and in parent classes : + {method} the method node, {class} the class node (the one where the virtual is implemented) + +=cut + +sub allVirtualMethods($$) +{ + my ( $classNode, $virtualMethods ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if ( $skippedClasses{$className} ); + + # Look at ancestors, and (recursively) call allVirtualMethods for each + # This is done first, so that virtual methods that are reimplemented as 'private' + # can be removed from the list afterwards (below) + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + allVirtualMethods( @_[0], $virtualMethods ); + }, undef + ); + + # Now look for virtual methods in $classNode - including private ones + my $doPrivate = $main::doPrivate; + $main::doPrivate = 1; + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + # Only interested in methods, and skip destructors + return unless( $m->{NodeType} eq "method" && $m->{ReturnType} ne '~' ); + + my $signature = methodSignature( $m, $#{$m->{ParamList}} ); + print STDERR $signature . " ($m->{Access})\n" if ($debug); + + # A method is virtual if marked as such (v=virtual p=pure virtual) + # or if a parent method with same signature was virtual + if ( $m->{Flags} =~ /[vp]/ or defined $virtualMethods->{$signature} ) { + if ( $m->{Access} =~ /private/ ) { + if ( defined $virtualMethods->{$signature} ) { # remove previously defined + delete $virtualMethods->{$signature}; + } + # else, nothing, just ignore private virtual method + } else { + $virtualMethods->{$signature}{method} = $m; + $virtualMethods->{$signature}{class} = $classNode; + } + } + }, + undef + ); + $main::doPrivate = $doPrivate; +} + +# Known typedef? If so, apply it. +sub applyTypeDef($) +{ + my $type = shift; + # Parse 'const' in front of it, and '*' or '&' after it + my $prefix = $type =~ s/^const\s+// ? 'const ' : ''; + my $suffix = $type =~ s/\s*([\&\*]+)$// ? $1 : ''; + + if (exists $typedeflist{$type}) { + return $prefix.$typedeflist{$type}.$suffix; + } + return $prefix.$type.$suffix; +} + +# Register type ($1) into %allTypes if not already there +sub registerType($$) { + my $type = shift; + #print "registerType: $type\n" if ($debug); + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + return if ( $type eq 'void' or $type eq '' or $type eq '~' ); + die if ( $type eq '...' ); # ouch + + # Let's register the real type, not its known equivalent + #$type = applyTypeDef($type); + + # Enum _value_ -> get corresponding type + if (exists $enumValueToType{$type}) { + $type = $enumValueToType{$type}; + } + + # Already in allTypes + if(exists $allTypes{$type}) { + return; + } + + die if $type eq 'TQTextEdit::UndoRedoInfo::Type'; + die if $type eq ''; + + my $realType = $type; + + # Look for references (&) and pointers (* or **) - this will not handle *& correctly. + # We do this parsing here because both the type list and iterproto need it + if($realType =~ s/&$//) { + $allTypes{$type}{typeFlags} = 'Smoke::tf_ref'; + } + elsif($realType ne 'void*' && $realType =~ s/\*$//) { + $allTypes{$type}{typeFlags} = 'Smoke::tf_ptr'; + } + else { + $allTypes{$type}{typeFlags} = 'Smoke::tf_stack'; + } + + if ( $realType =~ s/^const\s+// ) { # Remove 'const' + $allTypes{$type}{typeFlags} .= ' | Smoke::tf_const'; + } + + # Apply typedefs, and store the resulting type. + # For instance, if $type was Q_UINT16&, realType will be ushort + $allTypes{$type}{realType} = applyTypeDef( $realType ); + + # In the first phase we only create entries into allTypes. + # The values (indexes) are calculated afterwards, once the list is full. + $allTypes{$type}{index} = -1; + #print STDERR "Register $type. Realtype: $realType\n" if($debug); +} + +# Get type from %allTypes +# This returns a hash with {index}, {isEnum}, {typeFlags}, {realType} +# (and {typeId} after the types array is written by writeSmokeDataFile) +sub findTypeEntry($) { + my $type = shift; + my $typeIndex = -1; + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + return undef if ( $type =~ '~' or $type eq 'void' or $type eq '' ); + + # Enum _value_ -> get corresponding type + if (exists $enumValueToType{$type}) { + $type = $enumValueToType{$type}; + } + + die "type not known: $type" unless defined $allTypes{$type}; + return $allTypes{ $type }; +} + +# List of all csharp super-classes for a given class, via single inheritance. +# Excluding any which are mapped onto interfaces to avoid multiple inheritance. +sub direct_superclass_list($) +{ + my $classNode = shift; + my @super; + my $has_ancestor = 0; + my $direct_ancestor = undef; + my $name; + + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + ( $direct_ancestor, $name ) = @_; + if ($name =~ /TQMemArray|TQSqlFieldInfoList/) { + # Template classes, give up for now.. + $has_ancestor = 1; + } elsif (!defined kalyptusDataDict::interfacemap($name)) { + push @super, $direct_ancestor; + push @super, direct_superclass_list( $direct_ancestor ); + $has_ancestor = 1; + } + }, undef ); + + if (! $has_ancestor and defined $direct_ancestor) { + push @super, $direct_ancestor; + push @super, direct_superclass_list( $direct_ancestor ); + } + + return @super; +} + +# List of all super-classes for a given class +sub superclass_list($) +{ + my $classNode = shift; + my @super; + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + push @super, @_[0]; + push @super, superclass_list( @_[0] ); + }, undef ); + return @super; +} + +sub is_kindof($$) +{ + my $classNode = shift; + my $className = shift; + + if ($classNode->{astNodeName} eq $className) { + return 1; + } + + my @superclasses = superclass_list($classNode); + foreach my $ancestor (@superclasses) { + if ($ancestor->{astNodeName} eq $className) { + return 1; + } + } + + return 0; +} + +# Store the {case} dict in the class Node (method signature -> index in the "case" switch) +# This also determines which methods should NOT be in the switch, and sets {SkipFromSwitch} for them +sub prepareCaseDict($) { + + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + $classNode->AddProp("case", {}); + my $methodNumber = 0; + + # First look at all enums for this class + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'enum'; + foreach my $val ( @{$m->{ParamList}} ) { + my $fullEnumName = "$className\::".$val->{ArgName}; + print STDERR "Enum: $fullEnumName -> case $methodNumber\n" if ($debug); + $classNode->{case}{$fullEnumName} = $methodNumber; + $enumValueToType{$fullEnumName} = "$className\::$m->{astNodeName}"; + $methodNumber++; + } + }, undef ); + + # Check for static vars + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'var'; + my $name = "$className\::".$m->{astNodeName}; + print STDERR "Var: $name -> case $methodNumber\n" if ($debug); + $classNode->{case}{$name} = $methodNumber; + $methodNumber++; + + }, undef ); + + + # Now look at all methods for this class + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'method'; + my $name = $m->{astNodeName}; + my $isConstructor = ($name eq $classNode->{astNodeName} ); + if ($isConstructor and ($m->{ReturnType} eq '~')) # destructor + { + # Remember whether we'll generate a switch entry for the destructor + $m->{SkipFromSwitch} = 1 unless ($classNode->{CanBeInstanciated} and $classNode->{HasPublicDestructor}); + next; + } + + # Don't generate bindings for protected methods (incl. signals) if + # we're not deriving from the C++ class. Only take public and public_slots + my $ok = ( $classNode->{BindingDerives} or $m->{Access} =~ /public/ ) ? 1 : 0; + + # Don't generate bindings for pure virtuals - we can't call them ;) + $ok = 0 if ( $ok && $m->{Flags} =~ "p" ); + + # Bugfix for Qt-3.0.4: those methods are NOT implemented (report sent). + $ok = 0 if ( $ok && $className eq 'TQLineEdit' && ( $name eq 'setPasswordChar' || $name eq 'passwordChar' ) ); + $ok = 0 if ( $ok && $className eq 'TQWidgetItem' && $name eq 'widgetSizeHint' ); + + if ( !$ok ) + { + #print STDERR "Skipping $className\::$name\n" if ($debug); + $m->{SkipFromSwitch} = 1; + next; + } + + my @args = @{ $m->{ParamList} }; + my $last = $m->{FirstDefaultParam}; + $last = scalar @args unless defined $last; + my $iterationCount = scalar(@args) - $last; + while($iterationCount >= 0) { + my $sig = methodSignature( $m, $#args ); + $classNode->{case}{$sig} = $methodNumber; + #print STDERR "prepareCaseDict: registered case number $methodNumber for $sig in $className()\n" if ($debug); + pop @args; + $iterationCount--; + $methodNumber++; + } + }, undef ); + + # Add the destructor, at the end + if ($classNode->{CanBeInstanciated} and $classNode->{HasPublicDestructor}) { + $classNode->{case}{"~$className()"} = $methodNumber; + # workaround for ~Sub::Class() being seen as Sub::~Class() + $classNode->{case}{"~$classNode->{astNodeName}()"} = $methodNumber; + #print STDERR "prepareCaseDict: registered case number $methodNumber for ~$className()\n" if ($debug); + } +} + +sub writeSmokeDataFile($) { + my $rootnode = shift; + + # Make list of classes + my %allImports; # list of all header files for all classes + my @classlist; + push @classlist, ""; # Prepend empty item for "no class" + my %enumclasslist; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = $_[0]; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + push @classlist, $className; + $enumclasslist{$className}++ if keys %{$classNode->{enumerations}}; + $classNode->{ClassIndex} = $#classlist; + addImportForClass( $classNode, \%allImports, undef ); + } ); + + my %classidx = do { my $i = 0; map { $_ => $i++ } @classlist }; + + my $file = "$outputdir/smokedata.cpp"; +# open OUT, ">$file" or die "Couldn't create $file\n"; + +# foreach my $incl (sort{ +# return 1 if $a=~/qmotif/; # move qmotif* at bottom (they include dirty X11 headers) +# return -1 if $b=~/qmotif/; +# return -1 if substr($a,0,1) eq 'q' and substr($b,0,1) ne 'q'; # move Qt headers on top +# return 1 if substr($a,0,1) ne 'q' and substr($b,0,1) eq 'q'; +# $a cmp $b +# } keys %allIncludes) { +# die if $imp eq ''; +# print OUT "import $imp;\n"; +# } + +# print OUT "\n"; + + print STDERR "Writing ${libname}_cast function\n" if ($debug); + + # Prepare descendants information for each class + my %descendants; # classname -> list of descendant nodes + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + # Get _all_ superclasses (up any number of levels) + # and store that $classNode is a descendant of $s + my @super = superclass_list($classNode); + for my $s (@super) { + my $superClassName = join( "::", kdocAstUtil::heritage($s) ); + Ast::AddPropList( \%descendants, $superClassName, $classNode ); + } + } ); + + # Iterate over all classes, to write the xtypecast function + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + # @super will contain superclasses, the class itself, and all descendants + my @super = superclass_list($classNode); + push @super, $classNode; + if ( defined $descendants{$className} ) { + push @super, @{$descendants{$className}}; + } + my $cur = $classidx{$className}; + + return if $classNode->{NodeType} eq 'namespace'; + +# print OUT " case $cur:\t//$className\n"; +# print OUT "\tswitch(to) {\n"; +# $cur = -1; +# my %casevalues; +# for my $s (@super) { +# my $superClassName = join( "::", kdocAstUtil::heritage($s) ); +# next if !defined $classidx{$superClassName}; # inherits from unknown class, see below +# next if $classidx{$superClassName} == $cur; # shouldn't happen in Qt +# next if $s->kdocAstUtil::inheritsAsVirtual($classNode); # can't cast from a virtual base class +# $cur = $classidx{$superClassName}; # KDE has MI with diamond shaped cycles (cf. KXMLGUIClient) +# next if $casevalues{$cur}; # ..so skip any duplicate parents +# print OUT "\t case $cur: return (void*)($superClassName*)($className*)xptr;\n"; +# $casevalues{$cur} = 1; +# } +# print OUT "\t default: return xptr;\n"; +# print OUT "\t}\n"; + } ); +# print OUT " default: return xptr;\n"; +# print OUT " }\n"; +# print OUT "}\n\n"; + + + # Write inheritance array + # Imagine you have "Class : public super1, super2" + # The inheritlist array will get 3 new items: super1, super2, 0 + my %inheritfinder; # key = (super1, super2) -> data = (index in @inheritlist). This one allows reuse. + my %classinherit; # we store that index in %classinherit{className} + # We don't actually need to store inheritlist in memory, we write it + # directly to the file. We only need to remember its current size. + my $inheritlistsize = 1; + +# print OUT "// Group of class IDs (0 separated) used as super class lists.\n"; +# print OUT "// Classes with super classes have an index into this array.\n"; +# print OUT "static short ${libname}_inheritanceList[] = {\n"; +# print OUT "\t0,\t// 0: (no super class)\n"; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "__", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + print STDERR "inheritanceList: looking at $className\n" if ($debug); + + # Make list of direct ancestors + my @super; + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + my $superClassName = join( "::", kdocAstUtil::heritage($_[0]) ); + push @super, $superClassName; + }, undef ); + # Turn that into a list of class indexes + my $key = ''; + foreach my $superClass( @super ) { + if (defined $classidx{$superClass}) { + $key .= ', ' if ( length $key > 0 ); + $key .= $classidx{$superClass}; + } + } + if ( $key ne '' ) { + if ( !defined $inheritfinder{$key} ) { + print OUT "\t"; + my $index = $inheritlistsize; # Index of first entry (for this group) in inheritlist + foreach my $superClass( @super ) { + if (defined $classidx{$superClass}) { + print OUT "$classidx{$superClass}, "; + $inheritlistsize++; + } + } + $inheritlistsize++; + my $comment = join( ", ", @super ); + print OUT "0,\t// $index: $comment\n"; + $inheritfinder{$key} = $index; + } + $classinherit{$className} = $inheritfinder{$key}; + } else { # No superclass + $classinherit{$className} = 0; + } + } ); +# print OUT "};\n\n"; + + +# print OUT "// These are the xenum functions for manipulating enum pointers\n"; + for my $className (keys %enumclasslist) { + my $c = $className; + $c =~ s/::/__/g; +# print OUT "void xenum_$c\(Smoke::EnumOperation, Smoke::Index, void*&, long&);\n"; + } +# print OUT "\n"; +# print OUT "// Those are the xcall functions defined in each x_*.cpp file, for dispatching method calls\n"; + my $firstClass = 1; + for my $className (@classlist) { + if ($firstClass) { + $firstClass = 0; + next; + } + my $c = $className; # make a copy + $c =~ s/::/__/g; +# print OUT "void xcall_$c\(Smoke::Index, void*, Smoke::Stack);\n"; + } +# print OUT "\n"; + + # Write class list afterwards because it needs offsets to the inheritance array. +# print OUT "// List of all classes\n"; +# print OUT "// Name, index into inheritanceList, method dispatcher, enum dispatcher, class flags\n"; +# print OUT "static Smoke::Class ${libname}_classes[] = {\n"; + my $firstClass = 1; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "__", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + if ($firstClass) { + $firstClass = 0; + print OUT "\t{ 0L, 0, 0, 0, 0 }, \t// 0 (no class)\n"; + } + my $c = $className; + $c =~ s/::/__/g; + my $xcallFunc = "xcall_$c"; + my $xenumFunc = "0"; + $xenumFunc = "xenum_$c" if exists $enumclasslist{$className}; + # %classinherit needs Foo__Bar, not Foo::Bar? + die "problem with $className" unless defined $classinherit{$c}; + + my $xClassFlags = 0; + $xClassFlags .= "|Smoke::cf_constructor" if $classNode->{CanBeInstanciated}; # correct? + $xClassFlags .= "|Smoke::cf_deepcopy" if $classNode->{CanBeCopied}; # HasCopyConstructor would be wrong (when it's private) + $xClassFlags .= "|Smoke::cf_virtual" if hasVirtualDestructor($classNode, $classNode) == 1; + # $xClassFlags .= "|Smoke::cf_undefined" if ...; + $xClassFlags =~ s/0\|//; # beautify +# print OUT "\t{ \"$className\", $classinherit{$c}, $xcallFunc, $xenumFunc, $xClassFlags }, \t//$classidx{$className}\n"; + } ); +# print OUT "};\n\n"; + + +# print OUT "// List of all types needed by the methods (arguments and return values)\n"; +# print OUT "// Name, class ID if arg is a class, and TypeId\n"; +# print OUT "static Smoke::Type ${libname}_types[] = {\n"; + my $typeCount = 0; + $allTypes{''}{index} = 0; # We need an "item 0" + for my $type (sort keys %allTypes) { + $allTypes{$type}{index} = $typeCount; # Register proper index in allTypes + if ( $typeCount == 0 ) { +# print OUT "\t{ 0, 0, 0 },\t//0 (no type)\n"; + $typeCount++; + next; + } + my $isEnum = $allTypes{$type}{isEnum}; + my $typeId; + my $typeFlags = $allTypes{$type}{typeFlags}; + my $realType = $allTypes{$type}{realType}; + die "$type" if !defined $typeFlags; +# die "$realType" if $realType =~ /\(/; + # First write the name +# print OUT "\t{ \"$type\", "; + # Then write the classId (and find out the typeid at the same time) + if(exists $classidx{$realType}) { # this one first, we want t_class for TQBlah* + $typeId = 't_class'; +# print OUT "$classidx{$realType}, "; + } + elsif($type =~ /&$/ || $type =~ /\*$/) { + $typeId = 't_voidp'; +# print OUT "0, "; # no classId + } + elsif($isEnum || $allTypes{$realType}{isEnum}) { + $typeId = 't_enum'; + if($realType =~ /(.*)::/) { + my $c = $1; + if($classidx{$c}) { +# print OUT "$classidx{$c}, "; + } else { +# print OUT "0 /* unknown class $c */, "; + } + } else { +# print OUT "0 /* unknown $realType */, "; # no classId + } + } + else { + $typeId = $typeunion{$realType}; + if (defined $typeId) { + $typeId =~ s/s_/t_/; # from s_short to t_short for instance + } + else { + # Not a known class - ouch, this happens quite a lot + # (private classes, typedefs, template-based types, etc) + if ( $skippedClasses{$realType} ) { +# print STDERR "$realType has been skipped, using t_voidp for it\n"; + } else { + unless( $realType =~ / map to a void * + } +# print OUT "0, "; # no classId + } + # Then write the flags + die "$type" if !defined $typeId; +# print OUT "Smoke::$typeId | $typeFlags },"; +# print OUT "\t//$typeCount\n"; + $typeCount++; + # Remember it for coerce_type + $allTypes{$type}{typeId} = $typeId; + } +# print OUT "};\n\n"; + + + my %arglist; # registers the needs for argumentList (groups of type ids) + my %methods; + # Look for all methods and all enums, in all classes + # And fill in methods and arglist. This loop writes nothing to OUT. + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + print STDERR "writeSmokeDataFile: arglist: looking at $className\n" if ($debug); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + my $methName = $m->{astNodeName}; + # For destructors, get a proper signature that includes the '~' + if ( $m->{ReturnType} eq '~' ) + { + $methName = '~' . $methName ; + # Let's even store that change, otherwise we have to do it many times + $m->{astNodeName} = $methName; + } + + if( $m->{NodeType} eq "enum" ) { + + foreach my $enum ( @{$m->{ParamList}} ) { + my $enumName = $enum->{ArgName}; + $methods{$enumName}++; + } + + } elsif ( $m->{NodeType} eq 'var' ) { + + $methods{$m->{astNodeName}}++; + + } elsif( $m->{NodeType} eq "method" ) { + + $methods{$methName}++; + my @protos; + makeprotos(\%classidx, $m, \@protos); + + #print "made @protos from $className $methName $m->{Signature})\n" if ($debug); + for my $p (@protos) { + $methods{$p}++; + my $argcnt = 0; + $argcnt = length($1) if $p =~ /([\$\#\?]+)/; + my $sig = methodSignature($m, $argcnt-1); + # Store in a class hash named "proto", a proto+signature => method association + $classNode->{proto}{$p}{$sig} = $m; + #$classNode->{signature}{$sig} = $p; + # There's probably a way to do this better, but this is the fastest way + # to get the old code going: store classname into method + $m->{class} = $className; + } + + my $firstDefaultParam = $m->{FirstDefaultParam}; + $firstDefaultParam = scalar(@{ $m->{ParamList} }) unless defined $firstDefaultParam; + my $argNames = ''; + my $args = ''; + for(my $i = 0; $i < @{ $m->{ParamList} }; $i++) { + $args .= ', ' if $i; + $argNames .= ', ' if $i; + my $argType = $m->{ParamList}[$i]{ArgType}; + my $typeEntry = findTypeEntry( $argType ); + $args .= defined $typeEntry ? $typeEntry->{index} : 0; + $argNames .= $argType; + + if($i >= ($firstDefaultParam - 1)) { + #print "arglist entry: $args\n"; + $arglist{$args} = $argNames; + } + + } + # create an entry for e.g. "arg0,arg1,arg2" where argN is index in allTypes of type for argN + # The value, $argNames, is temporarily stored, to be written out as comment + # It gets replaced with the index in the next loop. + #print "arglist entry : $args\n"; + $arglist{$args} = $argNames; + } + }, # end of sub + undef + ); + }); + + + $arglist{''} = 0; + # Print arguments array +# print OUT "static Smoke::Index ${libname}_argumentList[] = {\n"; + my $argListCount = 0; + for my $args (sort keys %arglist) { + my @dunnohowtoavoidthat = split(',',$args); + my $numTypes = $#dunnohowtoavoidthat; + if ($args eq '') { +# print OUT "\t0,\t//0 (void)\n"; + } else { + # This is a nice trick : args can be written in one go ;) +# print OUT "\t$args, 0,\t//$argListCount $arglist{$args} \n"; + } + $arglist{$args} = $argListCount; # Register proper index in argList + $argListCount += $numTypes + 2; # Move forward by as much as we wrote out + } +# print OUT "};\n\n"; + + $methods{''} = 0; + my @methodlist = sort keys %methods; + my %methodidx = do { my $i = 0; map { $_ => $i++ } @methodlist }; + +# print OUT "// Raw list of all methods, using munged names\n"; +# print OUT "static const char *${libname}_methodNames[] = {\n"; + my $methodNameCount = $#methodlist; + for my $m (@methodlist) { +# print OUT qq( "$m",\t//$methodidx{$m}\n); + } +# print OUT "};\n\n"; + +# print OUT "// (classId, name (index in methodNames), argumentList index, number of args, method flags, return type (index in types), xcall() index)\n"; +# print OUT "static Smoke::Method ${libname}_methods[] = {\n"; + my @methods; + %allMethods = (); + my $methodCount = 0; + # Look at all classes and all enums again + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if $classNode->{NodeType} eq 'namespace'; + + my $classIndex = $classidx{$className}; + print STDERR "writeSmokeDataFile: methods: looking at $className\n" if ($debug); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + if( $m->{NodeType} eq "enum" ) { + + foreach my $enum ( @{$m->{ParamList}} ) { + my $enumName = $enum->{ArgName}; + my $fullEnumName = "$className\::$enumName"; + my $sig = "$className\::$enumName\()"; + my $xmethIndex = $methodidx{$enumName}; + die "'Method index' for enum $sig not found" unless defined $xmethIndex; + my $typeId = findTypeEntry( $fullEnumName )->{index}; + die "enum has no {case} value in $className: $fullEnumName" unless defined $classNode->{case}{$fullEnumName}; +# print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullEnumName}},\t//$methodCount $fullEnumName (enum)\n"; + $allMethods{$sig} = $methodCount; + print STDERR "Added entry for " . $sig . " into \$allMethods\n" if ($debug); + $methods[$methodCount] = { + c => $classIndex, + methIndex => $xmethIndex, + argcnt => '0', + args => 0, + retTypeIndex => 0, + idx => $classNode->{case}{$fullEnumName} + }; + $methodCount++; + } + + } elsif( $m->{NodeType} eq 'var' ) { + + my $name = $m->{astNodeName}; + my $fullName = "$className\::$name"; + my $sig = "$fullName\()"; + my $xmethIndex = $methodidx{$name}; + die "'Method index' for var $sig not found" unless defined $xmethIndex; + my $varType = $m->{Type}; + $varType =~ s/static\s//; + $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/\s*$//; + my $typeId = findTypeEntry( $varType )->{index}; + die "var has no {case} value in $className: $fullName" unless defined $classNode->{case}{$fullName}; +# print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullName}},\t//$methodCount $fullName (static var)\n"; + $allMethods{$sig} = $methodCount; + print STDERR "Added entry for " . $sig . " into \$allMethods\n" if ($debug); + $methods[$methodCount] = { + c => $classIndex, + methIndex => $xmethIndex, + argcnt => '0', + args => 0, + retTypeIndex => 0, + idx => $classNode->{case}{$fullName} + }; + $methodCount++; + + + } elsif( $m->{NodeType} eq "method" ) { + + # We generate a method entry only if the method is in the switch() code + # BUT: for pure virtuals, they need to have a method entry, even though they + # do NOT have a switch code. + return if ( $m->{SkipFromSwitch} && $m->{Flags} !~ "p" ); + + # No switch code for destructors if we didn't derive from the class (e.g. it has private ctors only) + return if ( $m->{ReturnType} eq '~' && ! ( $classNode->{BindingDerives} and $classNode->{HasPublicDestructor}) ); + + # Is this sorting really important? + #for my $m (sort {$a->{name} cmp $b->{name}} @{ $self->{$c}{method} }) { + + my $methName = $m->{astNodeName}; + my $def = $m->{FirstDefaultParam}; + $def = scalar(@{ $m->{ParamList} }) unless defined $def; + my $last = scalar(@{ $m->{ParamList} }) - 1; + #print STDERR "writeSmokeDataFile: methods: generating for method $methName, def=$def last=$last\n" if ($debug); + + while($last >= ($def-1)) { + last if $last < -1; + my $args = [ @{ $m->{ParamList} }[0..$last] ]; + my $sig = methodSignature($m, $last); + #my $methodSig = $classNode->{signature}{$sig}; # Munged signature + #print STDERR "writeSmokeDataFile: methods: sig=$className\::$sig methodSig=$methodSig\n" if ($debug); + #my $methodIndex = $methodidx{$methodSig}; + #die "$methodSig" if !defined $methodIndex; + + my $methodIndex = $methodidx{$methName}; + die "$methName" if !defined $methodIndex; + my $case = $classNode->{case}{$sig}; + my $typeEntry = findTypeEntry( $m->{ReturnType} ); + my $retTypeIndex = defined $typeEntry ? $typeEntry->{index} : 0; + + my $i = 0; + my $t = ''; + for my $arg (@$args) { + $t .= ', ' if $i++; + my $typeEntry = findTypeEntry( $arg->{ArgType} ); + $t .= defined $typeEntry ? $typeEntry->{index} : 0; + } + my $arglist = $t eq '' ? 0 : $arglist{$t}; + die "arglist for $t not found" unless defined $arglist; + if ( $m->{Flags} =~ "p" ) { + # Pure virtuals don't have a {case} number, that's normal + die if defined $case; + $case = -1; # This remains -1, not 0 ! + } else { + ; +# die "$className\::$methName has no case number for sig=$sig" unless defined $case; + } + my $argcnt = $last + 1; + my $methodFlags = '0'; + $methodFlags .= "|Smoke::mf_static" if $m->{Flags} =~ "s"; + $methodFlags .= "|Smoke::mf_const" if $m->{Flags} =~ "c"; # useful?? probably not + $methodFlags =~ s/0\|//; # beautify + +# print OUT "\t{$classIndex, $methodIndex, $arglist, $argcnt, $methodFlags, $retTypeIndex, $case},\t//$methodCount $className\::$sig"; +# print OUT " [pure virtual]" if ( $m->{Flags} =~ "p" ); # explain why $case = -1 ;) +# print OUT "\n"; + + $allMethods{$className . "::" . $sig} = $methodCount; + $methods[$methodCount] = { + c => $classIndex, + methIndex => $methodIndex, + argcnt => $argcnt, + args => $arglist, + retTypeIndex => $retTypeIndex, + idx => $case + }; + $methodCount++; + $last--; + } # while + } # if method + } ); # Method Iter + } ); # Class Iter +# print OUT "};\n\n"; + + my @protos; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + my $classIndex = $classidx{$className}; + print STDERR "writeSmokeDataFile: protos: looking at $className\n" if ($debug); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + if( $m->{NodeType} eq "enum" ) { + foreach my $enum ( @{$m->{ParamList}} ) { + my $enumName = $enum->{ArgName}; + my $sig = "$className\::$enumName\()"; + my $xmeth = $allMethods{$sig}; + die "'Method' for enum $sig not found" unless defined $xmeth; + my $xmethIndex = $methodidx{$enumName}; + die "'Method index' for enum $enumName not found" unless defined $xmethIndex; + push @protos, { + methIndex => $xmethIndex, + c => $classIndex, + over => { + $sig => { + sig => $sig, + } + }, + meth => $xmeth + }; + } + + } elsif( $m->{NodeType} eq 'var' ) { + + my $name = $m->{astNodeName}; + my $fullName = "$className\::$name"; + my $sig = "$fullName\()"; + my $xmeth = $allMethods{$sig}; + die "'Method' for var $sig not found" unless defined $xmeth; + my $xmethIndex = $methodidx{$name}; + die "'Method index' for var $name not found" unless defined $xmethIndex; + push @protos, { + methIndex => $xmethIndex, + c => $classIndex, + over => { + $sig => { + sig => $sig, + } + }, + meth => $xmeth + }; + + } + }); + + for my $p (keys %{ $classNode->{proto} }) { + # For each prototype + my $scratch = { %{ $classNode->{proto}{$p} } }; # sig->method association + # first, grab all the superclass voodoo + for my $supNode (superclass_list($classNode)) { + my $i = $supNode->{proto}{$p}; + next unless $i; + for my $k (keys %$i) { + $scratch->{$k} = $i->{$k} unless exists $scratch->{$k}; + } + } + + # Ok, now we have a full list + #if(scalar keys %$scratch > 1) { + #print STDERR "Overload: $p (@{[keys %$scratch]})\n" if ($debug); + #} + my $xmethIndex = $methodidx{$p}; + my $classIndex = $classidx{$className}; + for my $sig (keys %$scratch) { + #my $xsig = $scratch->{$sig}{class} . "::" . $sig; + my $xsig = $className . "::" . $sig; + $scratch->{$sig}{sig} = $xsig; + delete $scratch->{$sig} + if $scratch->{$sig}{Flags} =~ "p" # pure virtual + or not exists $allMethods{$xsig}; + } + push @protos, { + methIndex => $xmethIndex, + c => $classIndex, + over => $scratch + } if scalar keys %$scratch; + } + }); + + my @protolist = sort { $a->{c} <=> $b->{c} || $a->{methIndex} <=> $b->{methIndex} } @protos; +#for my $abc (@protos) { +#print "$abc->{methIndex}.$abc->{c}\n"; +#} + + print STDERR "Writing methodmap table\n" if ($debug); + my @resolve = (); +# print OUT "// Class ID, munged name ID (index into methodNames), method def (see methods) if >0 or number of overloads if <0\n"; + my $methodMapCount = 1; +# print OUT "static Smoke::MethodMap ${libname}_methodMaps[] = {\n"; +# print OUT "\t{ 0, 0, 0 },\t//0 (no method)\n"; + for my $cur (@protolist) { + if(scalar keys %{ $cur->{over} } > 1) { +# print OUT "\t{$cur->{c}, $cur->{methIndex}, -@{[1+scalar @resolve]}},\t//$methodMapCount $classlist[$cur->{c}]\::$methodlist[$cur->{methIndex}]\n"; + $methodMapCount++; + for my $k (keys %{ $cur->{over} }) { + my $p = $cur->{over}{$k}; + my $xsig = $p->{class} ? "$p->{class}\::$k" : $p->{sig}; + push @resolve, { k => $k, p => $p, cur => $cur, id => $allMethods{$xsig} }; + } + push @resolve, 0; + } else { + for my $k (keys %{ $cur->{over} }) { + my $p = $cur->{over}{$k}; + my $xsig = $p->{class} ? "$p->{class}\::$k" : $p->{sig}; +# print OUT "\t{$cur->{c}, $cur->{methIndex}, $allMethods{$xsig}},\t//$methodMapCount $classlist[$cur->{c}]\::$methodlist[$cur->{methIndex}]\n"; + $methodMapCount++; + } + } + } +# print OUT "};\n\n"; + + + print STDERR "Writing ambiguousMethodList\n" if ($debug); +# print OUT "static Smoke::Index ${libname}_ambiguousMethodList[] = {\n"; +# print OUT " 0,\n"; + for my $r (@resolve) { + unless($r) { +# print OUT " 0,\n"; + next; + } + my $xsig = $r->{p}{class} ? "$r->{p}{class}\::$r->{k}" : $r->{p}{sig}; + die "ambiguousMethodList: no method found for $xsig\n" if !defined $allMethods{$xsig}; +# print OUT " $allMethods{$xsig}, // $xsig\n"; + } +# print OUT "};\n\n"; + +# print OUT "extern \"C\" { // needed?\n"; +# print OUT " void init_${libname}_Smoke();\n"; +# print OUT "}\n"; +# print OUT "\n"; +# print OUT "Smoke* qt_Smoke = 0L;\n"; +# print OUT "\n"; +# print OUT "// Create the Smoke instance encapsulating all the above.\n"; +# print OUT "void init_${libname}_Smoke() {\n"; +# print OUT " qt_Smoke = new Smoke(\n"; +# print OUT " ${libname}_classes, ".$#classlist.",\n"; +# print OUT " ${libname}_methods, $methodCount,\n"; +# print OUT " ${libname}_methodMaps, $methodMapCount,\n"; +# print OUT " ${libname}_methodNames, $methodNameCount,\n"; +# print OUT " ${libname}_types, $typeCount,\n"; +# print OUT " ${libname}_inheritanceList,\n"; +# print OUT " ${libname}_argumentList,\n"; +# print OUT " ${libname}_ambiguousMethodList,\n"; +# print OUT " ${libname}_cast );\n"; +# print OUT "}\n"; +# close OUT; + +#print "@{[keys %allMethods ]}\n"; +} +=head2 printCSharpdocComment + + Parameters: docnode filehandle + + Converts a kdoc comment to csharpdoc format. + @ref's are converted to 's; @p's and @em's are converted + to inline HTML. + +=cut + +sub printCSharpdocComment($$$$) +{ + my( $docnode, $name, $indent, $signalLink ) = @_; + + my $node; + my $returntext = ''; + foreach $node ( @{$docnode->{Text}} ) { + next if $node->{NodeType} ne "DocText" and $node->{NodeType} ne "ListItem" + and $node->{NodeType} ne "Param"; + my $line = ''; + + if ($node->{NodeType} eq "Param") { + if ($node->{Name} !~ /argc/) { + $line = " name=\"" . $node->{Name} . "\" " . $node->{astNodeName} . ""; + } + } else { + $line = $node->{astNodeName}; + } + $line =~ s/argc, ?argv/args/g; + $line =~ s/int argc, ?char ?\* ?argv(\[\])?/string[] args/g; + $line =~ s/int argc, ?char ?\*\* ?argv/string[] args/g; + if ($node->{NodeType} eq "Param") { + $line =~ s/(const )?QC?StringList(\s*&)?/string[]/g; + } else { + $line =~ s/(const )?QC?StringList(\s*&)?/ArrayList/g; + } + $line =~ s/NodeList|KTrader::OfferList/ArrayList/g; + $line =~ s/(const )?TQDate(Time)?(\s*&)?/DateTime/g; + $line =~ s/(const )?TQTime([^r])/DateTime$1/g; + $line =~ s/TQString::null/null/g; + $line =~ s/(const )?QC?String(\s*&)?/string/g; + $line =~ s/(const )?KCmdLineOptions\s*(\w+)\[\]/string[][] $2/; + $line =~ s/KCmdLineLastOption//g; + $line =~ s/virtual //g; + $line =~ s/~\w+\(\)((\s*{\s*})|;)//g; + $line =~ s/0L/null/g; + $line =~ s/(\([^\)]*\))\s*:\s*\w+\([^\)]*\)/$1/g; + $line =~ s/\(void\)//g; + $line =~ s/const char/string/g; + $line =~ s/const (\w+)\&/$1/g; + $line =~ s/bool/bool/g; + $line =~ s/SLOT\(\s*([^\)]*)\) ?\)/SLOT("$1)")/g; + $line =~ s/SIGNAL\(\s*([^\)]*)\) ?\)/SIGNAL("$1)")/g; + $line =~ s/Q_OBJECT\n//g; + $line =~ s/public\s*(slots)?:\n/public /g; + $line =~ s/([^0-9"]\s*)\*(\s*[^0-9"-])/$1$2/g; + $line =~ s/^(\s*)\*/$1/g; + $line =~ s/\n \*/\n /g; + $line =~ s!\@ref\s+([\w]+)::([\w]+)\s*(\([^\)]*\))(\.)?!$4!g; + $line =~ s!\@ref\s+#([\w:]+)(\(\))?!!g; + $line =~ s!\@ref\s+([\w]+)\s*(\([^\)]*\))!!g; + $line =~ s!\@ref\s+([\w]+)::([\w]+)!!g; + $line =~ s!\@ref\s+([a-z][\w]+)!!g; + $line =~ s!\@ref\s+([\w]+)!!g; + while ($line =~ /\@c\s+([\w#\\\.<>]+)/ ) { + my $code = $1; + $code =~ s!!>!g; + $code =~ s!\\#!#!g; + $line =~ s!\@c\s+([\w#\\\.<>]+)!$code!; + } + $line =~ s!\@em\s+(\w+)!$1!g; + $line =~ s!\@p\s+([\w\._]*)!$1!g; + $line =~ s!\\paragraph\s+[\w]+\s([\w]+)!
  • $1
  • !g; + $line =~ s!\\b\s+([\w -]+)\\n!
  • $1
  • !g; + $line =~ s!\\c\s+([\w\@&\\?;-]+)!$1!g; + $line =~ s!\\p\s+([\w\@]+)!
    $1
    !g; + $line =~ s!\\li\s+([\w\@]+)!
  • $1
  • !g; + $line =~ s!([\w\t \(\)-]*:?)\\n!
  • $1
  • !g; + $line =~ s!static_cast<\s*([\w\.]*)\s*>!($1)!g; +# if ($name ne "") { +# $line =~ s/\@link #/\@link $name\#/g; +# } + + if ($node->{NodeType} eq "ListItem") { + $line =~ s/^/\n
  • \n/; + $line =~ s!$!\n
  • !; +# $line =~ s/\n/\n$indent\t/g; + } else { +# $line =~ s/^/$indent/; +# $line =~ s/\n/\n$indent/g; + } + +# $line =~ s/\n/\n$indent/g; + $returntext .= $line; + } + + $returntext .= "$signalLink
    "; + + if ( defined $docnode->{Returns} ) { + my $text = $docnode->{Returns}; + $text =~ s/TQString::null/null/g; + $returntext .= "\t\t $text\n"; + } + + if ( defined $docnode->{Author} ) { + $returntext .= "\t\t " . $docnode->{Author} . "\n" + } + + if ( defined $docnode->{Version} ) { + my $versionStr = $docnode->{Version}; + $versionStr =~ s/\$\s*Id:([^\$]*) Exp \$/$1/; + $returntext .= "\t\t $versionStr\n"; + } + + if ( defined $docnode->{ClassShort} ) { + my $shortText = $docnode->{ClassShort}; + $shortText =~ s![\*\n]! !g; + $returntext .= "\t\t $shortText\n"; + } + + if ( defined $docnode->{See} ) { + foreach my $text ( @{$docnode->{See}} ) { + next if ($text =~ /TQString|^\s*and\s*$|^\s*$|^[^\w]*$/); + $text =~ s/KIO:://g; + $text =~ s/KParts:://g; + while ($text =~ /((::)|(->))(.)/) { + my $temp = uc($4); + $text =~ s/$1$4/.$temp/; + } + $text =~ s/\(\)//g; + $text =~ s/^\s*([a-z].*)/$1/g; + $returntext .= "\t\t $text\n"; + } + } + + $returntext =~ s/DOM#([A-Z])/$1/g; + $returntext =~ s/KIO#([A-Z])/$1/g; + $returntext =~ s/KParts#([A-Z])/$1/g; + $returntext =~ s/const\s+(\w+)\s*\&/$1/g; + $returntext =~ s/TQChar/char/g; + $returntext =~ s/TQStringList/ArrayList/g; + $returntext =~ s/([Aa]) ArrayList/$1n ArrayList/g; + $returntext =~ s/TQString/string/g; + $returntext =~ s/KCmdLineOptions/string[][]/; + $returntext =~ s!\\note!Note:<\b>!g; + $returntext =~ s!\\(code|verbatim)!
    !g;
    +	$returntext =~ s!\\(endcode|endverbatim)!
    !g; + $returntext =~ s!\\addtogroup\s+[\w]+\s+"([^"\@]+)"\s+\@{!
  • $1
  • !g; + $returntext =~ s![\\\@]relates\s+([a-z][\w]*)!!g; + $returntext =~ s![\\\@]relates\s+(\w+)::(\w+)!!g; + $returntext =~ s![\\\@]relates\s+(#?\w+)!!g; + $returntext =~ s!\\c\s+([\w\@&\\?";-]+)!$1!g; + $returntext =~ s!\@p\s+([\w\._]*)!$1!g; + $returntext =~ s!\@a\s+([:\w]+)!$1!g; + $returntext =~ s![\@\\]b\s+[:\w]!$1!g; + $returntext =~ s/};/}/g; + + while ($returntext =~ /((::)|(->))(.)/) { + my $temp = uc($4); + $returntext =~ s/$1$4/.$temp/; + } + + $returntext =~ s/\s*$//; + if ($returntext =~ /^\s*<\/remarks>$/) { + return ""; + } else { + $returntext =~ s/\n/\n$indent/g; + $returntext =~ s/^/$indent/; + return $returntext . "\n"; + } +} + +1; diff --git a/kalyptus/kalyptusCxxToSmoke.pm b/kalyptus/kalyptusCxxToSmoke.pm index 3a1f53f..8aa6897 100644 --- a/kalyptus/kalyptusCxxToSmoke.pm +++ b/kalyptus/kalyptusCxxToSmoke.pm @@ -35,7 +35,7 @@ no strict "subs"; use vars qw/ $libname $rootnode $outputdir $opt $debug - $methodNumber + $methodNumber $headerSubdirectories %builtins %typeunion %allMethods %allTypes %enumValueToType %typedeflist %mungedTypeMap %skippedClasses /; @@ -69,12 +69,16 @@ BEGIN 'TQCString' => '$', 'TQCString*' => '$', 'TQCString&' => '$', - 'TQByteArray' => '$', - 'TQByteArray&' => '$', - 'TQByteArray*' => '$', 'char*' => '$', 'TQCOORD*' => '?', 'TQRgb*' => '?', + 'Q_UINT64' => '$', + 'Q_INT64' => '$', + 'Q_LLONG' => '$', + 'tquint64' => '$', + 'qint64' => '$', + 'long long' => '$', + 'qulonglong' => '$', ); # Yes some of this is in kalyptusDataDict's ctypemap @@ -111,20 +115,23 @@ BEGIN # 'TQTSMFI' => 'void*', # TQTextStream's TQTSManip # 'const GUID&' => 'void*', # 'TQWidgetMapper*' => 'void*', -# 'MSG*' => 'void*', + 'MSG*' => 'void*', # 'const TQSqlFieldInfoList&' => 'void*', # TQSqlRecordInfo - TODO (templates) 'TQPtrCollection::Item' => 'void*', # to avoid a warning + 'void(* )()' => 'void*', + 'void (*)(void* )' => 'void*', 'mode_t' => 'long', 'TQProcess::PID' => 'long', 'size_type' => 'int', # TQSqlRecordInfo 'TQt::ComparisonFlags' => 'uint', - 'TQt::ToolBarDock' => 'int', # compat thing, TQt shouldn't use it + 'TQt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it 'TQIODevice::Offset' => 'ulong', 'WState' => 'int', 'WId' => 'ulong', 'TQRgb' => 'uint', + 'ksocklen_t' => 'uint', 'TQCOORD' => 'int', 'TQTSMFI' => 'int', 'TQt::WState' => 'int', @@ -133,16 +140,98 @@ BEGIN 'TQEventLoop::ProcessEventsFlags' => 'uint', 'TQStyle::SCFlags' => 'int', 'TQStyle::SFlags' => 'int', - 'TTQ_INT16' => 'short', - 'TTQ_INT32' => 'int', - 'TTQ_INT8' => 'char', - 'TTQ_LONG' => 'long', - 'TTQ_UINT16' => 'ushort', - 'TTQ_UINT32' => 'uint', - 'TTQ_UINT8' => 'uchar', - 'TTQ_ULONG' => 'long', + 'Q_INT16' => 'short', + 'qint16' => 'short', + 'Q_INT32' => 'int', + 'qint32' => 'int', + 'qint32&' => 'int&', + 'Q_INT8' => 'char', + 'qint8' => 'char', + 'Q_LONG' => 'long', + 'Q_UINT16' => 'ushort', + 'tquint16' => 'ushort', + 'Q_UINT32' => 'uint', + 'tquint32' => 'uint', + 'Q_UINT8' => 'uchar', + 'tquint8' => 'uchar', + 'Q_ULONG' => 'long', + 'qreal' => 'double', + 'pid_t' => 'int', + 'size_t' => 'int', + 'pid_t' => 'int', + 'time_t' => 'int', + 'short int' => 'short', + 'signed long int' => 'long', + 'unsigned long int' => 'ulong', + 'unsigned short int' => 'ushort', + 'TQt::Alignment' => 'int', + 'TQt::Orientations' => 'int', + 'TQt::DockWidgetAreas' => 'int', + 'TQt::DropActions' => 'int', + 'TQt::ImageConversionFlags' => 'int', + 'TQt::ItemFlags' => 'int', + 'TQt::KeyboardModifiers' => 'int', + 'TQt::MatchFlags' => 'int', + 'TQt::MouseButtons' => 'int', + 'TQt::ToolBarAreas' => 'int', + 'TQt::WindowFlags' => 'int', + 'TQt::WindowStates' => 'int', + 'AutoFormatting' => 'int', + 'DirtyFlags' => 'int', + 'EditTriggers' => 'int', + 'FindFlags' => 'int', + 'Flags' => 'int', + 'FormattingOptions' => 'int', + 'GLenum' => 'int', + 'GLint' => 'int', + 'GLuint' => 'uint', + 'LoadOperator' => 'int', + 'NumberFlags' => 'int', + 'OpenMode' => 'int', + 'Options' => 'int', + 'PaintEngineFeatures' => 'int', + 'Permissions' => 'int', + 'PrintDialogOptions' => 'int', + 'ProcessEventsFlags' => 'int', + 'TQDir::Filters' => 'int', + 'TQDir::SortFlags' => 'int', + 'TQFile::Permissions' => 'int', + 'TQGL::FormatOptions' => 'int', + 'TQIODevice::OpenMode' => 'int', + 'TQImageReader::ImageReaderError' => 'int', + 'TQItemSelectionModel::SelectionFlags' => 'int', + 'TQPaintEngine::DirtyFlags' => 'int', + 'TQPainter::RenderHints' => 'int', + 'TQSql::ParamType' => 'int', + 'TQTextDocument::FindFlags' => 'int', + 'Q_PID' => 'int', + 'TQt::DropActions' => 'int', + 'TQt::ImageConversionFlags' => 'int', + 'TQt::ItemFlags' => 'int', + 'TQt::KeyboardModifiers' => 'int', + 'TQt::MatchFlags' => 'int', + 'TQt::MouseButtons' => 'int', + 'TQt::ToolBarAreas' => 'int', + 'TQt::WindowFlags' => 'int', + 'TQt::WindowStates' => 'int', + 'RenderFlags' => 'int', + 'RenderHints' => 'int', + 'SortFlags' => 'int', + 'StepEnabled' => 'int', + 'Sections' => 'int', + 'Filters' => 'int', + 'SortFlags' => 'int', + 'TQDir::Filters' => 'int', + 'TQDir::SortFlags' => 'int', + 'TQStyle::State' => 'int', + 'TQValidator::State' => 'int', + 'TQAbstractSpinBox::StepEnabled' => 'int', + 'TQDockWidget::DockWidgetFeatures' => 'int', + 'TQStyle::SubControls' => 'int', ); +$headerSubdirectories = "kio/|tdevelop/|kinterfacedesigner/|kontact/|kate/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|tdeprint/|tdesu/|knewstuff/" + } sub writeDoc @@ -156,7 +245,7 @@ sub writeDoc mkpath( $outputdir ) unless -f $outputdir; # Define TQPtrCollection::Item, for resolveType - unless ( kdocAstUtil::findRef( $rootnode, "TQPtrCollection::Item" ) ) { + unless ( kdocAstUtil::findRef( $rootnode, "TQPtrCollection::Item" ) || $main::qt4 ) { my $cNode = kdocAstUtil::findRef( $rootnode, "TQPtrCollection" ); warn "TQPtrCollection not found" if (!$cNode); my $node = Ast::New( 'Item' ); @@ -165,7 +254,7 @@ sub writeDoc kdocAstUtil::attachChild( $cNode, $node ) if ($cNode); $node->AddProp( "Access", "public" ); } - + print STDERR "Preparsing...\n"; # Preparse everything, to prepare some additional data in the classes and methods @@ -224,6 +313,14 @@ sub preParseClass exists $classNode->{Tmpl} || # Don't generate standard bindings for TQString, this class is handled as a native type $className eq 'TQString' || + $className eq 'TQStringData' || + $className eq 'TQLatin1String' || + $className eq 'TQTLWExtra' || + $className eq 'TQWExtra' || + $className eq 'TQBig5Codec' || + $className eq 'TQBig5hkscsCodec' || + $className eq 'TQPtrCollection' || + $className eq 'TQGCache' || $className eq 'TQConstString' || $className eq 'TQCString' || # Don't map classes which are really arrays @@ -232,16 +329,133 @@ sub preParseClass $className eq 'TQWidgetList' || $className eq 'TQObjectList' || $className eq 'TQStrList' || + $className eq 'KCmdLineOptions' || # Those are template related $className eq 'TQTSManip' || # cause compiler errors with several gcc versions $className eq 'TQGDict' || $className eq 'TQGList' || + $className eq 'TQGArray' || $className eq 'TQGVector' || $className eq 'TQStrIList' || $className eq 'TQStrIVec' || - $className eq 'TQByteArray' || $className eq 'TQBitArray' || - $classNode->{NodeType} eq 'union' # Skip unions for now, e.g. TQPDevCmdParam + $className eq 'TQMapData' || + $className eq 'TQMetaEnum::Item' || + $className eq 'TQWidgetContainerPlugin' || + $className eq 'TQGArray::array_data' || + ($className eq 'TQMenuItem' and $main::qt_embedded) || + ($className eq 'TQSignal' and $main::qt_embedded) || + ($className eq 'TQWSEvent' and $main::qt_embedded) || + ($className eq 'TQMetaObjectInit' and $main::qt_embedded) || + ($className eq 'TQKoi8Codec' and $main::qt_embedded) || + $className eq 'KAccelGen' || + ($className eq 'TQAbstractUndoItem' and $main::qt4) || + ($className eq 'TQAbstractItemDelegate' and $main::qt4) || + ($className eq 'TQDebug' and $main::qt4) || + ($className eq 'TQNoDebug' and $main::qt4) || + ($className eq 'TQObjectData' and $main::qt4) || + ($className eq 'TQSysInfo' and $main::qt4) || + ($className eq 'TQPNGImageWriter' and $main::qt4) || + ($className eq 'TQPNGImagePacker' and $main::qt4) || + ($className eq 'TQTextCodec::ConverterState' and $main::qt4) || + ($className eq 'TQTextLayout::Selection' and $main::qt4) || + ($className eq 'TQTextStreamManipulator' and $main::qt4) || + $className eq 'DCOPArg' || + $className eq 'DCOPReply' || + $className eq 'KBookmarkMenu::DynMenuInfo' || + $className eq 'KDE' || + $className eq 'KDEDesktopMimeType::Service' || + $className eq 'KEntry' || + $className eq 'KEntryKey' || + $className eq 'KGlobalSettings::KMouseSettings' || + $className eq 'KMimeType::Format' || + $className eq 'KNotifyClient::Instance' || + $className eq 'KParts::ComponentFactory' || + $className eq 'KParts::Plugin::PluginInfo' || + $className eq 'KProtocolInfo::ExtraField' || + $className eq 'KXMLGUIClient::StateChange' || + $className eq 'KIconTheme' || + $className eq 'KEditListBox::CustomEditor' || + $className eq 'KIO::KBookmarkMenuNSImporter' || + $className eq 'KExtendedSocket' || + $className eq 'KSocket' || + $className eq 'KPerDomainSettings' || + $className eq 'KApplicationPropsPlugin' || + $className eq 'KOpenWithHandler' || + $className eq 'KFileOpenWithHandler' || + $className eq 'KBindingPropsPlugin' || + $className eq 'KPropsDlgPlugin' || + $className eq 'KFileSharePropsPlugin' || + $className eq 'KBookmarkMenuNSImporter' || + $className eq 'KDevicePropsPlugin' || + $className eq 'KDEDModule' || + $className eq 'KFileMetaInfoProvider' || + $className eq 'KFileMimeTypeInfo' || + $className eq 'KExecPropsPlugin' || + $className eq 'KFilePermissionsPropsPlugin' || + $className eq 'KImageFilePreview' || + $className eq 'KBookmarkManager' || + $className eq 'KBookmarkNotifier' || + $className eq 'KOCRDialogFactory' || + $className eq 'KExtendedBookmarkOwner' || + $className eq 'KSharedPixmap' || + $className eq 'KLibrary' || + $className eq 'KScanDialogFactory' || + $className eq 'KBufferedIO' || + $className eq 'KDictSpellingHighlighter' || + $className eq 'KPropertiesDialog' || + $className eq 'ProgressItem' || + $className eq 'KIO::ChmodInfo' || + $className eq 'khtml::DrawContentsEvent' || # the khtml:: classes build, but don't link + $className eq 'khtml::MouseDoubleClickEvent' || + $className eq 'khtml::MouseMoveEvent' || + $className eq 'khtml::MousePressEvent' || + $className eq 'khtml::MouseReleaseEvent' || + $className eq 'khtml::MouseEvent' || + $className eq 'khtml' || + $className eq 'KURL::List' || + $className eq 'KWin::Info' || + $className eq 'TerminalInterface' || + $className eq 'TQForeachContainerBase' || # Qt4 + $className eq 'TQInputMethodEvent::Attribute' || # Qt4 + $className eq 'TQAbstractTextDocumentLayout::PaintContext' || # Qt4 + $className eq 'TQAbstractTextDocumentLayout::Selection' || # Qt4 + $className eq 'TQBrushData' || # Qt4 + $className eq 'TQIPv6Address' || # Qt4 + $className eq 'TQImageTextKeyLang' || # Qt4 + $className eq 'TQMap' || # Qt4 + $className eq 'TQMap::const_iterator' || # Qt4 + $className eq 'TQMap::iterator' || # Qt4 + $className eq 'TQMapData' || # Qt4 + $className eq 'TQMapData::Node' || # Qt4 + $className eq 'TQSharedData' || # Qt4 + $className eq 'TQPainterPath::Element' || # Qt4 + $className eq 'TQThreadStorageData' || # Qt4 + $className eq 'TQVFbHeader' || # Qt4 + $className eq 'TQStyleOptionQ3DockWindow' || # Qt4 + $className eq 'TQStyleOptionQ3ListView' || # Qt4 + $className eq 'TQStyleOptionQ3ListViewItem' || # Qt4 + $className eq 'TQStyleOptionQ3ListView' || # Qt4 + $className eq 'TQUpdateLaterEvent' || # Qt4 + $className eq 'TQVFbKeyData' || # Qt4 + $className eq 'TQVariant::Handler' || # Qt4 + $className eq 'TQVariant::PrivateShared' || # Qt4 + $className eq 'TQVectorData' || # Qt4 + $className eq 'TQWidgetData' || # Qt4 + $className eq 'TQThread' || # Qt4 + $className eq 'TQThreadStorage' || # Qt4 + $className eq 'TQMutex' || # Qt4 + $className eq 'TQMutexLocker' || # Qt4 + $className eq 'TQSemaphore' || # Qt4 + $className eq 'TQWaitCondition' || # Qt4 + $className eq 'TQReadWriteLock' || # Qt4 + $className eq 'TQReadLocker' || # Qt4 + $className eq 'TQWriteLocker' || + $className =~ /.*Private$/ || # Ignore any classes which aren't for public consumption + $className =~ /.*Impl$/ || + $className =~ /.*Internal.*/ || + $classNode->{Deprecated} || + $classNode->{NodeType} eq 'union' # Skip unions for now, e.g. TQPDevCmdParam ) { print STDERR "Skipping $className\n" if ($debug); print STDERR "Skipping union $className\n" if ( $classNode->{NodeType} eq 'union'); @@ -249,7 +463,7 @@ sub preParseClass delete $classNode->{Compound}; # Cheat, to get it excluded from Iter::LocalCompounds return; } - + my $signalCount = 0; my $eventHandlerCount = 0; my $defaultConstructor = 'none'; # none, public, protected or private. 'none' will become 'public'. @@ -264,6 +478,9 @@ sub preParseClass my $hasCopyConstructor = 0; my $hasPrivateCopyConstructor = 0; # Note: no need for hasPureVirtuals. $classNode{Pure} has that. + + # Hack to fix up KLed constructors in KDE 3.1 + my $kledAmbiguousConstructor = undef; my $doPrivate = $main::doPrivate; $main::doPrivate = 1; @@ -282,8 +499,8 @@ sub preParseClass } print STDERR "preParseClass: looking at $className\::$name $m->{Params}\n" if ($debug); - - if ( $name eq $classNode->{astNodeName} ) { + + if ( $name eq $classNode->{astNodeName} ) { if ( $m->{ReturnType} =~ /~/ ) { # A destructor $hasPublicDestructor = 0 if $m->{Access} ne 'public'; @@ -298,8 +515,10 @@ sub preParseClass # Copy constructor? if ( $#{$m->{ParamList}} == 0 ) { my $theArgType = @{$m->{ParamList}}[0]->{ArgType}; - if ($theArgType =~ /$className\s*\&/) { + (my $classNameWithoutNS = $className) =~ s/^.*:://; + if ($theArgType =~ /$classNameWithoutNS\s*\&/) { $hasCopyConstructor = 1; + $m->{Flags} .= "x"; $hasPrivateCopyConstructor = 1 if ( $m->{Access} eq 'private' ); } } @@ -320,7 +539,146 @@ sub preParseClass # All we want from private methods is to check for virtuals, nothing else next if ( $m->{Access} =~ /private/ ); + + # Don't generate code for deprecated methods, + # or where the code won't compile/link for obscure reasons. Or even obvious reasons.. + if ( ($classNode->{astNodeName} eq 'KCharSelectTable' and $name eq 'paintCell') + || ($classNode->{astNodeName} eq 'KAnimWidget' and $name eq 'KAnimWidget' and @{$m->{ParamList}} == 2) + || ($classNode->{astNodeName} eq 'KCModuleLoader' and $name eq 'errorModule') + || ($classNode->{astNodeName} eq 'KDCOPActionProxy' and $name eq 'actions') + || ($classNode->{astNodeName} eq 'KEditToolbarWidget' and $name eq 'insertActive') + || ($classNode->{astNodeName} eq 'KEditToolbarWidget' and $name eq 'removeActive') + || ($classNode->{astNodeName} eq 'KEditToolbarWidget' and $name eq 'moveActive') + || ($classNode->{astNodeName} eq 'KFileDialog' and $name eq 'addDirEntry') + || ($classNode->{astNodeName} eq 'KFileDialog' and $name eq 'getDirEntry') + || ($classNode->{astNodeName} eq 'KFileItem' and $name eq 'extraData') + || ($classNode->{astNodeName} eq 'KFileView' and $name eq 'selectionMode') + || ($classNode->{astNodeName} eq 'KFind' and $name eq 'KFind' and @{$m->{ParamList}} == 4) + || ($classNode->{astNodeName} eq 'KGlobalAccel' and $name eq 'setEnabled') + || ($classNode->{astNodeName} eq 'KCharsets' and $name eq 'encodingsForLanguage') + || ($classNode->{astNodeName} eq 'KInputDialog' and $name eq 'getInteger') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'checkCachedAuthentication') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'cacheAuthentication') + || ($classNode->{astNodeName} eq 'KInputDialog' and $name eq 'getDouble') + || ($classNode->{astNodeName} eq 'KToolBar' and $name eq 'enable') + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'insert' and @{$m->{ParamList}} == 2) + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'autoupdate') + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'getAutoUpdate') + || ($classNode->{astNodeName} eq 'KStdAccel' and $name eq 'insert') + || ($classNode->{astNodeName} eq 'KBookmarkMenu' and $name eq 'invalid') + || ($classNode->{astNodeName} eq 'KCharsets' and $name eq 'languages') + || ($classNode->{astNodeName} eq 'KCombiView' and $name eq 'setDropOptions') + || ($classNode->{astNodeName} eq 'KFileMetaInfoItem' and $name eq 'unit') + || ($classNode->{astNodeName} eq 'KInstance' and $name eq 'charsets') + || ($classNode->{astNodeName} eq 'KInstance' and $name eq 'KInstance' and $m->{Access} =~ /protected/) + || ($classNode->{astNodeName} eq 'KKey' and $name eq 'isValidQt') + || ($classNode->{astNodeName} eq 'KKey' and $name eq 'isValidNative') + || ($classNode->{astNodeName} eq 'KKeySequence' and $name eq 'init') + || ($classNode->{astNodeName} eq 'KKeySequence' and $name eq 'setTriggerOnRelease') + || ($classNode->{astNodeName} eq 'KEMailSettings' and $name eq 'getExtendedSetting') + || ($classNode->{astNodeName} eq 'KEMailSettings' and $name eq 'setExtendedSetting') + || ($classNode->{astNodeName} eq 'KProtocolManager' and $name eq 'defaultConnectTimeout') + || ($classNode->{astNodeName} eq 'KMD4' and $name eq 'transform') + || ($classNode->{astNodeName} eq 'KMD5' and $name eq 'transform') + || ($classNode->{astNodeName} eq 'KSSLCertificate' and $name eq 'operator!=') + || ($classNode->{astNodeName} eq 'KSSLPKCS7' and $name eq 'validate') + || ($classNode->{astNodeName} eq 'KSSLPKCS7' and $name eq 'revalidate') + || ($classNode->{astNodeName} eq 'KSSLSession' and $name eq 'KSSLSession' and @{$m->{ParamList}} == 1) + || ($classNode->{astNodeName} eq 'KSimpleFileFilter' and $name eq 'nameFilters') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'isTabReorderingEnabled') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'hoverCloseButton') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'hoverCloseButtonDelayed') + || ($classNode->{astNodeName} eq 'KTar' and $name eq 'writeFile_impl') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'buildHTMLErrorString') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'pasteClipboard') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'pasteData') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'pasteDataAsync') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'isClipboardEmpty') + || ($classNode->{astNodeName} eq 'DCOPRef' and $name eq 'callExt') + || ($classNode->{astNodeName} eq 'DCOPRef' and $name eq 'call') + || ($classNode->{astNodeName} eq 'DCOPRef' and $name eq 'send') + || ($classNode->{astNodeName} eq 'DOM' and $name eq 'operator<<') # Avoid kdbgstream debugging method + || ($name eq 'qInitJpegIO' and $main::qt4) + || ($name eq 'qInitPngIO' and $main::qt4) + || ($name eq 'virtual_hook') + || ($name eq 'handle') + + # Obsolete + || ($classNode->{astNodeName} eq 'TQTextStream' and $name eq 'TQTextStream' + and @{$m->{ParamList}} == 2 and $m->{ParamList}[0]->{ArgType} eq 'TQString&') + + # Various methods to skip in Qt/E (Qt 2.3.x) + || ($main::qt_embedded + && ( ($classNode->{astNodeName} eq 'TQUriDrag' and $name =~ /^decode$|decodeLocalFiles|decodeToUnicodeUris/) + || ($classNode->{astNodeName} eq 'TQApplication' and $name =~ /^qwsSetCustomColors|^setArgs$|^winMouseButtonUp|^winFocus|^winMouseButtonUP$|^winVersion$/) + || ($classNode->{astNodeName} eq 'TQPrinter' and $name =~ /^setIdle$|^setActive$/) + || ($classNode->{astNodeName} eq 'TQDragObject' and $name eq 'dragLink') + || ($classNode->{astNodeName} eq 'TQFont' and $name eq 'qwsRenderToDisk') + || ($classNode->{astNodeName} eq 'TQFontInfo' and $name eq 'font') + || ($classNode->{astNodeName} eq 'TQLineEdit' and $name eq 'getSelection') + || ($classNode->{astNodeName} eq 'TQMainWindow' and $name eq 'toolBars') + || ($classNode->{astNodeName} eq 'TQMovie' and $name eq 'setDisplayWidget') + || ($classNode->{astNodeName} eq 'TQMetaObject' and $name =~ /^new_metaenum_item$|^new_metaaccess$/) + || ($classNode->{astNodeName} eq 'TQPainter' and $name eq 'pos') + || ($classNode->{astNodeName} eq 'TQPixmap' and $name =~ /^allocCell$|^clut$|^freeCell|^hbm|^isMultiCellPixmap|^multiCellPixmap|^multiCellBitmap|^multiCellHandle|^multiCellOffset|^numCols/) + || ($name eq 'handle') + || ($name eq 'resetInputContext') + || ($name eq 'propagateUpdates') + || ($name eq 'bytesPerLine') + || ($name eq 'scanLine') + || ($name eq 'hPal') + || ($name eq 'copyX11Data') + || ($name eq 'getX11Data') + || ($name eq 'setX11Data') + || ($name eq 'realizePal') + || ($name eq 'qwsDisplay') + || ($name eq 'fixport') + || ($name eq 'hack_strrchr') + || ($name eq 'hack_strchr') + || ($name eq 'hack_strstr') ) ) + + # Assume only Qt classes have tr() and trUtf8() in their Q_OBJECT macro + || ($classNode->{astNodeName} !~ /^Q/ and $name eq 'tr') + || ($classNode->{astNodeName} !~ /^Q/ and $name eq 'trUtf8') + + || ($main::qt4 + && ( ($classNode->{astNodeName} eq 'TQWidgetListItem' and $name eq 'operator=') + || ($classNode->{astNodeName} eq 'TQColormap' and $name eq 'operator=') + || ($classNode->{astNodeName} eq 'TQListWidget' and $name eq 'setItemPosition') + || ($classNode->{astNodeName} eq 'TQFontMetricsF' and $name eq 'operator=') + || ($classNode->{astNodeName} eq 'TQFontMetricsF' and $name eq 'TQFontMetricsF' + and $#{$m->{ParamList}} == 0 && $m->{ParamList}[0]->{ArgType} eq 'const TQFontMetrics&') + || ($classNode->{astNodeName} eq 'TQHttp' and $name eq 'supportedOperations') + || ($classNode->{astNodeName} eq 'TQRectF' and $name eq 'setX') + || ($classNode->{astNodeName} eq 'TQRectF' and $name eq 'setY') + || ($classNode->{astNodeName} eq 'TQTextObject' and $name eq 'formatType') + || ($classNode->{astNodeName} eq 'TQUrl' and $name eq 'TQUrl' + and $#{$m->{ParamList}} == 0 && $m->{ParamList}[0]->{ArgType} eq 'TQUrlPrivate&') + || ($classNode->{astNodeName} eq 'TQGlobalSpace' and $name eq 'operator<<' and $m->{ParamList}[0]->{ArgType} =~ /TQDebug/) + || ($classNode->{astNodeName} eq 'TQGlobalSpace' and $#{$m->{ParamList}} > 0 and $name =~ /operator/ and $m->{ParamList}[1]->{ArgType} =~ /TQVariant::Type/) + || ($#{$m->{ParamList}} > 0 and $m->{ParamList}[0]->{ArgType} =~ /Private/) + || ($classNode->{astNodeName} eq 'TQScrollArea' and $name eq 'alignment') + || ($classNode->{astNodeName} eq 'TQScrollArea' and $name eq 'setAlignment') + || ($m->{ReturnType} =~ /QT3_SUPPORT/) ) ) + + || $m->{Deprecated} ) { + $m->{NodeType} = 'deleted'; + next; + } + # Hack for fixing up KDE 3.1 KLed where the no arg constructor was ambiguous + if ($classNode->{astNodeName} eq 'KLed' and $name eq 'KLed' && $#{$m->{ParamList}} > 0) { + if ($m->{ParamList}[0]->{ArgType} =~ /TQColor/ && defined $m->{ParamList}[0]->{DefaultValue}) { + $m->{ParamList}[0]->{DefaultValue} = undef; + if (defined $kledAmbiguousConstructor) { + $kledAmbiguousConstructor->{ParamList}[0]->{DefaultValue} = undef; + $kledAmbiguousConstructor->{FirstDefaultParam} = 1; + } + } else { + $kledAmbiguousConstructor = $m; + } + } + my $argId = 0; my $firstDefaultParam; foreach my $arg ( @{$m->{ParamList}} ) { @@ -334,16 +692,18 @@ sub preParseClass or $arg->{ArgType} eq 'DecoderFn' # TQFile's callback or $arg->{ArgType} eq 'EncoderFn' # TQFile's callback or $arg->{ArgType} =~ /bool \(\*\)\(TQObject/ # TQMetaObject's ctor - or $arg->{ArgType} eq 'TQtStaticMetaObjectFunction' # TQMetaObjectCleanUp's ctor with func pointer + or $arg->{ArgType} eq 'QtStaticMetaObjectFunction' # TQMetaObjectCleanUp's ctor with func pointer or $arg->{ArgType} eq 'const TQTextItem&' # ref to a private class in 3.2.0b1 or $arg->{ArgType} eq 'FILE*' # won't be able to handle that I think + or $arg->{ArgType} eq 'const KKeyNative&' # + or $arg->{ArgType} =~ /Node\s*\*/ # ) { $m->{NodeType} = 'deleted'; } else { # Resolve type in full, e.g. for TQSessionManager::RestartHint - # (x_TQSessionManager doesn't inherit TQSessionManager) + # (x_QSessionManager doesn't inherit TQSessionManager) $arg->{ArgType} = kalyptusDataDict::resolveType($arg->{ArgType}, $classNode, $rootnode); registerType( $arg->{ArgType} ); $argId++; @@ -355,7 +715,14 @@ sub preParseClass } elsif( $m->{NodeType} eq "enum" ) { my $fullEnumName = $className."::".$m->{astNodeName}; - $classNode->{enumerations}{$m->{astNodeName}} = $fullEnumName + + if ( ($fullEnumName eq 'KMimeType::Format' and $name eq 'compression') + || $m->{Deprecated} ) { + $m->{NodeType} = 'deleted'; + next; + } + + $classNode->{enumerations}{$m->{astNodeName}} = $fullEnumName if $m->{astNodeName} and $m->{Access} ne 'private'; # Define a type for this enum @@ -367,21 +734,60 @@ sub preParseClass #print STDERR "$fullEnumName is an enum\n"; } elsif( $m->{NodeType} eq 'var' ) { + if ( ($classNode->{astNodeName} eq 'TQUuid' and $name eq 'data4') + || ($name eq 'd') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'mIncomingMetaData') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'mOutgoingMetaData') ) + { + $m->{NodeType} = 'deleted'; + next; + } + my $varType = $m->{Type}; - # We are interested in public static vars, like TQColor::blue - if ( $varType =~ s/static\s+// && $m->{Access} ne 'private' ) - { $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/^\s*//; $varType =~ s/\s*$//; - print STDERR "var: $m->{astNodeName} '$varType'\n" if ($debug); - - # Register the type - registerType( $varType ); - - } else { - # To avoid duplicating the above test, we just get rid of any other var - $m->{NodeType} = 'deleted'; - } + $varType =~ s/static\s+//; + + if ( $m->{Flags} =~ "s" ) { + # We are interested in public static vars, like TQColor::blue + if ( $m->{Access} ne 'private' + && $className."::".$m->{astNodeName} ne "KSpell::modalListText" ) + { + print STDERR "var: $m->{astNodeName} '$varType'\n" if ($debug); + + # Register the type + registerType( $varType ); + } else { + $m->{NodeType} = 'deleted'; + } + } elsif ($m->{Access} eq 'public') { + # Add a setter method for a public instance variable + my $setMethod = $name; + if ($setMethod =~ /^(\w)(.*)/) { + my $ch = $1; + $ch =~ tr/a-z/A-Z/; + $setMethod = "set$ch$2"; + } + my $node = Ast::New( $setMethod ); + $node->AddProp( "NodeType", "method" ); + # Flags of "=" for a setter method + $node->AddProp( "Flags", "=" ); + $node->AddProp( "ReturnType", "void" ); + $node->AddProp( "Params", $varType ); + + my $param = Ast::New( 1 ); + $param->AddProp( "NodeType", "param" ); + $param->AddProp( "ArgType", $varType ); + $node->AddPropList( "ParamList", $param ); + + kdocAstUtil::attachChild( $classNode, $node ); + + # Register the type + registerType( $varType ); + } else { + $m->{NodeType} = 'deleted'; + } } }, undef @@ -393,7 +799,8 @@ sub preParseClass my $isGlobalSpace = ($className eq $main::globalSpaceClassName); # Note that if the class has _no_ constructor, the default ctor applies. Let's even generate it. - if ( !$constructorCount && $defaultConstructor eq 'none' && !$hasPrivatePureVirtual && !$isGlobalSpace ) { + if ( !$constructorCount && $defaultConstructor eq 'none' + && !$hasPrivatePureVirtual && !$isGlobalSpace && $classNode->{NodeType} ne 'namespace' ) { # Create a method node for the constructor my $methodNode = Ast::New( $classNode->{astNodeName} ); $methodNode->AddProp( "NodeType", "method" ); @@ -411,7 +818,7 @@ sub preParseClass } # Also, if the class has no explicit destructor, generate a default one. - if ( !$hasDestructor && !$hasPrivatePureVirtual && !$isGlobalSpace ) { + if ( !$hasDestructor && !$hasPrivatePureVirtual && !$isGlobalSpace && $classNode->{NodeType} ne 'namespace' ) { my $methodNode = Ast::New( "$classNode->{astNodeName}" ); $methodNode->AddProp( "NodeType", "method" ); $methodNode->AddProp( "Flags", "" ); @@ -462,7 +869,7 @@ sub propagateCanBeCopied($) if ( !$classNode->{HasCopyConstructor} && $classNode->{CanBeCopied} && $classNode->{CanBeInstanciated} ) { my $methodNode = Ast::New( "$classNode->{astNodeName}" ); $methodNode->AddProp( "NodeType", "method" ); - $methodNode->AddProp( "Flags", "" ); + $methodNode->AddProp( "Flags", "ix" ); # Only for internal use in marshallers my $argType = "const ".$className."&"; registerType( $argType ); $methodNode->AddProp( "Params", $argType ); @@ -502,7 +909,7 @@ my $fhn =1; # static print $fh "//Auto-generated by $0. DO NOT EDIT.\n"; print $fh "#include \n"; print $fh "#include <${libname}_smoke.h>\n"; - + my @code; for my $node ( @$nodelist ) { @@ -511,10 +918,40 @@ my $fhn =1; # static my %includes; map { for my $incl (keys %{$_->[2]}){ $includes{$incl}++ } } @code; + # Hack - some Qt/KDE headers need other headers included, but omit suitable #includes + if (defined $includes{"qregexp.h"} || defined $includes{"qcstring.h"}) { + print $fh "#include \n"; + delete $includes{"qregexp.h"}; + } + if (defined $includes{"qmime.h"}) { + print $fh "#include \n"; + delete $includes{"qurl.h"}; + } + if (defined $includes{"kshortcut.h"}) { + print $fh "#include \n"; + delete $includes{"kshortcut.h"}; + } + if (defined $includes{"kshortcutlist.h"}) { + print $fh "#include \n"; + print $fh "#include \n"; + delete $includes{"kconfigbase.h"}; + delete $includes{"kshortcutlist.h"}; + } + if (defined $includes{"kaction.h"}) { + print $fh "#include \n"; + delete $includes{"kaction.h"}; + } foreach my $incl (keys %includes) { die if $incl eq ''; print $fh "#include <$incl>\n"; } + if ( $main::qt4 + and ( defined $includes{"qtreewidget.h"} + or defined $includes{"qlistwidget.h"} + or defined $includes{"qtablewidget.h"} ) ) + { + print $fh "#include \"qwidgetitemdata_p.h\"\n"; + } print $fh "\n"; for my $c( 0..$#code ) { @@ -707,8 +1144,11 @@ sub addIncludeForClass($$$) { my ( $node, $addInclude, $debugMe ) = @_; my $sourcename = $node->{Source}->{astNodeName}; - $sourcename =~ s!.*/(.*)!$1!m; - die "Empty source name for $node->{astNodeName}" if ( $sourcename eq '' ); + if ( $sourcename !~ s!.*($headerSubdirectories)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } +# die "Empty source name for $node->{astNodeName}" if ( $sourcename eq '' ); + return if ( $sourcename eq '' ); unless ( defined $addInclude->{$sourcename} ) { print " Including $sourcename\n" if ($debugMe); $addInclude->{$sourcename} = 1; @@ -788,6 +1228,12 @@ sub generateVirtualMethod($$$$$) my $sig = $methodClass->{astNodeName} . "::" . $signature; my $idx = $allMethods{$sig}; + + if ( ! defined $idx ) { + my $class_name = join( "::", kdocAstUtil::heritage($methodClass) ); + $sig = $class_name . "::" . $signature; + $idx = $allMethods{$sig}; + } die "generateVirtualMethod: $className: No method found for $sig\n" if !defined $idx; if($flags =~ "p") { # pure virtual $methodCode .= "\t${libname}_Smoke->binding->callMethod($idx, (void*)$this, x, true /*pure virtual*/);\n"; @@ -798,7 +1244,7 @@ sub generateVirtualMethod($$$$$) $returnType = undef if ($returnType eq 'void'); if($returnType) { my $arg = $returnType; - my $it = $arg; + my $it = applyTypeDef( $arg ); my $cast; my $v = "x[0]"; my $indent = ($flags =~ "p") ? "\t" : ""; @@ -811,7 +1257,7 @@ sub generateVirtualMethod($$$$$) if($arg =~ s/&//) { $cast = "*($arg *)"; $methodCode .= "${indent}return $cast$v;\n"; - } elsif($arg !~ /\*/) { + } elsif($arg !~ /\*$/) { unless($flags =~ "p") { $indent = "\t "; $methodCode .= "{\n"; @@ -870,6 +1316,7 @@ sub generateMethod($$$) } my $returnType = $m->{ReturnType}; + $returnType = undef if ($returnType eq 'void'); # Don't use $className here, it's never the fully qualified (A::B) name for a ctor. @@ -919,17 +1366,17 @@ sub generateMethod($$$) my $argType = $arg->{ArgType}; push @argTypeList, $argType; - + # Detect objects passed by value checkIncludesForObject( $argType, $addInclude ); - } + } my @castedArgList = makeCastedArgList( @argTypeList ); my $isStatic = $flags =~ "s"; my $extra = ""; - $extra .= "static " if $isStatic || $isConstructor; + $extra .= "static " if $isStatic || $isConstructor || $classNode->{NodeType} eq 'namespace'; my $attr = ""; $attr .= "const " if $flags =~ "c"; @@ -973,7 +1420,7 @@ sub generateMethod($$$) } else { $switchCode .= "\tcase $methodNumber: "; - if ($flags =~ "s" || $isConstructor) { # static or constructor + if ($flags =~ "s" || $isConstructor || $classNode->{NodeType} eq 'namespace') { # static, namespace or constructor $switchCode .= "$xClassName\::"; } else { $switchCode .= "xself->" @@ -995,7 +1442,11 @@ sub generateMethod($$$) # Now generate the actual constructor for x_className # (Simply a forwarder to the className constructor with the same args - $methodCode .= " $xClassName("; + if ( $flags =~ "t" ) { + $methodCode .= " explicit $xClassName("; + } else { + $methodCode .= " $xClassName("; + } my $i = 0; for my $arg (@argTypeList) { $methodCode .= ", " if $i++; @@ -1015,15 +1466,29 @@ sub generateMethod($$$) } else { $methodCode .= $returnType . " xret = " if $returnType; - $methodCode .= "$this\->" unless $isStatic; + $methodCode .= "$this\->" unless $isStatic || $classNode->{NodeType} eq 'namespace'; if ($className ne $main::globalSpaceClassName) { - $methodCode .= "$className\::$name(@castedArgList[0..$#argTypeList]);\n"; + if ($flags =~ "=") { + # Setter method for a public instance variable + my $varName = $name; + $varName =~ /^set(\w)(.*)/; + my $ch = $1; + $ch =~ tr/A-Z/a-z/; + $varName = $ch . $2; + $methodCode .= "$varName = @castedArgList[0..$#argTypeList];\n"; + } else { + $methodCode .= "$className\::$name(@castedArgList[0..$#argTypeList]);\n"; + } } elsif ($name =~ /^operator\s?\W+/) { ( my $op = $name ) =~ s/^operator(.*)$/$1/; if (scalar(@argTypeList) == 2) { - $methodCode .= "(@castedArgList[0] $op @castedArgList[1]);\n"; # a + b + if( $name =~ /^operator(?:\+\+|--)/ ) { # postfix increment/decrement + $methodCode .= "(@castedArgList[0])$op;\n"; + } else { + $methodCode .= "(@castedArgList[0] $op @castedArgList[1]);\n"; # a + b + } } elsif (scalar(@argTypeList) == 1) { - $methodCode .= "($op@castedArgList[0]);\n"; # -a + $methodCode .= "$op(@castedArgList[0]);\n"; # -a } else { die "shouldn't reach here!"; } @@ -1037,21 +1502,6 @@ sub generateMethod($$$) $methodCode .= " }\n"; } - #} else { - # if ( $m->{Access} =~ /slots/ ) { - # print PIGSOURCE "$extra$returnType $name(", $cplusplusparams, ") slot;\n", - # } elsif ( $m->{Access} =~ /signals/ ) { - # print PIGSOURCE "$extra$returnType $name(", $cplusplusparams, ") signal;\n", - # } elsif ( $name =~ /operator(.*)/ ) { - # if ( $argId == 2 ) { - # print PIGSOURCE "$extra$returnType operator $1 (", $cplusplusparams, ") : operator $1 (\$0, \$1);\n", - # } else { - # print PIGSOURCE "$extra$returnType operator $1 (", $cplusplusparams, ")", ($m->{Flags} =~ "c" ? " const" : ""), ";\n", - # } - # } else { - # print PIGSOURCE "$extra$returnType $name(", $cplusplusparams, ")", ($m->{Flags} =~ "c" ? " const" : ""), ";\n", - # } - #} pop @argTypeList; $methodNumber++; @@ -1062,20 +1512,22 @@ sub generateMethod($$$) } -sub generateEnum($$) +sub generateEnum($$$) { - my( $classNode, $m ) = @_; # input + my( $classNode, $m, $addInclude ) = @_; # input my $methodCode = ''; # output my $switchCode = ''; # output my @heritage = kdocAstUtil::heritage($classNode); my $className = join( "::", @heritage ); my $xClassName = "x_" . join( "__", @heritage ); + + my $fullEnumType = "$className\::". $m->{astNodeName}; + checkIncludesForObject( $fullEnumType, $addInclude ); foreach my $enum ( @{$m->{ParamList}} ) { my $enumName = $enum->{ArgName}; my $fullEnumName = "$className\::$enumName"; - die "Invalid index for $fullEnumName: $classNode->{case}{$fullEnumName} instead of $methodNumber" if $classNode->{case}{$fullEnumName} != $methodNumber; $methodCode .= " static void x_$methodNumber(Smoke::Stack x) {\n"; $methodCode .= "\tx[0].s_enum = (long)$fullEnumName;\n"; @@ -1103,14 +1555,23 @@ sub generateVar($$$) $varType =~ s/const\s+(.*)\s*&/$1/; $varType =~ s/\s*$//; my $fullName = "$className\::$name"; + my $this = $classNode->{BindingDerives} > 0 ? "this" : "xthis"; checkIncludesForObject( $varType, $addInclude ); die "Invalid index for $fullName: $classNode->{case}{$fullName} instead of $methodNumber" if $classNode->{case}{$fullName} != $methodNumber; - $methodCode .= " static void x_$methodNumber(Smoke::Stack x) {\n"; - $methodCode .= "\tx[0].s_class = (void*)new $varType($fullName);\n"; - $methodCode .= " }\n"; - $switchCode .= "\tcase $methodNumber: $xClassName\::x_$methodNumber(args);\tbreak;\n"; + if ( $m->{Flags} =~ "s" ) { + $methodCode .= " static void x_$methodNumber(Smoke::Stack x) {\n "; + $methodCode .= coerce_type('x[0]', $fullName, $varType, 1); + $methodCode .= " }\n"; + $switchCode .= "\tcase $methodNumber: $xClassName\::x_$methodNumber(args);\tbreak;\n"; + } else { + $methodCode .= " void x_$methodNumber(Smoke::Stack x) {\n "; + $methodCode .= coerce_type('x[0]', "$this->$name", $varType, 1); + $methodCode .= " }\n"; + $switchCode .= "\tcase $methodNumber: xself->x_$methodNumber(args);\tbreak;\n"; + } + $methodNumber++; return ( $methodCode, $switchCode ); @@ -1124,6 +1585,13 @@ sub generateEnumCast($) $methodCode .= " static void xenum_operation(Smoke::EnumOperation xop, Smoke::Index xtype, void *&xdata, long &xvalue) {\n"; $methodCode .= "\tswitch(xtype) {\n"; for my $enum (values %{$classNode->{enumerations}}) { + + # Hack - this shouldn't be needed here - deprecated enums + next if ($enum eq 'KStatusBar::BarStatus' + or $enum eq 'KMdi::AddWindowFlags' + or $enum eq 'KToolBar::BarStatus' + or $enum eq 'KMimeType::Format:: compression : 4'); + my $type = findTypeEntry($enum); $methodCode .= "\t case $type->{index}: //$enum\n"; $methodCode .= "\t switch(xop) {\n"; @@ -1162,13 +1630,25 @@ sub generateAllMethods my $isGlobalSpace = ($xClassName eq ("x_".$main::globalSpaceClassName)); my $sourcename = $classNode->{Source}->{astNodeName}; - $sourcename =~ s!.*/(.*)!$1!m; + if ( $sourcename !~ s!.*($headerSubdirectories)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } die "Empty source name for $classNode->{astNodeName}" if ( $sourcename eq '' ); my %addInclude = ( $sourcename => 1 ); if (!$isGlobalSpace) { - if(! $classNode->{BindingDerives}) { + if($classNode->{NodeType} eq 'namespace') { + $switchCode .= " (void)obj;\n"; + $methodCode .= "public:\n"; + my $s; + for my $sn( @{$classNode->{Sources}} ) { + if ( ($s = $sn->{astNodeName}) !~ s!.*($headerSubdirectories)(.*)!$1$2!m ) { + $s =~ s!.*/(.*)!$1!m; + } + $addInclude{ $s } = 1; + } + } elsif(! $classNode->{BindingDerives}) { $methodCode .= "private:\n"; $methodCode .= " $className *xthis;\n"; $methodCode .= "public:\n"; @@ -1181,7 +1661,9 @@ sub generateAllMethods } else { my $s; for my $sn( @{$classNode->{Sources}} ) { - ($s = $sn->{astNodeName}) =~ s!.*/(.*)!$1!m; + if ( ($s = $sn->{astNodeName}) !~ s!.*($headerSubdirectories)(.*)!$1$2!m ) { + $s =~ s!.*/(.*)!$1!m; + } $addInclude{ $s } = 1; } $methodCode .= "public:\n"; @@ -1194,7 +1676,7 @@ sub generateAllMethods sub { my ($classNode, $methodNode ) = @_; if ( $methodNode->{NodeType} eq 'enum' ) { - my ($meth, $swit) = generateEnum( $classNode, $methodNode ); + my ($meth, $swit) = generateEnum( $classNode, $methodNode, \%addInclude ); $methodCode .= $meth; $switchCode .= $swit; } @@ -1241,7 +1723,7 @@ sub generateAllMethods # $methodCode .= " virtual ~$xClassName() {}\n"; #} # We generate a dtor though, because we might want to add stuff into it - if ( !$isGlobalSpace ) { + if ( !$isGlobalSpace && $classNode->{NodeType} ne 'namespace' ) { $methodCode .= " ~$xClassName() { ${libname}_Smoke->binding->deleted($classNode->{ClassIndex}, (void*)this); }\n"; } @@ -1369,6 +1851,9 @@ sub registerType($$) { $type =~ s/\s+const$//; # for 'char* const' $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + $type =~ s/(<[^>]*)\s+([^>]*>)/$1$2/; # Remove embedded space from template types, such as + # 'TQMap' return if ( $type eq 'void' or $type eq '' or $type eq '~' ); die if ( $type eq '...' ); # ouch @@ -1408,7 +1893,7 @@ sub registerType($$) { } # Apply typedefs, and store the resulting type. - # For instance, if $type was TTQ_UINT16&, realType will be ushort + # For instance, if $type was Q_UINT16&, realType will be ushort $allTypes{$type}{realType} = applyTypeDef( $realType ); # In the first phase we only create entries into allTypes. @@ -1426,6 +1911,9 @@ sub findTypeEntry($) { $type =~ s/\s+const$//; # for 'char* const' $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + $type =~ s/(<[^>]*)\s+([^>]*>)/$1$2/; # Remove embedded space from template types, such as + # 'TQMap' + return undef if ( $type =~ '~' or $type eq 'void' or $type eq '' ); # Enum _value_ -> get corresponding type @@ -1472,7 +1960,7 @@ sub prepareCaseDict($) { } }, undef ); - # Check for static vars + # Check for vars Iter::MembersByType ( $classNode, undef, sub { my ($classNode, $m ) = @_; @@ -1484,6 +1972,20 @@ sub prepareCaseDict($) { }, undef ); + my %const_methods = (); + # Now look at all const methods for this class, in order to use + # them in preference to any otherwise identical non-const method + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'method'; + my @args = @{ $m->{ParamList} }; + my $sig = methodSignature( $m, $#args ); + if ( $sig =~ /(.*) const$/ ) { + $const_methods{$1} = 1; + } + + }, undef ); # Now look at all methods for this class Iter::MembersByType ( $classNode, undef, @@ -1506,7 +2008,7 @@ sub prepareCaseDict($) { # Don't generate bindings for pure virtuals - we can't call them ;) $ok = 0 if ( $ok && $m->{Flags} =~ "p" ); - # Bugfix for TQt-3.0.4: those methods are NOT implemented (report sent). + # Bugfix for Qt-3.0.4: those methods are NOT implemented (report sent). $ok = 0 if ( $ok && $className eq 'TQLineEdit' && ( $name eq 'setPasswordChar' || $name eq 'passwordChar' ) ); $ok = 0 if ( $ok && $className eq 'TQWidgetItem' && $name eq 'widgetSizeHint' ); @@ -1518,11 +2020,18 @@ sub prepareCaseDict($) { } my @args = @{ $m->{ParamList} }; + my $sig = methodSignature( $m, $#args ); + if ( $const_methods{$sig} && $m->{Flags} !~ "v" ) { + # If there is a method which just differs from another by 'constness', + # then ignore the non-const version + $m->{SkipFromSwitch} = 1; + next; + } my $last = $m->{FirstDefaultParam}; $last = scalar @args unless defined $last; my $iterationCount = scalar(@args) - $last; while($iterationCount >= 0) { - my $sig = methodSignature( $m, $#args ); + $sig = methodSignature( $m, $#args ); $classNode->{case}{$sig} = $methodNumber; #print STDERR "prepareCaseDict: registered case number $methodNumber for $sig in $className()\n" if ($debug); pop @args; @@ -1555,6 +2064,7 @@ sub writeSmokeDataFile($) { Iter::LocalCompounds( $rootnode, sub { my $classNode = $_[0]; my $className = join( "::", kdocAstUtil::heritage($classNode) ); + push @classlist, $className; $enumclasslist{$className}++ if keys %{$classNode->{enumerations}}; $classNode->{ClassIndex} = $#classlist; @@ -1569,9 +2079,14 @@ sub writeSmokeDataFile($) { foreach my $incl (sort{ return 1 if $a=~/qmotif/; # move qmotif* at bottom (they include dirty X11 headers) return -1 if $b=~/qmotif/; + return -1 if substr($a,0,1) eq 'q' and substr($b,0,1) ne 'q'; # move Qt headers on top + return 1 if substr($a,0,1) ne 'q' and substr($b,0,1) eq 'q'; $a cmp $b } keys %allIncludes) { die if $incl eq ''; + if( $incl eq "kxmlguifactory.h" ) { + print OUT "#include \n"; + } print OUT "#include <$incl>\n"; } @@ -1609,15 +2124,25 @@ sub writeSmokeDataFile($) { push @super, @{$descendants{$className}}; } my $cur = $classidx{$className}; + + return if $classNode->{NodeType} eq 'namespace'; + print OUT " case $cur:\t//$className\n"; print OUT "\tswitch(to) {\n"; $cur = -1; + my %casevalues; for my $s (@super) { - my $superClassName = join( "::", kdocAstUtil::heritage($s) ); - next if !defined $classidx{$superClassName}; # inherits from unknown class, see below - next if $classidx{$superClassName} == $cur; # shouldn't happen in TQt - $cur = $classidx{$superClassName}; - print OUT "\t case $cur: return (void*)($superClassName*)($className*)xptr;\n"; + my $superClassName = join( "::", kdocAstUtil::heritage($s) ); + next if !defined $classidx{$superClassName}; # inherits from unknown class, see below + next if $classidx{$superClassName} == $cur; # shouldn't happen in Qt + if (!defined $s) { + die "problem with $className missing parent" + } + next if $s->kdocAstUtil::inheritsAsVirtual($classNode); # can't cast from a virtual base class + $cur = $classidx{$superClassName}; # KDE has MI with diamond shaped cycles (cf. KXMLGUIClient) + next if $casevalues{$cur}; # ..so skip any duplicate parents + print OUT "\t case $cur: return (void*)($superClassName*)($className*)xptr;\n"; + $casevalues{$cur} = 1; } print OUT "\t default: return xptr;\n"; print OUT "\t}\n"; @@ -1642,7 +2167,8 @@ sub writeSmokeDataFile($) { print OUT "\t0,\t// 0: (no super class)\n"; Iter::LocalCompounds( $rootnode, sub { my $classNode = shift; - my $className = join( "__", kdocAstUtil::heritage($classNode) ); + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + print STDERR "inheritanceList: looking at $className\n" if ($debug); # Make list of direct ancestors @@ -1709,7 +2235,7 @@ sub writeSmokeDataFile($) { my $firstClass = 1; Iter::LocalCompounds( $rootnode, sub { my $classNode = shift; - my $className = join( "__", kdocAstUtil::heritage($classNode) ); + my $className = join( "::", kdocAstUtil::heritage($classNode) ); if ($firstClass) { $firstClass = 0; @@ -1720,8 +2246,7 @@ sub writeSmokeDataFile($) { my $xcallFunc = "xcall_$c"; my $xenumFunc = "0"; $xenumFunc = "xenum_$c" if exists $enumclasslist{$className}; - # %classinherit needs Foo__Bar, not Foo::Bar? - die "problem with $className" unless defined $classinherit{$c}; + die "problem with $className" unless defined $classinherit{$className}; my $xClassFlags = 0; $xClassFlags .= "|Smoke::cf_constructor" if $classNode->{CanBeInstanciated}; # correct? @@ -1729,7 +2254,7 @@ sub writeSmokeDataFile($) { $xClassFlags .= "|Smoke::cf_virtual" if hasVirtualDestructor($classNode) == 1; # $xClassFlags .= "|Smoke::cf_undefined" if ...; $xClassFlags =~ s/0\|//; # beautify - print OUT "\t{ \"$className\", $classinherit{$c}, $xcallFunc, $xenumFunc, $xClassFlags }, \t//$classidx{$className}\n"; + print OUT "\t{ \"$className\", $classinherit{$className}, $xcallFunc, $xenumFunc, $xClassFlags }, \t//$classidx{$className}\n"; } ); print OUT "};\n\n"; @@ -1751,7 +2276,10 @@ sub writeSmokeDataFile($) { my $typeFlags = $allTypes{$type}{typeFlags}; my $realType = $allTypes{$type}{realType}; die "$type" if !defined $typeFlags; - die "$realType" if $realType =~ /\(/; +# die "$realType" if $realType =~ /\(/; + if ($realType =~ /\(/) { + print "FATAL ERROR $type $realType\n"; + } # First write the name print OUT "\t{ \"$type\", "; # Then write the classId (and find out the typeid at the same time) @@ -1834,10 +2362,8 @@ sub writeSmokeDataFile($) { $methods{$enumName}++; } - } elsif ( $m->{NodeType} eq 'var' ) { - - $methods{$m->{astNodeName}}++; - + } elsif ( $m->{NodeType} eq 'var' ) { + $methods{$m->{astNodeName}}++; } elsif( $m->{NodeType} eq "method" ) { $methods{$methName}++; @@ -1926,6 +2452,7 @@ sub writeSmokeDataFile($) { Iter::LocalCompounds( $rootnode, sub { my $classNode = shift; my $className = join( "::", kdocAstUtil::heritage($classNode) ); + my $classIndex = $classidx{$className}; print STDERR "writeSmokeDataFile: methods: looking at $className\n" if ($debug); @@ -1942,7 +2469,7 @@ sub writeSmokeDataFile($) { die "'Method index' for enum $sig not found" unless defined $xmethIndex; my $typeId = findTypeEntry( $fullEnumName )->{index}; die "enum has no {case} value in $className: $fullEnumName" unless defined $classNode->{case}{$fullEnumName}; - print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullEnumName}},\t//$methodCount $fullEnumName (enum)\n"; + print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static|Smoke::mf_enum, $typeId, $classNode->{case}{$fullEnumName}},\t//$methodCount $fullEnumName (enum)\n"; $allMethods{$sig} = $methodCount; print STDERR "Added entry for " . $sig . " into \$allMethods\n" if ($debug); $methods[$methodCount] = { @@ -1969,8 +2496,12 @@ sub writeSmokeDataFile($) { $varType =~ s/\s*$//; my $typeId = findTypeEntry( $varType )->{index}; die "var has no {case} value in $className: $fullName" unless defined $classNode->{case}{$fullName}; - print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullName}},\t//$methodCount $fullName (static var)\n"; - $allMethods{$sig} = $methodCount; + if ( $m->{Flags} =~ "s" ) { + print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullName}},\t//$methodCount $fullName (static var)\n"; + } else { + print OUT "\t{$classIndex, $xmethIndex, 0, 0, 0, $typeId, $classNode->{case}{$fullName}},\t//$methodCount $fullName (var)\n"; + } + $allMethods{$sig} = $methodCount; print STDERR "Added entry for " . $sig . " into \$allMethods\n" if ($debug); $methods[$methodCount] = { c => $classIndex, @@ -2035,8 +2566,14 @@ sub writeSmokeDataFile($) { } my $argcnt = $last + 1; my $methodFlags = '0'; - $methodFlags .= "|Smoke::mf_static" if $m->{Flags} =~ "s"; + # Make no distinction between a static method in an ordinary class, or a method in a namespace + $methodFlags .= "|Smoke::mf_static" if $m->{Flags} =~ "s" or $classNode->{NodeType} eq 'namespace'; $methodFlags .= "|Smoke::mf_const" if $m->{Flags} =~ "c"; # useful?? probably not + $methodFlags .= "|Smoke::mf_copyctor" if $m->{Flags} =~ "x"; + $methodFlags .= "|Smoke::mf_internal" if $m->{Flags} =~ "i"; + $methodFlags .= "|Smoke::mf_ctor" if $methName eq $className; + $methodFlags .= "|Smoke::mf_dtor" if $m->{ReturnType} eq '~'; + $methodFlags .= "|Smoke::mf_protected" if $m->{Access} =~ /protected/; $methodFlags =~ s/0\|//; # beautify print OUT "\t{$classIndex, $methodIndex, $arglist, $argcnt, $methodFlags, $retTypeIndex, $case},\t//$methodCount $className\::$sig"; @@ -2064,6 +2601,7 @@ sub writeSmokeDataFile($) { Iter::LocalCompounds( $rootnode, sub { my $classNode = shift; my $className = join( "::", kdocAstUtil::heritage($classNode) ); + my $classIndex = $classidx{$className}; print STDERR "writeSmokeDataFile: protos: looking at $className\n" if ($debug); diff --git a/kalyptus/kalyptusCxxToSwig.pm b/kalyptus/kalyptusCxxToSwig.pm new file mode 100644 index 0000000..f25387e --- /dev/null +++ b/kalyptus/kalyptusCxxToSwig.pm @@ -0,0 +1,996 @@ +package kalyptusCxxToSwig; + +use File::Path; +use File::Basename; + +use Carp; +use Ast; +use kdocAstUtil; +use kdocUtil; +use Iter; +use kalyptusDataDict; + +use strict; +no strict "subs"; + +use vars qw/ @clist $host $who $now $gentext %functionId $docTop %typedeflist + $lib $rootnode $outputdir $opt $debug $typeprefix $eventHandlerCount + $constructorCount *CLASS *HEADER *TQTCTYPES *KDETYPES /; + +BEGIN +{ +@clist = (); + +%typedeflist = +( + 'signed char' => 'char', + 'unsigned char' => 'uchar', + 'signed short' => 'short', + 'unsigned short' => 'ushort', + 'signed' => 'int', + 'signed int' => 'int', + 'unsigned' => 'uint', + 'unsigned int' => 'uint', + 'signed long' => 'long', + 'unsigned long' => 'ulong', + 'TQWSEvent*' => 'void*', + 'TQDiskFont*' => 'void*', + 'XEvent*' => 'void*', + 'TQStyleHintReturn*' => 'void*', + 'FILE*' => 'void*', + 'TQUnknownInterface*' => 'void*', + 'GDHandle' => 'void*', + '_NPStream*' => 'void*', + 'TQTextFormat*' => 'void*', + 'TQTextDocument*' => 'void*', + 'TQTextCursor*' => 'void*', + 'TQTextParag**' => 'void*', + 'TQTextParag* *' => 'void*', + 'TQTextParag*' => 'void*', + 'TQRemoteInterface*' => 'void*', + 'TQSqlRecordPrivate*' => 'void*', + 'TQTSMFI' => 'void*', # TQTextStream's TQTSManip + 'const GUID&' => 'void*', + 'TQWidgetMapper*' => 'void*', + 'TQWidgetMapper *' => 'void*', + 'MSG*' => 'void*', + 'const TQSqlFieldInfoList&' => 'void*', # TQSqlRecordInfo - TODO (templates) + + 'TQPtrCollection::Item' => 'void*', # to avoid a warning + + 'mode_t' => 'long', + 'TQProcess::PID' => 'long', + 'size_type' => 'int', # TQSqlRecordInfo + 'TQt::ComparisonFlags' => 'uint', + 'TQt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it + 'TQIODevice::Offset' => 'ulong', + 'WState' => 'int', + 'WId' => 'ulong', + 'TQRgb' => 'uint', + 'TQRgb *' => 'uint*', + 'TQRgb*' => 'uint*', + 'const TQCOORD*' => 'const int*', + 'TQCOORD*' => 'int*', + 'TQCOORD' => 'int', + 'TQCOORD &' => 'int&', + 'TQTSMFI' => 'int', + 'TQt::WState' => 'int', + 'TQt::WFlags' => 'int', + 'TQt::HANDLE' => 'uint', + 'TQEventLoop::ProcessEventsFlags' => 'uint', + 'TQStyle::SCFlags' => 'int', + 'TQStyle::SFlags' => 'int', + 'TQStyleOption&' => 'int&', + 'const TQStyleOption&' => 'const int&', + 'Q_INT16' => 'short', + 'Q_INT32' => 'int', + 'Q_INT8' => 'char', + 'Q_LONG' => 'long', + 'Q_UINT16' => 'ushort', + 'Q_UINT32' => 'uint', + 'Q_UINT8' => 'uchar', + 'Q_ULONG' => 'long', +); + # Page footer + + $who = kdocUtil::userName(); + $host = kdocUtil::hostName(); + $now = localtime; + $gentext = "$who\@$host on $now, using kalyptus $main::Version."; + + $docTop =<{NodeType} ne "method" ) { + return 1; + } + + my $access = $kid->{Access}; +# if ( $access eq "private" || $access eq "private_slots" || $access eq "signals" ) { + if ( $access eq "private_slots" || $access eq "signals" ) { + return 1; + } + return undef; +} + +# returns 1 if the $kid is not a protected method of object $node +sub isNotProtectedMethod($$) +{ + my ($node, $kid) = @_; + + print "HERE $node->{NodeType} $node->{astNodeName}, $kid->{NodeType} $kid->{astNodeName} \n"; + if ( $kid->{NodeType} ne "method" ) { + return 1; + } + + my $access = $kid->{Access}; + if ( $access ne "protected" && $access ne "protected_slots" ) { + return 1; + } + return undef; + +} + +# Returns the list of all classes this one inherits +# If $recurse is defined function returns also all the parents +# of the classes $classNode inherits from +sub superClassList($;$) +{ + my $classNode = shift; + my $recurse = shift; + my @super; + my @nodes; + + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + push @super, @_[0]; + if ( defined $recurse ) { + push @super, superClassList( @_[0] ); + } + }, undef ); + + return @super; +} + +# Returns the names of the classes the $classNode +# inherits from +sub parentClassNames($) +{ + my $classNode = shift; + my @names; + my @supers = superClassList($classNode); + foreach my $class (@supers) { + push @names, $class->{astNodeName}; + } + + return @names; +} + +#doesn't do anything, for me to test +sub hasPublicConstructors($) +{ + my ($node) = @_; + our $exists; + Iter::MembersByType ( $node, + sub { print SWIG_HEADER "1) @_\n"; }, + sub { my ($node, $kid ) = @_; + print SWIG_HEADER "\%$node->{NodeType} $node->{astNodeName}\% $kid->{NodeType} $kid->{astNodeName}\n"; + }, + sub { print SWIG_HEADER "3 @_ \n"; } + ); +} + + + +# Returns string representing $child method declaration or definition. +# $child is the method node for which the code should be generated, +# $parentName is the name of the parent for which the code should be generated, +# this is one is tricky, the reason for it is that $child node belongs +# to some class e.g. TQWidget and we want to generate a code for $child +# but in a class called TQWidget_bridge therefore we need to pass tha name +# $mangleProtected will mangle the name of the method to look like normalNameProtected +# $definition - if set the code generated will be a definition (without the opening +# and closing {} ) +sub generateMethodsCode($$$;$$) +{ + my ($child, $parentName, $mangleProtected, $definition, $inline ) = @_; + + my $ret = ""; + + if ( !(defined $definition) ) { + if ( $child->{Flags} =~ "s" ) { + $ret = "\tstatic "; + } elsif ( $child->{Flags} =~ "v" ) { + $ret = "\tvirtual "; + } else { + $ret = "\t"; + } + } + if ( defined $definition && !(defined $inline)) { + if ( $mangleProtected ) { + $ret .= "$child->{ReturnType} $parentName"."::"."$child->{astNodeName}Protected"; + } else { + $ret .= "$child->{ReturnType} $parentName"."::"."$child->{astNodeName}"; + } + } else { + if ( defined $inline ) { + $ret .= "\t"; + } + if ( $mangleProtected ) { + $ret .="$child->{ReturnType} $child->{astNodeName}Protected"; + } else { + $ret .= convertType($child->{ReturnType})." $child->{astNodeName}"; + } + } + $ret .= "("; + #$ret .= " $child->{Params} "; #can't be used because it includes names and default values + my @params = $child->{ParamList}; + foreach my $arg (@params) { + if ( $arg ) { + my @arr = @{$arg}; + my $num = @arr; + my $defParam = 'a'; + foreach my $param ( @{$arg} ) { + #print "Node: $param->{ArgType} is a $param->{NodeType}\n"; + # if ($param->{NodeType} eq "enum" ) { + #fix up enums + # $ret .= $parentName."::".$param->{astNodeName}; + #} + #else{ + $ret .= convertType($param->{ArgType})." "; + #} + # Apparently some languages do not appreciate the names and default values + ## FIXME: generate argument names for functions that do not have them + if ( ! $param->{ArgName} ) { + $param->{ArgName} = $defParam++; + $ret .= $param->{ArgName}; + } else { + $ret .= " $param->{ArgName}"; + } + # For some reason we are not getting all of these... + #if ( ! (defined $definition) ) { + # $ret .= "=$param->{DefaultValue}" if $param->{DefaultValue}; + #} + --$num; + $ret .= ", " if $num; + } + } + } + $ret .= ")"; + if ( $child->{Flags} =~ "c" ) { + $ret .= " const"; + } + if ( defined $definition ) { + $ret .= "\n"; + } else { + $ret .= ";\n"; + } +} + +sub normalMethodDeclarations($$;$&$) +{ + my ($node, $parentName, $definition, $writerSub, $inline) = @_; + my $accessType = ""; + my $defaultConstructor = 0; + my $hasPublicProtectedConstructor = 0; + my $hasDestructor = 1; + my $hasPublicDestructor = 1; + my $hasCopyConstructor = 0; + my $hasPrivateCopyConstructor = 1; + my $enums = ""; + + my @methods; + + my $ret = ""; + + Iter::MembersByType ( $node, undef, + sub { my ($classNode, $methodNode ) = @_; + if ( $methodNode->{NodeType} eq "method" || + $methodNode->{NodeType} eq "enum" || + $methodNode->{NodeType} eq "typedef" ) { + if ( $methodNode->{Access} ne "protected" && + $methodNode->{Access} ne "protected_slots" && + #$methodNode->{Access} eq "private" && + $methodNode->{Access} ne "private_slots" && + $methodNode->{Access} ne "signals" && + !$methodNode->{Pure} && + $methodNode->{astNodeName} !~ /qt_/ && + $methodNode->{astNodeName} !~ /operator/ && + $methodNode->{Params} !~ /std\:\:/ && + $methodNode->{Params} !~ /\.\.\./){ + push @methods, $methodNode; + } + } + }, undef ); + + foreach my $child ( @methods ) { + if ( $child->{Access} ne $accessType ) { + $accessType = $child->{Access}; + + if ( ! (defined $definition ) ) { + if ( $accessType eq "public_slots" ) { + $ret .= "public: //slots\n"; + } else { + $ret .= "$accessType:\n"; + } + } + } + ## check for private ctor, dtor or copy ctor... +# print " public $node->{astNodeName}, $child->{astNodeName}\n"; + if ( $node->{astNodeName} eq $child->{astNodeName} ) { +# print "Constructor..."; + if ( $child->{ReturnType} =~ /~/ ) { + # A destructor + $hasPublicDestructor = 0 if $child->{Access} ne 'public'; + $hasDestructor = 1; + } else { + if ( $child->{Params} eq '' && $child->{Access} ne 'private'){ + # A constructor + $defaultConstructor = 1; + } + } +# $hasPublicProtectedConstructor = 1 if ( $child->{Access} ne 'private' ); + + # Copy constructor? + if ( $#{$child->{ParamList}} == 0 ) { + my $theArgType = @{$child->{ParamList}}[0]->{ArgType}; + if ($theArgType =~ /$parentName\s*\&/) { + $hasCopyConstructor = 1; + $hasPrivateCopyConstructor = 1 if ( $child->{Access} eq 'private' ); + } + } + # Hack the return type for constructors, since constructors return an object pointer + #$child->{ReturnType} = $node->{astNodeName}."*"; + + } + + if( $child->{NodeType} eq "enum"){ + $ret .= "\tenum ".$child->{astNodeName}." {".$child->{Params}."};\n"; + $enums .= "\tenum ".$child->{astNodeName}." {".$child->{Params}."};\n"; + } + else{ + if ( $child->{NodeType} eq "typedef"){ + $ret .= "\t".$child->{NodeType}." ".$child->{Type}." ".$child->{astNodeName}.";\n"; + $enums .= "\t".$child->{NodeType}." ".$child->{Type}." ".$child->{astNodeName}.";\n"; + } + else{ + $ret .= generateMethodsCode( $child, $parentName, 0, $definition, $inline ); + } + } + + if ( defined $definition && defined $writerSub ) { + if ( defined $inline ) { $ret .= "\t"; } + $ret .= "{\n"; + $ret .= &$writerSub( $child ); + if ( defined $inline ) { $ret .= "\t"; } + $ret .= "}\n"; + } + + } + + if ( $defaultConstructor == 0) + { + #print "Private ctor for $node->{astNodeName}\n"; + $ret .= "private:\n\t"; + $ret .= $node->{astNodeName}."();\n"; + } + + if ( $hasCopyConstructor == 1 && $hasPrivateCopyConstructor == 1) + { + #print "Private copy ctor for $node->{astNodeName}\n"; + $ret .= "private:\n\t"; + $ret .= $node->{astNodeName}."(const ".$node->{astNodeName}."& );\n"; + } + + if ( $hasPublicDestructor == 0) + { + #print "Private dtor for $node->{astNodeName}\n"; + $ret .= "private:\n\t"; + $ret .= "~".$node->{astNodeName}."();\n"; + } + + if ( $enums ne "") + { + print "inlineing enums...\n"; + $ret .= "\n\n%{\n"; + $ret .= $enums; + $ret .= "%}\n"; + } + return $ret; +} + +sub definitionParentWriter +{ + my ($child) = @_; + my $ret = "\t\t$child->{Parent}->{astNodeName}::$child->{astNodeName}\( "; + $ret .= pureParamNames( $child ); + $ret .= ");\n"; + + return $ret; +} + +sub bridgeWriter +{ + my ($child) = @_; + my $ret = "\t\t$child->{astNodeName}Protected\( "; + $ret .= pureParamNames( $child ); + $ret .= ");\n"; + + return $ret; + +} + +# returns a list of parameter names for $method in the form: +# "a,b,c,d", suitable to call another method with the same +# parameters +sub pureParamNames($) +{ + my $method = shift; + my $ret = ""; + + my @params = $method->{ParamList}; + foreach my $arg (@params) { + if ( $arg ) { + my @arr = @{$arg}; + my $num = @arr; + foreach my $param ( @{$arg} ) { + $ret .= " $param->{ArgName}"; + --$num; + $ret .= ", " if $num; + } + } + } + return $ret; +} + +sub mangledProtectedDeclarations($$$;$$$) +{ + my ($node, $parentName, $mangle, $definition, $writerSub, $inline) = @_; + my $accessType = ""; + + my @methods; + + my $ret = ""; + + Iter::MembersByType ( $node, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq "method" ) { + if ( $methodNode->{Access} eq "protected" || + $methodNode->{Access} eq "protected_slots" ) { + push @methods, $methodNode; + } + } + }, undef ); + + foreach my $child ( @methods ) { + if ( $child->{Access} ne $accessType ) { + $accessType = $child->{Access}; + + if ( ! (defined $definition ) ) { + if ( $accessType eq "protected_slots" ) { + $ret .= "protected: //slots\n"; + } else { + $ret .= "$accessType:\n"; + } + } + } + $ret .= generateMethodsCode( $child, $parentName, $mangle, $definition, $inline ); + if ( defined $definition && defined $writerSub ) { + if ( defined $inline ) { $ret .= "\t"; } + $ret .= "{\n"; + #FIXME : from which of the parents does the method come from? + $ret .= &$writerSub( $child ); + if ( defined $inline ) { $ret .= "\t"; } + $ret .= "}\n"; + } + } + return $ret; +} + +sub neededImportsForObject($) +{ + my ($node) = @_; +# our @imports; + my @imports; + Iter::MembersByType ( $node, + sub { }, + sub { my ($node, $kid ) = @_; + if ( $kid->{NodeType} eq "method" && + $kid->{Access} eq "public" && + $kid->{astNodeName} !~ /qt_/ + ) { + #print "Method: $kid->{ReturnType} $kid->{astNodeName}\n"; + + my @params = $kid->{ParamList}; + foreach my $arg (@params) { + if ( $arg ) { + foreach my $param ( @{$arg} ) { + my $pname = convertType($param->{ArgType}); + if ( $pname !~ /\bQ_[A-Z0-9_]+/ && + $pname =~ /\bQ[A-Za-z0-9_]+/ && + $& ne $node->{astNodeName} + ) { + push @imports, checkObj($&); + #print "Adding $&\n"; + } + } + } + } + my $pname = convertType($kid->{ReturnType}); + if ( $pname !~ /\bQ_[A-Z0-9_]+/ && + $pname =~ /\bQ[A-Za-z0-9_]+/ && + $& ne $node->{astNodeName} + ) { + push @imports, checkObj($&); + #print "Adding $&\n"; + } + } + }, + sub { } + ); + my %seen = (); + my @uniq; + foreach my $item (@imports) { + push(@uniq, $item) unless $seen{$item}++; + } + return @uniq; +} + +sub convertType($) +{ + my ($item) = @_; + #print "-$item-\n"; + if (exists $typedeflist{$item}) { + print "$item change to $typedeflist{$item}\n"; + return $typedeflist{$item}; + } else { + return $item; + } +} + +sub checkObj($) +{ + + my ($item) = @_; + # Yes some of this is in kalyptusDataDict's ctypemap +# but that one would need to be separated (builtins vs normal classes) + + my $node = kdocAstUtil::findRef( $rootnode, $item ); + #print "Data item $item is a $node->{Access} node $node->{astNodeName}\n"; + return $node->{astNodeName}; + +} +sub generateNeededTemplatesForObject($) +{ + my ($node) = @_; + + Iter::MembersByType ( $node, + sub { }, + sub { my ($node, $kid ) = @_; + if ( $kid->{NodeType} eq "method" ) { + my @params = $kid->{ParamList}; + foreach my $arg (@params) { + if ( $arg ) { + foreach my $param ( @{$arg} ) { + my $pname = $param->{ArgType}; + if ( $pname =~ /\b(Q[A-Za-z0-9_]+)\<([A-Za-z0-9_]+)\>/ ) { + my $cname = $1; + my $tname = $2; + if ( $tname eq "type" || $tname eq "T"){ + $tname = "int"; + }else{ + print "Template $1::$2 in $pname\n"; + print SWIG_HEADER "\%template($tname",$cname,") $cname"."<",$tname,">;\n"; + } + } + } + } + } + my $returnName = $kid->{ReturnType}; + if ( $returnName =~ /\b(Q[A-Za-z0-9_]+)\<([A-Za-z0-9_]+)\>/ ) { + my $cname = $1; + my $tname = $2; + if ( $tname eq "type" || $tname eq "T"){ + $tname = "int"; + #}else{ + print "Template $1::$2 in $returnName\n"; + print SWIG_HEADER "\%template($tname",$cname,") $cname"."<",$tname,">;\n"; + } + + } + } + }, + sub { } + ); +} + +sub generateHeader($$) +{ + my ($node, $filename) = @_; + + open ( HEADER, ">$outputdir/$filename" ) || die "Can't open header $filename\n"; + print HEADER documentationHeader( $filename, "header file" ); + + my $macro = uc $filename; + $macro =~ s/\./_/g; + print HEADER "#ifndef ", $macro, "\n"; + print HEADER "#define ", $macro, "\n"; + + print HEADER "class $node->{astNodeName}Bridge;\n"; + my @parentNames = parentClassNames($node); + my $len = @parentNames; + if ( $len ) { + print HEADER "\n"; + print HEADER "$node->{NodeType} ",$typeprefix,$node->{astNodeName}," "; + my $idx = 0; + my $start = 0; + while ( $len-- ) { + if ( $len ) { + if ($parentNames[$idx] ) { + if ( !$start ) { + print HEADER ": "; + $start = 1; + } + print HEADER " public ",$typeprefix,"$parentNames[$idx],\n\t" if $parentNames[$idx]; + } + } else { + if ($parentNames[$idx] ) { + if ( !$start ) { + print HEADER ": "; + $start = 1; + } + print HEADER " public ",$typeprefix,"$parentNames[$idx]\n" if $parentNames[$idx]; + } + } + ++$idx; + } + } else { + print HEADER "$node->{NodeType} $node->{astNodeName} "; + } + print HEADER "{\n"; + print HEADER normalMethodDeclarations( $node, $typeprefix + $node->{NodeType} ); + my $prot = mangledProtectedDeclarations( $node, $typeprefix + $node->{NodeType}, 0 ); + $prot =~ s/protected\:/public\:/g; + print HEADER $prot; + print HEADER "private:\n"; + print HEADER "\t$node->{astNodeName}Bridge *mBridge;\n"; + print HEADER "};\n\n"; + print HEADER "#endif //", uc $filename, "\n"; + close HEADER; +} + +sub generateBridge($*) +{ + my($node, $fh) = @_; + + print $fh "$node->{NodeType} $node->{astNodeName}Bridge : public $node->{astNodeName}\n"; + print $fh "{\n"; + # print $fh "public:\n"; + # print $fh normalMethodDeclarations( $node, $node->{astNodeName}."Bridge" , 1, sub { definitionParentWriter(@_) }, 1 ); + print $fh "public:\n"; + print $fh mangledProtectedDeclarations( $node, $node->{astNodeName}."Bridge", 1, 1, sub { definitionParentWriter(@_) }, 1 ); + print $fh "protected:\n"; + print $fh mangledProtectedDeclarations( $node, $node->{astNodeName}."Bridge", 0, 1, sub { bridgeWriter(@_) }, 1 ); + print $fh "\n"; + print $fh "\n"; + print $fh "};\n"; + +} + +sub generateWrapper($*) +{ + my($node, $fh) = @_; + +} + +sub generateSource +{ + my ($node, $filename) = @_; + + open ( SOURCE, ">$outputdir/$filename" ) || die "Can't open $filename\n"; + + $filename =~ s/\.cpp$/\.h/; + print SOURCE "#include \"$filename\";\n\n\n"; + + generateBridge( $node, *SOURCE ); + generateWrapper( $node, *SOURCE ); + + close SOURCE; +} + +sub protectedMethods($) +{ + +} + +sub documentationHeader($$) +{ + my ($file, $descr) = @_; + my $ret = "/***************************************************************************\n"; + $ret .= " File: $file - $descr\n"; + $ret .= $docTop; + return $ret; +} + +sub writeDoc +{ + ( $lib, $rootnode, $outputdir, $opt ) = @_; + + $debug = $main::debuggen; + + mkpath( $outputdir ) unless -f $outputdir; + unlink $outputdir."/interfaces_all.i"; + + # Document all compound nodes + Iter::LocalCompounds( $rootnode, sub { writeClassDoc( shift ); } ); +} + + +sub addInterface($$$) +{ + my ($outputdir,$typeprefix,$node) = @_; + my $interfacesFile = "interfaces_all.i"; + open( IFILE, ">>$outputdir/$interfacesFile" ) || die "Can't open $outputdir/$interfacesFile"; + print IFILE "%include \"$typeprefix", kdocAstUtil::heritage($node),".i\"\n"; + close IFILE; +} + + +sub writeClassDoc +{ + my( $node ) = @_; + + if( exists $node->{ExtSource} ) { + print "Trying to write doc for ".$node->{AstNodeName}. + " from ".$node->{ExtSource}."\n"; + return; + } + + if( $node->{Access} eq "private" || + $node->{Access} eq "protected" ) { + return; + } + + my $typeName = $node->{astNodeName}."*"; + + if ( kalyptusDataDict::ctypemap($typeName) eq "" ) { + $typeprefix = ($typeName =~ /^Q/ ? "qt_" : "kde_"); + kalyptusDataDict::setctypemap($typeName, $typeprefix.$node->{astNodeName}."*"); + print "'$typeName' => '$typeprefix$typeName',\n"; + } elsif ( kalyptusDataDict::ctypemap($typeName) =~ /^qt_/ ) { + $typeprefix = "qt_"; + } elsif ( kalyptusDataDict::ctypemap($typeName) =~ /^kde_/ ) { + $typeprefix = "kde_"; + } else { + $typeprefix = "kde_"; + } + + my $basefile = "$typeprefix".join("__", kdocAstUtil::heritage($node)).".i"; + my $cppfile = $basefile; + $cppfile =~ s/\.i/_wrap\.cpp/; + + + my $file = "$outputdir/$typeprefix".join("__", kdocAstUtil::heritage($node)).".i"; + my $docnode = $node->{DocNode}; + my @list = (); + my $version = undef; + my $author = undef; + + addInterface( $outputdir, $typeprefix, $node ); + + # if( $#{$node->{Kids}} < 0 || $node->{Access} eq "private" || exists $node->{Tmpl} ) { + if( $#{$node->{Kids}} < 0 || $node->{Access} eq "private") { + return; + } + + open( SWIG_HEADER, ">$file" ) || die "Couldn't create $file\n"; + + # Header + + my $short = ""; + my $extra = ""; + + my $f = $typeprefix . $node->{astNodeName} . ".h"; + my $descr = documentationHeader( $f, "header" ); + print SWIG_HEADER $descr; + + generateHeader( $node, $f ); + $f =~ s/\.h$/\.cpp/; + generateSource( $node, $f ); + + if ( defined $docnode ) { + print SWIG_HEADER "/**\n"; + if ( defined $docnode->{Text} ) { + my $node; + foreach $node ( @{$docnode->{Text}} ) { + next if $node->{NodeType} ne "DocText"; + print SWIG_HEADER $node->{astNodeName}, "\n"; + } + } + + exists $docnode->{Author} && print SWIG_HEADER " \@author ", $docnode->{Author}, "\n"; + exists $docnode->{Version} && print SWIG_HEADER " \@version ", $docnode->{Version}, "\n"; + exists $docnode->{ClassShort} && print SWIG_HEADER " \@short ", $docnode->{ClassShort}, "\n"; + print SWIG_HEADER "*/\n"; + } + + my $sourcename = $node->{Source}->{astNodeName}; + + if ( $sourcename =~ m!.*(dom|kabc|tdeprint|tdesu|kio|kjs|kparts|ktexteditor|libkmid)/([^/]*$)! ) { + $sourcename = $1."/".$2; + } else { + $sourcename =~ s!.*/([^/]*$)!$1!; + } + + print SWIG_HEADER "\%module ",$typeprefix,$node->{astNodeName},"\n\n"; + + print SWIG_HEADER "\%{\n#include <",$sourcename , ">\n\%}\n\n"; + + #print SWIG_HEADER "\%import \"interfaces_all.i\"\n"; + + #print SWIG_HEADER "\%import \"", $basefile ,"\"\n"; + + # make this smarter i guess... +# my @types = neededImportsForObject($node); +# foreach my $f ( @types ) { +# print SWIG_HEADER "\%import \"qt_".$f.".i\"\n"; +# } +# print SWIG_HEADER "\%import \"qt_Qt.i\"\n"; + +# my @impor = parentClassNames($node); +# foreach my $f ( @impor ) { +# print SWIG_HEADER "\%import \"qt_".$f.".i\"\n"; +# } + + # Iter::LocalCompounds( $node, sub { my ($node) = @_; print STDERR "$node->{NodeType}||$node->{astNodeName} \n"; } ); + # Iter::Generic( $node, undef, + # &isNotProtectedMethod, + # sub { my ($node, $kid) = @_; debugPrint "This is :: ", $node->{astNodeName}, " | ", $kid->{astNodeName}, "\n"; }, + # undef ); + # Iter::MembersByType ( $node, undef, + # sub { my ($classNode, $methodNode ) = @_; + # + # if ( $methodNode->{NodeType} eq "method" ) { + # print SWIG_HEADER generateMethodsCode( $methodNode, 0 ); + # } + # }, undef ); + + my @parentNames = parentClassNames($node); + my $len = @parentNames; + if ( $len ) { + print SWIG_HEADER "\n"; + print SWIG_HEADER "$node->{NodeType} ",$node->{astNodeName}," "; + my $idx = 0; + my $start = 0; + while ( $len-- ) { + if ( $len ) { + if ($parentNames[$idx] ) { + if ( !$start ) { + print SWIG_HEADER ": "; + $start = 1; + } + print SWIG_HEADER " public $parentNames[$idx],\n\t" if $parentNames[$idx]; + } + } else { + if ($parentNames[$idx] ) { + if ( !$start ) { + print SWIG_HEADER ": "; + $start = 1; + } + print SWIG_HEADER " public $parentNames[$idx]\n" if $parentNames[$idx]; + } + } + ++$idx; + } + } else { + print SWIG_HEADER "$node->{NodeType} $node->{astNodeName} "; + } + print SWIG_HEADER "{\n"; +# my $name = $node->{astNodeName}."Bridge"; +# print SWIG_HEADER normalMethodDeclarations( $node, $name, 1 ); + print SWIG_HEADER normalMethodDeclarations( $node, $typeprefix + $node->{NodeType} ); + print SWIG_HEADER "};\n\n\n"; + + +# generateNeededTemplatesForObject( $node ); + print SWIG_HEADER "\n"; + + #print SWIG_HEADER "\%inline \%{\n\n"; + + #print SWIG_HEADER "class ",$node->{astNodeName},";\n"; + #print SWIG_HEADER "#include <",$sourcename , ">\n"; + #print SWIG_HEADER $node->{astNodeName}, " *",$node->{astNodeName},"Null()\n"; + #print SWIG_HEADER "{\n"; + #print SWIG_HEADER "\treturn ($node->{astNodeName}*)0L;\n"; + #print SWIG_HEADER "}\n\n"; + #print SWIG_HEADER "\%}\n"; + + $constructorCount = 0; + + # Iter::MembersByType ( $node, + # sub { print SWIG_HEADER "", $_[0], ""; }, + # sub { my ($node, $kid ) = @_; + # preParseMember( $node, $kid ); + # }, + # sub { print SWIG_HEADER ""; } + # ); + + # if ( ! exists $node->{Pure} && $constructorCount > 0 ) { + # print SWIG_HEADER "CLASS HEADER = class ", $node->{astNodeName}, "Bridge : public ", kalyptusDataDict::addNamespace($node->{astNodeName}), "\n{\npublic:\n"; + + # Iter::MembersByType ( $node, + # sub { print SWIG_HEADER "", $_[0], ""; }, + # sub { my ($node, $kid ) = @_; + # generateBridgeClass( $node, $kid ); + # }, + # sub { print SWIG_HEADER ""; } + # ); + + # generateBridgeEventHandlers($node); + # } + + %functionId = (); + $eventHandlerCount = 0; + + # Iter::MembersByType ( $node, + # sub { print SWIG_HEADER "", $_[0], ""; }, + # sub { my ($node, $kid ) = @_; + # listMember( $node, $kid ); + # }, + # sub { print SWIG_HEADER ""; } + # ); + + # ancestors + # my @ancestors = (); + # Iter::Ancestors( $node, $rootnode, undef, undef, + # sub { # print + # my ( $ances, $name, $type, $template ) = @_; + # + # push @ancestors, $name; + # + # }, + # undef + # ); + + # if ( $#ancestors > 0 ) { + # # 'type transfer' functions to cast for correct use of multiple inheritance + # foreach my $ancestor (@ancestors) { + # print SWIG_HEADER "\n/\*\* Casts a '$typeprefix", $node->{astNodeName}, " *' to a '", kalyptusDataDict::ctypemap($ancestor."\*"), "' \*/\n"; + # print SWIG_HEADER kalyptusDataDict::ctypemap($ancestor."\*"), " ", $typeprefix, $node->{astNodeName}, "_", $ancestor; + # print SWIG_HEADER "(", $typeprefix, $node->{astNodeName}, "* instPointer);\n"; + + # print CLASS kalyptusDataDict::ctypemap($ancestor."\*"), " ", $typeprefix, $node->{astNodeName}, "_", $ancestor; + # print CLASS "(", $typeprefix, $node->{astNodeName}, "* instPointer){\n"; + # print CLASS "\treturn (", kalyptusDataDict::ctypemap($ancestor."\*"), ") (", $ancestor, " *) (", $node->{astNodeName}, " *) instPointer;\n}\n"; + # } + # } + + close SWIG_HEADER; +} + +################################################################################### + +1; + diff --git a/kalyptus/kalyptusDataDict.pm b/kalyptus/kalyptusDataDict.pm index 8ba1996..586ddf3 100644 --- a/kalyptus/kalyptusDataDict.pm +++ b/kalyptus/kalyptusDataDict.pm @@ -1,5 +1,5 @@ #*************************************************************************** -# kalyptusDataDict.pm - A TQt/KDE types data dictionary +# kalyptusDataDict.pm - A Qt/KDE types data dictionary # ------------------- # begin : Fri Oct 20 12:00:00 2000 # copyright : (C) 2000-2001 Lost Highway Ltd. All Rights Reserved. @@ -27,6 +27,7 @@ BEGIN { %interfacemap = ( +'TQGL' => 'TQGLInterface', 'TQPaintDevice' => 'TQPaintDeviceInterface', 'TQMenuData' => 'TQMenuDataInterface', 'TQRangeControl' => 'TQRangeControlInterface', @@ -54,9 +55,9 @@ BEGIN ); -# A hard coded type translation table (the idea from the Roberto Alsina's TQtc +# A hard coded type translation table (the idea from the Roberto Alsina's Qtc # python conversion scripts). The particular format used here makes it possible to use -# the same table with three different kdoc based TQt/KDE language binding generators; +# the same table with three different kdoc based Qt/KDE language binding generators; # C, Objective-C and Java. %ctypemap = ( @@ -135,8 +136,6 @@ BEGIN 'AudioSubSystemStart*' => 'kde_AudioSubSystemStart*', 'AuthAccept&' => 'kde_AuthAccept*', 'AuthAccept*' => 'kde_AuthAccept*', -'AuthInfo&' => 'kde_AuthInfo*', -'AuthInfo*' => 'kde_AuthInfo*', 'BGMode' => 'int', 'BMToken*' => 'kde_BMToken*', 'BackgroundMode' => 'int', @@ -274,7 +273,6 @@ BEGIN 'Cursor*' => 'kde_Cursor*', 'CursorInterface*' => 'kde_CursorInterface*', 'DCOPClient*' => 'kde_DCOPClient*', -'DCOPClientTransaction*' => 'kde_DCOPClientTransaction*' , 'DCOPObject*' => 'kde_DCOPObject*', 'DCOPObjectProxy*' => 'kde_DCOPObjectProxy*', 'DCOPRef&' => 'kde_DCOPRef*' , @@ -284,23 +282,25 @@ BEGIN 'DOM::CSSProperty*' => 'kde_CSSProperty*' , 'DOM::DOMString&' => 'kde_DOMString*' , 'DOM::DOMString' => 'kde_DOMString*' , -'DOM::Document&' => 'kde_DOMDocument*' , -'DOM::Document' => 'kde_DOMDocument*' , -'DOM::Document*' => 'kde_DOMDocument*' , -'DOM::ElementImpl*' => 'kde_DOM_ElementImpl*' , +'DOM::Document&' => 'kde_Document*' , +'DOM::Document' => 'kde_Document*' , +'DOM::Document*' => 'kde_Document*' , 'DOM::HTMLDocument' => 'kde_HTMLDocument*' , 'DOM::MediaList&' => 'kde_MediaList*', -'DOM::MediaList' => 'kde_MediaList', +'DOM::MediaList' => 'kde_MediaList*', 'DOM::MediaList*' => 'kde_MediaList*', -'DOM::Node&' => 'kde_DOMNode*' , -'DOM::Node' => 'kde_DOMNode*' , +'DOM::Node&' => 'kde_Node*' , +'DOM::Node' => 'kde_Node*' , 'DOM::NodeList&' => 'kde_DOMNodeList*', 'DOM::NodeList' => 'kde_DOMNodeList*', 'DOM::NodeList*' => 'kde_DOMNodeList*', 'DOM::Range' => 'kde_Range*' , 'DOM::StyleSheetList&' => 'kde_StyleSheetList*', -'DOM::StyleSheetList' => 'kde_StyleSheetList', +'DOM::StyleSheetList' => 'kde_StyleSheetList*', 'DOM::StyleSheetList*' => 'kde_StyleSheetList*', +'StyleSheetList&' => 'kde_StyleSheetList*', +'StyleSheetList' => 'kde_StyleSheetList*', +'StyleSheetList*' => 'kde_StyleSheetList*', 'DOMException&' => 'kde_DOMException*', 'DOMException*' => 'kde_DOMException*', 'DOMImplementation&' => 'kde_DOMImplementation*', @@ -322,8 +322,6 @@ BEGIN 'Direction' => 'int', 'DispatchFunction' => 'kde_DispatchFunction*', 'Dispatcher*' => 'kde_Dispatcher*', -'Display' => 'Display', -'Display*' => 'Display*', 'DistributionList*' => 'kde_DistributionList*', 'DistributionListEditor*' => 'kde_DistributionListEditor*', 'DistributionListManager*' => 'kde_DistributionListManager*', @@ -412,7 +410,6 @@ BEGIN 'Element&' => 'kde_Element*', 'Element' => 'kde_Element*', 'Element*' => 'kde_Element*', -'ElementImpl*' => 'kde_ElementImpl*', 'EmailSelectDialog*' => 'kde_EmailSelectDialog*', 'EncoderFn' => 'int' , 'Endian' => 'int', @@ -434,7 +431,6 @@ BEGIN 'ExecState*' => 'kde_ExecState*', 'ExtensionLoader*' => 'kde_ExtensionLoader*', 'FALSE' => '0', -'FILE*' => 'FILE*', 'FMOut*' => 'kde_FMOut*', 'Factory*' => 'kde_Factory*', 'False' => '0', @@ -486,12 +482,12 @@ BEGIN 'GlobalComm_skel*' => 'kde_GlobalComm_skel*', 'GlobalComm_stub*' => 'kde_GlobalComm_stub*', 'HANDLE' => 'unsigned int', -'HBITMAP' => 'void *' , -'HCURSOR' => 'void *' , -'HDC' => 'void *' , -'HFONT' => 'void *' , -'HPALETTE' => 'void *' , -'HRGN' => 'void *' , +'HBITMAP' => 'void*' , +'HCURSOR' => 'void*' , +'HDC' => 'void*' , +'HFONT' => 'void*' , +'HPALETTE' => 'void*' , +'HRGN' => 'void*' , 'HTMLAnchorElement&' => 'kde_HTMLAnchorElement*', 'HTMLAnchorElement*' => 'kde_HTMLAnchorElement*', 'HTMLAnchorElementImpl*' => 'kde_HTMLAnchorElementImpl*', @@ -762,7 +758,6 @@ BEGIN 'KCharSelectTable*' => 'kde_KCharSelectTable*', 'KCharsets*' => 'kde_KCharsets*' , 'KCmdLineArgs*' => 'kde_KCmdLineArgs*' , -'KCmdLineOptions*' => 'kde_KCmdLineOptions*' , 'KCodecs*' => 'kde_KCodecs*', 'KColor&' => 'kde_KColor*' , 'KColor*' => 'kde_KColor*', @@ -778,13 +773,11 @@ BEGIN 'KCommandHistory*' => 'kde_KCommandHistory*', 'KCompletion*' => 'kde_KCompletion*' , 'KCompletionBase*' => 'kde_KCompletionBase*', -'KCompletionBase::KeyBindingType' => 'kde_KCompletionBase_KeyBindingType*' , 'KCompletionBox*' => 'kde_KCompletionBox*', 'KConfig*' => 'kde_KConfig*' , 'KConfigBackEnd*' => 'kde_KConfigBackEnd*', 'KConfigBase&' => 'kde_KConfigBase*', 'KConfigBase*' => 'kde_KConfigBase*' , -'KConfigBase::ConfigState' => 'kde_KConfigBase_ConfigState' , 'KConfigGroup*' => 'kde_KConfigGroup*', 'KConfigGroupSaver*' => 'kde_KConfigGroupSaver*', 'KConfigINIBackEnd*' => 'kde_KConfigINIBackEnd*', @@ -794,13 +787,12 @@ BEGIN 'KCookie*' => 'kde_KCookie*', 'KCrash*' => 'kde_KCrash*', 'KCursor*' => 'kde_KCursor*', -'KDBGFUNC' => 'void *' , +'KDBGFUNC' => 'void*' , 'KDCOPActionProxy*' => 'kde_KDCOPActionProxy*', 'KDCOPPropertyProxy*' => 'kde_KDCOPPropertyProxy*', 'KDEAniMenu*' => 'kde_KDEAniMenu*', 'KDEDModule*' => 'kde_KDEDModule*', 'KDEDesktopMimeType*' => 'kde_KDEDesktopMimeType*', -'KDEDesktopMimeType::Service&' => 'kde_KDEDesktopMimeType_Service*' , 'KDESasl*' => 'kde_KDESasl*', 'KDEStyle*' => 'kde_KDEStyle*', 'KDEsuClient*' => 'kde_KDEsuClient*', @@ -830,7 +822,6 @@ BEGIN 'KDialogBase*' => 'kde_KDialogBase*' , 'KDialogBaseTile*' => 'kde_KDialogBaseTile*', 'KDialogQueue*' => 'kde_KDialogQueue*', -'KDirLister*' => 'kde_KDirLister*', 'KDirNotify*' => 'kde_KDirNotify*', 'KDirNotify_stub*' => 'kde_KDirNotify_stub*', 'KDirOperator*' => 'kde_KDirOperator*', @@ -868,11 +859,8 @@ BEGIN 'KEntry*' => 'kde_KEntry*', 'KEntryKey&' => 'kde_KEntryKey*' , 'KEntryKey*' => 'kde_KEntryKey*', -'KEntryMap' => 'kde_KEntryMap*' , -'KEntryMap*' => 'kde_KEntryMap*' , 'KExecMimeType*' => 'kde_KExecMimeType*', 'KExecPropsPlugin*' => 'kde_KExecPropsPlugin*', -'KExtendedSocket*' => 'kde_KExtendedSocket*', 'KFile*' => 'kde_KFile*', 'KFile::FileView' => 'int' , 'KFile::Mode' => 'int' , @@ -886,8 +874,6 @@ BEGIN 'KFileFilterCombo*' => 'kde_KFileFilterCombo*', 'KFileIconView*' => 'kde_KFileIconView*', 'KFileIconViewItem*' => 'kde_KFileIconViewItem*', -'KFileItem&' => 'kde_KFileItem*', -'KFileItem*' => 'kde_KFileItem*' , 'KFileItemList&' => 'kde_KFileItemList*' , 'KFileItemList' => 'kde_KFileItemList*' , 'KFileItemList*' => 'kde_KFileItemList*' , @@ -943,19 +929,15 @@ BEGIN 'KHelpMenu*' => 'kde_KHelpMenu*', 'KHistoryCombo*' => 'kde_KHistoryCombo*', 'KIO*' => 'kde_KIO*', -'KIO::AuthInfo&' => 'kde_AuthInfo*', 'KIO::CopyJob*' => 'kde_CopyJob*' , 'KIO::DeleteJob*' => 'kde_DeleteJob*' , 'KIO::Job*' => 'kde_Job*' , 'KIO::ListJob*' => 'kde_ListJob*' , -'KIO::MetaData&' => 'kde_MetaData*', 'KIO::RenameDlg_Mode' => 'int', 'KIO::RenameDlg_Result' => 'int', 'KIO::SimpleJob*' => 'kde_SimpleJob*', 'KIO::SkipDlg_Result' => 'int', 'KIO::Slave*' => 'kde_Slave*', -'KIO::UDSEntry&' => 'kde_UDSEntry*' , -'KIO::UDSEntryList&' => 'kde_UDSEntryList*' , 'KIOInputStream&' => 'kde_KIOInputStream*', 'KIOInputStream*' => 'kde_KIOInputStream*', 'KIOTestSlow&' => 'kde_KIOTestSlow*', @@ -970,14 +952,11 @@ BEGIN 'KIconEffect*' => 'kde_KIconEffect*' , 'KIconLoader*' => 'kde_KIconLoader*' , 'KIconSelectAction*' => 'kde_KIconSelectAction*', -'KIconTheme*' => 'kde_KIconTheme*' , 'KIconView*' => 'kde_KIconView*', 'KIconViewItem*' => 'kde_KIconViewItem*', 'KImageEffect*' => 'kde_KImageEffect*', 'KImageFilePreview*' => 'kde_KImageFilePreview*', 'KImageIO*' => 'kde_KImageIO*', -'KInetSocketAddress&' => 'kde_KInetSocketAddress*', -'KInetSocketAddress*' => 'kde_KInetSocketAddress*', 'KInstance&' => 'kde_KInstance*' , 'KInstance' => 'kde_KInstance*' , 'KInstance*' => 'kde_KInstance*' , @@ -992,14 +971,7 @@ BEGIN 'KJSO*' => 'kde_KJSO*', 'KJScript*' => 'kde_KJScript*', 'KJanusWidget*' => 'kde_KJanusWidget*', -'KJavaApplet*' => 'kde_KJavaApplet*' , -'KJavaAppletContext*' => 'kde_KJavaAppletContext*' , -'KJavaAppletServer*' => 'kde_KJavaAppletServer*' , -'KJavaAppletWidget*' => 'kde_KJavaAppletWidget*', -'KJavaProcess*' => 'kde_KJavaProcess*', -'KJavaScriptAdvice&' => 'kde_KJavaScriptAdvice*' , 'KKeyChooser*' => 'kde_KKeyChooser*', -'KKeyChooserItem*' => 'kde_KKeyChooserItem*', 'KKeyDialog*' => 'kde_KKeyDialog*', 'KKeyEntry&' => 'kde_KKeyEntry*' , 'KKeyEntry*' => 'kde_KKeyEntry*', @@ -1016,10 +988,8 @@ BEGIN 'KLed*' => 'kde_KLed*', 'KLibFactory*' => 'kde_KLibFactory*' , 'KLibLoader*' => 'kde_KLibLoader*' , -'KLibrary*' => 'kde_KLibrary*' , 'KLineEdit*' => 'kde_KLineEdit*' , 'KLineEditDlg*' => 'kde_KLineEditDlg*', -'KListAction*' => 'kde_KListAction*', 'KListBox*' => 'kde_KListBox*', 'KListView*' => 'kde_KListView*' , 'KListViewItem*' => 'kde_KListViewItem*', @@ -1033,7 +1003,6 @@ BEGIN 'KMPrinter*' => 'kde_KMPrinter*', 'KMPrinterList*' => 'kde_KMPrinterList*', 'KMPrinterPage*' => 'kde_KMPrinterPage*', -'KMacroCommand*' => 'kde_KMacroCommand*', 'KMainWindow*' => 'kde_KMainWindow*', 'KMainWindowInterface*' => 'kde_KMainWindowInterface*', 'KMenuBar*' => 'kde_KMenuBar*' , @@ -1042,13 +1011,10 @@ BEGIN 'KMimeMagic*' => 'kde_KMimeMagic*' , 'KMimeMagicResult*' => 'kde_KMimeMagicResult*' , 'KMimeSourceFactory*' => 'kde_KMimeSourceFactory*' , -'KMimeType*' => 'kde_KMimeType*', 'KMimeType::List&' => 'kde_KMimeType_List*' , -'KMimeType::Ptr&' => 'kde_KMimeType_Ptr*' , -'KMimeType::Ptr' => 'kde_KMimeType_Ptr' , 'KMouseSettings*' => 'kde_KMouseSettings*', 'KMultipleDrag*' => 'kde_KMultipleDrag*', -'KNDBGFUNC' => 'void *' , +'KNDBGFUNC' => 'void*' , 'KNotifyClient*' => 'kde_KNotifyClient*', 'KNumInput*' => 'kde_KNumInput*' , 'KOCRDialog*' => 'kde_KOCRDialog*', @@ -1069,10 +1035,7 @@ BEGIN 'KParts::BrowserExtension*' => 'kde_BrowserExtension*' , 'KParts::GUIActivateEvent*' => 'kde_GUIActivateEvent*' , 'KParts::Part*' => 'kde_Part*', -'KParts::PartManager*' => 'kde_PartManager*' , 'KParts::ReadOnlyPart*' => 'kde_ReadOnlyPart*' , -'KParts::URLArgs&' => 'kde_URLArgs*' , -'KParts::URLArgs' => 'kde_URLArgs*', 'KPasswordDialog*' => 'kde_KPasswordDialog*', 'KPasswordEdit*' => 'kde_KPasswordEdit*', 'KPixmap&' => 'kde_KPixmap*' , @@ -1107,7 +1070,6 @@ BEGIN 'KRadioAction*' => 'kde_KRadioAction*', 'KRandomSequence*' => 'kde_KRandomSequence*', 'KRecentDocument*' => 'kde_KRecentDocument*', -'KRecentFilesAction*' => 'kde_KRecentFilesAction*' , 'KRegExp*' => 'kde_KRegExp*', 'KRegExpEditor*' => 'kde_KRegExpEditor*', 'KRegExpEditorInterface*' => 'kde_KRegExpEditorInterface*', @@ -1136,7 +1098,7 @@ BEGIN 'KSSLConnectionInfo*' => 'kde_KSSLConnectionInfo*', 'KSSLInfoDlg*' => 'kde_KSSLInfoDlg*', 'KSSLKeyGen*' => 'kde_KSSLKeyGen*', -'KSSLKeyType' => 'kde_KSSLKeyType', +'KSSLKeyType' => 'int', 'KSSLPKCS12*' => 'kde_KSSLPKCS12*', 'KSSLPKCS7*' => 'kde_KSSLPKCS7*', 'KSSLPeerInfo&' => 'kde_KSSLPeerInfo*', @@ -1157,11 +1119,8 @@ BEGIN 'KSelectAction*' => 'kde_KSelectAction*', 'KSelector*' => 'kde_KSelector*', 'KSeparator*' => 'kde_KSeparator*', -'KServerSocket*' => 'kde_KServerSocket*', 'KService&' => 'kde_KService*' , 'KService*' => 'kde_KService*', -'KService::List' => 'kde_KService_List*' , -'KService::Ptr' => 'kde_KService_Ptr*' , 'KServiceGroup*' => 'kde_KServiceGroup*', 'KServiceOffer&' => 'kde_KServiceOffer*' , 'KServiceOffer*' => 'kde_KServiceOffer*', @@ -1170,7 +1129,6 @@ BEGIN 'KSessionManaged*' => 'kde_KSessionManaged*', 'KShared&' => 'kde_KShared*' , 'KShared*' => 'kde_KShared*', -'KSharedPixmap*' => 'kde_KSharedPixmap*', 'KSharedPtr&' => 'kde_KSharedPtr*' , 'KSharedPtr*' => 'kde_KSharedPtr*', 'KShellCompletion*' => 'kde_KShellCompletion*', @@ -1182,10 +1140,6 @@ BEGIN 'KSimpleConfig&' => 'kde_KSimpleConfig*' , 'KSimpleConfig*' => 'kde_KSimpleConfig*', 'KSimpleFileFilter*' => 'kde_KSimpleFileFilter*', -'KSocket*' => 'kde_KSocket*', -'KSocketAddress&' => 'kde_KSocketAddress*', -'KSocketAddress*' => 'kde_KSocketAddress*', -'KSocks*' => 'kde_KSocks*', 'KSpell*' => 'kde_KSpell*', 'KSpellConfig&' => 'kde_KSpellConfig*' , 'KSpellConfig' => 'kde_KSpellConfig*' , @@ -1212,10 +1166,9 @@ BEGIN 'KStyle*' => 'kde_KStyle*' , 'KSycoca*' => 'kde_KSycoca*' , 'KSycocaEntry*' => 'kde_KSycocaEntry*' , -'KSycocaFactory*' => 'kde_KSycocaFactory*' , -'KSycocaFactoryId' => 'kde_KSycocaFactoryId' , -'KSycocaType&' => 'kde_KSycocaType*' , -'KSycocaType' => 'kde_KSycocaType*' , +'KSycocaFactoryId' => 'int' , +'KSycocaType&' => 'int' , +'KSycocaType' => 'int' , 'KSystemTray*' => 'kde_KSystemTray*', 'KTMainWindow*' => 'kde_KTMainWindow*', 'KTabButton*' => 'kde_KTabButton*', @@ -1265,6 +1218,10 @@ BEGIN 'KURL*' => 'kde_KURL*', 'KURL::List&' => 'kde_KURLList*' , 'KURL::List' => 'kde_KURLList*' , +'KURL::List*' => 'kde_KURLList*' , +'List&' => 'kde_KURLList*' , +'List' => 'kde_KURLList*' , +'List*' => 'kde_KURLList*' , 'KURLComboBox*' => 'kde_KURLComboBox*', 'KURLComboItem*' => 'kde_KURLComboItem*' , 'KURLCompletion*' => 'kde_KURLCompletion*', @@ -1301,9 +1258,6 @@ BEGIN 'Keymap*' => 'kde_Keymap*', 'LinkStyle&' => 'kde_LinkStyle*', 'LinkStyle*' => 'kde_LinkStyle*', -'List&' => 'kde_List*', -'List' => 'kde_List', -'List*' => 'kde_List*', 'ListIterator&' => 'kde_ListIterator*', 'ListIterator' => 'kde_ListIterator', 'ListIterator*' => 'kde_ListIterator*', @@ -1313,7 +1267,6 @@ BEGIN 'Lookup*' => 'kde_Lookup*', 'MCOPConfig*' => 'kde_MCOPConfig*', 'MCOPUtils*' => 'kde_MCOPUtils*', -'MSG*' => 'MSG*' , 'MailServer&' => 'MailServer*' , 'MailServer*' => 'kde_MailServer*', 'MainWindow*' => 'kde_MainWindow*', @@ -1323,7 +1276,7 @@ BEGIN 'MediaDataPacket*' => 'kde_MediaDataPacket*', 'MediaFrame*' => 'kde_MediaFrame*', 'MediaList&' => 'kde_MediaList*', -'MediaList' => 'kde_MediaList', +'MediaList' => 'kde_MediaList*', 'MediaList*' => 'kde_MediaList*', 'MediaListImpl*' => 'kde_MediaListImpl*', 'MediaModule&' => 'kde_MediaModule*', @@ -1333,9 +1286,6 @@ BEGIN 'MediaModule_skel*' => 'kde_MediaModule_skel*', 'MediaModule_stub*' => 'kde_MediaModule_stub*', 'MenuDockData*' => 'kde_MenuDockData*', -'MetaData&' => 'kde_MetaData*', -'MetaData' => 'kde_MetaData*', -'MetaData*' => 'kde_MetaData*', 'MethodDef&' => 'kde_MethodDef*', 'MethodDef*' => 'kde_MethodDef*', 'MidiEvent*' => 'kde_MidiEvent*', @@ -1383,9 +1333,9 @@ BEGIN 'NamedNodeMapImpl*' => 'kde_NamedNodeMapImpl*', 'NetAccess*' => 'kde_NetAccess*', 'NetRC*' => 'kde_NetRC*', -'Node&' => 'kde_DOMNode*', -'Node' => 'kde_DOMNode*', -'Node*' => 'kde_DOMNode*', +'Node&' => 'kde_Node*', +'Node' => 'kde_Node*', +'Node*' => 'kde_Node*', 'NodeFilter&' => 'kde_NodeFilter*', 'NodeFilter' => 'kde_NodeFilter*', 'NodeFilter*' => 'kde_NodeFilter*', @@ -1424,6 +1374,7 @@ BEGIN 'Object_stub*' => 'kde_Object_stub*', 'Observer*' => 'kde_Observer*', 'OfferList' => 'kde_OfferList*' , +'KTrader::OfferList' => 'kde_OfferList*' , 'Offset' => 'int', 'OnewayDispatchFunction' => 'kde_OnewayDispatchFunction*', 'OnewayInvocation&' => 'kde_OnewayInvocation*', @@ -1453,7 +1404,6 @@ BEGIN 'Part*' => 'kde_Part*', 'PartActivateEvent*' => 'kde_PartActivateEvent*', 'PartBase*' => 'kde_PartBase*', -'PartManager*' => 'kde_PartManager*', 'PartSelectEvent*' => 'kde_PartSelectEvent*', 'PassDlg*' => 'kde_PassDlg*', 'PasswordDialog*' => 'kde_PasswordDialog*', @@ -1505,851 +1455,841 @@ BEGIN 'ProgressItem*' => 'kde_ProgressItem*', 'PropagationMode' => 'int', 'ProtocolInfo*' => 'kde_ProtocolInfo*', -'Ptr' => 'void *', +'Ptr' => 'void*', 'PtyProcess*' => 'kde_PtyProcess*', -'TQAccel*' => 'qt_TQAccel*', -'TQAccessible*' => 'qt_TQAccessible*', -'TQAccessibleFactoryInterface*' => 'qt_TQAccessibleFactoryInterface*', -'TQAccessibleInterface*' => 'qt_TQAccessibleInterface*', -'TQAccessibleInterface**' => 'qt_TQAccessibleInterface**', -'TQAccessibleObject*' => 'qt_TQAccessibleObject*', -'TQAction*' => 'qt_TQAction*' , -'TQActionGroup*' => 'qt_TQActionGroup*', -'TQApplication*' => 'qt_TQApplication*' , -'TQArabicCodec*' => 'qt_TQArabicCodec*', -'TQArray*' => 'qt_TQArray*', -'TQAsciiBucket*' => 'qt_TQAsciiBucket*', -'TQAsciiCache*' => 'qt_TQAsciiCache*', -'TQAsciiCacheIterator*' => 'qt_TQAsciiCacheIterator*', -'TQAsciiDict*' => 'qt_TQAsciiDict*', -'TQAsciiDictIterator*' => 'qt_TQAsciiDictIterator*', -'TQAsyncIO*' => 'qt_TQAsyncIO*', -'TQAuBucket*' => 'qt_TQAuBucket*' , -'TQAuServer*' => 'qt_TQAuServer*', -'TQBaseBucket*' => 'qt_TQBaseBucket*' , -'TQBig5Codec*' => 'qt_TQBig5Codec*', -'TQBitArray&' => 'qt_TQBitArray*' , -'TQBitArray' => 'qt_TQBitArray*' , -'TQBitArray*' => 'qt_TQBitArray*' , -'TQBitVal&' => 'qt_TQBitVal*' , -'TQBitVal' => 'qt_TQBitVal*' , -'TQBitVal*' => 'qt_TQBitVal*', -'TQBitmap&' => 'qt_TQBitmap *', -'TQBitmap' => 'qt_TQBitmap *', -'TQBitmap*' => 'qt_TQBitmap *', -'TQBoxLayout*' => 'qt_TQBoxLayout*', -'TQBrush&' => 'qt_TQBrush *', -'TQBrush' => 'qt_TQBrush*' , -'TQBrush*' => 'qt_TQBrush*' , -'TQBrushData*' => 'qt_TQBrushData*', -'TQBuffer*' => 'qt_TQBuffer*', -'TQButton*' => 'qt_TQButton *', -'TQButtonGroup*' => 'qt_TQButtonGroup*' , -'TQByteArray& arr ()' => 'qt_TQByteArray*', -'TQByteArray&' => 'qt_TQByteArray*' , -'TQByteArray' => 'qt_TQByteArray*', -'TQByteArray*' => 'qt_TQByteArray*', -'TQCDEStyle*' => 'qt_TQCDEStyle*', +'TQAccel*' => 'qt_QAccel*', +'TQAccessible*' => 'qt_QAccessible*', +'TQAccessibleFactoryInterface*' => 'qt_QAccessibleFactoryInterface*', +'TQAccessibleInterface*' => 'qt_QAccessibleInterface*', +'TQAccessibleInterface**' => 'qt_QAccessibleInterface**', +'TQAccessibleObject*' => 'qt_QAccessibleObject*', +'TQAction*' => 'qt_QAction*' , +'TQActionGroup*' => 'qt_QActionGroup*', +'TQApplication*' => 'qt_QApplication*' , +'TQArabicCodec*' => 'qt_QArabicCodec*', +'TQArray*' => 'qt_QArray*', +'TQAsciiBucket*' => 'qt_QAsciiBucket*', +'TQAsciiCache*' => 'qt_QAsciiCache*', +'TQAsciiCacheIterator*' => 'qt_QAsciiCacheIterator*', +'TQAsciiDict*' => 'qt_QAsciiDict*', +'TQAsciiDictIterator*' => 'qt_QAsciiDictIterator*', +'TQAsyncIO*' => 'qt_QAsyncIO*', +'TQAuBucket*' => 'qt_QAuBucket*' , +'TQAuServer*' => 'qt_QAuServer*', +'TQBaseBucket*' => 'qt_QBaseBucket*' , +'TQBig5Codec*' => 'qt_QBig5Codec*', +'TQBitArray&' => 'qt_QBitArray*' , +'TQBitArray' => 'qt_QBitArray*' , +'TQBitArray*' => 'qt_QBitArray*' , +'TQBitVal&' => 'qt_QBitVal*' , +'TQBitVal' => 'qt_QBitVal*' , +'TQBitVal*' => 'qt_QBitVal*', +'TQBitmap&' => 'qt_QBitmap*', +'TQBitmap' => 'qt_QBitmap*', +'TQBitmap*' => 'qt_QBitmap*', +'TQBoxLayout*' => 'qt_QBoxLayout*', +'TQBrush&' => 'qt_QBrush*', +'TQBrush' => 'qt_QBrush*' , +'TQBrush*' => 'qt_QBrush*' , +'TQBrushData*' => 'qt_QBrushData*', +'TQBuffer*' => 'qt_QBuffer*', +'TQButton*' => 'qt_QButton*', +'TQButtonGroup*' => 'qt_QButtonGroup*' , +'TQByteArray& arr ()' => 'qt_QByteArray*', +'TQByteArray&' => 'qt_QByteArray*' , +'TQByteArray' => 'qt_QByteArray*', +'TQByteArray*' => 'qt_QByteArray*', +'TQCDEStyle*' => 'qt_QCDEStyle*', 'TQCOORD&' => 'short', 'TQCOORD' => 'short', -'TQCOORD*' => 'short *', -'TQCString&' => 'qt_TQCString*' , -'TQCString' => 'qt_TQCString*' , -'TQCString*' => 'qt_TQCString*' , -'TQCStringLess*' => 'qt_TQCStringLess*' , -'TQCStringList' => 'kde_TQCStringList*' , -'TQCache*' => 'qt_TQCache*', -'TQCacheIterator*' => 'qt_TQCacheIterator*', -'TQCanvas*' => 'qt_TQCanvas*' , -'TQCanvasEllipse*' => 'qt_TQCanvasEllipse*', -'TQCanvasItem*' => 'qt_TQCanvasItem*' , -'TQCanvasItemList' => 'qt_TQCanvasItemList*' , -'TQCanvasItemList*' => 'qt_TQCanvasItemList*', -'TQCanvasLine*' => 'qt_TQCanvasLine*', -'TQCanvasPixmap*' => 'qt_TQCanvasPixmap*' , -'TQCanvasPixmapArray*' => 'qt_TQCanvasPixmapArray*' , -'TQCanvasPolygon*' => 'qt_TQCanvasPolygon*', -'TQCanvasPolygonalItem*' => 'qt_TQCanvasPolygonalItem*', -'TQCanvasRectangle*' => 'qt_TQCanvasRectangle*', -'TQCanvasSpline*' => 'qt_TQCanvasSpline*', -'TQCanvasSprite*' => 'qt_TQCanvasSprite*', -'TQCanvasText*' => 'qt_TQCanvasText*', -'TQCanvasView*' => 'qt_TQCanvasView*' , -'TQChain*' => 'qt_TQChain*' , -'TQChar&' => 'qt_TQChar*' , -'TQChar' => 'qt_TQChar*' , -'TQChar*' => 'qt_TQChar*' , +'TQCOORD*' => 'short*', +'TQCString&' => 'qt_QCString*' , +'TQCString' => 'qt_QCString*' , +'TQCString*' => 'qt_QCString*' , +'TQCStringLess*' => 'qt_QCStringLess*' , +'QCStringList' => 'kde_QCStringList*' , +'TQCache*' => 'qt_QCache*', +'TQCacheIterator*' => 'qt_QCacheIterator*', +'TQCanvas*' => 'qt_QCanvas*' , +'TQCanvasEllipse*' => 'qt_QCanvasEllipse*', +'TQCanvasItem*' => 'qt_QCanvasItem*' , +'TQCanvasItemList' => 'qt_QCanvasItemList*' , +'TQCanvasItemList*' => 'qt_QCanvasItemList*', +'TQCanvasLine*' => 'qt_QCanvasLine*', +'TQCanvasPixmap*' => 'qt_QCanvasPixmap*' , +'TQCanvasPixmapArray*' => 'qt_QCanvasPixmapArray*' , +'TQCanvasPolygon*' => 'qt_QCanvasPolygon*', +'TQCanvasPolygonalItem*' => 'qt_QCanvasPolygonalItem*', +'TQCanvasRectangle*' => 'qt_QCanvasRectangle*', +'TQCanvasSpline*' => 'qt_QCanvasSpline*', +'TQCanvasSprite*' => 'qt_QCanvasSprite*', +'TQCanvasText*' => 'qt_QCanvasText*', +'TQCanvasView*' => 'qt_QCanvasView*' , +'TQChain*' => 'qt_QChain*' , 'TQChar::Category' => 'int' , 'TQChar::Decomposition' => 'int' , 'TQChar::Direction' => 'int' , 'TQChar::Joining' => 'int' , -'TQCharRef&' => 'qt_TQCharRef*' , -'TQCharRef' => 'qt_TQCharRef*' , -'TQCharRef*' => 'qt_TQCharRef*', -'TQCheckBox*' => 'qt_TQCheckBox*', -'TQCheckListItem*' => 'qt_TQCheckListItem *', -'TQCheckTableItem*' => 'qt_TQCheckTableItem*', -'TQChildEvent*' => 'qt_TQChildEvent*' , -'TQClassInfo*' => 'qt_TQClassInfo*' , -'TQCleanupHandler*' => 'qt_TQCleanupHandler*', -'TQClipboard*' => 'qt_TQClipboard *', -'TQCloseEvent*' => 'qt_TQCloseEvent*' , -'TQCollection&' => 'qt_TQCollection*' , -'TQCollection*' => 'qt_TQCollection*', -'TQCollection::Item&' => 'void *' , -'TQCollection::Item' => 'void *' , -'TQColor &' => 'qt_TQColor *', -'TQColor&' => 'qt_TQColor *', +'TQCharRef&' => 'qt_QCharRef*' , +'TQCharRef' => 'qt_QCharRef*' , +'TQCharRef*' => 'qt_QCharRef*', +'TQCheckBox*' => 'qt_QCheckBox*', +'TQCheckListItem*' => 'qt_QCheckListItem*', +'TQCheckTableItem*' => 'qt_QCheckTableItem*', +'TQChildEvent*' => 'qt_QChildEvent*' , +'TQClassInfo*' => 'qt_QClassInfo*' , +'TQCleanupHandler*' => 'qt_QCleanupHandler*', +'TQClipboard*' => 'qt_QClipboard*', +'TQCloseEvent*' => 'qt_QCloseEvent*' , +'TQCollection&' => 'qt_QCollection*' , +'TQCollection*' => 'qt_QCollection*', +'TQCollection::Item&' => 'void*' , +'TQCollection::Item' => 'void*' , +'TQColor &' => 'qt_QColor*', +'TQColor&' => 'qt_QColor*', 'TQColor&fillColor::white' => 'int' , 'TQColor&linkColor::blue' => 'int' , -'TQColor' => 'qt_TQColor *', -'TQColor*' => 'qt_TQColor*' , -'TQColorDialog*' => 'qt_TQColorDialog*', -'TQColorDrag*' => 'qt_TQColorDrag*', -'TQColorGroup&' => 'qt_TQColorGroup *', -'TQColorGroup' => 'qt_TQColorGroup*' , -'TQColorGroup*' => 'qt_TQColorGroup*' , +'TQColor' => 'qt_QColor*', +'TQColor*' => 'qt_QColor*' , +'TQColorDialog*' => 'qt_QColorDialog*', +'TQColorDrag*' => 'qt_QColorDrag*', +'TQColorGroup&' => 'qt_QColorGroup*', +'TQColorGroup' => 'qt_QColorGroup*' , +'TQColorGroup*' => 'qt_QColorGroup*' , 'TQColorGroup::ColorRole' => 'int' , -'TQComboBox*' => 'qt_TQComboBox*' , +'TQComboBox*' => 'qt_QComboBox*' , 'TQComboBox::Policy' => 'int' , 'TQComboBox::Policypolicy::AtBottom' => 'int' , -'TQComboTableItem*' => 'qt_TQComboTableItem*', -'TQCommonStyle*' => 'qt_TQCommonStyle*', -'TQCompactStyle*' => 'qt_TQCompactStyle*', -'TQComponentFactory*' => 'qt_TQComponentFactory*', -'TQComponentFactoryInterface*' => 'qt_TQComponentFactoryInterface*', -'TQComponentInterface*' => 'qt_TQComponentInterface*', -'TQComponentRegistration*' => 'qt_TQComponentRegistration*', -'TQComponentServerInterface*' => 'qt_TQComponentServerInterface*', -'TQConfigDB*' => 'qt_TQConfigDB*' , -'TQConfigDB*' => 'qt_TQConfigDB*' , -'TQConnection*' => 'qt_TQConnection*', -'TQConnectionList&' => 'qt_TQConnectionList*' , -'TQConnectionList*' => 'qt_TQConnectionList*' , -'TQConnectionListIt&' => 'qt_TQConnectionListIt*' , -'TQConnectionListIt*' => 'qt_TQConnectionListIt*', -'TQConstString' => 'qt_TQConstString*', -'TQConstString*' => 'qt_TQConstString*', -'TQContextMenuEvent*' => 'qt_TQContextMenuEvent*', -'TQCursor&' => 'qt_TQCursor *', -'TQCursor' => 'qt_TQCursor*' , -'TQCursor*' => 'qt_TQCursor *', -'TQCustomEvent*' => 'qt_TQCustomEvent*' , -'TQCustomMenuItem*' => 'qt_TQCustomMenuItem*' , +'TQComboTableItem*' => 'qt_QComboTableItem*', +'TQCommonStyle*' => 'qt_QCommonStyle*', +'TQCompactStyle*' => 'qt_QCompactStyle*', +'TQComponentFactory*' => 'qt_QComponentFactory*', +'TQComponentFactoryInterface*' => 'qt_QComponentFactoryInterface*', +'TQComponentInterface*' => 'qt_QComponentInterface*', +'TQComponentRegistration*' => 'qt_QComponentRegistration*', +'TQComponentServerInterface*' => 'qt_QComponentServerInterface*', +'TQConfigDB*' => 'qt_QConfigDB*' , +'TQConfigDB*' => 'qt_QConfigDB*' , +'TQConnection*' => 'qt_QConnection*', +'TQConnectionList&' => 'qt_QConnectionList*' , +'TQConnectionList*' => 'qt_QConnectionList*' , +'TQConnectionListIt&' => 'qt_QConnectionListIt*' , +'TQConnectionListIt*' => 'qt_QConnectionListIt*', +'TQConstString' => 'qt_QConstString*', +'TQConstString*' => 'qt_QConstString*', +'TQContextMenuEvent*' => 'qt_QContextMenuEvent*', +'TQCursor&' => 'qt_QCursor*', +'TQCursor' => 'qt_QCursor*' , +'TQCursor*' => 'qt_QCursor*', +'TQCustomEvent*' => 'qt_QCustomEvent*' , +'TQCustomMenuItem*' => 'qt_QCustomMenuItem*' , 'TQDOM_NodeListPrivate*' => 'void*' , 'TQDOM_NodePrivate*' => 'void*' , -'TQDataBrowser*' => 'qt_TQDataBrowser*', -'TQDataPump*' => 'qt_TQDataPump*', -'TQDataSink*' => 'qt_TQDataSink*' , -'TQDataSource*' => 'qt_TQDataSource*' , -'TQDataStream&' => 'qt_TQDataStream *', -'TQDataStream*' => 'qt_TQDataStream*' , -'TQDataTable*' => 'qt_TQDataTable*', -'TQDataView*' => 'qt_TQDataView*', -'TQDate &' => 'qt_TQDate *', -'TQDate date()' => 'qt_TQDate*', -'TQDate&' => 'qt_TQDate *', -'TQDate' => 'qt_TQDate *', -'TQDate*' => 'qt_TQDate*', -'TQDateEdit*' => 'qt_TQDateEdit*', -'TQDateTime&' => 'qt_TQDateTime *', -'TQDateTime' => 'qt_TQDateTime *', -'TQDateTime*' => 'qt_TQDateTime*' , -'TQDateTimeEdit*' => 'qt_TQDateTimeEdit*', -'TQDateTimeEditBase*' => 'qt_TQDateTimeEditBase*', -'TQDesktopWidget*' => 'qt_TQDesktopWidget*', -'TQDial*' => 'qt_TQDial*', -'TQDialog*' => 'qt_TQDialog*', -'TQDict*' => 'qt_TQDict*', -'TQDictIterator*' => 'qt_TQDictIterator*', -'TQDir&' => 'qt_TQDir *', -'TQDir' => 'qt_TQDir *', -'TQDir*' => 'qt_TQDir *', +'TQDataBrowser*' => 'qt_QDataBrowser*', +'TQDataPump*' => 'qt_QDataPump*', +'TQDataSink*' => 'qt_QDataSink*' , +'TQDataSource*' => 'qt_QDataSource*' , +'TQDataStream&' => 'qt_QDataStream*', +'TQDataStream*' => 'qt_QDataStream*' , +'TQDataTable*' => 'qt_QDataTable*', +'TQDataView*' => 'qt_QDataView*', +'TQDate &' => 'qt_QDate*', +'TQDate date()' => 'qt_QDate*', +'TQDate&' => 'qt_QDate*', +'TQDate' => 'qt_QDate*', +'TQDate*' => 'qt_QDate*', +'TQDateEdit*' => 'qt_QDateEdit*', +'TQDateTime&' => 'qt_QDateTime*', +'TQDateTime' => 'qt_QDateTime*', +'TQDateTime*' => 'qt_QDateTime*' , +'TQDateTimeEdit*' => 'qt_QDateTimeEdit*', +'TQDateTimeEditBase*' => 'qt_QDateTimeEditBase*', +'TQDesktopWidget*' => 'qt_QDesktopWidget*', +'TQDial*' => 'qt_QDial*', +'TQDialog*' => 'qt_QDialog*', +'TQDict*' => 'qt_QDict*', +'TQDictIterator*' => 'qt_QDictIterator*', +'TQDir&' => 'qt_QDir*', +'TQDir' => 'qt_QDir*', +'TQDir*' => 'qt_QDir*', 'TQDir::SortSpec&' => 'int' , 'TQDir::SortSpec' => 'int' , -'TQDirSortItem*' => 'qt_TQDirSortItem*', -'TQDiskFont*' => 'qt_TQDiskFont*', -'TQDispatchInterface*' => 'qt_TQDispatchInterface*', -'TQDns*' => 'qt_TQDns*', -'TQDnsSocket*' => 'qt_TQDnsSocket*', -'TQDockArea*' => 'qt_TQDockArea*', -'TQDockAreaLayout*' => 'qt_TQDockAreaLayout*', -'TQDockWindow*' => 'qt_TQDockWindow*', -'TQDomAttr&' => 'qt_TQDomAttr*' , -'TQDomAttr' => 'qt_TQDomAttr*' , -'TQDomAttr*' => 'qt_TQDomAttr*', -'TQDomCDATASection&' => 'qt_TQDomCDATASection*' , -'TQDomCDATASection' => 'qt_TQDomCDATASection*' , -'TQDomCDATASection*' => 'qt_TQDomCDATASection*', -'TQDomCharacterData&' => 'qt_TQDomCharacterData*' , -'TQDomCharacterData' => 'qt_TQDomCharacterData*' , -'TQDomCharacterData*' => 'qt_TQDomCharacterData*', -'TQDomComment&' => 'qt_TQDomComment*' , -'TQDomComment' => 'qt_TQDomComment*' , -'TQDomComment*' => 'qt_TQDomComment*', -'TQDomDocument&' => 'qt_TQDomDocument*' , -'TQDomDocument' => 'qt_TQDomDocument*' , -'TQDomDocument*' => 'qt_TQDomDocument*', -'TQDomDocumentFragment&' => 'qt_TQDomDocumentFragment*' , -'TQDomDocumentFragment' => 'qt_TQDomDocumentFragment*' , -'TQDomDocumentFragment*' => 'qt_TQDomDocumentFragment*', -'TQDomDocumentType&' => 'qt_TQDomDocumentType*' , -'TQDomDocumentType' => 'qt_TQDomDocumentType*' , -'TQDomDocumentType*' => 'qt_TQDomDocumentType*', -'TQDomElement&' => 'qt_TQDomElement*' , -'TQDomElement' => 'qt_TQDomElement*' , -'TQDomElement*' => 'qt_TQDomElement*', -'TQDomEntity&' => 'qt_TQDomEntity*' , -'TQDomEntity' => 'qt_TQDomEntity*' , -'TQDomEntity*' => 'qt_TQDomEntity*', -'TQDomEntityReference&' => 'qt_TQDomEntityReference*' , -'TQDomEntityReference' => 'qt_TQDomEntityReference*' , -'TQDomEntityReference*' => 'qt_TQDomEntityReference*', -'TQDomImplementation&' => 'qt_TQDomImplementation*' , -'TQDomImplementation' => 'qt_TQDomImplementation*' , -'TQDomImplementation*' => 'qt_TQDomImplementation*', -'TQDomNamedNodeMap&' => 'qt_TQDomNamedNodeMap*' , -'TQDomNamedNodeMap' => 'qt_TQDomNamedNodeMap*' , -'TQDomNamedNodeMap*' => 'qt_TQDomNamedNodeMap*', -'TQDomNode&' => 'qt_TQDomNode*' , -'TQDomNode' => 'qt_TQDomNode*' , -'TQDomNode*' => 'qt_TQDomNode*', +'TQDirSortItem*' => 'qt_QDirSortItem*', +'TQDiskFont*' => 'qt_QDiskFont*', +'TQDispatchInterface*' => 'qt_QDispatchInterface*', +'TQDns*' => 'qt_QDns*', +'TQDnsSocket*' => 'qt_QDnsSocket*', +'TQDockArea*' => 'qt_QDockArea*', +'TQDockAreaLayout*' => 'qt_QDockAreaLayout*', +'TQDockWindow*' => 'qt_QDockWindow*', +'TQDomAttr&' => 'qt_QDomAttr*' , +'TQDomAttr' => 'qt_QDomAttr*' , +'TQDomAttr*' => 'qt_QDomAttr*', +'TQDomCDATASection&' => 'qt_QDomCDATASection*' , +'TQDomCDATASection' => 'qt_QDomCDATASection*' , +'TQDomCDATASection*' => 'qt_QDomCDATASection*', +'TQDomCharacterData&' => 'qt_QDomCharacterData*' , +'TQDomCharacterData' => 'qt_QDomCharacterData*' , +'TQDomCharacterData*' => 'qt_QDomCharacterData*', +'TQDomComment&' => 'qt_QDomComment*' , +'TQDomComment' => 'qt_QDomComment*' , +'TQDomComment*' => 'qt_QDomComment*', +'TQDomDocument&' => 'qt_QDomDocument*' , +'TQDomDocument' => 'qt_QDomDocument*' , +'TQDomDocument*' => 'qt_QDomDocument*', +'TQDomDocumentFragment&' => 'qt_QDomDocumentFragment*' , +'TQDomDocumentFragment' => 'qt_QDomDocumentFragment*' , +'TQDomDocumentFragment*' => 'qt_QDomDocumentFragment*', +'TQDomDocumentType&' => 'qt_QDomDocumentType*' , +'TQDomDocumentType' => 'qt_QDomDocumentType*' , +'TQDomDocumentType*' => 'qt_QDomDocumentType*', +'TQDomElement&' => 'qt_QDomElement*' , +'TQDomElement' => 'qt_QDomElement*' , +'TQDomElement*' => 'qt_QDomElement*', +'TQDomEntity&' => 'qt_QDomEntity*' , +'TQDomEntity' => 'qt_QDomEntity*' , +'TQDomEntity*' => 'qt_QDomEntity*', +'TQDomEntityReference&' => 'qt_QDomEntityReference*' , +'TQDomEntityReference' => 'qt_QDomEntityReference*' , +'TQDomEntityReference*' => 'qt_QDomEntityReference*', +'TQDomImplementation&' => 'qt_QDomImplementation*' , +'TQDomImplementation' => 'qt_QDomImplementation*' , +'TQDomImplementation*' => 'qt_QDomImplementation*', +'TQDomNamedNodeMap&' => 'qt_QDomNamedNodeMap*' , +'TQDomNamedNodeMap' => 'qt_QDomNamedNodeMap*' , +'TQDomNamedNodeMap*' => 'qt_QDomNamedNodeMap*', +'TQDomNode&' => 'qt_QDomNode*' , +'TQDomNode' => 'qt_QDomNode*' , +'TQDomNode*' => 'qt_QDomNode*', 'TQDomNode::NodeType' => 'int', -'TQDomNodeList&' => 'qt_TQDomNodeList*' , -'TQDomNodeList' => 'qt_TQDomNodeList*' , -'TQDomNodeList*' => 'qt_TQDomNodeList*', -'TQDomNodePrivate*' => 'qt_TQDomNodePrivate*', -'TQDomNotation&' => 'qt_TQDomNotation*' , -'TQDomNotation' => 'qt_TQDomNotation*' , -'TQDomNotation*' => 'qt_TQDomNotation*', -'TQDomProcessingInstruction&' => 'qt_TQDomProcessingInstruction*' , -'TQDomProcessingInstruction' => 'qt_TQDomProcessingInstruction*' , -'TQDomProcessingInstruction*' => 'qt_TQDomProcessingInstruction*', -'TQDomText&' => 'qt_TQDomText*' , -'TQDomText' => 'qt_TQDomText*' , -'TQDomText*' => 'qt_TQDomText*', -'TQDoubleValidator*' => 'qt_TQDoubleValidator*', -'TQDragEnterEvent*' => 'qt_TQDragEnterEvent*' , -'TQDragLeaveEvent*' => 'qt_TQDragLeaveEvent*' , -'TQDragManager*' => 'qt_TQDragManager*', -'TQDragMoveEvent*' => 'qt_TQDragMoveEvent*' , -'TQDragObject*' => 'qt_TQDragObject*' , -'TQDragResponseEvent*' => 'qt_TQDragResponseEvent*', -'TQDropEvent*' => 'qt_TQDropEvent*' , -'TQDropSite*' => 'qt_TQDropSite*', -'TQEditorFactory*' => 'qt_TQEditorFactory*', -'TQErrorMessage*' => 'qt_TQErrorMessage*', -'TQEucJpCodec*' => 'qt_TQEucJpCodec*', -'TQEucKrCodec*' => 'qt_TQEucKrCodec*', -'TQEvent*' => 'qt_TQEvent *', +'TQDomNodeList&' => 'qt_QDomNodeList*' , +'TQDomNodeList' => 'qt_QDomNodeList*' , +'TQDomNodeList*' => 'qt_QDomNodeList*', +'TQDomNodePrivate*' => 'qt_QDomNodePrivate*', +'TQDomNotation&' => 'qt_QDomNotation*' , +'TQDomNotation' => 'qt_QDomNotation*' , +'TQDomNotation*' => 'qt_QDomNotation*', +'TQDomProcessingInstruction&' => 'qt_QDomProcessingInstruction*' , +'TQDomProcessingInstruction' => 'qt_QDomProcessingInstruction*' , +'TQDomProcessingInstruction*' => 'qt_QDomProcessingInstruction*', +'TQDomText&' => 'qt_QDomText*' , +'TQDomText' => 'qt_QDomText*' , +'TQDomText*' => 'qt_QDomText*', +'TQDoubleValidator*' => 'qt_QDoubleValidator*', +'TQDragEnterEvent*' => 'qt_QDragEnterEvent*' , +'TQDragLeaveEvent*' => 'qt_QDragLeaveEvent*' , +'TQDragManager*' => 'qt_QDragManager*', +'TQDragMoveEvent*' => 'qt_QDragMoveEvent*' , +'TQDragObject*' => 'qt_QDragObject*' , +'TQDragResponseEvent*' => 'qt_QDragResponseEvent*', +'TQDropEvent*' => 'qt_QDropEvent*' , +'TQDropSite*' => 'qt_QDropSite*', +'TQEditorFactory*' => 'qt_QEditorFactory*', +'TQErrorMessage*' => 'qt_QErrorMessage*', +'TQEucJpCodec*' => 'qt_QEucJpCodec*', +'TQEucKrCodec*' => 'qt_QEucKrCodec*', +'TQEvent*' => 'qt_QEvent*', 'TQEventLoop::ProcessEventsFlags' => 'uint', -'TQFeatureListInterface*' => 'qt_TQFeatureListInterface*', -'TQFile&' => 'qt_TQFile *', -'TQFile*' => 'qt_TQFile*' , -'TQFileDialog*' => 'qt_TQFileDialog*', -'TQFileIconProvider*' => 'qt_TQFileIconProvider*' , -'TQFileInfo&' => 'qt_TQFileInfo *', -'TQFileInfo*' => 'qt_TQFileInfo*', -'TQFileInfoList*' => 'qt_TQFileInfoList*' , -'TQFilePreview*' => 'qt_TQFilePreview*' , -'TQFocusData*' => 'qt_TQFocusData*' , -'TQFocusEvent*' => 'qt_TQFocusEvent*' , -'TQFont&' => 'qt_TQFont *', -'TQFont' => 'qt_TQFont *', -'TQFont*' => 'qt_TQFont *', +'TQFeatureListInterface*' => 'qt_QFeatureListInterface*', +'TQFile&' => 'qt_QFile*', +'TQFile*' => 'qt_QFile*' , +'TQFileDialog*' => 'qt_QFileDialog*', +'TQFileIconProvider*' => 'qt_QFileIconProvider*' , +'TQFileInfo&' => 'qt_QFileInfo*', +'TQFileInfo*' => 'qt_QFileInfo*', +'TQFileInfoList*' => 'qt_QFileInfoList*' , +'TQFilePreview*' => 'qt_QFilePreview*' , +'TQFocusData*' => 'qt_QFocusData*' , +'TQFocusEvent*' => 'qt_QFocusEvent*' , +'TQFont&' => 'qt_QFont*', +'TQFont' => 'qt_QFont*', +'TQFont*' => 'qt_QFont*', 'TQFont::CharSet' => 'int', 'TQFont::CharSetcharset::Unicode' => 'int' , 'TQFont::StyleHint' => 'int', -'TQFontData&' => 'qt_TQFontData*' , -'TQFontDatabase*' => 'qt_TQFontDatabase*', -'TQFontDialog*' => 'qt_TQFontDialog*', -'TQFontInfo&' => 'qt_TQFontInfo *', -'TQFontInfo' => 'qt_TQFontInfo *', -'TQFontInfo*' => 'qt_TQFontInfo*', -'TQFontMetrics&' => 'qt_TQFontMetrics *', -'TQFontMetrics' => 'qt_TQFontMetrics *', -'TQFontMetrics*' => 'qt_TQFontMetrics*', -'TQFrame*' => 'qt_TQFrame*' , -'TQFtp*' => 'qt_TQFtp*', -'TQGArray&' => 'qt_TQGArray*' , -'TQGArray*' => 'qt_TQGArray*', -'TQGCache&' => 'qt_TQGCache*' , -'TQGCache*' => 'qt_TQGCache*', -'TQGCacheIterator&' => 'qt_TQGCacheIterator*' , -'TQGCacheIterator*' => 'qt_TQGCacheIterator*', -'TQGDict&' => 'qt_TQGDict*' , -'TQGDict*' => 'qt_TQGDict*', -'TQGDictIterator&' => 'qt_TQGDictIterator*' , -'TQGDictIterator*' => 'qt_TQGDictIterator*', -'TQGL*' => 'qt_TQGL*', -'TQGLColormap&' => 'qt_TQGLColormap*', -'TQGLColormap*' => 'qt_TQGLColormap*', -'TQGLContext*' => 'qt_TQGLContext*' , -'TQGLFormat&' => 'qt_TQGLFormat*' , -'TQGLFormat' => 'qt_TQGLFormat*' , -'TQGLFormat*' => 'qt_TQGLFormat*', -'TQGLWidget*' => 'qt_TQGLWidget*' , -'TQGLayoutIterator*' => 'qt_TQGLayoutIterator*' , -'TQGList&' => 'qt_TQGList*' , -'TQGList*' => 'qt_TQGList*' , -'TQGListIterator&' => 'qt_TQGListIterator*' , -'TQGListIterator*' => 'qt_TQGListIterator*', -'TQGPlugin*' => 'qt_TQGPlugin*', -'TQGPluginManager*' => 'qt_TQGPluginManager*', -'TQGVector&' => 'qt_TQGVector*' , -'TQGVector*' => 'qt_TQGVector*' , -'TQGbkCodec*' => 'qt_TQGbkCodec*', -'TQGfx*' => 'qt_TQGfx*' , -'TQGrid*' => 'qt_TQGrid*' , +'TQFontData&' => 'qt_QFontData*' , +'TQFontDatabase*' => 'qt_QFontDatabase*', +'TQFontDialog*' => 'qt_QFontDialog*', +'TQFontInfo&' => 'qt_QFontInfo*', +'TQFontInfo' => 'qt_QFontInfo*', +'TQFontInfo*' => 'qt_QFontInfo*', +'TQFontMetrics&' => 'qt_QFontMetrics*', +'TQFontMetrics' => 'qt_QFontMetrics*', +'TQFontMetrics*' => 'qt_QFontMetrics*', +'TQFrame*' => 'qt_QFrame*' , +'TQFtp*' => 'qt_QFtp*', +'TQGArray&' => 'qt_QGArray*' , +'TQGArray*' => 'qt_QGArray*', +'TQGCache&' => 'qt_QGCache*' , +'TQGCache*' => 'qt_QGCache*', +'TQGCacheIterator&' => 'qt_QGCacheIterator*' , +'TQGCacheIterator*' => 'qt_QGCacheIterator*', +'TQGDict&' => 'qt_QGDict*' , +'TQGDict*' => 'qt_QGDict*', +'TQGDictIterator&' => 'qt_QGDictIterator*' , +'TQGDictIterator*' => 'qt_QGDictIterator*', +'TQGL*' => 'qt_QGL*', +'TQGLColormap&' => 'qt_QGLColormap*', +'TQGLColormap*' => 'qt_QGLColormap*', +'TQGLContext*' => 'qt_QGLContext*' , +'TQGLFormat&' => 'qt_QGLFormat*' , +'TQGLFormat' => 'qt_QGLFormat*' , +'TQGLFormat*' => 'qt_QGLFormat*', +'TQGLWidget*' => 'qt_QGLWidget*' , +'TQGLayoutIterator*' => 'qt_QGLayoutIterator*' , +'TQGListIterator&' => 'qt_QGListIterator*' , +'TQGListIterator*' => 'qt_QGListIterator*', +'TQGPlugin*' => 'qt_QGPlugin*', +'TQGPluginManager*' => 'qt_QGPluginManager*', +'TQGbkCodec*' => 'qt_QGbkCodec*', +'TQGfx*' => 'qt_QGfx*' , +'TQGrid*' => 'qt_QGrid*' , 'TQGrid::Direction' => 'int' , -'TQGridLayout*' => 'qt_TQGridLayout*', -'TQGridView*' => 'qt_TQGridView*', -'TQGroupBox*' => 'qt_TQGroupBox*', -'TQGuardedPtr*' => 'qt_TQGuardedPtr*', -'TQGuardedPtrPrivate*' => 'qt_TQGuardedPtrPrivate*', -'TQHBox*' => 'qt_TQHBox*' , -'TQHBoxLayout*' => 'qt_TQHBoxLayout*' , -'TQHButtonGroup*' => 'qt_TQHButtonGroup*', -'TQHGroupBox*' => 'qt_TQHGroupBox*', -'TQHeader*' => 'qt_TQHeader *', -'TQHebrewCodec*' => 'qt_TQHebrewCodec*', -'TQHideEvent*' => 'qt_TQHideEvent*' , -'TQHostAddress&' => 'qt_TQHostAddress*' , -'TQHostAddress' => 'qt_TQHostAddress*' , -'TQHostAddress*' => 'qt_TQHostAddress*' , -'TQHttp*' => 'qt_TQHttp*', -'TQIMEvent*' => 'qt_TQIMEvent*', -'TQIODevice*' => 'qt_TQIODevice *', +'TQGridLayout*' => 'qt_QGridLayout*', +'TQGridView*' => 'qt_QGridView*', +'TQGroupBox*' => 'qt_QGroupBox*', +'TQGuardedPtr*' => 'qt_QGuardedPtr*', +'TQGuardedPtrPrivate*' => 'qt_QGuardedPtrPrivate*', +'TQHBox*' => 'qt_QHBox*' , +'TQHBoxLayout*' => 'qt_QHBoxLayout*' , +'TQHButtonGroup*' => 'qt_QHButtonGroup*', +'TQHGroupBox*' => 'qt_QHGroupBox*', +'TQHeader*' => 'qt_QHeader*', +'TQHebrewCodec*' => 'qt_QHebrewCodec*', +'TQHideEvent*' => 'qt_QHideEvent*' , +'TQHostAddress&' => 'qt_QHostAddress*' , +'TQHostAddress' => 'qt_QHostAddress*' , +'TQHostAddress*' => 'qt_QHostAddress*' , +'TQHttp*' => 'qt_QHttp*', +'TQIMEvent*' => 'qt_QIMEvent*', +'TQIODevice*' => 'qt_QIODevice*', 'TQIODevice::Offset' => 'int', -'TQIODeviceSource*' => 'qt_TQIODeviceSource*', -'TQIOManager*' => 'qt_TQIOManager*', -'TQIOWatch*' => 'qt_TQIOWatch*', -'TQIconDrag*' => 'qt_TQIconDrag*', -'TQIconDragItem&' => 'qt_TQIconDragItem*' , -'TQIconDragItem*' => 'qt_TQIconDragItem*', -'TQIconSet&' => 'qt_TQIconSet*' , -'TQIconSet' => 'qt_TQIconSet*' , -'TQIconSet*' => 'qt_TQIconSet*' , -'TQIconView*' => 'qt_TQIconView*' , -'TQIconViewItem*' => 'qt_TQIconViewItem*' , -'TQImage&' => 'qt_TQImage *', -'TQImage' => 'qt_TQImage *', -'TQImage*' => 'qt_TQImage*' , -'TQImageConsumer*' => 'qt_TQImageConsumer*' , -'TQImageData*' => 'qt_TQImageData*', -'TQImageDecoder*' => 'qt_TQImageDecoder*', -'TQImageDrag*' => 'qt_TQImageDrag*', -'TQImageFormat*' => 'qt_TQImageFormat*' , -'TQImageFormatInterface*' => 'qt_TQImageFormatInterface*', -'TQImageFormatPlugin*' => 'qt_TQImageFormatPlugin*', -'TQImageFormatType*' => 'qt_TQImageFormatType*' , -'TQImageIO*' => 'qt_TQImageIO*', -'TQImageTextKeyLang&' => 'qt_TQImageTextKeyLang*' , -'TQImageTextKeyLang*' => 'qt_TQImageTextKeyLang*', -'TQInputDialog*' => 'qt_TQInputDialog*', -'TQIntBucket*' => 'qt_TQIntBucket*', -'TQIntCache*' => 'qt_TQIntCache*', -'TQIntCacheIterator*' => 'qt_TQIntCacheIterator*', -'TQIntDict*' => 'qt_TQIntDict*', -'TQIntDictIterator*' => 'qt_TQIntDictIterator*', -'TQIntValidator*' => 'qt_TQIntValidator*', -'TQInterfaceListInterface*' => 'qt_TQInterfaceListInterface*', -'TQInterfacePtr*' => 'qt_TQInterfacePtr*', -'TQInterlaceStyle*' => 'qt_TQInterlaceStyle*', -'TQInternal*' => 'qt_TQInternal*', -'TQJisCodec*' => 'qt_TQJisCodec*', -'TQJpUnicodeConv*' => 'qt_TQJpUnicodeConv*' , -'TQKeyEvent*' => 'qt_TQKeyEvent*' , -'TQKeySequence&' => 'qt_TQKeySequence*', -'TQKeySequence' => 'qt_TQKeySequence*', -'TQKeySequence*' => 'qt_TQKeySequence*', -'TQKoi8Codec*' => 'qt_TQKoi8Codec*', -'TQLCDNumber*' => 'qt_TQLCDNumber*', -'TQLNode*' => 'qt_TQLNode*' , -'TQLabel*' => 'qt_TQLabel *', -'TQLayout*' => 'qt_TQLayout *', -'TQLayoutItem*' => 'qt_TQLayoutItem*' , -'TQLayoutIterator&' => 'qt_TQLayoutIterator*' , -'TQLayoutIterator' => 'qt_TQLayoutIterator*' , -'TQLayoutIterator*' => 'qt_TQLayoutIterator*', -'TQLibrary*' => 'qt_TQLibrary*', +'TQIODeviceSource*' => 'qt_QIODeviceSource*', +'TQIOManager*' => 'qt_QIOManager*', +'TQIOWatch*' => 'qt_QIOWatch*', +'TQIconDrag*' => 'qt_QIconDrag*', +'TQIconDragItem&' => 'qt_QIconDragItem*' , +'TQIconDragItem*' => 'qt_QIconDragItem*', +'TQIconSet&' => 'qt_QIconSet*' , +'TQIconSet' => 'qt_QIconSet*' , +'TQIconSet*' => 'qt_QIconSet*' , +'TQIconView*' => 'qt_QIconView*' , +'TQIconViewItem*' => 'qt_QIconViewItem*' , +'TQImage&' => 'qt_QImage*', +'TQImage' => 'qt_QImage*', +'TQImage*' => 'qt_QImage*' , +'TQImageConsumer*' => 'qt_QImageConsumer*' , +'TQImageData*' => 'qt_QImageData*', +'TQImageDecoder*' => 'qt_QImageDecoder*', +'TQImageDrag*' => 'qt_QImageDrag*', +'TQImageFormat*' => 'qt_QImageFormat*' , +'TQImageFormatInterface*' => 'qt_QImageFormatInterface*', +'TQImageFormatPlugin*' => 'qt_QImageFormatPlugin*', +'TQImageFormatType*' => 'qt_QImageFormatType*' , +'TQImageIO*' => 'qt_QImageIO*', +'TQImageTextKeyLang&' => 'qt_QImageTextKeyLang*' , +'TQImageTextKeyLang*' => 'qt_QImageTextKeyLang*', +'TQInputDialog*' => 'qt_QInputDialog*', +'TQIntBucket*' => 'qt_QIntBucket*', +'TQIntCache*' => 'qt_QIntCache*', +'TQIntCacheIterator*' => 'qt_QIntCacheIterator*', +'TQIntDict*' => 'qt_QIntDict*', +'TQIntDictIterator*' => 'qt_QIntDictIterator*', +'TQIntValidator*' => 'qt_QIntValidator*', +'TQInterfaceListInterface*' => 'qt_QInterfaceListInterface*', +'TQInterfacePtr*' => 'qt_QInterfacePtr*', +'TQInterlaceStyle*' => 'qt_QInterlaceStyle*', +'TQInternal*' => 'qt_QInternal*', +'TQJisCodec*' => 'qt_QJisCodec*', +'TQJpUnicodeConv*' => 'qt_QJpUnicodeConv*' , +'TQKeyEvent*' => 'qt_QKeyEvent*' , +'TQKeySequence&' => 'qt_QKeySequence*', +'TQKeySequence' => 'qt_QKeySequence*', +'TQKeySequence*' => 'qt_QKeySequence*', +'TQKoi8Codec*' => 'qt_QKoi8Codec*', +'TQLCDNumber*' => 'qt_QLCDNumber*', +'TQLNode*' => 'qt_QLNode*' , +'TQLabel*' => 'qt_QLabel*', +'TQLayout*' => 'qt_QLayout*', +'TQLayoutItem*' => 'qt_QLayoutItem*' , +'TQLayoutIterator&' => 'qt_QLayoutIterator*' , +'TQLayoutIterator' => 'qt_QLayoutIterator*' , +'TQLayoutIterator*' => 'qt_QLayoutIterator*', +'TQLibrary*' => 'qt_QLibrary*', 'TQLibrary::Policy' => 'int', -'TQLibraryInterface*' => 'qt_TQLibraryInterface*', -'TQLineEdit*' => 'qt_TQLineEdit*' , +'TQLibraryInterface*' => 'qt_QLibraryInterface*', +'TQLineEdit*' => 'qt_QLineEdit*' , 'TQLineEdit::EchoMode' => 'int' , -'TQList*' => 'qt_TQList*', -'TQListBox*' => 'qt_TQListBox *', -'TQListBoxItem*' => 'qt_TQListBoxItem *', -'TQListBoxPixmap*' => 'qt_TQListBoxPixmap*', -'TQListBoxText*' => 'qt_TQListBoxText*', -'TQListIterator*' => 'qt_TQListIterator*', -'TQListView*' => 'qt_TQListView *', -'TQListViewItem*&' => 'qt_TQListViewItem*', -'TQListViewItem*' => 'qt_TQListViewItem *', -'TQListViewItemIterator&' => 'qt_TQListViewItemIterator*' , -'TQListViewItemIterator' => 'qt_TQListViewItemIterator*' , -'TQListViewItemIterator*' => 'qt_TQListViewItemIterator*', -'TQLocalFs*' => 'qt_TQLocalFs*', -'TQMCPI*' => 'qt_TQMCPI*', -'TQMSG*' => 'TQMSG*' , -'TQMainWindow*' => 'qt_TQMainWindow*' , +'TQList*' => 'qt_QList*', +'TQListBox*' => 'qt_QListBox*', +'TQListBoxItem*' => 'qt_QListBoxItem*', +'TQListBoxPixmap*' => 'qt_QListBoxPixmap*', +'TQListBoxText*' => 'qt_QListBoxText*', +'TQListIterator*' => 'qt_QListIterator*', +'TQListView*' => 'qt_QListView*', +'TQListViewItem*&' => 'qt_QListViewItem*', +'TQListViewItem*' => 'qt_QListViewItem*', +'TQListViewItemIterator&' => 'qt_QListViewItemIterator*' , +'TQListViewItemIterator' => 'qt_QListViewItemIterator*' , +'TQListViewItemIterator*' => 'qt_QListViewItemIterator*', +'TQLocalFs*' => 'qt_QLocalFs*', +'TQMCPI*' => 'qt_QMCPI*', +'TQMainWindow*' => 'qt_QMainWindow*' , 'TQMainWindow::ToolBarDock' => 'int', 'TQMainWindow::ToolBarDock::Top' => 'int' , -'TQMap&' => 'qt_TQMap*' , -'TQMap*' => 'qt_TQMap*', -'TQMapConstIterator*' => 'qt_TQMapConstIterator*', -'TQMapIterator*' => 'qt_TQMapIterator*', -'TQMapNode*' => 'qt_TQMapNode*', -'TQMapNodeBase*&' => 'qt_TQMapNodeBase*' , -'TQMapNodeBase*' => 'qt_TQMapNodeBase*' , -'TQMapPrivate*' => 'qt_TQMapPrivate*', -'TQMapPrivateBase*' => 'qt_TQMapPrivateBase*' , -'TQMemArray*' => 'qt_TQMemArray*', -'TQMember' => 'qt_TQMember*' , -'TQMember*' => 'qt_TQMember*' , -'TQMenuBar*' => 'qt_TQMenuBar *', -'TQMenuData*' => 'qt_TQMenuData*', -'TQMenuData**' => 'qt_TQMenuData**' , -'TQMenuItem*' => 'qt_TQMenuItem *', -'TQMessageBox*' => 'qt_TQMessageBox*', -'TQMetaData*' => 'qt_TQMetaData*' , +'TQMap&' => 'qt_QMap*' , +'TQMap*' => 'qt_QMap*', +'TQMapConstIterator*' => 'qt_QMapConstIterator*', +'TQMapIterator*' => 'qt_QMapIterator*', +'TQMapNode*' => 'qt_QMapNode*', +'TQMapNodeBase*&' => 'qt_QMapNodeBase*' , +'TQMapNodeBase*' => 'qt_QMapNodeBase*' , +'TQMapPrivate*' => 'qt_QMapPrivate*', +'TQMapPrivateBase*' => 'qt_QMapPrivateBase*' , +'TQMemArray*' => 'qt_QMemArray*', +'TQMember' => 'qt_QMember*' , +'TQMember*' => 'qt_QMember*' , +'TQMenuBar*' => 'qt_QMenuBar*', +'TQMenuData*' => 'qt_QMenuData*', +'TQMenuItem*' => 'qt_QMenuItem*', +'TQMessageBox*' => 'qt_QMessageBox*', +'TQMetaData*' => 'qt_QMetaData*' , 'TQMetaData::Access*' => 'int*' , -'TQMetaEnum*' => 'qt_TQMetaEnum*' , +'TQMetaEnum*' => 'qt_QMetaEnum*' , 'TQMetaEnum::Item*' => 'int*' , -'TQMetaObject*&' => 'qt_TQMetaObject*', -'TQMetaObject*' => 'qt_TQMetaObject *', -'TQMetaObjectCleanUp*' => 'qt_TQMetaObjectCleanUp*', -'TQMetaObjectInit*' => 'qt_TQMetaObjectInit*', -'TQMetaProperty*' => 'qt_TQMetaProperty*' , -'TQMimeSource*' => 'qt_TQMimeSource*' , -'TQMimeSourceFactory*' => 'qt_TQMimeSourceFactory*' , -'TQMotifPlusStyle*' => 'qt_TQMotifPlusStyle*', -'TQMotifStyle*' => 'qt_TQMotifStyle*', -'TQMouseEvent*' => 'qt_TQMouseEvent*' , -'TQMoveEvent*' => 'qt_TQMoveEvent*' , -'TQMovie&' => 'qt_TQMovie *', -'TQMovie*' => 'qt_TQMovie *', -'TQMultiLineEdit*' => 'qt_TQMultiLineEdit*', -'TQMultiLineEditRow*' => 'qt_TQMultiLineEditRow*', -'TQMutex*' => 'qt_TQMutex*', -'TQNPInstance*' => 'qt_TQNPInstance*', -'TQNPStream*' => 'qt_TQNPStream*', -'TQNPWidget*' => 'qt_TQNPWidget*', -'TQNPlugin*' => 'qt_TQNPlugin*', -'TQNetworkOperation*' => 'qt_TQNetworkOperation*' , -'TQNetworkProtocol*' => 'qt_TQNetworkProtocol*' , +'TQMetaObject*&' => 'qt_QMetaObject*', +'TQMetaObject*' => 'qt_QMetaObject*', +'TQMetaObjectCleanUp*' => 'qt_QMetaObjectCleanUp*', +'TQMetaObjectInit*' => 'qt_QMetaObjectInit*', +'TQMetaProperty*' => 'qt_QMetaProperty*' , +'TQMimeSource*' => 'qt_QMimeSource*' , +'TQMimeSourceFactory*' => 'qt_QMimeSourceFactory*' , +'TQMotifPlusStyle*' => 'qt_QMotifPlusStyle*', +'TQMotifStyle*' => 'qt_QMotifStyle*', +'TQMouseEvent*' => 'qt_QMouseEvent*' , +'TQMoveEvent*' => 'qt_QMoveEvent*' , +'TQMovie&' => 'qt_QMovie*', +'TQMovie*' => 'qt_QMovie*', +'TQMultiLineEdit*' => 'qt_QMultiLineEdit*', +'TQMultiLineEditRow*' => 'qt_QMultiLineEditRow*', +'TQMutex*' => 'qt_QMutex*', +'TQNPInstance*' => 'qt_QNPInstance*', +'TQNPStream*' => 'qt_QNPStream*', +'TQNPWidget*' => 'qt_QNPWidget*', +'TQNPlugin*' => 'qt_QNPlugin*', +'TQNetworkOperation*' => 'qt_QNetworkOperation*' , +'TQNetworkProtocol*' => 'qt_QNetworkProtocol*' , 'TQNetworkProtocol::Operation' => 'int' , 'TQNetworkProtocol::State' => 'int' , -'TQNetworkProtocolFactory*' => 'qt_TQNetworkProtocolFactory*', -'TQNetworkProtocolFactoryBase*' => 'qt_TQNetworkProtocolFactoryBase*' , -'TQObject*' => 'qt_TQObject *', -'TQObjectCleanupHandler*' => 'qt_TQObjectCleanupHandler*', -'TQObjectDictionary&' => 'qt_TQObjectDictionary*' , -'TQObjectDictionary*' => 'qt_TQObjectDictionary*', -'TQObjectInterface*' => 'qt_TQObjectInterface*', -'TQObjectList&' => 'qt_TQObjectList*' , -'TQObjectList*' => 'qt_TQObjectList*', -'TQObjectListIt&' => 'qt_TQObjectListIt*' , -'TQObjectListIt*' => 'qt_TQObjectListIt*', -'TQPNGImagePacker*' => 'qt_TQPNGImagePacker*', -'TQPNGImageWriter*' => 'qt_TQPNGImageWriter*', -'TQPaintDevice*' => 'qt_TQPaintDevice *', -'TQPaintDeviceMetrics*' => 'qt_TQPaintDeviceMetrics*', -'TQPaintDeviceX11Data*' => 'qt_TQPaintDeviceX11Data*' , -'TQPaintEvent*' => 'qt_TQPaintEvent*' , -'TQPainter&' => 'qt_TQPainter*' , -'TQPainter*' => 'qt_TQPainter *', -'TQPair*' => 'qt_TQPair*', -'TQPalData*' => 'qt_TQPalData*', -'TQPalette&' => 'qt_TQPalette *', -'TQPalette' => 'qt_TQPalette *', -'TQPalette*' => 'qt_TQPalette *', -'TQPen&' => 'qt_TQPen *', -'TQPen' => 'qt_TQPen*' , -'TQPen*' => 'qt_TQPen*', -'TQPenData*' => 'qt_TQPenData*', -'TQPicture&' => 'qt_TQPicture *', -'TQPicture' => 'qt_TQPicture*', -'TQPicture*' => 'qt_TQPicture*', -'TQPicturePrivate*' => 'qt_TQPicturePrivate*', -'TQPixmap& pixmap()' => 'kde_TQPixmap*', -'TQPixmap&' => 'qt_TQPixmap *', -'TQPixmap' => 'qt_TQPixmap *', -'TQPixmap*' => 'qt_TQPixmap *', +'TQNetworkProtocolFactory*' => 'qt_QNetworkProtocolFactory*', +'TQNetworkProtocolFactoryBase*' => 'qt_QNetworkProtocolFactoryBase*' , +'TQObject*' => 'qt_QObject*', +'TQObjectCleanupHandler*' => 'qt_QObjectCleanupHandler*', +'TQObjectDictionary&' => 'qt_QObjectDictionary*' , +'TQObjectDictionary*' => 'qt_QObjectDictionary*', +'TQObjectInterface*' => 'qt_QObjectInterface*', +'TQObjectList&' => 'qt_QObjectList*' , +'TQObjectList*' => 'qt_QObjectList*', +'TQObjectListIt&' => 'qt_QObjectListIt*' , +'TQObjectListIt*' => 'qt_QObjectListIt*', +'TQPNGImagePacker*' => 'qt_QPNGImagePacker*', +'TQPNGImageWriter*' => 'qt_QPNGImageWriter*', +'TQPaintDevice*' => 'qt_QPaintDevice*', +'TQPaintDeviceMetrics*' => 'qt_QPaintDeviceMetrics*', +'TQPaintDeviceX11Data*' => 'qt_QPaintDeviceX11Data*' , +'TQPaintEvent*' => 'qt_QPaintEvent*' , +'TQPainter&' => 'qt_QPainter*' , +'TQPainter*' => 'qt_QPainter*', +'TQPair*' => 'qt_QPair*', +'TQPalData*' => 'qt_QPalData*', +'TQPalette&' => 'qt_QPalette*', +'TQPalette' => 'qt_QPalette*', +'TQPalette*' => 'qt_QPalette*', +'TQPen&' => 'qt_QPen*', +'TQPen' => 'qt_QPen*' , +'TQPen*' => 'qt_QPen*', +'TQPenData*' => 'qt_QPenData*', +'TQPicture&' => 'qt_QPicture*', +'TQPicture' => 'qt_QPicture*', +'TQPicture*' => 'qt_QPicture*', +'TQPicturePrivate*' => 'qt_QPicturePrivate*', +'TQPixmap& pixmap()' => 'kde_QPixmap*', +'TQPixmap&' => 'qt_QPixmap*', +'TQPixmap' => 'qt_QPixmap*', +'TQPixmap*' => 'qt_QPixmap*', 'TQPixmap::Optimization' => 'int' , 'TQPixmap::Optimization' => 'int', 'TQPixmap::Optimization::DefaultOptim' => 'int' , -'TQPixmapCache*' => 'qt_TQPixmapCache*', -'TQPixmapData*' => 'qt_TQPixmapData*', -'TQPlatinumStyle*' => 'qt_TQPlatinumStyle*', -'TQPluginManager*' => 'qt_TQPluginManager*', -'TQPoint&' => 'qt_TQPoint*', +'TQPixmapCache*' => 'qt_QPixmapCache*', +'TQPixmapData*' => 'qt_QPixmapData*', +'TQPlatinumStyle*' => 'qt_QPlatinumStyle*', +'TQPluginManager*' => 'qt_QPluginManager*', +'TQPoint&' => 'qt_QPoint*', 'TQPoint&pos()' => 'int' , 'TQPoint&pos::pos()' => 'int' , -'TQPoint' => 'qt_TQPoint*', -'TQPoint*' => 'qt_TQPoint*' , -'TQPointArray&' => 'qt_TQPointArray*', -'TQPointArray' => 'qt_TQPointArray*', -'TQPointArray*' => 'qt_TQPointArray*', -'TQPointVal&' => 'qt_TQPointVal*' , -'TQPointVal' => 'qt_TQPointVal*' , -'TQPolygonScanner*' => 'qt_TQPolygonScanner*', -'TQPopupMenu*' => 'qt_TQPopupMenu*', -'TQPrintDialog*' => 'qt_TQPrintDialog*', -'TQPrinter*' => 'qt_TQPrinter*' , +'TQPoint' => 'qt_QPoint*', +'TQPoint*' => 'qt_QPoint*' , +'TQPointArray&' => 'qt_QPointArray*', +'TQPointArray' => 'qt_QPointArray*', +'TQPointArray*' => 'qt_QPointArray*', +'TQPointVal&' => 'qt_QPointVal*' , +'TQPointVal' => 'qt_QPointVal*' , +'TQPolygonScanner*' => 'qt_QPolygonScanner*', +'TQPopupMenu*' => 'qt_QPopupMenu*', +'TQPrintDialog*' => 'qt_QPrintDialog*', +'TQPrinter*' => 'qt_QPrinter*' , 'TQPrinter::PrinterMode' => 'int', -'TQProcess*' => 'qt_TQProcess*', -'TQProgressBar*' => 'qt_TQProgressBar*', -'TQProgressDialog*' => 'qt_TQProgressDialog*', -'TQPtrBucket*' => 'qt_TQPtrBucket*', -'TQPtrCollection&' => 'qt_TQPtrCollection*', -'TQPtrCollection*' => 'qt_TQPtrCollection*', -'TQPtrDict*' => 'qt_TQPtrDict*', -'TQPtrDictIterator*' => 'qt_TQPtrDictIterator*', -'TQPtrList*' => 'qt_TQPtrList*', -'TQPtrListIterator*' => 'qt_TQPtrListIterator*', -'TQPtrQueue*' => 'qt_TQPtrQueue*', -'TQPtrStack*' => 'qt_TQPtrStack*', -'TQPtrVector*' => 'qt_TQPtrVector*', -'TQPushButton*' => 'qt_TQPushButton*', -'TQQueue*' => 'qt_TQQueue*', +'TQProcess*' => 'qt_QProcess*', +'TQProgressBar*' => 'qt_QProgressBar*', +'TQProgressDialog*' => 'qt_QProgressDialog*', +'TQPtrBucket*' => 'qt_QPtrBucket*', +'TQPtrCollection&' => 'qt_QPtrCollection*', +'TQPtrCollection*' => 'qt_QPtrCollection*', +'TQPtrDict*' => 'qt_QPtrDict*', +'TQPtrDictIterator*' => 'qt_QPtrDictIterator*', +'TQPtrList*' => 'qt_QPtrList*', +'TQPtrListIterator*' => 'qt_QPtrListIterator*', +'TQPtrQueue*' => 'qt_QPtrQueue*', +'TQPtrStack*' => 'qt_QPtrStack*', +'TQPtrVector*' => 'qt_QPtrVector*', +'TQPushButton*' => 'qt_QPushButton*', +'TQQueue*' => 'qt_QQueue*', 'TQRESULT' => 'long', -'TQRadioButton*' => 'qt_TQRadioButton*', -'TQRangeControl*' => 'qt_TQRangeControl*', -'TQRect&' => 'qt_TQRect*', -'TQRect' => 'qt_TQRect*', -'TQRect*' => 'qt_TQRect*', -'TQRegExp&' => 'qt_TQRegExp*', -'TQRegExp*' => 'qt_TQRegExp*', -'TQRegExpValidator*' => 'qt_TQRegExpValidator*', -'TQRegion&' => 'qt_TQRegion *', -'TQRegion' => 'qt_TQRegion *', -'TQRegion*' => 'qt_TQRegion*', -'TQRegionData*' => 'qt_TQRegionData*', -'TQRemoteFactory*' => 'qt_TQRemoteFactory*', -'TQRemotePlugin*' => 'qt_TQRemotePlugin*', -'TQResizeEvent*' => 'qt_TQResizeEvent*' , +'TQRadioButton*' => 'qt_QRadioButton*', +'TQRangeControl*' => 'qt_QRangeControl*', +'TQRect&' => 'qt_QRect*', +'TQRect' => 'qt_QRect*', +'TQRect*' => 'qt_QRect*', +'TQRegExp&' => 'qt_QRegExp*', +'TQRegExp*' => 'qt_QRegExp*', +'TQRegExpValidator*' => 'qt_QRegExpValidator*', +'TQRegion&' => 'qt_QRegion*', +'TQRegion' => 'qt_QRegion*', +'TQRegion*' => 'qt_QRegion*', +'TQRegionData*' => 'qt_QRegionData*', +'TQRemoteFactory*' => 'qt_QRemoteFactory*', +'TQRemotePlugin*' => 'qt_QRemotePlugin*', +'TQResizeEvent*' => 'qt_QResizeEvent*' , 'TQRgb' => 'unsigned int', -'TQRgb*' => 'int *', -'TQRichText&' => 'qt_TQRichText*' , -'TQSGIStyle*' => 'qt_TQSGIStyle*', -'TQScrollBar&' => 'qt_TQScrollBar*' , -'TQScrollBar*' => 'qt_TQScrollBar*' , -'TQScrollView*' => 'qt_TQScrollView*', -'TQSemaphore*' => 'qt_TQSemaphore*', -'TQSemiModal*' => 'qt_TQSemiModal*', -'TQSenderObject*' => 'qt_TQSenderObject*', -'TQServerSocket*' => 'qt_TQServerSocket*', -'TQSessionManager&' => 'qt_TQSessionManager*' , -'TQSessionManager*' => 'qt_TQSessionManager*', -'TQSettings*' => 'qt_TQSettings*', -'TQShared*' => 'qt_TQShared*', -'TQShowEvent*' => 'qt_TQShowEvent*' , -'TQSignal*' => 'qt_TQSignal *', -'TQSignalDict&' => 'qt_TQSignalDict*' , -'TQSignalDict*' => 'qt_TQSignalDict*', -'TQSignalDictIt&' => 'qt_TQSignalDictIt*' , -'TQSignalDictIt*' => 'qt_TQSignalDictIt*', -'TQSignalMapper*' => 'qt_TQSignalMapper*', -'TQSignalVec&' => 'qt_TQSignalVec*', -'TQSignalVec*' => 'qt_TQSignalVec*', -'TQSimpleRichText*' => 'qt_TQSimpleRichText*', -'TQSize&' => 'qt_TQSize *', -'TQSize' => 'qt_TQSize *', -'TQSize*' => 'qt_TQSize*' , -'TQSizeGrip*' => 'qt_TQSizeGrip*', -'TQSizePolicy&' => 'qt_TQSizePolicy*' , -'TQSizePolicy' => 'qt_TQSizePolicy*' , -'TQSizePolicy*' => 'qt_TQSizePolicy*', +'TQRgb*' => 'int*', +'TQRichText&' => 'qt_QRichText*' , +'TQSGIStyle*' => 'qt_QSGIStyle*', +'TQScrollBar&' => 'qt_QScrollBar*' , +'TQScrollBar*' => 'qt_QScrollBar*' , +'TQScrollView*' => 'qt_QScrollView*', +'TQSemaphore*' => 'qt_QSemaphore*', +'TQSemiModal*' => 'qt_QSemiModal*', +'TQSenderObject*' => 'qt_QSenderObject*', +'TQServerSocket*' => 'qt_QServerSocket*', +'TQSessionManager&' => 'qt_QSessionManager*' , +'TQSessionManager*' => 'qt_QSessionManager*', +'TQSettings*' => 'qt_QSettings*', +'TQShared*' => 'qt_QShared*', +'TQShowEvent*' => 'qt_QShowEvent*' , +'TQSignal*' => 'qt_QSignal*', +'TQSignalDict&' => 'qt_QSignalDict*' , +'TQSignalDict*' => 'qt_QSignalDict*', +'TQSignalDictIt&' => 'qt_QSignalDictIt*' , +'TQSignalDictIt*' => 'qt_QSignalDictIt*', +'TQSignalMapper*' => 'qt_QSignalMapper*', +'TQSignalVec&' => 'qt_QSignalVec*', +'TQSignalVec*' => 'qt_QSignalVec*', +'TQSimpleRichText*' => 'qt_QSimpleRichText*', +'TQSize&' => 'qt_QSize*', +'TQSize' => 'qt_QSize*', +'TQSize*' => 'qt_QSize*' , +'TQSizeGrip*' => 'qt_QSizeGrip*', +'TQSizePolicy&' => 'qt_QSizePolicy*' , +'TQSizePolicy' => 'qt_QSizePolicy*' , +'TQSizePolicy*' => 'qt_QSizePolicy*', 'TQSizePolicy::ExpandData' => 'int' , 'TQSizePolicy::SizeTypehData::Minimum' => 'int' , 'TQSizePolicy::SizeTypevData::Minimum' => 'int' , -'TQSjisCodec*' => 'qt_TQSjisCodec*', -'TQSlider*' => 'qt_TQSlider*', -'TQSmartPtr&' => 'qt_TQSmartPtr*' , -'TQSmartPtr*' => 'qt_TQSmartPtr*', -'TQSmartPtrPrivate*' => 'qt_TQSmartPtrPrivate*', -'TQSocket*' => 'qt_TQSocket*', -'TQSocketDevice*' => 'qt_TQSocketDevice*' , -'TQSocketNotifier*' => 'qt_TQSocketNotifier*', +'TQSjisCodec*' => 'qt_QSjisCodec*', +'TQSlider*' => 'qt_QSlider*', +'TQSmartPtr&' => 'qt_QSmartPtr*' , +'TQSmartPtr*' => 'qt_QSmartPtr*', +'TQSmartPtrPrivate*' => 'qt_QSmartPtrPrivate*', +'TQSocket*' => 'qt_QSocket*', +'TQSocketDevice*' => 'qt_QSocketDevice*' , +'TQSocketNotifier*' => 'qt_QSocketNotifier*', 'TQSocketNotifier::Type' => 'int', -'TQSortedList*' => 'qt_TQSortedList*', -'TQSound*' => 'qt_TQSound*', -'TQSpacerItem*' => 'qt_TQSpacerItem*' , -'TQSpinBox*' => 'qt_TQSpinBox*', -'TQSpinWidget*' => 'qt_TQSpinWidget*', -'TQSplitter*' => 'qt_TQSplitter*', -'TQSql*' => 'qt_TQSql*', +'TQSortedList*' => 'qt_QSortedList*', +'TQSound*' => 'qt_QSound*', +'TQSpacerItem*' => 'qt_QSpacerItem*' , +'TQSpinBox*' => 'qt_QSpinBox*', +'TQSpinWidget*' => 'qt_QSpinWidget*', +'TQSplitter*' => 'qt_QSplitter*', +'TQSql*' => 'qt_QSql*', 'TQSql::Confirm' => 'int', 'TQSql::Op' => 'int', -'TQSqlCursor&' => 'qt_TQSqlCursor*', -'TQSqlCursor' => 'qt_TQSqlCursor*', -'TQSqlCursor*' => 'qt_TQSqlCursor*', -'TQSqlDatabase*' => 'qt_TQSqlDatabase*', -'TQSqlDriver*' => 'qt_TQSqlDriver*', -'TQSqlDriverCreator*' => 'qt_TQSqlDriverCreator*', -'TQSqlDriverCreatorBase*' => 'qt_TQSqlDriverCreatorBase*', -'TQSqlDriverFactoryInterface*' => 'qt_TQSqlDriverFactoryInterface*', -'TQSqlDriverPlugin*' => 'qt_TQSqlDriverPlugin*', -'TQSqlEditorFactory*' => 'qt_TQSqlEditorFactory*', -'TQSqlError&' => 'qt_TQSqlError*', -'TQSqlError' => 'qt_TQSqlError*', -'TQSqlError*' => 'qt_TQSqlError*', -'TQSqlField&' => 'qt_TQSqlField*', -'TQSqlField' => 'qt_TQSqlField*', -'TQSqlField*' => 'qt_TQSqlField*', -'TQSqlFieldInfo&' => 'qt_TQSqlFieldInfo*', -'TQSqlFieldInfo*' => 'qt_TQSqlFieldInfo*', -'TQSqlForm' => 'qt_TQSqlForm*', -'TQSqlForm*' => 'qt_TQSqlForm*', -'TQSqlIndex&' => 'qt_TQSqlIndex*', -'TQSqlIndex' => 'qt_TQSqlIndex*', -'TQSqlIndex*' => 'qt_TQSqlIndex*', -'TQSqlPropertyMap*' => 'qt_TQSqlPropertyMap*', -'TQSqlQuery&' => 'qt_TQSqlQuery*', -'TQSqlQuery' => 'qt_TQSqlQuery*', -'TQSqlQuery*' => 'qt_TQSqlQuery*', -'TQSqlRecord&' => 'qt_TQSqlRecord*', -'TQSqlRecord' => 'qt_TQSqlRecord*', -'TQSqlRecord*' => 'qt_TQSqlRecord*', -'TQSqlRecordInfo&' => 'qt_TQSqlRecordInfo*', -'TQSqlRecordInfo' => 'qt_TQSqlRecordInfo*', -'TQSqlRecordInfo*' => 'qt_TQSqlRecordInfo*', -'TQSqlRecordPrivate*' => 'qt_TQSqlRecordPrivate*', -'TQSqlRecordShared*' => 'qt_TQSqlRecordShared*', -'TQSqlResult' => 'qt_TQSqlResult*', -'TQSqlResult*' => 'qt_TQSqlResult*', -'TQSqlResultShared*' => 'qt_TQSqlResultShared*', -'TQStack*' => 'qt_TQStack*', -'TQStatusBar*' => 'qt_TQStatusBar*' , -'TQStoredDrag*' => 'qt_TQStoredDrag*', -'TQStrIList' => 'kde_TQStrIList', -'TQStrIList*' => 'qt_TQStrIList*', -'TQStrIVec*' => 'qt_TQStrIVec*', -'TQStrList&' => 'qt_TQStrList *', -'TQStrList' => 'qt_TQStrList *', -'TQStrList*' => 'qt_TQStrList *', -'TQStrListIterator*' => 'qt_TQStrListIterator*', -'TQStrVec*' => 'qt_TQStrVec*', -'TQString&' => 'qt_TQString *', -'TQString&::null' => 'qt_TQString*' , -'TQString&button0Text::null' => 'qt_TQString*' , -'TQString&button1Text::null' => 'qt_TQString*' , -'TQString&button2Text::null' => 'qt_TQString*' , -'TQString&buttonText::null' => 'qt_TQString*' , -'TQString&caption::null' => 'qt_TQString*' , -'TQString&charSet::null' => 'qt_TQString*' , -'TQString&context::null' => 'qt_TQString*' , -'TQString&defValue::null' => 'qt_TQString*' , -'TQString&dir::null' => 'qt_TQString*' , -'TQString&directory::null' => 'qt_TQString*' , -'TQString&filter::null' => 'qt_TQString*' , -'TQString&initially::null' => 'qt_TQString*' , -'TQString&location::null' => 'qt_TQString*' , -'TQString&n::null' => 'qt_TQString*' , -'TQString&nameFilter::null' => 'qt_TQString*' , -'TQString&noButtonText::null' => 'qt_TQString*' , -'TQString&search_delimiters::null' => 'qt_TQString*' , -'TQString&style::null' => 'qt_TQString*' , -'TQString&suffix::null' => 'qt_TQString*' , -'TQString&text::null' => 'qt_TQString*' , -'TQString&text_::null' => 'qt_TQString*' , -'TQString&translation::null' => 'qt_TQString*' , -'TQString&yesButtonText::null' => 'qt_TQString*' , -'TQString' => 'qt_TQString *', -'TQString*' => 'qt_TQString*' , -'TQString::null' => 'qt_TQString_null()' , -'TQStringBucket*' => 'qt_TQStringBucket*', -'TQStringData*' => 'qt_TQStringData*', -'TQStringList&' => 'qt_TQStringList*' , -'TQStringList' => 'qt_TQStringList*' , -'TQStringList*' => 'qt_TQStringList*' , -'TQStringcharSetName::null' => 'qt_TQStringcharSetName*' , -'TQStyle&' => 'qt_TQStyle*' , -'TQStyle*' => 'qt_TQStyle*' , +'TQSqlCursor&' => 'qt_QSqlCursor*', +'TQSqlCursor' => 'qt_QSqlCursor*', +'TQSqlCursor*' => 'qt_QSqlCursor*', +'TQSqlDatabase*' => 'qt_QSqlDatabase*', +'TQSqlDriver*' => 'qt_QSqlDriver*', +'TQSqlDriverCreator*' => 'qt_QSqlDriverCreator*', +'TQSqlDriverCreatorBase*' => 'qt_QSqlDriverCreatorBase*', +'TQSqlDriverFactoryInterface*' => 'qt_QSqlDriverFactoryInterface*', +'TQSqlDriverPlugin*' => 'qt_QSqlDriverPlugin*', +'TQSqlEditorFactory*' => 'qt_QSqlEditorFactory*', +'TQSqlError&' => 'qt_QSqlError*', +'TQSqlError' => 'qt_QSqlError*', +'TQSqlError*' => 'qt_QSqlError*', +'TQSqlField&' => 'qt_QSqlField*', +'TQSqlField' => 'qt_QSqlField*', +'TQSqlField*' => 'qt_QSqlField*', +'TQSqlFieldInfo&' => 'qt_QSqlFieldInfo*', +'TQSqlFieldInfo*' => 'qt_QSqlFieldInfo*', +'TQSqlForm' => 'qt_QSqlForm*', +'TQSqlForm*' => 'qt_QSqlForm*', +'TQSqlIndex&' => 'qt_QSqlIndex*', +'TQSqlIndex' => 'qt_QSqlIndex*', +'TQSqlIndex*' => 'qt_QSqlIndex*', +'TQSqlPropertyMap*' => 'qt_QSqlPropertyMap*', +'TQSqlQuery&' => 'qt_QSqlQuery*', +'TQSqlQuery' => 'qt_QSqlQuery*', +'TQSqlQuery*' => 'qt_QSqlQuery*', +'TQSqlRecord&' => 'qt_QSqlRecord*', +'TQSqlRecord' => 'qt_QSqlRecord*', +'TQSqlRecord*' => 'qt_QSqlRecord*', +'TQSqlRecordInfo&' => 'qt_QSqlRecordInfo*', +'TQSqlRecordInfo' => 'qt_QSqlRecordInfo*', +'TQSqlRecordInfo*' => 'qt_QSqlRecordInfo*', +'TQSqlRecordPrivate*' => 'qt_QSqlRecordPrivate*', +'TQSqlRecordShared*' => 'qt_QSqlRecordShared*', +'TQSqlResult' => 'qt_QSqlResult*', +'TQSqlResult*' => 'qt_QSqlResult*', +'TQSqlResultShared*' => 'qt_QSqlResultShared*', +'TQStack*' => 'qt_QStack*', +'TQStatusBar*' => 'qt_QStatusBar*' , +'TQStoredDrag*' => 'qt_QStoredDrag*', +'TQStrIList' => 'kde_QStrIList', +'TQStrIList*' => 'qt_QStrIList*', +'TQStrIVec*' => 'qt_QStrIVec*', +'TQStrList&' => 'qt_QStrList*', +'TQStrList' => 'qt_QStrList*', +'TQStrList*' => 'qt_QStrList*', +'TQStrListIterator*' => 'qt_QStrListIterator*', +'TQStrVec*' => 'qt_QStrVec*', +'TQString&' => 'qt_QString*', +'TQString&::null' => 'qt_QString*' , +'TQString&button0Text::null' => 'qt_QString*' , +'TQString&button1Text::null' => 'qt_QString*' , +'TQString&button2Text::null' => 'qt_QString*' , +'TQString&buttonText::null' => 'qt_QString*' , +'TQString&caption::null' => 'qt_QString*' , +'TQString&charSet::null' => 'qt_QString*' , +'TQString&context::null' => 'qt_QString*' , +'TQString&defValue::null' => 'qt_QString*' , +'TQString&dir::null' => 'qt_QString*' , +'TQString&directory::null' => 'qt_QString*' , +'TQString&filter::null' => 'qt_QString*' , +'TQString&initially::null' => 'qt_QString*' , +'TQString&location::null' => 'qt_QString*' , +'TQString&n::null' => 'qt_QString*' , +'TQString&nameFilter::null' => 'qt_QString*' , +'TQString&noButtonText::null' => 'qt_QString*' , +'TQString&search_delimiters::null' => 'qt_QString*' , +'TQString&style::null' => 'qt_QString*' , +'TQString&suffix::null' => 'qt_QString*' , +'TQString&text::null' => 'qt_QString*' , +'TQString&text_::null' => 'qt_QString*' , +'TQString&translation::null' => 'qt_QString*' , +'TQString&yesButtonText::null' => 'qt_QString*' , +'TQString' => 'qt_QString*', +'TQString*' => 'qt_QString*' , +'TQString::null' => 'qt_QString_null()' , +'TQStringBucket*' => 'qt_QStringBucket*', +'TQStringData*' => 'qt_QStringData*', +'TQStringList&' => 'qt_QStringList*' , +'TQStringList' => 'qt_QStringList*' , +'TQStringList*' => 'qt_QStringList*' , +'TQStringcharSetName::null' => 'qt_QStringcharSetName*' , +'TQStyle&' => 'qt_QStyle*' , +'TQStyle*' => 'qt_QStyle*' , 'TQStyle::ScrollControl' => 'int' , 'TQStyle::StylePixmap' => 'int', 'TQStyle::SubControl' => 'int', 'TQStyle::SubRect' => 'int', -'TQStyleFactory*' => 'qt_TQStyleFactory*', -'TQStyleFactoryInterface*' => 'qt_TQStyleFactoryInterface*', -'TQStyleHintReturn*' => 'qt_TQStyleHintReturn*', +'TQStyleFactory*' => 'qt_QStyleFactory*', +'TQStyleFactoryInterface*' => 'qt_QStyleFactoryInterface*', 'TQStyleOption&' => 'int', 'TQStyleOption' => 'int', 'TQStyleOption*' => 'int*', -'TQStylePlugin*' => 'qt_TQStylePlugin*', -'TQStyleSheet*' => 'qt_TQStyleSheet*' , -'TQStyleSheetItem&' => 'qt_TQStyleSheetItem*' , -'TQStyleSheetItem*' => 'qt_TQStyleSheetItem*' , +'TQStylePlugin*' => 'qt_QStylePlugin*', +'TQStyleSheet*' => 'qt_QStyleSheet*' , +'TQStyleSheetItem&' => 'qt_QStyleSheetItem*' , +'TQStyleSheetItem*' => 'qt_QStyleSheetItem*' , 'TQStyleSheetItem::DisplayMode*' => 'int', 'TQStyleSheetItem::ListStyle*' => 'int', 'TQStyleSheetItem::WhiteSpaceMode' => 'int', -'TQTSCIICodec*' => 'qt_TQTSCIICodec*', +'TQTSCIICodec*' => 'qt_QTSCIICodec*', 'TQTSMFI' => 'int' , -'TQTab*' => 'qt_TQTab*', -'TQTabBar*' => 'qt_TQTabBar*' , +'TQTab*' => 'qt_QTab*', +'TQTabBar*' => 'qt_QTabBar*' , 'TQTabBar::Shape' => 'int' , -'TQTabDialog*' => 'qt_TQTabDialog*', -'TQTabWidget*' => 'qt_TQTabWidget*', -'TQTable*' => 'qt_TQTable*' , -'TQTableHeader*' => 'qt_TQTableHeader*', -'TQTableItem*' => 'qt_TQTableItem*' , -'TQTableSelection&' => 'qt_TQTableSelection*' , -'TQTableSelection' => 'qt_TQTableSelection*' , -'TQTableSelection*' => 'qt_TQTableSelection*', -'TQTableView*' => 'qt_TQTableView*', -'TQTabletEvent*' => 'qt_TQTabletEvent*', -'TQTextBrowser*' => 'qt_TQTextBrowser*', -'TQTextCodec*' => 'qt_TQTextCodec*' , -'TQTextCodecFactory*' => 'qt_TQTextCodecFactory*', -'TQTextCodecFactoryInterface*' => 'qt_TQTextCodecFactoryInterface*', -'TQTextCodecPlugin*' => 'qt_TQTextCodecPlugin*', -'TQTextCursor*' => 'qt_TQTextCursor*', -'TQTextDecoder*' => 'qt_TQTextDecoder*' , -'TQTextDocument*' => 'qt_TQTextDocument*', -'TQTextDrag*' => 'qt_TQTextDrag*', -'TQTextEdit*' => 'qt_TQTextEdit*', -'TQTextEncoder*' => 'qt_TQTextEncoder*' , -'TQTextFormat*' => 'qt_TQTextFormat*', -'TQTextIStream*' => 'qt_TQTextIStream*', -'TQTextOStream&' => 'qt_TQTextOStream*' , -'TQTextOStream*' => 'qt_TQTextOStream*', -'TQTextOStreamIterator*' => 'qt_TQTextOStreamIterator*', -'TQTextParag**' => 'qt_TQTextParag**', -'TQTextStream&' => 'qt_TQTextStream*' , -'TQTextStream*' => 'qt_TQTextStream*' , -'TQTextView*' => 'qt_TQTextView*', -'TQThread*' => 'qt_TQThread*', -'TQThreadData*' => 'qt_TQThreadData*', -'TQThreadEvent*' => 'qt_TQThreadEvent*', -'TQTime&' => 'qt_TQTime *', -'TQTime' => 'qt_TQTime *', -'TQTime*' => 'qt_TQTime*', -'TQTimeEdit*' => 'qt_TQTimeEdit*', -'TQTimeWatch*' => 'qt_TQTimeWatch*', -'TQTimer*' => 'qt_TQTimer*', -'TQTimerEvent*' => 'qt_TQTimerEvent*' , -'TQToolBar*' => 'qt_TQToolBar*' , -'TQToolButton*' => 'qt_TQToolButton*' , -'TQToolTip*' => 'qt_TQToolTip*', -'TQToolTipGroup*' => 'qt_TQToolTipGroup *', -'TQTranslator*' => 'qt_TQTranslator*' , -'TQTranslatorMessage&' => 'qt_TQTranslatorMessage*' , -'TQTranslatorMessage' => 'qt_TQTranslatorMessage*' , -'TQTranslatorMessage*' => 'qt_TQTranslatorMessage*', -'TQTsciiCodec*' => 'qt_TQTsciiCodec*', -'TQUObject*' => 'qt_TQUObject*', -'TQUnknownInterface*' => 'qt_TQUnknownInterface*', -'TQUnknownInterface**' => 'qt_TQUnknownInterface**', -'TQUriDrag*' => 'qt_TQUriDrag*', -'TQUrl&' => 'qt_TQUrl*' , -'TQUrl' => 'qt_TQUrl*' , -'TQUrl*' => 'qt_TQUrl*', -'TQUrlInfo&' => 'qt_TQUrlInfo*' , -'TQUrlInfo' => 'qt_TQUrlInfo*' , -'TQUrlInfo*' => 'qt_TQUrlInfo*', -'TQUrlOperator&' => 'qt_TQUrlOperator*' , -'TQUrlOperator*' => 'qt_TQUrlOperator*' , -'TQUtf16Codec*' => 'qt_TQUtf16Codec*', -'TQUtf8Codec*' => 'qt_TQUtf8Codec*', -'TQUuid&' => 'qt_TQUuid*', -'TQUuid*' => 'qt_TQUuid*', -'TQVBox*' => 'qt_TQVBox*' , -'TQVBoxLayout*' => 'qt_TQVBoxLayout*', -'TQVButtonGroup*' => 'qt_TQVButtonGroup*', -'TQVFbHeader*' => 'qt_TQVFbHeader*', -'TQVFbKeyData*' => 'qt_TQVFbKeyData*', -'TQVGroupBox*' => 'qt_TQVGroupBox*', -'TQValidator*' => 'qt_TQValidator *', +'TQTabDialog*' => 'qt_QTabDialog*', +'TQTabWidget*' => 'qt_QTabWidget*', +'TQTable*' => 'qt_QTable*' , +'TQTableHeader*' => 'qt_QTableHeader*', +'TQTableItem*' => 'qt_QTableItem*' , +'TQTableSelection&' => 'qt_QTableSelection*' , +'TQTableSelection' => 'qt_QTableSelection*' , +'TQTableSelection*' => 'qt_QTableSelection*', +'TQTableView*' => 'qt_QTableView*', +'TQTabletEvent*' => 'qt_QTabletEvent*', +'TQTextBrowser*' => 'qt_QTextBrowser*', +'TQTextCodec*' => 'qt_QTextCodec*' , +'TQTextCodecFactory*' => 'qt_QTextCodecFactory*', +'TQTextCodecFactoryInterface*' => 'qt_QTextCodecFactoryInterface*', +'TQTextCodecPlugin*' => 'qt_QTextCodecPlugin*', +'TQTextCursor*' => 'qt_QTextCursor*', +'TQTextDecoder*' => 'qt_QTextDecoder*' , +'TQTextDocument*' => 'qt_QTextDocument*', +'TQTextDrag*' => 'qt_QTextDrag*', +'TQTextEdit*' => 'qt_QTextEdit*', +'TQTextEncoder*' => 'qt_QTextEncoder*' , +'TQTextFormat*' => 'qt_QTextFormat*', +'TQTextIStream*' => 'qt_QTextIStream*', +'TQTextOStream&' => 'qt_QTextOStream*' , +'TQTextOStream*' => 'qt_QTextOStream*', +'TQTextOStreamIterator*' => 'qt_QTextOStreamIterator*', +'TQTextParag**' => 'qt_QTextParag**', +'TQTextStream&' => 'qt_QTextStream*' , +'TQTextStream*' => 'qt_QTextStream*' , +'TQTextView*' => 'qt_QTextView*', +'TQThread*' => 'qt_QThread*', +'TQThreadData*' => 'qt_QThreadData*', +'TQThreadEvent*' => 'qt_QThreadEvent*', +'TQTime&' => 'qt_QTime*', +'TQTime' => 'qt_QTime*', +'TQTime*' => 'qt_QTime*', +'TQTimeEdit*' => 'qt_QTimeEdit*', +'TQTimeWatch*' => 'qt_QTimeWatch*', +'TQTimer*' => 'qt_QTimer*', +'TQTimerEvent*' => 'qt_QTimerEvent*' , +'TQToolBar*' => 'qt_QToolBar*' , +'TQToolButton*' => 'qt_QToolButton*' , +'TQToolTip*' => 'qt_QToolTip*', +'TQToolTipGroup*' => 'qt_QToolTipGroup*', +'TQTranslator*' => 'qt_QTranslator*' , +'TQTranslatorMessage&' => 'qt_QTranslatorMessage*' , +'TQTranslatorMessage' => 'qt_QTranslatorMessage*' , +'TQTranslatorMessage*' => 'qt_QTranslatorMessage*', +'TQTsciiCodec*' => 'qt_QTsciiCodec*', +'TQUObject*' => 'qt_QUObject*', +'TQUnknownInterface*' => 'qt_QUnknownInterface*', +'TQUnknownInterface**' => 'qt_QUnknownInterface**', +'TQUriDrag*' => 'qt_QUriDrag*', +'TQUrl&' => 'qt_QUrl*' , +'TQUrl' => 'qt_QUrl*' , +'TQUrl*' => 'qt_QUrl*', +'TQUrlInfo&' => 'qt_QUrlInfo*' , +'TQUrlInfo' => 'qt_QUrlInfo*' , +'TQUrlInfo*' => 'qt_QUrlInfo*', +'TQUrlOperator&' => 'qt_QUrlOperator*' , +'TQUrlOperator*' => 'qt_QUrlOperator*' , +'TQUtf16Codec*' => 'qt_QUtf16Codec*', +'TQUtf8Codec*' => 'qt_QUtf8Codec*', +'TQUuid&' => 'qt_QUuid*', +'TQUuid*' => 'qt_QUuid*', +'TQVBox*' => 'qt_QVBox*' , +'TQVBoxLayout*' => 'qt_QVBoxLayout*', +'TQVButtonGroup*' => 'qt_QVButtonGroup*', +'TQVFbHeader*' => 'qt_QVFbHeader*', +'TQVFbKeyData*' => 'qt_QVFbKeyData*', +'TQVGroupBox*' => 'qt_QVGroupBox*', +'TQValidator*' => 'qt_QValidator*', 'TQValidator::State' => 'int', -'TQValueList*' => 'qt_TQValueList*', -'TQValueListConstIterator*' => 'qt_TQValueListConstIterator*', -'TQValueListIterator*' => 'qt_TQValueListIterator*', -'TQValueListNode*' => 'qt_TQValueListNode*', -'TQValueListPrivate*' => 'qt_TQValueListPrivate*', -'TQValueStack*' => 'qt_TQValueStack*', -'TQValueVector*' => 'qt_TQValueVector*', -'TQValueVectorPrivate*' => 'qt_TQValueVectorPrivate*', -'TQVariant&' => 'qt_TQVariant *', -'TQVariant' => 'qt_TQVariant *', -'TQVariant*' => 'qt_TQVariant*', +'TQValueList*' => 'qt_QValueList*', +'TQValueListConstIterator*' => 'qt_QValueListConstIterator*', +'TQValueListIterator*' => 'qt_QValueListIterator*', +'TQValueListNode*' => 'qt_QValueListNode*', +'TQValueListPrivate*' => 'qt_QValueListPrivate*', +'TQValueStack*' => 'qt_QValueStack*', +'TQValueVector*' => 'qt_QValueVector*', +'TQValueVectorPrivate*' => 'qt_QValueVectorPrivate*', +'TQVariant&' => 'qt_QVariant*', +'TQVariant' => 'qt_QVariant*', +'TQVariant*' => 'qt_QVariant*', 'TQVariant::Type' => 'int' , -'TQVariantPrivate*' => 'qt_TQVariantPrivate*' , -'TQVector*' => 'qt_TQVector*', -'TQWMatrix&' => 'qt_TQWMatrix *', -'TQWMatrix' => 'qt_TQWMatrix *', -'TQWMatrix*' => 'qt_TQWMatrix*', -'TQWSDecoration&' => 'qt_TQWSDecoration*' , -'TQWSDecoration*' => 'qt_TQWSDecoration*' , -'TQWSDisplay*' => 'qt_TQWSDisplay*' , -'TQWSEvent*' => 'qt_TQWSEvent*' , -'TQWaitCondition*' => 'qt_TQWaitCondition*', -'TQWhatsThis*' => 'qt_TQWhatsThis*', -'TQWheelEvent*' => 'qt_TQWheelEvent*' , -'TQWidget *' => 'qt_TQWidget *', -'TQWidget' => 'qt_TQWidget *', -'TQWidget*' => 'qt_TQWidget *', -'TQWidgetFactory*' => 'qt_TQWidgetFactory*', -'TQWidgetIntDict&' => 'qt_TQWidgetIntDict*' , -'TQWidgetIntDict*' => 'qt_TQWidgetIntDict*', -'TQWidgetIntDictIt&' => 'qt_TQWidgetIntDictIt*' , -'TQWidgetIntDictIt*' => 'qt_TQWidgetIntDictIt*', -'TQWidgetItem*' => 'qt_TQWidgetItem*', -'TQWidgetList&' => 'qt_TQWidgetList *' , -'TQWidgetList&' => 'qt_TQWidgetList*' , -'TQWidgetList' => 'qt_TQWidgetList *' , -'TQWidgetList' => 'qt_TQWidgetList*' , -'TQWidgetList*' => 'qt_TQWidgetList *', -'TQWidgetList*' => 'qt_TQWidgetList*', -'TQWidgetListIt&' => 'qt_TQWidgetListIt*' , -'TQWidgetListIt*' => 'qt_TQWidgetListIt*', -'TQWidgetMapper*' => 'qt_TQWidgetMapper*', -'TQWidgetPlugin*' => 'qt_TQWidgetPlugin*', -'TQWidgetStack*' => 'qt_TQWidgetStack*', -'TQWindowsMime*' => 'qt_TQWindowsMime*' , -'TQWindowsStyle*' => 'qt_TQWindowsStyle*', -'TQWizard*' => 'qt_TQWizard*', -'TQWorkspace*' => 'qt_TQWorkspace*', -'TQXEmbed*' => 'qt_TQXEmbed*' , -'TQXmlAttributes&' => 'qt_TQXmlAttributes*' , -'TQXmlAttributes*' => 'qt_TQXmlAttributes*', -'TQXmlContentHandler*' => 'qt_TQXmlContentHandler*' , -'TQXmlDTDHandler*' => 'qt_TQXmlDTDHandler*' , -'TQXmlDeclHandler*' => 'qt_TQXmlDeclHandler*' , -'TQXmlDefaultHandler*' => 'qt_TQXmlDefaultHandler*', -'TQXmlEntityResolver*' => 'qt_TQXmlEntityResolver*' , -'TQXmlErrorHandler*' => 'qt_TQXmlErrorHandler*' , -'TQXmlInputSource&' => 'qt_TQXmlInputSource*' , -'TQXmlInputSource*&' => 'qt_TQXmlInputSource*', -'TQXmlInputSource*' => 'qt_TQXmlInputSource*' , -'TQXmlLexicalHandler*' => 'qt_TQXmlLexicalHandler*' , -'TQXmlLocator*' => 'qt_TQXmlLocator*' , -'TQXmlNamespaceSupport*' => 'qt_TQXmlNamespaceSupport*', -'TQXmlParseException&' => 'qt_TQXmlParseException*' , -'TQXmlParseException*' => 'qt_TQXmlParseException*', -'TQXmlReader*' => 'qt_TQXmlReader*', -'TQXmlSimpleReader*' => 'qt_TQXmlSimpleReader*' , -'TQXtApplication*' => 'qt_TQXtApplication*', -'TQXtWidget*' => 'qt_TQXtWidget*', -'TTQ_INT16&' => 'short', -'TTQ_INT16' => 'short', -'TTQ_INT32&' => 'int', -'TTQ_INT32' => 'int', -'TTQ_INT8&' => 'char', -'TTQ_INT8' => 'char', -'TTQ_LONG&' => 'long', -'TTQ_LONG' => 'long', -'TTQ_PACKED*' => 'void*', -'TTQ_UINT16&' => 'unsigned short', -'TTQ_UINT16' => 'unsigned short', -'TTQ_UINT32&' => 'unsigned int', -'TTQ_UINT32' => 'unsigned int', -'TTQ_UINT8&' => 'unsigned char', -'TTQ_UINT8' => 'unsigned char', -'TTQ_UINT8*' => 'unsigned char*' , -'TTQ_ULONG&' => 'long', -'TTQ_ULONG' => 'long', -'TQt*' => 'qt_TQt*' , +'TQVariantPrivate*' => 'qt_QVariantPrivate*' , +'TQVector*' => 'qt_QVector*', +'TQWMatrix&' => 'qt_QWMatrix*', +'TQWMatrix' => 'qt_QWMatrix*', +'TQWMatrix*' => 'qt_QWMatrix*', +'TQWSDecoration&' => 'qt_QWSDecoration*' , +'TQWSDecoration*' => 'qt_QWSDecoration*' , +'TQWSDisplay*' => 'qt_QWSDisplay*' , +'TQWSEvent*' => 'qt_QWSEvent*' , +'TQWaitCondition*' => 'qt_QWaitCondition*', +'TQWhatsThis*' => 'qt_QWhatsThis*', +'TQWheelEvent*' => 'qt_QWheelEvent*' , +'TQWidget*' => 'qt_QWidget*', +'TQWidget' => 'qt_QWidget*', +'TQWidget*' => 'qt_QWidget*', +'TQWidgetFactory*' => 'qt_QWidgetFactory*', +'TQWidgetIntDict&' => 'qt_QWidgetIntDict*' , +'TQWidgetIntDict*' => 'qt_QWidgetIntDict*', +'TQWidgetIntDictIt&' => 'qt_QWidgetIntDictIt*' , +'TQWidgetIntDictIt*' => 'qt_QWidgetIntDictIt*', +'TQWidgetItem*' => 'qt_QWidgetItem*', +'TQWidgetList&' => 'qt_QWidgetList*' , +'TQWidgetList&' => 'qt_QWidgetList*' , +'TQWidgetList' => 'qt_QWidgetList*' , +'TQWidgetList' => 'qt_QWidgetList*' , +'TQWidgetList*' => 'qt_QWidgetList*', +'TQWidgetList*' => 'qt_QWidgetList*', +'TQWidgetListIt&' => 'qt_QWidgetListIt*' , +'TQWidgetListIt*' => 'qt_QWidgetListIt*', +'TQWidgetMapper*' => 'qt_QWidgetMapper*', +'TQWidgetPlugin*' => 'qt_QWidgetPlugin*', +'TQWidgetStack*' => 'qt_QWidgetStack*', +'TQWindowsMime*' => 'qt_QWindowsMime*' , +'TQWindowsStyle*' => 'qt_QWindowsStyle*', +'TQWizard*' => 'qt_QWizard*', +'TQWorkspace*' => 'qt_QWorkspace*', +'TQXEmbed*' => 'qt_QXEmbed*' , +'TQXmlAttributes&' => 'qt_QXmlAttributes*' , +'TQXmlAttributes*' => 'qt_QXmlAttributes*', +'TQXmlContentHandler*' => 'qt_QXmlContentHandler*' , +'TQXmlDTDHandler*' => 'qt_QXmlDTDHandler*' , +'TQXmlDeclHandler*' => 'qt_QXmlDeclHandler*' , +'TQXmlDefaultHandler*' => 'qt_QXmlDefaultHandler*', +'TQXmlEntityResolver*' => 'qt_QXmlEntityResolver*' , +'TQXmlErrorHandler*' => 'qt_QXmlErrorHandler*' , +'TQXmlInputSource&' => 'qt_QXmlInputSource*' , +'TQXmlInputSource*&' => 'qt_QXmlInputSource*', +'TQXmlInputSource*' => 'qt_QXmlInputSource*' , +'TQXmlLexicalHandler*' => 'qt_QXmlLexicalHandler*' , +'TQXmlLocator*' => 'qt_QXmlLocator*' , +'TQXmlNamespaceSupport*' => 'qt_QXmlNamespaceSupport*', +'TQXmlParseException&' => 'qt_QXmlParseException*' , +'TQXmlParseException*' => 'qt_QXmlParseException*', +'TQXmlReader*' => 'qt_QXmlReader*', +'TQXmlSimpleReader*' => 'qt_QXmlSimpleReader*' , +'TQXtApplication*' => 'qt_QXtApplication*', +'TQXtWidget*' => 'qt_QXtWidget*', +'Q_INT16&' => 'short', +'Q_INT16' => 'short', +'Q_INT32&' => 'int', +'Q_INT32' => 'int', +'Q_INT8&' => 'char', +'Q_INT8' => 'char', +'Q_LONG&' => 'long', +'Q_LONG' => 'long', +'Q_PACKED*' => 'void*', +'Q_UINT16&' => 'unsigned short', +'Q_UINT16' => 'unsigned short', +'Q_UINT32&' => 'unsigned int', +'Q_UINT32' => 'unsigned int', +'Q_UINT8&' => 'unsigned char', +'Q_UINT8' => 'unsigned char', +'Q_UINT8*' => 'unsigned char*' , +'Q_ULONG&' => 'long', +'Q_ULONG' => 'long', +'Qt*' => 'qt_Qt*' , 'TQt::ArrowType' => 'int' , 'TQt::BackgroundMode' => 'int', 'TQt::DateFormat' => 'int', @@ -2360,9 +2300,9 @@ BEGIN 'TQt::RasterOp' => 'int' , 'TQt::UIEffect' => 'int' , 'TQt::WFlags' => 'int' , -'TQtMultiLineEdit*' => 'qt_TQtMultiLineEdit*', -'TQtMultiLineEditRow*' => 'qt_TQtMultiLineEditRow*', -'TQtTableView*' => 'qt_TQtTableView*', +'QtMultiLineEdit*' => 'qt_QtMultiLineEdit*', +'QtMultiLineEditRow*' => 'qt_QtMultiLineEditRow*', +'QtTableView*' => 'qt_QtTableView*', 'QwAbsSpriteFieldView*' => 'qt_QwAbsSpriteFieldView*' , 'QwClusterizer*' => 'qt_QwClusterizer*' , 'QwEllipse*' => 'qt_QwEllipse*', @@ -2655,14 +2595,9 @@ BEGIN 'UCharReference' => 'kde_UCharReference*', 'UCharReference*' => 'kde_UCharReference*', 'UDSAtom*' => 'kde_UDSAtom*', -'UDSEntry&' => 'kde_UDSEntry*', -'UDSEntryList&' => 'kde_UDSEntryList*', 'UIServer*' => 'kde_UIServer*', 'UIServer_stub*' => 'kde_UIServer_stub*', 'ULONG_MAX' => 'ULONG_MAX', -'URLArgs&' => 'kde_URLArgs*', -'URLArgs' => 'kde_URLArgs*', -'URLArgs*' => 'kde_URLArgs*', 'UString&' => 'kde_UString*', 'UString' => 'kde_UString*', 'UString*' => 'kde_UString*', @@ -2705,7 +2640,7 @@ BEGIN 'bool&' => 'int' , 'bool' => 'int', 'bool*' => 'int*', -'char *' => 'char *', +'char*' => 'char*', 'char&' => 'char' , 'char' => 'char', 'char* bugsEmailAddress @bugs.kde.org"' => 'String', @@ -2739,27 +2674,13 @@ BEGIN 'int&' => 'int', 'int' => 'int', 'int*' => 'int*', +'int short' => 'short', 'kdbgstream&' => 'kde_Kdbgstream*' , 'kdbgstream*' => 'kde_kdbgstream*', -'khtml*' => 'kde_khtml*', -'khtml::ChildFrame*' => 'kde_khtml_ChildFrame*' , -'khtml::DrawContentsEvent*' => 'kde_khtml_DrawContentsEvent*' , -'khtml::MouseDoubleClickEvent*' => 'kde_khtml_MouseDoubleClickEvent*' , -'khtml::MouseMoveEvent*' => 'kde_khtml_MouseMoveEvent*' , -'khtml::MousePressEvent*' => 'kde_khtml_MousePressEvent*' , -'khtml::MouseReleaseEvent*' => 'kde_khtml_MouseReleaseEvent*' , -'khtml::RenderObject*' => 'kde_khtml_RenderObject*' , -'khtml::RenderStyle*' => 'kde_khtml_RenderStyle*' , -'khtml__DrawContentsEvent*' => 'kde_khtml__DrawContentsEvent*', -'khtml__MouseDoubleClickEvent*' => 'kde_khtml__MouseDoubleClickEvent*', -'khtml__MouseEvent*' => 'kde_khtml__MouseEvent*', -'khtml__MouseMoveEvent*' => 'kde_khtml__MouseMoveEvent*', -'khtml__MousePressEvent*' => 'kde_khtml__MousePressEvent*', -'khtml__MouseReleaseEvent*' => 'kde_khtml__MouseReleaseEvent*', 'kndbgstream&' => 'void**' , 'kndbgstream*' => 'kde_kndbgstream*', 'ksockaddr_in*' => 'void*' , -'long _blockSize *' => 'long *', +'long _blockSize*' => 'long*', 'long int' => 'long', 'long unsigned int' => 'long', 'long&' => 'long' , @@ -2767,9 +2688,9 @@ BEGIN 'long_blockSize*' => 'long_blockSize*' , 'longint' => 'long', 'longunsigned int' => 'unsigned long', -'lt_dlhandle' => 'void *' , +'lt_dlhandle' => 'void*' , 'lt_user_dlloader*' => 'kde_lt_user_dlloader*', -'mcopbyte&' => 'void *', +'mcopbyte&' => 'void*', 'mcopbyte' => 'unsigned char', 'mode_t _mode (mode_t) -1' => 'int', 'mode_t' => 'long' , @@ -2794,8 +2715,8 @@ BEGIN 'snd_seq_event_t*' => 'int*', 'ssize_t' => 'int', 'std*' => 'kde_std*', -'std::string&' => 'char *' , -'std::string' => 'char *' , +'std::string&' => 'char*' , +'std::string' => 'char*' , 'time_t' => 'long' , 'timeval&' => 'int', 'true' => '1', @@ -2833,22 +2754,18 @@ BEGIN 'void(*)()' => 'void(*)()' , 'void*' => 'void*', '~' => '~', -'TQValueList' => 'qt_TQIntValueList*', -'TQValueList&' => 'qt_TQIntValueList*', -'TQValueList' => 'qt_TQIconDragItemValueList*', -'TQValueList&' => 'qt_TQIconDragItemValueList*', -'TQValueList' => 'qt_TQPixmapValueList*', -'TQValueList&' => 'qt_TQStringValueList*', -'TQValueList&' => 'qt_TQVariantValueList*', -'TQValueList*' => 'qt_TQUrlInfoValueList*', +'TQValueList' => 'qt_QIntValueList*', +'TQValueList&' => 'qt_QIntValueList*', +'TQValueList' => 'qt_QIconDragItemValueList*', +'TQValueList&' => 'qt_QIconDragItemValueList*', +'TQValueList' => 'qt_QPixmapValueList*', +'TQValueList&' => 'qt_QStringValueList*', +'TQValueList&' => 'qt_QVariantValueList*', +'TQValueList*' => 'qt_QUrlInfoValueList*', 'TQValueList&' => 'kde_KDataToolInfoValueList*', -'TQPtrList&' => 'kde_KActionPtrList*', -'TQPtrList&' => 'kde_KSSLCertificatePtrList*', -'TQPtrList*' => 'kde_KXMLGUIClientPtrList*', -'TQPtrList*' => 'qt_TQDockWindowPtrList*', -'TQPtrList' => 'qt_TQPixmapPtrList*', -'TQPtrList' => 'qt_TQPointPtrList*', -'KService::Ptr&' => 'kde_KServicePtr*', +'TQPtrList*' => 'qt_QDockWindowPtrList*', +'TQPtrList' => 'qt_QPixmapPtrList*', +'TQPtrList' => 'qt_QPointPtrList*', 'ClassContext*' => 'kde_ClassContext*', 'ClassStoreIface*' => 'kde_ClassStoreIface*', 'ClipboardDocumentIface*' => 'kde_ClipboardDocumentIface*', @@ -3021,6 +2938,22 @@ sub resolveType($$$) # Look for builtin words (int etc.) return $builtins{ $argType } if exists $builtins{ $argType }; + # take recursive care of templated types + if($argType =~ /([\w_]+\s*)<(.*)>/) { + my $tmpl = $2; + my $before = $`.$1; + my $after = $'; + my @args = kdocUtil::splitUnnested( ',', $tmpl); + grep s/^\s+//, @args; + grep s/\s+$//, @args; + for my $a(@args) { + $a = resolveType( $a, $contextClass, $rootnode ); + } + # normalize + $argType = $before."<".join( ", ", @args).">".$after; + $argType =~ s/>>/> >/g; # Nested template types must have a space + } + # Parse 'const' in front of it, and '*' or '&' after it my $prefix = $argType =~ s/^const\s+// ? 'const ' : ''; my $suffix = $argType =~ s/\s*([\&\*]+)$// ? $1 : ''; @@ -3030,6 +2963,12 @@ sub resolveType($$$) my $result = resolveTypeInternal( $argType, $contextClass, $rootnode ); return $prefix.$result.$suffix if $result; + # If the parent is a namespace, have a look there + if ($contextClass->{Parent} && $contextClass->{Parent}->{NodeType} eq 'namespace') { + $result = resolveTypeInternal( $argType, $contextClass->{Parent}, $rootnode ); + return $prefix.$result.$suffix if $result; + } + # Not found, so look as a toplevel class #print "Checking that ".$argType." exists.\n"; return $prefix.$argType.$suffix if ( kdocAstUtil::findRef( $rootnode, $argType ) ); diff --git a/kalyptus/kdocAstUtil.pm b/kalyptus/kdocAstUtil.pm index 9c8c0dd..8c24430 100644 --- a/kalyptus/kdocAstUtil.pm +++ b/kalyptus/kdocAstUtil.pm @@ -442,6 +442,33 @@ sub inheritedBy } } +=head2 inheritsAsVirtual + + Parameters: (selfNode) classNode + + Tells if C is a virtual ancestor of C + e.g: $self->kdocAstUtil::inheritsAsVirtual($other) + +=cut + +sub inheritsAsVirtual +{ + my ( $self, $node ) = @_; + + return 0 unless exists $self->{InList}; + + for my $in( @{ $self->{InList} } ) + { + return 1 if + inheritName($in) eq $node->{astNodeName} and + $in->{Type} =~ /virtual/; + return 1 if $in->{Node} && + $in->{Node}->kdocAstUtil::inheritsAsVirtual( $node ); + } + return 0 +} + + =head2 hasLocalInheritor Parameter: node diff --git a/kalyptus/kdocLib.pm b/kalyptus/kdocLib.pm index 3c0b727..700564a 100644 --- a/kalyptus/kdocLib.pm +++ b/kalyptus/kdocLib.pm @@ -29,7 +29,7 @@ NOTES ON THE NEW FORMAT - + diff --git a/kalyptus/kdocParseDoc.pm b/kalyptus/kdocParseDoc.pm index e5f19d5..f28b4e5 100644 --- a/kalyptus/kdocParseDoc.pm +++ b/kalyptus/kdocParseDoc.pm @@ -85,6 +85,9 @@ PARSELOOP: elsif ( $text =~ /^\s*\@deprecated\s*/ ) { codeProp( "Deprecated", 1 ); } + elsif ( $text =~ /^\s*\@obsolete\s*/ ) { + codeProp( "Deprecated", 1 ); + } elsif ( $text =~ /^\s*\@reimplemented\s*/ ) { codeProp( "Reimplemented", 1 ); } diff --git a/kalyptus/kdocUtil.pm b/kalyptus/kdocUtil.pm index e045a67..f77c083 100644 --- a/kalyptus/kdocUtil.pm +++ b/kalyptus/kdocUtil.pm @@ -161,23 +161,28 @@ sub splitUnnested($$) { my $depth = 0; my $start = 0; my $indoublequotes = 0; - while($string =~ /($delim|<<|>>|[][}{)(><\"])/g) { + my $insinglequotes = 0; + while($string =~ /($delim|<<|>>|[][}{)(><\"\'])/g) { my $c = $1; - if(!$depth and !$indoublequotes and $c eq $delim) { - my $len = pos($string) - $start - 1; - push @ret, substr($string, $start, $len); - $start = pos($string); - } elsif($open{$c}) { - $depth++; - } elsif($close{$c}) { - $depth--; - } elsif($c eq '"') { - if ($indoublequotes) { - $indoublequotes = 0; - } else { + if(!$insinglequotes and !$indoublequotes) { + if(!$depth and $c eq $delim) { + my $len = pos($string) - $start - 1; + push @ret, substr($string, $start, $len); + $start = pos($string); + } elsif( $c eq "'") { + $insinglequotes = 1; + } elsif( $c eq '"') { $indoublequotes = 1; - } - } + } elsif($open{$c}) { + $depth++; + } elsif($close{$c}) { + $depth--; + } + } elsif($c eq '"' and $indoublequotes) { + $indoublequotes = 0; + } elsif ($c eq "'" and $insinglequotes) { + $insinglequotes = 0; + } } my $subs = substr($string, $start); diff --git a/kalyptus/perlbin b/kalyptus/perlbin new file mode 100644 index 0000000..227afff --- /dev/null +++ b/kalyptus/perlbin @@ -0,0 +1 @@ +/usr/bin/perl