diff options
-rw-r--r-- | listamsb.1 | 21 | ||||
-rw-r--r-- | listamsb.c | 90 | ||||
-rw-r--r-- | listamsb.rst | 13 | ||||
-rw-r--r-- | listbas.c | 2 |
4 files changed, 101 insertions, 25 deletions
@@ -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. @@ -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. @@ -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) { |