termptyesc: handle CSI_ARG_ERROR

This commit is contained in:
Boris Faure 2018-12-14 20:45:12 +01:00
parent a4418b85f6
commit 6931f96d0d
1 changed files with 765 additions and 650 deletions

View File

@ -85,14 +85,22 @@ _safechar(unsigned int c)
return _str;
}
enum csi_arg_error {
CSI_ARG_NO_VALUE = 1,
CSI_ARG_ERROR = 2
};
static int
_csi_arg_get(Eina_Unicode **ptr)
_csi_arg_get(Termpty *ty, Eina_Unicode **ptr)
{
Eina_Unicode *b = *ptr;
int sum = 0;
if (!b)
goto error;
{
*ptr = NULL;
return -CSI_ARG_NO_VALUE;
}
/* Skip potential '?', '>'.... */
while ((*b) && ( (*b) != ';' && ((*b) < '0' || (*b) > '9')))
@ -102,16 +110,22 @@ _csi_arg_get(Eina_Unicode **ptr)
{
b++;
*ptr = b;
return -1;
return -CSI_ARG_NO_VALUE;
}
if (!*b)
goto error;
if (*b == '\0')
{
*ptr = NULL;
return -CSI_ARG_NO_VALUE;
}
while ((*b >= '0') && (*b <= '9'))
{
if (sum > INT32_MAX/10 )
{
ERR("Invalid sequence: argument is too large");
goto error;
}
sum *= 10;
sum += *b - '0';
b++;
@ -119,15 +133,24 @@ _csi_arg_get(Eina_Unicode **ptr)
if (*b == ';')
{
if (b[1])
b++;
}
*ptr = b;
}
else if (*b == '\0')
{
*ptr = NULL;
}
else
{
*ptr = b;
}
return sum;
error:
ty->decoding_error = EINA_TRUE;
*ptr = NULL;
return -1;
return -CSI_ARG_ERROR;
}
static void
@ -224,11 +247,13 @@ _move_cursor_to_origin(Termpty *ty)
static void
_handle_esc_csi_reset_mode(Termpty *ty, Eina_Unicode cc, Eina_Unicode *b)
_handle_esc_csi_reset_mode(Termpty *ty, Eina_Unicode cc, Eina_Unicode *b,
const Eina_Unicode * const end)
{
int mode = 0, priv = 0, arg;
if (cc == 'h') mode = 1;
if (cc == 'h')
mode = 1;
if (*b == '?')
{
priv = 1;
@ -236,15 +261,16 @@ _handle_esc_csi_reset_mode(Termpty *ty, Eina_Unicode cc, Eina_Unicode *b)
}
if (priv) /* DEC Private Mode Reset (DECRST) */
{
while (b)
{
arg = _csi_arg_get(&b);
if (b)
while (b && b <= end)
{
arg = _csi_arg_get(ty, &b);
// complete-ish list here:
// http://ttssh2.sourceforge.jp/manual/en/about/ctrlseq.html
switch (arg)
{
case -CSI_ARG_ERROR:
return;
/* TODO: -CSI_ARG_NO_VALUE */
case 1:
ty->termstate.appcursor = mode;
break;
@ -475,16 +501,17 @@ _handle_esc_csi_reset_mode(Termpty *ty, Eina_Unicode cc, Eina_Unicode *b)
}
}
}
}
else /* Reset Mode (RM) */
{
while (b)
{
arg = _csi_arg_get(&b);
if (b)
while (b && b <= end)
{
arg = _csi_arg_get(ty, &b);
switch (arg)
{
case -CSI_ARG_ERROR:
return;
/* TODO: -CSI_ARG_NO_VALUE */
case 1:
ty->termstate.appcursor = mode;
break;
@ -507,7 +534,6 @@ _handle_esc_csi_reset_mode(Termpty *ty, Eina_Unicode cc, Eina_Unicode *b)
}
}
}
}
static int
_csi_truecolor_arg_get(Eina_Unicode **ptr)
@ -666,10 +692,10 @@ _handle_esc_csi_truecolor_cmyk(Termpty *ty, Eina_Unicode **ptr)
}
static void
_handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr)
_handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr,
const Eina_Unicode * const end)
{
Eina_Unicode *b = *ptr;
int first = 1;
if (b && (*b == '>'))
{ // key resources used by xterm
@ -678,16 +704,14 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr)
return;
}
DBG("color set");
while (b)
while (b && b <= end)
{
int arg = _csi_arg_get(&b);
if ((first) && (!b))
termpty_reset_att(&(ty->termstate.att));
else if (b)
{
first = 0;
int arg = _csi_arg_get(ty, &b);
switch (arg)
{
case -CSI_ARG_ERROR:
return;
/* TODO: -CSI_ARG_NO_VALUE */
case 0: // reset to normal
termpty_reset_att(&(ty->termstate.att));
break;
@ -761,9 +785,12 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr)
ty->termstate.att.fgintense = 0;
break;
case 38: // xterm 256 fg color ???
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
switch (arg)
{
case -CSI_ARG_ERROR:
return;
/* TODO: -CSI_ARG_NO_VALUE */
case 1:
ty->termstate.att.fg256 = 0;
ty->termstate.att.fg = COL_INVIS;
@ -791,19 +818,16 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr)
break;
case 5:
// then get next arg - should be color index 0-255
arg = _csi_arg_get(&b);
if (!b)
{
ERR("Failed xterm 256 color fg esc val");
ty->decoding_error = EINA_TRUE;
}
else if (arg < 0 || arg > 255)
arg = _csi_arg_get(ty, &b);
if (arg <= -CSI_ARG_ERROR || arg > 255)
{
ERR("Invalid fg color %d", arg);
ty->decoding_error = EINA_TRUE;
}
else
{
if (arg == -CSI_ARG_NO_VALUE)
arg = 0;
ty->termstate.att.fg256 = 1;
ty->termstate.att.fg = arg;
}
@ -832,9 +856,12 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr)
ty->termstate.att.bgintense = 0;
break;
case 48: // xterm 256 bg color ???
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
switch (arg)
{
case -CSI_ARG_ERROR:
return;
/* TODO: -CSI_ARG_NO_VALUE */
case 1:
ty->termstate.att.bg256 = 0;
ty->termstate.att.bg = COL_INVIS;
@ -862,19 +889,16 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr)
break;
case 5:
// then get next arg - should be color index 0-255
arg = _csi_arg_get(&b);
if (!b)
{
ERR("Failed xterm 256 color bg esc val");
ty->decoding_error = EINA_TRUE;
}
else if (arg < 0 || arg > 255)
arg = _csi_arg_get(ty, &b);
if (arg <= -CSI_ARG_ERROR || arg > 255)
{
ERR("Invalid bg color %d", arg);
ty->decoding_error = EINA_TRUE;
}
else
{
if (arg == -CSI_ARG_NO_VALUE)
arg = 0;
ty->termstate.att.bg256 = 1;
ty->termstate.att.bg = arg;
}
@ -922,7 +946,9 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr)
break;
case 98: // xterm 256 fg color ???
// now check if next arg is 5
arg = _csi_arg_get(&b);
/* TODO: shall be like 38 ? */
/* TODO: -CSI_ARG_NO_VALUE */
arg = _csi_arg_get(ty, &b);
if (arg != 5)
{
ERR("Failed xterm 256 color fg esc 5 (got %d)", arg);
@ -931,19 +957,16 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr)
else
{
// then get next arg - should be color index 0-255
arg = _csi_arg_get(&b);
if (!b)
{
ERR("Failed xterm 256 color fg esc val");
ty->decoding_error = EINA_TRUE;
}
else if (arg < 0 || arg > 255)
arg = _csi_arg_get(ty, &b);
if (arg <= -CSI_ARG_ERROR || arg > 255)
{
ERR("Invalid fg color %d", arg);
ty->decoding_error = EINA_TRUE;
}
else
{
if (arg == -CSI_ARG_NO_VALUE)
arg = 0;
ty->termstate.att.fg256 = 1;
ty->termstate.att.fg = arg;
}
@ -969,7 +992,8 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr)
break;
case 108: // xterm 256 bg color ???
// now check if next arg is 5
arg = _csi_arg_get(&b);
/* TODO: -CSI_ARG_NO_VALUE */
arg = _csi_arg_get(ty, &b);
if (arg != 5)
{
ERR("Failed xterm 256 color bg esc 5 (got %d)", arg);
@ -978,19 +1002,16 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr)
else
{
// then get next arg - should be color index 0-255
arg = _csi_arg_get(&b);
if (!b)
{
ERR("Failed xterm 256 color bg esc val");
ty->decoding_error = EINA_TRUE;
}
else if (arg < 0 || arg > 255)
arg = _csi_arg_get(ty, &b);
if (arg <= -CSI_ARG_ERROR || arg > 255)
{
ERR("Invalid bg color %d", arg);
ty->decoding_error = EINA_TRUE;
}
else
{
if (arg == -CSI_ARG_NO_VALUE)
arg = 0;
ty->termstate.att.bg256 = 1;
ty->termstate.att.bg = arg;
}
@ -1009,7 +1030,6 @@ _handle_esc_csi_color_set(Termpty *ty, Eina_Unicode **ptr)
}
}
}
}
static void
_handle_esc_csi_dsr(Termpty *ty, Eina_Unicode *b)
@ -1029,9 +1049,11 @@ _handle_esc_csi_dsr(Termpty *ty, Eina_Unicode *b)
question_mark = EINA_TRUE;
b++;
}
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
switch (arg)
{
case -CSI_ARG_ERROR:
return;
case 5:
if (question_mark)
{
@ -1137,7 +1159,7 @@ _handle_esc_csi_dsr(Termpty *ty, Eina_Unicode *b)
if (question_mark)
{
/* DSR-DECCKSR (Memory Checksum) */
int pid = _csi_arg_get(&b);
int pid = _csi_arg_get(ty, &b);
len = snprintf(bf, sizeof(bf), "\033P%u!~0000\033\\", pid);
termpty_write(ty, bf, len);
}
@ -1161,6 +1183,7 @@ _handle_esc_csi_dsr(Termpty *ty, Eina_Unicode *b)
ty->decoding_error = EINA_TRUE;
}
break;
/* TODO: -CSI_ARG_NO_VALUE */
default:
WRN("unhandled DSR (dec specific: %s) %d",
(question_mark)? "yes": "no", arg);
@ -1172,18 +1195,22 @@ _handle_esc_csi_dsr(Termpty *ty, Eina_Unicode *b)
static void
_handle_esc_csi_decslrm(Termpty *ty, Eina_Unicode **b)
{
int left = _csi_arg_get(b);
int right = _csi_arg_get(b);
int left = _csi_arg_get(ty, b);
int right = _csi_arg_get(ty, b);
DBG("DECSLRM (%d;%d) Set Left and Right Margins", left, right);
if ((left == -CSI_ARG_ERROR) || (right == -CSI_ARG_ERROR))
goto bad;
TERMPTY_RESTRICT_FIELD(left, 1, ty->w);
if (right < 1)
right = ty->w;
TERMPTY_RESTRICT_FIELD(right, 3, ty->w+1);
if (left >= right) goto bad;
if (right - left < 2) goto bad;
if (left >= right)
goto bad;
if (right - left < 2)
goto bad;
if (right == ty->w)
right = 0;
@ -1202,10 +1229,12 @@ bad:
static void
_handle_esc_csi_decstbm(Termpty *ty, Eina_Unicode **b)
{
int top = _csi_arg_get(b);
int bottom = _csi_arg_get(b);
int top = _csi_arg_get(ty, b);
int bottom = _csi_arg_get(ty, b);
DBG("DECSTBM (%d;%d) Set Top and Bottom Margins", top, bottom);
if ((top == -CSI_ARG_ERROR) || (bottom == -CSI_ARG_ERROR))
goto bad;
TERMPTY_RESTRICT_FIELD(top, 1, ty->h);
TERMPTY_RESTRICT_FIELD(bottom, 1, ty->h+1);
@ -1293,16 +1322,25 @@ _clean_up_rect_coordinates(Termpty *ty,
static void
_handle_esc_csi_decfra(Termpty *ty, Eina_Unicode **b)
{
int c = _csi_arg_get(b);
int c = _csi_arg_get(ty, b);
int top = _csi_arg_get(b);
int left = _csi_arg_get(b);
int bottom = _csi_arg_get(b);
int right = _csi_arg_get(b);
int top = _csi_arg_get(ty, b);
int left = _csi_arg_get(ty, b);
int bottom = _csi_arg_get(ty, b);
int right = _csi_arg_get(ty, b);
int len;
DBG("DECFRA (%d; %d;%d;%d;%d) Fill Rectangular Area",
c, top, left, bottom, right);
if ((c == -CSI_ARG_ERROR) ||
(top == -CSI_ARG_ERROR) ||
(left == -CSI_ARG_ERROR) ||
(bottom == -CSI_ARG_ERROR) ||
(right == -CSI_ARG_ERROR))
return;
/* TODO: -CSI_ARG_NO_VALUE */
if (! ((c >= 32 && c <= 126) || (c >= 160 && c <= 255)))
return;
@ -1321,15 +1359,21 @@ _handle_esc_csi_decfra(Termpty *ty, Eina_Unicode **b)
static void
_handle_esc_csi_decera(Termpty *ty, Eina_Unicode **b)
{
int top = _csi_arg_get(b);
int left = _csi_arg_get(b);
int bottom = _csi_arg_get(b);
int right = _csi_arg_get(b);
int top = _csi_arg_get(ty ,b);
int left = _csi_arg_get(ty, b);
int bottom = _csi_arg_get(ty, b);
int right = _csi_arg_get(ty, b);
int len;
DBG("DECERA (%d;%d;%d;%d) Erase Rectangular Area",
top, left, bottom, right);
if ((top == -CSI_ARG_ERROR) ||
(left == -CSI_ARG_ERROR) ||
(bottom == -CSI_ARG_ERROR) ||
(right == -CSI_ARG_ERROR))
return;
if (_clean_up_rect_coordinates(ty, &top, &left, &bottom, &right) < 0)
return;
@ -1347,8 +1391,11 @@ _handle_esc_csi_cursor_pos_set(Termpty *ty, Eina_Unicode **b,
{
int cx = 0, cy = 0;
ty->termstate.wrapnext = 0;
cy = _csi_arg_get(b);
cx = _csi_arg_get(b);
cy = _csi_arg_get(ty, b);
cx = _csi_arg_get(ty, b);
if ((cx == -CSI_ARG_ERROR) || (cy == -CSI_ARG_ERROR))
return;
DBG("cursor pos set (%s) (%d;%d)", (*cc == 'H') ? "CUP" : "HVP",
cx, cy);
@ -1383,13 +1430,17 @@ _handle_esc_csi_cursor_pos_set(Termpty *ty, Eina_Unicode **b,
static void
_handle_esc_csi_decscusr(Termpty *ty, Eina_Unicode **b)
{
int arg = _csi_arg_get(b);
int arg = _csi_arg_get(ty, b);
Cursor_Shape shape = CURSOR_SHAPE_BLOCK;
DBG("DECSCUSR (%d) Set Cursor Shape", arg);
switch (arg)
{
case -CSI_ARG_ERROR:
return;
case -CSI_ARG_NO_VALUE:
EINA_FALLTHROUGH;
case 0:
EINA_FALLTHROUGH;
case 1:
@ -1408,7 +1459,7 @@ _handle_esc_csi_decscusr(Termpty *ty, Eina_Unicode **b)
shape = CURSOR_SHAPE_BAR;
break;
default:
WRN("Invalid DECSCUSR %d", shape);
WRN("Invalid DECSCUSR %d", arg);
ty->decoding_error = EINA_TRUE;
return;
}
@ -1448,7 +1499,9 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, const Eina_Unicode *ce)
/* sorted by ascii value */
case '@': // insert N blank chars (ICH)
/* TODO: SL */
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
TERMPTY_RESTRICT_FIELD(arg, 1, ty->w * ty->h);
DBG("insert %d blank chars", arg);
{
@ -1467,8 +1520,11 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, const Eina_Unicode *ce)
break;
case 'A': // cursor up N (CUU)
/* TODO: SR */
arg = _csi_arg_get(&b);
if (arg < 1) arg = 1;
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
if (arg < 1)
arg = 1;
DBG("cursor up %d", arg);
ty->termstate.wrapnext = 0;
ty->cursor_state.cy = MAX(0, ty->cursor_state.cy - arg);
@ -1481,8 +1537,11 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, const Eina_Unicode *ce)
break;
case 'B': // cursor down N (CUD)
CUD:
arg = _csi_arg_get(&b);
if (arg < 1) arg = 1;
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
if (arg < 1)
arg = 1;
DBG("cursor down %d", arg);
ty->termstate.wrapnext = 0;
ty->cursor_state.cy = MIN(ty->h - 1, ty->cursor_state.cy + arg);
@ -1495,8 +1554,11 @@ CUD:
break;
case 'C': // cursor right N
CUF:
arg = _csi_arg_get(&b);
if (arg < 1) arg = 1;
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
if (arg < 1)
arg = 1;
DBG("cursor right %d", arg);
ty->termstate.wrapnext = 0;
ty->cursor_state.cx += arg;
@ -1508,8 +1570,11 @@ CUF:
}
break;
case 'D': // cursor left N (CUB)
arg = _csi_arg_get(&b);
if (arg < 1) arg = 1;
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
if (arg < 1)
arg = 1;
DBG("cursor left %d", arg);
ty->termstate.wrapnext = 0;
ty->cursor_state.cx -= arg;
@ -1521,8 +1586,11 @@ CUF:
}
break;
case 'E': // down relative N rows, and to col 0
arg = _csi_arg_get(&b);
if (arg < 1) arg = 1;
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
if (arg < 1)
arg = 1;
DBG("down relative %d rows, and to col 0", arg);
ty->termstate.wrapnext = 0;
ty->cursor_state.cy += arg;
@ -1530,7 +1598,9 @@ CUF:
ty->cursor_state.cx = 0;
break;
case 'F': // up relative N rows, and to col 0
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
TERMPTY_RESTRICT_FIELD(arg, 1, ty->h);
DBG("up relative %d rows, and to col 0", arg);
ty->termstate.wrapnext = 0;
@ -1539,8 +1609,11 @@ CUF:
ty->cursor_state.cx = 0;
break;
case 'G': // to column N
arg = _csi_arg_get(&b);
if (arg < 1) arg = 1;
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
if (arg < 1)
arg = 1;
DBG("to column %d", arg);
ty->termstate.wrapnext = 0;
ty->cursor_state.cx = arg - 1;
@ -1549,7 +1622,9 @@ CUF:
case 'H': // cursor pos set (CUP)
goto HVP;
case 'I':
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
TERMPTY_RESTRICT_FIELD(arg, 1, ty->w);
DBG("Cursor Forward Tabulation (CHT): %d", arg);
_tab_forward(ty, arg);
@ -1558,13 +1633,21 @@ CUF:
if (*b == '?')
{
b++;
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
WRN("Unsupported selected erase in display %d", arg);
ty->decoding_error = EINA_TRUE;
break;
}
else
arg = _csi_arg_get(&b);
if (arg < 1) arg = 0;
{
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
}
if (arg < 1)
arg = 0;
/* 3J erases the backlog,
* 2J erases the screen,
* 1J erase from screen start to cursor,
@ -1590,12 +1673,18 @@ CUF:
if (*b == '?')
{
b++;
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
WRN("Unsupported selected erase in line %d", arg);
ty->decoding_error = EINA_TRUE;
break;
}
arg = _csi_arg_get(&b);
if (arg < 1) arg = 0;
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
if (arg < 1)
arg = 0;
DBG("EL/DECSEL %d: erase in line", arg);
switch (arg)
{
@ -1612,7 +1701,9 @@ CUF:
case 'L': // insert N lines - cy
EINA_FALLTHROUGH;
case 'M': // delete N lines - cy
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
TERMPTY_RESTRICT_FIELD(arg, 1, ty->h);
DBG("%s %d lines", (*cc == 'M') ? "delete" : "insert", arg);
if ((ty->cursor_state.cy >= ty->termstate.top_margin) &&
@ -1646,7 +1737,9 @@ CUF:
}
break;
case 'P': // erase and scrollback N chars
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
TERMPTY_RESTRICT_FIELD(arg, 1, ty->w);
DBG("erase and scrollback %d chars", arg);
{
@ -1673,21 +1766,27 @@ CUF:
}
break;
case 'S': // scroll up N lines
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
TERMPTY_RESTRICT_FIELD(arg, 1, ty->h);
DBG("scroll up %d lines", arg);
for (i = 0; i < arg; i++)
termpty_text_scroll(ty, EINA_TRUE);
break;
case 'T': // scroll down N lines
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
TERMPTY_RESTRICT_FIELD(arg, 1, ty->h);
DBG("scroll down %d lines", arg);
for (i = 0; i < arg; i++)
termpty_text_scroll_rev(ty, EINA_TRUE);
break;
case 'X': // erase N chars
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
TERMPTY_RESTRICT_FIELD(arg, 1, ty->w);
DBG("ECH: erase %d chars", arg);
termpty_clear_line(ty, TERMPTY_CLR_END, arg);
@ -1696,7 +1795,9 @@ CUF:
{
int cx = ty->cursor_state.cx;
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
DBG("Cursor Backward Tabulation (CBT): %d", arg);
TERMPTY_RESTRICT_FIELD(arg, 1, ty->w);
for (; arg > 0; arg--)
@ -1713,10 +1814,13 @@ CUF:
}
break;
case '`': // HPA
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
DBG("Horizontal Position Absolute (HPA): %d", arg);
arg--;
if (arg < 0) arg = 0;
if (arg < 0)
arg = 0;
ty->termstate.wrapnext = 0;
ty->cursor_state.cx = arg;
TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w);
@ -1739,7 +1843,9 @@ CUF:
case 'b': // repeat last char
if (ty->last_char)
{
arg = _csi_arg_get(&b);
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++)
@ -1774,8 +1880,11 @@ CUF:
}
break;
case 'd': // to row N
arg = _csi_arg_get(&b);
if (arg < 1) arg = 1;
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
if (arg < 1)
arg = 1;
DBG("to row %d", arg);
ty->termstate.wrapnext = 0;
ty->cursor_state.cy = arg - 1;
@ -1788,8 +1897,11 @@ HVP:
_handle_esc_csi_cursor_pos_set(ty, &b, cc);
break;
case 'g': // clear tabulation
arg = _csi_arg_get(&b);
if (arg < 0) arg = 0;
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
if (arg < 0)
arg = 0;
if (arg == 0)
{
int cx = ty->cursor_state.cx;
@ -1806,17 +1918,17 @@ HVP:
}
break;
case 'h':
_handle_esc_csi_reset_mode(ty, *cc, b);
_handle_esc_csi_reset_mode(ty, *cc, b, be);
break;
case 'i':
WRN("TODO: Media Copy (?:%s)", (*b == '?') ? "yes": "no");
ty->decoding_error = EINA_TRUE;
break;
case 'l':
_handle_esc_csi_reset_mode(ty, *cc, b);
_handle_esc_csi_reset_mode(ty, *cc, b, be);
break;
case 'm': // color set
_handle_esc_csi_color_set(ty, &b);
_handle_esc_csi_color_set(ty, &b, be);
break;
case 'n':
_handle_esc_csi_dsr(ty, b);
@ -1861,7 +1973,9 @@ HVP:
}
break;
case 't': // window manipulation
arg = _csi_arg_get(&b);
arg = _csi_arg_get(ty, &b);
if (arg == -CSI_ARG_ERROR)
goto error;
WRN("TODO: window operation %d not supported", arg);
ty->decoding_error = EINA_TRUE;
break;
@ -1882,6 +1996,7 @@ HVP:
cc++;
return cc - c;
unhandled:
error:
#if !defined(ENABLE_FUZZING) && !defined(ENABLE_TESTS)
if (eina_log_domain_level_check(_termpty_log_dom, EINA_LOG_LEVEL_WARN))
{