GtkSharp/parser/gapi_pp.pl
Mike Kestner d41f6593b0 2004-02-10 Mike Kestner <mkestner@ximian.com>
* art/Art.metadata : mark a field private
	* art/art-api.xml : regen
	* gda/Gda.metadata : mark a few structs opaque
	* gda/gda-api.xml : regen
	* gdk/*.custom : fix changed field names
	* gdk/gdk-api.xml : regen
	* generator/Field.cs : StudlyCase simple typed field names.
	* gnome/Gnome.metadata : mark FontEntry.weight private to
	avoid collision with Weight field. s|//|/api/namespace|g
	* gnome/gnome-api.xml : regen
	* gtk/Gtk.metadata : rename AccelKey.accel_key to key to
	avoid collision with type name.
	* gtk/*.custom : fix changed field names
	* gtk/gtk-api.xml : regen
	* pango/pango-api.xml : regen
	* parser/gapi_pp.pl : add a private_regex to hide BACKEND
	and ENGINE apis, which are by convention private.
	* sample/* : make compile
	* sample/GtkDemo/* : make compile
	* sample/test/* : make compile
	* sources/gtk-sharp-sources.xml : exclude a bunch of pango
	source files.

svn path=/trunk/gtk-sharp/; revision=22947
2004-02-10 16:04:50 +00:00

196 lines
4.6 KiB
Perl
Executable file

#!/usr/bin/perl
#
# gapi_pp.pl : A source preprocessor for the extraction of API info from a
# C library source directory.
#
# Authors: Mike Kestner <mkestner@speakeasy.net>
# Martin Willemoes Hansen <mwh@sysrq.dk>
#
# <c> 2001 Mike Kestner
# <c> 2003 Martin Willemoes Hansen
# <c> 2003 Novell, Inc.
$private_regex = "^#if.*(ENABLE_BACKEND|ENABLE_ENGINE)";
$eatit_regex = "^#if.*(__cplusplus|DEBUG|DISABLE_(DEPRECATED|COMPAT)|ENABLE_BROKEN|COMPILATION)";
$ignoreit_regex = '^\s+\*|#ident|#\s*include|#\s*else|#\s*endif|#\s*undef|G_(BEGIN|END)_DECLS|extern|GDKVAR|GTKVAR|GTKMAIN_C_VAR|GTKTYPEUTILS_VAR|VARIABLE|GTKTYPEBUILTIN';
foreach $arg (@ARGV) {
if (-d $arg && -e $arg) {
@hdrs = (@hdrs, `ls $arg/*.h`);
@srcs = (@srcs, `ls $arg/*.c`);
} elsif (-f $arg && -e $arg) {
@hdrs = (@hdrs, $arg) if ($arg =~ /\.h$/);
@srcs = (@srcs, $arg) if ($arg =~ /\.c$/);
} else {
die "unable to process arg: $arg";
}
}
foreach $fname (@hdrs) {
if ($fname =~ /test|private|internals|gtktextlayout|gtkmarshalers/) {
@privhdrs = (@privhdrs, $fname);
next;
}
open(INFILE, $fname) || die "Could open $fname\n";
$braces = 0;
$prepend = "";
while ($line = <INFILE>) {
$braces++ if ($line =~ /{/ and $line !~ /}/);
$braces-- if ($line =~ /}/ and $line !~ /{/);
next if ($line =~ /$ignoreit_regex/);
$line =~ s/\/\*.*?\*\///g;
next if ($line !~ /\S/);
$line = $prepend . $line;
$prepend = "";
if ($line =~ /#\s*define\s+\w+\s+\"/) {
$def = $line;
while ($def !~ /\".*\"/) {$def .= ($line = <INFILE>);}
print $def;
} elsif ($line =~ /#\s*define\s+\w+\s*\D+/) {
$def = $line;
while ($line =~ /\\\n/) {$def .= ($line = <INFILE>);}
if ($def =~ /_CHECK_\w*CAST|INSTANCE_GET_INTERFACE/) {
$def =~ s/\\\n//g;
print $def;
}
} elsif ($line =~ /^\s*\/\*/) {
while ($line !~ /\*\//) {$line = <INFILE>;}
} elsif ($line =~ /^#ifndef\s+\w+_H_*\b/) {
while ($line !~ /#define/) {$line = <INFILE>;}
} elsif ($line =~ /$private_regex/) {
$nested = 0;
while ($line = <INFILE>) {
last if (!$nested && ($line =~ /#else|#endif/));
if ($line =~ /#if/) {
$nested++;
} elsif ($line =~ /#endif/) {
$nested--
}
next if ($line !~ /^struct/);
print "private$line";
do {
$line = <INFILE>;
print $line;
} until ($line =~ /^\}/);
}
} elsif ($line =~ /$eatit_regex/) {
$nested = 0;
while ($line = <INFILE>) {
last if (!$nested && ($line =~ /#else|#endif/));
if ($line =~ /#if/) {
$nested++;
} elsif ($line =~ /#endif/) {
$nested--
}
}
} elsif ($line =~ /^#\s*ifn?\s*\!?def/) {
#warn "Ignored #if:\n$line";
} elsif ($line =~ /typedef struct\s*\{/) {
my $first_line = $line;
my @lines = ();
$line = <INFILE>;
while ($line !~ /^}\s*(\w+);/) {
push @lines, $line;
$line = <INFILE>;
}
$line =~ /^}\s*(\w+);/;
my $name = $1;
print "typedef struct _$name $name;\n";
print "struct _$name {\n";
foreach $line (@lines) {
if ($line =~ /(\s*.+\;)/) {
$field = $1;
$field =~ s/(\w+) const/const $1/;
print "$field\n";
}
}
print "};\n";
} elsif ($line =~ /^enum\s+\{/) {
while ($line !~ /^};/) {$line = <INFILE>;}
} elsif ($line =~ /(\s+)union\s*{/) {
# this is a hack for now, but I need it for the fields to work
$indent = $1;
$do_print = 1;
while ($line !~ /^$indent}\s*\w+;/) {
$line = <INFILE>;
next if ($line !~ /;/);
print $line if $do_print;
$do_print = 0;
}
} else {
if ($braces or $line =~ /;/) {
print $line;
} else {
$prepend = $line;
$prepend =~ s/\n/ /g;
}
}
}
}
foreach $fname (@srcs, @privhdrs) {
open(INFILE, $fname) || die "Could open $fname\n";
if ($fname =~ /builtins_ids/) {
while ($line = <INFILE>) {
next if ($line !~ /\{/);
chomp($line);
$builtin = "BUILTIN" . $line;
$builtin .= <INFILE>;
print $builtin;
}
next;
}
while ($line = <INFILE>) {
#next if ($line !~ /^(struct|\w+_class_init)|g_boxed_type_register_static/);
next if ($line !~ /^(struct|\w+_class_init|\w+_base_init|\w+_get_type)/);
if ($line =~ /^struct/) {
# need some of these to parse out parent types
print "private";
}
$comment = 0;
$begin = 0;
$end = 0;
do {
# Following ifs strips out // and /* */ C comments
if ($line =~ /\/\*/) {
$comment = 1;
$begin = 1;
}
if ($comment != 1) {
$line =~ s/\/\/.*//;
print $line;
}
if ($line =~ /\*\//) {
$comment = 0;
$end = 1;
}
if ($begin == 1 && $end == 1) {
$line =~ s/\/\*.*\*\///;
print $line;
}
$begin = 0;
$end = 0;
} until (($line = <INFILE>) =~ /^}/);
print $line;
}
}