diff options
-rw-r--r-- | listbas.1 | 46 | ||||
-rw-r--r-- | listbas.c | 173 | ||||
-rw-r--r-- | listbas.rst | 44 |
3 files changed, 182 insertions, 81 deletions
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "LISTBAS" 1 "2024-07-11" "0.2.1" "Urchlay's Atari 8-bit Tools" +.TH "LISTBAS" 1 "2024-07-12" "0.2.1" "Urchlay's Atari 8-bit Tools" .SH NAME listbas \- List the source of a tokenized Atari 8-bit BASIC program .SH SYNOPSIS @@ -42,31 +42,46 @@ format. By default, output is Unicode in UTF\-8 encoding, with ANSI/VT220 escape sequences for inverse video and color syntax highlighting. .SH OPTIONS -.SS List options +.SS Output modes +.sp +The default output mode is Unicode/UTF\-8 representations of ATASCII +characters. .INDENT 0.0 .TP .B \fB\-a\fP Output raw ATASCII; no translation to the host character set. Must be used with redirection; \fBlistbas\fP will not write ATASCII to the terminal. .TP -.B \fB\-b\fP -Use bold, for color output. This may make it easier to read on -some terminals. Or, it may hurt your eyes... -.TP .B \fB\-d\fP Print dots rather than Unicode/UTF\-8 characters. Color and inverse video are still supported in this mode. Use this only if your terminal \fIreally\fP doesn\(aqt support Unicode (e.g. \fBrxvt\fP(1)). .TP -.B \fB\-i\fP -Include the immediate mode command (line 32768) in the output. -.TP .B \fB\-m\fP Output "magazine listing". See the \fB\-m\fP option for \fBa8cat\fP for details. +Color is supported in this mode, +.TP +.B \fB\-x\fP +Output Unicode/UTF\-8 representations of the XL International Character +Set, rather than ATASCII. +.UNINDENT +.SS Other options +.INDENT 0.0 +.TP +.B \fB\-b\fP +Use bold for color output. This may make it easier to read on +some terminals. Or, it may hurt your eyes... +.TP +.B \fB\-i\fP +Include the immediate mode command (line 32768) in the output. .TP .B \fB\-n\fP -No color. Has no effect if \fB\-a\fP or \fB\-m\fP are in effect, since these -modes don\(aqt support color anyway. +No color. Has no effect if \fB\-a\fP is in effect, since this +mode doesn\(aqt support color anyway. Disabling color does not +disable reverse video. +.TP +.B \fB\-u\fP +Use underlining for inverse video, rather than reverse video output. .UNINDENT .SS General Options .INDENT 0.0 @@ -103,15 +118,16 @@ Functions. .TP .B \fBred\fP Numbers (except line numbers at the start of a line) and string -constants. +constants (but not the quotes around the string). .TP .B \fBcyan\fP Line numbers at the start of a line, comments (\fBREM\fP text) and \fBDATA\fP elements. .UNINDENT .sp -Variable names and commas between \fBDATA\fP elements are not highlighted, -so they\(aqll appear in the default foreground color (usually white if the -terminal has a black background, or black if the background is white). +Quotes around strings, variable names, and commas between \fBDATA\fP +elements are not highlighted, so they\(aqll appear in the default +foreground color (usually white if the terminal has a black +background, or black if the background is white). .sp Note that nothing is highlighted in blue. This is because it\(aqs difficult to read on many terminals. Also, black and white are not @@ -13,43 +13,76 @@ #include "tokens.h" #include "atables.h" +#define COLOR_FMT "\x1b[%d;3%dm" /* 1st %d is 1 for bold, 2nd is color */ + +#define COLOR_OFF "\x1b[0m" /* clears inverse, too! */ +#define INV_OFF "\x1b[0m" /* clears color, too! */ + +/* These would be better to use, allow turning off color and inverse + independently, but are not as widely supported by various terminals. */ +/* #define COLOR_OFF "\x1b[39;49m" */ +/* #define INV_OFF "\x1b[27m"" */ + +#define INV_ON "\x1b[7m" /* goes all the way back to the original VT100 */ +#define ULINE_ON "\x1b[4m" + +#define MAG_INV "{inv}" +#define MAG_NORM "{norm}" + +/* colors. don't use blue, it's fugly. */ #define C_RED 1 #define C_GREEN 2 #define C_YELLOW 3 #define C_PURPLE 5 #define C_CYAN 6 -int immediate = 0, utf8 = 1, magazine = 0, inv = 0, - color = 1, bold = 0, badtok = 0, dots = 0; +/* output modes */ +#define M_UTF8 0 /* default */ +#define M_UTF8_I 1 /* -x */ +#define M_ATASCII 2 /* -a */ +#define M_MAG 3 /* -m */ +#define M_DOTS 4 /* -d */ + +int output_mode = M_UTF8; -const char **table = ata2utf; +int bold = 0; /* 1 with -b */ +int color = 1; /* 0 with -n */ +int immediate = 0; /* 1 with -i */ +int underline = 0; /* 1 with -u */ +int badtok = 0; /* set to 1 if we find a bad token */ +int inv = 0; /* set to 1 when we're printing inverse */ +int cur_color = -1; /* -1 = no color */ FILE *outfh; void print_help(void) { - printf("Usage: %s [-a | -d | -m] [-b] [-i] [-n] [-v] <inputfile>\n", self); + printf("Usage: %s [-a | -d | -m | -x] [-b] [-i] [-n] [-v] <inputfile>\n", self); printf(" -a: output raw ATASCII.\n"); printf(" -d: use dots instead of Unicode/UTF-8.\n"); printf(" -m: magazine style listing (see a8cat(1)).\n"); + printf(" -x: XL international character set (UTF-8).\n"); printf(" -b: use bold for color output.\n"); printf(" -i: show immediate mode command (line 32768).\n"); printf(" -n: disable color syntax highlighting.\n"); + printf(" -n: use underline for inverse video.\n"); printf(" -v: verbose.\n"); } void parse_args(int argc, char **argv) { int opt; - int opt_a = 0, opt_m = 0, opt_d = 0; + int opt_a = 0, opt_m = 0, opt_d = 0, opt_x = 0; - while( (opt = getopt(argc, argv, "viamnbdh")) != -1) { + while( (opt = getopt(argc, argv, "viamnbdhxu")) != -1) { switch(opt) { - case 'v': verbose = 1; break; + case 'v': verbose = 1; break; case 'i': immediate = 1; break; - case 'a': opt_a = 1; break; - case 'm': opt_m = 1; break; - case 'd': opt_d = 1; break; - case 'n': color = 0; break; - case 'b': bold = 1; break; + case 'a': opt_a = 1; break; + case 'm': opt_m = 1; break; + case 'd': opt_d = 1; break; + case 'x': opt_x = 1; break; + case 'b': bold = 1; break; + case 'u': underline = 1; break; + case 'n': color = 0; break; case 'h': print_help(); exit(0); default: print_help(); @@ -57,19 +90,17 @@ void parse_args(int argc, char **argv) { } } - if(opt_a + opt_d + opt_m > 1) - die("Only use one of the -a, -d, -m options."); + if(opt_a + opt_d + opt_m + opt_x > 1) + die("Only use one of the -a, -d, -m, -x options."); if(opt_a) { - utf8 = magazine = color = dots = 0; - table = ata2utf; + output_mode = M_ATASCII; } else if(opt_d) { - magazine = 0; - utf8 = dots = 1; + output_mode = M_DOTS; } else if(opt_m) { - magazine = 1; - utf8 = color = dots = 0; - table = ata2mag; + output_mode = M_MAG; + } else if(opt_x) { + output_mode = M_UTF8_I; } if(optind >= argc) @@ -79,11 +110,12 @@ void parse_args(int argc, char **argv) { } void setup_outfh(void) { - if(! (utf8 || magazine) ) { + if(output_mode == M_ATASCII) { if(isatty(fileno(stdout))) { die("Refusing to write ATASCII data to the terminal."); } } + /* TODO: reopen in binary mode! */ outfh = stdout; return; } @@ -118,12 +150,13 @@ double bcd2double(const unsigned char *num) { } void color_on(unsigned char c) { - printf("\x1b[%d;3%dm", bold, c); + cur_color = c; + printf(COLOR_FMT, bold, c); } void color_off(void) { - /* fputs("\x1b[0m", outfh); */ /* NO: clears inverse, too! */ - fputs("\x1b[39;49m", outfh); + cur_color = -1; + fputs(COLOR_OFF, outfh); } void print_number(unsigned int pos) { @@ -162,27 +195,48 @@ int affects_inv(unsigned char c) { } void start_inv(unsigned char c) { - if(utf8) { - fputs("\x1b[7m", outfh); - inv = 1; - } else if(magazine) { - if(affects_inv(c)) { - fputs("{inv}", outfh); + switch(output_mode) { + case M_DOTS: + case M_UTF8: + case M_UTF8_I: + if(underline) + fputs(ULINE_ON, outfh); + else + fputs(INV_ON, outfh); inv = 1; - } + break; + case M_MAG: + if(affects_inv(c)) { + fputs(MAG_INV, outfh); + inv = 1; + } + break; + case M_ATASCII: + default: + break; } } void end_inv(unsigned char c) { - if(utf8) { - /* fputs("\x1b[0m", outfh); */ /* NO: turns off color, too. */ - fputs("\x1b[27m", outfh); - inv = 0; - } else if(magazine) { - if(affects_inv(c)) { - fputs("{norm}", outfh); + switch(output_mode) { + case M_DOTS: + case M_UTF8: + case M_UTF8_I: + fputs(INV_OFF, outfh); inv = 0; - } + /* work around INV_OFF also turning off color. */ + if(cur_color > -1) + color_on(cur_color); + break; + case M_MAG: + if(affects_inv(c)) { + fputs(MAG_NORM, outfh); + inv = 0; + } + break; + case M_ATASCII: + default: + break; } } @@ -196,22 +250,37 @@ void print_ata_chr(unsigned char c) { end_inv(c); } } - if(dots) - fputc(isprint(c & 0x7f) ? c & 0x7f : '.', outfh); - else if(utf8 || magazine) - fputs(table[c & 0x7f], outfh); - else - putchar(c); + + switch(output_mode) { + case M_DOTS: + fputc(isprint(c & 0x7f) ? c & 0x7f : '.', outfh); + break; + case M_UTF8: + fputs(ata2utf[c & 0x7f], outfh); + break; + case M_UTF8_I: + fputs(ics2utf[c & 0x7f], outfh); + break; + case M_MAG: + fputs(ata2mag[c & 0x7f], outfh); + break; + case M_ATASCII: + default: + outchr(c); + break; + } } void print_string(unsigned int pos, unsigned int len) { inv = 0; - if(color) color_on(C_RED); outchr('"'); + if(color) color_on(C_RED); while(len--) print_ata_chr(program[pos++]); - if(inv) end_inv(0); - outchr('"'); + if(inv) { + end_inv(0); + } if(color) color_off(); + outchr('"'); } CALLBACK(print_lineno) { @@ -310,10 +379,10 @@ CALLBACK(print_text) { } CALLBACK(print_newline) { - if(utf8 || magazine) - outchr('\n'); - else + if(output_mode == M_ATASCII) outchr(0x9b); + else + outchr('\n'); } CALLBACK(code_prot) { diff --git a/listbas.rst b/listbas.rst index d0c6e61..8321ab1 100644 --- a/listbas.rst +++ b/listbas.rst @@ -26,31 +26,46 @@ escape sequences for inverse video and color syntax highlighting. OPTIONS ======= -List options +Output modes ------------ +The default output mode is Unicode/UTF-8 representations of ATASCII +characters. + **-a** Output raw ATASCII; no translation to the host character set. Must be used with redirection; **listbas** will not write ATASCII to the terminal. -**-b** - Use bold, for color output. This may make it easier to read on - some terminals. Or, it may hurt your eyes... - **-d** Print dots rather than Unicode/UTF-8 characters. Color and inverse video are still supported in this mode. Use this only if your terminal *really* doesn't support Unicode (e.g. **rxvt**\(1)). -**-i** - Include the immediate mode command (line 32768) in the output. - **-m** Output "magazine listing". See the **-m** option for **a8cat** for details. + Color is supported in this mode, + +**-x** + Output Unicode/UTF-8 representations of the XL International Character + Set, rather than ATASCII. + +Other options +------------- + +**-b** + Use bold for color output. This may make it easier to read on + some terminals. Or, it may hurt your eyes... + +**-i** + Include the immediate mode command (line 32768) in the output. **-n** - No color. Has no effect if **-a** or **-m** are in effect, since these - modes don't support color anyway. + No color. Has no effect if **-a** is in effect, since this + mode doesn't support color anyway. Disabling color does not + disable reverse video. + +**-u** + Use underlining for inverse video, rather than reverse video output. .. include:: genopts.rst @@ -76,14 +91,15 @@ The color scheme is: **red** Numbers (except line numbers at the start of a line) and string - constants. + constants (but not the quotes around the string). **cyan** Line numbers at the start of a line, comments (**REM** text) and **DATA** elements. -Variable names and commas between **DATA** elements are not highlighted, -so they'll appear in the default foreground color (usually white if the -terminal has a black background, or black if the background is white). +Quotes around strings, variable names, and commas between **DATA** +elements are not highlighted, so they'll appear in the default +foreground color (usually white if the terminal has a black +background, or black if the background is white). Note that nothing is highlighted in blue. This is because it's difficult to read on many terminals. Also, black and white are not |