Mercurial > hg > dmlib
comparison tools/fanalyze.c @ 2229:72e15cc14927
Make the offset mode (-o) also support lists of offsets.
Also improve the readability of the output.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 14 Jun 2019 18:39:59 +0300 |
parents | 02d17784fdef |
children | ba639902d57c |
comparison
equal
deleted
inserted
replaced
2228:02d17784fdef | 2229:72e15cc14927 |
---|---|
98 | 98 |
99 | 99 |
100 typedef struct | 100 typedef struct |
101 { | 101 { |
102 char *name; | 102 char *name; |
103 char *fmtPrefix; | |
103 char *fmt; | 104 char *fmt; |
104 } DMGrepDisp; | 105 } DMGrepDisp; |
105 | 106 |
106 | 107 |
107 static const DMGrepDisp dmGrepDisp[DMGS_last] = | 108 static const DMGrepDisp dmGrepDisp[DMGS_last] = |
108 { | 109 { |
109 { "hex", "x" }, | 110 { "hex", "0", "x" }, |
110 { "dec", "d" }, | 111 { "dec", "" , "d" }, |
111 }; | 112 }; |
112 | 113 |
113 enum | 114 enum |
114 { | 115 { |
115 FA_ANALYZE, | 116 FA_ANALYZE, |
133 static const DMOptArg optList[] = | 134 static const DMOptArg optList[] = |
134 { | 135 { |
135 { 0, '?', "help", "Show this help", OPT_NONE }, | 136 { 0, '?', "help", "Show this help", OPT_NONE }, |
136 { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, | 137 { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, |
137 { 2, 'g', "grep", "Binary grep <val>[,<val2>...][:<le|be>[8|16|32]]", OPT_ARGREQ }, | 138 { 2, 'g', "grep", "Binary grep <val>[,<val2>...][:<le|be>[8|16|32]]", OPT_ARGREQ }, |
138 { 3, 'o', "offset", "Show data in offset <offset>:<le|be>[8|16|32][d|x]]", OPT_ARGREQ }, | 139 { 3, 'o', "offset", "Show data in offset <offs>[,<offs2>...][:<le|be>[8|16|32][d|x]]", OPT_ARGREQ }, |
139 }; | 140 }; |
140 | 141 |
141 static const int optListN = sizeof(optList) / sizeof(optList[0]); | 142 static const int optListN = sizeof(optList) / sizeof(optList[0]); |
142 | 143 |
143 | 144 |
195 } | 196 } |
196 | 197 |
197 | 198 |
198 void dmPrintGrepValueList(const DMGrepValue *node, const BOOL match, DMSourceFile *file, const size_t offs) | 199 void dmPrintGrepValueList(const DMGrepValue *node, const BOOL match, DMSourceFile *file, const size_t offs) |
199 { | 200 { |
200 char vfmt[16]; | 201 char mfmt[16]; |
201 | 202 |
202 snprintf(vfmt, sizeof(vfmt), "%%%s%d%s%%s", | 203 snprintf(mfmt, sizeof(mfmt), "%%%s%d%s%%s", |
203 node->disp == DMGS_HEX ? "0" : "", | 204 dmGrepDisp[node->disp].fmtPrefix, |
204 dmGrepTypes[node->type].bsize * 2, | 205 dmGrepTypes[node->type].bsize * 2, |
205 node->disp == DMGS_HEX ? "x" : "d"); | 206 dmGrepDisp[node->disp].fmt); |
206 | 207 |
207 for (int n = 0; n < node->nvalues; n++) | 208 for (int n = 0; n < node->nvalues; n++) |
208 { | 209 { |
209 const char *veol = (n < node->nvalues - 1) ? " " : "\n"; | 210 const char *veol = (n < node->nvalues - 1) ? " " : "\n"; |
210 | 211 |
211 if (match) | 212 if (match) |
212 { | 213 { |
213 Uint32 mval; | 214 Uint32 mval; |
214 dmGetData(node->type, file, offs + n, &mval); | 215 dmGetData(node->type, file, offs + n, &mval); |
215 dmPrint(1, vfmt, mval, veol); | 216 dmPrint(1, mfmt, mval, veol); |
216 } | 217 } |
217 else | 218 else |
218 { | 219 { |
219 if (node->vwildcards[n]) | 220 if (node->vwildcards[n]) |
220 dmPrint(1, "?%s", veol); | 221 dmPrint(1, "?%s", veol); |
221 else | 222 else |
222 dmPrint(1, vfmt, node->values[n], veol); | 223 dmPrint(1, mfmt, node->values[n], veol); |
223 } | 224 } |
224 } | 225 } |
225 } | 226 } |
226 | 227 |
227 | 228 |
415 if (nsetGrepValues < SET_MAX_VALUES) | 416 if (nsetGrepValues < SET_MAX_VALUES) |
416 { | 417 { |
417 DMGrepValue *node = &setGrepValues[nsetGrepValues++]; | 418 DMGrepValue *node = &setGrepValues[nsetGrepValues++]; |
418 memcpy(node, &val, sizeof(val)); | 419 memcpy(node, &val, sizeof(val)); |
419 | 420 |
420 dmMsg(1, "Grep %ss : ", | 421 if (mode == FA_GREP) |
421 dmGrepTypes[val.type].name); | 422 { |
422 | 423 dmPrint(1, "Grep %s: ", |
423 dmPrintGrepValueList(node, FALSE, NULL, 0); | 424 dmGrepTypes[val.type].name); |
425 | |
426 dmPrintGrepValueList(node, FALSE, NULL, 0); | |
427 } | |
424 } | 428 } |
425 else | 429 else |
426 { | 430 { |
427 ret = dmError(DMERR_BOUNDS, | 431 ret = dmError(DMERR_BOUNDS, |
428 "Too many values specified (max %d).", | 432 "Too many values specified (max %d).", |
590 } | 594 } |
591 } | 595 } |
592 | 596 |
593 if (match) | 597 if (match) |
594 { | 598 { |
595 dmPrint(0, "%08x : %s match ", | 599 dmPrint(0, "%08x : ", offs); |
596 offs, def->name); | |
597 | |
598 dmPrintGrepValueList(node, TRUE, file, offs); | 600 dmPrintGrepValueList(node, TRUE, file, offs); |
599 } | 601 } |
600 } | 602 } |
601 } | 603 } |
602 } | 604 } |
622 | 624 |
623 for (int n = 0; n < nsetGrepValues; n++) | 625 for (int n = 0; n < nsetGrepValues; n++) |
624 { | 626 { |
625 DMGrepValue *node = &setGrepValues[n]; | 627 DMGrepValue *node = &setGrepValues[n]; |
626 const DMGrepType *def = &dmGrepTypes[node->type]; | 628 const DMGrepType *def = &dmGrepTypes[node->type]; |
627 printf("%08x : ", node->values[0]); | 629 |
628 | 630 for (int nv = 0; nv < node->nvalues; nv++) |
629 for (int nfile = 0; nfile < nsrcFiles; nfile++) | 631 { |
630 { | 632 printf("%08x : ", node->values[nv]); |
631 DMSourceFile *file = &srcFiles[nfile]; | 633 |
632 Uint32 mval; | 634 for (int nfile = 0; nfile < nsrcFiles; nfile++) |
633 char mstr[32]; | |
634 int npad, nwidth; | |
635 | |
636 if (dmGetData(node->type, file, node->values[0], &mval)) | |
637 { | 635 { |
638 char mfmt[16]; | 636 DMSourceFile *file = &srcFiles[nfile]; |
639 nwidth = def->bsize * 2; | 637 Uint32 mval; |
640 snprintf(mfmt, sizeof(mfmt), "%%0%d%s", | 638 char mstr[32]; |
641 nwidth, dmGrepDisp[node->disp].fmt); | 639 int npad, nwidth; |
642 | 640 |
643 snprintf(mstr, sizeof(mstr), mfmt, mval); | 641 if (dmGetData(node->type, file, node->values[nv], &mval)) |
642 { | |
643 char mfmt[16]; | |
644 nwidth = def->bsize * 2; | |
645 snprintf(mfmt, sizeof(mfmt), "%%0%d%s", | |
646 nwidth, dmGrepDisp[node->disp].fmt); | |
647 | |
648 snprintf(mstr, sizeof(mstr), mfmt, mval); | |
649 } | |
650 else | |
651 { | |
652 strcpy(mstr, "----"); | |
653 nwidth = 4; | |
654 } | |
655 | |
656 npad = (10 - nwidth) / 2; | |
657 for (int q = 0; q < npad; q++) | |
658 fputc(' ', stdout); | |
659 | |
660 fputs(mstr, stdout); | |
661 | |
662 for (int q = 0; q < npad; q++) | |
663 fputc(' ', stdout); | |
644 } | 664 } |
645 else | 665 |
646 { | 666 printf(" [%s]\n", |
647 strcpy(mstr, "----"); | 667 dmGrepDisp[node->disp].name); |
648 nwidth = 4; | 668 } |
649 } | |
650 | |
651 npad = (10 - nwidth) / 2; | |
652 for (int q = 0; q < npad; q++) | |
653 fputc(' ', stdout); | |
654 | |
655 fputs(mstr, stdout); | |
656 | |
657 for (int q = 0; q < npad; q++) | |
658 fputc(' ', stdout); | |
659 } | |
660 | |
661 printf(" [%s]\n", | |
662 dmGrepDisp[node->disp].name); | |
663 } | 669 } |
664 } | 670 } |
665 else | 671 else |
666 if (setMode == FA_ANALYZE) | 672 if (setMode == FA_ANALYZE) |
667 { | 673 { |