43
};
44
45
static void diff_filespec_load_driver(struct diff_filespec *one);
46
-static size_t fill_textconv(const char *cmd,
46
+static size_t fill_textconv(struct userdiff_driver *driver,
47
struct diff_filespec *df, char **outbuf);
48
49
static int parse_diff_color_slot(const char *var, int ofs)
466
const char *name_b,
467
struct diff_filespec *one,
468
struct diff_filespec *two,
469
- const char *textconv_one,
470
- const char *textconv_two,
469
+ struct userdiff_driver *textconv_one,
470
+ struct userdiff_driver *textconv_two,
471
struct diff_options *o)
472
{
473
int lc_a, lc_b;
1569
options->b_prefix = b;
1570
}
1571
1572
-static const char *get_textconv(struct diff_filespec *one)
1572
+static struct userdiff_driver *get_textconv(struct diff_filespec *one)
1573
{
1574
if (!DIFF_FILE_VALID(one))
1575
return NULL;
1576
if (!S_ISREG(one->mode))
1577
return NULL;
1578
diff_filespec_load_driver(one);
1579
- return one->driver->textconv;
1579
+ if (!one->driver->textconv)
1580
+ return NULL;
1581
+
1582
+ if (one->driver->textconv_want_cache && !one->driver->textconv_cache) {
1583
+ struct notes_cache *c = xmalloc(sizeof(*c));
1584
+ struct strbuf name = STRBUF_INIT;
1585
+
1586
+ strbuf_addf(&name, "textconv/%s", one->driver->name);
1587
+ notes_cache_init(c, name.buf, one->driver->textconv);
1588
+ one->driver->textconv_cache = c;
1589
+ }
1590
+
1591
+ return one->driver;
1592
}
1593
1594
static void builtin_diff(const char *name_a,
1605
const char *set = diff_get_color_opt(o, DIFF_METAINFO);
1606
const char *reset = diff_get_color_opt(o, DIFF_RESET);
1607
const char *a_prefix, *b_prefix;
1596
- const char *textconv_one = NULL, *textconv_two = NULL;
1608
+ struct userdiff_driver *textconv_one = NULL;
1609
+ struct userdiff_driver *textconv_two = NULL;
1610
struct strbuf header = STRBUF_INIT;
1611
1612
if (DIFF_OPT_TST(o, SUBMODULE_LOG) &&
3901
return strbuf_detach(&buf, outsize);
3902
}
3903
3891
-static size_t fill_textconv(const char *cmd,
3904
+static size_t fill_textconv(struct userdiff_driver *driver,
3905
struct diff_filespec *df,
3906
char **outbuf)
3907
{
3908
size_t size;
3909
3897
- if (!cmd) {
3910
+ if (!driver || !driver->textconv) {
3911
if (!DIFF_FILE_VALID(df)) {
3912
*outbuf = "";
3913
return 0;
3918
return df->size;
3919
}
3920
3908
- *outbuf = run_textconv(cmd, df, &size);
3921
+ if (driver->textconv_cache) {
3922
+ *outbuf = notes_cache_get(driver->textconv_cache, df->sha1,
3923
+ &size);
3924
+ if (*outbuf)
3925
+ return size;
3926
+ }
3927
+
3928
+ *outbuf = run_textconv(driver->textconv, df, &size);
3929
if (!*outbuf)
3930
die("unable to read files to diff");
3931
+
3932
+ if (driver->textconv_cache) {
3933
+ /* ignore errors, as we might be in a readonly repository */
3934
+ notes_cache_put(driver->textconv_cache, df->sha1, *outbuf,
3935
+ size);
3936
+ /*
3937
+ * we could save up changes and flush them all at the end,
3938
+ * but we would need an extra call after all diffing is done.
3939
+ * Since generating a cache entry is the slow path anyway,
3940
+ * this extra overhead probably isn't a big deal.
3941
+ */
3942
+ notes_cache_write(driver->textconv_cache);
3943
+ }
3944
+
3945
return size;
3946
}