aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--listbas.163
-rw-r--r--listbas.c40
-rw-r--r--listbas.rst37
3 files changed, 132 insertions, 8 deletions
diff --git a/listbas.1 b/listbas.1
index 40097e8..2104dfb 100644
--- a/listbas.1
+++ b/listbas.1
@@ -27,12 +27,12 @@ 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-18" "0.2.1" "Urchlay's Atari 8-bit Tools"
+.TH "LISTBAS" 1 "2024-07-20" "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
.sp
-listbas [\fB\-a\fP | \fB\-d\fP | \fB\-m\fP | \fB\-x\fP | \fB\-U\fP] [\fB\-B\fP] [\fB\-u\fP] [\fB\-i\fP] [\fB\-l\fP] [\fB\-n\fP | \fB\-C\fP] [\fB\-v\fP] [\fB\-c\fP \fIcolors\fP] \fBinput\-file\fP
+listbas [\fB\-a\fP | \fB\-d\fP | \fB\-m\fP | \fB\-x\fP | \fB\-U\fP] [\fB\-B\fP] [\fB\-u\fP] [\fB\-i\fP] [\fB\-l\fP] [\fB\-n\fP | \fB\-C\fP] [\fB\-v\fP] [\fB\-c\fP \fIcolors\fP] [\fB\-r\fP \fIline\-range\fP] \fBinput\-file\fP
.SH DESCRIPTION
.sp
\fBlistbas\fP acts like the \fILIST\fP command in BASIC. It reads a
@@ -72,8 +72,17 @@ OSS BASIC XE.
.sp
See \fBBASIC DIALECTS\fP below for details.
.TP
+.B \fB\-r\fP \fIline\-range\fP
+Show only part of the listing. \fIline\-range\fP can be a single line, or
+a comma\-separated pair of starting and ending line numbers (e.g. \fB100,200\fP).
+If the start line number is omitted (e.g. \fB,100\fP), it will be treated as
+\fB0\fP (meaning, list from the beginning of the program). If the ending line
+number is omitted (e.g. \fB100,\fP), it means "list until the end of the program".
+\fB\-r,\fP is equivalent to not using the \fB\-r\fP option at all.
+.TP
.B \fB\-i\fP
-Include the immediate mode command (line 32768) in the output.
+Include the immediate mode command (line 32768) in the output. This option has no
+effect if the \fB\-r\fP option is used to stop listing before the end of the program.
.TP
.B \fB\-l\fP
Do not print line numbers at the start of each line. \fBGOTO\fP, \fBGOSUB\fP,
@@ -282,6 +291,54 @@ Turbo BASIC, at least, will "max out" the indentation level at some
point. Once there are 60 or so levels of indent, it stops adding
more. \fBlistbas\fP doesn\(aqt emulate this behaviour (shouldn\(aqt be a
problem, it\(aqs a pathological case).
+.sp
+BASIC XL actually does indentation within a line. If you write:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+10 IF A:IF B:IF C:REM
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+\&...BXL lists it as:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+10 If A: If B: If C:Rem
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+\fBlistbas\fP only indents at the start of a line, so this behaviour is
+not emulated.
+.sp
+One thing \fBlistbas\fP gets right: the \fBLIST\fP command in Turbo, A+,
+BXL, and BXE always starts out with 0 indent spaces, if you\(aqre only
+listing part of a program. BXE example:
+.INDENT 0.0
+.INDENT 3.5
+.sp
+.nf
+.ft C
+10 While 1
+20 If Peek(764)<>255
+30 ? "SOMEONE PRESSED A KEY":Poke 764,255
+40 Endif
+50 Endwhile
+.ft P
+.fi
+.UNINDENT
+.UNINDENT
+.sp
+\&...but if you give a \fBLIST 30\fP in BXE, you\(aqll get line 30 without any
+indentation. \fBlistbas\fP does this, too, if you use the \fB\-r\fP option.
.SS Protected Programs
.sp
\fBlistbas\fP will refuse to operate on a LIST\-protected program with
diff --git a/listbas.c b/listbas.c
index 338e8d0..3226340 100644
--- a/listbas.c
+++ b/listbas.c
@@ -79,6 +79,8 @@ int dump_tables = 0; /* 1 with -D */
int autodetect = 1; /* 0 with -b */
int mixed_case = 1; /* 0 with -k, or if input is B_ATARI or B_APLUS */
int indent = 1; /* 0 with -t, or if input is B_ATARI */
+int startline = 0; /* -r */
+int endline = 32767; /* -r */
/* change these with -c */
int color_cmd = C_YELLOW;
@@ -151,8 +153,37 @@ int get_bas_type(char *arg) {
exit(1);
}
+void get_line_range(const char *arg) {
+ int val = 0, comma = 0;
+ const char *p = arg;
+
+ while(*p) {
+ if(*p >= '0' && *p <= '9') {
+ val *= 10;
+ val += *p - '0';
+ if(val > 32768) die("Invalid line number for -r (range is 0-32768).");
+ } else if(*p == ',' || *p == '-') {
+ if(comma) die("Invalid argument for -r (too many commas).");
+ comma++;
+ startline = val;
+ val = 0;
+ } else {
+ if(comma) die("Invalid argument for -r (only digits and comma allowed).");
+ }
+ p++;
+ }
+
+ if(comma)
+ endline = val ? val : 32767;
+ else
+ startline = endline = val;
+
+ if(endline < startline)
+ die("Invalid argument for -r (end > start).");
+}
+
void print_help(void) {
- printf("Usage: %s [-a|-d|-m|-x|-U] [-B] [-i] [-l] [-u] [-n|-C] [-v] [-c *colors*] [-k] [-t] <inputfile>\n", self);
+ printf("Usage: %s [-a|-d|-m|-x|-U] [-B] [-i] [-l] [-u] [-n|-C] [-v] [-c *colors*] [-r *start,end* ] [-k] [-t] <inputfile>\n", self);
printf(" -b <XX>: set BASIC type. XX is: a = atari, t = turbo, xl, xe, a+.\n");
printf(" -U: output ATASCII as Unicode/UTF-8 (this is the default).\n");
printf(" -a: output raw ATASCII.\n");
@@ -168,6 +199,7 @@ void print_help(void) {
printf(" -c: use custom colors (see man page).\n");
printf(" -k: disable mixed case keywords for BXL/BXE (e.g. Print).\n");
printf(" -t: disable Turbo/BXL/BXE indentation.\n");
+ printf(" -r: only list lines numbered from *start* to *end*.\n");
printf(" -v: verbose.\n");
}
@@ -176,7 +208,7 @@ void parse_args(int argc, char **argv, int from_env) {
optind = 1;
- while( (opt = getopt(argc, argv, "Db:UCviamnBdhxulc:kt")) != -1) {
+ while( (opt = getopt(argc, argv, "r:Db:UCviamnBdhxulc:kt")) != -1) {
switch(opt) {
case 'U': output_mode = M_UTF8; break;
case 'a': output_mode = M_ATASCII; color = 0; break;
@@ -194,6 +226,7 @@ void parse_args(int argc, char **argv, int from_env) {
case 'k': mixed_case = 0; break;
case 't': indent = 0; break;
case 'b': autodetect = 0; bas_type = get_bas_type(optarg); break;
+ case 'r': get_line_range(optarg); break;
case 'c': parse_color_scheme(optarg); break;
case 'h': print_help(); exit(0);
default:
@@ -960,7 +993,8 @@ void init_callbacks(void) {
void list(void) {
init_callbacks();
- walk_code(0, 32767 + immediate);
+ if(endline == 32767 && immediate) endline++;
+ walk_code(startline, endline);
}
void init_bas_tables() {
diff --git a/listbas.rst b/listbas.rst
index 1a7a5c8..558d053 100644
--- a/listbas.rst
+++ b/listbas.rst
@@ -11,7 +11,7 @@ List the source of a tokenized Atari 8-bit BASIC program
SYNOPSIS
========
-listbas [**-a** | **-d** | **-m** | **-x** | **-U**] [**-B**] [**-u**] [**-i**] [**-l**] [**-n** | **-C**] [**-v**] [**-c** *colors*] **input-file**
+listbas [**-a** | **-d** | **-m** | **-x** | **-U**] [**-B**] [**-u**] [**-i**] [**-l**] [**-n** | **-C**] [**-v**] [**-c** *colors*] [**-r** *line-range*] **input-file**
DESCRIPTION
===========
@@ -54,8 +54,17 @@ BASIC options
See **BASIC DIALECTS** below for details.
+**-r** *line-range*
+ Show only part of the listing. *line-range* can be a single line, or
+ a comma-separated pair of starting and ending line numbers (e.g. **100,200**).
+ If the start line number is omitted (e.g. **,100**), it will be treated as
+ **0** (meaning, list from the beginning of the program). If the ending line
+ number is omitted (e.g. **100,**), it means "list until the end of the program".
+ **-r,** is equivalent to not using the **-r** option at all.
+
**-i**
- Include the immediate mode command (line 32768) in the output.
+ Include the immediate mode command (line 32768) in the output. This option has no
+ effect if the **-r** option is used to stop listing before the end of the program.
**-l**
Do not print line numbers at the start of each line. **GOTO**, **GOSUB**,
@@ -253,6 +262,30 @@ point. Once there are 60 or so levels of indent, it stops adding
more. **listbas** doesn't emulate this behaviour (shouldn't be a
problem, it's a pathological case).
+BASIC XL actually does indentation within a line. If you write::
+
+ 10 IF A:IF B:IF C:REM
+
+...BXL lists it as::
+
+ 10 If A: If B: If C:Rem
+
+**listbas** only indents at the start of a line, so this behaviour is
+not emulated.
+
+One thing **listbas** gets right: the **LIST** command in Turbo, A+,
+BXL, and BXE always starts out with 0 indent spaces, if you're only
+listing part of a program. BXE example::
+
+ 10 While 1
+ 20 If Peek(764)<>255
+ 30 ? "SOMEONE PRESSED A KEY":Poke 764,255
+ 40 Endif
+ 50 Endwhile
+
+...but if you give a **LIST 30** in BXE, you'll get line 30 without any
+indentation. **listbas** does this, too, if you use the **-r** option.
+
Protected Programs
------------------