1#pragma once
2
3#include <pw.h>
4#include <pwlib/ctype.h>
5
6#ifdef __cplusplus
7extern "C" {
8#endif
9
10[[nodiscard]] static inline bool pw_parse_hexdigit(char32_t* chr)
11{
12 uint8_t ctype_bits = _pw_chartype_bits(*chr);
13 if ((ctype_bits & (PW_CTYPE_XDIGIT | PW_CTYPE_LOWER)) == (PW_CTYPE_XDIGIT | PW_CTYPE_LOWER)) {
14 *chr -= 'a' - 10;
15 return true;
16 }
17 if ((ctype_bits & (PW_CTYPE_XDIGIT | PW_CTYPE_UPPER)) == (PW_CTYPE_XDIGIT | PW_CTYPE_UPPER)) {
18 *chr -= 'A' - 10;
19 return true;
20 }
21 if (ctype_bits & PW_CTYPE_DIGIT) {
22 *chr -= '0';
23 return true;
24 }
25 return false;
26}
27
28[[nodiscard]] bool _pw_parse_unsigned(PwValuePtr str, unsigned start_pos, unsigned* end_pos,
29 unsigned radix, bool allow_overflow, PwValuePtr result);
30/*
31 * Parse `str` from `start_pos` as unsigned integer value.
32 *
33 * Return value and if `end_pos` is not null, write where conversion has stopped.
34 */
35
36[[nodiscard]] bool _pw_parse_num_str(PwValuePtr str, unsigned start_pos,
37 int sign, unsigned* end_pos, char32_t* allowed_terminators,
38 bool allow_overflow, PwValuePtr result);
39/*
40 * `start_pos` points to the sign or first digit;
41 * `end_pos` (optional) receives position where conversion is stopped, regardless of result;
42 * `allow_overflow`: do not check numeric overflow;
43 * `allowed_terminators` (optional) contains characters at which conversion may stop without returning error.
44 *
45 * Normally conversion stops at space character or at end of line. If wrong character is encountered,
46 * and it is not among allowed terminators, this function returns error.
47 *
48 * Return Signed if parsed number fits into its range.
49 * Return Unsigned if parsed number is beyond positive range of Signed value.
50 * Return Float if string contains float number.
51 * Return status on error.
52 */
53
54[[nodiscard]] bool _pw_parse_number(PwValuePtr str, PwValuePtr result, bool allow_overflow);
55[[nodiscard]] static inline bool pw_parse_number(PwValuePtr str, PwValuePtr result)
56{
57 return _pw_parse_number(str, result, false);
58}
59[[nodiscard]] static inline bool pw_parse_number_with_overflow(PwValuePtr str, PwValuePtr result)
60{
61 return _pw_parse_number(str, result, true);
62}
63/*
64 * Convert string to number.
65 * Simplified wrapper for _pw_parse_number.
66 */
67
68[[nodiscard]] bool _pw_parse_datetime(PwValuePtr str, unsigned start_pos, unsigned* end_pos,
69 char32_t* allowed_terminators, PwValuePtr result);
70/*
71 * Parse `str` as date/time in mutual formats of ISO-8601 and RFC 3339
72 * (see https://ijmacd.github.io/rfc3339-iso8601/).
73 *
74 * In addition, T or space separator between date and time and dashes in the date part are optional.
75 */
76
77[[nodiscard]] bool pw_parse_datetime(PwValuePtr str, PwValuePtr result);
78/*
79 * Convert string to date/time.
80 * Simplified wrapper for _pw_parse_datetime.
81 */
82
83[[nodiscard]] bool _pw_parse_timestamp(PwValuePtr str, unsigned start_pos, unsigned* end_pos,
84 char32_t* allowed_terminators, PwValuePtr result);
85/*
86 * Parse `str` as timestamp in the form seconds\[.frac\], up to nanosecond resolution.
87 */
88
89[[nodiscard]] bool pw_parse_timestamp(PwValuePtr str, PwValuePtr result);
90/*
91 * Convert string to timestamp.
92 * Simplified wrapper for _pw_parse_timestamp.
93 */
94
95#ifdef __cplusplus
96}
97#endif