[STRIP_SUFFIX] ability to flag suffixes to be stripped.
[gnome.gobject-introspection] / tools / g-idl-offsets.pl
1 #! /usr/bin/perl -w
2
3 use Getopt::Long;
4 use XML::Parser;
5
6 my $INCLUDES;
7 my $PRINT_VERSION;
8 my $PRINT_HELP;
9
10 %optctl = (includes => \$INCLUDES);
11            
12 GetOptions(\%optctl, "includes=s");
13
14 my $file = shift;
15
16 die "Can't find file \"$file\""
17   unless -f $file;
18     
19 my $parser = new XML::Parser(ErrorContext => 2);
20
21 my $structname = "";
22 my $classname = "";
23
24 open OUTPUT, ">dump-sizes.c" || die "Cannot open dump-sizes.c: $!\n";
25
26 print OUTPUT <<EOT;
27 #include <glib.h>
28 $INCLUDES
29
30 int
31 main (int argc, char *argv[])
32 {
33 EOT
34
35 $parser->setHandlers(Start => \&start_handler,
36                      End => \&end_handler);
37
38 $parser->parsefile($file);
39
40 print OUTPUT <<EOT;
41
42   return 0;
43 }
44 EOT
45
46 close OUTPUT;
47
48 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
49 $LD = $ENV{LD} ? $ENV{LD} : $CC;
50 $CFLAGS = $ENV{CFLAGS} ? $ENV{CFLAGS} : "";
51 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
52
53 my $o_file;
54 if ($CC =~ /libtool/) {
55   $o_file  = "dump-sizes.lo"
56 } else {
57   $o_file = "dump-sizes.o"
58 }
59
60 $command = "$CC $CFLAGS -c -o $o_file dump-sizes.c && $LD -o dump-sizes $o_file $LDFLAGS";
61
62 system($command) == 0 or die "Compilation failed\n";
63
64 system("./dump-sizes > sizes.out") == 0 or die "Scan failed\n";
65
66 #unlink "./dump-sizes.c", "./dump-sizes.o", "./dump-sizes.lo", "./dump-sizes";
67
68 my %Sizes;
69
70 open SIZES, "<sizes.out" || die "Can't open sizes.out: $!";
71 while (<SIZES>) {
72   if (m/(\w*) (\w*) (\d*)/) {
73     $Sizes{$1 . "." . $2} = $3;
74   }
75 }
76
77 close SIZES;
78
79 open OUTPUT2, ">$file.new" || die "Cannot open $file.new: $!\n";
80
81 $parser->setHandlers(Start => \&dump_start_handler,
82                      End => \&dump_end_handler);
83
84 $parser->parsefile($file);
85
86 close OUTPUT2;
87
88 sub start_handler
89 {
90     my $p = shift;
91     my $el = shift;
92     my $name = "";
93     my $cname = "";
94     my $class = "";
95
96     while (@_) {
97         my $att = shift;
98         my $val = shift;
99
100         if ($att eq "name") {
101             $name = $val;
102         }
103         elsif ($att eq "cname") {
104             $cname = $val;
105         }
106         elsif ($att eq "class") {
107             $class = $val;
108         }
109     }
110
111     if (($el eq "object") || ($el eq "interface")) {
112         if (!($cname eq "")) {
113             $structname = $cname;
114         }
115         else {
116             $structname = $name;
117         }
118
119         if (!($class eq "")) {
120             $classname = $class;
121         }
122         elsif ($el eq "object") {
123             $classname = $structname . "Class";
124         }
125         else {
126             $classname = $structname . "Iface";
127         }
128     }
129     elsif ($el eq "field") {
130         if (!($cname eq "")) {
131             need_offset ($structname, $cname);
132         }
133         else {
134             need_offset ($structname, $name);
135         }
136     }
137     elsif ($el eq "vfunc") {
138         if (!($cname eq "")) {
139             need_offset ($classname, $cname);
140         }
141         else {
142             need_offset ($classname, $name);
143         }
144     }
145 }
146
147 sub end_handler
148 {
149     my $p = shift;
150     my $el = shift;
151     
152     if (($el eq "object") || 
153         ($el eq "interface") ||
154         ($el eq "boxed") ||
155         ($el eq "struct") ||
156         ($el eq "union")) {
157         $structname = "";
158         $classname = "";
159     }
160 }
161
162 sub need_offset
163 {
164     my $struct = shift;
165     my $name = shift;
166
167     print OUTPUT "  g_print (\"$struct $name %d\\n\", G_STRUCT_OFFSET ($struct, $name));\n";
168 }
169
170 sub write_offset
171 {
172     my $struct = shift;
173     my $name = shift;
174
175     print OUTPUT2 " offset=\"" . $Sizes{$struct . "." . $name } . "\""
176 }
177
178 sub dump_start_handler
179 {
180     my $p = shift;
181     my $el = shift;
182     my $name = "";
183     my $cname = "";
184     my $class = "";
185
186     print OUTPUT2 "<$el";
187
188     while (@_) {
189         my $att = shift;
190         my $val = shift;
191
192         print OUTPUT2 " $att=\"$val\"";
193
194         if ($att eq "name") {
195             $name = $val;
196         }
197         elsif ($att eq "cname") {
198             $cname = $val;
199         }
200         elsif ($att eq "class") {
201             $class = $val;
202         }
203     }
204
205     if (($el eq "object") || ($el eq "interface")) {
206         if (!($cname eq "")) {
207             $structname = $cname;
208         }
209         else {
210             $structname = $name;
211         }
212
213         if (!($class eq "")) {
214             $classname = $class;
215         }
216         elsif ($el eq "object") {
217             $classname = $structname . "Class";
218         }
219         else {
220             $classname = $structname . "Iface";
221         }
222     }
223     elsif ($el eq "field") {
224         if (!($cname eq "")) {
225           write_offset ($structname, $cname);
226         }
227         else {
228           write_offset ($structname, $name);
229         }
230     }
231     elsif ($el eq "vfunc") {
232       if (!($cname eq "")) {
233         write_offset ($classname, $cname);
234       }
235       else {
236         write_offset ($classname, $name);
237       }
238     }
239     print OUTPUT2 ">\n";
240 }
241
242 sub dump_end_handler
243 {
244     my $p = shift;
245     my $el = shift;
246     
247     if (($el eq "object") ||
248         ($el eq "interface") ||
249         ($el eq "boxed") ||
250         ($el eq "struct") ||
251         ($el eq "union")) {
252         $structname = "";
253         $classname = "";
254     }
255
256     print OUTPUT2 "</$el>\n";
257 }
258