4 sub pr2
{ print "$_[0]\n"; }
8 # to be launched from the git directory
9 die "usage: $0 commithashafter [commithashbefore]"
10 if(@ARGV <= 0 || @ARGV >= 3);
12 # update: now I also extract the headers files, the one
13 # that were modified in the commit and the one that are
14 # locally used and that may contain useful type information
17 # update: now I also extract some include/linux/header.h files, the
18 # one having the same name of one of the driver.
20 my $target_dir = "/tmp/extract_c_and_res/$ARGV[0]";
21 `mkdir -p $target_dir`;
22 my $old_dir = "/tmp/extract_c_and_res/$ARGV[0]_old";
24 my $new_dir = "/tmp/extract_c_and_res/$ARGV[0]_new";
27 my $commit_new = $ARGV[0];
28 my $commit_old = $ARGV[1] || "$commit_new^"; # default parent
30 my $gitfile = "$target_dir/$commit_new.gitinfo";
31 my $makefile = "$target_dir/Makefile";
33 `git show $commit_new > $gitfile `;
36 # processing the patch
40 my @driverheaders_in_include = ();
43 open FILE
, "$gitfile" or die "$!";
46 # allow other dir ? # fs|mm there is drivers under arch/ too
47 if(/^diff --git a\/((drivers
|sound
)\
/.*?\.[ch]) b/){
54 elsif(/^diff --git a\/(include\
/.*?\.h) b/) {
55 mylog
"potential header driver $1\n";
56 push @driverheaders_in_include, $1;
58 elsif(/^diff --git a\//) {
59 mylog
" not driver:$_";
62 die "PB: strange diff line: $_";
66 # extracting the .c and .h of the patch
70 # to be able to later find the corresponding local included header file
71 my $kerneldir_of_file = {};
76 foreach my $f (@files) {
77 my ($base) = `basename $f`;
84 $res =~ s/\.h$/.h.res/;
87 pr2
"processing: $f $base $res";
88 if(-e
"$target_dir/$base") {
90 $base = "${counter}_$base";
91 $res = "${counter}_$res";
92 pr2
"try transform one file because already exist: $base";
94 die "PB: Two header files share the same name: $base.";
98 die "PB: one of the file already exist: $base" if (-e
"$target_dir/$base");
100 `git-cat-file blob $commit_old:$f > $target_dir/$base`;
101 `git-cat-file blob $commit_new:$f > $target_dir/$res`;
103 `git-cat-file blob $commit_old:$f > $old_dir/$base`;
104 `git-cat-file blob $commit_new:$f > $new_dir/$base`;
106 $kerneldir_of_file->{$base} = `dirname $f`;
107 chomp $kerneldir_of_file->{$base};
109 push @finalcfiles, $base;
110 $finalcfiles->{$base} = 1;
117 open MAKE
, ">$makefile" or die "$!";
118 print MAKE
"CEDESCRIPTION=\"\"\n";
119 print MAKE
"SP=foo.cocci\n";
120 print MAKE
"SOURCES = ";
121 my $last = shift @finalcfiles;
122 foreach my $f (@finalcfiles) {
123 print MAKE
"$f \\\n\t";
125 print MAKE
"$last\n";
130 include \$(TOP)/generic_makefile
135 # process potential driver headers of include/
137 foreach my $f (@driverheaders_in_include) {
138 my $base = `basename $f`;
142 } else { die "PB: internal error"; }
145 # julia want all .h that were in the patch, not just the headers
146 # of our heuristic. Hence the comment.
149 # if(defined($finalcfiles->{$base})) {
151 # pr2 "found header of driver in include/: $f of $base";
152 my $dir = `dirname $f`;
154 `mkdir -p $target_dir/$dir`;
155 `git-cat-file blob $commit_old:$f > $target_dir/$f`;
156 `git-cat-file blob $commit_new:$f > $target_dir/$f.res`;
158 `mkdir -p $old_dir/$dir`;
159 `mkdir -p $new_dir/$dir`;
160 `git-cat-file blob $commit_old:$f > $old_dir/$f`;
161 `git-cat-file blob $commit_new:$f > $new_dir/$f`;
166 # compute other linux headers not in the patch
168 my @linuxheaders = `cd $target_dir; grep -E \"#include +\<[^>]*\>\" *.c *.h`;
169 foreach my $line (@linuxheaders) {
172 if($line =~ /^(.*)?:#include *\<([^>]*)\>/) {
173 my ($_file, $f) = ($1, $2);
175 my $base = `basename $f`;
179 } else { die "PB: internal error"; }
181 if(defined($finalcfiles->{$base}) && ! -e
"$target_dir/include/$f") {
182 pr2
"found header of driver in include/: $f of $base";
183 my $dir = `dirname $f`;
185 `mkdir -p $target_dir/include/$dir`;
186 `git-cat-file blob $commit_old:include/$f > $target_dir/include/$f`;
188 } else { pr2
"pb regexp: $line"; }
192 # compute other local headers not in the patch
194 my @headers = `cd $target_dir; grep -E \"#include +\\".*\\"\" *.c *.h`;
197 foreach my $line (@headers) {
200 if($line =~ /^(.*)?:#include *"(.*)"/) {
202 my ($file, $header) = ($1, $2);
203 my $dir = $kerneldir_of_file->{$file};
205 my $fullheader = "$dir/$header";
208 if($files->{$fullheader}) {
209 pr2
"INFO: $fullheader was already in commit";
211 $hfiles->{$fullheader} = 1;
214 } else { pr2
"pb regexp: $line"; }
218 foreach my $h (keys %{$hfiles}) {
219 my ($base) = `basename $h`;
221 pr2
"processing additionnal header file: $h $base";
223 if(-e
"$target_dir/$base") {
224 pr2
"-------------------------------------";
225 pr2
"PB: local header (not modified in the git) $base already exists";
226 pr2
"BUT I CONTINUE, but may have more .failed in the end";
227 pr2
"-------------------------------------";
229 `git-cat-file blob $commit_old:$h > $target_dir/$base`;