summaryrefslogtreecommitdiffstats
path: root/kalyptus
diff options
context:
space:
mode:
Diffstat (limited to 'kalyptus')
-rw-r--r--kalyptus/Ast.pm91
-rw-r--r--kalyptus/ChangeLog385
-rw-r--r--kalyptus/Iter.pm532
-rw-r--r--kalyptus/Makefile.cvs5
-rw-r--r--kalyptus/Makefile.in53
-rw-r--r--kalyptus/README92
-rw-r--r--kalyptus/TODO7
-rw-r--r--kalyptus/Version1
-rw-r--r--kalyptus/configure.in28
-rwxr-xr-xkalyptus/dcopidlng12
-rwxr-xr-xkalyptus/findperl17
-rw-r--r--kalyptus/install-sh251
-rw-r--r--kalyptus/kalyptus1829
-rw-r--r--kalyptus/kalyptus.spec.in62
-rw-r--r--kalyptus/kalyptusCxxToCSharp.pm764
-rw-r--r--kalyptus/kalyptusCxxToDcopIDL.pm1126
-rw-r--r--kalyptus/kalyptusCxxToECMA.pm570
-rw-r--r--kalyptus/kalyptusCxxToJNI.pm5595
-rw-r--r--kalyptus/kalyptusCxxToJava.pm3434
-rw-r--r--kalyptus/kalyptusCxxToKimono.pm3633
-rw-r--r--kalyptus/kalyptusCxxToSmoke.pm2759
-rw-r--r--kalyptus/kalyptusCxxToSwig.pm996
-rw-r--r--kalyptus/kalyptusDataDict.pm2981
-rw-r--r--kalyptus/kdocAstUtil.pm789
-rw-r--r--kalyptus/kdocLib.pm245
-rw-r--r--kalyptus/kdocParseDoc.pm422
-rw-r--r--kalyptus/kdocUtil.pm194
-rw-r--r--kalyptus/perlbin1
28 files changed, 26874 insertions, 0 deletions
diff --git a/kalyptus/Ast.pm b/kalyptus/Ast.pm
new file mode 100644
index 00000000..0fb4bd0d
--- /dev/null
+++ b/kalyptus/Ast.pm
@@ -0,0 +1,91 @@
+package Ast;
+use strict;
+
+use vars qw/ $this $pack @endCodes /;
+
+#-----------------------------------------------------------------------------
+# This package is used to create a simple Abstract Syntax tree. Each node
+# in the AST is an associative array and supports two kinds of properties -
+# scalars and lists of scalars.
+# See SchemParser.pm for an example of usage.
+# ... Sriram
+#-----------------------------------------------------------------------------
+
+# Constructor
+# e.g AST::New ("personnel")
+# Stores the argument in a property called astNodeName whose sole purpose
+# is to support Print()
+
+sub New {
+ my ($this) = {"astNodeName" => $_[0]};
+ bless ($this);
+ return $this;
+}
+
+# Add a property to this object
+# $astNode->AddProp("className", "Employee");
+
+sub AddProp {
+ my ($this) = $_[0];
+ $this->{$_[1]} = $_[2];
+}
+
+# Equivalent to AddProp, except the property name is associated
+# with a list of values
+# $classAstNode->AddProp("attrList", $attrAstNode);
+
+sub AddPropList {
+ my ($this) = $_[0];
+ if (! exists $this->{$_[1]}) {
+ $this->{$_[1]} = [];
+ }
+ push (@{$this->{$_[1]}}, $_[2]);
+}
+
+# Returns a list of all the property names of this object
+sub GetProps {
+ my ($this) = $_[0];
+ return keys %{$this};
+}
+
+sub Visit {
+ # Converts each of this AstNode's properties into global variables.
+ # The global variables are introduced into package "main"
+ # At the same time, a piece of code is formed to undo this work above -
+ # $endCode essentially contains the values of these global variables
+ # before they are mangled. endCode gets pushed into a stack (endCodes),
+ # which is unwound by UnVisit().
+
+ local ($this, $pack) = @_;
+
+
+ my $code = "";
+ my $endCode = "";
+
+
+ foreach my $k (keys %{$this}) {
+
+ my $glob = $pack."::".$k;
+
+ if ( defined $$glob ) {
+
+ if ( ${$glob} ne "" ) {
+ $$glob =~ s/\'/\\\'/g;
+ }
+
+ $endCode .= '$'.$pack.'::'.$k. " = '".$$glob."';";
+ } else {
+ $endCode .= '$'.$pack . "::". $k . ' = "";';
+ }
+ $code .= '$'.$pack . "::" . $k . "= \$this->{\"$k\"};";
+ }
+ push (@endCodes, $endCode);
+ eval($code) if $code;
+}
+
+sub UnVisit {
+ my $code = pop(@endCodes);
+ eval($code) if ($code);
+}
+
+1;
diff --git a/kalyptus/ChangeLog b/kalyptus/ChangeLog
new file mode 100644
index 00000000..adcb5ce4
--- /dev/null
+++ b/kalyptus/ChangeLog
@@ -0,0 +1,385 @@
+2005-09-26 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * Some fixes/enhancements from the trunk version. Most
+ importantly generating accessor methods to get and set
+ public instance variables.
+
+2005-02-17 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * Added a '--qt4' option to parse Qt 4 headers
+
+2005-02-06 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * Fixed problem where a call to super in java QWidet.polish() caused a loop
+ * DCOPArg and DCOPReply are ignored for java bindings generation
+
+2004-09-10 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * Fixed Smoke library generation for KDE 3.1
+
+2004-09-05 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * Removed forward declarations for classes embedded in method return types.
+ For instance:
+ virtual class View *createView ( QWidget *parent, const char *name = 0 ) = 0;
+ virtual QPtrList<class View> views () const = 0;
+ * Added kate as a KDE include header subdirectory
+
+
+2004-09-05 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * Added kontact to the expected KDE header subdirectory names
+ * Fixed a bug in the code generation for this method:
+
+ virtual QValueList<Kontact::Plugin*> pluginList() const = 0;
+
+ It was being incorrectly treated as a pointer type, because it contained as asterisk.
+
+2004-08-19 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * QMap and QPair template types such as 'QMap<QCString, DCOPRef>' with an
+ embedded comma, were not being correctly normalised. A space was left in
+ the smoke type.
+
+2004-07-25 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * After discussion with Germain Garand, QChars have been returned to
+ the Smoke runtime as first class members.
+
+2004-07-07 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * The QChar class is now treated as a primitive type just like QString.
+
+2004-06-30 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * Removed KMultiTabBarTab and KMultiTabBarButton from the Smoke runtime
+ * Added an instance variable '_smokeObject' to generated C# Kimono classes
+
+2004-06-09 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * Added patch from Michal Ceresna to fix code generation for QImage.bits() and
+ QImage.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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * The methods QPainter::pos() and QFontInfo::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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 QMainWindow return a QToolBar
+ and QMenuBar, rather than their KDE equivalent subclasses.
+
+2004-05-19 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * Now only 55 Qt C# warnings, too much use of the 'new' inheritance directive
+ though.
+
+2004-04-26 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <remarks> 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * Removed obsolete C and Objective-C code generation options
+
+2004-03-19 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * '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 kdebindings/smoke/kde/generate.pl.in
+ and change '-fsmoke' to '-fkimono'. Then configure kdebindings 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 kdebindings/smoke/kde/generate.pl.in. Then
+ configure kdebindings 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 QGlobalSpace.
+ 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * Avoid generating wrappers for private classes with 'Private',
+ 'Impl' or 'Internal' in the name. Other unneeded classes also
+ dropped.
+
+2003-10-08 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * Added various parser and code generation fixes so that a libsmokekde.so
+ can be generated from the kdelibs headers.
+
+2003-08-30 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * Applied Germain Garand's patch to no longer rename operator methods
+ in the QGlobalSpace pseudo class
+
+2003-08-21 Alexander Kellett <lypanov@kde.org>
+
+ * Added .kidl generation option (dcopidl replacement)
+ * Handled of several new constructs in the parsing:
+ * k_dcop: / k_dcop_signals: / K_DCOP:
+ * Use STDERR not STDOUT thus removing need for temporary file
+
+2003-08-21 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * Added missing getClassLoader() call to Proxy constructor
+
+2003-08-21 Richard Dale <Richard_Dale@tipitina.demon.co.uk>
+
+ * 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 <Richard_Dale@tipitina.demon.co.uk>
+
+ * Removed old SWIG style ruby generation option
+
+2003-08-09 Alexander Kellett <lypanov@kde.org>
+
+ * Parse static friend operator methods and place into a pseudo class (for smoke)
+
+2002-06-03 David Faure <faure@kde.org>
+
+ * The Smoke generation is in good shape. Removed old PerlPig and PerlQK
+ modules.
+
+2002-04-23 Richard Dale <duke@tipitina.demon.co.uk>
+
+ * Added patch from David Faure to correctly handle nested struct
+ or class names in perl .pig generation
+
+2002-03-15 Richard Dale <duke@tipitina.demon.co.uk>
+ * Added C# P/Invoke bindings generation option from Adam Treat
+2002-02-10 Richard Dale <duke@tipitina.demon.co.uk>
+ * Improved C destructor code generation
+ * QCanvasItemList mapped onto java.util.ArrayList
+ * 'bool *' type converted to java 'boolean[]' type.
+2002-02-03 Richard Dale <duke@tipitina.demon.co.uk>
+
+ * More fixes to .pig generation from Germain. Perl porting now
+ motoring 24*7...
+2002-02-02 Richard Dale <duke@tipitina.demon.co.uk>
+ * Various improvements to Perl .pig generation from Germain Garand
+2002-01-31 Richard Dale <duke@tipitina.demon.co.uk>
+ * Fixed bug in code generation for NULL default arguments
+ * Added some new KDE 3 types
+2002-01-26 Richard Dale <duke@tipitina.demon.co.uk>
+ * Perl .pig generation improved
+2002-01-25 Richard Dale <duke@tipitina.demon.co.uk>
+ * Added '-fperl' option to autogenerate .pig (Perl Interface
+ Generator) files, suitable for generating Ashley Winters' PerlQt/KDEQt
+ bindings
+2002-01-23 Richard Dale <duke@tipitina.demon.co.uk>
+ * Made dispose() public, added isDisposed() after SWT.
+2002-01-23 Richard Dale <duke@tipitina.demon.co.uk>
+ * Added generation of dispose() methods, to allow large resources,
+ such as pixmaps, to be freed before finalize() is called.
+2002-01-20 Richard Dale <duke@tipitina.demon.co.uk>
+ * Ruby bindings generation - initial checkin.
+2002-01-04 Richard Dale <duke@tipitina.demon.co.uk>
+ * Fixed bug in parsing decimal point in default argument values
+2001-12-29 Richard Dale <duke@tipitina.demon.co.uk
+ * JNI event handling methods are now generated.
+ * Some additions for KDevelop types.
+ * Removed assumption that a class ending in '..Interface' should always
+ be a java interface.
+2001-12-17 Richard Dale <duke@tipitina.demon.co.uk
+ * Improved code generation for String f'ns with default arguments.
+ * An implementation is no longer generated for classes which are
+ just interfaces.
+2001-12-03 Richard Dale <duke@tipitina.demon.co.uk
+ * Added new KDE 3 data types
+ * Improved code generation for classes defined within namespaces
+
diff --git a/kalyptus/Iter.pm b/kalyptus/Iter.pm
new file mode 100644
index 00000000..7279a6fa
--- /dev/null
+++ b/kalyptus/Iter.pm
@@ -0,0 +1,532 @@
+package Iter;
+
+=head1 Iterator Module
+
+A set of iterator functions for traversing the various trees and indexes.
+Each iterator expects closures that operate on the elements in the iterated
+data structure.
+
+
+=head2 Generic
+
+ Params: $node, &$loopsub, &$skipsub, &$applysub, &$recursesub
+
+Iterate over $node\'s children. For each iteration:
+
+If loopsub( $node, $kid ) returns false, the loop is terminated.
+If skipsub( $node, $kid ) returns true, the element is skipped.
+
+Applysub( $node, $kid ) is called
+If recursesub( $node, $kid ) returns true, the function recurses into
+the current node.
+
+=cut
+
+sub Generic
+{
+ my ( $root, $loopcond, $skipcond, $applysub, $recursecond ) = @_;
+
+ return sub {
+ foreach my $node ( @{$root->{Kids}} ) {
+
+ if ( defined $loopcond ) {
+ return 0 unless $loopcond->( $root, $node );
+ }
+
+ if ( defined $skipcond ) {
+ next if $skipcond->( $root, $node );
+ }
+
+ my $ret = $applysub->( $root, $node );
+ return $ret if defined $ret && $ret;
+
+ if ( defined $recursecond
+ && $recursecond->( $root, $node ) ) {
+ $ret = Generic( $node, $loopcond, $skipcond,
+ $applysub, $recursecond)->();
+ if ( $ret ) {
+ return $ret;
+ }
+ }
+ }
+
+ return 0;
+ };
+}
+
+sub Class
+{
+ my ( $root, $applysub, $recurse ) = @_;
+
+ return Generic( $root, undef,
+ sub {
+ return !( $node->{NodeType} eq "class"
+ || $node->{NodeType} eq "struct" );
+ },
+ $applysub, $recurse );
+}
+
+=head2 Tree
+
+ Params: $root, $recurse?, $commonsub, $compoundsub, $membersub,
+ $skipsub
+
+Traverse the ast tree starting at $root, skipping if skipsub returns true.
+
+Applying $commonsub( $node, $kid),
+then $compoundsub( $node, $kid ) or $membersub( $node, $kid ) depending on
+the Compound flag of the node.
+
+=cut
+
+sub Tree
+{
+ my ( $rootnode, $recurse, $commonsub, $compoundsub, $membersub,
+ $skipsub ) = @_;
+
+ my $recsub = $recurse ? sub { return 1 if $_[1]->{Compound}; }
+ : undef;
+
+ Generic( $rootnode, undef, $skipsub,
+ sub { # apply
+ my ( $root, $node ) = @_;
+ my $ret;
+
+ if ( defined $commonsub ) {
+ $ret = $commonsub->( $root, $node );
+ return $ret if defined $ret;
+ }
+
+ if ( $node->{Compound} && defined $compoundsub ) {
+ $ret = $compoundsub->( $root, $node );
+ return $ret if defined $ret;
+ }
+
+ if( !$node->{Compound} && defined $membersub ) {
+ $ret = $membersub->( $root, $node );
+ return $ret if defined $ret;
+ }
+ return;
+ },
+ $recsub # skip
+ )->();
+}
+
+=head2 LocalCompounds
+
+Apply $compoundsub( $node ) to all locally defined compound nodes
+(ie nodes that are not external to the library being processed).
+
+=cut
+
+sub LocalCompounds
+{
+ my ( $rootnode, $compoundsub ) = @_;
+
+ return unless defined $rootnode && defined $rootnode->{Kids};
+
+ foreach my $kid ( sort { $a->{astNodeName} cmp $b->{astNodeName} }
+ @{$rootnode->{Kids}} ) {
+ next if !defined $kid->{Compound};
+
+ $compoundsub->( $kid ) unless defined $kid->{ExtSource};
+ LocalCompounds( $kid, $compoundsub );
+ }
+}
+
+=head2 Hierarchy
+
+ Params: $node, $levelDownSub, $printSub, $levelUpSub
+
+This allows easy hierarchy traversal and printing.
+
+Traverses the inheritance hierarchy starting at $node, calling printsub
+for each node. When recursing downward into the tree, $levelDownSub($node) is
+called, the recursion takes place, and $levelUpSub is called when the
+recursion call is completed.
+
+=cut
+
+sub Hierarchy
+{
+ my ( $node, $ldownsub, $printsub, $lupsub, $nokidssub ) = @_;
+
+ return if defined $node->{ExtSource}
+ && (!defined $node->{InBy}
+ || !kdocAstUtil::hasLocalInheritor( $node ));
+
+ $printsub->( $node );
+
+ if ( defined $node->{InBy} ) {
+ $ldownsub->( $node );
+
+ foreach my $kid (
+ sort {$a->{astNodeName} cmp $b->{astNodeName}}
+ @{ $node->{InBy} } ) {
+ Hierarchy( $kid, $ldownsub, $printsub, $lupsub );
+ }
+
+ $lupsub->( $node );
+ }
+ elsif ( defined $nokidssub ) {
+ $nokidssub->( $node );
+ }
+
+ return;
+}
+
+=head2
+
+ Call $printsub for each *direct* ancestor of $node.
+ Only multiple inheritance can lead to $printsub being called more than once.
+
+=cut
+sub Ancestors
+{
+ my ( $node, $rootnode, $noancessub, $startsub, $printsub,
+ $endsub ) = @_;
+ my @anlist = ();
+
+ return if $node eq $rootnode;
+
+ if ( !exists $node->{InList} ) {
+ $noancessub->( $node ) unless !defined $noancessub;
+ return;
+ }
+
+ foreach my $innode ( @{ $node->{InList} } ) {
+ my $nref = $innode->{Node}; # real ancestor
+ next if defined $nref && $nref == $rootnode;
+
+ push @anlist, $innode;
+ }
+
+ if ( $#anlist < 0 ) {
+ $noancessub->( $node ) unless !defined $noancessub;
+ return;
+ }
+
+ $startsub->( $node ) unless !defined $startsub;
+
+ foreach my $innode ( sort { $a->{astNodeName} cmp $b->{astNodeName} }
+ @anlist ) {
+
+ # print
+ $printsub->( $innode->{Node}, $innode->{astNodeName},
+ $innode->{Type}, $innode->{TmplType} )
+ unless !defined $printsub;
+ }
+
+ $endsub->( $node ) unless !defined $endsub;
+
+ return;
+
+}
+
+sub Descendants
+{
+ my ( $node, $nodescsub, $startsub, $printsub, $endsub ) = @_;
+
+ if ( !exists $node->{InBy} ) {
+ $nodescsub->( $node ) unless !defined $nodescsub;
+ return;
+ }
+
+
+ my @desclist = ();
+ DescendantList( \@desclist, $node );
+
+ if ( $#desclist < 0 ) {
+ $nodescsub->( $node ) unless !defined $nodescsub;
+ return;
+ }
+
+ $startsub->( $node ) unless !defined $startsub;
+
+ foreach my $innode ( sort { $a->{astNodeName} cmp $b->{astNodeName} }
+ @desclist ) {
+
+ $printsub->( $innode)
+ unless !defined $printsub;
+ }
+
+ $endsub->( $node ) unless !defined $endsub;
+
+ return;
+
+}
+
+sub DescendantList
+{
+ my ( $list, $node ) = @_;
+
+ return unless exists $node->{InBy};
+
+ foreach my $kid ( @{ $node->{InBy} } ) {
+ push @$list, $kid;
+ DescendantList( $list, $kid );
+ }
+}
+
+=head2 DocTree
+
+=cut
+
+sub DocTree
+{
+ my ( $rootnode, $allowforward, $recurse,
+ $commonsub, $compoundsub, $membersub ) = @_;
+
+ Generic( $rootnode, undef,
+ sub { # skip
+ my( $node, $kid ) = @_;
+
+ unless (!(defined $kid->{ExtSource})
+ && ($allowforward || $kid->{NodeType} ne "Forward")
+ && ($main::doPrivate || !($kid->{Access} =~ /private/))
+ && exists $kid->{DocNode} ) {
+
+ return 1;
+ }
+
+ return;
+ },
+ sub { # apply
+ my ( $root, $node ) = @_;
+
+ my $ret;
+
+ if ( defined $commonsub ) {
+ $ret = $commonsub->( $root, $node );
+ return $ret if defined $ret;
+ }
+
+ if ( $node->{Compound} && defined $compoundsub ) {
+ $ret = $compoundsub->( $root, $node );
+ return $ret if defined $ret;
+ }
+ elsif( defined $membersub ) {
+ $ret = $membersub->( $root, $node );
+ return $ret if defined $ret;
+ }
+
+ return;
+ },
+ sub { return 1 if $recurse; return; } # recurse
+ )->();
+
+}
+
+sub MembersByType
+{
+ my ( $node, $startgrpsub, $methodsub, $endgrpsub, $nokidssub ) = @_;
+
+# public
+ # types
+ # data
+ # methods
+ # signals
+ # slots
+ # static
+# protected
+# private (if enabled)
+
+ if ( !defined $node->{Kids} ) {
+ $nokidssub->( $node ) if defined $nokidssub;
+ return;
+ }
+
+ foreach my $acc ( qw/public protected private/ ) {
+ next if $acc eq "private" && !$main::doPrivate;
+ $access = $acc;
+
+ my @types = ();
+ my @data = ();
+ my @signals = ();
+ my @k_dcops = ();
+ my @k_dcop_signals = ();
+ my @k_dcop_hiddens = ();
+ my @slots =();
+ my @methods = ();
+ my @static = ();
+ my @modules = ();
+ my @interfaces = ();
+
+ # Build lists
+ foreach my $kid ( @{$node->{Kids}} ) {
+ next unless ( $kid->{Access} =~ /$access/
+ && !$kid->{ExtSource})
+ || ( $access eq "public"
+ && ( $kid->{Access} eq "signals"
+ || $kid->{Access} =~ "k_dcop" # note the =~
+ || $kid->{Access} eq "K_DCOP"));
+
+ my $type = $kid->{NodeType};
+
+ if ( $type eq "method" ) {
+ if ( $kid->{Flags} =~ "s" ) {
+ push @static, $kid;
+ }
+ elsif ( $kid->{Flags} =~ "l" ) {
+ push @slots, $kid;
+ }
+ elsif ( $kid->{Flags} =~ "n" ) {
+ push @signals, $kid;
+ }
+ elsif ( $kid->{Flags} =~ "d" ) {
+ push @k_dcops, $kid;
+ }
+ elsif ( $kid->{Flags} =~ "z" ) {
+ push @k_dcop_signals, $kid;
+ }
+ elsif ( $kid->{Flags} =~ "y" ) {
+ push @k_dcop_hiddens, $kid;
+ }
+ else {
+ push @methods, $kid; }
+ }
+ elsif ( $kid->{Compound} ) {
+ if ( $type eq "module" ) {
+ push @modules, $kid;
+ }
+ elsif ( $type eq "interface" ) {
+ push @interfaces, $kid;
+ }
+ else {
+ push @types, $kid;
+ }
+ }
+ elsif ( $type eq "typedef" || $type eq "enum" ) {
+ push @types, $kid;
+ }
+ else {
+ push @data, $kid;
+ }
+ }
+
+ # apply
+ $uc_access = ucfirst( $access );
+
+ doGroup( "$uc_access Types", $node, \@types, $startgrpsub,
+ $methodsub, $endgrpsub);
+ doGroup( "Modules", $node, \@modules, $startgrpsub,
+ $methodsub, $endgrpsub);
+ doGroup( "Interfaces", $node, \@interfaces, $startgrpsub,
+ $methodsub, $endgrpsub);
+ doGroup( "$uc_access Methods", $node, \@methods, $startgrpsub,
+ $methodsub, $endgrpsub);
+ doGroup( "$uc_access Slots", $node, \@slots, $startgrpsub,
+ $methodsub, $endgrpsub);
+ doGroup( "Signals", $node, \@signals, $startgrpsub,
+ $methodsub, $endgrpsub);
+ doGroup( "k_dcop", $node, \@k_dcops, $startgrpsub,
+ $methodsub, $endgrpsub);
+ doGroup( "k_dcop_signals", $node, \@k_dcop_signals, $startgrpsub,
+ $methodsub, $endgrpsub);
+ doGroup( "k_dcop_hiddens", $node, \@k_dcop_hiddens, $startgrpsub,
+ $methodsub, $endgrpsub);
+ doGroup( "$uc_access Static Methods", $node, \@static,
+ $startgrpsub, $methodsub, $endgrpsub);
+ doGroup( "$uc_access Members", $node, \@data, $startgrpsub,
+ $methodsub, $endgrpsub);
+ }
+}
+
+sub doGroup
+{
+ my ( $name, $node, $list, $startgrpsub, $methodsub, $endgrpsub ) = @_;
+
+ my ( $hasMembers ) = 0;
+ foreach my $kid ( @$list ) {
+ if ( !exists $kid->{DocNode}->{Reimplemented} ) {
+ $hasMembers = 1;
+ break;
+ }
+ }
+ return if !$hasMembers;
+
+ if ( defined $methodsub ) {
+ foreach my $kid ( @$list ) {
+ if ( !exists $kid->{DocNode}->{Reimplemented} ) {
+ $methodsub->( $node, $kid );
+ }
+ }
+ }
+
+ $endgrpsub->( $name ) if defined $endgrpsub;
+}
+
+sub ByGroupLogical
+{
+ my ( $root, $startgrpsub, $itemsub, $endgrpsub ) = @_;
+
+ return 0 unless defined $root->{Groups};
+
+ foreach my $groupname ( sort keys %{$root->{Groups}} ) {
+ next if $groupname eq "astNodeName"||$groupname eq "NodeType";
+
+ my $group = $root->{Groups}->{ $group };
+ next unless $group->{Kids};
+
+ $startgrpsub->( $group->{astNodeName}, $group->{Desc} );
+
+ foreach my $kid (sort {$a->{astNodeName} cmp $b->{astNodeName}}
+ @group->{Kids} ) {
+ $itemsub->( $root, $kid );
+ }
+ $endgrpsub->( $group->{Desc} );
+ }
+
+ return 1;
+}
+
+sub SeeAlso
+{
+ my ( $node, $nonesub, $startsub, $printsub, $endsub ) = @_;
+
+ if( !defined $node ) {
+ $nonesub->();
+ return;
+ }
+
+ my $doc = $node;
+
+ if ( $node->{NodeType} ne "DocNode" ) {
+ $doc = $node->{DocNode};
+ if ( !defined $doc ) {
+ $nonesub->() if defined $nonesub;
+ return;
+ }
+ }
+
+ if ( !defined $doc->{See} ) {
+ $nonesub->() if defined $nonesub;
+ return;
+ }
+
+ my $see = $doc->{See};
+ my $ref = $doc->{SeeRef};
+
+ if ( $#$see < 1 ) {
+ $nonesub->() if defined $nonesub;
+ return;
+ }
+
+ $startsub->( $node ) if defined $startsub;
+
+ for my $i ( 0..$#$see ) {
+ my $seelabel = $see->[ $i ];
+ my $seenode = undef;
+ if ( defined $ref ) {
+ $seenode = $ref->[ $i ];
+ }
+
+ $printsub->( $seelabel, $seenode ) if defined $printsub;
+ }
+
+ $endsub->( $node ) if defined $endsub;
+
+ return;
+}
+
+1;
diff --git a/kalyptus/Makefile.cvs b/kalyptus/Makefile.cvs
new file mode 100644
index 00000000..3c0d8063
--- /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 00000000..86061207
--- /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
new file mode 100644
index 00000000..373e4000
--- /dev/null
+++ b/kalyptus/README
@@ -0,0 +1,92 @@
+
+KALYPTUS -- C, Objective-C and Java bindings generator
+
+Version 0.9
+
+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.
+
+REQUIREMENTS
+
+You need perl 5.005 or greater to run kalyptus.
+
+HOWTO
+
+If you are running this straight from CVS, you will need to run
+
+ make -f Makefile.cvs
+
+before building.
+
+This should install kalyptus:
+
+./configure; make; make install
+
+CREDITS
+-------
+
+Richard Dale - kdoc adaption, C/Objective-C/Java code generation.
+
+Sirtaj Singh Kang for writing the original kdoc utility (kalyptus was
+derived from kdoc).
+
+Copyright(C) 2001, Lost Highway Ltd
+
+------
+
+Copyright(C) 1999, Sirtaj Singh Kang <taj@kde.org>
+Distributed under the GPL.
+
+NOTES ON USING THE CONVERTER
+----------------------------
+
+JAVA
+----
+
+Here are some of the shell commands that were used in the conversion process:
+
+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
+
+# Shorten generated filenames
+mv DOM__Node.cpp DOMNode.cpp
+mv DOM__Node.java DOMNode.java
+mv DOM__Document.cpp DOMDocument.cpp
+mv DOM__Document.java DOMDocument.java
+for FILE in *__* ; do
+ NAME=`echo $FILE | sed -e 's/^.*__//'`;
+ echo $NAME;
+ mv $FILE $NAME;
+done
+mv SlaveInterface.cpp Slave.cpp
+mv SlaveInterface.java Slave.java
+
+# Edit and Compile the generated java
+cd kdejava/koala/org/kde/koala
+make
+
+# Build C++ JNI .h header files
+cd qtjava/javalib/org/kde/qt
+for FILE in *.class ; do NAME=`echo $FILE | sed 's/.class//'`; echo $NAME; javah -classpath '../../..' org.kde.qt.$NAME ; done
+for FILE in org_kde* ; do NAME=`echo $FILE | sed -e 's/org_kde_qt_//'`; echo $NAME; mv $FILE $NAME; done
+
+cd kdejava/koala/org/kde/koala
+for FILE in *.class ; do NAME=`echo $FILE | sed 's/.class//'`; echo $NAME; javah -classpath '../../..:../../../../../qtjava/javalib/qtjava.jar' org.kde.koala.$NAME ; done
+for FILE in org_kde* ; do NAME=`echo $FILE | sed -e 's/org_kde_koala_//'`; echo $NAME; mv $FILE $NAME; done
+# Copy headers to kdejava/koala/kdejava
+
+# Check that the JNI .h function names match the .cpp ones
+cd kdejava/koala/org/kde/koala
+grep ^Java_ *.cpp | sed -e 's/^[^:]*:\([^(]*\).*/\1/' | grep -v '[/]' | sort | uniq > cpp.fns
+grep Java_ *.h | awk '{ print $4 }' | grep -v '[/]' | sort | uniq > h.fns
+kompare h.fns cpp.fns
+# Reconcile and fix any differences
+
+# Edit and compile the generated .cpp and .h files with KDevelop
+
diff --git a/kalyptus/TODO b/kalyptus/TODO
new file mode 100644
index 00000000..2f90a449
--- /dev/null
+++ b/kalyptus/TODO
@@ -0,0 +1,7 @@
+Add more target languages, such as PHP and Pascal
+
+Use a perl parser generator to define the grammar for
+ C++ method arguments.
+
+Write documentation for a how to on bindings generation.
+
diff --git a/kalyptus/Version b/kalyptus/Version
new file mode 100644
index 00000000..0ac647cf
--- /dev/null
+++ b/kalyptus/Version
@@ -0,0 +1 @@
+0.91
diff --git a/kalyptus/configure.in b/kalyptus/configure.in
new file mode 100644
index 00000000..8d19b4c7
--- /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 00000000..fc405047
--- /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 kdebindings/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 00000000..451758d7
--- /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 00000000..e9de2384
--- /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
new file mode 100644
index 00000000..c81668ca
--- /dev/null
+++ b/kalyptus/kalyptus
@@ -0,0 +1,1829 @@
+#!/usr/bin/perl
+
+# KDOC -- C++ and CORBA IDL interface documentation tool.
+# Sirtaj Singh Kang <taj@kde.org>, Jan 1999.
+# $Id$
+
+# All files in this project are distributed under the GNU General
+# Public License. This is Free Software.
+
+require 5.000;
+
+use Carp;
+use Getopt::Long;
+use File::Basename;
+use strict;
+
+use Ast;
+
+use kdocUtil;
+use kdocAstUtil;
+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 $qt_embedded $qt4 $striphpath $doPrivate $readstdin
+ $Version $quiet $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 $inNamespace %stats %definitions @inputqueue @codeqobject @qt4_codeqobject @qte_codeqobject /;
+
+## globals
+
+%rootNodes = (); # root nodes for each file type
+$declNodeType = undef; # last declaration type
+
+@includes_list = (); # list of files included from the parsed .h
+
+# All options
+
+%options = (); # hash of options (set getopt below)
+@formats_wanted = ();
+$libdir = $ENV{KDOCLIBS};
+$libname = "";
+$outputdir = ".";
+@libs = (); # list of includes
+$striphpath = 0;
+
+@includeclasses = (); # names of classes to include
+$includeclasses = "";
+
+$doPrivate = 0;
+$Version = "0.9";
+
+$quiet = 0;
+$debug = 0;
+$debuggen = 0;
+$parseonly = 0;
+$globalSpaceClassName = "QGlobalSpace";
+
+$currentfile = "";
+
+$cpp = 0;
+$defcppcmd = "g++ -Wp,-C -E";
+$cppcmd = "";
+
+$exe = basename $0;
+
+@inputqueue = ();
+@codeqobject = split "\n", <<CODE;
+public:
+ virtual QMetaObject *metaObject() const;
+ virtual const char *className() const;
+ virtual void* qt_cast( const char* );
+ virtual bool qt_invoke( int, QUObject* );
+ virtual bool qt_emit( int, QUObject* );
+ virtual bool qt_property( int, int, QVariant* );
+ static QMetaObject* staticMetaObject();
+ QObject* qObject();
+ static QString tr( const char *, const char * = 0 );
+ static QString trUtf8( const char *, const char * = 0 );
+private:
+CODE
+
+@qt4_codeqobject = split "\n", <<CODE;
+public:
+ static const QMetaObject staticMetaObject;
+ virtual const QMetaObject *metaObject() const;
+ virtual void *qt_metacast(const char *);
+ static inline QString tr(const char *s, const char *c = 0)
+ { return staticMetaObject.tr(s, c); }
+ virtual int qt_metacall(QMetaObject::Call, int, void **);
+private:
+CODE
+
+@qte_codeqobject = split "\n", <<CODE;
+public:
+ QMetaObject *metaObject() const {
+ return staticMetaObject();
+ }
+ const char *className() const;
+ static QMetaObject* staticMetaObject();
+ static QString tr( const char *, const char * = 0 );
+protected:
+ void initMetaObject();
+private:
+CODE
+
+# Supported formats
+%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',
+ c => 'const', l => 'slot', i => 'inline', n => 'signal',
+ d => 'k_dcop', z => 'k_dcop_signals', y => 'k_dcop_hidden' );
+
+@allowed_k_dcop_accesors = qw(k_dcop k_dcop_hidden k_dcop_signals);
+$allowed_k_dcop_accesors_re = join("|", @allowed_k_dcop_accesors);
+
+%definitions = {
+ _STYLE_CDE => '',
+ _STYLE_MOTIF => '',
+ _STYLE_MOTIF_PLUS => '',
+ PLUS => '',
+ _STYLE_PLATINUM => '',
+ _STYLE_SGI => '',
+ _STYLE_WINDOWS => '',
+ QT_STATIC_CONST => 'static const',
+ Q_EXPORT => '',
+ Q_EXPORT_CODECS_BIG5 => '',
+ Q_REFCOUNT => '',
+ QM_EXPORT_CANVAS => '',
+ QM_EXPORT_DNS => '',
+ QM_EXPORT_ICONVIEW => '',
+ QM_EXPORT_NETWORK => '',
+ QM_EXPORT_SQL => '',
+ QM_EXPORT_WORKSPACE => '',
+ 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 QMetaObject *metaObject() const;
+ virtual const char *className() const;
+ virtual bool qt_invoke( int, QUObject* );
+ virtual bool qt_emit( int, QUObject* );
+ static QString tr( const char *, const char * = 0 );
+ static QString trUtf8( const char *, const char * = 0 );
+private:
+CODE
+};
+
+=head1 KDOC -- Source documentation tool
+
+ Sirtaj Singh Kang <taj@kde.org>, Dec 1998.
+
+=cut
+
+# read options
+
+Getopt::Long::config qw( no_ignore_case permute bundling auto_abbrev );
+
+GetOptions( \%options,
+ "format|f=s", \@formats_wanted,
+ "url|u=s",
+ "skip-internal", \$skipInternal,
+ "skip-deprecated|e",
+ "document-all|a",
+ "compress|z",
+ "no-cache", # do not create $HOME/.kalyptus cache
+ # HTML options
+ "html-cols=i",
+ "html-logo=s",
+
+ "strip-h-path", \$striphpath,
+ "outputdir|d=s", \$outputdir,
+ "stdin|i", \$readstdin,
+ "name|n=s", \$libname,
+ "help|h", \&show_usage,
+ "version|v|V", \&show_version,
+ "private|p", \$doPrivate,
+ "libdir|L=s", \$libdir,
+ "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,
+ "docincluded", \$docincluded,
+ "cppcmd|C=s", \$cppcmd,
+ "includedir|I=s", \@includes,
+ "define=s", \%defines, # define a single preprocessing symbol
+ "defines=s", \$defines, # file containing preprocessing symbols, one per line
+
+ "quiet|q", \$quiet,
+ "debug|D", \$debug, # debug the parsing
+ "debuggen", \$debuggen, # debug the file generation
+ "parse-only", \$parseonly )
+ || exit 1;
+
+$| = 1 if $debug or $debuggen;
+
+# preprocessor settings
+
+if ( $cppcmd eq "" ) {
+ $cppcmd = $defcppcmd;
+}
+else {
+ $cpp = 1;
+}
+
+if ($#includeclasses>=0)
+{
+ $includeclasses = join (" ", @includeclasses);
+ print "Using Classes: $includeclasses\n" unless $quiet;
+}
+
+if ( $#includes >= 0 && !$cpp ) {
+ die "$exe: --includedir requires --cpp\n";
+}
+
+# Check output formats. HTML is the default
+if( $#formats_wanted < 0 ) {
+ push @formats_wanted, "java";
+}
+
+foreach my $format ( @formats_wanted ) {
+ die "$exe: unsupported format '$format'.\n"
+ if !defined $formats{$format};
+}
+
+if( $defines )
+{
+ open( DEFS, $defines ) or die "Couldn't open $defines: $!\n";
+ my @defs = <DEFS>;
+ chomp @defs;
+ close DEFS;
+ foreach (@defs)
+ {
+ $defines{ $_ } = 1 unless exists $defines{ $_ };
+ }
+}
+
+# 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/^QT_(.*)/)[0] } keys %defines)
+{
+ 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\\s+QT_/ || return 0;
+ if(!\$1) { return \$s=~$regexp ? 0:1 }
+ else { return \$s=~$regexp ? 1:0 }
+ }";
+ die if $@;
+}
+else
+{
+ $match_qt_defines = eval q{
+ sub
+ {
+ my $s = shift;
+ $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.
+# We do it here to prevent the libraries being loaded up first.
+
+checkFileArgs();
+
+# work out libdir. This is created by kdocLib:writeDoc when
+# required.
+$libdir = $ENV{HOME}."/.kalyptus" unless $libdir ne "";
+
+
+######
+###### main program
+######
+ readLibraries();
+ parseFiles();
+
+ if ( $parseonly ) {
+ print "\n\tParse Tree\n\t------------\n\n";
+ kdocAstUtil::dumpAst( $rootNode );
+ }
+ else {
+ writeDocumentation();
+ writeLibrary() unless $libname eq "";
+ }
+
+ kdocAstUtil::printDebugStats() if $debug;
+
+ exit 0;
+######
+
+sub checkFileArgs
+{
+ return unless $#ARGV < 0;
+
+ die "$exe: no input files.\n" unless $readstdin;
+
+ # read filenames from standard input
+ while (<STDIN>) {
+ chop;
+ $_ =~ s,\\,/,g; # back to fwd slash (for Windows)
+ foreach my $file ( split( /\s+/, $_ ) ) {
+ push @ARGV, $file;
+ }
+ }
+}
+
+sub readLibraries
+{
+ return if $#libs < 0;
+
+ require kdocLib;
+ foreach my $lib ( @libs ) {
+ print "$exe: reading lib: $lib\n" unless $quiet;
+
+ my $relpath = exists $options{url} ?
+ $options{url} : $outputdir;
+ kdocLib::readLibrary( \&getRoot, $lib, $libdir, $relpath );
+ }
+}
+
+sub parseFiles
+{
+ foreach $currentfile ( @ARGV ) {
+ my $lang = "CXX";
+
+ if ( $currentfile =~ /\.idl\s*$/ ) {
+ # IDL file
+ $lang = "IDL";
+ }
+
+ # assume cxx file
+ if( $cpp ) {
+ # pass through preprocessor
+ my $cmd = $cppcmd;
+ foreach my $dir ( @includes ) {
+ $cmd .= " -I $dir ";
+ }
+
+ $cmd .= " -DQOBJECTDEFS_H $currentfile";
+
+ open( INPUT, "$cmd |" )
+ || croak "Can't preprocess $currentfile";
+ }
+ else {
+ open( INPUT, "$currentfile" )
+ || croak "Can't read from $currentfile";
+ }
+
+ print STDERR "$exe: processing $currentfile\n" unless $quiet;
+
+ # reset vars
+ $rootNode = getRoot( $lang );
+
+
+ # add to file lookup table
+ my $showname = $striphpath ? basename( $currentfile )
+ : $currentfile;
+ $cSourceNode = Ast::New( $showname );
+ $cSourceNode->AddProp( "NodeType", "source" );
+ $cSourceNode->AddProp( "Path", $currentfile );
+ $rootNode->AddPropList( "Sources", $cSourceNode );
+
+ # reset state
+ @classStack = ();
+ $cNode = $rootNode;
+ $inExtern = 0;
+ $inNamespace = 0;
+
+ # parse
+ my $k = undef;
+ while ( defined ($k = readDecl()) ) {
+ print "\nDecl: <$k>[$declNodeType]\n" if $debug;
+ if( identifyDecl( $k ) && $k =~ /{/ ) {
+ readCxxCodeBlock();
+ }
+ }
+ close INPUT;
+ }
+}
+
+
+sub writeDocumentation
+{
+ foreach my $node ( values %rootNodes ) {
+ # postprocess
+ kdocAstUtil::linkNamespaces( $node );
+ kdocAstUtil::makeInherit( $node, $node );
+ kdocAstUtil::linkReferences( $node, $node );
+ kdocAstUtil::calcStats( \%stats, $node, $node );
+
+ # write
+ no strict "refs";
+ foreach my $format ( @formats_wanted ) {
+ my $pack = $formats{ $format };
+ require $pack.".pm";
+
+ print STDERR "Generating bindings for $format ",
+ "language...\n" unless $quiet;
+
+ my $f = "$pack\::writeDoc";
+ &$f( $libname, $node, $outputdir, \%options );
+ }
+ }
+}
+
+sub writeLibrary
+{
+ if( $libname ne "" and !exists $options{'no-cache'} ) {
+ require kdocLib;
+ foreach my $lang ( keys %rootNodes ) {
+ my $node = $rootNodes{ $lang };
+ kdocLib::writeDoc( $libname, $node, $lang, $libdir,
+ $outputdir, $options{url},
+ exists $options{compress} ? 1 : 0 );
+ }
+ }
+}
+
+###### Parser routines
+
+=head2 readSourceLine
+
+ Returns a raw line read from the current input file.
+ This is used by routines outside main, since I don t know
+ how to share fds.
+
+=cut
+
+sub readSourceLine
+{
+ return <INPUT>;
+}
+
+=head2 readCxxLine
+
+ Reads a C++ source line, skipping comments, blank lines,
+ preprocessor tokens and the Q_OBJECT macro
+
+=cut
+
+sub readCxxLine
+{
+ my( $p );
+ my( $l );
+
+ while( 1 ) {
+ $p = shift @inputqueue || <INPUT>;
+ return undef if !defined ($p);
+
+ $p =~ s#//.*$##g; # C++ comment
+ $p =~ s#/\*(?!\*).*?\*/##g; # C comment
+
+ # join all multiline comments
+ if( $p =~ m#/\*(?!\*)#s ) {
+ # unterminated comment
+LOOP:
+ while( defined ($l = <INPUT>) ) {
+ $l =~ s#//.*$##g; # C++ comment
+ $p .= $l;
+ $p =~ s#/\*(?!\*).*?\*/##sg; # C comment
+ last LOOP unless $p =~ m#(/\*(?!\*))|(\*/)#sg;
+ }
+ }
+
+ 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/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/QWIDGETSIZE_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();/;
+ $p =~ s/KSVG_FORWARDGET/KJS::Value getforward();/;
+ $p =~ s/KSVG_PUT/bool put();/;
+ $p =~ s/KSVG_FORWARDPUT/bool putforward();/;
+ $p =~ s/KSVG_BASECLASS/virtual KJS::Value cache();/;
+ 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*Q_OBJECT/ # QObject macro
+# );
+#
+
+ next if ( $p =~ /^\s*Q_ENUMS/ # ignore Q_ENUMS
+ || $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*QDOC_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*$/;
+
+ # remove all preprocessor macros
+ if( $p =~ /^\s*#\s*(\w+)/ ) {
+ # Handling of preprocessed sources: skip anything included from
+ # other files, unless --docincluded was passed.
+ if (!$docincluded && $p =~ /^\s*#\s*[0-9]+\s*\".*$/
+ && not($p =~ /\"$currentfile\"/)) {
+ # include file markers
+ while( <INPUT> ) {
+ last if(/\"$currentfile\"/);
+ print "Overread $_" if $debug;
+ };
+ print "Cont: $_" if $debug;
+ }
+ else {
+ # Skip platform-specific stuff, or #if 0 stuff
+ # or #else of something we parsed (e.g. for QKeySequence)
+ 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\(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;
+ while ( defined $p && $if_depth > 0 ) {
+ $p = <INPUT>;
+ last if !defined $p;
+ $if_depth++ if $p =~ m/^#\s*if/;
+ $if_depth-- if $p =~ m/^#\s*endif/;
+ # 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;
+ }
+ }
+
+ # multiline macros
+ while ( defined $p && $p =~ m#\\\s*$# ) {
+ $p = <INPUT>;
+ }
+ }
+ next;
+ }
+
+ $lastLine = $p;
+ return $p;
+ }
+}
+
+=head2 readCxxCodeBlock
+
+ Reads a C++ code block (recursive curlies), returning the last line
+ or undef on error.
+
+ Parameters: none
+
+=cut
+
+sub readCxxCodeBlock
+{
+# Code: begins in a {, ends in }\s*;?
+# In between: cxx source, including {}
+ my ( $count ) = 0;
+ my $l = undef;
+
+ if ( defined $lastLine ) {
+ print "lastLine: '$lastLine'" if $debug;
+
+ my $open = kdocUtil::countReg( $lastLine, "{" );
+ my $close = kdocUtil::countReg( $lastLine, "}" );
+ $count = $open - $close;
+
+ return $lastLine if ( $open || $close) && $count == 0;
+ }
+
+ # find opening brace
+ if ( $count == 0 ) {
+ while( $count == 0 ) {
+ $l = readCxxLine();
+ return undef if !defined $l;
+ $l =~ s/\\.//g;
+ $l =~ s/'.?'//g;
+ $l =~ s/".*?"//g;
+
+ $count += kdocUtil::countReg( $l, "{" );
+ print "c ", $count, " at '$l'" if $debug;
+ }
+ $count -= kdocUtil::countReg( $l, "}" );
+ }
+
+ # find associated closing brace
+ while ( $count > 0 ) {
+ $l = readCxxLine();
+ croak "Confused by unmatched braces" if !defined $l;
+ $l =~ s/\\.//g;
+ $l =~ s/'.?'//g;
+ $l =~ s/".*?"//g;
+
+ my $add = kdocUtil::countReg( $l, "{" );
+ my $sub = kdocUtil::countReg( $l, "}" );
+ $count += $add - $sub;
+
+ print "o ", $add, " c ", $sub, " at '$l'" if $debug;
+ }
+
+ undef $lastLine;
+ return $l;
+}
+
+=head2 readDecl
+
+ Returns a declaration and sets the $declNodeType variable.
+
+ A decl starts with a type or keyword and ends with [{};]
+ The entire decl is returned in a single line, sans newlines.
+
+ declNodeType values: undef for error, "a" for access specifier,
+ "c" for doc comment, "d" for other decls.
+
+ readCxxLine is used to read the declaration.
+
+=cut
+
+sub readDecl
+{
+ undef $declNodeType;
+ my $l = readCxxLine();
+ my ( $decl ) = "";
+
+ my $allowed_accesors = "private|public|protected|signals";
+ $allowed_accesors .= "|$allowed_k_dcop_accesors_re" if $allow_k_dcop_accessors;
+
+ if( !defined $l ) {
+ return undef;
+ }
+ elsif ( $l =~ /^\s*($allowed_accesors)
+ (\s+\w+)?\s*:/x) { # access specifier
+ $declNodeType = "a";
+ return $l;
+ }
+ elsif ( $l =~ /K_DCOP/ ) {
+ $declNodeType = "k";
+ return $l;
+ }
+ elsif ( $l =~ m#^\s*/\*\*# ) { # doc comment
+ $declNodeType = "c";
+ return $l;
+ }
+ elsif ( $l =~ /Q_PROPERTY/ ) { # property
+ return $l;
+ }
+
+ do {
+ $decl .= $l;
+
+ if ( $l =~ /[{};]/ ) {
+ $decl =~ s/\n/ /gs;
+ $declNodeType = "d";
+ return $decl;
+ }
+ return undef if !defined ($l = readCxxLine());
+
+ } while ( 1 );
+}
+
+#### AST Generator Routines
+
+=head2 getRoot
+
+ Return a root node for the given type of input file.
+
+=cut
+
+sub getRoot
+{
+ my $type = shift;
+ carp "getRoot called without type" unless defined $type;
+
+ if ( !exists $rootNodes{ $type } ) {
+ my $node = Ast::New( "Global" ); # parent of all nodes
+ $node->AddProp( "NodeType", "root" );
+ $node->AddProp( "RootType", $type );
+ $node->AddProp( "Compound", 1 );
+ $node->AddProp( "KidAccess", "public" );
+
+ $rootNodes{ $type } = $node;
+ }
+ print "getRoot: call for $type\n" if $debug;
+
+ return $rootNodes{ $type };
+}
+
+=head2 identifyDecl
+
+ Parameters: decl
+
+ Identifies a declaration returned by readDecl. If a code block
+ needs to be skipped, this subroutine returns a 1, or 0 otherwise.
+
+=cut
+
+sub identifyDecl
+{
+ my( $decl ) = @_;
+
+ 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 );
+
+ # if it's the main doc, it is attached to the root node
+ if ( defined $docNode->{LibDoc} ) {
+ kdocParseDoc::attachDoc( $rootNode, $docNode,
+ $rootNode );
+ undef $docNode;
+ }
+
+ }
+ elsif ( $declNodeType eq "a" ) {
+ newAccess( $decl );
+ }
+ 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)
+ \s*([_\w\:]*)
+ \s*([;{])
+ /xs ) {
+ my ($type, $name, $endtag, $rest ) = ($1, $2, $3, $' );
+ $name = "--" if $name eq "";
+
+ warn "typedef '$type' n:'$name'\n" if $debug;
+
+ if ( $rest =~ /}\s*([\w_]+(?:::[\w_])*)\s*;/ ) {
+ # TODO: Doesn't parse members yet!
+ $endtag = ";";
+ $name = $1;
+ }
+
+ $newNode = newTypedefComp( $type, $name, $endtag );
+ }
+
+ # Typedef
+ elsif ( $decl =~ /^\s*typedef\s+
+ (?:typename\s+)? # `typename' keyword
+ (.*?\s*[\*&>]?) # type
+ \s*([-\w_\:]+) # name
+ \s*((?:\[[-\w_\:<>\s]*\])*) # array
+ \s*[{;]\s*$/xs ) {
+
+ print "Typedef: <$1 $3> <$2>\n" if $debug;
+ $newNode = newTypedef( $1." ".$3, $2 );
+ }
+
+ # Enum
+ elsif ( $decl =~ /^\s*enum\s+([-\w_:]*)?\s*\{(.*)/s ) {
+
+ print "Enum: <$1>\n" if $debug;
+ my $enumname = defined $2 ? $1 : "";
+
+ $newNode = newEnum( $enumname );
+ }
+
+ # Class/Struct
+ elsif ( $decl =~ /^\s*((?:template\s*<.*>)?) # 1 template
+ \s*(class|struct|union|namespace) # 2 struct type
+ (?:\s*Q[A-Z_]*EXPORT[A-Z_]*)?
+ (?:\s*Q_PACKED)?
+ (?:\s*Q_REFCOUNT)?
+ \s+([\w_]+ # 3 name
+ (?:<[\w_ :,]+?>)? # maybe explicit template
+ # (eat chars between <> non-hungry)
+ (?:::[\w_]+)* # maybe nested
+ )
+ ([^\(]*?) # 4 inheritance
+ ([;{])/xs ) { # 5 rest
+
+ print "Class: [$1]\n\t[$2]\n\t[$3]\n\t[$4]\n\t[$5]\n" if $debug;
+ my ( $tmpl, $ntype, $name, $rest, $endtag ) =
+ ( $1, $2, $3, $4, $5 );
+
+ if ($includeclasses)
+ {
+ if (! ($includeclasses =~ /$name/) )
+ {
+ return 1;
+
+ }
+ }
+ 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 "";
+
+ if( $rest =~ /^\s*:\s*/ ) {
+ # inheritance
+ $rest = $';
+ @inherits = parseInheritance( $rest );
+ }
+
+ $newNode = newClass( $tmpl, $ntype,
+ $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
+ \s+([-\w_]+) # name
+ (.*?) # inheritance?
+ ([;{])/xs ) {
+
+ my ( $type, $name, $rest, $fwd, $complete )
+ = ( $1, $2, $3, $4 eq ";" ? 1 : 0,
+ 0 );
+ my @in = ();
+ print "IDL: [$type] [$name] [$rest] [$fwd]\n" if $debug;
+
+ if( $rest =~ /^\s*:\s*/ ) {
+ $rest = $';
+ $rest =~ s/\s+//g;
+ @in = split ",", $rest;
+ }
+ if( $decl =~ /}\s*;/ ) {
+ $complete = 1;
+ }
+
+ $newNode = newIDLstruct( $type, $name, $fwd, $complete, @in );
+ }
+ # Method
+ 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
+
+ my $tpn = $1; # type + name
+ my $params = $2;
+ # Remove constructor initializer, that's not in the params
+ if ( $params =~ /\s*\)\s*:\s*/ ) {
+ # Hack: first .* made non-greedy for QSizePolicy using a?(b):c in ctor init
+ $params =~ s/(.*?)\s*\)\s*:\s*.*$/$1/;
+ }
+
+ 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
+ my $name = $1;
+ $tpn = $`;
+ $newNode = newMethod( $tpn, $name,
+ $params, $const, $pure, $isDeprecated );
+ }
+
+ $skipBlock = 1; # FIXME check end token before doing this!
+ }
+ # Using: import namespace
+ elsif ( $decl =~ /^\s*using\s+namespace\s+(\w+)/ ) {
+ newNamespace( $1 );
+
+ }
+
+ # extern block
+ elsif ( $decl =~ /^\s*extern\s*"(.*)"\s*{/ ) {
+ $inExtern = 1 unless $decl =~ /}/;
+ }
+
+ # Single variable
+ elsif ( $decl =~ /^
+ \s*( (?:[\w_:]+(?:\s+[\w_:]+)*? )# type
+ \s*(?:<.+>)? # template
+ \s*(?:[\&\*])? # ptr or ref
+ (?:\s*(?:const|volatile))* )
+ \s*([\w_:]+) # name
+ \s*( (?:\[[^\[\]]*\] (?:\s*\[[^\[\]]*\])*)? ) # array
+ \s*((?:=.*)?) # value
+ \s*([;{])\s*$/xs ) {
+ my $type = $1;
+ my $name = $2;
+ my $arr = $3;
+ my $val = $4;
+ my $end = $5;
+
+ $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 );
+ }
+
+ $skipBlock = 1 if $end eq '{';
+ }
+
+ # Multi variables
+ elsif ( $decl =~ m/^
+ \s*( (?:[\w_:]+(?:\s+[\w_:]+)*? ) # type
+ \s*(?:<.+>)?) # template
+
+ \s*( (?:\s*(?: [\&\*][\&\*\s]*)? # ptr or ref
+ [\w_:]+) # name
+ \s*(?:\[[^\[\]]*\] (?:\s*\[[^\[\]]*\])*)? # array
+ \s*(?:, # extra vars
+ \s*(?: [\&\*][\&\*\s]*)? # ptr or ref
+ \s*(?:[\w_:]+) # name
+ \s*(?:\[[^\[\]]*\] (?:\s*\[[^\[\]]*\])*)? # array
+ )*
+ \s*(?:=.*)?) # value
+ \s*[;]/xs ) {
+
+ my $type = $1;
+ my $names = $2;
+ my $end = $3;
+ my $doc = $docNode;
+
+ print "Multivar: type: [$type] names: [$names] \n" if $debug;
+
+ foreach my $vardecl ( split( /\s*,\s*/, $names ) ) {
+ next unless $vardecl =~ m/
+ \s*((?: [\&\*][\&\*\s]*)?) # ptr or ref
+ \s*([\w_:]+) # name
+ \s*( (?:\[[^\[\]]*\] (?:\s*\[[^\[\]]*\])*)? ) # array
+ \s*((?:=.*)?) # value
+ /xs;
+ my ($ptr, $name, $arr, $val) = ($1, $2, $3, $4);
+
+ print "Split: type: [$type$ptr$arr] ",
+ " name: [$name] val: [$val] \n" if $debug;
+
+ my $node = newVar( $type.$ptr.$arr, $name, $val );
+
+ $docNode = $doc; # reuse docNode for each
+ postInitNode( $node ) unless !defined $node;
+ }
+
+ $skipBlock = 1 if $end eq '{';
+ }
+ # end of an "extern" block
+ elsif ( $decl =~ /^\s*}\s*$/ && $inExtern ) {
+ $inExtern = 0;
+ }
+ # end of an in-block declaration
+ 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
+ # "typedef struct <name> { ..." is kept instead.
+ # TODO: Buglet. You should fix YOUR code dammit. ;)
+
+
+ $cNode->{astNodeName} = $1;
+ my $siblings = $cNode->{Parent}->{KidHash};
+ undef $siblings->{"--"};
+ $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;
+ }
+ else {
+ $cNode = pop @classStack;
+ print "end decl: popped $cNode->{astNodeName}\n"
+ if $debug;
+ }
+ }
+ # unidentified block start
+ elsif ( $decl =~ /{/ ) {
+ print "Unidentified block start: $decl\n" if $debug;
+ $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 ) {
+ # Nothing to be done with those.
+ }
+ else {
+
+ ## decl is unidentified.
+ warn "Unidentified decl: $decl\n";
+ }
+
+ # once we get here, the last doc node is already used.
+ # postInitNode should NOT be called for forward decls
+ postInitNode( $newNode ) unless !defined $newNode;
+
+ return $skipBlock;
+}
+
+sub postInitNode
+{
+ my $newNode = shift;
+
+ carp "Cannot postinit undef node." if !defined $newNode;
+
+ # The reasoning here:
+ # Forward decls never get a source node.
+ # Once a source node is defined, don't assign another one.
+
+ if ( $newNode->{NodeType} ne "Forward" && !defined $newNode->{Source}) {
+ $newNode->AddProp( "Source", $cSourceNode );
+ } elsif ( $newNode->{NodeType} eq "Forward" ) {
+ if ($debug) {
+ print "postInit: skipping fwd: $newNode->{astNodeName}\n";
+ }
+ undef $docNode;
+ return;
+ }
+
+ if( defined $docNode ) {
+ kdocParseDoc::attachDoc( $newNode, $docNode, $rootNode );
+ undef $docNode;
+ }
+}
+
+
+##### Node generators
+
+=head2 newEnum
+
+ Reads the parameters of an enumeration.
+
+ Returns the parameters, or undef on error.
+
+=cut
+
+sub newEnum
+{
+ my ( $enum ) = @_;
+ my $k = undef;
+ my $params = "";
+
+ $k = $lastLine if defined $lastLine;
+
+ if( defined $lastLine && $lastLine =~ /{/ ) {
+ $params = $';
+ if ( $lastLine =~ /}(.*?);/ ) {
+ return initEnum( $enum, $1, $params );
+ }
+ }
+
+ while ( defined ( $k = readCxxLine() ) ) {
+ $params .= $k;
+
+ if ( $k =~ /}(.*?);/ ) {
+ return initEnum( $enum, $1, $params );
+ }
+ }
+
+ return undef;
+}
+
+=head2 initEnum
+
+ Parameters: name, (ref) params
+
+ Returns an initialized enum node.
+
+=cut
+
+sub initEnum
+{
+ my( $name, $end, $params ) = @_;
+
+ ($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 );
+
+ return $node;
+}
+
+=head2 newIDLstruct
+
+ Parameters: type, name, forward, complete, inherits...
+
+ Handles an IDL structure definition (ie module, interface,
+ exception).
+
+=cut
+
+sub newIDLstruct
+{
+ my ( $type, $name, $fwd, $complete ) = @_;
+
+ my $node = exists $cNode->{KidHash} ?
+ $cNode->{KidHash}->{ $name } : undef;
+
+ if( !defined $node ) {
+ $node = Ast::New( $name );
+ $node->AddProp( "NodeType", $fwd ? "Forward" : $type );
+ $node->AddProp( "KidAccess", "public" );
+ $node->AddProp( "Compound", 1 ) unless $fwd;
+ kdocAstUtil::attachChild( $cNode, $node );
+ }
+ elsif ( $fwd ) {
+ # If we have a node already, we ignore forwards.
+ return undef;
+ }
+ elsif ( $node->{NodeType} eq "Forward" ) {
+ # we are defining a previously forward node.
+ $node->AddProp( "NodeType", $type );
+ $node->AddProp( "Compound", 1 );
+ $node->AddProp( "Source", $cSourceNode );
+ }
+
+ # register ancestors.
+ foreach my $ances ( splice ( @_, 4 ) ) {
+ my $n = kdocAstUtil::newInherit( $node, $ances );
+ }
+
+ if( !( $fwd || $complete) ) {
+ print "newIDL: pushing $cNode->{astNodeName},",
+ " new is $node->{astNodeName}\n"
+ if $debug;
+ push @classStack, $cNode;
+ $cNode = $node;
+ }
+
+ return $node;
+}
+
+=head2 newClass
+
+ Parameters: tmplArgs, cNodeType, name, endTag, isDeprecated, @inheritlist
+
+ Handles a class declaration (also fwd decls).
+
+=cut
+
+sub newClass
+{
+ my( $tmplArgs, $cNodeType, $name, $endTag, $isDeprecated ) = @_;
+
+ my $access = "private";
+ $access = "public" if $cNodeType ne "class";
+
+ # try to find an exisiting node, or create a new one
+ my $oldnode = kdocAstUtil::findRef( $cNode, $name );
+ my $node = defined $oldnode ? $oldnode : Ast::New( $name );
+
+ if ( $endTag ne "{" ) {
+ # forward
+ if ( !defined $oldnode ) {
+ # new forward node
+ $node->AddProp( "NodeType", "Forward" );
+ $node->AddProp( "KidAccess", $access );
+ kdocAstUtil::attachChild( $cNode, $node );
+ }
+ # Discard any doc comment against a forward decl
+ undef $docNode;
+ return $node;
+ }
+
+ # this is a class declaration
+
+ print "ClassName: $name\n" if $debug;
+
+ $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 (@_, 5) ) {
+ my $type = "";
+ my $name = $ances;
+ my $intmpl = undef;
+
+WORD:
+ foreach my $word ( split ( /([\w:]+(:?\s*<.*>)?)/, $ances ) ) {
+ next WORD unless $word =~ /^[\w:]/;
+ if ( $word =~ /(private|public|protected|virtual)/ ) {
+ $type .= "$1 ";
+ }
+ else {
+
+ if ( $word =~ /<(.*)>/ ) {
+ # FIXME: Handle multiple tmpl args
+ $name = $`;
+ $intmpl = $1;
+ }
+ else {
+ $name = $word;
+ }
+
+ last WORD;
+ }
+ }
+
+ # set inheritance access specifier if none specified
+ if ( $type eq "" ) {
+ $type = $cNodeType eq "class" ? "private ":"public ";
+ }
+ chop $type;
+
+ # attach inheritance information
+ my $n = kdocAstUtil::newInherit( $node, $name );
+ $n->AddProp( "Type", $type );
+
+ $n->AddProp( "TmplType", $intmpl ) if defined $intmpl;
+
+ print "In: $name type: $type, tmpl: $intmpl\n" if $debug;
+ }
+
+ # new current node
+ print "newClass: Pushing $cNode->{astNodeName}\n" if $debug;
+ push ( @classStack, $cNode );
+ $cNode = $node;
+
+ return $node;
+}
+
+
+=head3 parseInheritance
+
+ Param: inheritance decl string
+ Returns: list of superclasses (template decls included)
+
+ This will fail if < and > appear in strings in the decl.
+
+=cut
+
+sub parseInheritance
+{
+ my $instring = shift;
+ my @inherits = ();
+
+ my $accum = "";
+ foreach $instring ( split (/\s*,\s*/, $instring) ) {
+ $accum .= $instring.", ";
+ next unless (kdocUtil::countReg( $accum, "<" )
+ - kdocUtil::countReg( $accum, ">" ) ) == 0;
+
+ # matching no. of < and >, so assume the parent is
+ # complete
+ $accum =~ s/,\s*$//;
+ print "Inherits: '$accum'\n" if $debug;
+ push @inherits, $accum;
+ $accum = "";
+ }
+
+ return @inherits;
+}
+
+
+=head2 newNamespace
+
+ Param: namespace name.
+ Returns nothing.
+
+ Imports a namespace into the current node, for ref searches etc.
+ Triggered by "using namespace ..."
+
+=cut
+
+sub newNamespace
+{
+ $cNode->AddPropList( "ImpNames", shift );
+}
+
+
+
+=head2 newTypedef
+
+ Parameters: realtype, name
+
+ Handles a type definition.
+
+=cut
+
+sub newTypedef
+{
+ my ( $realtype, $name ) = @_;
+
+ my ( $node ) = Ast::New( $name );
+
+ $node->AddProp( "NodeType", "typedef" );
+ $node->AddProp( "Type", $realtype );
+
+ kdocAstUtil::attachChild( $cNode, $node );
+
+ return $node;
+}
+
+=head2 newTypedefComp
+
+ Params: realtype, name endtoken
+
+ Creates a new compound type definition.
+
+=cut
+
+sub newTypedefComp
+{
+ my ( $realtype, $name, $endtag ) = @_;
+
+ my ( $node ) = Ast::New( $name );
+
+ $node->AddProp( "NodeType", "typedef" );
+ $node->AddProp( "Type", $realtype );
+
+ kdocAstUtil::attachChild( $cNode, $node );
+
+ if ( $endtag eq '{' ) {
+ print "newTypedefComp: Pushing $cNode->{astNodeName}\n"
+ if $debug;
+ push ( @classStack, $cNode );
+ $cNode = $node;
+ }
+
+ return $node;
+}
+
+
+=head2 newMethod
+
+ Parameters: retType, name, params, const, pure?, deprecated?
+
+ Handles a new method declaration or definition.
+
+=cut
+BEGIN {
+
+my $theSourceNode = $cSourceNode;
+
+sub newMethod
+{
+ my ( $retType, $name, $params, $const, $pure, $deprecated ) = @_;
+ my $parent = $cNode;
+ my $class;
+
+ print "Cracked: [$retType] [$name]\n\t[$params]\n\t[$const]\n"
+ if $debug;
+
+ if ( $retType =~ /([\w\s_<>,]+)\s*::\s*$/ ) {
+ # check if stuff before :: got into rettype by mistake.
+ $retType = $`;
+ ($name = $1."::".$name);
+ $name =~ s/\s+/ /g;
+ print "New name = \"$name\" and type = '$retType'\n" if $debug;
+ }
+
+ # A 'friend method' declaration isn't a real method declaration
+ return undef if ( $retType =~ /^friend\s+/ || $retType =~ /^friend\s+class\s+/ );
+
+ my $isGlobalSpace = 0;
+
+ if( $name =~ /^\s*(.*?)\s*::\s*(.*?)\s*$/ ) {
+ # Fully qualified method name.
+ $name = $2;
+ $class = $1;
+
+ if( $class =~ /^\s*$/ ) {
+ $parent = $rootNode;
+ }
+ elsif ( $class eq $cNode->{astNodeName} ) {
+ $parent = $cNode;
+ }
+ else {
+ # ALWAYS IGNORE...
+ return undef;
+
+ my $node = kdocAstUtil::findRef( $cNode, $class );
+
+ if ( !defined $node ) {
+ # if we couldn't find the name, try again with
+ # all template parameters stripped off:
+ my $strippedClass = $class;
+ $strippedClass =~ s/<[^<>]*>//g;
+
+ $node = kdocAstUtil::findRef( $cNode, $strippedClass );
+
+ # if still not found: give up
+ if ( !defined $node ) {
+ warn "$exe: Unidentified class: $class ".
+ "in $currentfile\:$.\n";
+ return undef;
+ }
+ }
+
+ $parent = $node;
+ }
+ }
+ # TODO fix for $retType =~ /template<.*?>/
+ elsif( $parse_global_space && $parent->{NodeType} eq "root" && $name !~ /\s*qt_/ && $retType !~ /template\s*<.*?>/ ) {
+ $class = $globalSpaceClassName; # FIXME - sanitize the naming system?
+ $isGlobalSpace = 1;
+
+ my $opsNode = kdocAstUtil::findRef( $cNode, $class );
+ if (!$opsNode) {
+ # manually create a "GlobalSpace" class
+ $opsNode = Ast::New( $class );
+ $opsNode->AddProp( "NodeType", "class" );
+ $opsNode->AddProp( "Compound", 1 );
+ $opsNode->AddProp( "Source", $cSourceNode ); # dummy
+ $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 Qt
+ }
+ $parent = $opsNode;
+ }
+
+ # flags
+
+ my $flags = "";
+
+ if( $retType =~ /static/ || $isGlobalSpace ) {
+ $flags .= "s";
+ $retType =~ s/static//g;
+ }
+
+ if( $const && !$isGlobalSpace ) {
+ $flags .= "c";
+ }
+
+ if( $pure ) {
+ $flags .= "p";
+ }
+
+ if( $retType =~ /virtual/ ) {
+ $flags .= "v";
+ $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} ) {
+ warn "'", $parent->{astNodeName}, "' has no KidAccess ",
+ exists $parent->{Forward} ? "(forward)\n" :"\n";
+ }
+
+ # NB, these are =~, so make sure they are listed in correct order
+ if ( $parent->{KidAccess} =~ /slot/ ) {
+ $flags .= "l";
+ }
+ elsif ( $parent->{KidAccess} =~ /k_dcop_signals/ ) {
+ $flags .= "z";
+ }
+ elsif ( $parent->{KidAccess} =~ /k_dcop_hidden/ ) {
+ $flags .= "y";
+ }
+ elsif ( $parent->{KidAccess} =~ /k_dcop/ ) {
+ $flags .= "d";
+ }
+ elsif ( $parent->{KidAccess} =~ /signal/ ) {
+ $flags .= "n";
+ }
+
+ $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/<class\s/</;
+
+ # node
+
+ my $node = Ast::New( $name );
+ $node->AddProp( "NodeType", "method" );
+ $node->AddProp( "Flags", $flags );
+ $node->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;
+}
+
+}
+
+=head2 makeParamList
+
+ Parameters:
+ * method (or enum) node
+ * string containing the whole param list
+ * 1 for enums
+
+ Adds a property "ParamList" to the method node.
+ This property contains a list of nodes, one for each parameter.
+
+ Each parameter node has the following properties:
+ * ArgType the type of the argument, e.g. const QString&
+ * ArgName the name of the argument - optionnal
+ * DefaultValue the default value of the argument - optionnal
+
+ For enum values, ArgType is unset, ArgName is the name, DefaultValue its value.
+
+ Author: David Faure <david@mandrakesoft.com>
+=cut
+
+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 *, &
+ $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
+ $methodNode->AddProp( "ParamList", [] );
+
+ my @args = kdocUtil::splitUnnested( ',', $params);
+
+ my $argId = 0;
+ foreach my $arg ( @args ) {
+ my $argType;
+ my $argName;
+ 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 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*(("[^\"]*")|\([^)]*\)\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*$/ ) {
+ if ( defined $3 ) { # function pointer
+ $argType = $1."(*)($3)";
+ $argName = $2;
+ } else {
+ $argType = $1;
+ $argName = $2;
+ }
+ } else { # unnamed arg - or enum value
+ $argType = $arg if (!$isEnum);
+ $argName = $arg if ($isEnum);
+ }
+ $argId++;
+
+ my $node = Ast::New( $argId ); # let's make the arg index the node "name"
+ $node->AddProp( "NodeType", "param" );
+ $node->AddProp( "ArgType", $argType );
+ $node->AddProp( "ArgName", $argName ) if (defined $argName);
+ $node->AddProp( "DefaultValue", $defaultparam ) if (defined $defaultparam);
+ $methodNode->AddPropList( "ParamList", $node );
+ print STDERR "ArgType: $argType ArgName: $argName\n" if ($debug);
+ }
+}
+
+=head2 newAccess
+
+ Parameters: access
+
+ Sets the default "Access" specifier for the current class node. If
+ the access is a "slot" type, "_slots" is appended to the access
+ string.
+
+=cut
+
+sub newAccess
+{
+ my ( $access ) = @_;
+
+ return undef unless ($access =~ /^\s*(\w+)\s*(slots|$allowed_k_dcop_accesors_re)?/);
+
+ print "Access: [$1] [$2]\n" if $debug;
+
+ $access = $1;
+
+ if ( defined $2 && $2 ne "" ) {
+ $access .= "_" . $2;
+ }
+
+ $cNode->AddProp( "KidAccess", $access );
+
+ return $cNode;
+}
+
+
+=head2 newVar
+
+ Parameters: type, name, value
+
+ New variable. Value is ignored if undef
+
+=cut
+
+sub newVar
+{
+ my ( $type, $name, $val ) = @_;
+
+ my $node = Ast::New( $name );
+ $node->AddProp( "NodeType", "var" );
+
+ my $static = 0;
+ if ( $type =~ /static/ ) {
+ # $type =~ s/static//;
+ $static = 1;
+ }
+
+ $node->AddProp( "Type", $type );
+ $node->AddProp( "Flags", 's' ) if $static;
+ $node->AddProp( "Value", $val ) if defined $val;
+ kdocAstUtil::attachChild( $cNode, $node );
+
+ 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
+
+ Display usage information and quit.
+
+=cut
+
+sub show_usage
+{
+print<<EOF;
+usage:
+ $exe [options] [-f format] [-d outdir] [-n name] files... [-llib..]
+
+See the man page kdoc[1] for more info.
+EOF
+ exit 1;
+}
+
+
+=head2 show_version
+
+ Display short version information and quit.
+
+=cut
+
+sub show_version
+{
+ die "$exe: $Version (c) Sirtaj S. Kang <taj\@kde.org>\n";
+}
+
+
diff --git a/kalyptus/kalyptus.spec.in b/kalyptus/kalyptus.spec.in
new file mode 100644
index 00000000..edf4f603
--- /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/kde3
+
+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 KDEDIR=%{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 <bero@redhat.com>
+- initial
diff --git a/kalyptus/kalyptusCxxToCSharp.pm b/kalyptus/kalyptusCxxToCSharp.pm
new file mode 100644
index 00000000..419c0bef
--- /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 *QTCTYPES *KDETYPES /;
+
+BEGIN
+{
+ @clist = ();
+
+
+ # Page footer
+
+ $who = kdocUtil::userName();
+ $host = kdocUtil::hostName();
+ $now = localtime;
+ $gentext = "$who using kalyptus $main::Version.";
+
+ $docTop =<<EOF
+
+// begin : $now
+// copyright : (C) 2002 Adam Treat. All rights reserved.
+// email : manyoso\@yahoo.com
+// generated by : $gentext
+
+// 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.
+
+EOF
+}
+
+sub cplusplusToCSharp
+{
+ my ( $cplusplusType ) = @_;
+ if ( $cplusplusType =~ /bool/ && kalyptusDataDict::ctypemap($cplusplusType) eq "int" ) {
+ return "bool";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*void\s*\**/ ) {
+ return "int";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*int\s*\&*/ ) {
+ return "int";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*int\s*\*/) {
+ return "int[]";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*double\s*\*/ ) {
+ return "double[]";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*short\s*\*/ ) {
+ return "short[]";
+ } elsif ( $cplusplusType =~ /QByteArray/ || $cplusplusType =~ /QBitArray/ ) {
+ return "byte[]";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*char\s*\*\*/ ) {
+ return "string[]";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*char\s*\**/ ) {
+ return "string";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*unsigned int\s*\**/ ) {
+ return "uint";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*unsigned short\s*\**/ ) {
+ return "ushort";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*unsigned long\s*\**/ ) {
+ return "ulong";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*unsigned char\s*\**/ ) {
+ return "string";
+ } elsif ( $cplusplusType =~ /^GUID/ ) {
+ return "System.Guid";
+ } elsif ( $cplusplusType =~ /^FILE/ ) {
+ return "string";
+ } elsif ( $cplusplusType =~ /^_NPStream/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^QPtrCollection/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^QStyleHintReturn/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^type/i ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^Key/ || $cplusplusType =~ /^key_type/ || $cplusplusType =~ /^K/) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^QUnknownInterface/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^GDHandle/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^QTextParag/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^QDiskFont/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^QDomNodePrivate/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^Display/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^QUuid/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^Q_REFCOUNT/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^EventRef/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^MSG/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^QWSEvent/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^XEvent/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^CGContextRef/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^QWSDecoration/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^QTextFormat/ || $cplusplusType =~ /^QTextDocument/ || $cplusplusType =~ /^QTextCursor/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^QSqlRecordPrivate/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^Text/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^Event/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /^NavDirection/ ) {
+ return "IntPtr";
+ } elsif (
+ $cplusplusType =~ /^pointer$/
+ || $cplusplusType =~/T\*$/
+ || $cplusplusType =~/T\&*$/
+ || $cplusplusType =~/T1\&*$/
+ || $cplusplusType =~/T2\&*$/
+ || $cplusplusType =~/^Iterator/i
+ || $cplusplusType =~/^_iterator/i
+ || $cplusplusType =~/^reference/
+ || $cplusplusType =~/^_reference/) {
+ return "IntPtr";
+ } elsif ($cplusplusType =~ /::/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /::/ ||
+ $cplusplusType =~ /&$/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /&$/ ||
+ $cplusplusType =~ /\*/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /\*/) {
+
+ $cplusplusType =~ s/::/./g;
+ $cplusplusType =~ s/&//g;
+ $cplusplusType =~ s/\*//g;
+ return $cplusplusType;
+
+ } else {
+ return kalyptusDataDict::ctypemap($cplusplusType);
+ }
+}
+
+sub cplusplusToPInvoke
+{
+ my ( $cplusplusType ) = @_;
+ if ( $cplusplusType =~ /bool/ && kalyptusDataDict::ctypemap($cplusplusType) eq "int" ) {
+ return "bool";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*void\s*\*/ ) {
+ return "int";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*int\s*\&*/ ) {
+ return "int";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*int\s*\*/) {
+ return "int[]";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*double\s*\*/ ) {
+ return "double[]";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*short\s*\*/ ) {
+ return "short[]";
+ } elsif ( $cplusplusType =~ /QByteArray/ || $cplusplusType =~ /QBitArray/ ) {
+ return "byte[]";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*char\s*\*\*/ ) {
+ return "string[]";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*char\s*\**/ ) {
+ return "string";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*unsigned int\s*\**/ ) {
+ return "uint";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*unsigned short\s*\**&*/ ) {
+ return "ushort";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*unsigned long\s*\**/ ) {
+ return "ulong";
+ } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /\s*unsigned char\s*\**/ ) {
+ return "string";
+ } elsif ( $cplusplusType =~ /^GUID/ ) {
+ return "System.Guid";
+ } elsif ( $cplusplusType =~ /^FILE/ ) {
+ return "string";
+ } elsif ( $cplusplusType =~ /^_NPStream/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^QPtrCollection/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^QStyleHintReturn/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^type/i ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^Key/ || $cplusplusType =~ /^key_type/ || $cplusplusType =~ /^K/) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^QUnknownInterface/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^GDHandle/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^QTextParag/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^QDiskFont/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^QDomNodePrivate/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^Display/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^QUuid/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^Q_REFCOUNT/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^EventRef/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^MSG/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^QWSEvent/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^XEvent/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^CGContextRef/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^QWSDecoration/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^QTextFormat/ || $cplusplusType =~ /^QTextDocument/ || $cplusplusType =~ /^QTextCursor/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^QSqlRecordPrivate/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^Text/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^Event/ ) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /^NavDirection/ ) {
+ return "RawObject";
+ } elsif (
+ $cplusplusType =~ /^pointer$/
+ || $cplusplusType =~/T\*$/
+ || $cplusplusType =~/T\&*$/
+ || $cplusplusType =~/T1\&*$/
+ || $cplusplusType =~/T2\&*$/
+ || $cplusplusType =~/^iterator/i
+ || $cplusplusType =~/^_iterator/i
+ || $cplusplusType =~/^reference/
+ || $cplusplusType =~/^_reference/) {
+ return "RawObject";
+ } elsif ( $cplusplusType =~ /&$/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /&$/ ) {
+ return "IntPtr";
+ } elsif ( $cplusplusType =~ /\*/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /\*/ ) {
+ return "IntPtr";
+ } else {
+ return kalyptusDataDict::ctypemap($cplusplusType);
+ }
+}
+
+sub checkReserved
+{
+ my ( $name ) = @_;
+
+ if ( $name =~ /^lock$/i ) {
+ return "res_$name";
+ } elsif ( $name =~ /^object$/i ) {
+ return "res_$name";
+ } elsif ( $name =~ /^ref$/i ) {
+ return "res_$name";
+ } elsif ( $name =~ /^base$/i ) {
+ return "res_$name";
+ } elsif ( $name =~ /^string$/i ) {
+ return "res_$name";
+ } elsif ( $name =~ /^const$/i ) {
+ return "res_$name";
+ } elsif ( $name =~ /^event$/i ) {
+ return "res_$name";
+ } elsif ( $name =~ /^internal$/i ) {
+ return "res_$name";
+ } else {
+ return $name;
+ }
+}
+
+sub writeDoc
+{
+ ( $lib, $rootnode, $outputdir, $opt ) = @_;
+
+ $debug = $main::debuggen;
+
+ mkpath( $outputdir ) unless -f $outputdir;
+
+
+ # Document all compound nodes
+ Iter::LocalCompounds( $rootnode, sub { writeClassDoc( shift ); } );
+
+}
+
+sub writeClassDoc
+{
+ my( $node ) = @_;
+
+ print "Enter: $node->{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}, " : QNameSpace ";
+ } 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}, " : QNameSpace ";
+ } 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} =~ /QAuBucket/ || $m->{Params} =~ /QAuBucket/
+ || $m->{ReturnType} =~ /QMember/ || $m->{Params} =~ /QMember/ ) {
+ 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 '<arg> = <value>' 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 00000000..1e6540a4
--- /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 = (
+ 'QString' => '$',
+ 'QString*' => '$',
+ 'QString&' => '$',
+ 'QCString' => '$',
+ 'QCString*' => '$',
+ 'QCString&' => '$',
+ 'QByteArray' => '$',
+ 'QByteArray&' => '$',
+ 'QByteArray*' => '$',
+ 'char*' => '$',
+ 'QCOORD*' => '?',
+ 'QRgb*' => '?',
+);
+
+# 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
+# 'QWSEvent*' => 'void*',
+# 'QDiskFont*' => 'void*',
+# 'XEvent*' => 'void*',
+# 'QStyleHintReturn*' => 'void*',
+# 'FILE*' => 'void*',
+# 'QUnknownInterface*' => 'void*',
+# 'GDHandle' => 'void*',
+# '_NPStream*' => 'void*',
+# 'QTextFormat*' => 'void*',
+# 'QTextDocument*' => 'void*',
+# 'QTextCursor*' => 'void*',
+# 'QTextParag**' => 'void*',
+# 'QTextParag*' => 'void*',
+# 'QRemoteInterface*' => 'void*',
+# 'QSqlRecordPrivate*' => 'void*',
+# 'QTSMFI' => 'void*', # QTextStream's QTSManip
+# 'const GUID&' => 'void*',
+# 'QWidgetMapper*' => 'void*',
+# 'MSG*' => 'void*',
+# 'const QSqlFieldInfoList&' => 'void*', # QSqlRecordInfo - TODO (templates)
+
+ 'QPtrCollection::Item' => 'void*', # to avoid a warning
+
+ 'mode_t' => 'long',
+ 'QProcess::PID' => 'long',
+ 'size_type' => 'int', # QSqlRecordInfo
+ 'Qt::ComparisonFlags' => 'uint',
+ 'Qt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it
+ 'QIODevice::Offset' => 'ulong',
+ 'WState' => 'int',
+ 'WId' => 'ulong',
+ 'QRgb' => 'uint',
+ 'QCOORD' => 'int',
+ 'QTSMFI' => 'int',
+ 'Qt::WState' => 'int',
+ 'Qt::WFlags' => 'int',
+ 'Qt::HANDLE' => 'uint',
+ 'QEventLoop::ProcessEventsFlags' => 'uint',
+ 'QStyle::SCFlags' => 'int',
+ 'QStyle::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 QPtrCollection::Item, for resolveType
+ unless ( kdocAstUtil::findRef( $rootnode, "QPtrCollection::Item" ) ) {
+ my $cNode = kdocAstUtil::findRef( $rootnode, "QPtrCollection" );
+ warn "QPtrCollection 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 "<!DOCTYPE DCOP-IDL><DCOP-IDL>\n";
+
+ print STDOUT "<SOURCE>".@{$rootnode->{Sources}}[0]->{astNodeName}."</SOURCE>\n";
+
+ print STDOUT map { "<INCLUDE>$_</INCLUDE>\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 "<CLASS>\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 { "<PARA>$_</PARA>" } @docs;
+ print STDOUT " <DOC>$doc</DOC>\n";
+ }
+ print STDOUT " <NAME>$className</NAME>\n";
+ print STDOUT join("\n", map { " <SUPER>$_</SUPER>"; } grep { $_ ne "Global"; }
+ map {
+ my $name = $_->{astNodeName};
+ $name =~ s/</&lt;/;
+ $name =~ s/>/&gt;/;
+ my $tmpl = $_->{TmplType};
+ $tmpl =~ s/</&lt;/;
+ $tmpl =~ s/>/&gt;/;
+ $tmpl ? "$name&lt;<TYPE>$tmpl</TYPE>&gt;" : $name;
+ } @{$node->{InList}}) . "\n";
+ print STDOUT $methodCode;
+
+ print STDOUT "</CLASS>\n";
+ }
+ });
+
+ print STDOUT "</DCOP-IDL>\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. QPixmap::QPixmapData
+ exists $classNode->{Tmpl} ||
+ # Don't generate standard bindings for QString, this class is handled as a native type
+ $className eq 'QString' ||
+ $className eq 'QConstString' ||
+ $className eq 'QCString' ||
+ # Don't map classes which are really arrays
+ $className eq 'QStringList' ||
+ $className eq 'QCanvasItemList' ||
+ $className eq 'QWidgetList' ||
+ $className eq 'QObjectList' ||
+ $className eq 'QStrList' ||
+ # Those are template related
+ $className eq 'QTSManip' || # cause compiler errors with several gcc versions
+ $className eq 'QGDict' ||
+ $className eq 'QGList' ||
+ $className eq 'QGVector' ||
+ $className eq 'QStrIList' ||
+ $className eq 'QStrIVec' ||
+ $className eq 'QByteArray' ||
+ $className eq 'QBitArray' ||
+ $classNode->{NodeType} eq 'union' # Skip unions for now, e.g. QPDevCmdParam
+ ) {
+ 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' # QFile'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' # QImage's callback
+ or $arg->{ArgType} eq 'DecoderFn' # QFile's callback
+ or $arg->{ArgType} eq 'EncoderFn' # QFile's callback
+ or $arg->{ArgType} =~ /bool \(\*\)\(QObject/ # QMetaObject's ctor
+ or $arg->{ArgType} eq 'QtStaticMetaObjectFunction' # QMetaObjectCleanUp's ctor with func pointer
+ or $arg->{ArgType} eq 'const QTextItem&' # 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 QSessionManager::RestartHint
+ # (x_QSessionManager doesn't inherit QSessionManager)
+ $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 QColor::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 'QString' ) { # 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.
+# (QObject*)x[1].s_class,(QEvent*)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 'QString' ) { # hack
+ $cast = "{*($type *)}";
+ } else {
+ $cast = "$type";
+ }
+ }
+ push @castedList, "<TYPE>$cast</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};
+ $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/QGfx\s*\*/ );
+# return if ( $returnType eq 'CGContextRef' );
+# return if ( $returnType eq 'QWSDisplay *' );
+# # 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+/ );
+# # QFile's EncoderFn/DecoderFn
+# return if ( $name =~ /set[ED][ne]codingFunction/ );
+# # How to implement this? (QXmlDefaultHandler/QXmlEntityResolver::resolveEntity, needs A*&)
+# return if ( $name eq 'resolveEntity' and $className =~ /^QXml/ );
+# return if ( $className eq 'QBitArray' && $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=\"&amp;\"" if $x_isRef;
+
+ $argType =~ s/^\s*(.*?)\s*$/$1/;
+ $argType =~ s/</&lt;/g;
+ $argType =~ s/>/&gt;/g;
+
+ $args .= " <ARG><TYPE$typeAttrs>$argType</TYPE><NAME>$arg->{ArgName}</NAME></ARG>\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/</&lt;/g;
+ $returnType =~ s/>/&gt;/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 { "<PARA>$_</PARA>" } @docs;
+ $methodCode .= " <DOC>$doc</DOC>\n";
+ }
+
+ $methodCode .= " <TYPE>$returnType</TYPE>\n";
+ $methodCode .= " <NAME>$name</NAME>\n";
+ $methodCode .= "$args";
+ $methodCode .= " </$tagType>\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 'QTextEdit::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 QBlah*
+ $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 =~ /</ ) { # Don't warn for template stuff...
+ print STDERR "$realType isn't a known type (type=$type)\n";
+ }
+ }
+ $typeId = 't_voidp'; # Unknown -> 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 00000000..987e81c1
--- /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. QPixmap::QPixmapData
+ 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. QPDevCmdParam
+ ) {
+ 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 <ksvg_lookup.h>\n";
+ print OUT "#include <ksvg_ecma.h>\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<const KSVGBridge<$d> * >(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 00000000..df45eb94
--- /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 = (
+ 'QString' => '$',
+ 'QString*' => '$',
+ 'QString&' => '$',
+ 'QCString' => '$',
+ 'QCString*' => '$',
+ 'QCString&' => '$',
+ 'QByteArray' => '$',
+ 'QByteArray&' => '$',
+ 'QByteArray*' => '$',
+ 'char*' => '$',
+ 'QCOORD*' => '?',
+ 'QRgb*' => '?',
+);
+
+# 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
+# 'QWSEvent*' => 'void*',
+# 'QDiskFont*' => 'void*',
+# 'XEvent*' => 'void*',
+# 'FILE*' => 'void*',
+# 'QUnknownInterface*' => 'void*',
+# 'GDHandle' => 'void*',
+# '_NPStream*' => 'void*',
+# 'QTextFormat*' => 'void*',
+# 'QTextDocument*' => 'void*',
+# 'QTextCursor*' => 'void*',
+# 'QTextParag**' => 'void*',
+# 'QTextParag*' => 'void*',
+# 'QRemoteInterface*' => 'void*',
+# 'QSqlRecordPrivate*' => 'void*',
+# 'QTSMFI' => 'void*', # QTextStream's QTSManip
+# 'const GUID&' => 'void*',
+# 'QWidgetMapper*' => 'void*',
+# 'MSG*' => 'void*',
+# 'const QSqlFieldInfoList&' => 'void*', # QSqlRecordInfo - TODO (templates)
+
+ 'QStyleHintReturn*' => 'void*',
+ 'QPtrCollection::Item' => 'void*', # to avoid a warning
+
+ 'mode_t' => 'long',
+ 'QProcess::PID' => 'long',
+ 'size_type' => 'int', # QSqlRecordInfo
+ 'Qt::ComparisonFlags' => 'uint',
+ 'Qt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it
+ 'QIODevice::Offset' => 'ulong',
+ 'WState' => 'int',
+ 'WId' => 'ulong',
+ 'QRgb' => 'uint',
+ 'ksocklen_t' => 'uint',
+ 'QCOORD' => 'int',
+ 'QTSMFI' => 'int',
+ 'Qt::WState' => 'int',
+ 'Qt::WFlags' => 'int',
+ 'Qt::HANDLE' => 'uint',
+ 'QEventLoop::ProcessEventsFlags' => 'uint',
+ 'QStyle::SCFlags' => 'int',
+ 'QStyle::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_newQApplication___3Ljava_lang_String_2' => 1,
+ 'Java_org_kde_qt_QApplication_newQApplication___3Ljava_lang_String_2Z' => 1,
+ 'Java_org_kde_qt_QApplication_newQApplication___3Ljava_lang_String_2I' => 1,
+ 'Java_org_kde_qt_QApplication_newQApplication___3I_3Ljava_lang_String_2' => 1,
+ 'Java_org_kde_qt_QApplication_newQApplication___3I_3Ljava_lang_String_2Z' => 1,
+ 'Java_org_kde_qt_QApplication_newQApplication___3I_3Ljava_lang_String_2I' => 1,
+ 'Java_org_kde_qt_QApplication_newQApplication__I_3Ljava_lang_String_2I' => 1,
+ 'Java_org_kde_qt_QApplication_newQApplication__I_3Ljava_lang_String_2Z' => 1,
+ 'Java_org_kde_qt_QApplication_newQApplication__I_3Ljava_lang_String_2' => 1,
+ 'Java_org_kde_qt_QApplication_args__' => 1,
+ 'Java_org_kde_qt_QBitmap_newQBitmap__Lorg_kde_qt_QPixmap_2' => 1,
+ 'Java_org_kde_qt_QBitmap_newQBitmap__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 = <<EOF;
+ public native String[] args();
+
+EOF
+
+ $qapplicationjniExtras = <<EOF;
+static jobjectArray _args = 0;
+
+JNIEXPORT void JNICALL
+Java_org_kde_qt_QApplication_newQApplication___3Ljava_lang_String_2(JNIEnv *env, jobject obj, jobjectArray args)
+{
+ int argc = (int) env->GetArrayLength(args) + 1;
+ _args = (jobjectArray) env->NewGlobalRef(args);
+ if (QtSupport::getQt(env, obj) == 0) {
+ QtSupport::setQt(env, obj, new QApplicationJBridge(argc, QtSupport::toArgv(env, args)));
+ QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj));
+ }
+ return;
+}
+
+JNIEXPORT void JNICALL
+Java_org_kde_qt_QApplication_newQApplication___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 QApplicationJBridge(argc, QtSupport::toArgv(env, args), (bool) GUIenabled));
+ QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj));
+ }
+ return;
+}
+
+JNIEXPORT void JNICALL
+Java_org_kde_qt_QApplication_newQApplication___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 QApplicationJBridge(argc, QtSupport::toArgv(env, args), (QApplication::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 = <<EOF;
+ public QBitmap(QPixmap arg1) {
+ super((Class) null);
+ newQBitmap(arg1);
+ }
+ private native void newQBitmap(QPixmap arg1);
+ public QBitmap(QImage arg1) {
+ super((Class) null);
+ newQBitmap(arg1);
+ }
+ private native void newQBitmap(QImage arg1);
+
+EOF
+
+ $qbitmapjniExtras = <<EOF;
+JNIEXPORT void JNICALL
+Java_org_kde_qt_QBitmap_newQBitmap__Lorg_kde_qt_QPixmap_2(JNIEnv *env, jobject obj, jobject arg1)
+{
+ if (QtSupport::getQt(env, obj) == 0) {
+ QBitmap temp;
+ temp = (QPixmap&) *(QPixmap *) QtSupport::getQt(env, arg1);
+ QtSupport::setQt(env, obj, new QBitmapJBridge(temp));
+ QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj));
+ }
+ return;
+}
+
+JNIEXPORT void JNICALL
+Java_org_kde_qt_QBitmap_newQBitmap__Lorg_kde_qt_QImage_2(JNIEnv *env, jobject obj, jobject arg1)
+{
+ if (QtSupport::getQt(env, obj) == 0) {
+ QBitmap temp;
+ temp = (QImage&) *(QImage *) QtSupport::getQt(env, arg1);
+ QtSupport::setQt(env, obj, new QBitmapJBridge(temp));
+ QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj));
+ }
+ return;
+}
+
+EOF
+
+ $qlistviewExtras = <<EOF;
+ public native ArrayList itemList();
+
+EOF
+
+ $qlistviewjniExtras = <<EOF;
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_QListView_itemList(JNIEnv *env, jobject obj)
+{
+ QListViewItemIterator iterator((QListView*) QtSupport::getQt(env, obj));
+ return QtSupport::arrayWithQListViewItemList(env, &iterator);
+}
+
+EOF
+ $qlistviewitemExtras = <<EOF;
+ public native ArrayList itemList();
+
+EOF
+
+ $qlistviewitemjniExtras = <<EOF;
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_QListViewItem_itemList(JNIEnv *env, jobject obj)
+{
+ QListViewItemIterator iterator((QListViewItem*) QtSupport::getQt(env, obj));
+ return QtSupport::arrayWithQListViewItemList(env, &iterator);
+}
+
+EOF
+
+ $qtExtras = <<EOF;
+ /** This member allows a typecast of an instance which wraps a Qt instance,
+ to a more specialized type. Invokes the private qtjava.dynamicCast()
+ via reflection, as that method isn't part of the public Qt api */
+ public static QtSupport dynamicCast(String type, QtSupport source) {
+ Method method = null;
+
+ try {
+ method = qtjava.class.getDeclaredMethod( "dynamicCast",
+ new Class[] { String.class, QtSupport.class } );
+ } catch (NoSuchMethodException e1) {
+ Qt.qWarning("No such method : qtjava.dynamicCast()");
+ }
+
+ try {
+ method.setAccessible(true);
+ Object result = method.invoke(qtjava.class, new Object[] { type, source } );
+ return (QtSupport) result;
+ } catch (InvocationTargetException e) {
+ Qt.qWarning("Invocation failed : qtjava.dynamicCast()");
+ return null;
+ } catch (IllegalAccessException e) {
+ Qt.qWarning("Invocation failed : qtjava.dynamicCast()");
+ return null;
+ }
+ }
+
+ public static native QColor color0();
+ public static native QColor color1();
+ public static native QColor black();
+ public static native QColor white();
+ public static native QColor darkGray();
+ public static native QColor gray();
+ public static native QColor lightGray();
+ public static native QColor red();
+ public static native QColor green();
+ public static native QColor blue();
+ public static native QColor cyan();
+ public static native QColor magenta();
+ public static native QColor yellow();
+ public static native QColor darkRed();
+ public static native QColor darkGreen();
+ public static native QColor darkBlue();
+ public static native QColor darkCyan();
+ public static native QColor darkMagenta();
+ public static native QColor darkYellow();
+
+ // Global cursors
+
+ public static native QCursor arrowCursor(); // standard arrow cursor
+ public static native QCursor upArrowCursor(); // upwards arrow
+ public static native QCursor crossCursor(); // crosshair
+ public static native QCursor waitCursor(); // hourglass/watch
+ public static native QCursor ibeamCursor(); // ibeam/text entry
+ public static native QCursor sizeVerCursor(); // vertical resize
+ public static native QCursor sizeHorCursor(); // horizontal resize
+ public static native QCursor sizeBDiagCursor(); // diagonal resize (/)
+ public static native QCursor sizeFDiagCursor(); // diagonal resize (\)
+ public static native QCursor sizeAllCursor(); // all directions resize
+ public static native QCursor blankCursor(); // blank/invisible cursor
+ public static native QCursor splitVCursor(); // vertical bar with left-right
+ // arrows
+ public static native QCursor splitHCursor(); // horizontal bar with up-down
+ // arrows
+ public static native QCursor pointingHandCursor(); // pointing hand
+ public static native QCursor forbiddenCursor(); // forbidden cursor (slashed circle)
+ public static native QCursor whatsThisCursor(); // arrow with a question mark
+
+ public static native QApplication qApp();
+
+ public static native void qDebug(String message);
+ public static void qDebug(String pattern, Object[] arguments) {
+ qDebug(MessageFormat.format(pattern, arguments));
+ }
+
+ public static native void qWarning(String message);
+ public static void qWarning(String pattern, Object[] arguments) {
+ qWarning(MessageFormat.format(pattern, arguments));
+ }
+
+ public static native void qFatal(String message);
+ public static void qFatal(String pattern, Object[] arguments) {
+ qFatal(MessageFormat.format(pattern, arguments));
+ }
+
+ private static String sqeezeOut(String from, char toss) {
+ char[] chars = from.toCharArray();
+ int len = chars.length;
+ int put = 0;
+
+ for (int i = 0; i < len; i++) {
+ if (chars[i] != toss) {
+ chars[put++] = chars[i];
+ }
+ }
+
+ return new String(chars, 0, put);
+ }
+
+ /** Prepend a '2' to a signal string and remove any spaces */
+ public static String SIGNAL(String signal) {
+ return "2" + sqeezeOut(signal, ' ');
+ }
+
+ /** Prepend a '1' to a slot string and remove any spaces */
+ public static String SLOT(String slot) {
+ return "1" + sqeezeOut(slot, ' ');
+ }
+
+ /** Convert from a UTF-8 string to Unicode - the java equivalent to QString::fromUtf8() */
+ public String fromUtf8(byte[] bytes) {
+ String result = null;
+
+ try {
+ result = new String(bytes, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ qWarning("UTF-8 encoding not supported");
+ } finally {
+ return result;
+ }
+ }
+
+EOF
+
+ $qtjniExtras = <<EOF;
+#include <qapplication.h>
+#include <qstring.h>
+#include <qcstring.h>
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_color0(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::color0, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_color1(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::color1, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_black(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::black, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_white(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::white, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_darkGray(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkGray, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_lightGray(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::lightGray, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_gray(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::gray, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_red(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::red, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_green(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::green, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_blue(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::blue, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_cyan(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::cyan, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_magenta(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::magenta, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_yellow(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::yellow, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_darkRed(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkRed, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_darkGreen(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkGreen, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_darkBlue(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkBlue, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_darkCyan(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkCyan, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_darkMagenta(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkMagenta, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_darkYellow(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkYellow, "org.kde.qt.QColor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_arrowCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::arrowCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_upArrowCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::upArrowCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_crossCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::crossCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_waitCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::waitCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_ibeamCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::ibeamCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_sizeVerCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::sizeVerCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_sizeHorCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::sizeHorCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_sizeBDiagCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::sizeBDiagCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_sizeFDiagCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::sizeFDiagCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_sizeAllCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::sizeAllCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_blankCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::blankCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_splitVCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::splitVCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_splitHCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::splitHCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_pointingHandCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::pointingHandCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_forbiddenCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::forbiddenCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_whatsThisCursor(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::whatsThisCursor, "org.kde.qt.QCursor");
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_Qt_qApp(JNIEnv* env, jclass cls)
+{
+ (void) cls;
+ return (jobject) QtSupport::objectForQtKey(env, qApp, "org.kde.qt.QApplication");
+}
+
+JNIEXPORT void JNICALL
+Java_org_kde_qt_Qt_qDebug(JNIEnv* env, jclass cls, jstring message)
+{
+static QCString * _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 QCString * _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 QCString * _qstring_message = 0;
+ (void) cls;
+ qFatal("%s", (const char *) QtSupport::toCharString(env, message, &_qstring_message));
+ return;
+}
+
+EOF
+
+ $qobjectExtras = <<EOF;
+ /** i18n() is just a synonym of tr() for now */
+ public static String i18n(String s) {
+ return tr(s);
+ }
+
+ public native void emit(String signal, Object[] args);
+
+ protected void emit(String signal) {
+ Object[] args = new Object[0];
+ emit("2" + signal.trim() + "()", args);
+ }
+
+ protected void emit(String signal, Object value) {
+ Object[] args = new Object[1];
+ args[0] = value;
+ emit("2" + signal.trim() + "(" + value.getClass().getName() + ")", args);
+ }
+
+ protected void emit(String signal, Object value1, Object value2) {
+ Object[] args = new Object[2];
+ args[0] = value1;
+ args[1] = value2;
+ emit("2" + signal.trim() + "(" + value1.getClass().getName() + ","
+ + value2.getClass().getName()
+ + ")", args);
+ }
+
+ protected void emit(String signal, Object value1, Object value2, Object value3) {
+ Object[] args = new Object[3];
+ args[0] = value1;
+ args[1] = value2;
+ args[2] = value3;
+ emit("2" + signal.trim() + "(" + value1.getClass().getName() + ","
+ + value2.getClass().getName() + ","
+ + value3.getClass().getName()
+ + ")", args);
+ }
+
+ protected void emit(String signal, Object value1, Object value2, Object value3, Object value4) {
+ Object[] args = new Object[4];
+ args[0] = value1;
+ args[1] = value2;
+ args[2] = value3;
+ args[3] = value4;
+ emit("2" + signal.trim() + "(" + value1.getClass().getName() + ","
+ + value2.getClass().getName() + ","
+ + value3.getClass().getName() + ","
+ + value4.getClass().getName()
+ + ")", args);
+ }
+
+ protected void emit(String signal, boolean value) {
+ Object[] args = new Object[1];
+ args[0] = new Boolean(value);
+ emit("2" + signal.trim() + "(boolean)", args);
+ }
+
+ protected void emit(String signal, char value) {
+ Object[] args = new Object[1];
+ args[0] = new Character(value);
+ emit("2" + signal.trim() + "(char)", args);
+ }
+
+ protected void emit(String signal, byte value) {
+ Object[] args = new Object[1];
+ args[0] = new Byte(value);
+ emit("2" + signal.trim() + "(byte)", args);
+ }
+
+ protected void emit(String signal, short value) {
+ Object[] args = new Object[1];
+ args[0] = new Short(value);
+ emit("2" + signal.trim() + "(short)", args);
+ }
+
+ protected void emit(String signal, int value) {
+ Object[] args = new Object[1];
+ args[0] = new Integer(value);
+ emit("2" + signal.trim() + "(int)", args);
+ }
+
+ protected void emit(String signal, int value1, int value2) {
+ Object[] args = new Object[2];
+ args[0] = new Integer(value1);
+ args[1] = new Integer(value2);
+ emit("2" + signal.trim() + "(int,int)", args);
+ }
+
+ protected void emit(String signal, Object value1, int value2) {
+ Object[] args = new Object[2];
+ args[0] = value1;
+ args[1] = new Integer(value2);
+ emit("2" + signal.trim() + "(" + value1.getClass().getName() + ","
+ + "int"
+ + ")", args);
+ }
+
+ protected void emit(String signal, int value1, int value2, int value3) {
+ Object[] args = new Object[3];
+ args[0] = new Integer(value1);
+ args[1] = new Integer(value2);
+ args[2] = new Integer(value3);
+ emit("2" + signal.trim() + "(int,int,int)", args);
+ }
+
+ protected void emit(String signal, int value1, int value2, int value3, Object value4) {
+ Object[] args = new Object[4];
+ args[0] = new Integer(value1);
+ args[1] = new Integer(value2);
+ args[2] = new Integer(value3);
+ args[3] = value4;
+ emit("2" + signal.trim() + "(int,int,int," + value4.getClass().getName() + ")", args);
+ }
+
+ protected void emit(String signal, int value1, Object value2, Object value3) {
+ Object[] args = new Object[3];
+ args[0] = new Integer(value1);
+ args[1] = value2;
+ args[2] = value3;
+ emit("2" + signal.trim() + "(int,"
+ + value2.getClass().getName() + ","
+ + value3.getClass().getName()
+ + ")", args);
+ }
+
+ protected void emit(String signal, int value1, Object value2, Object value3, int value4) {
+ Object[] args = new Object[4];
+ args[0] = new Integer(value1);
+ args[1] = value2;
+ args[2] = value3;
+ args[3] = new Integer(value4);
+ emit("2" + signal.trim() + "(int,"
+ + value2.getClass().getName() + ","
+ + value3.getClass().getName()
+ + ",int)", args);
+ }
+
+ protected void emit(String signal, int value1, boolean value2) {
+ Object[] args = new Object[2];
+ args[0] = new Integer(value1);
+ args[1] = new Boolean(value2);
+ emit("2" + signal.trim() + "(int,boolean)", args);
+ }
+
+ protected void emit(String signal, long value) {
+ Object[] args = new Object[1];
+ args[0] = new Long(value);
+ emit("2" + signal.trim() + "(long)", args);
+ }
+
+ protected void emit(String signal, float value) {
+ Object[] args = new Object[1];
+ args[0] = new Float(value);
+ emit("2" + signal.trim() + "(float)", args);
+ }
+
+ protected void emit(String signal, double value) {
+ Object[] args = new Object[1];
+ args[0] = new Double(value);
+ emit("2" + signal.trim() + "(double)", args);
+ }
+
+ protected void emit(String signal, Object value1, int value2, int value3) {
+ Object[] args = new Object[3];
+ args[0] = value1;
+ args[1] = new Integer(value2);
+ args[2] = new Integer(value3);
+ emit("2" + signal.trim() + "(" + value1.getClass().getName() + ",int,int)", args);
+ }
+
+EOF
+
+ $qobjectjniExtras = <<EOF;
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QObject_connect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv* env, jclass cls, jobject sender, jstring signal, jobject receiver, jstring member)
+{
+ (void) cls;
+ return (jboolean) QtSupport::connect(env, sender, signal, receiver, member);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QObject_connect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Ljava_lang_String_2(JNIEnv* env, jobject obj, jobject sender, jstring signal, jstring member)
+{
+ return (jboolean) QtSupport::connect(env, sender, signal, obj, member);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QObject_disconnect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jclass cls, jobject sender, jstring signal, jobject receiver, jstring member)
+{
+ (void) cls;
+ return (jboolean) QtSupport::disconnect(env, sender, signal, receiver, member);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QObject_disconnect__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv* env, jobject obj, jstring signal, jobject receiver, jstring member)
+{
+ return (jboolean) QtSupport::disconnect(env, obj, signal, receiver, member);
+}
+
+JNIEXPORT void JNICALL
+Java_org_kde_qt_QObject_emit(JNIEnv* env, jobject obj, jstring signal, jobjectArray args)
+{
+ QtSupport::emitJavaSignal(env, obj, signal, args);
+ return;
+}
+
+EOF
+
+ $qwidgetExtras = <<EOF;
+ /** Internal method */
+ protected native long paintDevice();
+
+EOF
+
+ $qwidgetjniExtras = <<EOF;
+JNIEXPORT jlong JNICALL
+Java_org_kde_qt_QWidget_paintDevice(JNIEnv* env, jobject obj)
+{
+ return (jlong) (QPaintDevice*)(QWidget*) QtSupport::getQt(env, obj);
+}
+
+EOF
+
+ $qimagejniExtras = <<EOF;
+JNIEXPORT jbyteArray JNICALL
+Java_org_kde_qt_QImage_bits(JNIEnv *env, jobject obj)
+{
+static uchar * ptr = 0;
+ ptr = ((QImageJBridge*) QtSupport::getQt(env, obj))->bits();
+ int len = ((QImageJBridge*) 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 = ((QImageJBridge*) QtSupport::getQt(env, obj))->scanLine(arg1);
+ int len = ((QImageJBridge*) QtSupport::getQt(env, obj))->numBytes() / ((QImageJBridge*) 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 QRgb * ptr = 0;
+ ptr = ((QImageJBridge*) QtSupport::getQt(env, obj))->colorTable();
+ int len = ((QImageJBridge*) QtSupport::getQt(env, obj))->numColors();
+ jintArray result = env->NewIntArray(len);
+ env->SetIntArrayRegion(result, 0, len, (jint *) ptr);
+ return result;
+}
+
+EOF
+
+ $qpixmapExtras = <<EOF;
+ public native boolean loadFromData(char[] data);
+
+ /** Internal method */
+ protected native long paintDevice();
+
+EOF
+
+ $qpixmapjniExtras = <<EOF;
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QPixmap_loadFromData___3C(JNIEnv *env, jobject obj, jcharArray data)
+{
+static QByteArray * _qbyteArray_data = 0;
+ return (jboolean) ((QPixmapJBridge*) QtSupport::getQt(env, obj))->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) (QPaintDevice*)(QPixmap*) QtSupport::getQt(env, obj);
+}
+
+EOF
+
+ $qpaintdeviceExtras = <<EOF;
+ /** Internal method */
+ protected native long paintDevice();
+
+EOF
+
+ $qpaintdevicejniExtras = <<EOF;
+JNIEXPORT jlong JNICALL
+Java_org_kde_qt_QPaintDevice_paintDevice(JNIEnv* env, jobject obj)
+{
+ return (jlong) (QPaintDevice *) QtSupport::getQt(env, obj);
+}
+
+EOF
+
+ $qdragobjectExtras = <<EOF;
+ /** Internal method */
+ protected native long mimeSource();
+
+EOF
+
+ $qdragobjectjniExtras = <<EOF;
+JNIEXPORT jlong JNICALL
+Java_org_kde_qt_QDragObject_mimeSource(JNIEnv* env, jobject obj)
+{
+ return (jlong) (QMimeSource*) (QDragObject*) QtSupport::getQt(env, obj);
+}
+
+EOF
+
+ $qdropeventExtras = <<EOF;
+ /** Internal method */
+ protected native long mimeSource();
+
+EOF
+
+ $qdropeventjniExtras = <<EOF;
+JNIEXPORT jlong JNICALL
+Java_org_kde_qt_QDropEvent_mimeSource(JNIEnv* env, jobject obj)
+{
+ return (jlong) (QMimeSource*) (QDropEvent*) QtSupport::getQt(env, obj);
+}
+
+EOF
+
+ $qmimesourceExtras = <<EOF;
+ /** Internal method */
+ protected native long mimeSource();
+
+EOF
+
+ $qmimesourcejniExtras = <<EOF;
+JNIEXPORT jlong JNICALL
+Java_org_kde_qt_QMimeSource_mimeSource(JNIEnv* env, jobject obj)
+{
+ return (jlong) (QMimeSource *) QtSupport::getQt(env, obj);
+}
+
+EOF
+
+ $qiodeviceExtras = <<EOF;
+ public static final int IO_Direct = 0x0100; // direct access device
+ public static final int IO_Sequential = 0x0200; // sequential access device
+ public static final int IO_Combined = 0x0300; // combined direct/sequential
+ public static final int IO_TypeMask = 0x0f00;
+
+// IO handling modes
+
+ public static final int IO_Raw = 0x0040; // raw access (not buffered)
+ public static final int IO_Async = 0x0080; // asynchronous mode
+
+// IO device open modes
+
+ public static final int IO_ReadOnly = 0x0001; // readable device
+ public static final int IO_WriteOnly = 0x0002; // writable device
+ public static final int IO_ReadWrite = 0x0003; // read+write device
+ public static final int IO_Append = 0x0004; // append
+ public static final int IO_Truncate = 0x0008; // truncate device
+ public static final int IO_Translate = 0x0010; // translate CR+LF
+ public static final int IO_ModeMask = 0x00ff;
+
+// IO device state
+
+ public static final int IO_Open = 0x1000; // device is open
+ public static final int IO_StateMask = 0xf000;
+
+
+// IO device status
+
+ public static final int IO_Ok = 0;
+ public static final int IO_ReadError = 1; // read error
+ public static final int IO_WriteError = 2; // write error
+ public static final int IO_FatalError = 3; // fatal unrecoverable error
+ public static final int IO_ResourceError = 4; // resource limitation
+ public static final int IO_OpenError = 5; // cannot open device
+ public static final int IO_ConnectError = 5; // cannot connect to device
+ public static final int IO_AbortError = 6; // abort error
+ public static final int IO_TimeOutError = 7; // time out
+ public static final int IO_UnspecifiedError = 8; // unspecified error
+
+EOF
+
+ $qpointarrayExtras = <<EOF;
+ public native int size();
+ public native int count();
+ public native boolean isEmpty();
+ public native boolean isNull();
+ public native boolean resize( int size);
+ public native boolean truncate( int pos);
+ public native int begin();
+ public native int end();
+ public native QPoint at(int index);
+
+EOF
+
+ $qpointarrayjniExtras = <<EOF;
+JNIEXPORT void JNICALL
+Java_org_kde_qt_QPointArray_point__I_3I_3I(JNIEnv *env, jobject obj, jint i, jintArray x, jintArray y)
+{
+ int argx;
+ int argy;
+ ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->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 (!((QPointArrayJBridge*) QtSupport::getQt(env, obj))->resize((uint)nPoints)) {
+ return JNI_FALSE;
+ }
+
+ short * shortArray = QtSupport::toShortPtr(env, points);
+ for (int index = 0; index < nPoints; index++) {
+ ((QPointArrayJBridge*) 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 ( ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->size() < (uint) nPoints
+ && !((QPointArrayJBridge*) 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--) {
+ ((QPointArrayJBridge*) 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) ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->size();
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QPointArray_count(JNIEnv* env, jobject obj)
+{
+ return (jint) ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->count();
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QPointArray_isEmpty(JNIEnv* env, jobject obj)
+{
+ return (jboolean) ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->isEmpty();
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QPointArray_isNull(JNIEnv* env, jobject obj)
+{
+ return (jboolean) ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->isNull();
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QPointArray_resize(JNIEnv* env, jobject obj, jint size)
+{
+ return (jboolean) ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->resize((uint) size);
+}
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QPointArray_truncate(JNIEnv *env, jobject obj, jint pos)
+{
+ return (jboolean) ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->truncate((uint) pos);
+}
+
+JNIEXPORT jobject JNICALL
+Java_org_kde_qt_QPointArray_at(JNIEnv * env, jobject obj, jint index)
+{
+ QPoint _p= ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->at((uint) index);
+ return (jobject) QtSupport::objectForQtKey(env, (void *)new QPoint(_p.x(),_p.y()), "org.kde.qt.QPoint", TRUE);
+}
+
+EOF
+
+ $qpopupmenujniExtras = <<EOF;
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QPopupMenu_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QKeySequence_2II(JNIEnv *env, jobject obj, jstring text, jobject receiver, jstring member, jobject accel, jint identifier, jint index)
+{
+ identifier = Java_org_kde_qt_QPopupMenu_insertItem__Ljava_lang_String_2II(env, obj, text, identifier, index);
+
+ if ((bool) Java_org_kde_qt_QPopupMenu_connectItem(env, obj, identifier, receiver, member)) {
+ Java_org_kde_qt_QPopupMenu_setAccel(env, obj, accel, identifier);
+ }
+
+ return identifier;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QPopupMenu_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jstring text, jobject receiver, jstring member)
+{
+ jint identifier = Java_org_kde_qt_QPopupMenu_insertItem__Ljava_lang_String_2II(env, obj, text, -1, -1);
+ Java_org_kde_qt_QPopupMenu_connectItem(env, obj, identifier, receiver, member);
+
+ return identifier;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject icon, jstring text, jobject receiver, jstring member)
+{
+static QString * _qstring_text = 0;
+ jint identifier = Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2II(env, obj, icon, text, -1, -1);
+ Java_org_kde_qt_QPopupMenu_connectItem(env, obj, identifier, receiver, member);
+
+ return identifier;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject pixmap, jobject receiver, jstring member)
+{
+ jint identifier = Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QPixmap_2II(env, obj, pixmap, -1, -1);
+ Java_org_kde_qt_QPopupMenu_connectItem(env, obj, identifier, receiver, member);
+
+ return identifier;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject icon, jobject pixmap, jobject receiver, jstring member)
+{
+ jint identifier = Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2II(env, obj, icon, pixmap, -1, -1);
+ Java_org_kde_qt_QPopupMenu_connectItem(env, obj, identifier, receiver, member);
+
+ return identifier;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QPopupMenu_connectItem(JNIEnv *env, jobject obj, jint identifier, jobject receiver, jstring member)
+{
+ JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member);
+
+ if ( ((QPopupMenuJBridge*) QtSupport::getQt(env, obj))->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 ( ((QPopupMenuJBridge*) QtSupport::getQt(env, obj))->disconnectItem( identifier,
+ javaSlot,
+ javaSlot->javaToQtSlotName(env, member) ) )
+ {
+ return(jboolean) JNI_TRUE;
+ } else {
+ return (jboolean) JNI_FALSE;
+ }
+}
+
+EOF
+
+ $qmenudatajniExtras = <<EOF;
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QMenuData_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QKeySequence_2II(JNIEnv *env, jobject obj, jstring text, jobject receiver, jstring member, jobject accel, jint identifier, jint index)
+{
+ identifier = Java_org_kde_qt_QMenuData_insertItem__Ljava_lang_String_2II(env, obj, text, identifier, index);
+
+ if ((bool) Java_org_kde_qt_QMenuData_connectItem(env, obj, identifier, receiver, member)) {
+ Java_org_kde_qt_QMenuData_setAccel(env, obj, accel, identifier);
+ }
+
+ return identifier;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QMenuData_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jstring text, jobject receiver, jstring member)
+{
+ jint identifier = Java_org_kde_qt_QMenuData_insertItem__Ljava_lang_String_2II(env, obj, text, -1, -1);
+ Java_org_kde_qt_QMenuData_connectItem(env, obj, identifier, receiver, member);
+
+ return identifier;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject icon, jstring text, jobject receiver, jstring member)
+{
+static QString * _qstring_text = 0;
+ jint identifier = Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2II(env, obj, icon, text, -1, -1);
+ Java_org_kde_qt_QMenuData_connectItem(env, obj, identifier, receiver, member);
+
+ return identifier;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject pixmap, jobject receiver, jstring member)
+{
+ jint identifier = Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QPixmap_2II(env, obj, pixmap, -1, -1);
+ Java_org_kde_qt_QMenuData_connectItem(env, obj, identifier, receiver, member);
+
+ return identifier;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject icon, jobject pixmap, jobject receiver, jstring member)
+{
+ jint identifier = Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2II(env, obj, icon, pixmap, -1, -1);
+ Java_org_kde_qt_QMenuData_connectItem(env, obj, identifier, receiver, member);
+
+ return identifier;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QMenuData_connectItem(JNIEnv *env, jobject obj, jint identifier, jobject receiver, jstring member)
+{
+ JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member);
+
+ if ( ((QMenuDataJBridge*) QtSupport::getQt(env, obj))->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 ( ((QMenuDataJBridge*) QtSupport::getQt(env, obj))->disconnectItem( identifier,
+ javaSlot,
+ javaSlot->javaToQtSlotName(env, member) ) )
+ {
+ return(jboolean) JNI_TRUE;
+ } else {
+ return (jboolean) JNI_FALSE;
+ }
+}
+
+EOF
+
+ $qmenubarjniExtras = <<EOF;
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QMenuBar_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QKeySequence_2II(JNIEnv *env, jobject obj, jstring text, jobject receiver, jstring member, jobject accel, jint identifier, jint index)
+{
+ identifier = Java_org_kde_qt_QMenuBar_insertItem__Ljava_lang_String_2II(env, obj, text, identifier, index);
+
+ if ((bool) Java_org_kde_qt_QMenuBar_connectItem(env, obj, identifier, receiver, member)) {
+ Java_org_kde_qt_QMenuBar_setAccel(env, obj, accel, identifier);
+ }
+
+ return identifier;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QMenuBar_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jstring text, jobject receiver, jstring member)
+{
+ jint identifier = Java_org_kde_qt_QMenuBar_insertItem__Ljava_lang_String_2II(env, obj, text, -1, -1);
+ Java_org_kde_qt_QMenuBar_connectItem(env, obj, identifier, receiver, member);
+
+ return identifier;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject icon, jstring text, jobject receiver, jstring member)
+{
+static QString * _qstring_text = 0;
+ jint identifier = Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2II(env, obj, icon, text, -1, -1);
+ Java_org_kde_qt_QMenuBar_connectItem(env, obj, identifier, receiver, member);
+
+ return identifier;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject pixmap, jobject receiver, jstring member)
+{
+ jint identifier = Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QPixmap_2II(env, obj, pixmap, -1, -1);
+ Java_org_kde_qt_QMenuBar_connectItem(env, obj, identifier, receiver, member);
+
+ return identifier;
+}
+
+JNIEXPORT jint JNICALL
+Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject icon, jobject pixmap, jobject receiver, jstring member)
+{
+ jint identifier = Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2II(env, obj, icon, pixmap, -1, -1);
+ Java_org_kde_qt_QMenuBar_connectItem(env, obj, identifier, receiver, member);
+
+ return identifier;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QMenuBar_connectItem(JNIEnv *env, jobject obj, jint identifier, jobject receiver, jstring member)
+{
+ JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member);
+
+ if ( ((QMenuBarJBridge*) QtSupport::getQt(env, obj))->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 ( ((QMenuBarJBridge*) QtSupport::getQt(env, obj))->disconnectItem( identifier,
+ javaSlot,
+ javaSlot->javaToQtSlotName(env, member) ) )
+ {
+ return(jboolean) JNI_TRUE;
+ } else {
+ return (jboolean) JNI_FALSE;
+ }
+}
+
+
+EOF
+
+ $quridragExtras = <<EOF;
+ public static native boolean decode(QMimeSourceInterface e, ArrayList i);
+ public static native boolean decodeToUnicodeUris(QMimeSourceInterface e, ArrayList i);
+ public static native boolean decodeLocalFiles(QMimeSourceInterface e, ArrayList i);
+
+EOF
+
+ $quridragjniExtras = <<EOF;
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QUriDrag_decode(JNIEnv *env, jclass cls, jobject e, jobject i)
+{
+static QStrList * _qlist_i = 0;
+ if (_qlist_i == 0) {
+ _qlist_i = new QStrList();
+ }
+ (void) cls;
+ jboolean result = (jboolean) QUriDragJBridge::decode(QtSupport::mimeSource(env, e), *_qlist_i);
+ QtSupport::arrayWithQStrList(env, _qlist_i, i);
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QUriDrag_decodeToUnicodeUris(JNIEnv *env, jclass cls, jobject e, jobject i)
+{
+static QStringList * _qlist_i = 0;
+ if (_qlist_i == 0) {
+ _qlist_i = new QStringList();
+ }
+ (void) cls;
+ jboolean result = (jboolean) QUriDragJBridge::decodeToUnicodeUris(QtSupport::mimeSource(env, e), *_qlist_i);
+ QtSupport::arrayWithQStringList(env, _qlist_i, i);
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_kde_qt_QUriDrag_decodeLocalFiles(JNIEnv *env, jclass cls, jobject e, jobject i)
+{
+static QStringList * _qlist_i = 0;
+ if (_qlist_i == 0) {
+ _qlist_i = new QStringList();
+ }
+ (void) cls;
+ jboolean result = (jboolean) QUriDragJBridge::decodeLocalFiles(QtSupport::mimeSource(env, e), *_qlist_i);
+ QtSupport::arrayWithQStringList(env, _qlist_i, i);
+ return result;
+}
+
+EOF
+
+ $kapplicationExtras = <<EOF;
+ /**
+ Used internally by the KDE Koala Java bindings runtime
+ */
+ public static native void setJavaSlotFactory();
+
+EOF
+
+ $kapplicationjniExtras = <<EOF;
+#include <kdejava/KDEJavaSlot.h>
+
+JNIEXPORT void JNICALL
+Java_org_kde_koala_KApplication_setJavaSlotFactory(JNIEnv* env, jclass cls)
+{
+ (void) env;
+ (void) cls;
+ JavaSlot::setJavaSlotFactory(new KDEJavaSlotFactory());
+ return;
+}
+
+EOF
+
+ $kmainwindowExtras = <<EOF;
+ /**
+ List of members of KMainWindow class.
+ */
+ public native ArrayList memberList();
+
+ public static void RESTORE(String typeName) {
+ Class savedClass;
+
+ try {
+ savedClass = Class.forName(typeName);
+ int n = 1;
+ while (KMainWindow.canBeRestored(n)){
+ ((KMainWindow) savedClass.newInstance()).restore(n);
+ n++;
+ }
+ } catch(Exception e) {
+ return;
+ }
+
+ return;
+ }
+
+EOF
+
+ $kmainwindowjniExtras = <<EOF;
+JNIEXPORT jobject JNICALL
+Java_org_kde_koala_KMainWindow_memberList(JNIEnv* env, jobject obj)
+{
+ return (jobject) KDESupport::arrayWithKMainWindowList(env, KMainWindow::memberList);
+}
+
+EOF
+
+ $kcmdlineargsjniExtras = <<EOF;
+JNIEXPORT void JNICALL
+Java_org_kde_koala_KCmdLineArgs_init___3Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2(JNIEnv* env, jclass cls, jobjectArray args, jstring _appname, jstring programName, jstring _description, jstring _version)
+{
+ (void) cls;
+static QCString* _qstring__appname = 0;
+static QCString* _qstring_programName = 0;
+static QCString* _qstring__description = 0;
+static QCString* _qstring__version = 0;
+ int argc = (int) env->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 QCString* _qstring__appname = 0;
+static QCString* _qstring_programName = 0;
+static QCString* _qstring__description = 0;
+static QCString* _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 = <<EOF;
+JNIEXPORT jboolean JNICALL
+Java_org_kde_koala_Scheduler_connect__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv* env, jclass cls, jstring signal, jobject receiver, jstring member)
+{
+ (void) cls;
+ JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member);
+ QString qtSignalName(javaSlot->javaToQtSignalName(env, signal, 0));
+ jboolean xret = (jboolean) SchedulerJBridge::connect((const char*) qtSignalName, (const QObject*) 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*\*|QGfx|^Display\s*\*|KHTMLPart::PageSecurity|QFileInfoList|QValueList<QIconDragItem>|QValueList<QCString>|QValueList<QVariant>|QValueList<QPixmap>|QValueListConstIterator<QString>|QMap|EditMode|QPtrList<QPixmap>|QPtrList<QPoint>|QTextFormat|QTextCursor|QTextDocument|QNetworkProtocolFactoryBase|QDomNodePrivate|QSqlDriverCreatorBase|QSqlFieldInfoList|QObjectUserData|QUObject|QTextParag|QWidgetMapper|QMemArray<int>|QBitArray|QLayoutIterator|QAuBucket|QUnknownInterface|QConnectionList/ ) {
+ return ""; # Unsupported type
+ } elsif ( $cplusplusType =~ /QSignal\s*\*|QMenuItem|QWSEvent|QWSDisplay|QWSSocket|QPaintDeviceX11Data|QWindowsMime|QDirectPainter|QMember|QDiskFont|QGCache|QRichText|QWSDecoration/ && $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 =~ /QStringList/|| $cplusplusType =~ /QStrList/) {
+ 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 =~ /QMemArray<QRect>/
+ || $cplusplusType =~ /QArray<QRect>/
+ || 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 =~ /QString/ || $cplusplusType =~ /QCString/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /^(const )?char\s*\*/ ) {
+ return "String"
+ } elsif ( $cplusplusType =~ /QChar\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 =~ /QPaintDevice/ ) {
+ return "QPaintDeviceInterface"
+ } elsif ( $cplusplusType =~ /QByteArray/ ) {
+ 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 =~ /QDateTime/ ? "QDateTime" : "QDate";
+ $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 QTime* _qtime_$argName = 0;\n";
+ if ( $cplusplusType =~ /[\*]/ ) {
+ $jniArg = "($cplusplusType) QtSupport::toQTime(env, $argName, &_qtime_$argName)";
+ } else {
+ $jniArg = "($cplusplusType)*(QTime*) QtSupport::toQTime(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)*(QStrList*) 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 =~ /QStringList/ ) {
+ $jniLocal ="static QStringList* _qlist_$argName = 0;\n";
+ if ( $cplusplusType =~ /[\*]/ ) {
+ $jniArg = "($cplusplusType) QtSupport::toQStringList(env, $argName, &_qlist_$argName)";
+ } else {
+ $jniArg = "($cplusplusType)*(QStringList*) QtSupport::toQStringList(env, $argName, &_qlist_$argName)";
+ }
+ } elsif ( $cplusplusType =~ /QStrList/ ) {
+ $jniLocal ="static QStrList* _qlist_$argName = 0;\n";
+ if ( $cplusplusType =~ /[\*]/ ) {
+ $jniArg = "($cplusplusType) QtSupport::toQStrList(env, $argName, &_qlist_$argName)";
+ } else {
+ $jniArg = "($cplusplusType)*(QStrList*) QtSupport::toQStrList(env, $argName, &_qlist_$argName)";
+ }
+ } elsif ( $cplusplusType =~ /char\s*\*\*/ ) {
+ $jniArg = "($cplusplusType) QtSupport::toStringArray(env, $argName)";
+ }
+ } elsif ( $javaType =~ /StringBuffer/ ) {
+ if ( $cplusplusType =~ /QCString/ ) {
+ $jniLocal = "static QCString* _qcstring_$argName = 0;\n";
+ $jniLocal .= "\tif (_qcstring_$argName == 0) {\n";
+ $jniLocal .= "\t\t_qcstring_$argName = new QCString();\n";
+ $jniLocal .= "\t}\n";
+ if ( $cplusplusType =~ /[\*]/ ) {
+ $jniArg = "($cplusplusType) _qcstring_$argName";
+ } else {
+ $jniArg = "($cplusplusType)*(QCString*) _qcstring_$argName";
+ }
+ $jniCleanup = "\tQtSupport::fromQCStringToStringBuffer(env, _qcstring_$argName, $argName);\n";
+ } else {
+ $jniLocal ="static QString* _qstring_$argName = 0;\n";
+ if ( $cplusplusType =~ /[\*]/ ) {
+ $jniArg = "($cplusplusType) QtSupport::toQStringFromStringBuffer(env, $argName, &_qstring_$argName)";
+ } else {
+ $jniArg = "($cplusplusType)*(QString*) QtSupport::toQStringFromStringBuffer(env, $argName, &_qstring_$argName)";
+ }
+ $jniCleanup = "\tQtSupport::fromQStringToStringBuffer(env, _qstring_$argName, $argName);\n";
+ }
+ } elsif ( $javaType =~ /^String$/ ) {
+ if ( $cplusplusType =~ /QString/ ) {
+ $jniLocal ="static QString* _qstring_$argName = 0;\n";
+ if ( $cplusplusType =~ /[\*]/ ) {
+ $jniArg = "($cplusplusType) QtSupport::toQString(env, $argName, &_qstring_$argName)";
+ } else {
+ $jniArg = "($cplusplusType)*(QString*) QtSupport::toQString(env, $argName, &_qstring_$argName)";
+ }
+ } elsif ( $cplusplusType =~ /QCString/ ) {
+ $jniLocal ="static QCString* _qcstring_$argName = 0;\n";
+ if ( $cplusplusType =~ /[\*]/ ) {
+ $jniArg = "($cplusplusType) QtSupport::toQCString(env, $argName, &_qcstring_$argName)";
+ } else {
+ $jniArg = "($cplusplusType)*(QCString*) QtSupport::toQCString(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 QCString* _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 QByteArray* _qbytearray_$argName = 0;\n";
+ $jniArg = "($cplusplusType) QtSupport::toUcharArray(env, $argName, &_qbytearray_$argName)";
+ } elsif ( $javaType =~ /byte\[\]/ ) {
+ $jniLocal = "static QByteArray* _qbyteArray_$argName = 0;\n";
+ if ( $cplusplusType =~ /[\*]/ ) {
+ $jniArg = "($cplusplusType) QtSupport::toQByteArray(env, $argName, &_qbyteArray_$argName)";
+ } else {
+ $jniArg = "($cplusplusType)*(QByteArray*) QtSupport::toQByteArray(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 =~ /QValueList/ ) {
+ $jniLocal = "static QValueList<int>* _qlist_$argName = 0;\n";
+ $jniArg = "($cplusplusType) QtSupport::toQIntValueList(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 =~ /^QPaintDeviceInterface$/ ) {
+ $jniArg = "($cplusplusType) QtSupport::paintDevice(env, $argName)";
+ } elsif ( $javaType =~ /^QMimeSourceInterface$/ ) {
+ $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 =~ /QChar/ ) {
+ $jniLocal = "static QChar* _qchar_$argName = 0;\n";
+ if ( $cplusplusType =~ /[\*]/ ) {
+ $jniArg = "($cplusplusType) QtSupport::toQChar(env, $argName, &_qchar_$argName)";
+ } else {
+ $jniArg = "($cplusplusType)*(QChar*) QtSupport::toQChar(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 =~ /(QDateTime|QDate)\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 =~ /(QTime)\s*(\*)?&?\s*$/;
+ $jniLocal = "\t$1 $2 _qtime;\n";
+ $returnCall = "\t_qtime = $functionCall;\n$jniCleanups";
+ $returnCall .= "\treturn (jobject) QtSupport::fromQTime(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 =~ /(QStrList|QStringList|QCanvasItemList|QWidgetList|QDomNodeList|QObjectList)\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 =~ /QValueList<QIconDragItem>\s*([\*\&])?\s*$/ ) {
+ $returnCall .= "\treturn (jobject) QtSupport::arrayWithQIconDragItemList(env, (QValueList<QIconDragItem>*) " . ($1 eq "\*" ? "" : "&") . "_qlist);\n";
+ } elsif ( $cplusplusType =~ /QMemArray<QRect>\s*([\*\&])?\s*$/ ) {
+ $returnCall .= "\treturn (jobject) QtSupport::arrayWithQRectList(env, (QMemArray<QRect>*) " . ($1 eq "\*" ? "" : "&") . "_qlist);\n";
+ } elsif ( $cplusplusType =~ /QArray<QRect>\s*([\*\&])?\s*$/ ) {
+ $returnCall .= "\treturn (jobject) QtSupport::arrayWithQRectList(env, (QArray<QRect>*) " . ($1 eq "\*" ? "" : "&") . "_qlist);\n";
+ }
+ } elsif ( $javaType =~ /String\[\]/ ) {
+ ; # Do nothing, string arrays are ArrayLists as return values
+ } elsif ( $javaType =~ /String/ || $javaType =~ /StringBuffer/ ) {
+ if ( $cplusplusType =~ /QString(\s*\*)?/ ) {
+ $jniLocal = "\tQString $1 _qstring;\n";
+ $returnCall = "\t_qstring = $functionCall;\n$jniCleanups";
+ $returnCall .= "\treturn QtSupport::fromQString(env, " . ($cplusplusType =~ /\*/ ? "" : "&") . "_qstring);\n";
+ } elsif ($cplusplusType =~ /QCString(\s*\*)?/) {
+ $jniLocal = "\tQCString $1 _qstring;\n";
+ $returnCall = "\t_qstring = $functionCall;\n$jniCleanups";
+ $returnCall .= "\treturn QtSupport::fromQCString(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 = "\tQByteArray " . ($cplusplusType =~ /\*/ ? "*" : "") . "_qbyteArray;\n";
+ $returnCall = "\t_qbyteArray = $functionCall;\n$jniCleanups";
+ $returnCall .= "\treturn QtSupport::fromQByteArray(env, " . ($cplusplusType =~ /\*/ ? "" : "&") . "_qbyteArray);\n";
+ } elsif ( $javaType =~ /short\[\]/ ) {
+ ;
+ } elsif ( $javaType =~ /int\[\]/ && $cplusplusType !~ /\&/ ) {
+ if ( $cplusplusType =~ /(int\*|QRgb\*)/ ) {
+ $jniLocal = "\t$1 _qint;\n";
+ $returnCall = "\t_qint = $functionCall;\n$jniCleanups";
+ $returnCall .= "\treturn QtSupport::fromIntPtr(env, (int*)_qint);\n";
+ } else {
+ $jniLocal = "\tQValueList<int> _qintArray;\n";
+ $returnCall = "\t_qintArray = $functionCall;\n$jniCleanups";
+ $returnCall .= "\treturn QtSupport::fromQIntValueList(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 =~ /(QChar)(\s*\*)?\s*$/ ) {
+ $jniLocal = "\t$const$1 $2 _qchar;\n";
+ $returnCall = "\t_qchar = $functionCall;\n$jniCleanups";
+ $returnCall .= "\treturn (jchar) QtSupport::fromQChar(env, (QChar*) " . ($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 QPtrCollection::Item, for resolveType
+ unless ( kdocAstUtil::findRef( $rootnode, "QPtrCollection::Item" ) ) {
+ my $cNode = kdocAstUtil::findRef( $rootnode, "QPtrCollection" );
+ warn "QPtrCollection 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. QPixmap::QPixmapData
+ exists $classNode->{Tmpl} ||
+ # Don't generate standard bindings for QString, this class is handled as a native type
+ $className eq 'QString' ||
+ $className eq 'QConstString' ||
+ $className eq 'QCString' ||
+ # Don't map classes which are really arrays
+ $className eq 'QStringList' ||
+ $className eq 'QCanvasItemList' ||
+ $className eq 'QWidgetList' ||
+ $className eq 'QObjectList' ||
+ $className eq 'QStrList' ||
+ # Those are template related
+ $className eq 'QTSManip' || # cause compiler errors with several gcc versions
+ $className eq 'QIconFactory' ||
+ $className eq 'QGDict' ||
+ $className eq 'QGList' ||
+ $className eq 'QGVector' ||
+ $className eq 'QStrIList' ||
+ $className eq 'QStrIVec' ||
+ $className eq 'QByteArray' ||
+ $className eq 'QBitArray' ||
+ $className eq 'QWExtra' ||
+ $className eq 'QTLWExtra' ||
+ $className eq 'QMetaEnum::Item' ||
+ $className eq 'QWidgetContainerPlugin' ||
+ $className eq 'QGArray::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. QPDevCmdParam
+ ) {
+ 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' # QFile'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 'QUriDrag' and $name =~ /^decode$|decodeLocalFiles|decodeToUnicodeUris/)
+ || ($classNode->{astNodeName} eq 'QApplication' and $name =~ /^qwsSetCustomColors|^setArgs$|^winMouseButtonUp|^winFocus|^winMouseButtonUP$|^winVersion$/)
+ || ($classNode->{astNodeName} eq 'QPrinter' and $name =~ /^setIdle$|^setActive$/)
+ || ($classNode->{astNodeName} eq 'QDragObject' and $name eq 'dragLink')
+ || ($classNode->{astNodeName} eq 'QFont' and $name eq 'qwsRenderToDisk')
+ || ($classNode->{astNodeName} eq 'QFontInfo' and $name eq 'font')
+ || ($classNode->{astNodeName} eq 'QLineEdit' and $name eq 'getSelection')
+ || ($classNode->{astNodeName} eq 'QMainWindow' and $name eq 'toolBars')
+ || ($classNode->{astNodeName} eq 'QMovie' and $name eq 'setDisplayWidget')
+ || ($classNode->{astNodeName} eq 'QMetaObject' and $name =~ /^new_metaenum_item$|^new_metaaccess$/)
+ || ($classNode->{astNodeName} eq 'QPainter' and $name eq 'pos')
+ || ($classNode->{astNodeName} eq 'QPixmap' 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' # QImage's callback
+ or $arg->{ArgType} eq 'DecoderFn' # QFile's callback
+ or $arg->{ArgType} eq 'EncoderFn' # QFile's callback
+ or $arg->{ArgType} =~ /bool \(\*\)\(QObject/ # QMetaObject's ctor
+ or $arg->{ArgType} eq 'QtStaticMetaObjectFunction' # QMetaObjectCleanUp's ctor with func pointer
+ or $arg->{ArgType} eq 'const QTextItem&' # 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 QSessionManager::RestartHint
+ # (QSessionManagerJBridge doesn't inherit QSessionManager)
+ $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 QColor::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. QCanvasItem)
+ # Same if the class has only private constructors (e.g. QInputDialog)
+ $classNode->AddProp( "CanBeInstanciated", $hasPublicProtectedConstructor
+# && !$hasPrivatePureVirtual
+ && (!$classNode->{Pure} or $classNode->{astNodeName} eq 'QValidator')
+ && !($classNode->{NodeType} eq 'namespace')
+ && ($classNode->{astNodeName} !~ /^DrawContentsEvent$|^MouseEvent$|^MouseDoubleClickEvent$|^MouseMoveEvent$|^MouseReleaseEvent$|^MousePressEvent$/)
+ && ($classNode->{astNodeName} !~ /QMetaObject|QDragObject|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 QAsyncIO. 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 'QAsyncIO' );
+
+ # 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 "QMemArray" and $name ne "QArray" and $name ne "QSqlFieldInfoList" ) {
+ 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 'QListView' or $className eq 'QListViewItem' or $className eq 'QUriDrag' ) {
+ # 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 QCursor whatsThisCursor\(\);//;
+ $qtjniExtras =~ s/JNIEXPORT jobject JNICALL\nJava_org_kde_qt_Qt_whatsThisCursor[^}]*}//;
+ }
+ print CLASS $qtExtras;
+ $jniCode .= $qtjniExtras;
+ } elsif ( $className eq 'QApplication' ) {
+ print CLASS $qapplicationExtras;
+ $jniCode .= $qapplicationjniExtras;
+ } elsif ( $className eq 'QBitmap' ) {
+ print CLASS $qbitmapExtras;
+ $jniCode .= $qbitmapjniExtras;
+ } elsif ( $className eq 'QDropEvent' ) {
+ print CLASS $qdropeventExtras;
+ $jniCode .= $qdropeventjniExtras;
+ } elsif ( $className eq 'QDragObject' ) {
+ print CLASS $qdragobjectExtras;
+ $jniCode .= $qdragobjectjniExtras;
+ } elsif ( $className eq 'QObject' ) {
+ print CLASS $qobjectExtras;
+ $jniCode .= $qobjectjniExtras;
+ } elsif ( $className eq 'QImage' ) {
+ $jniCode .= $qimagejniExtras;
+ } elsif ( $className eq 'QListView' ) {
+ print CLASS $qlistviewExtras;
+ $jniCode .= $qlistviewjniExtras;
+ } elsif ( $className eq 'QListViewItem' ) {
+ print CLASS $qlistviewitemExtras;
+ $jniCode .= $qlistviewitemjniExtras;
+ } elsif ( $className eq 'QMenuBar' ) {
+ if ($main::qt_embedded) {
+ $qmenubarjniExtras =~ s/jobject accel/jlong accel/;
+ }
+ $jniCode .= $qmenubarjniExtras;
+ } elsif ( $className eq 'QMenuData' ) {
+ if ($main::qt_embedded) {
+ $qmenudatajniExtras =~ s/jobject accel/jlong accel/;
+ }
+ $jniCode .= $qmenudatajniExtras;
+ } elsif ( $className eq 'QMimeSource' ) {
+ print CLASS $qmimesourceExtras;
+ $jniCode .= $qmimesourcejniExtras;
+ } elsif ( $className eq 'QPopupMenu' ) {
+ if ($main::qt_embedded) {
+ $qpopupmenujniExtras =~ s/jobject accel/jlong accel/;
+ }
+ $jniCode .= $qpopupmenujniExtras;
+ } elsif ( $className eq 'QWidget' ) {
+ print CLASS $qwidgetExtras;
+ $jniCode .= $qwidgetjniExtras;
+ } elsif ( $className eq 'QPaintDevice' ) {
+ print CLASS $qpaintdeviceExtras;
+ $jniCode .= $qpaintdevicejniExtras;
+ } elsif ( $className eq 'QPixmap' ) {
+ print CLASS $qpixmapExtras;
+ $jniCode .= $qpixmapjniExtras;
+ } elsif ( $className eq 'QIODevice' ) {
+ print CLASS $qiodeviceExtras;
+ } elsif ( $className eq 'QPointArray' ) {
+ print CLASS $qpointarrayExtras;
+ $jniCode .= $qpointarrayjniExtras;
+ } elsif ( $className eq 'QUriDrag' ) {
+ 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 <qtjava/QtSupport.h>\n";
+
+ if ($jniCode =~ /JavaSlot/) {
+ print JNISOURCE "#include <qtjava/JavaSlot.h>\n";
+ }
+
+ if ( $typeprefix eq "qt_" ) {
+ print JNISOURCE "#include <qtjava/$javaClassName" . ".h>\n";
+ } else {
+ print JNISOURCE "#include <kdejava/KDESupport.h>\n";
+ print JNISOURCE "#include <kdejava/$javaClassName" . ".h>\n";
+ }
+
+ if ($javaClassName eq 'KIO') {
+ # Hack: namespaces can be defined in several source files, which doesn't work, so this..
+ print JNISOURCE "#include <kio/job.h>\n";
+ print JNISOURCE "#include <kio/davjob.h>\n";
+ print JNISOURCE "#include <kio/metainfojob.h>\n";
+ print JNISOURCE "#include <kio/previewjob.h>\n";
+ print JNISOURCE "#include <kio/paste.h>\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 'QString' ) { # 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.
+# (QObject*)x[1].s_class,(QEvent*)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 'QString' ) { # 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/|kdeprint/|kdesu/)(.*)!$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 'QWidget', while currentClassName is 'QRangeControl'
+ # and the QRangeControl methods are being copied into QWidget.
+ 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 QByteArray 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/|kdeprint/|kdesu/)(.*)!$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/QGfx\s*\*/ );
+# return if ( $returnType eq 'CGContextRef' );
+# return if ( $returnType eq 'QWSDisplay *' );
+# # 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+/ );
+# # QFile's EncoderFn/DecoderFn
+# return if ( $name =~ /set[ED][ne]codingFunction/ );
+# # How to implement this? (QXmlDefaultHandler/QXmlEntityResolver::resolveEntity, needs A*&)
+# return if ( $name eq 'resolveEntity' and $className =~ /^QXml/ );
+# return if ( $className eq 'QBitArray' && $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 'QApplication' 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 'QButtonGroup') {
+ # Can't override a static method find() in QWidget
+ $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 'QMessageBox' ) {
+ $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 'QTableHeader' ) {
+ $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 QQbject/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 QCString\* _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 = "QLayout";
+ } elsif ($javaSignature eq "defaultFactory()" and $javaReturnType eq 'QSqlEditorFactory') {
+ $javaReturnType = "QEditorFactory";
+ } 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 QWidget::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 QSize&';
+ } elsif ($name eq 'connectUpdate' or $name eq 'disconnectUpdate') {
+ $slotArgType = 'const QRect&';
+ }
+ # Look for args which are are a QQbject/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 QCString\* _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 QCString\(\); }\n\t_qstring_$1->resize\(\(uint\) $arg2\);\n/;
+ my $arg1 = $1;
+ $fcall =~ s/QtSupport::toCharString\([^\)]*\)/_qstring_$arg1->data()/;
+ $fcall =~ s/return xret;/QtSupport::fromQCStringToStringBuffer(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 QWidget current
+ # classname might be QPaintDevice, as its methods are needed in QWidget.
+ my $currentClassName = join( ".", kdocAstUtil::heritage($classNode) );
+
+ my $sourcename = $classNode->{Source}->{astNodeName};
+
+ if ( $sourcename !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|kdeprint/|kdesu/)(.*)!$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/|kdeprint/|kdesu/)(.*)!$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, 'QCheckListItem') ) {
+ $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QCheckListItem*)($className*)QtSupport::getQt(env, obj))->parent() == 0 && ((QCheckListItem*)($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, 'QTableItem')) {
+ $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QTableItem*)($className*)QtSupport::getQt(env, obj))->table() == 0) {\n";
+ } elsif ( is_kindof($classNode, 'QPopupMenu')) {
+ if ($main::qt_embedded) {
+ $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QPopupMenu*)($className*)QtSupport::getQt(env, obj))->parentWidget() == 0) {\n";
+ } else {
+ $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QPopupMenu*)($className*)QtSupport::getQt(env, obj))->parentWidget(FALSE) == 0) {\n";
+ }
+ } elsif ( is_kindof($classNode, 'QListViewItem') ) {
+ $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QListViewItem*)($className*)QtSupport::getQt(env, obj))->parent() == 0 && ((QListViewItem*)($className*)QtSupport::getQt(env, obj))->listView() == 0) {\n";
+ } elsif ( is_kindof($classNode, 'QIconViewItem')) {
+ $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QIconViewItem*)($className*)QtSupport::getQt(env, obj))->iconView() == 0) {\n";
+ } elsif ( is_kindof($classNode, 'QLayoutItem')) {
+ $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QLayoutItem*)($className*)QtSupport::getQt(env, obj))->layout() == 0 && ((QLayoutItem*)($className*)QtSupport::getQt(env, obj))->widget() == 0 && ((QLayoutItem*)($className*)QtSupport::getQt(env, obj))->spacerItem() == 0) {\n";
+ } elsif ( $classNode->{astNodeName} =~ /^KSpell$|^KReplace$/ ) {
+ $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj)) {\n";
+ } elsif ( $classNode->{astNodeName} =~ /^QWidget$/ || defined kdocAstUtil::findOverride( $rootnode, $classNode, "parentWidget" ) ) {
+ if ($main::qt_embedded) {
+ $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QWidget*)($className*)QtSupport::getQt(env, obj))->parentWidget() == 0) {\n";
+ } else {
+ $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QWidget*)($className*)QtSupport::getQt(env, obj))->parentWidget(TRUE) == 0) {\n";
+ }
+ } elsif ( $classNode->{astNodeName} =~ /^QObject$/ || 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 $isQObject = is_kindof($node, 'QObject');
+
+ 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/
+ && $isQObject )
+ {
+ @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 $isQObject and $#argTypeList eq 1) {
+ $jbridgeCode .= "\tbool eventFilter(QObject* object,QEvent* 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 'QValidator' ) {
+ $jbridgeCode .= "\tQValidator::State validate(QString& input,int& pos) const\n";
+ $jbridgeCode .= "\t{\n";
+ $jbridgeCode .= "\t\treturn (QValidator::State) QtSupport::validateDelegate((QValidator*)this,input,pos);\n";
+ $jbridgeCode .= "\t}\n";
+ $jbridgeCode .= "\tvoid fixup(QString& input) const\n";
+ $jbridgeCode .= "\t{\n";
+ $jbridgeCode .= "\t\tQtSupport::fixupDelegate((QValidator*) this, input);\n";
+ $jbridgeCode .= "\t\treturn;\n\t}\n";
+ } elsif( $m->{ReturnType} eq 'void' and $#argTypeList eq -1 and $isQObject) {
+ $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 $isQObject ) {
+ $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 'QTextEdit::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 =~ /QMemArray|QSqlFieldInfoList/) {
+ # 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 'QLineEdit' && ( $name eq 'setPasswordChar' || $name eq 'passwordChar' ) );
+ $ok = 0 if ( $ok && $className eq 'QWidgetItem' && $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 QBlah*
+ $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 =~ /</ ) { # Don't warn for template stuff...
+ print STDERR "$realType isn't a known type (type=$type)\n";
+ }
+ }
+ $typeId = 't_voidp'; # Unknown -> 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 )?QDate(Time)?(\s*&)?/Calendar/g;
+ $line =~ s/(const )?QTime([^r])/Date$1/g;
+ $line =~ s/QString::null/null/g;
+ $line =~ s/(const )?QC?String(\s*&)?/String/g;
+ $line =~ s/QByteArray/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!<!&lt;!g;
+ $code =~ s!>!&gt;!g;
+ $code =~ s!\\#!#!g;
+ $line =~ s!\@c\s+([\w#\\\.<>]+)!<code>$code</code>!;
+ }
+ $line =~ s!\@em\s+(\w+)!<b>$1</b>!g;
+ $line =~ s!\@p\s+([\w\._]*)!<code>$1</code>!g;
+ $line =~ s!\\paragraph\s+[\w]+\s([\w]+)!<li><b>$1</b></li>!g;
+ $line =~ s!\\b\s+([\w -]+)\\n!<li><b>$1</b></li>!g;
+ $line =~ s!\\c\s+([\w\@&\\?;-]+)!<code>$1</code>!g;
+ $line =~ s!\\p\s+([\w\@]+)!<pre>$1</pre>!g;
+ $line =~ s!\\li\s+([\w\@]+)!<li>$1</li>!g;
+ $line =~ s!<b>([\w\t \(\)-]*:?)</b>\\n!<li><b>$1</b></li>!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<li>\n/;
+ $line =~ s!$!\n</li>!;
+ $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/QString::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 =~ /QString|^\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/QChar/char/g;
+ $returntext =~ s/QStringList/ArrayList/g;
+ $returntext =~ s/([Aa]) ArrayList/$1n ArrayList/g;
+ $returntext =~ s/QString/String/g;
+ $returntext =~ s/KCmdLineOptions/String[][]/;
+ $returntext =~ s!\\note!<b>Note:<\b>!g;
+ $returntext =~ s!\\(code|verbatim)!<pre>!g;
+ $returntext =~ s!\\(endcode|endverbatim)!</pre>!g;
+ $returntext =~ s!\\addtogroup\s+[\w]+\s+"([^"\@]+)"\s+\@{!<li><b>$1</b></li>!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\@&\\?";-]+)!<code>$1</code>!g;
+ $returntext =~ s!\@p\s+([\w\._]*)!<code>$1</code>!g;
+ $returntext =~ s!\@a\s+([:\w]+)!<b>$1</b>!g;
+ $returntext =~ s![\@\\]b\s+[:\w]!<b>$1</b>!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 00000000..b6cfde77
--- /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 = (
+ 'QString' => '$',
+ 'QString*' => '$',
+ 'QString&' => '$',
+ 'QCString' => '$',
+ 'QCString*' => '$',
+ 'QCString&' => '$',
+ 'QByteArray' => '$',
+ 'QByteArray&' => '$',
+ 'QByteArray*' => '$',
+ 'char*' => '$',
+ 'QCOORD*' => '?',
+ 'QRgb*' => '?',
+);
+
+# 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
+# 'QWSEvent*' => 'void*',
+# 'QDiskFont*' => 'void*',
+# 'XEvent*' => 'void*',
+# 'FILE*' => 'void*',
+# 'QUnknownInterface*' => 'void*',
+# 'GDHandle' => 'void*',
+# '_NPStream*' => 'void*',
+# 'QTextFormat*' => 'void*',
+# 'QTextDocument*' => 'void*',
+# 'QTextCursor*' => 'void*',
+# 'QTextParag**' => 'void*',
+# 'QTextParag*' => 'void*',
+# 'QRemoteInterface*' => 'void*',
+# 'QSqlRecordPrivate*' => 'void*',
+# 'QTSMFI' => 'void*', # QTextStream's QTSManip
+# 'const GUID&' => 'void*',
+# 'QWidgetMapper*' => 'void*',
+# 'MSG*' => 'void*',
+# 'const QSqlFieldInfoList&' => 'void*', # QSqlRecordInfo - TODO (templates)
+
+ 'QStyleHintReturn*' => 'void*',
+ 'QPtrCollection::Item' => 'void*', # to avoid a warning
+
+ 'mode_t' => 'long',
+ 'QProcess::PID' => 'long',
+ 'size_type' => 'int', # QSqlRecordInfo
+ 'Qt::ComparisonFlags' => 'uint',
+ 'Qt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it
+ 'QIODevice::Offset' => 'ulong',
+ 'WState' => 'int',
+ 'WId' => 'ulong',
+ 'QRgb' => 'uint',
+ 'ksocklen_t' => 'uint',
+ 'QCOORD' => 'int',
+ 'QTSMFI' => 'int',
+ 'Qt::WState' => 'int',
+ 'Qt::WFlags' => 'int',
+ 'Qt::HANDLE' => 'uint',
+ 'QEventLoop::ProcessEventsFlags' => 'uint',
+ 'QStyle::SCFlags' => 'int',
+ 'QStyle::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 = <<EOF;
+// public native String[] args();
+
+EOF
+
+
+ $qbitmapExtras = <<EOF;
+// public QBitmap(QPixmap arg1) {
+// super((Class) null);
+// newQBitmap(arg1);
+// }
+// private native void newQBitmap(QPixmap arg1);
+// public QBitmap(QImage arg1) {
+// super((Class) null);
+// newQBitmap(arg1);
+// }
+// private native void newQBitmap(QImage arg1);
+
+EOF
+
+
+ $qlistviewExtras = <<EOF;
+// public native ArrayList itemList();
+
+EOF
+
+ $qlistviewitemExtras = <<EOF;
+ public native ArrayList itemList();
+
+EOF
+
+ $qtExtras = <<EOF;
+ /** This member allows a typecast of an instance which wraps a Qt instance,
+ to a more specialized type. Invokes the private qtjava.dynamicCast()
+ via reflection, as that method isn't part of the public Qt api */
+ public static QtSupport dynamicCast(String type, QtSupport source) {
+ Method method = null;
+
+ try {
+ method = qtjava.class.getDeclaredMethod( "dynamicCast",
+ new Class[] { String.class, QtSupport.class } );
+ } catch (NoSuchMethodException e1) {
+ Qt.qWarning("No such method : qtjava.dynamicCast()");
+ }
+
+ try {
+ method.setAccessible(true);
+ Object result = method.invoke(qtjava.class, new Object[] { type, source } );
+ return (QtSupport) result;
+ } catch (InvocationTargetException e) {
+ Qt.qWarning("Invocation failed : qtjava.dynamicCast()");
+ return null;
+ } catch (IllegalAccessException e) {
+ Qt.qWarning("Invocation failed : qtjava.dynamicCast()");
+ return null;
+ }
+ }
+
+ /*
+ public static native QColor color0();
+ public static native QColor color1();
+ public static native QColor black();
+ public static native QColor white();
+ public static native QColor darkGray();
+ public static native QColor gray();
+ public static native QColor lightGray();
+ public static native QColor red();
+ public static native QColor green();
+ public static native QColor blue();
+ public static native QColor cyan();
+ public static native QColor magenta();
+ public static native QColor yellow();
+ public static native QColor darkRed();
+ public static native QColor darkGreen();
+ public static native QColor darkBlue();
+ public static native QColor darkCyan();
+ public static native QColor darkMagenta();
+ public static native QColor darkYellow();
+
+ // Global cursors
+
+ public static native QCursor arrowCursor(); // standard arrow cursor
+ public static native QCursor upArrowCursor(); // upwards arrow
+ public static native QCursor crossCursor(); // crosshair
+ public static native QCursor waitCursor(); // hourglass/watch
+ public static native QCursor ibeamCursor(); // ibeam/text entry
+ public static native QCursor sizeVerCursor(); // vertical resize
+ public static native QCursor sizeHorCursor(); // horizontal resize
+ public static native QCursor sizeBDiagCursor(); // diagonal resize (/)
+ public static native QCursor sizeFDiagCursor(); // diagonal resize (\)
+ public static native QCursor sizeAllCursor(); // all directions resize
+ public static native QCursor blankCursor(); // blank/invisible cursor
+ public static native QCursor splitVCursor(); // vertical bar with left-right
+ // arrows
+ public static native QCursor splitHCursor(); // horizontal bar with up-down
+ // arrows
+ public static native QCursor pointingHandCursor(); // pointing hand
+ public static native QCursor forbiddenCursor(); // forbidden cursor (slashed circle)
+ */
+// public static native QApplication qApp();
+
+ public static native void qDebug(String message);
+ public static void qDebug(String pattern, Object[] arguments) {
+ qDebug(MessageFormat.format(pattern, arguments));
+ }
+
+ public static native void qWarning(String message);
+ public static void qWarning(String pattern, Object[] arguments) {
+ qWarning(MessageFormat.format(pattern, arguments));
+ }
+
+ public static native void qFatal(String message);
+ public static void qFatal(String pattern, Object[] arguments) {
+ qFatal(MessageFormat.format(pattern, arguments));
+ }
+
+ private static String sqeezeOut(String from, char toss) {
+ char[] chars = from.toCharArray();
+ int len = chars.length;
+ int put = 0;
+
+ for (int i = 0; i < len; i++) {
+ if (chars[i] != toss) {
+ chars[put++] = chars[i];
+ }
+ }
+
+ return new String(chars, 0, put);
+ }
+
+ /** Prepend a '2' to a signal string and remove any spaces */
+ public static String SIGNAL(String signal) {
+ return "2" + sqeezeOut(signal, ' ');
+ }
+
+ /** Prepend a '1' to a slot string and remove any spaces */
+ public static String SLOT(String slot) {
+ return "1" + sqeezeOut(slot, ' ');
+ }
+
+ /** Convert from a UTF-8 string to Unicode - the java equivalent to QString::fromUtf8() */
+ public String fromUtf8(byte[] bytes) {
+ String result = null;
+
+ try {
+ result = new String(bytes, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ qWarning("UTF-8 encoding not supported");
+ } finally {
+ return result;
+ }
+ }
+
+EOF
+
+
+ $qobjectExtras = <<EOF;
+ /** i18n() is just a synonym of tr() for now */
+ public static String i18n(String s) {
+ return tr(s);
+ }
+
+
+
+EOF
+
+ $qwidgetExtras = <<EOF;
+
+EOF
+
+
+ $qpixmapExtras = <<EOF;
+// public native boolean loadFromData(char[] data);
+
+EOF
+
+ $qpaintdeviceExtras = <<EOF;
+
+EOF
+
+
+ $qdragobjectExtras = <<EOF;
+
+EOF
+
+
+ $qdropeventExtras = <<EOF;
+EOF
+
+
+ $qmimesourceExtras = <<EOF;
+EOF
+
+
+ $qiodeviceExtras = <<EOF;
+ public static final int IO_Direct = 0x0100; // direct access device
+ public static final int IO_Sequential = 0x0200; // sequential access device
+ public static final int IO_Combined = 0x0300; // combined direct/sequential
+ public static final int IO_TypeMask = 0x0f00;
+
+// IO handling modes
+
+ public static final int IO_Raw = 0x0040; // raw access (not buffered)
+ public static final int IO_Async = 0x0080; // asynchronous mode
+
+// IO device open modes
+
+ public static final int IO_ReadOnly = 0x0001; // readable device
+ public static final int IO_WriteOnly = 0x0002; // writable device
+ public static final int IO_ReadWrite = 0x0003; // read+write device
+ public static final int IO_Append = 0x0004; // append
+ public static final int IO_Truncate = 0x0008; // truncate device
+ public static final int IO_Translate = 0x0010; // translate CR+LF
+ public static final int IO_ModeMask = 0x00ff;
+
+// IO device state
+
+ public static final int IO_Open = 0x1000; // device is open
+ public static final int IO_StateMask = 0xf000;
+
+
+// IO device status
+
+ public static final int IO_Ok = 0;
+ public static final int IO_ReadError = 1; // read error
+ public static final int IO_WriteError = 2; // write error
+ public static final int IO_FatalError = 3; // fatal unrecoverable error
+ public static final int IO_ResourceError = 4; // resource limitation
+ public static final int IO_OpenError = 5; // cannot open device
+ public static final int IO_ConnectError = 5; // cannot connect to device
+ public static final int IO_AbortError = 6; // abort error
+ public static final int IO_TimeOutError = 7; // time out
+ public static final int IO_UnspecifiedError = 8; // unspecified error
+
+EOF
+
+ $qpointarrayExtras = <<EOF;
+// public native int size();
+// public native int count();
+// public native boolean isEmpty();
+// public native boolean isNull();
+// public native boolean resize( int size);
+// public native boolean truncate( int pos);
+// public native int begin();
+// public native int end();
+// public native QPoint at(int index);
+
+EOF
+
+ $quridragExtras = <<EOF;
+// public static native boolean decode(QMimeSourceInterface e, ArrayList i);
+// public static native boolean decodeToUnicodeUris(QMimeSourceInterface e, ArrayList i);
+// public static native boolean decodeLocalFiles(QMimeSourceInterface e, ArrayList i);
+
+EOF
+
+
+ $kapplicationExtras = <<EOF;
+ /**
+ Used internally by the KDE Koala Java bindings runtime
+ */
+// public static native void setJavaSlotFactory();
+
+EOF
+
+
+ $kmainwindowExtras = <<EOF;
+ /**
+ List of members of KMainWindow class.
+ */
+// public native ArrayList memberList();
+
+ public static void RESTORE(String typeName) {
+ Class savedClass;
+
+ try {
+ savedClass = Class.forName(typeName);
+ int n = 1;
+ while (KMainWindow.canBeRestored(n)){
+ ((KMainWindow) savedClass.newInstance()).restore(n);
+ n++;
+ }
+ } catch(Exception e) {
+ return;
+ }
+
+ return;
+ }
+
+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\*|KHTMLPart::PageSecurity|QFileInfoList|QValueList<QIconDragItem>|QValueList<QCString>|QValueList<QVariant>|QValueList<QPixmap>|QValueListConstIterator<QString>|QMap|EditMode|QPtrList<QPixmap>|QPtrList<QPoint>|QTextFormat|QTextCursor|QTextDocument|QNetworkProtocolFactoryBase|QDomNodePrivate|QSqlDriverCreatorBase|QSqlFieldInfoList|QObjectUserData|QUObject|QTextParag|QWidgetMapper|QMemArray<int>|QBitArray|QLayoutIterator|QAuBucket|QUnknownInterface|QConnectionList/ ) {
+ 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 =~ /QStringList/|| $cplusplusType =~ /QStrList/) {
+ 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 =~ /QMemArray<QRect>/
+ || 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 =~ /QString/ || $cplusplusType =~ /QCString/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /^(const )?char\s*\*/ ) {
+ return "String"
+ } elsif ( $cplusplusType =~ /QChar\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 =~ /QPaintDevice/ ) {
+ return "QPaintDeviceInterface"
+ } elsif ( $cplusplusType =~ /QByteArray/ ) {
+ 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 QPtrCollection::Item, for resolveType
+ unless ( kdocAstUtil::findRef( $rootnode, "QPtrCollection::Item" ) ) {
+ my $cNode = kdocAstUtil::findRef( $rootnode, "QPtrCollection" );
+ warn "QPtrCollection 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. QPixmap::QPixmapData
+ exists $classNode->{Tmpl} ||
+ # Don't generate standard bindings for QString, this class is handled as a native type
+ $className eq 'QString' ||
+ $className eq 'QConstString' ||
+ $className eq 'QCString' ||
+ # Don't map classes which are really arrays
+ $className eq 'QStringList' ||
+ $className eq 'QCanvasItemList' ||
+ $className eq 'QWidgetList' ||
+ $className eq 'QObjectList' ||
+ $className eq 'QStrList' ||
+ # Those are template related
+ $className eq 'QTSManip' || # cause compiler errors with several gcc versions
+ $className eq 'QIconFactory' ||
+ $className eq 'QGDict' ||
+ $className eq 'QGList' ||
+ $className eq 'QGVector' ||
+ $className eq 'QStrIList' ||
+ $className eq 'QStrIVec' ||
+ $className eq 'QByteArray' ||
+ $className eq 'QBitArray' ||
+ $className eq 'QWExtra' ||
+ $className eq 'QTLWExtra' ||
+ $className eq 'QMetaEnum::Item' ||
+ $className eq 'QWidgetContainerPlugin' ||
+ $className eq 'QGArray::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. QPDevCmdParam
+ ) {
+ 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' # QFile'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 'QUriDrag' 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' # QImage's callback
+ or $arg->{ArgType} eq 'DecoderFn' # QFile's callback
+ or $arg->{ArgType} eq 'EncoderFn' # QFile's callback
+ or $arg->{ArgType} =~ /bool \(\*\)\(QObject/ # QMetaObject's ctor
+ or $arg->{ArgType} eq 'QtStaticMetaObjectFunction' # QMetaObjectCleanUp's ctor with func pointer
+ or $arg->{ArgType} eq 'const QTextItem&' # 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 QSessionManager::RestartHint
+ # (QSessionManagerJBridge doesn't inherit QSessionManager)
+ $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 QColor::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. QCanvasItem)
+ # Same if the class has only private constructors (e.g. QInputDialog)
+ $classNode->AddProp( "CanBeInstanciated", $hasPublicProtectedConstructor
+# && !$hasPrivatePureVirtual
+ && (!$classNode->{Pure} or $classNode->{astNodeName} eq 'QValidator')
+ && !($classNode->{NodeType} eq 'namespace')
+ && ($classNode->{astNodeName} !~ /^DrawContentsEvent$|^MouseEvent$|^MouseDoubleClickEvent$|^MouseMoveEvent$|^MouseReleaseEvent$|^MousePressEvent$/)
+ && ($classNode->{astNodeName} !~ /QMetaObject|QDragObject|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 QAsyncIO. 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 'QAsyncIO' );
+
+ # 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 "QMemArray" and $name ne "QSqlFieldInfoList" ) {
+ 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 'QListView' or $className eq 'QListViewItem' or $className eq 'QUriDrag' ) {
+ # 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 'QApplication' ) {
+ print CLASS $qapplicationExtras;
+ } elsif ( $className eq 'QBitmap' ) {
+ print CLASS $qbitmapExtras;
+ } elsif ( $className eq 'QDropEvent' ) {
+ print CLASS $qdropeventExtras;
+ } elsif ( $className eq 'QDragObject' ) {
+ print CLASS $qdragobjectExtras;
+ } elsif ( $className eq 'QObject' ) {
+ print CLASS $qobjectExtras;
+ } elsif ( $className eq 'QListView' ) {
+ print CLASS $qlistviewExtras;
+ } elsif ( $className eq 'QListViewItem' ) {
+ print CLASS $qlistviewitemExtras;
+ } elsif ( $className eq 'QMimeSource' ) {
+ print CLASS $qmimesourceExtras;
+ } elsif ( $className eq 'QWidget' ) {
+ print CLASS $qwidgetExtras;
+ } elsif ( $className eq 'QPaintDevice' ) {
+ print CLASS $qpaintdeviceExtras;
+ } elsif ( $className eq 'QPixmap' ) {
+ print CLASS $qpixmapExtras;
+ } elsif ( $className eq 'QIODevice' ) {
+ print CLASS $qiodeviceExtras;
+ } elsif ( $className eq 'QPointArray' ) {
+ print CLASS $qpointarrayExtras;
+ } elsif ( $className eq 'QUriDrag' ) {
+ 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 'QString' ) { # 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.
+# (QObject*)x[1].s_class,(QEvent*)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 'QString' ) { # 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 'QWidget', while currentClassName is 'QRangeControl'
+ # and the QRangeControl methods are being copied into QWidget.
+ 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/|kdeprint/|kdesu/)(.*)!$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/QGfx\s*\*/ );
+# return if ( $returnType eq 'CGContextRef' );
+# return if ( $returnType eq 'QWSDisplay *' );
+# # 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+/ );
+# # QFile's EncoderFn/DecoderFn
+# return if ( $name =~ /set[ED][ne]codingFunction/ );
+# # How to implement this? (QXmlDefaultHandler/QXmlEntityResolver::resolveEntity, needs A*&)
+# return if ( $name eq 'resolveEntity' and $className =~ /^QXml/ );
+# return if ( $className eq 'QBitArray' && $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 'QApplication' 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 'QButtonGroup') {
+ # Can't override a static method find() in QWidget
+ $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 'QMessageBox' ) {
+ $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 = "QLayout";
+ } elsif ($javaSignature eq "defaultFactory()" and $javaReturnType eq 'QSqlEditorFactory') {
+ $javaReturnType = "QEditorFactory";
+ } elsif ($javaSignature eq "statusBar()") {
+ $altReturnType = "QStatusBar";
+ } elsif ($javaSignature eq "menuBar()") {
+ $altReturnType = "QMenuBar";
+ } 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 QWidget current
+ # classname might be QPaintDevice, as its methods are needed in QWidget.
+ my $currentClassName = join( ".", kdocAstUtil::heritage($classNode) );
+
+ my $sourcename = $classNode->{Source}->{astNodeName};
+
+ if ( $sourcename !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|kdeprint/|kdesu/)(.*)!$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/|kdeprint/|kdesu/)(.*)!$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 'QTextEdit::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 =~ /QMemArray|QSqlFieldInfoList/) {
+ # 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 'QLineEdit' && ( $name eq 'setPasswordChar' || $name eq 'passwordChar' ) );
+ $ok = 0 if ( $ok && $className eq 'QWidgetItem' && $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 QBlah*
+ $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 =~ /</ ) { # Don't warn for template stuff...
+ print STDERR "$realType isn't a known type (type=$type)\n";
+ }
+ }
+ $typeId = 't_voidp'; # Unknown -> 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 )?QDate(Time)?(\s*&)?/Calendar/g;
+ $line =~ s/(const )?QTime([^r])/Date$1/g;
+ $line =~ s/QString::null/null/g;
+ $line =~ s/(const )?QC?String(\s*&)?/String/g;
+ $line =~ s/QByteArray/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!<!&lt;!g;
+ $code =~ s!>!&gt;!g;
+ $code =~ s!\\#!#!g;
+ $line =~ s!\@c\s+([\w#\\\.<>]+)!<code>$code</code>!;
+ }
+ $line =~ s!\@em\s+(\w+)!<b>$1</b>!g;
+ $line =~ s!\@p\s+([\w\._]*)!<code>$1</code>!g;
+ $line =~ s!\\paragraph\s+[\w]+\s([\w]+)!<li><b>$1</b></li>!g;
+ $line =~ s!\\b\s+([\w -]+)\\n!<li><b>$1</b></li>!g;
+ $line =~ s!\\c\s+([\w\@&\\?;-]+)!<code>$1</code>!g;
+ $line =~ s!\\p\s+([\w\@]+)!<pre>$1</pre>!g;
+ $line =~ s!\\li\s+([\w\@]+)!<li>$1</li>!g;
+ $line =~ s!<b>([\w\t \(\)-]*:?)</b>\\n!<li><b>$1</b></li>!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<li>\n/;
+ $line =~ s!$!\n</li>!;
+ $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/QString::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 =~ /QString|^\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/QChar/char/g;
+ $returntext =~ s/QStringList/ArrayList/g;
+ $returntext =~ s/([Aa]) ArrayList/$1n ArrayList/g;
+ $returntext =~ s/QString/String/g;
+ $returntext =~ s/KCmdLineOptions/String[][]/;
+ $returntext =~ s!\\note!<b>Note:<\b>!g;
+ $returntext =~ s!\\(code|verbatim)!<pre>!g;
+ $returntext =~ s!\\(endcode|endverbatim)!</pre>!g;
+ $returntext =~ s!\\addtogroup\s+[\w]+\s+"([^"\@]+)"\s+\@{!<li><b>$1</b></li>!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\@&\\?";-]+)!<code>$1</code>!g;
+ $returntext =~ s!\@p\s+([\w\._]*)!<code>$1</code>!g;
+ $returntext =~ s!\@a\s+([:\w]+)!<b>$1</b>!g;
+ $returntext =~ s![\@\\]b\s+[:\w]!<b>$1</b>!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 00000000..0ddd5d7e
--- /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 = (
+ 'QString' => '$',
+ 'QString*' => '$',
+ 'QString&' => '$',
+ 'QCString' => '$',
+ 'QCString*' => '$',
+ 'QCString&' => '$',
+ 'char*' => '$',
+ 'QCOORD*' => '?',
+ 'QRgb*' => '?',
+ 'Q_UINT64' => '$',
+ 'Q_INT64' => '$',
+ 'Q_LLONG' => '$',
+ 'quint64' => '$',
+ '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
+# 'QWSEvent*' => 'void*',
+# 'QDiskFont*' => 'void*',
+# 'XEvent*' => 'void*',
+# 'FILE*' => 'void*',
+# 'QUnknownInterface*' => 'void*',
+# 'GDHandle' => 'void*',
+# '_NPStream*' => 'void*',
+# 'QTextFormat*' => 'void*',
+# 'QTextDocument*' => 'void*',
+# 'QTextCursor*' => 'void*',
+# 'QTextParag**' => 'void*',
+# 'QTextParag*' => 'void*',
+# 'QRemoteInterface*' => 'void*',
+# 'QSqlRecordPrivate*' => 'void*',
+# 'QTSMFI' => 'void*', # QTextStream's QTSManip
+# 'const GUID&' => 'void*',
+# 'QWidgetMapper*' => 'void*',
+# 'MSG*' => 'void*',
+# 'const QSqlFieldInfoList&' => 'void*', # QSqlRecordInfo - TODO (templates)
+
+ 'QStyleHintReturn*' => 'void*',
+ 'QPtrCollection::Item' => 'void*', # to avoid a warning
+
+ 'mode_t' => 'long',
+ 'QProcess::PID' => 'long',
+ 'size_type' => 'int', # QSqlRecordInfo
+ 'Qt::ComparisonFlags' => 'uint',
+ 'Qt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it
+ 'QIODevice::Offset' => 'ulong',
+ 'WState' => 'int',
+ 'WId' => 'ulong',
+ 'QRgb' => 'uint',
+ 'ksocklen_t' => 'uint',
+ 'QCOORD' => 'int',
+ 'QTSMFI' => 'int',
+ 'Qt::WState' => 'int',
+ 'Qt::WFlags' => 'int',
+ 'Qt::HANDLE' => 'uint',
+ 'QEventLoop::ProcessEventsFlags' => 'uint',
+ 'QStyle::SCFlags' => 'int',
+ 'QStyle::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',
+ 'quint16' => 'ushort',
+ 'Q_UINT32' => 'uint',
+ 'quint32' => 'uint',
+ 'Q_UINT8' => 'uchar',
+ 'quint8' => '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',
+ 'Qt::Alignment' => 'int',
+ 'Qt::Orientations' => 'int',
+ 'Qt::DockWidgetAreas' => 'int',
+ 'Qt::DropActions' => 'int',
+ 'Qt::ImageConversionFlags' => 'int',
+ 'Qt::ItemFlags' => 'int',
+ 'Qt::KeyboardModifiers' => 'int',
+ 'Qt::MatchFlags' => 'int',
+ 'Qt::MouseButtons' => 'int',
+ 'Qt::ToolBarAreas' => 'int',
+ 'Qt::WindowFlags' => 'int',
+ 'Qt::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',
+ 'QDir::Filters' => 'int',
+ 'QDir::SortFlags' => 'int',
+ 'QFile::Permissions' => 'int',
+ 'QGL::FormatOptions' => 'int',
+ 'QIODevice::OpenMode' => 'int',
+ 'QImageReader::ImageReaderError' => 'int',
+ 'QItemSelectionModel::SelectionFlags' => 'int',
+ 'QPaintEngine::DirtyFlags' => 'int',
+ 'QPainter::RenderHints' => 'int',
+ 'QSql::ParamType' => 'int',
+ 'QTextDocument::FindFlags' => 'int',
+ 'Q_PID' => 'int',
+ 'Qt::DropActions' => 'int',
+ 'Qt::ImageConversionFlags' => 'int',
+ 'Qt::ItemFlags' => 'int',
+ 'Qt::KeyboardModifiers' => 'int',
+ 'Qt::MatchFlags' => 'int',
+ 'Qt::MouseButtons' => 'int',
+ 'Qt::ToolBarAreas' => 'int',
+ 'Qt::WindowFlags' => 'int',
+ 'Qt::WindowStates' => 'int',
+ 'RenderFlags' => 'int',
+ 'RenderHints' => 'int',
+ 'SortFlags' => 'int',
+ 'StepEnabled' => 'int',
+ 'Sections' => 'int',
+ 'Filters' => 'int',
+ 'SortFlags' => 'int',
+ 'QDir::Filters' => 'int',
+ 'QDir::SortFlags' => 'int',
+ 'QStyle::State' => 'int',
+ 'QValidator::State' => 'int',
+ 'QAbstractSpinBox::StepEnabled' => 'int',
+ 'QDockWidget::DockWidgetFeatures' => 'int',
+ 'QStyle::SubControls' => 'int',
+ 'QSocket::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 = <<EOF;
+ /* Constructor #1 */
+ public QApplication(string[] argv) : this((Type) null) {
+ Qyoto.Init_qyoto();
+ CreateProxy();
+ CreateSignalProxy();
+ Qt.qApp = this;
+
+ string[] args = new string[argv.Length + 1];
+ args[0] = System.Reflection.Assembly.GetExecutingAssembly().Location;
+ argv.CopyTo(args, 1);
+
+ NewQApplication(args);
+ }
+ private void NewQApplication(string[] argv) {
+ ProxyQApplication().NewQApplication(argv.Length, argv);
+ }
+ [SmokeMethod("QApplication(int&, char**)")]
+ private void NewQApplication(int argc, string[] argv) {
+ ProxyQApplication().NewQApplication(argc, argv);
+ }
+ /* end Constructor #1 */
+
+ /* Constructor #2 */
+ public QApplication(string[] argv, bool GUIenabled) : this((Type) null) {
+ Qyoto.Init_qyoto();
+ CreateProxy();
+ CreateSignalProxy();
+ Qt.qApp = this;
+
+ string[] args = new string[argv.Length + 1];
+ args[0] = System.Reflection.Assembly.GetExecutingAssembly().Location;
+ argv.CopyTo(args, 1);
+
+ NewQApplication(args,GUIenabled);
+ }
+ private void NewQApplication(string[] argv, bool GUIenabled) {
+ ProxyQApplication().NewQApplication(argv.Length, argv,GUIenabled);
+ }
+ [SmokeMethod("QApplication(int&, char**, bool)")]
+ private void NewQApplication(int argc, string[] argv, bool GUIenabled) {
+ ProxyQApplication().NewQApplication(argc, argv,GUIenabled);
+ }
+ /* end Constructor #2 */
+
+ /* Constructor #3 */
+ public QApplication(string[] argv, int arg3) : this((Type) null) {
+ Qyoto.Init_qyoto();
+ CreateProxy();
+ CreateSignalProxy();
+ Qt.qApp = this;
+
+ string[] args = new string[argv.Length + 1];
+ args[0] = System.Reflection.Assembly.GetExecutingAssembly().Location;
+ argv.CopyTo(args, 1);
+
+ NewQApplication(args,arg3);
+ }
+ private void NewQApplication(string[] argv, int arg3) {
+ ProxyQApplication().NewQApplication(argv.Length,argv,arg3);
+ }
+ [SmokeMethod("QApplication(int&, char**, QApplication::Type)")]
+ private void NewQApplication(int argc, string[] argv, int arg3) {
+ ProxyQApplication().NewQApplication(argc,argv,arg3);
+ }
+ /* end Constructor #3 */
+
+// public string[] args(return Argv());
+
+EOF
+
+
+ $qbitmapExtras = <<EOF;
+// public QBitmap(QPixmap arg1) {
+// super((Class) null);
+// newQBitmap(arg1);
+// }
+// private native void newQBitmap(QPixmap arg1);
+// public QBitmap(QImage arg1) {
+// super((Class) null);
+// newQBitmap(arg1);
+// }
+// private native void newQBitmap(QImage arg1);
+
+EOF
+
+ $qbytearrayExtras = <<EOF;
+
+EOF
+
+
+ $qlistviewExtras = <<EOF;
+
+EOF
+
+ $qlistviewitemExtras = <<EOF;
+
+EOF
+
+ $qtExtras = <<EOF;
+ public const int IO_Direct = 0x0100;
+ public const int IO_Sequential = 0x0200;
+ public const int IO_Combined = 0x0300;
+ public const int IO_TypeMask = 0x0f00;
+ public const int IO_Raw = 0x0040;
+ public const int IO_Async = 0x0080;
+ public const int IO_ReadOnly = 0x0001;
+ public const int IO_WriteOnly = 0x0002;
+ public const int IO_ReadWrite = 0x0003;
+ public const int IO_Append = 0x0004;
+ public const int IO_Truncate = 0x0008;
+ public const int IO_Translate = 0x0010;
+ public const int IO_ModeMask = 0x00ff;
+ public const int IO_Open = 0x1000;
+ public const int IO_StateMask = 0xf000;
+ public const int IO_Ok = 0;
+ public const int IO_ReadError = 1;
+ public const int IO_WriteError = 2;
+ public const int IO_FatalError = 3;
+ public const int IO_ResourceError = 4;
+ public const int IO_OpenError = 5;
+ public const int IO_ConnectError = 5;
+ public const int IO_AbortError = 6;
+ public const int IO_TimeOutError = 7;
+ public const int IO_UnspecifiedError= 8;
+
+ public static QApplication qApp = null;
+
+ public static string SIGNAL(string signal) {
+ return "2"+ signal;
+ }
+
+ public static string SLOT(string slot) {
+ return "1" + slot;
+ }
+EOF
+
+ $qobjectExtras = <<EOF;
+
+ protected Object Q_EMIT = null;
+EOF
+
+ $qwidgetExtras = <<EOF;
+
+EOF
+
+
+ $qpixmapExtras = <<EOF;
+// public native bool loadFromData(char[] data);
+
+EOF
+
+ $qpaintdeviceExtras = <<EOF;
+
+EOF
+
+
+ $qdragobjectExtras = <<EOF;
+
+EOF
+
+
+ $qdropeventExtras = <<EOF;
+EOF
+
+
+ $qmimesourceExtras = <<EOF;
+EOF
+
+
+ $qiodeviceExtras = <<EOF;
+
+
+EOF
+
+ $qpointarrayExtras = <<EOF;
+// public native int size();
+// public native int count();
+// public native bool isEmpty();
+// public native bool isNull();
+// public native bool resize( int size);
+// public native bool truncate( int pos);
+// public native int begin();
+// public native int end();
+// public native QPoint at(int index);
+
+EOF
+
+ $qsizepolicyExtras = <<EOF;
+
+ public const int HSize = 6;
+ public const int HMask = 0x3f;
+ public const int VMask = HMask<<HSize;
+ public const int MayGrow = 1;
+ public const int ExpMask = 2;
+ public const int MayShrink = 4;
+EOF
+
+ $quridragExtras = <<EOF;
+// public static native bool decode(QMimeSourceInterface e, ArrayList i);
+// public static native bool decodeToUnicodeUris(QMimeSourceInterface e, ArrayList i);
+// public static native bool decodeLocalFiles(QMimeSourceInterface e, ArrayList i);
+
+EOF
+
+
+ $kapplicationExtras = <<EOF;
+ /**
+ Used internally by the KDE Kimono CSharp bindings runtime
+ */
+// public static native void setCSharpSlotFactory();
+
+EOF
+
+
+ $kmainwindowExtras = <<EOF;
+
+EOF
+
+
+}
+
+sub csharpImport($)
+{
+ my ( $classname ) = @_;
+ my $classname_ptr = $classname . "*";
+ if ( cplusplusToCSharp($classname_ptr) eq "" or $classname eq $main::globalSpaceClassName ) {
+ return "";
+ } elsif ( cplusplusToCSharp($classname_ptr) eq "ArrayList" ) {
+ return "System.Collections";
+ } elsif ( cplusplusToCSharp($classname_ptr) eq "DateTime" ) {
+ return "";
+ } elsif ( cplusplusToCSharp($classname_ptr) eq "StringBuilder" ) {
+ return "System.Text";
+ } elsif ( cplusplusToCSharp($classname_ptr) eq "string" ) {
+ return "";
+ } elsif ( cplusplusToCSharp($classname_ptr) eq "string[][]" ) {
+ return "";
+ } elsif ( cplusplusToCSharp($classname_ptr) eq "string[]" ) {
+ return "";
+ } elsif ( cplusplusToCSharp($classname_ptr) eq "DateTime" ) {
+ return "";
+ } elsif ( cplusplusToCSharp($classname_ptr) =~ /^[a-z]/ ) {
+ return "";
+ }
+ return "";
+}
+
+sub cplusplusToCSharp
+{
+ my ( $cplusplusType ) = @_;
+ my $isConst = ($cplusplusType =~ /const / or $cplusplusType !~ /[*&]/ ? 1 : 0);
+ $cplusplusType =~ s/const //;
+ $cplusplusType =~ s/^signed//;
+ my $className = $cplusplusType;
+ $className =~ s/[*&]//;
+
+ if ( $cplusplusType =~ /void\*|KHTMLPart::PageSecurity|QFileInfoList|QValueList<QIconDragItem>|QValueList<QCString>|QValueList<QVariant>|QValueList<QPixmap>|QValueListConstIterator<QString>|QMap|EditMode|QPtrList<QPixmap>|QPtrList<QPoint>|QTextFormat|QTextCursor|QTextDocument|QNetworkProtocolFactoryBase|QDomNodePrivate|QSqlDriverCreatorBase|QSqlFieldInfoList|QObjectUserData|QUObject|QTextParag|QWidgetMapper|QMemArray<int>|QBitArray|QLayoutIterator|QAuBucket|QUnknownInterface|QConnectionList/ ) {
+ 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 =~ /QStringList/|| $cplusplusType =~ /QStrList/) {
+ 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 =~ /QMemArray<QRect>/
+ || 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 =~ /QString/ || $cplusplusType =~ /QCString/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /^(const )?char\s*\*/ ) {
+ return "string"
+ } elsif ( $cplusplusType =~ /QChar\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 =~ /QPaintDevice/ ) {
+ return "IQPaintDevice"
+ } 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 QPtrCollection::Item, for resolveType
+ unless ( kdocAstUtil::findRef( $rootnode, "QPtrCollection::Item" ) ) {
+ my $cNode = kdocAstUtil::findRef( $rootnode, "QPtrCollection" );
+ warn "QPtrCollection 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. QPixmap::QPixmapData
+ exists $classNode->{Tmpl} ||
+ # Don't generate standard bindings for QString, this class is handled as a native type
+ $className eq 'QString' ||
+ $className eq 'QConstString' ||
+ $className eq 'QCString' ||
+ $className eq 'QLatin1String' ||
+ # Don't map classes which are really arrays
+ $className eq 'QStringList' ||
+ $className eq 'QCanvasItemList' ||
+ $className eq 'QWidgetList' ||
+ $className eq 'QObjectList' ||
+ $className eq 'QStrList' ||
+ # Those are template related
+ $className eq 'QTSManip' || # cause compiler errors with several gcc versions
+ $className eq 'QIconFactory' ||
+ $className eq 'QGDict' ||
+ $className eq 'QGList' ||
+ $className eq 'QGVector' ||
+ $className eq 'QStrIList' ||
+ $className eq 'QStrIVec' ||
+ $className eq 'QBitArray' ||
+ $className eq 'QWExtra' ||
+ $className eq 'QTLWExtra' ||
+ ($className eq 'QAbstractUndoItem' and $main::qt4) ||
+ ($className eq 'QDebug' and $main::qt4) ||
+ ($className eq 'QNoDebug' and $main::qt4) ||
+ ($className eq 'QObjectData' and $main::qt4) ||
+ ($className eq 'QSysInfo' and $main::qt4) ||
+ ($className eq 'QPNGImageWriter' and $main::qt4) ||
+ ($className eq 'QPNGImagePacker' and $main::qt4) ||
+ ($className eq 'QTextCodec::ConverterState' and $main::qt4) ||
+ ($className eq 'QTextLayout::Selection' and $main::qt4) ||
+ ($className eq 'QTextStreamManipulator' and $main::qt4) ||
+ ($className eq 'iterator' and $main::qt4) ||
+ $className eq 'QMetaEnum::Item' ||
+ $className eq 'QWidgetContainerPlugin' ||
+ $className eq 'QGArray::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 'QForeachContainerBase' || # Qt4
+ $className eq 'QInputMethodEvent::Attribute' || # Qt4
+ $className eq 'QAbstractTextDocumentLayout::PaintContext' || # Qt4
+ $className eq 'QAbstractTextDocumentLayout::Selection' || # Qt4
+ $className eq 'QBrushData' || # Qt4
+ $className eq 'QIPv6Address' || # Qt4
+ $className eq 'QImageTextKeyLang' || # Qt4
+ $className eq 'QMap' || # Qt4
+ $className eq 'QMap::const_iterator' || # Qt4
+ $className eq 'QMap::iterator' || # Qt4
+ $className eq 'QMapData' || # Qt4
+ $className eq 'QMapData::Node' || # Qt4
+ $className eq 'QSharedData' || # Qt4
+ $className eq 'QPainterPath::Element' || # Qt4
+ $className eq 'QThreadStorageData' || # Qt4
+ $className eq 'QVFbHeader' || # Qt4
+ $className eq 'QStyleOptionQ3DockWindow' || # Qt4
+ $className eq 'QStyleOptionQ3ListView' || # Qt4
+ $className eq 'QStyleOptionQ3ListViewItem' || # Qt4
+ $className eq 'QStyleOptionQ3ListView' || # Qt4
+ $className eq 'QTextLayout::FormatRange' || # Qt4
+ $className eq 'QVFbKeyData' || # Qt4
+ $className eq 'QVariant::Handler' || # Qt4
+ $className eq 'QVariant::PrivateShared' || # Qt4
+ $className eq 'QVectorData' || # Qt4
+ $className eq 'QWidgetData' || # 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. QPDevCmdParam
+ ) {
+ 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' # QFile'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} =~ /^QUrl/ and $name eq 'operator==')
+ || ($classNode->{astNodeName} eq 'QUriDrag' 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 'QApplication' and $name eq 'QApplication')
+ # 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 'QWidgetListItem' and $name eq 'operator=')
+ || ($classNode->{astNodeName} eq 'QColormap' and $name eq 'operator=')
+ || ($classNode->{astNodeName} eq 'QMatrix' and $name eq 'operator*=')
+ || ($classNode->{astNodeName} eq 'QListWidget' and $name eq 'setItemPosition')
+ || ($classNode->{astNodeName} eq 'QFontMetricsF' and $name eq 'operator=')
+ || ($classNode->{astNodeName} eq 'QFontMetricsF' and $name eq 'QFontMetricsF'
+ and $#{$m->{ParamList}} == 0 && $m->{ParamList}[0]->{ArgType} eq 'const QFontMetrics&')
+ || ($classNode->{astNodeName} eq 'QHttp' and $name eq 'supportedOperations')
+ || ($classNode->{astNodeName} eq 'QRectF' and $name eq 'setX')
+ || ($classNode->{astNodeName} eq 'QRectF' and $name eq 'setY')
+ || ($classNode->{astNodeName} eq 'QTextObject' and $name eq 'formatType')
+ || ($classNode->{astNodeName} eq 'QUrl' and $name eq 'QUrl'
+ and $#{$m->{ParamList}} == 0 && $m->{ParamList}[0]->{ArgType} eq 'QUrlPrivate&')
+ || ($classNode->{astNodeName} eq 'QGlobalSpace' and $name eq 'operator<<' and $m->{ParamList}[0]->{ArgType} =~ /QDebug/)
+ || ($classNode->{astNodeName} eq 'QGlobalSpace' and $#{$m->{ParamList}} > 0 and $name =~ /operator/ and $m->{ParamList}[1]->{ArgType} =~ /QVariant::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' # QImage's callback
+ or $arg->{ArgType} eq 'DecoderFn' # QFile's callback
+ or $arg->{ArgType} eq 'EncoderFn' # QFile's callback
+ or $arg->{ArgType} =~ /bool \(\*\)\(QObject/ # QMetaObject's ctor
+ or $arg->{ArgType} eq 'QtStaticMetaObjectFunction' # QMetaObjectCleanUp's ctor with func pointer
+ or $arg->{ArgType} eq 'const QTextItem&' # 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 QSessionManager::RestartHint
+ # (QSessionManagerJBridge doesn't inherit QSessionManager)
+ $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 QColor::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. QCanvasItem)
+ # Same if the class has only private constructors (e.g. QInputDialog)
+ $classNode->AddProp( "CanBeInstanciated", $hasPublicProtectedConstructor
+# && !$hasPrivatePureVirtual
+ && (!$classNode->{Pure} or $classNode->{astNodeName} eq 'QValidator')
+ && !($classNode->{NodeType} eq 'namespace')
+ && ($classNode->{astNodeName} !~ /^DrawContentsEvent$|^MouseEvent$|^MouseDoubleClickEvent$|^MouseMoveEvent$|^MouseReleaseEvent$|^MousePressEvent$/)
+ && ($classNode->{astNodeName} !~ /QMetaObject|QDragObject|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 QAsyncIO. 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 'QAsyncIO' );
+
+ # 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 "QMemArray" and $name ne "QSqlFieldInfoList" ) {
+ 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 'QListView' or $className eq 'QListViewItem' or $className eq 'QUriDrag' ) {
+ # 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 <see cref=\"I$csharpClassName" . "Signals\"></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 'QApplication' and ! $main::qt4 ) {
+ print CLASS $qapplicationExtras;
+ } elsif ( $className eq 'QBitmap' ) {
+ print CLASS $qbitmapExtras;
+ } elsif ( $className eq 'QByteArray' and ! $main::qt4) {
+ print CLASS $qbytearrayExtras;
+ } elsif ( $className eq 'QDropEvent' ) {
+ print CLASS $qdropeventExtras;
+ } elsif ( $className eq 'QDragObject' ) {
+ print CLASS $qdragobjectExtras;
+ } elsif ( $className eq 'QObject' ) {
+ print CLASS $qobjectExtras;
+ } elsif ( $className eq 'QListView' ) {
+ print CLASS $qlistviewExtras;
+ } elsif ( $className eq 'QListViewItem' ) {
+ print CLASS $qlistviewitemExtras;
+ } elsif ( $className eq 'QMimeSource' ) {
+ print CLASS $qmimesourceExtras;
+ } elsif ( $className eq 'QWidget' ) {
+ print CLASS $qwidgetExtras;
+ } elsif ( $className eq 'QPaintDevice' ) {
+ print CLASS $qpaintdeviceExtras;
+ } elsif ( $className eq 'QPixmap' ) {
+ print CLASS $qpixmapExtras;
+ } elsif ( $className eq 'QIODevice' ) {
+ print CLASS $qiodeviceExtras;
+ } elsif ( $className eq 'QPointArray' ) {
+ print CLASS $qpointarrayExtras;
+ } elsif ( $className eq 'QSizePolicy' ) {
+ print CLASS $qsizepolicyExtras;
+ } elsif ( $className eq 'QUriDrag' ) {
+ print CLASS $quridragExtras;
+ } elsif ( $className eq 'KApplication' ) {
+ print CLASS $kapplicationExtras;
+ } elsif ( $className eq 'KMainWindow' ) {
+ print CLASS $kmainwindowExtras;
+ }
+
+
+ if ( is_kindof($node, "QObject") ) {
+ 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 'QString' ) { # 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.
+# (QObject*)x[1].s_class,(QEvent*)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 'QString' ) { # 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 'QWidget', while currentClassName is 'QRangeControl'
+ # and the QRangeControl methods are being copied into QWidget.
+ 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/|kdeprint/|kdesu/)(.*)!$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/QGfx\s*\*/ );
+# return if ( $returnType eq 'CGContextRef' );
+# return if ( $returnType eq 'QWSDisplay *' );
+# # 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+/ );
+# # QFile's EncoderFn/DecoderFn
+# return if ( $name =~ /set[ED][ne]codingFunction/ );
+# # How to implement this? (QXmlDefaultHandler/QXmlEntityResolver::resolveEntity, needs A*&)
+# return if ( $name eq 'resolveEntity' and $className =~ /^QXml/ );
+# return if ( $className eq 'QBitArray' && $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 'QApplication' 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 'QButtonGroup') {
+ # Can't override a static method find() in QWidget
+ $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 'QMessageBox' ) {
+ $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, "QObject") ) {
+ $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 QGlobalSpace 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 = "QLayout";
+ } elsif ($csharpSignature eq "defaultFactory()" and $csharpReturnType eq 'QSqlEditorFactory') {
+ $csharpReturnType = "QEditorFactory";
+ } elsif ($csharpSignature eq "statusBar()") {
+ $altReturnType = "QStatusBar";
+ } elsif ($csharpSignature eq "menuBar()") {
+ $altReturnType = "QMenuBar";
+ } 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 'QIODevice' 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 QWidget current
+ # classname might be QPaintDevice, as its methods are needed in QWidget.
+ my $currentClassName = join( ".", kdocAstUtil::heritage($classNode) );
+
+ my $sourcename = $classNode->{Source}->{astNodeName};
+
+ if ( $sourcename !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|kdeprint/|kdesu/)(.*)!$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/|kdeprint/|kdesu/)(.*)!$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 'QTextEdit::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 =~ /QMemArray|QSqlFieldInfoList/) {
+ # 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 'QLineEdit' && ( $name eq 'setPasswordChar' || $name eq 'passwordChar' ) );
+ $ok = 0 if ( $ok && $className eq 'QWidgetItem' && $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 QBlah*
+ $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 =~ /</ ) { # Don't warn for template stuff...
+ print STDERR "$realType isn't a known type (type=$type)\n";
+ }
+ }
+ $typeId = 't_voidp'; # Unknown -> 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 <see>'s; @p's and @em's are converted
+ to inline HTML.
+
+=cut
+
+sub printCSharpdocComment($$$$)
+{
+ my( $docnode, $name, $indent, $signalLink ) = @_;
+
+ my $node;
+ my $returntext = '<remarks>';
+ 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> name=\"" . $node->{Name} . "\" " . $node->{astNodeName} . "</param>";
+ }
+ } 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 )?QDate(Time)?(\s*&)?/DateTime/g;
+ $line =~ s/(const )?QTime([^r])/DateTime$1/g;
+ $line =~ s/QString::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*(\([^\)]*\))(\.)?!<see cref=\"$1#$2\"></see>$4!g;
+ $line =~ s!\@ref\s+#([\w:]+)(\(\))?!<see cref=\"#$1\"</see>!g;
+ $line =~ s!\@ref\s+([\w]+)\s*(\([^\)]*\))!<see cref=\"#$1\"></see>!g;
+ $line =~ s!\@ref\s+([\w]+)::([\w]+)!<see cref=\"$1#$2\"></see>!g;
+ $line =~ s!\@ref\s+([a-z][\w]+)!<see cref=\"#$1\"></see>!g;
+ $line =~ s!\@ref\s+([\w]+)!<see cref=\"$1\"></see>!g;
+ while ($line =~ /\@c\s+([\w#\\\.<>]+)/ ) {
+ my $code = $1;
+ $code =~ s!<!&lt;!g;
+ $code =~ s!>!&gt;!g;
+ $code =~ s!\\#!#!g;
+ $line =~ s!\@c\s+([\w#\\\.<>]+)!<code>$code</code>!;
+ }
+ $line =~ s!\@em\s+(\w+)!<b>$1</b>!g;
+ $line =~ s!\@p\s+([\w\._]*)!<code>$1</code>!g;
+ $line =~ s!\\paragraph\s+[\w]+\s([\w]+)!<li><b>$1</b></li>!g;
+ $line =~ s!\\b\s+([\w -]+)\\n!<li><b>$1</b></li>!g;
+ $line =~ s!\\c\s+([\w\@&\\?;-]+)!<code>$1</code>!g;
+ $line =~ s!\\p\s+([\w\@]+)!<pre>$1</pre>!g;
+ $line =~ s!\\li\s+([\w\@]+)!<li>$1</li>!g;
+ $line =~ s!<b>([\w\t \(\)-]*:?)</b>\\n!<li><b>$1</b></li>!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<li>\n/;
+ $line =~ s!$!\n</li>!;
+# $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</remarks>";
+
+ if ( defined $docnode->{Returns} ) {
+ my $text = $docnode->{Returns};
+ $text =~ s/QString::null/null/g;
+ $returntext .= "\t\t<return> $text</return>\n";
+ }
+
+ if ( defined $docnode->{Author} ) {
+ $returntext .= "\t\t<author> " . $docnode->{Author} . "</author>\n"
+ }
+
+ if ( defined $docnode->{Version} ) {
+ my $versionStr = $docnode->{Version};
+ $versionStr =~ s/\$\s*Id:([^\$]*) Exp \$/$1/;
+ $returntext .= "\t\t<version> $versionStr</version>\n";
+ }
+
+ if ( defined $docnode->{ClassShort} ) {
+ my $shortText = $docnode->{ClassShort};
+ $shortText =~ s![\*\n]! !g;
+ $returntext .= "\t\t<short> $shortText</short>\n";
+ }
+
+ if ( defined $docnode->{See} ) {
+ foreach my $text ( @{$docnode->{See}} ) {
+ next if ($text =~ /QString|^\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<see> $text</see>\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/QChar/char/g;
+ $returntext =~ s/QStringList/ArrayList/g;
+ $returntext =~ s/([Aa]) ArrayList/$1n ArrayList/g;
+ $returntext =~ s/QString/string/g;
+ $returntext =~ s/KCmdLineOptions/string[][]/;
+ $returntext =~ s!\\note!<b>Note:<\b>!g;
+ $returntext =~ s!\\(code|verbatim)!<pre>!g;
+ $returntext =~ s!\\(endcode|endverbatim)!</pre>!g;
+ $returntext =~ s!\\addtogroup\s+[\w]+\s+"([^"\@]+)"\s+\@{!<li><b>$1</b></li>!g;
+ $returntext =~ s![\\\@]relates\s+([a-z][\w]*)!<see cref=\"$1\"></see>!g;
+ $returntext =~ s![\\\@]relates\s+(\w+)::(\w+)!<see cref=\"$1.$2\"></see>!g;
+ $returntext =~ s![\\\@]relates\s+(#?\w+)!<see cref=\"$1\"></see>!g;
+ $returntext =~ s!\\c\s+([\w\@&\\?";-]+)!<code>$1</code>!g;
+ $returntext =~ s!\@p\s+([\w\._]*)!<code>$1</code>!g;
+ $returntext =~ s!\@a\s+([:\w]+)!<b>$1</b>!g;
+ $returntext =~ s![\@\\]b\s+[:\w]!<b>$1</b>!g;
+ $returntext =~ s/};/}/g;
+
+ while ($returntext =~ /((::)|(->))(.)/) {
+ my $temp = uc($4);
+ $returntext =~ s/$1$4/.$temp/;
+ }
+
+ $returntext =~ s/\s*$//;
+ if ($returntext =~ /^<remarks>\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
new file mode 100644
index 00000000..f8cba6f3
--- /dev/null
+++ b/kalyptus/kalyptusCxxToSmoke.pm
@@ -0,0 +1,2759 @@
+#***************************************************************************
+# kalyptusCxxToSmoke.pm - Generates x_*.cpp files for smoke
+# -------------------
+# 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 kalyptusCxxToSmoke;
+
+use File::Path;
+use File::Basename;
+use constant numSourceFiles => 20; # Total number of generated source files.
+ # All classes will be distributed across those.
+
+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
+ $methodNumber $headerSubdirectories
+ %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 = (
+ 'QString' => '$',
+ 'QString*' => '$',
+ 'QString&' => '$',
+ 'QCString' => '$',
+ 'QCString*' => '$',
+ 'QCString&' => '$',
+ 'char*' => '$',
+ 'QCOORD*' => '?',
+ 'QRgb*' => '?',
+ 'Q_UINT64' => '$',
+ 'Q_INT64' => '$',
+ 'Q_LLONG' => '$',
+ 'quint64' => '$',
+ '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',
+ 'signed long' => 'long',
+ 'unsigned long' => 'ulong',
+
+# Anything that is not known is mapped to void*, so no need for those here anymore
+# 'QWSEvent*' => 'void*',
+# 'QDiskFont*' => 'void*',
+# 'XEvent*' => 'void*',
+# 'QStyleHintReturn*' => 'void*',
+# 'FILE*' => 'void*',
+# 'QUnknownInterface*' => 'void*',
+# 'GDHandle' => 'void*',
+# '_NPStream*' => 'void*',
+# 'QTextFormat*' => 'void*',
+# 'QTextDocument*' => 'void*',
+# 'QTextCursor*' => 'void*',
+# 'QTextParag**' => 'void*',
+# 'QTextParag*' => 'void*',
+# 'QRemoteInterface*' => 'void*',
+# 'QSqlRecordPrivate*' => 'void*',
+# 'QTSMFI' => 'void*', # QTextStream's QTSManip
+# 'const GUID&' => 'void*',
+# 'QWidgetMapper*' => 'void*',
+ 'MSG*' => 'void*',
+# 'const QSqlFieldInfoList&' => 'void*', # QSqlRecordInfo - TODO (templates)
+
+ 'QPtrCollection::Item' => 'void*', # to avoid a warning
+
+ 'void(* )()' => 'void*',
+ 'void (*)(void* )' => 'void*',
+ 'mode_t' => 'long',
+ 'QProcess::PID' => 'long',
+ 'size_type' => 'int', # QSqlRecordInfo
+ 'Qt::ComparisonFlags' => 'uint',
+ 'Qt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it
+ 'QIODevice::Offset' => 'ulong',
+ 'WState' => 'int',
+ 'WId' => 'ulong',
+ 'QRgb' => 'uint',
+ 'ksocklen_t' => 'uint',
+ 'QCOORD' => 'int',
+ 'QTSMFI' => 'int',
+ 'Qt::WState' => 'int',
+ 'Qt::WFlags' => 'int',
+ 'Qt::HANDLE' => 'uint',
+ 'QEventLoop::ProcessEventsFlags' => 'uint',
+ 'QStyle::SCFlags' => 'int',
+ 'QStyle::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',
+ 'quint16' => 'ushort',
+ 'Q_UINT32' => 'uint',
+ 'quint32' => 'uint',
+ 'Q_UINT8' => 'uchar',
+ 'quint8' => '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',
+ 'Qt::Alignment' => 'int',
+ 'Qt::Orientations' => 'int',
+ 'Qt::DockWidgetAreas' => 'int',
+ 'Qt::DropActions' => 'int',
+ 'Qt::ImageConversionFlags' => 'int',
+ 'Qt::ItemFlags' => 'int',
+ 'Qt::KeyboardModifiers' => 'int',
+ 'Qt::MatchFlags' => 'int',
+ 'Qt::MouseButtons' => 'int',
+ 'Qt::ToolBarAreas' => 'int',
+ 'Qt::WindowFlags' => 'int',
+ 'Qt::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',
+ 'QDir::Filters' => 'int',
+ 'QDir::SortFlags' => 'int',
+ 'QFile::Permissions' => 'int',
+ 'QGL::FormatOptions' => 'int',
+ 'QIODevice::OpenMode' => 'int',
+ 'QImageReader::ImageReaderError' => 'int',
+ 'QItemSelectionModel::SelectionFlags' => 'int',
+ 'QPaintEngine::DirtyFlags' => 'int',
+ 'QPainter::RenderHints' => 'int',
+ 'QSql::ParamType' => 'int',
+ 'QTextDocument::FindFlags' => 'int',
+ 'Q_PID' => 'int',
+ 'Qt::DropActions' => 'int',
+ 'Qt::ImageConversionFlags' => 'int',
+ 'Qt::ItemFlags' => 'int',
+ 'Qt::KeyboardModifiers' => 'int',
+ 'Qt::MatchFlags' => 'int',
+ 'Qt::MouseButtons' => 'int',
+ 'Qt::ToolBarAreas' => 'int',
+ 'Qt::WindowFlags' => 'int',
+ 'Qt::WindowStates' => 'int',
+ 'RenderFlags' => 'int',
+ 'RenderHints' => 'int',
+ 'SortFlags' => 'int',
+ 'StepEnabled' => 'int',
+ 'Sections' => 'int',
+ 'Filters' => 'int',
+ 'SortFlags' => 'int',
+ 'QDir::Filters' => 'int',
+ 'QDir::SortFlags' => 'int',
+ 'QStyle::State' => 'int',
+ 'QValidator::State' => 'int',
+ 'QAbstractSpinBox::StepEnabled' => 'int',
+ 'QDockWidget::DockWidgetFeatures' => 'int',
+ 'QStyle::SubControls' => 'int',
+);
+
+$headerSubdirectories = "kio/|kdevelop/|kinterfacedesigner/|kontact/|kate/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|kdeprint/|kdesu/|knewstuff/"
+
+}
+
+sub writeDoc
+{
+ ( $libname, $rootnode, $outputdir, $opt ) = @_;
+
+ print STDERR "Starting writeDoc for $libname...\n";
+
+ $debug = $main::debuggen;
+
+ mkpath( $outputdir ) unless -f $outputdir;
+
+ # Define QPtrCollection::Item, for resolveType
+ unless ( kdocAstUtil::findRef( $rootnode, "QPtrCollection::Item" ) || $main::qt4 ) {
+ my $cNode = kdocAstUtil::findRef( $rootnode, "QPtrCollection" );
+ warn "QPtrCollection 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 ); } );
+
+ print STDERR "Writing smokedata.cpp...\n";
+
+ # Write out smokedata.cpp
+ writeSmokeDataFile($rootnode);
+
+ print STDERR "Writing x_*.cpp...\n";
+
+ # Generate x_*cpp file for each class
+
+ my $numclasses;
+ Iter::LocalCompounds( $rootnode, sub { $numclasses++ } );
+ my $classperfile = int($numclasses/numSourceFiles);
+ print STDERR "Total number of classes: ". $numclasses ."\n" if $debug;
+ my $nodelist = [];
+ my $currentfile = 1;
+ my $currentclass = 1;
+ Iter::LocalCompounds( $rootnode, sub {
+ push @$nodelist, shift;
+ if(@$nodelist == $classperfile and $currentfile != numSourceFiles)
+ {
+ print STDERR "Calling writeClassDoc for ". (scalar @$nodelist) . " classes\n" if $debug;
+ writeClassDoc( $nodelist );
+ $currentfile++;
+ $nodelist = []
+ }
+ if(@$nodelist and $currentclass == $numclasses)
+ {
+ print STDERR "Calling writeClassDoc for remaining ". (scalar @$nodelist) . " classes\n" if $debug;
+ writeClassDoc( $nodelist )
+ }
+ $currentclass++
+ });
+
+ 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. QPixmap::QPixmapData
+ exists $classNode->{Tmpl} ||
+ # Don't generate standard bindings for QString, this class is handled as a native type
+ $className eq 'QString' ||
+ $className eq 'QStringData' ||
+ $className eq 'QLatin1String' ||
+ $className eq 'QTLWExtra' ||
+ $className eq 'QWExtra' ||
+ $className eq 'QBig5Codec' ||
+ $className eq 'QBig5hkscsCodec' ||
+ $className eq 'QPtrCollection' ||
+ $className eq 'QGCache' ||
+ $className eq 'QConstString' ||
+ $className eq 'QCString' ||
+ # Don't map classes which are really arrays
+ $className eq 'QStringList' ||
+ $className eq 'QCanvasItemList' ||
+ $className eq 'QWidgetList' ||
+ $className eq 'QObjectList' ||
+ $className eq 'QStrList' ||
+ $className eq 'KCmdLineOptions' ||
+ # Those are template related
+ $className eq 'QTSManip' || # cause compiler errors with several gcc versions
+ $className eq 'QGDict' ||
+ $className eq 'QGList' ||
+ $className eq 'QGArray' ||
+ $className eq 'QGVector' ||
+ $className eq 'QStrIList' ||
+ $className eq 'QStrIVec' ||
+ $className eq 'QBitArray' ||
+ $className eq 'QMapData' ||
+ $className eq 'QMetaEnum::Item' ||
+ $className eq 'QWidgetContainerPlugin' ||
+ $className eq 'QGArray::array_data' ||
+ ($className eq 'QMenuItem' and $main::qt_embedded) ||
+ ($className eq 'QSignal' and $main::qt_embedded) ||
+ ($className eq 'QWSEvent' and $main::qt_embedded) ||
+ ($className eq 'QMetaObjectInit' and $main::qt_embedded) ||
+ ($className eq 'QKoi8Codec' and $main::qt_embedded) ||
+ $className eq 'KAccelGen' ||
+ ($className eq 'QAbstractUndoItem' and $main::qt4) ||
+ ($className eq 'QAbstractItemDelegate' and $main::qt4) ||
+ ($className eq 'QDebug' and $main::qt4) ||
+ ($className eq 'QNoDebug' and $main::qt4) ||
+ ($className eq 'QObjectData' and $main::qt4) ||
+ ($className eq 'QSysInfo' and $main::qt4) ||
+ ($className eq 'QPNGImageWriter' and $main::qt4) ||
+ ($className eq 'QPNGImagePacker' and $main::qt4) ||
+ ($className eq 'QTextCodec::ConverterState' and $main::qt4) ||
+ ($className eq 'QTextLayout::Selection' and $main::qt4) ||
+ ($className eq 'QTextStreamManipulator' 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 'QForeachContainerBase' || # Qt4
+ $className eq 'QInputMethodEvent::Attribute' || # Qt4
+ $className eq 'QAbstractTextDocumentLayout::PaintContext' || # Qt4
+ $className eq 'QAbstractTextDocumentLayout::Selection' || # Qt4
+ $className eq 'QBrushData' || # Qt4
+ $className eq 'QIPv6Address' || # Qt4
+ $className eq 'QImageTextKeyLang' || # Qt4
+ $className eq 'QMap' || # Qt4
+ $className eq 'QMap::const_iterator' || # Qt4
+ $className eq 'QMap::iterator' || # Qt4
+ $className eq 'QMapData' || # Qt4
+ $className eq 'QMapData::Node' || # Qt4
+ $className eq 'QSharedData' || # Qt4
+ $className eq 'QPainterPath::Element' || # Qt4
+ $className eq 'QThreadStorageData' || # Qt4
+ $className eq 'QVFbHeader' || # Qt4
+ $className eq 'QStyleOptionQ3DockWindow' || # Qt4
+ $className eq 'QStyleOptionQ3ListView' || # Qt4
+ $className eq 'QStyleOptionQ3ListViewItem' || # Qt4
+ $className eq 'QStyleOptionQ3ListView' || # Qt4
+ $className eq 'QUpdateLaterEvent' || # Qt4
+ $className eq 'QVFbKeyData' || # Qt4
+ $className eq 'QVariant::Handler' || # Qt4
+ $className eq 'QVariant::PrivateShared' || # Qt4
+ $className eq 'QVectorData' || # Qt4
+ $className eq 'QWidgetData' || # Qt4
+ $className eq 'QThread' || # Qt4
+ $className eq 'QThreadStorage' || # Qt4
+ $className eq 'QMutex' || # Qt4
+ $className eq 'QMutexLocker' || # Qt4
+ $className eq 'QSemaphore' || # Qt4
+ $className eq 'QWaitCondition' || # Qt4
+ $className eq 'QReadWriteLock' || # Qt4
+ $className eq 'QReadLocker' || # Qt4
+ $className eq 'QWriteLocker' ||
+ $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. QPDevCmdParam
+ ) {
+ 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.
+
+ # Hack to fix up KLed constructors in KDE 3.1
+ my $kledAmbiguousConstructor = undef;
+
+ 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' # QFile'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};
+ (my $classNameWithoutNS = $className) =~ s/^.*:://;
+ if ($theArgType =~ /$classNameWithoutNS\s*\&/) {
+ $hasCopyConstructor = 1;
+ $m->{Flags} .= "x";
+ $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 '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 'QTextStream' and $name eq 'QTextStream'
+ and @{$m->{ParamList}} == 2 and $m->{ParamList}[0]->{ArgType} eq 'QString&')
+
+ # Various methods to skip in Qt/E (Qt 2.3.x)
+ || ($main::qt_embedded
+ && ( ($classNode->{astNodeName} eq 'QUriDrag' and $name =~ /^decode$|decodeLocalFiles|decodeToUnicodeUris/)
+ || ($classNode->{astNodeName} eq 'QApplication' and $name =~ /^qwsSetCustomColors|^setArgs$|^winMouseButtonUp|^winFocus|^winMouseButtonUP$|^winVersion$/)
+ || ($classNode->{astNodeName} eq 'QPrinter' and $name =~ /^setIdle$|^setActive$/)
+ || ($classNode->{astNodeName} eq 'QDragObject' and $name eq 'dragLink')
+ || ($classNode->{astNodeName} eq 'QFont' and $name eq 'qwsRenderToDisk')
+ || ($classNode->{astNodeName} eq 'QFontInfo' and $name eq 'font')
+ || ($classNode->{astNodeName} eq 'QLineEdit' and $name eq 'getSelection')
+ || ($classNode->{astNodeName} eq 'QMainWindow' and $name eq 'toolBars')
+ || ($classNode->{astNodeName} eq 'QMovie' and $name eq 'setDisplayWidget')
+ || ($classNode->{astNodeName} eq 'QMetaObject' and $name =~ /^new_metaenum_item$|^new_metaaccess$/)
+ || ($classNode->{astNodeName} eq 'QPainter' and $name eq 'pos')
+ || ($classNode->{astNodeName} eq 'QPixmap' 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 'QWidgetListItem' and $name eq 'operator=')
+ || ($classNode->{astNodeName} eq 'QColormap' and $name eq 'operator=')
+ || ($classNode->{astNodeName} eq 'QListWidget' and $name eq 'setItemPosition')
+ || ($classNode->{astNodeName} eq 'QFontMetricsF' and $name eq 'operator=')
+ || ($classNode->{astNodeName} eq 'QFontMetricsF' and $name eq 'QFontMetricsF'
+ and $#{$m->{ParamList}} == 0 && $m->{ParamList}[0]->{ArgType} eq 'const QFontMetrics&')
+ || ($classNode->{astNodeName} eq 'QHttp' and $name eq 'supportedOperations')
+ || ($classNode->{astNodeName} eq 'QRectF' and $name eq 'setX')
+ || ($classNode->{astNodeName} eq 'QRectF' and $name eq 'setY')
+ || ($classNode->{astNodeName} eq 'QTextObject' and $name eq 'formatType')
+ || ($classNode->{astNodeName} eq 'QUrl' and $name eq 'QUrl'
+ and $#{$m->{ParamList}} == 0 && $m->{ParamList}[0]->{ArgType} eq 'QUrlPrivate&')
+ || ($classNode->{astNodeName} eq 'QGlobalSpace' and $name eq 'operator<<' and $m->{ParamList}[0]->{ArgType} =~ /QDebug/)
+ || ($classNode->{astNodeName} eq 'QGlobalSpace' and $#{$m->{ParamList}} > 0 and $name =~ /operator/ and $m->{ParamList}[1]->{ArgType} =~ /QVariant::Type/)
+ || ($#{$m->{ParamList}} > 0 and $m->{ParamList}[0]->{ArgType} =~ /Private/)
+ || ($classNode->{astNodeName} eq 'QScrollArea' and $name eq 'alignment')
+ || ($classNode->{astNodeName} eq 'QScrollArea' 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} =~ /QColor/ && 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}} ) {
+ # 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' # QImage's callback
+ or $arg->{ArgType} eq 'DecoderFn' # QFile's callback
+ or $arg->{ArgType} eq 'EncoderFn' # QFile's callback
+ or $arg->{ArgType} =~ /bool \(\*\)\(QObject/ # QMetaObject's ctor
+ or $arg->{ArgType} eq 'QtStaticMetaObjectFunction' # QMetaObjectCleanUp's ctor with func pointer
+ or $arg->{ArgType} eq 'const QTextItem&' # 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 QSessionManager::RestartHint
+ # (x_QSessionManager doesn't inherit QSessionManager)
+ $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};
+
+ 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
+ registerType( $fullEnumName );
+
+ # Remember that it's an enum
+ findTypeEntry( $fullEnumName )->{isEnum} = 1;
+
+ #print STDERR "$fullEnumName is an enum\n";
+ }
+ elsif( $m->{NodeType} eq 'var' ) {
+ if ( ($classNode->{astNodeName} eq 'QUuid' 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};
+ $varType =~ s/const\s+(.*)\s*&/$1/;
+ $varType =~ s/^\s*//;
+ $varType =~ s/\s*$//;
+ $varType =~ s/static\s+//;
+
+ if ( $m->{Flags} =~ "s" ) {
+ # We are interested in public static vars, like QColor::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
+ );
+ $main::doPrivate = $doPrivate;
+
+ print STDERR "$className: ctor count: $constructorCount, hasPublicProtectedConstructor: $hasPublicProtectedConstructor, hasCopyConstructor: $hasCopyConstructor:, defaultConstructor: $defaultConstructor, hasPublicDestructor: $hasPublicDestructor, hasPrivatePureVirtual:$hasPrivatePureVirtual\n" if ($debug);
+
+ 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 && $classNode->{NodeType} ne 'namespace' ) {
+ # 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 && !$isGlobalSpace && $classNode->{NodeType} ne 'namespace' ) {
+ 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. QCanvasItem)
+ # Same if the class has only private constructors (e.g. QInputDialog)
+ $classNode->AddProp( "CanBeInstanciated", $hasPublicProtectedConstructor && !$hasPrivatePureVirtual );
+
+ # 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 );
+
+ # We need a public dtor to destroy the object --- ### aren't protected dtors ok too ??
+ $classNode->AddProp( "HasPublicDestructor", $hasPublicDestructor );
+
+ # Hack for QAsyncIO. 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 'QAsyncIO' );
+
+ # 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", "ix" ); # Only for internal use in marshallers
+ 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 series of classes to be written out
+
+=cut
+
+BEGIN {
+
+my $fhn =1; # static
+
+ sub writeClassDoc
+ {
+ my $nodelist = shift;
+ my $file = "$outputdir/x_${fhn}.cpp";
+ open( my $fh, ">$file" ) || die "Couldn't create $file\n";
+
+ print $fh "//Auto-generated by $0. DO NOT EDIT.\n";
+ print $fh "#include <smoke.h>\n";
+ print $fh "#include <${libname}_smoke.h>\n";
+
+ my @code;
+ for my $node ( @$nodelist )
+ {
+ push @code, [generateAllMethods( $node )]
+ }
+ 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 <qregexp.h>\n";
+ delete $includes{"qregexp.h"};
+ }
+ if (defined $includes{"qmime.h"}) {
+ print $fh "#include <qurl.h>\n";
+ delete $includes{"qurl.h"};
+ }
+ if (defined $includes{"kshortcut.h"}) {
+ print $fh "#include <kshortcut.h>\n";
+ delete $includes{"kshortcut.h"};
+ }
+ if (defined $includes{"kshortcutlist.h"}) {
+ print $fh "#include <kconfigbase.h>\n";
+ print $fh "#include <kshortcutlist.h>\n";
+ delete $includes{"kconfigbase.h"};
+ delete $includes{"kshortcutlist.h"};
+ }
+ if (defined $includes{"kaction.h"}) {
+ print $fh "#include <kaction.h>\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 )
+ {
+ my ($methodCode, $switchCode, $incl) = @{ $code[$c] };
+ my $node = $$nodelist[$c];
+ my $className = join( "::", kdocAstUtil::heritage($node) );
+ my $legacyClassName = join( "__", kdocAstUtil::heritage($node) );
+ print $fh "class x_$legacyClassName ";
+ print $fh ": public $className " if $node->{BindingDerives};
+ print $fh "{\n";
+ print $fh $methodCode;
+ print $fh "};\n";
+ if(keys %{$node->{enumerations}}) {
+ print $fh "void xenum_${legacyClassName}(Smoke::EnumOperation xop, Smoke::Index xtype, void *&xdata, long &xvalue) {\n";
+ print $fh " x_${legacyClassName}\::xenum_operation(xop, xtype, xdata, xvalue);\n";
+ print $fh "}\n";
+ }
+ print $fh "void xcall_${legacyClassName}(Smoke::Index xi, void *obj, Smoke::Stack args) {\n";
+ print $fh $switchCode;
+ print $fh "}\n\n";
+ }
+ #if ( $className =~ /^(QBrush|QColor|QCursor|QFont|QImage|QPalette|QPixmap|QPoint|QPointArray|QRect|QRegion|QSize|QWMatrix)$/ ) {
+ # print XCPPFILE " const char *{serial} operator << () const : pig_serialize(\$this);\n";
+ # print XCPPFILE " void operator >> (const char *{serial}) : pig_deserialize(\$this, \$1);\n";
+ #}
+
+ close $fh;
+ $fhn++
+ }
+
+}
+
+# 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 'QString' ) { # 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.
+# (QObject*)x[1].s_class,(QEvent*)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 .= "x[$i].$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 'QString' ) { # 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};
+ 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;
+ }
+ 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 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, $addInclude ) = @_;
+ 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
+ checkIncludesForObject( $returnType, $addInclude ) if ($returnType ne 'void');
+
+ # Generate a matching virtual method in the x_ class
+ $methodCode .= " virtual $returnType $m->{astNodeName}(";
+ my $i = 0;
+ foreach my $arg ( @argList ) {
+ $methodCode .= ", " if $i++;
+ $methodCode .= $arg->{ArgType};
+ $methodCode .= " x$i";
+
+ # Detect objects passed by value
+ checkIncludesForObject( $arg->{ArgType}, $addInclude );
+ }
+ $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};
+
+ 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";
+ } else {
+ $methodCode .= "\tif(${libname}_Smoke->binding->callMethod($idx, (void*)$this, x)) ";
+ }
+
+ $returnType = undef if ($returnType eq 'void');
+ if($returnType) {
+ my $arg = $returnType;
+ my $it = applyTypeDef( $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 .= " }\n";
+ return ( $methodCode );
+}
+
+sub generateMethod($$$)
+{
+ my( $classNode, $m, $addInclude ) = @_; # input
+ my $methodCode = ''; # output
+ my $switchCode = ''; # 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/QGfx\s*\*/ );
+# return if ( $returnType eq 'CGContextRef' );
+# return if ( $returnType eq 'QWSDisplay *' );
+# # 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+/ );
+# # QFile's EncoderFn/DecoderFn
+# return if ( $name =~ /set[ED][ne]codingFunction/ );
+# # How to implement this? (QXmlDefaultHandler/QXmlEntityResolver::resolveEntity, needs A*&)
+# return if ( $name eq 'resolveEntity' and $className =~ /^QXml/ );
+# return if ( $className eq 'QBitArray' && $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=();
+
+ 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};
+ 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 || $classNode->{NodeType} eq 'namespace';
+
+ my $attr = "";
+ $attr .= "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 $iterationCount = scalar(@argTypeList) - $firstDefaultParam;
+
+ my $xretCode = '';
+ if($returnType) {
+ $xretCode .= coerce_type('x[0]', 'xret', $returnType, 1);
+ }
+
+ print STDERR " ". ($iterationCount+1). " iterations for $name\n" if ($debug);
+
+ while($iterationCount >= 0) {
+
+ local($") = ",";
+ # Handle case of a class with constructors, but with a private pure virtual
+ # so we can't create an instance of it
+ if($isConstructor and !$classNode->{CanBeInstanciated}) {
+
+ # We still generate "forwarder constructors" for x_className though
+ $methodCode .= " $xClassName(";
+ my $i = 0;
+ for my $arg (@argTypeList) {
+ $methodCode .= ", " if $i++;
+ $methodCode .= "$arg x$i";
+ }
+ $methodCode .= ") : $className(";
+ $i = 0;
+ for my $arg (@argTypeList) {
+ $methodCode .= ", " if $i++;
+ $methodCode .= "x$i";
+ }
+ $methodCode .= ") {}\n";
+
+ } else {
+
+ $switchCode .= "\tcase $methodNumber: ";
+ if ($flags =~ "s" || $isConstructor || $classNode->{NodeType} eq 'namespace') { # static, namespace or constructor
+ $switchCode .= "$xClassName\::";
+ } else {
+ $switchCode .= "xself->"
+ }
+ $switchCode .= "x_$methodNumber(args);";
+ $switchCode .= "\tbreak;\n";
+
+ $methodCode .= " ${extra}void x_$methodNumber\(Smoke::Stack x) $attr\{\n";
+ my $cplusplusparams = join( ", ", @argTypeList );
+ $methodCode .= "\t// $name($cplusplusparams)\n";
+ $methodCode .= "\t";
+
+ if ($isConstructor) {
+
+ $methodCode .= "$xClassName* xret = new $xClassName(@castedArgList[0..$#argTypeList]);\n";
+ #$m->{retnew} = 1;
+ $methodCode .= "\tx[0].s_class = (void*)xret;\n"; # the return value, containing the new object
+ $methodCode .= " }\n";
+
+ # Now generate the actual constructor for x_className
+ # (Simply a forwarder to the className constructor with the same args
+ if ( $flags =~ "t" ) {
+ $methodCode .= " explicit $xClassName(";
+ } else {
+ $methodCode .= " $xClassName(";
+ }
+ my $i = 0;
+ for my $arg (@argTypeList) {
+ $methodCode .= ", " if $i++;
+ if ($arg =~ s/\(\*\)/(* x$i)/) { # function pointer... need to insert argname inside
+ $methodCode .= $arg;
+ } else {
+ $methodCode .= "$arg x$i";
+ }
+ }
+ $methodCode .= ") : $className(";
+ $i = 0;
+ for my $arg (@argTypeList) {
+ $methodCode .= ", " if $i++;
+ $methodCode .= "x$i";
+ }
+ $methodCode .= ") {\n";
+
+ } else {
+ $methodCode .= $returnType . " xret = " if $returnType;
+ $methodCode .= "$this\->" unless $isStatic || $classNode->{NodeType} eq 'namespace';
+ if ($className ne $main::globalSpaceClassName) {
+ 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) {
+ 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
+ } else {
+ die "shouldn't reach here!";
+ }
+ } else {
+ $methodCode .= "$name(@castedArgList[0..$#argTypeList]);\n";
+ }
+ $methodCode .= "\t" . $xretCode if $returnType;
+ # To avoid unused parameter warning, add this to void methods:
+ $methodCode .= "\t(void)x; // noop (for compiler warning)\n" unless $returnType;
+ }
+ $methodCode .= " }\n";
+ }
+
+
+ pop @argTypeList;
+ $methodNumber++;
+ $iterationCount--;
+ } # Iteration loop
+
+ return ( $methodCode, $switchCode );
+}
+
+
+sub generateEnum($$$)
+{
+ 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";
+ $methodCode .= " }\n";
+ $switchCode .= "\tcase $methodNumber: $xClassName\::x_$methodNumber(args);\tbreak;\n";
+ $methodNumber++;
+ }
+
+ return ( $methodCode, $switchCode );
+}
+
+sub generateVar($$$)
+{
+ 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 $name = $m->{astNodeName};
+ my $varType = $m->{Type};
+ $varType =~ s/static\s//;
+ $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;
+ 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 );
+}
+
+sub generateEnumCast($)
+{
+ my( $classNode ) = @_;
+ my $methodCode = '';
+ return unless keys %{$classNode->{enumerations}};
+ $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";
+ $methodCode .= "\t case Smoke::EnumNew:\n";
+ $methodCode .= "\t\txdata = (void*)new $enum;\n";
+ $methodCode .= "\t\tbreak;\n";
+ $methodCode .= "\t case Smoke::EnumDelete:\n"; # unnecessary
+ $methodCode .= "\t\tdelete ($enum*)xdata;\n";
+ $methodCode .= "\t\tbreak;\n";
+ $methodCode .= "\t case Smoke::EnumFromLong:\n";
+ $methodCode .= "\t\t*($enum*)xdata = ($enum)xvalue;\n";
+ $methodCode .= "\t\tbreak;\n";
+ $methodCode .= "\t case Smoke::EnumToLong:\n";
+ $methodCode .= "\t\txvalue = (long)*($enum*)xdata;\n";
+ $methodCode .= "\t\tbreak;\n";
+ $methodCode .= "\t }\n";
+ $methodCode .= "\t break;\n";
+ }
+ $methodCode .= "\t}\n";
+ $methodCode .= " }\n";
+
+ return $methodCode;
+}
+
+## Called by writeClassDoc
+sub generateAllMethods
+{
+ my ($classNode) = @_;
+ my $methodCode = '';
+ my $switchCode = '';
+ $methodNumber = 0;
+
+ #my $className = $classNode->{astNodeName};
+ my $className = join( "::", kdocAstUtil::heritage($classNode) );
+ my $xClassName = "x_" . join( "__", kdocAstUtil::heritage($classNode) );
+ my $isGlobalSpace = ($xClassName eq ("x_".$main::globalSpaceClassName));
+ my $sourcename = $classNode->{Source}->{astNodeName};
+
+ 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->{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";
+ $methodCode .= " $xClassName\(void *x) : xthis(($className*)x) {}\n";
+ $switchCode .= " $xClassName xtmp(obj), *xself = &xtmp;\n";
+ } else {
+ $switchCode .= " $xClassName *xself = ($xClassName*)obj;\n";
+ $methodCode .= "public:\n";
+ }
+ } else {
+ my $s;
+ for my $sn( @{$classNode->{Sources}} ) {
+ if ( ($s = $sn->{astNodeName}) !~ s!.*($headerSubdirectories)(.*)!$1$2!m ) {
+ $s =~ s!.*/(.*)!$1!m;
+ }
+ $addInclude{ $s } = 1;
+ }
+ $methodCode .= "public:\n";
+ $switchCode .= " (void) obj;\n";
+ }
+ $switchCode .= " switch(xi) {\n";
+
+ # Do all enums first
+ Iter::MembersByType ( $classNode, undef,
+ sub { my ($classNode, $methodNode ) = @_;
+
+ if ( $methodNode->{NodeType} eq 'enum' ) {
+ my ($meth, $swit) = generateEnum( $classNode, $methodNode, \%addInclude );
+ $methodCode .= $meth;
+ $switchCode .= $swit;
+ }
+ }, undef );
+
+ # Then all static vars
+ Iter::MembersByType ( $classNode, undef,
+ sub { my ($classNode, $methodNode ) = @_;
+
+ if ( $methodNode->{NodeType} eq 'var' ) {
+ my ($meth, $swit) = generateVar( $classNode, $methodNode, \%addInclude );
+ $methodCode .= $meth;
+ $switchCode .= $swit;
+ }
+ }, undef );
+
+ # Then all methods
+ Iter::MembersByType ( $classNode, undef,
+ sub { my ($classNode, $methodNode ) = @_;
+
+ if ( $methodNode->{NodeType} eq 'method' ) {
+ my ($meth, $swit) = generateMethod( $classNode, $methodNode, \%addInclude );
+ $methodCode .= $meth;
+ $switchCode .= $swit;
+ }
+ }, 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}, \%addInclude );
+ $methodCode .= $meth;
+ }
+ }
+
+ $methodCode .= generateEnumCast( $classNode );
+
+ # 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 ~$xClassName() {}\n";
+ #}
+ # We generate a dtor though, because we might want to add stuff into it
+ if ( !$isGlobalSpace && $classNode->{NodeType} ne 'namespace' ) {
+ $methodCode .= " ~$xClassName() { ${libname}_Smoke->binding->deleted($classNode->{ClassIndex}, (void*)this); }\n";
+ }
+
+ if ($classNode->{CanBeInstanciated} and $classNode->{HasPublicDestructor}) {
+ die "$className destructor: methodNumber=$methodNumber != case entry=".$classNode->{case}{"~$className()"}."\n"
+ if $methodNumber != $classNode->{case}{"~$className()"};
+ $switchCode .= "\tcase $methodNumber: delete ($className*)xself;\tbreak;\n";
+ $methodNumber++;
+ }
+
+ $switchCode .= " }\n";
+ return ( $methodCode, $switchCode, \%addInclude );
+}
+
+# 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*'
+
+ $type =~ s/(<[^>]*)\s+([^>]*>)/$1$2/; # Remove embedded space from template types, such as
+ # 'QMap<QCString, DCOPRef>'
+
+ 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 'QTextEdit::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*'
+
+ $type =~ s/(<[^>]*)\s+([^>]*>)/$1$2/; # Remove embedded space from template types, such as
+ # 'QMap<QCString, DCOPRef>'
+
+ 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;
+}
+
+# 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 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 );
+
+ 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,
+ 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 'QLineEdit' && ( $name eq 'setPasswordChar' || $name eq 'passwordChar' ) );
+ $ok = 0 if ( $ok && $className eq 'QWidgetItem' && $name eq 'widgetSizeHint' );
+
+ if ( !$ok )
+ {
+ #print STDERR "Skipping $className\::$name\n" if ($debug);
+ $m->{SkipFromSwitch} = 1;
+ next;
+ }
+
+ 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) {
+ $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);
+ }
+}
+
+=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 );
+ } );
+
+ 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 $incl eq '';
+ if( $incl eq "kxmlguifactory.h" ) {
+ print OUT "#include <kxmlguiclient.h>\n";
+ }
+ print OUT "#include <$incl>\n";
+ }
+
+ print OUT "\n";
+ print OUT "#include <smoke.h>\n\n";
+ print OUT "#include <qt_smoke.h>\n\n";
+
+ # gcc optimizes this method like crazy. switch() is godly
+ print OUT "static void *${libname}_cast(void *xptr, Smoke::Index from, Smoke::Index to) {\n";
+ print OUT " switch(from) {\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
+ 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";
+ } );
+ 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};
+ die "problem with $className" unless defined $classinherit{$className};
+
+ 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{$className}, $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 =~ /\(/;
+ 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)
+ if(exists $classidx{$realType}) { # this one first, we want t_class for QBlah*
+ $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 =~ /</ ) { # Don't warn for template stuff...
+ print STDERR "$realType isn't a known type (type=$type)\n";
+ }
+ }
+ $typeId = 't_voidp'; # Unknown -> 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 $numTypes = scalar(split ',', $args);
+ 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 + 1; # 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) );
+
+ 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|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] = {
+ 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};
+ 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,
+ 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';
+ # 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";
+ 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) );
+
+ 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";
+}
+
+1;
diff --git a/kalyptus/kalyptusCxxToSwig.pm b/kalyptus/kalyptusCxxToSwig.pm
new file mode 100644
index 00000000..1430dd91
--- /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 *QTCTYPES *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',
+ 'QWSEvent*' => 'void*',
+ 'QDiskFont*' => 'void*',
+ 'XEvent*' => 'void*',
+ 'QStyleHintReturn*' => 'void*',
+ 'FILE*' => 'void*',
+ 'QUnknownInterface*' => 'void*',
+ 'GDHandle' => 'void*',
+ '_NPStream*' => 'void*',
+ 'QTextFormat*' => 'void*',
+ 'QTextDocument*' => 'void*',
+ 'QTextCursor*' => 'void*',
+ 'QTextParag**' => 'void*',
+ 'QTextParag* *' => 'void*',
+ 'QTextParag*' => 'void*',
+ 'QRemoteInterface*' => 'void*',
+ 'QSqlRecordPrivate*' => 'void*',
+ 'QTSMFI' => 'void*', # QTextStream's QTSManip
+ 'const GUID&' => 'void*',
+ 'QWidgetMapper*' => 'void*',
+ 'QWidgetMapper *' => 'void*',
+ 'MSG*' => 'void*',
+ 'const QSqlFieldInfoList&' => 'void*', # QSqlRecordInfo - TODO (templates)
+
+ 'QPtrCollection::Item' => 'void*', # to avoid a warning
+
+ 'mode_t' => 'long',
+ 'QProcess::PID' => 'long',
+ 'size_type' => 'int', # QSqlRecordInfo
+ 'Qt::ComparisonFlags' => 'uint',
+ 'Qt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it
+ 'QIODevice::Offset' => 'ulong',
+ 'WState' => 'int',
+ 'WId' => 'ulong',
+ 'QRgb' => 'uint',
+ 'QRgb *' => 'uint*',
+ 'QRgb*' => 'uint*',
+ 'const QCOORD*' => 'const int*',
+ 'QCOORD*' => 'int*',
+ 'QCOORD' => 'int',
+ 'QCOORD &' => 'int&',
+ 'QTSMFI' => 'int',
+ 'Qt::WState' => 'int',
+ 'Qt::WFlags' => 'int',
+ 'Qt::HANDLE' => 'uint',
+ 'QEventLoop::ProcessEventsFlags' => 'uint',
+ 'QStyle::SCFlags' => 'int',
+ 'QStyle::SFlags' => 'int',
+ 'QStyleOption&' => 'int&',
+ 'const QStyleOption&' => '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 =<<EOF
+ begin : $now
+ copyright : (C) 2003 Ian Geiser, Zack Rusin
+ email : geiseri\@kde.org, zack\@kde.org
+ generated by : $gentext
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This library is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library General Public License as *
+ * published by the Free Software Foundation; either version 2 of the *
+ * License, or (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+EOF
+
+}
+
+# Returns 1 if the $kid of the $node should be skipped
+sub skipMethod($$)
+{
+ my ($node, $kid) = @_;
+
+ if ( $kid->{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. QWidget and we want to generate a code for $child
+# but in a class called QWidget_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|kdeprint|kdesu|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
new file mode 100644
index 00000000..e2725160
--- /dev/null
+++ b/kalyptus/kalyptusDataDict.pm
@@ -0,0 +1,2981 @@
+#***************************************************************************
+# 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.
+# email : Richard_Dale@tipitina.demon.co.uk
+# author : 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 kalyptusDataDict;
+
+use strict;
+no strict "subs";
+
+use vars qw/ %interfacemap %ctypemap %builtins /;
+
+BEGIN
+{
+
+%interfacemap = (
+'QGL' => 'QGLInterface',
+'QPaintDevice' => 'QPaintDeviceInterface',
+'QMenuData' => 'QMenuDataInterface',
+'QRangeControl' => 'QRangeControlInterface',
+'QMimeSource' => 'QMimeSourceInterface',
+'QLayoutItem' => 'QLayoutItemInterface',
+'QUrl' => 'QUrlInterface',
+'QIODevice' => 'QIODeviceInterface',
+'QXmlContentHandler' => 'QXmlContentHandlerInterface',
+'QXmlErrorHandler' => 'QXmlErrorHandlerInterface',
+'QXmlDTDHandler' => 'QXmlDTDHandlerInterface',
+'QXmlEntityResolver' => 'QXmlEntityResolverInterface',
+'QXmlLexicalHandler' => 'QXmlLexicalHandlerInterface',
+'QXmlDeclHandler' => 'QXmlDeclHandlerInterface',
+'KInstance' => 'KInstanceInterface',
+'QwAbsSpriteFieldView' => 'QwAbsSpriteFieldViewInterface',
+'PartBase' => 'PartBaseInterface',
+'KCompletionBase' => 'KCompletionBaseInterface',
+'KDirNotify' => 'KDirNotifyInterface',
+'KXMLGUIClient' => 'KXMLGUIClientInterface',
+'KFileView' => 'KFileViewInterface',
+'KXMLGUIBuilder' => 'KXMLGUIBuilderInterface',
+'DCOPObject' => 'DCOPObjectInterface',
+'KDevCore' => 'KDevCoreInterface',
+'QSqlQuery' => 'QSqlQueryInterface',
+
+);
+
+# 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 Qt/KDE language binding generators;
+# C, Objective-C and Java.
+%ctypemap = (
+
+'ASConsumer*' => 'kde_ASConsumer*',
+'ASProducer*' => 'kde_ASProducer*',
+'ASYNC' => 'void' ,
+'Address&' => 'kde_Address*' ,
+'Address*' => 'kde_Address*',
+'AddressBook*' => 'kde_AddressBook*',
+'AddressBook::Entry&' => 'kde_Entry*' ,
+'Addressee&' => 'kde_Addressee*',
+'Addressee*' => 'kde_Addressee*',
+'AddresseeData*' => 'kde_AddresseeData*',
+'AddresseeDialog*' => 'kde_AddresseeDialog*',
+'AddresseeItem*' => 'kde_AddresseeItem*',
+'AlsaOut*' => 'kde_AlsaOut*',
+'AnyConstRef&' => 'kde_AnyConstRef*',
+'AnyConstRef*' => 'kde_AnyConstRef*',
+'AnyRef&' => 'kde_AnyRef*',
+'AnyRef*' => 'kde_AnyRef*',
+'AnyRefBase&' => 'kde_AnyRefBase*',
+'AnyRefBase*' => 'kde_AnyRefBase*',
+'ArgList' => 'int' ,
+'ArrowType' => 'int' ,
+'Arts*' => 'kde_Arts*',
+'Arts::AudioManagerClient' => 'int',
+'Arts::Buffer&' => 'kde_Arts_Buffer*',
+'Arts::Buffer*' => 'kde_Arts_Buffer*',
+'Arts::ByteSoundProducer' => 'kde_Arts_ByteSoundProducer*',
+'Arts::Connection*' => 'kde_Arts_Connection*',
+'Arts::DynamicCast&' => 'kde_Arts_DynamicCast*',
+'Arts::FlowSystemReceiver' => 'kde_Arts_FlowSystemReceiver*',
+'Arts::FlowSystemSender' => 'kde_Arts_FlowSystemSender*',
+'Arts::Format&' => 'kde_Arts_Format*',
+'Arts::Format' => 'kde_Arts_Format',
+'Arts::GenericAsyncStream*' => 'kde_Arts_GenericAsyncStream*',
+'Arts::GenericDataChannel*' => 'kde_Arts_GenericDataChannel*',
+'Arts::InterfaceDef' => 'kde_Arts_InterfaceDef*',
+'Arts::MethodDef&' => 'kde_Arts_MethodDef*',
+'Arts::ModuleDef&' => 'kde_Arts_ModuleDef*',
+'Arts::Notification&' => 'kde_Arts_Notification*',
+'Arts::Object' => 'kde_Arts_Object*',
+'Arts::Object::Pool&' => 'kde_Arts_Object_Pool*',
+'Arts::ObjectReference' => 'kde_Arts_ObjectReference*',
+'Arts::PlayObject' => 'kde_Arts_PlayObject*',
+'Arts::Reference&' => 'kde_Arts_Reference*',
+'Arts::StereoEffect' => 'kde_Arts_StereoEffect*',
+'Arts::StereoEffectStack' => 'kde_Arts_StereoEffectStack*',
+'Arts::SubClass&' => 'kde_Arts_SubClass*',
+'Arts::TypeDef' => 'kde_Arts_TypeDef*',
+'Arts::poTime&' => 'kde_Arts_poTime*',
+'Arts::poTime' => 'kde_Arts_poTime',
+'AsyncStream*' => 'kde_AsyncStream*',
+'Attr&' => 'kde_Attr*',
+'Attr' => 'kde_Attr*',
+'Attr*' => 'kde_Attr*',
+'AttrImpl*' => 'kde_AttrImpl*',
+'AttributeDef&' => 'kde_AttributeDef*',
+'AttributeDef*' => 'kde_AttributeDef*',
+'AudioManager&' => 'kde_AudioManager*',
+'AudioManager' => 'kde_AudioManager*',
+'AudioManager*' => 'kde_AudioManager*',
+'AudioManagerClient&' => 'kde_AudioManagerClient*',
+'AudioManagerClient' => 'kde_AudioManagerClient*',
+'AudioManagerClient*' => 'kde_AudioManagerClient*',
+'AudioManagerClient_base*' => 'kde_AudioManagerClient_base*',
+'AudioManagerClient_skel*' => 'kde_AudioManagerClient_skel*',
+'AudioManagerClient_stub*' => 'kde_AudioManagerClient_stub*',
+'AudioManagerInfo&' => 'kde_AudioManagerInfo*',
+'AudioManagerInfo*' => 'kde_AudioManagerInfo*',
+'AudioManager_base*' => 'kde_AudioManager_base*',
+'AudioManager_skel*' => 'kde_AudioManager_skel*',
+'AudioManager_stub*' => 'kde_AudioManager_stub*',
+'AudioPort*' => 'kde_AudioPort*',
+'AudioSubSystem*' => 'kde_AudioSubSystem*',
+'AudioSubSystemStart*' => 'kde_AudioSubSystemStart*',
+'AuthAccept&' => 'kde_AuthAccept*',
+'AuthAccept*' => 'kde_AuthAccept*',
+'BGMode' => 'int',
+'BMToken*' => 'kde_BMToken*',
+'BackgroundMode' => 'int',
+'BlockSelectionInterface*' => 'kde_BlockSelectionInterface*',
+'BookmarkTokenizer*' => 'kde_BookmarkTokenizer*',
+'Bool' => 'int' ,
+'Boolean&' => 'kde_Boolean*',
+'Boolean*' => 'kde_Boolean*',
+'BrowserExtension*' => 'kde_BrowserExtension*',
+'BrowserHostExtension*' => 'kde_BrowserHostExtension*',
+'BrowserInterface*' => 'kde_BrowserInterface*',
+'BrushStyle' => 'int',
+'Buffer&' => 'kde_Buffer*',
+'Buffer*' => 'kde_Buffer*',
+'ButtonCode' => 'int' ,
+'ButtonState' => 'int' ,
+'ByteAsyncStream*' => 'kde_ByteAsyncStream*',
+'ByteDataPacket*' => 'kde_ByteDataPacket*',
+'ByteSoundProducer&' => 'kde_ByteSoundProducer*',
+'ByteSoundProducer' => 'kde_ByteSoundProducer*',
+'ByteSoundProducer*' => 'kde_ByteSoundProducer*',
+'ByteSoundProducer_base*' => 'kde_ByteSoundProducer_base*',
+'ByteSoundProducer_skel*' => 'kde_ByteSoundProducer_skel*',
+'ByteSoundProducer_stub*' => 'kde_ByteSoundProducer_stub*',
+'ByteStreamToAudio&' => 'kde_ByteStreamToAudio*',
+'ByteStreamToAudio' => 'kde_ByteStreamToAudio*',
+'ByteStreamToAudio*' => 'kde_ByteStreamToAudio*',
+'ByteStreamToAudio_base*' => 'kde_ByteStreamToAudio_base*',
+'ByteStreamToAudio_skel*' => 'kde_ByteStreamToAudio_skel*',
+'ByteStreamToAudio_stub*' => 'kde_ByteStreamToAudio_stub*',
+'CDATASection&' => 'kde_CDATASection*',
+'CDATASection' => 'kde_CDATASection*',
+'CDATASection*' => 'kde_CDATASection*',
+'CFlags' => 'int',
+'COORD' => 'short' ,
+'CSSCharsetRule&' => 'kde_CSSCharsetRule*',
+'CSSCharsetRule*' => 'kde_CSSCharsetRule*',
+'CSSCharsetRuleImpl*' => 'kde_CSSCharsetRuleImpl*',
+'CSSException&' => 'kde_CSSException*',
+'CSSException*' => 'kde_CSSException*',
+'CSSFontFaceRule&' => 'kde_CSSFontFaceRule*',
+'CSSFontFaceRule*' => 'kde_CSSFontFaceRule*',
+'CSSFontFaceRuleImpl*' => 'kde_CSSFontFaceRuleImpl*',
+'CSSImportRule&' => 'kde_CSSImportRule*',
+'CSSImportRule*' => 'kde_CSSImportRule*',
+'CSSImportRuleImpl*' => 'kde_CSSImportRuleImpl*',
+'CSSMediaRule&' => 'kde_CSSMediaRule*',
+'CSSMediaRule*' => 'kde_CSSMediaRule*',
+'CSSMediaRuleImpl*' => 'kde_CSSMediaRuleImpl*',
+'CSSPageRule&' => 'kde_CSSPageRule*',
+'CSSPageRule*' => 'kde_CSSPageRule*',
+'CSSPageRuleImpl*' => 'kde_CSSPageRuleImpl*',
+'CSSPrimitiveValue&' => 'kde_CSSPrimitiveValue*',
+'CSSPrimitiveValue' => 'kde_CSSPrimitiveValue*',
+'CSSPrimitiveValue*' => 'kde_CSSPrimitiveValue*',
+'CSSPrimitiveValueImpl*' => 'kde_CSSPrimitiveValueImpl*',
+'CSSRule&' => 'kde_CSSRule*',
+'CSSRule' => 'kde_CSSRule*',
+'CSSRule*' => 'kde_CSSRule*',
+'CSSRuleImpl*' => 'kde_CSSRuleImpl*',
+'CSSRuleList&' => 'kde_CSSRuleList*',
+'CSSRuleList' => 'kde_CSSRuleList*',
+'CSSRuleList*' => 'kde_CSSRuleList*',
+'CSSRuleListImpl*' => 'kde_CSSRuleListImpl*',
+'CSSStyleDeclaration&' => 'kde_CSSStyleDeclaration*',
+'CSSStyleDeclaration' => 'kde_CSSStyleDeclaration*',
+'CSSStyleDeclaration*' => 'kde_CSSStyleDeclaration*',
+'CSSStyleDeclarationImpl*' => 'kde_CSSStyleDeclarationImpl*',
+'CSSStyleRule&' => 'kde_CSSStyleRule*',
+'CSSStyleRule*' => 'kde_CSSStyleRule*',
+'CSSStyleRuleImpl*' => 'kde_CSSStyleRuleImpl*',
+'CSSStyleSheet&' => 'kde_CSSStyleSheet*',
+'CSSStyleSheet' => 'kde_CSSStyleSheet*',
+'CSSStyleSheet*' => 'kde_CSSStyleSheet*',
+'CSSStyleSheetImpl*' => 'kde_CSSStyleSheetImpl*',
+'CSSUnknownRule&' => 'kde_CSSUnknownRule*',
+'CSSUnknownRule*' => 'kde_CSSUnknownRule*',
+'CSSUnknownRuleImpl*' => 'kde_CSSUnknownRuleImpl*',
+'CSSValue&' => 'kde_CSSValue*',
+'CSSValue' => 'kde_CSSValue*',
+'CSSValue*' => 'kde_CSSValue*',
+'CSSValueImpl*' => 'kde_CSSValueImpl*',
+'CSSValueList&' => 'kde_CSSValueList*',
+'CSSValueList*' => 'kde_CSSValueList*',
+'CSSValueListImpl*' => 'kde_CSSValueListImpl*',
+'CString&' => 'kde_CString*',
+'CString' => 'kde_CString*',
+'CString*' => 'kde_CString*',
+'Cache*' => 'kde_Cache*',
+'CacheInfo*' => 'kde_CacheInfo*',
+'CachedObject*' => 'kde_CachedObject*',
+'CachedWav*' => 'kde_CachedWav*',
+'Cardinal' => 'int' ,
+'CharSet' => 'int',
+'CharacterData&' => 'kde_CharacterData*',
+'CharacterData*' => 'kde_CharacterData*',
+'CharacterDataImpl*' => 'kde_CharacterDataImpl*',
+'ChmodJob*' => 'kde_ChmodJob*',
+'ClassInfo*' => 'kde_ClassInfo*',
+'ClassStore*' => 'kde_ClassStore*',
+'ClassTreeNode*' => 'kde_ClassTreeNode*',
+'ClientHello&' => 'kde_ClientHello*',
+'ClientHello*' => 'kde_ClientHello*',
+'ClipboardInterface*' => 'kde_ClipboardInterface*',
+'CodeCompletionInterface*' => 'kde_CodeCompletionInterface*',
+'ColorMode' => 'int',
+'Comment&' => 'kde_Comment*',
+'Comment' => 'kde_Comment*',
+'Comment*' => 'kde_Comment*',
+'CommentImpl*' => 'kde_CommentImpl*',
+'ComparisonFlags' => 'int',
+'Compl' => 'kde_Compl',
+'Completion&' => 'kde_Completion*',
+'Completion*' => 'kde_Completion*',
+'CompletionEntry&' => 'kde_CompletionEntry*',
+'CompletionEntry*' => 'kde_CompletionEntry*',
+'ComplexControl' => 'int',
+'ComponentFactory*' => 'kde_ComponentFactory*',
+'ConfigInterface*' => 'kde_ConfigInterface*',
+'Connection*' => 'kde_Connection*',
+'ConstIterator' => 'int' ,
+'Constructor' => 'kde_Constructor*',
+'Constructor*' => 'kde_Constructor*',
+'ConstructorImp*' => 'kde_ConstructorImp*',
+'ContentsType' => 'int',
+'Context&' => 'kde_Context*',
+'Context*' => 'kde_Context*',
+'ControlElement' => 'int',
+'CopyInfo*' => 'kde_CopyInfo*',
+'CopyJob*' => 'kde_CopyJob*',
+'Core*' => 'kde_Core*',
+'Counter&' => 'kde_Counter*',
+'Counter' => 'kde_Counter*',
+'Counter*' => 'kde_Counter*',
+'Cursor*' => 'kde_Cursor*',
+'CursorInterface*' => 'kde_CursorInterface*',
+'DCOPClient*' => 'kde_DCOPClient*',
+'DCOPObject*' => 'kde_DCOPObject*',
+'DCOPObjectProxy*' => 'kde_DCOPObjectProxy*',
+'DCOPRef&' => 'kde_DCOPRef*' ,
+'DCOPRef*' => 'kde_DCOPRef*',
+'DCOPStub*' => 'kde_DCOPStub*',
+'DOM*' => 'kde_DOM*',
+'DOM::CSSProperty*' => 'kde_CSSProperty*' ,
+'DOM::DOMString&' => 'kde_DOMString*' ,
+'DOM::DOMString' => 'kde_DOMString*' ,
+'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::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*',
+'StyleSheetList&' => 'kde_StyleSheetList*',
+'StyleSheetList' => 'kde_StyleSheetList*',
+'StyleSheetList*' => 'kde_StyleSheetList*',
+'DOMException&' => 'kde_DOMException*',
+'DOMException*' => 'kde_DOMException*',
+'DOMImplementation&' => 'kde_DOMImplementation*',
+'DOMImplementation' => 'kde_DOMImplementation*',
+'DOMImplementation*' => 'kde_DOMImplementation*',
+'DOMImplementationImpl*' => 'kde_DOMImplementationImpl*',
+'DOMString&' => 'kde_DOMString*',
+'DOMString' => 'kde_DOMString*',
+'DOMString*' => 'kde_DOMString*',
+'DOMStringImpl*' => 'kde_DOMStringImpl*',
+'DW_EXPORT*' => 'void*',
+'DataPacket*' => 'kde_DataPacket*',
+'DateFormat' => 'int',
+'Debug*' => 'kde_Debug*',
+'DecoderFn' => 'int' ,
+'DefaultProgress*' => 'kde_DefaultProgress*',
+'DeleteJob*' => 'kde_DeleteJob*',
+'DeviceManager*' => 'kde_DeviceManager*',
+'Direction' => 'int',
+'DispatchFunction' => 'kde_DispatchFunction*',
+'Dispatcher*' => 'kde_Dispatcher*',
+'DistributionList*' => 'kde_DistributionList*',
+'DistributionListEditor*' => 'kde_DistributionListEditor*',
+'DistributionListManager*' => 'kde_DistributionListManager*',
+'Dock&' => 'int',
+'Dock' => 'int',
+'DockMainWindow*' => 'kde_DockMainWindow*',
+'DockPosData&' => 'kde_DockPosData*' ,
+'DockPosData*' => 'kde_DockPosData*',
+'DockWindowData*' => 'long',
+'Document&' => 'kde_Document*',
+'Document' => 'kde_Document*',
+'Document*' => 'kde_Document*',
+'DocumentFragment&' => 'kde_DocumentFragment*',
+'DocumentFragment' => 'kde_DocumentFragment*',
+'DocumentFragment*' => 'kde_DocumentFragment*',
+'DocumentFragmentImpl*' => 'kde_DocumentFragmentImpl*',
+'DocumentImpl*' => 'kde_DocumentImpl*',
+'DocumentStyle&' => 'kde_DocumentStyle*',
+'DocumentStyle*' => 'kde_DocumentStyle*',
+'DocumentType&' => 'kde_DocumentType*',
+'DocumentType' => 'kde_DocumentType*',
+'DocumentType*' => 'kde_DocumentType*',
+'DocumentationContext*' => 'kde_DocumentationContext*',
+'DomShared*' => 'kde_DomShared*',
+'DrageMode' => 'int',
+'DrawContentsEvent*' => 'kde_DrawContentsEvent*',
+'DwAddress&' => 'kde_DwAddress*',
+'DwAddress*' => 'kde_DwAddress*',
+'DwAddressList&' => 'kde_DwAddressList*',
+'DwAddressList*' => 'kde_DwAddressList*',
+'DwBody&' => 'kde_DwBody*',
+'DwBody*' => 'kde_DwBody*',
+'DwBodyPart&' => 'kde_DwBodyPart*',
+'DwBodyPart*' => 'kde_DwBodyPart*',
+'DwBool' => 'int',
+'DwDateTime&' => 'kde_DwDateTime*',
+'DwDateTime*' => 'kde_DwDateTime*',
+'DwDispositionType&' => 'kde_DwDispositionType*',
+'DwDispositionType*' => 'kde_DwDispositionType*',
+'DwEntity&' => 'kde_DwEntity*',
+'DwField&' => 'kde_DwField*',
+'DwField*' => 'kde_DwField*',
+'DwFieldBody&' => 'kde_DwFieldBody*',
+'DwFieldBody*' => 'kde_DwFieldBody*',
+'DwGroup&' => 'kde_DwGroup*',
+'DwGroup*' => 'kde_DwGroup*',
+'DwHeaders&' => 'kde_DwHeaders*',
+'DwHeaders*' => 'kde_DwHeaders*',
+'DwInt32' => 'int',
+'DwMailbox&' => 'kde_DwMailbox*',
+'DwMailbox*' => 'kde_DwMailbox*',
+'DwMailboxList&' => 'kde_DwMailboxList*',
+'DwMailboxList*' => 'kde_DwMailboxList*',
+'DwMechanism&' => 'kde_DwMechanism*',
+'DwMechanism*' => 'kde_DwMechanism*',
+'DwMediaType&' => 'kde_DwMediaType*',
+'DwMediaType*' => 'kde_DwMediaType*',
+'DwMessage&' => 'kde_DwMessage*',
+'DwMessage*' => 'kde_DwMessage*',
+'DwMessageComponent&' => 'kde_DwMessageComponent*',
+'DwMessageComponent*' => 'kde_DwMessageComponent*',
+'DwMime*' => 'kde_DwMime*',
+'DwMsgId&' => 'kde_DwMsgId*',
+'DwMsgId*' => 'kde_DwMsgId*',
+'DwObserver*' => 'kde_DwObserver*',
+'DwParameter&' => 'kde_DwParameter*',
+'DwParameter*' => 'kde_DwParameter*',
+'DwProtocolClient*' => 'kde_DwProtocolClient*',
+'DwString&' => 'kde_DwString*',
+'DwString' => 'kde_DwString',
+'DwString*' => 'kde_DwString*',
+'DwText&' => 'kde_DwText*',
+'DwText*' => 'kde_DwText*',
+'DwTokenizer&' => 'kde_DwTokenizer*',
+'DwUint16' => 'unsigned short',
+'DwUint32' => 'unsigned int',
+'DwUint8' => 'unsigned char',
+'DynamicCast*' => 'kde_DynamicCast*',
+'DynamicRequest&' => 'kde_DynamicRequest*',
+'DynamicRequest*' => 'kde_DynamicRequest*',
+'EXPORT_DOCKCLASS*' => 'kde_EXPORT_DOCKCLASS*',
+'EchoMode' => 'int',
+'EditInterface*' => 'kde_EditInterface*',
+'Editor*' => 'kde_Editor*',
+'EditorContext*' => 'kde_EditorContext*',
+'Element&' => 'kde_Element*',
+'Element' => 'kde_Element*',
+'Element*' => 'kde_Element*',
+'EmailSelectDialog*' => 'kde_EmailSelectDialog*',
+'EncoderFn' => 'int' ,
+'Endian' => 'int',
+'Entity&' => 'kde_Entity*',
+'Entity*' => 'kde_Entity*',
+'EntityReference&' => 'kde_EntityReference*',
+'EntityReference' => 'kde_EntityReference*',
+'EntityReference*' => 'kde_EntityReference*',
+'Entry&' => 'kde_Entry*' ,
+'Entry*' => 'kde_Entry*',
+'Entry::Address&' => 'kde_EntryAddress' ,
+'EnumComponent&' => 'kde_EnumComponent*',
+'EnumComponent*' => 'kde_EnumComponent*',
+'EnumDef&' => 'kde_EnumDef*',
+'EnumDef*' => 'kde_EnumDef*',
+'EnumEntry*' => 'kde_EnumEntry*',
+'Error*' => 'kde_Error*',
+'Event*' => 'kde_Event*',
+'ExecState*' => 'kde_ExecState*',
+'ExtensionLoader*' => 'kde_ExtensionLoader*',
+'FALSE' => '0',
+'FMOut*' => 'kde_FMOut*',
+'Factory*' => 'kde_Factory*',
+'False' => '0',
+'FileCopyJob*' => 'kde_FileCopyJob*',
+'FileProtocol*' => 'kde_FileProtocol*',
+'FileView&' => 'int' ,
+'FloatAsyncStream*' => 'kde_FloatAsyncStream*',
+'FloatDataPacket*' => 'kde_FloatDataPacket*',
+'FlowSystem&' => 'kde_FlowSystem*',
+'FlowSystem' => 'kde_FlowSystem*',
+'FlowSystem*' => 'kde_FlowSystem*',
+'FlowSystemReceiver&' => 'kde_FlowSystemReceiver*',
+'FlowSystemReceiver' => 'kde_FlowSystemReceiver*',
+'FlowSystemReceiver*' => 'kde_FlowSystemReceiver*',
+'FlowSystemReceiver_base*' => 'kde_FlowSystemReceiver_base*',
+'FlowSystemReceiver_skel*' => 'kde_FlowSystemReceiver_skel*',
+'FlowSystemReceiver_stub*' => 'kde_FlowSystemReceiver_stub*',
+'FlowSystemSender&' => 'kde_FlowSystemSender*',
+'FlowSystemSender' => 'kde_FlowSystemSender*',
+'FlowSystemSender*' => 'kde_FlowSystemSender*',
+'FlowSystemSender_base*' => 'kde_FlowSystemSender_base*',
+'FlowSystemSender_skel*' => 'kde_FlowSystemSender_skel*',
+'FlowSystemSender_stub*' => 'kde_FlowSystemSender_stub*',
+'FlowSystem_base*' => 'kde_FlowSystem_base*',
+'FlowSystem_impl*' => 'kde_FlowSystem_impl*',
+'FlowSystem_skel*' => 'kde_FlowSystem_skel*',
+'FlowSystem_stub*' => 'kde_FlowSystem_stub*',
+'FocusPolicy' => 'int',
+'Format&' => 'kde_Format*',
+'Format*' => 'kde_Format*',
+'Function*' => 'kde_Function*',
+'FunctionImp*' => 'kde_FunctionImp*',
+'GCI&' => 'GCI*' ,
+'GCI' => 'GCI*' ,
+'GCI*' => 'GCI*' ,
+'GUIActivateEvent*' => 'kde_GUIActivateEvent*',
+'GUIStyle' => 'int',
+'GUSOut*' => 'kde_GUSOut*',
+'GenericAsyncStream*' => 'kde_GenericAsyncStream*',
+'GenericDataChannel*' => 'kde_GenericDataChannel*',
+'GenericDataPacket*' => 'kde_GenericDataPacket*',
+'GenericFactory*' => 'kde_GenericFactory*',
+'GenericFactoryBase*' => 'kde_GenericFactoryBase*',
+'Global*' => 'kde_Global*',
+'GlobalComm&' => 'kde_GlobalComm*',
+'GlobalComm' => 'kde_GlobalComm*',
+'GlobalComm*' => 'kde_GlobalComm*',
+'GlobalComm_base*' => 'kde_GlobalComm_base*',
+'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*' ,
+'HTMLAnchorElement&' => 'kde_HTMLAnchorElement*',
+'HTMLAnchorElement*' => 'kde_HTMLAnchorElement*',
+'HTMLAnchorElementImpl*' => 'kde_HTMLAnchorElementImpl*',
+'HTMLAppletElement&' => 'kde_HTMLAppletElement*',
+'HTMLAppletElement*' => 'kde_HTMLAppletElement*',
+'HTMLAppletElementImpl*' => 'kde_HTMLAppletElementImpl*',
+'HTMLAreaElement&' => 'kde_HTMLAreaElement*',
+'HTMLAreaElement*' => 'kde_HTMLAreaElement*',
+'HTMLAreaElementImpl*' => 'kde_HTMLAreaElementImpl*',
+'HTMLBRElement&' => 'kde_HTMLBRElement*',
+'HTMLBRElement*' => 'kde_HTMLBRElement*',
+'HTMLBRElementImpl*' => 'kde_HTMLBRElementImpl*',
+'HTMLBaseElement&' => 'kde_HTMLBaseElement*',
+'HTMLBaseElement*' => 'kde_HTMLBaseElement*',
+'HTMLBaseElementImpl*' => 'kde_HTMLBaseElementImpl*',
+'HTMLBaseFontElement&' => 'kde_HTMLBaseFontElement*',
+'HTMLBaseFontElement*' => 'kde_HTMLBaseFontElement*',
+'HTMLBaseFontElementImpl*' => 'kde_HTMLBaseFontElementImpl*',
+'HTMLBlockquoteElement&' => 'kde_HTMLBlockquoteElement*',
+'HTMLBlockquoteElement*' => 'kde_HTMLBlockquoteElement*',
+'HTMLBlockquoteElementImpl*' => 'kde_HTMLBlockquoteElementImpl*',
+'HTMLBodyElement&' => 'kde_HTMLBodyElement*',
+'HTMLBodyElement*' => 'kde_HTMLBodyElement*',
+'HTMLBodyElementImpl*' => 'kde_HTMLBodyElementImpl*',
+'HTMLButtonElement&' => 'kde_HTMLButtonElement*',
+'HTMLButtonElement*' => 'kde_HTMLButtonElement*',
+'HTMLButtonElementImpl*' => 'kde_HTMLButtonElementImpl*',
+'HTMLCollection&' => 'kde_HTMLCollection*',
+'HTMLCollection' => 'kde_HTMLCollection*',
+'HTMLCollection*' => 'kde_HTMLCollection*',
+'HTMLCollectionImpl*' => 'kde_HTMLCollectionImpl*',
+'HTMLDListElement&' => 'kde_HTMLDListElement*',
+'HTMLDListElement*' => 'kde_HTMLDListElement*',
+'HTMLDListElementImpl*' => 'kde_HTMLDListElementImpl*',
+'HTMLDirectoryElement&' => 'kde_HTMLDirectoryElement*',
+'HTMLDirectoryElement*' => 'kde_HTMLDirectoryElement*',
+'HTMLDirectoryElementImpl*' => 'kde_HTMLDirectoryElementImpl*',
+'HTMLDivElement&' => 'kde_HTMLDivElement*',
+'HTMLDivElement*' => 'kde_HTMLDivElement*',
+'HTMLDivElementImpl*' => 'kde_HTMLDivElementImpl*',
+'HTMLDocument&' => 'kde_HTMLDocument*',
+'HTMLDocument*' => 'kde_HTMLDocument*',
+'HTMLDocumentImpl*' => 'kde_HTMLDocumentImpl*',
+'HTMLElement&' => 'kde_HTMLElement*',
+'HTMLElement' => 'kde_HTMLElement*',
+'HTMLElement*' => 'kde_HTMLElement*',
+'HTMLElementImpl*' => 'kde_HTMLElementImpl*',
+'HTMLFieldSetElement&' => 'kde_HTMLFieldSetElement*',
+'HTMLFieldSetElement*' => 'kde_HTMLFieldSetElement*',
+'HTMLFieldSetElementImpl*' => 'kde_HTMLFieldSetElementImpl*',
+'HTMLFontElement&' => 'kde_HTMLFontElement*',
+'HTMLFontElement*' => 'kde_HTMLFontElement*',
+'HTMLFontElementImpl*' => 'kde_HTMLFontElementImpl*',
+'HTMLFormElement&' => 'kde_HTMLFormElement*',
+'HTMLFormElement' => 'kde_HTMLFormElement*',
+'HTMLFormElement*' => 'kde_HTMLFormElement*',
+'HTMLFormElementImpl*' => 'kde_HTMLFormElementImpl*',
+'HTMLFrameElement&' => 'kde_HTMLFrameElement*',
+'HTMLFrameElement*' => 'kde_HTMLFrameElement*',
+'HTMLFrameElementImpl*' => 'kde_HTMLFrameElementImpl*',
+'HTMLFrameSetElement&' => 'kde_HTMLFrameSetElement*',
+'HTMLFrameSetElement*' => 'kde_HTMLFrameSetElement*',
+'HTMLFrameSetElementImpl*' => 'kde_HTMLFrameSetElementImpl*',
+'HTMLHRElement&' => 'kde_HTMLHRElement*',
+'HTMLHRElement*' => 'kde_HTMLHRElement*',
+'HTMLHRElementImpl*' => 'kde_HTMLHRElementImpl*',
+'HTMLHeadElement&' => 'kde_HTMLHeadElement*',
+'HTMLHeadElement*' => 'kde_HTMLHeadElement*',
+'HTMLHeadElementImpl*' => 'kde_HTMLHeadElementImpl*',
+'HTMLHeadingElement&' => 'kde_HTMLHeadingElement*',
+'HTMLHeadingElement*' => 'kde_HTMLHeadingElement*',
+'HTMLHeadingElementImpl*' => 'kde_HTMLHeadingElementImpl*',
+'HTMLHtmlElement&' => 'kde_HTMLHtmlElement*',
+'HTMLHtmlElement*' => 'kde_HTMLHtmlElement*',
+'HTMLHtmlElementImpl*' => 'kde_HTMLHtmlElementImpl*',
+'HTMLIFrameElement&' => 'kde_HTMLIFrameElement*',
+'HTMLIFrameElement*' => 'kde_HTMLIFrameElement*',
+'HTMLIFrameElementImpl*' => 'kde_HTMLIFrameElementImpl*',
+'HTMLImageElement&' => 'kde_HTMLImageElement*',
+'HTMLImageElement*' => 'kde_HTMLImageElement*',
+'HTMLImageElementImpl*' => 'kde_HTMLImageElementImpl*',
+'HTMLInputElement&' => 'kde_HTMLInputElement*',
+'HTMLInputElement*' => 'kde_HTMLInputElement*',
+'HTMLInputElementImpl*' => 'kde_HTMLInputElementImpl*',
+'HTMLIsIndexElement&' => 'kde_HTMLIsIndexElement*',
+'HTMLIsIndexElement*' => 'kde_HTMLIsIndexElement*',
+'HTMLIsIndexElementImpl*' => 'kde_HTMLIsIndexElementImpl*',
+'HTMLLIElement&' => 'kde_HTMLLIElement*',
+'HTMLLIElement*' => 'kde_HTMLLIElement*',
+'HTMLLIElementImpl*' => 'kde_HTMLLIElementImpl*',
+'HTMLLabelElement&' => 'kde_HTMLLabelElement*',
+'HTMLLabelElement*' => 'kde_HTMLLabelElement*',
+'HTMLLabelElementImpl*' => 'kde_HTMLLabelElementImpl*',
+'HTMLLegendElement&' => 'kde_HTMLLegendElement*',
+'HTMLLegendElement*' => 'kde_HTMLLegendElement*',
+'HTMLLegendElementImpl*' => 'kde_HTMLLegendElementImpl*',
+'HTMLLinkElement&' => 'kde_HTMLLinkElement*',
+'HTMLLinkElement*' => 'kde_HTMLLinkElement*',
+'HTMLLinkElementImpl*' => 'kde_HTMLLinkElementImpl*',
+'HTMLMapElement&' => 'kde_HTMLMapElement*',
+'HTMLMapElement*' => 'kde_HTMLMapElement*',
+'HTMLMapElementImpl*' => 'kde_HTMLMapElementImpl*',
+'HTMLMenuElement&' => 'kde_HTMLMenuElement*',
+'HTMLMenuElement*' => 'kde_HTMLMenuElement*',
+'HTMLMenuElementImpl*' => 'kde_HTMLMenuElementImpl*',
+'HTMLMetaElement&' => 'kde_HTMLMetaElement*',
+'HTMLMetaElement*' => 'kde_HTMLMetaElement*',
+'HTMLMetaElementImpl*' => 'kde_HTMLMetaElementImpl*',
+'HTMLModElement&' => 'kde_HTMLModElement*',
+'HTMLModElement*' => 'kde_HTMLModElement*',
+'HTMLModElementImpl*' => 'kde_HTMLModElementImpl*',
+'HTMLOListElement&' => 'kde_HTMLOListElement*',
+'HTMLOListElement*' => 'kde_HTMLOListElement*',
+'HTMLOListElementImpl*' => 'kde_HTMLOListElementImpl*',
+'HTMLObjectElement&' => 'kde_HTMLObjectElement*',
+'HTMLObjectElement*' => 'kde_HTMLObjectElement*',
+'HTMLObjectElementImpl*' => 'kde_HTMLObjectElementImpl*',
+'HTMLOptGroupElement&' => 'kde_HTMLOptGroupElement*',
+'HTMLOptGroupElement*' => 'kde_HTMLOptGroupElement*',
+'HTMLOptGroupElementImpl*' => 'kde_HTMLOptGroupElementImpl*',
+'HTMLOptionElement&' => 'kde_HTMLOptionElement*',
+'HTMLOptionElement*' => 'kde_HTMLOptionElement*',
+'HTMLOptionElementImpl*' => 'kde_HTMLOptionElementImpl*',
+'HTMLParagraphElement&' => 'kde_HTMLParagraphElement*',
+'HTMLParagraphElement*' => 'kde_HTMLParagraphElement*',
+'HTMLParagraphElementImpl*' => 'kde_HTMLParagraphElementImpl*',
+'HTMLParamElement&' => 'kde_HTMLParamElement*',
+'HTMLParamElement*' => 'kde_HTMLParamElement*',
+'HTMLParamElementImpl*' => 'kde_HTMLParamElementImpl*',
+'HTMLPreElement&' => 'kde_HTMLPreElement*',
+'HTMLPreElement*' => 'kde_HTMLPreElement*',
+'HTMLPreElementImpl*' => 'kde_HTMLPreElementImpl*',
+'HTMLQuoteElement&' => 'kde_HTMLQuoteElement*',
+'HTMLQuoteElement*' => 'kde_HTMLQuoteElement*',
+'HTMLQuoteElementImpl*' => 'kde_HTMLQuoteElementImpl*',
+'HTMLScriptElement&' => 'kde_HTMLScriptElement*',
+'HTMLScriptElement*' => 'kde_HTMLScriptElement*',
+'HTMLScriptElementImpl*' => 'kde_HTMLScriptElementImpl*',
+'HTMLSelectElement&' => 'kde_HTMLSelectElement*',
+'HTMLSelectElement*' => 'kde_HTMLSelectElement*',
+'HTMLSelectElementImpl*' => 'kde_HTMLSelectElementImpl*',
+'HTMLStyleElement&' => 'kde_HTMLStyleElement*',
+'HTMLStyleElement*' => 'kde_HTMLStyleElement*',
+'HTMLStyleElementImpl*' => 'kde_HTMLStyleElementImpl*',
+'HTMLTableCaptionElement&' => 'kde_HTMLTableCaptionElement*',
+'HTMLTableCaptionElement' => 'kde_HTMLTableCaptionElement*',
+'HTMLTableCaptionElement*' => 'kde_HTMLTableCaptionElement*',
+'HTMLTableCaptionElementImpl*' => 'kde_HTMLTableCaptionElementImpl*',
+'HTMLTableCellElement&' => 'kde_HTMLTableCellElement*',
+'HTMLTableCellElement*' => 'kde_HTMLTableCellElement*',
+'HTMLTableCellElementImpl*' => 'kde_HTMLTableCellElementImpl*',
+'HTMLTableColElement&' => 'kde_HTMLTableColElement*',
+'HTMLTableColElement*' => 'kde_HTMLTableColElement*',
+'HTMLTableColElementImpl*' => 'kde_HTMLTableColElementImpl*',
+'HTMLTableElement&' => 'kde_HTMLTableElement*',
+'HTMLTableElement*' => 'kde_HTMLTableElement*',
+'HTMLTableElementImpl*' => 'kde_HTMLTableElementImpl*',
+'HTMLTableRowElement&' => 'kde_HTMLTableRowElement*',
+'HTMLTableRowElement*' => 'kde_HTMLTableRowElement*',
+'HTMLTableRowElementImpl*' => 'kde_HTMLTableRowElementImpl*',
+'HTMLTableSectionElement&' => 'kde_HTMLTableSectionElement*',
+'HTMLTableSectionElement' => 'kde_HTMLTableSectionElement*',
+'HTMLTableSectionElement*' => 'kde_HTMLTableSectionElement*',
+'HTMLTableSectionElementImpl*' => 'kde_HTMLTableSectionElementImpl*',
+'HTMLTextAreaElement&' => 'kde_HTMLTextAreaElement*',
+'HTMLTextAreaElement*' => 'kde_HTMLTextAreaElement*',
+'HTMLTextAreaElementImpl*' => 'kde_HTMLTextAreaElementImpl*',
+'HTMLTitleElement&' => 'kde_HTMLTitleElement*',
+'HTMLTitleElement*' => 'kde_HTMLTitleElement*',
+'HTMLTitleElementImpl*' => 'kde_HTMLTitleElementImpl*',
+'HTMLUListElement&' => 'kde_HTMLUListElement*',
+'HTMLUListElement*' => 'kde_HTMLUListElement*',
+'HTMLUListElementImpl*' => 'kde_HTMLUListElementImpl*',
+'HandlerType' => 'qt_HandlerType*' ,
+'HashEntry*' => 'kde_HashEntry*',
+'HashTable*' => 'kde_HashTable*',
+'Header&' => 'kde_Header*',
+'Header*' => 'kde_Header*',
+'HighlightingInterface*' => 'kde_HighlightingInterface*',
+'HistoryProvider*' => 'kde_HistoryProvider*',
+'HostImp*' => 'kde_HostImp*',
+'IDLFileReg*' => 'kde_IDLFileReg*',
+'IOManager*' => 'kde_IOManager*',
+'IONotify*' => 'kde_IONotify*',
+'IOType*' => 'kde_IOType*',
+'IOWatchFD*' => 'kde_IOWatchFD*',
+'Icon' => 'int',
+'IconListBox*' => 'kde_IconListBox*',
+'Imp*' => 'void*',
+'Info*' => 'kde_Info*',
+'InterfaceDef&' => 'kde_InterfaceDef*',
+'InterfaceDef' => 'kde_InterfaceDef*',
+'InterfaceDef*' => 'kde_InterfaceDef*',
+'InterfaceEntry*' => 'kde_InterfaceEntry*',
+'InterfaceRepo&' => 'kde_InterfaceRepo*',
+'InterfaceRepo' => 'kde_InterfaceRepo*',
+'InterfaceRepo*' => 'kde_InterfaceRepo*',
+'InterfaceRepo_base*' => 'kde_InterfaceRepo_base*',
+'InterfaceRepo_impl*' => 'kde_InterfaceRepo_impl*',
+'InterfaceRepo_skel*' => 'kde_InterfaceRepo_skel*',
+'InterfaceRepo_stub*' => 'kde_InterfaceRepo_stub*',
+'InternalFunctionImp*' => 'kde_InternalFunctionImp*',
+'Interpreter*' => 'kde_Interpreter*',
+'Invocation&' => 'kde_Invocation*',
+'Invocation*' => 'kde_Invocation*',
+'Iterator' => 'Iterator*' ,
+'Job*' => 'void*',
+'K&' => 'K*' ,
+'KAboutApplication*' => 'kde_KAboutApplication*',
+'KAboutContainer*' => 'kde_KAboutContainer*' ,
+'KAboutContributor*' => 'kde_KAboutContributor*',
+'KAboutData*' => 'kde_KAboutData*' ,
+'KAboutDialog*' => 'kde_KAboutDialog*',
+'KAboutKDE*' => 'kde_KAboutKDE*',
+'KAboutPerson*' => 'kde_KAboutPerson*',
+'KAboutTranslator*' => 'kde_KAboutTranslator*',
+'KAboutWidget*' => 'kde_KAboutWidget*',
+'KAccel*' => 'kde_KAccel*' ,
+'KAccelAction&' => 'kde_KAccelAction*',
+'KAccelAction*' => 'kde_KAccelAction*',
+'KAccelActions&' => 'kde_KAccelActions*',
+'KAccelActions*' => 'kde_KAccelActions*',
+'KAccelBase*' => 'kde_KAccelBase*',
+'KAccelGen*' => 'kde_KAccelGen*',
+'KAccelMenu*' => 'kde_KAccelMenu*',
+'KAccelSequence&' => 'kde_KAccelSequence*',
+'KAccelSequence' => 'kde_KAccelSequence*',
+'KAccelSequence*' => 'kde_KAccelSequence*',
+'KAccelShortcut&' => 'kde_KAccelShortcut*',
+'KAccelShortcut' => 'kde_KAccelShortcut*',
+'KAccelShortcut*' => 'kde_KAccelShortcut*',
+'KAccelShortcuts&' => 'kde_KAccelShortcuts*',
+'KAccelShortcuts*' => 'kde_KAccelShortcuts*',
+'KAction*' => 'kde_KAction*' ,
+'KActionCollection&' => 'kde_KActionCollection*' ,
+'KActionCollection' => 'kde_KActionCollection*' ,
+'KActionCollection*' => 'kde_KActionCollection*' ,
+'KActionMenu*' => 'kde_KActionMenu*',
+'KActionSeparator*' => 'kde_KActionSeparator*',
+'KAddressInfo*' => 'kde_KAddressInfo*',
+'KAlphaPainter*' => 'kde_KAlphaPainter*',
+'KAnimWidget*' => 'kde_KAnimWidget*' ,
+'KAppTreeListItem*' => 'kde_KAppTreeListItem*' ,
+'KApplication*' => 'kde_KApplication*' ,
+'KApplicationPropsPlugin*' => 'kde_KApplicationPropsPlugin*',
+'KApplicationTree*' => 'kde_KApplicationTree*',
+'KArchive*' => 'kde_KArchive*',
+'KArchiveDirectory*' => 'kde_KArchiveDirectory*',
+'KArchiveEntry*' => 'kde_KArchiveEntry*',
+'KArchiveFile*' => 'kde_KArchiveFile*',
+'KArrowButton*' => 'kde_KArrowButton*',
+'KArtsDispatcher*' => 'kde_KArtsDispatcher*',
+'KArtsFloatWatch*' => 'kde_KArtsFloatWatch*',
+'KAsyncIO*' => 'kde_KAsyncIO*',
+'KAudioPlayer*' => 'kde_KAudioPlayer*',
+'KAuthIcon*' => 'kde_KAuthIcon*',
+'KAutoMount*' => 'kde_KAutoMount*',
+'KAutoUnmount*' => 'kde_KAutoUnmount*',
+'KBindingPropsPlugin*' => 'kde_KBindingPropsPlugin*',
+'KBlankEffect*' => 'kde_KBlankEffect*',
+'KBufferedIO*' => 'kde_KBufferedIO*',
+'KBugReport*' => 'kde_KBugReport*',
+'KButtonBox*' => 'kde_KButtonBox*',
+'KCModule*' => 'kde_KCModule*' ,
+'KCatalogue&' => 'kde_KCatalogue*',
+'KCatalogue*' => 'kde_KCatalogue*',
+'KCharSelect*' => 'kde_KCharSelect*',
+'KCharSelectTable*' => 'kde_KCharSelectTable*',
+'KCharsets*' => 'kde_KCharsets*' ,
+'KCmdLineArgs*' => 'kde_KCmdLineArgs*' ,
+'KCodecs*' => 'kde_KCodecs*',
+'KColor&' => 'kde_KColor*' ,
+'KColor*' => 'kde_KColor*',
+'KColorButton*' => 'kde_KColorButton*',
+'KColorCells*' => 'kde_KColorCells*',
+'KColorCombo*' => 'kde_KColorCombo*',
+'KColorDialog*' => 'kde_KColorDialog*',
+'KColorDrag*' => 'kde_KColorDrag*' ,
+'KColorPatch*' => 'kde_KColorPatch*',
+'KCombiView*' => 'kde_KCombiView*',
+'KComboBox*' => 'kde_KComboBox*' ,
+'KCommand*' => 'kde_KCommand*',
+'KCommandHistory*' => 'kde_KCommandHistory*',
+'KCompletion*' => 'kde_KCompletion*' ,
+'KCompletionBase*' => 'kde_KCompletionBase*',
+'KCompletionBox*' => 'kde_KCompletionBox*',
+'KConfig*' => 'kde_KConfig*' ,
+'KConfigBackEnd*' => 'kde_KConfigBackEnd*',
+'KConfigBase&' => 'kde_KConfigBase*',
+'KConfigBase*' => 'kde_KConfigBase*' ,
+'KConfigGroup*' => 'kde_KConfigGroup*',
+'KConfigGroupSaver*' => 'kde_KConfigGroupSaver*',
+'KConfigINIBackEnd*' => 'kde_KConfigINIBackEnd*',
+'KContainerLayout*' => 'kde_KContainerLayout*',
+'KContainerLayoutItem*' => 'kde_KContainerLayoutItem*' ,
+'KContextMenuManager*' => 'kde_KContextMenuManager*',
+'KCookie*' => 'kde_KCookie*',
+'KCrash*' => 'kde_KCrash*',
+'KCursor*' => 'kde_KCursor*',
+'KDBGFUNC' => 'void*' ,
+'KDCOPActionProxy*' => 'kde_KDCOPActionProxy*',
+'KDCOPPropertyProxy*' => 'kde_KDCOPPropertyProxy*',
+'KDEAniMenu*' => 'kde_KDEAniMenu*',
+'KDEDModule*' => 'kde_KDEDModule*',
+'KDEDesktopMimeType*' => 'kde_KDEDesktopMimeType*',
+'KDESasl*' => 'kde_KDESasl*',
+'KDEStyle*' => 'kde_KDEStyle*',
+'KDEsuClient*' => 'kde_KDEsuClient*',
+'KDataTool*' => 'kde_KDataTool*',
+'KDataToolAction*' => 'kde_KDataToolAction*',
+'KDataToolInfo&' => 'kde_KDataToolInfo*',
+'KDataToolInfo*' => 'kde_KDataToolInfo*',
+'KDateInternalMonthPicker*' => 'kde_KDateInternalMonthPicker*',
+'KDateInternalYearSelector*' => 'kde_KDateInternalYearSelector*',
+'KDatePicker*' => 'kde_KDatePicker*',
+'KDateTable*' => 'kde_KDateTable*',
+'KDateValidator*' => 'kde_KDateValidator*',
+'KDateWidget*' => 'kde_KDateWidget*',
+'KDesktopFile*' => 'kde_KDesktopFile*' ,
+'KDevApi*' => 'kde_KDevApi*',
+'KDevAppFrontend*' => 'kde_KDevAppFrontend*',
+'KDevCompilerOptions*' => 'kde_KDevCompilerOptions*',
+'KDevCore*' => 'kde_KDevCore*',
+'KDevFactory*' => 'kde_KDevFactory*',
+'KDevLanguageSupport*' => 'kde_KDevLanguageSupport*',
+'KDevMakeFrontend*' => 'kde_KDevMakeFrontend*',
+'KDevPart*' => 'kde_KDevPart*',
+'KDevProject*' => 'kde_KDevProject*',
+'KDevVersionControl*' => 'kde_KDevVersionControl*',
+'KDevicePropsPlugin*' => 'kde_KDevicePropsPlugin*',
+'KDialog*' => 'kde_KDialog*',
+'KDialogBase*' => 'kde_KDialogBase*' ,
+'KDialogBaseTile*' => 'kde_KDialogBaseTile*',
+'KDialogQueue*' => 'kde_KDialogQueue*',
+'KDirNotify*' => 'kde_KDirNotify*',
+'KDirNotify_stub*' => 'kde_KDirNotify_stub*',
+'KDirOperator*' => 'kde_KDirOperator*',
+'KDirSelectDialog*' => 'kde_KDirSelectDialog*',
+'KDirSize*' => 'kde_KDirSize*' ,
+'KDirWatch*' => 'kde_KDirWatch*' ,
+'KDirectionButton*' => 'kde_KDirectionButton*',
+'KDockArea*' => 'kde_KDockArea*',
+'KDockMainWindow*' => 'kde_KDockMainWindow*',
+'KDockManager*' => 'kde_KDockManager*' ,
+'KDockTabBar*' => 'kde_KDockTabBar*',
+'KDockTabBar::TabPos' => 'int',
+'KDockTabBarPainter*' => 'kde_KDockTabBarPainter*',
+'KDockTabCtl*' => 'kde_KDockTabCtl*',
+'KDockTabCtl_PrivateStruct*' => 'kde_KDockTabCtl_PrivateStruct*' ,
+'KDockTabGroup*' => 'kde_KDockTabGroup*' ,
+'KDockWidget*' => 'kde_KDockWidget*' ,
+'KDockWidgetAbstractHeader*' => 'kde_KDockWidgetAbstractHeader*' ,
+'KDockWidgetAbstractHeaderDrag*' => 'kde_KDockWidgetAbstractHeaderDrag*',
+'KDockWidgetHeader*' => 'kde_KDockWidgetHeader*',
+'KDockWidgetHeaderDrag*' => 'kde_KDockWidgetHeaderDrag*',
+'KDockWindow*' => 'kde_KDockWindow*',
+'KDoubleNumInput*' => 'kde_KDoubleNumInput*',
+'KDualColorButton*' => 'kde_KDualColorButton*',
+'KEMailSettings*' => 'kde_KEMailSettings*',
+'KEdFind*' => 'kde_KEdFind*',
+'KEdGotoLine*' => 'kde_KEdGotoLine*',
+'KEdReplace*' => 'kde_KEdReplace*',
+'KEdit*' => 'kde_KEdit*',
+'KEditListBox*' => 'kde_KEditListBox*',
+'KEditToolbar*' => 'kde_KEditToolbar*',
+'KEditToolbarWidget*' => 'kde_KEditToolbarWidget*',
+'KEntry&' => 'kde_KEntry*' ,
+'KEntry' => 'kde_KEntry*' ,
+'KEntry*' => 'kde_KEntry*',
+'KEntryKey&' => 'kde_KEntryKey*' ,
+'KEntryKey*' => 'kde_KEntryKey*',
+'KExecMimeType*' => 'kde_KExecMimeType*',
+'KExecPropsPlugin*' => 'kde_KExecPropsPlugin*',
+'KFile*' => 'kde_KFile*',
+'KFile::FileView' => 'int' ,
+'KFile::Mode' => 'int' ,
+'KFile::SelectionMode' => 'int' ,
+'KFileBookmark*' => 'kde_KFileBookmark*' ,
+'KFileBookmarkManager*' => 'kde_KFileBookmarkManager*',
+'KFileComboBox*' => 'kde_KFileComboBox*',
+'KFileDetailView*' => 'kde_KFileDetailView*',
+'KFileDialog*' => 'kde_KFileDialog*' ,
+'KFileFilter*' => 'kde_KFileFilter*',
+'KFileFilterCombo*' => 'kde_KFileFilterCombo*',
+'KFileIconView*' => 'kde_KFileIconView*',
+'KFileIconViewItem*' => 'kde_KFileIconViewItem*',
+'KFileItemList&' => 'kde_KFileItemList*' ,
+'KFileItemList' => 'kde_KFileItemList*' ,
+'KFileItemList*' => 'kde_KFileItemList*' ,
+'KFileListViewItem*' => 'kde_KFileListViewItem*',
+'KFileMetaInfo*' => 'kde_KFileMetaInfo*',
+'KFileMetaInfoItem*' => 'kde_KFileMetaInfoItem*',
+'KFileMetaInfoProvider*' => 'kde_KFileMetaInfoProvider*',
+'KFileOpenWithHandler*' => 'kde_KFileOpenWithHandler*',
+'KFilePermissionsPropsPlugin*' => 'kde_KFilePermissionsPropsPlugin*',
+'KFilePlugin*' => 'kde_KFilePlugin*',
+'KFilePreview*' => 'kde_KFilePreview*',
+'KFilePropsPlugin*' => 'kde_KFilePropsPlugin*',
+'KFileReader*' => 'kde_KFileReader*' ,
+'KFileTreeBranch*' => 'kde_KFileTreeBranch*',
+'KFileTreeView*' => 'kde_KFileTreeView*',
+'KFileTreeViewItem*' => 'kde_KFileTreeViewItem*',
+'KFileTreeViewToolTip*' => 'kde_KFileTreeViewToolTip*',
+'KFileView*' => 'kde_KFileView*' ,
+'KFileView::FileView' => 'int',
+'KFileViewItem&' => 'kde_KFileViewItem*',
+'KFileViewItem*' => 'kde_KFileViewItem*' ,
+'KFileViewItem**' => 'kde_KFileViewItem**' ,
+'KFileViewItemList&' => 'kde_KFileViewItemList*' ,
+'KFileViewItemList*' => 'kde_KFileViewItemList*' ,
+'KFileViewSignaler*' => 'kde_KFileViewSignaler*',
+'KFilterBase*' => 'kde_KFilterBase*',
+'KFilterDev*' => 'kde_KFilterDev*',
+'KFloatValidator*' => 'kde_KFloatValidator*',
+'KFloatWatchProxy&' => 'kde_KFloatWatchProxy*',
+'KFloatWatchProxy' => 'kde_KFloatWatchProxy*',
+'KFloatWatchProxy*' => 'kde_KFloatWatchProxy*',
+'KFolderType*' => 'kde_KFolderType*',
+'KFontAction*' => 'kde_KFontAction*',
+'KFontChooser*' => 'kde_KFontChooser*',
+'KFontCombo*' => 'kde_KFontCombo*',
+'KFontDialog*' => 'kde_KFontDialog*',
+'KFontSizeAction*' => 'kde_KFontSizeAction*',
+'KGenericFactory*' => 'kde_KGenericFactory*',
+'KGenericFactoryBase*' => 'kde_KGenericFactoryBase*',
+'KGlobal*' => 'kde_KGlobal*',
+'KGlobalAccel*' => 'kde_KGlobalAccel*' ,
+'KGlobalSettings*' => 'kde_KGlobalSettings*',
+'KGlobalSettings::Completion' => 'int' ,
+'KGradientSelector*' => 'kde_KGradientSelector*',
+'KGuiItem&' => 'kde_KGuiItem*',
+'KGuiItem' => 'kde_KGuiItem*',
+'KGuiItem*' => 'kde_KGuiItem*',
+'KHSSelector*' => 'kde_KHSSelector*',
+'KHTMLPart*' => 'kde_KHTMLPart*' ,
+'KHTMLSettings&' => 'kde_KHTMLSettings*',
+'KHTMLSettings*' => 'kde_KHTMLSettings*' ,
+'KHTMLView*' => 'kde_KHTMLView*' ,
+'KHelpMenu*' => 'kde_KHelpMenu*',
+'KHistoryCombo*' => 'kde_KHistoryCombo*',
+'KIO*' => 'kde_KIO*',
+'KIO::CopyJob*' => 'kde_CopyJob*' ,
+'KIO::DeleteJob*' => 'kde_DeleteJob*' ,
+'KIO::Job*' => 'kde_Job*' ,
+'KIO::ListJob*' => 'kde_ListJob*' ,
+'KIO::RenameDlg_Mode' => 'int',
+'KIO::RenameDlg_Result' => 'int',
+'KIO::SimpleJob*' => 'kde_SimpleJob*',
+'KIO::SkipDlg_Result' => 'int',
+'KIO::Slave*' => 'kde_Slave*',
+'KIOInputStream&' => 'kde_KIOInputStream*',
+'KIOInputStream*' => 'kde_KIOInputStream*',
+'KIOTestSlow&' => 'kde_KIOTestSlow*',
+'KIOTestSlow' => 'kde_KIOTestSlow*',
+'KIOTestSlow*' => 'kde_KIOTestSlow*',
+'KIPC*' => 'kde_KIPC*',
+'KIcon' => 'kde_KIcon*' ,
+'KIcon*' => 'kde_KIcon*',
+'KIconButton*' => 'kde_KIconButton*',
+'KIconCanvas*' => 'kde_KIconCanvas*',
+'KIconDialog*' => 'kde_KIconDialog*',
+'KIconEffect*' => 'kde_KIconEffect*' ,
+'KIconLoader*' => 'kde_KIconLoader*' ,
+'KIconSelectAction*' => 'kde_KIconSelectAction*',
+'KIconView*' => 'kde_KIconView*',
+'KIconViewItem*' => 'kde_KIconViewItem*',
+'KImageEffect*' => 'kde_KImageEffect*',
+'KImageFilePreview*' => 'kde_KImageFilePreview*',
+'KImageIO*' => 'kde_KImageIO*',
+'KInstance&' => 'kde_KInstance*' ,
+'KInstance' => 'kde_KInstance*' ,
+'KInstance*' => 'kde_KInstance*' ,
+'KIntNumInput*' => 'kde_KIntNumInput*',
+'KIntSpinBox*' => 'kde_KIntSpinBox*',
+'KIntValidator*' => 'kde_KIntValidator*',
+'KJS*' => 'kde_KJS*',
+'KJS::KJSO&' => 'kde_KJS_KJSO*',
+'KJS::UString&' => 'kde_KJS_UString*',
+'KJSO&' => 'kde_KJSO*',
+'KJSO' => 'kde_KJSO*',
+'KJSO*' => 'kde_KJSO*',
+'KJScript*' => 'kde_KJScript*',
+'KJanusWidget*' => 'kde_KJanusWidget*',
+'KKeyChooser*' => 'kde_KKeyChooser*',
+'KKeyDialog*' => 'kde_KKeyDialog*',
+'KKeyEntry&' => 'kde_KKeyEntry*' ,
+'KKeyEntry*' => 'kde_KKeyEntry*',
+'KKeyEntryMap&' => 'kde_KKeyEntryMap*' ,
+'KKeyEntryMap' => 'kde_KKeyEntryMap*' ,
+'KKeyEntryMap*' => 'kde_KKeyEntryMap*' ,
+'KKeySequence&' => 'kde_KKeySequence*',
+'KKeySequence' => 'kde_KKeySequence*',
+'KKeySequence*' => 'kde_KKeySequence*',
+'KKeySequence::I18N' => 'int',
+'KKeySequences&' => 'kde_KKeySequences*',
+'KKeySequences' => 'kde_KKeySequences*',
+'KKeySequences*' => 'kde_KKeySequences*',
+'KLed*' => 'kde_KLed*',
+'KLibFactory*' => 'kde_KLibFactory*' ,
+'KLibLoader*' => 'kde_KLibLoader*' ,
+'KLineEdit*' => 'kde_KLineEdit*' ,
+'KLineEditDlg*' => 'kde_KLineEditDlg*',
+'KListBox*' => 'kde_KListBox*',
+'KListView*' => 'kde_KListView*' ,
+'KListViewItem*' => 'kde_KListViewItem*',
+'KLocale&' => 'kde_KLocale*' ,
+'KLocale*' => 'kde_KLocale*' ,
+'KMJobViewer*' => 'kde_KMJobViewer*',
+'KMMainView*' => 'kde_KMMainView*',
+'KMManager*' => 'kde_KMManager*',
+'KMObject*' => 'kde_KMObject*',
+'KMPrinter&' => 'kde_KMPrinter*',
+'KMPrinter*' => 'kde_KMPrinter*',
+'KMPrinterList*' => 'kde_KMPrinterList*',
+'KMPrinterPage*' => 'kde_KMPrinterPage*',
+'KMainWindow*' => 'kde_KMainWindow*',
+'KMainWindowInterface*' => 'kde_KMainWindowInterface*',
+'KMenuBar*' => 'kde_KMenuBar*' ,
+'KMessageBox*' => 'kde_KMessageBox*',
+'KMidSimpleAPI*' => 'kde_KMidSimpleAPI*',
+'KMimeMagic*' => 'kde_KMimeMagic*' ,
+'KMimeMagicResult*' => 'kde_KMimeMagicResult*' ,
+'KMimeSourceFactory*' => 'kde_KMimeSourceFactory*' ,
+'KMimeType::List&' => 'kde_KMimeType_List*' ,
+'KMouseSettings*' => 'kde_KMouseSettings*',
+'KMultipleDrag*' => 'kde_KMultipleDrag*',
+'KNDBGFUNC' => 'void*' ,
+'KNotifyClient*' => 'kde_KNotifyClient*',
+'KNumInput*' => 'kde_KNumInput*' ,
+'KOCRDialog*' => 'kde_KOCRDialog*',
+'KOCRDialogFactory*' => 'kde_KOCRDialogFactory*',
+'KOpenSSLProxy*' => 'kde_KOpenSSLProxy*',
+'KOpenWithDlg*' => 'kde_KOpenWithDlg*',
+'KOpenWithHandler*' => 'kde_KOpenWithHandler*' ,
+'KPAC*' => 'kde_KPAC*',
+'KPReloadObject*' => 'kde_KPReloadObject*',
+'KPalette&' => 'kde_KPalette*' ,
+'KPalette*' => 'kde_KPalette*',
+'KPaletteTable*' => 'kde_KPaletteTable*',
+'KPanelAppMenu*' => 'kde_KPanelAppMenu*',
+'KPanelApplet*' => 'kde_KPanelApplet*',
+'KPanelExtension*' => 'kde_KPanelExtension*',
+'KPanelMenu*' => 'kde_KPanelMenu*' ,
+'KParts*' => 'kde_KParts*',
+'KParts::BrowserExtension*' => 'kde_BrowserExtension*' ,
+'KParts::GUIActivateEvent*' => 'kde_GUIActivateEvent*' ,
+'KParts::Part*' => 'kde_Part*',
+'KParts::ReadOnlyPart*' => 'kde_ReadOnlyPart*' ,
+'KPasswordDialog*' => 'kde_KPasswordDialog*',
+'KPasswordEdit*' => 'kde_KPasswordEdit*',
+'KPixmap&' => 'kde_KPixmap*' ,
+'KPixmap' => 'kde_KPixmap*' ,
+'KPixmap*' => 'kde_KPixmap*',
+'KPixmapEffect*' => 'kde_KPixmapEffect*',
+'KPixmapIO*' => 'kde_KPixmapIO*',
+'KPixmapProvider*' => 'kde_KPixmapProvider*' ,
+'KPixmapSplitter*' => 'kde_KPixmapSplitter*',
+'KPlayObject*' => 'kde_KPlayObject*',
+'KPlayObjectFactory*' => 'kde_KPlayObjectFactory*',
+'KPopupFrame*' => 'kde_KPopupFrame*',
+'KPopupMenu*' => 'kde_KPopupMenu*' ,
+'KPopupTitle*' => 'kde_KPopupTitle*',
+'KPreviewWidgetBase*' => 'kde_KPreviewWidgetBase*',
+'KPrintAction*' => 'kde_KPrintAction*',
+'KPrintDialogPage*' => 'kde_KPrintDialogPage*',
+'KPrinter*' => 'kde_KPrinter*',
+'KPrinterWrapper*' => 'kde_KPrinterWrapper*',
+'KProcIO*' => 'kde_KProcIO*' ,
+'KProcess&' => 'kde_KProcess*' ,
+'KProcess*' => 'kde_KProcess*' ,
+'KProcessController*' => 'kde_KProcessController*',
+'KProcessRunner*' => 'kde_KProcessRunner*',
+'KProgress*' => 'kde_KProgress*',
+'KPropertiesDialog*' => 'kde_KPropertiesDialog*' ,
+'KPropsDlgPlugin*' => 'kde_KPropsDlgPlugin*' ,
+'KProtocolInfo*' => 'kde_KProtocolInfo*',
+'KProtocolManager*' => 'kde_KProtocolManager*',
+'KPushButton*' => 'kde_KPushButton*',
+'KRFCDate*' => 'kde_KRFCDate*',
+'KRadioAction*' => 'kde_KRadioAction*',
+'KRandomSequence*' => 'kde_KRandomSequence*',
+'KRecentDocument*' => 'kde_KRecentDocument*',
+'KRegExp*' => 'kde_KRegExp*',
+'KRegExpEditor*' => 'kde_KRegExpEditor*',
+'KRegExpEditorInterface*' => 'kde_KRegExpEditorInterface*',
+'KRestrictedLine*' => 'kde_KRestrictedLine*',
+'KRootPermsIcon*' => 'kde_KRootPermsIcon*',
+'KRootPixmap*' => 'kde_KRootPixmap*',
+'KRootProp*' => 'kde_KRootProp*',
+'KRuler*' => 'kde_KRuler*',
+'KRun*' => 'kde_KRun*',
+'KSSL&' => 'kde_KSSL*',
+'KSSL*' => 'kde_KSSL*',
+'KSSLAuthAction' => 'int',
+'KSSLAuthAction*' => 'int*',
+'KSSLCertBox*' => 'kde_KSSLCertBox*',
+'KSSLCertChain&' => 'kde_KSSLCertChain*',
+'KSSLCertChain*' => 'kde_KSSLCertChain*',
+'KSSLCertDlg*' => 'kde_KSSLCertDlg*',
+'KSSLCertDlgRet' => 'kde_KSSLCertDlgRet*',
+'KSSLCertDlgRet*' => 'kde_KSSLCertDlgRet*',
+'KSSLCertificate&' => 'kde_KSSLCertificate*',
+'KSSLCertificate*' => 'kde_KSSLCertificate*',
+'KSSLCertificateCache*' => 'kde_KSSLCertificateCache*',
+'KSSLCertificateFactory*' => 'kde_KSSLCertificateFactory*',
+'KSSLCertificateHome*' => 'kde_KSSLCertificateHome*',
+'KSSLConnectionInfo&' => 'kde_KSSLConnectionInfo*',
+'KSSLConnectionInfo*' => 'kde_KSSLConnectionInfo*',
+'KSSLInfoDlg*' => 'kde_KSSLInfoDlg*',
+'KSSLKeyGen*' => 'kde_KSSLKeyGen*',
+'KSSLKeyType' => 'int',
+'KSSLPKCS12*' => 'kde_KSSLPKCS12*',
+'KSSLPKCS7*' => 'kde_KSSLPKCS7*',
+'KSSLPeerInfo&' => 'kde_KSSLPeerInfo*',
+'KSSLPeerInfo*' => 'kde_KSSLPeerInfo*',
+'KSSLSettings*' => 'kde_KSSLSettings*',
+'KSSLSigners*' => 'kde_KSSLSigners*',
+'KSSLX509Map*' => 'kde_KSSLX509Map*',
+'KSSLX509V3&' => 'kde_KSSLX509V3*',
+'KSSLX509V3*' => 'kde_KSSLX509V3*',
+'KSaveFile*' => 'kde_KSaveFile*',
+'KScanDialog*' => 'kde_KScanDialog*',
+'KScanDialogFactory*' => 'kde_KScanDialogFactory*',
+'KScreenSaver*' => 'kde_KScreenSaver*',
+'KScriptClientInterface*' => 'kde_KScriptClientInterface*',
+'KScriptClientInterface::Result' => 'int',
+'KScriptInterface*' => 'kde_KScriptInterface*',
+'KScriptManager*' => 'kde_KScriptManager*',
+'KSelectAction*' => 'kde_KSelectAction*',
+'KSelector*' => 'kde_KSelector*',
+'KSeparator*' => 'kde_KSeparator*',
+'KService&' => 'kde_KService*' ,
+'KService*' => 'kde_KService*',
+'KServiceGroup*' => 'kde_KServiceGroup*',
+'KServiceOffer&' => 'kde_KServiceOffer*' ,
+'KServiceOffer*' => 'kde_KServiceOffer*',
+'KServiceType*' => 'kde_KServiceType*',
+'KServiceTypeProfile*' => 'kde_KServiceTypeProfile*' ,
+'KSessionManaged*' => 'kde_KSessionManaged*',
+'KShared&' => 'kde_KShared*' ,
+'KShared*' => 'kde_KShared*',
+'KSharedPtr&' => 'kde_KSharedPtr*' ,
+'KSharedPtr*' => 'kde_KSharedPtr*',
+'KShellCompletion*' => 'kde_KShellCompletion*',
+'KShellProcess*' => 'kde_KShellProcess*',
+'KShortcuts&' => 'kde_KShortcuts*',
+'KShortcuts' => 'kde_KShortcuts*',
+'KShortcuts*' => 'kde_KShortcuts*',
+'KShred*' => 'kde_KShred*',
+'KSimpleConfig&' => 'kde_KSimpleConfig*' ,
+'KSimpleConfig*' => 'kde_KSimpleConfig*',
+'KSimpleFileFilter*' => 'kde_KSimpleFileFilter*',
+'KSpell*' => 'kde_KSpell*',
+'KSpellConfig&' => 'kde_KSpellConfig*' ,
+'KSpellConfig' => 'kde_KSpellConfig*' ,
+'KSpellConfig*' => 'kde_KSpellConfig*' ,
+'KSpellDlg*' => 'kde_KSpellDlg*',
+'KSqueezedTextLabel*' => 'kde_KSqueezedTextLabel*',
+'KStandardDirs*' => 'kde_KStandardDirs*' ,
+'KStartupInfo*' => 'kde_KStartupInfo*',
+'KStartupInfoData&' => 'kde_KStartupInfoData*',
+'KStartupInfoData*' => 'kde_KStartupInfoData*',
+'KStartupInfoId&' => 'kde_KStartupInfoId*',
+'KStartupInfoId' => 'kde_KStartupInfoId*',
+'KStartupInfoId*' => 'kde_KStartupInfoId*',
+'KStaticDeleter*' => 'kde_KStaticDeleter*',
+'KStaticDeleterBase*' => 'kde_KStaticDeleterBase*' ,
+'KStatusBar*' => 'kde_KStatusBar*' ,
+'KStatusBar::BarStatusstat::Toggle' => 'int' ,
+'KStatusBarLabel*' => 'kde_KStatusBarLabel*',
+'KStdAccel*' => 'kde_KStdAccel*',
+'KStdAccel::StdAccel' => 'int' ,
+'KStdAction*' => 'kde_KStdAction*',
+'KStdGuiItem*' => 'kde_KStdGuiItem*',
+'KStringHandler*' => 'kde_KStringHandler*',
+'KStyle*' => 'kde_KStyle*' ,
+'KSycoca*' => 'kde_KSycoca*' ,
+'KSycocaEntry*' => 'kde_KSycocaEntry*' ,
+'KSycocaFactoryId' => 'int' ,
+'KSycocaType&' => 'int' ,
+'KSycocaType' => 'int' ,
+'KSystemTray*' => 'kde_KSystemTray*',
+'KTMainWindow*' => 'kde_KTMainWindow*',
+'KTabButton*' => 'kde_KTabButton*',
+'KTabCtl*' => 'kde_KTabCtl*',
+'KTar*' => 'kde_KTar*',
+'KTarBase*' => 'kde_KTarBase*' ,
+'KTarData*' => 'kde_KTarData*',
+'KTarDirectory*' => 'kde_KTarDirectory*' ,
+'KTarEntry*' => 'kde_KTarEntry*' ,
+'KTarFile*' => 'kde_KTarFile*',
+'KTarGz*' => 'kde_KTarGz*',
+'KTempFile*' => 'kde_KTempFile*',
+'KTextBrowser*' => 'kde_KTextBrowser*',
+'KTextEditor*' => 'kde_KTextEditor*',
+'KTextEditor__View&' => 'kde_KTextEditor__View*',
+'KTextEditor__View' => 'kde_KTextEditor__View*',
+'KTextEditor__View*' => 'kde_KTextEditor__View*',
+'KThemeBase*' => 'kde_KThemeBase*', ,
+'KThemeCache*' => 'kde_KThemeCache*',
+'KThemePixmap&' => 'kde_KThemePixmap*' ,
+'KThemePixmap*' => 'kde_KThemePixmap*' ,
+'KThemeStyle*' => 'kde_KThemeStyle*',
+'KTipDatabase*' => 'kde_KTipDatabase*',
+'KTipDialog*' => 'kde_KTipDialog*',
+'KToggleAction*' => 'kde_KToggleAction*' ,
+'KToolBar*' => 'kde_KToolBar*' ,
+'KToolBar::BarStatus' => 'int',
+'KToolBar::BarStatusstat::Toggle' => 'int' ,
+'KToolBarButton*' => 'kde_KToolBarButton*' ,
+'KToolBarButtonList*' => 'kde_KToolBarButtonList*',
+'KToolBarPopupAction*' => 'kde_KToolBarPopupAction*',
+'KToolBarPos' => 'int' ,
+'KToolBarRadioGroup*' => 'kde_KToolBarRadioGroup*',
+'KToolBarSeparator*' => 'kde_KToolBarSeparator*',
+'KToolButtonType' => 'int' ,
+'KTrader*' => 'kde_KTrader*' ,
+'KTypeList*' => 'kde_KTypeList*',
+'KURIFilter*' => 'kde_KURIFilter*' ,
+'KURIFilterData&' => 'kde_KURIFilterData*' ,
+'KURIFilterData*' => 'kde_KURIFilterData*',
+'KURIFilterPlugin*' => 'kde_KURIFilterPlugin*',
+'KURIFilterPluginList*' => 'kde_KURIFilterPluginList*',
+'KURL& url ()' => 'kde_KURL*',
+'KURL& urlName ()' => 'kde_KURL*',
+'KURL&' => 'kde_KURL*' ,
+'KURL' => 'kde_KURL*' ,
+'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*',
+'KURLDrag*' => 'kde_KURLDrag*',
+'KURLLabel*' => 'kde_KURLLabel*',
+'KURLPixmapProvider*' => 'kde_KURLPixmapProvider*',
+'KURLPropsPlugin*' => 'kde_KURLPropsPlugin*',
+'KURLRequester*' => 'kde_KURLRequester*',
+'KURLRequesterDlg*' => 'kde_KURLRequesterDlg*',
+'KUniqueApplication*' => 'kde_KUniqueApplication*',
+'KUnixSocketAddress*' => 'kde_KUnixSocketAddress*',
+'KValueSelector*' => 'kde_KValueSelector*',
+'KWin*' => 'kde_KWin*',
+'KWinModule*' => 'kde_KWinModule*',
+'KWindowListMenu*' => 'kde_KWindowListMenu*',
+'KWizard*' => 'kde_KWizard*',
+'KWordWrap*' => 'kde_KWordWrap*',
+'KWritePermsIcon*' => 'kde_KWritePermsIcon*',
+'KXMLGUIBuilder*' => 'kde_KXMLGUIBuilder*' ,
+'KXMLGUIClient*' => 'kde_KXMLGUIClient*' ,
+'KXMLGUIFactory*' => 'kde_KXMLGUIFactory*' ,
+'KXMessages*' => 'kde_KXMessages*',
+'KXYSelector*' => 'kde_KXYSelector*',
+'KZoneAllocator*' => 'kde_KZoneAllocator*',
+'KabAPI*' => 'kde_KabAPI*',
+'KabKey&' => 'kde_KabKey*' ,
+'KabKey' => 'kde_KabKey*' ,
+'KabKey*' => 'kde_KabKey*',
+'Key&' => 'Key*' ,
+'KeyBindingMap' => 'kde_KeyBindingMap*' ,
+'KeyValueMap&' => 'kde_KeyValueMap*' ,
+'KeyValueMap*&' => 'kde_KeyValueMap*' ,
+'KeyValueMap*' => 'kde_KeyValueMap*' ,
+'Keymap*' => 'kde_Keymap*',
+'LinkStyle&' => 'kde_LinkStyle*',
+'LinkStyle*' => 'kde_LinkStyle*',
+'ListIterator&' => 'kde_ListIterator*',
+'ListIterator' => 'kde_ListIterator',
+'ListIterator*' => 'kde_ListIterator*',
+'ListJob*' => 'kde_ListJob*',
+'ListNode*' => 'kde_ListNode*',
+'ListProgress*' => 'kde_ListProgress*',
+'Lookup*' => 'kde_Lookup*',
+'MCOPConfig*' => 'kde_MCOPConfig*',
+'MCOPUtils*' => 'kde_MCOPUtils*',
+'MailServer&' => 'MailServer*' ,
+'MailServer*' => 'kde_MailServer*',
+'MainWindow*' => 'kde_MainWindow*',
+'Mark*' => 'kde_Mark*',
+'MarkInterface*' => 'kde_MarkInterface*',
+'MediaAsyncStream*' => 'kde_MediaAsyncStream*',
+'MediaDataPacket*' => 'kde_MediaDataPacket*',
+'MediaFrame*' => 'kde_MediaFrame*',
+'MediaList&' => 'kde_MediaList*',
+'MediaList' => 'kde_MediaList*',
+'MediaList*' => 'kde_MediaList*',
+'MediaListImpl*' => 'kde_MediaListImpl*',
+'MediaModule&' => 'kde_MediaModule*',
+'MediaModule' => 'kde_MediaModule*',
+'MediaModule*' => 'kde_MediaModule*',
+'MediaModule_base*' => 'kde_MediaModule_base*',
+'MediaModule_skel*' => 'kde_MediaModule_skel*',
+'MediaModule_stub*' => 'kde_MediaModule_stub*',
+'MenuDockData*' => 'kde_MenuDockData*',
+'MethodDef&' => 'kde_MethodDef*',
+'MethodDef*' => 'kde_MethodDef*',
+'MidiEvent*' => 'kde_MidiEvent*',
+'MidiFileInfo*' => 'kde_MidiFileInfo*',
+'MidiMapper*' => 'kde_MidiMapper*',
+'MidiOut*' => 'kde_MidiOut*',
+'MidiPlayer*' => 'kde_MidiPlayer*',
+'MidiStatus*' => 'kde_MidiStatus*',
+'MidiTrack*' => 'kde_MidiTrack*',
+'MimetypeJob*' => 'kde_MimetypeJob*',
+'Mode' => 'int',
+'ModuleDef&' => 'kde_ModuleDef*',
+'ModuleDef*' => 'kde_ModuleDef*',
+'MouseDoubleClickEvent*' => 'kde_MouseDoubleClickEvent*',
+'MouseEvent*' => 'kde_MouseEvent*',
+'MouseMoveEvent*' => 'kde_MouseMoveEvent*',
+'MousePressEvent*' => 'kde_MousePressEvent*',
+'MouseReleaseEvent*' => 'kde_MouseReleaseEvent*',
+'MultiGetJob*' => 'kde_MultiGetJob*',
+'MultiPort*' => 'kde_MultiPort*',
+'NET*' => 'kde_NET*',
+'NET::WindowType' => 'int' ,
+'NETIcon' => 'kdeNETIcon*' ,
+'NETIcon*' => 'kde_NETIcon*',
+'NETPoint&' => 'kde_NETPoint*' ,
+'NETPoint' => 'kde_NETPoint*' ,
+'NETPoint*' => 'kde_NETPoint*',
+'NETRect&' => 'kde_NETRect*' ,
+'NETRect' => 'kde_NETRect*' ,
+'NETRect*' => 'kde_NETRect*',
+'NETRootInfo&' => 'kde_NETRootInfo*' ,
+'NETRootInfo*' => 'kde_NETRootInfo*',
+'NETRootInfoPrivate*' => 'kde_NETRootInfoPrivate*',
+'NETSize&' => 'kde_NETSize*' ,
+'NETSize' => 'kde_NETSize*' ,
+'NETSize*' => 'kde_NETSize*',
+'NETStrut' => 'kde_NETStrut*' ,
+'NETStrut*' => 'kde_NETStrut*',
+'NETWinInfo&' => 'kde_NETWinInfo*' ,
+'NETWinInfo*' => 'kde_NETWinInfo*',
+'NETWinInfoPrivate*' => 'kde_NETWinInfoPrivate*',
+'NamedNodeMap&' => 'kde_NamedNodeMap*',
+'NamedNodeMap' => 'kde_NamedNodeMap*',
+'NamedNodeMap*' => 'kde_NamedNodeMap*',
+'NamedNodeMapImpl*' => 'kde_NamedNodeMapImpl*',
+'NetAccess*' => 'kde_NetAccess*',
+'NetRC*' => 'kde_NetRC*',
+'Node&' => 'kde_Node*',
+'Node' => 'kde_Node*',
+'Node*' => 'kde_Node*',
+'NodeFilter&' => 'kde_NodeFilter*',
+'NodeFilter' => 'kde_NodeFilter*',
+'NodeFilter*' => 'kde_NodeFilter*',
+'NodeFilterImpl*' => 'kde_NodeFilterImpl*',
+'NodeImpl*' => 'kde_NodeImpl*',
+'NodeIterator&' => 'kde_NodeIterator*',
+'NodeIterator' => 'kde_NodeIterator*',
+'NodeIterator*' => 'kde_NodeIterator*',
+'NodeIteratorImpl*' => 'kde_NodeIteratorImpl*',
+'NodeList&' => 'kde_DOMNodeList*',
+'NodeList' => 'kde_DOMNodeList*',
+'NodeList*' => 'kde_DOMNodeList*',
+'NodeListImpl*' => 'kde_NodeListImpl*',
+'NodePtr' => 'int' ,
+'NodeType' => 'int' ,
+'Notation&' => 'kde_Notation*',
+'Notation*' => 'kde_Notation*',
+'NoteArray*' => 'kde_NoteArray*',
+'Notification&' => 'kde_Notification*',
+'Notification' => 'kde_Notification*',
+'Notification*' => 'kde_Notification*',
+'NotificationClient*' => 'kde_NotificationClient*',
+'NotificationManager*' => 'kde_NotificationManager*',
+'Null*' => 'null',
+'Number&' => 'kde_Number*',
+'Number*' => 'kde_Number*',
+'Object&' => 'kde_Object*',
+'Object' => 'kde_Object*',
+'Object*' => 'kde_Object*',
+'ObjectImp*' => 'kde_ObjectImp*',
+'ObjectManager*' => 'kde_ObjectManager*',
+'ObjectReference&' => 'kde_ObjectReference*',
+'ObjectReference*' => 'kde_ObjectReference*',
+'Object_base*' => 'kde_Object_base*',
+'Object_skel*' => 'kde_Object_skel*',
+'Object_stub*' => 'kde_Object_stub*',
+'Observer*' => 'kde_Observer*',
+'OfferList' => 'kde_OfferList*' ,
+'KTrader::OfferList' => 'kde_OfferList*' ,
+'Offset' => 'int',
+'OnewayDispatchFunction' => 'kde_OnewayDispatchFunction*',
+'OnewayInvocation&' => 'kde_OnewayInvocation*',
+'OnewayInvocation*' => 'kde_OnewayInvocation*',
+'OpenURLEvent*' => 'kde_OpenURLEvent*',
+'Orientation' => 'int',
+'PFlags' => 'int',
+'PIAccess' => 'int',
+'PID' => 'long',
+'PIType' => 'int',
+'PTY*' => 'kde_PTY*',
+'PageSize' => 'int',
+'ParamDef&' => 'kde_ParamDef*',
+'ParamDef*' => 'kde_ParamDef*',
+'ParsedArgument*' => 'kde_ParsedArgument*',
+'ParsedAttribute*' => 'kde_ParsedAttribute*',
+'ParsedClass&' => 'kde_ParsedClass&',
+'ParsedClass*' => 'kde_ParsedClass*',
+'ParsedClassContainer*' => 'kde_ParsedClassContainer*',
+'ParsedContainer*' => 'kde_ParsedContainer*',
+'ParsedItem*' => 'kde_ParsedItem*',
+'ParsedMethod*' => 'kde_ParsedMethod*',
+'ParsedParent*' => 'kde_ParsedParent*',
+'ParsedScopeContainer*' => 'kde_ParsedScopeContainer*',
+'ParsedSignalSlot*' => 'kde_ParsedSignalSlot*',
+'ParsedStruct*' => 'kde_ParsedStruct*',
+'Part*' => 'kde_Part*',
+'PartActivateEvent*' => 'kde_PartActivateEvent*',
+'PartBase*' => 'kde_PartBase*',
+'PartSelectEvent*' => 'kde_PartSelectEvent*',
+'PassDlg*' => 'kde_PassDlg*',
+'PasswordDialog*' => 'kde_PasswordDialog*',
+'PenCapStyle' => 'int' ,
+'PenJoinStyle' => 'int' ,
+'PenStyle' => 'int',
+'PersistantClassStore*' => 'kde_PersistantClassStore*',
+'PhoneNumber&' => 'kde_PhoneNumber*',
+'PhoneNumber*' => 'kde_PhoneNumber*',
+'PipeBuffer*' => 'kde_PipeBuffer*',
+'PipeSegment*' => 'kde_PipeSegment*',
+'Pix&' => 'kde_Pix*' ,
+'Pix' => 'kde_Pix*' ,
+'PixelMetric' => 'int',
+'PlayObject&' => 'kde_PlayObject*',
+'PlayObject' => 'kde_PlayObject*',
+'PlayObject*' => 'kde_PlayObject*',
+'PlayObjectFactory&' => 'kde_PlayObjectFactory*',
+'PlayObjectFactory' => 'kde_PlayObjectFactory',
+'PlayObjectFactory*' => 'kde_PlayObjectFactory*',
+'PlayObjectFactory_base*' => 'kde_PlayObjectFactory_base*',
+'PlayObjectFactory_skel*' => 'kde_PlayObjectFactory_skel*',
+'PlayObjectFactory_stub*' => 'kde_PlayObjectFactory_stub*',
+'PlayObject_base*' => 'kde_PlayObject_base*',
+'PlayObject_private&' => 'kde_PlayObject_private*',
+'PlayObject_private' => 'kde_PlayObject_private',
+'PlayObject_private*' => 'kde_PlayObject_private*',
+'PlayObject_private_base*' => 'kde_PlayObject_private_base*',
+'PlayObject_private_skel*' => 'kde_PlayObject_private_skel*',
+'PlayObject_private_stub*' => 'kde_PlayObject_private_stub*',
+'PlayObject_skel*' => 'kde_PlayObject_skel*',
+'PlayObject_stub*' => 'kde_PlayObject_stub*',
+'PlayerController*' => 'kde_PlayerController*',
+'Plugin*' => 'kde_Plugin*',
+'PluginInfo*' => 'kde_PluginInfo*',
+'Policy' => 'int',
+'Pool&' => 'kde_Pool*',
+'Pool*' => 'kde_Pool*',
+'PopupMenuInterface*' => 'kde_PopupMenuInterface*',
+'Port*' => 'kde_Port*',
+'PreviewJob*' => 'kde_PreviewJob*',
+'PrimitiveElement' => 'int',
+'PrintInterface*' => 'kde_PrintInterface*',
+'PrinterMode' => 'int',
+'ProcessingInstruction&' => 'kde_ProcessingInstruction*',
+'ProcessingInstruction' => 'kde_ProcessingInstruction*',
+'ProcessingInstruction*' => 'kde_ProcessingInstruction*',
+'ProgressBase*' => 'kde_ProgressBase*',
+'ProgressItem*' => 'kde_ProgressItem*',
+'PropagationMode' => 'int',
+'ProtocolInfo*' => 'kde_ProtocolInfo*',
+'Ptr' => 'void*',
+'PtyProcess*' => 'kde_PtyProcess*',
+'QAccel*' => 'qt_QAccel*',
+'QAccessible*' => 'qt_QAccessible*',
+'QAccessibleFactoryInterface*' => 'qt_QAccessibleFactoryInterface*',
+'QAccessibleInterface*' => 'qt_QAccessibleInterface*',
+'QAccessibleInterface**' => 'qt_QAccessibleInterface**',
+'QAccessibleObject*' => 'qt_QAccessibleObject*',
+'QAction*' => 'qt_QAction*' ,
+'QActionGroup*' => 'qt_QActionGroup*',
+'QApplication*' => 'qt_QApplication*' ,
+'QArabicCodec*' => 'qt_QArabicCodec*',
+'QArray*' => 'qt_QArray*',
+'QAsciiBucket*' => 'qt_QAsciiBucket*',
+'QAsciiCache*' => 'qt_QAsciiCache*',
+'QAsciiCacheIterator*' => 'qt_QAsciiCacheIterator*',
+'QAsciiDict*' => 'qt_QAsciiDict*',
+'QAsciiDictIterator*' => 'qt_QAsciiDictIterator*',
+'QAsyncIO*' => 'qt_QAsyncIO*',
+'QAuBucket*' => 'qt_QAuBucket*' ,
+'QAuServer*' => 'qt_QAuServer*',
+'QBaseBucket*' => 'qt_QBaseBucket*' ,
+'QBig5Codec*' => 'qt_QBig5Codec*',
+'QBitArray&' => 'qt_QBitArray*' ,
+'QBitArray' => 'qt_QBitArray*' ,
+'QBitArray*' => 'qt_QBitArray*' ,
+'QBitVal&' => 'qt_QBitVal*' ,
+'QBitVal' => 'qt_QBitVal*' ,
+'QBitVal*' => 'qt_QBitVal*',
+'QBitmap&' => 'qt_QBitmap*',
+'QBitmap' => 'qt_QBitmap*',
+'QBitmap*' => 'qt_QBitmap*',
+'QBoxLayout*' => 'qt_QBoxLayout*',
+'QBrush&' => 'qt_QBrush*',
+'QBrush' => 'qt_QBrush*' ,
+'QBrush*' => 'qt_QBrush*' ,
+'QBrushData*' => 'qt_QBrushData*',
+'QBuffer*' => 'qt_QBuffer*',
+'QButton*' => 'qt_QButton*',
+'QButtonGroup*' => 'qt_QButtonGroup*' ,
+'QByteArray& arr ()' => 'qt_QByteArray*',
+'QByteArray&' => 'qt_QByteArray*' ,
+'QByteArray' => 'qt_QByteArray*',
+'QByteArray*' => 'qt_QByteArray*',
+'QCDEStyle*' => 'qt_QCDEStyle*',
+'QCOORD&' => 'short',
+'QCOORD' => 'short',
+'QCOORD*' => 'short*',
+'QCString&' => 'qt_QCString*' ,
+'QCString' => 'qt_QCString*' ,
+'QCString*' => 'qt_QCString*' ,
+'QCStringLess*' => 'qt_QCStringLess*' ,
+'QCStringList' => 'kde_QCStringList*' ,
+'QCache*' => 'qt_QCache*',
+'QCacheIterator*' => 'qt_QCacheIterator*',
+'QCanvas*' => 'qt_QCanvas*' ,
+'QCanvasEllipse*' => 'qt_QCanvasEllipse*',
+'QCanvasItem*' => 'qt_QCanvasItem*' ,
+'QCanvasItemList' => 'qt_QCanvasItemList*' ,
+'QCanvasItemList*' => 'qt_QCanvasItemList*',
+'QCanvasLine*' => 'qt_QCanvasLine*',
+'QCanvasPixmap*' => 'qt_QCanvasPixmap*' ,
+'QCanvasPixmapArray*' => 'qt_QCanvasPixmapArray*' ,
+'QCanvasPolygon*' => 'qt_QCanvasPolygon*',
+'QCanvasPolygonalItem*' => 'qt_QCanvasPolygonalItem*',
+'QCanvasRectangle*' => 'qt_QCanvasRectangle*',
+'QCanvasSpline*' => 'qt_QCanvasSpline*',
+'QCanvasSprite*' => 'qt_QCanvasSprite*',
+'QCanvasText*' => 'qt_QCanvasText*',
+'QCanvasView*' => 'qt_QCanvasView*' ,
+'QChain*' => 'qt_QChain*' ,
+'QChar::Category' => 'int' ,
+'QChar::Decomposition' => 'int' ,
+'QChar::Direction' => 'int' ,
+'QChar::Joining' => 'int' ,
+'QCharRef&' => 'qt_QCharRef*' ,
+'QCharRef' => 'qt_QCharRef*' ,
+'QCharRef*' => 'qt_QCharRef*',
+'QCheckBox*' => 'qt_QCheckBox*',
+'QCheckListItem*' => 'qt_QCheckListItem*',
+'QCheckTableItem*' => 'qt_QCheckTableItem*',
+'QChildEvent*' => 'qt_QChildEvent*' ,
+'QClassInfo*' => 'qt_QClassInfo*' ,
+'QCleanupHandler*' => 'qt_QCleanupHandler*',
+'QClipboard*' => 'qt_QClipboard*',
+'QCloseEvent*' => 'qt_QCloseEvent*' ,
+'QCollection&' => 'qt_QCollection*' ,
+'QCollection*' => 'qt_QCollection*',
+'QCollection::Item&' => 'void*' ,
+'QCollection::Item' => 'void*' ,
+'QColor &' => 'qt_QColor*',
+'QColor&' => 'qt_QColor*',
+'QColor&fillColor::white' => 'int' ,
+'QColor&linkColor::blue' => 'int' ,
+'QColor' => 'qt_QColor*',
+'QColor*' => 'qt_QColor*' ,
+'QColorDialog*' => 'qt_QColorDialog*',
+'QColorDrag*' => 'qt_QColorDrag*',
+'QColorGroup&' => 'qt_QColorGroup*',
+'QColorGroup' => 'qt_QColorGroup*' ,
+'QColorGroup*' => 'qt_QColorGroup*' ,
+'QColorGroup::ColorRole' => 'int' ,
+'QComboBox*' => 'qt_QComboBox*' ,
+'QComboBox::Policy' => 'int' ,
+'QComboBox::Policypolicy::AtBottom' => 'int' ,
+'QComboTableItem*' => 'qt_QComboTableItem*',
+'QCommonStyle*' => 'qt_QCommonStyle*',
+'QCompactStyle*' => 'qt_QCompactStyle*',
+'QComponentFactory*' => 'qt_QComponentFactory*',
+'QComponentFactoryInterface*' => 'qt_QComponentFactoryInterface*',
+'QComponentInterface*' => 'qt_QComponentInterface*',
+'QComponentRegistration*' => 'qt_QComponentRegistration*',
+'QComponentServerInterface*' => 'qt_QComponentServerInterface*',
+'QConfigDB*' => 'qt_QConfigDB*' ,
+'QConfigDB*' => 'qt_QConfigDB*' ,
+'QConnection*' => 'qt_QConnection*',
+'QConnectionList&' => 'qt_QConnectionList*' ,
+'QConnectionList*' => 'qt_QConnectionList*' ,
+'QConnectionListIt&' => 'qt_QConnectionListIt*' ,
+'QConnectionListIt*' => 'qt_QConnectionListIt*',
+'QConstString' => 'qt_QConstString*',
+'QConstString*' => 'qt_QConstString*',
+'QContextMenuEvent*' => 'qt_QContextMenuEvent*',
+'QCursor&' => 'qt_QCursor*',
+'QCursor' => 'qt_QCursor*' ,
+'QCursor*' => 'qt_QCursor*',
+'QCustomEvent*' => 'qt_QCustomEvent*' ,
+'QCustomMenuItem*' => 'qt_QCustomMenuItem*' ,
+'QDOM_NodeListPrivate*' => 'void*' ,
+'QDOM_NodePrivate*' => 'void*' ,
+'QDataBrowser*' => 'qt_QDataBrowser*',
+'QDataPump*' => 'qt_QDataPump*',
+'QDataSink*' => 'qt_QDataSink*' ,
+'QDataSource*' => 'qt_QDataSource*' ,
+'QDataStream&' => 'qt_QDataStream*',
+'QDataStream*' => 'qt_QDataStream*' ,
+'QDataTable*' => 'qt_QDataTable*',
+'QDataView*' => 'qt_QDataView*',
+'QDate &' => 'qt_QDate*',
+'QDate date()' => 'qt_QDate*',
+'QDate&' => 'qt_QDate*',
+'QDate' => 'qt_QDate*',
+'QDate*' => 'qt_QDate*',
+'QDateEdit*' => 'qt_QDateEdit*',
+'QDateTime&' => 'qt_QDateTime*',
+'QDateTime' => 'qt_QDateTime*',
+'QDateTime*' => 'qt_QDateTime*' ,
+'QDateTimeEdit*' => 'qt_QDateTimeEdit*',
+'QDateTimeEditBase*' => 'qt_QDateTimeEditBase*',
+'QDesktopWidget*' => 'qt_QDesktopWidget*',
+'QDial*' => 'qt_QDial*',
+'QDialog*' => 'qt_QDialog*',
+'QDict*' => 'qt_QDict*',
+'QDictIterator*' => 'qt_QDictIterator*',
+'QDir&' => 'qt_QDir*',
+'QDir' => 'qt_QDir*',
+'QDir*' => 'qt_QDir*',
+'QDir::SortSpec&' => 'int' ,
+'QDir::SortSpec' => 'int' ,
+'QDirSortItem*' => 'qt_QDirSortItem*',
+'QDiskFont*' => 'qt_QDiskFont*',
+'QDispatchInterface*' => 'qt_QDispatchInterface*',
+'QDns*' => 'qt_QDns*',
+'QDnsSocket*' => 'qt_QDnsSocket*',
+'QDockArea*' => 'qt_QDockArea*',
+'QDockAreaLayout*' => 'qt_QDockAreaLayout*',
+'QDockWindow*' => 'qt_QDockWindow*',
+'QDomAttr&' => 'qt_QDomAttr*' ,
+'QDomAttr' => 'qt_QDomAttr*' ,
+'QDomAttr*' => 'qt_QDomAttr*',
+'QDomCDATASection&' => 'qt_QDomCDATASection*' ,
+'QDomCDATASection' => 'qt_QDomCDATASection*' ,
+'QDomCDATASection*' => 'qt_QDomCDATASection*',
+'QDomCharacterData&' => 'qt_QDomCharacterData*' ,
+'QDomCharacterData' => 'qt_QDomCharacterData*' ,
+'QDomCharacterData*' => 'qt_QDomCharacterData*',
+'QDomComment&' => 'qt_QDomComment*' ,
+'QDomComment' => 'qt_QDomComment*' ,
+'QDomComment*' => 'qt_QDomComment*',
+'QDomDocument&' => 'qt_QDomDocument*' ,
+'QDomDocument' => 'qt_QDomDocument*' ,
+'QDomDocument*' => 'qt_QDomDocument*',
+'QDomDocumentFragment&' => 'qt_QDomDocumentFragment*' ,
+'QDomDocumentFragment' => 'qt_QDomDocumentFragment*' ,
+'QDomDocumentFragment*' => 'qt_QDomDocumentFragment*',
+'QDomDocumentType&' => 'qt_QDomDocumentType*' ,
+'QDomDocumentType' => 'qt_QDomDocumentType*' ,
+'QDomDocumentType*' => 'qt_QDomDocumentType*',
+'QDomElement&' => 'qt_QDomElement*' ,
+'QDomElement' => 'qt_QDomElement*' ,
+'QDomElement*' => 'qt_QDomElement*',
+'QDomEntity&' => 'qt_QDomEntity*' ,
+'QDomEntity' => 'qt_QDomEntity*' ,
+'QDomEntity*' => 'qt_QDomEntity*',
+'QDomEntityReference&' => 'qt_QDomEntityReference*' ,
+'QDomEntityReference' => 'qt_QDomEntityReference*' ,
+'QDomEntityReference*' => 'qt_QDomEntityReference*',
+'QDomImplementation&' => 'qt_QDomImplementation*' ,
+'QDomImplementation' => 'qt_QDomImplementation*' ,
+'QDomImplementation*' => 'qt_QDomImplementation*',
+'QDomNamedNodeMap&' => 'qt_QDomNamedNodeMap*' ,
+'QDomNamedNodeMap' => 'qt_QDomNamedNodeMap*' ,
+'QDomNamedNodeMap*' => 'qt_QDomNamedNodeMap*',
+'QDomNode&' => 'qt_QDomNode*' ,
+'QDomNode' => 'qt_QDomNode*' ,
+'QDomNode*' => 'qt_QDomNode*',
+'QDomNode::NodeType' => 'int',
+'QDomNodeList&' => 'qt_QDomNodeList*' ,
+'QDomNodeList' => 'qt_QDomNodeList*' ,
+'QDomNodeList*' => 'qt_QDomNodeList*',
+'QDomNodePrivate*' => 'qt_QDomNodePrivate*',
+'QDomNotation&' => 'qt_QDomNotation*' ,
+'QDomNotation' => 'qt_QDomNotation*' ,
+'QDomNotation*' => 'qt_QDomNotation*',
+'QDomProcessingInstruction&' => 'qt_QDomProcessingInstruction*' ,
+'QDomProcessingInstruction' => 'qt_QDomProcessingInstruction*' ,
+'QDomProcessingInstruction*' => 'qt_QDomProcessingInstruction*',
+'QDomText&' => 'qt_QDomText*' ,
+'QDomText' => 'qt_QDomText*' ,
+'QDomText*' => 'qt_QDomText*',
+'QDoubleValidator*' => 'qt_QDoubleValidator*',
+'QDragEnterEvent*' => 'qt_QDragEnterEvent*' ,
+'QDragLeaveEvent*' => 'qt_QDragLeaveEvent*' ,
+'QDragManager*' => 'qt_QDragManager*',
+'QDragMoveEvent*' => 'qt_QDragMoveEvent*' ,
+'QDragObject*' => 'qt_QDragObject*' ,
+'QDragResponseEvent*' => 'qt_QDragResponseEvent*',
+'QDropEvent*' => 'qt_QDropEvent*' ,
+'QDropSite*' => 'qt_QDropSite*',
+'QEditorFactory*' => 'qt_QEditorFactory*',
+'QErrorMessage*' => 'qt_QErrorMessage*',
+'QEucJpCodec*' => 'qt_QEucJpCodec*',
+'QEucKrCodec*' => 'qt_QEucKrCodec*',
+'QEvent*' => 'qt_QEvent*',
+'QEventLoop::ProcessEventsFlags' => 'uint',
+'QFeatureListInterface*' => 'qt_QFeatureListInterface*',
+'QFile&' => 'qt_QFile*',
+'QFile*' => 'qt_QFile*' ,
+'QFileDialog*' => 'qt_QFileDialog*',
+'QFileIconProvider*' => 'qt_QFileIconProvider*' ,
+'QFileInfo&' => 'qt_QFileInfo*',
+'QFileInfo*' => 'qt_QFileInfo*',
+'QFileInfoList*' => 'qt_QFileInfoList*' ,
+'QFilePreview*' => 'qt_QFilePreview*' ,
+'QFocusData*' => 'qt_QFocusData*' ,
+'QFocusEvent*' => 'qt_QFocusEvent*' ,
+'QFont&' => 'qt_QFont*',
+'QFont' => 'qt_QFont*',
+'QFont*' => 'qt_QFont*',
+'QFont::CharSet' => 'int',
+'QFont::CharSetcharset::Unicode' => 'int' ,
+'QFont::StyleHint' => 'int',
+'QFontData&' => 'qt_QFontData*' ,
+'QFontDatabase*' => 'qt_QFontDatabase*',
+'QFontDialog*' => 'qt_QFontDialog*',
+'QFontInfo&' => 'qt_QFontInfo*',
+'QFontInfo' => 'qt_QFontInfo*',
+'QFontInfo*' => 'qt_QFontInfo*',
+'QFontMetrics&' => 'qt_QFontMetrics*',
+'QFontMetrics' => 'qt_QFontMetrics*',
+'QFontMetrics*' => 'qt_QFontMetrics*',
+'QFrame*' => 'qt_QFrame*' ,
+'QFtp*' => 'qt_QFtp*',
+'QGArray&' => 'qt_QGArray*' ,
+'QGArray*' => 'qt_QGArray*',
+'QGCache&' => 'qt_QGCache*' ,
+'QGCache*' => 'qt_QGCache*',
+'QGCacheIterator&' => 'qt_QGCacheIterator*' ,
+'QGCacheIterator*' => 'qt_QGCacheIterator*',
+'QGDict&' => 'qt_QGDict*' ,
+'QGDict*' => 'qt_QGDict*',
+'QGDictIterator&' => 'qt_QGDictIterator*' ,
+'QGDictIterator*' => 'qt_QGDictIterator*',
+'QGL*' => 'qt_QGL*',
+'QGLColormap&' => 'qt_QGLColormap*',
+'QGLColormap*' => 'qt_QGLColormap*',
+'QGLContext*' => 'qt_QGLContext*' ,
+'QGLFormat&' => 'qt_QGLFormat*' ,
+'QGLFormat' => 'qt_QGLFormat*' ,
+'QGLFormat*' => 'qt_QGLFormat*',
+'QGLWidget*' => 'qt_QGLWidget*' ,
+'QGLayoutIterator*' => 'qt_QGLayoutIterator*' ,
+'QGListIterator&' => 'qt_QGListIterator*' ,
+'QGListIterator*' => 'qt_QGListIterator*',
+'QGPlugin*' => 'qt_QGPlugin*',
+'QGPluginManager*' => 'qt_QGPluginManager*',
+'QGbkCodec*' => 'qt_QGbkCodec*',
+'QGfx*' => 'qt_QGfx*' ,
+'QGrid*' => 'qt_QGrid*' ,
+'QGrid::Direction' => 'int' ,
+'QGridLayout*' => 'qt_QGridLayout*',
+'QGridView*' => 'qt_QGridView*',
+'QGroupBox*' => 'qt_QGroupBox*',
+'QGuardedPtr*' => 'qt_QGuardedPtr*',
+'QGuardedPtrPrivate*' => 'qt_QGuardedPtrPrivate*',
+'QHBox*' => 'qt_QHBox*' ,
+'QHBoxLayout*' => 'qt_QHBoxLayout*' ,
+'QHButtonGroup*' => 'qt_QHButtonGroup*',
+'QHGroupBox*' => 'qt_QHGroupBox*',
+'QHeader*' => 'qt_QHeader*',
+'QHebrewCodec*' => 'qt_QHebrewCodec*',
+'QHideEvent*' => 'qt_QHideEvent*' ,
+'QHostAddress&' => 'qt_QHostAddress*' ,
+'QHostAddress' => 'qt_QHostAddress*' ,
+'QHostAddress*' => 'qt_QHostAddress*' ,
+'QHttp*' => 'qt_QHttp*',
+'QIMEvent*' => 'qt_QIMEvent*',
+'QIODevice*' => 'qt_QIODevice*',
+'QIODevice::Offset' => 'int',
+'QIODeviceSource*' => 'qt_QIODeviceSource*',
+'QIOManager*' => 'qt_QIOManager*',
+'QIOWatch*' => 'qt_QIOWatch*',
+'QIconDrag*' => 'qt_QIconDrag*',
+'QIconDragItem&' => 'qt_QIconDragItem*' ,
+'QIconDragItem*' => 'qt_QIconDragItem*',
+'QIconSet&' => 'qt_QIconSet*' ,
+'QIconSet' => 'qt_QIconSet*' ,
+'QIconSet*' => 'qt_QIconSet*' ,
+'QIconView*' => 'qt_QIconView*' ,
+'QIconViewItem*' => 'qt_QIconViewItem*' ,
+'QImage&' => 'qt_QImage*',
+'QImage' => 'qt_QImage*',
+'QImage*' => 'qt_QImage*' ,
+'QImageConsumer*' => 'qt_QImageConsumer*' ,
+'QImageData*' => 'qt_QImageData*',
+'QImageDecoder*' => 'qt_QImageDecoder*',
+'QImageDrag*' => 'qt_QImageDrag*',
+'QImageFormat*' => 'qt_QImageFormat*' ,
+'QImageFormatInterface*' => 'qt_QImageFormatInterface*',
+'QImageFormatPlugin*' => 'qt_QImageFormatPlugin*',
+'QImageFormatType*' => 'qt_QImageFormatType*' ,
+'QImageIO*' => 'qt_QImageIO*',
+'QImageTextKeyLang&' => 'qt_QImageTextKeyLang*' ,
+'QImageTextKeyLang*' => 'qt_QImageTextKeyLang*',
+'QInputDialog*' => 'qt_QInputDialog*',
+'QIntBucket*' => 'qt_QIntBucket*',
+'QIntCache*' => 'qt_QIntCache*',
+'QIntCacheIterator*' => 'qt_QIntCacheIterator*',
+'QIntDict*' => 'qt_QIntDict*',
+'QIntDictIterator*' => 'qt_QIntDictIterator*',
+'QIntValidator*' => 'qt_QIntValidator*',
+'QInterfaceListInterface*' => 'qt_QInterfaceListInterface*',
+'QInterfacePtr*' => 'qt_QInterfacePtr*',
+'QInterlaceStyle*' => 'qt_QInterlaceStyle*',
+'QInternal*' => 'qt_QInternal*',
+'QJisCodec*' => 'qt_QJisCodec*',
+'QJpUnicodeConv*' => 'qt_QJpUnicodeConv*' ,
+'QKeyEvent*' => 'qt_QKeyEvent*' ,
+'QKeySequence&' => 'qt_QKeySequence*',
+'QKeySequence' => 'qt_QKeySequence*',
+'QKeySequence*' => 'qt_QKeySequence*',
+'QKoi8Codec*' => 'qt_QKoi8Codec*',
+'QLCDNumber*' => 'qt_QLCDNumber*',
+'QLNode*' => 'qt_QLNode*' ,
+'QLabel*' => 'qt_QLabel*',
+'QLayout*' => 'qt_QLayout*',
+'QLayoutItem*' => 'qt_QLayoutItem*' ,
+'QLayoutIterator&' => 'qt_QLayoutIterator*' ,
+'QLayoutIterator' => 'qt_QLayoutIterator*' ,
+'QLayoutIterator*' => 'qt_QLayoutIterator*',
+'QLibrary*' => 'qt_QLibrary*',
+'QLibrary::Policy' => 'int',
+'QLibraryInterface*' => 'qt_QLibraryInterface*',
+'QLineEdit*' => 'qt_QLineEdit*' ,
+'QLineEdit::EchoMode' => 'int' ,
+'QList*' => 'qt_QList*',
+'QListBox*' => 'qt_QListBox*',
+'QListBoxItem*' => 'qt_QListBoxItem*',
+'QListBoxPixmap*' => 'qt_QListBoxPixmap*',
+'QListBoxText*' => 'qt_QListBoxText*',
+'QListIterator*' => 'qt_QListIterator*',
+'QListView*' => 'qt_QListView*',
+'QListViewItem*&' => 'qt_QListViewItem*',
+'QListViewItem*' => 'qt_QListViewItem*',
+'QListViewItemIterator&' => 'qt_QListViewItemIterator*' ,
+'QListViewItemIterator' => 'qt_QListViewItemIterator*' ,
+'QListViewItemIterator*' => 'qt_QListViewItemIterator*',
+'QLocalFs*' => 'qt_QLocalFs*',
+'QMCPI*' => 'qt_QMCPI*',
+'QMainWindow*' => 'qt_QMainWindow*' ,
+'QMainWindow::ToolBarDock' => 'int',
+'QMainWindow::ToolBarDock::Top' => 'int' ,
+'QMap&' => 'qt_QMap*' ,
+'QMap*' => 'qt_QMap*',
+'QMapConstIterator*' => 'qt_QMapConstIterator*',
+'QMapIterator*' => 'qt_QMapIterator*',
+'QMapNode*' => 'qt_QMapNode*',
+'QMapNodeBase*&' => 'qt_QMapNodeBase*' ,
+'QMapNodeBase*' => 'qt_QMapNodeBase*' ,
+'QMapPrivate*' => 'qt_QMapPrivate*',
+'QMapPrivateBase*' => 'qt_QMapPrivateBase*' ,
+'QMemArray*' => 'qt_QMemArray*',
+'QMember' => 'qt_QMember*' ,
+'QMember*' => 'qt_QMember*' ,
+'QMenuBar*' => 'qt_QMenuBar*',
+'QMenuData*' => 'qt_QMenuData*',
+'QMenuItem*' => 'qt_QMenuItem*',
+'QMessageBox*' => 'qt_QMessageBox*',
+'QMetaData*' => 'qt_QMetaData*' ,
+'QMetaData::Access*' => 'int*' ,
+'QMetaEnum*' => 'qt_QMetaEnum*' ,
+'QMetaEnum::Item*' => 'int*' ,
+'QMetaObject*&' => 'qt_QMetaObject*',
+'QMetaObject*' => 'qt_QMetaObject*',
+'QMetaObjectCleanUp*' => 'qt_QMetaObjectCleanUp*',
+'QMetaObjectInit*' => 'qt_QMetaObjectInit*',
+'QMetaProperty*' => 'qt_QMetaProperty*' ,
+'QMimeSource*' => 'qt_QMimeSource*' ,
+'QMimeSourceFactory*' => 'qt_QMimeSourceFactory*' ,
+'QMotifPlusStyle*' => 'qt_QMotifPlusStyle*',
+'QMotifStyle*' => 'qt_QMotifStyle*',
+'QMouseEvent*' => 'qt_QMouseEvent*' ,
+'QMoveEvent*' => 'qt_QMoveEvent*' ,
+'QMovie&' => 'qt_QMovie*',
+'QMovie*' => 'qt_QMovie*',
+'QMultiLineEdit*' => 'qt_QMultiLineEdit*',
+'QMultiLineEditRow*' => 'qt_QMultiLineEditRow*',
+'QMutex*' => 'qt_QMutex*',
+'QNPInstance*' => 'qt_QNPInstance*',
+'QNPStream*' => 'qt_QNPStream*',
+'QNPWidget*' => 'qt_QNPWidget*',
+'QNPlugin*' => 'qt_QNPlugin*',
+'QNetworkOperation*' => 'qt_QNetworkOperation*' ,
+'QNetworkProtocol*' => 'qt_QNetworkProtocol*' ,
+'QNetworkProtocol::Operation' => 'int' ,
+'QNetworkProtocol::State' => 'int' ,
+'QNetworkProtocolFactory*' => 'qt_QNetworkProtocolFactory*',
+'QNetworkProtocolFactoryBase*' => 'qt_QNetworkProtocolFactoryBase*' ,
+'QObject*' => 'qt_QObject*',
+'QObjectCleanupHandler*' => 'qt_QObjectCleanupHandler*',
+'QObjectDictionary&' => 'qt_QObjectDictionary*' ,
+'QObjectDictionary*' => 'qt_QObjectDictionary*',
+'QObjectInterface*' => 'qt_QObjectInterface*',
+'QObjectList&' => 'qt_QObjectList*' ,
+'QObjectList*' => 'qt_QObjectList*',
+'QObjectListIt&' => 'qt_QObjectListIt*' ,
+'QObjectListIt*' => 'qt_QObjectListIt*',
+'QPNGImagePacker*' => 'qt_QPNGImagePacker*',
+'QPNGImageWriter*' => 'qt_QPNGImageWriter*',
+'QPaintDevice*' => 'qt_QPaintDevice*',
+'QPaintDeviceMetrics*' => 'qt_QPaintDeviceMetrics*',
+'QPaintDeviceX11Data*' => 'qt_QPaintDeviceX11Data*' ,
+'QPaintEvent*' => 'qt_QPaintEvent*' ,
+'QPainter&' => 'qt_QPainter*' ,
+'QPainter*' => 'qt_QPainter*',
+'QPair*' => 'qt_QPair*',
+'QPalData*' => 'qt_QPalData*',
+'QPalette&' => 'qt_QPalette*',
+'QPalette' => 'qt_QPalette*',
+'QPalette*' => 'qt_QPalette*',
+'QPen&' => 'qt_QPen*',
+'QPen' => 'qt_QPen*' ,
+'QPen*' => 'qt_QPen*',
+'QPenData*' => 'qt_QPenData*',
+'QPicture&' => 'qt_QPicture*',
+'QPicture' => 'qt_QPicture*',
+'QPicture*' => 'qt_QPicture*',
+'QPicturePrivate*' => 'qt_QPicturePrivate*',
+'QPixmap& pixmap()' => 'kde_QPixmap*',
+'QPixmap&' => 'qt_QPixmap*',
+'QPixmap' => 'qt_QPixmap*',
+'QPixmap*' => 'qt_QPixmap*',
+'QPixmap::Optimization' => 'int' ,
+'QPixmap::Optimization' => 'int',
+'QPixmap::Optimization::DefaultOptim' => 'int' ,
+'QPixmapCache*' => 'qt_QPixmapCache*',
+'QPixmapData*' => 'qt_QPixmapData*',
+'QPlatinumStyle*' => 'qt_QPlatinumStyle*',
+'QPluginManager*' => 'qt_QPluginManager*',
+'QPoint&' => 'qt_QPoint*',
+'QPoint&pos()' => 'int' ,
+'QPoint&pos::pos()' => 'int' ,
+'QPoint' => 'qt_QPoint*',
+'QPoint*' => 'qt_QPoint*' ,
+'QPointArray&' => 'qt_QPointArray*',
+'QPointArray' => 'qt_QPointArray*',
+'QPointArray*' => 'qt_QPointArray*',
+'QPointVal&' => 'qt_QPointVal*' ,
+'QPointVal' => 'qt_QPointVal*' ,
+'QPolygonScanner*' => 'qt_QPolygonScanner*',
+'QPopupMenu*' => 'qt_QPopupMenu*',
+'QPrintDialog*' => 'qt_QPrintDialog*',
+'QPrinter*' => 'qt_QPrinter*' ,
+'QPrinter::PrinterMode' => 'int',
+'QProcess*' => 'qt_QProcess*',
+'QProgressBar*' => 'qt_QProgressBar*',
+'QProgressDialog*' => 'qt_QProgressDialog*',
+'QPtrBucket*' => 'qt_QPtrBucket*',
+'QPtrCollection&' => 'qt_QPtrCollection*',
+'QPtrCollection*' => 'qt_QPtrCollection*',
+'QPtrDict*' => 'qt_QPtrDict*',
+'QPtrDictIterator*' => 'qt_QPtrDictIterator*',
+'QPtrList*' => 'qt_QPtrList*',
+'QPtrListIterator*' => 'qt_QPtrListIterator*',
+'QPtrQueue*' => 'qt_QPtrQueue*',
+'QPtrStack*' => 'qt_QPtrStack*',
+'QPtrVector*' => 'qt_QPtrVector*',
+'QPushButton*' => 'qt_QPushButton*',
+'QQueue*' => 'qt_QQueue*',
+'QRESULT' => 'long',
+'QRadioButton*' => 'qt_QRadioButton*',
+'QRangeControl*' => 'qt_QRangeControl*',
+'QRect&' => 'qt_QRect*',
+'QRect' => 'qt_QRect*',
+'QRect*' => 'qt_QRect*',
+'QRegExp&' => 'qt_QRegExp*',
+'QRegExp*' => 'qt_QRegExp*',
+'QRegExpValidator*' => 'qt_QRegExpValidator*',
+'QRegion&' => 'qt_QRegion*',
+'QRegion' => 'qt_QRegion*',
+'QRegion*' => 'qt_QRegion*',
+'QRegionData*' => 'qt_QRegionData*',
+'QRemoteFactory*' => 'qt_QRemoteFactory*',
+'QRemotePlugin*' => 'qt_QRemotePlugin*',
+'QResizeEvent*' => 'qt_QResizeEvent*' ,
+'QRgb' => 'unsigned int',
+'QRgb*' => 'int*',
+'QRichText&' => 'qt_QRichText*' ,
+'QSGIStyle*' => 'qt_QSGIStyle*',
+'QScrollBar&' => 'qt_QScrollBar*' ,
+'QScrollBar*' => 'qt_QScrollBar*' ,
+'QScrollView*' => 'qt_QScrollView*',
+'QSemaphore*' => 'qt_QSemaphore*',
+'QSemiModal*' => 'qt_QSemiModal*',
+'QSenderObject*' => 'qt_QSenderObject*',
+'QServerSocket*' => 'qt_QServerSocket*',
+'QSessionManager&' => 'qt_QSessionManager*' ,
+'QSessionManager*' => 'qt_QSessionManager*',
+'QSettings*' => 'qt_QSettings*',
+'QShared*' => 'qt_QShared*',
+'QShowEvent*' => 'qt_QShowEvent*' ,
+'QSignal*' => 'qt_QSignal*',
+'QSignalDict&' => 'qt_QSignalDict*' ,
+'QSignalDict*' => 'qt_QSignalDict*',
+'QSignalDictIt&' => 'qt_QSignalDictIt*' ,
+'QSignalDictIt*' => 'qt_QSignalDictIt*',
+'QSignalMapper*' => 'qt_QSignalMapper*',
+'QSignalVec&' => 'qt_QSignalVec*',
+'QSignalVec*' => 'qt_QSignalVec*',
+'QSimpleRichText*' => 'qt_QSimpleRichText*',
+'QSize&' => 'qt_QSize*',
+'QSize' => 'qt_QSize*',
+'QSize*' => 'qt_QSize*' ,
+'QSizeGrip*' => 'qt_QSizeGrip*',
+'QSizePolicy&' => 'qt_QSizePolicy*' ,
+'QSizePolicy' => 'qt_QSizePolicy*' ,
+'QSizePolicy*' => 'qt_QSizePolicy*',
+'QSizePolicy::ExpandData' => 'int' ,
+'QSizePolicy::SizeTypehData::Minimum' => 'int' ,
+'QSizePolicy::SizeTypevData::Minimum' => 'int' ,
+'QSjisCodec*' => 'qt_QSjisCodec*',
+'QSlider*' => 'qt_QSlider*',
+'QSmartPtr&' => 'qt_QSmartPtr*' ,
+'QSmartPtr*' => 'qt_QSmartPtr*',
+'QSmartPtrPrivate*' => 'qt_QSmartPtrPrivate*',
+'QSocket*' => 'qt_QSocket*',
+'QSocketDevice*' => 'qt_QSocketDevice*' ,
+'QSocketNotifier*' => 'qt_QSocketNotifier*',
+'QSocketNotifier::Type' => 'int',
+'QSortedList*' => 'qt_QSortedList*',
+'QSound*' => 'qt_QSound*',
+'QSpacerItem*' => 'qt_QSpacerItem*' ,
+'QSpinBox*' => 'qt_QSpinBox*',
+'QSpinWidget*' => 'qt_QSpinWidget*',
+'QSplitter*' => 'qt_QSplitter*',
+'QSql*' => 'qt_QSql*',
+'QSql::Confirm' => 'int',
+'QSql::Op' => 'int',
+'QSqlCursor&' => 'qt_QSqlCursor*',
+'QSqlCursor' => 'qt_QSqlCursor*',
+'QSqlCursor*' => 'qt_QSqlCursor*',
+'QSqlDatabase*' => 'qt_QSqlDatabase*',
+'QSqlDriver*' => 'qt_QSqlDriver*',
+'QSqlDriverCreator*' => 'qt_QSqlDriverCreator*',
+'QSqlDriverCreatorBase*' => 'qt_QSqlDriverCreatorBase*',
+'QSqlDriverFactoryInterface*' => 'qt_QSqlDriverFactoryInterface*',
+'QSqlDriverPlugin*' => 'qt_QSqlDriverPlugin*',
+'QSqlEditorFactory*' => 'qt_QSqlEditorFactory*',
+'QSqlError&' => 'qt_QSqlError*',
+'QSqlError' => 'qt_QSqlError*',
+'QSqlError*' => 'qt_QSqlError*',
+'QSqlField&' => 'qt_QSqlField*',
+'QSqlField' => 'qt_QSqlField*',
+'QSqlField*' => 'qt_QSqlField*',
+'QSqlFieldInfo&' => 'qt_QSqlFieldInfo*',
+'QSqlFieldInfo*' => 'qt_QSqlFieldInfo*',
+'QSqlForm' => 'qt_QSqlForm*',
+'QSqlForm*' => 'qt_QSqlForm*',
+'QSqlIndex&' => 'qt_QSqlIndex*',
+'QSqlIndex' => 'qt_QSqlIndex*',
+'QSqlIndex*' => 'qt_QSqlIndex*',
+'QSqlPropertyMap*' => 'qt_QSqlPropertyMap*',
+'QSqlQuery&' => 'qt_QSqlQuery*',
+'QSqlQuery' => 'qt_QSqlQuery*',
+'QSqlQuery*' => 'qt_QSqlQuery*',
+'QSqlRecord&' => 'qt_QSqlRecord*',
+'QSqlRecord' => 'qt_QSqlRecord*',
+'QSqlRecord*' => 'qt_QSqlRecord*',
+'QSqlRecordInfo&' => 'qt_QSqlRecordInfo*',
+'QSqlRecordInfo' => 'qt_QSqlRecordInfo*',
+'QSqlRecordInfo*' => 'qt_QSqlRecordInfo*',
+'QSqlRecordPrivate*' => 'qt_QSqlRecordPrivate*',
+'QSqlRecordShared*' => 'qt_QSqlRecordShared*',
+'QSqlResult' => 'qt_QSqlResult*',
+'QSqlResult*' => 'qt_QSqlResult*',
+'QSqlResultShared*' => 'qt_QSqlResultShared*',
+'QStack*' => 'qt_QStack*',
+'QStatusBar*' => 'qt_QStatusBar*' ,
+'QStoredDrag*' => 'qt_QStoredDrag*',
+'QStrIList' => 'kde_QStrIList',
+'QStrIList*' => 'qt_QStrIList*',
+'QStrIVec*' => 'qt_QStrIVec*',
+'QStrList&' => 'qt_QStrList*',
+'QStrList' => 'qt_QStrList*',
+'QStrList*' => 'qt_QStrList*',
+'QStrListIterator*' => 'qt_QStrListIterator*',
+'QStrVec*' => 'qt_QStrVec*',
+'QString&' => 'qt_QString*',
+'QString&::null' => 'qt_QString*' ,
+'QString&button0Text::null' => 'qt_QString*' ,
+'QString&button1Text::null' => 'qt_QString*' ,
+'QString&button2Text::null' => 'qt_QString*' ,
+'QString&buttonText::null' => 'qt_QString*' ,
+'QString&caption::null' => 'qt_QString*' ,
+'QString&charSet::null' => 'qt_QString*' ,
+'QString&context::null' => 'qt_QString*' ,
+'QString&defValue::null' => 'qt_QString*' ,
+'QString&dir::null' => 'qt_QString*' ,
+'QString&directory::null' => 'qt_QString*' ,
+'QString&filter::null' => 'qt_QString*' ,
+'QString&initially::null' => 'qt_QString*' ,
+'QString&location::null' => 'qt_QString*' ,
+'QString&n::null' => 'qt_QString*' ,
+'QString&nameFilter::null' => 'qt_QString*' ,
+'QString&noButtonText::null' => 'qt_QString*' ,
+'QString&search_delimiters::null' => 'qt_QString*' ,
+'QString&style::null' => 'qt_QString*' ,
+'QString&suffix::null' => 'qt_QString*' ,
+'QString&text::null' => 'qt_QString*' ,
+'QString&text_::null' => 'qt_QString*' ,
+'QString&translation::null' => 'qt_QString*' ,
+'QString&yesButtonText::null' => 'qt_QString*' ,
+'QString' => 'qt_QString*',
+'QString*' => 'qt_QString*' ,
+'QString::null' => 'qt_QString_null()' ,
+'QStringBucket*' => 'qt_QStringBucket*',
+'QStringData*' => 'qt_QStringData*',
+'QStringList&' => 'qt_QStringList*' ,
+'QStringList' => 'qt_QStringList*' ,
+'QStringList*' => 'qt_QStringList*' ,
+'QStringcharSetName::null' => 'qt_QStringcharSetName*' ,
+'QStyle&' => 'qt_QStyle*' ,
+'QStyle*' => 'qt_QStyle*' ,
+'QStyle::ScrollControl' => 'int' ,
+'QStyle::StylePixmap' => 'int',
+'QStyle::SubControl' => 'int',
+'QStyle::SubRect' => 'int',
+'QStyleFactory*' => 'qt_QStyleFactory*',
+'QStyleFactoryInterface*' => 'qt_QStyleFactoryInterface*',
+'QStyleOption&' => 'int',
+'QStyleOption' => 'int',
+'QStyleOption*' => 'int*',
+'QStylePlugin*' => 'qt_QStylePlugin*',
+'QStyleSheet*' => 'qt_QStyleSheet*' ,
+'QStyleSheetItem&' => 'qt_QStyleSheetItem*' ,
+'QStyleSheetItem*' => 'qt_QStyleSheetItem*' ,
+'QStyleSheetItem::DisplayMode*' => 'int',
+'QStyleSheetItem::ListStyle*' => 'int',
+'QStyleSheetItem::WhiteSpaceMode' => 'int',
+'QTSCIICodec*' => 'qt_QTSCIICodec*',
+'QTSMFI' => 'int' ,
+'QTab*' => 'qt_QTab*',
+'QTabBar*' => 'qt_QTabBar*' ,
+'QTabBar::Shape' => 'int' ,
+'QTabDialog*' => 'qt_QTabDialog*',
+'QTabWidget*' => 'qt_QTabWidget*',
+'QTable*' => 'qt_QTable*' ,
+'QTableHeader*' => 'qt_QTableHeader*',
+'QTableItem*' => 'qt_QTableItem*' ,
+'QTableSelection&' => 'qt_QTableSelection*' ,
+'QTableSelection' => 'qt_QTableSelection*' ,
+'QTableSelection*' => 'qt_QTableSelection*',
+'QTableView*' => 'qt_QTableView*',
+'QTabletEvent*' => 'qt_QTabletEvent*',
+'QTextBrowser*' => 'qt_QTextBrowser*',
+'QTextCodec*' => 'qt_QTextCodec*' ,
+'QTextCodecFactory*' => 'qt_QTextCodecFactory*',
+'QTextCodecFactoryInterface*' => 'qt_QTextCodecFactoryInterface*',
+'QTextCodecPlugin*' => 'qt_QTextCodecPlugin*',
+'QTextCursor*' => 'qt_QTextCursor*',
+'QTextDecoder*' => 'qt_QTextDecoder*' ,
+'QTextDocument*' => 'qt_QTextDocument*',
+'QTextDrag*' => 'qt_QTextDrag*',
+'QTextEdit*' => 'qt_QTextEdit*',
+'QTextEncoder*' => 'qt_QTextEncoder*' ,
+'QTextFormat*' => 'qt_QTextFormat*',
+'QTextIStream*' => 'qt_QTextIStream*',
+'QTextOStream&' => 'qt_QTextOStream*' ,
+'QTextOStream*' => 'qt_QTextOStream*',
+'QTextOStreamIterator*' => 'qt_QTextOStreamIterator*',
+'QTextParag**' => 'qt_QTextParag**',
+'QTextStream&' => 'qt_QTextStream*' ,
+'QTextStream*' => 'qt_QTextStream*' ,
+'QTextView*' => 'qt_QTextView*',
+'QThread*' => 'qt_QThread*',
+'QThreadData*' => 'qt_QThreadData*',
+'QThreadEvent*' => 'qt_QThreadEvent*',
+'QTime&' => 'qt_QTime*',
+'QTime' => 'qt_QTime*',
+'QTime*' => 'qt_QTime*',
+'QTimeEdit*' => 'qt_QTimeEdit*',
+'QTimeWatch*' => 'qt_QTimeWatch*',
+'QTimer*' => 'qt_QTimer*',
+'QTimerEvent*' => 'qt_QTimerEvent*' ,
+'QToolBar*' => 'qt_QToolBar*' ,
+'QToolButton*' => 'qt_QToolButton*' ,
+'QToolTip*' => 'qt_QToolTip*',
+'QToolTipGroup*' => 'qt_QToolTipGroup*',
+'QTranslator*' => 'qt_QTranslator*' ,
+'QTranslatorMessage&' => 'qt_QTranslatorMessage*' ,
+'QTranslatorMessage' => 'qt_QTranslatorMessage*' ,
+'QTranslatorMessage*' => 'qt_QTranslatorMessage*',
+'QTsciiCodec*' => 'qt_QTsciiCodec*',
+'QUObject*' => 'qt_QUObject*',
+'QUnknownInterface*' => 'qt_QUnknownInterface*',
+'QUnknownInterface**' => 'qt_QUnknownInterface**',
+'QUriDrag*' => 'qt_QUriDrag*',
+'QUrl&' => 'qt_QUrl*' ,
+'QUrl' => 'qt_QUrl*' ,
+'QUrl*' => 'qt_QUrl*',
+'QUrlInfo&' => 'qt_QUrlInfo*' ,
+'QUrlInfo' => 'qt_QUrlInfo*' ,
+'QUrlInfo*' => 'qt_QUrlInfo*',
+'QUrlOperator&' => 'qt_QUrlOperator*' ,
+'QUrlOperator*' => 'qt_QUrlOperator*' ,
+'QUtf16Codec*' => 'qt_QUtf16Codec*',
+'QUtf8Codec*' => 'qt_QUtf8Codec*',
+'QUuid&' => 'qt_QUuid*',
+'QUuid*' => 'qt_QUuid*',
+'QVBox*' => 'qt_QVBox*' ,
+'QVBoxLayout*' => 'qt_QVBoxLayout*',
+'QVButtonGroup*' => 'qt_QVButtonGroup*',
+'QVFbHeader*' => 'qt_QVFbHeader*',
+'QVFbKeyData*' => 'qt_QVFbKeyData*',
+'QVGroupBox*' => 'qt_QVGroupBox*',
+'QValidator*' => 'qt_QValidator*',
+'QValidator::State' => 'int',
+'QValueList*' => 'qt_QValueList*',
+'QValueListConstIterator*' => 'qt_QValueListConstIterator*',
+'QValueListIterator*' => 'qt_QValueListIterator*',
+'QValueListNode*' => 'qt_QValueListNode*',
+'QValueListPrivate*' => 'qt_QValueListPrivate*',
+'QValueStack*' => 'qt_QValueStack*',
+'QValueVector*' => 'qt_QValueVector*',
+'QValueVectorPrivate*' => 'qt_QValueVectorPrivate*',
+'QVariant&' => 'qt_QVariant*',
+'QVariant' => 'qt_QVariant*',
+'QVariant*' => 'qt_QVariant*',
+'QVariant::Type' => 'int' ,
+'QVariantPrivate*' => 'qt_QVariantPrivate*' ,
+'QVector*' => 'qt_QVector*',
+'QWMatrix&' => 'qt_QWMatrix*',
+'QWMatrix' => 'qt_QWMatrix*',
+'QWMatrix*' => 'qt_QWMatrix*',
+'QWSDecoration&' => 'qt_QWSDecoration*' ,
+'QWSDecoration*' => 'qt_QWSDecoration*' ,
+'QWSDisplay*' => 'qt_QWSDisplay*' ,
+'QWSEvent*' => 'qt_QWSEvent*' ,
+'QWaitCondition*' => 'qt_QWaitCondition*',
+'QWhatsThis*' => 'qt_QWhatsThis*',
+'QWheelEvent*' => 'qt_QWheelEvent*' ,
+'QWidget*' => 'qt_QWidget*',
+'QWidget' => 'qt_QWidget*',
+'QWidget*' => 'qt_QWidget*',
+'QWidgetFactory*' => 'qt_QWidgetFactory*',
+'QWidgetIntDict&' => 'qt_QWidgetIntDict*' ,
+'QWidgetIntDict*' => 'qt_QWidgetIntDict*',
+'QWidgetIntDictIt&' => 'qt_QWidgetIntDictIt*' ,
+'QWidgetIntDictIt*' => 'qt_QWidgetIntDictIt*',
+'QWidgetItem*' => 'qt_QWidgetItem*',
+'QWidgetList&' => 'qt_QWidgetList*' ,
+'QWidgetList&' => 'qt_QWidgetList*' ,
+'QWidgetList' => 'qt_QWidgetList*' ,
+'QWidgetList' => 'qt_QWidgetList*' ,
+'QWidgetList*' => 'qt_QWidgetList*',
+'QWidgetList*' => 'qt_QWidgetList*',
+'QWidgetListIt&' => 'qt_QWidgetListIt*' ,
+'QWidgetListIt*' => 'qt_QWidgetListIt*',
+'QWidgetMapper*' => 'qt_QWidgetMapper*',
+'QWidgetPlugin*' => 'qt_QWidgetPlugin*',
+'QWidgetStack*' => 'qt_QWidgetStack*',
+'QWindowsMime*' => 'qt_QWindowsMime*' ,
+'QWindowsStyle*' => 'qt_QWindowsStyle*',
+'QWizard*' => 'qt_QWizard*',
+'QWorkspace*' => 'qt_QWorkspace*',
+'QXEmbed*' => 'qt_QXEmbed*' ,
+'QXmlAttributes&' => 'qt_QXmlAttributes*' ,
+'QXmlAttributes*' => 'qt_QXmlAttributes*',
+'QXmlContentHandler*' => 'qt_QXmlContentHandler*' ,
+'QXmlDTDHandler*' => 'qt_QXmlDTDHandler*' ,
+'QXmlDeclHandler*' => 'qt_QXmlDeclHandler*' ,
+'QXmlDefaultHandler*' => 'qt_QXmlDefaultHandler*',
+'QXmlEntityResolver*' => 'qt_QXmlEntityResolver*' ,
+'QXmlErrorHandler*' => 'qt_QXmlErrorHandler*' ,
+'QXmlInputSource&' => 'qt_QXmlInputSource*' ,
+'QXmlInputSource*&' => 'qt_QXmlInputSource*',
+'QXmlInputSource*' => 'qt_QXmlInputSource*' ,
+'QXmlLexicalHandler*' => 'qt_QXmlLexicalHandler*' ,
+'QXmlLocator*' => 'qt_QXmlLocator*' ,
+'QXmlNamespaceSupport*' => 'qt_QXmlNamespaceSupport*',
+'QXmlParseException&' => 'qt_QXmlParseException*' ,
+'QXmlParseException*' => 'qt_QXmlParseException*',
+'QXmlReader*' => 'qt_QXmlReader*',
+'QXmlSimpleReader*' => 'qt_QXmlSimpleReader*' ,
+'QXtApplication*' => 'qt_QXtApplication*',
+'QXtWidget*' => '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*' ,
+'Qt::ArrowType' => 'int' ,
+'Qt::BackgroundMode' => 'int',
+'Qt::DateFormat' => 'int',
+'Qt::GUIStyle' => 'int' ,
+'Qt::GUIStylecolorStyle::WindowsStyle' => 'int' ,
+'Qt::GUIStylestyle::WindowsStyle' => 'int' ,
+'Qt::Orientation' => 'int' ,
+'Qt::RasterOp' => 'int' ,
+'Qt::UIEffect' => 'int' ,
+'Qt::WFlags' => 'int' ,
+'QtMultiLineEdit*' => 'qt_QtMultiLineEdit*',
+'QtMultiLineEditRow*' => 'qt_QtMultiLineEditRow*',
+'QtTableView*' => 'qt_QtTableView*',
+'QwAbsSpriteFieldView*' => 'qt_QwAbsSpriteFieldView*' ,
+'QwClusterizer*' => 'qt_QwClusterizer*' ,
+'QwEllipse*' => 'qt_QwEllipse*',
+'QwImageSpriteField*' => 'qt_QwImageSpriteField*',
+'QwMobilePositionedSprite*' => 'qt_QwMobilePositionedSprite*',
+'QwMobileSprite*' => 'qt_QwMobileSprite*',
+'QwPolygon*' => 'qt_QwPolygon*',
+'QwPolygonalGraphic*' => 'qt_QwPolygonalGraphic*',
+'QwPositionedSprite*' => 'qt_QwPositionedSprite*',
+'QwPublicList*' => 'qt_QwPublicList*' ,
+'QwRealMobileSprite*' => 'qt_QwRealMobileSprite*',
+'QwRealSprite*' => 'qt_QwRealSprite*',
+'QwRectangle*' => 'qt_QwRectangle*',
+'QwScrollingSpriteFieldView*' => 'qt_QwScrollingSpriteFieldView*',
+'QwSprite*' => 'qt_QwSprite*',
+'QwSpriteField*' => 'qt_QwSpriteField*' ,
+'QwSpriteField*' => 'qt_QwSpriteField*' ,
+'QwSpriteFieldGraphic&' => 'qt_QwSpriteFieldGraphic*' ,
+'QwSpriteFieldGraphic*' => 'qt_QwSpriteFieldGraphic*' ,
+'QwSpriteFieldView*' => 'qt_QwSpriteFieldView*',
+'QwSpritePixmap*' => 'qt_QwSpritePixmap*' ,
+'QwSpritePixmapSequence*' => 'qt_QwSpritePixmapSequence*' ,
+'QwTextSprite*' => 'qt_QwTextSprite*',
+'QwTiledSpriteField*' => 'qt_QwTiledSpriteField*',
+'QwVirtualSprite*' => 'qt_QwVirtualSprite*',
+'RArray*' => 'kde_RArray*',
+'RGBColor&' => 'kde_RGBColor*',
+'RGBColor' => 'kde_RGBColor*',
+'RGBColor*' => 'kde_RGBColor*',
+'Range&' => 'kde_Range*',
+'Range' => 'kde_Range*',
+'Range*' => 'kde_Range*',
+'RangeException&' => 'kde_RangeException*',
+'RangeException*' => 'kde_RangeException*',
+'RangeImpl*' => 'kde_RangeImpl*',
+'RasterOp' => 'int',
+'RawDataPacket*' => 'kde_RawDataPacket*',
+'ReadOnlyPart*' => 'kde_ReadOnlyPart*',
+'ReadWritePart*' => 'kde_ReadWritePart*',
+'Rect&' => 'kde_Rect*',
+'Rect' => 'kde_Rect*',
+'Rect*' => 'kde_Rect*',
+'Reference&' => 'kde_Reference*',
+'Reference*' => 'kde_Reference*',
+'ReferenceClean*' => 'kde_ReferenceClean*',
+'ReferenceHelper*' => 'kde_ReferenceHelper*',
+'Region' => 'int',
+'RegionType' => 'int',
+'RemoteScheduleNode*' => 'kde_RemoteScheduleNode*',
+'RenameDlg*' => 'kde_RenameDlg*',
+'RenderStyle*' => 'kde_RenderStyle*' ,
+'Rep*' => 'kde_Rep*',
+'RunMode' => 'int' ,
+'SButton*' => 'kde_SButton*',
+'SCFlags' => 'int',
+'SFlags' => 'int',
+'ScheduleNode*' => 'kde_ScheduleNode*',
+'Scheduler*' => 'kde_Scheduler*',
+'ScrollBarMode' => 'int',
+'ScrollControl' => 'int' ,
+'SearchInterface*' => 'kde_SearchInterface*',
+'Section&' => 'kde_Section*' ,
+'Section*&' => 'kde_Section*' ,
+'Section*' => 'kde_Section*' ,
+'SegmentStyle' => 'int',
+'SelectionInterface*' => 'kde_SelectionInterface*',
+'Separator' => 'int',
+'Server&' => 'Server*' ,
+'Server*' => 'kde_Server*',
+'ServerHello&' => 'kde_ServerHello*',
+'ServerHello*' => 'kde_ServerHello*',
+'Service*' => 'kde_Service*',
+'SessionData*' => 'kde_SessionData*',
+'SimpleFormat*' => 'kde_SimpleFormat*',
+'SimpleJob*' => 'kde_SimpleJob*',
+'SimpleSoundServer&' => 'kde_SimpleSoundServer*',
+'SimpleSoundServer' => 'kde_SimpleSoundServer*',
+'SimpleSoundServer*' => 'kde_SimpleSoundServer*',
+'SimpleSoundServer_base*' => 'kde_SimpleSoundServer_base*',
+'SimpleSoundServer_skel*' => 'kde_SimpleSoundServer_skel*',
+'SimpleSoundServer_stub*' => 'kde_SimpleSoundServer_stub*',
+'SkipDlg*' => 'kde_SkipDlg*',
+'Slave*' => 'kde_Slave*',
+'SlaveBase*' => 'kde_SlaveBase*',
+'SlaveBasePrivate*' => 'kde_SlaveBasePrivate*',
+'SlaveConfig*' => 'kde_SlaveConfig*',
+'SlaveInterface*' => 'kde_SlaveInterface*',
+'SocketConnection*' => 'kde_SocketConnection*',
+'Spec' => 'int',
+'SpecialEvent*' => 'kde_SpecialEvent*',
+'SshProcess*' => 'kde_SshProcess*',
+'SshProcessPrivate*' => 'kde_SshProcessPrivate*',
+'StartupClass*' => 'kde_StartupClass*',
+'StartupManager*' => 'kde_StartupManager*',
+'StatJob*' => 'kde_StatJob*',
+'State' => 'int',
+'QSocket::State' => 'int',
+'StatusbarProgress*' => 'kde_StatusbarProgress*',
+'StdAddressBook*' => 'kde_StdAddressBook*',
+'StdFlowSystem*' => 'kde_StdFlowSystem*',
+'StdIOManager*' => 'kde_StdIOManager*',
+'StdScheduleNode*' => 'kde_StdScheduleNode*',
+'StdSynthModule*' => 'kde_StdSynthModule*',
+'StereoEffect&' => 'kde_StereoEffect*',
+'StereoEffect' => 'kde_StereoEffect*',
+'StereoEffect*' => 'kde_StereoEffect*',
+'StereoEffectStack&' => 'kde_StereoEffectStack*',
+'StereoEffectStack' => 'kde_StereoEffectStack*',
+'StereoEffectStack*' => 'kde_StereoEffectStack*',
+'StereoEffectStack_base*' => 'kde_StereoEffectStack_base*',
+'StereoEffectStack_skel*' => 'kde_StereoEffectStack_skel*',
+'StereoEffectStack_stub*' => 'kde_StereoEffectStack_stub*',
+'StereoEffect_base*' => 'kde_StereoEffect_base*',
+'StereoEffect_skel*' => 'kde_StereoEffect_skel*',
+'StereoEffect_stub*' => 'kde_StereoEffect_stub*',
+'StereoFFTScope&' => 'kde_StereoFFTScope*',
+'StereoFFTScope' => 'kde_StereoFFTScope*',
+'StereoFFTScope*' => 'kde_StereoFFTScope*',
+'StereoFFTScope_base*' => 'kde_StereoFFTScope_base*',
+'StereoFFTScope_skel*' => 'kde_StereoFFTScope_skel*',
+'StereoFFTScope_stub*' => 'kde_StereoFFTScope_stub*',
+'StereoVolumeControl&' => 'kde_StereoVolumeControl*',
+'StereoVolumeControl' => 'kde_StereoVolumeControl*',
+'StereoVolumeControl*' => 'kde_StereoVolumeControl*',
+'StereoVolumeControl_base*' => 'kde_StereoVolumeControl_base*',
+'StereoVolumeControl_skel*' => 'kde_StereoVolumeControl_skel*',
+'StereoVolumeControl_stub*' => 'kde_StereoVolumeControl_stub*',
+'StreamMode&' => 'int',
+'String*' => 'kde_String*',
+'StringSectionMap::iterator&' => 'kde_StringSectionMap*' ,
+'StringSectionMap::iterator' => 'kde_StringSectionMap*r' ,
+'StubProcess*' => 'kde_StubProcess*',
+'StyleHint' => 'int',
+'StyleListImpl*' => 'kde_StyleListImpl*',
+'StylePixmap' => 'int',
+'StyleSheet&' => 'kde_StyleSheet*',
+'StyleSheet' => 'kde_StyleSheet*',
+'StyleSheet*' => 'kde_StyleSheet*',
+'StyleSheetImpl*' => 'kde_StyleSheetImpl*',
+'StyleSheetList&' => 'kde_StyleSheetList*',
+'StyleSheetList' => 'kde_StyleSheetList',
+'StyleSheetList*' => 'kde_StyleSheetList*',
+'StyleSheetListImpl*' => 'kde_StyleSheetListImpl*',
+'StyleStrategy' => 'int',
+'SuProcess*' => 'kde_SuProcess*',
+'SubClass&' => 'kde_SubClass*',
+'SubClass*' => 'kde_SubClass*',
+'SubControl' => 'int',
+'SubRect' => 'int',
+'SynthBuffer*' => 'kde_SynthBuffer*',
+'SynthModule&' => 'kde_SynthModule*',
+'SynthModule' => 'kde_SynthModule*',
+'SynthModule*' => 'kde_SynthModule*',
+'SynthModule_base*' => 'kde_SynthModule_base*',
+'SynthModule_skel*' => 'kde_SynthModule_skel*',
+'SynthModule_stub*' => 'kde_SynthModule_stub*',
+'SynthOut*' => 'kde_SynthOut*',
+'Synth_ADD&' => 'kde_Synth_ADD*',
+'Synth_ADD' => 'kde_Synth_ADD*',
+'Synth_ADD*' => 'kde_Synth_ADD*',
+'Synth_ADD_base*' => 'kde_Synth_ADD_base*',
+'Synth_ADD_skel*' => 'kde_Synth_ADD_skel*',
+'Synth_ADD_stub*' => 'kde_Synth_ADD_stub*',
+'Synth_AMAN_PLAY&' => 'kde_Synth_AMAN_PLAY*',
+'Synth_AMAN_PLAY' => 'kde_Synth_AMAN_PLAY*',
+'Synth_AMAN_PLAY*' => 'kde_Synth_AMAN_PLAY*',
+'Synth_AMAN_PLAY_base*' => 'kde_Synth_AMAN_PLAY_base*',
+'Synth_AMAN_PLAY_skel*' => 'kde_Synth_AMAN_PLAY_skel*',
+'Synth_AMAN_PLAY_stub*' => 'kde_Synth_AMAN_PLAY_stub*',
+'Synth_AMAN_RECORD&' => 'kde_Synth_AMAN_RECORD*',
+'Synth_AMAN_RECORD' => 'kde_Synth_AMAN_RECORD*',
+'Synth_AMAN_RECORD*' => 'kde_Synth_AMAN_RECORD*',
+'Synth_AMAN_RECORD_base*' => 'kde_Synth_AMAN_RECORD_base*',
+'Synth_AMAN_RECORD_skel*' => 'kde_Synth_AMAN_RECORD_skel*',
+'Synth_AMAN_RECORD_stub*' => 'kde_Synth_AMAN_RECORD_stub*',
+'Synth_BUS_DOWNLINK&' => 'kde_Synth_BUS_DOWNLINK*',
+'Synth_BUS_DOWNLINK' => 'kde_Synth_BUS_DOWNLINK*',
+'Synth_BUS_DOWNLINK*' => 'kde_Synth_BUS_DOWNLINK*',
+'Synth_BUS_DOWNLINK_base*' => 'kde_Synth_BUS_DOWNLINK_base*',
+'Synth_BUS_DOWNLINK_skel*' => 'kde_Synth_BUS_DOWNLINK_skel*',
+'Synth_BUS_DOWNLINK_stub*' => 'kde_Synth_BUS_DOWNLINK_stub*',
+'Synth_BUS_UPLINK&' => 'kde_Synth_BUS_UPLINK*',
+'Synth_BUS_UPLINK' => 'kde_Synth_BUS_UPLINK*',
+'Synth_BUS_UPLINK*' => 'kde_Synth_BUS_UPLINK*',
+'Synth_BUS_UPLINK_base*' => 'kde_Synth_BUS_UPLINK_base*',
+'Synth_BUS_UPLINK_skel*' => 'kde_Synth_BUS_UPLINK_skel*',
+'Synth_BUS_UPLINK_stub*' => 'kde_Synth_BUS_UPLINK_stub*',
+'Synth_FREQUENCY&' => 'kde_Synth_FREQUENCY*',
+'Synth_FREQUENCY' => 'kde_Synth_FREQUENCY*',
+'Synth_FREQUENCY*' => 'kde_Synth_FREQUENCY*',
+'Synth_FREQUENCY_base*' => 'kde_Synth_FREQUENCY_base*',
+'Synth_FREQUENCY_skel*' => 'kde_Synth_FREQUENCY_skel*',
+'Synth_FREQUENCY_stub*' => 'kde_Synth_FREQUENCY_stub*',
+'Synth_MUL&' => 'kde_Synth_MUL*',
+'Synth_MUL' => 'kde_Synth_MUL*',
+'Synth_MUL*' => 'kde_Synth_MUL*',
+'Synth_MULTI_ADD&' => 'kde_Synth_MULTI_ADD*',
+'Synth_MULTI_ADD' => 'kde_Synth_MULTI_ADD*',
+'Synth_MULTI_ADD*' => 'kde_Synth_MULTI_ADD*',
+'Synth_MULTI_ADD_base*' => 'kde_Synth_MULTI_ADD_base*',
+'Synth_MULTI_ADD_skel*' => 'kde_Synth_MULTI_ADD_skel*',
+'Synth_MULTI_ADD_stub*' => 'kde_Synth_MULTI_ADD_stub*',
+'Synth_MUL_base*' => 'kde_Synth_MUL_base*',
+'Synth_MUL_skel*' => 'kde_Synth_MUL_skel*',
+'Synth_MUL_stub*' => 'kde_Synth_MUL_stub*',
+'Synth_PLAY&' => 'kde_Synth_PLAY*',
+'Synth_PLAY' => 'kde_Synth_PLAY*',
+'Synth_PLAY*' => 'kde_Synth_PLAY*',
+'Synth_PLAY_WAV&' => 'kde_Synth_PLAY_WAV*',
+'Synth_PLAY_WAV' => 'kde_Synth_PLAY_WAV*',
+'Synth_PLAY_WAV*' => 'kde_Synth_PLAY_WAV*',
+'Synth_PLAY_WAV_base*' => 'kde_Synth_PLAY_WAV_base*',
+'Synth_PLAY_WAV_skel*' => 'kde_Synth_PLAY_WAV_skel*',
+'Synth_PLAY_WAV_stub*' => 'kde_Synth_PLAY_WAV_stub*',
+'Synth_PLAY_base*' => 'kde_Synth_PLAY_base*',
+'Synth_PLAY_skel*' => 'kde_Synth_PLAY_skel*',
+'Synth_PLAY_stub*' => 'kde_Synth_PLAY_stub*',
+'Synth_RECORD&' => 'kde_Synth_RECORD*',
+'Synth_RECORD' => 'kde_Synth_RECORD*',
+'Synth_RECORD*' => 'kde_Synth_RECORD*',
+'Synth_RECORD_base*' => 'kde_Synth_RECORD_base*',
+'Synth_RECORD_skel*' => 'kde_Synth_RECORD_skel*',
+'Synth_RECORD_stub*' => 'kde_Synth_RECORD_stub*',
+'Synth_WAVE_SIN&' => 'kde_Synth_WAVE_SIN*',
+'Synth_WAVE_SIN' => 'kde_Synth_WAVE_SIN*',
+'Synth_WAVE_SIN*' => 'kde_Synth_WAVE_SIN*',
+'Synth_WAVE_SIN_base*' => 'kde_Synth_WAVE_SIN_base*',
+'Synth_WAVE_SIN_skel*' => 'kde_Synth_WAVE_SIN_skel*',
+'Synth_WAVE_SIN_stub*' => 'kde_Synth_WAVE_SIN_stub*',
+'T&' => 'T*' ,
+'T' => 'T*' ,
+'T*' => 'T*' ,
+'TCPConnection*' => 'kde_TCPConnection*',
+'TCPServer*' => 'kde_TCPServer*',
+'TCPSlaveBase*' => 'kde_TCPSlaveBase*',
+'TRUE' => '1',
+'Task*' => 'kde_Task*',
+'Text&' => 'kde_Text*',
+'Text' => 'kde_Text*',
+'Text*' => 'kde_Text*',
+'TextFormat' => 'int' ,
+'TextImpl*' => 'kde_TextImpl*',
+'ThumbCreator*' => 'kde_ThumbCreator*',
+'TickSetting' => 'int',
+'Ticket*' => 'kde_Ticket*',
+'TimeNotify*' => 'kde_TimeNotify*',
+'TimeWatcher*' => 'kde_TimeWatcher*',
+'TimeZone&' => 'kde_TimeZone*',
+'TimeZone*' => 'kde_TimeZone*',
+'TmpGlobalComm&' => 'kde_TmpGlobalComm*',
+'TmpGlobalComm' => 'kde_TmpGlobalComm*',
+'TmpGlobalComm*' => 'kde_TmpGlobalComm*',
+'TmpGlobalComm_base*' => 'kde_TmpGlobalComm_base*',
+'TmpGlobalComm_skel*' => 'kde_TmpGlobalComm_skel*',
+'TmpGlobalComm_stub*' => 'kde_TmpGlobalComm_stub*',
+'ToolBarDock&' => 'int' ,
+'ToolBarDock' => 'int',
+'TraderOffer&' => 'kde_TraderOffer*',
+'TraderOffer' => 'kde_TraderOffer*',
+'TraderOffer*' => 'kde_TraderOffer*',
+'TraderOffer_base*' => 'kde_TraderOffer_base*',
+'TraderOffer_skel*' => 'kde_TraderOffer_skel*',
+'TraderOffer_stub*' => 'kde_TraderOffer_stub*',
+'TraderQuery&' => 'kde_TraderQuery*',
+'TraderQuery' => 'kde_TraderQuery*',
+'TraderQuery*' => 'kde_TraderQuery*',
+'TraderQuery_base*' => 'kde_TraderQuery_base*',
+'TraderQuery_skel*' => 'kde_TraderQuery_skel*',
+'TraderQuery_stub*' => 'kde_TraderQuery_stub*',
+'TransferJob*' => 'kde_TransferJob*',
+'TreeWalker&' => 'kde_TreeWalker*',
+'TreeWalker' => 'kde_TreeWalker*',
+'TreeWalker*' => 'kde_TreeWalker*',
+'TreeWalkerImpl*' => 'kde_TreeWalkerImpl*',
+'True' => '1',
+'Type&' => 'kde_Type*',
+'Type' => 'int',
+'Type*' => 'kde_Type*',
+'TypeComponent&' => 'kde_TypeComponent*',
+'TypeComponent*' => 'kde_TypeComponent*',
+'TypeDef&' => 'kde_TypeDef*',
+'TypeDef' => 'kde_TypeDef*',
+'TypeDef*' => 'kde_TypeDef*',
+'TypeEntry*' => 'kde_TypeEntry*',
+'TypeInfo*' => 'kde_TypeInfo*',
+'UChar&' => 'kde_UChar*',
+'UChar' => 'kde_UChar*',
+'UChar*' => 'kde_UChar*',
+'UCharReference&' => 'kde_UCharReference*',
+'UCharReference' => 'kde_UCharReference*',
+'UCharReference*' => 'kde_UCharReference*',
+'UDSAtom*' => 'kde_UDSAtom*',
+'UIServer*' => 'kde_UIServer*',
+'UIServer_stub*' => 'kde_UIServer_stub*',
+'ULONG_MAX' => 'ULONG_MAX',
+'UString&' => 'kde_UString*',
+'UString' => 'kde_UString*',
+'UString*' => 'kde_UString*',
+'Undefined*' => 'kde_Undefined*',
+'UndoInterface*' => 'kde_UndoInterface*',
+'UndoRedoInfo*' => 'int*',
+'UnixConnection*' => 'kde_UnixConnection*',
+'UnixServer*' => 'kde_UnixServer*',
+'VCardFormat*' => 'kde_VCardFormat*',
+'VPort*' => 'kde_VPort*',
+'Value&' => 'kde_Value*',
+'Value' => 'kde_Value*',
+'Value*' => 'kde_Value*',
+'VerticalAlignment*' => 'int*',
+'View*' => 'kde_View*' ,
+'ViewCursorInterface*' => 'kde_ViewCursorInterface*',
+'VoiceManager*' => 'kde_VoiceManager*',
+'WFlags' => 'int',
+'WId' => 'unsigned int',
+'WState' => 'int',
+'WavPlayObject&' => 'kde_WavPlayObject*',
+'WavPlayObject' => 'kde_WavPlayObject*',
+'WavPlayObject*' => 'kde_WavPlayObject*',
+'WavPlayObject_base*' => 'kde_WavPlayObject_base*',
+'WavPlayObject_skel*' => 'kde_WavPlayObject_skel*',
+'WavPlayObject_stub*' => 'kde_WavPlayObject_stub*',
+'WeakReference*' => 'kde_WeakReference*',
+'WeakReferenceBase*' => 'kde_WeakReferenceBase*',
+'Widget' => 'int' ,
+'WidgetClass' => 'int' ,
+'WidthMode' => 'int',
+'Window' => 'kde_Window*',
+'Window*' => 'kde_Window*',
+'WindowArgs&' => 'kde_WindowArgs*',
+'WindowArgs*' => 'kde_WindowArgs*',
+'WindowsVersion' => 'int' ,
+'XrmOptionDescRec*' => 'XrmOptionDescRec*' ,
+'array_data*' => 'void*' ,
+'bitarr_data*' => 'void*',
+'bool&' => 'int' ,
+'bool' => 'int',
+'bool*' => 'int*',
+'char*' => 'char*',
+'char&' => 'char' ,
+'char' => 'char',
+'char* bugsEmailAddress @bugs.kde.org"' => 'String',
+'char*&' => 'char*',
+'char*' => 'char*',
+'char**' => 'char**',
+'char*xpm[]' => 'char**' ,
+'classConnection*' => 'kde_classConnection*',
+'classDeviceManager*' => 'kde_classDeviceManager*',
+'classExtensionLoader*' => 'kde_classExtensionLoader*',
+'classMidiStatus*' => 'kde_classMidiStatus*',
+'classObjectReference' => 'kde_classObjectReference*',
+'classQPainter*' => 'kde_classQPainter*',
+'classStartupClass*' => 'kde_classStartupClass*',
+'double d .0' => 'double',
+'double nDefault .0' => 'double',
+'double pri .0' => 'double',
+'double&' => 'double' ,
+'double' => 'double',
+'double*' => 'double*' ,
+'false' => '0',
+'float desat .3' => 'float',
+'float&' => 'float' ,
+'float' => 'float',
+'float*' => 'float*',
+'image_io_handler' => 'int' ,
+'int a |' => 'int',
+'int buttonMask|Apply|Cancel' => 'int',
+'int buttonMask|No|Cancel' => 'int',
+'int desktop' => 'int',
+'int&' => 'int',
+'int' => 'int',
+'int*' => 'int*',
+'int short' => 'short',
+'kdbgstream&' => 'kde_Kdbgstream*' ,
+'kdbgstream*' => 'kde_kdbgstream*',
+'kndbgstream&' => 'void**' ,
+'kndbgstream*' => 'kde_kndbgstream*',
+'ksockaddr_in*' => 'void*' ,
+'long _blockSize*' => 'long*',
+'long int' => 'long',
+'long unsigned int' => 'long',
+'long&' => 'long' ,
+'long' => 'long',
+'long_blockSize*' => 'long_blockSize*' ,
+'longint' => 'long',
+'longunsigned int' => 'unsigned long',
+'lt_dlhandle' => 'void*' ,
+'lt_user_dlloader*' => 'kde_lt_user_dlloader*',
+'mcopbyte&' => 'void*',
+'mcopbyte' => 'unsigned char',
+'mode_t _mode (mode_t) -1' => 'int',
+'mode_t' => 'long' ,
+'noteCmd' => 'kde_noteCmd*',
+'noteCmd*' => 'kde_noteCmd*',
+'ostream&' => 'int',
+'ostream*' => 'int',
+'pid_t' => 'long' ,
+'poTime&' => 'kde_poTime*',
+'poTime*' => 'kde_poTime*',
+'short unsigned' => 'short',
+'short' => 'short',
+'short*' => 'short*',
+'shortunsigned' => 'unsigned short',
+'signed int&' => 'signed int' ,
+'signed long&' => 'signed long' ,
+'signed short&' => 'signed short' ,
+'signed' => 'signed' ,
+'size_t' => 'int' ,
+'size_t*' => 'int*',
+'size_type' => 'int' ,
+'snd_seq_event_t*' => 'int*',
+'ssize_t' => 'int',
+'std*' => 'kde_std*',
+'std::string&' => 'char*' ,
+'std::string' => 'char*' ,
+'time_t' => 'long' ,
+'timeval&' => 'int',
+'true' => '1',
+'type&' => 'int' ,
+'type*' => 'int*' ,
+'type**' => 'int**' ,
+'uchar&' => 'unsigned char' ,
+'uchar' => 'unsigned char' ,
+'uchar*' => 'unsigned char*',
+'uchar**' => 'unsigned char**',
+'uint&' => 'unsigned int',
+'uint' => 'unsigned int',
+'uint*' => 'unsigned int*' ,
+'uintf~0' => 'unsigned int' ,
+'ulong' => 'unsigned long',
+'unsigned char&' => 'unsigned char',
+'unsigned char' => 'unsigned char' ,
+'unsigned char*' => 'unsigned char*' ,
+'unsigned int&' => 'unsigned int' ,
+'unsigned int' => 'unsigned int' ,
+'unsigned int*' => 'int*' ,
+'unsigned long int' => 'long',
+'unsigned long&' => 'unsigned long' ,
+'unsigned long' => 'unsigned long' ,
+'unsigned short int' => 'unsigned short' ,
+'unsigned short&' => 'unsigned short' ,
+'unsigned short' => 'unsigned short' ,
+'unsigned short*' => 'short*' ,
+'unsigned shortint' => 'unsigned short' ,
+'unsigned' => 'unsigned int' ,
+'ushort' => 'unsigned short',
+'ushort*' => 'short*' ,
+'voice*' => 'int',
+'void' => 'void',
+'void(*)()' => 'void(*)()' ,
+'void*' => 'void*',
+'~' => '~',
+'QValueList<int>' => 'qt_QIntValueList*',
+'QValueList<int>&' => 'qt_QIntValueList*',
+'QValueList<QIconDragItem>' => 'qt_QIconDragItemValueList*',
+'QValueList<QIconDragItem>&' => 'qt_QIconDragItemValueList*',
+'QValueList<QPixmap>' => 'qt_QPixmapValueList*',
+'QValueList<QString>&' => 'qt_QStringValueList*',
+'QValueList<QVariant>&' => 'qt_QVariantValueList*',
+'QValueList<QUrlInfo>*' => 'qt_QUrlInfoValueList*',
+'QValueList<KDataToolInfo>&' => 'kde_KDataToolInfoValueList*',
+'QPtrList<QDockWindow>*' => 'qt_QDockWindowPtrList*',
+'QPtrList<QPixmap>' => 'qt_QPixmapPtrList*',
+'QPtrList<QPoint>' => 'qt_QPointPtrList*',
+'ClassContext*' => 'kde_ClassContext*',
+'ClassStoreIface*' => 'kde_ClassStoreIface*',
+'ClipboardDocumentIface*' => 'kde_ClipboardDocumentIface*',
+'CodeCompletionDocumentIface*' => 'kde_CodeCompletionDocumentIface*',
+'CursorDocumentIface*' => 'kde_CursorDocumentIface*',
+'DebugDocumentIface*' => 'kde_DebugDocumentIface*',
+'DocumentInterface*' => 'kde_DocumentInterface*',
+'EditDocumentIface*' => 'kde_EditDocumentIface*',
+'EditorInterface*' => 'kde_EditorInterface*',
+'FileContext*' => 'kde_FileContext*',
+'KDevAppFrontendIface*' => 'kde_KDevAppFrontendIface*',
+'KDevCoreIface*' => 'kde_KDevCoreIface*',
+'KDevMakeFrontendIface*' => 'kde_KDevMakeFrontendIface*',
+'KEditor*' => 'kde_KEditor*',
+'KEditor::Document*' => 'kde_Document*',
+'ParsedClassContainer&' => 'kde_ParsedClassContainer*',
+'ParsedContainer&' => 'kde_ParsedContainer*',
+'ParsedScopeContainer&' => 'kde_ParsedScopeContainer*',
+'QValueList<ParsedMethod>*' => 'kde_ParsedMethodList*',
+'QValueList<CompletionEntry>' => 'kde_CompletionEntryValueList*',
+'StatusDocumentIface*' => 'kde_StatusDocumentIface*',
+'UndoDocumentIface*' => 'kde_UndoDocumentIface*',
+'KShortcut&' => 'kde_KShortcut*',
+'KShortcut' => 'kde_KShortcut*',
+'KShortcut*' => 'kde_KShortcut*',
+'KKey&' => 'kde_KKey*',
+'KKey*' => 'kde_KKey*',
+'KKeyNative&' => 'kde_KKeyNative*',
+'KKeyNative*' => 'kde_KKeyNative*',
+'KKeyVariations&' => 'kde_KKeyVariations*',
+'KKeyVariations*' => 'kde_KKeyVariations*',
+'KKeyX11&' => 'kde_KKeyX11*',
+'KKeyX11' => 'kde_KKeyX11*',
+'KKeyX11*' => 'kde_KKeyX11*',
+'KAccelActions' => 'kde_KAccelActions*',
+'KRandomSequence&' => 'kde_KRandomSequence*',
+'KIcon::Context' => 'int',
+'KIcon::Group' => 'int',
+);
+
+
+ # Initialize %builtins, used by resolveType
+ my @noreflist = qw( const int char long double template
+ unsigned signed float void bool true false uint
+ uint32 uint64 extern static inline virtual operator );
+ foreach my $r ( @noreflist ) {
+ $builtins{ $r } = $r;
+ }
+
+}
+
+sub interfacemap
+{
+ my ( $interfaceType ) = @_;
+ return $interfacemap{$interfaceType};
+}
+
+sub ctypemap
+{
+ my ( $cType ) = @_;
+ return $ctypemap{$cType};
+}
+
+sub setctypemap
+{
+ my ( $cType, $cValue ) = @_;
+
+ $ctypemap{$cType} = $cValue;
+ return;
+}
+
+sub addNamespace
+{
+ my ( $className ) = @_;
+
+ if ( $className =~ /Bridge$/ ) {
+ return $className;
+ }
+
+ if ( $className =~ /^(AbstractView|Attr|CDATASection|CSSCharsetRule|CSSException|CSSFontFaceRule|CSSImportRule|CSSMediaRule|CSSPageRule|CSSPrimitiveValue|CSSRule|CSSRuleList|CSSStyleDeclaration|CSSStyleRule|CSSStyleSheet|CSSUnknownRule|CSSValue|CSSValueList|CharacterData|Comment|Counter|CustomNodeFilter|DOMException|DOMImplementation|DOMString|Document|DocumentFragment|DocumentStyle|DocumentType|DomShared|Element|Entity|EntityReference|EventException|EventListener|LinkStyle|MediaList|MutationEvent|NamedNodeMap|Node|NodeFilter|NodeIterator|NodeList|Notation|ProcessingInstruction|RGBColor|Range|RangeException|Rect|StyleSheet|StyleSheetList|Text|TreeWalker|UIEvent|HTML.*)/ )
+ {
+ return "DOM::".$className;
+ }
+
+ if ( $className =~ /^(BrowserExtension|BrowserHostExtensionBrowserInterface|ComponentFactory|DockMainWindow|Event|Factory|GUIActivateEvent|HistoryProvider|MainWindow|OpenURLEvent|Part|PartActivateEvent|PartBase|PartManager|PartSelectEvent|Plugin|PluginInfo|ReadOnlyPart|ReadWritePart|URLArgs|WindowArgs)/ )
+ {
+ return "KParts::".$className;
+ }
+
+ if ( $className =~ /^(AuthInfo|AutoLogin|CacheInfo|ChmodJob|Connection|CopyInfo|CopyJob|DefaultProgress|DeleteJob|FileCopyJob|Job|ListJob|MetaData|MimetypeJob|MultiGetJob|NetAccess|NetRC|PasswordDialog|PreviewJob|ProgressBase|RenameDlg|Scheduler|SessionData|SimpleJob|SkipDlg|Slave|SlaveBase|SlaveConfig|SlaveInterface|StatJob|StatusbarProgress|TCPSlaveBase|Task|TransferJob|UDSAtom)/ )
+ {
+ return "KIO::".$className;
+ }
+
+ if ( $className =~ /^(DrawContentsEvent|MouseDoubleClickEvent|MouseEvent|MouseMoveEvent|MousePressEvent|MouseReleaseEvent)/ )
+ {
+ return "khtml::".$className;
+ }
+
+ if ( $className =~ /^(OfferList)/ )
+ {
+ return "KTrader::".$className;
+ }
+
+ if ( $className =~ /^(BlockSelectionInterface|ClipboardInterface|CodeCompletionInterface|CompletionEntry|ConfigInterface|Cursor|CursorInterface|Document|EditInterface|Editor|HighlightingInterface|Mark|MarkInterface|PopupMenuInterface|PrintInterface|SearchInterface|SelectionInterface|UndoInterface|View|ViewCursorInterface)/ )
+ {
+ return "KTextEditor::".$className;
+ }
+
+
+ return $className;
+}
+
+
+# Helper for resolveType. This one is recursive and returns undef if not found.
+sub resolveTypeInternal($$$)
+{
+ my ( $argType, $contextClass, $rootnode ) = @_;
+
+ #print "resolveTypeInternal type:'$argType' context:'$contextClass->{astNodeName}' ($contextClass)\n";
+
+ my $contextClassName = join( "::", kdocAstUtil::heritage($contextClass) );
+
+ # 'A' resolves to 'A' in context 'A' ;) (i.e. classname itself)
+ return $contextClassName if ( $argType eq $contextClass->{astNodeName} );
+
+ # Try as an identifier of contextClass
+ #print "Trying as ".$contextClassName."::".$argType."\n";
+
+ my $node = kdocAstUtil::findRef( $rootnode, $contextClassName."::".$argType );
+
+ #print "Found as $node->{NodeType}\n" if $node;
+
+ return $contextClassName."::".$argType if ( $node
+ && $node->{NodeType} ne 'method'
+ && $node->{NodeType} ne 'deleted'
+ && $node->{NodeType} ne 'var' );
+
+ my $found;
+
+ # Then look at ancestors, and try for each one
+ Iter::Ancestors( $contextClass, $rootnode, undef, undef,
+ sub {
+ my ( $ances, $name, $type, $template ) = @_;
+ unless ($found) {
+ $found = resolveTypeInternal( $argType, $ances, $rootnode );
+ }
+ },
+ undef
+ );
+
+ return $found;
+}
+
+=head2
+
+ Look up a type, following the class hierarchy.
+ e.g. "Mode", if ContextClassName is A, will be looked as A::Mode,
+ then as B::Mode (if B is a parent class of A), then as Qt::Mode,
+ then as just Mode.
+
+=cut
+
+sub resolveType($$$)
+{
+ my ( $argType, $contextClass, $rootnode ) = @_;
+ $argType =~ s/\s*(\*)\s*$/$1/g; # remove space before *
+ #print "resolveType: '$argType'\n";
+
+ # 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 : '';
+ #print "resolveType: prefix:$prefix, '$argType', suffix:$suffix\n";
+
+ # Launch the (possibly recursive) resolveTypeInternal
+ 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 ) );
+
+ #print "resolveType: $argType not found (context $contextClass->{astNodeName})\n\n";
+
+ return $prefix.$argType.$suffix;
+}
+
+1;
diff --git a/kalyptus/kdocAstUtil.pm b/kalyptus/kdocAstUtil.pm
new file mode 100644
index 00000000..8c24430c
--- /dev/null
+++ b/kalyptus/kdocAstUtil.pm
@@ -0,0 +1,789 @@
+=head1 kdocAstUtil
+
+ Utilities for syntax trees.
+
+=cut
+
+
+package kdocAstUtil;
+
+use Ast;
+use Carp;
+use File::Basename;
+use kdocUtil;
+use Iter;
+use strict;
+
+use vars qw/ $depth $refcalls $refiters @noreflist %noref /;
+
+sub BEGIN {
+# statistics for findRef
+
+ $depth = 0;
+ $refcalls = 0;
+ $refiters = 0;
+
+# findRef will ignore these words
+
+ @noreflist = qw( const int char long double template
+ unsigned signed float void bool true false uint
+ uint32 uint64 extern static inline virtual operator );
+
+ foreach my $r ( @noreflist ) {
+ $noref{ $r } = 1;
+ }
+}
+
+
+=head2 findNodes
+
+ Parameters: outlist ref, full list ref, key, value
+
+ Find all nodes in full list that have property "key=value".
+ All resulting nodes are stored in outlist.
+
+=cut
+
+sub findNodes
+{
+ my( $rOutList, $rInList, $key, $value ) = @_;
+
+ my $node;
+
+ foreach $node ( @{$rInList} ) {
+ next if !exists $node->{ $key };
+ if ( $node->{ $key } eq $value ) {
+ push @$rOutList, $node;
+ }
+ }
+}
+
+=head2 allTypes
+
+ Parameters: node list ref
+ returns: list
+
+ Returns a sorted list of all distinct "NodeType"s in the nodes
+ in the list.
+
+=cut
+
+sub allTypes
+{
+ my ( $lref ) = @_;
+
+ my %types = ();
+ foreach my $node ( @{$lref} ) {
+ $types{ $node->{NodeType} } = 1;
+ }
+
+ return sort keys %types;
+}
+
+
+
+
+=head2 findRef
+
+ Parameters: root, ident, report-on-fail
+ Returns: node, or undef
+
+ Given a root node and a fully qualified identifier (:: separated),
+ this function will try to find a child of the root node that matches
+ the identifier.
+
+=cut
+
+sub findRef
+{
+ my( $root, $name, $r ) = @_;
+
+ confess "findRef: no name" if !defined $name || $name eq "";
+
+ $name =~ s/\s+//g;
+ return undef if exists $noref{ $name };
+
+ $name =~ s/^#//g;
+
+ my ($iter, @tree) = split /(?:\:\:|#)/, $name;
+ my $kid;
+
+ $refcalls++;
+
+ # Upward search for the first token
+ return undef if !defined $iter;
+
+ while ( !defined findIn( $root, $iter ) ) {
+ return undef if !defined $root->{Parent};
+ $root = $root->{Parent};
+ }
+ $root = $root->{KidHash}->{$iter};
+ carp if !defined $root;
+
+ # first token found, resolve the rest of the tree downwards
+ foreach $iter ( @tree ) {
+ confess "iter in $name is undefined\n" if !defined $iter;
+ next if $iter =~ /^\s*$/;
+
+ unless ( defined findIn( $root, $iter ) ) {
+ confess "findRef: failed on '$name' at '$iter'\n"
+ if defined $r;
+ return undef;
+ }
+
+ $root = $root->{KidHash}->{ $iter };
+ carp if !defined $root;
+ }
+
+ return $root;
+}
+
+=head2 findIn
+
+ node, name: search for a child
+
+=cut
+
+sub findIn
+{
+ return undef unless defined $_[0]->{KidHash};
+
+ my $ret = $_[0]->{KidHash}->{ $_[1] };
+
+ return $ret;
+}
+
+=head2 linkReferences
+
+ Parameters: root, node
+
+ Recursively links references in the documentation for each node
+ to real nodes if they can be found. This should be called once
+ the entire parse tree is filled.
+
+=cut
+
+sub linkReferences
+{
+ my( $root, $node ) = @_;
+
+ if ( exists $node->{DocNode} ) {
+ linkDocRefs( $root, $node, $node->{DocNode} );
+
+ if( exists $node->{Compound} ) {
+ linkSee( $root, $node, $node->{DocNode} );
+ }
+ }
+
+ my $kids = $node->{Kids};
+ return unless defined $kids;
+
+ foreach my $kid ( @$kids ) {
+ # only continue in a leaf node if it has documentation.
+ next if !exists $kid->{Kids} && !exists $kid->{DocNode};
+ if( !exists $kid->{Compound} ) {
+ linkSee( $root, $node, $kid->{DocNode} );
+ }
+ linkReferences( $root, $kid );
+ }
+}
+
+sub linkNamespaces
+{
+ my ( $node ) = @_;
+
+ if ( defined $node->{ImpNames} ) {
+ foreach my $space ( @{$node->{ImpNames}} ) {
+ my $spnode = findRef( $node, $space );
+
+ if( defined $spnode ) {
+ $node->AddPropList( "ExtNames", $spnode );
+ }
+ else {
+ warn "namespace not found: $space\n";
+ }
+ }
+ }
+
+ return unless defined $node->{Compound} || !defined $node->{Kids};
+
+
+ foreach my $kid ( @{$node->{Kids}} ) {
+ next unless localComp( $kid );
+
+ linkNamespaces( $kid );
+ }
+}
+
+sub calcStats
+{
+ my ( $stats, $root, $node ) = @_;
+# stats:
+# num types
+# num nested
+# num global funcs
+# num methods
+
+
+ my $type = $node->{NodeType};
+
+ if ( $node eq $root ) {
+ # global methods
+ if ( defined $node->{Kids} ) {
+ foreach my $kid ( @{$node->{Kids}} ) {
+ $stats->{Global}++ if $kid->{NodeType} eq "method";
+ }
+ }
+
+ $node->AddProp( "Stats", $stats );
+ }
+ elsif ( kdocAstUtil::localComp( $node )
+ || $type eq "enum" || $type eq "typedef" ) {
+ $stats->{Types}++;
+ $stats->{Nested}++ if $node->{Parent} ne $root;
+ }
+ elsif( $type eq "method" ) {
+ $stats->{Methods}++;
+ }
+
+ return unless defined $node->{Compound} || !defined $node->{Kids};
+
+ foreach my $kid ( @{$node->{Kids}} ) {
+ next if defined $kid->{ExtSource};
+ calcStats( $stats, $root, $kid );
+ }
+}
+
+=head2 linkDocRefs
+
+ Parameters: root, node, docnode
+
+ Link references in the docs if they can be found. This should
+ be called once the entire parse tree is filled.
+
+=cut
+
+sub linkDocRefs
+{
+ my ( $root, $node, $docNode ) = @_;
+ return unless exists $docNode->{Text};
+
+ my ($text, $ref, $item, $tosearch);
+
+ foreach $item ( @{$docNode->{Text}} ) {
+ next if $item->{NodeType} ne 'Ref';
+
+ $text = $item->{astNodeName};
+
+ if ( $text =~ /^(?:#|::)/ ) {
+ $text = $';
+ $tosearch = $node;
+ }
+ else {
+ $tosearch = $root;
+ }
+
+ $ref = findRef( $tosearch, $text );
+ $item->AddProp( 'Ref', $ref ) if defined $ref;
+
+ confess "Ref failed for ", $item->{astNodeName},
+ "\n" unless defined $ref;
+ }
+}
+
+sub linkSee
+{
+ my ( $root, $node, $docNode ) = @_;
+ return unless exists $docNode->{See};
+
+ my ( $text, $tosearch, $ref );
+
+ foreach $text ( @{$docNode->{See}} ) {
+ if ( $text =~ /^\s*(?:#|::)/ ) {
+ $text = $';
+ $tosearch = $node;
+ }
+ else {
+ $tosearch = $root;
+ }
+
+ $ref = findRef( $tosearch, $text );
+ $docNode->AddPropList( 'SeeRef', $ref )
+ if defined $ref;
+ }
+}
+
+
+
+#
+# Inheritance utilities
+#
+
+=head2 makeInherit
+
+ Parameter: $rootnode, $parentnode
+
+ Make an inheritance graph from the parse tree that begins
+ at rootnode. parentnode is the node that is the parent of
+ all base class nodes.
+
+=cut
+
+sub makeInherit
+{
+ my( $rnode, $parent ) = @_;
+
+ foreach my $node ( @{ $rnode->{Kids} } ) {
+ next if !defined $node->{Compound};
+
+ # set parent to root if no inheritance
+
+ if ( !exists $node->{InList} ) {
+ newInherit( $node, "Global", $parent );
+ $parent->AddPropList( 'InBy', $node );
+
+ makeInherit( $node, $parent );
+ next;
+ }
+
+ # link each ancestor
+ my $acount = 0;
+ANITER:
+ foreach my $in ( @{ $node->{InList} } ) {
+ unless ( defined $in ) {
+ Carp::cluck "warning: $node->{astNodeName} "
+ ." has undef in InList.";
+ next ANITER;
+ }
+
+ my $ref = kdocAstUtil::findRef( $rnode,
+ $in->{astNodeName} );
+
+ if( !defined $ref ) {
+ # ancestor undefined
+ warn "warning: ", $node->{astNodeName},
+ " inherits unknown class '",
+ $in->{astNodeName},"'\n";
+
+ $parent->AddPropList( 'InBy', $node );
+ }
+ else {
+ # found ancestor
+ $in->AddProp( "Node", $ref );
+ $ref->AddPropList( 'InBy', $node );
+ $acount++;
+ }
+ }
+
+ if ( $acount == 0 ) {
+ # inherits no known class: just parent it to global
+ newInherit( $node, "Global", $parent );
+ $parent->AddPropList( 'InBy', $node );
+ }
+ makeInherit( $node, $parent );
+ }
+}
+
+=head2 newInherit
+
+ p: $node, $name, $lnode?
+
+ Add a new ancestor to $node with raw name = $name and
+ node = lnode.
+=cut
+
+sub newInherit
+{
+ my ( $node, $name, $link ) = @_;
+
+ my $n = Ast::New( $name );
+ $n->AddProp( "Node", $link ) unless !defined $link;
+
+ $node->AddPropList( "InList", $n );
+ return $n;
+}
+
+=head2 inheritName
+
+ pr: $inheritance node.
+
+ Returns the name of the inherited node. This checks for existence
+ of a linked node and will use the "raw" name if it is not found.
+
+=cut
+
+sub inheritName
+{
+ my ( $innode ) = @_;
+
+ return defined $innode->{Node} ?
+ $innode->{Node}->{astNodeName}
+ : $innode->{astNodeName};
+}
+
+=head2 inheritedBy
+
+ Parameters: out listref, node
+
+ Recursively searches for nodes that inherit from this one, returning
+ a list of inheriting nodes in the list ref.
+
+=cut
+
+sub inheritedBy
+{
+ my ( $list, $node ) = @_;
+
+ return unless exists $node->{InBy};
+
+ foreach my $kid ( @{ $node->{InBy} } ) {
+ push @$list, $kid;
+ inheritedBy( $list, $kid );
+ }
+}
+
+=head2 inheritsAsVirtual
+
+ Parameters: (selfNode) classNode
+
+ Tells if C<classNode> is a virtual ancestor of C<selfNode>
+ 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
+ Returns: 0 on fail
+
+ Checks if the node has an inheritor that is defined within the
+ current library. This is useful for drawing the class hierarchy,
+ since you don't want to display classes that have no relationship
+ with classes within this library.
+
+ NOTE: perhaps we should cache the value to reduce recursion on
+ subsequent calls.
+
+=cut
+
+sub hasLocalInheritor
+{
+ my $node = shift;
+
+ return 0 if !exists $node->{InBy};
+
+ my $in;
+ foreach $in ( @{$node->{InBy}} ) {
+ return 1 if !exists $in->{ExtSource}
+ || hasLocalInheritor( $in );
+ }
+
+ return 0;
+}
+
+
+
+=head2 allMembers
+
+ Parameters: hashref outlist, node, $type
+
+ Fills the outlist hashref with all the methods of outlist,
+ recursively traversing the inheritance tree.
+
+ If type is not specified, it is assumed to be "method"
+
+=cut
+
+sub allMembers
+{
+ my ( $outlist, $n, $type ) = @_;
+ my $in;
+ $type = "method" if !defined $type;
+
+ if ( exists $n->{InList} ) {
+
+ foreach $in ( @{$n->{InList}} ) {
+ next if !defined $in->{Node};
+ my $i = $in->{Node};
+
+ allMembers( $outlist, $i )
+ unless $i == $main::rootNode;
+ }
+ }
+
+ return unless exists $n->{Kids};
+
+ foreach $in ( @{$n->{Kids}} ) {
+ next if $in->{NodeType} ne $type;
+
+ $outlist->{ $in->{astNodeName} } = $in;
+ }
+}
+
+=head2 findOverride
+
+ Parameters: root, node, name
+
+ Looks for nodes of the same name as the parameter, in its parent
+ and the parent's ancestors. It returns a node if it finds one.
+
+=cut
+
+sub findOverride
+{
+ my ( $root, $node, $name ) = @_;
+ return undef if !exists $node->{InList};
+
+ foreach my $in ( @{$node->{InList}} ) {
+ my $n = $in->{Node};
+ next unless defined $n && $n != $root && exists $n->{KidHash};
+
+ my $ref = $n->{KidHash}->{ $name };
+
+ return $n if defined $ref && $ref->{NodeType} eq "method";
+
+ if ( exists $n->{InList} ) {
+ $ref = findOverride( $root, $n, $name );
+ return $ref if defined $ref;
+ }
+ }
+
+ return undef;
+}
+
+=head2 attachChild
+
+ Parameters: parent, child
+
+ Attaches child to the parent, setting Access, Kids
+ and KidHash of respective nodes.
+
+=cut
+
+sub attachChild
+{
+ my ( $parent, $child ) = @_;
+ confess "Attempt to attach ".$child->{astNodeName}." to an ".
+ "undefined parent\n" if !defined $parent;
+
+ $child->AddProp( "Access", $parent->{KidAccess} );
+ $child->AddProp( "Parent", $parent );
+
+ $parent->AddPropList( "Kids", $child );
+
+ if( !exists $parent->{KidHash} ) {
+ my $kh = Ast::New( "LookupTable" );
+ $parent->AddProp( "KidHash", $kh );
+ }
+
+ $parent->{KidHash}->AddProp( $child->{astNodeName},
+ $child );
+}
+
+=head2 makeClassList
+
+ Parameters: node, outlist ref
+
+ fills outlist with a sorted list of all direct, non-external
+ compound children of node.
+
+=cut
+
+sub makeClassList
+{
+ my ( $rootnode, $list ) = @_;
+
+ @$list = ();
+
+ Iter::LocalCompounds( $rootnode,
+ sub {
+ my $node = shift;
+
+ my $her = join ( "::", heritage( $node ) );
+ $node->AddProp( "FullName", $her );
+
+ if ( !exists $node->{DocNode}->{Internal} ||
+ !$main::skipInternal ) {
+ push @$list, $node;
+ }
+ } );
+
+ @$list = sort { $a->{FullName} cmp $b->{FullName} } @$list;
+}
+
+#
+# Debugging utilities
+#
+
+=head2 dumpAst
+
+ Parameters: node, deep
+ Returns: none
+
+ Does a recursive dump of the node and its children.
+ If deep is set, it is used as the recursion property, otherwise
+ "Kids" is used.
+
+=cut
+
+sub dumpAst
+{
+ my ( $node, $deep ) = @_;
+
+ $deep = "Kids" if !defined $deep;
+
+ print "\t" x $depth, $node->{astNodeName},
+ " (", $node->{NodeType}, ")\n";
+
+ my $kid;
+
+ foreach $kid ( $node->GetProps() ) {
+ print "\t" x $depth, " -\t", $kid, " -> ", $node->{$kid},"\n"
+ unless $kid =~ /^(astNodeName|NodeType|$deep)$/;
+ }
+ if ( exists $node->{InList} ) {
+ print "\t" x $depth, " -\tAncestors -> ";
+ foreach my $innode ( @{$node->{InList}} ) {
+ print $innode->{astNodeName} . ",";
+ }
+ print "\n";
+ }
+
+ print "\t" x $depth, " -\n" if (defined $node->{ $deep } && scalar(@{$node->{ $deep }}) != 0);
+
+ $depth++;
+ foreach $kid ( @{$node->{ $deep }} ) {
+ dumpAst( $kid );
+ }
+
+ print "\t" x $depth, "Documentation nodes:\n" if defined
+ @{ $node->{Doc}->{ "Text" }};
+
+ foreach $kid ( @{ $node->{Doc}->{ "Text" }} ) {
+ dumpAst( $kid );
+ }
+
+ $depth--;
+}
+
+=head2 testRef
+
+ Parameters: rootnode
+
+ Interactive testing of referencing system. Calling this
+ will use the readline library to allow interactive entering of
+ identifiers. If a matching node is found, its node name will be
+ printed.
+
+=cut
+
+sub testRef {
+ require Term::ReadLine;
+
+ my $rootNode = $_[ 0 ];
+
+ my $term = new Term::ReadLine 'Testing findRef';
+
+ my $OUT = $term->OUT || *STDOUT{IO};
+ my $prompt = "Identifier: ";
+
+ while( defined ($_ = $term->readline($prompt)) ) {
+
+ my $node = kdocAstUtil::findRef( $rootNode, $_ );
+
+ if( defined $node ) {
+ print $OUT "Reference: '", $node->{astNodeName},
+ "', Type: '", $node->{NodeType},"'\n";
+ }
+ else {
+ print $OUT "No reference found.\n";
+ }
+
+ $term->addhistory( $_ ) if /\S/;
+ }
+}
+
+sub printDebugStats
+{
+ print "findRef: ", $refcalls, " calls, ",
+ $refiters, " iterations.\n";
+}
+
+sub External
+{
+ return defined $_[0]->{ExtSource};
+}
+
+sub Compound
+{
+ return defined $_[0]->{Compound};
+}
+
+sub localComp
+{
+ my ( $node ) = $_[0];
+ return defined $node->{Compound}
+ && !defined $node->{ExtSource}
+ && $node->{NodeType} ne "Forward";
+}
+
+sub hasDoc
+{
+ return defined $_[0]->{DocNode};
+}
+
+### Warning: this returns the list of parents, e.g. the 3 words in KParts::ReadOnlyPart::SomeEnum
+### It has nothing do to with inheritance.
+sub heritage
+{
+ my $node = shift;
+ my @heritage;
+
+ while( 1 ) {
+ push @heritage, $node->{astNodeName};
+
+ last unless defined $node->{Parent};
+ $node = $node->{Parent};
+ last unless defined $node->{Parent};
+ }
+
+ return reverse @heritage;
+}
+
+sub refHeritage
+{
+ my $node = shift;
+ my @heritage;
+
+ while( 1 ) {
+ push @heritage, $node;
+
+ last unless defined $node->{Parent};
+ $node = $node->{Parent};
+ last unless defined $node->{Parent};
+ }
+
+ return reverse @heritage;
+
+}
+
+
+1;
diff --git a/kalyptus/kdocLib.pm b/kalyptus/kdocLib.pm
new file mode 100644
index 00000000..6eac4dff
--- /dev/null
+++ b/kalyptus/kdocLib.pm
@@ -0,0 +1,245 @@
+
+=head1 kdocLib
+
+Writes out a library file.
+
+NOTES ON THE NEW FORMAT
+
+ Stores: class name, members, hierarchy
+ node types are not stored
+
+
+ File Format Spec
+ ----------------
+
+ header
+ zero or more members, each of
+ method
+ member
+ class, each of
+ inheritance
+ zero or more members
+
+
+
+ Unrecognized lines ignored.
+
+ Sample
+ ------
+
+ <! KDOC Library HTML Reference File>
+ <VERSION="2.0">
+ <BASE URL="http://www.kde.org/API/kdecore/">
+
+ <C NAME="KApplication" REF="KApplication.html">
+ <IN NAME="QObject">
+ <ME NAME="getConfig" REF="KApplication.html#getConfig">
+ <M NAME="" REF="">
+ </C>
+
+=cut
+
+package kdocLib;
+use strict;
+
+use Carp;
+use File::Path;
+use File::Basename;
+
+use Ast;
+use kdocAstUtil;
+use kdocUtil;
+
+
+use vars qw/ $exe $lib $root $plang $outputdir $docpath $url $compress /;
+
+BEGIN {
+ $exe = basename $0;
+}
+
+sub writeDoc
+{
+ ( $lib, $root, $plang, $outputdir, $docpath, $url,
+ $compress ) = @_;
+ my $outfile = "$outputdir/$lib.kalyptus";
+ $url = $docpath unless defined $url;
+
+ mkpath( $outputdir ) unless -f $outputdir;
+
+ if( $compress ) {
+ open( LIB, "| gzip -9 > \"$outfile.gz\"" )
+ || die "$exe: couldn't write to $outfile.gz\n";
+
+ }
+ else {
+ open( LIB, ">$outfile" )
+ || die "$exe: couldn't write to $outfile\n";
+ }
+
+ my $libdesc = "";
+ if ( defined $root->{LibDoc} ) {
+ $libdesc="<LIBDESC>".$root->{LibDoc}->{astNodeName}."</LIBDESC>";
+ }
+
+ print LIB<<LTEXT;
+<! KDOC Library HTML Reference File>
+<VERSION="$main::Version">
+<BASE URL="$url">
+<PLANG="$plang">
+<LIBNAME>$lib</LIBNAME>
+$libdesc
+
+LTEXT
+
+ writeNode( $root, "" );
+ close LIB;
+}
+
+sub writeNode
+{
+ my ( $n, $prefix ) = @_;
+ return if !exists $n->{Compound};
+ return if exists $n->{Forward} && !exists $n->{KidAccess};
+
+ if( $n != $root ) {
+ $prefix .= $n->{astNodeName};
+ print LIB "<C NAME=\"", $n->{astNodeName},
+ "\" REF=\"$prefix.html\">\n";
+ }
+ else {
+ print LIB "<STATS>\n";
+ my $stats = $root->{Stats};
+ foreach my $stat ( keys %$stats ) {
+ print LIB "<STAT NAME=\"$stat\">",
+ $stats->{$stat},"</STAT>\n";
+ }
+ print LIB "</STATS>\n";
+ }
+
+ if( exists $n->{Ancestors} ) {
+ my $in;
+ foreach $in ( @{$n->{Ancestors}} ) {
+ $in =~ s/\s+//g;
+ print LIB "<IN NAME=\"",$in,"\">\n";
+ }
+ }
+
+ return if !exists $n->{Kids};
+ my $kid;
+ my $type;
+
+ foreach $kid ( @{$n->{Kids}} ) {
+ next if exists $kid->{ExtSource}
+ || $kid->{Access} eq "private";
+
+ if ( exists $kid->{Compound} ) {
+ if( $n != $root ) {
+ writeNode( $kid, $prefix."::" );
+ }
+ else {
+ writeNode( $kid, "" );
+ }
+ next;
+ }
+
+ $type = $kid->{NodeType} eq "method" ?
+ "ME" : "M";
+
+ print LIB "<$type NAME=\"", $kid->{astNodeName},
+ "\" REF=\"$prefix.html#", $kid->{astNodeName}, "\">\n";
+ }
+
+ if( $n != $root ) {
+ print LIB "</C>\n";
+ }
+}
+
+sub readLibrary
+{
+ my( $rootsub, $name, $path, $relurl ) = @_;
+ $path = "." unless defined $path;
+ my $real = $path."/".$name.".kalyptus";
+ my $url = ".";
+ my @stack = ();
+ my $version = "2.0";
+ my $new;
+ my $root = undef;
+ my $n = undef;
+ my $havecomp = -r "$real.gz";
+ my $haveuncomp = -r "$real";
+
+ if ( $haveuncomp ) {
+ open( LIB, "$real" ) || die "Can't read lib $real\n";
+ }
+
+ if( $havecomp ) {
+ if ( $haveuncomp ) {
+ warn "$exe: two libs exist: $real and $real.gz. "
+ ."Using $real\n";
+ }
+ else {
+ open( LIB, "gunzip < \"$real.gz\"|" )
+ || die "Can't read pipe gunzip < \"$real.gz\": $?\n";
+ }
+ }
+
+ while( <LIB> ) {
+ next if /^\s*$/;
+ if ( !/^\s*</ ) {
+ close LIB;
+ #readOldLibrary( $root, $name, $path );
+ return;
+ }
+
+ if( /<VER\w+\s+([\d\.]+)>/ ) {
+ # TODO: what do we do with the version number?
+ $version = $1;
+ }
+ elsif ( /<BASE\s*URL\s*=\s*"(.*?)"/ ) {
+ $url = $1;
+ $url .= "/" unless $url =~ m:/$:;
+
+ my $test = kdocUtil::makeRelativePath( $relurl, $url );
+ $url = $test;
+ }
+ elsif( /<PLANG\s*=\s*"(.*?)">/ ) {
+ $root = $rootsub->( $1 );
+ $n = $root;
+ }
+ elsif ( /<C\s*NAME="(.*?)"\s*REF="(.*?)"\s*>/ ) {
+ # class
+ $new = Ast::New( $1 );
+ $new->AddProp( "NodeType", "class" );
+ $new->AddProp( "Compound", 1 );
+ $new->AddProp( "ExtSource", $name );
+
+ # already escaped at this point!
+ $new->AddProp( "Ref", $url.$2 );
+
+ $root = $n = $rootsub->( "CXX" ) unless defined $root;
+ kdocAstUtil::attachChild( $n, $new );
+ push @stack, $n;
+ $n = $new;
+ }
+ elsif ( m#<IN\s*NAME\s*=\s*"(.*?)"\s*># ) {
+ # ancestor
+ kdocAstUtil::newInherit( $n, $1 );
+ }
+ elsif ( m#</C># ) {
+ # end class
+ $n = pop @stack;
+ }
+ elsif ( m#<(M\w*)\s+NAME="(.*?)"\s+REF="(.*?)"\s*># ) {
+ # member
+ $new = Ast::New( $2 );
+ $new->AddProp( "NodeType", $1 eq "ME" ? "method" : "var" );
+ $new->AddProp( "ExtSource", $name );
+ $new->AddProp( "Flags", "" );
+ $new->AddProp( "Ref", $url.$3 );
+
+ kdocAstUtil::attachChild( $n, $new );
+ }
+ }
+}
+
+1;
diff --git a/kalyptus/kdocParseDoc.pm b/kalyptus/kdocParseDoc.pm
new file mode 100644
index 00000000..f28b4e56
--- /dev/null
+++ b/kalyptus/kdocParseDoc.pm
@@ -0,0 +1,422 @@
+package kdocParseDoc;
+
+use Ast;
+use strict;
+
+use vars qw/ $buffer $docNode %extraprops $currentProp $propType /;
+
+=head1 kdocParseDoc
+
+ Routines for parsing of javadoc comments.
+
+=head2 newDocComment
+
+ Parameters: begin (starting line of declaration)
+
+ Reads a doc comment to the end and creates a new doc node.
+
+ Read a line
+ check if it changes the current context
+ yes
+ flush old context
+ check if it is a non-text tag
+ (ie internal/deprecated etc)
+ yes
+ reset context to text
+ set associated property
+ no
+ set the new context
+ assign text to new buffer
+ no add to text buffer
+ continue
+ at end
+ flush anything pending.
+
+=cut
+
+sub newDocComment
+{
+ my( $text ) = @_;
+ return undef unless $text =~ m#/\*\*+#;
+
+ setType( "DocText", 2 );
+ $text =~ m#/\*#; # need to do the match again, otherwise /***/ doesn't parse
+ ### TODO update this method from kdoc
+ $buffer = $'; # everything after the first \*
+ $docNode = undef;
+ %extraprops = (); # used for textprops when flushing.
+ my $finished = 0;
+ my $inbounded = 0;
+
+ if ( $buffer =~ m#\*/# ) {
+ $buffer = $`;
+ $finished = 1;
+ }
+
+PARSELOOP:
+ while ( defined $text && !$finished ) {
+ # read text and remove leading junk
+ $text = main::readSourceLine();
+ next if !defined $text;
+ $text =~ s#^\s*\*(?!\/)##;
+
+# if ( $text =~ /^\s*<\/pre>/i ) {
+# flushProp();
+# $inbounded = 0;
+# }
+ if( $inbounded ) {
+ if ( $text =~ m#\*/# ) {
+ $finished = 1;
+ $text = $`;
+ }
+ $buffer .= $text;
+ next PARSELOOP;
+ }
+# elsif ( $text =~ /^\s*<pre>/i ) {
+# textProp( "Pre" );
+# $inbounded = 1;
+# }
+ elsif ( $text =~ /^\s*$/ ) {
+ textProp( "ParaBreak", "\n" );
+ }
+ elsif ( $text =~ /^\s*\@internal\s*/ ) {
+ codeProp( "Internal", 1 );
+ }
+ elsif ( $text =~ /^\s*\@deprecated\s*/ ) {
+ codeProp( "Deprecated", 1 );
+ }
+ elsif ( $text =~ /^\s*\@obsolete\s*/ ) {
+ codeProp( "Deprecated", 1 );
+ }
+ elsif ( $text =~ /^\s*\@reimplemented\s*/ ) {
+ codeProp( "Reimplemented", 1 );
+ }
+ elsif ( $text =~ /^\s*\@group\s*/ ) {
+ # logical group tag in which this node belongs
+ # multiples allowed
+
+ my $groups = $';
+ $groups =~ s/^\s*(.*?)\s*$/$1/;
+
+ if ( $groups ne "" ) {
+ foreach my $g ( split( /[^_\w]+/, $groups) ) {
+
+ codeProp( "InGroup", $g );
+ }
+ }
+ }
+ elsif ( $text =~ /^\s*\@defgroup\s+(\w+)\s*/ ) {
+ # parse group tag and description
+ my $grptag = $1;
+ my $grpdesc = $' eq "" ? $grptag : $';
+
+ # create group node
+ my $grpnode = Ast::New( $grptag );
+ $grpnode->AddProp( "Desc", $grpdesc );
+ $grpnode->AddProp( "NodeType", "GroupDef" );
+
+ # attach
+ codeProp( "Groups", $grpnode );
+ }
+ elsif ( $text =~ /^\s*\@see\s*/ ) {
+ docListProp( "See" );
+ }
+ elsif( $text =~ /^\s*\@short\s*/ ) {
+ docProp( "ClassShort" );
+ }
+ elsif( $text =~ /^\s*\@author\s*/ ) {
+ docProp( "Author" );
+
+ }
+ elsif( $text =~ /^\s*\@version\s*/ ) {
+ docProp( "Version" );
+ }
+ elsif( $text =~ /^\s*\@id\s*/ ) {
+
+ docProp( "Id" );
+ }
+ elsif( $text =~ /^\s*\@since\s*/ ) {
+ docProp( "Since" );
+ }
+ elsif( $text =~ /^\s*\@returns?\s*/ ) {
+ docProp( "Returns" );
+ }
+ elsif( $text =~ /^\s*\@(?:throws|exception|raises)\s*/ ) {
+ docListProp( "Throws" );
+ }
+ elsif( $text =~ /^\s*\@image\s+([^\s]+)\s*/ ) {
+ textProp( "Image" );
+ $extraprops{ "Path" } = $1;
+ }
+ elsif( $text =~ /^\s*\@param\s+(\w+)\s*/ ) {
+ textProp( "Param" );
+ $extraprops{ "Name" } = $1;
+ }
+ elsif( $text =~ /^\s*\@sect\s+/ ) {
+
+ textProp( "DocSection" );
+ }
+ elsif( $text =~ /^\s*\@li\s+/ ) {
+
+ textProp( "ListItem" );
+ }
+ elsif ( $text =~ /^\s*\@libdoc\s+/ ) {
+ # Defines the text for the entire library
+ docProp( "LibDoc" );
+ }
+ else {
+ if ( $text =~ m#\*/# ) {
+ $finished = 1;
+ $text = $`;
+ }
+ $buffer .= $text;
+ }
+ }
+
+ flushProp();
+
+
+ return undef if !defined $docNode;
+
+# postprocess docnode
+
+ # add a . to the end of the short if required.
+ my $short = $docNode->{ClassShort};
+
+ if ( defined $short ) {
+ if ( !($short =~ /\.\s*$/) ) {
+ $docNode->{ClassShort} =~ s/\s*$/./;
+ }
+ }
+ else {
+ # use first line of normal text as short name.
+ if ( defined $docNode->{Text} ) {
+ my $node;
+ foreach $node ( @{$docNode->{Text}} ) {
+ next if $node->{NodeType} ne "DocText";
+ $short = $node->{astNodeName};
+ $short = $`."." if $short =~ /\./;
+ $docNode->{ClassShort} = $short;
+ goto shortdone;
+ }
+ }
+ }
+shortdone:
+
+# Join and break all word list props so that they are one string per list
+# node, ie remove all commas and spaces.
+
+ recombineOnWords( $docNode, "See" );
+ recombineOnWords( $docNode, "Throws" );
+
+ return $docNode;
+}
+
+=head3 setType
+
+ Parameters: propname, proptype ( 0 = single, 1 = list, 2 = text )
+
+ Set the name and type of the pending property.
+
+=cut
+
+sub setType
+{
+ ( $currentProp, $propType ) = @_;
+}
+
+=head3 flushProp
+
+ Flush any pending item and reset the buffer. type is set to DocText.
+
+=cut
+
+sub flushProp
+{
+ return if $buffer eq "";
+ initDocNode() unless defined $docNode;
+
+ if( $propType == 1 ) {
+ # list prop
+ $docNode->AddPropList( $currentProp, $buffer );
+ }
+ elsif ( $propType == 2 ) {
+ # text prop
+ my $textnode = Ast::New( $buffer );
+ $textnode->AddProp( 'NodeType', $currentProp );
+ $docNode->AddPropList( 'Text', $textnode );
+
+ foreach my $prop ( keys %extraprops ) {
+ $textnode->AddProp( $prop,
+ $extraprops{ $prop } );
+ }
+
+ %extraprops = ();
+ }
+ else {
+ # one-off prop
+ $docNode->AddProp( $currentProp, $buffer );
+ }
+
+ # reset buffer
+ $buffer = "";
+ setType( "DocText", 2 );
+}
+
+=head3 codeProp
+
+ Flush the last node, add a new property and reset type to DocText.
+
+=cut
+
+sub codeProp
+{
+ my( $prop, $val ) = @_;
+
+ flushProp();
+
+ initDocNode() unless defined $docNode;
+ $docNode->AddPropList( $prop, $val );
+
+ setType( "DocText", 2 );
+
+}
+
+=head3 docListProp
+
+ The next item is a list property of docNode.
+
+=cut
+
+sub docListProp
+{
+ my( $prop ) = @_;
+
+ flushProp();
+
+ $buffer = $';
+ setType( $prop, 1 );
+}
+
+=head3 docProp
+
+ The next item is a simple property of docNode.
+
+=cut
+
+sub docProp
+{
+ my( $prop ) = @_;
+
+ flushProp();
+
+ $buffer = $';
+ setType( $prop, 0 );
+}
+
+=head3 textProp
+
+ Parameters: prop, val
+
+ Set next item to be a 'Text' list node. if val is assigned, the
+ new node is assigned that text and flushed immediately. If this
+ is the case, the next item is given the 'DocText' text property.
+
+=cut
+
+sub textProp
+{
+ my( $prop, $val ) = @_;
+
+ flushProp();
+
+ if ( defined $val ) {
+ $buffer = $val;
+ setType( $prop, 2 );
+ flushProp();
+ $prop = "DocText";
+ }
+
+ setType( $prop, 2 );
+ $buffer = $';
+}
+
+
+=head3 initDocNode
+
+ Creates docNode if it is not defined.
+
+=cut
+
+sub initDocNode
+{
+ $docNode = Ast::New( "Doc" );
+ $docNode->AddProp( "NodeType", "DocNode" );
+}
+
+sub recombineOnWords
+{
+ my ( $docNode, $prop ) = @_;
+
+ if ( exists $docNode->{$prop} ) {
+ my @oldsee = @{$docNode->{$prop}};
+ @{$docNode->{$prop}} = split (/[\s,]+/, join( " ", @oldsee ));
+ }
+}
+
+###############
+
+=head2 attachDoc
+
+Connects a docnode to a code node, setting any other properties
+if required, such as groups, internal/deprecated flags etc.
+
+=cut
+
+sub attachDoc
+{
+ my ( $node, $doc, $rootnode ) = @_;
+
+ $node->AddProp( "DocNode", $doc );
+ $node->AddProp( "Internal", 1 ) if defined $doc->{Internal};
+ $node->AddProp( "Deprecated", 1 ) if defined $doc->{Deprecated};
+
+ # attach group definitions if they exist
+ if ( defined $doc->{Groups} ) {
+ my $groupdef = $rootnode->{Groups};
+ if( !defined $groupdef ) {
+ $groupdef = Ast::New( "Groups" );
+ $rootnode->AddProp( "Groups", $groupdef );
+ }
+
+ foreach my $grp ( @{$doc->{Groups}} ) {
+ if ( defined $groupdef->{ $grp->{astNodeName} } ) {
+ $groupdef->{ $grp->{ astNodeName}
+ }->AddProp( "Desc", $grp->{Desc} );
+ }
+ else {
+ $groupdef->AddProp( $grp->{astNodeName}, $grp );
+ }
+ }
+ }
+
+ # attach node to group index(es)
+ # create groups if not found, they may be parsed later.
+
+ if ( defined $doc->{InGroup} ) {
+ my $groupdef = $rootnode->{Groups};
+
+ foreach my $grp ( @{$doc->{InGroup}} ) {
+ if ( !exists $groupdef->{$grp} ) {
+ my $newgrp = Ast::New( $grp );
+ $newgrp->AddProp( "Desc", $grp );
+ $newgrp->AddProp( "NodeType", "GroupDef" );
+ $groupdef->AddProp( $grp, $newgrp );
+ }
+
+ $groupdef->{$grp}->AddPropList( "Kids", $node );
+ }
+ }
+}
+
+1;
diff --git a/kalyptus/kdocUtil.pm b/kalyptus/kdocUtil.pm
new file mode 100644
index 00000000..827b3771
--- /dev/null
+++ b/kalyptus/kdocUtil.pm
@@ -0,0 +1,194 @@
+
+package kdocUtil;
+
+use strict;
+
+
+=head1 kdocUtil
+
+ General utilities.
+
+=head2 countReg
+
+ Parameters: string, regexp
+
+ Returns the number of times of regexp occurs in string.
+
+=cut
+
+sub countReg
+{
+ my( $str, $regexp ) = @_;
+ my( $count ) = 0;
+
+ while( $str =~ /$regexp/s ) {
+ $count++;
+
+ $str =~ s/$regexp//s;
+ }
+
+ return $count;
+}
+
+=head2 findCommonPrefix
+
+ Parameters: string, string
+
+ Returns the prefix common to both strings. An empty string
+ is returned if the strings have no common prefix.
+
+=cut
+
+sub findCommonPrefix
+{
+ my @s1 = split( "/", $_[0] );
+ my @s2 = split( "/", $_[1] );
+ my $accum = "";
+ my $len = ($#s2 > $#s1 ) ? $#s1 : $#s2;
+
+ for my $i ( 0..$len ) {
+# print "Compare: $i '$s1[$i]', '$s2[$i]'\n";
+ last if $s1[ $i ] ne $s2[ $i ];
+ $accum .= $s1[ $i ]."/";
+ }
+
+ return $accum;
+}
+
+=head2 makeRelativePath
+
+ Parameters: localpath, destpath
+
+ Returns a relative path to the destination from the local path,
+ after removal of any common prefix.
+
+=cut
+
+sub makeRelativePath
+{
+ my ( $from, $to ) = @_;
+
+ # remove prefix
+ $from .= '/' unless $from =~ m#/$#;
+ $to .= '/' unless $to =~ m#/$#;
+
+ my $pfx = findCommonPrefix( $from, $to );
+
+ if ( $pfx ne "" ) {
+ $from =~ s/^$pfx//g;
+ $to =~ s/^$pfx//g;
+ }
+# print "Prefix is '$pfx'\n";
+
+ $from =~ s#/+#/#g;
+ $to =~ s#/+#/#g;
+ $pfx = countReg( $from, '\/' );
+
+ my $rel = "../" x $pfx;
+ $rel .= $to;
+
+ return $rel;
+}
+
+sub hostName
+{
+ my $host = "";
+ my @hostenvs = qw( HOST HOSTNAME COMPUTERNAME );
+
+ # Host name
+ foreach my $evar ( @hostenvs ) {
+ next unless defined $ENV{ $evar };
+
+ $host = $ENV{ $evar };
+ last;
+ }
+
+ if( $host eq "" ) {
+ $host = `uname -n`;
+ chop $host;
+ }
+
+ return $host;
+}
+
+sub userName
+{
+ my $who = "";
+ my @userenvs = qw( USERNAME USER LOGNAME );
+
+ # User name
+ foreach my $evar ( @userenvs ) {
+ next unless defined $ENV{ $evar };
+
+ $who = $ENV{ $evar };
+ last;
+ }
+
+ if( $who eq "" ) {
+ if ( $who = `whoami` ) {
+ chop $who;
+ }
+ elsif ( $who - `who am i` ) {
+ $who = ( split (/ /, $who ) )[0];
+ }
+ }
+
+ return $who;
+}
+
+=head2 splitUnnested
+ Helper to split a list using a delimiter, but looking for
+ nesting with (), {}, [] and <>.
+ Example: splitting int a, QPair<c,b> d, e=","
+ on ',' will give 3 items in the list.
+
+ Parameter: delimiter, string
+ Returns: array, after splitting the string
+
+ Thanks to Ashley Winters
+=cut
+sub splitUnnested($$) {
+ my $delim = shift;
+ my $string = shift;
+ my(%open) = (
+ '[' => ']',
+ '(' => ')',
+ '<' => '>',
+ '{' => '}',
+ );
+ my(%close) = reverse %open;
+ my @ret;
+ my $depth = 0;
+ my $start = 0;
+ my $indoublequotes = 0;
+ my $insinglequotes = 0;
+ while($string =~ /($delim|<<|>>|[][}{)(><\"\'])/g) {
+ my $c = $1;
+ 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);
+ push @ret, $subs if ($subs);
+ return @ret;
+}
+
+1;
+
diff --git a/kalyptus/perlbin b/kalyptus/perlbin
new file mode 100644
index 00000000..227afff8
--- /dev/null
+++ b/kalyptus/perlbin
@@ -0,0 +1 @@
+/usr/bin/perl