aboutsummaryrefslogtreecommitdiff
path: root/diff.c
diff options
context:
space:
mode:
Diffstat (limited to 'diff.c')
-rw-r--r--diff.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/diff.c b/diff.c
index dabd7f50e..e368fef14 100644
--- a/diff.c
+++ b/diff.c
@@ -38,6 +38,9 @@ static char diff_colors[][COLOR_MAXLEN] = {
"\033[41m", /* WHITESPACE (red background) */
};
+static void diff_filespec_load_driver(struct diff_filespec *one);
+static char *run_textconv(const char *, struct diff_filespec *, size_t *);
+
static int parse_diff_color_slot(const char *var, int ofs)
{
if (!strcasecmp(var+ofs, "plain"))
@@ -290,8 +293,19 @@ static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
}
else if (diff_populate_filespec(one, 0))
return -1;
- mf->ptr = one->data;
- mf->size = one->size;
+
+ diff_filespec_load_driver(one);
+ if (one->driver->textconv) {
+ size_t size;
+ mf->ptr = run_textconv(one->driver->textconv, one, &size);
+ if (!mf->ptr)
+ return -1;
+ mf->size = size;
+ }
+ else {
+ mf->ptr = one->data;
+ mf->size = one->size;
+ }
return 0;
}
@@ -3373,3 +3387,34 @@ void diff_unmerge(struct diff_options *options,
fill_filespec(one, sha1, mode);
diff_queue(&diff_queued_diff, one, two)->is_unmerged = 1;
}
+
+static char *run_textconv(const char *pgm, struct diff_filespec *spec,
+ size_t *outsize)
+{
+ struct diff_tempfile temp;
+ const char *argv[3];
+ const char **arg = argv;
+ struct child_process child;
+ struct strbuf buf = STRBUF_INIT;
+
+ prepare_temp_file(spec->path, &temp, spec);
+ *arg++ = pgm;
+ *arg++ = temp.name;
+ *arg = NULL;
+
+ memset(&child, 0, sizeof(child));
+ child.argv = argv;
+ child.out = -1;
+ if (start_command(&child) != 0 ||
+ strbuf_read(&buf, child.out, 0) < 0 ||
+ finish_command(&child) != 0) {
+ if (temp.name == temp.tmp_path)
+ unlink(temp.name);
+ error("error running textconv command '%s'", pgm);
+ return NULL;
+ }
+ if (temp.name == temp.tmp_path)
+ unlink(temp.name);
+
+ return strbuf_detach(&buf, outsize);
+}