From 9a128303b403eacac3db0351fceade7a0e7c5897 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Tue, 25 Jun 2024 18:49:54 -0400 Subject: listbas: pipe through a8eol or a8utf8; do not write ATASCII to terminal; add docs. --- listbas.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 16 deletions(-) (limited to 'listbas.c') diff --git a/listbas.c b/listbas.c index 6469009..86bb3f7 100644 --- a/listbas.c +++ b/listbas.c @@ -4,25 +4,35 @@ #include #include #include + #include +#include #include "bas.h" #include "bcdfp.h" #include "tokens.h" -int immediate = 0; +int immediate = 0, a8utf8 = 0, a8eol = 1; + +FILE *outfh; void print_help(void) { - printf("Usage: %s [-v] [-i] \n", self); + printf("Usage: %s [-v] [-i] [-a|-u] \n", self); + printf(" -v: verbose.\n"); + printf(" -i: show immediate mode command (line 32768).\n"); + printf(" -a: output raw ATASCII.\n"); + printf(" -u: output Unicode.\n"); } void parse_args(int argc, char **argv) { int opt; - while( (opt = getopt(argc, argv, "vi")) != -1) { + while( (opt = getopt(argc, argv, "viau")) != -1) { switch(opt) { case 'v': verbose = 1; break; case 'i': immediate = 1; break; + case 'a': a8utf8 = a8eol = 0; break; + case 'u': a8utf8 = 1; a8eol = 0; break; default: print_help(); exit(1); @@ -35,6 +45,11 @@ void parse_args(int argc, char **argv) { open_input(argv[optind]); } +void outchr(char c) { + putc(c, outfh); +} + +/* this should probably be moved to bcdfp.c */ double bcd2double(const unsigned char *num) { double result = 0, sign; int exp, i; @@ -60,17 +75,17 @@ double bcd2double(const unsigned char *num) { } void print_number(unsigned int pos) { - printf("%G", bcd2double(program + pos)); + fprintf(outfh, "%G", bcd2double(program + pos)); } void print_string(unsigned int pos, unsigned int len) { - putchar('"'); - while(len--) putchar(program[pos++]); - putchar('"'); + outchr('"'); + while(len--) outchr(program[pos++]); + outchr('"'); } CALLBACK(print_lineno) { - printf("%d ", lineno); + fprintf(outfh, "%d ", lineno); } CALLBACK(print_cmd) { @@ -88,9 +103,9 @@ CALLBACK(print_cmd) { } if(bad) - printf("(bad cmd token $%02x)", tok); + fprintf(outfh, "(bad cmd token $%02x)", tok); else - printf("%s ", name); + fprintf(outfh, "%s ", name); } CALLBACK(print_op) { @@ -119,9 +134,9 @@ CALLBACK(print_op) { } if(bad) - printf("(bad op token $%02x)", tok); + fprintf(outfh, "(bad op token $%02x)", tok); else - printf("%s", name); + fprintf(outfh, "%s", name); } CALLBACK(print_varname) { @@ -134,17 +149,51 @@ CALLBACK(print_varname) { } while(1) { c = program[i++]; - putchar(c & 0x7f); + outchr(c & 0x7f); if(c & 0x80) break; } } CALLBACK(print_text) { - while(program[pos] != 0x9b) putchar(program[pos++]); + while(program[pos] != 0x9b) outchr(program[pos++]); } CALLBACK(print_newline) { - putchar('\n'); + outchr(0x9b); +} + +void setup_outfh(void) { + const char *cmd; + + /* search current dir before PATH. no easy way to detect errors here, + have to wait until we call pclose(). */ + if(a8eol) { + cmd = "./a8eol -u -c 2>/dev/null || a8eol -u -c 2>/dev/null || exit 1"; + } else if(a8utf8) { + cmd = "./a8utf8 2>/dev/null || a8utf8 2>/dev/null || exit 1"; + } else { + if(isatty(fileno(stdout))) { + die("Refusing to write ATASCII data to the terminal."); + } + outfh = stdout; + return; + } + + outfh = popen(cmd, "w"); + if(!outfh) { + /* fork() or pipe() failed. does NOT detect if the command + wasn't found. */ + perror(self); + exit(1); + } +} + +void close_outfh(void) { + if(a8eol || a8utf8) { + if(pclose(outfh)) { + die("output filter failed; a8eol or a8utf8 not in current dir or $PATH."); + } + } } void list(void) { @@ -165,7 +214,9 @@ int main(int argc, char **argv) { readfile(); parse_header(); + setup_outfh(); list(); - + close_outfh(); + return 0; } -- cgit v1.2.3