Update examples.
This commit is contained in:
parent
2cdb088697
commit
5861677f5e
|
@ -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;
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ctlseqs.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
@ -29,6 +31,8 @@
|
|||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <ctlseqs.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue