dte test coverage


Directory: ./
File: src/filetype/signatures.c
Date: 2025-09-07 23:01:39
Exec Total Coverage
Lines: 49 49 100.0%
Functions: 4 4 100.0%
Branches: 46 51 90.2%

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