From b737fef13a9f5102ecedbb3ea88d9f131c1e5b40 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (laptop)" <j.wuttke@fz-juelich.de>
Date: Tue, 8 Jan 2013 10:27:15 +0100
Subject: [PATCH] new curve per script mode 'cl': parameters on command line,
 instead of stdin

---
 pub/src/curve.cpp | 93 +++++++++++++++++++++++++++++++----------------
 pub/src/olf.h     |  4 +-
 2 files changed, 63 insertions(+), 34 deletions(-)

diff --git a/pub/src/curve.cpp b/pub/src/curve.cpp
index 835eb530..b11bf2a3 100644
--- a/pub/src/curve.cpp
+++ b/pub/src/curve.cpp
@@ -104,7 +104,7 @@ void COlc::parseFunction( const string& _expr )
 void COlc::askCurve( const string& quest )
 {
 ask_again:
-    string resp = sask( quest+" (or c,ci; h for help) ?" );
+    string resp = sask( quest+" (or c,ci,cl; h for help) ?" );
     if        ( resp=="h" ) {
         cout <<
         "curve definition:\n"
@@ -113,7 +113,8 @@ ask_again:
         "    for instance: p0+p1*t\n"
         "- or one of the following keywords:\n"
         "    c: external curve evaluation command (hc for help)\n"
-        "    ci: external command followed by interpolation (hci for help)\n";
+        "    ci: external command followed by interpolation (hci for help)\n"
+        "    cl: dito, input from command line (hcl for help)\n";
         goto ask_again;
     } else if ( resp=="hc" ) {
         cout <<
@@ -137,12 +138,27 @@ ask_again:
             "  - N*2*double: N lines with pairs x y\n"
             "- write error messages to stderr\n";
         goto ask_again;
+    } else if ( resp=="hcl" ) {
+        cout <<
+            "the external curve evaluation command must:\n"
+            "- read from M parameters from the command line\n"
+            "- write to stdout:\n"
+            "  - N*2*double: N lines with pairs x y\n"
+            "- write error messages to stderr\n";
+        goto ask_again;
     } else if ( resp=="c" ) {
         evaMode = COlc::_SCR;
+        scrInpMode = COlc::_STDIN;
         expr = sask( "Curve evaluation command ?" );
         nP = iask( "Number of parameters ?" );
     } else if ( resp=="ci" ) {
         evaMode = COlc::_SCR_INTP;
+        scrInpMode = COlc::_STDIN;
+        expr = sask( "Curve evaluation command ?" );
+        nP = iask( "Number of parameters ?" );
+    } else if ( resp=="cl" ) {
+        evaMode = COlc::_SCR_INTP;
+        scrInpMode = COlc::_CMDLIN;
         expr = sask( "Curve evaluation command ?" );
         nP = iask( "Number of parameters ?" );
     } else {
@@ -181,43 +197,56 @@ void COlc::curve_val_vec( vector<double>* ret, const vector<double>& vt,
         }
     } else if ( evaMode==_SCR || evaMode==_SCR_INTP ) {
 
-        string par_fifonam = string("/tmp/par-") + getenv( "LOGNAME" );
+        // Create FIFO to receive return values.
+           // TODO: choose name as: triv::next_tmp_file( "/tmp/frida.%d" );
         string ret_fifonam = string("/tmp/ret-") + getenv( "LOGNAME" );
-
-        // TODO: choose name as: triv::next_tmp_file( "/tmp/frida.%d" );
-
-        triv::system( "rm -f "+par_fifonam );
         triv::system( "rm -f "+ret_fifonam );
-        if ( mkfifo( par_fifonam.c_str(), 0666 ) )
-            throw "SYSTEM ERROR cannot make " + par_fifonam;
         if ( mkfifo( ret_fifonam.c_str(), 0666 ) )
-            throw "SYSTEM ERROR cannot make " + par_fifonam;
+            throw "SYSTEM ERROR cannot make " + ret_fifonam;
   
-        string cmd = expr + " < " + par_fifonam + " > " + ret_fifonam + " &";
-        system( cmd.c_str() );
-
-        int par_fifo;
-        // we use open instead of fopen or ofstream,
-        // because we need non-blocking mode.
-        if ( !( par_fifo = open( par_fifonam.c_str(), O_WRONLY ) ) )
-            throw "SYSTEM ERROR cannot open " + par_fifonam;
-        fcntl( par_fifo, F_SETFL, O_NONBLOCK);
-
-        string out = str( format("%i ") % nP );
-        write( par_fifo, out.c_str(), out.size() );
-        for ( uint ip=0; ip<nP; ++ip ) {
-            string out = str( format("%g ") % VC(j)->P[ip] );
-            write( par_fifo, out.c_str(), out.size() );
-        }
-        if ( evaMode==_SCR ) {
-            string out = str( format("%i ") % vt.size() );
+        if ( scrInpMode==_STDIN ){
+
+            string par_fifonam = string("/tmp/par-") + getenv( "LOGNAME" );
+            triv::system( "rm -f "+par_fifonam );
+            if ( mkfifo( par_fifonam.c_str(), 0666 ) )
+                throw "SYSTEM ERROR cannot make " + par_fifonam;
+
+            string cmd = expr + " < " + par_fifonam +
+                " > " + ret_fifonam + " &";
+            system( cmd.c_str() );
+
+            int par_fifo;
+            // we use open instead of fopen or ofstream,
+            // because we need non-blocking mode.
+            if ( !( par_fifo = open( par_fifonam.c_str(), O_WRONLY ) ) )
+                throw "SYSTEM ERROR cannot open " + par_fifonam;
+            fcntl( par_fifo, F_SETFL, O_NONBLOCK);
+
+            string out = str( format("%i ") % nP );
             write( par_fifo, out.c_str(), out.size() );
-            for ( uint i=0; i<vt.size(); ++i ) {
-                string out = str( format("%g ") % vt[i] );
+            for ( uint ip=0; ip<nP; ++ip ) {
+                string out = str( format("%g ") % VC(j)->P[ip] );
                 write( par_fifo, out.c_str(), out.size() );
             }
+            if ( evaMode==_SCR ) {
+                string out = str( format("%i ") % vt.size() );
+                write( par_fifo, out.c_str(), out.size() );
+                for ( uint i=0; i<vt.size(); ++i ) {
+                    string out = str( format("%g ") % vt[i] );
+                    write( par_fifo, out.c_str(), out.size() );
+                }
+            }
+            close( par_fifo );
+
+        } else { // scrInpMode==_CMDLIN
+
+            string pars = "";
+            for ( uint ip=0; ip<nP; ++ip )
+                pars += " " + str( format("%g ") % VC(j)->P[ip] );
+
+            string cmd = expr + pars + " > " + ret_fifonam + " &";
+            system( cmd.c_str() );
         }
-        close( par_fifo );
 
         FILE *F;
         if( !(F = fopen( ret_fifonam.c_str(), "r")) )
@@ -229,7 +258,7 @@ void COlc::curve_val_vec( vector<double>* ret, const vector<double>& vt,
                     throw "script returns no value for t["+
                         S(i)+"]="+S(vt[i]);
             }
-        } else {
+        } else { // evaMode==_SCR_INTP
             CSpec S;
             double x, y;
             while ( fscanf( F, "%lg %lg\n", &x, &y )==2 )
diff --git a/pub/src/olf.h b/pub/src/olf.h
index bc2c979c..25158df6 100644
--- a/pub/src/olf.h
+++ b/pub/src/olf.h
@@ -73,8 +73,8 @@ class COld : public COlo {
 
 class COlc : public COlo {
  private:
-    // This cries for inheritance:
-    enum TEva { _EXPR, _SCR, _SCR_INTP } evaMode;
+    enum TEva    { _EXPR, _SCR, _SCR_INTP } evaMode;
+    enum TScrInp { _STDIN, _CMDLIN } scrInpMode;
  public:
     // Function:
     string expr;          ///< The curve's definition (input expression).
-- 
GitLab