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