Commit: c59760708c5c34d620221773c128f39e70d4ac85
Parent: 7b2a7bda201ec0b716f53108d9c2abff434c95bc
Author: Randy Palamar
Date: Mon, 17 Feb 2025 15:16:02 -0700
terminal: fix currently supported delete character modes
Diffstat:
2 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/build.sh b/build.sh
@@ -54,10 +54,12 @@ fuzz)
;;
fuzz_llvm)
clang ${testcflags} -O0 -fsanitize=fuzzer,address,undefined -o tests/test-fuzz tests/test-fuzz.c
- mkdir -p tests/llvm_fuzz_corpus
input=tests/llvm_fuzz_corpus
if [ ! -d ${input} ]; then
- ./tests/test-fuzz -merge=1 tests/llvm_fuzz_corpus tests/fuzz_in
+ mkdir -p tests/llvm_fuzz_corpus
+ # NOTE(rnp): libFuzzer can't handle arbitrary utf-8 inputs and seems
+ # to leak memory at startup (gg llvm devs)
+ ./tests/test-fuzz -detect_leaks=0 -merge=1 tests/llvm_fuzz_corpus tests/fuzz_in
else
./tests/test-fuzz tests/llvm_fuzz_corpus
fi
@@ -70,10 +72,10 @@ fuzz_results)
echo ${file}
./tests/test-fuzz-results "${file}"
done
- for file in tests/llvm_fuzz_corpus/*; do
- echo ${file}
- ./tests/test-fuzz-results "${file}"
- done
+ #for file in tests/llvm_fuzz_corpus/*; do
+ # echo ${file}
+ # ./tests/test-fuzz-results "${file}"
+ #done
exit 0
;;
*)
diff --git a/terminal.c b/terminal.c
@@ -562,8 +562,41 @@ erase_lines(Term *t, i32 count)
fb_scroll_up(t, t->cursor.pos.y, count);
}
-/* DCH: Delete Characters (NOTE: DCH is technically different but we are ignoring that) */
-/* ECH: Erase Characters */
+/* DCH: Delete <count> Characters */
+static void
+delete_characters(Term *t, i32 requested_count)
+{
+ iv2 cpos = t->cursor.pos;
+ /* TODO(rnp): if the cursor is outside the left/right margins do nothing */
+
+ TermView *tv = t->views + t->view_idx;
+ i32 count = MAX(0, MIN(requested_count, t->size.w - cpos.x));
+ i32 total = t->size.w - count;
+
+ Cell *dst = tv->fb.rows[cpos.y] + cpos.x;
+ if (dst->bg & ATTR_WDUMMY) dst--;
+ Cell *src = dst + count;
+
+ i32 dst_off = 0, src_off = 0;
+ for (i32 i = 0; i < total; i++) {
+ b32 dst_wide = (dst[i].bg & ATTR_WIDE) != 0;
+ b32 src_wide = (src[i].bg & ATTR_WIDE) != 0;
+
+ if (dst_wide && !src_wide)
+ dst[i + 1].bg &= ~ATTR_WDUMMY;
+
+ dst[i + dst_off] = src[i + src_off];
+
+ if (src_wide && !dst_wide) {
+ dst[i + 1] = src[i + 1];
+ i++;
+ }
+ }
+
+ fb_clear_region(t, cpos.y, cpos.y, t->size.w - count, t->size.w);
+}
+
+/* ECH: Erase <count> Characters */
static void
erase_characters(Term *t, i32 count)
{
@@ -962,7 +995,7 @@ handle_csi(Term *t, CSI *csi)
case 'K': erase_in_line(t, csi); break;
case 'L': insert_blank_lines(t, ORONE(csi->argv[0])); break;
case 'M': erase_lines(t, ORONE(csi->argv[0])); break;
- case 'P': erase_characters(t, ORONE(csi->argv[0])); break;
+ case 'P': delete_characters(t, ORONE(csi->argv[0])); break;
case 'X': erase_characters(t, ORONE(csi->argv[0])); break;
case 'S': fb_scroll_up(t, t->top, ORONE(csi->argv[0])); break;
case 'T': fb_scroll_down(t, t->top, ORONE(csi->argv[0])); break;