#!/usr/bin/perl
#
# USAGE: specparser.pl file.spec
#
# Output:
#   stdout:
#     list of:
#       <md5><space><url>\n
#     for given specfile.
#     except for lines prefixed with: ERROR:
#   exit status:
#     0 - normal
#     2 - cannot open spec file
#

%macro = ();

# expand macros in string
sub expand($)
{
  my $v = shift;
  my $cnt = 20;

  $v =~ s/\s+$//;
  $v =~ s/^\s+//;
  
  while ($cnt-- > 0 && $v =~ /\%\{([^\{]+)\}/) {
    my $value;
    if (defined $macro{$1}) {
      $value = $macro{$1};
    } else {
      $value = "\@undef:$1\@";
    }
    $v =~ s/\%\{([^\{]+)\}/$value/;
    last if (length $v > 1000);
  }
  return $v;
}

# define given macro
sub define($$)
{
  my ($n, $v) = @_;
  $macro{$n} = expand($v);
}

# sets hash of macros defined with %define or %global
# also define %{name}, %{version} and %{source_N}
sub parse_defines($)
{
  open(F, "< $_[0]") or die;
  while (<F>) {
    chomp;
    if (/^\s*\%(define|global)\s+([^\s]+)\s+([^\s].*)$/) {
     define($2, $3);
    } elsif (/^Version\s*:\s*(.*)/i) {
      define("version", $1);
    } elsif (/^Name\s*:\s*(.*)/i) {
      define("name", $1);
    } elsif (/^Source(\d+)\s*:\s*(.*)/i) {
      define("source_$1", $2);
    }
  }
  close(F);
}

sub print_md5($)
{
  open(F, "< $_[0]") or die;
  while (<F>) {
    chomp;
    if (/^\s*#\s*source(\d+)-md5\s*:\s*([a-f0-9]{32})/i) {
      my $no = $1;
      my $md5 = $2;
      if (defined $macro{"source_$1"}) {
        my $s = $macro{"source_$1"};
	if ($s =~ /^([a-z0-9A-Z:\+\~\.\-\/_]|\%[0-9])+$/) {
	  if ($s =~ /^(ftp|http):\/\//) {
            print "$md5 $s\n";
	  } else {
	    print "ERROR: $_[0]: source $no ($s) isn't http/ftp url\n";
	  }
	} else {
	  print "ERROR: $_[0]: source $no url $s is ill-formatted\n";
	}
      } else {
        print "ERROR: $_[0]: source $no not defined\n";
      }
    }
  }
  close(F);
}

$spec = shift;

parse_defines($spec);
print_md5($spec);

exit(0);
