1 #ifndef __MLBUF_H
2 #define __MLBUF_H
3 
4 #include <stdio.h>
5 #include <stdint.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <unistd.h>
9 #include <pcre.h>
10 #include <utlist.h>
11 
12 // Typedefs
13 typedef struct buffer_s buffer_t; // A buffer of text (stored as a linked list of blines)
14 typedef struct bline_s bline_t; // A line in a buffer
15 typedef struct bline_char_s bline_char_t; // Metadata about a character in a bline
16 typedef struct baction_s baction_t; // An insert or delete action (used for undo)
17 typedef struct mark_s mark_t; // A mark in a buffer
18 typedef struct srule_s srule_t; // A style rule
19 typedef struct srule_node_s srule_node_t; // A node in a list of style rules
20 typedef struct sblock_s sblock_t; // A style of a particular character
21 typedef struct str_s str_t; // A dynamically resizeable string
22 typedef void (*buffer_callback_t)(buffer_t *buffer, baction_t *action, void *udata);
23 typedef intmax_t bint_t;
24 
25 // str_t
26 struct str_s {
27     char *data;
28     size_t len;
29     size_t cap;
30     ssize_t inc;
31 };
32 
33 // buffer_t
34 struct buffer_s {
35     bline_t *first_line;
36     bline_t *last_line;
37     bint_t byte_count;
38     bint_t line_count;
39     srule_node_t *single_srules;
40     srule_node_t *multi_srules;
41     baction_t *actions;
42     baction_t *action_tail;
43     baction_t *action_undone;
44     str_t registers[26];
45     mark_t *lettered_marks[26];
46     char *path;
47     struct stat st;
48     int is_unsaved;
49     char *data;
50     bint_t data_len;
51     int is_data_dirty;
52     int ref_count;
53     int tab_width;
54     buffer_callback_t callback;
55     void *callback_udata;
56     int mmap_fd;
57     char *mmap;
58     size_t mmap_len;
59     bline_char_t *slabbed_chars;
60     bline_t *slabbed_blines;
61     int num_applied_srules;
62     int is_in_open;
63     int is_in_callback;
64     int is_style_disabled;
65     int _is_in_undo;
66 };
67 
68 // bline_t
69 struct bline_s {
70     buffer_t *buffer;
71     char *data;
72     bint_t data_len;
73     bint_t data_cap;
74     bint_t line_index;
75     bint_t char_count;
76     bint_t char_vwidth;
77     bline_char_t *chars;
78     bint_t chars_cap;
79     mark_t *marks;
80     srule_t *bol_rule;
81     srule_t *eol_rule;
82     int is_chars_dirty;
83     int is_slabbed;
84     int is_data_slabbed;
85     bline_t *next;
86     bline_t *prev;
87 };
88 
89 // sblock_t
90 struct sblock_s {
91     uint16_t fg;
92     uint16_t bg;
93 };
94 
95 // bline_char_t
96 struct bline_char_s {
97     uint32_t ch;
98     int len;
99     bint_t index;
100     bint_t vcol;
101     bint_t index_to_vcol; // accessed via >chars[index], not >chars[char]
102     sblock_t style;
103 };
104 
105 // baction_t
106 struct baction_s {
107     int type; // MLBUF_BACTION_TYPE_*
108     buffer_t *buffer;
109     bline_t *start_line;
110     bint_t start_line_index;
111     bint_t start_col;
112     bline_t *maybe_end_line;
113     bint_t maybe_end_line_index;
114     bint_t maybe_end_col;
115     bint_t byte_delta;
116     bint_t char_delta;
117     bint_t line_delta;
118     char *data;
119     bint_t data_len;
120     baction_t *next;
121     baction_t *prev;
122 };
123 
124 // mark_t
125 struct mark_s {
126     bline_t *bline;
127     bint_t col;
128     bint_t target_col;
129     srule_t *range_srule;
130     char letter;
131     mark_t *next;
132     mark_t *prev;
133     int lefty;
134 };
135 
136 // srule_t
137 struct srule_s {
138     int type; // MLBUF_SRULE_TYPE_*
139     char *re;
140     char *re_end;
141     pcre *cre;
142     pcre *cre_end;
143     pcre_extra *crex;
144     pcre_extra *crex_end;
145     mark_t *range_a;
146     mark_t *range_b;
147     sblock_t style;
148 };
149 
150 // srule_node_t
151 struct srule_node_s {
152     srule_t *srule;
153     srule_node_t *next;
154     srule_node_t *prev;
155 };
156 
157 // buffer functions
158 buffer_t *buffer_new();
159 buffer_t *buffer_new_open(char *path);
160 mark_t *buffer_add_mark(buffer_t *self, bline_t *maybe_line, bint_t maybe_col);
161 mark_t *buffer_add_mark_ex(buffer_t *self, char letter, bline_t *maybe_line, bint_t maybe_col);
162 int buffer_get_lettered_mark(buffer_t *self, char letter, mark_t **ret_mark);
163 int buffer_destroy_mark(buffer_t *self, mark_t *mark);
164 int buffer_open(buffer_t *self, char *path);
165 int buffer_save(buffer_t *self);
166 int buffer_save_as(buffer_t *self, char *path, bint_t *optret_nbytes);
167 int buffer_write_to_file(buffer_t *self, FILE *fp, size_t *optret_nbytes);
168 int buffer_write_to_fd(buffer_t *self, int fd, size_t *optret_nbytes);
169 int buffer_get(buffer_t *self, char **ret_data, bint_t *ret_data_len);
170 int buffer_clear(buffer_t *self);
171 int buffer_set(buffer_t *self, char *data, bint_t data_len);
172 int buffer_set_mmapped(buffer_t *self, char *data, bint_t data_len);
173 int buffer_substr(buffer_t *self, bline_t *start_line, bint_t start_col, bline_t *end_line, bint_t end_col, char **ret_data, bint_t *ret_data_len, bint_t *ret_nchars);
174 int buffer_insert(buffer_t *self, bint_t offset, char *data, bint_t data_len, bint_t *optret_num_chars);
175 int buffer_delete(buffer_t *self, bint_t offset, bint_t num_chars);
176 int buffer_replace(buffer_t *self, bint_t offset, bint_t num_chars, char *data, bint_t data_len);
177 int buffer_insert_w_bline(buffer_t *self, bline_t *start_line, bint_t start_col, char *data, bint_t data_len, bint_t *optret_num_chars);
178 int buffer_delete_w_bline(buffer_t *self, bline_t *start_line, bint_t start_col, bint_t num_chars);
179 int buffer_replace_w_bline(buffer_t *self, bline_t *start_line, bint_t start_col, bint_t num_chars, char *data, bint_t data_len);
180 int buffer_get_bline(buffer_t *self, bint_t line_index, bline_t **ret_bline);
181 int buffer_get_bline_col(buffer_t *self, bint_t offset, bline_t **ret_bline, bint_t *ret_col);
182 int buffer_get_offset(buffer_t *self, bline_t *bline, bint_t col, bint_t *ret_offset);
183 int buffer_undo(buffer_t *self);
184 int buffer_redo(buffer_t *self);
185 int buffer_add_srule(buffer_t *self, srule_t *srule);
186 int buffer_remove_srule(buffer_t *self, srule_t *srule);
187 int buffer_set_callback(buffer_t *self, buffer_callback_t fn_cb, void *udata);
188 int buffer_set_tab_width(buffer_t *self, int tab_width);
189 int buffer_set_styles_enabled(buffer_t *self, int is_enabled);
190 int buffer_apply_styles(buffer_t *self, bline_t *start_line, bint_t line_delta);
191 int buffer_register_set(buffer_t *self, char reg, char *data, size_t data_len);
192 int buffer_register_append(buffer_t *self, char reg, char *data, size_t data_len);
193 int buffer_register_prepend(buffer_t *self, char reg, char *data, size_t data_len);
194 int buffer_register_clear(buffer_t *self, char reg);
195 int buffer_register_get(buffer_t *self, char reg, int dup, char **ret_data, size_t *ret_data_len);
196 int buffer_destroy(buffer_t *self);
197 
198 // bline functions
199 int bline_insert(bline_t *self, bint_t col, char *data, bint_t data_len, bint_t *ret_num_chars);
200 int bline_delete(bline_t *self, bint_t col, bint_t num_chars);
201 int bline_replace(bline_t *self, bint_t col, bint_t num_chars, char *data, bint_t data_len);
202 int bline_get_col(bline_t *self, bint_t index, bint_t *ret_col);
203 int bline_get_col_from_vcol(bline_t *self, bint_t vcol, bint_t *ret_col);
204 int bline_count_chars(bline_t *bline);
205 
206 // mark functions
207 int mark_clone(mark_t *self, mark_t **ret_mark);
208 int mark_clone_w_letter(mark_t *self, char letter, mark_t **ret_mark);
209 int mark_delete_after(mark_t *self, bint_t num_chars);
210 int mark_delete_before(mark_t *self, bint_t num_chars);
211 int mark_delete_between_mark(mark_t *self, mark_t *other);
212 int mark_destroy(mark_t *self);
213 int mark_find_bracket_pair(mark_t *self, bint_t max_chars, bline_t **ret_line, bint_t *ret_col, bint_t *ret_brkt);
214 int mark_find_bracket_top(mark_t *self, bint_t max_chars, bline_t **ret_line, bint_t *ret_col, bint_t *ret_brkt);
215 int mark_find_next_cre(mark_t *self, pcre *cre, bline_t **ret_line, bint_t *ret_col, bint_t *ret_num_chars);
216 int mark_find_next_re(mark_t *self, char *re, bint_t re_len, bline_t **ret_line, bint_t *ret_col, bint_t *ret_num_chars);
217 int mark_find_next_str(mark_t *self, char *str, bint_t str_len, bline_t **ret_line, bint_t *ret_col, bint_t *ret_num_chars);
218 int mark_find_prev_cre(mark_t *self, pcre *cre, bline_t **ret_line, bint_t *ret_col, bint_t *ret_num_chars);
219 int mark_find_prev_re(mark_t *self, char *re, bint_t re_len, bline_t **ret_line, bint_t *ret_col, bint_t *ret_num_chars);
220 int mark_find_prev_str(mark_t *self, char *str, bint_t str_len, bline_t **ret_line, bint_t *ret_col, bint_t *ret_num_chars);
221 int mark_get_between_mark(mark_t *self, mark_t *other, char **ret_str, bint_t *ret_str_len);
222 int mark_get_char_after(mark_t *self, uint32_t *ret_char);
223 int mark_get_char_before(mark_t *self, uint32_t *ret_char);
224 int mark_get_offset(mark_t *self, bint_t *ret_offset);
225 int mark_insert_after(mark_t *self, char *data, bint_t data_len);
226 int mark_insert_before(mark_t *self, char *data, bint_t data_len);
227 int mark_is_after_col_minus_lefties(mark_t *self, bint_t col);
228 int mark_is_at_bol(mark_t *self);
229 int mark_is_at_eol(mark_t *self);
230 int mark_is_at_word_bound(mark_t *self, int side);
231 int mark_is_eq(mark_t *self, mark_t *other);
232 int mark_is_gte(mark_t *self, mark_t *other);
233 int mark_is_gt(mark_t *self, mark_t *other);
234 int mark_is_lte(mark_t *self, mark_t *other);
235 int mark_is_lt(mark_t *self, mark_t *other);
236 int mark_join(mark_t *self, mark_t *other);
237 int mark_move_beginning(mark_t *self);
238 int mark_move_bol(mark_t *self);
239 int mark_move_bracket_pair_ex(mark_t *self, bint_t max_chars, bline_t **optret_line, bint_t *optret_col, bint_t *optret_num_chars);
240 int mark_move_bracket_pair(mark_t *self, bint_t max_chars);
241 int mark_move_bracket_top_ex(mark_t *self, bint_t max_chars, bline_t **optret_line, bint_t *optret_col, bint_t *optret_num_chars);
242 int mark_move_bracket_top(mark_t *self, bint_t max_chars);
243 int mark_move_by(mark_t *self, bint_t char_delta);
244 int mark_move_col(mark_t *self, bint_t col);
245 int mark_move_end(mark_t *self);
246 int mark_move_eol(mark_t *self);
247 int mark_move_next_cre_ex(mark_t *self, pcre *cre, bline_t **optret_line, bint_t *optret_col, bint_t *optret_num_chars);
248 int mark_move_next_cre(mark_t *self, pcre *cre);
249 int mark_move_next_cre_nudge(mark_t *self, pcre *cre);
250 int mark_move_next_re_ex(mark_t *self, char *re, bint_t re_len, bline_t **optret_line, bint_t *optret_col, bint_t *optret_num_chars);
251 int mark_move_next_re(mark_t *self, char *re, bint_t re_len);
252 int mark_move_next_re_nudge(mark_t *self, char *re, bint_t re_len);
253 int mark_move_next_str_ex(mark_t *self, char *str, bint_t str_len, bline_t **optret_line, bint_t *optret_col, bint_t *optret_num_chars);
254 int mark_move_next_str(mark_t *self, char *str, bint_t str_len);
255 int mark_move_next_str_nudge(mark_t *self, char *str, bint_t str_len);
256 int mark_move_offset(mark_t *self, bint_t offset);
257 int mark_move_prev_cre_ex(mark_t *self, pcre *cre, bline_t **optret_line, bint_t *optret_col, bint_t *optret_num_chars);
258 int mark_move_prev_cre(mark_t *self, pcre *cre);
259 int mark_move_prev_re_ex(mark_t *self, char *re, bint_t re_len, bline_t **optret_line, bint_t *optret_col, bint_t *optret_num_chars);
260 int mark_move_prev_re(mark_t *self, char *re, bint_t re_len);
261 int mark_move_prev_str_ex(mark_t *self, char *str, bint_t str_len, bline_t **optret_line, bint_t *optret_col, bint_t *optret_num_chars);
262 int mark_move_prev_str(mark_t *self, char *str, bint_t str_len);
263 int mark_move_to(mark_t *self, bint_t line_index, bint_t col);
264 int mark_move_to_w_bline(mark_t *self, bline_t *bline, bint_t col);
265 int mark_move_vert(mark_t *self, bint_t line_delta);
266 int mark_replace_between_mark(mark_t *self, mark_t *other, char *data, bint_t data_len);
267 int mark_replace(mark_t *self, bint_t num_chars, char *data, bint_t data_len);
268 int mark_set_pcre_capture(int *rc, int *ovector, int ovector_size);
269 int mark_swap_with_mark(mark_t *self, mark_t *other);
270 
271 // srule functions
272 srule_t *srule_new_single(char *re, bint_t re_len, int caseless, uint16_t fg, uint16_t bg);
273 srule_t *srule_new_multi(char *re, bint_t re_len, char *re_end, bint_t re_end_len, uint16_t fg, uint16_t bg);
274 srule_t *srule_new_range(mark_t *range_a, mark_t *range_b, uint16_t fg, uint16_t bg);
275 int srule_destroy(srule_t *srule);
276 
277 // utf8 functions
278 int utf8_char_length(char c);
279 int utf8_char_to_unicode(uint32_t *out, const char *c, const char *stop);
280 int utf8_unicode_to_char(char *out, uint32_t c);
281 
282 // util functions
283 void *recalloc(void *ptr, size_t orig_num, size_t new_num, size_t el_size);
284 void _mark_mark_move_inner(mark_t *mark, bline_t *bline_target, bint_t col, int do_set_target, int do_style);
285 void str_append_stop(str_t *str, char *data, char *data_stop);
286 void str_append(str_t *str, char *data);
287 void str_append_char(str_t *str, char c);
288 void str_append_len(str_t *str, char *data, size_t data_len);
289 void str_prepend_stop(str_t *str, char *data, char *data_stop);
290 void str_prepend(str_t *str, char *data);
291 void str_prepend_len(str_t *str, char *data, size_t data_len);
292 void str_set(str_t *str, char *data);
293 void str_set_len(str_t *str, char *data, size_t data_len);
294 void str_put_len(str_t *str, char *data, size_t data_len, int is_prepend);
295 void str_ensure_cap(str_t *str, size_t cap);
296 void str_clear(str_t *str);
297 void str_free(str_t *str);
298 void str_append_replace_with_backrefs(str_t *str, char *subj, char *repl, int pcre_rc, int *pcre_ovector, int pcre_ovecsize);
299 
300 // Macros
301 #define MLBUF_DEBUG 1
302 
303 // #define MLBUF_LARGE_FILE_SIZE 10485760
304 #define MLBUF_LARGE_FILE_SIZE 0
305 
306 #define MLBUF_OK 0
307 #define MLBUF_ERR 1
308 
309 #define MLBUF_BACTION_TYPE_INSERT 0
310 #define MLBUF_BACTION_TYPE_DELETE 1
311 
312 #define MLBUF_SRULE_TYPE_SINGLE 0
313 #define MLBUF_SRULE_TYPE_MULTI 1
314 #define MLBUF_SRULE_TYPE_RANGE 2
315 
316 #define MLBUF_MIN(a,b) (((a)<(b)) ? (a) : (b))
317 #define MLBUF_MAX(a,b) (((a)>(b)) ? (a) : (b))
318 
319 #define MLBUF_BLINE_DATA_STOP(bline) ((bline)->data + ((bline)->data_len))
320 
321 #define MLBUF_DEBUG_PRINTF(fmt, ...) do { \
322     if (MLBUF_DEBUG) { \
323         fprintf(stderr, "%lu ", time(0)); \
324         fprintf(stderr, (fmt), __VA_ARGS__); \
325         fflush(stderr); \
326     } \
327 } while (0)
328 
329 #define MLBUF_BLINE_ENSURE_CHARS(b) do { \
330     if ((b)->is_chars_dirty) { \
331         bline_count_chars(b); \
332     } \
333 } while (0)
334 
335 #define MLBUF_MAKE_GT_EQ0(v) if ((v) < 0) v = 0
336 
337 #define MLBUF_INIT_PCRE_EXTRA(n) \
338     pcre_extra n = { .flags = PCRE_EXTRA_MATCH_LIMIT_RECURSION, .match_limit_recursion = 256 }
339 
340 #define MLBUF_ENSURE_AZ(c) \
341     if ((c) < 'a' || (c) > 'z') return MLBUF_ERR
342 
343 #define MLBUF_REG_PTR(buf, lett) \
344     &((buf)->registers[(lett) - 'a'])
345 
346 #define MLBUF_LETT_MARK(buf, lett) \
347     (buf)->lettered_marks[(lett) - 'a']
348 
349 #ifndef PCRE_STUDY_JIT_COMPILE
350 #define PCRE_STUDY_JIT_COMPILE 0
351 #endif
352 
353 #ifdef PCRE_CONFIG_JIT
354 #define pcre_free_study_ex pcre_free_study
355 #else
356 #define pcre_free_study_ex pcre_free
357 #endif
358 
359 #endif
360