dte test coverage


Directory: ./
File: src/util/ascii.h
Date: 2025-05-08 15:05:54
Exec Total Coverage
Lines: 35 35 100.0%
Functions: 12 12 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_PUNCT = 0x40,
19 ASCII_UNDERSCORE = 0x80,
20 ASCII_ALPHA = ASCII_LOWER | ASCII_UPPER,
21 ASCII_ALNUM = ASCII_ALPHA | ASCII_DIGIT,
22 ASCII_NONWORD = ASCII_SPACE | ASCII_CNTRL | ASCII_PUNCT,
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_ispunct(x) ascii_test(x, ASCII_PUNCT | ASCII_UNDERSCORE)
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_NONWORD) // See comment in ascii.c
37
38 95818 static inline bool ascii_test(unsigned char c, AsciiCharType mask)
39 {
40 95818 return (ascii_table[c] & mask) != 0;
41 }
42
43 277 static inline bool ascii_isprint(unsigned char c)
44 {
45 277 return c >= ' ' && c <= '~';
46 }
47
48 8853 static inline bool ascii_isblank(unsigned char c)
49 {
50 8853 return c == ' ' || c == '\t';
51 }
52
53 1828 static inline bool ascii_isdigit(unsigned char c)
54 {
55 1828 return c >= '0' && c <= '9';
56 }
57
58 81 static inline bool ascii_is_digit_or_dot(unsigned char c)
59 {
60
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 == '.';
61 }
62
63 16 static inline bool ascii_is_nonspace_cntrl(unsigned char c)
64 {
65 16 return ascii_table[c] == ASCII_CNTRL;
66 }
67
68 55036 static inline unsigned char ascii_tolower(unsigned char c)
69 {
70 55036 static_assert(ASCII_UPPER == 0x20);
71 55036 return c + (ascii_table[c] & ASCII_UPPER);
72 }
73
74 272 static inline unsigned char ascii_toupper(unsigned char c)
75 {
76 272 static_assert(ASCII_LOWER << 1 == 0x20);
77 272 return c - ((ascii_table[c] & ASCII_LOWER) << 1);
78 }
79
80 NONNULL_ARGS
81 8275 static inline int ascii_strcmp_icase(const char *s1, const char *s2)
82 {
83 13821 unsigned char c1, c2;
84 13821 do {
85 13821 c1 = ascii_tolower(*s1++);
86 13821 c2 = ascii_tolower(*s2++);
87
2/2
✓ Branch 0 (3→3) taken 5546 times.
✓ Branch 1 (3→4) taken 8275 times.
13821 } while (c1 && c1 == c2);
88
89 8275 return c1 - c2;
90 }
91
92 NONNULL_ARGS
93 7841 static inline bool ascii_streq_icase(const char *s1, const char *s2)
94 {
95 7841 return ascii_strcmp_icase(s1, s2) == 0;
96 }
97
98 9258 static inline size_t ascii_blank_prefix_length(const char *str, size_t len)
99 {
100 9258 size_t i = 0;
101
4/4
✓ Branch 0 (4→5) taken 8250 times.
✓ Branch 1 (4→6) taken 1456 times.
✓ Branch 2 (5→3) taken 448 times.
✓ Branch 3 (5→6) taken 7802 times.
9706 while (i < len && ascii_isblank(str[i])) {
102 448 i++;
103 }
104 9258 return i;
105 }
106
107 3 static inline bool strn_contains_ascii_char_type (
108 const char *str,
109 size_t len,
110 AsciiCharType mask
111 ) {
112
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++) {
113
1/2
✓ Branch 0 (3→4) taken 20 times.
✗ Branch 1 (3→6) not taken.
20 if (ascii_test(str[i], mask)) {
114 return true;
115 }
116 }
117 return false;
118 }
119
120 #endif
121