|
@@ -243,19 +243,25 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size) |
|
|
* Functions for Coded Character Sets", 5.4. Control sequences. */ |
|
|
* Functions for Coded Character Sets", 5.4. Control sequences. */ |
|
|
if(buffer[i] == '\x1b' && buffer[i + 1] == '[') |
|
|
if(buffer[i] == '\x1b' && buffer[i + 1] == '[') |
|
|
{ |
|
|
{ |
|
|
unsigned int argv[1024]; /* Should be enough. Will it be? */ |
|
|
|
|
|
unsigned int argc = 0; |
|
|
|
|
|
|
|
|
unsigned int argc, argv[101]; |
|
|
unsigned int param, inter, final; |
|
|
unsigned int param, inter, final; |
|
|
|
|
|
|
|
|
/* Offset to parameter bytes */ |
|
|
|
|
|
|
|
|
/* Compute offsets to parameter bytes, intermediate bytes and |
|
|
|
|
|
* to the final byte. Only the final byte is mandatory, there |
|
|
|
|
|
* can be zero of the others. |
|
|
|
|
|
* |
|
|
|
|
|
* +-----+------------------+---------------------+-----------------+ |
|
|
|
|
|
* | CSI | parameter bytes | intermediate bytes | final byte | |
|
|
|
|
|
* | | 0x30 - 0x3f | 0x20 - 0x2f | 0x40 - 0x7e | |
|
|
|
|
|
* | ^[[ | 0123456789:;<=>? | SPC !"#$%&'()*+,-./ | azAZ@[\]^_`{|}~ | |
|
|
|
|
|
* +-----+------------------+---------------------+-----------------+ |
|
|
|
|
|
*/ |
|
|
param = 2; |
|
|
param = 2; |
|
|
|
|
|
|
|
|
/* Offset to intermediate bytes: skip parameter bytes */ |
|
|
|
|
|
for(inter = param; i + inter < size; inter++) |
|
|
for(inter = param; i + inter < size; inter++) |
|
|
if(buffer[i + inter] < 0x30 || buffer[i + inter] > 0x3f) |
|
|
if(buffer[i + inter] < 0x30 || buffer[i + inter] > 0x3f) |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
/* Offset to final byte: skip intermediate bytes */ |
|
|
|
|
|
for(final = inter; i + final < size; final++) |
|
|
for(final = inter; i + final < size; final++) |
|
|
if(buffer[i + final] < 0x20 || buffer[i + final] > 0x2f) |
|
|
if(buffer[i + final] < 0x20 || buffer[i + final] > 0x2f) |
|
|
break; |
|
|
break; |
|
@@ -265,6 +271,7 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size) |
|
|
|
|
|
|
|
|
skip += final; |
|
|
skip += final; |
|
|
|
|
|
|
|
|
|
|
|
/* Sanity checks */ |
|
|
if(param < inter && buffer[i + param] >= 0x3c) |
|
|
if(param < inter && buffer[i + param] >= 0x3c) |
|
|
{ |
|
|
{ |
|
|
//fprintf(stderr, "private sequence \"^[[%.*s\"\n", |
|
|
//fprintf(stderr, "private sequence \"^[[%.*s\"\n", |
|
@@ -272,7 +279,10 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size) |
|
|
continue; /* Private sequence, skip it entirely */ |
|
|
continue; /* Private sequence, skip it entirely */ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* Parse parameter bytes, if any */ |
|
|
|
|
|
|
|
|
if(final - param > 100) |
|
|
|
|
|
continue; /* Suspiciously long sequence, skip it */ |
|
|
|
|
|
|
|
|
|
|
|
/* ECMA-48 5.4.2: Parameter string format */ |
|
|
if(param < inter) |
|
|
if(param < inter) |
|
|
{ |
|
|
{ |
|
|
argv[0] = 0; |
|
|
argv[0] = 0; |
|
@@ -286,49 +296,50 @@ static cucul_canvas_t *import_ansi(void const *data, unsigned int size) |
|
|
argc++; |
|
|
argc++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* Interpret final byte */ |
|
|
|
|
|
|
|
|
/* Interpret final byte. The code representations are given in |
|
|
|
|
|
* ECMA-48 5.4: Control sequences, and the code definitions are |
|
|
|
|
|
* given in ECMA-48 8.3: Definition of control functions. */ |
|
|
switch(buffer[i + final]) |
|
|
switch(buffer[i + final]) |
|
|
{ |
|
|
{ |
|
|
case 'f': |
|
|
|
|
|
case 'H': |
|
|
|
|
|
|
|
|
case 'f': /* CUP - Cursor Position */ |
|
|
|
|
|
case 'H': /* HVP - Character And Line Position */ |
|
|
x = (argc > 1) ? argv[1] - 1 : 0; |
|
|
x = (argc > 1) ? argv[1] - 1 : 0; |
|
|
y = (argc > 0) ? argv[0] - 1 : 0; |
|
|
y = (argc > 0) ? argv[0] - 1 : 0; |
|
|
break; |
|
|
break; |
|
|
case 'A': |
|
|
|
|
|
|
|
|
case 'A': /* CUU - Cursor Up */ |
|
|
y -= argc ? argv[0] : 1; |
|
|
y -= argc ? argv[0] : 1; |
|
|
if(y < 0) |
|
|
if(y < 0) |
|
|
y = 0; |
|
|
y = 0; |
|
|
break; |
|
|
break; |
|
|
case 'B': |
|
|
|
|
|
|
|
|
case 'B': /* CUD - Cursor Down */ |
|
|
y += argc ? argv[0] : 1; |
|
|
y += argc ? argv[0] : 1; |
|
|
break; |
|
|
break; |
|
|
case 'C': |
|
|
|
|
|
|
|
|
case 'C': /* CUF - Cursor Right */ |
|
|
x += argc ? argv[0] : 1; |
|
|
x += argc ? argv[0] : 1; |
|
|
break; |
|
|
break; |
|
|
case 'D': |
|
|
|
|
|
|
|
|
case 'D': /* CUB - Cursor Left */ |
|
|
x -= argc ? argv[0] : 1; |
|
|
x -= argc ? argv[0] : 1; |
|
|
if(x < 0) |
|
|
if(x < 0) |
|
|
x = 0; |
|
|
x = 0; |
|
|
break; |
|
|
break; |
|
|
case 's': |
|
|
|
|
|
|
|
|
case 's': /* Private (save cursor position) */ |
|
|
save_x = x; |
|
|
save_x = x; |
|
|
save_y = y; |
|
|
save_y = y; |
|
|
break; |
|
|
break; |
|
|
case 'u': |
|
|
|
|
|
|
|
|
case 'u': /* Private (reload cursor positin) */ |
|
|
x = save_x; |
|
|
x = save_x; |
|
|
y = save_y; |
|
|
y = save_y; |
|
|
break; |
|
|
break; |
|
|
case 'J': |
|
|
|
|
|
|
|
|
case 'J': /* ED - Erase In Page */ |
|
|
if(argv[0] == 2) |
|
|
if(argv[0] == 2) |
|
|
x = y = 0; |
|
|
x = y = 0; |
|
|
break; |
|
|
break; |
|
|
case 'K': |
|
|
|
|
|
// CLEAR END OF LINE |
|
|
|
|
|
|
|
|
case 'K': /* EL - Erase In Line */ |
|
|
for(j = x; j < width; j++) |
|
|
for(j = x; j < width; j++) |
|
|
_cucul_putchar32(cv, j, y, (uint32_t)' '); |
|
|
_cucul_putchar32(cv, j, y, (uint32_t)' '); |
|
|
x = width; |
|
|
x = width; |
|
|
break; |
|
|
break; |
|
|
case 'm': |
|
|
|
|
|
|
|
|
case 'm': /* SGR - Select Graphic Rendition */ |
|
|
for(j = 0; j < argc; j++) |
|
|
for(j = 0; j < argc; j++) |
|
|
manage_modifiers(argv[j], &fg, &bg, |
|
|
manage_modifiers(argv[j], &fg, &bg, |
|
|
&save_fg, &save_bg, &bold, &reverse); |
|
|
&save_fg, &save_bg, &bold, &reverse); |
|
|