git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jonathan Nieder <jrnieder@gmail.com>
To: Jakub Narebski <jnareb@gmail.com>
Cc: "Nguyen Thai Ngoc Duy" <pclouds@gmail.com>,
	git <git@vger.kernel.org>,
	computerdruid <computerdruid@gmail.com>, joey <joey@kitenet.net>,
	"Ramkumar Ramachandra" <artagnon@gmail.com>,
	"René Scharfe" <rene.scharfe@lsrfire.ath.cx>
Subject: [PATCH] grep -A/-B/-Cinfinity to get full context
Date: Fri, 20 Aug 2010 06:55:27 -0500	[thread overview]
Message-ID: <20100820115527.GR10407@burratino> (raw)
In-Reply-To: <201008201122.09392.jnareb@gmail.com>

Just a proof of concept.

Cc: René Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Jakub Narebski wrote:

> If there were more options that use <n> == 0 to actually mean unlimited
> (infinity), perhaps it would be better to extend parseopt to provide for
> such situation, e.g. OPT_INT_INF or something.

Something like this, maybe.

 Documentation/technical/api-parse-options.txt |    6 ++++++
 builtin/grep.c                                |    8 ++++++--
 grep.c                                        |    8 +++++---
 grep.h                                        |    4 ++--
 parse-options.c                               |   21 +++++++++++++++++++++
 parse-options.h                               |    4 ++++
 6 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt
index 312e3b2..f152a3f 100644
--- a/Documentation/technical/api-parse-options.txt
+++ b/Documentation/technical/api-parse-options.txt
@@ -160,6 +160,12 @@ There are some macros to easily define options:
 	Introduce an option with integer argument.
 	The integer is put into `int_var`.
 
+`OPT_INT_INF(short, long, &int_var, inf_val, description)`::
+	Introduce an option with integer argument.
+	The integer is put into `int_var`.  If the special value
+	"inf" (or "infinity") is used as an argument, then `inf_val`
+	is put into `int_var`.
+
 `OPT_DATE(short, long, &int_var, description)`::
 	Introduce an option with date argument, see `approxidate()`.
 	The timestamp is put into `int_var`.
diff --git a/builtin/grep.c b/builtin/grep.c
index 597f76b..9fbc985 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -750,6 +750,10 @@ static int context_callback(const struct option *opt, const char *arg,
 		grep_opt->pre_context = grep_opt->post_context = 0;
 		return 0;
 	}
