From 312837a5a4e26e65cca738f44bd3c14e3c203b1e Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Sat, 29 Jun 2024 06:30:34 -0400 Subject: a8cat: add -v (verbose) and --version, die() function, etc. --- a8cat.1 | 6 ++++++ a8cat.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++------------ a8cat.rst | 6 ++++++ 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/a8cat.1 b/a8cat.1 index 42f2017..30f96d0 100644 --- a/a8cat.1 +++ b/a8cat.1 @@ -106,6 +106,9 @@ Strip the inverse video bit (bit 7) from all characters except the EOL (\fB$9B\fP). Output created with this option can be converted back to ATASCII with the \fB\-r\fP option, but of course there won\(aqt be any inverse\-video characters in the result. +.TP +.B \-v +Verbose operation. .UNINDENT .INDENT 0.0 .TP @@ -115,6 +118,9 @@ trying to work with files whose names begin with \fI\-\fP\&. .TP .B \fB\-h\fP, \fB\-\-help\fP Show built\-in help and exit. +.TP +.B \fB\-\-version\fP +Show version number and exit. .UNINDENT .SH COPYRIGHT .sp diff --git a/a8cat.c b/a8cat.c index df72501..148b9ce 100644 --- a/a8cat.c +++ b/a8cat.c @@ -14,17 +14,35 @@ const char **table = ata2utf; const char *inverse_on = "\x1b[7m"; const char *inverse_off = "\x1b[0m"; +int verbose = 0; int underline = 0, reverse = 0, textmode = 0, ics = 0; int magazine = 0, stripinv = 0; +const char *self; + +void set_self(const char *argv0) { + char *p; + + self = argv0; + p = strrchr(self, '/'); + if(p) self = p + 1; +} + +void die(const char *msg) { + fprintf(stderr, "%s: %s\n", self, msg); + exit(1); +} + void print_help(void) { - printf("Usage: a8cat [-i] [-u] [file ...]\n"); + printf("Usage: %s [-i] [-u] [file ...]\n", self); } FILE *open_input(const char *file) { FILE *input; if(file[0] == '-' && file[1] == 0) { + if(verbose) + fprintf(stderr, "%s: reading from standard input.\n", self); if(freopen(NULL, "rb", stdin)) { input = stdin; } else { @@ -36,10 +54,13 @@ FILE *open_input(const char *file) { return NULL; } + if(verbose) + fprintf(stderr, "%s: reading from file '%s'.\n", self, file); + return input; } -int handle_escape_seq(int inv, FILE *input) { +int handle_escape_seq(int inv, FILE *input, const char *file, int line) { int count, c; char buf[5] = { 0x1b, 0, 0, 0, 0 }; @@ -54,6 +75,7 @@ int handle_escape_seq(int inv, FILE *input) { } else if(strcmp(inverse_off, buf) == 0) { return 0; } else { + fprintf(stderr, "%s: warning: %s:%d: unrecognized ANSI escape sequence.\n", self, file, line); fputs(buf, stdout); return inv; } @@ -61,17 +83,17 @@ int handle_escape_seq(int inv, FILE *input) { int a8revcat(const char *file) { FILE *input; - int c, d, inv = 0; + int c, d, inv = 0, line = 1; if( !(input = open_input(file)) ) return 1; - setlocale(LC_CTYPE, "en_US.UTF-8"); while( (c = fgetwc(input)) != WEOF ) { if(c == 0x1b) { - inv = handle_escape_seq(inv, input); + inv = handle_escape_seq(inv, input, file, line); } else if(c == '\n') { putchar(0x9b); + line++; } else if(c == '\t') { putchar(0x7f); } else if(c == '\b' || c == 0x7f) { @@ -83,13 +105,17 @@ int a8revcat(const char *file) { } else { d = wchar2atascii(c, ics); if(d == -1) { - fprintf(stderr, "warning: unrecognized Unicode character %04x\n", c); + fprintf(stderr, "%s: warning: %s:%d: unrecognized Unicode character %04x.\n", self, file, line, c); } else { putchar(d | inv); } } } + if(verbose) + fprintf(stderr, "%s: %s: converted %d lines, closing file.\n", self, file, line - 1); + + fclose(input); return 0; } @@ -102,7 +128,7 @@ void inverse(int onoff) { int a8cat(const char *file) { FILE *input; - int c, inv = 0; + int c, inv = 0, line = 1; if( !(input = open_input(file)) ) return 1; @@ -110,6 +136,7 @@ int a8cat(const char *file) { while( (c = fgetc(input)) != EOF ) { if(c == 0x9b) { putchar('\n'); + line++; continue; } @@ -190,6 +217,9 @@ int a8cat(const char *file) { inverse(0); } + if(verbose) + fprintf(stderr, "%s: %s: converted %d lines, closing file.\n", self, file, line - 1); + fclose(input); return 0; } @@ -197,12 +227,19 @@ int a8cat(const char *file) { int main(int argc, char **argv) { int opt, result = 0; + set_self(argv[0]); + if(argc > 1 && strcmp(argv[1], "--help") == 0) { print_help(); exit(0); } - while( (opt = getopt(argc, argv, "ihurtms")) != -1) { + if(argc > 1 && strcmp(argv[1], "--version") == 0) { + printf("%s %s\n", self, VERSION); + exit(0); + } + + while( (opt = getopt(argc, argv, "ihurtmsv")) != -1) { switch(opt) { case 'i': table = ics2utf; ics = 1; break; case 'h': print_help(); exit(0); break; @@ -211,21 +248,24 @@ int main(int argc, char **argv) { case 't': textmode = 1; break; case 'm': table = ata2mag; magazine = 1; break; case 's': stripinv = 1; break; + case 'v': verbose = 1; break; default: print_help(); exit(1); break; } } if(reverse) { if(underline || textmode || stripinv || magazine) { - fprintf(stderr, "-t, -u, -m, -s options don't make sense with -r.\n"); - exit(1); + die("-t, -u, -m, -s options don't make sense with -r.\n"); } + /* the language_country part of the locale doesn't matter, + since we aren't doing localization. the encoding *has* + to be UTF-8. */ + setlocale(LC_CTYPE, "en_US.UTF-8"); } if(magazine) { if(ics || stripinv || underline) { - fprintf(stderr, "-i, -s, -u options don't make sense with -m.\n"); - exit(1); + die("-i, -s, -u options don't make sense with -m.\n"); } } diff --git a/a8cat.rst b/a8cat.rst index 7b91fa9..8367e35 100644 --- a/a8cat.rst +++ b/a8cat.rst @@ -81,6 +81,9 @@ OPTIONS back to ATASCII with the **-r** option, but of course there won't be any inverse-video characters in the result. +-v + Verbose operation. + **--** End of options; the rest of the arguments are filenames. Use this if you're trying to work with files whose names begin with *-*. @@ -88,4 +91,7 @@ OPTIONS **-h**, **--help** Show built-in help and exit. +**--version** + Show version number and exit. + .. include:: manftr.rst -- cgit v1.2.3