Signed-off-by: Bert Wesarg <bert.wesarg@xxxxxxxxxxxxxx> --- grep.c | 33 +++++++++++++++++++++++++++++++++ grep.h | 7 +++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/grep.c b/grep.c index f21b022..cbb3757 100644 --- a/grep.c +++ b/grep.c @@ -87,6 +87,15 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt) } } +static void parse_lno(struct grep_pat *p, struct grep_opt *opt) +{ + char *eon; + + p->u.lno = strtoul(p->pattern, &eon, 10); + if (*eon || p->u.lno == 0) + die("'%s': Invalid number for line match", p->pattern); +} + static struct grep_expr *compile_pattern_or(struct grep_pat **); static struct grep_expr *compile_pattern_atom(struct grep_pat **list) { @@ -100,6 +109,7 @@ static struct grep_expr *compile_pattern_atom(struct grep_pat **list) case GREP_PATTERN: /* atom */ case GREP_PATTERN_HEAD: case GREP_PATTERN_BODY: + case GREP_LNO: x = xcalloc(1, sizeof (struct grep_expr)); x->node = GREP_NODE_ATOM; x->u.atom = p; @@ -264,6 +274,9 @@ void compile_grep_patterns(struct grep_opt *opt) case GREP_PATTERN_BODY: compile_regexp(p, opt); break; + case GREP_LNO: + parse_lno(p, opt); + break; default: opt->extended = 1; break; @@ -297,6 +310,7 @@ static void free_pattern_expr(struct grep_expr *x) switch (x->node) { case GREP_NODE_TRUE: case GREP_NODE_ATOM: + case GREP_NODE_LNO: break; case GREP_NODE_NOT: free_pattern_expr(x->u.unary); @@ -436,6 +450,21 @@ static struct { { "committer ", 10 }, }; +static int match_lno(struct grep_pat *p, char *bol, char *eol, unsigned lno, + regmatch_t *pmatch) +{ + if (p->u.lno == lno) { + /* + * because coloring will stop at so == eo, match at the end + * of line, so that the whole line can be colored + */ + pmatch->rm_so = eol - bol; + pmatch->rm_eo = eol - bol; + return 1; + } + return 0; +} + static int match_one_pattern(struct grep_pat *p, char *bol, char *eol, unsigned lno, enum grep_context ctx, regmatch_t *pmatch, int eflags) @@ -444,6 +473,9 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol, int saved_ch = 0; const char *start = bol; + if (p->token == GREP_LNO) + return match_lno(p, bol, eol, lno, pmatch); + if ((p->token != GREP_PATTERN) && ((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD))) return 0; @@ -614,6 +646,7 @@ static int next_match(struct grep_opt *opt, char *bol, char *eol, unsigned lno, case GREP_PATTERN: /* atom */ case GREP_PATTERN_HEAD: case GREP_PATTERN_BODY: + case GREP_LNO: hit |= match_next_pattern(p, bol, eol, lno, ctx, pmatch, eflags); break; diff --git a/grep.h b/grep.h index 9912c11..41821f3 100644 --- a/grep.h +++ b/grep.h @@ -10,7 +10,8 @@ enum grep_pat_token { GREP_OPEN_PAREN, GREP_CLOSE_PAREN, GREP_NOT, - GREP_OR + GREP_OR, + GREP_LNO }; enum grep_context { @@ -34,6 +35,7 @@ struct grep_pat { enum grep_header_field field; union { regex_t regexp; + unsigned lno; } u; unsigned fixed:1; unsigned ignore_case:1; @@ -45,7 +47,8 @@ enum grep_expr_node { GREP_NODE_NOT, GREP_NODE_AND, GREP_NODE_TRUE, - GREP_NODE_OR + GREP_NODE_OR, + GREP_NODE_LNO }; struct grep_expr { -- 1.7.5.349.gfeb1a -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html