+	if (!strcasecmp(arg, "inf") || !strcasecmp(arg, "infinity")) {
+		grep_opt->pre_context = grep_opt->post_context = -1;
+		return 0;
+	}
 	value = strtol(arg, (char **)&endp, 10);
 	if (*endp) {
 		return error("switch `%c' expects a numerical value",
@@ -890,9 +894,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 		OPT_CALLBACK('C', NULL, &opt, "n",
 			"show <n> context lines before and after matches",
 			context_callback),
-		OPT_INTEGER('B', NULL, &opt.pre_context,
+		OPT_INT_INF('B', NULL, &opt.pre_context, -1,
 			"show <n> context lines before matches"),
-		OPT_INTEGER('A', NULL, &opt.post_context,
+		OPT_INT_INF('A', NULL, &opt.post_context, -1,
 			"show <n> context lines after matches"),
 		OPT_NUMBER_CALLBACK(&opt, "shortcut for -C NUM",
 			context_callback),
diff --git a/grep.c b/grep.c
index 82fb349..793d41f 100644
--- a/grep.c
+++ b/grep.c
@@ -687,7 +687,7 @@ static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
 	unsigned cur = lno, from = 1, funcname_lno = 0;
 	int funcname_needed = opt->funcname;
 
-	if (opt->pre_context < lno)
+	if (opt->pre_context >= 0 && opt->pre_context < lno)
 		from = lno - opt->pre_context;
 	if (from <= opt->last_shown)
 		from = opt->last_shown + 1;
@@ -861,7 +861,8 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
 		 */
 		if (try_lookahead
 		    && !(last_hit
-			 && lno <= last_hit + opt->post_context)
+			 && (opt->post_context < 0
+			     || lno <= last_hit + opt->post_context))
 		    && look_ahead(opt, &left, &lno, &bol))
 			break;
 		eol = end_of_line(bol, &left);
@@ -916,7 +917,8 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
 			last_hit = lno;
 		}
 		else if (last_hit &&
-			 lno <= last_hit + opt->post_context) {
+			 (opt->post_context < 0 ||
+			  lno <= last_hit + opt->post_context)) {
 			/* If the last hit is within the post context,
 			 * we need to show this line.
 			 */
diff --git a/grep.h b/grep.h
index efa8cff..13aae94 100644
--- a/grep.h
+++ b/grep.h
@@ -95,8 +95,8 @@ struct grep_opt {
 	char color_selected[COLOR_MAXLEN];
 	char color_sep[COLOR_MAXLEN];
 	int regflags;
-	unsigned pre_context;
-	unsigned post_context;
+	int pre_context;
+	int post_context;
 	unsigned last_shown;
 	int show_hunk_mark;
 	void *priv;
diff --git a/parse-options.c b/parse-options.c
index 0fa79bc..b299125 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -612,6 +612,27 @@ int parse_opt_approxidate_cb(const struct option *opt, const char *arg,
 	return 0;
 }
 
+int parse_opt_infinity_cb(const struct option *opt, const char *arg,
+			  int unset)
+{
+	const char *endp;
+
+	if (unset) {
+		*(int *)opt->value = 0;
+		return 0;
+	}
+	if (!arg)
+		return opterror(opt, "expects a numerical value", 0);
+	if (!strcasecmp(arg, "inf") || !strcasecmp(arg, "infinity")) {
+		*(int *)opt->value = opt->defval;
+		return 0;
+	}
+	*(int *)opt->value = strtol(arg, (char **)&endp, 10);
+	if (*endp)
+		return opterror(opt, "expects a numerical value", 0);
+	return 0;
+}
+
 int parse_opt_color_flag_cb(const struct option *opt, const char *arg,
 			    int unset)
 {
diff --git a/parse-options.h b/parse-options.h
index 7435cdb..6ae041a 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -126,6 +126,9 @@ struct option {
 #define OPT_STRING(s, l, v, a, h)   { OPTION_STRING,  (s), (l), (v), (a), (h) }
 #define OPT_UYN(s, l, v, h)         { OPTION_CALLBACK, (s), (l), (v), NULL, \
 				      (h), PARSE_OPT_NOARG, &parse_opt_tertiary }
+#define OPT_INT_INF(s, l, v, i, h) \
+	{ OPTION_CALLBACK, (s), (l), (v), "n", (h), 0, \
+	  parse_opt_infinity_cb, (intptr_t)(i) }
 #define OPT_DATE(s, l, v, h) \
 	{ OPTION_CALLBACK, (s), (l), (v), "time",(h), 0, \
 	  parse_opt_approxidate_cb }
@@ -193,6 +196,7 @@ extern int parse_options_concat(struct option *dst, size_t, struct option *src);
 /*----- some often used options -----*/
 extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
 extern int parse_opt_approxidate_cb(const struct option *, const char *, int);
+extern int parse_opt_infinity_cb(const struct option *, const char *, int);
 extern int parse_opt_color_flag_cb(const struct option *, const char *, int);
 extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
 extern int parse_opt_with_commit(const struct option *, const char *, int);
-- 
1.7.2.2.536.g42dab.dirty

  parent reply	other threads:[~2010-08-20 11:57 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-17  0:49 fully deepening a shallow clone Joey Hess
2010-08-18  9:36 ` Nguyen Thai Ngoc Duy
2010-08-18 12:54   ` Daniel Johnson
2010-08-19 10:40     ` [PATCH 1/3] clone: do not accept --depth on local clones Nguyễn Thái Ngọc Duy
2010-08-19 14:31       ` Daniel Johnson
2010-08-19 22:15         ` Nguyen Thai Ngoc Duy
2010-08-19 20:49       ` Mikael Magnusson
2010-08-19 10:40     ` [PATCH 2/3] fetch-pack: use args.shallow to detect shallow clone instead of args.depth Nguyễn Thái Ngọc Duy
2010-08-19 10:40     ` [PATCH 3/3] {fetch,upload}-pack: allow --depth=0 to deepen into full repo again Nguyễn Thái Ngọc Duy
2010-08-19 21:22       ` Jakub Narebski
2010-08-19 22:11         ` Nguyen Thai Ngoc Duy
2010-08-20  9:22           ` Jakub Narebski
2010-08-20  9:28             ` Ramkumar Ramachandra
2010-08-20 11:55             ` Jonathan Nieder [this message]
2010-08-20 13:32               ` [PATCH] grep -A/-B/-Cinfinity to get full context Ramkumar Ramachandra
2010-08-18 15:48   ` fully deepening a shallow clone Joey Hess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100820115527.GR10407@burratino \
    --to=jrnieder@gmail.com \
    --cc=artagnon@gmail.com \
    --cc=computerdruid@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=jnareb@gmail.com \
    --cc=joey@kitenet.net \
    --cc=pclouds@gmail.com \
    --cc=rene.scharfe@lsrfire.ath.cx \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).