Branch data Line data Source code
1 : : // Copyright 2019-2026 David Robillard <d@drobilla.net> 2 : : // SPDX-License-Identifier: ISC 3 : : 4 : : #include "date_utils.h" 5 : : #include "number_utils.h" 6 : : #include "result.h" 7 : : #include "year.h" 8 : : 9 : : #include <exess/exess.h> 10 : : 11 : : #include <stddef.h> 12 : : 13 : : EXESS_NONBLOCKING ExessResult 14 : 453 : read_date_m(uint8_t* const m_out, const char* const str) 15 : : { 16 : : // Skip year-month delimiter 17 [ + + ]: 453 : if (str[0] != '-') { 18 : 4 : return RESULT(EXESS_EXPECTED_DASH, 0); 19 : : } 20 : : 21 : : // Read month 22 : 449 : const ExessResult r = read_two_digit_number(m_out, 1, 12, str + 1U); 23 : 449 : return RESULT(r.status, 1U + r.count); 24 : : } 25 : : 26 : : EXESS_NONBLOCKING ExessResult 27 : 402 : read_date_ym(int16_t* const y_out, uint8_t* const m_out, const char* const str) 28 : : { 29 : : // Read leading year 30 : 402 : ExessResult r = read_year_number(y_out, str); 31 [ + + ]: 402 : if (r.status) { 32 : 21 : return r; 33 : : } 34 : : 35 : 381 : size_t i = r.count; 36 : 381 : r = read_date_m(m_out, str + i); 37 : 381 : r.count = i + r.count; 38 : 381 : return r; 39 : : } 40 : : 41 : : EXESS_NONBLOCKING ExessResult 42 : 407 : read_date_d(uint8_t* const d_out, const char* const str) 43 : : { 44 : : // Skip month-day delimiter 45 [ + + ]: 407 : if (str[0] != '-') { 46 : 2 : return RESULT(EXESS_EXPECTED_DASH, 0); 47 : : } 48 : : 49 : : // Read day 50 : 405 : ExessResult r = read_two_digit_number(d_out, 1, 31, str + 1U); 51 : 405 : r.count = 1U + r.count; 52 : 405 : return r; 53 : : } 54 : : 55 : : EXESS_NONBLOCKING ExessResult 56 : 354 : read_date_numbers(ExessDate* const out, const char* const str) 57 : : { 58 : : // Read year and month 59 : 354 : ExessResult r = read_date_ym(&out->year, &out->month, str); 60 : : 61 [ + + ]: 354 : if (!r.status) { 62 : : // Read (month-day delimiter and) day 63 : 337 : size_t i = r.count; 64 : 337 : r = read_date_d(&out->day, str + i); 65 : 337 : r.count = i + r.count; 66 : : } 67 : : 68 : : // Check that day is in range 69 [ + + + + ]: 354 : if (!r.status && out->day > days_in_month(out->year, out->month)) { 70 : 5 : r.status = EXESS_OUT_OF_RANGE; 71 : : } 72 : : 73 : 354 : return r; 74 : : }