From 3833252ad2883f309c562116dc0a31094d5cf8ce Mon Sep 17 00:00:00 2001 From: Boris Faure Date: Sat, 19 Jan 2019 23:02:51 +0100 Subject: [PATCH] termptyesc: extract REP handler to its own function + tests --- src/bin/termptyesc.c | 51 +++++++++++++++++++++++++++++++++----------- tests/rep.sh | 48 +++++++++++++++++++++++++++++++++++++++++ tests/tests.results | 1 + 3 files changed, 87 insertions(+), 13 deletions(-) create mode 100755 tests/rep.sh diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c index 87090171..0f6954f8 100644 --- a/src/bin/termptyesc.c +++ b/src/bin/termptyesc.c @@ -2836,10 +2836,43 @@ _handle_esc_csi_cbt(Termpty *ty, Eina_Unicode **ptr) TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); } +static void +_handle_esc_csi_rep(Termpty *ty, Eina_Unicode **ptr) +{ + Eina_Unicode *b = *ptr; + int arg = _csi_arg_get(ty, &b); + + if (arg == -CSI_ARG_ERROR) + return; + DBG("REP - Repeat last character %d times", arg); + + if (ty->last_char) + { + int screen_size = ty->w * ty->h; + int i; + + if (arg <= 0) + { + arg = 1; + } + else if (arg > screen_size) + { + /* if value is too large, restrict it to something that makes + * rendering correct (but not in the backlog, but who cares…) + */ + arg = screen_size + (arg % screen_size); + } + for (i = 0; i < arg; i++) + { + termpty_text_append(ty, &ty->last_char, 1); + } + } +} + static int _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, const Eina_Unicode *ce) { - int arg, i; + int arg; const Eina_Unicode *cc, *be; Eina_Unicode buf[4096], *b; @@ -2946,20 +2979,11 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, const Eina_Unicode *ce) case '`': _handle_esc_csi_cha(ty, &b, cc); break; - case 'a': // cursor right N (HPR) + case 'a': _handle_esc_csi_cuf(ty, &b); break; - case 'b': // repeat last char - if (ty->last_char) - { - arg = _csi_arg_get(ty, &b); - if (arg == -CSI_ARG_ERROR) - goto error; - TERMPTY_RESTRICT_FIELD(arg, 1, ty->w * ty->h); - DBG("REP: repeat %d times last char %x", arg, ty->last_char); - for (i = 0; i < arg; i++) - termpty_text_append(ty, &ty->last_char, 1); - } + case 'b': + _handle_esc_csi_rep(ty, &b); break; case 'c': // query device attributes DBG("query device attributes"); @@ -3123,6 +3147,7 @@ error: #if !defined(ENABLE_FUZZING) && !defined(ENABLE_TESTS) if (eina_log_domain_level_check(_termpty_log_dom, EINA_LOG_LEVEL_WARN)) { + int i; Eina_Strbuf *bf = eina_strbuf_new(); for (i = 0; c + i <= cc && i < 100; i++) diff --git a/tests/rep.sh b/tests/rep.sh new file mode 100755 index 00000000..520cd1dd --- /dev/null +++ b/tests/rep.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +# fill space with E +printf '\033[69;1;1;25;80\044x' + +#set color +printf '\033[46;31;3m' + + +# go too far +printf '\033[1;10H1\033[11111b1' + +# no arg +printf '\033[2;10H2\033[b2' + +# arg = 3 +printf '\033[3;10H3\033[3b1' + +# arg == 0 +printf '\033[4;10H4\033[0b4' + +#with snowmen +printf '\033[5;10H5☃\033[4b' + +# set top/bottom margins: +printf '\033[10;20r' +# allow left/right margins +printf '\033[?69h' +# set left/right margins: +printf '\033[6;15s' +# fill margin with @ +printf '\033[64;10;6;20;15\044x' + +# From inside to outside +printf '\033[12;12HA\033[20`A' + +# From outside (on the left) to outside (on the right) +printf '\033[12;2HB\033[40bB' + +# restrict cursor +printf '\033[?6h' + +# From inside to outside +printf '\033[2;2HC\033[40bC' + +# From inside to inside +printf '\033[4;4HD\033[6bD' + diff --git a/tests/tests.results b/tests/tests.results index ea768190..aa63534a 100644 --- a/tests/tests.results +++ b/tests/tests.results @@ -69,3 +69,4 @@ ech.sh 57a3ff127abbb3efa4082fab7de59970 text_append_after_right_margin.sh 26b334188d39e2b12538a6ca91ca168c cbt.sh 417cd352d3eba45d6016df67a0314444 hpa.sh 0f86ca83e072d41b89dd1a012f0749a7 +rep.sh b91ebb46fb5ebd95aa2cb87ad12bb4ba