Module: sems
Branch: sayer/dsm_lang
Commit: 26db3fae3371e2ad2eb1ff107334911153468a63
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=26db3fae3371e2ad2eb1ff107334911153468a63

Author: Stefan Sayer <[email protected]>
Committer: Stefan Sayer <[email protected]>
Date:   Sun Jan 23 18:33:31 2011 +0100

DSM: implement for ($x in range(2, 5))

Development sponsored by TelTech Systems Inc.

---

 apps/dsm/DSMChartReader.cpp |   30 +++++++++++++++--
 apps/dsm/DSMStateEngine.cpp |   79 +++++++++++++++++++++++++++++-------------
 apps/dsm/DSMStateEngine.h   |   12 ++++++-
 3 files changed, 92 insertions(+), 29 deletions(-)

diff --git a/apps/dsm/DSMChartReader.cpp b/apps/dsm/DSMChartReader.cpp
index 94c8954..08358bc 100644
--- a/apps/dsm/DSMChartReader.cpp
+++ b/apps/dsm/DSMChartReader.cpp
@@ -167,19 +167,43 @@ bool DSMChartReader::forFromToken(DSMArrayFor& af, const 
string& token) {
     return false;
   }
 
-  af.array_struct = forh_v[1];
-
   vector<string> kv = explode(forh_v[0], ",");
   if (kv.size() == 2) {
+    af.for_type = DSMArrayFor::Struct;
     af.k = kv[0];
     af.v = kv[1];
+    af.array_struct = forh_v[1];
     DBG("for (%s,%s in %s) {\n", af.k.c_str(), af.v.c_str(), 
af.array_struct.c_str());
+  } else if (forh_v[1].length() > 7 &&
+       forh_v[1].substr(0,6)=="range(" &&
+       forh_v[1][forh_v[1].length()-1] == ')') {
+    af.for_type = DSMArrayFor::Range;
+    string range_s = forh_v[1].substr(6, forh_v[1].length()-7);
+    vector<string> range_v = explode(range_s, ",");
+    if (range_v.size() == 2) {
+      if (!str2int(range_v[0], af.range[0]) ||
+         !str2int(range_v[1], af.range[1])) {
+       ERROR("range(%s,%s) not understood in for\n",
+             range_v[0].c_str(), range_v[1].c_str());
+       return false;
+      }
+    } else {
+      af.range[0] = 0;
+      if (!str2int(range_s, af.range[1])) {
+       ERROR("range(%s) not understood in for\n", range_s.c_str());
+       return false;
+      }
+    }
+    af.k = forh_v[0];
+    DBG("for (%s in range(%d, %d) {\n",
+       af.k.c_str(), af.range[0], af.range[1]);
   } else {
+    af.for_type = DSMArrayFor::Array;
+    af.array_struct = forh_v[1];
     af.k = forh_v[0];
     DBG("for (%s in %s) {\n", af.k.c_str(), af.array_struct.c_str());
   }
 
-
   return true;
 }
 
