Code

Merge branch 'jb/filter-ignore-sigpipe'
[git.git] / convert.c
1 #include "cache.h"
2 #include "attr.h"
3 #include "run-command.h"
4 #include "quote.h"
5 #include "sigchain.h"
7 /*
8  * convert.c - convert a file when checking it out and checking it in.
9  *
10  * This should use the pathname to decide on whether it wants to do some
11  * more interesting conversions (automatic gzip/unzip, general format
12  * conversions etc etc), but by default it just does automatic CRLF<->LF
13  * translation when the "text" attribute or "auto_crlf" option is set.
14  */
16 enum crlf_action {
17         CRLF_GUESS = -1,
18         CRLF_BINARY = 0,
19         CRLF_TEXT,
20         CRLF_INPUT,
21         CRLF_CRLF,
22         CRLF_AUTO
23 };
25 struct text_stat {
26         /* NUL, CR, LF and CRLF counts */
27         unsigned nul, cr, lf, crlf;
29         /* These are just approximations! */
30         unsigned printable, nonprintable;
31 };
33 static void gather_stats(const char *buf, unsigned long size, struct text_stat *stats)
34 {
35         unsigned long i;
37         memset(stats, 0, sizeof(*stats));
39         for (i = 0; i < size; i++) {
40                 unsigned char c = buf[i];
41                 if (c == '\r') {
42                         stats->cr++;
43                         if (i+1 < size && buf[i+1] == '\n')
44                                 stats->crlf++;
45                         continue;
46                 }
47                 if (c == '\n') {
48                         stats->lf++;
49                         continue;
50                 }
51                 if (c == 127)
52                         /* DEL */
53                         stats->nonprintable++;
54                 else if (c < 32) {
55                         switch (c) {
56                                 /* BS, HT, ESC and FF */
57                         case '\b': case '\t': case '\033': case '\014':
58                                 stats->printable++;
59                                 break;
60                         case 0:
61                                 stats->nul++;
62                                 /* fall through */
63                         default:
64                                 stats->nonprintable++;
65                         }
66                 }
67                 else
68                         stats->printable++;
69         }
71         /* If file ends with EOF then don't count this EOF as non-printable. */
72         if (size >= 1 && buf[size-1] == '\032')
73                 stats->nonprintable--;
74 }
76 /*
77  * The same heuristics as diff.c::mmfile_is_binary()
78  */
79 static int is_binary(unsigned long size, struct text_stat *stats)
80 {
82         if (stats->nul)
83                 return 1;
84         if ((stats->printable >> 7) < stats->nonprintable)
85                 return 1;
86         /*
87          * Other heuristics? Average line length might be relevant,
88          * as might LF vs CR vs CRLF counts..
89          *
90          * NOTE! It might be normal to have a low ratio of CRLF to LF
91          * (somebody starts with a LF-only file and edits it with an editor
92          * that adds CRLF only to lines that are added..). But do  we
93          * want to support CR-only? Probably not.
94          */
95         return 0;
96 }
98 static enum eol output_eol(enum crlf_action crlf_action)
99 {
100         switch (crlf_action) {
101         case CRLF_BINARY:
102                 return EOL_UNSET;
103         case CRLF_CRLF:
104                 return EOL_CRLF;
105         case CRLF_INPUT:
106                 return EOL_LF;
107         case CRLF_GUESS:
108                 if (!auto_crlf)
109                         return EOL_UNSET;
110                 /* fall through */
111         case CRLF_TEXT:
112         case CRLF_AUTO:
113                 if (auto_crlf == AUTO_CRLF_TRUE)
114                         return EOL_CRLF;
115                 else if (auto_crlf == AUTO_CRLF_INPUT)
116                         return EOL_LF;
117                 else if (core_eol == EOL_UNSET)
118                         return EOL_NATIVE;
119         }
120         return core_eol;
123 static void check_safe_crlf(const char *path, enum crlf_action crlf_action,
124                             struct text_stat *stats, enum safe_crlf checksafe)
126         if (!checksafe)
127                 return;
129         if (output_eol(crlf_action) == EOL_LF) {
130                 /*
131                  * CRLFs would not be restored by checkout:
132                  * check if we'd remove CRLFs
133                  */
134                 if (stats->crlf) {
135                         if (checksafe == SAFE_CRLF_WARN)
136                                 warning("CRLF will be replaced by LF in %s.\nThe file will have its original line endings in your working directory.", path);
137                         else /* i.e. SAFE_CRLF_FAIL */
138                                 die("CRLF would be replaced by LF in %s.", path);
139                 }
140         } else if (output_eol(crlf_action) == EOL_CRLF) {
141                 /*
142                  * CRLFs would be added by checkout:
143                  * check if we have "naked" LFs
144                  */
145                 if (stats->lf != stats->crlf) {
146                         if (checksafe == SAFE_CRLF_WARN)
147                                 warning("LF will be replaced by CRLF in %s.\nThe file will have its original line endings in your working directory.", path);
148                         else /* i.e. SAFE_CRLF_FAIL */
149                                 die("LF would be replaced by CRLF in %s", path);
150                 }
151         }
154 static int has_cr_in_index(const char *path)
156         int pos, len;
157         unsigned long sz;
158         enum object_type type;
159         void *data;
160         int has_cr;
161         struct index_state *istate = &the_index;
163         len = strlen(path);
164         pos = index_name_pos(istate, path, len);
165         if (pos < 0) {
166                 /*
167                  * We might be in the middle of a merge, in which
168                  * case we would read stage #2 (ours).
169                  */
170                 int i;
171                 for (i = -pos - 1;
172                      (pos < 0 && i < istate->cache_nr &&
173                       !strcmp(istate->cache[i]->name, path));
174                      i++)
175                         if (ce_stage(istate->cache[i]) == 2)
176                                 pos = i;
177         }
178         if (pos < 0)
179                 return 0;
180         data = read_sha1_file(istate->cache[pos]->sha1, &type, &sz);
181         if (!data || type != OBJ_BLOB) {
182                 free(data);
183                 return 0;
184         }
186         has_cr = memchr(data, '\r', sz) != NULL;
187         free(data);
188         return has_cr;
191 static int crlf_to_git(const char *path, const char *src, size_t len,
192                        struct strbuf *buf,
193                        enum crlf_action crlf_action, enum safe_crlf checksafe)
195         struct text_stat stats;
196         char *dst;
198         if (crlf_action == CRLF_BINARY ||
199             (crlf_action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE) || !len)
200                 return 0;
202         gather_stats(src, len, &stats);
204         if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS) {
205                 /*
206                  * We're currently not going to even try to convert stuff
207                  * that has bare CR characters. Does anybody do that crazy
208                  * stuff?
209                  */
210                 if (stats.cr != stats.crlf)
211                         return 0;
213                 /*
214                  * And add some heuristics for binary vs text, of course...
215                  */
216                 if (is_binary(len, &stats))
217                         return 0;
219                 if (crlf_action == CRLF_GUESS) {
220                         /*
221                          * If the file in the index has any CR in it, do not convert.
222                          * This is the new safer autocrlf handling.
223                          */
224                         if (has_cr_in_index(path))
225                                 return 0;
226                 }
227         }
229         check_safe_crlf(path, crlf_action, &stats, checksafe);
231         /* Optimization: No CR? Nothing to convert, regardless. */
232         if (!stats.cr)
233                 return 0;
235         /* only grow if not in place */
236         if (strbuf_avail(buf) + buf->len < len)
237                 strbuf_grow(buf, len - buf->len);
238         dst = buf->buf;
239         if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS) {
240                 /*
241                  * If we guessed, we already know we rejected a file with
242                  * lone CR, and we can strip a CR without looking at what
243                  * follow it.
244                  */
245                 do {
246                         unsigned char c = *src++;
247                         if (c != '\r')
248                                 *dst++ = c;
249                 } while (--len);
250         } else {
251                 do {
252                         unsigned char c = *src++;
253                         if (! (c == '\r' && (1 < len && *src == '\n')))
254                                 *dst++ = c;
255                 } while (--len);
256         }
257         strbuf_setlen(buf, dst - buf->buf);
258         return 1;
261 static int crlf_to_worktree(const char *path, const char *src, size_t len,
262                             struct strbuf *buf, enum crlf_action crlf_action)
264         char *to_free = NULL;
265         struct text_stat stats;
267         if (!len || output_eol(crlf_action) != EOL_CRLF)
268                 return 0;
270         gather_stats(src, len, &stats);
272         /* No LF? Nothing to convert, regardless. */
273         if (!stats.lf)
274                 return 0;
276         /* Was it already in CRLF format? */
277         if (stats.lf == stats.crlf)
278                 return 0;
280         if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS) {
281                 if (crlf_action == CRLF_GUESS) {
282                         /* If we have any CR or CRLF line endings, we do not touch it */
283                         /* This is the new safer autocrlf-handling */
284                         if (stats.cr > 0 || stats.crlf > 0)
285                                 return 0;
286                 }
288                 /* If we have any bare CR characters, we're not going to touch it */
289                 if (stats.cr != stats.crlf)
290                         return 0;
292                 if (is_binary(len, &stats))
293                         return 0;
294         }
296         /* are we "faking" in place editing ? */
297         if (src == buf->buf)
298                 to_free = strbuf_detach(buf, NULL);
300         strbuf_grow(buf, len + stats.lf - stats.crlf);
301         for (;;) {
302                 const char *nl = memchr(src, '\n', len);
303                 if (!nl)
304                         break;
305                 if (nl > src && nl[-1] == '\r') {
306                         strbuf_add(buf, src, nl + 1 - src);
307                 } else {
308                         strbuf_add(buf, src, nl - src);
309                         strbuf_addstr(buf, "\r\n");
310                 }
311                 len -= nl + 1 - src;
312                 src  = nl + 1;
313         }
314         strbuf_add(buf, src, len);
316         free(to_free);
317         return 1;
320 struct filter_params {
321         const char *src;
322         unsigned long size;
323         const char *cmd;
324         const char *path;
325 };
327 static int filter_buffer(int in, int out, void *data)
329         /*
330          * Spawn cmd and feed the buffer contents through its stdin.
331          */
332         struct child_process child_process;
333         struct filter_params *params = (struct filter_params *)data;
334         int write_err, status;
335         const char *argv[] = { NULL, NULL };
337         /* apply % substitution to cmd */
338         struct strbuf cmd = STRBUF_INIT;
339         struct strbuf path = STRBUF_INIT;
340         struct strbuf_expand_dict_entry dict[] = {
341                 { "f", NULL, },
342                 { NULL, NULL, },
343         };
345         /* quote the path to preserve spaces, etc. */
346         sq_quote_buf(&path, params->path);
347         dict[0].value = path.buf;
349         /* expand all %f with the quoted path */
350         strbuf_expand(&cmd, params->cmd, strbuf_expand_dict_cb, &dict);
351         strbuf_release(&path);
353         argv[0] = cmd.buf;
355         memset(&child_process, 0, sizeof(child_process));
356         child_process.argv = argv;
357         child_process.use_shell = 1;
358         child_process.in = -1;
359         child_process.out = out;
361         if (start_command(&child_process))
362                 return error("cannot fork to run external filter %s", params->cmd);
364         sigchain_push(SIGPIPE, SIG_IGN);
366         write_err = (write_in_full(child_process.in, params->src, params->size) < 0);
367         if (close(child_process.in))
368                 write_err = 1;
369         if (write_err)
370                 error("cannot feed the input to external filter %s", params->cmd);
372         sigchain_pop(SIGPIPE);
374         status = finish_command(&child_process);
375         if (status)
376                 error("external filter %s failed %d", params->cmd, status);
378         strbuf_release(&cmd);
379         return (write_err || status);
382 static int apply_filter(const char *path, const char *src, size_t len,
383                         struct strbuf *dst, const char *cmd)
385         /*
386          * Create a pipeline to have the command filter the buffer's
387          * contents.
388          *
389          * (child --> cmd) --> us
390          */
391         int ret = 1;
392         struct strbuf nbuf = STRBUF_INIT;
393         struct async async;
394         struct filter_params params;
396         if (!cmd)
397                 return 0;
399         memset(&async, 0, sizeof(async));
400         async.proc = filter_buffer;
401         async.data = &params;
402         async.out = -1;
403         params.src = src;
404         params.size = len;
405         params.cmd = cmd;
406         params.path = path;
408         fflush(NULL);
409         if (start_async(&async))
410                 return 0;       /* error was already reported */
412         if (strbuf_read(&nbuf, async.out, len) < 0) {
413                 error("read from external filter %s failed", cmd);
414                 ret = 0;
415         }
416         if (close(async.out)) {
417                 error("read from external filter %s failed", cmd);
418                 ret = 0;
419         }
420         if (finish_async(&async)) {
421                 error("external filter %s failed", cmd);
422                 ret = 0;
423         }
425         if (ret) {
426                 strbuf_swap(dst, &nbuf);
427         }
428         strbuf_release(&nbuf);
429         return ret;
432 static struct convert_driver {
433         const char *name;
434         struct convert_driver *next;
435         const char *smudge;
436         const char *clean;
437 } *user_convert, **user_convert_tail;
439 static int read_convert_config(const char *var, const char *value, void *cb)
441         const char *ep, *name;
442         int namelen;
443         struct convert_driver *drv;
445         /*
446          * External conversion drivers are configured using
447          * "filter.<name>.variable".
448          */
449         if (prefixcmp(var, "filter.") || (ep = strrchr(var, '.')) == var + 6)
450                 return 0;
451         name = var + 7;
452         namelen = ep - name;
453         for (drv = user_convert; drv; drv = drv->next)
454                 if (!strncmp(drv->name, name, namelen) && !drv->name[namelen])
455                         break;
456         if (!drv) {
457                 drv = xcalloc(1, sizeof(struct convert_driver));
458                 drv->name = xmemdupz(name, namelen);
459                 *user_convert_tail = drv;
460                 user_convert_tail = &(drv->next);
461         }
463         ep++;
465         /*
466          * filter.<name>.smudge and filter.<name>.clean specifies
467          * the command line:
468          *
469          *      command-line
470          *
471          * The command-line will not be interpolated in any way.
472          */
474         if (!strcmp("smudge", ep))
475                 return git_config_string(&drv->smudge, var, value);
477         if (!strcmp("clean", ep))
478                 return git_config_string(&drv->clean, var, value);
480         return 0;
483 static int count_ident(const char *cp, unsigned long size)
485         /*
486          * "$Id: 0000000000000000000000000000000000000000 $" <=> "$Id$"
487          */
488         int cnt = 0;
489         char ch;
491         while (size) {
492                 ch = *cp++;
493                 size--;
494                 if (ch != '$')
495                         continue;
496                 if (size < 3)
497                         break;
498                 if (memcmp("Id", cp, 2))
499                         continue;
500                 ch = cp[2];
501                 cp += 3;
502                 size -= 3;
503                 if (ch == '$')
504                         cnt++; /* $Id$ */
505                 if (ch != ':')
506                         continue;
508                 /*
509                  * "$Id: ... "; scan up to the closing dollar sign and discard.
510                  */
511                 while (size) {
512                         ch = *cp++;
513                         size--;
514                         if (ch == '$') {
515                                 cnt++;
516                                 break;
517                         }
518                         if (ch == '\n')
519                                 break;
520                 }
521         }
522         return cnt;
525 static int ident_to_git(const char *path, const char *src, size_t len,
526                         struct strbuf *buf, int ident)
528         char *dst, *dollar;
530         if (!ident || !count_ident(src, len))
531                 return 0;
533         /* only grow if not in place */
534         if (strbuf_avail(buf) + buf->len < len)
535                 strbuf_grow(buf, len - buf->len);
536         dst = buf->buf;
537         for (;;) {
538                 dollar = memchr(src, '$', len);
539                 if (!dollar)
540                         break;
541                 memmove(dst, src, dollar + 1 - src);
542                 dst += dollar + 1 - src;
543                 len -= dollar + 1 - src;
544                 src  = dollar + 1;
546                 if (len > 3 && !memcmp(src, "Id:", 3)) {
547                         dollar = memchr(src + 3, '$', len - 3);
548                         if (!dollar)
549                                 break;
550                         if (memchr(src + 3, '\n', dollar - src - 3)) {
551                                 /* Line break before the next dollar. */
552                                 continue;
553                         }
555                         memcpy(dst, "Id$", 3);
556                         dst += 3;
557                         len -= dollar + 1 - src;
558                         src  = dollar + 1;
559                 }
560         }
561         memmove(dst, src, len);
562         strbuf_setlen(buf, dst + len - buf->buf);
563         return 1;
566 static int ident_to_worktree(const char *path, const char *src, size_t len,
567                              struct strbuf *buf, int ident)
569         unsigned char sha1[20];
570         char *to_free = NULL, *dollar, *spc;
571         int cnt;
573         if (!ident)
574                 return 0;
576         cnt = count_ident(src, len);
577         if (!cnt)
578                 return 0;
580         /* are we "faking" in place editing ? */
581         if (src == buf->buf)
582                 to_free = strbuf_detach(buf, NULL);
583         hash_sha1_file(src, len, "blob", sha1);
585         strbuf_grow(buf, len + cnt * 43);
586         for (;;) {
587                 /* step 1: run to the next '$' */
588                 dollar = memchr(src, '$', len);
589                 if (!dollar)
590                         break;
591                 strbuf_add(buf, src, dollar + 1 - src);
592                 len -= dollar + 1 - src;
593                 src  = dollar + 1;
595                 /* step 2: does it looks like a bit like Id:xxx$ or Id$ ? */
596                 if (len < 3 || memcmp("Id", src, 2))
597                         continue;
599                 /* step 3: skip over Id$ or Id:xxxxx$ */
600                 if (src[2] == '$') {
601                         src += 3;
602                         len -= 3;
603                 } else if (src[2] == ':') {
604                         /*
605                          * It's possible that an expanded Id has crept its way into the
606                          * repository, we cope with that by stripping the expansion out.
607                          * This is probably not a good idea, since it will cause changes
608                          * on checkout, which won't go away by stash, but let's keep it
609                          * for git-style ids.
610                          */
611                         dollar = memchr(src + 3, '$', len - 3);
612                         if (!dollar) {
613                                 /* incomplete keyword, no more '$', so just quit the loop */
614                                 break;
615                         }
617                         if (memchr(src + 3, '\n', dollar - src - 3)) {
618                                 /* Line break before the next dollar. */
619                                 continue;
620                         }
622                         spc = memchr(src + 4, ' ', dollar - src - 4);
623                         if (spc && spc < dollar-1) {
624                                 /* There are spaces in unexpected places.
625                                  * This is probably an id from some other
626                                  * versioning system. Keep it for now.
627                                  */
628                                 continue;
629                         }
631                         len -= dollar + 1 - src;
632                         src  = dollar + 1;
633                 } else {
634                         /* it wasn't a "Id$" or "Id:xxxx$" */
635                         continue;
636                 }
638                 /* step 4: substitute */
639                 strbuf_addstr(buf, "Id: ");
640                 strbuf_add(buf, sha1_to_hex(sha1), 40);
641                 strbuf_addstr(buf, " $");
642         }
643         strbuf_add(buf, src, len);
645         free(to_free);
646         return 1;
649 static enum crlf_action git_path_check_crlf(const char *path, struct git_attr_check *check)
651         const char *value = check->value;
653         if (ATTR_TRUE(value))
654                 return CRLF_TEXT;
655         else if (ATTR_FALSE(value))
656                 return CRLF_BINARY;
657         else if (ATTR_UNSET(value))
658                 ;
659         else if (!strcmp(value, "input"))
660                 return CRLF_INPUT;
661         else if (!strcmp(value, "auto"))
662                 return CRLF_AUTO;
663         return CRLF_GUESS;
666 static enum eol git_path_check_eol(const char *path, struct git_attr_check *check)
668         const char *value = check->value;
670         if (ATTR_UNSET(value))
671                 ;
672         else if (!strcmp(value, "lf"))
673                 return EOL_LF;
674         else if (!strcmp(value, "crlf"))
675                 return EOL_CRLF;
676         return EOL_UNSET;
679 static struct convert_driver *git_path_check_convert(const char *path,
680                                              struct git_attr_check *check)
682         const char *value = check->value;
683         struct convert_driver *drv;
685         if (ATTR_TRUE(value) || ATTR_FALSE(value) || ATTR_UNSET(value))
686                 return NULL;
687         for (drv = user_convert; drv; drv = drv->next)
688                 if (!strcmp(value, drv->name))
689                         return drv;
690         return NULL;
693 static int git_path_check_ident(const char *path, struct git_attr_check *check)
695         const char *value = check->value;
697         return !!ATTR_TRUE(value);
700 static enum crlf_action input_crlf_action(enum crlf_action text_attr, enum eol eol_attr)
702         if (text_attr == CRLF_BINARY)
703                 return CRLF_BINARY;
704         if (eol_attr == EOL_LF)
705                 return CRLF_INPUT;
706         if (eol_attr == EOL_CRLF)
707                 return CRLF_CRLF;
708         return text_attr;
711 struct conv_attrs {
712         struct convert_driver *drv;
713         enum crlf_action crlf_action;
714         enum eol eol_attr;
715         int ident;
716 };
718 static const char *conv_attr_name[] = {
719         "crlf", "ident", "filter", "eol", "text",
720 };
721 #define NUM_CONV_ATTRS ARRAY_SIZE(conv_attr_name)
723 static void convert_attrs(struct conv_attrs *ca, const char *path)
725         int i;
726         static struct git_attr_check ccheck[NUM_CONV_ATTRS];
728         if (!ccheck[0].attr) {
729                 for (i = 0; i < NUM_CONV_ATTRS; i++)
730                         ccheck[i].attr = git_attr(conv_attr_name[i]);
731                 user_convert_tail = &user_convert;
732                 git_config(read_convert_config, NULL);
733         }
735         if (!git_check_attr(path, NUM_CONV_ATTRS, ccheck)) {
736                 ca->crlf_action = git_path_check_crlf(path, ccheck + 4);
737                 if (ca->crlf_action == CRLF_GUESS)
738                         ca->crlf_action = git_path_check_crlf(path, ccheck + 0);
739                 ca->ident = git_path_check_ident(path, ccheck + 1);
740                 ca->drv = git_path_check_convert(path, ccheck + 2);
741                 ca->eol_attr = git_path_check_eol(path, ccheck + 3);
742         } else {
743                 ca->drv = NULL;
744                 ca->crlf_action = CRLF_GUESS;
745                 ca->eol_attr = EOL_UNSET;
746                 ca->ident = 0;
747         }
750 int convert_to_git(const char *path, const char *src, size_t len,
751                    struct strbuf *dst, enum safe_crlf checksafe)
753         int ret = 0;
754         const char *filter = NULL;
755         struct conv_attrs ca;
757         convert_attrs(&ca, path);
758         if (ca.drv)
759                 filter = ca.drv->clean;
761         ret |= apply_filter(path, src, len, dst, filter);
762         if (ret) {
763                 src = dst->buf;
764                 len = dst->len;
765         }
766         ca.crlf_action = input_crlf_action(ca.crlf_action, ca.eol_attr);
767         ret |= crlf_to_git(path, src, len, dst, ca.crlf_action, checksafe);
768         if (ret) {
769                 src = dst->buf;
770                 len = dst->len;
771         }
772         return ret | ident_to_git(path, src, len, dst, ca.ident);
775 static int convert_to_working_tree_internal(const char *path, const char *src,
776                                             size_t len, struct strbuf *dst,
777                                             int normalizing)
779         int ret = 0;
780         const char *filter = NULL;
781         struct conv_attrs ca;
783         convert_attrs(&ca, path);
784         if (ca.drv)
785                 filter = ca.drv->smudge;
787         ret |= ident_to_worktree(path, src, len, dst, ca.ident);
788         if (ret) {
789                 src = dst->buf;
790                 len = dst->len;
791         }
792         /*
793          * CRLF conversion can be skipped if normalizing, unless there
794          * is a smudge filter.  The filter might expect CRLFs.
795          */
796         if (filter || !normalizing) {
797                 ca.crlf_action = input_crlf_action(ca.crlf_action, ca.eol_attr);
798                 ret |= crlf_to_worktree(path, src, len, dst, ca.crlf_action);
799                 if (ret) {
800                         src = dst->buf;
801                         len = dst->len;
802                 }
803         }
804         return ret | apply_filter(path, src, len, dst, filter);
807 int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst)
809         return convert_to_working_tree_internal(path, src, len, dst, 0);
812 int renormalize_buffer(const char *path, const char *src, size_t len, struct strbuf *dst)
814         int ret = convert_to_working_tree_internal(path, src, len, dst, 1);
815         if (ret) {
816                 src = dst->buf;
817                 len = dst->len;
818         }
819         return ret | convert_to_git(path, src, len, dst, SAFE_CRLF_FALSE);
822 /*****************************************************************
823  *
824  * Streaming converison support
825  *
826  *****************************************************************/
828 typedef int (*filter_fn)(struct stream_filter *,
829                          const char *input, size_t *isize_p,
830                          char *output, size_t *osize_p);
831 typedef void (*free_fn)(struct stream_filter *);
833 struct stream_filter_vtbl {
834         filter_fn filter;
835         free_fn free;
836 };
838 struct stream_filter {
839         struct stream_filter_vtbl *vtbl;
840 };
842 static int null_filter_fn(struct stream_filter *filter,
843                           const char *input, size_t *isize_p,
844                           char *output, size_t *osize_p)
846         size_t count;
848         if (!input)
849                 return 0; /* we do not keep any states */
850         count = *isize_p;
851         if (*osize_p < count)
852                 count = *osize_p;
853         if (count) {
854                 memmove(output, input, count);
855                 *isize_p -= count;
856                 *osize_p -= count;
857         }
858         return 0;
861 static void null_free_fn(struct stream_filter *filter)
863         ; /* nothing -- null instances are shared */
866 static struct stream_filter_vtbl null_vtbl = {
867         null_filter_fn,
868         null_free_fn,
869 };
871 static struct stream_filter null_filter_singleton = {
872         &null_vtbl,
873 };
875 int is_null_stream_filter(struct stream_filter *filter)
877         return filter == &null_filter_singleton;
881 /*
882  * LF-to-CRLF filter
883  */
885 struct lf_to_crlf_filter {
886         struct stream_filter filter;
887         unsigned has_held:1;
888         char held;
889 };
891 static int lf_to_crlf_filter_fn(struct stream_filter *filter,
892                                 const char *input, size_t *isize_p,
893                                 char *output, size_t *osize_p)
895         size_t count, o = 0;
896         struct lf_to_crlf_filter *lf_to_crlf = (struct lf_to_crlf_filter *)filter;
898         /*
899          * We may be holding onto the CR to see if it is followed by a
900          * LF, in which case we would need to go to the main loop.
901          * Otherwise, just emit it to the output stream.
902          */
903         if (lf_to_crlf->has_held && (lf_to_crlf->held != '\r' || !input)) {
904                 output[o++] = lf_to_crlf->held;
905                 lf_to_crlf->has_held = 0;
906         }
908         /* We are told to drain */
909         if (!input) {
910                 *osize_p -= o;
911                 return 0;
912         }
914         count = *isize_p;
915         if (count || lf_to_crlf->has_held) {
916                 size_t i;
917                 int was_cr = 0;
919                 if (lf_to_crlf->has_held) {
920                         was_cr = 1;
921                         lf_to_crlf->has_held = 0;
922                 }
924                 for (i = 0; o < *osize_p && i < count; i++) {
925                         char ch = input[i];
927                         if (ch == '\n') {
928                                 output[o++] = '\r';
929                         } else if (was_cr) {
930                                 /*
931                                  * Previous round saw CR and it is not followed
932                                  * by a LF; emit the CR before processing the
933                                  * current character.
934                                  */
935                                 output[o++] = '\r';
936                         }
938                         /*
939                          * We may have consumed the last output slot,
940                          * in which case we need to break out of this
941                          * loop; hold the current character before
942                          * returning.
943                          */
944                         if (*osize_p <= o) {
945                                 lf_to_crlf->has_held = 1;
946                                 lf_to_crlf->held = ch;
947                                 continue; /* break but increment i */
948                         }
950                         if (ch == '\r') {
951                                 was_cr = 1;
952                                 continue;
953                         }
955                         was_cr = 0;
956                         output[o++] = ch;
957                 }
959                 *osize_p -= o;
960                 *isize_p -= i;
962                 if (!lf_to_crlf->has_held && was_cr) {
963                         lf_to_crlf->has_held = 1;
964                         lf_to_crlf->held = '\r';
965                 }
966         }
967         return 0;
970 static void lf_to_crlf_free_fn(struct stream_filter *filter)
972         free(filter);
975 static struct stream_filter_vtbl lf_to_crlf_vtbl = {
976         lf_to_crlf_filter_fn,
977         lf_to_crlf_free_fn,
978 };
980 static struct stream_filter *lf_to_crlf_filter(void)
982         struct lf_to_crlf_filter *lf_to_crlf = xcalloc(1, sizeof(*lf_to_crlf));
984         lf_to_crlf->filter.vtbl = &lf_to_crlf_vtbl;
985         return (struct stream_filter *)lf_to_crlf;
988 /*
989  * Cascade filter
990  */
991 #define FILTER_BUFFER 1024
992 struct cascade_filter {
993         struct stream_filter filter;
994         struct stream_filter *one;
995         struct stream_filter *two;
996         char buf[FILTER_BUFFER];
997         int end, ptr;
998 };
1000 static int cascade_filter_fn(struct stream_filter *filter,
1001                              const char *input, size_t *isize_p,
1002                              char *output, size_t *osize_p)
1004         struct cascade_filter *cas = (struct cascade_filter *) filter;
1005         size_t filled = 0;
1006         size_t sz = *osize_p;
1007         size_t to_feed, remaining;
1009         /*
1010          * input -- (one) --> buf -- (two) --> output
1011          */
1012         while (filled < sz) {
1013                 remaining = sz - filled;
1015                 /* do we already have something to feed two with? */
1016                 if (cas->ptr < cas->end) {
1017                         to_feed = cas->end - cas->ptr;
1018                         if (stream_filter(cas->two,
1019                                           cas->buf + cas->ptr, &to_feed,
1020                                           output + filled, &remaining))
1021                                 return -1;
1022                         cas->ptr += (cas->end - cas->ptr) - to_feed;
1023                         filled = sz - remaining;
1024                         continue;
1025                 }
1027                 /* feed one from upstream and have it emit into our buffer */
1028                 to_feed = input ? *isize_p : 0;
1029                 if (input && !to_feed)
1030                         break;
1031                 remaining = sizeof(cas->buf);
1032                 if (stream_filter(cas->one,
1033                                   input, &to_feed,
1034                                   cas->buf, &remaining))
1035                         return -1;
1036                 cas->end = sizeof(cas->buf) - remaining;
1037                 cas->ptr = 0;
1038                 if (input) {
1039                         size_t fed = *isize_p - to_feed;
1040                         *isize_p -= fed;
1041                         input += fed;
1042                 }
1044                 /* do we know that we drained one completely? */
1045                 if (input || cas->end)
1046                         continue;
1048                 /* tell two to drain; we have nothing more to give it */
1049                 to_feed = 0;
1050                 remaining = sz - filled;
1051                 if (stream_filter(cas->two,
1052                                   NULL, &to_feed,
1053                                   output + filled, &remaining))
1054                         return -1;
1055                 if (remaining == (sz - filled))
1056                         break; /* completely drained two */
1057                 filled = sz - remaining;
1058         }
1059         *osize_p -= filled;
1060         return 0;
1063 static void cascade_free_fn(struct stream_filter *filter)
1065         struct cascade_filter *cas = (struct cascade_filter *)filter;
1066         free_stream_filter(cas->one);
1067         free_stream_filter(cas->two);
1068         free(filter);
1071 static struct stream_filter_vtbl cascade_vtbl = {
1072         cascade_filter_fn,
1073         cascade_free_fn,
1074 };
1076 static struct stream_filter *cascade_filter(struct stream_filter *one,
1077                                             struct stream_filter *two)
1079         struct cascade_filter *cascade;
1081         if (!one || is_null_stream_filter(one))
1082                 return two;
1083         if (!two || is_null_stream_filter(two))
1084                 return one;
1086         cascade = xmalloc(sizeof(*cascade));
1087         cascade->one = one;
1088         cascade->two = two;
1089         cascade->end = cascade->ptr = 0;
1090         cascade->filter.vtbl = &cascade_vtbl;
1091         return (struct stream_filter *)cascade;
1094 /*
1095  * ident filter
1096  */
1097 #define IDENT_DRAINING (-1)
1098 #define IDENT_SKIPPING (-2)
1099 struct ident_filter {
1100         struct stream_filter filter;
1101         struct strbuf left;
1102         int state;
1103         char ident[45]; /* ": x40 $" */
1104 };
1106 static int is_foreign_ident(const char *str)
1108         int i;
1110         if (prefixcmp(str, "$Id: "))
1111                 return 0;
1112         for (i = 5; str[i]; i++) {
1113                 if (isspace(str[i]) && str[i+1] != '$')
1114                         return 1;
1115         }
1116         return 0;
1119 static void ident_drain(struct ident_filter *ident, char **output_p, size_t *osize_p)
1121         size_t to_drain = ident->left.len;
1123         if (*osize_p < to_drain)
1124                 to_drain = *osize_p;
1125         if (to_drain) {
1126                 memcpy(*output_p, ident->left.buf, to_drain);
1127                 strbuf_remove(&ident->left, 0, to_drain);
1128                 *output_p += to_drain;
1129                 *osize_p -= to_drain;
1130         }
1131         if (!ident->left.len)
1132                 ident->state = 0;
1135 static int ident_filter_fn(struct stream_filter *filter,
1136                            const char *input, size_t *isize_p,
1137                            char *output, size_t *osize_p)
1139         struct ident_filter *ident = (struct ident_filter *)filter;
1140         static const char head[] = "$Id";
1142         if (!input) {
1143                 /* drain upon eof */
1144                 switch (ident->state) {
1145                 default:
1146                         strbuf_add(&ident->left, head, ident->state);
1147                 case IDENT_SKIPPING:
1148                         /* fallthru */
1149                 case IDENT_DRAINING:
1150                         ident_drain(ident, &output, osize_p);
1151                 }
1152                 return 0;
1153         }
1155         while (*isize_p || (ident->state == IDENT_DRAINING)) {
1156                 int ch;
1158                 if (ident->state == IDENT_DRAINING) {
1159                         ident_drain(ident, &output, osize_p);
1160                         if (!*osize_p)
1161                                 break;
1162                         continue;
1163                 }
1165                 ch = *(input++);
1166                 (*isize_p)--;
1168                 if (ident->state == IDENT_SKIPPING) {
1169                         /*
1170                          * Skipping until '$' or LF, but keeping them
1171                          * in case it is a foreign ident.
1172                          */
1173                         strbuf_addch(&ident->left, ch);
1174                         if (ch != '\n' && ch != '$')
1175                                 continue;
1176                         if (ch == '$' && !is_foreign_ident(ident->left.buf)) {
1177                                 strbuf_setlen(&ident->left, sizeof(head) - 1);
1178                                 strbuf_addstr(&ident->left, ident->ident);
1179                         }
1180                         ident->state = IDENT_DRAINING;
1181                         continue;
1182                 }
1184                 if (ident->state < sizeof(head) &&
1185                     head[ident->state] == ch) {
1186                         ident->state++;
1187                         continue;
1188                 }
1190                 if (ident->state)
1191                         strbuf_add(&ident->left, head, ident->state);
1192                 if (ident->state == sizeof(head) - 1) {
1193                         if (ch != ':' && ch != '$') {
1194                                 strbuf_addch(&ident->left, ch);
1195                                 ident->state = 0;
1196                                 continue;
1197                         }
1199                         if (ch == ':') {
1200                                 strbuf_addch(&ident->left, ch);
1201                                 ident->state = IDENT_SKIPPING;
1202                         } else {
1203                                 strbuf_addstr(&ident->left, ident->ident);
1204                                 ident->state = IDENT_DRAINING;
1205                         }
1206                         continue;
1207                 }
1209                 strbuf_addch(&ident->left, ch);
1210                 ident->state = IDENT_DRAINING;
1211         }
1212         return 0;
1215 static void ident_free_fn(struct stream_filter *filter)
1217         struct ident_filter *ident = (struct ident_filter *)filter;
1218         strbuf_release(&ident->left);
1219         free(filter);
1222 static struct stream_filter_vtbl ident_vtbl = {
1223         ident_filter_fn,
1224         ident_free_fn,
1225 };
1227 static struct stream_filter *ident_filter(const unsigned char *sha1)
1229         struct ident_filter *ident = xmalloc(sizeof(*ident));
1231         sprintf(ident->ident, ": %s $", sha1_to_hex(sha1));
1232         strbuf_init(&ident->left, 0);
1233         ident->filter.vtbl = &ident_vtbl;
1234         ident->state = 0;
1235         return (struct stream_filter *)ident;
1238 /*
1239  * Return an appropriately constructed filter for the path, or NULL if
1240  * the contents cannot be filtered without reading the whole thing
1241  * in-core.
1242  *
1243  * Note that you would be crazy to set CRLF, smuge/clean or ident to a
1244  * large binary blob you would want us not to slurp into the memory!
1245  */
1246 struct stream_filter *get_stream_filter(const char *path, const unsigned char *sha1)
1248         struct conv_attrs ca;
1249         enum crlf_action crlf_action;
1250         struct stream_filter *filter = NULL;
1252         convert_attrs(&ca, path);
1254         if (ca.drv && (ca.drv->smudge || ca.drv->clean))
1255                 return filter;
1257         if (ca.ident)
1258                 filter = ident_filter(sha1);
1260         crlf_action = input_crlf_action(ca.crlf_action, ca.eol_attr);
1262         if ((crlf_action == CRLF_BINARY) || (crlf_action == CRLF_INPUT) ||
1263             (crlf_action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE))
1264                 filter = cascade_filter(filter, &null_filter_singleton);
1266         else if (output_eol(crlf_action) == EOL_CRLF &&
1267                  !(crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS))
1268                 filter = cascade_filter(filter, lf_to_crlf_filter());
1270         return filter;
1273 void free_stream_filter(struct stream_filter *filter)
1275         filter->vtbl->free(filter);
1278 int stream_filter(struct stream_filter *filter,
1279                   const char *input, size_t *isize_p,
1280                   char *output, size_t *osize_p)
1282         return filter->vtbl->filter(filter, input, isize_p, output, osize_p);