#include #include #include #include #include struct termios saved_tattr; void restore_tattr (void) { if (isatty (STDIN_FILENO)) tcsetattr (STDIN_FILENO, TCSANOW, &saved_tattr); } int main (void) { printf ("end with ^D\n"); if (isatty (STDIN_FILENO)) { tcgetattr (STDIN_FILENO, &saved_tattr); struct termios tattr = saved_tattr; cfmakeraw(&tattr); tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr); // atexit (restore_tattr); } #ifdef use_read setbuf (stdout, 0); #endif // enable focus reporting printf("\e[?1004h"); static int nread = 0; static unsigned char prevc = 0; while (1) { unsigned char c; #ifdef use_read int n = read(0, &c, 1); if (n < 1) break; #else c = getchar(); #endif switch (c) { case 0x00 ... 0x1f: printf ("\e[7m^%c\e[m", c + '@'); //if (c == '\r') printf ("\r\n"); break; case 0x7f: printf ("\e[7m^?\e[m"); break; case 0x80 ... 0xFF: printf ("\\x%2X", c); break; default: putchar (c); } // count escape sequences if (c == '\e') nread++; // detect mangled focus report, like [[O or O[O if (c == '[' && prevc != '\e') { printf("\e[41mFAIL%4d\e[m", nread); // touch a marker file (and log nread in it), // so a test script can detect it to stop char s[99]; sprintf(s, "echo failed at %d > .minstop", nread); system(s); } if (c == 4) { printf ("\r\n"); break; } prevc = c; } restore_tattr (); return 0; }