[SR-Dev] git:master: Kamailio compatibility: parse_repl

Jan Janak jan at iptel.org
Sun Mar 8 04:43:57 CET 2009


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

Author: Jan Janak <jan at iptel.org>
Committer: Jan Janak <jan at iptel.org>
Date:   Sun Mar  8 04:16:08 2009 +0100

Kamailio compatibility: parse_repl

 * Move the replace parser into a separate function called parse_repl
 * Declare the function in the header file
 * Add support for PV_MARKER (pseudo-variable marker $) to the parser

---

 re.c |  133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 re.h |    2 +
 2 files changed, 134 insertions(+), 1 deletions(-)

diff --git a/re.c b/re.c
index 3380a45..ecb8312 100644
--- a/re.c
+++ b/re.c
@@ -64,12 +64,143 @@ void replace_lst_free(struct replace_lst* l)
 	}
 }
 
+int parse_repl(struct replace_with * rw, char ** begin, 
+				char * end, int *max_token_nb, int with_sep)
+{
+
+	char* p0;
+	char * repl;
+	str s;
+	int token_nb;
+	int escape;
+	int max_pmatch;
+	char *p, c;
+
+	/* parse replacement */
+	p = *begin;
+	c = *p;
+	if(with_sep)
+		p++;
+	repl= p;
+	token_nb=0;
+	max_pmatch=0;
+	escape=0;
+	for(;p<end; p++){
+		if (escape){
+			escape=0;
+			switch (*p){
+				/* special char escapes */
+				case '\\':
+					rw[token_nb].size=2;
+					rw[token_nb].offset=(p-1)-repl;
+					rw[token_nb].type=REPLACE_CHAR;
+					rw[token_nb].u.c='\\';
+					break;
+				case 'n':
+					rw[token_nb].size=2;
+					rw[token_nb].offset=(p-1)-repl;
+					rw[token_nb].type=REPLACE_CHAR;
+					rw[token_nb].u.c='\n';
+					break;
+				case 'r':
+					rw[token_nb].size=2;
+					rw[token_nb].offset=(p-1)-repl;
+					rw[token_nb].type=REPLACE_CHAR;
+					rw[token_nb].u.c='\r';
+					break;
+				case 't':
+					rw[token_nb].size=2;
+					rw[token_nb].offset=(p-1)-repl;
+					rw[token_nb].type=REPLACE_CHAR;
+					rw[token_nb].u.c='\t';
+					break;
+				case PV_MARKER:
+					rw[token_nb].size=2;
+					rw[token_nb].offset=(p-1)-repl;
+					rw[token_nb].type=REPLACE_CHAR;
+					rw[token_nb].u.c=PV_MARKER;
+					break;
+				/* special sip msg parts escapes */
+				case 'u':
+					rw[token_nb].size=2;
+					rw[token_nb].offset=(p-1)-repl;
+					rw[token_nb].type=REPLACE_URI;
+					break;
+				/* re matches */
+				case '0': /* allow 0, too, reference to the whole match */
+				case '1':
+				case '2':
+				case '3':
+				case '4':
+				case '5':
+				case '6':
+				case '7':
+				case '8':
+				case '9':
+					rw[token_nb].size=2;
+					rw[token_nb].offset=(p-1)-repl;
+					rw[token_nb].type=REPLACE_NMATCH;
+					rw[token_nb].u.nmatch=(*p)-'0';
+								/* 0 is the whole matched str*/
+					if (max_pmatch<rw[token_nb].u.nmatch) 
+						max_pmatch=rw[token_nb].u.nmatch;
+					break;
+				default: /* just print current char */
+					if (*p!=c){
+						WARN("subst_parser:\\%c unknown escape in %s\n", *p, *begin);
+					}
+					rw[token_nb].size=2;
+					rw[token_nb].offset=(p-1)-repl;
+					rw[token_nb].type=REPLACE_CHAR;
+					rw[token_nb].u.c=*p;
+					break;
+			}
+
+			token_nb++;
+
+			if (token_nb>=MAX_REPLACE_WITH){
+				ERR("subst_parser: too many escapes in the replace part %s\n", *begin);
+				goto error;
+			}
+		}else if (*p=='\\') {
+			escape=1;
+		}else if (*p==PV_MARKER) {
+			s.s = p;
+			s.len = end - s.s;
+			p0 = pv_parse_spec(&s, &rw[token_nb].u.spec);
+			if(p0==NULL)
+			{
+				ERR("subst_parser: bad specifier in replace part %s\n", *begin);
+				goto error;
+			}
+			rw[token_nb].size=p0-p;
+			rw[token_nb].offset=p-repl;
+			rw[token_nb].type=REPLACE_SPEC;
+			token_nb++;
+			p=p0-1;
+		}else  if (*p==c && with_sep){
+				goto found_repl;
+		}
+	}
+	if(with_sep){
+		ERR("subst_parser: missing separator: %s\n", *begin);
+		goto error;
+	}
+
+found_repl:
+
+	*max_token_nb = max_pmatch;
+	*begin = p;
+	return token_nb;
+
+error:
+	return -1;
+}
 
 
 /* parse a /regular expression/replacement/flags into a subst_expr structure */
 struct subst_expr* subst_parser(str* subst)
 {
-#define MAX_REPLACE_WITH 100
 	char c;
 	char* end;
 	char* p;
diff --git a/re.h b/re.h
index 06022f2..b31a62d 100644
--- a/re.h
+++ b/re.h
@@ -79,6 +79,8 @@ struct replace_lst{
 
 void subst_expr_free(struct subst_expr* se);
 void replace_lst_free(struct replace_lst* l);
+int parse_repl(struct replace_with * rw, char ** begin, 
+				char * end, int *max_token_nb, int flag);
 struct subst_expr*  subst_parser(str* subst);
 struct replace_lst* subst_run( struct subst_expr* se, const char* input, 
 		                       struct sip_msg* msg, int *count);




More information about the sr-dev mailing list