summaryrefslogtreecommitdiff
path: root/spec_add_patch
diff options
context:
space:
mode:
authorZhang Qiang <qiang.z.zhang@intel.com>2014-04-03 15:53:09 +0800
committerZhang Qiang <qiang.z.zhang@intel.com>2014-04-03 15:53:09 +0800
commitb979ae3b9b879ce19582770e2ba89eb3e66f964a (patch)
tree758e7684bbaa43d8899ccbc49b133ff0112d3a88 /spec_add_patch
downloadbuild-b979ae3b9b879ce19582770e2ba89eb3e66f964a.tar.gz
build-b979ae3b9b879ce19582770e2ba89eb3e66f964a.tar.bz2
build-b979ae3b9b879ce19582770e2ba89eb3e66f964a.zip
Imported Upstream version 2013.11.12upstream/2013.11.12
Diffstat (limited to 'spec_add_patch')
-rwxr-xr-xspec_add_patch143
1 files changed, 143 insertions, 0 deletions
diff --git a/spec_add_patch b/spec_add_patch
new file mode 100755
index 0000000..fd62753
--- /dev/null
+++ b/spec_add_patch
@@ -0,0 +1,143 @@
+#!/usr/bin/perl -w
+# vim:sw=4:et
+# Author: Dirk Mueller
+
+use strict;
+
+sub helpexit {
+ print "$0: <patches...> [file.spec]\n";
+ exit 1;
+}
+
+my $specname;
+my %diffs;
+
+for my $arg (@ARGV) {
+ if ($arg =~ /\.spec$/) {
+ helpexit() if $specname;
+ $specname = $arg;
+ next;
+ }
+ $diffs{$arg} = 1;
+}
+
+sub find_specfile()
+{
+ opendir(D, ".");
+ my @specs = grep { /\.spec$/ } readdir(D);
+ closedir(D);
+
+ # choose the one with the shortest name (heuristic)
+ $specname = ( sort { length($a) - length($b) } @specs)[0];
+
+}
+
+if (!defined($specname) || ! -f $specname) {
+ &find_specfile();
+}
+
+
+open(S, '<', $specname) or die;
+
+my $ifdef_level = 0;
+my $in_prep = 0;
+my $in_global = 1;
+my $last_patch_in_prep_index = 0;
+my $last_patch_in_global_index = 0;
+my @c = ();
+my $index = 0;
+
+# first read the specfile, parse useful information
+while(<S>)
+{
+
+ if(/^\s*%\s*endif/) {
+ $ifdef_level--;
+ $last_patch_in_prep_index = $index if ($in_prep && $ifdef_level == 0);
+ }
+ die if ($ifdef_level < 0);
+ $ifdef_level++ if(/^\s*%\s*if/);
+
+ if ($ifdef_level == 0 && !$in_prep && $in_global
+ && /^\%(?:prep|build|install|package|description|doc)/) {
+ $in_global = 0;
+ }
+
+ if (!$in_prep && /^%prep/i) {
+ $in_prep = 1;
+ die if ($in_global);
+ }
+
+ if ($in_prep
+ && /^%setup\b/) {
+ $last_patch_in_prep_index = $index;
+ }
+
+ if ($in_prep
+ && /^\%(?:build|install|package|description|doc)/) {
+ $in_prep = 0;
+ }
+
+ die if (($in_prep + $in_global) > 1);
+
+ if ($in_global && /^Patch(?:\d+)?:\s+(.+)/) {
+ $last_patch_in_global_index = $index;
+ if ($diffs{$1}) {
+ print "$1 already in, skipped.";
+ delete $diffs{$1};
+ }
+ }
+
+ if ($in_global && $ifdef_level == 0 && /^Source(?:\d+)?:/) {
+ $last_patch_in_global_index = $index;
+ }
+
+ if ($in_prep && $ifdef_level == 0 && /^\%patch/) {
+ $last_patch_in_prep_index = $index;
+ }
+ push(@c, $_);
+ $index++;
+}
+close(S);
+
+die if ($ifdef_level > 0);
+die if ($in_global || $in_prep);
+die if ($last_patch_in_prep_index == 0);
+die if ($last_patch_in_global_index == 0);
+
+#print "adding Patch: $diffname to line $last_patch_in_global_index\n";
+#print "adding %patch to line $last_patch_in_prep_index\n";
+
+# determine patch number
+my $patchnum = 0;
+$patchnum = $1+1 if ($c[$last_patch_in_global_index] =~ /Patch(\d+):/);
+$patchnum = 1 if ($c[$last_patch_in_global_index] =~ /Patch:/);
+
+for my $diffname (keys %diffs) {
+ # determine strip level
+ my $striplevel = "";
+ open(P, '<', $diffname) or die "$diffname: $!\n";
+ while(<P>) {
+ $striplevel = " -p1" if (m/^--- a/ or m/^--- [^\/]+-\d+\./);
+ last if (/^--- /);
+
+ }
+ close(P);
+
+ print "Adding patch$striplevel $diffname to $specname\n";
+
+
+ splice @c, $last_patch_in_prep_index+1, 0, ("\%patch$patchnum$striplevel\n");
+ splice @c, $last_patch_in_global_index+1, 0,
+ (sprintf "Patch%s:%s%s\n", $patchnum, ' ' x (10-length($patchnum)), $diffname);
+ ++$last_patch_in_global_index;
+ $last_patch_in_prep_index+=2; # actually line number
+ ++$patchnum;
+}
+
+open(O, '>', "$specname.new") or die;
+print O @c;
+close(O);
+
+system("diff", "-u", $specname, "$specname.new");
+rename("$specname.new", $specname);