dte test coverage


Directory: ./
File: src/util/ascii.h
Date: 2024-12-21 16:03:22
Exec Total Coverage
Lines: 33 33 100.0%
Functions: 11 11 100.0%
Branches: 13 14 92.9%

Line Branch Exec Source
1 #ifndef UTIL_ASCII_H
2 #define UTIL_ASCII_H
3
4 #include <stdbool.h>
5 #include <stddef.h>
6 #include <stdint.h>
7 #include "macros.h"
8
9 extern const uint8_t ascii_table[256];
10
11 typedef enum {
12 ASCII_SPACE = 0x01,
13 ASCII_DIGIT = 0x02,
14 ASCII_CNTRL = 0x04,
15 ASCII_REGEX = 0x08, // [$()*+.?[^{|\]
16 ASCII_LOWER = 0x10,
17 ASCII_UPPER = 0x20,
18 ASCII_UNDERSCORE = 0x40,
19 ASCII_NONASCII = 0x80,
20 ASCII_ALPHA = ASCII_LOWER | ASCII_UPPER,
21 ASCII_ALNUM = ASCII_ALPHA | ASCII_DIGIT,
22 ASCII_WORDBYTE = ASCII_ALNUM | ASCII_UNDERSCORE | ASCII_NONASCII,
23 } AsciiCharType;
24
25 #define ascii_isspace(x) ascii_test(x, ASCII_SPACE)
26 #define ascii_iscntrl(x) ascii_test(x, ASCII_CNTRL)
27 #define ascii_islower(x) ascii_test(x, ASCII_LOWER)
28 #define ascii_isupper(x) ascii_test(x, ASCII_UPPER)
29 #define ascii_isalpha(x) ascii_test(x, ASCII_ALPHA)
30 #define ascii_isalnum(x) ascii_test(x, ASCII_ALNUM)
31 #define ascii_isprint(x) (!ascii_test(x, ASCII_CNTRL | ASCII_NONASCII))
32
33 #define is_alpha_or_underscore(x) ascii_test(x, ASCII_ALPHA | ASCII_UNDERSCORE)
34 #define is_alnum_or_underscore(x) ascii_test(x, ASCII_ALNUM | ASCII_UNDERSCORE)
35 #define is_regex_special_char(x) ascii_test(x, ASCII_REGEX)
36 #define is_word_byte(x) ascii_test(x, ASCII_WORDBYTE)
37
38 74229 static inline bool ascii_test(unsigned char c, AsciiCharType mask)
39 {
40 74229 return (ascii_table[c] & mask) != 0;
41 }
42
43 8054 static inline bool ascii_isblank(unsigned char c)
44 {
45 8054 return c == ' ' || c == '\t';
46 }
47
48 1770 static inline bool ascii_isdigit(unsigned char c)
49 {
50 1770 return (unsigned int)c - '0' <= 9;
51 }
52
53 81 static inline bool ascii_is_digit_or_dot(unsigned char c)
54 {
55
4/4
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 65 times.
✓ Branch 3 taken 5 times.
81 return ascii_isdigit(c) || c == '.';
56 }
57
58 269 static inline bool ascii_is_nonspace_cntrl(unsigned char c)
59 {
60 269 return ascii_table[c] == ASCII_CNTRL;
61 }
62
63 51843 static inline unsigned char ascii_tolower(unsigned char c)
64 {
65 51843 static_assert(ASCII_UPPER == 0x20);
66 51843 return c + (ascii_table[c] & ASCII_UPPER);
67 }
68
69 272 static inline unsigned char ascii_toupper(unsigned char c)
70 {
71 272 static_assert(ASCII_LOWER << 1 == 0x20);
72 272 return c - ((ascii_table[c] & ASCII_LOWER) << 1);
73 }
74
75 NONNULL_ARGS
76 7360 static inline int ascii_strcmp_icase(const char *s1, const char *s2)
77 {
78 12242 unsigned char c1, c2;
79 12242 do {
80 12242 c1 = ascii_tolower(*s1++);
81 12242 c2 = ascii_tolower(*s2++);
82
2/2
✓ Branch 0 taken 4882 times.
✓ Branch 1 taken 7360 times.
12242 } while (c1 && c1 == c2);
83
84 7360 return c1 - c2;
85 }
86
87 NONNULL_ARGS
88 6990 static inline bool ascii_streq_icase(const char *s1, const char *s2)
89 {
90 6990 return ascii_strcmp_icase(s1, s2) == 0;
91 }
92
93 8471 static inline size_t ascii_blank_prefix_length(const char *str, size_t len)
94 {
95 8471 size_t i = 0;
96
4/4
✓ Branch 0 taken 7491 times.
✓ Branch 1 taken 1356 times.
✓ Branch 2 taken 376 times.
✓ Branch 3 taken 7115 times.
8847 while (i < len && ascii_isblank(str[i])) {
97 376 i++;
98 }
99 8471 return i;
100 }
101
102 3 static inline bool strn_contains_char_type(const char *str, size_t len, AsciiCharType mask)
103 {
104
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 3 times.
23 for (size_t i = 0; i < len; i++) {
105
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (ascii_test(str[i], mask)) {
106 return true;
107 }
108 }
109 return false;
110 }
111
112 #endif
113