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
