dte test coverage


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 50.0% high: ≥ 85.0%
Coverage Exec / Excl / Total
Lines: 75.0% 36 / 0 / 48
Functions: 92.9% 13 / 0 / 14
Branches: 57.7% 15 / 2 / 28

src/block-iter.h
Line Branch Exec Source
1 #ifndef BLOCK_ITER_H
2 #define BLOCK_ITER_H
3
4 #include <stdbool.h>
5 #include <stddef.h>
6 #include "block.h"
7 #include "util/list.h"
8 #include "util/macros.h"
9 #include "util/string-view.h"
10 #include "util/string.h"
11 #include "util/unicode.h"
12
13 // An iterator used to represent the cursor position for each View of a
14 // Buffer (see View::cursor) and also as a means for accessing/iterating
15 // the Blocks that make up the text contents of a Buffer (see Buffer::blocks).
16 typedef struct {
17 Block *blk; // The Block this iterator/cursor currently points to
18 const ListHead *head; // A pointer to the Buffer::blocks that owns `blk`
19 size_t offset; // The current position within `blk->data`
20 } BlockIter;
21
22 typedef struct {
23 StringView line;
24 size_t cursor_offset;
25 } CurrentLineRef;
26
27 15 static inline Block *block_iter_get_first_block(BlockIter *bi)
28 {
29 15 return BLOCK(bi->head->next);
30 }
31
32 8 static inline Block *block_iter_get_last_block(BlockIter *bi)
33 {
34 8 return BLOCK(bi->head->prev);
35 }
36
37 11 static inline void block_iter_bof(BlockIter *bi)
38 {
39 11 bi->blk = block_iter_get_first_block(bi);
40 11 bi->offset = 0;
41 11 }
42
43 8 static inline void block_iter_eof(BlockIter *bi)
44 {
45 8 bi->blk = block_iter_get_last_block(bi);
46 8 bi->offset = bi->blk->size;
47 8 }
48
49 101 static inline bool block_iter_is_bof(const BlockIter *bi)
50 {
51
3/4
✓ Branch 2 → 3 taken 10 times.
✓ Branch 2 → 5 taken 91 times.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 10 times.
101 return bi->offset == 0 && !block_has_prev(bi->blk, bi->head);
52 }
53
54 405 static inline bool block_iter_is_eof(const BlockIter *bi)
55 {
56
3/4
✓ Branch 2 → 3 taken 74 times.
✓ Branch 2 → 5 taken 331 times.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 74 times.
405 return bi->offset == bi->blk->size && !block_has_next(bi->blk, bi->head);
57 }
58
59 472 static inline bool block_iter_is_bol(const BlockIter *bi)
60 {
61 // See also: Block invariants mentioned in sanity_check_blocks()
62
4/4
✓ Branch 2 → 3 taken 373 times.
✓ Branch 2 → 5 taken 99 times.
✓ Branch 3 → 4 taken 211 times.
✓ Branch 3 → 5 taken 162 times.
472 return bi->offset == 0 || bi->blk->data[bi->offset - 1] == '\n';
63 }
64
65 static inline bool block_iter_is_eol(const BlockIter *bi)
66 {
67 const Block *blk = bi->blk;
68 if (bi->offset == blk->size) {
69 bool is_last_block = !block_has_next(bi->blk, bi->head);
70 return is_last_block || block_next(blk)->data[0] == '\n';
71 }
72
73 return blk->data[bi->offset] == '\n';
74 }
75
76 143 static inline bool block_iter_next_block(BlockIter *bi)
77 {
78
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 143 times.
143 if (!block_has_next(bi->blk, bi->head)) {
79 return false; // Already on last Block
80 }
81
82 bi->blk = block_next(bi->blk);
83 bi->offset = 0; // Beginning of next Block
84 return true;
85 }
86
87 6 static inline bool block_iter_end_of_prev_block(BlockIter *bi)
88 {
89
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 6 times.
6 if (!block_has_prev(bi->blk, bi->head)) {
90 return false; // Already on first Block
91 }
92
93 bi->blk = block_prev(bi->blk);
94 bi->offset = bi->blk->size; // End of previous Block
95 return true;
96 }
97
98 1520 static inline bool block_iter_normalize(BlockIter *bi)
99 {
100 1520 BUG_ON(bi->offset > bi->blk->size);
101
3/4
✓ Branch 4 → 5 taken 103 times.
✓ Branch 4 → 8 taken 1417 times.
✓ Branch 6 → 7 taken 103 times.
✗ Branch 6 → 8 not taken.
1520 return (bi->offset == bi->blk->size) && block_iter_next_block(bi);
102 }
103
104 size_t block_iter_eat_line(BlockIter *bi) NONNULL_ARGS;
105 size_t block_iter_next_line(BlockIter *bi) NONNULL_ARGS;
106 size_t block_iter_prev_line(BlockIter *bi) NONNULL_ARGS;
107 size_t block_iter_next_char(BlockIter *bi, CodePoint *up) NONNULL_ARGS READWRITE(1) WRITEONLY(2);
108 size_t block_iter_prev_char(BlockIter *bi, CodePoint *up) NONNULL_ARGS READWRITE(1) WRITEONLY(2);
109 size_t block_iter_next_column(BlockIter *bi) NONNULL_ARGS;
110 size_t block_iter_prev_column(BlockIter *bi) NONNULL_ARGS;
111 size_t block_iter_bol(BlockIter *bi) NONNULL_ARGS;
112 size_t block_iter_eol(BlockIter *bi) NONNULL_ARGS;
113 size_t block_iter_skip_blanks_fwd(BlockIter *bi) NONNULL_ARGS;
114 size_t block_iter_skip_blanks_bwd(BlockIter *bi) NONNULL_ARGS;
115 bool block_iter_find_non_empty_line_bwd(BlockIter *bi) NONNULL_ARGS;
116 void block_iter_back_bytes(BlockIter *bi, size_t count) NONNULL_ARGS;
117 void block_iter_skip_bytes(BlockIter *bi, size_t count) NONNULL_ARGS;
118 void block_iter_goto_offset(BlockIter *bi, size_t offset) NONNULL_ARGS;
119 void block_iter_goto_line(BlockIter *bi, size_t line) NONNULL_ARGS;
120 size_t block_iter_get_offset(const BlockIter *bi) WARN_UNUSED_RESULT NONNULL_ARGS;
121 size_t block_iter_get_char(const BlockIter *bi, CodePoint *up) WARN_UNUSED_RESULT NONNULL_ARGS READONLY(1) WRITEONLY(2);
122 String block_iter_get_bytes(BlockIter bi, size_t len) WARN_UNUSED_RESULT;
123 StringView block_iter_get_line_with_nl(BlockIter *bi) NONNULL_ARGS;
124
125 // Like block_iter_get_line_with_nl(), but excluding the newline
126 386 static inline StringView block_iter_get_line(BlockIter *bi)
127 {
128 386 StringView line = block_iter_get_line_with_nl(bi);
129 386 line.length -= (line.length > 0); // Trim the newline (if any)
130 386 return line;
131 }
132
133 // Like block_iter_get_line(), but always returning whole lines
134 18 static inline StringView get_current_line(BlockIter tmp)
135 {
136 18 block_iter_bol(&tmp);
137 18 return block_iter_get_line(&tmp);
138 }
139
140 // Like get_current_line(), but returning a struct that also includes the
141 // cursor offset (relative to BOL)
142 55 static inline CurrentLineRef get_current_line_and_offset(BlockIter tmp)
143 {
144 55 size_t offset = block_iter_bol(&tmp);
145 110 return (CurrentLineRef) {
146 55 .line = block_iter_get_line(&tmp),
147 .cursor_offset = offset,
148 };
149 }
150
151 #endif
152