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 коммит произвёл Junio C Hamano
Родитель b84be55354
Коммит 234fa07e06
1 изменённых файлов: 34 добавлений и 26 удалений

Просмотреть файл

@ -442,7 +442,7 @@ static int filter_buffer_or_fd(int in, int out, void *data)
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)
{
/*
@ -456,12 +456,6 @@ static int apply_filter(const char *path, const char *src, size_t len, int fd,
struct async async;
struct filter_params params;
if (!cmd || !*cmd)
return 0;
if (!dst)
return 1;
memset(&async, 0, sizeof(async));
async.proc = filter_buffer_or_fd;
async.data = &params;
@ -493,6 +487,9 @@ static int apply_filter(const char *path, const char *src, size_t len, int fd,
return !err;
}
#define CAP_CLEAN (1u<<0)
#define CAP_SMUDGE (1u<<1)
static struct convert_driver {
const char *name;
struct convert_driver *next;
@ -501,6 +498,29 @@ static struct convert_driver {
int required;
} *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)
{
const char *key, *name;
@ -839,7 +859,7 @@ int would_convert_to_git_filter_fd(const char *path)
if (!ca.drv->required)
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)
@ -872,18 +892,12 @@ int convert_to_git(const char *path, const char *src, size_t len,
struct strbuf *dst, enum safe_crlf checksafe)
{
int ret = 0;
const char *filter = NULL;
int required = 0;
struct conv_attrs ca;
convert_attrs(&ca, path);
if (ca.drv) {
filter = ca.drv->clean;
required = ca.drv->required;
}
ret |= apply_filter(path, src, len, -1, dst, filter);
if (!ret && required)
ret |= apply_filter(path, src, len, -1, dst, ca.drv, CAP_CLEAN);
if (!ret && ca.drv && ca.drv->required)
die("%s: clean filter '%s' failed", path, ca.drv->name);
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->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);
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 ret = 0, ret_filter = 0;
const char *filter = NULL;
int required = 0;
struct conv_attrs ca;
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);
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
* 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);
if (ret) {
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);
if (!ret_filter && required)
ret_filter = apply_filter(path, src, len, -1, dst, ca.drv, CAP_SMUDGE);
if (!ret_filter && ca.drv && ca.drv->required)
die("%s: smudge filter %s failed", path, ca.drv->name);
return ret | ret_filter;