File Coverage

src/sorting.c
Criterion Covered Total %
statement 26 33 78.7
branch 12 28 42.8
condition n/a
subroutine n/a
pod n/a
total 38 61 62.3


line stmt bran cond sub pod time code
1             typedef struct {
2             #ifdef USE_ITHREADS
3             PerlInterpreter *my_perl;
4             #endif
5             CV *callback; /* can be NULL */
6             SV *err;
7             } sort_ctx_t;
8              
9             static int
10 18           shvxs_sort_cmp(const void *a, const void *b, void *ctx)
11             {
12 18           sort_ctx_t *c = (sort_ctx_t *)ctx;
13             #ifdef USE_ITHREADS
14             dTHXa(c->my_perl);
15             #endif
16              
17 18 50         if (c->err) return 0;
18              
19 18           SV *sv_a = *(SV * const *)a;
20 18           SV *sv_b = *(SV * const *)b;
21              
22 18 100         if (!c->callback) {
23             /* default string comparison */
24 5           return sv_cmp(sv_a, sv_b);
25             }
26              
27 13           int result = 0;
28            
29 13           dSP;
30 13           ENTER;
31 13           SAVETMPS;
32              
33 13 50         PUSHMARK(SP);
34 13 50         EXTEND(SP, 2);
35 13 50         XPUSHs(sv_a);
36 13 50         XPUSHs(sv_b);
37 13           PUTBACK;
38              
39 13           I32 count = call_sv((SV *)c->callback, G_SCALAR | G_EVAL);
40 13           SPAGAIN;
41              
42 13 50         if (SvTRUE(ERRSV)) {
    50          
43 0 0         c->err = newSVsv(ERRSV);
44 0 0         sv_setsv(ERRSV, &PL_sv_undef);
45 0           PUTBACK;
46 0 0         FREETMPS;
47 0           LEAVE;
48 0           return 0;
49             }
50              
51 13 50         SV *ret = (count > 0) ? POPs : &PL_sv_undef;
52 13 50         if (!SvOK(ret)) {
53 0           result = 0;
54             }
55             else {
56 13           result = (int)SvIV(ret);
57             }
58              
59 13           PUTBACK;
60 13 50         FREETMPS;
61 13           LEAVE;
62              
63 13           return result;
64             }
65              
66             #if defined(_WIN32)
67              
68             static int __cdecl
69             shvxs_sort_cmp_win32(void *ctx, const void *a, const void *b) {
70             sort_ctx_t *c = (sort_ctx_t *)ctx;
71             return shvxs_sort_cmp(a, b, ctx);
72             }
73              
74             #define SHVXS_QSORT(base, n, size, ctx) qsort_s((base), (n), (size), shvxs_sort_cmp_win32, (ctx))
75              
76             #elif defined(__APPLE__) || defined(__FreeBSD__)
77              
78             static int
79             shvxs_sort_cmp_bsd(void *ctx, const void *a, const void *b) {
80             sort_ctx_t *c = (sort_ctx_t *)ctx;
81             return shvxs_sort_cmp(a, b, ctx);
82             }
83              
84             #define SHVXS_QSORT(base, n, size, ctx) qsort_r((base), (n), (size), (ctx), shvxs_sort_cmp_bsd)
85              
86             #else
87              
88             #define SHVXS_QSORT(base, n, size, ctx) qsort_r((base), (n), (size), shvxs_sort_cmp, (ctx))
89              
90             #endif