Index: /trunk/FACT++/src/dimctrl.cc
===================================================================
--- /trunk/FACT++/src/dimctrl.cc	(revision 14127)
+++ /trunk/FACT++/src/dimctrl.cc	(revision 14128)
@@ -1,16 +1,36 @@
-#ifndef FACT_DimCtrl
-#define FACT_DimCtrl
-
-#include "Main.h"
-#include "tools.h"
-#include "MessageDim.h"
+#include "StateMachineDimControl.h"
 #include "RemoteControl.h"
-
-#include "InterpreterV8.h"
 
 using namespace std;
 
-// ========================================================================
+// ------------------------------------------------------------------------
 
+#include "Main.h"
+
+template<class T>
+int RunShell(Configuration &conf)
+{
+    StateMachineDimControl::fIsServer = conf.Get<bool>("server");
+    return Main::execute<T, StateMachineDimControl>(conf);
+}
+
+void SetupConfiguration(Configuration &conf)
+{
+    po::options_description control("Dim control options");
+    control.add_options()
+        ("server",       po_bool(false),  "Start dimctrl as a dim server")
+        // ("verbosity,v",  var<uint32_t>()->implicit_value(0), "Set a new verbosity level (see MessageImp)")
+        // ("quiet,q",      po_bool(false),  "Suppress all output except comments (log-level>=90)")
+        ("debug",        po_bool(false),  "Print the labels for debugging purpose")
+        ("start",        var<string>(),   "Start a java script with the given name")
+        ("batch",        var<string>(),   "Start a batch script with the given name at the given label (script.dim[:N])")
+        ("stop",         po_switch(),     "Stop a currently running script")
+        ("user,u",       var<string>(""), "A user name - just for logging purposes (default is ${USER})")
+        ;
+
+    conf.AddEnv("user", "USER");
+
+    conf.AddOptions(control);
+}
 
 /*
@@ -25,10 +45,14 @@
 void PrintUsage()
 {
-    cout << "\n"
-        "The console connects to all available Dim Servers and allows to "
-        "easily access all of their commands.\n"
+    cout <<
+        "The feedback control the BIAS voltages based on the calibration signal.\n"
         "\n"
-        "Usage: dimctrl [-c type] [OPTIONS]\n"
-        "  or:  dimctrl [OPTIONS]\n\n";
+        "The default is that the program is started without user intercation. "
+        "All actions are supposed to arrive as DimCommands. Using the -c "
+        "option, a local shell can be initialized. With h or help a short "
+        "help message about the usuage can be brought to the screen.\n"
+        "\n"
+        "Usage: feedback [-c type] [OPTIONS]\n"
+        "  or:  feedback [OPTIONS]\n";
     cout << endl;
 }
@@ -36,278 +60,25 @@
 void PrintHelp()
 {
-    Main::PrintUsage();
+    Main::PrintHelp<StateMachineDimControl>();
+
+    /* Additional help text which is printed after the configuration
+     options goes here */
+
+    /*
+     cout << "bla bla bla" << endl << endl;
+     cout << endl;
+     cout << "Environment:" << endl;
+     cout << "environment" << endl;
+     cout << endl;
+     cout << "Examples:" << endl;
+     cout << "test exam" << endl;
+     cout << endl;
+     cout << "Files:" << endl;
+     cout << "files" << endl;
+     cout << endl;
+     */
 }
 
