dte test coverage


Directory: ./
File: src/file-option.c
Date: 2025-09-07 23:01:39
Exec Total Coverage
Lines: 65 93 69.9%
Functions: 7 7 100.0%
Branches: 25 40 62.5%

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 0 (5→3) taken 7 times.
✓ Branch 1 (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 0 (2→3) not taken.
✓ Branch 1 (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 0 (15→3) taken 2478 times.
✓ Branch 1 (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 0 (3→4) taken 2408 times.
✓ Branch 1 (3→7) taken 70 times.
2478 if (opt->type == FOPTS_FILETYPE) {
88
2/2
✓ Branch 0 (4→5) taken 6 times.
✓ Branch 1 (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 0 (9→10) taken 64 times.
✓ Branch 1 (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 0 (12→13) taken 1 times.
✓ Branch 1 (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 0 (4→5) taken 10 times.
✓ Branch 1 (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 0 (22→3) taken 48 times.
✓ Branch 1 (22→23) taken 1 times.
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 0 (3→4) taken 2 times.
✓ Branch 1 (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 0 (7→8) taken 2 times.
✓ Branch 1 (7→9) taken 46 times.
48 if (opt->type == FOPTS_FILENAME) {
143 2 string_append_literal(buf, "-r ");
144 }
145
2/4
✓ Branch 0 (9→10) taken 48 times.
✗ Branch 1 (9→11) not taken.
✗ Branch 2 (10→11) not taken.
✓ Branch 3 (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 0 (19→14) taken 52 times.
✓ Branch 1 (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