xxd: implement -i "C style output"
No binary (build failed)
—
(log yok)
| @@ -34,6 +34,7 @@ typedef struct dumper_t { | |
| smallint dump_vflag; /*enum dump_vflag_t*/ | |
| FS *fshead; | |
| const char *xxd_eofstring; | |
| + | off_t address; /* address/offset in stream */ |
| long long xxd_displayoff; | |
| } dumper_t; | |
| @@ -34,7 +34,6 @@ typedef struct priv_dumper_t { | |
| FU *endfu; | |
| off_t savaddress; /* saved address/offset in stream */ | |
| off_t eaddress; /* end address */ | |
| - | off_t address; /* address/offset in stream */ |
| int blocksize; | |
| smallint exitval; /* final exit value */ | |
| @@ -335,14 +334,14 @@ static void do_skip(priv_dumper_t *dumper, const char *fname) | |
| ) { | |
| /* If st_size is valid and pub.dump_skip >= st_size */ | |
| dumper->pub.dump_skip -= sbuf.st_size; | |
| - | dumper->address += sbuf.st_size; |
| + | dumper->pub.address += sbuf.st_size; |
| return; | |
| } | |
| if (fseeko(stdin, dumper->pub.dump_skip, SEEK_SET)) { | |
| bb_simple_perror_msg_and_die(fname); | |
| } | |
| - | dumper->address += dumper->pub.dump_skip; |
| - | dumper->savaddress = dumper->address; |
| + | dumper->pub.address += dumper->pub.dump_skip; |
| + | dumper->savaddress = dumper->pub.address; |
| dumper->pub.dump_skip = 0; | |
| } | |
| @@ -381,7 +380,7 @@ static unsigned char *get(priv_dumper_t *dumper) | |
| int blocksize = dumper->blocksize; | |
| if (!dumper->get__curp) { | |
| - | dumper->address = (off_t)0; /*DBU:[[email protected]] initialize,initialize..*/ |
| + | dumper->pub.address = (off_t)0; /*DBU:[[email protected]] initialize,initialize..*/ |
| dumper->get__curp = xmalloc(blocksize); | |
| dumper->get__savp = xzalloc(blocksize); /* need to be initialized */ | |
| } else { | |
| @@ -389,7 +388,7 @@ static unsigned char *get(priv_dumper_t *dumper) | |
| dumper->get__curp = dumper->get__savp; | |
| dumper->get__savp = tmp; | |
| dumper->savaddress += blocksize; | |
| - | dumper->address = dumper->savaddress; |
| + | dumper->pub.address = dumper->savaddress; |
| } | |
| need = blocksize; | |
| nread = 0; | |
| @@ -412,7 +411,7 @@ static unsigned char *get(priv_dumper_t *dumper) | |
| } | |
| } | |
| memset(dumper->get__curp + nread, 0, need); | |
| - | dumper->eaddress = dumper->address + nread; |
| + | dumper->eaddress = dumper->pub.address + nread; |
| return dumper->get__curp; | |
| } | |
| n = fread(dumper->get__curp + nread, sizeof(unsigned char), | |
| @@ -444,7 +443,7 @@ static unsigned char *get(priv_dumper_t *dumper) | |
| } | |
| dumper->pub.dump_vflag = DUP; | |
| dumper->savaddress += blocksize; | |
| - | dumper->address = dumper->savaddress; |
| + | dumper->pub.address = dumper->savaddress; |
| need = blocksize; | |
| nread = 0; | |
| } else { | |
| @@ -545,8 +544,8 @@ static void display(priv_dumper_t* dumper) | |
| fs = dumper->pub.fshead; | |
| savebp = bp; | |
| - | saveaddress = dumper->address; |
| - | for (; fs; fs = fs->nextfs, bp = savebp, dumper->address = saveaddress) { |
| + | saveaddress = dumper->pub.address; |
| + | for (; fs; fs = fs->nextfs, bp = savebp, dumper->pub.address = saveaddress) { |
| FU *fu; | |
| for (fu = fs->nextfu; fu; fu = fu->nextfu) { | |
| int cnt; | |
| @@ -555,10 +554,10 @@ static void display(priv_dumper_t* dumper) | |
| } | |
| for (cnt = fu->reps; cnt; --cnt) { | |
| PR *pr; | |
| - | for (pr = fu->nextpr; pr; dumper->address += pr->bcnt, |
| + | for (pr = fu->nextpr; pr; dumper->pub.address += pr->bcnt, |
| bp += pr->bcnt, pr = pr->nextpr) { | |
| if (dumper->eaddress | |
| - | && dumper->address >= dumper->eaddress |
| + | && dumper->pub.address >= dumper->eaddress |
| ) { | |
| if (dumper->pub.xxd_eofstring) { | |
| /* xxd support: requested to not pad incomplete blocks */ | |
| @@ -574,7 +573,7 @@ static void display(priv_dumper_t* dumper) | |
| } | |
| switch (pr->flags) { | |
| case F_ADDRESS: | |
| - | printf(pr->fmt, (unsigned long long) dumper->address + dumper->pub.xxd_displayoff); |
| + | printf(pr->fmt, (unsigned long long) dumper->pub.address + dumper->pub.xxd_displayoff); |
| break; | |
| case F_BPAD: | |
| printf(pr->fmt, ""); | |
| @@ -668,10 +667,10 @@ static void display(priv_dumper_t* dumper) | |
| * of blocksize, and no partial block ever found. | |
| */ | |
| if (!dumper->eaddress) { | |
| - | if (!dumper->address) { |
| + | if (!dumper->pub.address) { |
| return; | |
| } | |
| - | dumper->eaddress = dumper->address; |
| + | dumper->eaddress = dumper->pub.address; |
| } | |
| for (pr = dumper->endfu->nextpr; pr; pr = pr->nextpr) { | |
| switch (pr->flags) { | |
| @@ -41,12 +41,13 @@ | |
| // -u use upper case hex letters. | |
| //usage:#define xxd_trivial_usage | |
| - | //usage: "[-pr] [-g N] [-c N] [-n LEN] [-s OFS] [-o OFS] [FILE]" |
| + | //usage: "[-pri] [-g N] [-c N] [-n LEN] [-s OFS] [-o OFS] [FILE]" |
| //usage:#define xxd_full_usage "\n\n" | |
| //usage: "Hex dump FILE (or stdin)\n" | |
| //usage: "\n -g N Bytes per group" | |
| //usage: "\n -c N Bytes per line" | |
| //usage: "\n -p Show only hex bytes, assumes -c30" | |
| + | //usage: "\n -i C include file style" |
| // exactly the same help text lines in hexdump and xxd: | |
| //usage: "\n -l LENGTH Show only first LENGTH bytes" | |
| //usage: "\n -s OFFSET Skip OFFSET bytes" | |
| @@ -62,10 +63,11 @@ | |
| #define OPT_s (1 << 1) | |
| #define OPT_a (1 << 2) | |
| #define OPT_p (1 << 3) | |
| - | #define OPT_r (1 << 4) |
| - | #define OPT_g (1 << 5) |
| - | #define OPT_c (1 << 6) |
| - | #define OPT_o (1 << 7) |
| + | #define OPT_i (1 << 4) |
| + | #define OPT_r (1 << 5) |
| + | #define OPT_g (1 << 6) |
| + | #define OPT_c (1 << 7) |
| + | #define OPT_o (1 << 8) |
| static void reverse(unsigned opt, unsigned cols, const char *filename) | |
| { | |
| @@ -126,6 +128,15 @@ static void reverse(unsigned opt, unsigned cols, const char *filename) | |
| fflush_stdout_and_exit(EXIT_SUCCESS); | |
| } | |
| + | static void print_C_style(const char *p, const char *hdr) |
| + | { |
| + | printf(hdr, isdigit(p[0]) ? "__" : ""); |
| + | while (*p) { |
| + | bb_putchar(isalnum(*p) ? *p : '_'); |
| + | p++; |
| + | } |
| + | } |
| + | |
| int xxd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int xxd_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| @@ -135,10 +146,11 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |
| unsigned bytes = 2; | |
| unsigned cols = 0; | |
| unsigned opt; | |
| + | int r; |
| dumper = alloc_dumper(); | |
| - | opt = getopt32(argv, "^" "l:s:aprg:+c:+o:" "\0" "?1" /* 1 argument max */, |
| + | opt = getopt32(argv, "^" "l:s:apirg:+c:+o:" "\0" "?1" /* 1 argument max */, |
| &opt_l, &opt_s, &bytes, &cols, &opt_o | |
| ); | |
| argv += optind; | |
| @@ -173,8 +185,11 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |
| bytes = cols; /* -p ignores -gN */ | |
| } else { | |
| if (cols == 0) | |
| - | cols = 16; |
| - | bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: " |
| + | cols = (opt & OPT_i) ? 12 : 16; |
| + | if (opt & OPT_i) |
| + | bytes = 1; /* -i ignores -gN */ |
| + | else |
| + | bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: " |
| } | |
| if (opt & OPT_r) { | |
| @@ -186,7 +201,10 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |
| bb_dump_add(dumper, buf); | |
| } | |
| else if (bytes == 1) { | |
| - | sprintf(buf, "%u/1 \"%%02x \"", cols); // cols * "xx " |
| + | if (opt & OPT_i) |
| + | sprintf(buf, "%u/1 \" 0x%%02x,\"", cols); // cols * " 0xxx," |
| + | else |
| + | sprintf(buf, "%u/1 \"%%02x \"", cols); // cols * "xx " |
| bb_dump_add(dumper, buf); | |
| } | |
| else { | |
| @@ -210,7 +228,7 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |
| free(bigbuf); | |
| } | |
| - | if (!(opt & OPT_p)) { |
| + | if (!(opt & (OPT_p|OPT_i))) { |
| sprintf(buf, "\" \"%u/1 \"%%_p\"\"\n\"", cols); // " ASCII\n" | |
| bb_dump_add(dumper, buf); | |
| } else { | |
| @@ -218,5 +236,14 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |
| dumper->xxd_eofstring = "\n"; | |
| } | |
| - | return bb_dump_dump(dumper, argv); |
| + | if ((opt & OPT_i) && argv[0]) { |
| + | print_C_style(argv[0], "unsigned char %s"); |
| + | printf("[] = {\n"); |
| + | } |
| + | r = bb_dump_dump(dumper, argv); |
| + | if (r == 0 && (opt & OPT_i) && argv[0]) { |
| + | print_C_style(argv[0], "};\nunsigned int %s"); |
| + | printf("_len = %"OFF_FMT"u;\n", dumper->address); |
| + | } |
| + | return r; |
| } | |