diff --git a/apps/dsm/DSMStateEngine.cpp b/apps/dsm/DSMStateEngine.cpp
index 2de1cfa..2466bd3 100644
--- a/apps/dsm/DSMStateEngine.cpp
+++ b/apps/dsm/DSMStateEngine.cpp
@@ -291,29 +291,39 @@ bool 
DSMStateEngine::runactions(vector<DSMElement*>::iterator from,
 
     DSMArrayFor* array_for = dynamic_cast<DSMArrayFor*>(*it);
     if (array_for) {
-      DBG("running for (%s%s in %s) {\n",
-         array_for->k.c_str(), array_for->v.empty() ? "" : 
(","+array_for->v).c_str(),
-         array_for->array_struct.c_str());
+      if (array_for->for_type == DSMArrayFor::Range) {
+       DBG("running for (%s in range(%d, %d) {\n",
+           array_for->k.c_str(), array_for->range[0], array_for->range[1]);
+      } else {
+       DBG("running for (%s%s in %s) {\n",
+           array_for->k.c_str(), array_for->v.empty() ? "" : 
(","+array_for->v).c_str(),
+           array_for->array_struct.c_str());
+      }
 
       string array_name = array_for->array_struct;
       string k_name = array_for->k;
       string v_name = array_for->v;
 
-      if (!array_name.length() || !k_name.length()) {
-       WARN("empty array or counter name in for\n");
+      if (!k_name.length()) {
+       ERROR("empty counter name in for\n");
+       continue;
+      }
+
+      if (array_for->for_type != DSMArrayFor::Range && !array_name.length()) {
+       ERROR("empty array name in for\n");
        continue;
       }
 
       if (array_name[0] == '$')        array_name.erase(0, 1);
       if (k_name[0] == '$') k_name.erase(0, 1);
-      bool is_kv = !v_name.empty();
-      if (is_kv && v_name[0] == '$') v_name.erase(0, 1);
 
+      if (array_for->for_type == DSMArrayFor::Struct && v_name[0] == '$')
+       v_name.erase(0, 1);
 
       vector<pair<string, string> > cnt_values;
 
       // get the counter values
-      if (is_kv) {
+      if (array_for->for_type == DSMArrayFor::Struct) {
        VarMapT::iterator lb = sc_sess->var.lower_bound(array_name);
        while (lb != sc_sess->var.end()) {
          if ((lb->first.length() < array_name.length()) ||
@@ -326,7 +336,7 @@ bool 
DSMStateEngine::runactions(vector<DSMElement*>::iterator from,
          DBG("      '%s,%s'\n", varname.c_str(), valname.c_str());
          lb++;
        }
-      } else {
+      } else if (array_for->for_type == DSMArrayFor::Array) {
        unsigned int a_index = 0;
        while (true) {
          VarMapT::iterator v = 
sc_sess->var.find(array_name+"["+int2str(a_index)+"]");
@@ -338,13 +348,14 @@ bool 
DSMStateEngine::runactions(vector<DSMElement*>::iterator from,
        }
       }
 
-      // save counter
+      // save counter k
       VarMapT::iterator c_it = sc_sess->var.find(k_name);
       bool k_exists = c_it != sc_sess->var.end();
       string k_save = k_exists ? c_it->second : string("");
 
+      // save counter v for Struct
       bool v_exists = false; string v_save;
-      if (is_kv) {
+      if (array_for->for_type == DSMArrayFor::Struct) {
        c_it = sc_sess->var.find(v_name);
        v_exists = c_it != sc_sess->var.end();
        if (v_exists)
@@ -352,28 +363,46 @@ bool 
DSMStateEngine::runactions(vector<DSMElement*>::iterator from,
       }
 
       // run the loop
-      DBG("running for loop with %zd items\n", cnt_values.size());
-      for (vector<pair<string, string> >::iterator f_it=
-            cnt_values.begin(); f_it != cnt_values.end(); f_it++) {
-       if (is_kv) {
-         DBG("setting $%s=%s, $%s=%s\n", k_name.c_str(), f_it->first.c_str(),
-             v_name.c_str(), f_it->second.c_str());
-         sc_sess->var[k_name] = f_it->first;
-         sc_sess->var[v_name] = f_it->second;
-       } else {
-         DBG("setting $%s=%s\n", k_name.c_str(), f_it->first.c_str());
-         sc_sess->var[k_name] = f_it->first;
+      if (array_for->for_type == DSMArrayFor::Range) {
+       int cnt = array_for->range[0];
+       while (cnt != array_for->range[1]) {
+         sc_sess->var[k_name] = int2str(cnt);
+         DBG("setting $%s=%s\n", k_name.c_str(), sc_sess->var[k_name].c_str());
+
+         runactions(array_for->actions.begin(), array_for->actions.end(),
+                    sess, sc_sess, event, event_params, is_consumed);
+
+         if (array_for->range[1] > array_for->range[0])
+           cnt++;
+         else
+           cnt--;
+       }
+
+      } else {
+       DBG("running for loop with %zd items\n", cnt_values.size());
+       for (vector<pair<string, string> > ::iterator f_it=
+              cnt_values.begin(); f_it != cnt_values.end(); f_it++) {
+         if (array_for->for_type == DSMArrayFor::Struct) {
+           DBG("setting $%s=%s, $%s=%s\n", k_name.c_str(), f_it->first.c_str(),
+               v_name.c_str(), f_it->second.c_str());
+           sc_sess->var[k_name] = f_it->first;
+           sc_sess->var[v_name] = f_it->second;
+         } else {
+           DBG("setting $%s=%s\n", k_name.c_str(), f_it->first.c_str());
+           sc_sess->var[k_name] = f_it->first;
+         }
+         runactions(array_for->actions.begin(), array_for->actions.end(),
+                    sess, sc_sess, event, event_params, is_consumed);
        }
-       runactions(array_for->actions.begin(), array_for->actions.end(),
-                  sess, sc_sess, event, event_params, is_consumed);
       }
+
       // restore the counter[s]
       if (k_exists)
        sc_sess->var[k_name] = k_save;
       else
        sc_sess->var.erase(k_name);
 
-      if (is_kv) {
+      if (array_for->for_type == DSMArrayFor::Struct) {
        if (v_exists)
          sc_sess->var[v_name] = v_save;
        else
diff --git a/apps/dsm/DSMStateEngine.h b/apps/dsm/DSMStateEngine.h
index 97edd2f..118cda4 100644
--- a/apps/dsm/DSMStateEngine.h
+++ b/apps/dsm/DSMStateEngine.h
@@ -180,8 +180,18 @@ class DSMFunction
 class DSMArrayFor
 : public DSMElement {
  public:
+  DSMArrayFor() { }
+  ~DSMArrayFor() { }
+
+  enum DSMForType {
+    Range,
+    Array,
+    Struct
+  } for_type;
+
   string k; // for(k in array)
-  string v; // if set, for(k,v in struct)
+  string v; // for(k,v in struct)
+  int range[2];
   string array_struct; // array or struct name
   vector<DSMElement*> actions;
 };

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

Reply via email to