Author: sayer
Date: 2009-03-23 12:00:59 +0100 (Mon, 23 Mar 2009)
New Revision: 1321

Modified:
   trunk/apps/dsm/DSM.cpp
   trunk/apps/dsm/DSMChartReader.cpp
   trunk/apps/dsm/DSMCoreModule.cpp
   trunk/apps/dsm/DSMCoreModule.h
   trunk/apps/dsm/DSMDialog.cpp
   trunk/apps/dsm/DSMModule.cpp
   trunk/apps/dsm/DSMModule.h
   trunk/apps/dsm/DSMSession.h
   trunk/apps/dsm/DSMStateEngine.cpp
   trunk/apps/dsm/doc/dsm_syntax.txt
   trunk/apps/dsm/mods/mod_conference/ModConference.cpp
   trunk/apps/dsm/mods/mod_conference/ModConference.h
   trunk/apps/dsm/mods/mod_dlg/ModDlg.cpp
   trunk/apps/dsm/mods/mod_dlg/ModDlg.h
   trunk/apps/dsm/mods/mod_monitoring/ModMonitoring.cpp
   trunk/apps/dsm/mods/mod_monitoring/ModMonitoring.h
   trunk/apps/dsm/mods/mod_sys/ModSys.cpp
   trunk/apps/dsm/mods/mod_sys/ModSys.h
   trunk/apps/dsm/mods/mod_uri/ModUri.cpp
   trunk/apps/dsm/mods/mod_uri/ModUri.h
Log:
- simplified and beautified modules with better looking macros:
   DEF_TwoParAction -> DEF_ACTION_2P
   CONST_TwoParAction -> CONST_ACTION_2P
   -DEF_SCStrArgAction-> DEF_ACTION_1P

   EXEC_ACTION_START, EXEC_ACTION_END
   MATCH_CONDITION_START, MATCH_CONDITION_END

- quoting (+escaping) added to Actions' parameters

- added logVars debugging function to log all variables

- added avar AmArg array, to replace var (string) array


This work was kindly sponsored by Teltech Systems Inc.



Modified: trunk/apps/dsm/DSM.cpp
===================================================================
--- trunk/apps/dsm/DSM.cpp      2009-03-19 12:21:33 UTC (rev 1320)
+++ trunk/apps/dsm/DSM.cpp      2009-03-23 11:00:59 UTC (rev 1321)
@@ -216,7 +216,7 @@
   }
 
   for (std::map<string,string>::const_iterator it = 
-        cfg.begin(); it != cfg.end(); it++)
+        cfg.begin(); it != cfg.end(); it++) 
     config[it->first] = it->second;
 
   RunInviteEvent = cfg.getParameter("run_invite_event")=="yes";
@@ -231,7 +231,7 @@
 void DSMFactory::addVariables(DSMDialog* s, const string& prefix,
                              map<string, string>& vars) {
   for (map<string, string>::iterator it = 
-        vars.begin(); it != vars.end(); it++)
+        vars.begin(); it != vars.end(); it++) 
     s->var[prefix+it->first] = it->second;
 }
 
@@ -249,6 +249,7 @@
   }
   DSMDialog* s = new DSMDialog(&prompts, diags, start_diag, NULL);
   prepareSession(s);
+  addVariables(s, "config.", config);
   return s;
 }
 

Modified: trunk/apps/dsm/DSMChartReader.cpp
===================================================================
--- trunk/apps/dsm/DSMChartReader.cpp   2009-03-19 12:21:33 UTC (rev 1320)
+++ trunk/apps/dsm/DSMChartReader.cpp   2009-03-23 11:00:59 UTC (rev 1321)
@@ -66,8 +66,13 @@
        last_chr = str[pos1];
        pos1++;
       }
-    }
-    if (str[pos1] == '(') {
+    } else  if (str[pos1] == '\'') {
+      pos1++;
+      while (pos1<str.length() && !((str[pos1] == '\'') && (last_chr != 
'\\'))) {
+       last_chr = str[pos1];
+       pos1++;
+      }
+    } else if (str[pos1] == '(') {
       int lvl = 0;
       pos1++;
       while (pos1<str.length() && (lvl || (str[pos1] != ')'))) {
@@ -77,13 +82,20 @@
        else if (str[pos1] == ')')
          lvl--;
            
-       if (str[pos1] == '"') {
+       else if (str[pos1] == '"') {
          pos1++;
          while (pos1<str.length() && !((str[pos1] == '"') && (last_chr != 
'\\'))) {
            last_chr = str[pos1];
            pos1++;
          }
        }
+       else if (str[pos1] == '\'') {
+         pos1++;
+         while (pos1<str.length() && !((str[pos1] == '\'') && (last_chr != 
'\\'))) {
+           last_chr = str[pos1];
+           pos1++;
+         }
+       }
        last_chr = str[pos1];
        pos1++;
       }
@@ -93,7 +105,7 @@
   }
 
   string res;
-  if (str[pos] == '"')
+  if ((str[pos] == '"') || (str[pos] == '\''))
     res = str.substr(pos+1, pos1-pos-2);
   else 
     res = str.substr(pos, pos1-pos);
@@ -129,16 +141,6 @@
   return c;
 }
 
