1#! /usr/bin/perl -w
2# ----------------------------------------------------------------------------
3# "THE BEER-WARE LICENSE" (Revision 42)
4# <tobez@FreeBSD.org> wrote this file.  As long as you retain this notice you
5# can do whatever you want with this stuff. If we meet some day, and you think
6# this stuff is worth it, you can buy me a beer in return.   Anton Berezin
7# ----------------------------------------------------------------------------
8#
9use strict;
10
11# good tests:
12# /usr/ports/archivers/zoo/files/patch-aa  (context diff)
13# /usr/ports/astro/xplanet/files/patch-aa  (unified with paths)
14
15my ($in,$fl,$abort,$state,$out);
16
17if (!@ARGV || $ARGV[0] =~ /^-/) {
18	print STDERR "Usage:
19	$0 patchfile ...
20"
21}
22
23while (@ARGV) {
24	$in = shift;
25	$state = \&nofile;
26	if (open IN, "< $in") {
27		$abort = 0;
28		$out = "";
29		$fl = "";
30		while (<IN>) {
31			$state->();
32			last if $abort;
33		}
34		close IN;
35		if ($out && !$abort) {
36			print "Wrote $out\n";
37		}
38	} else {
39		print STDERR "cannot open $in: $!\n";
40	}
41}
42
43sub nofile
44{
45	if (/^\*\*\*\s+/ && !/^\*\*\*\s+\d+,\d+\s+/) {
46		$state = \&cstart;
47		$fl = $_;
48	} elsif (/^---\s+/ && !/^---\s+\d+,\d+\s+/) {
49		$state = \&ustart;
50		$fl = $_;
51	}
52}
53
54sub cstart
55{
56	if (!/^---\s+\d+,\d+\s+/ && /^---\s+(\S+)\s+/) {
57		$state = \&body;
58		$out = $1;
59		$out =~ s|/|__|g;
60		$out = "patch-$out";
61		if (open OUT, "> $out") {
62			print OUT $fl;
63			print OUT $_;
64		} else {
65			print STDERR "Cannot create $out: $!, aborting\n";
66			$abort = 1;
67		}
68	} else {
69		print STDERR "Bad context diff in $in, aborting\n";
70		$abort = 1;
71	}
72}
73
74sub ustart
75{
76	if (/^\+\+\+\s+(\S+)\s+/) {
77		$state = \&body;
78		$out = $1;
79		$out =~ s|/|__|g;
80		$out = "patch-$out";
81		if (open OUT, "> $out") {
82			print OUT $fl;
83			print OUT $_;
84		} else {
85			print STDERR "Cannot create $out: $!, aborting\n";
86			$abort = 1;
87		}
88	} else {
89		print STDERR "Bad unified diff in $in, aborting\n";
90		$abort = 1;
91	}
92}
93
94sub body
95{
96	if (/^\*\*\*\s+/ && !/^\*\*\*\s+\d+,\d+\s+/) {
97		close OUT;
98		print "Wrote $out\n";
99		$state = \&cstart;
100		$fl = $_;
101	} elsif (/^---\s+/ && !/^---\s+\d+,\d+\s+/) {
102		close OUT;
103		print "Wrote $out\n";
104		$state = \&ustart;
105		$fl = $_;
106	} else {
107		print OUT $_;
108	}
109}
110