diff options
Diffstat (limited to 'libbb/dump.c')
-rw-r--r-- | libbb/dump.c | 70 |
1 files changed, 47 insertions, 23 deletions
diff --git a/libbb/dump.c b/libbb/dump.c index 8029cca0e..1ba1132b3 100644 --- a/libbb/dump.c +++ b/libbb/dump.c | |||
@@ -13,13 +13,19 @@ | |||
13 | #include "libbb.h" | 13 | #include "libbb.h" |
14 | #include "dump.h" | 14 | #include "dump.h" |
15 | 15 | ||
16 | static const char dot_flags_width_chars[] ALIGN1 = ".#-+ 0123456789"; | 16 | #define F_IGNORE 0x01 /* %_A */ |
17 | 17 | #define F_SETREP 0x02 /* rep count set, not default */ | |
18 | static const char size_conv_str[] ALIGN1 = | 18 | #define F_ADDRESS 0x001 /* print offset */ |
19 | "\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG"; | 19 | #define F_BPAD 0x002 /* blank pad */ |
20 | 20 | #define F_C 0x004 /* %_c */ | |
21 | static const char int_convs[] ALIGN1 = "diouxX"; | 21 | #define F_CHAR 0x008 /* %c */ |
22 | 22 | #define F_DBL 0x010 /* %[EefGf] */ | |
23 | #define F_INT 0x020 /* %[di] */ | ||
24 | #define F_P 0x040 /* %_p */ | ||
25 | #define F_STR 0x080 /* %s */ | ||
26 | #define F_U 0x100 /* %_u */ | ||
27 | #define F_UINT 0x200 /* %[ouXx] */ | ||
28 | #define F_TEXT 0x400 /* no conversions */ | ||
23 | 29 | ||
24 | typedef struct priv_dumper_t { | 30 | typedef struct priv_dumper_t { |
25 | dumper_t pub; | 31 | dumper_t pub; |
@@ -39,6 +45,13 @@ typedef struct priv_dumper_t { | |||
39 | unsigned char *get__savp; | 45 | unsigned char *get__savp; |
40 | } priv_dumper_t; | 46 | } priv_dumper_t; |
41 | 47 | ||
48 | static const char dot_flags_width_chars[] ALIGN1 = ".#-+ 0123456789"; | ||
49 | |||
50 | static const char size_conv_str[] ALIGN1 = | ||
51 | "\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG"; | ||
52 | |||
53 | static const char int_convs[] ALIGN1 = "diouxX"; | ||
54 | |||
42 | dumper_t* FAST_FUNC alloc_dumper(void) | 55 | dumper_t* FAST_FUNC alloc_dumper(void) |
43 | { | 56 | { |
44 | priv_dumper_t *dumper = xzalloc(sizeof(*dumper)); | 57 | priv_dumper_t *dumper = xzalloc(sizeof(*dumper)); |
@@ -48,7 +61,6 @@ dumper_t* FAST_FUNC alloc_dumper(void) | |||
48 | return &dumper->pub; | 61 | return &dumper->pub; |
49 | } | 62 | } |
50 | 63 | ||
51 | |||
52 | static NOINLINE int bb_dump_size(FS *fs) | 64 | static NOINLINE int bb_dump_size(FS *fs) |
53 | { | 65 | { |
54 | FU *fu; | 66 | FU *fu; |
@@ -284,7 +296,9 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | |||
284 | * repeat it as necessary. | 296 | * repeat it as necessary. |
285 | * | 297 | * |
286 | * if rep count is greater than 1, no trailing whitespace | 298 | * if rep count is greater than 1, no trailing whitespace |
287 | * gets output from the last iteration of the format unit. | 299 | * gets output from the last iteration of the format unit: |
300 | * 2/1 "%02x " prints "XX XX", not "XX XX " | ||
301 | * 2/1 "%02x\n" prints "XX\nXX", not "XX\nXX\n" | ||
288 | */ | 302 | */ |
289 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { | 303 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { |
290 | if (!fu->nextfu | 304 | if (!fu->nextfu |
@@ -394,7 +408,6 @@ static unsigned char *get(priv_dumper_t *dumper) | |||
394 | if (dumper->pub.dump_vflag != DUP) { | 408 | if (dumper->pub.dump_vflag != DUP) { |
395 | puts("*"); | 409 | puts("*"); |
396 | } | 410 | } |
397 | return NULL; | ||
398 | } | 411 | } |
399 | memset(dumper->get__curp + nread, 0, need); | 412 | memset(dumper->get__curp + nread, 0, need); |
400 | dumper->eaddress = dumper->address + nread; | 413 | dumper->eaddress = dumper->address + nread; |
@@ -453,7 +466,7 @@ static void bpad(PR *pr) | |||
453 | for (p2 = ++p1; *p1 && strchr(" -0+#", *p1); ++p1) | 466 | for (p2 = ++p1; *p1 && strchr(" -0+#", *p1); ++p1) |
454 | if (pr->nospace) | 467 | if (pr->nospace) |
455 | pr->nospace--; | 468 | pr->nospace--; |
456 | while ((*p2++ = *p1++) != 0) | 469 | while ((*p2++ = *p1++) != '\0') |
457 | continue; | 470 | continue; |
458 | } | 471 | } |
459 | 472 | ||
@@ -520,36 +533,43 @@ static void conv_u(PR *pr, unsigned char *p) | |||
520 | 533 | ||
521 | static void display(priv_dumper_t* dumper) | 534 | static void display(priv_dumper_t* dumper) |
522 | { | 535 | { |
523 | FS *fs; | 536 | unsigned char *bp; |
524 | FU *fu; | ||
525 | PR *pr; | ||
526 | int cnt; | ||
527 | unsigned char *bp, *savebp; | ||
528 | off_t saveaddress; | ||
529 | unsigned char savech = '\0'; | 537 | unsigned char savech = '\0'; |
530 | 538 | ||
531 | while ((bp = get(dumper)) != NULL) { | 539 | while ((bp = get(dumper)) != NULL) { |
540 | FS *fs; | ||
541 | unsigned char *savebp; | ||
542 | off_t saveaddress; | ||
543 | |||
532 | fs = dumper->pub.fshead; | 544 | fs = dumper->pub.fshead; |
533 | savebp = bp; | 545 | savebp = bp; |
534 | saveaddress = dumper->address; | 546 | saveaddress = dumper->address; |
535 | for (; fs; fs = fs->nextfs, bp = savebp, dumper->address = saveaddress) { | 547 | for (; fs; fs = fs->nextfs, bp = savebp, dumper->address = saveaddress) { |
548 | FU *fu; | ||
536 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { | 549 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { |
550 | int cnt; | ||
537 | if (fu->flags & F_IGNORE) { | 551 | if (fu->flags & F_IGNORE) { |
538 | break; | 552 | break; |
539 | } | 553 | } |
540 | for (cnt = fu->reps; cnt; --cnt) { | 554 | for (cnt = fu->reps; cnt; --cnt) { |
555 | PR *pr; | ||
541 | for (pr = fu->nextpr; pr; dumper->address += pr->bcnt, | 556 | for (pr = fu->nextpr; pr; dumper->address += pr->bcnt, |
542 | bp += pr->bcnt, pr = pr->nextpr) { | 557 | bp += pr->bcnt, pr = pr->nextpr) { |
543 | if (dumper->eaddress && dumper->address >= dumper->eaddress | 558 | if (dumper->eaddress |
544 | && !(pr->flags & (F_TEXT | F_BPAD)) | 559 | && dumper->address >= dumper->eaddress |
545 | ) { | 560 | ) { |
546 | bpad(pr); | 561 | if (dumper->pub.eofstring) { |
562 | /* xxd support: requested to not pad incomplete blocks */ | ||
563 | fputs(dumper->pub.eofstring, stdout); | ||
564 | return; | ||
565 | } | ||
566 | if (!(pr->flags & (F_TEXT | F_BPAD))) | ||
567 | bpad(pr); | ||
547 | } | 568 | } |
548 | if (cnt == 1 && pr->nospace) { | 569 | if (cnt == 1 && pr->nospace) { |
549 | savech = *pr->nospace; | 570 | savech = *pr->nospace; |
550 | *pr->nospace = '\0'; | 571 | *pr->nospace = '\0'; |
551 | } | 572 | } |
552 | /* PRINT; */ | ||
553 | switch (pr->flags) { | 573 | switch (pr->flags) { |
554 | case F_ADDRESS: | 574 | case F_ADDRESS: |
555 | printf(pr->fmt, (unsigned) dumper->address); | 575 | printf(pr->fmt, (unsigned) dumper->address); |
@@ -638,7 +658,9 @@ static void display(priv_dumper_t* dumper) | |||
638 | } | 658 | } |
639 | } | 659 | } |
640 | } | 660 | } |
661 | |||
641 | if (dumper->endfu) { | 662 | if (dumper->endfu) { |
663 | PR *pr; | ||
642 | /* | 664 | /* |
643 | * if eaddress not set, error or file size was multiple | 665 | * if eaddress not set, error or file size was multiple |
644 | * of blocksize, and no partial block ever found. | 666 | * of blocksize, and no partial block ever found. |
@@ -695,8 +717,7 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
695 | { | 717 | { |
696 | const char *p; | 718 | const char *p; |
697 | FS *tfs; | 719 | FS *tfs; |
698 | FU *tfu, **nextfupp; | 720 | FU **nextfupp; |
699 | const char *savep; | ||
700 | 721 | ||
701 | /* start new linked list of format units */ | 722 | /* start new linked list of format units */ |
702 | tfs = xzalloc(sizeof(FS)); /*DBU:[dave@cray.com] start out NULL */ | 723 | tfs = xzalloc(sizeof(FS)); /*DBU:[dave@cray.com] start out NULL */ |
@@ -713,6 +734,9 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
713 | /* take the format string and break it up into format units */ | 734 | /* take the format string and break it up into format units */ |
714 | p = fmt; | 735 | p = fmt; |
715 | for (;;) { | 736 | for (;;) { |
737 | FU *tfu; | ||
738 | const char *savep; | ||
739 | |||
716 | p = skip_whitespace(p); | 740 | p = skip_whitespace(p); |
717 | if (*p == '\0') { | 741 | if (*p == '\0') { |
718 | break; | 742 | break; |