diff options
-rw-r--r-- | main.c | 111 |
1 files changed, 83 insertions, 28 deletions
@@ -6,17 +6,18 @@ #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> +#include <endian.h> #include <errno.h> -#define ZXDUMP_STRIDE_LINE 16 -#define ZXDUMP_STRIDE_GROUP 2 -#define ZXDUMP_CHARSET_LEN 64 +#define ZX_DUMP_STRIDE_LINE 16 +#define ZX_DUMP_STRIDE_GROUP 2 +#define ZX_DUMP_CHARSET_LEN 64 -#define ZXDUMP_FLAGS_NONE 0 -#define ZXDUMP_FLAGS_BASIC (1 << 0) +#define ZX_DUMP_FLAGS_NONE 0 +#define ZX_DUMP_FLAGS_BASIC (1 << 0) #define ZX_CHAR_LOW(c) \ - (c <= ZXDUMP_CHARSET_LEN) + (c <= ZX_DUMP_CHARSET_LEN) #define ZX_CHAR_INVERSE_START 0x80 #define ZX_CHAR_INVERSE_END 0xbf @@ -30,6 +31,9 @@ #define ZX_CHAR_TOKEN_LOW(c) \ (c >= ZX_CHAR_TOKEN_LOW_START && c <= ZX_CHAR_TOKEN_LOW_END) +#define ZX_CHAR_NEWLINE(c) \ + (c == 0x76) + #define ZX_CHAR_TOKEN_HIGH_START 0xc0 #define ZX_CHAR_TOKEN_HIGH_END 0xff @@ -42,7 +46,7 @@ typedef struct _zx_basic_line { uint16_t num, len; } zx_basic_line; -static uint32_t zx_charset[ZXDUMP_CHARSET_LEN] = { +static uint32_t zx_charset[ZX_DUMP_CHARSET_LEN] = { 0x0020, 0x2598, 0x259d, 0x2580, 0x2596, 0x258c, 0x259e, 0x259b, 0x2592, '.', '.', '"', 0x00a3, '$', ':', '?', '(', ')', '>', '<', '=', '+', '-', '*', @@ -128,7 +132,7 @@ static ssize_t hexdump_line(off_t offset, void *buf, size_t len, int tty) { } for (i=0; i<len; i++) { - if (i > 0 && (i % ZXDUMP_STRIDE_GROUP) == 0) { + if (i > 0 && (i % ZX_DUMP_STRIDE_GROUP) == 0) { if (putchar(' ') < 0) { goto error_io; } @@ -171,7 +175,7 @@ error_io: return -1; } -static ssize_t hexdump_fd(int fd) { +static ssize_t zx_dump_hex(int fd) { void *buf; ssize_t total = 0; int tty = isatty(fileno(stdout)); @@ -195,9 +199,9 @@ static ssize_t hexdump_fd(int fd) { break; } - for (i=0; i<len; i+=ZXDUMP_STRIDE_LINE) { + for (i=0; i<len; i+=ZX_DUMP_STRIDE_LINE) { size_t left = len - i, - linesz = left < ZXDUMP_STRIDE_LINE? left: ZXDUMP_STRIDE_LINE; + linesz = left < ZX_DUMP_STRIDE_LINE? left: ZX_DUMP_STRIDE_LINE; if (hexdump_line(offset, buf, linesz, tty) < 0) { goto error_hexdump_line; @@ -226,17 +230,22 @@ static inline int zx_print(uint8_t c, int tty) { return zx_putchar(c, 0); } else if (ZX_CHAR_TOKEN_LOW(c)) { return fputs(zx_tokens_low[c - ZX_CHAR_TOKEN_LOW_START], stdout); + } else if (ZX_CHAR_NEWLINE(c)) { + return putchar('\n'); } else if (ZX_CHAR_INVERSE(c)) { - return zx_putchar(c, tty); + return zx_putchar(c - ZX_CHAR_INVERSE_START, tty); } else if (ZX_CHAR_TOKEN_HIGH(c)) { return fputs(zx_tokens[c - ZX_CHAR_TOKEN_HIGH_START], stdout); } + + return 0; } -static ssize_t basic_dump_fd(int fd) { +static ssize_t zx_dump_basic(int fd) { void *buf; - struct stat st; ssize_t total = 0; + int tty = isatty(fileno(stdout)); + struct stat st; if (fstat(fd, &st) < 0) { goto error_fstat; @@ -246,17 +255,52 @@ static ssize_t basic_dump_fd(int fd) { goto error_malloc; } + if (lseek(fd, ZX_BASIC_STATE_LEN, SEEK_CUR) < 0) { + goto error_io; + } + while (1) { - ssize_t len, i; + ssize_t readlen, len, i; + zx_basic_line line; + uint8_t last = 0; - if ((len = read(fd, buf, st.st_blksize)) < 0) { - goto error_read; - } else if (len == 0) { + if ((readlen = read(fd, &line, sizeof(line))) < 0) { + goto error_io; + } else if (readlen == 0) { break; } + if (printf("%d", (int)be16toh(line.num)) < 0) { + goto error_io; + } + + len = le16toh(line.len); + + if (read(fd, buf, len) < 0) { + goto error_io; + } + for (i=0; i<len; i++) { + uint8_t c = ((uint8_t *)buf)[i]; + + if (ZX_CHAR_TOKEN_LOW(c) || ZX_CHAR_TOKEN_HIGH(c) + || ZX_CHAR_TOKEN_LOW(last) || ZX_CHAR_TOKEN_HIGH(last)) { + if (putchar(' ') < 0) { + goto error_io; + } + } + + if (zx_print(c, tty) < 0) { + goto error_io; + } + + last = c; + } + if (!ZX_CHAR_NEWLINE(((uint8_t *)buf)[i-1])) { + if (putchar('\n') < 0) { + goto error_io; + } } } @@ -264,7 +308,7 @@ static ssize_t basic_dump_fd(int fd) { return total; -error_read: +error_io: free(buf); error_malloc: @@ -288,7 +332,7 @@ static void usage(const char *prog, char *message, ...) { int main(int argc, char **argv) { int fd, - flags = ZXDUMP_FLAGS_NONE, + flags = ZX_DUMP_FLAGS_NONE, argn; while (1) { @@ -300,7 +344,7 @@ int main(int argc, char **argv) { switch (c) { case 'b': - flags |= ZXDUMP_FLAGS_BASIC; + flags |= ZX_DUMP_FLAGS_BASIC; break; case '?': @@ -323,13 +367,24 @@ int main(int argc, char **argv) { usage(argv[0], "Too many arguments provided"); } - if (hexdump_fd(fd) < 0) { - fprintf(stderr, "%s: %s: %s\n", - argv[0], - (argn == 1)? argv[optind]: "(stdin)", - strerror(errno)); + if (flags & ZX_DUMP_FLAGS_BASIC) { + if (zx_dump_basic(fd) < 0) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], + (argn == 1)? argv[optind]: "(stdin)", + strerror(errno)); - goto error_hexdump_fd; + goto error_dump; + } + } else { + if (zx_dump_hex(fd) < 0) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], + (argn == 1)? argv[optind]: "(stdin)", + strerror(errno)); + + goto error_dump; + } } if (argn == 1) { @@ -338,7 +393,7 @@ int main(int argc, char **argv) { return 0; -error_hexdump_fd: +error_dump: if (argn == 1) { close(fd); } |