blob: 2738f92e0d1bfdba44549be95aec2c95a12e0ee7 [file] [log] [blame]
fitzhardinge7e343cd2003-12-16 02:14:00 +00001#!/usr/bin/perl
2
3my $output = shift @ARGV;
4my $indent = "";
5my $headerguard;
6my $include;
7my $passcomment = 1;
8
9my $struct = "VG_(tool_interface)";
10
11my %pfxmap = ("track" => "SK_",
12 "tool" => "SK_",
13 "malloc"=> "SK_",
14 );
15
16sub getargnames(@) {
17 my @args = @_;
18 my @ret;
19
20 foreach my $a (@args) {
21 my @pieces = split /\s+/, $a;
22 my $name = pop @pieces;
23 push @ret, $name unless $name eq "void";
24 }
25 return @ret;
26}
27
28sub getargtypes(@) {
29 my @args = @_;
30 my @ret;
31
32 foreach my $a (@args) {
33 my @pieces = split /\s+/, $a;
34 pop @pieces;
35 push @ret, (join " ", @pieces);
36 }
37 @ret = "void" if ($#ret == -1);
38 return @ret;
39}
40
41# Different output modes
42if ($output eq "callwrap") {
43 $include = "vg_include.h";
44 $generate = sub ($$$@) {
45 my ($pfx, $ret, $func, @args) = @_;
46 my $args = join ", ", @args;
47 my $argnames = join ", ", getargnames(@args);
48 print "$ret $pfxmap{$pfx}($func)($args)\n{\n";
49 print " return (*$struct.${pfx}_$func)($argnames);\n";
50 print "}\n";
51 }
52} elsif ($output eq "proto") {
53 $include = "vg_include.h";
54 $generate = sub ($$$@) {
55 my ($pfx, $ret, $func, @args) = @_;
56 my $args = join ', ', @args;
57
58 print "$ret $pfxmap{$pfx}($func)($args);\n";
59 print "Bool VG_(defined_$func)(void);\n";
60 }
61} elsif ($output eq "toolproto") {
62 $generate = sub ($$$@) {
63 my ($pfx, $ret, $func, @args) = @_;
64 my $args = join ', ', @args;
65
66 print "$ret $pfxmap{$pfx}($func)($args);\n";
67 }
68} elsif ($output eq "missingfuncs") {
69 $include = "vg_include.h";
70 $generate = sub ($$$@) {
71 my ($pfx, $ret, $func, @args) = @_;
72 my $args = join ", ", @args;
73
74 print "static $ret missing_${pfx}_$func($args) {\n";
75 print " VG_(missing_tool_func)(\"${pfx}_$func\");\n";
76 print "}\n";
77 print "Bool VG_(defined_$func)(void) {\n";
78 print " return $struct.${pfx}_$func != missing_${pfx}_$func;\n";
79 print "}\n\n";
80 };
81 $indent = " ";
82} elsif ($output eq "struct") {
83 $include = "vg_include.h";
84 $pre = sub () {
85 print "typedef struct {\n";
86 };
87 $post = sub () {
88 print "} VgToolInterface;\n\n";
89 print "extern VgToolInterface $struct;\n"
90 };
91 $generate = sub ($$$@) {
92 my ($pfx, $ret, $func, @args) = @_;
93 my $args = join ", ", @args;
94
95 print "$indent$ret (*${pfx}_$func)($args);\n";
96 };
97 $indent = " ";
98 $headerguard=$output;
99} elsif ($output eq "structdef") {
100 $include = "vg_toolint.h";
101 $pre = sub () {
102 print "VgToolInterface $struct = {\n";
103 };
104 $post = sub () {
105 print "};\n";
106 };
107 $generate = sub ($$$@) {
108 my ($pfx, $ret, $func, @args) = @_;
109
110 print "$indent.${pfx}_$func = missing_${pfx}_$func,\n"
111 };
112 $indent = " ";
113} elsif ($output eq "initfunc") {
114 $include = "vg_skin.h";
115 $generate = sub ($$$@) {
116 my ($pfx, $ret, $func, @args) = @_;
117 my $args = join ", ", @args;
118 my $argnames = join ", ", getargnames(@args);
119
120 print <<EOF;
121void VG_(init_$func)($ret (*func)($args))
122{
123 if (func == NULL)
124 func = missing_${pfx}_$func;
125 if (VG_(defined_$func)())
126 VG_(printf)("Warning tool is redefining $func\\n");
127 if (func == SK_($func))
128 VG_(printf)("Warning tool is defining $func recursively\\n");
129 $struct.${pfx}_$func = func;
130}
131EOF
132 }
133} elsif ($output eq "initproto") {
134 $generate = sub ($$$@) {
135 my ($pfx, $ret, $func, @args) = @_;
136 my $args = join ', ', @args;
137 print "void VG_(init_$func)($ret (*func)($args));\n";
138 };
139 $headerguard=$output;
140} elsif ($output eq "initdlsym") {
141 $pre = sub () {
142 print <<EOF;
143#include <dlfcn.h>
144void VG_(tool_init_dlsym)(void *dlhandle)
145{
146 void *ret;
147
148EOF
149 };
150 $post = sub () {
151 print "}\n";
152 };
153 $generate = sub ($$$@) {
154 my ($pfx, $ret, $func, @args) = @_;
155 my $args = join ", ", getargtypes(@args);
156
157 print <<EOF;
158 ret = dlsym(dlhandle, "vgSkin_$func");
159 if (ret != NULL)
160 VG_(init_$func)(($ret (*)($args))ret);
161
162EOF
163 };
164
165 $passcomment = 0;
166}
167
168die "Unknown output format \"$output\"" unless defined $generate;
169
170print "/* Generated by \"gen_toolint.pl $output\" */\n";
171
172print <<EOF if defined $headerguard;
173
174#ifndef VG_toolint_$headerguard
175#define VG_toolint_$headerguard
176
177EOF
178
179print <<EOF if defined $include;
180#include \"$include\"
181EOF
182
183&$pre() if defined $pre; # preamble
184
185my $state = "idle";
186
187my $buf;
188my $lines;
189
190while(<STDIN>) {
191 # skip simple comments
192 next if (/^#[^#]/);
193
194 if (/^:/) {
195 s/^://;
196 chomp;
197 $prefix=$_;
198 next;
199 }
200
201 # look for inserted comments
202 if (/^##/) {
203 if ($state eq "idle") {
204 $state = "comment";
205 $lines = 1;
206 $_ =~ s,^## ,/* ,;
207 $buf = $_;
208 next;
209 } elsif ($state eq "comment") {
210 $lines++;
211 $_ =~ s,^## , ,;
212 print $indent.$buf if $passcomment;
213 $buf = $_;
214 next;
215 }
216 next;
217 }
218
219 # blank lines in a comment are part of the comment
220 if (/^\s*$/) {
221 if ($state eq "comment") {
222 $lines++;
223 print $indent.$buf if $passcomment;
224 $buf = "\n";
225 } else {
226 print "\n" if $passcomment;
227 }
228 next;
229 }
230
231 # coming out of a comment
232 if ($state eq "comment") {
233 chomp $buf;
234
235 if ($passcomment) {
236 if ($lines == 1) {
237 print "$indent$buf */\n";
238 } else {
239 print "$indent$buf\n$indent */\n";
240 }
241 }
242 $buf = "";
243 $state = "idle";
244 }
245
246 chomp;
247 my @func = split /,\s*/;
248
249 my $rettype = shift @func;
250 my $funcname = shift @func;
251
252 @func = "void" if scalar @func == 0;
253
254 &$generate ($prefix, $rettype, $funcname, @func);
255}
256
257&$post() if defined $post; # postamble
258
259print <<EOF if defined $headerguard;
260
261#endif /* VG_toolint_$headerguard */
262EOF