Module: sip-router
Branch: master
Commit: 33c5fc98db553ae28385608890df1a883aaa51d4
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=33c5fc98db553ae28385608890df1a883aaa51d4

Author: Alex Hermann <[email protected]>
Committer: Alex Hermann <[email protected]>
Date:   Thu Aug 11 13:19:21 2011 +0200

modules/textops: allow pseudovariables in re.subst parameter

---

 modules_k/textops/txt_var.c |  142 +++++++++++++++++++++++++++++-------------
 1 files changed, 98 insertions(+), 44 deletions(-)

diff --git a/modules_k/textops/txt_var.c b/modules_k/textops/txt_var.c
index a13e5e1..adcb860 100644
--- a/modules_k/textops/txt_var.c
+++ b/modules_k/textops/txt_var.c
@@ -42,6 +42,7 @@ int tr_txt_eval_re(struct sip_msg *msg, tr_param_t *tp, int 
subtype,
        str* result;
 #define TR_TXT_BUF_SIZE        2048
        static char tr_txt_buf[TR_TXT_BUF_SIZE];
+       pv_value_t v;
 
        if(val==NULL || (!(val->flags&PV_VAL_STR)) || val->rs.len<=0)
                return -1;
@@ -49,14 +50,31 @@ int tr_txt_eval_re(struct sip_msg *msg, tr_param_t *tp, int 
subtype,
        switch(subtype)
        {
                case TR_TXT_RE_SUBST:
-                       se = (struct subst_expr*)tp->v.data;
-                       if(se==NULL)
-                               return 0;
+                       if (tp->type == TR_PARAM_SUBST) {
+                               se = (struct subst_expr*)tp->v.data;
+                               if (se==NULL)
+                                       return 0;
+                       } else if (tp->type == TR_PARAM_SPEC) {
+                               if (pv_get_spec_value(msg, 
(pv_spec_p)tp->v.data, &v)!=0
+                                               || (!(v.flags&PV_VAL_STR)) || 
v.rs.len<=0)
+                               {
+                                       LM_ERR("Can't evaluate regexp\n");
+                                       return -1;
+                               }
+                               se=subst_parser(&v.rs);
+                               if (se==0) {
+                                       LM_ERR("Can't compile regexp\n");
+                                       return -1;
+                               }
+                       } else {
+                               LM_ERR("Unknown parameter type\n");
+                               return -1;
+                       }
                        if(val->rs.len>=TR_TXT_BUF_SIZE-1)
                        {
                                LM_ERR("PV value too big %d, increase buffer 
size\n",
                                                val->rs.len);
-                               return -1;
+                               goto error;
                        }
                        memcpy(tr_txt_buf, val->rs.s, val->rs.len);
                        tr_txt_buf[val->rs.len] = '\0';
@@ -67,17 +85,17 @@ int tr_txt_eval_re(struct sip_msg *msg, tr_param_t *tp, int 
subtype,
                                if (nmatches==0)
                                {
                                        LM_DBG("no match for subst 
expression\n");
-                                       return 0;
+                                       break;
                                }
                                if (nmatches<0)
                                        LM_ERR("subst failed\n");
-                               return -1;
+                               goto error;
                        }
                        if(result->len>=TR_TXT_BUF_SIZE-1)
                        {
                                LM_ERR("subst result too big %d, increase 
buffer size\n",
                                                result->len);
-                               return -1;
+                               goto error;
                        }
                        memcpy(tr_txt_buf, result->s, result->len);
                        tr_txt_buf[result->len] = '\0';
@@ -90,20 +108,80 @@ int tr_txt_eval_re(struct sip_msg *msg, tr_param_t *tp, 
int subtype,
                        break;
                default:
                        LM_ERR("unknown subtype %d\n", subtype);
-                       return -1;
+                       goto error;
+       }
+
+       if (tp->type == TR_PARAM_SPEC) {
+               subst_expr_free(se);
        }
        return 0;
 
+error:
+       if (tp->type == TR_PARAM_SPEC) {
+               subst_expr_free(se);
+       }
+       return -1;
 }
 
+#define _tr_parse_sparam(_p, _p0, _tp, _spec, _ps, _in, _s) \
+       while(is_in_str(_p, _in) && (*_p==' ' || *_p=='\t' || *_p=='\n')) _p++; 
\
+       if(*_p==PV_MARKER) \
+       { /* pseudo-variable */ \
+               _spec = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t)); \
+               if(_spec==NULL) \
+               { \
+                       LM_ERR("no more private memory!\n"); \
+                       goto error; \
+               } \
+               _s.s = _p; _s.len = _in->s + _in->len - _p; \
+               _p0 = pv_parse_spec(&_s, _spec); \
+               if(_p0==NULL) \
+               { \
+                       LM_ERR("invalid spec in substr transformation: 
%.*s!\n", \
+                               _in->len, _in->s); \
+                       goto error; \
+               } \
+               _p = _p0; \
+               _tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t)); \
+               if(_tp==NULL) \
+               { \
+                       LM_ERR("no more private memory!\n"); \
+                       goto error; \
+               } \
+               memset(_tp, 0, sizeof(tr_param_t)); \
+               _tp->type = TR_PARAM_SPEC; \
+               _tp->v.data = (void*)_spec; \
+       } else { /* string */ \
+               _ps = _p; \
+               while(is_in_str(_p, _in) && *_p!='\t' && *_p!='\n' \
+                               && *_p!=TR_PARAM_MARKER && *_p!=TR_RBRACKET) \
+                               _p++; \
+               if(*_p=='\0') \
+               { \
+                       LM_ERR("invalid param in transformation: %.*s!!\n", \
+                               _in->len, _in->s); \
+                       goto error; \
+               } \
+               _tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t)); \
+               if(_tp==NULL) \
+               { \
+                       LM_ERR("no more private memory!\n"); \
+                       goto error; \
+               } \
+               memset(_tp, 0, sizeof(tr_param_t)); \
+               _tp->type = TR_PARAM_STRING; \
+               _tp->v.s.s = _ps; \
+               _tp->v.s.len = _p - _ps; \
+       }
+
 char* tr_txt_parse_re(str *in, trans_t *t)
 {
-       char *p;
+       char *p, *p0, *ps;
        str name;
-       str tok;
+       str s;
        struct subst_expr *se = NULL;
        tr_param_t *tp = NULL;
-       int n;
+       pv_spec_t *spec = NULL;
 
 
        if(in==NULL || t==NULL)
@@ -127,39 +205,16 @@ char* tr_txt_parse_re(str *in, trans_t *t)
                if(*p!=TR_PARAM_MARKER)
                        goto error;
                p++;
-               /* get trans here */
-               n = 0;
-               tok.s = p;
-               while(is_in_str(p, in))
-               {
-                       if(*p==TR_RBRACKET)
-                       {
-                               if(n==0)
-                                               break;
-                               n--;
-                       }
-                       if(*p == TR_LBRACKET)
-                               n++;
-                       p++;
-               }
-               if(!is_in_str(p, in))
-                       goto error;
-               if(p==tok.s)
-                       goto error;
-               tok.len = p - tok.s;
-               tp = (tr_param_t*)pkg_malloc(sizeof(tr_param_t));
-               if(tp==NULL)
-               {
-                       LM_ERR("no more private memory!\n");
-                       goto error;
+               /* get parameter */
+               _tr_parse_sparam(p, p0, tp, spec, ps, in, s);
+               if (tp->type == TR_PARAM_STRING) {
+                       /* precompile static regexp */
+                       se=subst_parser(&tp->v.s);
+                       if (se==0)
+                               goto error;
+                       tp->type = TR_PARAM_SUBST;
+                       tp->v.data = (void*)se;
                }
-
-               se=subst_parser(&tok);
-
-               if (se==0)
-                       goto error;
-               tp->type = TR_PARAM_SUBST;
-               tp->v.data = (void*)se;
                t->params = tp;
 
                while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
@@ -181,6 +236,5 @@ error:
 done:
        t->name = name;
        return p;
-
 }
 


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to