// // unhex -- Converts hex dump file back into original binary file. // // 30-Mar-2009 tvb www.LeapSecond.com/tools // #include #include #include #define WIDE 16 int decode_16 (char *line, FILE *f); // Global variables. char *Path; void main (int argc, char *argv[]) { char line[1000], dup[1000]; long n, count; FILE *out; long line_addr, next_addr; if (argc < 2) { fprintf(stderr, "Usage: unhex output next_addr) { n = decode_16(dup, out); if (n != WIDE) { fprintf(stderr, "%s: not hex file (dup error)\n", Path); exit(1); } count += n; next_addr += WIDE; } if (line_addr == next_addr) { n = decode_16(line, out); count += n; next_addr += WIDE; if (n < WIDE) { break; } } if (line[8] == '*') { strcpy(dup, line); } } fclose(out); fprintf(stderr, "unhex: wrote %ld bytes to %s\n", count, Path); } #define RANGE(lo,x,hi) ( (x) >= (lo) && (x) <= (hi) ) int ishex (char c) { return RANGE('0', c, '9') || RANGE('a', c, 'f') || RANGE('A', c, 'F'); } int hex2dec (char c) { return RANGE('0', c, '9') ? (c - '0') : RANGE('a', c, 'f') ? (c - 'a' + 10) : RANGE('A', c, 'F') ? (c - 'A' + 10) : -1; } int decode_16 (char *line, FILE *f) { int i, n; char byte, *p; p = &line[8]; if (*p != ':' && *p != '*') { fprintf(stderr, "%s: non hex address: %s\n", Path, line); exit(1); } p += 1; if (*p != ' ') { fprintf(stderr, "%s: non hex format: %s\n", Path, line); exit(1); } p += 1; n = 0; for (i = 0; i < WIDE; i += 1, p += 3) { if (strncmp(p, "end", 3) == 0) { return n; } if (strncmp(p, "-- ", 3) == 0) { return n; } #if 0 if (strncmp(p, " ", 2) == 0) { return n; } #endif if (!ishex(p[0]) || !ishex(p[1]) || p[2] != ' ') { fprintf(stderr, "%s: malformed hex digits: %s\n", Path, line); exit(1); } byte = hex2dec(p[0]) * 16 + hex2dec(p[1]); fwrite(&byte, 1, 1, f); n += 1; } return n; }