#!/usr/bin/perl -w

#check commandline:
unless ($ARGV[0])
{ 
   print <<EOL;
Syntax: xmg.pl <script> [code|eval] <arguments>

Reads <script> which is a xmgrace/perl program, and transforms
it into a perl program. The resulting perl program is evaluated
and the output piped to xmgrace.

Debugging:
            xmg.pl <script> code <arguments>
            xmg.pl <script> eval <arguments>
        
Prints out the Perl code corresponding to the script, or
the xmgrace batch commands that resulted from evaluating
the script.

Scripts should start like this:
#!/bin/sh
eval 'exec perl ~/bin/xmg.pl $0 ${1+"$@"}'
##xmgrace -geometry 1320x960 -nosafe
:
script
:

Line two makes shell runs xmg.pl as the parser of the script,
while the 3rd line (optional) defines the commandline arguments
for xmgrace.

Syntax:
## are remarks
#  are xmgrace batch language statements (converted to print "..")
anything else is assumed to be Perl statements.

Example:
make graph of y/x vs. x for all files matching a glob.
Run as e.g. plot_test 'output/*.dat'

#get glob from commandline
\$g=shift @ARGV;   

#title "Graph of files: \$g"

#load, transform and plot
\$c=1;  #black
foreach (glob \$g)
{
#  read "\$_"
#  s_ legend "\$_"
#  s_ line color \$c
#  s_.y=s_.y/s_.x
\$c++;
}
EOL
   die;
}

#arguments
my $xmgracearg="";

#code
my $code;

#script filename
my $file=shift @ARGV;

open FI, $file or die "$! $file\n";
while (<FI>)
  {
     chomp;
     if (/^##\s*xmgrace\s+(.*)$/i) { $xmgracearg.=" $1 "; }
     elsif (/^#!/ or /^eval\s+'\s*exec/i)  {}                    #dump
     elsif (/^#(#.+)/)                     {$code .= $1."\n";}   #keep remarks
     elsif (/^#(.+)/)
       {
          $t=$1;
          $t=~ s/\\/\\\\/g;
          $t=~ s/"/\\"/g;
          $code.="\t\t\tprint \"".$t.'\n'."\";\n";
       }
     else
       {
          $code.=$_."\n";
       }
  }
close FI;

#check for debugging mode
if ( $ARGV[0] )
  {   
    if ( $ARGV[0] =~ /code/i ) 
       {
          shift @ARGV;
          print $code;
          die;
       }
    elsif  ($ARGV[0] =~ /eval/i ) 
       {
          shift @ARGV;
          print eval($code);
          die;
       }
   }

#play the pipe
my $FIFO = "/tmp/xmgrace_pipe".scalar(time);

#create pipe
if (not -p $FIFO)
   {
      unlink $FIFO;
      $com="/bin/mknod --mode 777 $FIFO p";
      system ($com); # or die "Can't create pipe $! $FIFO\ncommand: $com\n";
   }

#fork process
if (my $pid=fork())
  {
     open  STDOUT,">$FIFO" or die "Can't write to FIFO";
     select STDOUT; $|=1;  #set STDOUT to go through pipe unbuffered
     eval($code);

     die "PERL ERROR:\n$@\n" if ($@);
     sleep 1;
     waitpid($pid,0);   #don't kill parent before child completes
  }
 else
  { 
     system "xmgrace $xmgracearg -npipe $FIFO";  #run xmgrace process
     unlink $FIFO;
     exit;
  }

