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 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
|
#ifndef __MLBUF_H
#define __MLBUF_H
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pcre2.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 smemo_s smemo_t; // A memoization of pcre2_match
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 *srules;
srule_node_t *range_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 *action_group;
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 *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;
int action_group;
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;
};
// smemo_t
struct smemo_s {
int looked;
bint_t look_offset;
int found;
bint_t start;
bint_t stop;
};
// srule_t
struct srule_s {
int type; // MLBUF_SRULE_TYPE_*
char *re;
char *re_end;
pcre2_code *cre;
pcre2_code *cre_end;
mark_t *range_a;
mark_t *range_b;
sblock_t style;
smemo_t memo;
smemo_t memo_end;
};
// 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_w_hint(buffer_t *self, bint_t line_index, bline_t *opt_hint, 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_undo_action_group(buffer_t *self);
int buffer_redo_action_group(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_action_group_ptr(buffer_t *self, int *action_group);
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_index_to_col(bline_t *bline, bint_t index, bint_t *ret_col);
int bline_count_chars(bline_t *bline);
// mark functions
int mark_block_delete_between(mark_t *self, mark_t *other);
int mark_block_get_between(mark_t *self, mark_t *other, char **ret_str, bint_t *ret_str_len);
int mark_block_get_top_left(mark_t *self, mark_t *other, bline_t **ret_bline, bint_t *ret_col);
int mark_block_insert_before(mark_t *self, char *data, bint_t data_len);
int mark_block_is_between(mark_t *self, mark_t *ma, mark_t *mb);
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_cmp(mark_t *a, mark_t *b, mark_t **optret_first, mark_t **optret_second);
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_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, pcre2_code *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, pcre2_code *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_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_nchars_between(mark_t *self, mark_t *other, bint_t *ret_nchars);
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_is_between(mark_t *self, mark_t *ma, mark_t *mb);
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, pcre2_code *cre, bline_t **optret_line, bint_t *optret_col, bint_t *optret_num_chars);
int mark_move_next_cre(mark_t *self, pcre2_code *cre);
int mark_move_next_cre_nudge(mark_t *self, pcre2_code *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, pcre2_code *cre, bline_t **optret_line, bint_t *optret_col, bint_t *optret_num_chars);
int mark_move_prev_cre(mark_t *self, pcre2_code *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_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, PCRE2_SIZE *ovector, int ovector_size);
int mark_swap(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);
size_t utf8_str_length(char *data, size_t len);
// 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);
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, PCRE2_SIZE *pcre_ovector, int pcre_ovecsize);
// Globals
extern pcre2_match_data *pcre2_md;
// 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_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']
#endif
|