This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository terminology.

View the commit online.

commit 27ad9f518edc9ee30196fc2df4e2f32408f6fd44
Author: Boris Faure <[email protected]>
AuthorDate: Sat Aug 22 14:37:32 2026 +0200

    tytest: add --dump to print the state in a diffable form
---
 src/bin/tytest.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 168 insertions(+), 2 deletions(-)

diff --git a/src/bin/tytest.c b/src/bin/tytest.c
index 95c0a340..dd99b46c 100644
--- a/src/bin/tytest.c
+++ b/src/bin/tytest.c
@@ -14,6 +14,7 @@
 #include "termpty.h"
 #include "termptyops.h"
 #include "backlog.h"
+#include "utf8.h"
 #include "termiointernals.h"
 #include "tytest.h"
 #include "unit_tests.h"
@@ -246,18 +247,181 @@ _tytest_checksum(Termpty *ty)
 }
 
 
+/* Render a cell's codepoint into a dump-safe form.
+ *
+ * Anything that would move the cursor or otherwise talk back to the terminal
+ * displaying the dump has to be escaped, or reading a dump would garble the
+ * reader's own screen. */
+static void
+_dump_codepoint(Eina_Unicode g)
+{
+   char utf8[8];
+   int n;
+
+   if (g == 0)
+     {
+        putchar(' ');
+        return;
+     }
+   /* Media blocks are encoded with bit 31 set and are not text at all. */
+   if (g & 0x80000000)
+     {
+        printf("\\B");
+        return;
+     }
+   if (g < 0x20 || g == 0x7f)
+     {
+        printf("\\x%02x", (unsigned int)g);
+        return;
+     }
+   n = codepoint_to_utf8(g, utf8);
+   if (n <= 0)
+     {
+        printf("\\u%04x", (unsigned int)g);
+        return;
+     }
+   fwrite(utf8, 1, n, stdout);
+}
+
+/* Emit one row as text plus a run-length summary of its attributes.
+ *
+ * Attributes are summarised rather than printed per cell because the point is
+ * to make a diff between two dumps land on the cell that actually differs,
+ * without burying it in eighty identical attribute records. */
+static void
+_dump_row(const Termcell *cells, int w, const char *label)
+{
+   int x, start;
+
+   printf("%s |", label);
+   for (x = 0; x < w; x++)
+     _dump_codepoint(cells[x].codepoint);
+   printf("|\n");
+
+   x = 0;
+   while (x < w)
+     {
+        const Termatt *a = &cells[x].att;
+
+        start = x;
+        while ((x < w) &&
+               (memcmp(&cells[x].att, a, sizeof(Termatt)) == 0))
+          x++;
+        /* Skip the default run: saying nothing is clearer than saying nothing
+         * verbosely, and it keeps a clean screen's dump short. */
+        if ((a->fg != 0) || (a->bg != 0) || a->bold || a->faint || a->italic ||
+            a->underline || a->blink || a->blink2 || a->inverse ||
+            a->invisible || a->strike || a->fg256 || a->bg256 ||
+            a->fgintense || a->bgintense || a->dblwidth || a->autowrapped ||
+            a->newline || a->fraktur || a->framed || a->encircled ||
+            a->overlined || a->link_id)
+          {
+             printf("%s  att %d-%d fg=%u bg=%u", label, start, x - 1,
+                    (unsigned)a->fg, (unsigned)a->bg);
+             if (a->fg256)      printf(" fg256");
+             if (a->bg256)      printf(" bg256");
+             if (a->fgintense)  printf(" fgint");
+             if (a->bgintense)  printf(" bgint");
+             if (a->bold)       printf(" bold");
+             if (a->faint)      printf(" faint");
+             if (a->italic)     printf(" italic");
+             if (a->underline)  printf(" underline");
+             if (a->blink)      printf(" blink");
+             if (a->blink2)     printf(" blink2");
+             if (a->inverse)    printf(" inverse");
+             if (a->invisible)  printf(" invisible");
+             if (a->strike)     printf(" strike");
+             if (a->dblwidth)   printf(" dblwidth");
+             if (a->autowrapped) printf(" autowrapped");
+             if (a->newline)    printf(" newline");
+             if (a->fraktur)    printf(" fraktur");
+             if (a->framed)     printf(" framed");
+             if (a->encircled)  printf(" encircled");
+             if (a->overlined)  printf(" overlined");
+             if (a->link_id)    printf(" link=%u", (unsigned)a->link_id);
+             printf("\n");
+          }
+     }
+}
+
+/* Human-readable counterpart to _tytest_checksum().
+ *
+ * The checksum answers "did anything change"; this answers "what changed",
+ * which is the question a scalar-versus-SIMD parity failure actually raises.
+ * Two dumps piped through diff point straight at the offending cell. */
+static void
+_tytest_dump(Termpty *ty)
+{
+   ssize_t backlog_len;
+   int y;
+
+   printf("geom w=%d h=%d\n", ty->w, ty->h);
+   printf("cursor x=%d y=%d wrapnext=%d shape=%s\n",
+          ty->cursor_state.cx, ty->cursor_state.cy,
+          (int)ty->cursor_state.wrapnext, tytest_cursor_shape_get());
+   printf("mode altbuf=%d insert=%d wrap=%d bracketed_paste=%d\n",
+          (int)ty->altbuf, (int)ty->termstate.insert,
+          (int)ty->termstate.wrap, (int)ty->bracketed_paste);
+   printf("margin top=%d bottom=%d left=%d right=%d restrict=%d\n",
+          ty->termstate.top_margin, ty->termstate.bottom_margin,
+          ty->termstate.left_margin, ty->termstate.right_margin,
+          (int)ty->termstate.restrict_cursor);
+   printf("title=%s\n", ty->prop.title ? ty->prop.title : "(NULL)");
+   printf("icon=%s\n", ty->prop.icon ? ty->prop.icon : "(NULL)");
+
+   backlog_len = termpty_backlog_length(ty);
+   printf("backlog rows=%d\n", (int)backlog_len);
+   for (y = (int)backlog_len; y >= 1; y--)
+     {
+        const Termcell *cells;
+        ssize_t w = 0;
+        char label[32];
+
+        cells = termpty_cellrow_get(ty, -y, &w);
+        snprintf(label, sizeof(label), "b%-4d", -y);
+        if (cells && (w > 0)) _dump_row(cells, (int)w, label);
+        else printf("%s ||\n", label);
+     }
+
+   printf("screen\n");
+   for (y = 0; y < ty->h; y++)
+     {
+        char label[32];
+
+        snprintf(label, sizeof(label), "s%-4d", y);
+        _dump_row(&(TERMPTY_SCREEN(ty, 0, y)), ty->w, label);
+     }
+
+   if (ty->write_buffer.len)
+     {
+        size_t i;
+
+        printf("reply ");
+        for (i = 0; i < ty->write_buffer.len; i++)
+          {
+             unsigned char ch = (unsigned char)ty->write_buffer.buf[i];
+
+             if ((ch >= 0x20) && (ch < 0x7f)) putchar(ch);
+             else printf("\\x%02x", ch);
+          }
+        printf("\n");
+     }
+}
+
 static void
 _usage(const char *argv0)
 {
    fprintf(stderr,
            "usage: %s                 read escape codes on stdin, print a state checksum\n"
+           "       %s --dump          same, but print the state in a diffable text form\n"
            "       %s <test>|all      run the built-in unit tests\n",
-           argv0, argv0);
+           argv0, argv0, argv0);
 }
 
 int
 main(int argc, char **argv)
 {
+   Eina_Bool dump = EINA_FALSE;
    int chunk = 0;
    int i;
 
@@ -268,6 +432,7 @@ main(int argc, char **argv)
              _usage(argv[0]);
              return 0;
           }
+        else if (!strcmp(argv[i], "--dump")) dump = EINA_TRUE;
         else if (!strncmp(argv[i], "--chunk=", 8)) chunk = atoi(argv[i] + 8);
         /* Anything else is a unit test name, and those take over entirely. */
         else return _run_tytests(argc, argv);
@@ -283,7 +448,8 @@ main(int argc, char **argv)
 
    tytest_common_main_loop();
 
-   _tytest_checksum(tytest_termpty_get());
+   if (dump) _tytest_dump(tytest_termpty_get());
+   else _tytest_checksum(tytest_termpty_get());
 
    tytest_common_shutdown();
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to