patch 9.0.0774: the libvterm code is outdated

Problem:    The libvterm code is outdated.
Solution:   Include libvterm changes from revision 802 to 817.  Revert some
            changes made for C89.
diff --git a/src/libvterm/t/10state_putglyph.test b/src/libvterm/t/10state_putglyph.test
index bae0423..c82c525 100644
--- a/src/libvterm/t/10state_putglyph.test
+++ b/src/libvterm/t/10state_putglyph.test
@@ -52,6 +52,12 @@
   putglyph 0x65,0x301 1 0,0
   putglyph 0x5a 1 0,1
 
+!Spare combining chars get truncated
+RESET
+PUSH "e" . "\xCC\x81" x 10
+  putglyph 0x65,0x301,0x301,0x301,0x301,0x301 1 0,0
+  # and nothing more
+
 RESET
 PUSH "e"
   putglyph 0x65 1 0,0
diff --git a/src/libvterm/t/13state_edit.test b/src/libvterm/t/13state_edit.test
index b435655..d3f3e9e 100644
--- a/src/libvterm/t/13state_edit.test
+++ b/src/libvterm/t/13state_edit.test
@@ -1,6 +1,6 @@
 INIT
 UTF8 1
-WANTSTATE se
+WANTSTATE seb
 
 !ICH
 RESET
@@ -242,6 +242,10 @@
   erase 0..25,0..80
   ?cursor = 1,1
 
+!ED 3
+PUSH "\e[3J"
+  sb_clear
+
 !SED
 RESET
   erase 0..25,0..80
diff --git a/src/libvterm/t/26state_query.test b/src/libvterm/t/26state_query.test
index e4513de..41e7cf8 100644
--- a/src/libvterm/t/26state_query.test
+++ b/src/libvterm/t/26state_query.test
@@ -9,7 +9,7 @@
 !XTVERSION
 RESET
 PUSH "\e[>q"
-  output "\eP>|libvterm(0.2)\e\\"
+  output "\eP>|libvterm(0.3)\e\\"
 
 !DSR
 RESET
diff --git a/src/libvterm/t/30state_pen.test b/src/libvterm/t/30state_pen.test
index 915baec..92cf01d 100644
--- a/src/libvterm/t/30state_pen.test
+++ b/src/libvterm/t/30state_pen.test
@@ -112,3 +112,14 @@
 PUSH "\e[m\e[37;1m"
   ?pen bold = on
   ?pen foreground = idx(15)
+
+!Super/Subscript
+PUSH "\e[73m"
+  ?pen small = on
+  ?pen baseline = raise
+PUSH "\e[74m"
+  ?pen small = on
+  ?pen baseline = lower
+PUSH "\e[75m"
+  ?pen small = off
+  ?pen baseline = normal
diff --git a/src/libvterm/t/64screen_pen.test b/src/libvterm/t/64screen_pen.test
index 3a78140..1cb6324 100644
--- a/src/libvterm/t/64screen_pen.test
+++ b/src/libvterm/t/64screen_pen.test
@@ -35,6 +35,12 @@
 PUSH "\e[42mH\e[m"
   ?screen_cell 0,7 = {0x48} width=1 attrs={} fg=rgb(240,240,240) bg=idx(2)
 
+!Super/subscript
+PUSH "x\e[74m0\e[73m2\e[m"
+  ?screen_cell 0,8  = {0x78} width=1 attrs={} fg=rgb(240,240,240) bg=rgb(0,0,0)
+  ?screen_cell 0,9  = {0x30} width=1 attrs={S_} fg=rgb(240,240,240) bg=rgb(0,0,0)
+  ?screen_cell 0,10 = {0x32} width=1 attrs={S^} fg=rgb(240,240,240) bg=rgb(0,0,0)
+
 !EL sets reverse and colours to end of line
 PUSH "\e[H\e[7;33;44m\e[K"
   ?screen_cell 0,0  = {} width=1 attrs={R} fg=idx(3) bg=idx(4)
