Code

Merge branch 'cn/maint-lf-to-crlf-filter'
authorJunio C Hamano <gitster@pobox.com>
Wed, 14 Dec 2011 06:49:45 +0000 (22:49 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 14 Dec 2011 06:49:45 +0000 (22:49 -0800)
* cn/maint-lf-to-crlf-filter:
  convert: track state in LF-to-CRLF filter

1  2 
convert.c

diff --combined convert.c
index 86e9c29ec05139844ff46868e2b52dfbc274cc39,c2c2c1144df2a65f947943c94d8bb9a29f5e3fcc..346f9d45e0f48048603d779f909e6c29bdd60b5b
+++ b/convert.c
@@@ -641,7 -641,7 +641,7 @@@ static int ident_to_worktree(const cha
        return 1;
  }
  
 -static int git_path_check_crlf(const char *path, struct git_attr_check *check)
 +static enum crlf_action git_path_check_crlf(const char *path, struct git_attr_check *check)
  {
        const char *value = check->value;
  
        return CRLF_GUESS;
  }
  
 -static int git_path_check_eol(const char *path, struct git_attr_check *check)
 +static enum eol git_path_check_eol(const char *path, struct git_attr_check *check)
  {
        const char *value = check->value;
  
@@@ -811,7 -811,7 +811,7 @@@ int renormalize_buffer(const char *path
                src = dst->buf;
                len = dst->len;
        }
 -      return ret | convert_to_git(path, src, len, dst, 0);
 +      return ret | convert_to_git(path, src, len, dst, SAFE_CRLF_FALSE);
  }
  
  /*****************************************************************
@@@ -876,24 -876,39 +876,39 @@@ int is_null_stream_filter(struct stream
  /*
   * LF-to-CRLF filter
   */
+ struct lf_to_crlf_filter {
+       struct stream_filter filter;
+       int want_lf;
+ };
  static int lf_to_crlf_filter_fn(struct stream_filter *filter,
                                const char *input, size_t *isize_p,
                                char *output, size_t *osize_p)
  {
-       size_t count;
+       size_t count, o = 0;
+       struct lf_to_crlf_filter *lf_to_crlf = (struct lf_to_crlf_filter *)filter;
+       /* Output a pending LF if we need to */
+       if (lf_to_crlf->want_lf) {
+               output[o++] = '\n';
+               lf_to_crlf->want_lf = 0;
+       }
  
        if (!input)
-               return 0; /* we do not keep any states */
+               return 0; /* We've already dealt with the state */
        count = *isize_p;
        if (count) {
-               size_t i, o;
-               for (i = o = 0; o < *osize_p && i < count; i++) {
+               size_t i;
+               for (i = 0; o < *osize_p && i < count; i++) {
                        char ch = input[i];
                        if (ch == '\n') {
-                               if (o + 1 < *osize_p)
-                                       output[o++] = '\r';
-                               else
-                                       break;
+                               output[o++] = '\r';
+                               if (o >= *osize_p) {
+                                       lf_to_crlf->want_lf = 1;
+                                       continue; /* We need to increase i */
+                               }
                        }
                        output[o++] = ch;
                }
        return 0;
  }
  
+ static void lf_to_crlf_free_fn(struct stream_filter *filter)
+ {
+       free(filter);
+ }
  static struct stream_filter_vtbl lf_to_crlf_vtbl = {
        lf_to_crlf_filter_fn,
-       null_free_fn,
+       lf_to_crlf_free_fn,
  };
  
- static struct stream_filter lf_to_crlf_filter_singleton = {
-       &lf_to_crlf_vtbl,
};
+ static struct stream_filter *lf_to_crlf_filter(void)
+ {
      struct lf_to_crlf_filter *lf_to_crlf = xmalloc(sizeof(*lf_to_crlf));
  
+       lf_to_crlf->filter.vtbl = &lf_to_crlf_vtbl;
+       lf_to_crlf->want_lf = 0;
+       return (struct stream_filter *)lf_to_crlf;
+ }
  
  /*
   * Cascade filter
@@@ -1194,7 -1218,7 +1218,7 @@@ struct stream_filter *get_stream_filter
  
        else if (output_eol(crlf_action) == EOL_CRLF &&
                 !(crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS))
-               filter = cascade_filter(filter, &lf_to_crlf_filter_singleton);
+               filter = cascade_filter(filter, lf_to_crlf_filter());
  
        return filter;
  }