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.