diff --git a/src/libvterm/t/69screen_reflow.test b/src/libvterm/t/69screen_reflow.test
new file mode 100644
index 0000000..278cc5b
--- /dev/null
+++ b/src/libvterm/t/69screen_reflow.test
@@ -0,0 +1,79 @@
+INIT
+# Run these tests on a much smaller default screen, so debug output is
+# nowhere near as noisy
+RESIZE 5,10
+WANTSTATE
+WANTSCREEN r
+RESET
+
+!Resize wider reflows wide lines
+RESET
+PUSH "A"x12
+  ?screen_row 0 = "AAAAAAAAAA"
+  ?screen_row 1 = "AA"
+  ?lineinfo 1 = cont
+  ?cursor = 1,2
+RESIZE 5,15
+  ?screen_row 0 = "AAAAAAAAAAAA"
+  ?screen_row 1 = 
+  ?lineinfo 1 =
+  ?cursor = 0,12
+RESIZE 5,20
+  ?screen_row 0 = "AAAAAAAAAAAA"
+  ?screen_row 1 = 
+  ?lineinfo 1 =
+  ?cursor = 0,12
+
+!Resize narrower can create continuation lines
+RESET
+RESIZE 5,10
+PUSH "ABCDEFGHI"
+  ?screen_row 0 = "ABCDEFGHI"
+  ?screen_row 1 = ""
+  ?lineinfo 1 =
+  ?cursor = 0,9
+RESIZE 5,8
+  ?screen_row 0 = "ABCDEFGH"
+  ?screen_row 1 = "I"
+  ?lineinfo 1 = cont
+  ?cursor = 1,1
+RESIZE 5,6
+  ?screen_row 0 = "ABCDEF"
+  ?screen_row 1 = "GHI"
+  ?lineinfo 1 = cont
+  ?cursor = 1,3
+
+!Shell wrapped prompt behaviour
+RESET
+RESIZE 5,10
+PUSH "PROMPT GOES HERE\r\n> \r\n\r\nPROMPT GOES HERE\r\n> "
+  ?screen_row 0 = "> "
+  ?screen_row 1 = ""
+  ?screen_row 2 = "PROMPT GOE"
+  ?screen_row 3 = "S HERE"
+  ?lineinfo 3 = cont
+  ?screen_row 4 = "> "
+  ?cursor = 4,2
+RESIZE 5,11
+  ?screen_row 0 = "> "
+  ?screen_row 1 = ""
+  ?screen_row 2 = "PROMPT GOES"
+  ?screen_row 3 = " HERE"
+  ?lineinfo 3 = cont
+  ?screen_row 4 = "> "
+  ?cursor = 4,2
+RESIZE 5,12
+  ?screen_row 0 = "> "
+  ?screen_row 1 = ""
+  ?screen_row 2 = "PROMPT GOES "
+  ?screen_row 3 = "HERE"
+  ?lineinfo 3 = cont
+  ?screen_row 4 = "> "
+  ?cursor = 4,2
+RESIZE 5,16
+  ?screen_row 0 = "> "
+  ?screen_row 1 = ""
+  ?screen_row 2 = "PROMPT GOES HERE"
+  ?lineinfo 3 =
+  ?screen_row 3 = "> "
+  ?cursor = 3,2
diff --git a/src/libvterm/t/harness.c b/src/libvterm/t/harness.c
index 4e24198..d12c120 100644
--- a/src/libvterm/t/harness.c
+++ b/src/libvterm/t/harness.c
@@ -1,6 +1,7 @@
 #include "vterm.h"
 #include "../src/vterm_internal.h" // We pull in some internal bits too
 
+#include <assert.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -409,6 +410,8 @@
   int conceal;
   int strike;
   int font;
+  int small;
+  int baseline;
   VTermColor foreground;
   VTermColor background;
 } state_pen;
@@ -439,6 +442,12 @@
   case VTERM_ATTR_FONT:
     state_pen.font = val->number;
     break;
+  case VTERM_ATTR_SMALL:
+    state_pen.small = val->boolean;
+    break;
+  case VTERM_ATTR_BASELINE:
+    state_pen.baseline = val->number;
+    break;
   case VTERM_ATTR_FOREGROUND:
     state_pen.foreground = val->color;
     break;
@@ -458,6 +467,15 @@
   return 1;
 }
 
+static int want_state_scrollback = 0;
+static int state_sb_clear(void *user UNUSED) {
+  if(!want_state_scrollback)
+    return 1;
+
+  printf("sb_clear\n");
+  return 0;
+}
+
 VTermStateCallbacks state_cbs = {
   state_putglyph, // putglyph
   movecursor, // movecursor
@@ -470,6 +488,7 @@
   NULL, // bell
   NULL, // resize
   state_setlineinfo, // setlineinfo
+  state_sb_clear, // sb_clear
 };
 
 static int selection_set(VTermSelectionMask mask, VTermStringFragment frag, void *user UNUSED)
