diff options
| author | B. Watson <urchlay@slackware.uk> | 2024-06-29 21:45:25 -0400 | 
|---|---|---|
| committer | B. Watson <urchlay@slackware.uk> | 2024-06-29 21:45:25 -0400 | 
| commit | ad20c5466321f6c8bd3006953b3b37e50935cdb4 (patch) | |
| tree | 6f4d9bec4ebd87eecf1aac9a80ea06a7fb90df27 | |
| parent | c9e479515fa95dd77b6430331dc53ba2174308a5 (diff) | |
| download | bw-atari8-tools-ad20c5466321f6c8bd3006953b3b37e50935cdb4.tar.gz | |
a8xd: implement -o, -s, -l, add more messages for -v.
| -rw-r--r-- | a8xd.1 | 14 | ||||
| -rw-r--r-- | a8xd.c | 73 | ||||
| -rw-r--r-- | a8xd.rst | 14 | 
3 files changed, 79 insertions, 22 deletions
| @@ -73,7 +73,7 @@ Print XL/XE International Character Set conversions instead of ATASCII.  .INDENT 0.0  .TP  .B \-l \fIlen\fP -\fB*\fP Stop after dumping \fIlen\fP bytes. \fIlen\fP may be given in decimal or hex (with +Stop after dumping \fIlen\fP bytes. \fIlen\fP may be given in decimal or hex (with  leading \fI0x\fP or \fI$\fP).  .UNINDENT  .INDENT 0.0 @@ -86,10 +86,12 @@ set are still displayed in inverse.  .TP  .B \-o \fIoffset\fP  Add \fIoffset\fP to displayed file position. \fIoffset\fP can be given in decimal -or hex (with leading \fI0x\fP or \fI$\fP). +or hex (with leading \fI0x\fP or \fI$\fP). Negative offsets are allowed, but they +will be printed as very large positive numbers in the output (this matches +\fBxxd\fP\(aqs behaviour).  .TP  .B \-s \fI[\-]seek\fP -\fB*\fP Start at \fIseek\fP bytes. Without \fI\-\fP, this is an absolute offset. With \fI\-\fP, +Start at \fIseek\fP bytes. Without \fI\-\fP, this is an absolute offset. With \fI\-\fP,  it\(aqs relative to the end of the file. The \fI\-\fP option won\(aqt work when  reading from standard input. \fIseek\fP may be given in decimal or hex  (with leading \fI0x\fP or \fI$\fP). @@ -100,7 +102,8 @@ reading from standard input. \fIseek\fP may be given in decimal or hex  Use uppercase letters for hex digits; the default is lowercase.  .TP  .B  \-v -Verbose. Currently, this option is accepted, but it doesn\(aqt do anything yet. +Verbose. Shows various debug messages that are probably only useful +if you\(aqre hacking on \fBa8xd\fP\&.  .UNINDENT  .INDENT 0.0  .TP @@ -134,6 +137,9 @@ missing are:  .IP \(bu 2  \fB\-b\fP (bits mode).  .UNINDENT +.sp +Another difference is that \fBa8xd\fP doesn\(aqt support files larger than +2GB. This won\(aqt be a problem for Atari 8\-bit\-related files!  .SH COPYRIGHT  .sp  WTFPL. See \fI\%http://www.wtfpl.net/txt/copying/\fP for details. @@ -54,7 +54,6 @@ void parse_seek_arg(const char *arg) {  	if(*arg == '-') {  		seek_whence = SEEK_END; -		arg++;  	}  	seekpos = parse_num_arg(arg); @@ -64,8 +63,6 @@ int parse_offset_arg(const char *arg) {  	int got;  	got = parse_num_arg(arg); -	if(got < 0) -		die("negative arguments to -o (offset) are not supported.");  	return got;  } @@ -84,22 +81,24 @@ FILE *open_input(const char *file) {  	FILE *input;  	if(file[0] == '-' && file[1] == 0) { -		if(verbose) -			fprintf(stderr, "%s: reading from standard input.\n", self);  		if(freopen(NULL, "rb", stdin)) {  			input = stdin;  		} else { +			fprintf(stderr, "%s: ", self);  			perror("(standard input)");  			return NULL;  		} -	} else if(!(input = fopen(file, "rb"))) { -		perror(file); -		return NULL; +		if(verbose) +			fprintf(stderr, "%s: reading from standard input.\n", self); +	} else { +		if(!(input = fopen(file, "rb"))) { +			perror(file); +			return NULL; +		} +		if(verbose) +			fprintf(stderr, "%s: reading from file '%s'.\n", self, file);  	} -	if(verbose) -		fprintf(stderr, "%s: reading from file '%s'.\n", self, file); -  	return input;  } @@ -128,6 +127,44 @@ char *get_color(unsigned char c) {  	return outbuf;  } +void fake_seek(FILE *input) { +	char junkbuf[1024]; +	int pos = 0, chunksize; + +	if(verbose) +		fprintf(stderr, "%s: faking fseek() for stdin, skipping %d bytes.\n", self, seekpos); + +	while(pos < seekpos) { +		chunksize = seekpos - pos; +		if(chunksize > 1024) chunksize = 1024; +		if(fread(junkbuf, 1, chunksize, input) != chunksize) +			die("can't seek past end of input"); +		pos += chunksize; +	} +} + +void seek_input(FILE *input) { +	if(verbose) +		fprintf(stderr, "%s: seeking %d bytes (whence = %d) in input.\n", self, seekpos, seek_whence); +	if(input == stdin) { +		/* can't fseek() a stream, fake it */ +		if(seek_whence != SEEK_SET) +			die("can't seek from the end of standard input."); +		fake_seek(input); +	} else { +		if(fseek(input, seekpos, seek_whence) < 0) { +			fprintf(stderr, "%s: ", self); +			perror("fseek() failed"); +			exit(1); +		} +		if((filepos = ftell(input)) < 0) { +			fprintf(stderr, "%s: ", self); +			perror("ftell() failed"); +			exit(1); +		} +	} +} +  void dump_line(const unsigned char *buf, int len) {  	char hex[1024], asc[1024];  	int hpos = 0, apos = 0, count = len; @@ -165,13 +202,17 @@ void dump_line(const unsigned char *buf, int len) {  int a8xd(const char *file) {  	FILE *input; -	int c, len = 0; +	int c, len = 0, count = 0;  	unsigned char buf[16];  	if( !(input = open_input(file)) )  		return 1; +	if(seekpos) seek_input(input); +  	while( (c = fgetc(input)) != EOF ) { +		if(limit && (count == limit)) break; +		count++;  		if(len && (len % 16 == 0)) {  			dump_line(buf, len);  			len = 0; @@ -181,6 +222,10 @@ int a8xd(const char *file) {  	if(len) dump_line(buf, len); +	if(verbose) +		fprintf(stderr, "%s: dumped %d (0x%04x) bytes from '%s'.\n", self, count, count, file); + +	fclose(input);  	return 0;  } @@ -199,7 +244,7 @@ int main(int argc, char **argv) {  		exit(0);  	} -	while( (opt = getopt(argc, argv, "vimus:o:l")) != -1) { +	while( (opt = getopt(argc, argv, "vimus:o:l:")) != -1) {  		switch(opt) {  			case 'v': verbose = 1; break;  			case 'i': table = ics2utf; break; @@ -207,7 +252,7 @@ int main(int argc, char **argv) {  			case 'u': word_format = "%04X"; byte_format = "%02X"; break;  			case 's': parse_seek_arg(optarg); break;  			case 'o': disp_offset = parse_offset_arg(optarg); break; -			case 'l': disp_offset = parse_limit_arg(optarg); break; +			case 'l': limit = parse_limit_arg(optarg); break;  			default: print_help(); exit(1); break;  		}  	} @@ -47,7 +47,7 @@ Options marked with **\*** are not yet implemented.    Print XL/XE International Character Set conversions instead of ATASCII.  -l *len* -  **\*** Stop after dumping *len* bytes. *len* may be given in decimal or hex (with +  Stop after dumping *len* bytes. *len* may be given in decimal or hex (with    leading *0x* or *$*).  -m @@ -56,10 +56,12 @@ Options marked with **\*** are not yet implemented.  -o *offset*    Add *offset* to displayed file position. *offset* can be given in decimal -  or hex (with leading *0x* or *$*). +  or hex (with leading *0x* or *$*). Negative offsets are allowed, but they +  will be printed as very large positive numbers in the output (this matches +  **xxd**\'s behaviour).  -s *[-]seek* -  **\*** Start at *seek* bytes. Without *-*, this is an absolute offset. With *-*, +  Start at *seek* bytes. Without *-*, this is an absolute offset. With *-*,    it's relative to the end of the file. The *-* option won't work when    reading from standard input. *seek* may be given in decimal or hex    (with leading *0x* or *$*). @@ -68,7 +70,8 @@ Options marked with **\*** are not yet implemented.    Use uppercase letters for hex digits; the default is lowercase.  -v -  Verbose. Currently, this option is accepted, but it doesn't do anything yet. +  Verbose. Shows various debug messages that are probably only useful +  if you're hacking on **a8xd**.  **--**    End of options; the nex argument is the filename. Use this if you're @@ -100,4 +103,7 @@ missing are:  - **-b** (bits mode). +Another difference is that **a8xd** doesn't support files larger than +2GB. This won't be a problem for Atari 8-bit-related files! +  .. include:: manftr.rst | 
