aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--listamsb.121
-rw-r--r--listamsb.c90
-rw-r--r--listamsb.rst13
-rw-r--r--listbas.c2
4 files changed, 101 insertions, 25 deletions
diff --git a/listamsb.1 b/listamsb.1
index a80a17d..a9f36e2 100644
--- a/listamsb.1
+++ b/listamsb.1
@@ -63,12 +63,23 @@ with this option.
Check only. No output on stdout. Diagnostics are still printed on stderr,
and the exit status is unchanged.
.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\-v\fP
Verbose output, on stderr.
.TP
-.B \fB\-h\fP
+.B \fB\-h\fP, \fB\-\-help\fP
Print built\-in help and exit.
.TP
+.B \fB\-\-version\fP
+Print version number and exit.
+.TP
.B \fB\-i\fP, \fB\-u\fP, \fB\-t\fP, \fB\-m\fP, \fB\-s\fP
These options are passed to \fBa8cat\fP\&. See its man page for details. If
the \fB\-a\fP or \fB\-c\fP option is used, these options have no effect.
@@ -116,7 +127,7 @@ unexpected EOF, file truncated?
A tokenized AMSB file always ends with three null bytes (\fI$00\fP).
This file doesn\(aqt. Probably the rest of the file is missing.
.IP \(bu 2
-line \fIN\fP: EOL address \fIA\fP too (low|high)
+line \fIL\fP: EOL address \fIA\fP too (low|high)
.sp
Each line begins with the address of the next line. If the address
is below \fI$0700\fP, it\(aqs below the minimum value of \fIMEMLO\fP, which
@@ -124,11 +135,11 @@ is impossible. If it\(aqs above \fI$bc1f\fP, it would be in the display
list, screen memory, or OS ROM (also impossible). File is
corrupt, or not an AMSB file.
.IP \(bu 2
-line \fIN\fP: EOL address \fIA\fP <= previous \fIB\fP
+line \fIL\fP: EOL address \fIA\fP <= previous \fIB\fP
.sp
Corrupt file, or not an AMSB file.
.IP \(bu 2
-line \fIN\fP EOL address doesn\(aqt match actual line length \fIL\fP
+line \fIL\fP EOL address doesn\(aqt match actual line length \fIN\fP
.sp
Same as above: corrupt, or not AMSB.
.IP \(bu 2
@@ -141,7 +152,7 @@ line number out range
The program contains a line number that\(aqs greater than \fI63999\fP\&. How
did that happen?
.IP \(bu 2
-line \fIN\fP has character \fIC\fP outside of a string. maybe Atari BASIC?
+line \fIL\fP has character \fIC\fP outside of a string. maybe Atari BASIC?
.sp
This happens when ATASCII codes 0 to 31 (\fI$1f\fP) appear in the program.
AMSB can create files like this, but at runtime, it\(aqs a syntax error.
diff --git a/listamsb.c b/listamsb.c
index c0bf3e8..3111735 100644
--- a/listamsb.c
+++ b/listamsb.c
@@ -49,9 +49,12 @@ const char *self;
char pipe_command[BUFSIZ + 1] = { "a8cat" };
-int verbose = 0; /* -v */
-int raw_output = 0; /* -a */
-int check_only = 0; /* -c */
+int verbose = 0; /* -v */
+int raw_output = 0; /* -a */
+int check_only = 0; /* -c */
+int startline = 0; /* -r */
+int endline = MAX_LINENO; /* -r */
+
int need_pclose = 0;
int bytes_read = 0;
@@ -128,7 +131,6 @@ void read_header(void) {
}
void unknown_token(int lineno, unsigned char byte, int ext) {
- warnings++;
fprintf(outfile, "<unknown %stoken ", (ext ? "extended " : ""));
fprintf(outfile, "%s%02x>", (ext ? "$ff ": ""), byte);
}
@@ -137,6 +139,7 @@ int next_line(void) {
static int last_lineno = -1;
static int last_ptr = -1;
int ptr, lineno, was_ff, in_string, offset, len;
+ int printing;
unsigned char byte;
offset = bytes_read;
@@ -155,6 +158,8 @@ int next_line(void) {
if(verbose)
fprintf(stderr, "found line %d, offset %d, end-of-line %d\n", lineno, offset, ptr);
+ printing = (lineno >= startline) && (lineno <= endline);
+
if(ptr < MIN_PTR) {
fprintf(stderr, "%s: line %d: EOL address $%04x too low (<$%04x)\n",
self, lineno, ptr, MIN_PTR);
@@ -188,7 +193,7 @@ int next_line(void) {
last_lineno = lineno;
/* note that AMSB always puts a space after the line number in LIST */
- fprintf(outfile, "%d ", lineno);
+ if(printing) fprintf(outfile, "%d ", lineno);
was_ff = 0;
in_string = 0;
@@ -201,7 +206,7 @@ int next_line(void) {
if(byte == 0x00 || byte == '|') {
/* end of string */
in_string = 0;
- putc('"', outfile);
+ if(printing) putc('"', outfile);
/* if we read a null, that means the line ends with a string
that's missing its closing double-quote. */
@@ -211,31 +216,33 @@ int next_line(void) {
continue;
}
}
- putc(byte, outfile);
+ if(printing) putc(byte, outfile);
} else if(byte == ':') {
/* don't print the colon if the next token is a ! or ' for a comment */
unsigned char next = read_byte();
if( !(next == 0x9a || next == 0x9b) )
- putc(byte, outfile);
+ if(printing) putc(byte, outfile);
ungetc(next, infile);
bytes_read--;
} else if(byte == '"') {
/* strings start but *don't end* with a double-quote */
in_string = 1;
- putc(byte, outfile);
+ if(printing) putc(byte, outfile);
} else if(was_ff) {
if(byte >= MIN_EXT_TOK && byte <= MAX_EXT_TOK) {
- fprintf(outfile, "%s", ext_tokens[byte - MIN_EXT_TOK]);
+ if(printing) fprintf(outfile, "%s", ext_tokens[byte - MIN_EXT_TOK]);
} else {
- unknown_token(lineno, byte, 1);
+ if(printing) unknown_token(lineno, byte, 1);
+ warnings++;
}
was_ff = 0;
} else if(byte == 0xff) {
was_ff = 1;
} else if(byte >= MIN_STD_TOK && byte <= MAX_STD_TOK) {
- fprintf(outfile, "%s", std_tokens[byte - MIN_STD_TOK]);
+ if(printing) fprintf(outfile, "%s", std_tokens[byte - MIN_STD_TOK]);
} else if(byte >= 0x80) {
- unknown_token(lineno, byte, 0);
+ if(printing) unknown_token(lineno, byte, 0);
+ warnings++;
} else {
if(!byte) break;
if(byte < 0x20) {
@@ -245,7 +252,7 @@ int next_line(void) {
self, lineno, byte);
warnings++;
}
- putc(byte, outfile);
+ if(printing) putc(byte, outfile);
}
}
@@ -266,7 +273,7 @@ int next_line(void) {
last_ptr = ptr;
- putc(EOL, outfile);
+ if(printing) putc(EOL, outfile);
return 1;
}
@@ -278,21 +285,69 @@ void print_help(void) {
puts(" -a: raw ATASCII output");
puts(" -c: check only (no listing)");
puts(" -v: verbose");
- puts(" -h: show this help");
+ puts(" --help, -h: print this help and exit");
+ puts(" --version: print version number and exit");
puts(" -i -u -t -m -s: passed to a8cat (try 'a8cat -h')");
puts("file must be a tokenized (SAVEd) AMSB file. if not given, reads from stdin.");
}
+void version(void) {
+ printf("%s " VERSION "\n", self);
+}
+
+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 > MAX_LINENO) {
+ fprintf(stderr, "invalid line number for -r (range is 0-%d)\n", MAX_LINENO);
+ exit(1);
+ }
+ } 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 : MAX_LINENO;
+ else
+ startline = endline = val;
+
+ if(endline < startline)
+ die("invalid argument for -r (start > end)");
+}
+
void parse_args(int argc, char **argv) {
char tmp[10];
int opt;
- while( (opt = getopt(argc, argv, "cvaiutmsh")) != -1) {
+ if(argc >= 2) {
+ if(strcmp(argv[1], "--help") == 0) {
+ print_help();
+ exit(0);
+ } else if(strcmp(argv[1], "--version") == 0) {
+ version();
+ exit(0);
+ }
+ }
+
+ while( (opt = getopt(argc, argv, "r:cvaiutmsh")) != -1) {
switch(opt) {
case 'c': check_only = 1; break;
case 'a': raw_output = 1; break;
case 'h': print_help(); exit(0);
case 'v': verbose = 1; break;
+ case 'r': get_line_range(optarg); break;
case 'i':
case 'u':
case 't':
@@ -303,7 +358,6 @@ void parse_args(int argc, char **argv) {
sprintf(tmp, " -%c", opt);
strcat(pipe_command, tmp);
break;
-
default: print_help(); exit(1);
}
}
diff --git a/listamsb.rst b/listamsb.rst
index 98c36ae..d4174f9 100644
--- a/listamsb.rst
+++ b/listamsb.rst
@@ -45,12 +45,23 @@ OPTIONS
Check only. No output on stdout. Diagnostics are still printed on stderr,
and the exit status is unchanged.
+**-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.
+
**-v**
Verbose output, on stderr.
-**-h**
+**-h**\, **--help**
Print built-in help and exit.
+**--version**
+ Print version number and exit.
+
**-i**\, **-u**\, **-t**\, **-m**\, **-s**
These options are passed to **a8cat**. See its man page for details. If
the **-a** or **-c** option is used, these options have no effect.
diff --git a/listbas.c b/listbas.c
index ab23fc3..e7b5002 100644
--- a/listbas.c
+++ b/listbas.c
@@ -179,7 +179,7 @@ void get_line_range(const char *arg) {
startline = endline = val;
if(endline < startline)
- die("Invalid argument for -r (end > start).");
+ die("Invalid argument for -r (start > end).");
}
void print_help(void) {