summaryrefslogtreecommitdiff
path: root/tools/g-idl-offsets.pl
diff options
context:
space:
mode:
authorRob Taylor <rob.taylor@codethink.co.uk>2008-02-08 15:31:03 +0000
committerRobert James Taylor <robtaylor@src.gnome.org>2008-02-08 15:31:03 +0000
commitb935261f387dffa2c7006fe1be04820004810e87 (patch)
tree0c077cee05c725e1e56309374a1ceea8d8881b7d /tools/g-idl-offsets.pl
parentc6c15af80d8a6d34e5c77d3111c638126edb3d45 (diff)
downloadgobject-introspection-b935261f387dffa2c7006fe1be04820004810e87.tar.gz
Added: Added: Renamed to tools/Makefile.am: Renamed to tools/compiler.c:
2008-02-08 Rob Taylor <rob.taylor@codethink.co.uk> * Makefile.am: * configure.ac: * gidl/Makefile.am: Added: * girepository/Makefile.am: Added: * src/Makefile.am: Renamed to tools/Makefile.am: * src/compiler.c: Renamed to tools/compiler.c: * src/g-idl-offsets.pl: Renamed to tools/g-idl-offsets.pl: * src/generate.c: Renamed to tools/generate.c: * src/gidlmodule.c: Renamed to tools/gidlmodule.c: * src/gidlmodule.h: Renamed to tools/gidlmodule.h: * src/gidlnode.c: Renamed to tools/gidlnode.c: * src/gidlnode.h: Renamed to tools/gidlnode.h: * src/gidlparser.c: Renamed to tools/gidlparser.c: * src/gidlparser.h: Renamed to tools/gidlparser.h: * src/gidlwriter.c: Renamed to tools/gidlwriter.c: * src/gidlwriter.h: Renamed to tools/gidlwriter.h: * src/ginfo.c: Renamed to girepository/ginfo.c: * src/ginvoke.c: Renamed to girepository/ginvoke.c: * src/girepository.c: Renamed to girepository/girepository.c: * src/girepository.h: Renamed to girepository/girepository.h: * src/gmetadata.c: Renamed to girepository/gmetadata.c: * src/gmetadata.h: Renamed to girepository/gmetadata.h: * src/scanner.c: Renamed to tools/scanner.c: * src/scanner.h: Renamed to tools/scanner.h: * src/scannerlexer.l: Renamed to tools/scannerlexer.l: * src/scannerparser.y: Renamed to tools/scannerparser.y: * tests/invoke/Makefile.am: Split src/ into girepository/ and tools/ * Makefile.am: * configure.ac: * girepository/Makefile.am: * tests/Makefile.am: * tests/invoke/Makefile.am: * tests/parser/Makefile.am: * tests/roundtrips.sh: * tools/Makefile.am: Make distcheck work. svn path=/trunk/; revision=104
Diffstat (limited to 'tools/g-idl-offsets.pl')
-rwxr-xr-xtools/g-idl-offsets.pl258
1 files changed, 258 insertions, 0 deletions
diff --git a/tools/g-idl-offsets.pl b/tools/g-idl-offsets.pl
new file mode 100755
index 00000000..55318708
--- /dev/null
+++ b/tools/g-idl-offsets.pl
@@ -0,0 +1,258 @@
+#! /usr/bin/perl -w
+
+use Getopt::Long;
+use XML::Parser;
+
+my $INCLUDES;
+my $PRINT_VERSION;
+my $PRINT_HELP;
+
+%optctl = (includes => \$INCLUDES);
+
+GetOptions(\%optctl, "includes=s");
+
+my $file = shift;
+
+die "Can't find file \"$file\""
+ unless -f $file;
+
+my $parser = new XML::Parser(ErrorContext => 2);
+
+my $structname = "";
+my $classname = "";
+
+open OUTPUT, ">dump-sizes.c" || die "Cannot open dump-sizes.c: $!\n";
+
+print OUTPUT <<EOT;
+#include <glib.h>
+$INCLUDES
+
+int
+main (int argc, char *argv[])
+{
+EOT
+
+$parser->setHandlers(Start => \&start_handler,
+ End => \&end_handler);
+
+$parser->parsefile($file);
+
+print OUTPUT <<EOT;
+
+ return 0;
+}
+EOT
+
+close OUTPUT;
+
+$CC = $ENV{CC} ? $ENV{CC} : "gcc";
+$LD = $ENV{LD} ? $ENV{LD} : $CC;
+$CFLAGS = $ENV{CFLAGS} ? $ENV{CFLAGS} : "";
+$LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
+
+my $o_file;
+if ($CC =~ /libtool/) {
+ $o_file = "dump-sizes.lo"
+} else {
+ $o_file = "dump-sizes.o"
+}
+
+$command = "$CC $CFLAGS -c -o $o_file dump-sizes.c && $LD -o dump-sizes $o_file $LDFLAGS";
+
+system($command) == 0 or die "Compilation failed\n";
+
+system("./dump-sizes > sizes.out") == 0 or die "Scan failed\n";
+
+#unlink "./dump-sizes.c", "./dump-sizes.o", "./dump-sizes.lo", "./dump-sizes";
+
+my %Sizes;
+
+open SIZES, "<sizes.out" || die "Can't open sizes.out: $!";
+while (<SIZES>) {
+ if (m/(\w*) (\w*) (\d*)/) {
+ $Sizes{$1 . "." . $2} = $3;
+ }
+}
+
+close SIZES;
+
+open OUTPUT2, ">$file.new" || die "Cannot open $file.new: $!\n";
+
+$parser->setHandlers(Start => \&dump_start_handler,
+ End => \&dump_end_handler);
+
+$parser->parsefile($file);
+
+close OUTPUT2;
+
+sub start_handler
+{
+ my $p = shift;
+ my $el = shift;
+ my $name = "";
+ my $cname = "";
+ my $class = "";
+
+ while (@_) {
+ my $att = shift;
+ my $val = shift;
+
+ if ($att eq "name") {
+ $name = $val;
+ }
+ elsif ($att eq "cname") {
+ $cname = $val;
+ }
+ elsif ($att eq "class") {
+ $class = $val;
+ }
+ }
+
+ if (($el eq "object") || ($el eq "interface")) {
+ if (!($cname eq "")) {
+ $structname = $cname;
+ }
+ else {
+ $structname = $name;
+ }
+
+ if (!($class eq "")) {
+ $classname = $class;
+ }
+ elsif ($el eq "object") {
+ $classname = $structname . "Class";
+ }
+ else {
+ $classname = $structname . "Iface";
+ }
+ }
+ elsif ($el eq "field") {
+ if (!($cname eq "")) {
+ need_offset ($structname, $cname);
+ }
+ else {
+ need_offset ($structname, $name);
+ }
+ }
+ elsif ($el eq "vfunc") {
+ if (!($cname eq "")) {
+ need_offset ($classname, $cname);
+ }
+ else {
+ need_offset ($classname, $name);
+ }
+ }
+}
+
+sub end_handler
+{
+ my $p = shift;
+ my $el = shift;
+
+ if (($el eq "object") ||
+ ($el eq "interface") ||
+ ($el eq "boxed") ||
+ ($el eq "struct") ||
+ ($el eq "union")) {
+ $structname = "";
+ $classname = "";
+ }
+}
+
+sub need_offset
+{
+ my $struct = shift;
+ my $name = shift;
+
+ print OUTPUT " g_print (\"$struct $name %d\\n\", G_STRUCT_OFFSET ($struct, $name));\n";
+}
+
+sub write_offset
+{
+ my $struct = shift;
+ my $name = shift;
+
+ print OUTPUT2 " offset=\"" . $Sizes{$struct . "." . $name } . "\""
+}
+
+sub dump_start_handler
+{
+ my $p = shift;
+ my $el = shift;
+ my $name = "";
+ my $cname = "";
+ my $class = "";
+
+ print OUTPUT2 "<$el";
+
+ while (@_) {
+ my $att = shift;
+ my $val = shift;
+
+ print OUTPUT2 " $att=\"$val\"";
+
+ if ($att eq "name") {
+ $name = $val;
+ }
+ elsif ($att eq "cname") {
+ $cname = $val;
+ }
+ elsif ($att eq "class") {
+ $class = $val;
+ }
+ }
+
+ if (($el eq "object") || ($el eq "interface")) {
+ if (!($cname eq "")) {
+ $structname = $cname;
+ }
+ else {
+ $structname = $name;
+ }
+
+ if (!($class eq "")) {
+ $classname = $class;
+ }
+ elsif ($el eq "object") {
+ $classname = $structname . "Class";
+ }
+ else {
+ $classname = $structname . "Iface";
+ }
+ }
+ elsif ($el eq "field") {
+ if (!($cname eq "")) {
+ write_offset ($structname, $cname);
+ }
+ else {
+ write_offset ($structname, $name);
+ }
+ }
+ elsif ($el eq "vfunc") {
+ if (!($cname eq "")) {
+ write_offset ($classname, $cname);
+ }
+ else {
+ write_offset ($classname, $name);
+ }
+ }
+ print OUTPUT2 ">\n";
+}
+
+sub dump_end_handler
+{
+ my $p = shift;
+ my $el = shift;
+
+ if (($el eq "object") ||
+ ($el eq "interface") ||
+ ($el eq "boxed") ||
+ ($el eq "struct") ||
+ ($el eq "union")) {
+ $structname = "";
+ $classname = "";
+ }
+
+ print OUTPUT2 "</$el>\n";
+}
+