xxd: implement -o DISPLAYOFFSET
function old new delta xxd_main 680 710 +30 xstrtoll - 30 +30 bb_dump_dump 1511 1531 +20 rewrite 941 951 +10 packed_usage 33629 33639 +10 .rodata 103250 103252 +2 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 5/0 up/down: 102/0) Total: 102 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
a0f8076d19
commit
4d16161797
@ -32,8 +32,9 @@ typedef struct dumper_t {
|
|||||||
off_t dump_skip; /* bytes to skip */
|
off_t dump_skip; /* bytes to skip */
|
||||||
int dump_length; /* max bytes to read */
|
int dump_length; /* max bytes to read */
|
||||||
smallint dump_vflag; /*enum dump_vflag_t*/
|
smallint dump_vflag; /*enum dump_vflag_t*/
|
||||||
const char *eofstring;
|
|
||||||
FS *fshead;
|
FS *fshead;
|
||||||
|
const char *xxd_eofstring;
|
||||||
|
long long xxd_displayoff;
|
||||||
} dumper_t;
|
} dumper_t;
|
||||||
|
|
||||||
dumper_t* alloc_dumper(void) FAST_FUNC;
|
dumper_t* alloc_dumper(void) FAST_FUNC;
|
||||||
|
11
libbb/dump.c
11
libbb/dump.c
@ -228,7 +228,8 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs)
|
|||||||
if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) {
|
if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) {
|
||||||
goto DO_BAD_CONV_CHAR;
|
goto DO_BAD_CONV_CHAR;
|
||||||
}
|
}
|
||||||
*p1 = p1[2];
|
*p1++ = 'l';
|
||||||
|
*p1++ = 'l';
|
||||||
break;
|
break;
|
||||||
case 'c': /* %_c: chars, \ooo, \n \r \t etc */
|
case 'c': /* %_c: chars, \ooo, \n \r \t etc */
|
||||||
pr->flags = F_C;
|
pr->flags = F_C;
|
||||||
@ -558,9 +559,9 @@ static void display(priv_dumper_t* dumper)
|
|||||||
if (dumper->eaddress
|
if (dumper->eaddress
|
||||||
&& dumper->address >= dumper->eaddress
|
&& dumper->address >= dumper->eaddress
|
||||||
) {
|
) {
|
||||||
if (dumper->pub.eofstring) {
|
if (dumper->pub.xxd_eofstring) {
|
||||||
/* xxd support: requested to not pad incomplete blocks */
|
/* xxd support: requested to not pad incomplete blocks */
|
||||||
fputs_stdout(dumper->pub.eofstring);
|
fputs_stdout(dumper->pub.xxd_eofstring);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(pr->flags & (F_TEXT | F_BPAD)))
|
if (!(pr->flags & (F_TEXT | F_BPAD)))
|
||||||
@ -572,7 +573,7 @@ static void display(priv_dumper_t* dumper)
|
|||||||
}
|
}
|
||||||
switch (pr->flags) {
|
switch (pr->flags) {
|
||||||
case F_ADDRESS:
|
case F_ADDRESS:
|
||||||
printf(pr->fmt, (unsigned) dumper->address);
|
printf(pr->fmt, (unsigned long long) dumper->address + dumper->pub.xxd_displayoff);
|
||||||
break;
|
break;
|
||||||
case F_BPAD:
|
case F_BPAD:
|
||||||
printf(pr->fmt, "");
|
printf(pr->fmt, "");
|
||||||
@ -674,7 +675,7 @@ static void display(priv_dumper_t* dumper)
|
|||||||
for (pr = dumper->endfu->nextpr; pr; pr = pr->nextpr) {
|
for (pr = dumper->endfu->nextpr; pr; pr = pr->nextpr) {
|
||||||
switch (pr->flags) {
|
switch (pr->flags) {
|
||||||
case F_ADDRESS:
|
case F_ADDRESS:
|
||||||
printf(pr->fmt, (unsigned) dumper->eaddress);
|
printf(pr->fmt, (unsigned long long) dumper->eaddress + dumper->pub.xxd_displayoff);
|
||||||
break;
|
break;
|
||||||
case F_TEXT:
|
case F_TEXT:
|
||||||
printf(pr->fmt);
|
printf(pr->fmt);
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
// -u use upper case hex letters.
|
// -u use upper case hex letters.
|
||||||
|
|
||||||
//usage:#define xxd_trivial_usage
|
//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:#define xxd_full_usage "\n\n"
|
||||||
//usage: "Hex dump FILE (or stdin)\n"
|
//usage: "Hex dump FILE (or stdin)\n"
|
||||||
//usage: "\n -g N Bytes per group"
|
//usage: "\n -g N Bytes per group"
|
||||||
@ -50,6 +50,7 @@
|
|||||||
// exactly the same help text lines in hexdump and xxd:
|
// exactly the same help text lines in hexdump and xxd:
|
||||||
//usage: "\n -l LENGTH Show only first LENGTH bytes"
|
//usage: "\n -l LENGTH Show only first LENGTH bytes"
|
||||||
//usage: "\n -s OFFSET Skip OFFSET 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)"
|
//usage: "\n -r Reverse (with -p, assumes no offsets in input)"
|
||||||
|
|
||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
@ -62,6 +63,9 @@
|
|||||||
#define OPT_a (1 << 2)
|
#define OPT_a (1 << 2)
|
||||||
#define OPT_p (1 << 3)
|
#define OPT_p (1 << 3)
|
||||||
#define OPT_r (1 << 4)
|
#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)
|
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];
|
char buf[80];
|
||||||
dumper_t *dumper;
|
dumper_t *dumper;
|
||||||
char *opt_l, *opt_s;
|
char *opt_l, *opt_s, *opt_o;
|
||||||
unsigned bytes = 2;
|
unsigned bytes = 2;
|
||||||
unsigned cols = 0;
|
unsigned cols = 0;
|
||||||
unsigned opt;
|
unsigned opt;
|
||||||
|
|
||||||
dumper = alloc_dumper();
|
dumper = alloc_dumper();
|
||||||
|
|
||||||
opt = getopt32(argv, "^" "l:s:aprg:+c:+" "\0" "?1" /* 1 argument max */,
|
opt = getopt32(argv, "^" "l:s:aprg:+c:+o:" "\0" "?1" /* 1 argument max */,
|
||||||
&opt_l, &opt_s, &bytes, &cols
|
&opt_l, &opt_s, &bytes, &cols, &opt_o
|
||||||
);
|
);
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
@ -158,6 +162,11 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
//BUGGY for /proc/version (unseekable?)
|
//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 (opt & OPT_p) {
|
||||||
if (cols == 0)
|
if (cols == 0)
|
||||||
cols = 30;
|
cols = 30;
|
||||||
@ -206,7 +215,7 @@ int xxd_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
bb_dump_add(dumper, buf);
|
bb_dump_add(dumper, buf);
|
||||||
} else {
|
} else {
|
||||||
bb_dump_add(dumper, "\"\n\"");
|
bb_dump_add(dumper, "\"\n\"");
|
||||||
dumper->eofstring = "\n";
|
dumper->xxd_eofstring = "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return bb_dump_dump(dumper, argv);
|
return bb_dump_dump(dumper, argv);
|
||||||
|
Loading…
Reference in New Issue
Block a user