aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2024-07-12 06:01:59 -0400
committerB. Watson <urchlay@slackware.uk>2024-07-12 06:01:59 -0400
commitf9f49e0e20ea64e99372b77e49b7cd9b84c25acf (patch)
tree82a26b2facc19bbb4f76e3fd2de37dd3b98cc862
parentd3f053d40f01aa807c10f0699ed9ff4349150adc (diff)
downloadbw-atari8-tools-f9f49e0e20ea64e99372b77e49b7cd9b84c25acf.tar.gz
listbas: code cleanup, add -x and -u opts, fix color bug in strings, don't highlight quotes around strings.
-rw-r--r--listbas.146
-rw-r--r--listbas.c173
-rw-r--r--listbas.rst44
3 files changed, 182 insertions, 81 deletions
diff --git a/listbas.1 b/listbas.1
index 0fc70b4..97ebb9c 100644
--- a/listbas.1
+++ b/listbas.1
@@ -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
diff --git a/listbas.c b/listbas.c
index d085460..e3b4225 100644
--- a/listbas.c
+++ b/listbas.c
@@ -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