| 2639 | #define is_in_str(p, in) (p<in->s+in->len && *p) |
| 2640 | |
| 2641 | char* parse_transformation(str *in, trans_t **tr) |
| 2642 | { |
| 2643 | char *p; |
| 2644 | str tclass; |
| 2645 | trans_t *t = NULL; |
| 2646 | trans_t *t0 = NULL; |
| 2647 | str s; |
| 2648 | const trans_export_t *tr_export; |
| 2649 | trans_extra_t *tr_extra; |
| 2650 | int i, nesting_level = 0; |
| 2651 | |
| 2652 | if(in==NULL || in->s==NULL || tr==NULL) |
| 2653 | return NULL; |
| 2654 | |
| 2655 | p = in->s; |
| 2656 | do { |
| 2657 | while(is_in_str(p, in) && is_ws(*p)) p++; |
| 2658 | if(*p != TR_LBRACKET) |
| 2659 | break; |
| 2660 | p++; |
| 2661 | |
| 2662 | t = (trans_t*)pkg_malloc(sizeof(trans_t)); |
| 2663 | if(t == NULL) |
| 2664 | { |
| 2665 | LM_ERR("no more private memory\n"); |
| 2666 | return NULL; |
| 2667 | } |
| 2668 | memset(t, 0, sizeof(trans_t)); |
| 2669 | if(t0==NULL) |
| 2670 | *tr = t; |
| 2671 | else |
| 2672 | t0->next = t; |
| 2673 | t0 = t; |
| 2674 | |
| 2675 | /* find transformation class */ |
| 2676 | tclass.s = p; |
| 2677 | while(is_in_str(p, in) && *p!=TR_CLASS_MARKER) p++; |
| 2678 | if(*p!=TR_CLASS_MARKER || tclass.s == p) |
| 2679 | { |
| 2680 | LM_ERR("invalid transformation: %.*s (%c)!\n", in->len, in->s, *p); |
| 2681 | goto error; |
| 2682 | } |
| 2683 | tclass.len = p - tclass.s; |
| 2684 | p++; |
| 2685 | |
| 2686 | tr_export = NULL; |
| 2687 | |
| 2688 | /* search through core transformations */ |
| 2689 | for (i = 0; core_trans[i].name.s; i++) |
| 2690 | if (core_trans[i].name.len == tclass.len && |
| 2691 | !strncasecmp(core_trans[i].name.s, tclass.s, tclass.len)) { |
| 2692 | tr_export = &core_trans[i]; |
| 2693 | break; |
| 2694 | } |
| 2695 | |
| 2696 | if (!tr_export) |
| 2697 | /* search through module exported transformations */ |
| 2698 | for (tr_extra = tr_extra_list; tr_extra; tr_extra = tr_extra->next) |
no test coverage detected