dte test coverage


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 50.0% high: ≥ 85.0%
Coverage Exec / Excl / Total
Lines: 100.0% 61 / 0 / 61
Functions: 100.0% 6 / 0 / 6
Branches: 90.2% 55 / 0 / 61

src/filetype/signatures.c
Line Branch Exec Source
1 #include <stddef.h>
2 #include <stdint.h>
3 #include "filetype.h"
4 #include "filetype/types.h"
5 #include "util/ascii.h"
6 #include "util/bsearch.h"
7 #include "util/log.h"
8 #include "util/strtonum.h"
9 #include "util/xmemmem.h"
10
11 static const struct EmacsModeEntry {
12 char name[15];
13 uint8_t type; // FileTypeEnum
14 } emacs_modes[] = {
15 // Strings already in builtin_filetype_names[] need not be included here
16 {"autoconf", M4},
17 {"c++", CPLUSPLUS},
18 {"cperl", PERL},
19 {"latex", TEX},
20 {"makefile", MAKE},
21 {"muttrc", CONFIG},
22 {"nroff", ROFF},
23 {"nxml", XML},
24 {"shell-script", SH},
25 };
26
27 24 UNITTEST {
28 24 CHECK_BSEARCH_ARRAY(emacs_modes, name);
29 24 }
30
31 47 static ssize_t find_var_delim(StringView sv)
32 {
33 47 const char *delim = xmemmem(sv.data, MIN(sv.length, 128), STRN("-*-"));
34
2/2
✓ Branch 2 → 3 taken 28 times.
✓ Branch 2 → 4 taken 19 times.
47 return delim ? delim - sv.data : -1;
35 }
36
37 33 static FileTypeEnum filetype_from_emacs_var(const StringView line)
38 {
39 33 ssize_t pos = find_var_delim(line);
40
2/2
✓ Branch 2 → 3 taken 14 times.
✓ Branch 2 → 18 taken 19 times.
33 if (pos < 0) {
41 return NONE;
42 }
43
44 14 size_t dlen = STRLEN("-*-");
45 14 StringView vars = strview_from_slice(line.data, pos + dlen, line.length);
46 14 strview_trim_left(&vars);
47
48 14 pos = find_var_delim(vars);
49
1/2
✓ Branch 5 → 6 taken 14 times.
✗ Branch 5 → 18 not taken.
14 if (pos <= 0) {
50 return NONE;
51 }
52
53 14 vars.length = pos;
54 14 strview_trim_right(&vars);
55 14 LOG_DEBUG("found emacs file-local vars: '%.*s'", (int)vars.length, vars.data);
56
57 // TODO: Handle multiple local vars like e.g. "mode: example; other: xyz;",
58 // in addition to a single major mode string (by searching for "[Mm]ode:")?
59
1/2
✓ Branch 8 → 9 taken 14 times.
✗ Branch 8 → 18 not taken.
14 if (vars.length > FILETYPE_NAME_MAX) {
60 return NONE;
61 }
62
63 // Write the extracted var string into a buffer, to null-terminate and
64 // convert to lowercase (making the lookup effectively case-insensitive)
65 14 char name[FILETYPE_NAME_MAX + 1];
66 14 name[vars.length] = '\0';
67
2/2
✓ Branch 11 → 10 taken 187 times.
✓ Branch 11 → 12 taken 14 times.
201 for (size_t i = 0; i < vars.length; i++) {
68 187 name[i] = ascii_tolower(vars.data[i]);
69 }
70
71 // TODO: Remove "-ts" (tree-sitter), "-base" and "-ts-base" suffixes
72 // from name, before lookup?
73 14 const struct EmacsModeEntry *entry = BSEARCH(name, emacs_modes, vstrcmp);
74
2/2
✓ Branch 13 → 14 taken 2 times.
✓ Branch 13 → 15 taken 12 times.
14 if (entry) {
75 2 return entry->type;
76 }
77
78 12 ssize_t ft = BSEARCH_IDX(name, builtin_filetype_names, vstrcmp);
79
2/2
✓ Branch 16 → 17 taken 6 times.
✓ Branch 16 → 18 taken 6 times.
12 return (ft >= 0) ? (FileTypeEnum)ft : NONE;
80 }
81
82 4 static bool is_gitlog_commit_line(StringView line)
83 {
84
2/4
✓ Branch 3 → 4 taken 4 times.
✗ Branch 3 → 13 not taken.
✓ Branch 4 → 5 taken 4 times.
✗ Branch 4 → 13 not taken.
4 if (!strview_remove_matching_prefix(&line, "commit ") || line.length < 40) {
85 return false;
86 }
87
88 4 size_t ndigits = ascii_hex_prefix_length(line);
89
2/2
✓ Branch 6 → 7 taken 3 times.
✓ Branch 6 → 13 taken 1 time.
4 if (ndigits < 40) {
90 return false;
91 }
92
93 3 strview_remove_prefix(&line, ndigits);
94
4/4
✓ Branch 8 → 9 taken 2 times.
✓ Branch 8 → 12 taken 1 time.
✓ Branch 10 → 11 taken 1 time.
✓ Branch 10 → 12 taken 1 time.
4 return line.length == 0 || strview_has_prefix_and_suffix(line, " (", ")");
95 }
96
97 178 FileTypeEnum filetype_from_signature(StringView line)
98 {
99
2/2
✓ Branch 2 → 3 taken 77 times.
✓ Branch 2 → 25 taken 101 times.
178 if (line.length < 5) {
100 return NONE;
101 }
102
103
9/9
✓ Branch 3 → 4 taken 9 times.
✓ Branch 3 → 8 taken 3 times.
✓ Branch 3 → 10 taken 18 times.
✓ Branch 3 → 12 taken 1 time.
✓ Branch 3 → 15 taken 4 times.
✓ Branch 3 → 18 taken 3 times.
✓ Branch 3 → 21 taken 2 times.
✓ Branch 3 → 24 taken 12 times.
✓ Branch 3 → 25 taken 25 times.
77 switch (line.data[0]) {
104 9 case '<':
105
2/2
✓ Branch 5 → 6 taken 7 times.
✓ Branch 5 → 25 taken 2 times.
9 if (strview_has_prefix_icase(line, "<!DOCTYPE HTML")) {
106 return HTML;
107
2/2
✓ Branch 7 → 24 taken 3 times.
✓ Branch 7 → 25 taken 4 times.
7 } else if (strview_has_either_prefix(line, "<!DOCTYPE", "<?xml")) {
108 return XML;
109 }
110 break;
111 3 case '%':
112
2/2
✓ Branch 9 → 24 taken 2 times.
✓ Branch 9 → 25 taken 1 time.
3 if (strview_has_prefix(line, "%YAML")) {
113 return YAML;
114 }
115 break;
116 18 case '#':
117
2/2
✓ Branch 11 → 24 taken 16 times.
✓ Branch 11 → 25 taken 2 times.
18 if (strview_has_either_prefix(line, "#compdef ", "#autoload")) {
118 return SH;
119 }
120 break;
121 1 case 'I':
122
1/2
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 25 taken 1 time.
1 return strview_has_prefix(line, "ISO-10303-21;") ? STEP : NONE;
123 4 case 'c':
124
2/2
✓ Branch 16 → 17 taken 2 times.
✓ Branch 16 → 25 taken 2 times.
4 return is_gitlog_commit_line(line) ? GITLOG : NONE;
125 3 case 'd':
126
2/2
✓ Branch 19 → 20 taken 2 times.
✓ Branch 19 → 25 taken 1 time.
3 return strview_has_prefix(line, "diff --git") ? DIFF : NONE;
127 2 case 's':
128
2/2
✓ Branch 22 → 23 taken 1 time.
✓ Branch 22 → 25 taken 1 time.
2 return strview_has_prefix(line, "stash@{") ? GITSTASH : NONE;
129 case '/':
130 case '.':
131 case ';':
132 case '-':
133 case '\\':
134 // See: "emacs style file-local variables" in test_find_ft_firstline()
135 break;
136 default:
137 return NONE;
138 }
139
140 33 return filetype_from_emacs_var(line);
141 }
142
143 94 FileTypeEnum filetype_from_signature_late(StringView line)
144 {
145 94 strview_trim_right(&line);
146
147 94 if (
148
2/2
✓ Branch 3 → 4 taken 54 times.
✓ Branch 3 → 11 taken 40 times.
94 line.length >= 4
149
2/2
✓ Branch 5 → 6 taken 5 times.
✓ Branch 5 → 11 taken 49 times.
54 && strview_has_prefix(line, "[")
150
2/2
✓ Branch 7 → 8 taken 3 times.
✓ Branch 7 → 11 taken 2 times.
5 && strview_has_suffix(line, "]")
151
2/2
✓ Branch 8 → 9 taken 2 times.
✓ Branch 8 → 11 taken 1 time.
3 && is_word_byte(line.data[1])
152
1/2
✓ Branch 9 → 10 taken 2 times.
✗ Branch 9 → 11 not taken.
2 && !strview_contains_char_type(line, ASCII_CNTRL)
153 ) {
154 // Use "ini" filetype, if first line looks like an INI [section]
155 2 return INI;
156 }
157
158 return NONE;
159 }
160