#! /usr/bin/perl -w
#
# Created	: Thu 07 Dec 2006 03:35:39 PM PST
# Modified	: Wed 25 Mar 2009 11:44:39 AM PDT
# Author	: Gautam Iyer <gi1242ATusersDOTsourceforgeDOTnet>
# Description	: Substiute arguments and execute a command

use strict;

use Getopt::Long qw(:config no_ignore_case bundling);
use Term::ANSIColor qw(:constants);

# Terminal colors
my ($BD,$UL,$IT,$ER,$RE)=(RESET.CYAN,RESET.GREEN,RESET.YELLOW,RESET.RED,RESET);

# Options
my $echo_only	= 0;
my $print_help	= 0;
my $input;
my $delim	= '\s*,\s*';
my $command;
my $cmdfile	= "-";
my $varsign	= '%';

# Subroutines
# {{{1 print_usage()
sub print_usage
{
    print << "EOF";
$BD$0$RE [options]

    Execute a command substuting $UL%n$RE with field values from an input file.

${BD}OPTIONS$RE

    $UL-i ${IT}file$RE	Read input fields from ${IT}file$RE
    $UL-d ${IT}delim$RE	Use ${IT}delim$RE as delimiter (instead of $BD$delim$RE).
    $UL-v ${IT}varsign$RE	Use ${IT}varsign$RE for variable interpolation (default $BD$varsign$RE).
    $UL-c ${IT}cmd$RE	Execute command ${IT}cmd$RE. (Must be the last argument).
    $UL-C ${IT}file$RE	Read command from ${IT}file$RE (default ${BD}stdin$RE).
    $UL-e$RE		Only echo command, and don't execute anything.
    $UL-h$RE		Print this help.

EOF
    exit(1);
}

# {{{1 quit
sub quit
{
    print( "${ER}Error:$RE @_\n" );
    exit(1);
}
#}}}1


# Variables
my $line;
my @fields;
my $nlines=0;

GetOptions(
    "input|i=s"	    => \$input,
    "delim|d=s"     => \$delim,
    "varsign|v=s"   => \$varsign,
    "c"		    => sub { $command = join( ' ', @ARGV); die("!FINISH") },
    "cmdfile|C=s"   => \$cmdfile,
    "echo|e"	    => \$echo_only,
    "help|h"	    => \$print_help
) or print_usage();

print_usage if( $print_help );

if( !defined( $command ) && defined( $cmdfile ) )
{
    # Read command from cmdfile (default stdin).
    open( CMDFILE, "< $cmdfile" )
	or quit( "Could not read command from ${IT}$cmdfile$RE" );
    $command = join( '', <CMDFILE> );
    close( CMDFILE );
}

quit( "No input defined" ) if( !defined( $input ) );
quit( "No command defined" ) if( !defined( $command ) );

open( INPUT, "< $input" )
    or quit( "Could not open ${IT}$input$RE for reading" );

while( my $line = <INPUT> )
{
    chomp($line);
    $fields[$nlines++] = [ split( $delim, $line ) ];
}

close( INPUT );

foreach my $record (@fields)
{
    my $this_command = $command;
    
    while( $this_command =~ m/$varsign(\d+|$varsign)/g )
    {
	my $matchlen = length($&);
	my $pos = pos($this_command) - $matchlen;
	my $repl;

	if( $1 eq $varsign )
	{
	    $repl = $varsign;
	}
	elsif( defined( $record->[$1-1] ) )
	{
	    $repl = $record->[$1-1];
	}

	if( defined( $repl ) )
	{
	    #$this_command =~ s//$repl/;
	    substr( $this_command, $pos, $matchlen) = $repl;
	    pos( $this_command ) = $pos + length($repl);
	}
    }

    if( $echo_only )
    {
	print( "$this_command\n" );
    }
    else
    {
	system( $this_command );
    }
}
