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>
Lars Schneider committed
Oct 16, 2016 at 16:20 UTC
234fa07e066d6bc0728c3d9b92686c69a811e5ac
1 file changed
+34
-26
convert.c
+34
-26
@@ -442,7 +442,7 @@ static int filter_buffer_or_fd(int in, int out, void *data)
442
return (write_err || status);
443
}
444
445
-static int apply_filter(const char *path, const char *src, size_t len, int fd,
445
+static int apply_single_file_filter(const char *path, const char *src, size_t len, int fd,
446
struct strbuf *dst, const char *cmd)
447
{
448
/*
@@ -456,12 +456,6 @@ static int apply_filter(const char *path, const char *src, size_t len, int fd,
456
struct async async;
457
struct filter_params params;
458
459
- if (!cmd || !*cmd)
460
- return 0;
461
-
462
- if (!dst)
463
- return 1;
464
-
459
memset(&async, 0, sizeof(async));
460
async.proc = filter_buffer_or_fd;
461
async.data = ¶ms;
@@ -493,6 +487,9 @@ static int apply_filter(const char *path, const char *src, size_t len, int fd,
487
return !err;
488
}
489
490
+#define CAP_CLEAN (1u<<0)
491
+#define CAP_SMUDGE (1u<<1)
492
+
493
static struct convert_driver {
494
const char *name;
495
struct convert_driver *next;
@@ -501,6 +498,29 @@ static struct convert_driver {
498
int required;
499
} *user_convert, **user_convert_tail;
500
501
+static int apply_filter(const char *path, const char *src, size_t len,
502
+ int fd, struct strbuf *dst, struct convert_driver *drv,
503
+ const unsigned int wanted_capability)
504
+{
505
+ const char *cmd = NULL;
506
+
507
+ if (!drv)
508
+ return 0;
509
+
510
+ if (!dst)
511
+ return 1;
512
+
513
+ if ((CAP_CLEAN & wanted_capability) && drv->clean)
514
+ cmd = drv->clean;
515
+ else if ((CAP_SMUDGE & wanted_capability) && drv->smudge)
516
+ cmd = drv->smudge;
517
+
518
+ if (cmd && *cmd)
519
+ return apply_single_file_filter(path, src, len, fd, dst, cmd);
520
+
521
+ return 0;
522
+}
523
+
524
static int read_convert_config(const char *var, const char *value, void *cb)
525
{
526
const char *key, *name;
@@ -839,7 +859,7 @@ int would_convert_to_git_filter_fd(const char *path)
859
if (!ca.drv->required)
860
return 0;
861
842
- return apply_filter(path, NULL, 0, -1, NULL, ca.drv->clean);
862
+ return apply_filter(path, NULL, 0, -1, NULL, ca.drv, CAP_CLEAN);
863
}
864
865
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,
892
struct strbuf *dst, enum safe_crlf checksafe)
893
{
894
int ret = 0;
875
- const char *filter = NULL;
876
- int required = 0;
895
struct conv_attrs ca;
896
897
convert_attrs(&ca, path);
880
- if (ca.drv) {
881
- filter = ca.drv->clean;
882
- required = ca.drv->required;
883
- }
898
885
- ret |= apply_filter(path, src, len, -1, dst, filter);
886
- if (!ret && required)
899
+ ret |= apply_filter(path, src, len, -1, dst, ca.drv, CAP_CLEAN);
900
+ if (!ret && ca.drv && ca.drv->required)
901
die("%s: clean filter '%s' failed", path, ca.drv->name);
902
903
if (ret && dst) {
@@ -907,7 +921,7 @@ void convert_to_git_filter_fd(const char *path, int fd, struct strbuf *dst,
921
assert(ca.drv);
922
assert(ca.drv->clean);
923
910
- if (!apply_filter(path, NULL, 0, fd, dst, ca.drv->clean))
924
+ if (!apply_filter(path, NULL, 0, fd, dst, ca.drv, CAP_CLEAN))
925
die("%s: clean filter '%s' failed", path, ca.drv->name);
926
927
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,
933
int normalizing)
934
{
935
int ret = 0, ret_filter = 0;
922
- const char *filter = NULL;
923
- int required = 0;
936
struct conv_attrs ca;
937
938
convert_attrs(&ca, path);
927
- if (ca.drv) {
928
- filter = ca.drv->smudge;
929
- required = ca.drv->required;
930
- }
939
940
ret |= ident_to_worktree(path, src, len, dst, ca.ident);
941
if (ret) {
@@ -938,7 +946,7 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
946
* CRLF conversion can be skipped if normalizing, unless there
947
* is a smudge filter. The filter might expect CRLFs.
948
*/
941
- if (filter || !normalizing) {
949
+ if ((ca.drv && ca.drv->smudge) || !normalizing) {
950
ret |= crlf_to_worktree(path, src, len, dst, ca.crlf_action);
951
if (ret) {
952
src = dst->buf;
@@ -946,8 +954,8 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
954
}
955
}
956
949
- ret_filter = apply_filter(path, src, len, -1, dst, filter);
950
- if (!ret_filter && required)
957
+ ret_filter = apply_filter(path, src, len, -1, dst, ca.drv, CAP_SMUDGE);
958
+ if (!ret_filter && ca.drv && ca.drv->required)
959
die("%s: smudge filter %s failed", path, ca.drv->name);
960
961
return ret | ret_filter;