As suggested in previous PR (#2936). This is much more flexible as it can also handle sub XAVPs, and indexes.
This ended up being more complicated than I anticipated, but I wanted to handle all possible cases. The tests I performed are detailled after, they should cover every possible use case.
#### Type Of Change - [x] New feature (non-breaking change which adds new functionality)
#### Checklist: - [x] Tested changes locally
#### Description
Allows counting XAVPs with `$cnt($xavp(...))` In addition to the `$cnt($avp(...))` - which is not modified.
/* Usage: * * $cnt($xavp(key[*])) : number of XAVPs "key". * $cnt($xavp(key[n]=>sub[*])) : number of children "sub" in XAVP "key[n]". * $cnt($xavp(key[*]=>sub[*])) : total number of children "sub" in all XAVPs "key". * * $cnt($xavp(key[n])) : 1 or 0 (if this index exists or not). * $cnt($xavp(key[-n])) : same but with reverse indexing (-1 is the last index). * * $cnt($xavp(key[*]=>sub[n])) : number of children "sub[n]" that exist in all XAPVs "key". * * $cnt($xavp(key)) is the same as $cnt($xavp(key[*])). * $cnt($xavp(key=>sub)) is the same as $cnt($xavp(key[*]=>sub[*])). * * Note: Usually for a XAVP no index means "index 0", not all. * But this would be less intuitive in our case for counting. */
#### Tests
I tried to be exhaustive. All the test cases below do work as expected.
``` $xavp(case1) = "case1.value1"; $xavp(case1) = "case1.value2"; $xavp(case1) = "case1.value3";
$xavp(case2=>sub1) = "case2.value1 sub1.value1"; $xavp(case2[0]=>sub1) = "case2.value1 sub1.value2"; $xavp(case2[0]=>sub1) = "case2.value1 sub1.value3"; $xavp(case2[0]=>sub2) = "case2.value1 sub2.value1"; $xavp(case2[0]=>sub2) = "case2.value1 sub2.value2"; # => will become case2[1] after adding the next entry
$xavp(case2=>sub1) = "case2.value2 sub1.value1"; $xavp(case2[0]=>sub1) = "case2.value2 sub1.value2";
xlog("L_INFO", "----------- TESTS $$cnt($$xavp...) - root XAVPs with no sub XAVPs\n");
xlog("L_INFO", "xavp(case1[0]) : value = $xavp(case1[0]) : cnt (expect: 1) = $cnt($xavp(case1[0]))\n"); xlog("L_INFO", "xavp(case1[1]) : value = $xavp(case1[1]) : cnt (expect: 1) = $cnt($xavp(case1[1]))\n"); xlog("L_INFO", "xavp(case1[-1]) : value = $xavp(case1[-1]) : cnt (expect: 1) = $cnt($xavp(case1[-1]))\n"); xlog("L_INFO", "xavp(case1[-2]) : value = $xavp(case1[-2]) : cnt (expect: 1) = $cnt($xavp(case1[-2]))\n"); xlog("L_INFO", "xavp(case1[-66]) : value = $xavp(case1[-66]) : cnt (expect: 0) = $cnt($xavp(case1[-66]))\n"); xlog("L_INFO", "xavp(case1[66]) : value = $xavp(case1[66]) : cnt (expect: 0) = $cnt($xavp(case1[66]))\n"); xlog("L_INFO", "xavp(case1[*]) : cnt (expect: 3) = $cnt($xavp(case1[*]))\n"); xlog("L_INFO", "xavp(case1) : cnt (expect: 3) = $cnt($xavp(case1))\n"); xlog("L_INFO", "xavp(case1=>sub) : cnt (expect: 0) = $cnt($xavp(case1=>sub))\n"); xlog("L_INFO", "xavp(case1[0]=>sub) : cnt (expect: 0) = $cnt($xavp(case1[0]=>sub))\n"); xlog("L_INFO", "xavp(case1[0]=>sub[0]) : value = $xavp(case1[0]=>sub[0]) : cnt (expect: 0) = $cnt($xavp(case1[0]=>sub[0]))\n");
xlog("L_INFO", "----------- TESTS $$cnt($$xavp...) - root XAVPs using single index\n");
xlog("L_INFO", "xavp(case2[1]=>sub1[0]) : value = $xavp(case2[1]=>sub1[0]) : cnt (expect: 1) = $cnt($xavp(case2[1]=>sub1[0]))\n"); xlog("L_INFO", "xavp(case2[1]=>sub1[-1]) : value = $xavp(case2[1]=>sub1[-1]) : cnt (expect: 1) = $cnt($xavp(case2[1]=>sub1[-1]))\n"); xlog("L_INFO", "xavp(case2[1]=>sub1[3]) : value = $xavp(case2[1]=>sub1[3]) : cnt (expect: 0) = $cnt($xavp(case2[1]=>sub1[3]))\n"); xlog("L_INFO", "xavp(case2[1]=>sub1[*]) : cnt (expect: 3) = $cnt($xavp(case2[1]=>sub1[*]))\n"); xlog("L_INFO", "xavp(case2[1]=>sub1) : cnt (expect: 3) = $cnt($xavp(case2[1]=>sub1))\n"); xlog("L_INFO", "xavp(case2[1]=>sub2[*]) : cnt (expect: 2) = $cnt($xavp(case2[1]=>sub2[*]))\n"); xlog("L_INFO", "xavp(case2[1]=>sub2) : cnt (expect: 2) = $cnt($xavp(case2[1]=>sub2))\n"); xlog("L_INFO", "xavp(case2[66]=>sub1) : cnt (expect: 0) = $cnt($xavp(case2[66]=>sub1))\n"); xlog("L_INFO", "xavp(case2[66]=>sub1[0]) : cnt (expect: 0) = $cnt($xavp(case2[66]=>sub1[0]))\n");
xlog("L_INFO", "----------- TESTS $$cnt($$xavp...) - root XAVPs using all index\n");
xlog("L_INFO", "xavp(case2=>sub1) : cnt (expect: 5) = $cnt($xavp(case2=>sub1))\n"); xlog("L_INFO", "xavp(case2=>sub1[*]) : cnt (expect: 5) = $cnt($xavp(case2=>sub1[*]))\n"); xlog("L_INFO", "xavp(case2[*]=>sub1) : cnt (expect: 5) = $cnt($xavp(case2[*]=>sub1))\n"); xlog("L_INFO", "xavp(case2[*]=>sub1[*]) : cnt (expect: 5) = $cnt($xavp(case2[*]=>sub1[*]))\n"); xlog("L_INFO", "xavp(case2[*]=>sub1) : cnt (expect: 5) = $cnt($xavp(case2[*]=>sub1))\n"); xlog("L_INFO", "xavp(case2[*]=>sub1[0]) : cnt (expect: 2) = $cnt($xavp(case2[*]=>sub1[0]))\n"); xlog("L_INFO", "xavp(case2[*]=>sub1[2]) : cnt (expect: 1) = $cnt($xavp(case2[*]=>sub1[2]))\n"); xlog("L_INFO", "xavp(case2[*]=>sub1[-1]) : cnt (expect: 2) = $cnt($xavp(case2[*]=>sub1[-1]))\n"); xlog("L_INFO", "xavp(case2[*]=>sub2) : cnt (expect: 2) = $cnt($xavp(case2[*]=>sub2))\n"); xlog("L_INFO", "xavp(case2[*]=>sub2[*]) : cnt (expect: 2) = $cnt($xavp(case2[*]=>sub2[*]))\n");
#xlog("L_INFO", "----------- TESTS $$cnt(...) - parsing errors\n"); # parsing error => server fails to start #xlog("L_INFO", "PARSE ERROR: $cnt($xavu(test))\n"); #xlog("L_INFO", "PARSE ERROR: $cnt($var(test))\n"); #xlog("L_INFO", "PARSE ERROR: $cnt($unknown(test))\n"); ```
You can view, comment on, or merge this pull request online at:
https://github.com/kamailio/kamailio/pull/2940
-- Commit Summary --
* pv: extend $cnt to work with $xavp
-- File Changes --
M src/modules/pv/pv_core.c (156)
-- Patch Links --
https://github.com/kamailio/kamailio/pull/2940.patch https://github.com/kamailio/kamailio/pull/2940.diff