convert: prepare filter.<driver>.process option

Refactor the existing 'single shot filter mechanism' and prepare the
new 'long running filter mechanism'.

Signed-off-by: Lars Schneider <larsxschneider@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Lars Schneider 2016-10-16 16:20:36 -07:00 committed by Junio C Hamano
parent b84be55354
commit 234fa07e06

View File

@ -442,7 +442,7 @@ static int filter_buffer_or_fd(int in, int out, void *data)
return (write_err || status); return (write_err || status);
} }
static int apply_filter(const char *path, const char *src, size_t len, int fd, static int apply_single_file_filter(const char *path, const char *src, size_t len, int fd,
struct strbuf *dst, const char *cmd) struct strbuf *dst, const char *cmd)
{ {
/* /*
@ -456,12 +456,6 @@ static int apply_filter(const char *path, const char *src, size_t len, int fd,
struct async async; struct async async;
struct filter_params params; struct filter_params params;
if (!cmd || !*cmd)
return 0;
if (!dst)
return 1;
memset(&async, 0, sizeof(async)); memset(&async, 0, sizeof(async));
async.proc = filter_buffer_or_fd; async.proc = filter_buffer_or_fd;
async.data = &params; async.data = &params;
@ -493,6 +487,9 @@ static int apply_filter(const char *path, const char *src, size_t len, int fd,
return !err; return !err;
} }
#define CAP_CLEAN (1u<<0)
#define CAP_SMUDGE (1u<<1)
static struct convert_driver { static struct convert_driver {
const char *name; const char *name;
struct convert_driver *next; struct convert_driver *next;
@ -501,6 +498,29 @@ static struct convert_driver {
int required; int required;
} *user_convert, **user_convert_tail; } *user_convert, **user_convert_tail;
static int apply_filter(const char *path, const char *src, size_t len,
int fd, struct strbuf *dst, struct convert_driver *drv,
const unsigned int wanted_capability)
{
const char *cmd = NULL;
if (!drv)
return 0;
if (!dst)
return 1;
if ((CAP_CLEAN & wanted_capability) && drv->clean)
cmd = drv->clean;
else if ((CAP_SMUDGE & wanted_capability) && drv->smudge)
cmd = drv->smudge;
if (cmd && *cmd)
return apply_single_file_filter(path, src, len, fd, dst, cmd);
return 0;
}
static int read_convert_config(const char *var, const char *value, void *cb) static int read_convert_config(const char *var, const char *value, void *cb)
{ {
const char *key, *name; const char *key, *name;
@ -839,7 +859,7 @@ int would_convert_to_git_filter_fd(const char *path)
if (!ca.drv->required) if (!ca.drv->required)
return 0; return 0;
return apply_filter(path, NULL, 0, -1, NULL, ca.drv->clean); return apply_filter(path, NULL, 0, -1, NULL, ca.drv, CAP_CLEAN);
} }
const char *get_convert_attr_ascii(const char *path) const char *get_convert_attr_ascii(const char *path)
@ -872,18 +892,12 @@ int convert_to_git(const char *path, const char *src, size_t len,
struct strbuf *dst, enum safe_crlf checksafe) struct strbuf *dst, enum safe_crlf checksafe)
{ {
int ret = 0; int ret = 0;
const char *filter = NULL;
int required = 0;
struct conv_attrs ca; struct conv_attrs ca;
convert_attrs(&ca, path); convert_attrs(&ca, path);
if (ca.drv) {
filter = ca.drv->clean;
required = ca.drv->required;
}
ret |= apply_filter(path, src, len, -1, dst, filter); ret |= apply_filter(path, src, len, -1, dst, ca.drv, CAP_CLEAN);
if (!ret && required) if (!ret && ca.drv && ca.drv->required)
die("%s: clean filter '%s' failed", path, ca.drv->name); die("%s: clean filter '%s' failed", path, ca.drv->name);
if (ret && dst) { if (ret && dst) {
@ -907,7 +921,7 @@ void convert_to_git_filter_fd(const char *path, int fd, struct strbuf *dst,
assert(ca.drv); assert(ca.drv);
assert(ca.drv->clean); assert(ca.drv->clean);
if (!apply_filter(path, NULL, 0, fd, dst, ca.drv->clean)) if (!apply_filter(path, NULL, 0, fd, dst, ca.drv, CAP_CLEAN))
die("%s: clean filter '%s' failed", path, ca.drv->name); die("%s: clean filter '%s' failed", path, ca.drv->name);
crlf_to_git(path, dst->buf, dst->len, dst, ca.crlf_action, checksafe); crlf_to_git(path, dst->buf, dst->len, dst, ca.crlf_action, checksafe);
@ -919,15 +933,9 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
int normalizing) int normalizing)
{ {
int ret = 0, ret_filter = 0; int ret = 0, ret_filter = 0;
const char *filter = NULL;
int required = 0;
struct conv_attrs ca; struct conv_attrs ca;
convert_attrs(&ca, path); convert_attrs(&ca, path);
if (ca.drv) {
filter = ca.drv->smudge;
required = ca.drv->required;
}
ret |= ident_to_worktree(path, src, len, dst, ca.ident); ret |= ident_to_worktree(path, src, len, dst, ca.ident);
if (ret) { if (ret) {
@ -938,7 +946,7 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
* CRLF conversion can be skipped if normalizing, unless there * CRLF conversion can be skipped if normalizing, unless there
* is a smudge filter. The filter might expect CRLFs. * is a smudge filter. The filter might expect CRLFs.
*/ */
if (filter || !normalizing) { if ((ca.drv && ca.drv->smudge) || !normalizing) {
ret |= crlf_to_worktree(path, src, len, dst, ca.crlf_action); ret |= crlf_to_worktree(path, src, len, dst, ca.crlf_action);
if (ret) { if (ret) {
src = dst->buf; src = dst->buf;
@ -946,8 +954,8 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
} }
} }
ret_filter = apply_filter(path, src, len, -1, dst, filter); ret_filter = apply_filter(path, src, len, -1, dst, ca.drv, CAP_SMUDGE);
if (!ret_filter && required) if (!ret_filter && ca.drv && ca.drv->required)
die("%s: smudge filter %s failed", path, ca.drv->name); die("%s: smudge filter %s failed", path, ca.drv->name);
return ret | ret_filter; return ret | ret_filter;