File Coverage

tstr_parse.c
Criterion Covered Total %
statement 36 40 90.0
branch 37 42 88.1
condition n/a
subroutine n/a
pod n/a
total 73 82 89.0


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5              
6             #include "tstr_parsed.h"
7             #include "tstr_format.h"
8             #include "tstr_calendar.h"
9             #include "tstr_sv.h"
10             #include "tstr_regexp.h"
11             #include "tstr_cparse.h"
12             #include "tstr_parse_result.h"
13             #include "tstr_carp.h"
14             #include "tstr_time.h"
15              
16             #define DEFAULT_PIVOT_YEAR 1950
17              
18 1031           static tstr_parse_result_t validate_parsed(const tstr_parsed_t *p) {
19 1031 100         int m = (p->flags & TSTR_PARSED_HAS_MONTH) ? p->month : 1;
20 1031 100         int d = (p->flags & TSTR_PARSED_HAS_DAY) ? p->day : 1;
21              
22 1031 100         if (!tstr_calendar_valid_ymd(p->year, m, d))
23 2           return TSTR_PARSE_ERR_DATE_RANGE;
24              
25 1029 100         if ((p->flags & TSTR_PARSED_HAS_DAY_NAME) &&
26 168 50         tstr_calendar_ymd_to_dow(p->year, p->month, p->day) != p->day_name)
27 0           return TSTR_PARSE_ERR_DAY_NAME_MISMATCH;
28              
29 1029 100         if (p->flags & TSTR_PARSED_HAS_MERIDIEM) {
30 22 50         if (p->hour < 1 || p->hour > 12)
    50          
31 0           return TSTR_PARSE_ERR_HOUR_RANGE;
32             }
33              
34 1029 100         if (p->flags & TSTR_PARSED_HAS_TIME) {
35 898           int h = p->hour;
36 898 100         if (p->flags & TSTR_PARSED_HAS_MERIDIEM)
37 22           h = p->hour % 12 + p->meridiem;
38 898 100         if (!tstr_time_valid_hms60(h, p->minute, p->second))
39 6           return TSTR_PARSE_ERR_TIME_RANGE;
40             }
41              
42 1023           return TSTR_PARSE_OK;
43             }
44              
45 1038           void tstr_parse(pTHX_ SV *input, tstr_format_t fmt, int pivot_year,
46             REGEXP **regexps, tstr_sv_keys_t *keys, tstr_parsed_t *p) {
47             char *s;
48             STRLEN slen;
49             tstr_parse_result_t rc;
50              
51 1038           s = SvPV(input, slen);
52              
53 1038           rc = tstr_cparse_dispatch(s, slen, fmt, p);
54              
55 1038 100         if (rc == TSTR_PARSE_NOMATCH)
56 2           tstr_croakf("Unable to parse: string does not match the %s format",
57             tstr_format_name(fmt));
58              
59 1036 100         if (rc == TSTR_PARSE_NOPARSER) {
60 418           REGEXP *rx = regexps[fmt];
61              
62 418 50         if (!rx)
63 0           croak("panic: no regexp for format '%s'", tstr_format_name(fmt));
64              
65 418 50         if (!pregexec(rx, s, s + slen, s, 0, input, 1))
66 0           tstr_croakf("Unable to parse: string does not match the %s format",
67             tstr_format_name(fmt));
68              
69 418           rc = tstr_regexp_extract(aTHX_ rx, p, keys);
70             }
71              
72 1036 100         if (rc != TSTR_PARSE_OK)
73 5           tstr_croakf("Unable to parse: %s", tstr_parse_error_message(rc));
74              
75 1031 100         if (p->flags & TSTR_PARSED_HAS_YEAR2)
76 41 100         p->year = tstr_calendar_resolve_century(
77             p->year, pivot_year >= 0 ? pivot_year : DEFAULT_PIVOT_YEAR);
78              
79 1031 100         if (fmt == TSTR_FORMAT_RFC2616 && !(p->flags & TSTR_PARSED_HAS_TZ_UTC))
    100          
80 2           tstr_parsed_set_tz_utc(p, "GMT", 3);
81              
82 1031           rc = validate_parsed(p);
83 1031 100         if (rc != TSTR_PARSE_OK)
84 8           tstr_croakf("Unable to parse: %s", tstr_parse_error_message(rc));
85 1023           }