aboutsummaryrefslogtreecommitdiff
path: root/a8xd.c
diff options
context:
space:
mode:
Diffstat (limited to 'a8xd.c')
-rw-r--r--a8xd.c73
1 files changed, 59 insertions, 14 deletions
diff --git a/a8xd.c b/a8xd.c
index c322624..f051c4b 100644
--- a/a8xd.c
+++ b/a8xd.c
@@ -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;
}
}