[PATCH/RFC 3/4] grep: introduce pattern which matches at line number

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]