#!/usr/bin/perl


use strict;

my @names;
my @series;

sub banner {
    print "/**************************************\n";
    print " * DO NOT EDIT THIS FILE              *\n";
    print " * File autogenerated from a template *\n";
    print " * DO NOT EDIT THIS FILE              *\n";
    print " **************************************/\n";
}

banner();

while (<>) {
    chomp;
    if (/^__BEGIN_TEMPLATE_ARGS_NAME__$/) {
	@names=();
	@series=();
      ARGS_NAME: {
	  banner();
	  while (<>) {
	      chomp;
	      if (/^__END_TEMPLATE_ARGS_NAME__$/) {
		  last ARGS_NAME;
	      }
	      if (! /^[a-zA-Z0-9_]+$/) {
		  die "Invalid name '$_'";
	      }
	      push @names, $_;
	  }
	  print STDERR "End of file while reading ARGS_NAME\n";
	  exit 1;
      }
    } elsif (/^__BEGIN_TEMPLATE_ARGS__$/) {
	my @args;
      ARGS: {
	  while (<>) {
	      chomp;
	      if (/^__END_TEMPLATE_ARGS__$/) {
		  last ARGS;
	      }
	      push @args, $_;
	  }
	  print STDERR "End of file while reading ARGS\n";
	  exit 1;
      }
	if (scalar(@args) != scalar(@names)) {
	    die "Bad number of ARGS";
	}
	push @series, \@args;
    } elsif (/^__TEMPLATE_ARGS_AUTOFILL__([0-9]*)$/) {
        my $nmax=$1;
        for(my $i=1; $i<$nmax; $i++) {
	    my @args;
	    push @args, $i;
	    my ($list_params, $store_params);
	    for(my $j=1; $j<=$i; $j++) {
		$list_params .= ',P'.$j;
		$store_params .= '*(__args++)=(unsigned long)(P'.$j.');';
            }
	    push @args, $list_params, $list_params, $store_params;
	    if (scalar(@args) != scalar(@names)) {
		die "Bad number of ARGS: ";
	    }
	    push @series, \@args;
        }
    } elsif (/^__BEGIN_TEMPLATE__$/) {
	my @code;
      TEMPLATE: {
	  while (<>) {
	      chomp;
	      if (/^__END_TEMPLATE__$/) {
		  last TEMPLATE;
	      }
	      push @code, $_;
	  }
	  print STDERR "End of file while reading TEMPLATE\n";
	  exit 1;
      }
	foreach my $serie (@series) {
	    my @block=@code;
	    foreach my $line (@block) {
		my $index=0;
		foreach my $name (@names) {
		    $line =~ s/__${name}__/$serie->[$index]/g;
		    $index++;
		}
	    }
	    print join("\n", @block)."\n";
	}
    } else {
	print $_."\n";
    }
}
