2002-01-04 02:02:28 +00:00
#!/usr/bin/perl
#
# gapi2xml.pl : Generates an XML representation of GObject based APIs.
#
# Author: Mike Kestner <mkestner@speakeasy.net>
#
2004-06-25 16:35:15 +00:00
# Copyright (c) 2001-2003 Mike Kestner
# Copyright (c) 2003-2004 Novell, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
2002-01-04 02:02:28 +00:00
##############################################################
2003-10-09 05:54:55 +00:00
$ debug = 0 ;
2002-01-04 02:02:28 +00:00
use XML::LibXML ;
2002-06-21 20:25:43 +00:00
if ( ! $ ARGV [ 2 ] ) {
die "Usage: gapi_pp.pl <srcdir> | gapi2xml.pl <namespace> <outfile> <libname>\n" ;
2002-01-04 02:02:28 +00:00
}
$ ns = $ ARGV [ 0 ] ;
2002-06-21 20:25:43 +00:00
$ libname = $ ARGV [ 2 ] ;
2002-06-14 Rachel Hestilow <hestilow@ximian.com>
* glib/GException.cs: Added.
* generator/Ctor.cs, Method.cs: Tag function as unsafe if it throws
an exception. Call parms.HandleException.
* generator/Paramaters.cs: Add property ThrowsException (based
on a trailing GError**). If ThrowsException, mask GError in the
signature, initialize a GError in Initialize, and add new method
HandleException to throw an exception if error != null.
* generator/SymbolTable.cs: Add gdk-pixbuf DLL, and GError type.
* gdk.imaging, gdk.imaging/Makefile.in, gdk.imaging/makefile.win32:
Added.
* configure.in, Makefile, makefile.win32: Build gdk.imaging.
* gtk/Makefile.in, gtk/makefile.win32: Link against gdk.imaging.
* parser/gapi2xml.pl: Support namespace renaming.
* parser/build.pl: Build gdk-pixbuf as gdk.imaging.
svn path=/trunk/gtk-sharp/; revision=5281
2002-06-14 18:27:04 +00:00
2002-01-04 02:02:28 +00:00
##############################################################
2002-06-21 20:25:43 +00:00
# Check if the filename provided exists. We parse existing files into
2002-01-04 02:02:28 +00:00
# a tree and append the namespace to the root node. If the file doesn't
# exist, we create a doc tree and root node to work with.
##############################################################
2002-06-21 20:25:43 +00:00
if ( - e $ ARGV [ 1 ] ) {
2002-01-04 02:02:28 +00:00
#parse existing file and get root node.
$ doc = XML::LibXML - > new - > parse_file ( $ ARGV [ 1 ] ) ;
$ root = $ doc - > getDocumentElement ( ) ;
} else {
$ doc = XML::LibXML::Document - > new ( ) ;
$ root = $ doc - > createElement ( 'api' ) ;
$ doc - > setDocumentElement ( $ root ) ;
2003-01-22 13:57:34 +00:00
$ warning_node = XML::LibXML::Comment - > new ( "\n\n This file was automatically generated.\n Please DO NOT MODIFY THIS FILE, modify .metadata files instead.\n\n" ) ;
$ root - > appendChild ( $ warning_node ) ;
2002-01-04 02:02:28 +00:00
}
$ ns_elem = $ doc - > createElement ( 'namespace' ) ;
2002-06-21 20:25:43 +00:00
$ ns_elem - > setAttribute ( 'name' , $ ns ) ;
$ ns_elem - > setAttribute ( 'library' , $ libname ) ;
2002-01-04 02:02:28 +00:00
$ root - > appendChild ( $ ns_elem ) ;
##############################################################
# First we parse the input for typedefs, structs, enums, and class_init funcs
# and put them into temporary hashes.
##############################################################
while ( $ line = <STDIN> ) {
if ( $ line =~ /typedef\s+(struct\s+\w+\s+)\*+(\w+);/ ) {
$ ptrs { $ 2 } = $ 1 ;
} elsif ( $ line =~ /typedef\s+(struct\s+\w+)\s+(\w+);/ ) {
2002-07-19 04:07:50 +00:00
next if ( $ 2 =~ /Private$/ ) ;
2002-07-30 23:02:12 +00:00
# fixme: siiigh
$ 2 = "GdkDrawable" if ( $ 1 eq "_GdkDrawable" ) ;
2002-01-04 02:02:28 +00:00
$ types { $ 2 } = $ 1 ;
2004-01-26 04:10:32 +00:00
} elsif ( $ line =~ /typedef\s+struct/ ) {
$ sdef = $ line ;
while ( $ line = <STDIN> ) {
$ sdef . = $ line ;
2005-07-18 21:27:00 +00:00
last if ( $ line =~ /^(deprecated)?}/ ) ;
2004-01-26 04:10:32 +00:00
}
$ sdef =~ s!/\*.*?(\*/|\n)!!g ;
$ sdef =~ s/\n\s*//g ;
$ types { $ 1 } = $ sdef if ( $ sdef =~ /.*\}\s*(\w+);/ ) ;
2004-01-26 04:53:05 +00:00
} elsif ( $ line =~ /typedef\s+(unsigned\s+\w+)\s+(\**)(\w+);/ ) {
$ types { $ 3 } = $ 1 . $ 2 ;
2003-06-14 16:15:17 +00:00
} elsif ( $ line =~ /typedef\s+(\w+)\s+(\**)(\w+);/ ) {
$ types { $ 3 } = $ 1 . $ 2 ;
2003-12-12 22:36:52 +00:00
} elsif ( $ line =~ /typedef\s+enum\s+(\w+)\s+(\w+);/ ) {
$ etypes { $ 1 } = $ 2 ;
2004-10-29 20:33:07 +00:00
} elsif ( $ line =~ /^((deprecated)?typedef\s+)?\benum\b/ ) {
2002-01-04 02:02:28 +00:00
$ edef = $ line ;
while ( $ line = <STDIN> ) {
$ edef . = $ line ;
2004-10-29 20:33:07 +00:00
last if ( $ line =~ /^(deprecated)?}\s*(\w+)?;/ ) ;
2002-01-04 02:02:28 +00:00
}
$ edef =~ s/\n\s*//g ;
$ edef =~ s | /\*.*?\*/ || g ;
2003-10-02 15:48:36 +00:00
if ( $ edef =~ /typedef.*}\s*(\w+);/ ) {
$ ename = $ 1 ;
2004-10-29 20:33:07 +00:00
} elsif ( $ edef =~ /^(deprecated)?enum\s+(\w+)\s*{/ ) {
$ ename = $ 2 ;
2003-10-02 15:48:36 +00:00
} else {
print "Unexpected enum format\n$edef" ;
next ;
}
2002-01-04 02:02:28 +00:00
$ edefs { $ ename } = $ edef ;
2002-01-10 15:01:31 +00:00
} elsif ( $ line =~ /typedef\s+\w+\s*\**\s*\(\*\s*(\w+)\)\s*\(/ ) {
2002-01-04 02:02:28 +00:00
$ fname = $ 1 ;
$ fdef = "" ;
while ( $ line !~ /;/ ) {
$ fdef . = $ line ;
$ line = <STDIN> ;
}
$ fdef . = $ line ;
$ fdef =~ s/\n\s+//g ;
2002-01-10 15:01:31 +00:00
$ fpdefs { $ fname } = $ fdef ;
2004-10-29 20:33:07 +00:00
} elsif ( $ line =~ /^(private|deprecated)?struct\s+(\w+)/ ) {
2003-11-07 18:14:35 +00:00
next if ( $ line =~ /;/ ) ;
$ sname = $ 2 ;
2002-01-04 02:02:28 +00:00
$ sdef = $ line ;
while ( $ line = <STDIN> ) {
$ sdef . = $ line ;
2004-10-29 20:33:07 +00:00
last if ( $ line =~ /^(deprecated)?}/ ) ;
2002-01-04 02:02:28 +00:00
}
2004-12-16 23:22:07 +00:00
$ sdef =~ s!/\*[^<].*?(\*/|\n)!!g ;
2002-01-04 02:02:28 +00:00
$ sdef =~ s/\n\s*//g ;
2005-07-28 21:24:55 +00:00
$ sdefs { $ sname } = $ sdef if ( ! exists ( $ sdefs { $ sname } ) ) ;
2002-06-21 Rachel Hestilow <hestilow@ximian.com>
* generator/ClassBase.cs: New base class for classes and interfaces.
* generator/InterfaceGen.cs: Inherit from ClassBase, generate declarations.
* generator/ObjectGen.cs: Move half of this into ClassBase.
* generator/Method.cs: Turn all applicable Get/Set functions into .NET
accessors. Remove redundant == overload and move into Equals, as
it was confusing "!= null".
* generator/Parameters.cs: Alter signature creation to accept "is_set"
option, add support for variable arguments. Add properties "Count",
"IsVarArgs", "VAType".
* generator/Ctor.cs: Fixup for changes in Parameters (indenting,
signature creation).
* generator/Signal.cs: Support generating declarations.
* generator/SymbolTable: Change GetObjectGen to GetClassGen.
* glib/IWrapper.cs: Move "Handle" declaration to here, so
both classes and interfaces can benefit from it.
* glib/Object.cs: Inherit from IWrapper.cs
* parser/Metadata.pm: Support attribute changes on constructors,
methods, signals, and paramater lists.
* parser/gapi2xml.pl: Parse init funcs for interfaces. Ignore "_"
functions here.
* parser/gapi_pp.pl: Remove boxed_type_register check, as it will
be caught in the init funcs.
* parser/Atk.metadata: Added.
* parser/Gtk.metadata: Add all needed signal/method collision
renames. Rename GtkEditable.Editable accessors to IsEditable,
as .NET does not like accessors with the same name as their
declaring type. Tag TreeStore constructor as varargs.
* samples/ButtonApp.cs: s/EmitAdd/Add.
* samples/Menu.cs: s/EmitAdd/Add, s/Activate/Activated.
svn path=/trunk/gtk-sharp/; revision=5394
2002-06-21 17:15:19 +00:00
} elsif ( $ line =~ /^(\w+)_(class|base)_init\b/ ) {
2002-01-04 02:02:28 +00:00
$ class = StudlyCaps ( $ 1 ) ;
$ pedef = $ line ;
while ( $ line = <STDIN> ) {
$ pedef . = $ line ;
2005-07-18 21:27:00 +00:00
last if ( $ line =~ /^(deprecated)?}/ ) ;
2002-01-04 02:02:28 +00:00
}
2002-06-25 23:19:36 +00:00
$ pedefs { lc ( $ class ) } = $ pedef ;
2002-06-21 Rachel Hestilow <hestilow@ximian.com>
* generator/ClassBase.cs: New base class for classes and interfaces.
* generator/InterfaceGen.cs: Inherit from ClassBase, generate declarations.
* generator/ObjectGen.cs: Move half of this into ClassBase.
* generator/Method.cs: Turn all applicable Get/Set functions into .NET
accessors. Remove redundant == overload and move into Equals, as
it was confusing "!= null".
* generator/Parameters.cs: Alter signature creation to accept "is_set"
option, add support for variable arguments. Add properties "Count",
"IsVarArgs", "VAType".
* generator/Ctor.cs: Fixup for changes in Parameters (indenting,
signature creation).
* generator/Signal.cs: Support generating declarations.
* generator/SymbolTable: Change GetObjectGen to GetClassGen.
* glib/IWrapper.cs: Move "Handle" declaration to here, so
both classes and interfaces can benefit from it.
* glib/Object.cs: Inherit from IWrapper.cs
* parser/Metadata.pm: Support attribute changes on constructors,
methods, signals, and paramater lists.
* parser/gapi2xml.pl: Parse init funcs for interfaces. Ignore "_"
functions here.
* parser/gapi_pp.pl: Remove boxed_type_register check, as it will
be caught in the init funcs.
* parser/Atk.metadata: Added.
* parser/Gtk.metadata: Add all needed signal/method collision
renames. Rename GtkEditable.Editable accessors to IsEditable,
as .NET does not like accessors with the same name as their
declaring type. Tag TreeStore constructor as varargs.
* samples/ButtonApp.cs: s/EmitAdd/Add.
* samples/Menu.cs: s/EmitAdd/Add, s/Activate/Activated.
svn path=/trunk/gtk-sharp/; revision=5394
2002-06-21 17:15:19 +00:00
} elsif ( $ line =~ /^(\w+)_get_type\b/ ) {
$ class = StudlyCaps ( $ 1 ) ;
$ pedef = $ line ;
while ( $ line = <STDIN> ) {
$ pedef . = $ line ;
if ( $ line =~ /g_boxed_type_register_static/ ) {
$ boxdef = $ line ;
while ( $ line !~ /;/ ) {
$ boxdef . = ( $ line = <STDIN> ) ;
}
$ boxdef =~ s/\n\s*//g ;
$ boxdef =~ /\(\"(\w+)\"/ ;
my $ boxtype = $ 1 ;
$ boxtype =~ s/($ns)Type(\w+)/$ns$2/ ;
$ boxdefs { $ boxtype } = $ boxdef ;
2005-05-04 16:54:24 +00:00
} elsif ( $ line =~ /g_(enum|flags)_register_static/ ) {
$ pedef =~ /^(\w+_get_type)/ ;
$ enum_gtype { $ class } = $ 1 ;
2002-06-21 Rachel Hestilow <hestilow@ximian.com>
* generator/ClassBase.cs: New base class for classes and interfaces.
* generator/InterfaceGen.cs: Inherit from ClassBase, generate declarations.
* generator/ObjectGen.cs: Move half of this into ClassBase.
* generator/Method.cs: Turn all applicable Get/Set functions into .NET
accessors. Remove redundant == overload and move into Equals, as
it was confusing "!= null".
* generator/Parameters.cs: Alter signature creation to accept "is_set"
option, add support for variable arguments. Add properties "Count",
"IsVarArgs", "VAType".
* generator/Ctor.cs: Fixup for changes in Parameters (indenting,
signature creation).
* generator/Signal.cs: Support generating declarations.
* generator/SymbolTable: Change GetObjectGen to GetClassGen.
* glib/IWrapper.cs: Move "Handle" declaration to here, so
both classes and interfaces can benefit from it.
* glib/Object.cs: Inherit from IWrapper.cs
* parser/Metadata.pm: Support attribute changes on constructors,
methods, signals, and paramater lists.
* parser/gapi2xml.pl: Parse init funcs for interfaces. Ignore "_"
functions here.
* parser/gapi_pp.pl: Remove boxed_type_register check, as it will
be caught in the init funcs.
* parser/Atk.metadata: Added.
* parser/Gtk.metadata: Add all needed signal/method collision
renames. Rename GtkEditable.Editable accessors to IsEditable,
as .NET does not like accessors with the same name as their
declaring type. Tag TreeStore constructor as varargs.
* samples/ButtonApp.cs: s/EmitAdd/Add.
* samples/Menu.cs: s/EmitAdd/Add, s/Activate/Activated.
svn path=/trunk/gtk-sharp/; revision=5394
2002-06-21 17:15:19 +00:00
}
2005-07-18 21:27:00 +00:00
last if ( $ line =~ /^(deprecated)?}/ ) ;
2002-01-17 00:26:46 +00:00
}
2002-06-25 23:19:36 +00:00
$ typefuncs { lc ( $ class ) } = $ pedef ;
2005-06-02 19:18:44 +00:00
} elsif ( $ line =~ /^G_DEFINE_TYPE_WITH_CODE\s*\(\s*(\w+)/ ) {
$ typefuncs { lc ( $ 1 ) } = $ line ;
2005-04-21 17:10:54 +00:00
} elsif ( $ line =~ /^(deprecated)?(const|G_CONST_RETURN)?\s*(struct\s+)?\w+\s*\**(\s*(const|G_CONST_RETURN)\s*\**)?\s*(\w+)\s*\(/ ) {
$ fname = $ 6 ;
2002-01-04 02:02:28 +00:00
$ fdef = "" ;
while ( $ line !~ /;/ ) {
$ fdef . = $ line ;
$ line = <STDIN> ;
}
$ fdef . = $ line ;
2002-01-17 Mike Kestner <mkestner@speakeasy.net>
* generator/BoxedGen.cs : Removed Name, CName, and QualifiedName.
* generator/ObjectGen.cs : Removed Name, CName, and QualifiedName.
* generator/StructBase.cs : Add Name, CName, and QualifiedName. Add
GenCtor method. Stub GetCallString, GetImportSig, and GetSignature
methods.
* generator/StructGen.cs : Removed Name, CName, and QualifiedName.
* generator/SymbolTable.cs : Add GetDllName method.
* parser/gapi2xml.pl : Fix a couple <parameters> bugs.
svn path=/trunk/gtk-sharp/; revision=2030
2002-01-17 23:44:56 +00:00
$ fdef =~ s/\n\s*//g ;
2003-07-06 04:08:13 +00:00
if ( $ fdef !~ /^_/ ) {
$ fdefs { $ fname } = $ fdef ;
}
2004-01-28 21:44:25 +00:00
} elsif ( $ line =~ /CHECK_(\w*)CAST/ ) {
$ cast_macro = $ line ;
while ( $ line =~ /\\$/ ) {
$ line = <STDIN> ;
$ cast_macro . = $ line ;
}
$ cast_macro =~ s/\\\n\s*//g ;
$ cast_macro =~ s/\s+/ /g ;
2005-02-23 17:37:06 +00:00
if ( $ cast_macro =~ /G_TYPE_CHECK_(\w+)_CAST.*,\s*(\w+),\s*(\w+)\)/ ) {
2004-01-28 21:44:25 +00:00
if ( $ 1 eq "INSTANCE" ) {
$ objects { $ 2 } = $ 3 . $ objects { $ 2 } ;
} else {
$ objects { $ 2 } . = ":$3" ;
}
2005-02-23 17:37:06 +00:00
} elsif ( $ cast_macro =~ /G_TYPE_CHECK_(\w+)_CAST.*,\s*([a-zA-Z0-9]+)_(\w+)_get_type\s*\(\),\s*(\w+)\)/ ) {
$ typename = uc ( "$2_type_$3" ) ;
if ( $ 1 eq "INSTANCE" ) {
$ objects { $ typename } = $ 4 . $ objects { $ typename } ;
} else {
$ objects { $ typename } . = ":$4" ;
}
2004-01-28 21:44:25 +00:00
} elsif ( $ cast_macro =~ /GTK_CHECK_CAST.*,\s*(\w+),\s*(\w+)/ ) {
$ objects { $ 1 } = $ 2 . $ objects { $ 1 } ;
} elsif ( $ cast_macro =~ /GTK_CHECK_CLASS_CAST.*,\s*(\w+),\s*(\w+)/ ) {
$ objects { $ 1 } . = ":$2" ;
2005-03-30 20:53:46 +00:00
} elsif ( $ cast_macro =~ /GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_CAST.*,\s*(\w+),\s*(\w+)/ ) {
$ objects { $ 1 } = $ 2 . $ objects { $ 1 } ;
2002-01-04 02:02:28 +00:00
}
2002-01-07 23:30:01 +00:00
} elsif ( $ line =~ /INSTANCE_GET_INTERFACE.*,\s*(\w+),\s*(\w+)/ ) {
$ ifaces { $ 1 } = $ 2 ;
2002-01-17 00:26:46 +00:00
} elsif ( $ line =~ /^BUILTIN\s*\{\s*\"(\w+)\".*GTK_TYPE_BOXED/ ) {
$ boxdefs { $ 1 } = $ line ;
} elsif ( $ line =~ /^BUILTIN\s*\{\s*\"(\w+)\".*GTK_TYPE_(ENUM|FLAGS)/ ) {
# ignoring these for now.
2004-10-29 20:33:07 +00:00
} elsif ( $ line =~ /^(deprecated)?\#define/ ) {
2002-07-05 20:22:21 +00:00
my $ test_ns = uc ( $ ns ) ;
2004-10-29 20:33:07 +00:00
if ( $ line =~ /^deprecated\#define\s+(\w+)\s+\"(.*)\"/ ) {
$ defines { "deprecated$1" } = $ 2 ;
} elsif ( $ line =~ /\#define\s+(\w+)\s+\"(.*)\"/ ) {
2002-07-05 20:22:21 +00:00
$ defines { $ 1 } = $ 2 ;
}
2004-12-16 23:22:07 +00:00
} elsif ( $ line !~ /\/\*/ ) {
2002-01-04 02:02:28 +00:00
print $ line ;
}
}
##############################################################
# Produce the enum definitions.
##############################################################
2003-02-21 05:54:32 +00:00
% enums = ( ) ;
2002-01-04 02:02:28 +00:00
foreach $ cname ( sort ( keys ( % edefs ) ) ) {
$ ecnt + + ;
2003-12-12 22:36:52 +00:00
$ def = $ edefs { $ cname } ;
$ cname = $ etypes { $ cname } if ( exists ( $ etypes { $ cname } ) ) ;
2003-02-21 05:54:32 +00:00
$ enums { lc ( $ cname ) } = $ cname ;
2002-01-04 02:02:28 +00:00
$ enum_elem = addNameElem ( $ ns_elem , 'enum' , $ cname , $ ns ) ;
2004-10-29 20:33:07 +00:00
if ( $ def =~ /^deprecated/ ) {
$ enum_elem - > setAttribute ( "deprecated" , "1" ) ;
$ def =~ s/deprecated//g ;
}
2005-05-04 16:54:24 +00:00
if ( $ enum_gtype { $ cname } ) {
$ enum_elem - > setAttribute ( "gtype" , $ enum_gtype { $ cname } ) ;
}
2005-05-24 18:11:33 +00:00
if ( $ def =~ /<</ ) {
2002-01-04 02:02:28 +00:00
$ enum_elem - > setAttribute ( 'type' , "flags" ) ;
} else {
$ enum_elem - > setAttribute ( 'type' , "enum" ) ;
}
2005-05-24 18:11:33 +00:00
$ def =~ /\{(.*\S)\s*\}/ ;
2002-01-04 02:02:28 +00:00
@ vals = split ( /,\s*/ , $ 1 ) ;
2004-12-22 19:12:15 +00:00
$ vals [ 0 ] =~ s/^\s+// ;
2002-01-04 02:02:28 +00:00
@ v0 = split ( /_/ , $ vals [ 0 ] ) ;
if ( @ vals > 1 ) {
$ done = 0 ;
for ( $ idx = 0 , $ regex = "" ; $ idx < @ v0 ; $ idx + + ) {
$ regex . = ( $ v0 [ $ idx ] . "_" ) ;
foreach $ val ( @ vals ) {
$ done = 1 if ( $ val !~ /$regex/ ) ;
}
last if $ done ;
}
$ common = join ( "_" , @ v0 [ 0 .. $ idx - 1 ] ) ;
} else {
$ common = join ( "_" , @ v0 [ 0 .. $# v0 - 1 ] ) ;
}
foreach $ val ( @ vals ) {
2005-05-24 18:11:33 +00:00
$ val =~ s/=\s*\(\s*(.*\S)\s*\)\s*/= \1/ ;
if ( $ val =~ /$common\_?(\w+)\s*=\s*(.*)$/ ) {
2002-01-04 02:02:28 +00:00
$ name = $ 1 ;
2005-05-24 18:11:33 +00:00
$ enumval = $ 2 ;
if ( $ enumval =~ /^(\d+|0x[0-9A-Fa-f]+)u?\s*<<\s*(\d+)$/ ) {
$ enumval = "$1 << $2" ;
} elsif ( $ enumval =~ /^$common\_?(\w+)$/ ) {
$ enumval = StudlyCaps ( lc ( $ 1 ) )
2002-01-04 02:02:28 +00:00
}
2003-11-07 18:14:35 +00:00
} elsif ( $ val =~ /$common\_?(\w+)/ ) {
2002-01-04 02:02:28 +00:00
$ name = $ 1 ; $ enumval = "" ;
} else {
2003-11-07 18:14:35 +00:00
die "Unexpected enum value: $val for common value $common\n" ;
2002-01-04 02:02:28 +00:00
}
$ val_elem = addNameElem ( $ enum_elem , 'member' ) ;
$ val_elem - > setAttribute ( 'cname' , "$common\_$name" ) ;
$ val_elem - > setAttribute ( 'name' , StudlyCaps ( lc ( $ name ) ) ) ;
if ( $ enumval ) {
$ val_elem - > setAttribute ( 'value' , $ enumval ) ;
}
}
}
##############################################################
# Parse the callbacks.
##############################################################
foreach $ cbname ( sort ( keys ( % fpdefs ) ) ) {
2005-01-07 21:29:38 +00:00
next if ( $ cbname =~ /^_/ ) ;
2002-01-04 02:02:28 +00:00
$ cbcnt + + ;
$ fdef = $ cb = $ fpdefs { $ cbname } ;
$ cb_elem = addNameElem ( $ ns_elem , 'callback' , $ cbname , $ ns ) ;
$ cb =~ /typedef\s+(.*)\(.*\).*\((.*)\);/ ;
$ ret = $ 1 ; $ params = $ 2 ;
addReturnElem ( $ cb_elem , $ ret ) ;
if ( $ params && ( $ params ne "void" ) ) {
addParamsElem ( $ cb_elem , split ( /,/ , $ params ) ) ;
}
}
2002-01-07 23:30:01 +00:00
##############################################################
# Parse the interfaces list.
##############################################################
foreach $ type ( sort ( keys ( % ifaces ) ) ) {
$ iface = $ ifaces { $ type } ;
( $ inst , $ dontcare ) = split ( /:/ , delete $ objects { $ type } ) ;
2002-06-25 23:19:36 +00:00
$ initfunc = $ pedefs { lc ( $ inst ) } ;
2002-01-07 23:30:01 +00:00
$ ifacetype = delete $ types { $ iface } ;
delete $ types { $ inst } ;
2002-06-21 Rachel Hestilow <hestilow@ximian.com>
* generator/ClassBase.cs: New base class for classes and interfaces.
* generator/InterfaceGen.cs: Inherit from ClassBase, generate declarations.
* generator/ObjectGen.cs: Move half of this into ClassBase.
* generator/Method.cs: Turn all applicable Get/Set functions into .NET
accessors. Remove redundant == overload and move into Equals, as
it was confusing "!= null".
* generator/Parameters.cs: Alter signature creation to accept "is_set"
option, add support for variable arguments. Add properties "Count",
"IsVarArgs", "VAType".
* generator/Ctor.cs: Fixup for changes in Parameters (indenting,
signature creation).
* generator/Signal.cs: Support generating declarations.
* generator/SymbolTable: Change GetObjectGen to GetClassGen.
* glib/IWrapper.cs: Move "Handle" declaration to here, so
both classes and interfaces can benefit from it.
* glib/Object.cs: Inherit from IWrapper.cs
* parser/Metadata.pm: Support attribute changes on constructors,
methods, signals, and paramater lists.
* parser/gapi2xml.pl: Parse init funcs for interfaces. Ignore "_"
functions here.
* parser/gapi_pp.pl: Remove boxed_type_register check, as it will
be caught in the init funcs.
* parser/Atk.metadata: Added.
* parser/Gtk.metadata: Add all needed signal/method collision
renames. Rename GtkEditable.Editable accessors to IsEditable,
as .NET does not like accessors with the same name as their
declaring type. Tag TreeStore constructor as varargs.
* samples/ButtonApp.cs: s/EmitAdd/Add.
* samples/Menu.cs: s/EmitAdd/Add, s/Activate/Activated.
svn path=/trunk/gtk-sharp/; revision=5394
2002-06-21 17:15:19 +00:00
2002-01-07 23:30:01 +00:00
$ ifacecnt + + ;
$ iface_el = addNameElem ( $ ns_elem , 'interface' , $ inst , $ ns ) ;
2002-08-09 03:56:27 +00:00
$ elem_table { lc ( $ inst ) } = $ iface_el ;
2002-06-21 Rachel Hestilow <hestilow@ximian.com>
* generator/ClassBase.cs: New base class for classes and interfaces.
* generator/InterfaceGen.cs: Inherit from ClassBase, generate declarations.
* generator/ObjectGen.cs: Move half of this into ClassBase.
* generator/Method.cs: Turn all applicable Get/Set functions into .NET
accessors. Remove redundant == overload and move into Equals, as
it was confusing "!= null".
* generator/Parameters.cs: Alter signature creation to accept "is_set"
option, add support for variable arguments. Add properties "Count",
"IsVarArgs", "VAType".
* generator/Ctor.cs: Fixup for changes in Parameters (indenting,
signature creation).
* generator/Signal.cs: Support generating declarations.
* generator/SymbolTable: Change GetObjectGen to GetClassGen.
* glib/IWrapper.cs: Move "Handle" declaration to here, so
both classes and interfaces can benefit from it.
* glib/Object.cs: Inherit from IWrapper.cs
* parser/Metadata.pm: Support attribute changes on constructors,
methods, signals, and paramater lists.
* parser/gapi2xml.pl: Parse init funcs for interfaces. Ignore "_"
functions here.
* parser/gapi_pp.pl: Remove boxed_type_register check, as it will
be caught in the init funcs.
* parser/Atk.metadata: Added.
* parser/Gtk.metadata: Add all needed signal/method collision
renames. Rename GtkEditable.Editable accessors to IsEditable,
as .NET does not like accessors with the same name as their
declaring type. Tag TreeStore constructor as varargs.
* samples/ButtonApp.cs: s/EmitAdd/Add.
* samples/Menu.cs: s/EmitAdd/Add, s/Activate/Activated.
svn path=/trunk/gtk-sharp/; revision=5394
2002-06-21 17:15:19 +00:00
$ classdef = $ sdefs { $ 1 } if ( $ ifacetype =~ /struct\s+(\w+)/ ) ;
if ( $ initfunc ) {
2004-11-13 05:32:26 +00:00
parseInitFunc ( $ iface_el , $ initfunc ) ;
2002-06-21 Rachel Hestilow <hestilow@ximian.com>
* generator/ClassBase.cs: New base class for classes and interfaces.
* generator/InterfaceGen.cs: Inherit from ClassBase, generate declarations.
* generator/ObjectGen.cs: Move half of this into ClassBase.
* generator/Method.cs: Turn all applicable Get/Set functions into .NET
accessors. Remove redundant == overload and move into Equals, as
it was confusing "!= null".
* generator/Parameters.cs: Alter signature creation to accept "is_set"
option, add support for variable arguments. Add properties "Count",
"IsVarArgs", "VAType".
* generator/Ctor.cs: Fixup for changes in Parameters (indenting,
signature creation).
* generator/Signal.cs: Support generating declarations.
* generator/SymbolTable: Change GetObjectGen to GetClassGen.
* glib/IWrapper.cs: Move "Handle" declaration to here, so
both classes and interfaces can benefit from it.
* glib/Object.cs: Inherit from IWrapper.cs
* parser/Metadata.pm: Support attribute changes on constructors,
methods, signals, and paramater lists.
* parser/gapi2xml.pl: Parse init funcs for interfaces. Ignore "_"
functions here.
* parser/gapi_pp.pl: Remove boxed_type_register check, as it will
be caught in the init funcs.
* parser/Atk.metadata: Added.
* parser/Gtk.metadata: Add all needed signal/method collision
renames. Rename GtkEditable.Editable accessors to IsEditable,
as .NET does not like accessors with the same name as their
declaring type. Tag TreeStore constructor as varargs.
* samples/ButtonApp.cs: s/EmitAdd/Add.
* samples/Menu.cs: s/EmitAdd/Add, s/Activate/Activated.
svn path=/trunk/gtk-sharp/; revision=5394
2002-06-21 17:15:19 +00:00
} else {
warn "Don't have an init func for $inst.\n" if $ debug ;
2004-11-13 05:32:26 +00:00
addVirtualMethods ( $ classdef , $ iface_el ) ;
2002-06-21 Rachel Hestilow <hestilow@ximian.com>
* generator/ClassBase.cs: New base class for classes and interfaces.
* generator/InterfaceGen.cs: Inherit from ClassBase, generate declarations.
* generator/ObjectGen.cs: Move half of this into ClassBase.
* generator/Method.cs: Turn all applicable Get/Set functions into .NET
accessors. Remove redundant == overload and move into Equals, as
it was confusing "!= null".
* generator/Parameters.cs: Alter signature creation to accept "is_set"
option, add support for variable arguments. Add properties "Count",
"IsVarArgs", "VAType".
* generator/Ctor.cs: Fixup for changes in Parameters (indenting,
signature creation).
* generator/Signal.cs: Support generating declarations.
* generator/SymbolTable: Change GetObjectGen to GetClassGen.
* glib/IWrapper.cs: Move "Handle" declaration to here, so
both classes and interfaces can benefit from it.
* glib/Object.cs: Inherit from IWrapper.cs
* parser/Metadata.pm: Support attribute changes on constructors,
methods, signals, and paramater lists.
* parser/gapi2xml.pl: Parse init funcs for interfaces. Ignore "_"
functions here.
* parser/gapi_pp.pl: Remove boxed_type_register check, as it will
be caught in the init funcs.
* parser/Atk.metadata: Added.
* parser/Gtk.metadata: Add all needed signal/method collision
renames. Rename GtkEditable.Editable accessors to IsEditable,
as .NET does not like accessors with the same name as their
declaring type. Tag TreeStore constructor as varargs.
* samples/ButtonApp.cs: s/EmitAdd/Add.
* samples/Menu.cs: s/EmitAdd/Add, s/Activate/Activated.
svn path=/trunk/gtk-sharp/; revision=5394
2002-06-21 17:15:19 +00:00
}
2002-01-07 23:30:01 +00:00
}
2002-01-04 02:02:28 +00:00
##############################################################
# Parse the classes by walking the objects list.
##############################################################
foreach $ type ( sort ( keys ( % objects ) ) ) {
( $ inst , $ class ) = split ( /:/ , $ objects { $ type } ) ;
$ class = $ inst . "Class" if ( ! $ class ) ;
2002-06-25 23:19:36 +00:00
$ initfunc = $ pedefs { lc ( $ inst ) } ;
$ typefunc = $ typefuncs { lc ( $ inst ) } ;
2002-01-04 02:02:28 +00:00
$ insttype = delete $ types { $ inst } ;
$ classtype = delete $ types { $ class } ;
$ instdef = $ classdef = "" ;
$ instdef = $ sdefs { $ 1 } if ( $ insttype =~ /struct\s+(\w+)/ ) ;
$ classdef = $ sdefs { $ 1 } if ( $ classtype =~ /struct\s+(\w+)/ ) ;
2004-10-29 20:33:07 +00:00
$ classdef =~ s/deprecated//g ;
2004-12-16 23:22:07 +00:00
$ instdef =~ s/\s+(\*+)([^\/])/\1 \2/g ;
2002-01-04 02:02:28 +00:00
warn "Strange Class $inst\n" if ( ! $ instdef && $ debug ) ;
$ classcnt + + ;
$ obj_el = addNameElem ( $ ns_elem , 'object' , $ inst , $ ns ) ;
2002-07-23 22:23:40 +00:00
$ elem_table { lc ( $ inst ) } = $ obj_el ;
2004-10-29 20:33:07 +00:00
# Check if the object is deprecated
if ( $ instdef =~ /^deprecatedstruct/ ) {
$ obj_el - > setAttribute ( "deprecated" , "1" ) ;
$ instdef =~ s/deprecated//g ;
}
2002-01-04 02:02:28 +00:00
# Extract parent and fields from the struct
if ( $ instdef =~ /^struct/ ) {
$ instdef =~ /\{(.*)\}/ ;
2004-01-28 21:44:25 +00:00
$ fieldstr = $ 1 ;
2004-12-16 23:22:07 +00:00
$ fieldstr =~ s | /\*[^<].*?\*/ || g ;
2004-01-28 21:44:25 +00:00
@ fields = split ( /;/ , $ fieldstr ) ;
2004-12-16 23:22:07 +00:00
addFieldElems ( $ obj_el , 'private' , @ fields ) ;
$ obj_el - > setAttribute ( 'parent' , $ obj_el - > firstChild - > getAttribute ( 'type' ) ) ;
$ obj_el - > removeChild ( $ obj_el - > firstChild ) ;
2002-01-04 02:02:28 +00:00
} elsif ( $ instdef =~ /privatestruct/ ) {
# just get the parent for private structs
$ instdef =~ /\{\s*(\w+)/ ;
$ obj_el - > setAttribute ( 'parent' , "$1" ) ;
}
# Get the props from the class_init func.
if ( $ initfunc ) {
2004-11-13 05:32:26 +00:00
parseInitFunc ( $ obj_el , $ initfunc ) ;
2002-01-04 02:02:28 +00:00
} else {
warn "Don't have an init func for $inst.\n" if $ debug ;
}
2002-06-21 Rachel Hestilow <hestilow@ximian.com>
* generator/ClassBase.cs: New base class for classes and interfaces.
* generator/InterfaceGen.cs: Inherit from ClassBase, generate declarations.
* generator/ObjectGen.cs: Move half of this into ClassBase.
* generator/Method.cs: Turn all applicable Get/Set functions into .NET
accessors. Remove redundant == overload and move into Equals, as
it was confusing "!= null".
* generator/Parameters.cs: Alter signature creation to accept "is_set"
option, add support for variable arguments. Add properties "Count",
"IsVarArgs", "VAType".
* generator/Ctor.cs: Fixup for changes in Parameters (indenting,
signature creation).
* generator/Signal.cs: Support generating declarations.
* generator/SymbolTable: Change GetObjectGen to GetClassGen.
* glib/IWrapper.cs: Move "Handle" declaration to here, so
both classes and interfaces can benefit from it.
* glib/Object.cs: Inherit from IWrapper.cs
* parser/Metadata.pm: Support attribute changes on constructors,
methods, signals, and paramater lists.
* parser/gapi2xml.pl: Parse init funcs for interfaces. Ignore "_"
functions here.
* parser/gapi_pp.pl: Remove boxed_type_register check, as it will
be caught in the init funcs.
* parser/Atk.metadata: Added.
* parser/Gtk.metadata: Add all needed signal/method collision
renames. Rename GtkEditable.Editable accessors to IsEditable,
as .NET does not like accessors with the same name as their
declaring type. Tag TreeStore constructor as varargs.
* samples/ButtonApp.cs: s/EmitAdd/Add.
* samples/Menu.cs: s/EmitAdd/Add, s/Activate/Activated.
svn path=/trunk/gtk-sharp/; revision=5394
2002-06-21 17:15:19 +00:00
# Get the interfaces from the class_init func.
if ( $ typefunc ) {
2005-06-02 19:18:44 +00:00
if ( $ typefunc =~ /G_DEFINE_TYPE_WITH_CODE/ ) {
parseTypeFuncMacro ( $ obj_el , $ typefunc ) ;
} else {
parseTypeFunc ( $ obj_el , $ typefunc ) ;
}
2002-06-21 Rachel Hestilow <hestilow@ximian.com>
* generator/ClassBase.cs: New base class for classes and interfaces.
* generator/InterfaceGen.cs: Inherit from ClassBase, generate declarations.
* generator/ObjectGen.cs: Move half of this into ClassBase.
* generator/Method.cs: Turn all applicable Get/Set functions into .NET
accessors. Remove redundant == overload and move into Equals, as
it was confusing "!= null".
* generator/Parameters.cs: Alter signature creation to accept "is_set"
option, add support for variable arguments. Add properties "Count",
"IsVarArgs", "VAType".
* generator/Ctor.cs: Fixup for changes in Parameters (indenting,
signature creation).
* generator/Signal.cs: Support generating declarations.
* generator/SymbolTable: Change GetObjectGen to GetClassGen.
* glib/IWrapper.cs: Move "Handle" declaration to here, so
both classes and interfaces can benefit from it.
* glib/Object.cs: Inherit from IWrapper.cs
* parser/Metadata.pm: Support attribute changes on constructors,
methods, signals, and paramater lists.
* parser/gapi2xml.pl: Parse init funcs for interfaces. Ignore "_"
functions here.
* parser/gapi_pp.pl: Remove boxed_type_register check, as it will
be caught in the init funcs.
* parser/Atk.metadata: Added.
* parser/Gtk.metadata: Add all needed signal/method collision
renames. Rename GtkEditable.Editable accessors to IsEditable,
as .NET does not like accessors with the same name as their
declaring type. Tag TreeStore constructor as varargs.
* samples/ButtonApp.cs: s/EmitAdd/Add.
* samples/Menu.cs: s/EmitAdd/Add, s/Activate/Activated.
svn path=/trunk/gtk-sharp/; revision=5394
2002-06-21 17:15:19 +00:00
} else {
warn "Don't have a GetType func for $inst.\n" if $ debug ;
}
2002-01-04 02:02:28 +00:00
}
##############################################################
# Parse the remaining types.
##############################################################
foreach $ key ( sort ( keys ( % types ) ) ) {
$ lasttype = $ type = $ key ;
while ( $ type && ( $ types { $ type } !~ /struct/ ) ) {
$ lasttype = $ type ;
$ type = $ types { $ type } ;
}
if ( $ types { $ type } =~ /struct\s+(\w+)/ ) {
$ type = $ 1 ;
2004-01-26 04:10:32 +00:00
if ( exists ( $ sdefs { $ type } ) ) {
$ def = $ sdefs { $ type } ;
} else {
$ def = "privatestruct" ;
}
} elsif ( $ types { $ type } =~ /struct/ && $ type =~ /^$ns/ ) {
$ def = $ types { $ type } ;
2002-01-04 02:02:28 +00:00
} else {
$ elem = addNameElem ( $ ns_elem , 'alias' , $ key , $ ns ) ;
$ elem - > setAttribute ( 'type' , $ lasttype ) ;
warn "alias $key to $lasttype\n" if $ debug ;
next ;
}
2002-07-30 23:02:12 +00:00
# fixme: hack
if ( $ key eq "GdkBitmap" ) {
$ struct_el = addNameElem ( $ ns_elem , 'object' , $ key , $ ns ) ;
} elsif ( exists ( $ boxdefs { $ key } ) ) {
2002-01-17 00:26:46 +00:00
$ struct_el = addNameElem ( $ ns_elem , 'boxed' , $ key , $ ns ) ;
} else {
$ struct_el = addNameElem ( $ ns_elem , 'struct' , $ key , $ ns ) ;
}
2002-07-23 22:23:40 +00:00
2004-10-29 20:33:07 +00:00
if ( $ def =~ /^deprecated/ ) {
$ struct_el - > setAttribute ( "deprecated" , "1" ) ;
$ def =~ s/deprecated//g ;
}
2002-07-23 22:23:40 +00:00
$ elem_table { lc ( $ key ) } = $ struct_el ;
2002-01-04 02:02:28 +00:00
$ def =~ s/\s+/ /g ;
2002-07-19 05:44:32 +00:00
if ( $ def =~ /privatestruct/ ) {
$ struct_el - > setAttribute ( 'opaque' , 'true' ) ;
} else {
$ def =~ /\{(.+)\}/ ;
2004-12-16 23:22:07 +00:00
addFieldElems ( $ struct_el , 'public' , split ( /;/ , $ 1 ) ) ;
2002-07-19 05:44:32 +00:00
}
2002-01-04 02:02:28 +00:00
}
2002-07-06 07:08:19 +00:00
2002-09-08 01:29:07 +00:00
# really, _really_ opaque structs that aren't even defined in sources. Lovely.
foreach $ key ( sort ( keys ( % ptrs ) ) ) {
next if $ ptrs { $ key } !~ /struct\s+(\w+)/ ;
$ type = $ 1 ;
$ struct_el = addNameElem ( $ ns_elem , 'struct' , $ key , $ ns ) ;
$ struct_el - > setAttribute ( 'opaque' , 'true' ) ;
$ elem_table { lc ( $ key ) } = $ struct_el ;
}
2002-07-23 22:23:40 +00:00
addFuncElems ( ) ;
2003-07-06 04:08:13 +00:00
addStaticFuncElems ( ) ;
2002-07-23 22:23:40 +00:00
2002-07-06 07:08:19 +00:00
# This should probably be done in a more generic way
foreach $ define ( sort ( keys ( % defines ) ) ) {
next if $ define !~ /[A-Z]_STOCK_/ ;
if ( $ stocks { $ ns } ) {
$ stock_el = $ stocks { $ ns } ;
} else {
$ stock_el = addNameElem ( $ ns_elem , "object" , $ ns . "Stock" , $ ns ) ;
$ stocks { $ ns } = $ stock_el ;
}
$ string_el = addNameElem ( $ stock_el , "static-string" , $ define ) ;
$ string_name = lc ( $ define ) ;
$ string_name =~ s/\w+_stock_// ;
$ string_el - > setAttribute ( 'name' , StudlyCaps ( $ string_name ) ) ;
$ string_el - > setAttribute ( 'value' , $ defines { $ define } ) ;
}
2002-01-04 02:02:28 +00:00
##############################################################
# Output the tree
##############################################################
if ( $ ARGV [ 1 ] ) {
open ( XMLFILE , ">$ARGV[1]" ) ||
die "Couldn't open $ARGV[1] for writing.\n" ;
print XMLFILE $ doc - > toString ( ) ;
close ( XMLFILE ) ;
} else {
print $ doc - > toString ( ) ;
}
##############################################################
# Generate a few stats from the parsed source.
##############################################################
$ scnt = keys ( % sdefs ) ; $ fcnt = keys ( % fdefs ) ; $ tcnt = keys ( % types ) ;
print "structs: $scnt enums: $ecnt callbacks: $cbcnt\n" ;
print "funcs: $fcnt types: $tcnt classes: $classcnt\n" ;
2004-11-05 16:47:15 +00:00
print "props: $propcnt childprops: $childpropcnt signals: $sigcnt\n\n" ;
2002-01-04 02:02:28 +00:00
sub addFieldElems
{
2004-12-16 23:22:07 +00:00
my ( $ parent , $ defaultaccess , @ fields ) = @ _ ;
my $ access = $ defaultaccess ;
2002-01-04 02:02:28 +00:00
foreach $ field ( @ fields ) {
2005-07-08 22:04:50 +00:00
if ( $ field =~ m !/\*< (public|private) >.*\*/(.*)$! ) {
2004-12-16 23:22:07 +00:00
$ access = $ 1 ;
$ field = $ 2 ;
}
2002-01-04 02:02:28 +00:00
next if ( $ field !~ /\S/ ) ;
$ field =~ s/\s+(\*+)/\1 /g ;
2005-06-20 16:09:27 +00:00
$ field =~ s/(const\s+)?(\w+)\*\s+const\*/const \2\*/g ;
2005-08-23 18:03:43 +00:00
$ field =~ s/(\w+)\s+const\s*\*/const \1\*/g ;
2002-01-04 02:02:28 +00:00
$ field =~ s/const /const\-/g ;
2002-07-26 06:08:52 +00:00
$ field =~ s/struct /struct\-/g ;
2002-07-13 Rachel Hestilow <hestilow@ximian.com>
* parser/Gnome.metadata, Gtk.metadata: More conflict
fixes.
* parser/build.pl: Fully qualify all lib names. (Gtk+ packages
are now LFS-compliant in Debian...)
* parser/gapi2xml.pl: Fix for whitespace in fields, defines,
and docs.
* generator/BoxedGen.cs: Remove extraneous CallByName definition,
add "override" keyword to FromNative.
(Generate): Generate methods after fields.
* generator/ClassBase.cs: Change CallByName, FromNative to virtual.
(.ctor): Ignore "hidden" nodes. Set container on signal.
(GenSignals, GenMethods): Add "implementor" argument for interface
use.
(Get(Method|Signal|Property)Recursively): Rework to correctly
recurse interfaces.
(Implements): Added.
* generator/Ctor.cs (Initialize): Move clash initialization completely
out of Generate, so we can check for collisions.
* generator/Method.cs (GenerateDeclCommon): Check for duplicates,
for "new" keyword.
(Generate): Add "implementor" argument.
* generator/ObjectGen.cs (Generate): Initialize ctor clashes on
this and all parents, before generating.
(Ctors, InitializeCtors): Added.
* generator/Signal.cs: Store the container_type, check for
collisions.
* generator/StructGen.cs: Add "override" keyword to overriden methods.
* gtk/FileSelection.custom (ActionArea): Add "new" keyword.
svn path=/trunk/gtk-sharp/; revision=5782
2002-07-13 20:31:23 +00:00
$ field =~ s/.*\*\///g ;
next if ( $ field !~ /\S/ ) ;
2004-10-29 20:33:07 +00:00
2002-01-04 02:02:28 +00:00
if ( $ field =~ /(\S+\s+\*?)\(\*\s*(.+)\)\s*\((.*)\)/ ) {
$ elem = addNameElem ( $ parent , 'callback' , $ 2 ) ;
addReturnElem ( $ elem , $ 1 ) ;
addParamsElem ( $ elem , $ 3 ) ;
2004-01-26 04:53:05 +00:00
} elsif ( $ field =~ /(unsigned )?(\S+)\s+(.+)/ ) {
2004-01-28 21:44:25 +00:00
my $ type = $ 1 . $ 2 ; $ symb = $ 3 ;
2002-01-04 02:02:28 +00:00
foreach $ tok ( split ( /,\s*/ , $ symb ) ) {
if ( $ tok =~ /(\w+)\s*\[(.*)\]/ ) {
2004-12-16 23:22:07 +00:00
$ elem = addNameElem ( $ parent , 'field' , $ 1 , "" ) ;
2002-01-04 02:02:28 +00:00
$ elem - > setAttribute ( 'array_len' , "$2" ) ;
2002-01-06 13:33:25 +00:00
} elsif ( $ tok =~ /(\w+)\s*\:\s*(\d+)/ ) {
2004-12-16 23:22:07 +00:00
$ elem = addNameElem ( $ parent , 'field' , $ 1 , "" ) ;
2002-01-06 13:33:25 +00:00
$ elem - > setAttribute ( 'bits' , "$2" ) ;
2002-01-04 02:02:28 +00:00
} else {
2004-12-16 23:22:07 +00:00
$ elem = addNameElem ( $ parent , 'field' , $ tok , "" ) ;
2002-01-04 02:02:28 +00:00
}
2002-01-06 13:33:25 +00:00
$ elem - > setAttribute ( 'type' , "$type" ) ;
2004-12-16 23:22:07 +00:00
if ( $ access ne $ defaultaccess ) {
$ elem - > setAttribute ( 'access' , "$access" ) ;
}
2002-01-04 02:02:28 +00:00
}
} else {
die "$field\n" ;
}
}
}
sub addFuncElems
{
2002-07-23 22:23:40 +00:00
my ( $ obj_el , $ inst , $ prefix ) ;
2002-01-04 02:02:28 +00:00
$ fcnt = keys ( % fdefs ) ;
2002-07-23 22:23:40 +00:00
foreach $ mname ( sort ( keys ( % fdefs ) ) ) {
next if ( $ mname =~ /^_/ ) ;
$ obj_el = "" ;
$ prefix = $ mname ;
2002-08-03 22:24:37 +00:00
$ prepend = undef ;
2002-07-23 22:23:40 +00:00
while ( $ prefix =~ /(\w+)_/ ) {
$ prefix = $ key = $ 1 ;
$ key =~ s/_//g ;
2002-08-03 22:24:37 +00:00
# FIXME: lame Gdk API hack
if ( $ key eq "gdkdraw" ) {
$ key = "gdkdrawable" ;
$ prepend = "draw_" ;
}
2002-07-23 22:23:40 +00:00
if ( exists ( $ elem_table { $ key } ) ) {
$ prefix . = "_" ;
$ obj_el = $ elem_table { $ key } ;
$ inst = $ key ;
last ;
2003-07-06 04:08:13 +00:00
} elsif ( exists ( $ enums { $ key } ) && ( $ mname =~ /_get_type/ ) ) {
delete $ fdefs { $ mname } ;
last ;
2002-07-23 22:23:40 +00:00
}
}
next if ( ! $ obj_el ) ;
$ mdef = delete $ fdefs { $ mname } ;
2004-10-29 20:33:07 +00:00
2002-02-08 23:56:27 +00:00
if ( $ mname =~ /$prefix(new)/ ) {
2004-10-29 20:33:07 +00:00
$ el = addNameElem ( $ obj_el , 'constructor' , $ mname ) ;
if ( $ mdef =~ /^deprecated/ ) {
$ el - > setAttribute ( "deprecated" , "1" ) ;
$ mdef =~ s/deprecated//g ;
}
2002-02-08 23:56:27 +00:00
$ drop_1st = 0 ;
2002-07-23 22:23:40 +00:00
} else {
2002-08-03 22:24:37 +00:00
$ el = addNameElem ( $ obj_el , 'method' , $ mname , $ prefix , $ prepend ) ;
2004-10-29 20:33:07 +00:00
if ( $ mdef =~ /^deprecated/ ) {
$ el - > setAttribute ( "deprecated" , "1" ) ;
$ mdef =~ s/deprecated//g ;
}
2002-07-23 22:23:40 +00:00
$ mdef =~ /(.*?)\w+\s*\(/ ;
2002-01-04 02:02:28 +00:00
addReturnElem ( $ el , $ 1 ) ;
2002-07-23 22:23:40 +00:00
$ mdef =~ /\(\s*(const)?\s*(\w+)/ ;
if ( lc ( $ 2 ) ne $ inst ) {
$ el - > setAttribute ( "shared" , "true" ) ;
$ drop_1st = 0 ;
} else {
$ drop_1st = 1 ;
}
2002-01-04 02:02:28 +00:00
}
2003-07-06 04:08:13 +00:00
parseParms ( $ el , $ mdef , $ drop_1st ) ;
2002-02-17 20:54:54 +00:00
* parser/gapi2xml.pl (addFuncElems): if a struct or boxed type has
a constructor or a ref, unref, or destroy method, then it must be
a reference type, so mark it "opaque" but then also mark all of
its fields public and writable.
* */*-api*.raw: Regen
* generator/Parser.cs (ParseNamespace): make the opaque attribute
check actually look at the value of the attribute rather than just
checking if it's there, so that you can change a struct's opaque
attribute from "true" to "false" via metadata and have that work.
* generator/BoxedGen.cs (Generate): do not generate the boxed's
"Free" method (since it's guaranteed to crash when we pass it a
stack pointer). If "Copy" is marked deprecated, create a
deprecated no-op for it, otherwise just skip it (since otherwise
it will just leak memory when we copy its result onto the stack).
* pango/Pango.metadata: deprecate Pango.Color.Copy and
Pango.Matrix.Copy. Hide some array fields in Pango.GlyphString
that we've never generated correctly. Tweak Pango.LayoutLine
fields to be the same as they used to be.
* pango/GlyphItem.custom (glyphs, item):
* pango/GlyphString.custom (Zero, New):
* pango/Item.custom (Zero, New):
* pango/LayoutRun.custom (glyphs, item): add deprecated API compat
* gdk/Gdk.metadata: undo the parser's new opaquification of
Gdk.Font; it's been deprecated since pre-gtk# times, and no one
should be using it, so there's no point in fixing it now. Fix up a
few other things to match how they used to be. Fix RgbCmap's
constructor args.
* gdk/RgbCmap.custom (Zero, New): deprecated API compat
* gdk/PangoAttrEmbossed.custom:
* gdk/PangoAttrStipple.custom (Zero, New, Attr): deprecated API
compat
(explicit operator ...): allow casting back and forth between
Pango.Attribute. (We can't usefully make them real subclasses of
Pango.Attribute, because there's no way for
Pango.Attribute.GetAttribute() to be able to dtrt with them.)
* gtk/Gtk.metadata: deprecate Gtk.Requisition.Copy,
Gtk.TextIter.Copy, and Gtk.TreeIter.Copy. Mark the return value of
TextView.DefaultAttributes as "owned". Mark TargetList's fields
private so it stays how it used to be.
* gtk/TextAttributes.custom (Zero, New): deprecated API compat
* gnomevfs/Gnomevfs.metadata: remove a bunch of opaque
declarations that the parser figures out on its own now.
* art/Art.metadata:
* glade/Glade.metadata:
* rsvg/Rsvg.metadata: un-mark everything the parser marked opaque
in these libraries, because all of the structs in question would
still be unusably broken, so the API churn would be pointless.
svn path=/trunk/gtk-sharp/; revision=48387
2005-08-15 15:15:57 +00:00
# Don't add "free" to this regexp; that will wrongly catch all boxed types
if ( $ mname =~ /$prefix(new|destroy|ref|unref)/ &&
( $ obj_el - > nodeName eq "boxed" || $ obj_el - > nodeName eq "struct" ) &&
$ obj_el - > getAttribute ( "opaque" ) ne "true" ) {
$ obj_el - > setAttribute ( "opaque" , "true" ) ;
for my $ field ( $ obj_el - > getElementsByTagName ( "field" ) ) {
if ( ! $ field - > getAttribute ( "access" ) ) {
$ field - > setAttribute ( "access" , "public" ) ;
$ field - > setAttribute ( "writeable" , "true" ) ;
}
}
}
2003-07-06 04:08:13 +00:00
}
}
sub parseParms
{
my ( $ el , $ mdef , $ drop_1st ) = @ _ ;
2005-01-19 02:31:41 +00:00
$ fmt_args = 0 ;
if ( $ mdef =~ /G_GNUC_PRINTF.*\((\d+,\s*\d+)\s*\)/ ) {
$ fmt_args = $ 1 ;
$ mdef =~ s/\s*G_GNUC_PRINTF.*\)// ;
}
2003-07-06 04:08:13 +00:00
if ( ( $ mdef =~ /\((.*)\)/ ) && ( $ 1 ne "void" ) ) {
@ parms = ( ) ;
$ parm = "" ;
$ pcnt = 0 ;
foreach $ char ( split ( // , $ 1 ) ) {
if ( $ char eq "(" ) {
$ pcnt + + ;
} elsif ( $ char eq ")" ) {
$ pcnt - - ;
} elsif ( ( $ pcnt == 0 ) && ( $ char eq "," ) ) {
2002-02-17 20:54:54 +00:00
@ parms = ( @ parms , $ parm ) ;
2003-07-06 04:08:13 +00:00
$ parm = "" ;
next ;
2002-02-17 20:54:54 +00:00
}
2003-07-06 04:08:13 +00:00
$ parm . = $ char ;
}
if ( $ parm ) {
@ parms = ( @ parms , $ parm ) ;
}
# @parms = split(/,/, $1);
( $ dump , @ parms ) = @ parms if $ drop_1st ;
if ( @ parms > 0 ) {
addParamsElem ( $ el , @ parms ) ;
}
2005-01-19 02:31:41 +00:00
if ( $ fmt_args != 0 ) {
$ fmt_args =~ /(\d+),\s*(\d+)/ ;
$ fmt = $ 1 ; $ args = $ 2 ;
( $ params_el , @ junk ) = $ el - > getElementsByTagName ( "parameters" ) ;
( @ params ) = $ params_el - > getElementsByTagName ( "parameter" ) ;
2005-01-31 15:23:41 +00:00
$ offset = 1 + $ drop_1st ;
$ params [ $ fmt - $ offset ] - > setAttribute ( "printf_format" , "true" ) ;
$ params [ $ args - $ offset ] - > setAttribute ( "printf_format_args" , "true" ) ;
2005-01-19 02:31:41 +00:00
}
2003-07-06 04:08:13 +00:00
}
}
sub addStaticFuncElems
{
my ( $ global_el , $ ns_prefix ) ;
@ mnames = sort ( keys ( % fdefs ) ) ;
$ mcount = @ mnames ;
return if ( $ mcount == 0 ) ;
$ ns_prefix = "" ;
$ global_el = "" ;
for ( $ i = 0 ; $ i < $ mcount ; $ i + + ) {
$ mname = $ mnames [ $ i ] ;
$ prefix = $ mname ;
next if ( $ prefix =~ /^_/ ) ;
if ( $ ns_prefix eq "" ) {
my ( @ toks ) = split ( /_/ , $ prefix ) ;
for ( $ j = 0 ; $ j < @ toks ; $ j + + ) {
if ( join ( "" , @ toks [ 0 .. $ j ] ) eq lc ( $ ns ) ) {
$ ns_prefix = join ( "_" , @ toks [ 0 .. $ j ] ) ;
last ;
}
}
next if ( $ ns_prefix eq "" ) ;
}
next if ( $ mname !~ /^$ns_prefix/ ) ;
if ( $ mname =~ /($ns_prefix)_([a-zA-Z]+)_\w+/ ) {
$ classname = $ 2 ;
2003-07-11 02:00:13 +00:00
$ key = $ prefix = $ 1 . "_" . $ 2 . "_" ;
$ key =~ s/_//g ;
2003-07-06 04:08:13 +00:00
$ cnt = 1 ;
2003-07-11 02:00:13 +00:00
if ( exists ( $ enums { $ key } ) ) {
$ cnt = 1 ;
} elsif ( $ classname ne "set" && $ classname ne "get" &&
2003-07-06 04:08:13 +00:00
$ classname ne "scan" && $ classname ne "find" &&
$ classname ne "add" && $ classname ne "remove" &&
$ classname ne "free" && $ classname ne "register" &&
$ classname ne "execute" && $ classname ne "show" &&
2003-10-19 01:35:24 +00:00
$ classname ne "parse" && $ classname ne "paint" &&
$ classname ne "string" ) {
2003-07-06 04:08:13 +00:00
while ( $ mnames [ $ i + $ cnt ] =~ /$prefix/ ) { $ cnt + + ; }
}
if ( $ cnt == 1 ) {
$ mdef = delete $ fdefs { $ mname } ;
2004-10-29 20:33:07 +00:00
2003-07-06 04:08:13 +00:00
if ( ! $ global_el ) {
2003-07-11 02:00:13 +00:00
$ global_el = $ doc - > createElement ( 'class' ) ;
2003-07-06 04:08:13 +00:00
$ global_el - > setAttribute ( 'name' , "Global" ) ;
2003-07-11 02:00:13 +00:00
$ global_el - > setAttribute ( 'cname' , $ ns . "Global" ) ;
2003-07-06 04:08:13 +00:00
$ ns_elem - > appendChild ( $ global_el ) ;
}
$ el = addNameElem ( $ global_el , 'method' , $ mname , $ ns_prefix ) ;
2004-10-29 20:33:07 +00:00
if ( $ mdef =~ /^deprecated/ ) {
$ el - > setAttribute ( "deprecated" , "1" ) ;
$ mdef =~ s/deprecated//g ;
}
2003-07-06 04:08:13 +00:00
$ mdef =~ /(.*?)\w+\s*\(/ ;
addReturnElem ( $ el , $ 1 ) ;
$ el - > setAttribute ( "shared" , "true" ) ;
parseParms ( $ el , $ mdef , 0 ) ;
next ;
} else {
2003-07-11 02:00:13 +00:00
$ class_el = $ doc - > createElement ( 'class' ) ;
2003-07-06 04:08:13 +00:00
$ class_el - > setAttribute ( 'name' , StudlyCaps ( $ classname ) ) ;
2003-07-11 02:00:13 +00:00
$ class_el - > setAttribute ( 'cname' , StudlyCaps ( $ prefix ) ) ;
2003-07-06 04:08:13 +00:00
$ ns_elem - > appendChild ( $ class_el ) ;
for ( $ j = 0 ; $ j < $ cnt ; $ j + + ) {
$ mdef = delete $ fdefs { $ mnames [ $ i + $ j ] } ;
2004-10-29 20:33:07 +00:00
2003-07-06 04:08:13 +00:00
$ el = addNameElem ( $ class_el , 'method' , $ mnames [ $ i + $ j ] , $ prefix ) ;
2004-10-29 20:33:07 +00:00
if ( $ mdef =~ /^deprecated/ ) {
$ el - > setAttribute ( "deprecated" , "1" ) ;
$ mdef =~ s/deprecated//g ;
}
2003-07-06 04:08:13 +00:00
$ mdef =~ /(.*?)\w+\s*\(/ ;
addReturnElem ( $ el , $ 1 ) ;
$ el - > setAttribute ( "shared" , "true" ) ;
parseParms ( $ el , $ mdef , 0 ) ;
}
$ i += ( $ cnt - 1 ) ;
next ;
2002-01-04 02:02:28 +00:00
}
}
}
}
sub addNameElem
{
2002-08-03 22:24:37 +00:00
my ( $ node , $ type , $ cname , $ prefix , $ prepend ) = @ _ ;
2002-01-04 02:02:28 +00:00
my $ elem = $ doc - > createElement ( $ type ) ;
$ node - > appendChild ( $ elem ) ;
2004-12-16 23:22:07 +00:00
if ( defined $ prefix ) {
2003-01-12 17:45:19 +00:00
my $ match ;
if ( $ cname =~ /$prefix(\w+)/ ) {
$ match = $ 1 ;
} else {
$ match = $ cname ;
}
2002-08-03 22:24:37 +00:00
if ( $ prepend ) {
2003-01-12 17:45:19 +00:00
$ name = $ prepend . $ match ;
2002-08-03 22:24:37 +00:00
} else {
2003-01-12 17:45:19 +00:00
$ name = $ match ;
2002-08-03 22:24:37 +00:00
}
$ elem - > setAttribute ( 'name' , StudlyCaps ( $ name ) ) ;
2002-01-04 02:02:28 +00:00
}
if ( $ cname ) {
$ elem - > setAttribute ( 'cname' , $ cname ) ;
}
return $ elem ;
}
sub addParamsElem
{
my ( $ parent , @ params ) = @ _ ;
my $ parms_elem = $ doc - > createElement ( 'parameters' ) ;
$ parent - > appendChild ( $ parms_elem ) ;
2003-10-20 20:02:16 +00:00
my $ parm_num = 0 ;
2002-01-04 02:02:28 +00:00
foreach $ parm ( @ params ) {
2003-10-20 20:02:16 +00:00
$ parm_num + + ;
2002-02-03 03:44:10 +00:00
$ parm =~ s/\s+(\*+)/\1 /g ;
2005-07-27 13:21:15 +00:00
my $ out = $ parm =~ s/G_CONST_RETURN/const/g ;
2005-06-20 16:09:27 +00:00
$ parm =~ s/(const\s+)?(\w+)\*\s+const\*/const \2\*/g ;
2003-12-04 17:52:02 +00:00
$ parm =~ s/(\*+)\s*const\s+/\1 /g ;
2005-08-22 23:11:08 +00:00
$ parm =~ s/(\w+)\s+const\s*\*/const \1\*/g ;
2002-01-04 02:02:28 +00:00
$ parm =~ s/const\s+/const-/g ;
2005-01-31 15:23:41 +00:00
$ parm =~ s/unsigned\s+/unsigned-/g ;
2002-02-17 20:54:54 +00:00
if ( $ parm =~ /(.*)\(\s*\**\s*(\w+)\)\s+\((.*)\)/ ) {
my $ ret = $ 1 ; my $ cbn = $ 2 ; my $ params = $ 3 ;
* parser/gapi2xml.pl (addParamsElem): change the handling of
anonymous function pointer types in method signatures. Before, we
added a <callback> child to the <parameters> node, but the
generator just ignored it. Now we add the callback (with a made-up
name) to the toplevel node, and add an ordinary <param> node
referencing it to the <parameters> node. Also, if the last param
of the callback is a gpointer, rename it from "arg#" to "data" so
it will be treated correctly (as the user data passed from the
calling method). [Fixes #66241]
* art/art-api.raw:
* gdk/gdk-api-2.4.raw:
* gdk/gdk-api-2.6.raw: Regen
* generator/Parameters.cs (IsHidden): loosen the definition of
hideable user_data; it doesn't have to occur at the end of the
parameter list, as long as there's a callback arg before it.
* generator/MethodBody.cs (GetCallString): Use Parameters.IsHidden
to decide whether or not to squash user_data params, rather than
trying to duplicate its logic. As a side effect, this also causes
a handful of methods that take non-hidden IntPtr arguments to
start actually passing those arguments to C rather than always
passing IntPtr.Zero.
* generator/Method.cs (Equals, GetHashCode): Remove unnecessary
and possibly erroneous hashing overrides.
* gtk/Gtk.metadata: Hide Gtk.Container.ForeachFull, since it's
useless and wasn't in gtk# 1.0
* gtk/Menu.custom (Popup):
* gtk/TextIter.custom (ForwardFindChar, BackwardFindChar):
* gnome/App.custom (CreateMenusInterp, InsertMenusInterp,
CreateToolbarInterp):
* gnome/Client.custom (RequestInteractionInterp):
* gnome/Popup.custom (MenuDoPopupModal, MenuDoPopup): Add
[Obsolete] compat overloads for methods that have now lost a
useless IntPtr.
svn path=/trunk/gtk-sharp/; revision=47566
2005-07-22 19:10:04 +00:00
my $ type = $ parent - > getAttribute ( 'name' ) . StudlyCaps ( $ cbn ) ;
$ cb_elem = addNameElem ( $ ns_elem , 'callback' , $ type , $ ns ) ;
2002-02-17 20:54:54 +00:00
addReturnElem ( $ cb_elem , $ ret ) ;
if ( $ params && ( $ params ne "void" ) ) {
addParamsElem ( $ cb_elem , split ( /,/ , $ params ) ) ;
* parser/gapi2xml.pl (addParamsElem): change the handling of
anonymous function pointer types in method signatures. Before, we
added a <callback> child to the <parameters> node, but the
generator just ignored it. Now we add the callback (with a made-up
name) to the toplevel node, and add an ordinary <param> node
referencing it to the <parameters> node. Also, if the last param
of the callback is a gpointer, rename it from "arg#" to "data" so
it will be treated correctly (as the user data passed from the
calling method). [Fixes #66241]
* art/art-api.raw:
* gdk/gdk-api-2.4.raw:
* gdk/gdk-api-2.6.raw: Regen
* generator/Parameters.cs (IsHidden): loosen the definition of
hideable user_data; it doesn't have to occur at the end of the
parameter list, as long as there's a callback arg before it.
* generator/MethodBody.cs (GetCallString): Use Parameters.IsHidden
to decide whether or not to squash user_data params, rather than
trying to duplicate its logic. As a side effect, this also causes
a handful of methods that take non-hidden IntPtr arguments to
start actually passing those arguments to C rather than always
passing IntPtr.Zero.
* generator/Method.cs (Equals, GetHashCode): Remove unnecessary
and possibly erroneous hashing overrides.
* gtk/Gtk.metadata: Hide Gtk.Container.ForeachFull, since it's
useless and wasn't in gtk# 1.0
* gtk/Menu.custom (Popup):
* gtk/TextIter.custom (ForwardFindChar, BackwardFindChar):
* gnome/App.custom (CreateMenusInterp, InsertMenusInterp,
CreateToolbarInterp):
* gnome/Client.custom (RequestInteractionInterp):
* gnome/Popup.custom (MenuDoPopupModal, MenuDoPopup): Add
[Obsolete] compat overloads for methods that have now lost a
useless IntPtr.
svn path=/trunk/gtk-sharp/; revision=47566
2005-07-22 19:10:04 +00:00
my $ data_parm = $ cb_elem - > lastChild ( ) - > lastChild ( ) ;
if ( $ data_parm && $ data_parm - > getAttribute ( 'type' ) eq "gpointer" ) {
$ data_parm - > setAttribute ( 'name' , 'data' ) ;
}
2002-02-17 20:54:54 +00:00
}
* parser/gapi2xml.pl (addParamsElem): change the handling of
anonymous function pointer types in method signatures. Before, we
added a <callback> child to the <parameters> node, but the
generator just ignored it. Now we add the callback (with a made-up
name) to the toplevel node, and add an ordinary <param> node
referencing it to the <parameters> node. Also, if the last param
of the callback is a gpointer, rename it from "arg#" to "data" so
it will be treated correctly (as the user data passed from the
calling method). [Fixes #66241]
* art/art-api.raw:
* gdk/gdk-api-2.4.raw:
* gdk/gdk-api-2.6.raw: Regen
* generator/Parameters.cs (IsHidden): loosen the definition of
hideable user_data; it doesn't have to occur at the end of the
parameter list, as long as there's a callback arg before it.
* generator/MethodBody.cs (GetCallString): Use Parameters.IsHidden
to decide whether or not to squash user_data params, rather than
trying to duplicate its logic. As a side effect, this also causes
a handful of methods that take non-hidden IntPtr arguments to
start actually passing those arguments to C rather than always
passing IntPtr.Zero.
* generator/Method.cs (Equals, GetHashCode): Remove unnecessary
and possibly erroneous hashing overrides.
* gtk/Gtk.metadata: Hide Gtk.Container.ForeachFull, since it's
useless and wasn't in gtk# 1.0
* gtk/Menu.custom (Popup):
* gtk/TextIter.custom (ForwardFindChar, BackwardFindChar):
* gnome/App.custom (CreateMenusInterp, InsertMenusInterp,
CreateToolbarInterp):
* gnome/Client.custom (RequestInteractionInterp):
* gnome/Popup.custom (MenuDoPopupModal, MenuDoPopup): Add
[Obsolete] compat overloads for methods that have now lost a
useless IntPtr.
svn path=/trunk/gtk-sharp/; revision=47566
2005-07-22 19:10:04 +00:00
$ parm_elem = $ doc - > createElement ( 'parameter' ) ;
$ parm_elem - > setAttribute ( 'type' , $ type ) ;
$ parm_elem - > setAttribute ( 'name' , $ cbn ) ;
$ parms_elem - > appendChild ( $ parm_elem ) ;
2002-02-17 20:54:54 +00:00
next ;
2002-07-19 04:07:50 +00:00
} elsif ( $ parm =~ /\.\.\./ ) {
$ parm_elem = $ doc - > createElement ( 'parameter' ) ;
$ parms_elem - > appendChild ( $ parm_elem ) ;
$ parm_elem - > setAttribute ( 'ellipsis' , 'true' ) ;
next ;
2002-02-17 20:54:54 +00:00
}
$ parm_elem = $ doc - > createElement ( 'parameter' ) ;
$ parms_elem - > appendChild ( $ parm_elem ) ;
2003-10-20 20:02:16 +00:00
my $ name = "" ;
2003-11-19 18:44:01 +00:00
if ( $ parm =~ /struct\s+(\S+)\s+(\S+)/ ) {
$ parm_elem - > setAttribute ( 'type' , $ 1 ) ;
$ name = $ 2 ;
2004-01-26 04:53:05 +00:00
} elsif ( $ parm =~ /(unsigned )?(\S+)\s+(\S+)/ ) {
$ parm_elem - > setAttribute ( 'type' , $ 1 . $ 2 ) ;
$ name = $ 3 ;
2003-10-20 20:02:16 +00:00
} elsif ( $ parm =~ /(\S+)/ ) {
$ parm_elem - > setAttribute ( 'type' , $ 1 ) ;
$ name = "arg" . $ parm_num ;
}
2002-06-26 Rachel Hestilow <hestilow@ximian.com>
* configure.in, makefile, makefile.win32: add gnome.
* doc/index.html, netdoc.xsl: Add gnome.
* gdk/Event.cs: New manual wrap for GdkEvent.
* generator/ClassBase.cs: Add methods GetProperty,
GetPropertyRecursively, GetMethodRecursively.
Move Parent property here from ObjectGen.cs. Pass this pointer
into Property.
* generator/Ctor.cs: Generate docs.
* generator/Method.cs, Property.cs: Tag method as "new" if a
Method/Property with the same name is found in the class hierarchy.
* generator/SignalHandler.cs: Correctly wrap complex signal argument
types. Add gnome directory.
* generator/SymbolTable.cs: Add manually wrapped types hash
(contains GLib.GSList and Gdk.Event). Add method IsManuallyWrapped.
* glib/SList.cs: Add constructor from IntPtr.
* glue/slist.c, glue/event.c: Added (field accessor glue).
* glue/Makefile.am: Update.
* parser/Gtk.metadata: Add new signal renames for new signals
exposed by GdkEvent changes.
* parser/README, parser/build.pl: Add libgnome, libgnomecanvas,
libgnomeui.
* parser/gapi2xml.pl: Handle literal-length array parameters,
and NULL property doc strings.
* sample/: Add new test GnomeHelloWorld.cs.
* gnome/: Added.
* parser/Gnome.metadata: Added.
svn path=/trunk/gtk-sharp/; revision=5461
2002-06-26 08:36:05 +00:00
if ( $ name =~ /(\w+)\[.*\]/ ) {
2002-02-03 03:44:10 +00:00
$ name = $ 1 ;
$ parm_elem - > setAttribute ( 'array' , "true" ) ;
}
2005-07-27 13:21:15 +00:00
if ( $ out ) {
$ parm_elem - > setAttribute ( 'pass_as' , "out" ) ;
}
2002-02-03 03:44:10 +00:00
$ parm_elem - > setAttribute ( 'name' , $ name ) ;
2002-01-04 02:02:28 +00:00
}
}
sub addReturnElem
{
my ( $ parent , $ ret ) = @ _ ;
2005-08-23 18:24:56 +00:00
$ ret =~ s/(\w+)\s+const\s*\*/const \1\*/g ;
2002-01-04 02:02:28 +00:00
$ ret =~ s/const|G_CONST_RETURN/const-/g ;
$ ret =~ s/\s+//g ;
2005-05-03 13:59:25 +00:00
$ ret =~ s/(const-)?(\w+)\*(const-)\*/const-\2\*\*/g ;
2002-01-04 02:02:28 +00:00
my $ ret_elem = $ doc - > createElement ( 'return-type' ) ;
$ parent - > appendChild ( $ ret_elem ) ;
$ ret_elem - > setAttribute ( 'type' , $ ret ) ;
Automatic memory management for opaque types [#49565]
* glib/Opaque.cs (Owned): new property saying whether or not gtk#
owns the memory.
(Opaque): Set Owned to true in the void ctor and false in the
IntPtr one.
(GetOpaque): add a new overload that can also create opaques, a la
GLib.Object.GetObject.
(Ref, Unref, Free): empty virtual methods to be overridden by
subclasses.
(set_Raw): Unref() and possibly Free() the old value, Ref() the
new one.
(~Opaque, Dispose): set Raw to IntPtr.Zero (triggering Free/Unref
if needed)
* parser/gapi2xml.pl (addReturnElem): if the method is named Copy
and returns a pointer, set the "owned" attribute on the
return-type.
* */*-api.raw: Regen
* generator/HandleBase.cs (FromNative): Add new
FromNative/FromNativeReturn overloads that takes a "bool owned"
param. Implement the 1-arg FromNative and FromNativeReturn in
terms of that.
* generator/ObjectBase.cs (FromNative): Implement HandleBase's new
overload. Use the two-arg version of GLib.Object.GetObject when
"owned" is true.
* generator/OpaqueGen.cs (Generate): Pull out Ref, Unref, and
Free/Destroy/Dispose methods and handle them specially by
overriding Opaque.Ref, .Unref, and .Free appropriately. (If any
of the methods are marked deprecated, output a deprecated
do-nothing method as well, to save us from having to write all
those deprecated methods by hand.)
(FromNative): use GetOpaque, passing "owned".
* generator/ReturnValue.cs (FromNative): if the value is a
HandleBase, pass Owned to its FromNative().
* generator/Parameters.cs (Owned): new property (for use on out
params)
(FromNative): Call FromNative() on the generatable, handling Owned
in the case of HandleBase.
* generator/ManagedCallString.cs:
* generator/MethodBody.cs:
* generator/Signal.cs: use param.FromNative() rather than
param.Generatable.FromNative(), to get ownership right.
* */*.metadata: Mark opaque ref/unref/free methods deprecated
(except where we were hiding them before). Add "owned" attributes
to return values and out params as needed.
* pango/AttrIterator.custom (GetFont): work around a
memory-management oddity of the underlying method.
* pango/AttrFontDesc.cs (AttrFontDesc): copy the passed-in
FontDescriptor, since the attribute will assume ownership of it.
* gtk/TreeView.custom (GetPathAtPos): set the "owned" flag on the
returned TreePaths.
* gtk/TargetList.custom: Remove refcounting stuff, which is
now handled automatically
* gtk/NodeStore.cs (GetPath): clear the Owned flag on the created
TreePath so that the underlying structure doesn't get freed when
the function returns
* gtkhtml/HTMLStream.custom (Destroy): hide this and then
reimplement it by hand to keep OpaqueGen from using it in
Dispose(), since calling it after an HTMLStream.Close() will
result in a crash.
svn path=/trunk/gtk-sharp/; revision=47928
2005-08-02 18:45:21 +00:00
if ( $ parent - > getAttribute ( 'name' ) eq "Copy" && $ ret =~ /\*$/ ) {
$ ret_elem - > setAttribute ( 'owned' , 'true' ) ;
}
2002-01-04 02:02:28 +00:00
return $ ret_elem ;
}
sub addPropElem
{
2004-11-05 16:47:15 +00:00
my ( $ spec , $ node , $ is_child ) = @ _ ;
2002-01-04 02:02:28 +00:00
my ( $ name , $ mode , $ docs ) ;
2002-01-12 02:08:16 +00:00
$ spec =~ /g_param_spec_(\w+)\s*\((.*)\s*\)\s*\)/ ;
2002-01-04 02:02:28 +00:00
my $ type = $ 1 ;
2002-01-12 02:08:16 +00:00
my @ params = split ( /,/ , $ 2 ) ;
2002-01-04 02:02:28 +00:00
2002-01-12 02:08:16 +00:00
$ name = $ params [ 0 ] ;
2002-07-05 20:22:21 +00:00
if ( $ defines { $ name } ) {
$ name = $ defines { $ name } ;
} else {
2002-07-13 Rachel Hestilow <hestilow@ximian.com>
* parser/Gnome.metadata, Gtk.metadata: More conflict
fixes.
* parser/build.pl: Fully qualify all lib names. (Gtk+ packages
are now LFS-compliant in Debian...)
* parser/gapi2xml.pl: Fix for whitespace in fields, defines,
and docs.
* generator/BoxedGen.cs: Remove extraneous CallByName definition,
add "override" keyword to FromNative.
(Generate): Generate methods after fields.
* generator/ClassBase.cs: Change CallByName, FromNative to virtual.
(.ctor): Ignore "hidden" nodes. Set container on signal.
(GenSignals, GenMethods): Add "implementor" argument for interface
use.
(Get(Method|Signal|Property)Recursively): Rework to correctly
recurse interfaces.
(Implements): Added.
* generator/Ctor.cs (Initialize): Move clash initialization completely
out of Generate, so we can check for collisions.
* generator/Method.cs (GenerateDeclCommon): Check for duplicates,
for "new" keyword.
(Generate): Add "implementor" argument.
* generator/ObjectGen.cs (Generate): Initialize ctor clashes on
this and all parents, before generating.
(Ctors, InitializeCtors): Added.
* generator/Signal.cs: Store the container_type, check for
collisions.
* generator/StructGen.cs: Add "override" keyword to overriden methods.
* gtk/FileSelection.custom (ActionArea): Add "new" keyword.
svn path=/trunk/gtk-sharp/; revision=5782
2002-07-13 20:31:23 +00:00
$ name =~ s/\s*\"//g ;
2002-07-05 20:22:21 +00:00
}
2002-01-12 02:08:16 +00:00
$ mode = $ params [ $# params ] ;
2004-12-20 22:05:21 +00:00
if ( $ type =~ /boolean|float|double|^u?int|pointer|unichar/ ) {
2002-01-04 02:02:28 +00:00
$ type = "g$type" ;
} elsif ( $ type =~ /string/ ) {
$ type = "gchar*" ;
2003-07-05 04:07:48 +00:00
} elsif ( $ type =~ /boxed|object/ ) {
$ type = $ params [ $# params - 1 ] ;
$ type =~ s/TYPE_// ;
$ type =~ s/\s+//g ;
$ type = StudlyCaps ( lc ( $ type ) ) ;
} elsif ( $ type =~ /enum|flags/ ) {
$ type = $ params [ $# params - 2 ] ;
2002-01-04 02:02:28 +00:00
$ type =~ s/TYPE_// ;
2002-01-12 02:08:16 +00:00
$ type =~ s/\s+//g ;
2002-01-04 02:02:28 +00:00
$ type = StudlyCaps ( lc ( $ type ) ) ;
}
2004-11-05 16:47:15 +00:00
$ prop_elem = $ doc - > createElement ( $ is_child ? "childprop" : "property" ) ;
2002-01-04 02:02:28 +00:00
$ node - > appendChild ( $ prop_elem ) ;
2002-01-12 02:08:16 +00:00
$ prop_elem - > setAttribute ( 'name' , StudlyCaps ( $ name ) ) ;
$ prop_elem - > setAttribute ( 'cname' , $ name ) ;
2002-01-04 02:02:28 +00:00
$ prop_elem - > setAttribute ( 'type' , $ type ) ;
2002-01-12 02:08:16 +00:00
$ prop_elem - > setAttribute ( 'readable' , "true" ) if ( $ mode =~ /READ/ ) ;
$ prop_elem - > setAttribute ( 'writeable' , "true" ) if ( $ mode =~ /WRIT/ ) ;
2005-06-10 15:46:24 +00:00
$ prop_elem - > setAttribute ( 'construct' , "true" ) if ( $ mode =~ /CONSTRUCT(?!_)/ ) ;
$ prop_elem - > setAttribute ( 'construct-only' , "true" ) if ( $ mode =~ /CONSTRUCT_ONLY/ ) ;
2002-01-04 02:02:28 +00:00
}
2004-01-28 21:44:25 +00:00
sub parseTypeToken
{
my ( $ tok ) = @ _ ;
if ( $ tok =~ /G_TYPE_(\w+)/ ) {
my $ type = $ 1 ;
if ( $ type eq "NONE" ) {
return "void" ;
} elsif ( $ type eq "INT" ) {
return "gint32" ;
} elsif ( $ type eq "UINT" ) {
return "guint32" ;
} elsif ( $ type eq "ENUM" || $ type eq "FLAGS" ) {
return "gint32" ;
} elsif ( $ type eq "STRING" ) {
return "gchar*" ;
} elsif ( $ type eq "OBJECT" ) {
return "GObject*" ;
} else {
return "g" . lc ( $ type ) ;
}
} else {
$ tok =~ s/_TYPE// ;
$ tok =~ s/\|.*STATIC_SCOPE// ;
2005-02-23 20:16:40 +00:00
$ tok =~ s/\W+//g ;
2004-01-28 21:44:25 +00:00
return StudlyCaps ( lc ( $ tok ) ) ;
}
}
2002-01-04 02:02:28 +00:00
sub addSignalElem
{
my ( $ spec , $ class , $ node ) = @ _ ;
$ spec =~ s/\n\s*//g ; $ class =~ s/\n\s*//g ;
$ sig_elem = $ doc - > createElement ( 'signal' ) ;
$ node - > appendChild ( $ sig_elem ) ;
2002-02-15 01:08:57 +00:00
if ( $ spec =~ /\(\"([\w\-]+)\"/ ) {
$ sig_elem - > setAttribute ( 'name' , StudlyCaps ( $ 1 ) ) ;
$ sig_elem - > setAttribute ( 'cname' , $ 1 ) ;
}
2002-01-04 02:02:28 +00:00
$ sig_elem - > setAttribute ( 'when' , $ 1 ) if ( $ spec =~ /_RUN_(\w+)/ ) ;
my $ method = "" ;
if ( $ spec =~ /_OFFSET\s*\(\w+,\s*(\w+)\)/ ) {
$ method = $ 1 ;
} else {
@ args = split ( /,/ , $ spec ) ;
2004-01-28 21:44:25 +00:00
my $ rettype = parseTypeToken ( $ args [ 7 ] ) ;
addReturnElem ( $ sig_elem , $ rettype ) ;
$ parmcnt = $ args [ 8 ] ;
$ parmcnt =~ s/.*(\d+).*/\1/ ;
$ parms_elem = $ doc - > createElement ( 'parameters' ) ;
$ sig_elem - > appendChild ( $ parms_elem ) ;
$ parm_elem = $ doc - > createElement ( 'parameter' ) ;
$ parms_elem - > appendChild ( $ parm_elem ) ;
$ parm_elem - > setAttribute ( 'name' , "inst" ) ;
$ parm_elem - > setAttribute ( 'type' , "$inst*" ) ;
for ( my $ idx = 0 ; $ idx < $ parmcnt ; $ idx + + ) {
my $ argtype = parseTypeToken ( $ args [ 9 + $ idx ] ) ;
$ parm_elem = $ doc - > createElement ( 'parameter' ) ;
$ parms_elem - > appendChild ( $ parm_elem ) ;
$ parm_elem - > setAttribute ( 'name' , "p$idx" ) ;
$ parm_elem - > setAttribute ( 'type' , $ argtype ) ;
2002-01-04 02:02:28 +00:00
}
2004-03-18 20:25:07 +00:00
return $ class ;
2002-01-04 02:02:28 +00:00
}
2006-07-15 05:22:11 +00:00
if ( $ class =~ /;\s*(\/\*< public >\*\/)?(G_CONST_RETURN\s+)?(\w+\s*\**)\s*\(\s*\*\s*$method\)\s*\((.*?)\);/ ) {
$ ret = $ 3 ; $ parms = $ 4 ;
2002-01-04 02:02:28 +00:00
addReturnElem ( $ sig_elem , $ ret ) ;
if ( $ parms && ( $ parms ne "void" ) ) {
addParamsElem ( $ sig_elem , split ( /,/ , $ parms ) ) ;
}
2006-07-15 05:22:11 +00:00
$ class =~ s/;\s*(\/\*< public >\*\/)?(G_CONST_RETURN\s+)?\w+\s*\**\s*\(\s*\*\s*$method\)\s*\(.*?\);/;/ ;
2002-01-04 02:02:28 +00:00
} else {
die "$method $class" ;
}
2004-03-18 20:25:07 +00:00
return $ class ;
2004-03-08 18:08:48 +00:00
}
2002-01-04 02:02:28 +00:00
2004-03-08 18:08:48 +00:00
sub addVirtualMethods
{
my ( $ class , $ node ) = @ _ ;
$ class =~ s/\n\s*//g ;
2004-12-16 23:22:07 +00:00
$ class =~ s/\/\*.*?\*\///g ;
2004-03-08 18:08:48 +00:00
2005-04-21 17:10:54 +00:00
while ( $ class =~ /;\s*(G_CONST_RETURN\s+)?(\S+\s*\**)\s*\(\s*\*\s*(\w+)\)\s*\((.*?)\);/ ) {
2004-11-13 05:32:26 +00:00
$ ret = $ 1 . $ 2 ; $ cname = $ 3 ; $ parms = $ 4 ;
2004-03-08 18:08:48 +00:00
if ( $ cname !~ /reserved/ ) {
$ vm_elem = $ doc - > createElement ( 'virtual_method' ) ;
$ node - > appendChild ( $ vm_elem ) ;
$ vm_elem - > setAttribute ( 'name' , StudlyCaps ( $ cname ) ) ;
$ vm_elem - > setAttribute ( 'cname' , $ cname ) ;
addReturnElem ( $ vm_elem , $ ret ) ;
if ( $ parms && ( $ parms ne "void" ) ) {
addParamsElem ( $ vm_elem , split ( /,/ , $ parms ) ) ;
}
}
2005-04-21 17:10:54 +00:00
$ class =~ s/;\s*(G_CONST_RETURN\s+)?\S+\s*\**\s*\(\s*\*\s*\w+\)\s*\(.*?\);/;/ ;
2004-03-08 18:08:48 +00:00
}
2002-01-04 02:02:28 +00:00
}
2002-06-21 Rachel Hestilow <hestilow@ximian.com>
* generator/ClassBase.cs: New base class for classes and interfaces.
* generator/InterfaceGen.cs: Inherit from ClassBase, generate declarations.
* generator/ObjectGen.cs: Move half of this into ClassBase.
* generator/Method.cs: Turn all applicable Get/Set functions into .NET
accessors. Remove redundant == overload and move into Equals, as
it was confusing "!= null".
* generator/Parameters.cs: Alter signature creation to accept "is_set"
option, add support for variable arguments. Add properties "Count",
"IsVarArgs", "VAType".
* generator/Ctor.cs: Fixup for changes in Parameters (indenting,
signature creation).
* generator/Signal.cs: Support generating declarations.
* generator/SymbolTable: Change GetObjectGen to GetClassGen.
* glib/IWrapper.cs: Move "Handle" declaration to here, so
both classes and interfaces can benefit from it.
* glib/Object.cs: Inherit from IWrapper.cs
* parser/Metadata.pm: Support attribute changes on constructors,
methods, signals, and paramater lists.
* parser/gapi2xml.pl: Parse init funcs for interfaces. Ignore "_"
functions here.
* parser/gapi_pp.pl: Remove boxed_type_register check, as it will
be caught in the init funcs.
* parser/Atk.metadata: Added.
* parser/Gtk.metadata: Add all needed signal/method collision
renames. Rename GtkEditable.Editable accessors to IsEditable,
as .NET does not like accessors with the same name as their
declaring type. Tag TreeStore constructor as varargs.
* samples/ButtonApp.cs: s/EmitAdd/Add.
* samples/Menu.cs: s/EmitAdd/Add, s/Activate/Activated.
svn path=/trunk/gtk-sharp/; revision=5394
2002-06-21 17:15:19 +00:00
sub addImplementsElem
{
my ( $ spec , $ node ) = @ _ ;
$ spec =~ s/\n\s*//g ;
if ( $ spec =~ /,\s*(\w+)_TYPE_(\w+),/ ) {
$ impl_elem = $ doc - > createElement ( 'interface' ) ;
$ name = StudlyCaps ( lc ( "$1_$2" ) ) ;
$ impl_elem - > setAttribute ( "cname" , "$name" ) ;
$ node - > appendChild ( $ impl_elem ) ;
}
}
2002-01-04 02:02:28 +00:00
sub parseInitFunc
{
2004-11-13 05:32:26 +00:00
my ( $ obj_el , $ initfunc ) = @ _ ;
2002-01-04 02:02:28 +00:00
my @ init_lines = split ( /\n/ , $ initfunc ) ;
my $ linenum = 0 ;
while ( $ linenum < @ init_lines ) {
my $ line = $ init_lines [ $ linenum ] ;
2002-01-12 02:08:16 +00:00
if ( $ line =~ /#define/ ) {
# FIXME: This ignores the bool helper macro thingie.
2005-07-22 18:35:37 +00:00
} elsif ( $ line =~ /g_object_(class|interface)_install_prop/ ) {
2002-01-12 02:08:16 +00:00
my $ prop = $ line ;
do {
$ prop . = $ init_lines [ + + $ linenum ] ;
2003-10-07 19:28:40 +00:00
} until ( $ init_lines [ $ linenum ] =~ /\)\s*;/ ) ;
2004-11-05 16:47:15 +00:00
addPropElem ( $ prop , $ obj_el , 0 ) ;
2002-01-12 02:08:16 +00:00
$ propcnt + + ;
2004-11-05 16:47:15 +00:00
} elsif ( $ line =~ /gtk_container_class_install_child_property/ ) {
my $ prop = $ line ;
do {
$ prop . = $ init_lines [ + + $ linenum ] ;
} until ( $ init_lines [ $ linenum ] =~ /\)\s*;/ ) ;
addPropElem ( $ prop , $ obj_el , 1 ) ;
$ childpropcnt + + ;
2004-01-28 21:44:25 +00:00
} elsif ( $ line =~ /\bg.*_signal_new/ ) {
2002-01-12 02:08:16 +00:00
my $ sig = $ line ;
do {
$ sig . = $ init_lines [ + + $ linenum ] ;
} until ( $ init_lines [ $ linenum ] =~ /;/ ) ;
2004-03-18 20:25:07 +00:00
$ classdef = addSignalElem ( $ sig , $ classdef , $ obj_el ) ;
2002-01-12 02:08:16 +00:00
$ sigcnt + + ;
2002-01-04 02:02:28 +00:00
}
$ linenum + + ;
}
2004-03-08 18:08:48 +00:00
2004-11-13 05:32:26 +00:00
addVirtualMethods ( $ classdef , $ obj_el ) ;
2002-01-04 02:02:28 +00:00
}
2005-06-02 19:18:44 +00:00
sub parseTypeFuncMacro
{
my ( $ obj_el , $ typefunc ) = @ _ ;
$ impls_node = undef ;
while ( $ typefunc =~ /G_IMPLEMENT_INTERFACE\s*\(\s*(\w+)/ ) {
$ iface = $ 1 ;
if ( not $ impls_node ) {
$ impls_node = $ doc - > createElement ( "implements" ) ;
$ obj_el - > appendChild ( $ impls_node ) ;
}
addImplementsElem ( $ prop , $ impl_node ) ;
if ( $ iface =~ /(\w+)_TYPE_(\w+)/ ) {
$ impl_elem = $ doc - > createElement ( 'interface' ) ;
$ name = StudlyCaps ( lc ( "$1_$2" ) ) ;
$ impl_elem - > setAttribute ( "cname" , "$name" ) ;
$ impls_node - > appendChild ( $ impl_elem ) ;
}
$ typefunc =~ s/G_IMPLEMENT_INTERFACE\s*\(.*?\)// ;
}
}
2002-06-21 Rachel Hestilow <hestilow@ximian.com>
* generator/ClassBase.cs: New base class for classes and interfaces.
* generator/InterfaceGen.cs: Inherit from ClassBase, generate declarations.
* generator/ObjectGen.cs: Move half of this into ClassBase.
* generator/Method.cs: Turn all applicable Get/Set functions into .NET
accessors. Remove redundant == overload and move into Equals, as
it was confusing "!= null".
* generator/Parameters.cs: Alter signature creation to accept "is_set"
option, add support for variable arguments. Add properties "Count",
"IsVarArgs", "VAType".
* generator/Ctor.cs: Fixup for changes in Parameters (indenting,
signature creation).
* generator/Signal.cs: Support generating declarations.
* generator/SymbolTable: Change GetObjectGen to GetClassGen.
* glib/IWrapper.cs: Move "Handle" declaration to here, so
both classes and interfaces can benefit from it.
* glib/Object.cs: Inherit from IWrapper.cs
* parser/Metadata.pm: Support attribute changes on constructors,
methods, signals, and paramater lists.
* parser/gapi2xml.pl: Parse init funcs for interfaces. Ignore "_"
functions here.
* parser/gapi_pp.pl: Remove boxed_type_register check, as it will
be caught in the init funcs.
* parser/Atk.metadata: Added.
* parser/Gtk.metadata: Add all needed signal/method collision
renames. Rename GtkEditable.Editable accessors to IsEditable,
as .NET does not like accessors with the same name as their
declaring type. Tag TreeStore constructor as varargs.
* samples/ButtonApp.cs: s/EmitAdd/Add.
* samples/Menu.cs: s/EmitAdd/Add, s/Activate/Activated.
svn path=/trunk/gtk-sharp/; revision=5394
2002-06-21 17:15:19 +00:00
sub parseTypeFunc
{
my ( $ obj_el , $ typefunc ) = @ _ ;
my @ type_lines = split ( /\n/ , $ typefunc ) ;
my $ linenum = 0 ;
$ impl_node = undef ;
while ( $ linenum < @ type_lines ) {
my $ line = $ type_lines [ $ linenum ] ;
if ( $ line =~ /#define/ ) {
# FIXME: This ignores the bool helper macro thingie.
} elsif ( $ line =~ /g_type_add_interface_static/ ) {
my $ prop = $ line ;
do {
$ prop . = $ type_lines [ + + $ linenum ] ;
} until ( $ type_lines [ $ linenum ] =~ /;/ ) ;
if ( not $ impl_node ) {
$ impl_node = $ doc - > createElement ( "implements" ) ;
$ obj_el - > appendChild ( $ impl_node ) ;
}
addImplementsElem ( $ prop , $ impl_node ) ;
}
$ linenum + + ;
}
}
2002-01-04 02:02:28 +00:00
##############################################################
# Converts a dash or underscore separated name to StudlyCaps.
##############################################################
% num2txt = ( '1' , "One" , '2' , "Two" , '3' , "Three" , '4' , "Four" , '5' , "Five" ,
'6' , "Six" , '7' , "Seven" , '8' , "Eight" , '9' , "Nine" , '0' , "Zero" ) ;
sub StudlyCaps
{
my ( $ symb ) = @ _ ;
$ symb =~ s/^([a-z])/\u\1/ ;
$ symb =~ s/^(\d)/\1_/ ;
$ symb =~ s/[-_]([a-z])/\u\1/g ;
$ symb =~ s/[-_](\d)/\1/g ;
$ symb =~ s/^2/Two/ ;
$ symb =~ s/^3/Three/ ;
return $ symb ;
}