예제 #1
0
파일: dp_repl.c 프로젝트: Danfx/opensips
struct subst_expr* repl_exp_parse(str subst)
{
	struct replace_with rw[MAX_REPLACE_WITH];
	int rw_no;
	struct subst_expr * se;
	int replace_all;
	char * p, *end, *repl, *repl_end;
	int max_pmatch, r;

	se = 0;
	replace_all = 0;
	p = subst.s;
	end = p + subst.len;
	rw_no = 0;

	repl = p;
	if((rw_no = parse_repl(rw, &p, end, &max_pmatch, WITHOUT_SEP))< 0)
		goto error;

	repl_end=p;

	/* construct the subst_expr structure */
	se = shm_malloc(sizeof(struct subst_expr)+
					((rw_no)?(rw_no-1)*sizeof(struct replace_with):0));
		/* 1 replace_with structure is  already included in subst_expr */
	if (se==0){
		LM_ERR("out of shm memory (subst_expr)\n");
		goto error;
	}
	memset((void*)se, 0, sizeof(struct subst_expr));

	se->replacement.len=repl_end-repl;
	if (!(se->replacement.s=shm_malloc(se->replacement.len * sizeof(char))) ){
		LM_ERR("out of shm memory \n");
		goto error;
	}
	if(!rw_no){
		replace_all = 1;
	}
	/* start copying */
	memcpy(se->replacement.s, repl, se->replacement.len);
	se->re=0;
	se->replace_all=replace_all;
	se->n_escapes=rw_no;
	se->max_pmatch=max_pmatch;

	/*replace_with is a simple structure, no shm alloc needed*/
	for (r=0; r<rw_no; r++) se->replace[r]=rw[r];
	return se;

error:
	if (se) { repl_expr_free(se);}
	return NULL;
}
예제 #2
0
파일: re.c 프로젝트: KISSMonX/opensips
/*! \brief Parse a /regular expression/replacement/flags into a subst_expr structure 
 */
struct subst_expr* subst_parser(str* subst)
{
	char c;
	char* end;
	char* p;
	char* re;
	char* re_end;
	char* repl;
	char* repl_end;
	struct replace_with rw[MAX_REPLACE_WITH];
	int rw_no;
	//int escape;
	int cflags; /* regcomp flags */
	int replace_all;
	struct subst_expr* se;
	regex_t* regex;
	int max_pmatch;
	int r;
	
	/* init */
	se=0;
	regex=0;
	cflags=REG_EXTENDED  | REG_NEWLINE; /* don't match newline */
	replace_all=0;
	if (subst->len<3){
		LM_ERR("expression is too short: %.*s\n", subst->len, subst->s);
		goto error;
	}
	
	p=subst->s;
	end=subst->s+subst->len;

	c=*p;
	if (c=='\\'){
		LM_ERR("invalid separator char <%c> in %.*s\n", c, 
				subst->len, subst->s);
		goto error;
	}
	p++;
	
	/* find re */
	re=p;
	for (;p<end;p++){
		/* if unescaped sep. char */
		if ((*p==c) && (*(p-1)!='\\')) goto found_re;
	}
	LM_ERR("no separator found: %.*s\n", subst->len, subst->s);
	goto error;
found_re:
	re_end=p;
	if(end< (p+2) ){
		LM_ERR("string too short\n");
		goto error;
	}
	repl=p+1;
	if((rw_no = parse_repl(rw, &p, end, &max_pmatch, WITH_SEP))< 0)
		goto error;
	

	repl_end=p;
	p++;
	/* parse flags */
	for(;p<end; p++){
		switch(*p){
			case 'i':
				cflags|=REG_ICASE;
				break;
			case 's':
				cflags&=(~REG_NEWLINE);
				break;
			case 'g':
				replace_all=1;
				break;
			default:
				LM_ERR("unknown flag %c in %.*s\n",	*p, subst->len, subst->s);
				goto error;
		}
	}

	/* compile the re */
	if ((regex=pkg_malloc(sizeof(regex_t)))==0){
		LM_ERR("out of pkg memory (re)\n");
		goto error;
	}
	c=*re_end; /* regcomp expects null terminated strings -- save */
	*re_end=0;
	if (regcomp(regex, re, cflags)!=0){
		pkg_free(regex);
		*re_end=c; /* restore */
		LM_ERR("bad regular expression %.*s in %.*s\n", 
				(int)(re_end-re), re, subst->len, subst->s);
		goto error;
	}
	*re_end=c; /* restore */
	/* construct the subst_expr structure */
	se=pkg_malloc(sizeof(struct subst_expr)+
					((rw_no)?(rw_no-1)*sizeof(struct replace_with):0));
		/* 1 replace_with structure is  already included in subst_expr */
	if (se==0){
		LM_ERR("out of pkg memory (subst_expr)\n");
		goto error;
	}
	memset((void*)se, 0, sizeof(struct subst_expr));

	se->replacement.len=repl_end-repl;
	if ((se->replacement.s=pkg_malloc(se->replacement.len))==0){
		LM_ERR("out of pkg memory (replacement)\n");
		goto error;
	}

	/* start copying */
	memcpy(se->replacement.s, repl, se->replacement.len);
	se->re=regex;
	se->replace_all=replace_all;
	se->n_escapes=rw_no;
	se->max_pmatch=max_pmatch;
	for (r=0; r<rw_no; r++) se->replace[r]=rw[r];
	LM_DBG("ok, se is %p\n", se);
	return se;
	
error:
	if (se) { subst_expr_free(se); regex=0; }
	if (regex) { regfree (regex); pkg_free(regex); }
	return 0;
}