13a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek#!/usr/bin/perl -w
23a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekuse strict;
33a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekuse File::Temp qw/ tempdir /;
43a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekmy $prog = "reducer";
53a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek
63a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekdie "$prog <code file> <error string> [optional command]\n" if ($#ARGV < 0);
73a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekmy $file = shift @ARGV;
83a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekdie "$prog: [error] cannot read file $file\n" if (! -r $file);
93a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek
103a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekmy $magic = shift @ARGV;
113a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekdie "$prog: [error] no error string specified\n" if (! defined $magic);
123a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek
137c45163d4daafbc367ff4e9c2324b4568b9abe5eTed Kremenek# Create a backup of the file.
143a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekmy $dir = tempdir( CLEANUP => 1 );
153a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekprint "$prog: created temporary directory '$dir'\n";
163a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekmy $srcFile = "$dir/$file";
173a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek`cp $file $srcFile`;
183a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek
193a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek# Create the script.
203a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekmy $scriptFile = "$dir/script";
213a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekopen(OUT, ">$scriptFile") or die "$prog: cannot create '$scriptFile'\n";
223a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekmy $reduceOut = "$dir/reduceOut";
233a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek
243a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekmy $command;
253a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekif (scalar(@ARGV) > 0) { $command = \@ARGV; }
263a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekelse {
2786674ec4bfc835e97714bbffe4132da24b260110Ted Kremenek  my $compiler = "clang";
283a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek  $command = [$compiler, "-fsyntax-only", "-Wfatal-errors", "-Wno-deprecated-declarations", "-Wimplicit-function-declaration"];
293a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek}
303a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekpush @$command, $srcFile;
313a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekmy $commandStr = "@$command";
323a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek
333a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekprint OUT <<ENDTEXT;
343a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek#!/usr/bin/perl -w
353a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekuse strict;
363a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekmy \$BAD = 1;
373a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekmy \$GOOD = 0;
383a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek`rm -f $reduceOut`;
393a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekmy \$command = "$commandStr > $reduceOut 2>&1";
403a4653039524e1518243ae8e77ca10534e50e378Ted Kremeneksystem(\$command);
413a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekopen(IN, "$reduceOut") or exit(\$BAD);
423a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekmy \$found = 0;
433a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekwhile(<IN>) {
443a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek  if (/$magic/) { exit \$GOOD; }
453a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek}
463a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekexit \$BAD;
473a4653039524e1518243ae8e77ca10534e50e378Ted KremenekENDTEXT
483a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekclose(OUT);
493a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek`chmod +x $scriptFile`;
503a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek
513a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekprint "$prog: starting reduction\n";
5286674ec4bfc835e97714bbffe4132da24b260110Ted Kremeneksub multidelta($) {
5386674ec4bfc835e97714bbffe4132da24b260110Ted Kremenek    my ($level) = @_;
543a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek    system("multidelta -level=$level $scriptFile $srcFile");
553a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek}
563a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek
573a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekfor (my $i = 1 ; $i <= 5; $i++) {
583a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek  foreach my $level (0,0,1,1,2,2,10) {
593a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek    multidelta($level);
603a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek  }
613a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek}
623a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek
633a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek# Copy the final file.
643a4653039524e1518243ae8e77ca10534e50e378Ted Kremenek`cp $srcFile $file.reduced`;
653a4653039524e1518243ae8e77ca10534e50e378Ted Kremenekprint "$prog: generated '$file.reduced";
66