| 14075 | TOML_NODISCARD |
| 14076 | TOML_NEVER_INLINE |
| 14077 | double parse_hex_float() |
| 14078 | { |
| 14079 | return_if_error({}); |
| 14080 | assert_not_eof(); |
| 14081 | TOML_ASSERT_ASSUME(is_match(*cp, U'0', U'+', U'-')); |
| 14082 | push_parse_scope("hexadecimal floating-point"sv); |
| 14083 | |
| 14084 | #if TOML_LANG_UNRELEASED // toml/issues/562 (hexfloats) |
| 14085 | |
| 14086 | // sign |
| 14087 | const int sign = *cp == U'-' ? -1 : 1; |
| 14088 | if (is_match(*cp, U'+', U'-')) |
| 14089 | advance_and_return_if_error_or_eof({}); |
| 14090 | |
| 14091 | // '0' |
| 14092 | if (*cp != U'0') |
| 14093 | set_error_and_return_default(" expected '0', saw '"sv, to_sv(*cp), "'"sv); |
| 14094 | advance_and_return_if_error_or_eof({}); |
| 14095 | |
| 14096 | // 'x' or 'X' |
| 14097 | if (!is_match(*cp, U'x', U'X')) |
| 14098 | set_error_and_return_default("expected 'x' or 'X', saw '"sv, to_sv(*cp), "'"sv); |
| 14099 | advance_and_return_if_error_or_eof({}); |
| 14100 | |
| 14101 | // <HEX DIGITS> ([.]<HEX DIGITS>)? [pP] [+-]? <DEC DIGITS> |
| 14102 | |
| 14103 | // consume value fragments |
| 14104 | struct fragment |
| 14105 | { |
| 14106 | char chars[24]; |
| 14107 | size_t length; |
| 14108 | double value; |
| 14109 | }; |
| 14110 | fragment fragments[] = { |
| 14111 | {}, // mantissa, whole part |
| 14112 | {}, // mantissa, fractional part |
| 14113 | {} // exponent |
| 14114 | }; |
| 14115 | fragment* current_fragment = fragments; |
| 14116 | const utf8_codepoint* prev = {}; |
| 14117 | int exponent_sign = 1; |
| 14118 | while (!is_eof() && !is_value_terminator(*cp)) |
| 14119 | { |
| 14120 | if (*cp == U'_') |
| 14121 | { |
| 14122 | if (!prev || !is_hexadecimal_digit(*prev)) |
| 14123 | set_error_and_return_default("underscores may only follow digits"sv); |
| 14124 | |
| 14125 | prev = cp; |
| 14126 | advance_and_return_if_error_or_eof({}); |
| 14127 | continue; |
| 14128 | } |
| 14129 | else if (prev && *prev == U'_' && !is_hexadecimal_digit(*cp)) |
| 14130 | set_error_and_return_default("underscores must be followed by digits"sv); |
| 14131 | else if (*cp == U'.') |
| 14132 | { |
| 14133 | // 0x10.0p-.0 (exponent cannot have '.') |
| 14134 | if (current_fragment == fragments + 2) |
nothing calls this directly
no outgoing calls
no test coverage detected