aboutsummaryrefslogtreecommitdiff
path: root/libbb/dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/dump.c')
-rw-r--r--libbb/dump.c70
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
16static 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 */
18static 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 */
21static 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
24typedef struct priv_dumper_t { 30typedef 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
48static const char dot_flags_width_chars[] ALIGN1 = ".#-+ 0123456789";
49
50static const char size_conv_str[] ALIGN1 =
51"\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG";
52
53static const char int_convs[] ALIGN1 = "diouxX";
54
42dumper_t* FAST_FUNC alloc_dumper(void) 55dumper_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
52static NOINLINE int bb_dump_size(FS *fs) 64static 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
521static void display(priv_dumper_t* dumper) 534static 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;