dte test coverage


Directory: ./
File: src/file-option.c
Date: 2025-02-14 16:55:22
Exec Total Coverage
Lines: 66 91 72.5%
Functions: 7 7 100.0%
Branches: 25 42 59.5%

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