diff options
| author | B. Watson <urchlay@slackware.uk> | 2025-02-26 15:12:11 -0500 | 
|---|---|---|
| committer | B. Watson <urchlay@slackware.uk> | 2025-02-26 15:12:27 -0500 | 
| commit | 2797f43e4cef6bea12e37208d3425cc72bd5778d (patch) | |
| tree | d5c239f35da3384baa2b47e68793ee3c45338476 | |
| parent | 920ca094b9acd1e2b147cdb323a472a0da65dcc2 (diff) | |
| download | bw-atari8-tools-2797f43e4cef6bea12e37208d3425cc72bd5778d.tar.gz | |
listamsb: add -r option; listbas: fix typo in -r error message.
| -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) { | 
