dte test coverage


Directory: ./
File: src/util/ascii.h
Date: 2025-02-14 16:55: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 80568 static inline bool ascii_test(unsigned char c, AsciiCharType mask)
39 {
40 80568 return (ascii_table[c] & mask) != 0;
41 }
42
43 8441 static inline bool ascii_isblank(unsigned char c)
44 {
45 8441 return c == ' ' || c == '\t';
46 }
47
48 1801 static inline bool ascii_isdigit(unsigned char c)
49 {
50 1801 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 (2→3) taken 70 times.
✓ Branch 1 (2→5) taken 11 times.
✓ Branch 2 (3→4) taken 65 times.
✓ Branch 3 (3→5) 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 51878 static inline unsigned char ascii_tolower(unsigned char c)
64 {
65 51878 static_assert(ASCII_UPPER == 0x20);
66 51878 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 (3→3) taken 4882 times.
✓ Branch 1 (3→4) 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 8814 static inline size_t ascii_blank_prefix_length(const char *str, size_t len)
94 {
95 8814 size_t i = 0;
96
4/4
✓ Branch 0 (4→5) taken 7841 times.
✓ Branch 1 (4→6) taken 1409 times.
✓ Branch 2 (5→3) taken 436 times.
✓ Branch 3 (5→6) taken 7405 times.
9250 while (i < len && ascii_isblank(str[i])) {
97 436 i++;
98 }
99 8814 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 (5→3) taken 20 times.
✓ Branch 1 (5→6) taken 3 times.
23 for (size_t i = 0; i < len; i++) {
105
1/2
✓ Branch 0 (3→4) taken 20 times.
✗ Branch 1 (3→6) not taken.
20 if (ascii_test(str[i], mask)) {
106 return true;
107 }
108 }
109 return false;
110 }
111
112 #endif
113