#include #include #include void dump12_usage() { log_info("Usage: dump12 [-b|-t] [source] [dest]"); } i32 dump12_main(i32 argc, char *argv[]) { bool to_bin = true; char *inpath = nullptr; char *outpath = nullptr; for (i32 i = 1; i < argc; ++i) { char *arg = argv[i]; if (arg[0] == '-' && arg[1] == 'b' && arg[2] == '\0') { to_bin = true; } else if (arg[0] == '-' && arg[1] == 't' && arg[2] == '\0') { to_bin = false; } else if (arg[0] == '-' && arg[1] == 'h' && arg[2] == '\0') { dump12_usage(); return 0; } else if (inpath == nullptr) { inpath = arg; } else if (outpath == nullptr) { outpath = arg; } else { log_err("Too many arguments"); return 1; } } int infd = (inpath == nullptr) ? 0 : open(inpath, O_RDONLY); if (infd < 0) { log_err_errno("Couldn't open `%s`", inpath); return 1; } int outfd = (inpath == nullptr) ? 1 : open(outpath, O_CREAT | O_TRUNC | O_WRONLY); if (outfd < 0) { log_err_errno("Couldn't open `%s`", outpath); return 1; } if (to_bin) { u12 byte12 = 0; u8 count = 0; u8 c; while (read(infd, &c, 1) > 0) { switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': byte12 = (byte12 << 3) | (c - '0'); count++; break; default: } if (count == 4) { u8 bs[2] = {byte12 & 0xFF, (byte12 >> 8) & 0xFF}; write(outfd, bs, 2); count = 0; byte12 = 0; } } } else { usz bytecount = 0; u8 readbuf[2]; while (read(infd, readbuf, 2) > 0) { u12 byte12 = readbuf[0] | (readbuf[1] << 8); bytecount ++; u8 outbuf[5] = { ((byte12 >> 9) & 7) + '0', ((byte12 >> 6) & 7) + '0', ((byte12 >> 3) & 7) + '0', (byte12 & 7) + '0', (bytecount % 8) ? ' ': '\n', }; write(outfd, outbuf, 5); } } close(infd); close(outfd); return 0; }