/* WARNING: input must be 0 terminated! */ struct replace_lst* subst_run(struct subst_expr* se, char* input, struct sip_msg* msg) { struct replace_lst *head; struct replace_lst **crt; char *p; int r; regmatch_t* pmatch; int nmatch; int eflags; /* init */ head=0; crt=&head; p=input; nmatch=se->max_pmatch+1; /* no of () referenced + 1 for the whole string: pmatch[0] */ pmatch=pkg_malloc(nmatch*sizeof(regmatch_t)); if (pmatch==0){ LOG(L_ERR, "ERROR: subst_run_ out of mem. (pmatch)\n"); goto error; } eflags=0; do{ r=regexec(se->re, p, nmatch, pmatch, eflags); DBG("subst_run: running. r=%d\n", r); /* subst */ if (r==0){ /* != REG_NOMATCH */ /* change eflags, not to match any more at string start */ eflags|=REG_NOTBOL; *crt=pkg_malloc(sizeof(struct replace_lst)); if (*crt==0){ LOG(L_ERR, "ERROR: subst_run: out of mem (crt)\n"); goto error; } memset(*crt, 0, sizeof(struct replace_lst)); if (pmatch[0].rm_so==-1){ LOG(L_ERR, "ERROR: subst_run: unknown offset?\n"); goto error; } (*crt)->offset=pmatch[0].rm_so+(int)(p-input); (*crt)->size=pmatch[0].rm_eo-pmatch[0].rm_so; DBG("subst_run: matched (%d, %d): [%.*s]\n", (*crt)->offset, (*crt)->size, (*crt)->size, input+(*crt)->offset); /* create subst. string */ /* construct the string from replace[] */ if (replace_build(p, nmatch, pmatch, se, msg, &((*crt)->rpl))<0){ goto error; } crt=&((*crt)->next); p+=pmatch[0].rm_eo; } }while((r==0) && se->replace_all); pkg_free(pmatch); return head; error: if (head) replace_lst_free(head); if (pmatch) pkg_free(pmatch); return 0; }
/*! \brief run substitutions * \return 0 if no match or error, or subst result; if count!=0 * it will be set to 0 (no match), the number of matches * or -1 (error). * \note WARNING: input must be 0 terminated! */ struct replace_lst* subst_run(struct subst_expr* se, const char* input, struct sip_msg* msg, int* count) { struct replace_lst *head; struct replace_lst **crt; const char *p; int r; regmatch_t* pmatch; int nmatch; int eflags; int cnt; /* init */ head=0; cnt=0; crt=&head; p=input; nmatch=se->max_pmatch+1; /* no of () referenced + 1 for the whole string: pmatch[0] */ pmatch=pkg_malloc(nmatch*sizeof(regmatch_t)); if (pmatch==0){ LM_ERR("out of pkg mem. (pmatch)\n"); goto error; } eflags=0; do{ r=regexec(se->re, p, nmatch, pmatch, eflags); LM_DBG("running. r=%d\n", r); /* subst */ if (r==0){ /* != REG_NOMATCH */ /* some checks */ if (pmatch[0].rm_so==-1){ LM_ERR("unknown offset?\n"); goto error; } if (pmatch[0].rm_so==pmatch[0].rm_eo){ LM_ERR("matched string is empty... invalid regexp?\n"); goto error; } *crt=pkg_malloc(sizeof(struct replace_lst)); if (*crt==0){ LM_ERR("out of pkg mem (crt)\n"); goto error; } memset(*crt, 0, sizeof(struct replace_lst)); (*crt)->offset=pmatch[0].rm_so+(int)(p-input); (*crt)->size=pmatch[0].rm_eo-pmatch[0].rm_so; LM_DBG("matched (%d, %d): [%.*s]\n", (*crt)->offset, (*crt)->size, (*crt)->size, input+(*crt)->offset); /* create subst. string */ /* construct the string from replace[] */ if (replace_build(p, nmatch, pmatch, se, msg, &((*crt)->rpl))<0){ goto error; } crt=&((*crt)->next); p+=pmatch[0].rm_eo; /* is it still a string start? */ if (*(p-1)=='\n' || *(p-1)=='\r') eflags&=~REG_NOTBOL; else eflags|=REG_NOTBOL; cnt++; } }while((r==0) && se->replace_all); pkg_free(pmatch); if (count)*count=cnt; return head; error: if (head) replace_lst_free(head); if (pmatch) pkg_free(pmatch); if (count) *count=-1; return 0; }