summaryrefslogtreecommitdiffstats
path: root/text-utils/hexdump-display.c
diff options
context:
space:
mode:
authorOndrej Oprala2014-01-21 17:13:56 +0100
committerKarel Zak2014-02-10 16:01:37 +0100
commit098ab0778f5a46ab4519c8404fd4ba8ec137368b (patch)
tree62e319ce561e1b9e725312ae66d7f4d7d28824ea /text-utils/hexdump-display.c
parentlib/color: add colorscheme parser (diff)
downloadkernel-qcow2-util-linux-098ab0778f5a46ab4519c8404fd4ba8ec137368b.tar.gz
kernel-qcow2-util-linux-098ab0778f5a46ab4519c8404fd4ba8ec137368b.tar.xz
kernel-qcow2-util-linux-098ab0778f5a46ab4519c8404fd4ba8ec137368b.zip
hexdump: add highlighting support
[kzak@redhat.com: - fix coding style, - use xalloc in all code, - fix strtol usage] Signed-off-by: Ondrej Oprala <ooprala@redhat.com> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'text-utils/hexdump-display.c')
-rw-r--r--text-utils/hexdump-display.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/text-utils/hexdump-display.c b/text-utils/hexdump-display.c
index b195a01ae..ce714f68c 100644
--- a/text-utils/hexdump-display.c
+++ b/text-utils/hexdump-display.c
@@ -44,6 +44,7 @@
#include "xalloc.h"
#include "c.h"
#include "nls.h"
+#include "colors.h"
static void doskip(const char *, int, struct hexdump *);
static u_char *get(struct hexdump *);
@@ -53,9 +54,67 @@ enum _vflag vflag = FIRST;
static off_t address; /* address/offset in stream */
static off_t eaddress; /* end address */
+static const char *color_cond(struct hexdump_pr *pr, unsigned char *bp, int bcnt)
+{
+ register struct list_head *p;
+ register struct hexdump_clr *clr;
+ off_t offt;
+ int match;
+
+ list_for_each(p, pr->colorlist) {
+ clr = list_entry(p, struct hexdump_clr, colorlist);
+ offt = clr->offt;
+ match = 0;
+
+ /* no offset or offset outside this print unit */
+ if (offt < 0)
+ offt = address;
+ if (offt < address || offt + clr->range > address + bcnt)
+ continue;
+
+ /* match a string */
+ if (clr->str) {
+ if (pr->flags == F_ADDRESS) {
+ /* TODO */
+ }
+ else if (!strncmp(clr->str, (char *)bp + offt
+ - address, clr->range))
+ match = 1;
+ /* match a value */
+ } else if (clr->val != -1) {
+ int val = 0;
+ /* addresses are not part of the input, so we can't
+ * compare with the contents of bp */
+ if (pr->flags == F_ADDRESS) {
+ if (clr->val == address)
+ match = 1;
+ } else {
+ memcpy(&val, bp + offt - address, clr->range);
+ if (val == clr->val)
+ match = 1;
+ }
+ /* no conditions, only a color was specified */
+ } else
+ return clr->fmt;
+
+ /* return the format string or check for another */
+ if (match ^ clr->invert)
+ return clr->fmt;
+ continue;
+ }
+
+ /* no match */
+ return NULL;
+}
+
static inline void
print(struct hexdump_pr *pr, unsigned char *bp) {
+ const char *color = NULL;
+
+ if (pr->colorlist && (color = color_cond(pr, bp, pr->bcnt)))
+ color_enable(color);
+
switch(pr->flags) {
case F_ADDRESS:
printf(pr->fmt, address);
@@ -148,6 +207,8 @@ print(struct hexdump_pr *pr, unsigned char *bp) {
break;
}
}
+ if (color) /* did we colorize something? */
+ color_disable();
}
static void bpad(struct hexdump_pr *pr)
@@ -239,6 +300,13 @@ void display(struct hexdump *hex)
}
list_for_each (p, &endfu->prlist) {
pr = list_entry(p, struct hexdump_pr, prlist);
+
+ const char *color = NULL;
+ if (colors_wanted() && pr->colorlist
+ && (color = color_cond(pr, bp, pr->bcnt))) {
+ color_enable(color);
+ }
+
switch(pr->flags) {
case F_ADDRESS:
printf(pr->fmt, eaddress);
@@ -247,6 +315,8 @@ void display(struct hexdump *hex)
printf("%s", pr->fmt);
break;
}
+ if (color) /* did we highlight something? */
+ color_disable();
}
}
}