From 66da2fdd51b2cbe6a2074da88ef17c7cc592f56b Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Tue, 12 Jan 2010 23:54:09 +0000 Subject: [PATCH] Support cat's -AeEtTv flags in zzcat. --- doc/zzcat.1.in | 26 ++++++++++++++- src/zzcat.c | 89 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 106 insertions(+), 9 deletions(-) diff --git a/doc/zzcat.1.in b/doc/zzcat.1.in index d6b6e29..325729c 100644 --- a/doc/zzcat.1.in +++ b/doc/zzcat.1.in @@ -2,7 +2,7 @@ .SH NAME zzcat \- debugging tool for zzuf .SH SYNOPSIS -\fBzzcat\fR [\fB\-x\fR \fIsequence\fR] [\fIFILE\fR]... +\fBzzcat\fR [\fB\-AbeEntTv\fR] [\fB\-x\fR \fIsequence\fR] [\fIFILE\fR]... .br \fBzzcat \-l\fR | \fB\-\-list\fR .br @@ -21,6 +21,30 @@ used to seek and read data. \fB zzcat -x "fread(1,10000)" /dev/zero\fR .SH OPTIONS .TP +\fB\-A\fR, \fB\-\-show\-all\fR +Equivalent to \fB\-vET\fR. +.TP +\fB\-b\fR, \fB\-\-number\-nonblank\fR +Number nonempty output lines. +.TP +\fB\-e\fR +Equivalent to \fB\-vET\fR. +.TP +\fB\-E\fR, \fB\-\-show\-ends\fR +Display $ at end of each line. +.TP +\fB\-n\fR, \fB\-\-number\fR +Number all output lines. +.TP +\fB\-t\fR +Equivalent to \fB\-vT\fR. +.TP +\fB\-T\fR, \fB\-\-show\-tabs\fR +Display TAB characters as ^I. +.TP +\fB\-v\fR, \fB\-\-show\-nonprinting\fR +Use ^ and M- notation, except for LFD and TAB. +.TP \fB\-x\fR, \fB\-\-execute\fR=\fIsequence\fR Read a file or a stream using the instruction sequence specified in \fIsequence\fR. diff --git a/src/zzcat.c b/src/zzcat.c index 068a513..9d407d7 100644 --- a/src/zzcat.c +++ b/src/zzcat.c @@ -60,6 +60,13 @@ static void syntax(void); static void version(void); static void usage(void); +/* Output parameters */ +static int escape_tabs = 0; +static int escape_ends = 0; +static int escape_other = 0; +static int number_lines = 0; +static int number_nonblank = 0; + /* * Main program. */ @@ -71,16 +78,22 @@ int main(int argc, char *argv[]) for (;;) { -#define OPTSTR "+x:lhV" +#define OPTSTR "+AbeEntTvx:lhV" #define MOREINFO "Try `%s --help' for more information.\n" int option_index = 0; static struct myoption long_options[] = { - { "execute", 1, NULL, 'x' }, - { "list", 0, NULL, 'l' }, - { "help", 0, NULL, 'h' }, - { "version", 0, NULL, 'V' }, - { NULL, 0, NULL, 0 } + { "show-all", 0, NULL, 'A' }, + { "number-nonblank", 0, NULL, 'b' }, + { "show-ends", 0, NULL, 'E' }, + { "number", 0, NULL, 'n' }, + { "show-tabs", 0, NULL, 'T' }, + { "show-nonprinting", 0, NULL, 'v' }, + { "execute", 1, NULL, 'x' }, + { "list", 0, NULL, 'l' }, + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { NULL, 0, NULL, 0 } }; int c = mygetopt(argc, argv, OPTSTR, long_options, &option_index); @@ -89,6 +102,30 @@ int main(int argc, char *argv[]) switch (c) { + case 'A': /* --show-all */ + escape_tabs = escape_ends = escape_other = 1; + break; + case 'b': /* --number-nonblank */ + number_lines = 1; + break; + case 'e': + escape_ends = escape_other = 1; + break; + case 'E': /* --show-ends */ + escape_ends = 1; + break; + case 'n': /* --number */ + number_nonblank = 1; + break; + case 't': + escape_tabs = escape_other = 1; + break; + case 'T': /* --show-tabs */ + escape_tabs = 1; + break; + case 'v': /* --show-nonprinting */ + escape_tabs = 1; + break; case 'x': /* --execute */ if (myoptarg[0] == '=') myoptarg++; @@ -450,7 +487,35 @@ static int run(char const *sequence, char const *file) if (fd >= 0) close(fd); - fwrite(retbuf, retlen, 1, stdout); + if (escape_tabs || escape_ends || escape_other || number_lines) + { + size_t i; + + for (i = 0; i < retlen; i++) + { + int ch = (unsigned int)(unsigned char)retbuf[i]; + + if (escape_other && ch >= 0x80) + { + if (ch - 0x80 < 0x20 || ch - 0x80 == 0x7f) + fprintf(stdout, "M-^%c", (ch - 0x80) ^ 0x40); + else + fprintf(stdout, "M-%c", ch - 0x80); + } + else if (escape_tabs && ch == '\t') + fprintf(stdout, "^I"); + else if (escape_ends && ch == '\n') + puts("$"); + else if (escape_other && (ch < 0x20 || ch == 0x7f)) + fprintf(stdout, "^%c", ch ^ 0x40); + else + putchar(ch); + } + } + else + { + fwrite(retbuf, retlen, 1, stdout); + } free(retbuf); free(tmp); @@ -660,13 +725,21 @@ static void version(void) static void usage(void) { - printf("Usage: zzcat [-x sequence] [FILE...]\n"); + printf("Usage: zzcat [AbeEntTv] [-x sequence] [FILE...]\n"); printf(" zzcat -l | --list\n"); printf(" zzcat -h | --help\n"); printf(" zzcat -V | --version\n"); printf("Read FILE using a sequence of various I/O methods.\n"); printf("\n"); printf("Mandatory arguments to long options are mandatory for short options too.\n"); + printf(" -A, --show-all equivalent to -vET\n"); + printf(" -b, --number-nonblank number nonempty output lines\n"); + printf(" -e equivalent to -vE\n"); + printf(" -E, --show-ends display $ at end of each line\n"); + printf(" -n, --number number all output lines\n"); + printf(" -t equivalent to -vT\n"); + printf(" -T, --show-tabs display TAB characters as ^I\n"); + printf(" -v, --show-nonprinting use ^ and M- notation, except for LFD and TAB\n"); printf(" -x, --execute execute commands in \n"); printf(" -l, --list list available program functions\n"); printf(" -h, --help display this help and exit\n");