blob: e6f629ce50a0c43d2d92cd0b93cea567670dbe9c [file] [log] [blame]
thughesd64e87d2004-11-02 09:45:21 +00001#!/usr/bin/perl -w
fitzhardinge7e343cd2003-12-16 02:14:00 +00002
njnb9c427c2004-12-01 14:14:42 +00003# This file is part of Valgrind, a dynamic binary instrumentation
4# framework.
jseward2886b0e2004-01-04 03:46:11 +00005#
njn53612422005-03-12 16:22:54 +00006# Copyright (C) 2000-2005 Julian Seward
jseward2886b0e2004-01-04 03:46:11 +00007# jseward@acm.org
8#
9# This program is free software; you can redistribute it and/or
10# modify it under the terms of the GNU General Public License as
11# published by the Free Software Foundation; either version 2 of the
12# License, or (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful, but
15# WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17# General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22# 02111-1307, USA.
23#
24# The GNU General Public License is contained in the file COPYING.
25
nethercoted1c71402004-01-04 13:08:56 +000026use strict;
jseward2886b0e2004-01-04 03:46:11 +000027
fitzhardinge7e343cd2003-12-16 02:14:00 +000028my $output = shift @ARGV;
29my $indent = "";
30my $headerguard;
31my $include;
32my $passcomment = 1;
nethercoted1c71402004-01-04 13:08:56 +000033my $pre;
34my $post;
35my $generate;
fitzhardinge7e343cd2003-12-16 02:14:00 +000036
njncf81d552005-03-31 04:52:26 +000037my $struct = "VG_(tdict)";
fitzhardinge7e343cd2003-12-16 02:14:00 +000038
njn26f02512004-11-22 18:33:15 +000039my %pfxmap = ("track" => "TL_",
40 "tool" => "TL_",
41 "malloc"=> "TL_",
fitzhardinge7e343cd2003-12-16 02:14:00 +000042 );
43
44sub getargnames(@) {
45 my @args = @_;
46 my @ret;
47
48 foreach my $a (@args) {
49 my @pieces = split /\s+/, $a;
50 my $name = pop @pieces;
51 push @ret, $name unless $name eq "void";
52 }
53 return @ret;
54}
55
56sub getargtypes(@) {
57 my @args = @_;
58 my @ret;
59
60 foreach my $a (@args) {
61 my @pieces = split /\s+/, $a;
62 pop @pieces;
63 push @ret, (join " ", @pieces);
64 }
65 @ret = "void" if ($#ret == -1);
66 return @ret;
67}
68
69# Different output modes
70if ($output eq "callwrap") {
nethercotef1e5e152004-09-01 23:58:16 +000071 $include = "core.h";
fitzhardinge7e343cd2003-12-16 02:14:00 +000072 $generate = sub ($$$@) {
73 my ($pfx, $ret, $func, @args) = @_;
74 my $args = join ", ", @args;
75 my $argnames = join ", ", getargnames(@args);
76 print "$ret $pfxmap{$pfx}($func)($args)\n{\n";
77 print " return (*$struct.${pfx}_$func)($argnames);\n";
78 print "}\n";
79 }
80} elsif ($output eq "proto") {
nethercotef1e5e152004-09-01 23:58:16 +000081 $include = "core.h";
fitzhardinge7e343cd2003-12-16 02:14:00 +000082 $generate = sub ($$$@) {
83 my ($pfx, $ret, $func, @args) = @_;
84 my $args = join ', ', @args;
85
86 print "$ret $pfxmap{$pfx}($func)($args);\n";
sewardjb5f6f512005-03-10 23:59:00 +000087 print "$ret VG_(missing_$func)($args);\n";
fitzhardinge7e343cd2003-12-16 02:14:00 +000088 print "Bool VG_(defined_$func)(void);\n";
89 }
90} elsif ($output eq "toolproto") {
91 $generate = sub ($$$@) {
92 my ($pfx, $ret, $func, @args) = @_;
93 my $args = join ', ', @args;
94
95 print "$ret $pfxmap{$pfx}($func)($args);\n";
96 }
97} elsif ($output eq "missingfuncs") {
nethercotef1e5e152004-09-01 23:58:16 +000098 $include = "core.h";
fitzhardinge7e343cd2003-12-16 02:14:00 +000099 $generate = sub ($$$@) {
100 my ($pfx, $ret, $func, @args) = @_;
101 my $args = join ", ", @args;
102
sewardjb5f6f512005-03-10 23:59:00 +0000103 print "__attribute__ ((weak))\n$ret VG_(missing_$func)($args) {\n";
fitzhardinge7e343cd2003-12-16 02:14:00 +0000104 print " VG_(missing_tool_func)(\"${pfx}_$func\");\n";
105 print "}\n";
106 print "Bool VG_(defined_$func)(void) {\n";
sewardjb5f6f512005-03-10 23:59:00 +0000107 print " return $struct.${pfx}_$func != VG_(missing_$func);\n";
fitzhardinge7e343cd2003-12-16 02:14:00 +0000108 print "}\n\n";
109 };
110 $indent = " ";
111} elsif ($output eq "struct") {
nethercotef1e5e152004-09-01 23:58:16 +0000112 $include = "core.h";
fitzhardinge7e343cd2003-12-16 02:14:00 +0000113 $pre = sub () {
114 print "typedef struct {\n";
115 };
116 $post = sub () {
117 print "} VgToolInterface;\n\n";
118 print "extern VgToolInterface $struct;\n"
119 };
120 $generate = sub ($$$@) {
121 my ($pfx, $ret, $func, @args) = @_;
122 my $args = join ", ", @args;
123
124 print "$indent$ret (*${pfx}_$func)($args);\n";
125 };
126 $indent = " ";
127 $headerguard=$output;
128} elsif ($output eq "structdef") {
129 $include = "vg_toolint.h";
130 $pre = sub () {
131 print "VgToolInterface $struct = {\n";
132 };
133 $post = sub () {
134 print "};\n";
135 };
136 $generate = sub ($$$@) {
137 my ($pfx, $ret, $func, @args) = @_;
138
sewardjb5f6f512005-03-10 23:59:00 +0000139 print "$indent.${pfx}_$func = VG_(missing_$func),\n"
fitzhardinge7e343cd2003-12-16 02:14:00 +0000140 };
141 $indent = " ";
142} elsif ($output eq "initfunc") {
nethercote46063202004-09-02 08:51:43 +0000143 $include = "tool.h";
fitzhardinge7e343cd2003-12-16 02:14:00 +0000144 $generate = sub ($$$@) {
145 my ($pfx, $ret, $func, @args) = @_;
146 my $args = join ", ", @args;
147 my $argnames = join ", ", getargnames(@args);
148
149 print <<EOF;
150void VG_(init_$func)($ret (*func)($args))
151{
152 if (func == NULL)
sewardjb5f6f512005-03-10 23:59:00 +0000153 func = VG_(missing_$func);
fitzhardinge7e343cd2003-12-16 02:14:00 +0000154 if (VG_(defined_$func)())
155 VG_(printf)("Warning tool is redefining $func\\n");
njn26f02512004-11-22 18:33:15 +0000156 if (func == TL_($func))
fitzhardinge7e343cd2003-12-16 02:14:00 +0000157 VG_(printf)("Warning tool is defining $func recursively\\n");
158 $struct.${pfx}_$func = func;
159}
160EOF
161 }
162} elsif ($output eq "initproto") {
163 $generate = sub ($$$@) {
164 my ($pfx, $ret, $func, @args) = @_;
165 my $args = join ', ', @args;
166 print "void VG_(init_$func)($ret (*func)($args));\n";
167 };
168 $headerguard=$output;
fitzhardinge7e343cd2003-12-16 02:14:00 +0000169}
170
171die "Unknown output format \"$output\"" unless defined $generate;
172
173print "/* Generated by \"gen_toolint.pl $output\" */\n";
174
175print <<EOF if defined $headerguard;
176
177#ifndef VG_toolint_$headerguard
178#define VG_toolint_$headerguard
179
180EOF
181
182print <<EOF if defined $include;
183#include \"$include\"
184EOF
185
186&$pre() if defined $pre; # preamble
187
188my $state = "idle";
189
190my $buf;
191my $lines;
nethercoted1c71402004-01-04 13:08:56 +0000192my $prefix;
fitzhardinge7e343cd2003-12-16 02:14:00 +0000193
194while(<STDIN>) {
195 # skip simple comments
196 next if (/^#[^#]/);
197
198 if (/^:/) {
199 s/^://;
200 chomp;
201 $prefix=$_;
202 next;
203 }
204
205 # look for inserted comments
206 if (/^##/) {
207 if ($state eq "idle") {
208 $state = "comment";
209 $lines = 1;
210 $_ =~ s,^## ,/* ,;
211 $buf = $_;
212 next;
213 } elsif ($state eq "comment") {
214 $lines++;
215 $_ =~ s,^## , ,;
216 print $indent.$buf if $passcomment;
217 $buf = $_;
218 next;
219 }
220 next;
221 }
222
223 # blank lines in a comment are part of the comment
224 if (/^\s*$/) {
225 if ($state eq "comment") {
226 $lines++;
227 print $indent.$buf if $passcomment;
228 $buf = "\n";
229 } else {
230 print "\n" if $passcomment;
231 }
232 next;
233 }
234
235 # coming out of a comment
236 if ($state eq "comment") {
237 chomp $buf;
238
239 if ($passcomment) {
240 if ($lines == 1) {
241 print "$indent$buf */\n";
242 } else {
243 print "$indent$buf\n$indent */\n";
244 }
245 }
246 $buf = "";
247 $state = "idle";
248 }
249
250 chomp;
251 my @func = split /,\s*/;
252
253 my $rettype = shift @func;
254 my $funcname = shift @func;
255
256 @func = "void" if scalar @func == 0;
257
258 &$generate ($prefix, $rettype, $funcname, @func);
259}
260
261&$post() if defined $post; # postamble
262
263print <<EOF if defined $headerguard;
264
265#endif /* VG_toolint_$headerguard */
266EOF