From af4c619575b3ab268d90fdff4eabf8a5f4da1db6 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Sun, 21 Jan 2024 00:40:37 +0100 Subject: Print byte-offsets into files --- man/grab.1 | 5 ++++- src/grab.c | 33 +++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/man/grab.1 b/man/grab.1 index e73307b..b2d3edd 100644 --- a/man/grab.1 +++ b/man/grab.1 @@ -212,6 +212,9 @@ The keys are as follows: .Bl -tag -compact .It fn filenames prefixing any content line. +.It ln +line- and column-numbers, +as well as byte offsets when reporting the location of a match. .It ma text matched by a .Sq g @@ -223,7 +226,7 @@ separators inserted between filenames and content lines. .El .Pp The default value is -.Sq fn=35,ma=01;31,se=36 +.Sq fn=35,ln=32,ma=01;31,se=36 .It Ev NO_COLOR Do not display any colored output when set to a non-empty string, even if the standard-output is a terminal. diff --git a/src/grab.c b/src/grab.c index 2a643f4..bc86b8d 100644 --- a/src/grab.c +++ b/src/grab.c @@ -37,6 +37,7 @@ #define EEARLY "Input string terminated prematurely" #define DEFCOL_FN "35" +#define DEFCOL_LN "32" #define DEFCOL_MA "01;31" #define DEFCOL_SE "36" @@ -51,7 +52,7 @@ struct ops { }; struct sv { - char *p; + char *bp, *p; size_t len; }; @@ -288,6 +289,7 @@ grab(struct ops ops, FILE *stream, const char *filename) warn("fread: %s", filename); else { struct sv sv = { + .bp = chars.buf, .p = chars.buf, .len = chars.len, }; @@ -331,7 +333,11 @@ cmdx(struct sv sv, struct ops ops, size_t i, const char *filename) if (regexec(&op.pat, sv.p, 1, &rm, REG_STARTEND) == REG_NOMATCH) break; - nsv = (struct sv){.p = sv.p + rm.rm_so, .len = rm.rm_eo - rm.rm_so}; + nsv = (struct sv){ + .bp = sv.bp, + .p = sv.p + rm.rm_so, + .len = rm.rm_eo - rm.rm_so, + }; if (i + 1 == ops.len) putm(nsv, nullptr, filename); else @@ -367,6 +373,7 @@ cmdy(struct sv sv, struct ops ops, size_t i, const char *filename) if (prev.rm_so || prev.rm_eo || rm.rm_so) { nsv = (struct sv){ + .bp = sv.bp, .p = sv.p + prev.rm_eo, .len = rm.rm_so - prev.rm_eo, }; @@ -387,6 +394,7 @@ cmdy(struct sv sv, struct ops ops, size_t i, const char *filename) if (prev.rm_eo < rm.rm_eo) { struct sv nsv = { + .bp = sv.bp, .p = sv.p + rm.rm_so, .len = rm.rm_eo - rm.rm_so, }; @@ -400,19 +408,21 @@ cmdy(struct sv sv, struct ops ops, size_t i, const char *filename) void putm(struct sv sv, regmatch_t *rm, const char *filename) { - static const char *fn, *ma, *se; + static const char *fn, *ln, *ma, *se; if (cflag && !fn) { char *optstr; if ((optstr = env_or_default("GRAB_COLORS", nullptr))) { enum { OPT_FN, + OPT_LN, OPT_MA, OPT_SE, }; /* clang-format off */ static char *const tokens[] = { [OPT_FN] = "fn", + [OPT_LN] = "ln", [OPT_MA] = "ma", [OPT_SE] = "se", nullptr @@ -426,6 +436,10 @@ putm(struct sv sv, regmatch_t *rm, const char *filename) if (sgrvalid(val)) fn = val; break; + case OPT_LN: + if (sgrvalid(val)) + fn = val; + break; case OPT_MA: if (sgrvalid(val)) ma = val; @@ -443,6 +457,8 @@ putm(struct sv sv, regmatch_t *rm, const char *filename) if (!fn) fn = DEFCOL_FN; + if (!ln) + ln = DEFCOL_LN; if (!ma) ma = DEFCOL_MA; if (!se) @@ -450,11 +466,16 @@ putm(struct sv sv, regmatch_t *rm, const char *filename) } if (fflag || filecnt > 1) { + char sep = zflag ? '\0' : ':'; if (cflag) { - printf("\33[%sm%s\33[%sm%c\33[0m", fn, filename, se, - zflag ? '\0' : ':'); + printf("\33[%sm%s\33[0m" /* filename */ + "\33[%sm%c\33[0m" /* separator */ + "\33[%sm%td\33[0m" /* byte offset */ + "\33[%sm%c\33[0m" /* separator */ + , + fn, filename, se, sep, ln, sv.p - sv.bp, se, sep); } else - printf("%s%c", filename, zflag ? '\0' : ':'); + printf("%s%c", filename, sep); } if (rm) { fwrite(sv.p, 1, rm->rm_so, stdout); -- cgit v1.2.3