Branch Coverage

Base.xs
Criterion Covered Total %
branch 64 132 48.4


line true false branch
41 1 38 if (!global_root) {
50 12 0 if (!path || !*path) { *count = 0; return NULL; }
0 12 if (!path || !*path) { *count = 0; return NULL; }
52 0 12 if (!s) { *count = 0; return NULL; }
55 12 12 while ((p = strstr(p, "->"))) { n++; p += 2; }
57 0 12 if (!parts) { free(s); *count = 0; return NULL; }
61 12 12 while ((sep = strstr(cur, "->"))) {
73 0 12 if (!parts) return;
74 24 0 for (I32 i = 0; i < count; i++) if (parts[i]) free(parts[i]);
24 12 for (I32 i = 0; i < count; i++) if (parts[i]) free(parts[i]);
93 0 3 if (!path) croak("XS::Base::has: key required");
97 3 0 if (!parts || parts_n == 0) { free_parts(parts, parts_n); croak("invalid key"); }
0 3 if (!parts || parts_n == 0) { free_parts(parts, parts_n); croak("invalid key"); }
101 6 0 for (I32 i = 0; i < parts_n; i++) {
105 3 3 if (i == parts_n - 1) {
113 0 3 if (psv && *psv) {
0 0 if (psv && *psv) {
115 0 0 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV) {
0 0 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV) {
118 0 0 if (strict_mode) {
124 0 0 if (old) SvREFCNT_dec(old);
148 8 0 if (!path || !*path) return NULL;
0 8 if (!path || !*path) return NULL;
153 8 0 if (!parts || parts_n == 0) { free_parts(parts, parts_n); return NULL; }
0 8 if (!parts || parts_n == 0) { free_parts(parts, parts_n); return NULL; }
157 12 0 for (I32 i = 0; i < parts_n; i++) {
160 9 3 if (!svp || !*svp) { val = NULL; break; }
0 9 if (!svp || !*svp) { val = NULL; break; }
163 5 4 if (i == parts_n - 1) {
167 4 0 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV) {
4 0 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV) {
183 0 0 if (existing) return existing; /* 已是“拷贝” */
190 1 0 if (!path || !*path) croak("XS::Base::del: key required");
0 1 if (!path || !*path) croak("XS::Base::del: key required");
194 1 0 if (!parts || parts_n == 0) { free_parts(parts, parts_n); croak("invalid key"); }
0 1 if (!parts || parts_n == 0) { free_parts(parts, parts_n); croak("invalid key"); }
199 1 0 if (!parents || !pkeys) {
0 1 if (!parents || !pkeys) {
205 3 0 for (I32 i = 0; i < parts_n; i++) {
211 3 0 if (!svp || !*svp) { ok = 0; break; }
0 3 if (!svp || !*svp) { ok = 0; break; }
214 2 1 if (i < parts_n - 1) {
215 2 0 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV) {
2 0 if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVHV) {
222 0 1 if (removed) SvREFCNT_dec(removed);
224 3 0 for (I32 j = parts_n - 1; j >= 0; j--) {
225 2 1 if (hv_is_empty(parents[j]) && j > 0) {
2 0 if (hv_is_empty(parents[j]) && j > 0) {
227 0 2 if (rem) SvREFCNT_dec(rem);
234 3 0 for (I32 i = 0; i < parts_n; i++) if (pkeys[i]) free(pkeys[i]);
3 1 for (I32 i = 0; i < parts_n; i++) if (pkeys[i]) free(pkeys[i]);
255 0 0 if (!newroot || !SvROK(newroot) || SvTYPE(SvRV(newroot)) != SVt_PVHV) {
0 0 if (!newroot || !SvROK(newroot) || SvTYPE(SvRV(newroot)) != SVt_PVHV) {
0 0 if (!newroot || !SvROK(newroot) || SvTYPE(SvRV(newroot)) != SVt_PVHV) {
264 0 0 while ((he = hv_iternext(src)) != NULL) {
275 0 0 if (sv) SvREFCNT_dec(sv);
295 3 8 if (items != 1 && items != 2) croak("Usage: XS::Base::has(KEY) or XS::Base::has(KEY, VAL)");
0 3 if (items != 1 && items != 2) croak("Usage: XS::Base::has(KEY) or XS::Base::has(KEY, VAL)");
299 3 8 if (items == 2) {
305 3 0 if (ret) ST(0) = ret;
312 5 3 if (ret) ST(0) = ret;
329 0 1 RETVAL = r;
343 0 0 if (items != 2) croak("Usage: XS::Base::def(KEY, VAL)");
352 0 0 EXTEND(SP, 1);
353 0 0 if (ret) { PUSHs(sv_2mortal(ret)); } else { PUSHs(&PL_sv_undef); }
412 0 0 RETVAL = strict_mode;