diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2020-10-20 18:54:36 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-10-20 18:57:02 +0200 |
commit | dac5b8314236338963877903cba3d7edfbfc9c58 (patch) | |
tree | 5e7ce92407b9079b4e49e728f28f8a7c6311999c /libbb | |
parent | 085f19cdffd653013b1483c08851ecc35cdd818e (diff) | |
download | busybox-w32-dac5b8314236338963877903cba3d7edfbfc9c58.tar.gz busybox-w32-dac5b8314236338963877903cba3d7edfbfc9c58.tar.bz2 busybox-w32-dac5b8314236338963877903cba3d7edfbfc9c58.zip |
xxd: fix printing of trailing spaces
function old new delta
bb_dump_dump 1497 1523 +26
xxd_main 459 466 +7
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 33/0) Total: 33 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/dump.c | 93 |
1 files changed, 71 insertions, 22 deletions
diff --git a/libbb/dump.c b/libbb/dump.c index 8029cca0e..920f003ef 100644 --- a/libbb/dump.c +++ b/libbb/dump.c | |||
@@ -13,13 +13,43 @@ | |||
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 */ | ||
29 | |||
30 | typedef struct PR { | ||
31 | struct PR *nextpr; /* next print unit */ | ||
32 | unsigned flags; /* flag values */ | ||
33 | int bcnt; /* byte count */ | ||
34 | char *cchar; /* conversion character */ | ||
35 | char *fmt; /* printf format */ | ||
36 | char *nospace; /* no whitespace version */ | ||
37 | } PR; | ||
38 | |||
39 | typedef struct FU { | ||
40 | struct FU *nextfu; /* next format unit */ | ||
41 | struct PR *nextpr; /* next print unit */ | ||
42 | unsigned flags; /* flag values */ | ||
43 | int reps; /* repetition count */ | ||
44 | int bcnt; /* byte count */ | ||
45 | char *fmt; /* format string */ | ||
46 | } FU; | ||
47 | |||
48 | typedef struct FS { /* format strings */ | ||
49 | struct FS *nextfs; /* linked list of format strings */ | ||
50 | struct FU *nextfu; /* linked list of format units */ | ||
51 | int bcnt; | ||
52 | } FS; | ||
23 | 53 | ||
24 | typedef struct priv_dumper_t { | 54 | typedef struct priv_dumper_t { |
25 | dumper_t pub; | 55 | dumper_t pub; |
@@ -39,6 +69,13 @@ typedef struct priv_dumper_t { | |||
39 | unsigned char *get__savp; | 69 | unsigned char *get__savp; |
40 | } priv_dumper_t; | 70 | } priv_dumper_t; |
41 | 71 | ||
72 | static const char dot_flags_width_chars[] ALIGN1 = ".#-+ 0123456789"; | ||
73 | |||
74 | static const char size_conv_str[] ALIGN1 = | ||
75 | "\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG"; | ||
76 | |||
77 | static const char int_convs[] ALIGN1 = "diouxX"; | ||
78 | |||
42 | dumper_t* FAST_FUNC alloc_dumper(void) | 79 | dumper_t* FAST_FUNC alloc_dumper(void) |
43 | { | 80 | { |
44 | priv_dumper_t *dumper = xzalloc(sizeof(*dumper)); | 81 | priv_dumper_t *dumper = xzalloc(sizeof(*dumper)); |
@@ -48,7 +85,6 @@ dumper_t* FAST_FUNC alloc_dumper(void) | |||
48 | return &dumper->pub; | 85 | return &dumper->pub; |
49 | } | 86 | } |
50 | 87 | ||
51 | |||
52 | static NOINLINE int bb_dump_size(FS *fs) | 88 | static NOINLINE int bb_dump_size(FS *fs) |
53 | { | 89 | { |
54 | FU *fu; | 90 | FU *fu; |
@@ -284,7 +320,9 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | |||
284 | * repeat it as necessary. | 320 | * repeat it as necessary. |
285 | * | 321 | * |
286 | * if rep count is greater than 1, no trailing whitespace | 322 | * if rep count is greater than 1, no trailing whitespace |
287 | * gets output from the last iteration of the format unit. | 323 | * gets output from the last iteration of the format unit: |
324 | * 2/1 "%02x " prints "XX XX", not "XX XX " | ||
325 | * 2/1 "%02x\n" prints "XX\nXX", not "XX\nXX\n" | ||
288 | */ | 326 | */ |
289 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { | 327 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { |
290 | if (!fu->nextfu | 328 | if (!fu->nextfu |
@@ -453,7 +491,7 @@ static void bpad(PR *pr) | |||
453 | for (p2 = ++p1; *p1 && strchr(" -0+#", *p1); ++p1) | 491 | for (p2 = ++p1; *p1 && strchr(" -0+#", *p1); ++p1) |
454 | if (pr->nospace) | 492 | if (pr->nospace) |
455 | pr->nospace--; | 493 | pr->nospace--; |
456 | while ((*p2++ = *p1++) != 0) | 494 | while ((*p2++ = *p1++) != '\0') |
457 | continue; | 495 | continue; |
458 | } | 496 | } |
459 | 497 | ||
@@ -520,36 +558,43 @@ static void conv_u(PR *pr, unsigned char *p) | |||
520 | 558 | ||
521 | static void display(priv_dumper_t* dumper) | 559 | static void display(priv_dumper_t* dumper) |
522 | { | 560 | { |
523 | FS *fs; | 561 | 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'; | 562 | unsigned char savech = '\0'; |
530 | 563 | ||
531 | while ((bp = get(dumper)) != NULL) { | 564 | while ((bp = get(dumper)) != NULL) { |
565 | FS *fs; | ||
566 | unsigned char *savebp; | ||
567 | off_t saveaddress; | ||
568 | |||
532 | fs = dumper->pub.fshead; | 569 | fs = dumper->pub.fshead; |
533 | savebp = bp; | 570 | savebp = bp; |
534 | saveaddress = dumper->address; | 571 | saveaddress = dumper->address; |
535 | for (; fs; fs = fs->nextfs, bp = savebp, dumper->address = saveaddress) { | 572 | for (; fs; fs = fs->nextfs, bp = savebp, dumper->address = saveaddress) { |
573 | FU *fu; | ||
536 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { | 574 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { |
575 | int cnt; | ||
537 | if (fu->flags & F_IGNORE) { | 576 | if (fu->flags & F_IGNORE) { |
538 | break; | 577 | break; |
539 | } | 578 | } |
540 | for (cnt = fu->reps; cnt; --cnt) { | 579 | for (cnt = fu->reps; cnt; --cnt) { |
580 | PR *pr; | ||
541 | for (pr = fu->nextpr; pr; dumper->address += pr->bcnt, | 581 | for (pr = fu->nextpr; pr; dumper->address += pr->bcnt, |
542 | bp += pr->bcnt, pr = pr->nextpr) { | 582 | bp += pr->bcnt, pr = pr->nextpr) { |
543 | if (dumper->eaddress && dumper->address >= dumper->eaddress | 583 | if (dumper->eaddress |
544 | && !(pr->flags & (F_TEXT | F_BPAD)) | 584 | && dumper->address >= dumper->eaddress |
545 | ) { | 585 | ) { |
546 | bpad(pr); | 586 | if (dumper->pub.eofstring) { |
587 | /* xxd support: requested to not pad incomplete blocks */ | ||
588 | fputs(dumper->pub.eofstring, stdout); | ||
589 | return; | ||
590 | } | ||
591 | if (!(pr->flags & (F_TEXT | F_BPAD))) | ||
592 | bpad(pr); | ||
547 | } | 593 | } |
548 | if (cnt == 1 && pr->nospace) { | 594 | if (cnt == 1 && pr->nospace) { |
549 | savech = *pr->nospace; | 595 | savech = *pr->nospace; |
550 | *pr->nospace = '\0'; | 596 | *pr->nospace = '\0'; |
551 | } | 597 | } |
552 | /* PRINT; */ | ||
553 | switch (pr->flags) { | 598 | switch (pr->flags) { |
554 | case F_ADDRESS: | 599 | case F_ADDRESS: |
555 | printf(pr->fmt, (unsigned) dumper->address); | 600 | printf(pr->fmt, (unsigned) dumper->address); |
@@ -638,7 +683,9 @@ static void display(priv_dumper_t* dumper) | |||
638 | } | 683 | } |
639 | } | 684 | } |
640 | } | 685 | } |
686 | |||
641 | if (dumper->endfu) { | 687 | if (dumper->endfu) { |
688 | PR *pr; | ||
642 | /* | 689 | /* |
643 | * if eaddress not set, error or file size was multiple | 690 | * if eaddress not set, error or file size was multiple |
644 | * of blocksize, and no partial block ever found. | 691 | * of blocksize, and no partial block ever found. |
@@ -695,8 +742,7 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
695 | { | 742 | { |
696 | const char *p; | 743 | const char *p; |
697 | FS *tfs; | 744 | FS *tfs; |
698 | FU *tfu, **nextfupp; | 745 | FU **nextfupp; |
699 | const char *savep; | ||
700 | 746 | ||
701 | /* start new linked list of format units */ | 747 | /* start new linked list of format units */ |
702 | tfs = xzalloc(sizeof(FS)); /*DBU:[dave@cray.com] start out NULL */ | 748 | tfs = xzalloc(sizeof(FS)); /*DBU:[dave@cray.com] start out NULL */ |
@@ -713,6 +759,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 */ | 759 | /* take the format string and break it up into format units */ |
714 | p = fmt; | 760 | p = fmt; |
715 | for (;;) { | 761 | for (;;) { |
762 | FU *tfu; | ||
763 | const char *savep; | ||
764 | |||
716 | p = skip_whitespace(p); | 765 | p = skip_whitespace(p); |
717 | if (*p == '\0') { | 766 | if (*p == '\0') { |
718 | break; | 767 | break; |