File Coverage

src/moment_parse.c
Criterion Covered Total %
statement 50 55 90.9
branch 32 42 76.1
condition n/a
subroutine n/a
pod n/a
total 82 97 84.5


line stmt bran cond sub pod time code
1             #include "moment.h"
2             #include "dt_core.h"
3             #include "dt_parse_iso.h"
4              
5             static int
6 66           parse_string_lenient(const char *str, size_t len, int64_t *sp, IV *np, IV *op) {
7             size_t n;
8             dt_t dt;
9             char c;
10             int sod, nanosecond, offset;
11              
12 66           n = dt_parse_iso_date(str, len, &dt);
13 66 50         if (!n || n == len)
    50          
14 0           return 1;
15              
16 66           c = str[n++];
17 66 100         if (!(c == 'T' || c == 't' || c == ' '))
    100          
    50          
18 0           return 1;
19              
20 66           str += n;
21 66           len -= n;
22              
23 66           n = dt_parse_iso_time(str, len, &sod, &nanosecond);
24 66 50         if (!n || n == len)
    50          
25 0           return 1;
26              
27 66 100         if (str[n] == ' ')
28 27           n++;
29              
30 66           str += n;
31 66           len -= n;
32              
33 66           n = dt_parse_iso_zone_lenient(str, len, &offset);
34 66 50         if (!n || n != len)
    50          
35 0           return 1;
36              
37 66           *sp = ((int64_t)dt_rdn(dt) - 719163) * 86400 + sod - offset * 60;
38 66           *np = nanosecond;
39 66           *op = offset;
40 66           return 0;
41             }
42              
43             static int
44 200           parse_string_strict(const char *str, size_t len, int64_t *sp, IV *np, IV *op) {
45             size_t n;
46             dt_t dt;
47             int sod, nanosecond, offset;
48             bool extended;
49              
50 200           n = dt_parse_iso_date(str, len, &dt);
51 200 50         if (!n || n == len)
    50          
52 0           return 1;
53              
54             /*
55             * 0123456789
56             * 2012-12-14
57             */
58 200           extended = str[4] == '-';
59 200 100         if (str[n++] != 'T')
60 62           return 1;
61              
62 138           str += n;
63 138           len -= n;
64              
65 138 100         if (extended)
66 123           n = dt_parse_iso_time_extended(str, len, &sod, &nanosecond);
67             else
68 15           n = dt_parse_iso_time_basic(str, len, &sod, &nanosecond);
69              
70 138 100         if (!n || n == len)
    50          
71 1           return 1;
72              
73 137           str += n;
74 137           len -= n;
75              
76 137 100         if (extended)
77 122           n = dt_parse_iso_zone_extended(str, len, &offset);
78             else
79 15           n = dt_parse_iso_zone_basic(str, len, &offset);
80              
81 137 100         if (!n || n != len)
    100          
82 3           return 1;
83              
84 134           *sp = ((int64_t)dt_rdn(dt) - 719163) * 86400 + sod - offset * 60;
85 134           *np = nanosecond;
86 134           *op = offset;
87 200           return 0;
88             }
89              
90             moment_t
91 266           THX_moment_from_string(pTHX_ const char *str, STRLEN len, bool lenient) {
92             int ret;
93             int64_t seconds;
94             IV nanosecond, offset;
95              
96 266 100         if (lenient)
97 66           ret = parse_string_lenient(str, len, &seconds, &nanosecond, &offset);
98             else
99 200           ret = parse_string_strict(str, len, &seconds, &nanosecond, &offset);
100              
101 266 100         if (ret != 0)
102 66           croak("Could not parse the given string");
103              
104 200           return moment_from_epoch(seconds, nanosecond, offset);
105             }
106