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 = &params;
@@ -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;