! \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! */
| 507 | * \note WARNING: input must be 0 terminated! |
| 508 | */ |
| 509 | struct replace_lst* subst_run(struct subst_expr* se, const char* input, |
| 510 | struct sip_msg* msg, int* count) |
| 511 | { |
| 512 | struct replace_lst *head; |
| 513 | struct replace_lst **crt; |
| 514 | const char *p; |
| 515 | int r; |
| 516 | regmatch_t* pmatch; |
| 517 | int nmatch; |
| 518 | int eflags; |
| 519 | int cnt; |
| 520 | |
| 521 | |
| 522 | /* init */ |
| 523 | head=0; |
| 524 | cnt=0; |
| 525 | crt=&head; |
| 526 | p=input; |
| 527 | nmatch=se->max_pmatch+1; |
| 528 | /* no of () referenced + 1 for the whole string: pmatch[0] */ |
| 529 | pmatch=pkg_malloc(nmatch*sizeof(regmatch_t)); |
| 530 | if (pmatch==0){ |
| 531 | LM_ERR("out of pkg mem. (pmatch)\n"); |
| 532 | goto error; |
| 533 | } |
| 534 | eflags=0; |
| 535 | do{ |
| 536 | r=regexec(se->re, p, nmatch, pmatch, eflags); |
| 537 | LM_DBG("running. r=%d\n", r); |
| 538 | /* subst */ |
| 539 | if (r==0){ /* != REG_NOMATCH */ |
| 540 | /* some checks */ |
| 541 | if (pmatch[0].rm_so==-1){ |
| 542 | LM_ERR("unknown offset?\n"); |
| 543 | goto error; |
| 544 | } |
| 545 | if (pmatch[0].rm_so==pmatch[0].rm_eo){ |
| 546 | LM_ERR("matched string is empty... invalid regexp?\n"); |
| 547 | goto error; |
| 548 | } |
| 549 | *crt=pkg_malloc(sizeof(struct replace_lst)); |
| 550 | if (*crt==0){ |
| 551 | LM_ERR("out of pkg mem (crt)\n"); |
| 552 | goto error; |
| 553 | } |
| 554 | memset(*crt, 0, sizeof(struct replace_lst)); |
| 555 | (*crt)->offset=pmatch[0].rm_so+(int)(p-input); |
| 556 | (*crt)->size=pmatch[0].rm_eo-pmatch[0].rm_so; |
| 557 | LM_DBG("matched (%d, %d): [%.*s]\n", |
| 558 | (*crt)->offset, (*crt)->size, |
| 559 | (*crt)->size, input+(*crt)->offset); |
| 560 | /* create subst. string */ |
| 561 | /* construct the string from replace[] */ |
| 562 | if (replace_build(p, nmatch, pmatch, se, msg, &((*crt)->rpl))<0){ |
| 563 | goto error; |
| 564 | } |
| 565 | crt=&((*crt)->next); |
| 566 | p+=pmatch[0].rm_eo; |
no test coverage detected