dte test coverage


Directory: ./
File: src/vars.c
Date: 2024-12-21 16:03:22
Exec Total Coverage
Lines: 34 56 60.7%
Functions: 13 13 100.0%
Branches: 12 36 33.3%

Line Branch Exec Source
1 #include <stddef.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include "vars.h"
5 #include "editor.h"
6 #include "selection.h"
7 #include "util/array.h"
8 #include "util/bsearch.h"
9 #include "util/numtostr.h"
10 #include "util/path.h"
11 #include "util/str-util.h"
12 #include "util/xmalloc.h"
13 #include "view.h"
14
15 typedef struct {
16 char name[12];
17 char *(*expand)(const EditorState *e);
18 } BuiltinVar;
19
20 2 static char *expand_dte_home(const EditorState *e)
21 {
22 2 return xstrdup(e->user_config_dir);
23 }
24
25 1 static char *expand_file(const EditorState *e)
26 {
27
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if (!e->buffer || !e->buffer->abs_filename) {
28 return NULL;
29 }
30 return xstrdup(e->buffer->abs_filename);
31 }
32
33 1 static char *expand_file_dir(const EditorState *e)
34 {
35
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if (!e->buffer || !e->buffer->abs_filename) {
36 return NULL;
37 }
38 return path_dirname(e->buffer->abs_filename);
39 }
40
41 2 static char *expand_rfile(const EditorState *e)
42 {
43
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if (!e->buffer || !e->buffer->abs_filename) {
44 return NULL;
45 }
46 char buf[8192];
47 const char *cwd = getcwd(buf, sizeof buf);
48 const char *abs = e->buffer->abs_filename;
49 return likely(cwd) ? path_relative(abs, cwd) : xstrdup(abs);
50 }
51
52 1 static char *expand_rfiledir(const EditorState *e)
53 {
54 1 char *rfile = expand_rfile(e);
55
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!rfile) {
56 return NULL;
57 }
58
59 StringView dir = path_slice_dirname(rfile);
60 if (rfile != (char*)dir.data) {
61 // rfile contains no directory part (i.e. no slashes), so there's
62 // nothing to "slice" and we simply return "." instead
63 free(rfile);
64 return xstrdup(".");
65 }
66
67 // Overwrite the last slash in rfile with a null terminator, so as
68 // to remove the last path component (the filename)
69 rfile[dir.length] = '\0';
70 return rfile;
71 }
72
73 1 static char *expand_filetype(const EditorState *e)
74 {
75
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 return e->buffer ? xstrdup(e->buffer->options.filetype) : NULL;
76 }
77
78 1 static char *expand_colno(const EditorState *e)
79 {
80
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 return e->view ? xstrdup(umax_to_str(e->view->cx_display + 1)) : NULL;
81 }
82
83 1 static char *expand_lineno(const EditorState *e)
84 {
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 return e->view ? xstrdup(umax_to_str(e->view->cy + 1)) : NULL;
86 }
87
88 1 static char *expand_msgpos(const EditorState *e)
89 {
90 1 return xstrdup(umax_to_str(e->messages.pos + 1));
91 }
92
93 1 static char *expand_word(const EditorState *e)
94 {
95 1 const View *view = e->view;
96
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (unlikely(!view)) {
97 return NULL;
98 }
99
100 if (view->selection) {
101 SelectionInfo info = init_selection(view);
102 size_t len = info.eo - info.so;
103 if (unlikely(len == 0)) {
104 return NULL;
105 }
106 char *selection = block_iter_get_bytes(&info.si, len);
107 BUG_ON(!selection);
108 selection[len] = '\0'; // See comment in block_iter_get_bytes()
109 return selection;
110 }
111
112 StringView word = view_get_word_under_cursor(view);
113 return word.length ? xstrcut(word.data, word.length) : NULL;
114 }
115
116 static const BuiltinVar normal_vars[] = {
117 {"COLNO", expand_colno},
118 {"DTE_HOME", expand_dte_home},
119 {"FILE", expand_file},
120 {"FILEDIR", expand_file_dir},
121 {"FILETYPE", expand_filetype},
122 {"LINENO", expand_lineno},
123 {"MSGPOS", expand_msgpos},
124 {"RFILE", expand_rfile},
125 {"RFILEDIR", expand_rfiledir},
126 {"WORD", expand_word},
127 };
128
129 18 UNITTEST {
130 18 CHECK_BSEARCH_ARRAY(normal_vars, name, strcmp);
131 18 }
132
133 19 char *expand_normal_var(const EditorState *e, const char *name)
134 {
135 19 const BuiltinVar *var = BSEARCH(name, normal_vars, vstrcmp);
136
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 8 times.
19 if (var) {
137 11 return var->expand(e);
138 }
139 8 const char *str = xgetenv(name);
140
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 return str ? xstrdup(str) : NULL;
141 }
142
143 1 void collect_normal_vars(PointerArray *a, const char *prefix)
144 {
145 1 COLLECT_STRING_FIELDS(normal_vars, name, a, prefix);
146 1 }
147