dte test coverage


Directory: ./
File: src/msg.c
Date: 2025-05-08 15:05:54
Exec Total Coverage
Lines: 35 79 44.3%
Functions: 5 7 71.4%
Branches: 10 40 25.0%

Line Branch Exec Source
1 #include <stdlib.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include "msg.h"
5 #include "command/error.h"
6 #include "editor.h"
7 #include "util/debug.h"
8 #include "util/numtostr.h"
9 #include "util/path.h"
10 #include "util/xmalloc.h"
11
12 1 static void free_message(Message *m)
13 {
14
1/2
✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→4) not taken.
1 if (m->loc) {
15 1 file_location_free(m->loc);
16 }
17 1 free(m);
18 1 }
19
20 Message *new_message(const char *msg, size_t len)
21 {
22 Message *m = xmalloc(sizeof(*m) + len + 1);
23 m->loc = NULL;
24 if (len) {
25 memcpy(m->msg, msg, len);
26 }
27 m->msg[len] = '\0';
28 return m;
29 }
30
31 1 void add_message(MessageArray *msgs, Message *m)
32 {
33 1 ptr_array_append(&msgs->array, m);
34 1 }
35
36 // Jump to the FileLocation of the current Message
37 1 bool activate_current_message(const MessageArray *msgs, Window *window)
38 {
39 1 size_t count = msgs->array.count;
40
1/2
✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→12) not taken.
1 if (count == 0) {
41 return false;
42 }
43
44 1 size_t pos = msgs->pos;
45 1 BUG_ON(pos >= count);
46 1 const Message *m = msgs->array.ptrs[pos];
47 1 const FileLocation *loc = m->loc;
48
3/6
✓ Branch 0 (5→6) taken 1 times.
✗ Branch 1 (5→9) not taken.
✓ Branch 2 (6→7) taken 1 times.
✗ Branch 3 (6→9) not taken.
✓ Branch 4 (8→9) taken 1 times.
✗ Branch 5 (8→12) not taken.
1 if (loc && loc->filename && !file_location_go(window, loc)) {
49 // Failed to jump to location; error message is visible
50 return false;
51 }
52
53 1 ErrorBuffer *ebuf = &window->editor->err;
54
1/2
✓ Branch 0 (9→10) taken 1 times.
✗ Branch 1 (9→11) not taken.
1 if (count == 1) {
55 1 return info_msg(ebuf, "%s", m->msg);
56 }
57
58 return info_msg(ebuf, "[%zu/%zu] %s", pos + 1, count, m->msg);
59 }
60
61 // Like activate_current_message(), but also pushing the previous
62 // FileLocation on the bookmark stack if the cursor moves
63 1 void activate_current_message_save (
64 const MessageArray *msgs,
65 PointerArray *bookmarks,
66 const View *view
67 ) {
68 1 size_t nmsgs = msgs->array.count;
69
1/2
✓ Branch 0 (2→3) taken 1 times.
✗ Branch 1 (2→12) not taken.
1 if (nmsgs == 0) {
70 return;
71 }
72
73 1 const BlockIter save = view->cursor;
74 1 const unsigned long line = view->cy + 1;
75 1 const unsigned long col = view->cx_char + 1;
76 1 activate_current_message(msgs, view->window);
77
78 1 const BlockIter *cursor = &view->window->editor->view->cursor;
79
2/6
✓ Branch 0 (4→5) taken 1 times.
✗ Branch 1 (4→7) not taken.
✗ Branch 2 (5→6) not taken.
✓ Branch 3 (5→7) taken 1 times.
✗ Branch 4 (6→7) not taken.
✗ Branch 5 (6→12) not taken.
1 if (nmsgs == 1 && cursor->blk == save.blk && cursor->offset == save.offset) {
80 // Only one message and cursor position not changed; don't bookmark.
81 // TODO: Make this condition configurable (some people may prefer
82 // to *always* push a bookmark)
83 return;
84 }
85
86 // Active view or cursor position changed, or MAY change due to
87 // there being multiple Messages to navigate with `msg -n|-p`;
88 // bookmark the previous location
89 1 const Buffer *b = view->buffer;
90
1/2
✗ Branch 0 (7→8) not taken.
✓ Branch 1 (7→9) taken 1 times.
1 char *filename = b->abs_filename ? xstrdup(b->abs_filename) : NULL;
91 1 bookmark_push(bookmarks, new_file_location(filename, b->id, line, col));
92 }
93
94 10 void clear_messages(MessageArray *msgs)
95 {
96 10 msgs->pos = 0;
97 10 ptr_array_free_cb(&msgs->array, FREE_FUNC(free_message));
98 10 }
99
100 String dump_messages(const MessageArray *messages)
101 {
102 String buf = string_new(4096);
103 char cwd[8192];
104 if (unlikely(!getcwd(cwd, sizeof cwd))) {
105 return buf;
106 }
107
108 for (size_t i = 0, n = messages->array.count; i < n; i++) {
109 char *ptr = string_reserve_space(&buf, DECIMAL_STR_MAX(i));
110 buf.len += buf_umax_to_str(i + 1, ptr);
111 string_append_literal(&buf, ": ");
112
113 const Message *m = messages->array.ptrs[i];
114 const FileLocation *loc = m->loc;
115 if (!loc || !loc->filename) {
116 goto append_msg;
117 }
118
119 if (path_is_absolute(loc->filename)) {
120 char *rel = path_relative(loc->filename, cwd);
121 string_append_cstring(&buf, rel);
122 free(rel);
123 } else {
124 string_append_cstring(&buf, loc->filename);
125 }
126
127 string_append_byte(&buf, ':');
128
129 if (loc->pattern) {
130 string_append_literal(&buf, " /");
131 string_append_cstring(&buf, loc->pattern);
132 string_append_literal(&buf, "/\n");
133 continue;
134 }
135
136 if (loc->line != 0) {
137 string_append_cstring(&buf, ulong_to_str(loc->line));
138 string_append_byte(&buf, ':');
139 if (loc->column != 0) {
140 string_append_cstring(&buf, ulong_to_str(loc->column));
141 string_append_byte(&buf, ':');
142 }
143 }
144
145 string_append_literal(&buf, " ");
146
147 append_msg:
148 string_append_cstring(&buf, m->msg);
149 string_append_byte(&buf, '\n');
150 }
151
152 return buf;
153 }
154