#!/usr/bin/env perl use strict; my $error; my %state; sub usage() { die <<EOF; Usage: $0 <file> <command> [<arguments>] Commands: add-hash <variable> <value> fix-hash <variable> <value> rename-var <variable> <name> EOF } sub set_var($) { my $var = shift; $state{var} = $var; if ($var =~ /(.*):(.*)/) { $state{template} = $1; $state{var} = $2; $state{related_var} = "URL"; } else { $state{context} = 1; $state{related_var} = "PKG_SOURCE_URL"; } } my %check_command = ( "add-hash" => sub { set_var($ARGV[0]); $state{value} = $ARGV[1]; length($ARGV[1]) == 64 or die "Invalid hash value\n"; }, "fix-hash" => sub { set_var($ARGV[0]); $state{value} = $ARGV[1]; $state{prev_value} = $ARGV[2]; length($ARGV[1]) == 64 or die "Invalid hash value\n"; }, "rename-var" => sub { set_var($ARGV[0]); $state{new_var} = $ARGV[1]; $state{new_var} =~ s/.*://g; }, ); sub check_context($) { my $line = shift; return unless $state{template}; $state{next} and do { $state{context} = 1; undef $state{next}; return; }; if (not $state{context}) { $line =~ /^\s*define\s+$state{template}/ and $state{next} = 1; } else { $line =~ /^\s*endef/ and do { $state{done} = 1; undef $state{context}; } } } my %commands = ( "add-hash" => sub { my $line = shift; check_context($line); return $line unless $state{context}; # skip existing hash variable return "" if $line =~ /^(\s*)$state{var}(\s*):?=(\s*)(.*)\n/; # insert md5sum after related variable return $line unless $line =~ /^(\s*)$state{related_var}(\s*):?=(\s*)(.*)\n/; return "$line$1$state{var}$2:=$3$state{value}\n"; }, "fix-hash" => sub { my $line = shift; check_context($line); return $line unless $state{context}; return $line unless $line =~ /^(\s*)$state{var}(\s*):?=(\s*)(.*)$state{prev_value}(.*)\n/; $state{done} = 1; $4 =~ /\$/ and do { warn "$state{var} contains a reference to another variable, can't fix automatically\n"; return $line; }; return "$1$state{var}$2:=$3$state{value}\n"; }, "rename-var" => sub { my $line = shift; check_context($line); return $line unless $state{context}; return $line unless $line =~ /^(\s*)$state{var}(\s*:?=.*)\n/; return "$1$state{new_var}$2\n"; }, ); my $file = shift @ARGV; my $command = shift @ARGV; ($file and $command and $check_command{$command}) or usage; &{$check_command{$command}}(); -f $file or die "File $file not found\n"; open IN, "<${file}" or die "Cannot open input file\n"; open OUT, ">${file}.new" or die "Cannot open output file\n"; my $cmd = $commands{$command}; while (my $line = <IN>) { $line = &$cmd($line) unless $state{done}; print OUT $line; last if $error; } close OUT; close IN; $error and do { unlink "${file}.new"; exit 1; }; rename "${file}.new", "$file";