Add and delete all the files which need adding and deleting.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2119 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/gen_toolint.pl b/coregrind/gen_toolint.pl
new file mode 100644
index 0000000..2738f92
--- /dev/null
+++ b/coregrind/gen_toolint.pl
@@ -0,0 +1,262 @@
+#!/usr/bin/perl
+
+my $output = shift @ARGV;
+my $indent = "";
+my $headerguard;
+my $include;
+my $passcomment = 1;
+
+my $struct = "VG_(tool_interface)";
+
+my %pfxmap = ("track" => "SK_",
+	      "tool"  => "SK_",
+	      "malloc"=> "SK_",
+	     );
+
+sub getargnames(@) {
+    my @args = @_;
+    my @ret;
+
+    foreach my $a (@args) {
+	my @pieces = split /\s+/, $a;
+	my $name = pop @pieces;
+	push @ret, $name unless $name eq "void";
+    }
+    return @ret;
+}
+
+sub getargtypes(@) {
+    my @args = @_;
+    my @ret;
+
+    foreach my $a (@args) {
+	my @pieces = split /\s+/, $a;
+	pop @pieces;
+	push @ret, (join " ", @pieces);
+    }
+    @ret = "void" if ($#ret == -1);
+    return @ret;
+}
+
+# Different output modes
+if ($output eq "callwrap") {
+    $include = "vg_include.h";
+    $generate = sub ($$$@) {
+	my ($pfx, $ret, $func, @args) = @_;
+	my $args = join ", ", @args;
+	my $argnames = join ", ", getargnames(@args);
+	print "$ret $pfxmap{$pfx}($func)($args)\n{\n";
+	print "   return (*$struct.${pfx}_$func)($argnames);\n";
+	print "}\n";
+    }
+} elsif ($output eq "proto") {
+    $include = "vg_include.h";
+    $generate = sub ($$$@) {
+	my ($pfx, $ret, $func, @args) = @_;
+	my $args = join ', ', @args;
+
+	print "$ret $pfxmap{$pfx}($func)($args);\n";
+	print "Bool VG_(defined_$func)(void);\n";
+    }
+} elsif ($output eq "toolproto") {
+    $generate = sub ($$$@) {
+	my ($pfx, $ret, $func, @args) = @_;
+	my $args = join ', ', @args;
+
+	print "$ret $pfxmap{$pfx}($func)($args);\n";
+    }
+} elsif ($output eq "missingfuncs") {
+    $include = "vg_include.h";
+    $generate = sub ($$$@) {
+	my ($pfx, $ret, $func, @args) = @_;
+	my $args = join ", ", @args;
+
+	print "static $ret missing_${pfx}_$func($args) {\n";
+	print "   VG_(missing_tool_func)(\"${pfx}_$func\");\n";
+	print "}\n";
+	print "Bool VG_(defined_$func)(void) {\n";
+	print "   return $struct.${pfx}_$func != missing_${pfx}_$func;\n";
+	print "}\n\n";
+    };
+    $indent = "   ";
+} elsif ($output eq "struct") {
+    $include = "vg_include.h";
+    $pre = sub () {
+	print "typedef struct {\n";
+    };
+    $post = sub () {
+	print "} VgToolInterface;\n\n";
+	print "extern VgToolInterface $struct;\n"
+    };
+    $generate = sub ($$$@) {
+	my ($pfx, $ret, $func, @args) = @_;
+	my $args = join ", ", @args;
+
+	print "$indent$ret (*${pfx}_$func)($args);\n";
+    };
+    $indent = "   ";
+    $headerguard=$output;
+} elsif ($output eq "structdef") {
+    $include = "vg_toolint.h";
+    $pre = sub () {
+	print "VgToolInterface $struct = {\n";
+    };
+    $post = sub () {
+	print "};\n";
+    };
+    $generate = sub ($$$@) {
+	my ($pfx, $ret, $func, @args) = @_;
+
+	print "$indent.${pfx}_$func = missing_${pfx}_$func,\n"
+    };
+    $indent = "   ";
+} elsif ($output eq "initfunc") {
+    $include = "vg_skin.h";
+    $generate = sub ($$$@) {
+	my ($pfx, $ret, $func, @args) = @_;
+	my $args = join ", ", @args;
+	my $argnames = join ", ", getargnames(@args);
+
+	print <<EOF;
+void VG_(init_$func)($ret (*func)($args))
+{
+	if (func == NULL)
+		func = missing_${pfx}_$func;
+	if (VG_(defined_$func)())
+		VG_(printf)("Warning tool is redefining $func\\n");
+	if (func == SK_($func))
+		VG_(printf)("Warning tool is defining $func recursively\\n");
+	$struct.${pfx}_$func = func;
+}
+EOF
+    }
+} elsif ($output eq "initproto") {
+    $generate = sub ($$$@) {
+	my ($pfx, $ret, $func, @args) = @_;
+	my $args = join ', ', @args;
+	print "void VG_(init_$func)($ret (*func)($args));\n";
+    };
+    $headerguard=$output;
+} elsif ($output eq "initdlsym") {
+    $pre = sub () {
+	print <<EOF;
+#include <dlfcn.h>
+void VG_(tool_init_dlsym)(void *dlhandle)
+{
+   void *ret;
+
+EOF
+    };
+    $post = sub () {
+	print "}\n";
+    };
+    $generate = sub ($$$@) {
+	my ($pfx, $ret, $func, @args) = @_;
+	my $args = join ", ", getargtypes(@args);
+
+	print <<EOF;
+   ret = dlsym(dlhandle, "vgSkin_$func");
+   if (ret != NULL)
+      VG_(init_$func)(($ret (*)($args))ret);
+
+EOF
+    };
+
+    $passcomment = 0;
+}
+
+die "Unknown output format \"$output\"" unless defined $generate;
+
+print "/* Generated by \"gen_toolint.pl $output\" */\n";
+
+print <<EOF if defined $headerguard;
+
+#ifndef VG_toolint_$headerguard
+#define VG_toolint_$headerguard
+
+EOF
+
+print <<EOF if defined $include;
+#include \"$include\"
+EOF
+
+&$pre() if defined $pre;	# preamble
+
+my $state = "idle";
+
+my $buf;
+my $lines;
+
+while(<STDIN>) {
+    # skip simple comments
+    next if (/^#[^#]/);
+
+    if (/^:/) {
+	s/^://;
+	chomp;
+	$prefix=$_;
+	next;
+    }
+
+    # look for inserted comments
+    if (/^##/) {
+	if ($state eq "idle") {
+	    $state = "comment";
+	    $lines = 1;
+	    $_ =~ s,^## ,/* ,;
+	    $buf = $_;
+	    next;
+	} elsif ($state eq "comment") {
+	    $lines++;
+	    $_ =~ s,^## ,   ,;
+	    print $indent.$buf if $passcomment;
+	    $buf = $_;
+	    next;
+	}
+	next;
+    }
+
+    # blank lines in a comment are part of the comment
+    if (/^\s*$/) {
+	if ($state eq "comment") {
+	    $lines++;
+	    print $indent.$buf if $passcomment;
+	    $buf = "\n";
+	} else {
+	    print "\n" if $passcomment;
+	}
+	next;
+    }
+
+    # coming out of a comment
+    if ($state eq "comment") {
+	chomp $buf;
+
+	if ($passcomment) {
+	    if ($lines == 1) {
+		print "$indent$buf */\n";
+	    } else {
+		print "$indent$buf\n$indent */\n";
+	    }
+	}
+	$buf = "";
+	$state = "idle";
+    }
+
+    chomp;
+    my @func = split /,\s*/;
+
+    my $rettype = shift @func;
+    my $funcname = shift @func;
+
+    @func = "void" if scalar @func == 0;
+
+    &$generate ($prefix, $rettype, $funcname, @func);
+}
+
+&$post() if defined $post;	# postamble
+
+print <<EOF if defined $headerguard;
+
+#endif /* VG_toolint_$headerguard */
+EOF