From 58acdc9f4aec8d575de28f14da7d968dc604fd9c Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Wed, 17 Dec 2014 13:53:53 +0100
Subject: [PATCH] Support command-line arguments and shebang mechanism:
 arguments are file names of scripts to be executed before Frida goes
 interactive.

---
 TODO                 |  3 ---
 pub/CHANGELOG        |  3 +++
 pub/lib/toplevel.cpp | 35 ++++++++++++++++++++++++++---------
 pub/lib/toplevel.hpp |  3 ++-
 pub/man/frida.pod    | 16 +++-------------
 pub/src/frida2.cpp   | 23 ++++++++++++++++++++---
 6 files changed, 54 insertions(+), 29 deletions(-)

diff --git a/TODO b/TODO
index 5c6dbdc5..751282f7 100644
--- a/TODO
+++ b/TODO
@@ -5,7 +5,6 @@ unify cp&dz
 
 update infoLine header
 
-shibang mechanism to invoke Frida scripts
 cp should show quality of last fit
 latest action on pX should be part of history
 history replay must not stop for error
@@ -37,8 +36,6 @@ Terminology:
 
 == Command-line interface ==
 
-ignore leading spaces in command
-
 Default file selection:
 - inform user about new file selection as result of an operation
 - inform user about renumbering after deletion?
diff --git a/pub/CHANGELOG b/pub/CHANGELOG
index e514b046..d8573508 100644
--- a/pub/CHANGELOG
+++ b/pub/CHANGELOG
@@ -1,8 +1,11 @@
 Release 2.2.1b of, to be used with frida2libs-141216:
 
 - changed interface:
+  - 'frida' command takes script names as arguments; these scripts are
+    executed before Frida goes interactive. This also allows for shebang files.
   - shorter syntax: 'integral[..]' expands to 'integral(x[..],y[..])
   - outcome, chi2, R2 replace obscure fit quality metrics cq0,cq2,cq1
+  - be more tolerant with unnecessary blanks (trim in readany)
 - removed functionality:
   - GridSum, because it is a composite of two elementary operations
 
diff --git a/pub/lib/toplevel.cpp b/pub/lib/toplevel.cpp
index c99c4688..a2dda48f 100644
--- a/pub/lib/toplevel.cpp
+++ b/pub/lib/toplevel.cpp
@@ -63,7 +63,7 @@ void my_gsl_error_handler (
 }
 
 
-//! Start interactive Frida session.
+//! Prepare interactive Frida session.
 
 Frida::Frida()
 {
@@ -91,19 +91,36 @@ Frida::Frida()
     time_cmd=0;
 }
 
-//! One command within Frida main loop.
 
-void Frida::run_one()
+//! Get one command from the user.
+
+string Frida::prompt()
 {
     try{
-        // Get a word from the user: // TODO: wask must respect quotes
-        string cmd = wask( NOlm::sel_str() + " > " );
-        // cout << "executing '" << cmd << "'\n";
+        return wask( NOlm::sel_str() + " > " );
+    } catch( string& s ) {
+        cerr << s << endl;
+        NRead::clear();
+    } catch( const char* s ) {
+        cerr << s << endl;
+        NRead::clear();
+    } catch( ... ) {
+        cerr << "catched invalid exception\n";
+        NRead::clear();
+    }
+    return "";
+}
 
-        // Empty input is just ignored.
-        if ( cmd=="" )
-            return;
 
+//! Execute one Frida command.
+
+void Frida::execute( const string cmd )
+{
+    try{
+        // Empty input, comment lines.
+        if ( cmd=="" || cmd[0]=='#' )
+            return;
+        
         // Is it a list?
         if ( cmd.find_first_of("-*0123456789")==0 ) {
             if( NOlm::sel_try( cmd ) )
diff --git a/pub/lib/toplevel.hpp b/pub/lib/toplevel.hpp
index 10f44713..b84a1e55 100644
--- a/pub/lib/toplevel.hpp
+++ b/pub/lib/toplevel.hpp
@@ -12,7 +12,8 @@
 class Frida {
  public:
     Frida();
-    void run_one();
+    std::string prompt();
+    void execute( const std::string cmd );
  private:
 // Time spent in frida, for optimizing numerical routines:
     clock_t clock_start;
diff --git a/pub/man/frida.pod b/pub/man/frida.pod
index 73f8aad7..4c32e317 100644
--- a/pub/man/frida.pod
+++ b/pub/man/frida.pod
@@ -14,12 +14,12 @@ Frida - Flexible rapid interactive data analysis
 
 =head1 SYNOPSIS
 
-B<frida>
+B<frida> [script] ..
 
 
 =head1 DESCRIPTION
 
-Frida is software for scientific data analysis, primarily written for inelastic neutron scattering. Its data model is quite generic (data files consist of x-y-dy tables that are differentiated by z coordinates), so that it can be used for many different kinds of observational data.
+Frida is an interactive, command-line driven program for scientific data analysis. Originally, Frida has been written for inelastic neutron scattering, but its data model is quite generic (data files consist of x-y-dy tables that are differentiated by z coordinates), so that it can be used for many different kinds of observational data.
 
 
 =head1 RESOURCES
@@ -49,17 +49,7 @@ Send bug reports to j.wuttke@fz-juelich.de.
 Frida1, written in FORTRAN, was developed in the 1990s. The original name IDA was changed to Frida just because there were too many other open-source projects all called IDA.
 
 Frida2 is a rewrite in C++.
-It is the standard tool for data analysis
-at the backscattering spectrometer SPHERES.
-The more specific routines for time-of-flight spectroscopy
-are currently being ported from Frida1 to Frida2,
-so that Frida1 can be phased out by mid-2010.
-
-Frida1 includes raw data reduction routines
-for numerous backscattering and time-of-flight spectrometers.
-These routines are not ported to Frida2,
-but to the separate raw-data reduction package SLAW:
-http://iffwww.iff.kfa-juelich.de/~wuttke/slaw/.
+It is mainly used for data analysis at the backscattering spectrometer SPHERES.
 
 
 =head1 AUTHOR
diff --git a/pub/src/frida2.cpp b/pub/src/frida2.cpp
index af64450a..84684795 100644
--- a/pub/src/frida2.cpp
+++ b/pub/src/frida2.cpp
@@ -4,18 +4,35 @@
 //* http://apps.jcns.fz-juelich.de/frida                                   *//
 //**************************************************************************//
 
-//! \file frida2.cpp
+//! \file  frida2.cpp
 //! \brief main program
 
+#include <iostream>
+#include <fstream>
+#include <string>
 #include "toplevel.hpp"
 
+using namespace std;
+
 //! Frida main program.
 
-int main()
+int main(int argc, char* argv[])
 {
+    // cout << "initializing\n";
     Frida frida;
 
+    for( int iarg=1; iarg<argc; ++iarg ){
+        ifstream script(argv[iarg]);
+        string cmd;
+        // cout << "executing " << argv[iarg] << "\n";
+        while (getline(script, cmd))
+            frida.execute( cmd );
+    }
+
+    // cout << "getting interactive\n";
     while(1) {
-        frida.run_one();
+        string cmd = frida.prompt();
+        // cout << "got cmd '" << cmd << "'\n";
+        frida.execute( cmd );
     }
 }
-- 
GitLab