-// A simple dummy state machine
-class DimCtrl : public MainImp, public DimCommandHandler, public MessageDimTX
-{
-    int    fLabel;
-    int    fStop;
-    int    fVerbosity;
-    bool   fDebug;
-    bool   fIsServer;
-    string fUser;
-
-    DimDescribedService fSrvState;
-    DimCommand          fDimStart;
-    DimCommand          fDimStop;
-
-    map<string,string> fData;
-    string fScript;
-    string fScriptUser;
-
-    void ProcessStart()
-    {
-        if (!fScript.empty() || fLabel>-3)
-        {
-            Error("Script execution still in progress.");
-            return;
-        }
-
-        string opt(fDimStart.getString());
-
-        fData = Tools::Split(opt);
-
-        if (opt.size()>0)
-            Debug("Start '"+opt+"' received.");
-
-        if (fDebug)
-            Debug("Received data: "+string(fDimStart.getString()));
-
-        if (opt.size()==0)
-        {
-            if (fData.size()==0)
-                Error("File name missing in DIM_CONTROL/START");
-            else
-                Error("Equal sign missing in argument '"+fData.begin()->first+"'");
-
-            return;
-        }
-
-        const auto user = fData.find("user");
-        if (user!=fData.end())
-            fScriptUser = user->second;
-
-        if (fDebug)
-        {
-            for (auto it=fData.begin(); it!=fData.end(); it++)
-                Debug("   Arg: "+it->first+" = "+it->second);
-        }
-
-        fScript = opt;
-    }
-
-    void StopScript()
-    {
-        Readline::StopScript();
-        InterpreterV8::JsStop();
-    }
-
-    void commandHandler()
-    {
-        if (getCommand()==&fDimStop)
-        {
-            const string user = fDimStop.getSize()>0 ? fDimStop.getString() : "";
-
-            string msg = "Stop received";
-            if (!user.empty())
-                msg += " from user '"+user+"'";
-
-            Debug(msg);
-            StopScript();
-        }
-
-        if (getCommand()==&fDimStart)
-            ProcessStart();
-    }
-
-public:
-    DimCtrl(ostream &out=cout) : MessageDimTX("DIM_CONTROL", out),
-        fLabel(-3), fStop(-1), fVerbosity(0), fDebug(false), fIsServer(false),
-        fSrvState("DIM_CONTROL/STATE", "C",
-                  "Provides the state of the state machine as quality of service."
-                  "|Text[string]:A human readable string sent by the last state change."),
-        fDimStart("DIM_CONTROL/START", "C", this),
-        fDimStop("DIM_CONTROL/STOP", "C", this)
-    {
-    }
-    ~DimCtrl()
-    {
-        DimServer::stop();
-    }
-
-    bool check(string &str)
-    {
-        for (auto c=str.begin(); c<str.end(); c++)
-        {
-            if ((*c>='A' && *c<='Z') || *c=='_')
-                continue;
-
-            if (*c++!=':')
-                return false;
-
-            if (c==str.end())
-                return false;
-
-            if (*c!=' ')
-                return false;
-
-            str = string(c+1, str.end());
-            return true;
-        }
-
-        return false;
-    }
-
-    string Line(const string &txt, char fill)
-    {
-        const int n = (55-txt.length())/2;
-
-        ostringstream out;
-        out << setfill(fill);
-        out << setw(n) << fill << ' ';
-        out << txt;
-        out << ' ' << setw(n) << fill;
-
-        if (2*n+txt.length()+2 != 57)
-            out << fill;
-
-        return out.str();
-    }
-
-    int ChangeState(int qos, const Time &time=Time())
-    {
-        ostringstream pid;
-        pid << getpid();
-
-        fLabel = qos;
-
-        string msg;
-        switch (fLabel)
-        {
-        case -4: msg = "Boot";  break;
-        case -3: msg = "End";   break;
-        case -2: msg = "Load";  break;
-        case -1: msg = "Start"; break;
-        default:
-            {
-                ostringstream out;
-                out << "Label " << fLabel;
-                msg = out.str();
-            }
-        }
-
-        if (fLabel<0)
-            msg += "-"+to_string(Readline::GetScriptDepth());
-
-        msg += ": "+Readline::GetScript()+" [";
-        if (!fScriptUser.empty())
-            msg += fScriptUser+":"+pid.str();
-        msg += "]";
-
-        if (fDebug)
-            MessageDimTX::Write(time, Line(msg, fLabel<-1 ? '=' :'-'), 90);
-
-        fSrvState.setQuality(fLabel);
-        return fSrvState.Update(msg);
-    }
-
-    int Write(const Time &time, const std::string &txt, int qos=kMessage)
-    {
-        if (txt=="")
-            return ChangeState(qos, time);
-
-        if (qos<fVerbosity)
-            return 0;
-
-        // Avoid recursions
-        if (fIsServer && txt.substr(0, 13)=="DIM_CONTROL: ")
-            return 0;
-
-        // Don't send received messages via dim
-        string cpy(txt);
-        if (fIsServer && check(cpy))
-            return MessageImp::Write(time, cpy, qos);
-
-        // Send all of our own messages via dim
-        return MessageDimTX::Write(time, txt, qos);
-    }
-
-    int EvalOptions(Configuration &conf)
-    {
-        fVerbosity = 90;
-
-        fUser = conf.Get<string>("user");
-        fScriptUser = fUser;
-
-        if (conf.Get<bool>("stop"))
-            return Dim::SendCommand("DIM_CONTROL/STOP", fUser) + 1;
-
-        if (conf.Has("start"))
-            return Dim::SendCommand("DIM_CONTROL/START", conf.Get<string>("start")+" user="+fUser) + 1;
-
-        fVerbosity = 40;
-
-        if (conf.Has("verbosity"))
-            fVerbosity = conf.Get<uint32_t>("verbosity");
-
-        if (conf.Get<bool>("quiet"))
-            fVerbosity = 90;
-
-        fIsServer = conf.Get<bool>("server");
-        fDebug    = conf.Get<bool>("debug");
-
-        if (fIsServer)
-        {
-            // Sleep needed to ensure that the server can send
-            // an EXIT if another instance is already running
-            DimServer::start("DIM_CONTROL");
-            //sleep(1);
-            ChangeState(-4);
-        }
-
-        return -1;
-    }
-
-    void Stop(int stop=0) { fStop = stop; StopScript(); }
-    int Run(bool)
-    {
-        while (fStop<0)
-        {
-            const string s = fScript;
-            if (!s.empty())
-            {
-                Readline::Instance()->Execute(s, fData);
-                fScript = "";
-                fScriptUser = fUser;
-            }
-
-            usleep(1000);
-        }
-
-        return fStop;
-    }
-
-};
-
-void SetupConfiguration(Configuration &conf)
-{
-    po::options_description control("Dim Control");
-    control.add_options()
-        ("server",      po_bool(false),  "Start dimctrl as a dim server")
-        ("verbosity,v", var<uint32_t>()->implicit_value(0), "Set a new verbosity level (see MessageImp)")
-        ("quiet,q",     po_bool(false),  "Suppress all output except comments (log-level>=90)")
-        ("debug",       po_bool(false),  "Print the labels for debugging purpose")
-        ("start",       var<string>(),   "Start a script with the given name at the given label (script.dim[:N])")
-        ("stop",        po_switch(),     "Stop a currently running script")
-        ("user,u",      var<string>(""), "A user name - just for logging purposes (default is ${USER})")
-        ;
-
-    conf.AddEnv("user", "USER");
-
-    conf.AddOptions(control);
-}
-
-int main(int argc, const char *argv[])
+int main(int argc, const char* argv[])
 {
     Configuration conf(argv[0]);
@@ -319,13 +90,12 @@
         return 127;
 
+    //return RunShell<LocalStream>(conf);
+
     if (!conf.Has("console"))
-        return Main::execute<RemoteStream, DimCtrl>(conf);
+        return RunShell<RemoteStream>(conf);
 
     if (conf.Get<int>("console")==0)
-        return Main::execute<RemoteShell, DimCtrl>(conf);
+        return RunShell<RemoteShell>(conf);
     else
-        return Main::execute<RemoteConsole, DimCtrl>(conf);
-
-    return 0;
+        return RunShell<RemoteConsole>(conf);
 }
-#endif
