3 #include "run-command.h"
 
   7  * convert.c - convert a file when checking it out and checking it in.
 
   9  * This should use the pathname to decide on whether it wants to do some
 
  10  * more interesting conversions (automatic gzip/unzip, general format
 
  11  * conversions etc etc), but by default it just does automatic CRLF<->LF
 
  12  * translation when the "text" attribute or "auto_crlf" option is set.
 
  25         /* NUL, CR, LF and CRLF counts */
 
  26         unsigned nul, cr, lf, crlf;
 
  28         /* These are just approximations! */
 
  29         unsigned printable, nonprintable;
 
  32 static void gather_stats(const char *buf, unsigned long size, struct text_stat *stats)
 
  36         memset(stats, 0, sizeof(*stats));
 
  38         for (i = 0; i < size; i++) {
 
  39                 unsigned char c = buf[i];
 
  42                         if (i+1 < size && buf[i+1] == '\n')
 
  52                         stats->nonprintable++;
 
  55                                 /* BS, HT, ESC and FF */
 
  56                         case '\b': case '\t': case '\033': case '\014':
 
  63                                 stats->nonprintable++;
 
  70         /* If file ends with EOF then don't count this EOF as non-printable. */
 
  71         if (size >= 1 && buf[size-1] == '\032')
 
  72                 stats->nonprintable--;
 
  76  * The same heuristics as diff.c::mmfile_is_binary()
 
  78 static int is_binary(unsigned long size, struct text_stat *stats)
 
  83         if ((stats->printable >> 7) < stats->nonprintable)
 
  86          * Other heuristics? Average line length might be relevant,
 
  87          * as might LF vs CR vs CRLF counts..
 
  89          * NOTE! It might be normal to have a low ratio of CRLF to LF
 
  90          * (somebody starts with a LF-only file and edits it with an editor
 
  91          * that adds CRLF only to lines that are added..). But do  we
 
  92          * want to support CR-only? Probably not.
 
  97 static enum eol output_eol(enum crlf_action crlf_action)
 
  99         switch (crlf_action) {
 
 112                 if (auto_crlf == AUTO_CRLF_TRUE)
 
 114                 else if (auto_crlf == AUTO_CRLF_INPUT)
 
 116                 else if (core_eol == EOL_UNSET)
 
 122 static void check_safe_crlf(const char *path, enum crlf_action crlf_action,
 
 123                             struct text_stat *stats, enum safe_crlf checksafe)
 
 128         if (output_eol(crlf_action) == EOL_LF) {
 
 130                  * CRLFs would not be restored by checkout:
 
 131                  * check if we'd remove CRLFs
 
 134                         if (checksafe == SAFE_CRLF_WARN)
 
 135                                 warning("CRLF will be replaced by LF in %s.\nThe file will have its original line endings in your working directory.", path);
 
 136                         else /* i.e. SAFE_CRLF_FAIL */
 
 137                                 die("CRLF would be replaced by LF in %s.", path);
 
 139         } else if (output_eol(crlf_action) == EOL_CRLF) {
 
 141                  * CRLFs would be added by checkout:
 
 142                  * check if we have "naked" LFs
 
 144                 if (stats->lf != stats->crlf) {
 
 145                         if (checksafe == SAFE_CRLF_WARN)
 
 146                                 warning("LF will be replaced by CRLF in %s.\nThe file will have its original line endings in your working directory.", path);
 
 147                         else /* i.e. SAFE_CRLF_FAIL */
 
 148                                 die("LF would be replaced by CRLF in %s", path);
 
 153 static int has_cr_in_index(const char *path)
 
 157         enum object_type type;
 
 160         struct index_state *istate = &the_index;
 
 163         pos = index_name_pos(istate, path, len);
 
 166                  * We might be in the middle of a merge, in which
 
 167                  * case we would read stage #2 (ours).
 
 171                      (pos < 0 && i < istate->cache_nr &&
 
 172                       !strcmp(istate->cache[i]->name, path));
 
 174                         if (ce_stage(istate->cache[i]) == 2)
 
 179         data = read_sha1_file(istate->cache[pos]->sha1, &type, &sz);
 
 180         if (!data || type != OBJ_BLOB) {
 
 185         has_cr = memchr(data, '\r', sz) != NULL;
 
 190 static int crlf_to_git(const char *path, const char *src, size_t len,
 
 192                        enum crlf_action crlf_action, enum safe_crlf checksafe)
 
 194         struct text_stat stats;
 
 197         if (crlf_action == CRLF_BINARY ||
 
 198             (crlf_action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE) || !len)
 
 201         gather_stats(src, len, &stats);
 
 203         if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS) {
 
 205                  * We're currently not going to even try to convert stuff
 
 206                  * that has bare CR characters. Does anybody do that crazy
 
 209                 if (stats.cr != stats.crlf)
 
 213                  * And add some heuristics for binary vs text, of course...
 
 215                 if (is_binary(len, &stats))
 
 218                 if (crlf_action == CRLF_GUESS) {
 
 220                          * If the file in the index has any CR in it, do not convert.
 
 221                          * This is the new safer autocrlf handling.
 
 223                         if (has_cr_in_index(path))
 
 228         check_safe_crlf(path, crlf_action, &stats, checksafe);
 
 230         /* Optimization: No CR? Nothing to convert, regardless. */
 
 234         /* only grow if not in place */
 
 235         if (strbuf_avail(buf) + buf->len < len)
 
 236                 strbuf_grow(buf, len - buf->len);
 
 238         if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS) {
 
 240                  * If we guessed, we already know we rejected a file with
 
 241                  * lone CR, and we can strip a CR without looking at what
 
 245                         unsigned char c = *src++;
 
 251                         unsigned char c = *src++;
 
 252                         if (! (c == '\r' && (1 < len && *src == '\n')))
 
 256         strbuf_setlen(buf, dst - buf->buf);
 
 260 static int crlf_to_worktree(const char *path, const char *src, size_t len,
 
 261                             struct strbuf *buf, enum crlf_action crlf_action)
 
 263         char *to_free = NULL;
 
 264         struct text_stat stats;
 
 266         if (!len || output_eol(crlf_action) != EOL_CRLF)
 
 269         gather_stats(src, len, &stats);
 
 271         /* No LF? Nothing to convert, regardless. */
 
 275         /* Was it already in CRLF format? */
 
 276         if (stats.lf == stats.crlf)
 
 279         if (crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS) {
 
 280                 if (crlf_action == CRLF_GUESS) {
 
 281                         /* If we have any CR or CRLF line endings, we do not touch it */
 
 282                         /* This is the new safer autocrlf-handling */
 
 283                         if (stats.cr > 0 || stats.crlf > 0)
 
 287                 /* If we have any bare CR characters, we're not going to touch it */
 
 288                 if (stats.cr != stats.crlf)
 
 291                 if (is_binary(len, &stats))
 
 295         /* are we "faking" in place editing ? */
 
 297                 to_free = strbuf_detach(buf, NULL);
 
 299         strbuf_grow(buf, len + stats.lf - stats.crlf);
 
 301                 const char *nl = memchr(src, '\n', len);
 
 304                 if (nl > src && nl[-1] == '\r') {
 
 305                         strbuf_add(buf, src, nl + 1 - src);
 
 307                         strbuf_add(buf, src, nl - src);
 
 308                         strbuf_addstr(buf, "\r\n");
 
 313         strbuf_add(buf, src, len);
 
 319 struct filter_params {
 
 326 static int filter_buffer(int in, int out, void *data)
 
 329          * Spawn cmd and feed the buffer contents through its stdin.
 
 331         struct child_process child_process;
 
 332         struct filter_params *params = (struct filter_params *)data;
 
 333         int write_err, status;
 
 334         const char *argv[] = { NULL, NULL };
 
 336         /* apply % substitution to cmd */
 
 337         struct strbuf cmd = STRBUF_INIT;
 
 338         struct strbuf path = STRBUF_INIT;
 
 339         struct strbuf_expand_dict_entry dict[] = {
 
 344         /* quote the path to preserve spaces, etc. */
 
 345         sq_quote_buf(&path, params->path);
 
 346         dict[0].value = path.buf;
 
 348         /* expand all %f with the quoted path */
 
 349         strbuf_expand(&cmd, params->cmd, strbuf_expand_dict_cb, &dict);
 
 350         strbuf_release(&path);
 
 354         memset(&child_process, 0, sizeof(child_process));
 
 355         child_process.argv = argv;
 
 356         child_process.use_shell = 1;
 
 357         child_process.in = -1;
 
 358         child_process.out = out;
 
 360         if (start_command(&child_process))
 
 361                 return error("cannot fork to run external filter %s", params->cmd);
 
 363         write_err = (write_in_full(child_process.in, params->src, params->size) < 0);
 
 364         if (close(child_process.in))
 
 367                 error("cannot feed the input to external filter %s", params->cmd);
 
 369         status = finish_command(&child_process);
 
 371                 error("external filter %s failed %d", params->cmd, status);
 
 373         strbuf_release(&cmd);
 
 374         return (write_err || status);
 
 377 static int apply_filter(const char *path, const char *src, size_t len,
 
 378                         struct strbuf *dst, const char *cmd)
 
 381          * Create a pipeline to have the command filter the buffer's
 
 384          * (child --> cmd) --> us
 
 387         struct strbuf nbuf = STRBUF_INIT;
 
 389         struct filter_params params;
 
 394         memset(&async, 0, sizeof(async));
 
 395         async.proc = filter_buffer;
 
 396         async.data = ¶ms;
 
 404         if (start_async(&async))
 
 405                 return 0;       /* error was already reported */
 
 407         if (strbuf_read(&nbuf, async.out, len) < 0) {
 
 408                 error("read from external filter %s failed", cmd);
 
 411         if (close(async.out)) {
 
 412                 error("read from external filter %s failed", cmd);
 
 415         if (finish_async(&async)) {
 
 416                 error("external filter %s failed", cmd);
 
 421                 strbuf_swap(dst, &nbuf);
 
 423         strbuf_release(&nbuf);
 
 427 static struct convert_driver {
 
 429         struct convert_driver *next;
 
 432 } *user_convert, **user_convert_tail;
 
 434 static int read_convert_config(const char *var, const char *value, void *cb)
 
 436         const char *ep, *name;
 
 438         struct convert_driver *drv;
 
 441          * External conversion drivers are configured using
 
 442          * "filter.<name>.variable".
 
 444         if (prefixcmp(var, "filter.") || (ep = strrchr(var, '.')) == var + 6)
 
 448         for (drv = user_convert; drv; drv = drv->next)
 
 449                 if (!strncmp(drv->name, name, namelen) && !drv->name[namelen])
 
 452                 drv = xcalloc(1, sizeof(struct convert_driver));
 
 453                 drv->name = xmemdupz(name, namelen);
 
 454                 *user_convert_tail = drv;
 
 455                 user_convert_tail = &(drv->next);
 
 461          * filter.<name>.smudge and filter.<name>.clean specifies
 
 466          * The command-line will not be interpolated in any way.
 
 469         if (!strcmp("smudge", ep))
 
 470                 return git_config_string(&drv->smudge, var, value);
 
 472         if (!strcmp("clean", ep))
 
 473                 return git_config_string(&drv->clean, var, value);
 
 478 static int count_ident(const char *cp, unsigned long size)
 
 481          * "$Id: 0000000000000000000000000000000000000000 $" <=> "$Id$"
 
 493                 if (memcmp("Id", cp, 2))
 
 504                  * "$Id: ... "; scan up to the closing dollar sign and discard.
 
 520 static int ident_to_git(const char *path, const char *src, size_t len,
 
 521                         struct strbuf *buf, int ident)
 
 525         if (!ident || !count_ident(src, len))
 
 528         /* only grow if not in place */
 
 529         if (strbuf_avail(buf) + buf->len < len)
 
 530                 strbuf_grow(buf, len - buf->len);
 
 533                 dollar = memchr(src, '$', len);
 
 536                 memmove(dst, src, dollar + 1 - src);
 
 537                 dst += dollar + 1 - src;
 
 538                 len -= dollar + 1 - src;
 
 541                 if (len > 3 && !memcmp(src, "Id:", 3)) {
 
 542                         dollar = memchr(src + 3, '$', len - 3);
 
 545                         if (memchr(src + 3, '\n', dollar - src - 3)) {
 
 546                                 /* Line break before the next dollar. */
 
 550                         memcpy(dst, "Id$", 3);
 
 552                         len -= dollar + 1 - src;
 
 556         memmove(dst, src, len);
 
 557         strbuf_setlen(buf, dst + len - buf->buf);
 
 561 static int ident_to_worktree(const char *path, const char *src, size_t len,
 
 562                              struct strbuf *buf, int ident)
 
 564         unsigned char sha1[20];
 
 565         char *to_free = NULL, *dollar, *spc;
 
 571         cnt = count_ident(src, len);
 
 575         /* are we "faking" in place editing ? */
 
 577                 to_free = strbuf_detach(buf, NULL);
 
 578         hash_sha1_file(src, len, "blob", sha1);
 
 580         strbuf_grow(buf, len + cnt * 43);
 
 582                 /* step 1: run to the next '$' */
 
 583                 dollar = memchr(src, '$', len);
 
 586                 strbuf_add(buf, src, dollar + 1 - src);
 
 587                 len -= dollar + 1 - src;
 
 590                 /* step 2: does it looks like a bit like Id:xxx$ or Id$ ? */
 
 591                 if (len < 3 || memcmp("Id", src, 2))
 
 594                 /* step 3: skip over Id$ or Id:xxxxx$ */
 
 598                 } else if (src[2] == ':') {
 
 600                          * It's possible that an expanded Id has crept its way into the
 
 601                          * repository, we cope with that by stripping the expansion out.
 
 602                          * This is probably not a good idea, since it will cause changes
 
 603                          * on checkout, which won't go away by stash, but let's keep it
 
 606                         dollar = memchr(src + 3, '$', len - 3);
 
 608                                 /* incomplete keyword, no more '$', so just quit the loop */
 
 612                         if (memchr(src + 3, '\n', dollar - src - 3)) {
 
 613                                 /* Line break before the next dollar. */
 
 617                         spc = memchr(src + 4, ' ', dollar - src - 4);
 
 618                         if (spc && spc < dollar-1) {
 
 619                                 /* There are spaces in unexpected places.
 
 620                                  * This is probably an id from some other
 
 621                                  * versioning system. Keep it for now.
 
 626                         len -= dollar + 1 - src;
 
 629                         /* it wasn't a "Id$" or "Id:xxxx$" */
 
 633                 /* step 4: substitute */
 
 634                 strbuf_addstr(buf, "Id: ");
 
 635                 strbuf_add(buf, sha1_to_hex(sha1), 40);
 
 636                 strbuf_addstr(buf, " $");
 
 638         strbuf_add(buf, src, len);
 
 644 static int git_path_check_crlf(const char *path, struct git_attr_check *check)
 
 646         const char *value = check->value;
 
 648         if (ATTR_TRUE(value))
 
 650         else if (ATTR_FALSE(value))
 
 652         else if (ATTR_UNSET(value))
 
 654         else if (!strcmp(value, "input"))
 
 656         else if (!strcmp(value, "auto"))
 
 661 static int git_path_check_eol(const char *path, struct git_attr_check *check)
 
 663         const char *value = check->value;
 
 665         if (ATTR_UNSET(value))
 
 667         else if (!strcmp(value, "lf"))
 
 669         else if (!strcmp(value, "crlf"))
 
 674 static struct convert_driver *git_path_check_convert(const char *path,
 
 675                                              struct git_attr_check *check)
 
 677         const char *value = check->value;
 
 678         struct convert_driver *drv;
 
 680         if (ATTR_TRUE(value) || ATTR_FALSE(value) || ATTR_UNSET(value))
 
 682         for (drv = user_convert; drv; drv = drv->next)
 
 683                 if (!strcmp(value, drv->name))
 
 688 static int git_path_check_ident(const char *path, struct git_attr_check *check)
 
 690         const char *value = check->value;
 
 692         return !!ATTR_TRUE(value);
 
 695 static enum crlf_action input_crlf_action(enum crlf_action text_attr, enum eol eol_attr)
 
 697         if (text_attr == CRLF_BINARY)
 
 699         if (eol_attr == EOL_LF)
 
 701         if (eol_attr == EOL_CRLF)
 
 707         struct convert_driver *drv;
 
 708         enum crlf_action crlf_action;
 
 713 static const char *conv_attr_name[] = {
 
 714         "crlf", "ident", "filter", "eol", "text",
 
 716 #define NUM_CONV_ATTRS ARRAY_SIZE(conv_attr_name)
 
 718 static void convert_attrs(struct conv_attrs *ca, const char *path)
 
 721         static struct git_attr_check ccheck[NUM_CONV_ATTRS];
 
 723         if (!ccheck[0].attr) {
 
 724                 for (i = 0; i < NUM_CONV_ATTRS; i++)
 
 725                         ccheck[i].attr = git_attr(conv_attr_name[i]);
 
 726                 user_convert_tail = &user_convert;
 
 727                 git_config(read_convert_config, NULL);
 
 730         if (!git_check_attr(path, NUM_CONV_ATTRS, ccheck)) {
 
 731                 ca->crlf_action = git_path_check_crlf(path, ccheck + 4);
 
 732                 if (ca->crlf_action == CRLF_GUESS)
 
 733                         ca->crlf_action = git_path_check_crlf(path, ccheck + 0);
 
 734                 ca->ident = git_path_check_ident(path, ccheck + 1);
 
 735                 ca->drv = git_path_check_convert(path, ccheck + 2);
 
 736                 ca->eol_attr = git_path_check_eol(path, ccheck + 3);
 
 739                 ca->crlf_action = CRLF_GUESS;
 
 740                 ca->eol_attr = EOL_UNSET;
 
 745 int convert_to_git(const char *path, const char *src, size_t len,
 
 746                    struct strbuf *dst, enum safe_crlf checksafe)
 
 749         const char *filter = NULL;
 
 750         struct conv_attrs ca;
 
 752         convert_attrs(&ca, path);
 
 754                 filter = ca.drv->clean;
 
 756         ret |= apply_filter(path, src, len, dst, filter);
 
 761         ca.crlf_action = input_crlf_action(ca.crlf_action, ca.eol_attr);
 
 762         ret |= crlf_to_git(path, src, len, dst, ca.crlf_action, checksafe);
 
 767         return ret | ident_to_git(path, src, len, dst, ca.ident);
 
 770 static int convert_to_working_tree_internal(const char *path, const char *src,
 
 771                                             size_t len, struct strbuf *dst,
 
 775         const char *filter = NULL;
 
 776         struct conv_attrs ca;
 
 778         convert_attrs(&ca, path);
 
 780                 filter = ca.drv->smudge;
 
 782         ret |= ident_to_worktree(path, src, len, dst, ca.ident);
 
 788          * CRLF conversion can be skipped if normalizing, unless there
 
 789          * is a smudge filter.  The filter might expect CRLFs.
 
 791         if (filter || !normalizing) {
 
 792                 ca.crlf_action = input_crlf_action(ca.crlf_action, ca.eol_attr);
 
 793                 ret |= crlf_to_worktree(path, src, len, dst, ca.crlf_action);
 
 799         return ret | apply_filter(path, src, len, dst, filter);
 
 802 int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst)
 
 804         return convert_to_working_tree_internal(path, src, len, dst, 0);
 
 807 int renormalize_buffer(const char *path, const char *src, size_t len, struct strbuf *dst)
 
 809         int ret = convert_to_working_tree_internal(path, src, len, dst, 1);
 
 814         return ret | convert_to_git(path, src, len, dst, 0);
 
 817 /*****************************************************************
 
 819  * Streaming converison support
 
 821  *****************************************************************/
 
 823 typedef int (*filter_fn)(struct stream_filter *,
 
 824                          const char *input, size_t *isize_p,
 
 825                          char *output, size_t *osize_p);
 
 826 typedef void (*free_fn)(struct stream_filter *);
 
 828 struct stream_filter_vtbl {
 
 833 struct stream_filter {
 
 834         struct stream_filter_vtbl *vtbl;
 
 837 static int null_filter_fn(struct stream_filter *filter,
 
 838                           const char *input, size_t *isize_p,
 
 839                           char *output, size_t *osize_p)
 
 844                 return 0; /* we do not keep any states */
 
 846         if (*osize_p < count)
 
 849                 memmove(output, input, count);
 
 856 static void null_free_fn(struct stream_filter *filter)
 
 858         ; /* nothing -- null instances are shared */
 
 861 static struct stream_filter_vtbl null_vtbl = {
 
 866 static struct stream_filter null_filter_singleton = {
 
 870 int is_null_stream_filter(struct stream_filter *filter)
 
 872         return filter == &null_filter_singleton;
 
 879 static int lf_to_crlf_filter_fn(struct stream_filter *filter,
 
 880                                 const char *input, size_t *isize_p,
 
 881                                 char *output, size_t *osize_p)
 
 886                 return 0; /* we do not keep any states */
 
 890                 for (i = o = 0; o < *osize_p && i < count; i++) {
 
 893                                 if (o + 1 < *osize_p)
 
 907 static struct stream_filter_vtbl lf_to_crlf_vtbl = {
 
 908         lf_to_crlf_filter_fn,
 
 912 static struct stream_filter lf_to_crlf_filter_singleton = {
 
 920 #define FILTER_BUFFER 1024
 
 921 struct cascade_filter {
 
 922         struct stream_filter filter;
 
 923         struct stream_filter *one;
 
 924         struct stream_filter *two;
 
 925         char buf[FILTER_BUFFER];
 
 929 static int cascade_filter_fn(struct stream_filter *filter,
 
 930                              const char *input, size_t *isize_p,
 
 931                              char *output, size_t *osize_p)
 
 933         struct cascade_filter *cas = (struct cascade_filter *) filter;
 
 935         size_t sz = *osize_p;
 
 936         size_t to_feed, remaining;
 
 939          * input -- (one) --> buf -- (two) --> output
 
 941         while (filled < sz) {
 
 942                 remaining = sz - filled;
 
 944                 /* do we already have something to feed two with? */
 
 945                 if (cas->ptr < cas->end) {
 
 946                         to_feed = cas->end - cas->ptr;
 
 947                         if (stream_filter(cas->two,
 
 948                                           cas->buf + cas->ptr, &to_feed,
 
 949                                           output + filled, &remaining))
 
 951                         cas->ptr += (cas->end - cas->ptr) - to_feed;
 
 952                         filled = sz - remaining;
 
 956                 /* feed one from upstream and have it emit into our buffer */
 
 957                 to_feed = input ? *isize_p : 0;
 
 958                 if (input && !to_feed)
 
 960                 remaining = sizeof(cas->buf);
 
 961                 if (stream_filter(cas->one,
 
 963                                   cas->buf, &remaining))
 
 965                 cas->end = sizeof(cas->buf) - remaining;
 
 968                         size_t fed = *isize_p - to_feed;
 
 973                 /* do we know that we drained one completely? */
 
 974                 if (input || cas->end)
 
 977                 /* tell two to drain; we have nothing more to give it */
 
 979                 remaining = sz - filled;
 
 980                 if (stream_filter(cas->two,
 
 982                                   output + filled, &remaining))
 
 984                 if (remaining == (sz - filled))
 
 985                         break; /* completely drained two */
 
 986                 filled = sz - remaining;
 
 992 static void cascade_free_fn(struct stream_filter *filter)
 
 994         struct cascade_filter *cas = (struct cascade_filter *)filter;
 
 995         free_stream_filter(cas->one);
 
 996         free_stream_filter(cas->two);
 
1000 static struct stream_filter_vtbl cascade_vtbl = {
 
1005 static struct stream_filter *cascade_filter(struct stream_filter *one,
 
1006                                             struct stream_filter *two)
 
1008         struct cascade_filter *cascade;
 
1010         if (!one || is_null_stream_filter(one))
 
1012         if (!two || is_null_stream_filter(two))
 
1015         cascade = xmalloc(sizeof(*cascade));
 
1018         cascade->end = cascade->ptr = 0;
 
1019         cascade->filter.vtbl = &cascade_vtbl;
 
1020         return (struct stream_filter *)cascade;
 
1026 #define IDENT_DRAINING (-1)
 
1027 #define IDENT_SKIPPING (-2)
 
1028 struct ident_filter {
 
1029         struct stream_filter filter;
 
1032         char ident[45]; /* ": x40 $" */
 
1035 static int is_foreign_ident(const char *str)
 
1039         if (prefixcmp(str, "$Id: "))
 
1041         for (i = 5; str[i]; i++) {
 
1042                 if (isspace(str[i]) && str[i+1] != '$')
 
1048 static void ident_drain(struct ident_filter *ident, char **output_p, size_t *osize_p)
 
1050         size_t to_drain = ident->left.len;
 
1052         if (*osize_p < to_drain)
 
1053                 to_drain = *osize_p;
 
1055                 memcpy(*output_p, ident->left.buf, to_drain);
 
1056                 strbuf_remove(&ident->left, 0, to_drain);
 
1057                 *output_p += to_drain;
 
1058                 *osize_p -= to_drain;
 
1060         if (!ident->left.len)
 
1064 static int ident_filter_fn(struct stream_filter *filter,
 
1065                            const char *input, size_t *isize_p,
 
1066                            char *output, size_t *osize_p)
 
1068         struct ident_filter *ident = (struct ident_filter *)filter;
 
1069         static const char head[] = "$Id";
 
1072                 /* drain upon eof */
 
1073                 switch (ident->state) {
 
1075                         strbuf_add(&ident->left, head, ident->state);
 
1076                 case IDENT_SKIPPING:
 
1078                 case IDENT_DRAINING:
 
1079                         ident_drain(ident, &output, osize_p);
 
1084         while (*isize_p || (ident->state == IDENT_DRAINING)) {
 
1087                 if (ident->state == IDENT_DRAINING) {
 
1088                         ident_drain(ident, &output, osize_p);
 
1097                 if (ident->state == IDENT_SKIPPING) {
 
1099                          * Skipping until '$' or LF, but keeping them
 
1100                          * in case it is a foreign ident.
 
1102                         strbuf_addch(&ident->left, ch);
 
1103                         if (ch != '\n' && ch != '$')
 
1105                         if (ch == '$' && !is_foreign_ident(ident->left.buf)) {
 
1106                                 strbuf_setlen(&ident->left, sizeof(head) - 1);
 
1107                                 strbuf_addstr(&ident->left, ident->ident);
 
1109                         ident->state = IDENT_DRAINING;
 
1113                 if (ident->state < sizeof(head) &&
 
1114                     head[ident->state] == ch) {
 
1120                         strbuf_add(&ident->left, head, ident->state);
 
1121                 if (ident->state == sizeof(head) - 1) {
 
1122                         if (ch != ':' && ch != '$') {
 
1123                                 strbuf_addch(&ident->left, ch);
 
1129                                 strbuf_addch(&ident->left, ch);
 
1130                                 ident->state = IDENT_SKIPPING;
 
1132                                 strbuf_addstr(&ident->left, ident->ident);
 
1133                                 ident->state = IDENT_DRAINING;
 
1138                 strbuf_addch(&ident->left, ch);
 
1139                 ident->state = IDENT_DRAINING;
 
1144 static void ident_free_fn(struct stream_filter *filter)
 
1146         struct ident_filter *ident = (struct ident_filter *)filter;
 
1147         strbuf_release(&ident->left);
 
1151 static struct stream_filter_vtbl ident_vtbl = {
 
1156 static struct stream_filter *ident_filter(const unsigned char *sha1)
 
1158         struct ident_filter *ident = xmalloc(sizeof(*ident));
 
1160         sprintf(ident->ident, ": %s $", sha1_to_hex(sha1));
 
1161         strbuf_init(&ident->left, 0);
 
1162         ident->filter.vtbl = &ident_vtbl;
 
1164         return (struct stream_filter *)ident;
 
1168  * Return an appropriately constructed filter for the path, or NULL if
 
1169  * the contents cannot be filtered without reading the whole thing
 
1172  * Note that you would be crazy to set CRLF, smuge/clean or ident to a
 
1173  * large binary blob you would want us not to slurp into the memory!
 
1175 struct stream_filter *get_stream_filter(const char *path, const unsigned char *sha1)
 
1177         struct conv_attrs ca;
 
1178         enum crlf_action crlf_action;
 
1179         struct stream_filter *filter = NULL;
 
1181         convert_attrs(&ca, path);
 
1183         if (ca.drv && (ca.drv->smudge || ca.drv->clean))
 
1187                 filter = ident_filter(sha1);
 
1189         crlf_action = input_crlf_action(ca.crlf_action, ca.eol_attr);
 
1191         if ((crlf_action == CRLF_BINARY) || (crlf_action == CRLF_INPUT) ||
 
1192             (crlf_action == CRLF_GUESS && auto_crlf == AUTO_CRLF_FALSE))
 
1193                 filter = cascade_filter(filter, &null_filter_singleton);
 
1195         else if (output_eol(crlf_action) == EOL_CRLF &&
 
1196                  !(crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS))
 
1197                 filter = cascade_filter(filter, &lf_to_crlf_filter_singleton);
 
1202 void free_stream_filter(struct stream_filter *filter)
 
1204         filter->vtbl->free(filter);
 
1207 int stream_filter(struct stream_filter *filter,
 
1208                   const char *input, size_t *isize_p,
 
1209                   char *output, size_t *osize_p)
 
1211         return filter->vtbl->filter(filter, input, isize_p, output, osize_p);