[PATCH/RFC v2 2/2] describe: add basic and extended posix regex matching for completeness

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

 



Signed-off-by: Mostyn Bramley-Moore <mostynb@xxxxxxxxx>
---
 Documentation/git-describe.txt |  6 ++++++
 builtin/describe.c             | 41 +++++++++++++++++++++++++++++++++++++++++
 t/t6120-describe.sh            | 14 ++++++++++++++
 3 files changed, 61 insertions(+)

diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt
index b8279ec..0c237c3 100644
--- a/Documentation/git-describe.txt
+++ b/Documentation/git-describe.txt
@@ -89,6 +89,12 @@ OPTIONS
 --glob::
 	Use `glob(7)` patterns with --match, this is the default.
 
+-E::
+--extended-regexp::
+-G::
+--basic-regexp::
+	Use POSIX extended/basic regexp for patterns with --match.
+
 -P::
 --perl-regexp::
 	Use Perl-compatible regexp for patterns with --match. Requires
diff --git a/builtin/describe.c b/builtin/describe.c
index d9ab5bd..3bff610 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -9,6 +9,7 @@
 #include "diff.h"
 #include "hashmap.h"
 #include "argv-array.h"
+#include <regex.h>
 
 #ifdef USE_LIBPCRE
 #include <pcre.h>
@@ -25,6 +26,8 @@ static const char * const describe_usage[] = {
 
 enum match_type {
 	MATCH_GLOB = 0,
+	MATCH_BRE,
+	MATCH_ERE,
 	MATCH_PCRE
 };
 
@@ -41,6 +44,7 @@ static const char *pattern;
 static int always;
 static const char *dirty;
 static enum match_type pattern_type_arg = MATCH_GLOB;
+static regex_t posix_regex;
 
 #ifdef USE_LIBPCRE
 static pcre *pcre_regex = NULL;
@@ -134,6 +138,27 @@ static void add_to_known_names(const char *path,
 	}
 }
 
+static void re_init(enum match_type type)
+{
+	int cflags = REG_NOSUB;
+	if (type == MATCH_ERE)
+		cflags |= REG_EXTENDED;
+
+	if (regcomp(&posix_regex, pattern, cflags))
+		die("Invalid regular expression: %s", pattern);
+}
+
+static void re_cleanup()
+{
+	regfree(&posix_regex);
+}
+
+/* return 1 on match, 0 on no match. */
+static int posix_re_match(const char *text)
+{
+	return regexec(&posix_regex, text, 0, NULL, 0) != 0;
+}
+
 #ifdef USE_LIBPCRE
 static void pcre_init()
 {
@@ -180,6 +205,8 @@ static int match(const char *pattern, const char *text, enum match_type t)
 {
 	if (t == MATCH_GLOB) {
 		return wildmatch(pattern, text, 0, NULL);
+	} else if (t == MATCH_ERE || t == MATCH_BRE) {
+		return posix_re_match(text);
 #ifdef USE_LIBPCRE
 	} else if (t == MATCH_PCRE) {
 		return pcre_match(text);
@@ -479,6 +506,12 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
 		OPT_SET_INT(0, "glob", &pattern_type_arg,
 			   N_("use glob patterns with --match (default)"),
 			   MATCH_GLOB),
+		OPT_SET_INT('E', "extended-regexp", &pattern_type_arg,
+			   N_("use extended POSIX regular expressions with --match"),
+			   MATCH_ERE),
+		OPT_SET_INT('G', "basic-regexp", &pattern_type_arg,
+			   N_("use basic POSIX regular expressions with --match"),
+			   MATCH_BRE),
 #ifdef USE_LIBPCRE
 		OPT_SET_INT('P', "perl-regexp", &pattern_type_arg,
 			   N_("use Perl-compatible regular expressions with --match"),
@@ -507,6 +540,10 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
 	if (longformat && abbrev == 0)
 		die(_("--long is incompatible with --abbrev=0"));
 
+	if (pattern && (pattern_type_arg == MATCH_ERE ||
+			pattern_type_arg == MATCH_BRE))
+		re_init(pattern_type_arg);
+
 #ifdef USE_LIBPCRE
 	if (pattern && pattern_type_arg == MATCH_PCRE)
 		pcre_init();
@@ -538,6 +575,10 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
 	if (!names.size && !always)
 		die(_("No names found, cannot describe anything."));
 
+	if (pattern && (pattern_type_arg == MATCH_ERE ||
+			pattern_type_arg == MATCH_BRE))
+		re_cleanup();
+
 #ifdef USE_LIBPCRE
 	if (pattern && pattern_type_arg == MATCH_PCRE)
 		pcre_cleanup();
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index 47427c4..e3d8663 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -184,17 +184,31 @@ test_expect_success 'set-up matching pattern tests' '
 '
 
 check_describe "test-annotated-*" --match="test-*"
+check_describe "test-annotated-*" --match="^test-" --basic-regexp
+check_describe "test-annotated-*" --match="^test-" --extended-regexp
 check_describe_pcre "test-annotated-*" --match="^test-" --perl-regexp
 
 check_describe "test1-lightweight-*" --tags --match="test1-*"
+check_describe "test1-lightweight-*" --tags --match="^test1-" \
+	--extended-regexp
+check_describe "test1-lightweight-*" --tags --match="^test1-" \
+	--basic-regexp
 check_describe_pcre "test1-lightweight-*" --tags --match="^test1-" \
 	--perl-regexp
 
 check_describe "test2-lightweight-*" --tags --match="test2-*"
+check_describe "test2-lightweight-*" --tags --match="^test2-" \
+	--extended-regexp
+check_describe "test2-lightweight-*" --tags --match="^test2-" \
+	--basic-regexp
 check_describe_pcre "test2-lightweight-*" --tags --match="^test2-" \
 	--perl-regexp
 
 check_describe "test2-lightweight-*" --long --tags --match="test2-*" HEAD^
+check_describe "test2-lightweight-*" --long --tags --match="test2-*" \
+	--extended-regexp HEAD^
+check_describe "test2-lightweight-*" --long --tags --match="test2-*" \
+	--basic-regexp HEAD^
 check_describe_pcre "test2-lightweight-*" --long --tags --match="^test2-" \
 	--perl-regexp HEAD^
 
-- 
2.5.0

--
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]