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