xxd: implement -o DISPLAYOFFSET
No binary (build failed)
—
(log yok)
| @@ -32,8 +32,9 @@ typedef struct dumper_t { | |
| off_t dump_skip; /* bytes to skip */ | |
| int dump_length; /* max bytes to read */ | |
| smallint dump_vflag; /*enum dump_vflag_t*/ | |
| - | const char *eofstring; |
| FS *fshead; | |
| + | const char *xxd_eofstring; |
| + | long long xxd_displayoff; |
| } dumper_t; | |
| dumper_t* alloc_dumper(void) FAST_FUNC; | |
| @@ -228,7 +228,8 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | |
| if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) { | |
| goto DO_BAD_CONV_CHAR; | |
| } | |
| - | *p1 = p1[2]; |
| + | *p1++ = 'l'; |
| + | *p1++ = 'l'; |
| break; | |
| case 'c': /* %_c: chars, \ooo, \n \r \t etc */ | |
| pr->flags = F_C; | |
| @@ -558,9 +559,9 @@ static void display(priv_dumper_t* dumper) | |
| if (dumper->eaddress | |
| && dumper->address >= dumper->eaddress | |
| ) { | |
| - | if (dumper->pub.eofstring) { |
| + | if (dumper->pub.xxd_eofstring) { |
| /* xxd support: requested to not pad incomplete blocks */ | |
| - | fputs_stdout(dumper->pub.eofstring); |
| + | fputs_stdout(dumper->pub.xxd_eofstring); |
| return; | |
| } | |
| if (!(pr->flags & (F_TEXT | F_BPAD))) | |
| @@ -572,7 +573,7 @@ static void display(priv_dumper_t* dumper) | |
| } | |
| switch (pr->flags) { | |
| case F_ADDRESS: | |
| - | printf(pr->fmt, (unsigned) dumper->address); |
| + | printf(pr->fmt, (unsigned long long) dumper->address + dumper->pub.xxd_displayoff); |
| break; | |
| case F_BPAD: | |
| printf(pr->fmt, ""); | |
| @@ -674,7 +675,7 @@ static void display(priv_dumper_t* dumper) | |
| for (pr = dumper->endfu->nextpr; pr; pr = pr->nextpr) { | |
| switch (pr->flags) { | |
| case F_ADDRESS: | |
| - | printf(pr->fmt, (unsigned) dumper->eaddress); |
| + | printf(pr->fmt, (unsigned long long) dumper->eaddress + dumper->pub.xxd_displayoff); |
| break; | |
| case F_TEXT: | |
| printf(pr->fmt); | |
| @@ -41,7 +41,7 @@ | |
| // -u use upper case hex letters. | |
| //usage:#define xxd_trivial_usage | |
| - | //usage: "[-pr] [-g N] [-c N] [-n LEN] [-s OFS] [FILE]" |
| + | //usage: "[-pr] [-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" | |
| @@ -50,6 +50,7 @@ | |
| // 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" | |
| + | //usage: "\n -o OFFSET Add OFFSET to displayed offset" |
| //usage: "\n -r Reverse (with -p, assumes no offsets in input)" | |
| #include "libbb.h" | |
| @@ -62,6 +63,9 @@ | |
| #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) |
| static void reverse(unsigned opt, unsigned cols, const char *filename) | |
| { | |
| @@ -127,15 +131,15 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| char buf[80]; | |
| dumper_t *dumper; | |
| - | char *opt_l, *opt_s; |
| + | char *opt_l, *opt_s, *opt_o; |
| unsigned bytes = 2; | |
| unsigned cols = 0; | |
| unsigned opt; | |
| dumper = alloc_dumper(); | |
| - | opt = getopt32(argv, "^" "l:s:aprg:+c:+" "\0" "?1" /* 1 argument max */, |
| - | &opt_l, &opt_s, &bytes, &cols |
| + | opt = getopt32(argv, "^" "l:s:aprg:+c:+o:" "\0" "?1" /* 1 argument max */, |
| + | &opt_l, &opt_s, &bytes, &cols, &opt_o |
| ); | |
| argv += optind; | |
| @@ -158,6 +162,11 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |
| //BUGGY for /proc/version (unseekable?) | |
| } | |
| + | if (opt & OPT_o) { |
| + | /* -o accepts negative numbers too */ |
| + | dumper->xxd_displayoff = xstrtoll(opt_o, /*base:*/ 0); |
| + | } |
| + | |
| if (opt & OPT_p) { | |
| if (cols == 0) | |
| cols = 30; | |
| @@ -206,7 +215,7 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |
| bb_dump_add(dumper, buf); | |
| } else { | |
| bb_dump_add(dumper, "\"\n\""); | |
| - | dumper->eofstring = "\n"; |
| + | dumper->xxd_eofstring = "\n"; |
| } | |
| return bb_dump_dump(dumper, argv); | |