diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-01-21 22:52:54 +0100 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-01-21 22:52:54 +0100 |
| commit | dcacc00e3750300617ba6e16eb346713f91a783a (patch) | |
| tree | 38e2d4fb5ed9d119711d4295c6eda4b014af73fd /examples/dte/edit.c | |
| parent | 58dac10aeb8f5a041c46bddbeaf4c7966a99b998 (diff) | |
| download | crep-dcacc00e3750300617ba6e16eb346713f91a783a.tar.gz | |
Remove testing data
Diffstat (limited to 'examples/dte/edit.c')
| -rw-r--r-- | examples/dte/edit.c | 394 |
1 files changed, 0 insertions, 394 deletions
diff --git a/examples/dte/edit.c b/examples/dte/edit.c deleted file mode 100644 index 337a1e9..0000000 --- a/examples/dte/edit.c +++ /dev/null @@ -1,394 +0,0 @@ -#include <string.h> -#include "edit.h" -#include "block.h" -#include "buffer.h" -#include "syntax/highlight.h" -#include "util/debug.h" -#include "util/list.h" -#include "util/xmalloc.h" - -enum { - BLOCK_EDIT_SIZE = 512 -}; - -static void sanity_check_blocks(const View *view, bool check_newlines) -{ -#if DEBUG >= 1 - const Buffer *buffer = view->buffer; - BUG_ON(list_empty(&buffer->blocks)); - BUG_ON(view->cursor.offset > view->cursor.blk->size); - - const Block *blk = BLOCK(buffer->blocks.next); - if (blk->size == 0) { - // The only time a zero-sized block is valid is when it's the - // first and only block - BUG_ON(buffer->blocks.next->next != &buffer->blocks); - BUG_ON(view->cursor.blk != blk); - return; - } - - bool cursor_seen = false; - block_for_each(blk, &buffer->blocks) { - const size_t size = blk->size; - BUG_ON(size == 0); - BUG_ON(size > blk->alloc); - if (blk == view->cursor.blk) { - cursor_seen = true; - } - if (check_newlines) { - BUG_ON(blk->data[size - 1] != '\n'); - } - if (DEBUG > 2) { - BUG_ON(count_nl(blk->data, size) != blk->nl); - } - } - BUG_ON(!cursor_seen); -#else - // Silence "unused parameter" warnings - (void)view; - (void)check_newlines; -#endif -} - -static size_t copy_count_nl(char *dst, const char *src, size_t len) -{ - size_t nl = 0; - for (size_t i = 0; i < len; i++) { - dst[i] = src[i]; - if (src[i] == '\n') { - nl++; - } - } - return nl; -} - -static size_t insert_to_current(BlockIter *cursor, const char *buf, size_t len) -{ - Block *blk = cursor->blk; - size_t offset = cursor->offset; - size_t size = blk->size + len; - - if (size > blk->alloc) { - blk->alloc = round_size_to_next_multiple(size, BLOCK_ALLOC_MULTIPLE); - xrenew(blk->data, blk->alloc); - } - memmove(blk->data + offset + len, blk->data + offset, blk->size - offset); - size_t nl = copy_count_nl(blk->data + offset, buf, len); - blk->nl += nl; - blk->size = size; - return nl; -} - -/* - * Combine current block and new data into smaller blocks: - * - Block _must_ contain whole lines - * - Block _must_ contain at least one line - * - Preferred maximum size of block is BLOCK_EDIT_SIZE - * - Size of any block can be larger than BLOCK_EDIT_SIZE - * only if there's a very long line - */ -static size_t split_and_insert(BlockIter *cursor, const char *buf, size_t len) -{ - Block *blk = cursor->blk; - ListHead *prev_node = blk->node.prev; - const char *buf1 = blk->data; - const char *buf2 = buf; - const char *buf3 = blk->data + cursor->offset; - size_t size1 = cursor->offset; - size_t size2 = len; - size_t size3 = blk->size - size1; - size_t total = size1 + size2 + size3; - size_t start = 0; // Beginning of new block - size_t size = 0; // Size of new block - size_t pos = 0; // Current position - size_t nl_added = 0; - - while (start < total) { - // Size of new block if next line would be added - size_t new_size = 0; - size_t copied = 0; - - if (pos < size1) { - const char *nl = memchr(buf1 + pos, '\n', size1 - pos); - if (nl) { - new_size = nl - buf1 + 1 - start; - } - } - - if (!new_size && pos < size1 + size2) { - size_t offset = 0; - if (pos > size1) { - offset = pos - size1; - } - - const char *nl = memchr(buf2 + offset, '\n', size2 - offset); - if (nl) { - new_size = size1 + nl - buf2 + 1 - start; - } - } - - if (!new_size && pos < total) { - size_t offset = 0; - if (pos > size1 + size2) { - offset = pos - size1 - size2; - } - - const char *nl = memchr(buf3 + offset, '\n', size3 - offset); - if (nl) { - new_size = size1 + size2 + nl - buf3 + 1 - start; - } else { - new_size = total - start; - } - } - - if (new_size <= BLOCK_EDIT_SIZE) { - // Fits - size = new_size; - pos = start + new_size; - if (pos < total) { - continue; - } - } else { - // Does not fit - if (!size) { - // One block containing one very long line - size = new_size; - pos = start + new_size; - } - } - - BUG_ON(!size); - Block *new = block_new(size); - if (start < size1) { - size_t avail = size1 - start; - size_t count = MIN(size, avail); - new->nl += copy_count_nl(new->data, buf1 + start, count); - copied += count; - start += count; - } - if (start >= size1 && start < size1 + size2) { - size_t offset = start - size1; - size_t avail = size2 - offset; - size_t count = MIN(size - copied, avail); - new->nl += copy_count_nl(new->data + copied, buf2 + offset, count); - copied += count; - start += count; - } - if (start >= size1 + size2) { - size_t offset = start - size1 - size2; - size_t avail = size3 - offset; - size_t count = size - copied; - BUG_ON(count > avail); - new->nl += copy_count_nl(new->data + copied, buf3 + offset, count); - copied += count; - start += count; - } - - new->size = size; - BUG_ON(copied != size); - list_add_before(&new->node, &blk->node); - - nl_added += new->nl; - size = 0; - } - - cursor->blk = BLOCK(prev_node->next); - while (cursor->offset > cursor->blk->size) { - cursor->offset -= cursor->blk->size; - cursor->blk = BLOCK(cursor->blk->node.next); - } - - nl_added -= blk->nl; - block_free(blk); - return nl_added; -} - -static size_t insert_bytes(BlockIter *cursor, const char *buf, size_t len) -{ - // Blocks must contain whole lines. - // Last char of buf might not be newline. - block_iter_normalize(cursor); - - Block *blk = cursor->blk; - size_t new_size = blk->size + len; - if (new_size <= blk->alloc || new_size <= BLOCK_EDIT_SIZE) { - return insert_to_current(cursor, buf, len); - } - - if (blk->nl <= 1 && !memchr(buf, '\n', len)) { - // Can't split this possibly very long line. - // insert_to_current() is much faster than split_and_insert(). - return insert_to_current(cursor, buf, len); - } - return split_and_insert(cursor, buf, len); -} - -void do_insert(View *view, const char *buf, size_t len) -{ - Buffer *buffer = view->buffer; - size_t nl = insert_bytes(&view->cursor, buf, len); - buffer->nl += nl; - sanity_check_blocks(view, true); - - view_update_cursor_y(view); - buffer_mark_lines_changed(buffer, view->cy, nl ? LONG_MAX : view->cy); - if (buffer->syn) { - hl_insert(buffer, view->cy, nl); - } -} - -static bool only_block(const Buffer *buffer, const Block *blk) -{ - return blk->node.prev == &buffer->blocks && blk->node.next == &buffer->blocks; -} - -char *do_delete(View *view, size_t len, bool sanity_check_newlines) -{ - ListHead *saved_prev_node = NULL; - Block *blk = view->cursor.blk; - size_t offset = view->cursor.offset; - size_t pos = 0; - size_t deleted_nl = 0; - - if (!len) { - return NULL; - } - - if (!offset) { - // The block where cursor is can become empty and thereby may be deleted - saved_prev_node = blk->node.prev; - } - - Buffer *buffer = view->buffer; - char *deleted = xmalloc(len); - while (pos < len) { - ListHead *next = blk->node.next; - size_t avail = blk->size - offset; - size_t count = MIN(len - pos, avail); - size_t nl = copy_count_nl(deleted + pos, blk->data + offset, count); - if (count < avail) { - memmove ( - blk->data + offset, - blk->data + offset + count, - avail - count - ); - } - - deleted_nl += nl; - buffer->nl -= nl; - blk->nl -= nl; - blk->size -= count; - if (!blk->size && !only_block(buffer, blk)) { - block_free(blk); - } - - offset = 0; - pos += count; - blk = BLOCK(next); - - BUG_ON(pos < len && next == &buffer->blocks); - } - - if (saved_prev_node) { - // Cursor was at beginning of a block that was possibly deleted - if (saved_prev_node->next == &buffer->blocks) { - view->cursor.blk = BLOCK(saved_prev_node); - view->cursor.offset = view->cursor.blk->size; - } else { - view->cursor.blk = BLOCK(saved_prev_node->next); - } - } - - blk = view->cursor.blk; - if ( - blk->size - && blk->data[blk->size - 1] != '\n' - && blk->node.next != &buffer->blocks - ) { - Block *next = BLOCK(blk->node.next); - size_t size = blk->size + next->size; - - if (size > blk->alloc) { - blk->alloc = round_size_to_next_multiple(size, BLOCK_ALLOC_MULTIPLE); - xrenew(blk->data, blk->alloc); - } - memcpy(blk->data + blk->size, next->data, next->size); - blk->size = size; - blk->nl += next->nl; - block_free(next); - } - - sanity_check_blocks(view, sanity_check_newlines); - - view_update_cursor_y(view); - buffer_mark_lines_changed(buffer, view->cy, deleted_nl ? LONG_MAX : view->cy); - if (buffer->syn) { - hl_delete(buffer, view->cy, deleted_nl); - } - return deleted; -} - -char *do_replace(View *view, size_t del, const char *buf, size_t ins) -{ - block_iter_normalize(&view->cursor); - Block *blk = view->cursor.blk; - size_t offset = view->cursor.offset; - - size_t avail = blk->size - offset; - if (del >= avail) { - goto slow; - } - - size_t new_size = blk->size + ins - del; - if (new_size > BLOCK_EDIT_SIZE) { - // Should split - if (blk->nl > 1 || memchr(buf, '\n', ins)) { - // Most likely can be split - goto slow; - } - } - - if (new_size > blk->alloc) { - blk->alloc = round_size_to_next_multiple(new_size, BLOCK_ALLOC_MULTIPLE); - xrenew(blk->data, blk->alloc); - } - - // Modification is limited to one block - Buffer *buffer = view->buffer; - char *ptr = blk->data + offset; - char *deleted = xmalloc(del); - size_t del_nl = copy_count_nl(deleted, ptr, del); - blk->nl -= del_nl; - buffer->nl -= del_nl; - - if (del != ins) { - memmove(ptr + ins, ptr + del, avail - del); - } - - size_t ins_nl = copy_count_nl(ptr, buf, ins); - blk->nl += ins_nl; - buffer->nl += ins_nl; - blk->size = new_size; - sanity_check_blocks(view, true); - view_update_cursor_y(view); - - // If the number of inserted and removed bytes are the same, some - // line(s) changed but the lines after them didn't move up or down - long max = (del_nl == ins_nl) ? view->cy + del_nl : LONG_MAX; - buffer_mark_lines_changed(buffer, view->cy, max); - - if (buffer->syn) { - hl_delete(buffer, view->cy, del_nl); - hl_insert(buffer, view->cy, ins_nl); - } - - return deleted; - -slow: - // The "sanity_check_newlines" argument of do_delete() is false here - // because it may be removing a terminating newline that do_insert() - // is going to insert again at a different position: - deleted = do_delete(view, del, false); - do_insert(view, buf, ins); - return deleted; -} |
