Signed-off-by: Mostyn Bramley-Moore <most...@opera.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to