/* cst_shell_compact: ANSI stripping, \r progress folding, repeated-line * collapse and head/tail cutting of run_shell output. */ #include "cst_tools.h" #include #include #include static int nfail; #define CHECK(cond, msg) \ do { \ if (!(cond)) { \ fprintf(stderr, "FAIL %s:%d: %s\n", __FILE__, __LINE__, msg); \ nfail++; \ } \ } while (0) static char *compact(const char *s) { size_t n = 0; return cst_shell_compact(s, strlen(s), &n); } int main(void) { char *o; o = compact("plain\noutput\n"); CHECK(o && strcmp(o, "plain\noutput\n") == 0, "clean output unchanged"); free(o); o = compact("no newline"); CHECK(o && strcmp(o, "no newline") == 0, "missing final newline kept"); free(o); o = compact(""); CHECK(o && strcmp(o, "") == 0, "empty"); free(o); o = compact("a\n\nb\n"); CHECK(o && strcmp(o, "a\n\nb\n") == 0, "blank lines kept"); free(o); o = compact("\x1b[1;31merror\x1b[0m: bad\n\x1b]0;title\x07ok\n"); CHECK(o && strcmp(o, "error: bad\nok\n") == 0, "ANSI CSI and OSC removed"); free(o); o = compact(" 0%\r 50%\r100%\ndone\r\n"); CHECK(o && strcmp(o, "100%\ndone\n") == 0, "\\r progress folded, CRLF ok"); free(o); o = compact("ab\bc\n"); CHECK(o && strcmp(o, "ac\n") == 0, "backspace applied"); free(o); o = compact("x\nx\ny\n"); CHECK(o && strcmp(o, "x\nx\ny\n") == 0, "a pair is kept as is"); free(o); o = compact("start\nwarn\nwarn\nwarn\nwarn\nend\n"); CHECK(o && strcmp(o, "start\nwarn\n… (previous line repeated 3 more " "times)\nend\n") == 0, "runs collapsed"); free(o); { char *big = malloc(1000 * 16); size_t used = 0; for (int i = 1; i <= 1000; i++) used += (size_t)sprintf(big + used, "line %d\n", i); o = compact(big); CHECK(o && strstr(o, "line 1\n") && strstr(o, "line 80\n") && !strstr(o, "line 81\n") && strstr(o, "… 800 lines omitted …\n") && strstr(o, "line 881\n") && strstr(o, "line 1000\n"), "head + tail with omitted count"); free(o); free(big); } { char *wide = malloc(5000 + 2); memset(wide, 'w', 5000); wide[5000] = '\n'; wide[5001] = 0; o = compact(wide); CHECK(o && strstr(o, " … [+3000 bytes]\n") && strlen(o) < 2100, "long line cut"); free(o); free(wide); } { /* 200 lines of 1 KB: over the byte budget, the tail wins */ char *fat = malloc(200 * 1030); size_t used = 0; for (int i = 1; i <= 200; i++) { used += (size_t)sprintf(fat + used, "%04d ", i); memset(fat + used, 'f', 1000); used += 1000; fat[used++] = '\n'; } fat[used] = 0; o = compact(fat); CHECK(o && strlen(o) <= 42 * 1024 && strstr(o, "0200 ") && strstr(o, "lines omitted"), "byte budget keeps the tail"); free(o); free(fat); } if (nfail) { fprintf(stderr, "test_shell_compact: %d failure(s)\n", nfail); return 1; } printf("test_shell_compact: OK\n"); return 0; }