#!/usr/bin/perl
use Math::Trig;    # includes trigonometric functions
use Math::Complex; # includes support for complex functions

push @files, "<&STDIN" unless -t STDIN; # stdin is treated like any other file
foreach (@ARGV){
    if (-s $_){                     # if file exists, it mush be function name
	push @files, $_;
    } else{
	push @trans, $_;            # otherwise it is an expression for trans
    }
}

foreach (@trans)
{
    if ($_ eq "-h")
    {
	print "**************** STRANS *************\n";
	print "**      transform data files       **\n";
	print "** Copyright        Kristjan Haule **\n";
	print "** Version 2.0            5.5.1999 **\n";   
	print "*************************************\n";
	print "\n";
	print "[... |] strans f1(#1, #2, ...) [f2(#1, #2, ...)]\n";
	print "\n";
	print "Example: cat file | strans #1 #3-#2 \"tan(#4)\"\n";
	exit;
    }
    # in any user defined rule, it replaces symbol # by spl in the following way
    #    #2:3  ->  $spl[1][2]
    #    #3    ->  $spl[0][3]
    s/\#(\d+):(\d+)/\$spl\[${\($1-1)}\]\[${\($2-1)}\]/g;
    s/\#(\d+)/\$spl\[0\]\[${\($1-1)}\]/g;
}

foreach (@files){ open $_, $_;} # All files being transformed are opened

@{$spl[0]} = (' '); # object spl is initialized

# Main loop
LB: while (defined($spl[0][0])){  # goes ower all coumns
    $i=0;
    foreach $f (@files){          # goes ower all files
	$_ = <$f>;                # reads one line from this file
	if (/\#/){                # if the file is commented, just print it and do nothing
            print; $_ = <$f>;     # read next line in this case 
        }
	@{$spl[$i++]} = split(' ',$_); # saves the contents of the file into two dimentional array spl
    }                                  # $spl[i][j] containes j-th column of i-th file
    if (not defined($spl[0][0])){      # if first column does not exist, we reached end-of-file or 
	last LB;                       # end of continuous lines region of file -> finish
    }
    $line = "";                   # the output line initialized
    foreach $col (@trans){        # each column of each file is being processed
	$val = eval $col;         # the code for this column, as prepared above, is being evaluated - core step
	$line .= $val . " ";      # this transformed column is being glued together into a line
    }
    print "$line\n";              # Finally, print out the resulting row
}

sub ferm{                         # An example of fermi function which can be used in strans
  return 1.0/(exp(@_[0])+1);
}
sub nbose{                        # and bose function
  return 1.0/(exp(@_[0])-1);
}