-void splitCmd(const string& from_str, 
-             string& cmd, string& params) {
-  size_t b_pos = from_str.find('(');
-  if (b_pos != string::npos) {
-    cmd = from_str.substr(0, b_pos);
-    params = from_str.substr(b_pos + 1, from_str.rfind(')') - b_pos -1);
-  } else 
-    cmd = from_str;  
-}
-
 bool DSMChartReader::importModule(const string& mod_cmd, const string& 
mod_path) {
   string cmd;
   string params;

Modified: trunk/apps/dsm/DSMCoreModule.cpp
===================================================================
--- trunk/apps/dsm/DSMCoreModule.cpp    2009-03-19 12:21:33 UTC (rev 1320)
+++ trunk/apps/dsm/DSMCoreModule.cpp    2009-03-23 11:00:59 UTC (rev 1321)
@@ -34,15 +34,8 @@
 DSMCoreModule::DSMCoreModule() {
 }
 
-string trim(string const& str,char const* sepSet)
-{
-  string::size_type const first = str.find_first_not_of(sepSet);
-  return ( first==string::npos )
-    ? std::string()  : 
-    str.substr(first, str.find_last_not_of(sepSet)-first+1);
-}
 
-void DSMCoreModule::splitCmd(const string& from_str, 
+void splitCmd(const string& from_str, 
                            string& cmd, string& params) {
   size_t b_pos = from_str.find('(');
   if (b_pos != string::npos) {
@@ -57,15 +50,6 @@
   string params;
   splitCmd(from_str, cmd, params);
 
-#define DEF_CMD(cmd_name, class_name) \
-                                     \
-  if (cmd == cmd_name) {             \
-    class_name * a =                 \
-      new class_name(params);        \
-    a->name = from_str;                      \
-    return a;                        \
-  }
-
   DEF_CMD("repost", SCRepostAction);
   DEF_CMD("jumpFSM", SCJumpFSMAction);
   DEF_CMD("callFSM", SCCallFSMAction);
@@ -85,6 +69,7 @@
   DEF_CMD("set", SCSetAction);
   DEF_CMD("append", SCAppendAction);
   DEF_CMD("log", SCLogAction);
+  DEF_CMD("logVars", SCLogVarsAction);
 
   DEF_CMD("setTimer", SCSetTimerAction);
 
@@ -152,90 +137,24 @@
   return NULL;
 }
 
-
-inline string resolveVars(const string s, AmSession* sess,
-                         DSMSession* sc_sess, map<string,string>* 
event_params) {
-  if (s.length()) {
-    switch(s[0]) {
-    case '$': return sc_sess->var[s.substr(1)];
-    case '#': 
-      if (event_params) 
-       return  (*event_params)[s.substr(1)];
-      else 
-       return string();
-    case '@': {
-      string s1 = s.substr(1); 
-      if (s1 == "local_tag")
-       return sess->getLocalTag();     
-      else if (s1 == "user")
-       return sess->dlg.user;
-      else if (s1 == "domain")
-       return sess->dlg.domain;
-      else if (s1 == "remote_tag")
-       return sess->getRemoteTag();
-      else if (s1 == "callid")
-       return sess->getCallID();
-      else if (s1 == "local_uri")
-       return sess->dlg.local_uri;
-      else if (s1 == "remote_uri")
-       return sess->dlg.remote_uri;
-      else
-       return string();
-    } 
-    default: return trim(s, "\"");
-    }
-  }
-  return s;
-}
-
-#define GET_SCSESSION()                                       \
-  DSMSession* sc_sess = dynamic_cast<DSMSession*>(sess); \
-  if (!sc_sess) {                                     \
-    ERROR("wrong session type\n");                    \
-    return false;                                             \
-  }
-
-
-bool SCPlayPromptAction::execute(AmSession* sess, 
-                                DSMCondition::EventType event,
-                                map<string,string>* event_params) {
-  GET_SCSESSION();
+EXEC_ACTION_START(SCPlayPromptAction) {
   sc_sess->playPrompt(resolveVars(arg, sess, sc_sess, event_params));
-  return false;
-}
+} EXEC_ACTION_END;
 
-
-bool SCSetPromptsAction::execute(AmSession* sess, 
-                                DSMCondition::EventType event,
-                                map<string,string>* event_params) {
-  GET_SCSESSION();
+EXEC_ACTION_START(SCSetPromptsAction) {
   sc_sess->setPromptSet(resolveVars(arg, sess, sc_sess, event_params));
-  return false;
-}
+} EXEC_ACTION_END;
 
-bool SCAddSeparatorAction::execute(AmSession* sess, 
-                                  DSMCondition::EventType event,
-                                  map<string,string>* event_params) {
-  GET_SCSESSION();
+EXEC_ACTION_START(SCAddSeparatorAction){
   sc_sess->addSeparator(resolveVars(arg, sess, sc_sess, event_params));
-  return false;
-}
+} EXEC_ACTION_END;
 
-bool SCPlayPromptLoopedAction::execute(AmSession* sess, 
-                                DSMCondition::EventType event,
-                                map<string,string>* event_params) {
-  GET_SCSESSION();
+EXEC_ACTION_START(SCPlayPromptLoopedAction){
   sc_sess->playPrompt(resolveVars(arg, sess, sc_sess, event_params), true);
-  return false;
-}
+} EXEC_ACTION_END;
 
-CONST_TwoParAction(SCPostEventAction, ",", true);
-
-bool SCPostEventAction::execute(AmSession* sess, 
-                              DSMCondition::EventType event,
-                              map<string,string>* event_params) {
-
-  GET_SCSESSION();
+CONST_ACTION_2P(SCPostEventAction, ',', true);
+EXEC_ACTION_START(SCPostEventAction){
   string sess_id = resolveVars(par1, sess, sc_sess, event_params);
   string var = resolveVars(par2, sess, sc_sess, event_params);
   DSMEvent* ev = new DSMEvent();
@@ -251,69 +170,41 @@
     sc_sess->SET_ERRNO(DSM_ERRNO_UNKNOWN_ARG);
   else 
     sc_sess->SET_ERRNO(DSM_ERRNO_OK);
+} EXEC_ACTION_END;
 
-  return false;
-}
-
-bool SCPlayFileAction::execute(AmSession* sess, 
-                              DSMCondition::EventType event,
-                              map<string,string>* event_params) {
-  GET_SCSESSION();
-
+EXEC_ACTION_START(SCPlayFileAction) {
   bool loop = 
     resolveVars(par2, sess, sc_sess, event_params) == "true";
   DBG("par1 = '%s', par2 = %s\n", par1.c_str(), par2.c_str());
   sc_sess->playFile(resolveVars(par1, sess, sc_sess, event_params), 
                    loop);
-  return false;
-}
+} EXEC_ACTION_END;
 
-bool SCRecordFileAction::execute(AmSession* sess, 
-                                DSMCondition::EventType event,
-                                map<string,string>* event_params) {
-  GET_SCSESSION();
+EXEC_ACTION_START(SCRecordFileAction) {
   sc_sess->recordFile(resolveVars(arg, sess, sc_sess, event_params));
-  return false;
-}
+} EXEC_ACTION_END;
 
-bool SCStopRecordAction::execute(AmSession* sess, 
-                                DSMCondition::EventType event,
-                                map<string,string>* event_params) {
-  GET_SCSESSION();
+EXEC_ACTION_START(SCStopRecordAction) {
   sc_sess->stopRecord();
-  return false;
-}
+} EXEC_ACTION_END;
 
-bool SCClosePlaylistAction::execute(AmSession* sess, 
-                                   DSMCondition::EventType event,
-                                   map<string,string>* event_params) {
-  GET_SCSESSION();
+EXEC_ACTION_START(SCClosePlaylistAction) {
   bool notify = 
     resolveVars(arg, sess, sc_sess, event_params) == "true";
   sc_sess->closePlaylist(notify);
-  return false;
-}
+} EXEC_ACTION_END;
 
-bool SCConnectMediaAction::execute(AmSession* sess, 
-                                  DSMCondition::EventType event,
-                                  map<string,string>* event_params) {
-  GET_SCSESSION();
+EXEC_ACTION_START(SCConnectMediaAction) {
   sc_sess->connectMedia();
-  return false;
-}
+} EXEC_ACTION_END;
 
-
-bool SCStopAction::execute(AmSession* sess, 
-                          DSMCondition::EventType event,
-                          map<string,string>* event_params) {
-  GET_SCSESSION();
+EXEC_ACTION_START(SCStopAction) {
   if (resolveVars(arg, sess, sc_sess, event_params) == "true") {
     DBG("sending bye\n");
     sess->dlg.bye();
   }
   sess->setStopped();
-  return false;
-}
+} EXEC_ACTION_END;
 
 #define DEF_SCModActionExec(clsname)                           \
                                                                \
@@ -348,14 +239,11 @@
 #undef DEF_SCModActionExec
 
 
-CONST_TwoParAction(SCPlayFileAction, ",", true);
+CONST_ACTION_2P(SCPlayFileAction, ',', true);
 
-CONST_TwoParAction(SCLogAction, ",", false);
-bool SCLogAction::execute(AmSession* sess, 
-                         DSMCondition::EventType event,
-                         map<string,string>* event_params) {
-  GET_SCSESSION();
-  
+CONST_ACTION_2P(SCLogAction, ',', false);
+EXEC_ACTION_START(SCLogAction) {
+
   unsigned int lvl;
   if (str2i(resolveVars(par1, sess, sc_sess, event_params), lvl)) {
     ERROR("unknown log level '%s'\n", par1.c_str());
@@ -364,29 +252,35 @@
   string l_line = resolveVars(par2, sess, sc_sess, event_params).c_str();
   _LOG((int)lvl, "FSM: %s '%s'\n", (par2 != l_line)?par2.c_str():"",
        l_line.c_str());
-  return false;
-}
+} EXEC_ACTION_END;
 
-CONST_TwoParAction(SCSetAction,"=", false);
-bool SCSetAction::execute(AmSession* sess, 
-                         DSMCondition::EventType event,
-                         map<string,string>* event_params) {
-  GET_SCSESSION();
+EXEC_ACTION_START(SCLogVarsAction) {
+  unsigned int lvl;
+  if (str2i(resolveVars(arg, sess, sc_sess, event_params), lvl)) {
+    ERROR("unknown log level '%s'\n", arg.c_str());
+    return false;
+  }
+
+  _LOG((int)lvl, "FSM: variables set ---\n");
+  for (map<string, string>::iterator it = 
+        sc_sess->var.begin(); it != sc_sess->var.end(); it++) {
+    _LOG((int)lvl, "FSM:  $%s='%s'\n", it->first.c_str(), it->second.c_str());
+  }
+  _LOG((int)lvl, "FSM: variables end ---\n");
+} EXEC_ACTION_END;
+
+CONST_ACTION_2P(SCSetAction,'=', false);
+EXEC_ACTION_START(SCSetAction) {
   string var_name = (par1.length() && par1[0] == '$')?
     par1.substr(1) : par1;
 
   sc_sess->var[var_name] = resolveVars(par2, sess, sc_sess, event_params);
   DBG("set variable '%s'='%s'\n", 
       var_name.c_str(), sc_sess->var[var_name].c_str());
-  return false;
-}
+} EXEC_ACTION_END;
 
-CONST_TwoParAction(SCAppendAction,",", false);
-bool SCAppendAction::execute(AmSession* sess, 
-                         DSMCondition::EventType event,
-                         map<string,string>* event_params) {
-  GET_SCSESSION();
-
+CONST_ACTION_2P(SCAppendAction,',', false);
+EXEC_ACTION_START(SCAppendAction) {
   string var_name = (par1.length() && par1[0] == '$')?
     par1.substr(1) : par1;
 
@@ -394,14 +288,10 @@
 
   DBG("$%s now '%s'\n", 
       var_name.c_str(), sc_sess->var[var_name].c_str());
-  return false;
-}
+} EXEC_ACTION_END;
 
-CONST_TwoParAction(SCSetTimerAction,",", false);
-bool SCSetTimerAction::execute(AmSession* sess, 
-                              DSMCondition::EventType event,
-                              map<string,string>* event_params) {
-  GET_SCSESSION();
+CONST_ACTION_2P(SCSetTimerAction,',', false);
+EXEC_ACTION_START(SCSetTimerAction) {
 
   unsigned int timerid;
   if (str2i(resolveVars(par1, sess, sc_sess, event_params), timerid)) {
@@ -436,10 +326,10 @@
   di_args.push((int)timeout);      // in seconds
   di_args.push(sess->getLocalTag().c_str());
   user_timer->invoke("setTimer", di_args, ret);
-  return false;
-}
 
+} EXEC_ACTION_END;
 
+
 // TODO: replace with real expression matching 
 TestDSMCondition::TestDSMCondition(const string& expr, DSMCondition::EventType 
evt) {
 
@@ -554,10 +444,7 @@
   }
 }
 
-bool SCDIAction::execute(AmSession* sess,
-                        DSMCondition::EventType event,
-                        map<string,string>* event_params) {
-  GET_SCSESSION();
+EXEC_ACTION_START(SCDIAction) {
 
   if (params.size() < 2) {
     ERROR("DI needs at least: mod_name, "
@@ -657,7 +544,6 @@
       ERROR("unsupported AmArg return type!");
     }
   }
-  return false;
-}
+} EXEC_ACTION_END;
   
 

Modified: trunk/apps/dsm/DSMCoreModule.h
===================================================================
--- trunk/apps/dsm/DSMCoreModule.h      2009-03-19 12:21:33 UTC (rev 1320)
+++ trunk/apps/dsm/DSMCoreModule.h      2009-03-23 11:00:59 UTC (rev 1321)
@@ -37,11 +37,12 @@
 class AmSession;
 class DSMSession;
 
+void splitCmd(const string& from_str, 
+               string& cmd, string& params);
+
 class DSMCoreModule 
 : public DSMModule {
 
-  void splitCmd(const string& from_str, 
-               string& cmd, string& params);
  public:
   DSMCoreModule();
     
@@ -49,15 +50,15 @@
   DSMCondition* getCondition(const string& from_str);
 };
 
-DEF_SCStrArgAction(SCPlayPromptAction);
-DEF_SCStrArgAction(SCPlayPromptLoopedAction);
-DEF_SCStrArgAction(SCRecordFileAction);
-DEF_SCStrArgAction(SCStopRecordAction);
-DEF_SCStrArgAction(SCClosePlaylistAction);
-DEF_SCStrArgAction(SCStopAction);
-DEF_SCStrArgAction(SCConnectMediaAction);
-DEF_SCStrArgAction(SCSetPromptsAction);
-DEF_SCStrArgAction(SCAddSeparatorAction);
+DEF_ACTION_1P(SCPlayPromptAction);
+DEF_ACTION_1P(SCPlayPromptLoopedAction);
+DEF_ACTION_1P(SCRecordFileAction);
+DEF_ACTION_1P(SCStopRecordAction);
+DEF_ACTION_1P(SCClosePlaylistAction);
+DEF_ACTION_1P(SCStopAction);
+DEF_ACTION_1P(SCConnectMediaAction);
+DEF_ACTION_1P(SCSetPromptsAction);
+DEF_ACTION_1P(SCAddSeparatorAction);
 
 DEF_SCModSEStrArgAction(SCRepostAction);
 DEF_SCModSEStrArgAction(SCJumpFSMAction);
@@ -65,12 +66,13 @@
 DEF_SCModSEStrArgAction(SCReturnFSMAction);
 
 
-DEF_TwoParAction(SCSetAction);
-DEF_TwoParAction(SCAppendAction);
-DEF_TwoParAction(SCSetTimerAction);
-DEF_TwoParAction(SCLogAction);
-DEF_TwoParAction(SCPlayFileAction);
-DEF_TwoParAction(SCPostEventAction);
+DEF_ACTION_2P(SCSetAction);
+DEF_ACTION_2P(SCAppendAction);
+DEF_ACTION_2P(SCSetTimerAction);
+DEF_ACTION_2P(SCLogAction);
+DEF_ACTION_1P(SCLogVarsAction);
+DEF_ACTION_2P(SCPlayFileAction);
+DEF_ACTION_2P(SCPostEventAction);
 
 class SCDIAction                                       
 : public DSMAction {
@@ -104,9 +106,5 @@
             map<string,string>* event_params);
 };
 
-string resolveVars(const string s, AmSession* sess,
-                  DSMSession* sc_sess, map<string,string>* event_params);
 
-string trim(string const& str,char const* sepSet);
-
 #endif

Modified: trunk/apps/dsm/DSMDialog.cpp
===================================================================
--- trunk/apps/dsm/DSMDialog.cpp        2009-03-19 12:21:33 UTC (rev 1320)
+++ trunk/apps/dsm/DSMDialog.cpp        2009-03-23 11:00:59 UTC (rev 1321)
@@ -151,7 +151,9 @@
   if(audio_event && 
      ((audio_event->event_id == AmAudioEvent::cleared) || 
       (audio_event->event_id == AmAudioEvent::noAudio))){
-    engine.runEvent(this, DSMCondition::NoAudio, NULL);
+    map<string, string> params;
+    params["type"] = audio_event->event_id == 
AmAudioEvent::cleared?"cleared":"noAudio";
+    engine.runEvent(this, DSMCondition::NoAudio, &params);
     return;
   }
 

Modified: trunk/apps/dsm/DSMModule.cpp
===================================================================
--- trunk/apps/dsm/DSMModule.cpp        2009-03-19 12:21:33 UTC (rev 1320)
+++ trunk/apps/dsm/DSMModule.cpp        2009-03-23 11:00:59 UTC (rev 1321)
@@ -26,6 +26,8 @@
  */
 
 #include "DSMModule.h"
+#include "DSMSession.h"
+#include "AmSession.h"
 
 DSMModule::DSMModule() {
 }
@@ -33,3 +35,53 @@
 DSMModule::~DSMModule() {
 }
 
+SCStrArgAction::SCStrArgAction(const string& m_arg) { 
+  arg = trim(m_arg, " \t");
+  if (arg.length() && arg[0] == '"')
+    arg = trim(arg, "\"");
+  else if (arg.length() && arg[0] == '\'')
+    arg = trim(arg, "'");
+}
+
+string trim(string const& str,char const* sepSet)
+{
+  string::size_type const first = str.find_first_not_of(sepSet);
+  return ( first==string::npos )
+    ? std::string()  : 
+    str.substr(first, str.find_last_not_of(sepSet)-first+1);
+}
+
+string resolveVars(const string s, AmSession* sess,
+                  DSMSession* sc_sess, map<string,string>* event_params) {
+  if (s.length()) {
+    switch(s[0]) {
+    case '$': return sc_sess->var[s.substr(1)];
+    case '#': 
+      if (event_params) 
+       return  (*event_params)[s.substr(1)];
+      else 
+       return string();
+    case '@': {
+      string s1 = s.substr(1); 
+      if (s1 == "local_tag")
+       return sess->getLocalTag();     
+      else if (s1 == "user")
+       return sess->dlg.user;
+      else if (s1 == "domain")
+       return sess->dlg.domain;
+      else if (s1 == "remote_tag")
+       return sess->getRemoteTag();
+      else if (s1 == "callid")
+       return sess->getCallID();
+      else if (s1 == "local_uri")
+       return sess->dlg.local_uri;
+      else if (s1 == "remote_uri")
+       return sess->dlg.remote_uri;
+      else
+       return string();
+    } 
+    default: return trim(s, "\"");
+    }
+  }
+  return s;
+}

Modified: trunk/apps/dsm/DSMModule.h
===================================================================
--- trunk/apps/dsm/DSMModule.h  2009-03-19 12:21:33 UTC (rev 1320)
+++ trunk/apps/dsm/DSMModule.h  2009-03-23 11:00:59 UTC (rev 1321)
@@ -29,11 +29,14 @@
 #include "DSMStateEngine.h"
 #include "AmSipMsg.h"
 #include "AmArg.h"
+
 class DSMSession;
 
 #include <string>
 using std::string;
 
+#include <typeinfo>
+
 // script modules interface
 // factory only: it produces actions and conditions from script statements.
 class DSMModule {
@@ -75,17 +78,17 @@
   EXPORT_SC_FACTORY(SC_FACTORY_EXPORT,class_name)
 
 
+string trim(string const& str,char const* sepSet);
 
 class SCStrArgAction   
 : public DSMAction {
  protected:
   string arg;
  public:
-  SCStrArgAction(const string& arg)
-    : arg(arg) { }
+  SCStrArgAction(const string& m_arg); 
 };
 
-#define DEF_SCStrArgAction(CL_Name)                                    \
+#define DEF_ACTION_1P(CL_Name)                                         \
   class CL_Name                                                                
\
   : public SCStrArgAction {                                            \
   public:                                                              \
@@ -96,7 +99,7 @@
   };                                                                   \
   
 
-#define DEF_SCModSEStrArgAction(CL_Name)                                       
\
+#define DEF_SCModSEStrArgAction(CL_Name)                               \
   class CL_Name                                                                
\
   : public SCStrArgAction {                                            \
   public:                                                              \
@@ -107,7 +110,7 @@
     SEAction getSEAction(std::string&);                                        
\
   };                                                                   \
 
-#define DEF_TwoParAction(CL_Name)                                      \
+#define DEF_ACTION_2P(CL_Name)                                         \
   class CL_Name                                                                
\
   : public DSMAction {                                                 \
     string par1;                                                       \
@@ -119,15 +122,127 @@
                 map<string,string>* event_params);                     \
   };                                                                   \
 
-#define CONST_TwoParAction(CL_name, sep, optional)             \
-  CL_name::CL_name(const string& arg) {                                \
-    vector<string> args = explode(arg,sep);                    \
-    if (!optional && args.size()!=2) {                         \
-      ERROR("expression '%s' not valid\n", arg.c_str());       \
-      return;                                                  \
-    }                                                          \
-    par1 = args.size()?trim(args[0], " \t"):"";                        \
-    par2 = args.size()>1?trim(args[1], " \t"):"";              \
+/* bool xsplit(const string& arg, char sep, bool optional, string& par1, 
string& par2); */
+
+#define CONST_ACTION_2P(CL_name, sep, optional)                                
\
+  CL_name::CL_name(const string& arg) {                                        
\
+    size_t p = 0;                                                      \
+    char last_c = ' ';                                                 \
+    bool quot=false;                                                   \
+    char quot_c = ' ';                                                 \
+    bool sep_found = false;                                            \
+    while (p<arg.size()) {                                             \
+      if (quot) {                                                      \
+       if (last_c != '\\' && arg[p]==quot_c)                           \
+         quot=false;                                                   \
+      } else {                                                         \
+       if (last_c != '\\'  && (arg[p]=='\'' || arg[p]=='\"')) {        \
+         quot = true;                                                  \
+         quot_c = arg[p];                                              \
+       } else {                                                        \
+         if (arg[p] == sep) {                                          \
+           sep_found = true;                                           \
+           break;                                                      \
+         }                                                             \
+       }                                                               \
+      }                                                                        
\
+      p++;                                                             \
+      last_c = arg[p];                                                 \
+    }                                                                  \
+                                                                       \
+    if ((!optional) && (!sep_found)) {                                 \
+      ERROR("expected two parameters separated with '%c' in expression '%s' 
for %s\n", \
+           sep,arg.c_str(),typeid(this).name());                       \
+      return;                                                          \
+    }                                                                  \
+                                                                       \
+    par1 = trim(arg.substr(0,p), " \t");                               \
+    if (sep_found)                                                     \
+      par2 = trim(arg.substr(p+1), " \t");                             \
+                                                                       \
+    if (par1.length() && par1[0]=='\'') {                              \
+      par1 = trim(par1, "\'");                                         \
+      size_t rpos = 0;                                                 \
+      while ((rpos=par1.find("\\\'")) != string::npos)                 \
+       par1.erase(rpos, 1);                                            \
+    } else if (par1.length() && par1[0]=='\"') {                       \
+      par1 = trim(par1, "\"");                                         \
+      size_t rpos = 0;                                                 \
+      while ((rpos=par1.find("\\\"")) != string::npos)                 \
+       par1.erase(rpos, 1);                                            \
+    }                                                                  \
+                                                                       \
+    if (par2.length() && par2[0]=='\'') {                              \
+      par2 = trim(par2, "\'");                                         \
+      size_t rpos = 0;                                                 \
+      while ((rpos=par2.find("\\\'")) != string::npos)                 \
+       par2.erase(rpos, 1);                                            \
+    } else if (par2.length() && par2[0]=='\"') {                       \
+      par2 = trim(par2, "\"");                                         \
+      size_t rpos = 0;                                                 \
+      while ((rpos=par2.find("\\\"")) != string::npos)                 \
+       par2.erase(rpos, 1);                                            \
+    }                                                                  \
+                                                                       \
+    if ((!optional) && ((par1.empty())||(par2.empty()))) {             \
+      ERROR("expected two parameters separated with '%c' in expression '%s' 
for %s\n", \
+           sep,arg.c_str(),typeid(this).name());                       \
+      return;                                                          \
+    }                                                                  \
+  }                                                                    \
+  
+
+#define GET_SCSESSION()                                               \
+  DSMSession* sc_sess = dynamic_cast<DSMSession*>(sess);       \
+  if (!sc_sess) {                                             \
+    ERROR("wrong session type\n");                            \
+    return false;                                             \
   }
 
+
+#define EXEC_ACTION_START(act_name)                                    \
+  bool act_name::execute(AmSession* sess,                              \
+                        DSMCondition::EventType event,                 \
+                        map<string,string>* event_params) {            \
+  GET_SCSESSION();                                                     
+
+#define EXEC_ACTION_END                                \
+  return false;                                        \
+  }
+
+string resolveVars(const string s, AmSession* sess,
+                  DSMSession* sc_sess, map<string,string>* event_params);
+
+#define DEF_CMD(cmd_name, class_name) \
+                                     \
+  if (cmd == cmd_name) {             \
+    class_name * a =                 \
+      new class_name(params);        \
+    a->name = from_str;                      \
+    return a;                        \
+  }
+
+#define DEF_SCCondition(cond_name)             \
+  class cond_name                              \
+  : public DSMCondition {                      \
+    string arg;                                        \
+    bool inv;                                  \
+                                               \
+  public:                                      \
+                                               \
+  cond_name(const string& arg, bool inv)                       \
+    : arg(arg), inv(inv) { }                                   \
+    bool match(AmSession* sess, DSMCondition::EventType event, \
+              map<string,string>* event_params);               \
+  };                                                           \
+  
+
+#define MATCH_CONDITION_START(cond_clsname)                            \
+  bool cond_clsname::match(AmSession* sess, DSMCondition::EventType event, \
+                          map<string,string>* event_params) {          \
+  GET_SCSESSION();
+
+#define MATCH_CONDITION_END }                  
+
+
 #endif

Modified: trunk/apps/dsm/DSMSession.h
===================================================================
--- trunk/apps/dsm/DSMSession.h 2009-03-19 12:21:33 UTC (rev 1320)
+++ trunk/apps/dsm/DSMSession.h 2009-03-23 11:00:59 UTC (rev 1321)
@@ -78,6 +78,9 @@
   /* holds variables which are accessed by $varname */
   map<string, string> var;
 
+  /* holds AmArg variables. todo: merge var with these */
+  map<string, AmArg> avar;
+
   /* result of the last DI call */
   AmArg di_res;
 

Modified: trunk/apps/dsm/DSMStateEngine.cpp
===================================================================
--- trunk/apps/dsm/DSMStateEngine.cpp   2009-03-19 12:21:33 UTC (rev 1320)
+++ trunk/apps/dsm/DSMStateEngine.cpp   2009-03-23 11:00:59 UTC (rev 1321)
@@ -297,6 +297,9 @@
        }
        
        // go into new state
+       if (!target_st) {
+         break;
+       }
        DBG("changing to new state '%s'\n", target_st->name.c_str());
        current = target_st;
        

Modified: trunk/apps/dsm/doc/dsm_syntax.txt
===================================================================
--- trunk/apps/dsm/doc/dsm_syntax.txt   2009-03-19 12:21:33 UTC (rev 1320)
+++ trunk/apps/dsm/doc/dsm_syntax.txt   2009-03-23 11:00:59 UTC (rev 1321)
@@ -62,6 +62,8 @@
 
  log(level, text)
    e.g. log(1, $var1)
+ -- log all variables:
+ logVars(level) 
 
  setTimer(timer_id, timeout)
    e.g. setTimer(1, $timeout)

Modified: trunk/apps/dsm/mods/mod_conference/ModConference.cpp
===================================================================
--- trunk/apps/dsm/mods/mod_conference/ModConference.cpp        2009-03-19 
12:21:33 UTC (rev 1320)
+++ trunk/apps/dsm/mods/mod_conference/ModConference.cpp        2009-03-23 
11:00:59 UTC (rev 1321)
@@ -87,7 +87,7 @@
   }
 
 
-CONST_TwoParAction(ConfPostEventAction, ",", true);
+CONST_ACTION_2P(ConfPostEventAction, ',', true);
 
 bool ConfPostEventAction::execute(AmSession* sess, 
                             DSMCondition::EventType event,

Modified: trunk/apps/dsm/mods/mod_conference/ModConference.h
===================================================================
--- trunk/apps/dsm/mods/mod_conference/ModConference.h  2009-03-19 12:21:33 UTC 
(rev 1320)
+++ trunk/apps/dsm/mods/mod_conference/ModConference.h  2009-03-23 11:00:59 UTC 
(rev 1321)
@@ -51,7 +51,7 @@
   ~DSMConfChannel() { }
 };
 
-DEF_SCStrArgAction(ConfJoinAction);
-DEF_TwoParAction(ConfPostEventAction);
-DEF_SCStrArgAction(ConfSetPlayoutTypeAction);
+DEF_ACTION_1P(ConfJoinAction);
+DEF_ACTION_2P(ConfPostEventAction);
+DEF_ACTION_1P(ConfSetPlayoutTypeAction);
 #endif

Modified: trunk/apps/dsm/mods/mod_dlg/ModDlg.cpp
===================================================================
--- trunk/apps/dsm/mods/mod_dlg/ModDlg.cpp      2009-03-19 12:21:33 UTC (rev 
1320)
+++ trunk/apps/dsm/mods/mod_dlg/ModDlg.cpp      2009-03-23 11:00:59 UTC (rev 
1321)
@@ -89,7 +89,7 @@
     return false;                                       \
   }
 
-CONST_TwoParAction(DLGReplyAction, ",", true);
+CONST_ACTION_2P(DLGReplyAction, ',', true);
 
 bool DLGReplyAction::execute(AmSession* sess, 
                             DSMCondition::EventType event,
@@ -119,7 +119,7 @@
   return false;
 }
 
-CONST_TwoParAction(DLGAcceptInviteAction, ",", true);
+CONST_ACTION_2P(DLGAcceptInviteAction, ',', true);
 
 bool DLGAcceptInviteAction::execute(AmSession* sess, 
                                     DSMCondition::EventType event,

Modified: trunk/apps/dsm/mods/mod_dlg/ModDlg.h
===================================================================
--- trunk/apps/dsm/mods/mod_dlg/ModDlg.h        2009-03-19 12:21:33 UTC (rev 
1320)
+++ trunk/apps/dsm/mods/mod_dlg/ModDlg.h        2009-03-23 11:00:59 UTC (rev 
1321)
@@ -41,6 +41,6 @@
   bool onInvite(const AmSipRequest& req, DSMSession* sess);
 };
 
-DEF_TwoParAction(DLGReplyAction);
-DEF_TwoParAction(DLGAcceptInviteAction);
+DEF_ACTION_2P(DLGReplyAction);
+DEF_ACTION_2P(DLGAcceptInviteAction);
 #endif

Modified: trunk/apps/dsm/mods/mod_monitoring/ModMonitoring.cpp
===================================================================
--- trunk/apps/dsm/mods/mod_monitoring/ModMonitoring.cpp        2009-03-19 
12:21:33 UTC (rev 1320)
+++ trunk/apps/dsm/mods/mod_monitoring/ModMonitoring.cpp        2009-03-23 
11:00:59 UTC (rev 1321)
@@ -81,7 +81,7 @@
   }
 
 
-CONST_TwoParAction(MonLogAction, ",", true);
+CONST_ACTION_2P(MonLogAction, ',', true);
 bool MonLogAction::execute(AmSession* sess, 
                           DSMCondition::EventType event,
                           map<string,string>* event_params) {
@@ -95,7 +95,7 @@
   return false;
 }
 
-CONST_TwoParAction(MonLogAddAction, ",", true);
+CONST_ACTION_2P(MonLogAddAction, ',', true);
 bool MonLogAddAction::execute(AmSession* sess, 
                           DSMCondition::EventType event,
                           map<string,string>* event_params) {

Modified: trunk/apps/dsm/mods/mod_monitoring/ModMonitoring.h
===================================================================
--- trunk/apps/dsm/mods/mod_monitoring/ModMonitoring.h  2009-03-19 12:21:33 UTC 
(rev 1320)
+++ trunk/apps/dsm/mods/mod_monitoring/ModMonitoring.h  2009-03-23 11:00:59 UTC 
(rev 1321)
@@ -40,8 +40,8 @@
   DSMCondition* getCondition(const string& from_str);
 };
 
-DEF_TwoParAction(MonLogAction);
-DEF_TwoParAction(MonLogAddAction);
-DEF_SCStrArgAction(MonLogVarsAction);
+DEF_ACTION_2P(MonLogAction);
+DEF_ACTION_2P(MonLogAddAction);
+DEF_ACTION_1P(MonLogVarsAction);
 
 #endif

Modified: trunk/apps/dsm/mods/mod_sys/ModSys.cpp
===================================================================
--- trunk/apps/dsm/mods/mod_sys/ModSys.cpp      2009-03-19 12:21:33 UTC (rev 
1320)
+++ trunk/apps/dsm/mods/mod_sys/ModSys.cpp      2009-03-23 11:00:59 UTC (rev 
1321)
@@ -59,14 +59,6 @@
   string params;
   splitCmd(from_str, cmd, params);
 
-#define DEF_CMD(cmd_name, class_name) \
-                                     \
-  if (cmd == cmd_name) {             \
-    class_name * a =                 \
-      new class_name(params);        \
-    a->name = from_str;                      \
-    return a;                        \
-  }
   DEF_CMD("sys.mkdir", SCMkDirAction);
 
   return NULL;
@@ -89,16 +81,7 @@
   return NULL;
 }
 
-#define GET_SCSESSION()                                       \
-  DSMSession* sc_sess = dynamic_cast<DSMSession*>(sess); \
-  if (!sc_sess) {                                     \
-    ERROR("wrong session type\n");                    \
-    return false;                                             \
-  }
-
-bool FileExistsCondition::match(AmSession* sess, DSMCondition::EventType event,
-                               map<string,string>* event_params) {
-  GET_SCSESSION();
+MATCH_CONDITION_START(FileExistsCondition) {
   DBG("checking file '%s'\n", arg.c_str());
   string fname = resolveVars(arg, sess, sc_sess, event_params);
   bool ex =  file_exists(fname);
@@ -110,18 +93,15 @@
     DBG("returning %s\n", (ex)?"true":"false");
     return ex;
   }
-}
+} MATCH_CONDITION_END;
 
 
-bool SCMkDirAction::execute(AmSession* sess, 
-                           DSMCondition::EventType event,
-                           map<string,string>* event_params) {
-  GET_SCSESSION();
+EXEC_ACTION_START(SCMkDirAction) {
   string d = resolveVars(arg, sess, sc_sess, event_params);
   DBG("mkdir '%s'\n", d.c_str());
   if (mkdir(d.c_str(),  S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) {
     ERROR("kmdir failed for '%s': %s\n", 
          d.c_str(), strerror(errno));
   }
-  return false;
-}
+} EXEC_ACTION_END;
+

Modified: trunk/apps/dsm/mods/mod_sys/ModSys.h
===================================================================
--- trunk/apps/dsm/mods/mod_sys/ModSys.h        2009-03-19 12:21:33 UTC (rev 
1320)
+++ trunk/apps/dsm/mods/mod_sys/ModSys.h        2009-03-23 11:00:59 UTC (rev 
1321)
@@ -39,18 +39,6 @@
   DSMCondition* getCondition(const string& from_str);
 };
 
-class FileExistsCondition 
-: public DSMCondition {
-  string arg;
-  bool inv;
-
- public:
-
- FileExistsCondition(const string& arg, bool inv) 
-   : arg(arg), inv(inv) { }
-  bool match(AmSession* sess, DSMCondition::EventType event,
-            map<string,string>* event_params);
-};
-
-DEF_SCStrArgAction(SCMkDirAction);
+DEF_SCCondition(FileExistsCondition);
+DEF_ACTION_1P(SCMkDirAction);
 #endif

Modified: trunk/apps/dsm/mods/mod_uri/ModUri.cpp
===================================================================
--- trunk/apps/dsm/mods/mod_uri/ModUri.cpp      2009-03-19 12:21:33 UTC (rev 
1320)
+++ trunk/apps/dsm/mods/mod_uri/ModUri.cpp      2009-03-23 11:00:59 UTC (rev 
1321)
@@ -86,7 +86,7 @@
     return false;                                       \
   }
 
-CONST_TwoParAction(URIParseAction, ",", true);
+CONST_ACTION_2P(URIParseAction, ',', true);
 
 bool URIParseAction::execute(AmSession* sess, 
                             DSMCondition::EventType event,
@@ -116,8 +116,7 @@
   return true;
 }
 
-CONST_TwoParAction(URIGetHeaderAction, ",", false);
-
+CONST_ACTION_2P(URIGetHeaderAction, ',', false);
 bool URIGetHeaderAction::execute(AmSession* sess, 
                                 DSMCondition::EventType event,
                                 map<string,string>* event_params) {
@@ -126,8 +125,7 @@
   string hname  = resolveVars(par1, sess, sc_sess, event_params);
   string dstname = resolveVars(par2, sess, sc_sess, event_params);
 
-  sc_sess->var[dstname] = getHeader(sc_sess->var["hdrs"], hname);
-  DBG("got header '%s' value '%s' as $%s\n", 
+  sc_sess->var[dstname] = getHeader(sc_sess->var["hdrs"], hname);  DBG("got 
header '%s' value '%s' as $%s\n", 
       hname.c_str(), sc_sess->var[dstname].c_str(), dstname.c_str());
   return false;
 }

Modified: trunk/apps/dsm/mods/mod_uri/ModUri.h
===================================================================
--- trunk/apps/dsm/mods/mod_uri/ModUri.h        2009-03-19 12:21:33 UTC (rev 
1320)
+++ trunk/apps/dsm/mods/mod_uri/ModUri.h        2009-03-23 11:00:59 UTC (rev 
1321)
@@ -41,7 +41,7 @@
   bool onInvite(const AmSipRequest& req, DSMSession* sess);
 };
 
-DEF_TwoParAction(URIParseAction);
-DEF_TwoParAction(URIGetHeaderAction);
+DEF_ACTION_2P(URIParseAction);
+DEF_ACTION_2P(URIGetHeaderAction);
 
 #endif

_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to