summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2016-02-22 13:28:54 -0500
committerJunio C Hamano <gitster@pobox.com>2016-02-22 10:40:35 -0800
commita64e6a44c63a965c5bc26242ddd3ed049b42e117 (patch)
tree7bf3c3388e48bcbc548da65a688ba2425afc42f0
parenta2558fb8e1e387b630312311e1d22c95663da5d0 (diff)
downloadgit-a64e6a44c63a965c5bc26242ddd3ed049b42e117.tar.gz
diff: clarify textconv interfacejk/more-comments-on-textconv
The memory allocation scheme for the textconv interface is a bit tricky, and not well documented. It was originally designed as an internal part of diff.c (matching fill_mmfile), but gradually was made public. Refactoring it is difficult, but we can at least improve the situation by documenting the intended flow and enforcing it with an in-code assertion. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--diff.c5
-rw-r--r--diff.h16
-rw-r--r--userdiff.h4
3 files changed, 24 insertions, 1 deletions
diff --git a/diff.c b/diff.c
index f62b7f73d8..a09b0b6ae3 100644
--- a/diff.c
+++ b/diff.c
@@ -4996,7 +4996,7 @@ size_t fill_textconv(struct userdiff_driver *driver,
{
size_t size;
- if (!driver || !driver->textconv) {
+ if (!driver) {
if (!DIFF_FILE_VALID(df)) {
*outbuf = "";
return 0;
@@ -5007,6 +5007,9 @@ size_t fill_textconv(struct userdiff_driver *driver,
return df->size;
}
+ if (!driver->textconv)
+ die("BUG: fill_textconv called with non-textconv driver");
+
if (driver->textconv_cache && df->sha1_valid) {
*outbuf = notes_cache_get(driver->textconv_cache, df->sha1,
&size);
diff --git a/diff.h b/diff.h
index 1ac0582228..65a5e78f64 100644
--- a/diff.h
+++ b/diff.h
@@ -342,10 +342,26 @@ extern void diff_no_index(struct rev_info *, int, const char **, const char *);
extern int index_differs_from(const char *def, int diff_flags);
+/*
+ * Fill the contents of the filespec "df", respecting any textconv defined by
+ * its userdiff driver. The "driver" parameter must come from a
+ * previous call to get_textconv(), and therefore should either be NULL or have
+ * textconv enabled.
+ *
+ * Note that the memory ownership of the resulting buffer depends on whether
+ * the driver field is NULL. If it is, then the memory belongs to the filespec
+ * struct. If it is non-NULL, then "outbuf" points to a newly allocated buffer
+ * that should be freed by the caller.
+ */
extern size_t fill_textconv(struct userdiff_driver *driver,
struct diff_filespec *df,
char **outbuf);
+/*
+ * Look up the userdiff driver for the given filespec, and return it if
+ * and only if it has textconv enabled (otherwise return NULL). The result
+ * can be passed to fill_textconv().
+ */
extern struct userdiff_driver *get_textconv(struct diff_filespec *one);
extern int parse_rename_score(const char **cp_p);
diff --git a/userdiff.h b/userdiff.h
index 4a7e78ffbc..2ef0ce5452 100644
--- a/userdiff.h
+++ b/userdiff.h
@@ -23,6 +23,10 @@ int userdiff_config(const char *k, const char *v);
struct userdiff_driver *userdiff_find_by_name(const char *name);
struct userdiff_driver *userdiff_find_by_path(const char *path);
+/*
+ * Initialize any textconv-related fields in the driver and return it, or NULL
+ * if it does not have textconv enabled at all.
+ */
struct userdiff_driver *userdiff_get_textconv(struct userdiff_driver *driver);
#endif /* USERDIFF */