File Coverage

XS.xs
Criterion Covered Total %
statement 73 75 97.3
branch 101 194 52.0
condition n/a
subroutine n/a
pod n/a
total 174 269 64.6


line stmt bran cond sub pod time code
1             #include
2              
3             using namespace xs;
4             using namespace panda::time;
5              
6             using panda::string;
7             using panda::string_view;
8              
9             #ifdef _WIN32
10             #define LT_FORMAT "%a %b %d %H:%M:%S %Y"
11             #else
12             #define LT_FORMAT "%a %b %e %H:%M:%S %Y"
13             #endif
14              
15 103011           static inline Hash export_transition (const Timezone::Transition& trans, bool is_past) {
16 103011           auto hash = Hash::create();
17 103011 50         hash.store("offset", Simple(trans.offset));
    50          
18 103011 50         hash.store("abbrev", Simple(trans.abbrev));
    50          
19 103011 100         if (!is_past) {
20 101783 50         hash.store("start", Simple(trans.start));
    50          
21 101783 50         hash.store("isdst", Simple(trans.isdst));
    50          
22 101783 50         hash.store("gmt_offset", Simple(trans.gmt_offset));
    50          
23 101783 50         hash.store("leap_corr", Simple(trans.leap_corr));
    50          
24 101783 50         hash.store("leap_delta", Simple(trans.leap_delta));
    50          
25             }
26 103011           return hash;
27             }
28              
29             MODULE = Time::XS PACKAGE = Time::XS
30             PROTOTYPES: DISABLE
31              
32             TimezoneSP tzget (string_view zonename = string_view()) {
33 2512           RETVAL = tzget(zonename);
34 1256 50         }
35              
36             string tzname () {
37 15 50         RETVAL = tzlocal()->name;
    50          
38             }
39              
40             void tzset (SV* newzone = NULL) {
41 112 100         if (!newzone || !SvOK(newzone)) panda::time::tzset(string_view());
    50          
    0          
    0          
    50          
42 109 100         else if (SvROK(newzone)) panda::time::tzset(xs::in(aTHX_ newzone));
    50          
    50          
43 108 50         else panda::time::tzset(xs::in(aTHX_ newzone));
    50          
44             }
45              
46             string tzdir (SV* newdirSV = NULL) {
47 29 100         if (newdirSV) {
48 52 50         string newdir = xs::in(aTHX_ newdirSV);
49 26 50         if (tzdir(newdir)) RETVAL = "1";
    50          
    50          
50 26 50         else XSRETURN_UNDEF;
51             } else
52 3 50         RETVAL = tzdir();
    50          
53             }
54              
55             string tzsysdir () {
56 26 50         RETVAL = tzsysdir();
    50          
57             }
58              
59             void gmtime (SV* epochSV = NULL) : ALIAS(localtime=1) {
60             ptime_t epoch;
61 23760 50         if (epochSV) epoch = xs::in(aTHX_ epochSV);
    50          
62 0           else epoch = (ptime_t) ::time(NULL);
63              
64             datetime date;
65 23760 100         bool success = (ix == 0) ? gmtime(epoch, &date) : localtime(epoch, &date);
    50          
    50          
66              
67 23760 50         if (GIMME_V == G_ARRAY) {
    0          
    100          
68 23749 100         if (!success) XSRETURN_EMPTY;
69 23747 50         EXTEND(SP, 9);
    0          
70 23747 50         EXTEND_MORTAL(9);
    0          
71 23747 50         mPUSHu(date.sec);
    50          
72 23747 50         mPUSHu(date.min);
    50          
73 23747 50         mPUSHu(date.hour);
    50          
74 23747 50         mPUSHu(date.mday);
    50          
75 23747 50         mPUSHu(date.mon);
    50          
76 23747 50         mPUSHi(date.year);
    50          
77 23747 50         mPUSHu(date.wday);
    50          
78 23747 50         mPUSHu(date.yday);
    50          
79 23747 50         mPUSHu(date.isdst);
    50          
80 23747           XSRETURN(9);
81             } else {
82 11 50         EXTEND(SP, 1);
    0          
83 11 100         if (!success) XSRETURN_UNDEF;
84 9 50         SV* ret = newSV(1000);
85 9           SvPOK_on(ret);
86 9           char* str = SvPVX(ret);
87 9 50         size_t strlen = strftime(str, 1000, LT_FORMAT, &date);
88 9           SvCUR_set(ret, strlen);
89 9 50         mPUSHs(ret);
90 23760           XSRETURN(1);
91             }
92             }
93              
94             ptime_t timegm (SV* sec, SV* min, SV* hour, SV* mday, SV* mon, SV* year, SV* isdst = NULL) : ALIAS(timelocal=1, timegmn=2, timelocaln=3) {
95             datetime date;
96 23827 50         date.sec = xs::in(aTHX_ sec);
97 23827 50         date.min = xs::in(aTHX_ min);
98 23827 50         date.hour = xs::in(aTHX_ hour);
99 23827 50         date.mday = xs::in(aTHX_ mday);
100 23827 50         date.mon = xs::in(aTHX_ mon);
101 23827 50         date.year = xs::in(aTHX_ year);
102              
103 23827 100         if (isdst) date.isdst = SvIV(isdst);
    50          
    0          
104 34           else date.isdst = -1;
105              
106 23827           switch (ix) {
107             case 0:
108 4723 50         RETVAL = timegml(&date);
109 4723           break;
110             case 1:
111 19069 50         RETVAL = timelocall(&date);
112 19069           break;
113             case 2:
114 5 50         RETVAL = timegm(&date);
115 5           break;
116             case 3:
117 30 50         RETVAL = timelocal(&date);
118 30           break;
119 0           default: croak("not reached");
120             }
121              
122 23827 100         if (ix & 2) {
123 35 50         sv_setiv(sec, date.sec);
124 34 50         sv_setiv(min, date.min);
125 34 50         sv_setiv(hour, date.hour);
126 34 50         sv_setiv(mday, date.mday);
127 34 50         sv_setiv(mon, date.mon);
128 34 50         sv_setiv(year, date.year);
129 34 100         if (isdst) sv_setiv(isdst, date.isdst);
    50          
130             }
131             }
132              
133             INCLUDE: Timezone.xsi