Update tcsgrep.

This commit is contained in:
CismonX 2021-01-04 02:14:48 +08:00
parent 7af0b35bb1
commit c20ca12750
Signed by: cismonx
GPG Key ID: 3094873E29A482FB
1 changed files with 39 additions and 30 deletions

View File

@ -64,6 +64,7 @@ struct tcsgrep_ctx {
int limit; int limit;
bool purge_long_seqs; bool purge_long_seqs;
bool verbose; bool verbose;
bool not_tty;
}; };
static inline void static inline void
@ -84,6 +85,28 @@ parse_int(char const *str, int *dest)
return true; return true;
} }
static inline void
print_char(int ch)
{
static char const *ascii_table[] = {
"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
"BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
"CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
};
if (ch == ' ') {
printf(" SP");
} else if (isprint(ch)) {
printf(" %c", ch);
} else if (ch == 0x7f) {
printf(" DEL");
} else if (!iscntrl(ch)) {
printf(" \\x%02x", ch);
} else {
printf(" %s", ascii_table[ch]);
}
}
static void static void
print_generic_seq(char const *header, union ctlseqs_value *result, bool newline) print_generic_seq(char const *header, union ctlseqs_value *result, bool newline)
{ {
@ -91,16 +114,7 @@ print_generic_seq(char const *header, union ctlseqs_value *result, bool newline)
char const *seq = result[1].str; char const *seq = result[1].str;
printf("%s %zu", header, length); printf("%s %zu", header, length);
for (size_t idx = 0; idx < length; ++idx) { for (size_t idx = 0; idx < length; ++idx) {
char ch = seq[idx]; print_char((unsigned)seq[idx]);
if (ch == ' ') {
printf(" SP");
} if (isprint(ch)) {
printf(" %c", ch);
} else if (ch == 0x1b) {
printf(" ESC");
} else {
printf(" \\x%02x", ch);
}
} }
if (newline) { if (newline) {
printf("\n"); printf("\n");
@ -143,8 +157,6 @@ main(int argc, char **argv)
.prog_name = argv[0], .prog_name = argv[0],
.timeout = -1, .timeout = -1,
.limit = 4096, .limit = 4096,
.purge_long_seqs = false,
.verbose = false,
}; };
int opt; int opt;
@ -374,22 +386,18 @@ main(int argc, char **argv)
return 1; return 1;
} }
if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO)) {
print_error(&ctx, "not a tty");
return false;
}
struct termios old_termios; struct termios old_termios;
if (tcgetattr(STDIN_FILENO, &old_termios) != 0) { if (tcgetattr(STDIN_FILENO, &old_termios) != 0) {
print_error(&ctx, "failed to get terminal attributes"); ctx.not_tty = true;
return 1; } else {
} struct termios new_termios = old_termios;
struct termios new_termios = old_termios; new_termios.c_cc[VMIN] = 0;
new_termios.c_cc[VMIN] = 0; new_termios.c_cc[VTIME] = 0;
new_termios.c_cc[VTIME] = 0; new_termios.c_lflag &= ~(ICANON | ISIG | ECHO);
new_termios.c_lflag &= ~(ICANON | ISIG | ECHO); if (tcsetattr(STDIN_FILENO, TCSANOW, &new_termios) != 0) {
if (tcsetattr(STDIN_FILENO, TCSANOW, &new_termios) != 0) { print_error(&ctx, "failed to set terminal attributes");
print_error(&ctx, "failed to set terminal attributes"); return 1;
return 1; }
} }
int status = 0; int status = 0;
@ -409,7 +417,7 @@ main(int argc, char **argv)
break; break;
case CTLSEQS_EOF: case CTLSEQS_EOF:
printf("EOF\n"); printf("EOF\n");
break; goto terminate;
case CTLSEQS_PARTIAL: case CTLSEQS_PARTIAL:
if (ctx.verbose) { if (ctx.verbose) {
print_generic_seq("PARTIAL", result, true); print_generic_seq("PARTIAL", result, true);
@ -429,7 +437,7 @@ main(int argc, char **argv)
} }
case CTLSEQS_NOSEQ: case CTLSEQS_NOSEQ:
print_generic_seq("NOSEQ", result, true); print_generic_seq("NOSEQ", result, true);
if (result[1].str[0] == 0x03) { if (result[1].str[0] == 0x04) {
goto terminate; goto terminate;
} }
break; break;
@ -440,9 +448,10 @@ main(int argc, char **argv)
} }
terminate: terminate:
free(patterns);
ctlseqs_matcher_free(matcher); ctlseqs_matcher_free(matcher);
ctlseqs_reader_free(reader); ctlseqs_reader_free(reader);
tcsetattr(STDIN_FILENO, TCSANOW, &old_termios); if (!ctx.not_tty) {
tcsetattr(STDIN_FILENO, TCSANOW, &old_termios);
}
return status; return status;
} }