Patch 8.2.0798
Problem: Libvterm code lags behind the upstream version.
Solution: Include revisions 755 - 758.
Files: src/libvterm/t/
run-test.pl, src/libvterm/src/screen.c,
src/libvterm/t/harness.c, src/libvterm/include/vterm.h,
src/libvterm/src/parser.c, src/libvterm/src/state.c,
src/libvterm/src/vterm.c, src/libvterm/src/vterm_internal.h,
src/libvterm/t/02parser.test,
src/libvterm/t/18state_termprops.test,
src/libvterm/t/29state_fallback.test,
src/libvterm/t/68screen_termprops.test, src/terminal.c
*** ../vim-8.2.0797/src/libvterm/t/
run-test.pl 2020-05-18 21:50:32.932742338 +0200
--- src/libvterm/t/
run-test.pl 2020-05-19 19:15:23.211486825 +0200
***************
*** 11,17 ****
my $EXECUTABLE = "t/.libs/harness";
GetOptions(
'valgrind|v+' => \$VALGRIND,
! 'executable|e=s' => \$EXECUTABLE
) or exit 1;
my ( $hin, $hout, $hpid );
--- 11,18 ----
my $EXECUTABLE = "t/.libs/harness";
GetOptions(
'valgrind|v+' => \$VALGRIND,
! 'executable|e=s' => \$EXECUTABLE,
! 'fail-early|F' => \(my $FAIL_EARLY),
) or exit 1;
my ( $hin, $hout, $hpid );
***************
*** 65,70 ****
--- 66,72 ----
}
$exitcode = 1 if $fail_printed;
+ exit $exitcode if $exitcode and $FAIL_EARLY;
}
sub do_line
***************
*** 105,112 ****
elsif( $line =~ m/^csi (\S+) (.*)$/ ) {
$line = sprintf "csi %02x %s", eval($1), $2; # TODO
}
! elsif( $line =~ m/^(escape|osc|dcs) (.*)$/ ) {
! $line = "$1 " . join "", map sprintf("%02x", $_), unpack "C*", eval($2);
}
elsif( $line =~ m/^putglyph (\S+) (.*)$/ ) {
$line = "putglyph " . join( ",", map sprintf("%x", $_), eval($1) ) . " $2";
--- 107,121 ----
elsif( $line =~ m/^csi (\S+) (.*)$/ ) {
$line = sprintf "csi %02x %s", eval($1), $2; # TODO
}
! elsif( $line =~ m/^(osc) (\[\d+)? *(.*?)(\]?)$/ ) {
! my ( $cmd, $initial, $data, $final ) = ( $1, $2, $3, $4 );
! $initial //= "";
! $initial .= ";" if $initial =~ m/\d+/;
!
! $line = "$cmd $initial" . join( "", map sprintf("%02x", $_), unpack "C*", eval($data) ) . "$final";
! }
! elsif( $line =~ m/^(escape|dcs) (\[?)(.*?)(\]?)$/ ) {
! $line = "$1 $2" . join( "", map sprintf("%02x", $_), unpack "C*", eval($3) ) . "$4";
}
elsif( $line =~ m/^putglyph (\S+) (.*)$/ ) {
$line = "putglyph " . join( ",", map sprintf("%x", $_), eval($1) ) . " $2";
***************
*** 139,144 ****
--- 148,154 ----
"# Expected: $want\n" .
"# Actual: $response\n";
$exitcode = 1;
+ exit $exitcode if $exitcode and $FAIL_EARLY;
}
}
# Assertions start with '?'
***************
*** 162,167 ****
--- 172,178 ----
"# Expected: $expectation\n" .
"# Actual: $response\n";
$exitcode = 1;
+ exit $exitcode if $exitcode and $FAIL_EARLY;
}
}
# Test controls start with '$'
*** ../vim-8.2.0797/src/libvterm/src/screen.c 2020-05-18 21:50:32.932742338 +0200
--- src/libvterm/src/screen.c 2020-05-19 19:10:17.072705379 +0200
***************
*** 533,539 ****
ScreenCell *dst = &new_buffer[pos.row * new_cols + pos.col];
int i;
! for(i = 0; ; i++) {
dst->chars[i] = src->chars[i];
if(!src->chars[i])
break;
--- 533,539 ----
ScreenCell *dst = &new_buffer[pos.row * new_cols + pos.col];
int i;
! for(i = 0; i < VTERM_MAX_CHARS_PER_CELL; i++) {
dst->chars[i] = src->chars[i];
if(!src->chars[i])
break;
***************
*** 804,810 ****
if(!intcell)
return 0;
! for(i = 0; ; i++) {
cell->chars[i] = intcell->chars[i];
if(!intcell->chars[i])
break;
--- 804,810 ----
if(!intcell)
return 0;
! for(i = 0; i < VTERM_MAX_CHARS_PER_CELL; i++) {
cell->chars[i] = intcell->chars[i];
if(!intcell->chars[i])
break;
*** ../vim-8.2.0797/src/libvterm/t/harness.c 2020-05-18 21:50:32.932742338 +0200
--- src/libvterm/t/harness.c 2020-05-19 21:14:58.824143429 +0200
***************
*** 153,173 ****
return 1;
}
! static int parser_osc(const char *command, size_t cmdlen, void *user UNUSED)
{
printf("osc ");
! printhex(command, cmdlen);
printf("\n");
return 1;
}
! static int parser_dcs(const char *command, size_t cmdlen, void *user UNUSED)
{
-
printf("dcs ");
! printhex(command, cmdlen);
printf("\n");
return 1;
--- 153,196 ----
return 1;
}
! static int parser_osc(int command, VTermStringFragment frag, void *user UNUSED)
{
printf("osc ");
!
! if(frag.initial) {
! if(command == -1)
! printf("[");
! else
! printf("[%d;", command);
! }
!
! printhex(frag.str, frag.len);
!
! if(frag.final)
! printf("]");
!
printf("\n");
return 1;
}
! static int parser_dcs(const char *command, size_t commandlen, VTermStringFragment frag, void *user UNUSED)
{
printf("dcs ");
!
! if(frag.initial) {
! size_t i;
! printf("[");
! for(i = 0; i < commandlen; i++)
! printf("%02x", command[i]);
! }
!
! printhex(frag.str, frag.len);
!
! if(frag.final)
! printf("]");
!
printf("\n");
return 1;
***************
*** 239,245 ****
printf("settermprop %d %d\n", prop, val->number);
return 1;
case VTERM_VALUETYPE_STRING:
! printf("settermprop %d \"%s\"\n", prop, val->string);
return 1;
case VTERM_VALUETYPE_COLOR:
printf("settermprop %d rgb(%d,%d,%d)\n", prop, val->color.red, val->color.green, val->color.blue);
--- 262,269 ----
printf("settermprop %d %d\n", prop, val->number);
return 1;
case VTERM_VALUETYPE_STRING:
! printf("settermprop %d %s\"%.*s\"%s\n", prop,
! val->string.initial ? "[" : "", val->string.len, val->string.str, val->string.final ? "]" : "");
return 1;
case VTERM_VALUETYPE_COLOR:
printf("settermprop %d rgb(%d,%d,%d)\n", prop, val->color.red, val->color.green, val->color.blue);
***************
*** 262,268 ****
return 1;
printf("putglyph ");
! for(i = 0; info->chars[i]; i++)
printf(i ? ",%x" : "%x", info->chars[i]);
printf(" %d %d,%d", info->width, pos.row, pos.col);
if(info->protected_cell)
--- 286,292 ----
return 1;
printf("putglyph ");
! for(i = 0; i < VTERM_MAX_CHARS_PER_CELL && info->chars[i]; i++)
printf(i ? ",%x" : "%x", info->chars[i]);
printf(" %d %d,%d", info->width, pos.row, pos.col);
if(info->protected_cell)
*** ../vim-8.2.0797/src/libvterm/include/vterm.h 2020-05-18 21:50:32.932742338 +0200
--- src/libvterm/include/vterm.h 2020-05-19 19:17:11.043085163 +0200
***************
*** 107,116 ****
VTERM_N_VALUETYPES
} VTermValueType;
typedef union {
int boolean;
int number;
! char *string;
VTermColor color;
} VTermValue;
--- 107,123 ----
VTERM_N_VALUETYPES
} VTermValueType;
+ typedef struct {
+ const char *str;
+ size_t len : 30;
+ unsigned int initial : 1;
+ unsigned int final : 1;
+ } VTermStringFragment;
+
typedef union {
int boolean;
int number;
! VTermStringFragment string;
VTermColor color;
} VTermValue;
***************
*** 257,264 ****
int (*control)(unsigned char control, void *user);
int (*escape)(const char *bytes, size_t len, void *user);
int (*csi)(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user);
! int (*osc)(const char *command, size_t cmdlen, void *user);
! int (*dcs)(const char *command, size_t cmdlen, void *user);
int (*resize)(int rows, int cols, void *user);
} VTermParserCallbacks;
--- 264,271 ----
int (*control)(unsigned char control, void *user);
int (*escape)(const char *bytes, size_t len, void *user);
int (*csi)(const char *leader, const long args[], int argcount, const char *intermed, char command, void *user);
! int (*osc)(int command, VTermStringFragment frag, void *user);
! int (*dcs)(const char *command, size_t commandlen, VTermStringFragment frag, void *user);
int (*resize)(int rows, int cols, void *user);
} VTermParserCallbacks;
*** ../vim-8.2.0797/src/libvterm/src/parser.c 2020-01-08 22:06:11.057866613 +0100
--- src/libvterm/src/parser.c 2020-05-19 21:09:25.825081936 +0200
***************
*** 23,32 ****
{
#ifdef DEBUG_PARSER
printf("Parsed CSI args as:\n", arglen, args);
! printf(" leader: %s\n", vt->parser.csi_leader);
! for(int argi = 0; argi < vt->parser.csi_argi; argi++) {
! printf(" %lu", CSI_ARG(vt->parser.csi_args[argi]));
! if(!CSI_ARG_HAS_MORE(vt->parser.csi_args[argi]))
printf("\n");
printf(" intermed: %s\n", vt->parser.intermed);
}
--- 23,32 ----
{
#ifdef DEBUG_PARSER
printf("Parsed CSI args as:\n", arglen, args);
! printf(" leader: %s\n", vt->parser.v.csi.leader);
! for(int argi = 0; argi < vt->parser.v.csi.argi; argi++) {
! printf(" %lu", CSI_ARG(vt->parser.v.csi.args[argi]));
! if(!CSI_ARG_HAS_MORE(vt->parser.v.csi.args[argi]))
printf("\n");
printf(" intermed: %s\n", vt->parser.intermed);
}
***************
*** 34,42 ****
if(vt->parser.callbacks && vt->parser.callbacks->csi)
if((*vt->parser.callbacks->csi)(
! vt->parser.csi_leaderlen ? vt->parser.csi_leader : NULL,
! vt->parser.csi_args,
! vt->parser.csi_argi,
vt->parser.intermedlen ? vt->parser.intermed : NULL,
command,
vt->parser.cbdata))
--- 34,42 ----
if(vt->parser.callbacks && vt->parser.callbacks->csi)
if((*vt->parser.callbacks->csi)(
! vt->parser.v.csi.leaderlen ? vt->parser.v.csi.leader : NULL,
! vt->parser.v.csi.args,
! vt->parser.v.csi.argi,
vt->parser.intermedlen ? vt->parser.intermed : NULL,
command,
vt->parser.cbdata))
***************
*** 61,125 ****
DEBUG_LOG1("libvterm: Unhandled escape ESC 0x%02x\n", command);
}
! static void append_strbuffer(VTerm *vt, const char *str, size_t len)
{
! if(len > vt->parser.strbuffer_len - vt->parser.strbuffer_cur) {
! len = vt->parser.strbuffer_len - vt->parser.strbuffer_cur;
! DEBUG_LOG1("Truncating strbuffer preserve to %zu bytes\n", len);
! }
!
! if(len > 0) {
! strncpy(vt->parser.strbuffer + vt->parser.strbuffer_cur, str, len);
! vt->parser.strbuffer_cur += len;
! }
! }
!
! static void start_string(VTerm *vt, VTermParserStringType type)
! {
! vt->parser.stringtype = type;
! vt->parser.strbuffer_cur = 0;
! }
! static void more_string(VTerm *vt, const char *str, size_t len)
! {
! append_strbuffer(vt, str, len);
! }
! static void done_string(VTerm *vt, const char *str, size_t len)
! {
! if(vt->parser.strbuffer_cur) {
! if(str)
! append_strbuffer(vt, str, len);
! str = vt->parser.strbuffer;
! len = vt->parser.strbuffer_cur;
! }
! else if(!str) {
! DEBUG_LOG("parser.c: TODO: No strbuffer _and_ no final fragment???\n");
! len = 0;
}
! switch(vt->parser.stringtype) {
! case VTERM_PARSER_OSC:
! if(vt->parser.callbacks && vt->parser.callbacks->osc)
! if((*vt->parser.callbacks->osc)(str, len, vt->parser.cbdata))
! return;
!
! DEBUG_LOG2("libvterm: Unhandled OSC %.*s\n", (int)len, str);
! return;
!
! case VTERM_PARSER_DCS:
! if(vt->parser.callbacks && vt->parser.callbacks->dcs)
! if((*vt->parser.callbacks->dcs)(str, len, vt->parser.cbdata))
! return;
!
! DEBUG_LOG2("libvterm: Unhandled DCS %.*s\n", (int)len, str);
! return;
!
! case VTERM_N_PARSER_TYPES:
! return;
! }
}
size_t vterm_input_write(VTerm *vt, const char *bytes, size_t len)
--- 61,96 ----
DEBUG_LOG1("libvterm: Unhandled escape ESC 0x%02x\n", command);
}
! static void string_fragment(VTerm *vt, const char *str, size_t len, int final)
{
! VTermStringFragment frag;
! frag.str = str;
! frag.len = len;
! frag.initial = vt->parser.string_initial;
! frag.final = final;
! switch(vt->parser.state) {
! case OSC:
! if(vt->parser.callbacks && vt->parser.callbacks->osc)
! (*vt->parser.callbacks->osc)(vt->parser.v.osc.command, frag, vt->parser.cbdata);
! break;
! case DCS:
! if(len && vt->parser.callbacks && vt->parser.callbacks->dcs)
! (*vt->parser.callbacks->dcs)(vt->parser.v.dcs.command, vt->parser.v.dcs.commandlen, frag, vt->parser.cbdata);
! break;
! case NORMAL:
! case CSI_LEADER:
! case CSI_ARGS:
! case CSI_INTERMED:
! case OSC_COMMAND:
! case DCS_COMMAND:
! break;
}
! vt->parser.string_initial = FALSE;
}
size_t vterm_input_write(VTerm *vt, const char *bytes, size_t len)
***************
*** 135,177 ****
case CSI_LEADER:
case CSI_ARGS:
case CSI_INTERMED:
! case ESC:
string_start = NULL;
break;
! case STRING:
! case ESC_IN_STRING:
string_start = bytes;
break;
}
- #define ENTER_STRING_STATE() do { vt->parser.state = STRING; string_start = bytes + pos + 1; } while(0)
#define ENTER_STATE(st) do { vt->parser.state = st; string_start = NULL; } while(0)
#define ENTER_NORMAL_STATE() ENTER_STATE(NORMAL)
for( ; pos < len; pos++) {
unsigned char c = bytes[pos];
if(c == 0x00 || c == 0x7f) { // NUL, DEL
! if(vt->parser.state >= STRING) {
! more_string(vt, string_start, bytes + pos - string_start);
string_start = bytes + pos + 1;
}
continue;
}
if(c == 0x18 || c == 0x1a) { // CAN, SUB
ENTER_NORMAL_STATE();
continue;
}
else if(c == 0x1b) { // ESC
vt->parser.intermedlen = 0;
! if(vt->parser.state == STRING)
! vt->parser.state = ESC_IN_STRING;
! else
! ENTER_STATE(ESC);
continue;
}
else if(c == 0x07 && // BEL, can stand for ST in OSC or DCS state
! vt->parser.state == STRING) {
// fallthrough
}
else if(c < 0x20) { // other C0
--- 106,150 ----
case CSI_LEADER:
case CSI_ARGS:
case CSI_INTERMED:
! case OSC_COMMAND:
! case DCS_COMMAND:
string_start = NULL;
break;
! case OSC:
! case DCS:
string_start = bytes;
break;
}
#define ENTER_STATE(st) do { vt->parser.state = st; string_start = NULL; } while(0)
#define ENTER_NORMAL_STATE() ENTER_STATE(NORMAL)
for( ; pos < len; pos++) {
unsigned char c = bytes[pos];
+ int c1_allowed = !vt->mode.utf8;
+ size_t string_len;
if(c == 0x00 || c == 0x7f) { // NUL, DEL
! if(vt->parser.state >= OSC) {
! string_fragment(vt, string_start, bytes + pos - string_start, FALSE);
string_start = bytes + pos + 1;
}
continue;
}
if(c == 0x18 || c == 0x1a) { // CAN, SUB
+ vt->parser.in_esc = FALSE;
ENTER_NORMAL_STATE();
continue;
}
else if(c == 0x1b) { // ESC
vt->parser.intermedlen = 0;
! if(vt->parser.state < OSC)
! vt->parser.state = NORMAL;
! vt->parser.in_esc = TRUE;
continue;
}
else if(c == 0x07 && // BEL, can stand for ST in OSC or DCS state
! vt->parser.state >= OSC) {
// fallthrough
}
else if(c < 0x20) { // other C0
***************
*** 182,277 ****
if(pos + 2 < len && bytes[pos + 1] == 0x20 && bytes[pos + 2] == 0x08)
vt->in_backspace = 2; // Trigger when count down to 1
}
! if(vt->parser.state >= STRING)
! more_string(vt, string_start, bytes + pos - string_start);
do_control(vt, c);
! if(vt->parser.state >= STRING)
string_start = bytes + pos + 1;
continue;
}
// else fallthrough
! switch(vt->parser.state) {
! case ESC_IN_STRING:
! if(c == 0x5c) { // ST
! vt->parser.state = STRING;
! done_string(vt, string_start, bytes + pos - string_start - 1);
! ENTER_NORMAL_STATE();
! break;
! }
! vt->parser.state = ESC;
! // else fallthrough
! case ESC:
! switch(c) {
! case 0x50: // DCS
! start_string(vt, VTERM_PARSER_DCS);
! ENTER_STRING_STATE();
! break;
! case 0x5b: // CSI
! vt->parser.csi_leaderlen = 0;
! ENTER_STATE(CSI_LEADER);
! break;
! case 0x5d: // OSC
! start_string(vt, VTERM_PARSER_OSC);
! ENTER_STRING_STATE();
! break;
! default:
! if(is_intermed(c)) {
! if(vt->parser.intermedlen < INTERMED_MAX-1)
! vt->parser.intermed[vt->parser.intermedlen++] = c;
! }
! else if(!vt->parser.intermedlen && c >= 0x40 && c < 0x60) {
! do_control(vt, c + 0x40);
! ENTER_NORMAL_STATE();
! }
! else if(c >= 0x30 && c < 0x7f) {
! do_escape(vt, c);
! ENTER_NORMAL_STATE();
! }
! else {
! DEBUG_LOG1("TODO: Unhandled byte %02x in Escape\n", c);
! }
}
! break;
case CSI_LEADER:
// Extract leader bytes 0x3c to 0x3f
if(c >= 0x3c && c <= 0x3f) {
! if(vt->parser.csi_leaderlen < CSI_LEADER_MAX-1)
! vt->parser.csi_leader[vt->parser.csi_leaderlen++] = c;
break;
}
// else fallthrough
! vt->parser.csi_leader[vt->parser.csi_leaderlen] = 0;
! vt->parser.csi_argi = 0;
! vt->parser.csi_args[0] = CSI_ARG_MISSING;
vt->parser.state = CSI_ARGS;
// fallthrough
case CSI_ARGS:
// Numerical value of argument
if(c >= '0' && c <= '9') {
! if(vt->parser.csi_args[vt->parser.csi_argi] == CSI_ARG_MISSING)
! vt->parser.csi_args[vt->parser.csi_argi] = 0;
! vt->parser.csi_args[vt->parser.csi_argi] *= 10;
! vt->parser.csi_args[vt->parser.csi_argi] += c - '0';
break;
}
if(c == ':') {
! vt->parser.csi_args[vt->parser.csi_argi] |= CSI_ARG_FLAG_MORE;
c = ';';
}
if(c == ';') {
! vt->parser.csi_argi++;
! vt->parser.csi_args[vt->parser.csi_argi] = CSI_ARG_MISSING;
break;
}
// else fallthrough
! vt->parser.csi_argi++;
vt->parser.intermedlen = 0;
vt->parser.state = CSI_INTERMED;
// fallthrough
--- 155,226 ----
if(pos + 2 < len && bytes[pos + 1] == 0x20 && bytes[pos + 2] == 0x08)
vt->in_backspace = 2; // Trigger when count down to 1
}
! if(vt->parser.state >= OSC)
! string_fragment(vt, string_start, bytes + pos - string_start, FALSE);
do_control(vt, c);
! if(vt->parser.state >= OSC)
string_start = bytes + pos + 1;
continue;
}
// else fallthrough
! string_len = bytes + pos - string_start;
! if(vt->parser.in_esc) {
! // Hoist an ESC letter into a C1 if we're not in a string mode
! // Always accept ESC \ == ST even in string mode
! if(!vt->parser.intermedlen &&
! c >= 0x40 && c < 0x60 &&
! ((vt->parser.state < OSC || c == 0x5c))) {
! c += 0x40;
! c1_allowed = TRUE;
! string_len -= 1;
! vt->parser.in_esc = FALSE;
}
! else {
! string_start = NULL;
! vt->parser.state = NORMAL;
! }
! }
+ switch(vt->parser.state) {
case CSI_LEADER:
// Extract leader bytes 0x3c to 0x3f
if(c >= 0x3c && c <= 0x3f) {
! if(vt->parser.v.csi.leaderlen < CSI_LEADER_MAX-1)
! vt->parser.v.csi.leader[vt->parser.v.csi.leaderlen++] = c;
break;
}
// else fallthrough
! vt->parser.v.csi.leader[vt->parser.v.csi.leaderlen] = 0;
! vt->parser.v.csi.argi = 0;
! vt->parser.v.csi.args[0] = CSI_ARG_MISSING;
vt->parser.state = CSI_ARGS;
// fallthrough
case CSI_ARGS:
// Numerical value of argument
if(c >= '0' && c <= '9') {
! if(vt->parser.v.csi.args[vt->parser.v.csi.argi] == CSI_ARG_MISSING)
! vt->parser.v.csi.args[vt->parser.v.csi.argi] = 0;
! vt->parser.v.csi.args[vt->parser.v.csi.argi] *= 10;
! vt->parser.v.csi.args[vt->parser.v.csi.argi] += c - '0';
break;
}
if(c == ':') {
! vt->parser.v.csi.args[vt->parser.v.csi.argi] |= CSI_ARG_FLAG_MORE;
c = ';';
}
if(c == ';') {
! vt->parser.v.csi.argi++;
! vt->parser.v.csi.args[vt->parser.v.csi.argi] = CSI_ARG_MISSING;
break;
}
// else fallthrough
! vt->parser.v.csi.argi++;
vt->parser.intermedlen = 0;
vt->parser.state = CSI_INTERMED;
// fallthrough
***************
*** 293,323 ****
ENTER_NORMAL_STATE();
break;
! case STRING:
! if(c == 0x07 || (c == 0x9c && !vt->mode.utf8)) {
! done_string(vt, string_start, bytes + pos - string_start);
! ENTER_NORMAL_STATE();
}
! else if (pos + 1 == len) {
! // end of input but OSC string isn't finished yet, copy it to
! // vt->parser.strbuffer to continue it later
! more_string(vt, string_start, bytes + pos + 1 - string_start);
}
break;
case NORMAL:
! if(c >= 0x80 && c < 0xa0 && !vt->mode.utf8) {
switch(c) {
case 0x90: // DCS
! start_string(vt, VTERM_PARSER_DCS);
! ENTER_STRING_STATE();
break;
case 0x9b: // CSI
ENTER_STATE(CSI_LEADER);
break;
case 0x9d: // OSC
! start_string(vt, VTERM_PARSER_OSC);
! ENTER_STRING_STATE();
break;
default:
do_control(vt, c);
--- 242,318 ----
ENTER_NORMAL_STATE();
break;
! case OSC_COMMAND:
! /* Numerical value of command */
! if(c >= '0' && c <= '9') {
! if(vt->parser.v.osc.command == -1)
! vt->parser.v.osc.command = 0;
! else
! vt->parser.v.osc.command *= 10;
! vt->parser.v.osc.command += c - '0';
! break;
! }
! if(c == ';') {
! vt->parser.state = OSC;
! string_start = bytes + pos + 1;
! break;
! }
!
! /* else fallthrough */
! string_start = bytes + pos;
! vt->parser.state = OSC;
! goto string_state;
!
! case DCS_COMMAND:
! if(vt->parser.v.dcs.commandlen < CSI_LEADER_MAX)
! vt->parser.v.dcs.command[vt->parser.v.dcs.commandlen++] = c;
!
! if(c >= 0x40 && c<= 0x7e) {
! string_start = bytes + pos + 1;
! vt->parser.state = DCS;
}
! break;
!
! string_state:
! case OSC:
! case DCS:
! if(c == 0x07 || (c1_allowed && c == 0x9c)) {
! string_fragment(vt, string_start, string_len, TRUE);
! ENTER_NORMAL_STATE();
}
break;
case NORMAL:
! if(vt->parser.in_esc) {
! if(is_intermed(c)) {
! if(vt->parser.intermedlen < INTERMED_MAX-1)
! vt->parser.intermed[vt->parser.intermedlen++] = c;
! }
! else if(c >= 0x30 && c < 0x7f) {
! do_escape(vt, c);
! vt->parser.in_esc = 0;
! ENTER_NORMAL_STATE();
! }
! else {
! DEBUG_LOG1("TODO: Unhandled byte %02x in Escape\n", c);
! }
! break;
! }
! if(c1_allowed && c >= 0x80 && c < 0xa0) {
switch(c) {
case 0x90: // DCS
! vt->parser.string_initial = TRUE;
! vt->parser.v.dcs.commandlen = 0;
! ENTER_STATE(DCS_COMMAND);
break;
case 0x9b: // CSI
+ vt->parser.v.csi.leaderlen = 0;
ENTER_STATE(CSI_LEADER);
break;
case 0x9d: // OSC
! vt->parser.v.osc.command = -1;
! vt->parser.string_initial = TRUE;
! ENTER_STATE(OSC_COMMAND);
break;
default:
do_control(vt, c);
***************
*** 341,346 ****
--- 336,344 ----
}
}
+ if(string_start)
+ string_fragment(vt, string_start, bytes + pos - string_start, FALSE);
+
return len;
}
*** ../vim-8.2.0797/src/libvterm/src/state.c 2020-05-19 10:32:59.291518426 +0200
--- src/libvterm/src/state.c 2020-05-19 21:12:12.744611031 +0200
***************
*** 582,600 ****
return vterm_state_set_termprop(state, prop, &val);
}
! static int settermprop_string(VTermState *state, VTermProp prop, const char *str, size_t len)
{
- char *strvalue;
- int r;
VTermValue val;
! strvalue = vterm_allocator_malloc(state->vt, (len+1) * sizeof(char));
! strncpy(strvalue, str, len);
! strvalue[len] = 0;
!
! val.string = strvalue;
! r = vterm_state_set_termprop(state, prop, &val);
! vterm_allocator_free(state->vt, strvalue);
! return r;
}
static void savecursor(VTermState *state, int save)
--- 582,593 ----
return vterm_state_set_termprop(state, prop, &val);
}
! static int settermprop_string(VTermState *state, VTermProp prop, VTermStringFragment frag)
{
VTermValue val;
!
! val.string = frag;
! return vterm_state_set_termprop(state, prop, &val);
}
static void savecursor(VTermState *state, int save)
***************
*** 1602,1701 ****
return 1;
}
! static int on_osc(const char *command, size_t cmdlen, void *user)
{
VTermState *state = user;
! if(cmdlen < 2)
! return 0;
! if(strneq(command, "0;", 2)) {
! settermprop_string(state, VTERM_PROP_ICONNAME, command + 2, cmdlen - 2);
! settermprop_string(state, VTERM_PROP_TITLE, command + 2, cmdlen - 2);
! return 1;
! }
! else if(strneq(command, "1;", 2)) {
! settermprop_string(state, VTERM_PROP_ICONNAME, command + 2, cmdlen - 2);
! return 1;
! }
! else if(strneq(command, "2;", 2)) {
! settermprop_string(state, VTERM_PROP_TITLE, command + 2, cmdlen - 2);
! return 1;
! }
! else if(strneq(command, "10;", 3)) {
! // request foreground color: <Esc>]10;?<0x07>
! int red = state->default_fg.red;
! int blue = state->default_fg.blue;
! int green = state->default_fg.green;
! vterm_push_output_sprintf_ctrl(state->vt, C1_OSC, "10;rgb:%02x%02x/%02x%02x/%02x%02x\x07", red, red, green, green, blue, blue);
! return 1;
! }
! else if(strneq(command, "11;", 3)) {
! // request background color: <Esc>]11;?<0x07>
! int red = state->default_bg.red;
! int blue = state->default_bg.blue;
! int green = state->default_bg.green;
! vterm_push_output_sprintf_ctrl(state->vt, C1_OSC, "11;rgb:%02x%02x/%02x%02x/%02x%02x\x07", red, red, green, green, blue, blue);
! return 1;
! }
! else if(strneq(command, "12;", 3)) {
! settermprop_string(state, VTERM_PROP_CURSORCOLOR, command + 3, cmdlen - 3);
! return 1;
! }
! else if(state->fallbacks && state->fallbacks->osc)
! if((*state->fallbacks->osc)(command, cmdlen, state->fbdata))
return 1;
return 0;
}
! static void request_status_string(VTermState *state, const char *command, size_t cmdlen)
{
VTerm *vt = state->vt;
! if(cmdlen == 1)
! switch(command[0]) {
! case 'm': // Query SGR
! {
! long args[20];
! int argc = vterm_state_getpen(state, args, sizeof(args)/sizeof(args[0]));
! int argi;
! size_t cur = 0;
!
! cur += SNPRINTF(vt->tmpbuffer + cur, vt->tmpbuffer_len - cur,
! vt->mode.ctrl8bit ? "\x90" "1$r" : ESC_S "P" "1$r"); // DCS 1$r ...
! if(cur >= vt->tmpbuffer_len)
! return;
!
! for(argi = 0; argi < argc; argi++) {
! cur += SNPRINTF(vt->tmpbuffer + cur, vt->tmpbuffer_len - cur,
! argi == argc - 1 ? "%ld" :
! CSI_ARG_HAS_MORE(args[argi]) ? "%ld:" :
! "%ld;",
! CSI_ARG(args[argi]));
!
! if(cur >= vt->tmpbuffer_len)
! return;
! }
!
! cur += SNPRINTF(vt->tmpbuffer + cur, vt->tmpbuffer_len - cur,
! vt->mode.ctrl8bit ? "m" "\x9C" : "m" ESC_S "\\"); // ... m ST
! if(cur >= vt->tmpbuffer_len)
! return;
! vterm_push_output_bytes(vt, vt->tmpbuffer, cur);
! }
! return;
! case 'r': // Query DECSTBM
! vterm_push_output_sprintf_dcs(vt, "1$r%d;%dr", state->scrollregion_top+1, SCROLLREGION_BOTTOM(state));
return;
! case 's': // Query DECSLRM
! vterm_push_output_sprintf_dcs(vt, "1$r%d;%ds", SCROLLREGION_LEFT(state)+1, SCROLLREGION_RIGHT(state));
return;
}
! if(cmdlen == 2) {
! if(strneq(command, " q", 2)) {
int reply;
switch(state->mode.cursor_shape) {
case VTERM_PROP_CURSORSHAPE_BLOCK: reply = 2; break;
--- 1595,1715 ----
return 1;
}
! static int on_osc(int command, VTermStringFragment frag, void *user)
{
VTermState *state = user;
! switch(command) {
! case 0:
! settermprop_string(state, VTERM_PROP_ICONNAME, frag);
! settermprop_string(state, VTERM_PROP_TITLE, frag);
! return 1;
! case 1:
! settermprop_string(state, VTERM_PROP_ICONNAME, frag);
return 1;
+ case 2:
+ settermprop_string(state, VTERM_PROP_TITLE, frag);
+ return 1;
+
+ case 10:
+ {
+ // request foreground color: <Esc>]10;?<0x07>
+ int red = state->default_fg.red;
+ int blue = state->default_fg.blue;
+ int green = state->default_fg.green;
+ vterm_push_output_sprintf_ctrl(state->vt, C1_OSC, "10;rgb:%02x%02x/%02x%02x/%02x%02x\x07", red, red, green, green, blue, blue);
+ return 1;
+ }
+
+ case 11:
+ {
+ // request background color: <Esc>]11;?<0x07>
+ int red = state->default_bg.red;
+ int blue = state->default_bg.blue;
+ int green = state->default_bg.green;
+ vterm_push_output_sprintf_ctrl(state->vt, C1_OSC, "11;rgb:%02x%02x/%02x%02x/%02x%02x\x07", red, red, green, green, blue, blue);
+ return 1;
+ }
+ case 12:
+ settermprop_string(state, VTERM_PROP_CURSORCOLOR, frag);
+ return 1;
+
+ default:
+ if(state->fallbacks && state->fallbacks->osc)
+ if((*state->fallbacks->osc)(command, frag, state->fbdata))
+ return 1;
+ }
+
return 0;
}
! static void request_status_string(VTermState *state, VTermStringFragment frag)
{
VTerm *vt = state->vt;
! char *tmp = state->tmp.decrqss;
! size_t i = 0;
! if(frag.initial)
! tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0;
!
! while(i < sizeof(state->tmp.decrqss)-1 && tmp[i])
! i++;
! while(i < sizeof(state->tmp.decrqss)-1 && frag.len--)
! tmp[i++] = (frag.str++)[0];
! tmp[i] = 0;
!
! if(!frag.final)
! return;
!
! fprintf(stderr, "DECRQSS on <%s>\n", tmp);
!
! switch(tmp[0] | tmp[1]<<8 | tmp[2]<<16) {
! case 'm': {
! // Query SGR
! long args[20];
! int argc = vterm_state_getpen(state, args, sizeof(args)/sizeof(args[0]));
! size_t cur = 0;
! int argi;
!
! cur += snprintf(vt->tmpbuffer + cur, vt->tmpbuffer_len - cur,
! vt->mode.ctrl8bit ? "\x90" "1$r" : ESC_S "P" "1$r"); // DCS 1$r ...
! if(cur >= vt->tmpbuffer_len)
return;
!
! for(argi = 0; argi < argc; argi++) {
! cur += snprintf(vt->tmpbuffer + cur, vt->tmpbuffer_len - cur,
! argi == argc - 1 ? "%ld" :
! CSI_ARG_HAS_MORE(args[argi]) ? "%ld:" :
! "%ld;",
! CSI_ARG(args[argi]));
! if(cur >= vt->tmpbuffer_len)
! return;
! }
!
! cur += snprintf(vt->tmpbuffer + cur, vt->tmpbuffer_len - cur,
! vt->mode.ctrl8bit ? "m" "\x9C" : "m" ESC_S "\\"); // ... m ST
! if(cur >= vt->tmpbuffer_len)
return;
+
+ vterm_push_output_bytes(vt, vt->tmpbuffer, cur);
+ return;
}
! case 'r':
! // Query DECSTBM
! vterm_push_output_sprintf_dcs(vt, "1$r%d;%dr", state->scrollregion_top+1, SCROLLREGION_BOTTOM(state));
! return;
!
! case 's':
! // Query DECSLRM
! vterm_push_output_sprintf_dcs(vt, "1$r%d;%ds", SCROLLREGION_LEFT(state)+1, SCROLLREGION_RIGHT(state));
! return;
!
! case ' '|('q'<<8): {
! // Query DECSCUSR
int reply;
switch(state->mode.cursor_shape) {
case VTERM_PROP_CURSORSHAPE_BLOCK: reply = 2; break;
***************
*** 1707,1733 ****
vterm_push_output_sprintf_dcs(vt, "1$r%d q", reply);
return;
}
! else if(strneq(command, "\"q", 2)) {
vterm_push_output_sprintf_dcs(vt, "1$r%d\"q", state->protected_cell ? 1 : 2);
return;
- }
}
! vterm_push_output_sprintf_dcs(state->vt, "0$r%.s", (int)cmdlen, command);
}
! static int on_dcs(const char *command, size_t cmdlen, void *user)
{
VTermState *state = user;
! if(cmdlen >= 2 && strneq(command, "$q", 2)) {
! request_status_string(state, command+2, cmdlen-2);
return 1;
}
else if(state->fallbacks && state->fallbacks->dcs)
! if((*state->fallbacks->dcs)(command, cmdlen, state->fbdata))
return 1;
return 0;
}
--- 1721,1749 ----
vterm_push_output_sprintf_dcs(vt, "1$r%d q", reply);
return;
}
!
! case '\"'|('q'<<8):
! // Query DECSCA
vterm_push_output_sprintf_dcs(vt, "1$r%d\"q", state->protected_cell ? 1 : 2);
return;
}
! vterm_push_output_sprintf_dcs(state->vt, "0$r%s", tmp);
}
! static int on_dcs(const char *command, size_t commandlen, VTermStringFragment frag, void *user)
{
VTermState *state = user;
! if(commandlen == 2 && strneq(command, "$q", 2)) {
! request_status_string(state, frag);
return 1;
}
else if(state->fallbacks && state->fallbacks->dcs)
! if((*state->fallbacks->dcs)(command, commandlen, frag, state->fbdata))
return 1;
+ DEBUG_LOG2("libvterm: Unhandled DCS %.*s\n", (int)commandlen, command);
return 0;
}
*** ../vim-8.2.0797/src/libvterm/src/vterm.c 2020-05-17 23:34:37.576176126 +0200
--- src/libvterm/src/vterm.c 2020-05-19 19:40:53.294811735 +0200
***************
*** 55,89 ****
vt->parser.callbacks = NULL;
vt->parser.cbdata = NULL;
- vt->parser.strbuffer_len = 500; // should be able to hold an OSC string
- vt->parser.strbuffer_cur = 0;
- vt->parser.strbuffer = vterm_allocator_malloc(vt, vt->parser.strbuffer_len);
- if (vt->parser.strbuffer == NULL)
- {
- vterm_allocator_free(vt, vt);
- return NULL;
- }
-
vt->outfunc = NULL;
vt->outdata = NULL;
vt->outbuffer_len = 200;
vt->outbuffer_cur = 0;
vt->outbuffer = vterm_allocator_malloc(vt, vt->outbuffer_len);
- if (vt->outbuffer == NULL)
- {
- vterm_allocator_free(vt, vt->parser.strbuffer);
- vterm_allocator_free(vt, vt);
- return NULL;
- }
vt->tmpbuffer_len = 64;
vt->tmpbuffer = vterm_allocator_malloc(vt, vt->tmpbuffer_len);
! if (vt->tmpbuffer == NULL)
{
- vterm_allocator_free(vt, vt->parser.strbuffer);
- vterm_allocator_free(vt, vt);
vterm_allocator_free(vt, vt->outbuffer);
return NULL;
}
--- 55,77 ----
vt->parser.callbacks = NULL;
vt->parser.cbdata = NULL;
vt->outfunc = NULL;
vt->outdata = NULL;
vt->outbuffer_len = 200;
vt->outbuffer_cur = 0;
vt->outbuffer = vterm_allocator_malloc(vt, vt->outbuffer_len);
vt->tmpbuffer_len = 64;
vt->tmpbuffer = vterm_allocator_malloc(vt, vt->tmpbuffer_len);
!
! if (vt->tmpbuffer == NULL
! || vt->outbuffer == NULL
! || vt->tmpbuffer == NULL)
{
vterm_allocator_free(vt, vt->outbuffer);
+ vterm_allocator_free(vt, vt->tmpbuffer);
+ vterm_allocator_free(vt, vt);
return NULL;
}
***************
*** 98,104 ****
if(vt->state)
vterm_state_free(vt->state);
- vterm_allocator_free(vt, vt->parser.strbuffer);
vterm_allocator_free(vt, vt->outbuffer);
vterm_allocator_free(vt, vt->tmpbuffer);
--- 86,91 ----
*** ../vim-8.2.0797/src/libvterm/src/vterm_internal.h 2020-05-18 21:12:55.226306815 +0200
--- src/libvterm/src/vterm_internal.h 2020-05-19 19:44:40.386559385 +0200
***************
*** 160,173 ****
unsigned int cursor_shape:2;
} mode;
} saved;
- };
-
- typedef enum {
- VTERM_PARSER_OSC,
- VTERM_PARSER_DCS,
! VTERM_N_PARSER_TYPES
! } VTermParserStringType;
struct VTerm
{
--- 160,171 ----
unsigned int cursor_shape:2;
} mode;
} saved;
! /* Temporary state for DECRQSS parsing */
! union {
! char decrqss[4];
! } tmp;
! };
struct VTerm
{
***************
*** 188,215 ****
CSI_LEADER,
CSI_ARGS,
CSI_INTERMED,
! ESC,
// below here are the "string states"
! STRING,
! ESC_IN_STRING,
} state;
int intermedlen;
char intermed[INTERMED_MAX];
! int csi_leaderlen;
! char csi_leader[CSI_LEADER_MAX];
!
! int csi_argi;
! long csi_args[CSI_ARGS_MAX];
const VTermParserCallbacks *callbacks;
void *cbdata;
! VTermParserStringType stringtype;
! char *strbuffer;
! size_t strbuffer_len;
! size_t strbuffer_cur;
} parser;
// len == malloc()ed size; cur == number of valid bytes
--- 186,224 ----
CSI_LEADER,
CSI_ARGS,
CSI_INTERMED,
! OSC_COMMAND,
! DCS_COMMAND,
// below here are the "string states"
! OSC,
! DCS,
} state;
+ unsigned int in_esc : 1;
+
int intermedlen;
char intermed[INTERMED_MAX];
! union {
! struct {
! int leaderlen;
! char leader[CSI_LEADER_MAX];
!
! int argi;
! long args[CSI_ARGS_MAX];
! } csi;
! struct {
! int command;
! } osc;
! struct {
! int commandlen;
! char command[CSI_LEADER_MAX];
! } dcs;
! } v;
const VTermParserCallbacks *callbacks;
void *cbdata;
! int string_initial;
} parser;
// len == malloc()ed size; cur == number of valid bytes
*** ../vim-8.2.0797/src/libvterm/t/02parser.test 2017-06-24 16:44:02.000000000 +0200
--- src/libvterm/t/02parser.test 2020-05-19 19:15:23.211486825 +0200
***************
*** 132,146 ****
!OSC BEL
PUSH "\e]1;Hello\x07"
! osc "1;Hello"
!OSC ST (7bit)
PUSH "\e]1;Hello\e\\"
! osc "1;Hello"
!OSC ST (8bit)
PUSH "\x{9d}1;Hello\x9c"
! osc "1;Hello"
!Escape cancels OSC, starts Escape
PUSH "\e]Something\e9"
--- 132,154 ----
!OSC BEL
PUSH "\e]1;Hello\x07"
! osc [1 "Hello"]
!OSC ST (7bit)
PUSH "\e]1;Hello\e\\"
! osc [1 "Hello"]
!OSC ST (8bit)
PUSH "\x{9d}1;Hello\x9c"
! osc [1 "Hello"]
!
! !OSC in parts
! PUSH "\e]52;abc"
! osc [52 "abc"
! PUSH "def"
! osc "def"
! PUSH "ghi\e\\"
! osc "ghi"]
!Escape cancels OSC, starts Escape
PUSH "\e]Something\e9"
***************
*** 152,171 ****
!C0 in OSC interrupts and continues
PUSH "\e]2;\nBye\x07"
control 10
! osc "2;Bye"
!DCS BEL
PUSH "\ePHello\x07"
! dcs "Hello"
!DCS ST (7bit)
PUSH "\ePHello\e\\"
! dcs "Hello"
!DCS ST (8bit)
PUSH "\x{90}Hello\x9c"
! dcs "Hello"
!Escape cancels DCS, starts Escape
PUSH "\ePSomething\e9"
--- 160,180 ----
!C0 in OSC interrupts and continues
PUSH "\e]2;\nBye\x07"
+ osc [2 ""
control 10
! osc "Bye"]
!DCS BEL
PUSH "\ePHello\x07"
! dcs ["Hello"]
!DCS ST (7bit)
PUSH "\ePHello\e\\"
! dcs ["Hello"]
!DCS ST (8bit)
PUSH "\x{90}Hello\x9c"
! dcs ["Hello"]
!Escape cancels DCS, starts Escape
PUSH "\ePSomething\e9"
***************
*** 177,184 ****
!C0 in OSC interrupts and continues
PUSH "\ePBy\ne\x07"
control 10
! dcs "Bye"
!NUL ignored
PUSH "\x{00}"
--- 186,194 ----
!C0 in OSC interrupts and continues
PUSH "\ePBy\ne\x07"
+ dcs ["By"
control 10
! dcs "e"]
!NUL ignored
PUSH "\x{00}"
*** ../vim-8.2.0797/src/libvterm/t/18state_termprops.test 2017-06-24 16:44:02.000000000 +0200
--- src/libvterm/t/18state_termprops.test 2020-05-19 19:15:23.211486825 +0200
***************
*** 33,36 ****
!Title
PUSH "\e]2;Here is my title\a"
! settermprop 4 "Here is my title"
--- 33,42 ----
!Title
PUSH "\e]2;Here is my title\a"
! settermprop 4 ["Here is my title"]
!
! !Title split write
! PUSH "\e]2;Here is"
! settermprop 4 ["Here is"
! PUSH " another title\a"
! settermprop 4 " another title"]
*** ../vim-8.2.0797/src/libvterm/t/29state_fallback.test 2017-06-24 16:44:02.000000000 +0200
--- src/libvterm/t/29state_fallback.test 2020-05-19 19:15:23.211486825 +0200
***************
*** 12,19 ****
!Unrecognised OSC
PUSH "\e]27;Something\e\\"
! osc "27;Something"
!Unrecognised DCS
PUSH "\ePz123\e\\"
! dcs "z123"
--- 12,19 ----
!Unrecognised OSC
PUSH "\e]27;Something\e\\"
! osc [27 "Something"]
!Unrecognised DCS
PUSH "\ePz123\e\\"
! dcs ["z123"]
*** ../vim-8.2.0797/src/libvterm/t/68screen_termprops.test 2020-05-17 16:28:47.087869402 +0200
--- src/libvterm/t/68screen_termprops.test 2020-05-19 19:15:23.211486825 +0200
***************
*** 14,17 ****
!Title
PUSH "\e]2;Here is my title\a"
! settermprop 4 "Here is my title"
--- 14,17 ----
!Title
PUSH "\e]2;Here is my title\a"
! settermprop 4 ["Here is my title"]
*** ../vim-8.2.0797/src/libvterm/t/harness.c 2020-05-18 21:50:32.932742338 +0200
--- src/libvterm/t/harness.c 2020-05-19 21:14:58.824143429 +0200
***************
*** 153,173 ****
return 1;
}
! static int parser_osc(const char *command, size_t cmdlen, void *user UNUSED)
{
printf("osc ");
! printhex(command, cmdlen);
printf("\n");
return 1;
}
! static int parser_dcs(const char *command, size_t cmdlen, void *user UNUSED)
{
-
printf("dcs ");
! printhex(command, cmdlen);
printf("\n");
return 1;
--- 153,196 ----
return 1;
}
! static int parser_osc(int command, VTermStringFragment frag, void *user UNUSED)
{
printf("osc ");
!
! if(frag.initial) {
! if(command == -1)
! printf("[");
! else
! printf("[%d;", command);
! }
!
! printhex(frag.str, frag.len);
!
! if(frag.final)
! printf("]");
!
printf("\n");
return 1;
}
! static int parser_dcs(const char *command, size_t commandlen, VTermStringFragment frag, void *user UNUSED)
{
printf("dcs ");
!
! if(frag.initial) {
! size_t i;
! printf("[");
! for(i = 0; i < commandlen; i++)
! printf("%02x", command[i]);
! }
!
! printhex(frag.str, frag.len);
!
! if(frag.final)
! printf("]");
!
printf("\n");
return 1;
***************
*** 239,245 ****
printf("settermprop %d %d\n", prop, val->number);
return 1;
case VTERM_VALUETYPE_STRING:
! printf("settermprop %d \"%s\"\n", prop, val->string);
return 1;
case VTERM_VALUETYPE_COLOR:
printf("settermprop %d rgb(%d,%d,%d)\n", prop, val->color.red, val->color.green, val->color.blue);
--- 262,269 ----
printf("settermprop %d %d\n", prop, val->number);
return 1;
case VTERM_VALUETYPE_STRING:
! printf("settermprop %d %s\"%.*s\"%s\n", prop,
! val->string.initial ? "[" : "", val->string.len, val->string.str, val->string.final ? "]" : "");
return 1;
case VTERM_VALUETYPE_COLOR:
printf("settermprop %d rgb(%d,%d,%d)\n", prop, val->color.red, val->color.green, val->color.blue);
***************
*** 262,268 ****
return 1;
printf("putglyph ");
! for(i = 0; info->chars[i]; i++)
printf(i ? ",%x" : "%x", info->chars[i]);
printf(" %d %d,%d", info->width, pos.row, pos.col);
if(info->protected_cell)
--- 286,292 ----
return 1;
printf("putglyph ");
! for(i = 0; i < VTERM_MAX_CHARS_PER_CELL && info->chars[i]; i++)
printf(i ? ",%x" : "%x", info->chars[i]);
printf(" %d %d,%d", info->width, pos.row, pos.col);
if(info->protected_cell)
*** ../vim-8.2.0797/src/terminal.c 2020-04-26 16:05:58.574358031 +0200
--- src/terminal.c 2020-05-19 21:05:54.929679591 +0200
***************
*** 2998,3019 ****
void *user)
{
term_T *term = (term_T *)user;
switch (prop)
{
case VTERM_PROP_TITLE:
vim_free(term->tl_title);
// a blank title isn't useful, make it empty, so that "running" is
// displayed
! if (*skipwhite((char_u *)value->string) == NUL)
term->tl_title = NULL;
// Same as blank
else if (term->tl_arg0_cmd != NULL
! && STRNCMP(term->tl_arg0_cmd, (char_u *)value->string,
(int)STRLEN(term->tl_arg0_cmd)) == 0)
term->tl_title = NULL;
// Empty corrupted data of winpty
! else if (STRNCMP(" - ", (char_u *)value->string, 4) == 0)
term->tl_title = NULL;
#ifdef MSWIN
else if (!enc_utf8 && enc_codepage > 0)
--- 2998,3024 ----
void *user)
{
term_T *term = (term_T *)user;
+ char_u *strval = NULL;
switch (prop)
{
case VTERM_PROP_TITLE:
+ strval = vim_strnsave((char_u *)value->string.str,
+ (int)value->string.len);
+ if (strval == NULL)
+ break;
vim_free(term->tl_title);
// a blank title isn't useful, make it empty, so that "running" is
// displayed
! if (*skipwhite(strval) == NUL)
term->tl_title = NULL;
// Same as blank
else if (term->tl_arg0_cmd != NULL
! && STRNCMP(term->tl_arg0_cmd, strval,
(int)STRLEN(term->tl_arg0_cmd)) == 0)
term->tl_title = NULL;
// Empty corrupted data of winpty
! else if (STRNCMP(" - ", strval, 4) == 0)
term->tl_title = NULL;
#ifdef MSWIN
else if (!enc_utf8 && enc_codepage > 0)
***************
*** 3022,3029 ****
int length = 0;
MultiByteToWideChar_alloc(CP_UTF8, 0,
! (char*)value->string, (int)STRLEN(value->string),
! &ret, &length);
if (ret != NULL)
{
WideCharToMultiByte_alloc(enc_codepage, 0,
--- 3027,3034 ----
int length = 0;
MultiByteToWideChar_alloc(CP_UTF8, 0,
! (char*)value->string.str,
! (int)value->string.len, &ret, &length);
if (ret != NULL)
{
WideCharToMultiByte_alloc(enc_codepage, 0,
***************
*** 3034,3040 ****
}
#endif
else
! term->tl_title = vim_strsave((char_u *)value->string);
VIM_CLEAR(term->tl_status_text);
if (term == curbuf->b_term)
maketitle();
--- 3039,3048 ----
}
#endif
else
! {
! term->tl_title = vim_strsave(strval);
! strval = NULL;
! }
VIM_CLEAR(term->tl_status_text);
if (term == curbuf->b_term)
maketitle();
***************
*** 3057,3063 ****
break;
case VTERM_PROP_CURSORCOLOR:
! cursor_color_copy(&term->tl_cursor_color, (char_u*)value->string);
may_set_cursor_props(term);
break;
--- 3065,3075 ----
break;
case VTERM_PROP_CURSORCOLOR:
! strval = vim_strnsave((char_u *)value->string.str,
! (int)value->string.len);
! if (strval == NULL)
! break;
! cursor_color_copy(&term->tl_cursor_color, strval);
may_set_cursor_props(term);
break;
***************
*** 3069,3074 ****
--- 3081,3088 ----
default:
break;
}
+ vim_free(strval);
+
// Always return 1, otherwise vterm doesn't store the value internally.
return 1;
}
***************
*** 4181,4187 ****
* We recognize a terminal API command.
*/
static int
! parse_osc(const char *command, size_t cmdlen, void *user)
{
term_T *term = (term_T *)user;
js_read_T reader;
--- 4195,4201 ----
* We recognize a terminal API command.
*/
static int
! parse_osc(int command, VTermStringFragment frag, void *user)
{
term_T *term = (term_T *)user;
js_read_T reader;
***************
*** 4190,4199 ****
: term->tl_job->jv_channel;
// We recognize only OSC 5 1 ; {command}
! if (cmdlen < 3 || STRNCMP(command, "51;", 3) != 0)
! return 0; // not handled
! reader.js_buf = vim_strnsave((char_u *)command + 3, (int)(cmdlen - 3));
if (reader.js_buf == NULL)
return 1;
reader.js_fill = NULL;
--- 4204,4213 ----
: term->tl_job->jv_channel;
// We recognize only OSC 5 1 ; {command}
! if (command != 51)
! return 0;
! reader.js_buf = vim_strnsave((char_u *)frag.str, (int)(frag.len));
if (reader.js_buf == NULL)
return 1;
reader.js_fill = NULL;
*** ../vim-8.2.0797/src/version.c 2020-05-19 10:32:59.291518426 +0200
--- src/version.c 2020-05-19 21:17:50.119661570 +0200
***************
*** 748,749 ****
--- 748,751 ----
{ /* Add new patch number below this line */
+ /**/
+ 798,
/**/
--
hundred-and-one symptoms of being an internet addict:
136. You decide to stay in a low-paying job teaching just for the
free Internet access.
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language --
http://www.Zimbu.org ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///