Line | Branch | Exec | Source |
---|---|---|---|
1 | #ifndef UTIL_STRTONUM_H | ||
2 | #define UTIL_STRTONUM_H | ||
3 | |||
4 | #include <limits.h> | ||
5 | #include <stdbool.h> | ||
6 | #include <stddef.h> | ||
7 | #include <stdint.h> | ||
8 | #include "macros.h" | ||
9 | |||
10 | extern const uint8_t hex_decode_table[64]; | ||
11 | |||
12 | enum { | ||
13 | HEX_INVALID = 0xF0, | ||
14 | }; | ||
15 | |||
16 | // Decodes a single, hexadecimal digit and returns a numerical value | ||
17 | // between 0-15, or HEX_INVALID for invalid digits | ||
18 | 1068 | static inline unsigned int hex_decode(unsigned char c) | |
19 | { | ||
20 | 1068 | c -= '0'; // Lookup table starts at '0' | |
21 | 1068 | return hex_decode_table[(c < sizeof(hex_decode_table)) ? c : 63]; | |
22 | } | ||
23 | |||
24 | 419 | static inline bool ascii_isxdigit(unsigned char c) | |
25 | { | ||
26 | 419 | return hex_decode(c) <= 0xF; | |
27 | } | ||
28 | |||
29 | 4 | static inline size_t ascii_hex_prefix_length(const char *str, size_t len) | |
30 | { | ||
31 | 4 | size_t i = 0; | |
32 |
4/4✓ Branch 0 (4→5) taken 162 times.
✓ Branch 1 (4→6) taken 1 times.
✓ Branch 2 (5→3) taken 159 times.
✓ Branch 3 (5→6) taken 3 times.
|
163 | while (i < len && ascii_isxdigit(str[i])) { |
33 | 159 | i++; | |
34 | } | ||
35 | 4 | return i; | |
36 | } | ||
37 | |||
38 | WARN_UNUSED_RESULT | ||
39 | 59 | static inline size_t buf_parse_hex_uint(const char *str, size_t len, unsigned int *valp) | |
40 | { | ||
41 | 59 | unsigned int val = 0; | |
42 | 59 | size_t i; | |
43 |
2/2✓ Branch 0 (6→3) taken 184 times.
✓ Branch 1 (6→7) taken 50 times.
|
234 | for (i = 0; i < len; i++) { |
44 | 184 | unsigned int x = hex_decode(str[i]); | |
45 |
2/2✓ Branch 0 (3→4) taken 177 times.
✓ Branch 1 (3→7) taken 7 times.
|
184 | if (unlikely(x > 0xF)) { |
46 | break; | ||
47 | } | ||
48 |
2/2✓ Branch 0 (4→5) taken 175 times.
✓ Branch 1 (4→8) taken 2 times.
|
177 | if (unlikely(val > (UINT_MAX >> 4))) { |
49 | return 0; // Overflow | ||
50 | } | ||
51 | 175 | val = val << 4 | x; | |
52 | } | ||
53 | 57 | *valp = val; | |
54 | 57 | return i; | |
55 | } | ||
56 | |||
57 | size_t size_str_width(size_t x) CONST_FN WARN_UNUSED_RESULT; | ||
58 | size_t buf_parse_uintmax(const char *str, size_t len, uintmax_t *valp) WARN_UNUSED_RESULT WRITEONLY(3); | ||
59 | size_t buf_parse_ulong(const char *str, size_t len, unsigned long *valp) WARN_UNUSED_RESULT WRITEONLY(3); | ||
60 | size_t buf_parse_uint(const char *str, size_t len, unsigned int *valp) WARN_UNUSED_RESULT WRITEONLY(3); | ||
61 | size_t buf_parse_size(const char *str, size_t len, size_t *valp) WARN_UNUSED_RESULT WRITEONLY(3); | ||
62 | bool str_to_int(const char *str, int *valp) NONNULL_ARGS WARN_UNUSED_RESULT WRITEONLY(2); | ||
63 | bool str_to_uint(const char *str, unsigned int *valp) NONNULL_ARGS WARN_UNUSED_RESULT WRITEONLY(2); | ||
64 | bool str_to_size(const char *str, size_t *valp) NONNULL_ARGS WARN_UNUSED_RESULT WRITEONLY(2); | ||
65 | bool str_to_ulong(const char *str, unsigned long *valp) NONNULL_ARGS WARN_UNUSED_RESULT WRITEONLY(2); | ||
66 | bool str_to_filepos(const char *str, size_t *linep, size_t *colp) NONNULL_ARGS WARN_UNUSED_RESULT WRITEONLY(2) WRITEONLY(3); | ||
67 | bool str_to_xfilepos(const char *str, size_t *linep, size_t *colp) NONNULL_ARGS WARN_UNUSED_RESULT WRITEONLY(2) WRITEONLY(3); | ||
68 | intmax_t parse_filesize(const char *str) NONNULL_ARGS WARN_UNUSED_RESULT; | ||
69 | |||
70 | #endif | ||
71 |