From 5861677f5ea34369c5330a1e80113e83b7ac3cfe Mon Sep 17 00:00:00 2001 From: CismonX Date: Fri, 18 Dec 2020 18:37:47 +0800 Subject: [PATCH] Update examples. --- examples/sixdraw.c | 39 +++++++++++++------------ tests/tcsgrep.c | 73 +++++++++++++++++++++++++++++++++------------- 2 files changed, 73 insertions(+), 39 deletions(-) diff --git a/examples/sixdraw.c b/examples/sixdraw.c index a7888ac..8da72f2 100644 --- a/examples/sixdraw.c +++ b/examples/sixdraw.c @@ -43,7 +43,7 @@ struct sixdraw_ctx { struct termios termios; - union ctlseqs_value buffer[10]; + union ctlseqs_value buffer[64]; char const *prog_name; struct ctlseqs_matcher *matcher; struct ctlseqs_reader *reader; @@ -111,7 +111,6 @@ sixdraw_get_winsize(struct sixdraw_ctx *ctx) ctx->cols = ws.ws_col; ctx->ch_width = ws.ws_xpixel / ws.ws_col; ctx->ch_height = ws.ws_ypixel / ws.ws_row; - dprintf(ctx->out_fd, "%d %d \n%d %d %d %d\n", ws.ws_xpixel, ws.ws_ypixel, ctx->rows, ctx->cols, ctx->ch_width, ctx->ch_height); return true; } @@ -125,7 +124,7 @@ sixdraw_init(struct sixdraw_ctx *ctx, int argc, char **argv) .timeout = SIXDRAW_DEFAULT_TIMEOUT_MILLIS, }; - // Process command line arguments + // Process command line arguments. int opt; while (-1 != (opt = getopt(argc, argv, "t:"))) { switch (opt) { @@ -138,7 +137,7 @@ sixdraw_init(struct sixdraw_ctx *ctx, int argc, char **argv) } } - // Initialize control sequence matcher + // Initialize control sequence matcher. ctx->matcher = ctlseqs_matcher_init(); if (ctx->matcher == NULL) { sixdraw_print_error(ctx, "failed to initialize matcher"); @@ -157,7 +156,7 @@ sixdraw_init(struct sixdraw_ctx *ctx, int argc, char **argv) return false; } - // Initialize control sequence reader + // Initialize control sequence reader. ctx->reader = ctlseqs_reader_init(); if (ctx->reader == NULL) { sixdraw_print_error(ctx, "failed to initialize reader"); @@ -166,14 +165,14 @@ sixdraw_init(struct sixdraw_ctx *ctx, int argc, char **argv) struct ctlseqs_reader_options reader_options = { .buffer = ctx->buffer, .fd = ctx->in_fd, - .maxlen = 32, + .maxlen = 4096, }; if (ctlseqs_reader_config(ctx->reader, &reader_options) != CTLSEQS_OK) { sixdraw_print_error(ctx, "failed to set reader options"); return false; } - // Block SIGWINCH + // Block SIGWINCH. sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGWINCH); @@ -186,13 +185,13 @@ sixdraw_init(struct sixdraw_ctx *ctx, int argc, char **argv) static bool sixdraw_prepare(struct sixdraw_ctx *ctx) { - // Check whether we're running on a terminal + // Check whether we're running on a terminal. if (!isatty(ctx->in_fd) || !isatty(ctx->out_fd)) { sixdraw_print_error(ctx, "this program can only run in a terminal"); return false; } - // Set terminal to noncanonical mode + // Set terminal to noncanonical mode. if (tcgetattr(ctx->in_fd, &ctx->termios) != 0) { sixdraw_print_error(ctx, "failed to get terminal attributes"); return false; @@ -202,12 +201,12 @@ sixdraw_prepare(struct sixdraw_ctx *ctx) termios.c_cc[VTIME] = 0; termios.c_lflag &= ~(ICANON | ISIG | ECHO); if (tcsetattr(ctx->in_fd, TCSANOW, &termios) != 0) { - sixdraw_print_error(ctx, "failed to get terminal attributes"); + sixdraw_print_error(ctx, "failed to set terminal attributes"); return false; } ctx->has_termios = true; - // Set STDIN flags to non-blocking + // Set STDIN flags to nonblocking. int flags = fcntl(ctx->in_fd, F_GETFL); if (flags == -1) { sixdraw_print_error(ctx, "failed to get file status flags"); @@ -218,18 +217,20 @@ sixdraw_prepare(struct sixdraw_ctx *ctx) return false; } - // Get initial terminal window size + // Get initial terminal window size. if (!sixdraw_get_winsize(ctx)) { sixdraw_print_error(ctx, "failed to get terminal window size"); return false; } - return true; - // Check terminal support for sixel graphics and DEC locator + // Check terminal support for sixel graphics and DEC locator. dprintf(ctx->out_fd, CTLSEQS_PRIMARY_DA()); - ssize_t result = ctlseqs_read(ctx->reader, ctx->matcher, 500); + ssize_t result; + do { + result = ctlseqs_read(ctx->reader, ctx->matcher, ctx->timeout); + } while (result == CTLSEQS_PARTIAL); if (result != 0) { - sixdraw_print_error(ctx, "failed to get terminal attributes"); + sixdraw_print_error(ctx, "failed to get terminal features"); return false; } bool has_sixel = false; @@ -251,9 +252,11 @@ sixdraw_prepare(struct sixdraw_ctx *ctx) return false; } - // Get current cursor status + // Get current cursor status. dprintf(ctx->out_fd, CTLSEQS_DECRQM("25")); - result = ctlseqs_read(ctx->reader, ctx->matcher, ctx->timeout); + do { + result = ctlseqs_read(ctx->reader, ctx->matcher, ctx->timeout); + } while (result == CTLSEQS_PARTIAL); if (result != 1) { sixdraw_print_error(ctx, "failed to get cursor status"); return false; diff --git a/tests/tcsgrep.c b/tests/tcsgrep.c index fa71d58..52f8448 100644 --- a/tests/tcsgrep.c +++ b/tests/tcsgrep.c @@ -17,7 +17,9 @@ * along with this program. If not, see . */ -#include "ctlseqs.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif // HAVE_CONFIG_H #include #include @@ -29,6 +31,8 @@ #include #include +#include + #define TCSGREP_NINTH_ARG_(a1, a2, a3, a4, a5, a6, a7, a8, a9, ...) a9 #define TCSGREP_COUNT_ARGS_(...) TCSGREP_NINTH_ARG_(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0) @@ -58,6 +62,8 @@ struct tcsgrep_ctx { char const *prog_name; int timeout; int limit; + bool purge_long_seqs; + bool verbose; }; static inline void @@ -79,7 +85,7 @@ parse_int(char const *str, int *dest) } static void -print_generic_seq(char const *header, union ctlseqs_value *buffer) +print_generic_seq(char const *header, union ctlseqs_value *buffer, bool newline) { size_t length = buffer[0].num; char const *seq = buffer[1].str; @@ -96,13 +102,21 @@ print_generic_seq(char const *header, union ctlseqs_value *buffer) printf(" \\x%02x", ch); } } - printf("\n"); + if (newline) { + printf("\n"); + } } static void -print_matching_seq(struct tcsgrep_sequence *seq, union ctlseqs_value *buffer) +print_matching_seq(struct tcsgrep_sequence *seq, union ctlseqs_value *buffer, bool verbose) { - printf("OK %s", seq->name); + if (verbose) { + print_generic_seq("OK", buffer, false); + buffer += 2; + } else { + printf("OK"); + } + printf(" %s", seq->name); for (int idx = 0; idx < 8; ++idx) { char placeholder = seq->args[idx]; switch (placeholder) { @@ -126,13 +140,15 @@ int main(int argc, char **argv) { struct tcsgrep_ctx ctx = { - .prog_name = argv[0], - .timeout = -1, - .limit = 4096, + .prog_name = argv[0], + .timeout = -1, + .limit = 4096, + .purge_long_seqs = false, + .verbose = false, }; int opt; - while (-1 != (opt = getopt(argc, argv, "t:l:"))) { + while (-1 != (opt = getopt(argc, argv, "t:l:pv"))) { switch (opt) { case 't': if (!parse_int(optarg, &ctx.timeout)) { @@ -146,6 +162,12 @@ main(int argc, char **argv) return 1; } break; + case 'p': + ctx.purge_long_seqs = true; + break; + case 'v': + ctx.verbose = true; + break; case '?': default: print_error(&ctx, "invalid arguments"); @@ -183,7 +205,7 @@ main(int argc, char **argv) TCSGREP_DEFSEQ_NOARGS(DECKPAM), TCSGREP_DEFSEQ_NOARGS(DECKPNM), TCSGREP_DEFSEQ_NOARGS(RIS), - TCSGREP_DEFSEQ(DECUDK, CTLSEQS_PH_NUM, CTLSEQS_PH_NUM, CTLSEQS_PH_NUMS), + TCSGREP_DEFSEQ(DECUDK, CTLSEQS_PH_NUM, CTLSEQS_PH_NUM, CTLSEQS_PH_STR), TCSGREP_DEFSEQ(DECRQSS, CTLSEQS_PH_STR), TCSGREP_DEFSEQ(DECRSPS, CTLSEQS_PH_NUM, CTLSEQS_PH_STR), TCSGREP_DEFSEQ(XTGETXRES, CTLSEQS_PH_STR), @@ -340,11 +362,12 @@ main(int argc, char **argv) if (reader == NULL) { print_error(&ctx, "failed to initialize reader"); } - union ctlseqs_value buffer[16]; + static union ctlseqs_value buffer[4096]; struct ctlseqs_reader_options reader_options = { .fd = STDIN_FILENO, .maxlen = ctx.limit, - .buffer = buffer + .buffer = buffer, + .flags = ctx.verbose ? CTLSEQS_READER_SAVE_MATCHED_SEQS : 0, }; if (ctlseqs_reader_config(reader, &reader_options) != CTLSEQS_OK) { print_error(&ctx, "reader setopt failed"); @@ -373,17 +396,14 @@ main(int argc, char **argv) while (true) { ssize_t result = ctlseqs_read(reader, matcher, ctx.timeout); switch (result) { - case CTLSEQS_NOMEM: - print_error(&ctx, "failed to allocate memory"); - status = 1; - goto terminate; case CTLSEQS_ERROR: print_error(&ctx, "unexpected error"); status = 1; goto terminate; case CTLSEQS_TIMEOUT: printf("TIMEOUT\n"); - break; + status = 1; + goto terminate; case CTLSEQS_INTR: printf("INTR\n"); break; @@ -391,19 +411,30 @@ main(int argc, char **argv) printf("EOF\n"); break; case CTLSEQS_PARTIAL: - print_generic_seq("PARTIAL", buffer); + if (ctx.verbose) { + print_generic_seq("PARTIAL", buffer, true); + } break; case CTLSEQS_NOMATCH: - print_generic_seq("NOMATCH", buffer); + print_generic_seq("NOMATCH", buffer, true); break; + case CTLSEQS_NOMEM: + print_generic_seq("NOMEM", buffer, true); + if (ctx.purge_long_seqs) { + ctlseqs_purge(reader, buffer[0].num); + break; + } else { + status = 1; + goto terminate; + } case CTLSEQS_NOSEQ: - print_generic_seq("NOSEQ", buffer); + print_generic_seq("NOSEQ", buffer, true); if (buffer[1].str[0] == 0x03) { goto terminate; } break; default: - print_matching_seq(&seqs[result], buffer); + print_matching_seq(&seqs[result], buffer, ctx.verbose); break; } }