commit 9f0a76556ac7ee316996d439e3c2881135231dce
parent 8d6904c603a82258eac50aae3e006e386e90c9a2
Author: Stephen Gregoratto <dev@sgregoratto.me>
Date: Wed, 16 Sep 2020 16:27:50 +1000
Rework highlighting code
- Highlighting defaults to on if stdout is a tty.
- Rename the variables to be terser.
- Replace while with for because everyone should be using c99.
- Remove unused ANSI code strings, replace used ones with preprocessor
defines.
Diffstat:
M | ngrep.8 | | | 1 | + |
M | ngrep.c | | | 101 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
M | ngrep.h | | | 9 | ++++----- |
3 files changed, 54 insertions(+), 57 deletions(-)
diff --git a/ngrep.8 b/ngrep.8
@@ -43,6 +43,7 @@ packets of trailing context after matching a packet.
Highlight the first occurence of
.Ar expression
in bright red.
+This is the default if standard output is a terminal.
.It Fl c Ar cols
Explicitly set the console width to
.Ar cols .
diff --git a/ngrep.c b/ngrep.c
@@ -57,7 +57,7 @@ bool invert_match = false;
bool bin_match = false;
bool live_read = true;
bool want_delay = false;
-bool enable_hilite = false;
+bool highlight = false;
uint32_t keep_matching = 0;
uint32_t limitlen = 65535;
@@ -84,7 +84,7 @@ pcre_extra *pattern_extra = NULL;
char *match_data = NULL;
char *bin_data = NULL;
bool add_hex_exp_pfx = true;
-uint16_t match_len = 0;
+size_t match_len = 0;
match_func matcher = blank_match_func;
bool dump_single = false;
@@ -148,6 +148,8 @@ main(int argc, char **argv)
signal(SIGPIPE, clean_exit);
signal(SIGWINCH, update_windowsize);
+ highlight = isatty(STDOUT_FILENO);
+
while ((c = getopt(argc, argv, optstring)) != EOF) {
switch (c) {
case 'A':
@@ -163,7 +165,7 @@ main(int argc, char **argv)
errx(2, "cols is %s: %s", errstr, optarg);
break;
case 'C':
- enable_hilite = true;
+ highlight = true;
break;
case 'd':
usedev = optarg;
@@ -945,53 +947,47 @@ blank_match_func(UNUSED uint8_t *data, UNUSED uint32_t len, size_t *mindex,
void
dump_byline(uint8_t *data, uint32_t len, size_t mindex, size_t msize)
{
- const uint8_t *s = data;
- bool should_hilite = (msize && enable_hilite);
- uint8_t *hilite_start = data + mindex;
- uint8_t *hilite_end = hilite_start + msize;
-
- while (s < data + len) {
- if (should_hilite && s == hilite_start)
- printf("%s", ANSI_hilite);
-
- printf("%c", (*s == '\n' || isprint(*s)) ? *s : nonprint_char);
- s++;
-
- if (should_hilite && s == hilite_end)
- printf("%s", ANSI_off);
+ bool should_hl = (highlight && msize);
+ uint8_t *hl_start = data + mindex;
+ uint8_t *hl_end = hl_start + msize;
+
+ for (uint8_t *s = data; s < data + len; s++) {
+ if (should_hl) {
+ if (s == hl_start)
+ fputs(RED, stdout);
+ else if (s == hl_end)
+ fputs(RESET, stdout);
+ }
+ putchar((*s == '\n' || isprint(*s)) ? *s : nonprint_char);
}
-
- printf("\n");
+ putchar('\n');
}
void
dump_unwrapped(uint8_t *data, uint32_t len, size_t mindex, size_t msize)
{
- const uint8_t *s = data;
- bool should_hilite = (msize && enable_hilite);
- uint8_t *hilite_start = data + mindex;
- uint8_t *hilite_end = hilite_start + msize;
-
- while (s < data + len) {
- if (should_hilite && s == hilite_start)
- printf("%s", ANSI_hilite);
-
- printf("%c", isprint(*s) ? *s : nonprint_char);
- s++;
-
- if (should_hilite && s == hilite_end)
- printf("%s", ANSI_off);
+ bool should_hl = (highlight && msize);
+ uint8_t *hl_start = data + mindex;
+ uint8_t *hl_end = hl_start + msize;
+
+ for (uint8_t *s = data; s < data + len; s++) {
+ if (should_hl) {
+ if (s == hl_start)
+ fputs(RED, stdout);
+ else if (s == hl_end)
+ fputs(RESET, stdout);
+ }
+ putchar(isprint(*s) ? *s : nonprint_char);
}
-
- printf("\n");
+ putchar('\n');
}
void
dump_formatted(uint8_t *data, uint32_t len, size_t mindex, size_t msize)
{
- bool should_hilite = (msize && enable_hilite);
+ bool should_hl = (highlight && msize);
uint8_t *str = data;
- bool hiliting = false;
+ bool hl_state = false;
uint8_t width = show_hex ? 16 : (ws_col - 5);
uint32_t i = 0, j = 0;
@@ -1000,10 +996,11 @@ dump_formatted(uint8_t *data, uint32_t len, size_t mindex, size_t msize)
if (show_hex) {
for (j = 0; j < width; j++) {
- if (should_hilite && mindex <= i + j &&
+ if (should_hl &&
+ mindex <= i + j &&
i + j < mindex + msize) {
- hiliting = true;
- printf("%s", ANSI_hilite);
+ hl_state = true;
+ fputs(RED, stdout);
}
if (i + j < len)
@@ -1014,36 +1011,36 @@ dump_formatted(uint8_t *data, uint32_t len, size_t mindex, size_t msize)
if ((j + 1) % (width / 2) == 0)
printf(" ");
- if (hiliting) {
- hiliting = false;
- printf("%s", ANSI_off);
+ if (hl_state) {
+ hl_state = false;
+ fputs(RESET, stdout);
}
}
}
for (j = 0; j < width; j++) {
- if (should_hilite && mindex <= i + j &&
+ if (should_hl &&
+ mindex <= i + j &&
i + j < mindex + msize) {
- hiliting = true;
- printf("%s", ANSI_hilite);
+ hl_state = true;
+ fputs(RED, stdout);
}
if (i + j < len)
- printf("%c", isprint(str[j]) ? str[j]
- : nonprint_char);
+ putchar(isprint(str[j]) ? str[j] : nonprint_char);
else
printf(" ");
- if (hiliting) {
- hiliting = false;
- printf("%s", ANSI_off);
+ if (hl_state) {
+ hl_state = false;
+ fputs(RESET, stdout);
}
}
str += width;
i += j;
- printf("\n");
+ putchar('\n');
}
}
diff --git a/ngrep.h b/ngrep.h
@@ -56,6 +56,10 @@
#define WORD_REGEX "((^%s\\W)|(\\W%s$)|(\\W%s\\W))"
+/* ANSI codes for expression highlighting. */
+#define RED "\33[01;31m"
+#define RESET "\33[00m"
+
typedef void (*dump_func)(uint8_t *, uint32_t, size_t, size_t);
typedef bool (*match_func)(uint8_t *, uint32_t, size_t *, size_t *);
typedef void (*delay_func)(struct pcap_pkthdr *);
@@ -98,8 +102,3 @@ char *get_filter_from_argv(char **);
void drop_privs(void);
-/* ANSI color/hilite stuff. */
-const char ANSI_red[] = "\33[01;31m";
-const char ANSI_bold[] = "\33[01m";
-const char *ANSI_hilite = ANSI_red;
-const char ANSI_off[] = "\33[00m";