@@ -592,6 +611,15 @@
   return 1;
 }
 
+static int screen_sb_clear(void *user UNUSED)
+{
+  if(!want_screen_scrollback)
+    return 1;
+
+  printf("sb_clear\n");
+  return 0;
+}
+
 VTermScreenCallbacks screen_cbs = {
   screen_damage, // damage
   moverect, // moverect
@@ -600,7 +628,8 @@
   NULL, // bell
   NULL, // resize
   screen_sb_pushline, // sb_pushline
-  screen_sb_popline // sb_popline
+  screen_sb_popline, // sb_popline
+  screen_sb_clear, // sb_clear
 };
 
 int main(int argc UNUSED, char **argv UNUSED)
@@ -629,12 +658,14 @@
     }
 
     else if(streq(line, "WANTPARSER")) {
+      assert(vt);
       vterm_parser_set_callbacks(vt, &parser_cbs, NULL);
     }
 
     else if(strstartswith(line, "WANTSTATE") && (line[9] == '\0' || line[9] == ' ')) {
       int i = 9;
       int sense = 1;
+      assert(vt);
       if(!state) {
         state = vterm_obtain_state(vt);
         vterm_state_set_callbacks(state, &state_cbs, NULL);
@@ -671,6 +702,9 @@
         case 'f':
           vterm_state_set_unrecognised_fallbacks(state, sense ? &fallbacks : NULL, NULL);
           break;
+        case 'b':
+          want_state_scrollback = sense;
+          break;
         default:
           fprintf(stderr, "Unrecognised WANTSTATE flag '%c'\n", line[i]);
         }
@@ -679,6 +713,7 @@
     else if(strstartswith(line, "WANTSCREEN") && (line[10] == '\0' || line[10] == ' ')) {
       int i = 10;
       int sense = 1;
+      assert(vt);
       if(!screen)
         screen = vterm_obtain_screen(vt);
       vterm_screen_set_callbacks(screen, &screen_cbs, NULL);
@@ -712,6 +747,9 @@
         case 'b':
           want_screen_scrollback = sense;
           break;
+        case 'r':
+          vterm_screen_enable_reflow(screen, sense);
+          break;
         default:
           fprintf(stderr, "Unrecognised WANTSCREEN flag '%c'\n", line[i]);
         }
@@ -743,6 +781,8 @@
     else if(strstartswith(line, "PUSH ")) {
       char *bytes = line + 5;
       size_t len = inplace_hex2bytes(bytes);
+      assert(len);
+
       size_t written = vterm_input_write(vt, bytes, len);
       if(written < len)
         fprintf(stderr, "! short write\n");
@@ -759,6 +799,7 @@
     else if(strstartswith(line, "ENCIN ")) {
       char *bytes = line + 6;
       size_t len = inplace_hex2bytes(bytes);
+      assert(len);
 
       uint32_t cp[1024];
       int cpi = 0;
@@ -814,6 +855,7 @@
     }
 
     else if(strstartswith(line, "FOCUS ")) {
+      assert(state);
       char *linep = line + 6;
       if(streq(linep, "IN"))
         vterm_state_focus_in(state);
@@ -869,6 +911,8 @@
       }
       frag.len = inplace_hex2bytes(linep);
       frag.str = linep;
+      assert(frag.len);
+
       linep += frag.len * 2;
       while(linep[0] == ' ')
         linep++;
@@ -879,6 +923,7 @@
     }
 
     else if(strstartswith(line, "DAMAGEMERGE ")) {
+      assert(screen);
       char *linep = line + 12;
       while(linep[0] == ' ')
         linep++;
@@ -893,11 +938,13 @@
     }
 
     else if(strstartswith(line, "DAMAGEFLUSH")) {
+      assert(screen);
       vterm_screen_flush_damage(screen);
     }
 
     else if(line[0] == '?') {
       if(streq(line, "?cursor")) {
+        assert(state);
         VTermPos pos;
         vterm_state_get_cursorpos(state, &pos);
         if(pos.row != state_pos.row)
@@ -910,6 +957,7 @@
           printf("%d,%d\n", state_pos.row, state_pos.col);
       }
       else if(strstartswith(line, "?pen ")) {
+        assert(state);
         VTermValue val;
         char *linep = line + 5;
         while(linep[0] == ' ')
@@ -965,6 +1013,24 @@
           else
             printf("%d\n", state_pen.font);
         }
+        else if(streq(linep, "small")) {
+          vterm_state_get_penattr(state, VTERM_ATTR_SMALL, &val);
+          if(val.boolean != state_pen.small)
+            printf("! pen small mismatch; state=%s, event=%s\n",
+                BOOLSTR(val.boolean), BOOLSTR(state_pen.small));
+          else
+            printf("%s\n", BOOLSTR(state_pen.small));
+        }
+        else if(streq(linep, "baseline")) {
+          vterm_state_get_penattr(state, VTERM_ATTR_BASELINE, &val);
+          if(val.number != state_pen.baseline)
+            printf("! pen baseline mismatch: state=%d, event=%d\n",
+                val.number, state_pen.baseline);
+          else
+            printf("%s\n", state_pen.baseline == VTERM_BASELINE_RAISE ? "raise"
+                         : state_pen.baseline == VTERM_BASELINE_LOWER ? "lower"
+                         : "normal");
+        }
         else if(streq(linep, "foreground")) {
           print_color(&state_pen.foreground);
           printf("\n");
@@ -977,6 +1043,7 @@
           printf("?\n");
       }
       else if(strstartswith(line, "?lineinfo ")) {
+        assert(state);
         char *linep = line + 10;
         int row;
         const VTermLineInfo *info;
@@ -996,6 +1063,7 @@
         printf("\n");
       }
       else if(strstartswith(line, "?screen_chars ")) {
+        assert(screen);
         char *linep = line + 13;
         VTermRect rect;
         size_t len;
@@ -1028,6 +1096,7 @@
         }
       }
       else if(strstartswith(line, "?screen_text ")) {
+        assert(screen);
         char *linep = line + 12;
         VTermRect rect;
         size_t len;
@@ -1067,6 +1136,7 @@
         }
       }
       else if(strstartswith(line, "?screen_cell ")) {
+        assert(screen);
         char *linep = line + 12;
 	int i;
         VTermPos pos;
@@ -1090,6 +1160,10 @@
         if(cell.attrs.blink)     printf("K");
         if(cell.attrs.reverse)   printf("R");
         if(cell.attrs.font)      printf("F%d", cell.attrs.font);
+        if(cell.attrs.small)     printf("S");
+        if(cell.attrs.baseline)  printf(
+            cell.attrs.baseline == VTERM_BASELINE_RAISE ? "^" :
+                                                          "_");
         printf("} ");
         if(cell.attrs.dwl)       printf("dwl ");
         if(cell.attrs.dhl)       printf("dhl-%s ", cell.attrs.dhl == 2 ? "bottom" : "top");
@@ -1102,6 +1176,7 @@
         printf("\n");
       }
       else if(strstartswith(line, "?screen_eol ")) {
+        assert(screen);
         VTermPos pos;
         char *linep = line + 12;
         while(linep[0] == ' ')
@@ -1113,6 +1188,7 @@
         printf("%d\n", vterm_screen_is_eol(screen, pos));
       }
       else if(strstartswith(line, "?screen_attrs_extent ")) {
+        assert(screen);
         VTermPos pos;
         VTermRect rect;
         char *linep = line + 21;
diff --git a/src/libvterm/t/run-test.pl b/src/libvterm/t/run-test.pl
index 7d5cc7b..3440465 100644
--- a/src/libvterm/t/run-test.pl
+++ b/src/libvterm/t/run-test.pl
@@ -124,7 +124,7 @@
       elsif( $line =~ m/^putglyph (\S+) (.*)$/ ) {
          $line = "putglyph " . join( ",", map sprintf("%x", $_), eval($1) ) . " $2";
       }
-      elsif( $line =~ m/^(?:movecursor|scrollrect|moverect|erase|damage|sb_pushline|sb_popline|settermprop|setmousefunc|selection-query) / ) {
+      elsif( $line =~ m/^(?:movecursor|scrollrect|moverect|erase|damage|sb_pushline|sb_popline|sb_clear|settermprop|setmousefunc|selection-query) ?/ ) {
          # no conversion
       }
       elsif( $line =~ m/^(selection-set) (.*?) (\[?)(.*?)(\]?)$/ ) {