summaryrefslogtreecommitdiff
path: root/src/diff_driver.c
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2014-01-21 10:39:27 -0800
committerRussell Belfer <rb@github.com>2014-01-24 10:51:08 -0800
commit2c65602e45964f695bda91a6b1cfbf6b2f4903ea (patch)
treeb63770227f21526f96c6de10792f35b02f0f20b0 /src/diff_driver.c
parenta5a386436b823257b9e1b1365d3e36c00a1a5d89 (diff)
downloadlibgit2-2c65602e45964f695bda91a6b1cfbf6b2f4903ea.tar.gz
Import git drivers and test HTML driver
Reorganize the builtin driver table slightly so that core Git builtin definitions can be imported verbatim. Then take a few of the core Git drivers and pull them in. This also creates a test of diffs with the builtin HTML driver which led to some small error handling fixes in the driver selection logic.
Diffstat (limited to 'src/diff_driver.c')
-rw-r--r--src/diff_driver.c59
1 files changed, 43 insertions, 16 deletions
diff --git a/src/diff_driver.c b/src/diff_driver.c
index dcd74adf0..169f7b025 100644
--- a/src/diff_driver.c
+++ b/src/diff_driver.c
@@ -52,10 +52,38 @@ typedef struct {
int flags;
} git_diff_driver_definition;
+#define WORD_DEFAULT "|[^[:space:]]|[\xc0-\xff][\x80-\xbf]+"
+
+/* builtin driver definition macros have same signature as in core git
+ * userdiff.c so that the data can be extracted verbatim
+ */
+#define PATTERNS(NAME, FN_PATS, WORD_PAT) \
+ { NAME, FN_PATS, WORD_PAT WORD_DEFAULT, 0 }
+#define IPATTERN(NAME, FN_PATS, WORD_PAT) \
+ { NAME, FN_PATS, WORD_PAT WORD_DEFAULT, REG_ICASE }
+
static git_diff_driver_definition builtin_defs[] = {
- { "html", "^[ \t]*(<h[1-8]([ \t][^>]*)?>.*)$", "[^<> \t]+", REG_ICASE },
+PATTERNS("html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$",
+ "[^<>= \t]+"),
+PATTERNS("java",
+ "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
+ "^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$",
+ /* -- */
+ "[a-zA-Z_][a-zA-Z0-9_]*"
+ "|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
+ "|[-+*/<>%&^|=!]="
+ "|--|\\+\\+|<<=?|>>>?=?|&&|\\|\\|"),
+PATTERNS("ruby", "^[ \t]*((class|module|def)[ \t].*)$",
+ /* -- */
+ "(@|@@|\\$)?[a-zA-Z_][a-zA-Z0-9_]*"
+ "|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+|\\?(\\\\C-)?(\\\\M-)?."
+ "|//=?|[-+*/<>%&^|=!]=|<<=?|>>=?|===|\\.{1,3}|::|[!=]~"),
};
+#undef IPATTERN
+#undef PATTERNS
+#undef WORD_DEFAULT
+
struct git_diff_driver_registry {
git_strmap *drivers;
};
@@ -208,14 +236,14 @@ static int git_diff_driver_builtin(
}
git_strmap_insert(reg->drivers, drv->name, drv, error);
+ if (error > 0)
+ error = 0;
done:
- if (error || !drv) {
+ if (error && drv)
git_diff_driver_free(drv);
- *out = &global_drivers[DIFF_DRIVER_AUTO];
- } else {
+ else
*out = drv;
- }
return error;
}
@@ -324,6 +352,7 @@ static int git_diff_driver_load(
git_strmap_insert(reg->drivers, drv->name, drv, error);
if (error < 0)
goto done;
+ error = 0;
*out = drv;
@@ -349,14 +378,13 @@ int git_diff_driver_lookup(
const char *value;
assert(out);
+ *out = NULL;
if (!repo || !path || !strlen(path))
- goto use_auto;
-
- if ((error = git_attr_get(&value, repo, 0, path, "diff")) < 0)
- return error;
-
- if (GIT_ATTR_UNSPECIFIED(value))
+ /* just use the auto value */;
+ else if ((error = git_attr_get(&value, repo, 0, path, "diff")) < 0)
+ /* return error below */;
+ else if (GIT_ATTR_UNSPECIFIED(value))
/* just use the auto value */;
else if (GIT_ATTR_FALSE(value))
*out = &global_drivers[DIFF_DRIVER_BINARY];
@@ -365,17 +393,16 @@ int git_diff_driver_lookup(
/* otherwise look for driver information in config and build driver */
else if ((error = git_diff_driver_load(out, repo, value)) < 0) {
- if (error != GIT_ENOTFOUND)
- return error;
- else
+ if (error == GIT_ENOTFOUND) {
+ error = 0;
giterr_clear();
+ }
}
-use_auto:
if (!*out)
*out = &global_drivers[DIFF_DRIVER_AUTO];
- return 0;
+ return error;
}
void git_diff_driver_free(git_diff_driver *driver)