Add fallback to tmpfile for use in cases where user's relying on
[p5sagit/p5-mst-13.2.git] / Porting / p4d2p
1 #!/l/local/bin/perl -wspi.bak
2
3 #
4 # reads a perforce style diff on stdin and outputs appropriate headers
5 # so the diff can be applied with the patch program
6 #
7 # Gurusamy Sarathy <gsar@activestate.com>
8 #
9
10 BEGIN {
11     $0 =~ s|.*/||;
12     if ($h or $help) {
13         print STDERR <<USAGE;
14 Usage: $0 [-v] [-h] files
15
16         -h      print this help
17         -v      output progress messages
18
19 Does inplace edit of diff files output by the perforce commands
20 "p4 describe", "p4 diff", and "p4 diff2". The result is suitable
21 for feeding to the "patch" program.
22
23 If no files are specified, reads from stdin and writes to stdout.
24
25 WARNING: It only handles context or unified diffs.
26
27 Example: p4 describe -du 123 | $0 > change-123.patch
28
29 USAGE
30         exit(0);
31     }
32     unless (@ARGV) { @ARGV = '-'; undef $^I; }
33     use vars qw($thisfile $time $file $fnum $v $h $help);
34     $thisfile = "";
35     $time = localtime(time);
36 }
37
38 my ($cur, $match);
39 $cur = m<^==== //depot/(.+?)\#\d+.* ====$> ... m<^(\@\@.+\@\@|\*+)$>;
40
41 $match = $1;
42
43 if ($ARGV ne $thisfile) {
44     warn "processing patchfile [$ARGV]\n" unless $ARGV eq '-';
45     $thisfile = $ARGV;
46 }
47
48 # while we are within range
49 if ($cur) {
50     # set the file name after first line
51     if ($cur == 1) {
52         $file = $match;
53         $fnum++;
54     }
55     # emit the diff header when we hit last line
56     elsif ($cur =~ /E0$/) {
57         my $f = $file;
58
59         # special hack for perl so we can always use "patch -p1"
60         $f =~ s<^.*?(perl.*?/)><$1>;
61
62         # unified diff
63         if ($match =~ /^\@/) {
64             warn "emitting udiff header\n" if $v;
65             $_ = "Index: $f\n--- $f.~1~\t$time\n+++ $f\t$time\n$_";
66         }
67         # context diff
68         elsif ($match =~ /^\*/) {
69             warn "emitting cdiff header\n" if $v;
70             $_ = "Index: $f\n*** $f.~1~\t$time\n--- $f\t$time\n$_";
71         }
72     }
73     # see if we hit another patch (i.e. previous patch was empty)
74     elsif (m<^==== //depot/(.+?)\#\d+.* ====$>) {
75         $file = $match = $1;
76     }
77     # suppress all other lines in the header
78     else {
79         $_ = "";
80     }
81     warn "file [$file] line [$cur] file# [$fnum]\n" if $v;
82 }
83
84 $_ .= "End of Patch.\n" if eof;