dte test coverage


Directory: ./
File: src/block-iter.h
Date: 2025-05-08 15:05:54
Exec Total Coverage
Lines: 29 39 74.4%
Functions: 8 9 88.9%
Branches: 10 16 62.5%

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/unicode.h"
11
12 // An iterator used to represent the cursor position for each View of a
13 // Buffer (see View::cursor) and also as a means for accessing/iterating
14 // the Blocks that make up the text contents of a Buffer (see Buffer::blocks).
15 typedef struct {
16 Block *blk; // The Block this iterator/cursor currently points to
17 const ListHead *head; // A pointer to the Buffer::blocks that owns `blk`
18 size_t offset; // The current position within `blk->data`
19 } BlockIter;
20
21 10 static inline void block_iter_bof(BlockIter *bi)
22 {
23 10 bi->blk = BLOCK(bi->head->next);
24 10 bi->offset = 0;
25 10 }
26
27 8 static inline void block_iter_eof(BlockIter *bi)
28 {
29 8 bi->blk = BLOCK(bi->head->prev);
30 8 bi->offset = bi->blk->size;
31 8 }
32
33 320 static inline bool block_iter_is_eof(const BlockIter *bi)
34 {
35
3/4
✓ Branch 0 (2→3) taken 58 times.
✓ Branch 1 (2→4) taken 262 times.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→5) taken 58 times.
320 return bi->offset == bi->blk->size && bi->blk->node.next == bi->head;
36 }
37
38 268 static inline bool block_iter_is_bol(const BlockIter *bi)
39 {
40 // See also: Block invariants mentioned in sanity_check_blocks()
41
4/4
✓ Branch 0 (2→3) taken 178 times.
✓ Branch 1 (2→5) taken 90 times.
✓ Branch 2 (3→4) taken 103 times.
✓ Branch 3 (3→5) taken 75 times.
268 return bi->offset == 0 || bi->blk->data[bi->offset - 1] == '\n';
42 }
43
44 static inline bool block_iter_is_eol(const BlockIter *bi)
45 {
46 const Block *blk = bi->blk;
47 size_t offset = bi->offset;
48 if (offset == blk->size) {
49 if (blk->node.next == bi->head) {
50 // EOF
51 return true;
52 }
53 // Normalize
54 blk = BLOCK(blk->node.next);
55 offset = 0;
56 }
57 return blk->data[offset] == '\n';
58 }
59
60 1288 static inline void block_iter_normalize(BlockIter *bi)
61 {
62 1288 const Block *blk = bi->blk;
63
3/4
✓ Branch 0 (2→3) taken 98 times.
✓ Branch 1 (2→5) taken 1190 times.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→5) taken 98 times.
1288 if (bi->offset == blk->size && blk->node.next != bi->head) {
64 bi->blk = BLOCK(blk->node.next);
65 bi->offset = 0;
66 }
67 1288 }
68
69 size_t block_iter_eat_line(BlockIter *bi);
70 size_t block_iter_next_line(BlockIter *bi);
71 size_t block_iter_prev_line(BlockIter *bi);
72 size_t block_iter_next_char(BlockIter *bi, CodePoint *up);
73 size_t block_iter_prev_char(BlockIter *bi, CodePoint *up);
74 size_t block_iter_next_column(BlockIter *bi);
75 size_t block_iter_prev_column(BlockIter *bi);
76 size_t block_iter_bol(BlockIter *bi);
77 size_t block_iter_eol(BlockIter *bi);
78 size_t block_iter_skip_blanks_fwd(BlockIter *bi);
79 size_t block_iter_skip_blanks_bwd(BlockIter *bi);
80 bool block_iter_find_non_empty_line_bwd(BlockIter *bi);
81 void block_iter_back_bytes(BlockIter *bi, size_t count);
82 void block_iter_skip_bytes(BlockIter *bi, size_t count);
83 void block_iter_goto_offset(BlockIter *bi, size_t offset);
84 void block_iter_goto_line(BlockIter *bi, size_t line);
85 size_t block_iter_get_offset(const BlockIter *bi) WARN_UNUSED_RESULT;
86 size_t block_iter_get_char(const BlockIter *bi, CodePoint *up) WARN_UNUSED_RESULT;
87 char *block_iter_get_bytes(const BlockIter *bi, size_t len) WARN_UNUSED_RESULT;
88 StringView block_iter_get_line_with_nl(BlockIter *bi);
89
90 // Like block_iter_get_line_with_nl(), but excluding the newline
91 374 static inline StringView block_iter_get_line(BlockIter *bi)
92 {
93 374 StringView line = block_iter_get_line_with_nl(bi);
94 374 line.length -= (line.length > 0); // Trim the newline (if any)
95 374 return line;
96 }
97
98 // Like block_iter_get_line(), but always returning whole lines
99 14 static inline StringView get_current_line(const BlockIter *bi)
100 {
101 14 BlockIter tmp = *bi;
102 14 block_iter_bol(&tmp);
103 14 return block_iter_get_line(&tmp);
104 }
105
106 // Like get_current_line(), but returning the cursor offset (relative to BOL)
107 // and setting `line` via an out-param
108 52 static inline size_t get_current_line_and_offset(const BlockIter *bi, StringView *line)
109 {
110 52 BlockIter tmp = *bi;
111 52 size_t count = block_iter_bol(&tmp);
112 52 *line = block_iter_get_line(&tmp);
113 52 return count;
114 }
115
116 #endif
117