aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--listamsb.14
-rw-r--r--listamsb.c63
-rw-r--r--listamsb.rst4
3 files changed, 46 insertions, 25 deletions
diff --git a/listamsb.1 b/listamsb.1
index 5b4fa65..ca92ee6 100644
--- a/listamsb.1
+++ b/listamsb.1
@@ -144,8 +144,8 @@ detect Atari BASIC files, but occasionally you\(aqll get gibberish output instea
.SH EXIT STATUS
.sp
0 for success, 1 if there was an error reading the input (e.g. file
-not found), or 2 if the input file has invalid tokens (if this
-happens, you will also see a warning about it on stderr).
+not found), or 2 if the input file had errors or warnings (see
+\fBDIAGNOSTICS\fP).
.SH COPYRIGHT
.sp
WTFPL. See \fI\%http://www.wtfpl.net/txt/copying/\fP for details.
diff --git a/listamsb.c b/listamsb.c
index 6d125b9..a70d57e 100644
--- a/listamsb.c
+++ b/listamsb.c
@@ -23,12 +23,13 @@
even with cart-based AMSB2 and no DOS loaded. */
#define MAX_PROGLEN 30000
-/* a program whose header has a length less than this can't be
- a real AMSB program. The minimum size is what you get if you
+/* a program whose header has a length less than MIN_PROGLEN can't be
+ a real AMSB program. EMPTY_PROGLEN is what you get if you
SAVE when there's no program in memory (right after boot or
a NEW). The minimum size for a program that actually contains
code seems to be 5 (for 10 PRINT) */
-#define MIN_PROGLEN 2
+#define MIN_PROGLEN 5
+#define EMPTY_PROGLEN 2
const char *self;
@@ -40,7 +41,7 @@ int check_only = 0; /* -c */
int need_pclose = 0;
int bytes_read = 0;
-int unknowns = 0;
+int warnings = 0;
FILE *infile;
FILE *outfile;
@@ -53,18 +54,21 @@ void set_self(const char *argv0) {
if(p) self = p + 1;
}
-void die(const char *msg) {
+void die_with(const char *msg, int status) {
fprintf(stderr, "%s: %s\n", self, msg);
- exit(1);
+ exit(status);
}
+#define die(x) die_with(x,1)
+#define die2(x) die_with(x,2)
+
unsigned char read_byte(void) {
int c;
c = fgetc(infile);
if(c < 0)
- die("unexpected EOF, file truncated?");
+ die2("unexpected EOF, file truncated?");
bytes_read++;
return (unsigned char)c;
@@ -85,7 +89,7 @@ int read_header(void) {
int proglen;
b = read_byte();
- if(b) die("not an AMSB file: first byte not $00");
+ if(b) die2("not an AMSB file: first byte not $00");
proglen = read_word();
@@ -95,20 +99,25 @@ int read_header(void) {
if(proglen > MAX_PROGLEN) {
fprintf(stderr, "%s: not an AMSB file: too big (%d bytes), won't fit in Atari memory\n",
self, proglen);
- exit(1);
+ exit(2);
}
- if(proglen < MIN_PROGLEN) {
- fprintf(stderr, "%s: not an AMSB file: program size too small (%d). Atari BASIC file?\n",
- self, proglen);
- exit(1);
+ if(proglen == EMPTY_PROGLEN) {
+ fprintf(stderr, "%s: program length is 2, no code in file (SAVE after NEW)\n", self);
+ warnings++;
+ } else {
+ if(proglen < MIN_PROGLEN) {
+ fprintf(stderr, "%s: not an AMSB file: program size too small (%d). Atari BASIC file?\n",
+ self, proglen);
+ exit(2);
+ }
}
return proglen;
}
void unknown_token(int lineno, unsigned char byte, int ext) {
- unknowns++;
+ warnings++;
fprintf(outfile, "<unknown %stoken ", (ext ? "extended " : ""));
fprintf(outfile, "%s%02x>", (ext ? "ff ": ""), byte);
}
@@ -135,11 +144,13 @@ int next_line(void) {
if(lineno <= last_lineno) {
fprintf(stderr, "%s: line number out of order (%d <= %d)\n",
self, lineno, last_lineno);
+ warnings++;
}
if(lineno > MAX_LINENO) {
fprintf(stderr, "%s: line number out range (%d > %d)\n",
self, lineno, MAX_LINENO);
+ warnings++;
}
last_lineno = lineno;
@@ -200,6 +211,7 @@ int next_line(void) {
fprintf(stderr, "%s: line %d has character %d outside of a string, "
"maybe not an AMSB file?\n",
self, lineno, byte);
+ warnings++;
}
putc(byte, outfile);
}
@@ -207,7 +219,7 @@ int next_line(void) {
putc(EOL, outfile);
- return lineno;
+ return 1;
}
void print_help(void) {
@@ -294,7 +306,7 @@ void open_output() {
}
int main(int argc, char **argv) {
- int proglen, lineno, rv = 0;
+ int proglen, lineno, rv = 0, linecount = 0;
set_self(argv[0]);
@@ -305,24 +317,33 @@ int main(int argc, char **argv) {
proglen = read_header();
while( (lineno = next_line()) != -1 )
- /* nop */ ;
+ linecount++;
- if(verbose)
- fprintf(stderr, "read %d bytes\n", bytes_read);;
+ if(verbose) {
+ fprintf(stderr, "read %d bytes\n", bytes_read);
+ fprintf(stderr, "listed %d lines\n", linecount);
+ }
+
+ if(!linecount) {
+ fprintf(stderr, "%s: no lines of code in program\n", self);
+ warnings++;
+ }
if(proglen == (bytes_read - 3)) {
if(verbose)
fprintf(stderr, "file size matches proglen\n");
} else {
fprintf(stderr, "%s: actual program size doesn't match program size in header\n", self);
+ warnings++;
}
if(fgetc(infile) != EOF) {
fprintf(stderr, "%s: trailing garbage at end of file\n", self);
+ warnings++;
}
- if(unknowns) {
- fprintf(stderr, "%s: file has %d unknown tokens\n", self, unknowns);;
+ if(warnings) {
+ fprintf(stderr, "%s: file has %d warnings\n", self, warnings);
rv = 2;
}
diff --git a/listamsb.rst b/listamsb.rst
index c04c638..ad0c897 100644
--- a/listamsb.rst
+++ b/listamsb.rst
@@ -131,7 +131,7 @@ EXIT STATUS
===========
0 for success, 1 if there was an error reading the input (e.g. file
-not found), or 2 if the input file has invalid tokens (if this
-happens, you will also see a warning about it on stderr).
+not found), or 2 if the input file had errors or warnings (see
+**DIAGNOSTICS**).
.. include:: manftr.rst