dte test coverage


Directory: ./
File: src/file-option.c
Date: 2025-11-12 12:04:10
Coverage Exec Excl Total
Lines: 69.9% 65 0 93
Functions: 100.0% 7 0 7
Branches: 62.5% 25 0 40

Line Branch Exec Source
1 #include <stdbool.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include "file-option.h"
6 #include "command/serialize.h"
7 #include "editor.h"
8 #include "editorconfig/editorconfig.h"
9 #include "options.h"
10 #include "regexp.h"
11 #include "util/debug.h"
12 #include "util/intern.h"
13 #include "util/str-array.h"
14 #include "util/str-util.h"
15 #include "util/xmalloc.h"
16
17 typedef struct {
18 FileOptionType type;
19 char **strs;
20 FileTypeOrFileName u;
21 } FileOption;
22
23 7 static void set_options(EditorState *e, char **args)
24 {
25
2/2
✓ Branch 5 → 3 taken 7 times.
✓ Branch 5 → 6 taken 7 times.
14 for (size_t i = 0; args[i]; i += 2) {
26 7 set_option(e, args[i], args[i + 1], true, false);
27 }
28 7 }
29
30 59 void set_editorconfig_options(Buffer *buffer)
31 {
32 59 LocalOptions *options = &buffer->options;
33
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 25 taken 59 times.
59 if (!options->editorconfig) {
34 59 return;
35 }
36
37 const char *path = buffer->abs_filename;
38 char cwd[8192];
39 if (!path) {
40 // For buffers with no associated filename, use a dummy path of
41 // "$PWD/__", to obtain generic settings for the working directory
42 // or the user's default settings
43 static const char suffix[] = "/__";
44 if (unlikely(!getcwd(cwd, sizeof(cwd) - sizeof(suffix)))) {
45 return;
46 }
47 memcpy(cwd + strlen(cwd), suffix, sizeof(suffix));
48 path = cwd;
49 }
50
51 EditorConfigOptions opts = get_editorconfig_options(path);
52 EditorConfigIndentStyle style = opts.indent_style;
53 if (style != INDENT_STYLE_UNSPECIFIED) {
54 BUG_ON(style != INDENT_STYLE_SPACE && style != INDENT_STYLE_TAB);
55 options->expand_tab = (style == INDENT_STYLE_SPACE);
56 options->emulate_tab = (style == INDENT_STYLE_SPACE);
57 options->detect_indent = 0;
58 }
59
60 unsigned int iw = opts.indent_size;
61 if (iw) {
62 BUG_ON(iw > INDENT_WIDTH_MAX);
63 options->indent_width = iw;
64 options->detect_indent = 0;
65 }
66
67 unsigned int tw = opts.tab_width;
68 if (tw) {
69 BUG_ON(tw > TAB_WIDTH_MAX);
70 options->tab_width = tw;
71 }
72
73 unsigned int maxlen = opts.max_line_length;
74 if (maxlen) {
75 BUG_ON(maxlen > TEXT_WIDTH_MAX);
76 options->text_width = maxlen;
77 }
78 }
79
80 60 void set_file_options(EditorState *e, Buffer *buffer)
81 {
82 60 const PointerArray *fileopts = &e->file_options;
83 60 const char *buffer_filetype = buffer->options.filetype;
84
85
2/2
✓ Branch 15 → 3 taken 2478 times.
✓ Branch 15 → 16 taken 60 times.
2538 for (size_t i = 0, n = fileopts->count; i < n; i++) {
86 2478 const FileOption *opt = fileopts->ptrs[i];
87
2/2
✓ Branch 3 → 4 taken 2408 times.
✓ Branch 3 → 7 taken 70 times.
2478 if (opt->type == FOPTS_FILETYPE) {
88
2/2
✓ Branch 4 → 5 taken 6 times.
✓ Branch 4 → 6 taken 2402 times.
2408 if (interned_strings_equal(opt->u.filetype, buffer_filetype)) {
89 6 set_options(e, opt->strs);
90 }
91 2408 continue;
92 }
93
94 70 BUG_ON(opt->type != FOPTS_FILENAME);
95 70 const char *filename = buffer->abs_filename;
96
2/2
✓ Branch 9 → 10 taken 64 times.
✓ Branch 9 → 11 taken 6 times.
70 if (!filename) {
97 64 continue;
98 }
99
100 6 const regex_t *re = &opt->u.filename->re;
101
2/2
✓ Branch 12 → 13 taken 1 time.
✓ Branch 12 → 14 taken 5 times.
6 if (regexp_exec(re, filename, strlen(filename), 0, NULL, 0)) {
102 1 set_options(e, opt->strs);
103 }
104 }
105 60 }
106
107 360 void add_file_options (
108 PointerArray *file_options,
109 FileOptionType type,
110 FileTypeOrFileName u,
111 char **strs,
112 size_t nstrs
113 ) {
114 360 BUG_ON(nstrs < 2);
115
2/2
✓ Branch 4 → 5 taken 10 times.
✓ Branch 4 → 9 taken 350 times.
360 if (type == FOPTS_FILENAME) {
116 10 BUG_ON(!u.filename);
117 10 BUG_ON(!u.filename->str);
118 } else {
119 350 BUG_ON(type != FOPTS_FILETYPE);
120 350 BUG_ON(!u.filetype);
121 }
122
123 360 FileOption *opt = xmalloc(sizeof(*opt));
124 360 opt->u = u;
125 360 opt->type = type;
126 360 opt->strs = copy_string_array(strs, nstrs);
127 360 ptr_array_append(file_options, opt);
128 360 }
129
130 1 void dump_file_options(const PointerArray *file_options, String *buf)
131 {
132
2/2
✓ Branch 22 → 3 taken 48 times.
✓ Branch 22 → 23 taken 1 time.
49 for (size_t i = 0, n = file_options->count; i < n; i++) {
133 48 const FileOption *opt = file_options->ptrs[i];
134 48 const char *tp;
135
2/2
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 5 taken 46 times.
48 if (opt->type == FOPTS_FILENAME) {
136 2 tp = opt->u.filename->str;
137 } else {
138 46 tp = opt->u.filetype;
139 }
140 48 char **strs = opt->strs;
141 48 string_append_literal(buf, "option ");
142
2/2
✓ Branch 7 → 8 taken 2 times.
✓ Branch 7 → 9 taken 46 times.
48 if (opt->type == FOPTS_FILENAME) {
143 2 string_append_literal(buf, "-r ");
144 }
145
2/4
✓ Branch 9 → 10 taken 48 times.
✗ Branch 9 → 11 not taken.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 48 times.
48 if (str_has_prefix(tp, "-") || string_array_contains_prefix(strs, "-")) {
146 string_append_literal(buf, "-- ");
147 }
148 48 string_append_escaped_arg(buf, tp, true);
149
2/2
✓ Branch 19 → 14 taken 52 times.
✓ Branch 19 → 20 taken 48 times.
100 for (size_t j = 0; strs[j]; j += 2) {
150 52 string_append_byte(buf, ' ');
151 52 string_append_cstring(buf, strs[j]);
152 52 string_append_byte(buf, ' ');
153 52 string_append_escaped_arg(buf, strs[j + 1], true);
154 }
155 48 string_append_byte(buf, '\n');
156 }
157 1 }
158
159 360 static void free_file_option(FileOption *opt)
160 {
161 360 free_string_array(opt->strs);
162 360 free(opt);
163 360 }
164
165 11 void free_file_options(PointerArray *file_options)
166 {
167 11 ptr_array_free_cb(file_options, FREE_FUNC(free_file_option));
168 11 }
169