#!/usr/bin/perl -w
##
## RPM: Extract `Source*: ...` filenames from a SPEC file
## Copyright (c) 2007-2010 SATOH Fumiyasu @ OSS Technology, Inc.
##                         <http://www.osstech.co.jp/>
##
## License: GNU General Public License version 2 or later
## Date: 2010-07-02, since 2007-05-24
##

use strict;
#use warnings;

## Nested macro pattern
## See also: http://www.din.or.jp/~ohzaki/regex.htm#GetNestedParen
my $macro_re;
$macro_re = qr/%\{[^{}]*(?:(??{$macro_re})[^{}]*)*\}/;

## External command macro pattern
my $macro_command_re = qr/%\((?:(?!%\().)*\)/;

my %v = ();

sub pwarn
{
  print STDERR "$0: WARNING: $_[0]\n";
}

sub value
{
  my $name = shift;
  my $value = $v{$name};

  unless (defined($value)) {
    #pwarn "Undefined value: \%$name";
    $value = "### Undefined value: $name ###";
  }

  return $value;
}

sub subst
{
  my $str = shift;

  if ($str =~ /^\s*%(?:define|global)\s+(\w+)\s+(.*?)\s*$/) {
    my ($l, $r) = ($1, $2);
    $v{$l} = subst($r);
    return '';
  }

  ## Expand %{macro}
  $str =~ s/($macro_re)/subst_nested($1)/ge;
  ## Expand %(macro)
  $str =~ s/($macro_command_re)/subst_shell($1)/ge;
  ## Expand %macro
  $str =~ s/%([a-z_]\w*)/subst(value($1))/ge;

  return $str;
}

sub subst_nested
{
  my $str = shift;

  return $str if $str =~ /^%\{(\w+)\s.*\}$/;

  my ($negative, $if_defined, $name, $value) = $str =~ /^%\{(!)?(\?)?(\w+)(?::(.*))?\}$/;

  if ($if_defined) {
    return '' if (!defined($v{$name}) xor $negative);
  }
  return subst($value) if (defined($value));
  return value($name);
}

sub subst_shell
{
  my $str = shift;

  my ($shell_cmd) = $str =~ /^%\((.*)\)$/;

  my $value = eval {
    local $SIG{__WARN__} = sub {};
    `exec </dev/null; $shell_cmd`;
  };
  if (defined($value)) {
    chomp($value);
  }
  else {
    #pwarn "Command substitution failed: $shell_cmd";
    $value = "### Command substitution failed: $shell_cmd ###";
  }

  return $value;
}

while (<>) {
  chomp;

  ## FIXME
  s/\\\\/\\/g;

  if (/^%(prep|changelog)\s*$/) {
    last;
  }
  elsif (/^source\d*:\s(.*)$/i) {
    my $s = subst($1);
    #$s =~ s/%\{(\w+)\}/defined($v{$1}) ? $v{$1} : '*** UNDEFINED VALUE ***'/ge;
    if ( $s =~/^https:\/\/github\.com\/.*/){
        print "$s\n";
        next;
    }
    $s =~ s#.*/##;
    print "$s\n";
  }
  elsif (/^(\w+):\s+(.*)$/) {
    my ($l, $r) = (lc($1), $2);
    $v{$l} = subst($r);
  }
  else {
    subst($_);
  }
}

exit(0);

