/*
 * subst.c :  generic eol/keyword substitution routines
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */



#define APR_WANT_STRFUNC
#include <apr_want.h>

#include <stdlib.h>
#include <assert.h>
#include <apr_pools.h>
#include <apr_tables.h>
#include <apr_file_io.h>
#include <apr_strings.h>

#include "svn_hash.h"
#include "svn_cmdline.h"
#include "svn_types.h"
#include "svn_string.h"
#include "svn_time.h"
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_error.h"
#include "svn_utf.h"
#include "svn_io.h"
#include "svn_subst.h"
#include "svn_pools.h"
#include "private/svn_io_private.h"

#include "svn_private_config.h"

#include "private/svn_string_private.h"
#include "private/svn_eol_private.h"

/**
 * The textual elements of a detranslated special file.  One of these
 * strings must appear as the first element of any special file as it
 * exists in the repository or the text base.
 */
#define SVN_SUBST__SPECIAL_LINK_STR "link"

void
svn_subst_eol_style_from_value(svn_subst_eol_style_t *style,
                               const char **eol,
                               const char *value)
{
  if (value == NULL)
    {
      /* property doesn't exist. */
      *eol = NULL;
      if (style)
        *style = svn_subst_eol_style_none;
    }
  else if (! strcmp("native", value))
    {
      *eol = APR_EOL_STR;       /* whee, a portability library! */
      if (style)
        *style = svn_subst_eol_style_native;
    }
  else if (! strcmp("LF", value))
    {
      *eol = "\n";
      if (style)
        *style = svn_subst_eol_style_fixed;
    }
  else if (! strcmp("CR", value))
    {
      *eol = "\r";
      if (style)
        *style = svn_subst_eol_style_fixed;
    }
  else if (! strcmp("CRLF", value))
    {
      *eol = "\r\n";
      if (style)
        *style = svn_subst_eol_style_fixed;
    }
  else
    {
      *eol = NULL;
      if (style)
        *style = svn_subst_eol_style_unknown;
    }
}


svn_boolean_t
svn_subst_translation_required(svn_subst_eol_style_t style,
                               const char *eol,
                               apr_hash_t *keywords,
                               svn_boolean_t special,
                               svn_boolean_t force_eol_check)
{
  return (special || keywords
          || (style != svn_subst_eol_style_none && force_eol_check)
          || (style == svn_subst_eol_style_native &&
              strcmp(APR_EOL_STR, SVN_SUBST_NATIVE_EOL_STR) != 0)
          || (style == svn_subst_eol_style_fixed &&
              strcmp(APR_EOL_STR, eol) != 0));
}



/* Helper function for svn_subst_build_keywords */

/* Given a printf-like format string, return a string with proper
 * information filled in.
 *
 * Important API note: This function is the core of the implementation of
 * svn_subst_build_keywords (all versions), and as such must implement the
 * tolerance of NULL and zero inputs that that function's documentation
 * stipulates.
 *
 * The format codes:
 *
 * %a author of this revision
 * %b basename of the URL of this file
 * %d short format of date of this revision
 * %D long format of date of this revision
 * %P path relative to root of repos
 * %r number of this revision
 * %R root url of repository
 * %u URL of this file
 * %_ a space
 * %% a literal %
 *
 * The following special format codes are also recognized:
 *   %H is equivalent to %P%_%r%_%d%_%a
 *   %I is equivalent to %b%_%r%_%d%_%a
 *
 * All memory is allocated out of @a pool.
 */
static svn_string_t *
keyword_printf(const char *fmt,
               const char *rev,
               const char *url,
               const char *repos_root_url,
               apr_time_t date,
               const char *author,
               apr_pool_t *pool)
{
  svn_stringbuf_t *value = svn_stringbuf_create_empty(pool);
  const char *cur;
  size_t n;

  for (;;)
    {
      cur = fmt;

      while (*cur != '\0' && *cur != '%')
        cur++;

      if ((n = cur - fmt) > 0) /* Do we have an as-is string? */
        svn_stringbuf_appendbytes(value, fmt, n);

      if (*cur == '\0')
        break;

      switch (cur[1])
        {
        case 'a': /* author of this revision */
          if (author)
            svn_stringbuf_appendcstr(value, author);
          break;
        case 'b': /* basename of this file */
          if (url && *url)
            {
              const char *base_name = svn_uri_basename(url, pool);
              svn_stringbuf_appendcstr(value, base_name);
            }
          break;
        case 'd': /* short format of date of this revision */
          if (date)
            {
              apr_time_exp_t exploded_time;
              const char *human;

              apr_time_exp_gmt(&exploded_time, date);

              human = apr_psprintf(pool, "%04d-%02d-%02d %02d:%02d:%02dZ",
                                   exploded_time.tm_year + 1900,
                                   exploded_time.tm_mon + 1,
                                   exploded_time.tm_mday,
                                   exploded_time.tm_hour,
                                   exploded_time.tm_min,
                                   exploded_time.tm_sec);

              svn_stringbuf_appendcstr(value, human);
            }
          break;
        case 'D': /* long format of date of this revision */
          if (date)
            svn_stringbuf_appendcstr(value,
                                     svn_time_to_human_cstring(date, pool));
          break;
        case 'P': /* relative path of this file */
          if (repos_root_url && *repos_root_url != '\0' && url && *url != '\0')
            {
              const char *repos_relpath;

              repos_relpath = svn_uri_skip_ancestor(repos_root_url, url, pool);
              if (repos_relpath)
                svn_stringbuf_appendcstr(value, repos_relpath);
            }
          break;
        case 'R': /* root of repos */
          if (repos_root_url && *repos_root_url != '\0')
            svn_stringbuf_appendcstr(value, repos_root_url);
          break;
        case 'r': /* number of this revision */
          if (rev)
            svn_stringbuf_appendcstr(value, rev);
          break;
        case 'u': /* URL of this file */
          if (url)
            svn_stringbuf_appendcstr(value, url);
          break;
        case '_': /* '%_' => a space */
          svn_stringbuf_appendbyte(value, ' ');
          break;
        case '%': /* '%%' => a literal % */
          svn_stringbuf_appendbyte(value, *cur);
          break;
        case '\0': /* '%' as the last character of the string. */
          svn_stringbuf_appendbyte(value, *cur);
          /* Now go back one character, since this was just a one character
           * sequence, whereas all others are two characters, and we do not
           * want to skip the null terminator entirely and carry on
           * formatting random memory contents. */
          cur--;
          break;
        case 'H':
          {
            svn_string_t *s = keyword_printf("%P%_%r%_%d%_%a", rev, url,
                                             repos_root_url, date, author,
                                             pool);
            svn_stringbuf_appendcstr(value, s->data);
          }
          break;
        case 'I':
          {
            svn_string_t *s = keyword_printf("%b%_%r%_%d%_%a", rev, url,
                                             repos_root_url, date, author,
                                             pool);
            svn_stringbuf_appendcstr(value, s->data);
          }
          break;
        default: /* Unrecognized code, just print it literally. */
          svn_stringbuf_appendbytes(value, cur, 2);
          break;
        }

      /* Format code is processed - skip it, and get ready for next chunk. */
      fmt = cur + 2;
    }

  return svn_stringbuf__morph_into_string(value);
}

static svn_error_t *
build_keywords(apr_hash_t **kw,
               svn_boolean_t expand_custom_keywords,
               const char *keywords_val,
               const char *rev,
               const char *url,
               const char *repos_root_url,
               apr_time_t date,
               const char *author,
               apr_pool_t *pool)
{
  apr_array_header_t *keyword_tokens;
  int i;
  *kw = apr_hash_make(pool);

  keyword_tokens = svn_cstring_split(keywords_val, " \t\v\n\b\r\f",
                                     TRUE /* chop */, pool);

  for (i = 0; i < keyword_tokens->nelts; ++i)
    {
      const char *keyword = APR_ARRAY_IDX(keyword_tokens, i, const char *);
      const char *custom_fmt = NULL;

      if (expand_custom_keywords)
        {
          char *sep;

          /* Check if there is a custom keyword definition, started by '='. */
          sep = strchr(keyword, '=');
          if (sep)
            {
              *sep = '\0'; /* Split keyword's name from custom format. */
              custom_fmt = sep + 1;
            }
        }

      if (custom_fmt)
        {
          svn_string_t *custom_val;

          /* Custom keywords must be allowed to match the name of an
           * existing fixed keyword. This is for compatibility purposes,
           * in case new fixed keywords are added to Subversion which
           * happen to match a custom keyword defined somewhere.
           * There is only one global namespace for keyword names. */
          custom_val = keyword_printf(custom_fmt, rev, url, repos_root_url,
                                      date, author, pool);
          svn_hash_sets(*kw, keyword, custom_val);
        }
      else if ((! strcmp(keyword, SVN_KEYWORD_REVISION_LONG))
               || (! strcmp(keyword, SVN_KEYWORD_REVISION_MEDIUM))
               || (! svn_cstring_casecmp(keyword, SVN_KEYWORD_REVISION_SHORT)))
        {
          svn_string_t *revision_val;

          revision_val = keyword_printf("%r", rev, url, repos_root_url,
                                        date, author, pool);
          svn_hash_sets(*kw, SVN_KEYWORD_REVISION_LONG, revision_val);
          svn_hash_sets(*kw, SVN_KEYWORD_REVISION_MEDIUM, revision_val);
          svn_hash_sets(*kw, SVN_KEYWORD_REVISION_SHORT, revision_val);
        }
      else if ((! strcmp(keyword, SVN_KEYWORD_DATE_LONG))
               || (! svn_cstring_casecmp(keyword, SVN_KEYWORD_DATE_SHORT)))
        {
          svn_string_t *date_val;

          date_val = keyword_printf("%D", rev, url, repos_root_url, date,
                                    author, pool);
          svn_hash_sets(*kw, SVN_KEYWORD_DATE_LONG, date_val);
          svn_hash_sets(*kw, SVN_KEYWORD_DATE_SHORT, date_val);
        }
      else if ((! strcmp(keyword, SVN_KEYWORD_AUTHOR_LONG))
               || (! svn_cstring_casecmp(keyword, SVN_KEYWORD_AUTHOR_SHORT)))
        {
          svn_string_t *author_val;

          author_val = keyword_printf("%a", rev, url, repos_root_url, date,
                                      author, pool);
          svn_hash_sets(*kw, SVN_KEYWORD_AUTHOR_LONG, author_val);
          svn_hash_sets(*kw, SVN_KEYWORD_AUTHOR_SHORT, author_val);
        }
      else if ((! strcmp(keyword, SVN_KEYWORD_URL_LONG))
               || (! svn_cstring_casecmp(keyword, SVN_KEYWORD_URL_SHORT)))
        {
          svn_string_t *url_val;

          url_val = keyword_printf("%u", rev, url, repos_root_url, date,
                                   author, pool);
          svn_hash_sets(*kw, SVN_KEYWORD_URL_LONG, url_val);
          svn_hash_sets(*kw, SVN_KEYWORD_URL_SHORT, url_val);
        }
      else if ((! svn_cstring_casecmp(keyword, SVN_KEYWORD_ID)))
        {
          svn_string_t *id_val;

          id_val = keyword_printf("%b %r %d %a", rev, url, repos_root_url,
                                  date, author, pool);
          svn_hash_sets(*kw, SVN_KEYWORD_ID, id_val);
        }
      else if ((! svn_cstring_casecmp(keyword, SVN_KEYWORD_HEADER)))
        {
          svn_string_t *header_val;

          header_val = keyword_printf("%u %r %d %a", rev, url, repos_root_url,
                                      date, author, pool);
          svn_hash_sets(*kw, SVN_KEYWORD_HEADER, header_val);
        }
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_subst_build_keywords2(apr_hash_t **kw,
                          const char *keywords_val,
                          const char *rev,
                          const char *url,
                          apr_time_t date,
                          const char *author,
                          apr_pool_t *pool)
{
  return svn_error_trace(build_keywords(kw, FALSE, keywords_val, rev, url,
                                        NULL, date, author, pool));
}


svn_error_t *
svn_subst_build_keywords3(apr_hash_t **kw,
                          const char *keywords_val,
                          const char *rev,
                          const char *url,
                          const char *repos_root_url,
                          apr_time_t date,
                          const char *author,
                          apr_pool_t *pool)
{
  return svn_error_trace(build_keywords(kw, TRUE, keywords_val,
                                        rev, url, repos_root_url,
                                        date, author, pool));
}


/*** Helpers for svn_subst_translate_stream2 ***/


/* Write out LEN bytes of BUF into STREAM. */
/* ### TODO: 'stream_write()' would be a better name for this. */
static svn_error_t *
translate_write(svn_stream_t *stream,
                const void *buf,
                apr_size_t len)
{
  SVN_ERR(svn_stream_write(stream, buf, &len));
  /* (No need to check LEN, as a short write always produces an error.) */
  return SVN_NO_ERROR;
}


/* Perform the substitution of VALUE into keyword string BUF (with len
   *LEN), given a pre-parsed KEYWORD (and KEYWORD_LEN), and updating
   *LEN to the new size of the substituted result.  Return TRUE if all
   goes well, FALSE otherwise.  If VALUE is NULL, keyword will be
   contracted, else it will be expanded.  */
static svn_boolean_t
translate_keyword_subst(char *buf,
                        apr_size_t *len,
                        const char *keyword,
                        apr_size_t keyword_len,
                        const svn_string_t *value)
{
  char *buf_ptr;

  /* Make sure we gotz good stuffs. */
  assert(*len <= SVN_KEYWORD_MAX_LEN);
  assert((buf[0] == '$') && (buf[*len - 1] == '$'));

  /* Need at least a keyword and two $'s. */
  if (*len < keyword_len + 2)
    return FALSE;

  /* Need at least space for two $'s, two spaces and a colon, and that
     leaves zero space for the value itself. */
  if (keyword_len > SVN_KEYWORD_MAX_LEN - 5)
    return FALSE;

  /* The keyword needs to match what we're looking for. */
  if (strncmp(buf + 1, keyword, keyword_len))
    return FALSE;

  buf_ptr = buf + 1 + keyword_len;

  /* Check for fixed-length expansion.
   * The format of fixed length keyword and its data is
   * Unexpanded keyword:         "$keyword::       $"
   * Expanded keyword:           "$keyword:: value $"
   * Expanded kw with filling:   "$keyword:: value   $"
   * Truncated keyword:          "$keyword:: longval#$"
   */
  if ((buf_ptr[0] == ':') /* first char after keyword is ':' */
      && (buf_ptr[1] == ':') /* second char after keyword is ':' */
      && (buf_ptr[2] == ' ') /* third char after keyword is ' ' */
      && ((buf[*len - 2] == ' ')  /* has ' ' for next to last character */
          || (buf[*len - 2] == '#')) /* .. or has '#' for next to last
                                        character */
      && ((6 + keyword_len) < *len))  /* holds "$kw:: x $" at least */
    {
      /* This is fixed length keyword, so *len remains unchanged */
      apr_size_t max_value_len = *len - (6 + keyword_len);

      if (! value)
        {
          /* no value, so unexpand */
          buf_ptr += 2;
          while (*buf_ptr != '$')
            *(buf_ptr++) = ' ';
        }
      else
        {
          if (value->len <= max_value_len)
            { /* replacement not as long as template, pad with spaces */
              strncpy(buf_ptr + 3, value->data, value->len);
              buf_ptr += 3 + value->len;
              while (*buf_ptr != '$')
                *(buf_ptr++) = ' ';
            }
          else
            {
              /* replacement needs truncating */
              strncpy(buf_ptr + 3, value->data, max_value_len);
              buf[*len - 2] = '#';
              buf[*len - 1] = '$';
            }
        }
      return TRUE;
    }

  /* Check for unexpanded keyword. */
  else if (buf_ptr[0] == '$')          /* "$keyword$" */
    {
      /* unexpanded... */
      if (value)
        {
          /* ...so expand. */
          buf_ptr[0] = ':';
          buf_ptr[1] = ' ';
          if (value->len)
            {
              apr_size_t vallen = value->len;

              /* "$keyword: value $" */
              if (vallen > (SVN_KEYWORD_MAX_LEN - 5 - keyword_len))
                vallen = SVN_KEYWORD_MAX_LEN - 5 - keyword_len;
              strncpy(buf_ptr + 2, value->data, vallen);
              buf_ptr[2 + vallen] = ' ';
              buf_ptr[2 + vallen + 1] = '$';
              *len = 5 + keyword_len + vallen;
            }
          else
            {
              /* "$keyword: $"  */
              buf_ptr[2] = '$';
              *len = 4 + keyword_len;
            }
        }
      else
        {
          /* ...but do nothing. */
        }
      return TRUE;
    }

  /* Check for expanded keyword. */
  else if (((*len >= 4 + keyword_len ) /* holds at least "$keyword: $" */
           && (buf_ptr[0] == ':')      /* first char after keyword is ':' */
           && (buf_ptr[1] == ' ')      /* second char after keyword is ' ' */
           && (buf[*len - 2] == ' '))
        || ((*len >= 3 + keyword_len ) /* holds at least "$keyword:$" */
           && (buf_ptr[0] == ':')      /* first char after keyword is ':' */
           && (buf_ptr[1] == '$')))    /* second char after keyword is '$' */
    {
      /* expanded... */
      if (! value)
        {
          /* ...so unexpand. */
          buf_ptr[0] = '$';
          *len = 2 + keyword_len;
        }
      else
        {
          /* ...so re-expand. */
          buf_ptr[0] = ':';
          buf_ptr[1] = ' ';
          if (value->len)
            {
              apr_size_t vallen = value->len;

              /* "$keyword: value $" */
              if (vallen > (SVN_KEYWORD_MAX_LEN - 5 - keyword_len))
                vallen = SVN_KEYWORD_MAX_LEN - 5 - keyword_len;
              strncpy(buf_ptr + 2, value->data, vallen);
              buf_ptr[2 + vallen] = ' ';
              buf_ptr[2 + vallen + 1] = '$';
              *len = 5 + keyword_len + vallen;
            }
          else
            {
              /* "$keyword: $"  */
              buf_ptr[2] = '$';
              *len = 4 + keyword_len;
            }
        }
      return TRUE;
    }

  return FALSE;
}

/* Parse BUF (whose length is LEN, and which starts and ends with '$'),
   trying to match one of the keyword names in KEYWORDS.  If such a
   keyword is found, update *KEYWORD_NAME with the keyword name and
   return TRUE. */
static svn_boolean_t
match_keyword(char *buf,
              apr_size_t len,
              char *keyword_name,
              apr_hash_t *keywords)
{
  apr_size_t i;

  /* Early return for ignored keywords */
  if (! keywords)
    return FALSE;

  /* Extract the name of the keyword */
  for (i = 0; i < len - 2 && buf[i + 1] != ':'; i++)
    keyword_name[i] = buf[i + 1];
  keyword_name[i] = '\0';

  return svn_hash_gets(keywords, keyword_name) != NULL;
}

/* Try to translate keyword *KEYWORD_NAME in BUF (whose length is LEN):
   optionally perform the substitution in place, update *LEN with
   the new length of the translated keyword string, and return TRUE.
   If this buffer doesn't contain a known keyword pattern, leave BUF
   and *LEN untouched and return FALSE.

   See the docstring for svn_subst_copy_and_translate for how the
   EXPAND and KEYWORDS parameters work.

   NOTE: It is assumed that BUF has been allocated to be at least
   SVN_KEYWORD_MAX_LEN bytes longs, and that the data in BUF is less
   than or equal SVN_KEYWORD_MAX_LEN in length.  Also, any expansions
   which would result in a keyword string which is greater than
   SVN_KEYWORD_MAX_LEN will have their values truncated in such a way
   that the resultant keyword string is still valid (begins with
   "$Keyword:", ends in " $" and is SVN_KEYWORD_MAX_LEN bytes long).  */
static svn_boolean_t
translate_keyword(char *buf,
                  apr_size_t *len,
                  const char *keyword_name,
                  svn_boolean_t expand,
                  apr_hash_t *keywords)
{
  const svn_string_t *value;

  /* Make sure we gotz good stuffs. */
  assert(*len <= SVN_KEYWORD_MAX_LEN);
  assert((buf[0] == '$') && (buf[*len - 1] == '$'));

  /* Early return for ignored keywords */
  if (! keywords)
    return FALSE;

  value = svn_hash_gets(keywords, keyword_name);

  if (value)
    {
      return translate_keyword_subst(buf, len,
                                     keyword_name, strlen(keyword_name),
                                     expand ? value : NULL);
    }

  return FALSE;
}

/* A boolean expression that evaluates to true if the first STR_LEN characters
   of the string STR are one of the end-of-line strings LF, CR, or CRLF;
   to false otherwise.  */
#define STRING_IS_EOL(str, str_len) \
  (((str_len) == 2 &&  (str)[0] == '\r' && (str)[1] == '\n') || \
   ((str_len) == 1 && ((str)[0] == '\n' || (str)[0] == '\r')))

/* A boolean expression that evaluates to true if the end-of-line string EOL1,
   having length EOL1_LEN, and the end-of-line string EOL2, having length
   EOL2_LEN, are different, assuming that EOL1 and EOL2 are both from the
   set {"\n", "\r", "\r\n"};  to false otherwise.

   Given that EOL1 and EOL2 are either "\n", "\r", or "\r\n", then if
   EOL1_LEN is not the same as EOL2_LEN, then EOL1 and EOL2 are of course
   different. If EOL1_LEN and EOL2_LEN are both 2 then EOL1 and EOL2 are both
   "\r\n" and *EOL1 == *EOL2. Otherwise, EOL1_LEN and EOL2_LEN are both 1.
   We need only check the one character for equality to determine whether
   EOL1 and EOL2 are different in that case. */
#define DIFFERENT_EOL_STRINGS(eol1, eol1_len, eol2, eol2_len) \
  (((eol1_len) != (eol2_len)) || (*(eol1) != *(eol2)))


/* Translate the newline string NEWLINE_BUF (of length NEWLINE_LEN) to
   the newline string EOL_STR (of length EOL_STR_LEN), writing the
   result (which is always EOL_STR) to the stream DST.

   This function assumes that NEWLINE_BUF is either "\n", "\r", or "\r\n".

   Also check for consistency of the source newline strings across
   multiple calls, using SRC_FORMAT (length *SRC_FORMAT_LEN) as a cache
   of the first newline found.  If the current newline is not the same
   as SRC_FORMAT, look to the REPAIR parameter.  If REPAIR is TRUE,
   ignore the inconsistency, else return an SVN_ERR_IO_INCONSISTENT_EOL
   error.  If *SRC_FORMAT_LEN is 0, assume we are examining the first
   newline in the file, and copy it to {SRC_FORMAT, *SRC_FORMAT_LEN} to
   use for later consistency checks.

   If TRANSLATED_EOL is not NULL, then set *TRANSLATED_EOL to TRUE if the
   newline string that was written (EOL_STR) is not the same as the newline
   string that was translated (NEWLINE_BUF), otherwise leave *TRANSLATED_EOL
   untouched.

   Note: all parameters are required even if REPAIR is TRUE.
   ### We could require that REPAIR must not change across a sequence of
       calls, and could then optimize by not using SRC_FORMAT at all if
       REPAIR is TRUE.
*/
static svn_error_t *
translate_newline(const char *eol_str,
                  apr_size_t eol_str_len,
                  char *src_format,
                  apr_size_t *src_format_len,
                  const char *newline_buf,
                  apr_size_t newline_len,
                  svn_stream_t *dst,
                  svn_boolean_t *translated_eol,
                  svn_boolean_t repair)
{
  SVN_ERR_ASSERT(STRING_IS_EOL(newline_buf, newline_len));

  /* If we've seen a newline before, compare it with our cache to
     check for consistency, else cache it for future comparisons. */
  if (*src_format_len)
    {
      /* Comparing with cache.  If we are inconsistent and
         we are NOT repairing the file, generate an error! */
      if ((! repair) && DIFFERENT_EOL_STRINGS(src_format, *src_format_len,
                                              newline_buf, newline_len))
        return svn_error_create(SVN_ERR_IO_INCONSISTENT_EOL, NULL, NULL);
    }
  else
    {
      /* This is our first line ending, so cache it before
         handling it. */
      strncpy(src_format, newline_buf, newline_len);
      *src_format_len = newline_len;
    }

  /* Write the desired newline */
  SVN_ERR(translate_write(dst, eol_str, eol_str_len));

  /* Report whether we translated it.  Note: Not using DIFFERENT_EOL_STRINGS()
   * because EOL_STR may not be a valid EOL sequence. */
  if (translated_eol != NULL &&
      (eol_str_len != newline_len ||
       memcmp(eol_str, newline_buf, eol_str_len) != 0))
    *translated_eol = TRUE;

  return SVN_NO_ERROR;
}



/*** Public interfaces. ***/

svn_boolean_t
svn_subst_keywords_differ(const svn_subst_keywords_t *a,
                          const svn_subst_keywords_t *b,
                          svn_boolean_t compare_values)
{
  if (((a == NULL) && (b == NULL)) /* no A or B */
      /* no A, and B has no contents */
      || ((a == NULL)
          && (b->revision == NULL)
          && (b->date == NULL)
          && (b->author == NULL)
          && (b->url == NULL))
      /* no B, and A has no contents */
      || ((b == NULL)           && (a->revision == NULL)
          && (a->date == NULL)
          && (a->author == NULL)
          && (a->url == NULL))
      /* neither A nor B has any contents */
      || ((a != NULL) && (b != NULL)
          && (b->revision == NULL)
          && (b->date == NULL)
          && (b->author == NULL)
          && (b->url == NULL)
          && (a->revision == NULL)
          && (a->date == NULL)
          && (a->author == NULL)
          && (a->url == NULL)))
    {
      return FALSE;
    }
  else if ((a == NULL) || (b == NULL))
    return TRUE;

  /* Else both A and B have some keywords. */

  if ((! a->revision) != (! b->revision))
    return TRUE;
  else if ((compare_values && (a->revision != NULL))
           && (strcmp(a->revision->data, b->revision->data) != 0))
    return TRUE;

  if ((! a->date) != (! b->date))
    return TRUE;
  else if ((compare_values && (a->date != NULL))
           && (strcmp(a->date->data, b->date->data) != 0))
    return TRUE;

  if ((! a->author) != (! b->author))
    return TRUE;
  else if ((compare_values && (a->author != NULL))
           && (strcmp(a->author->data, b->author->data) != 0))
    return TRUE;

  if ((! a->url) != (! b->url))
    return TRUE;
  else if ((compare_values && (a->url != NULL))
           && (strcmp(a->url->data, b->url->data) != 0))
    return TRUE;

  /* Else we never found a difference, so they must be the same. */

  return FALSE;
}

svn_boolean_t
svn_subst_keywords_differ2(apr_hash_t *a,
                           apr_hash_t *b,
                           svn_boolean_t compare_values,
                           apr_pool_t *pool)
{
  apr_hash_index_t *hi;
  unsigned int a_count, b_count;

  /* An empty hash is logically equal to a NULL,
   * as far as this API is concerned. */
  a_count = (a == NULL) ? 0 : apr_hash_count(a);
  b_count = (b == NULL) ? 0 : apr_hash_count(b);

  if (a_count != b_count)
    return TRUE;

  if (a_count == 0)
    return FALSE;

  /* The hashes are both non-NULL, and have the same number of items.
   * We must check that every item of A is present in B. */
  for (hi = apr_hash_first(pool, a); hi; hi = apr_hash_next(hi))
    {
      const void *key;
      apr_ssize_t klen;
      void *void_a_val;
      svn_string_t *a_val, *b_val;

      apr_hash_this(hi, &key, &klen, &void_a_val);
      a_val = void_a_val;
      b_val = apr_hash_get(b, key, klen);

      if (!b_val || (compare_values && !svn_string_compare(a_val, b_val)))
        return TRUE;
    }

  return FALSE;
}


/* Baton for translate_chunk() to store its state in. */
struct translation_baton
{
  const char *eol_str;
  svn_boolean_t *translated_eol;
  svn_boolean_t repair;
  apr_hash_t *keywords;
  svn_boolean_t expand;

  /* 'short boolean' array that encodes what character values
     may trigger a translation action, hence are 'interesting' */
  char interesting[256];

  /* Length of the string EOL_STR points to. */
  apr_size_t eol_str_len;

  /* Buffer to cache any newline state between translation chunks */
  char newline_buf[2];

  /* Offset (within newline_buf) of the first *unused* character */
  apr_size_t newline_off;

  /* Buffer to cache keyword-parsing state between translation chunks */
  char keyword_buf[SVN_KEYWORD_MAX_LEN];

  /* Offset (within keyword-buf) to the first *unused* character */
  apr_size_t keyword_off;

  /* EOL style used in the chunk-source */
  char src_format[2];

  /* Length of the EOL style string found in the chunk-source,
     or zero if none encountered yet */
  apr_size_t src_format_len;

  /* If this is svn_tristate_false, translate_newline() will be called
     for every newline in the file */
  svn_tristate_t nl_translation_skippable;
};


/* Allocate a baton for use with translate_chunk() in POOL and
 * initialize it for the first iteration.
 *
 * The caller must assure that EOL_STR and KEYWORDS at least
 * have the same life time as that of POOL.
 */
static struct translation_baton *
create_translation_baton(const char *eol_str,
                         svn_boolean_t *translated_eol,
                         svn_boolean_t repair,
                         apr_hash_t *keywords,
                         svn_boolean_t expand,
                         apr_pool_t *pool)
{
  struct translation_baton *b = apr_palloc(pool, sizeof(*b));

  /* For efficiency, convert an empty set of keywords to NULL. */
  if (keywords && (apr_hash_count(keywords) == 0))
    keywords = NULL;

  b->eol_str = eol_str;
  b->eol_str_len = eol_str ? strlen(eol_str) : 0;
  b->translated_eol = translated_eol;
  b->repair = repair;
  b->keywords = keywords;
  b->expand = expand;
  b->newline_off = 0;
  b->keyword_off = 0;
  b->src_format_len = 0;
  b->nl_translation_skippable = svn_tristate_unknown;

  /* Most characters don't start translation actions.
   * Mark those that do depending on the parameters we got. */
  memset(b->interesting, FALSE, sizeof(b->interesting));
  if (keywords)
    b->interesting['$'] = TRUE;
  if (eol_str)
    {
      b->interesting['\r'] = TRUE;
      b->interesting['\n'] = TRUE;
    }

  return b;
}

/* Return TRUE if the EOL starting at BUF matches the eol_str member of B.
 * Be aware of special cases like "\n\r\n" and "\n\n\r". For sequences like
 * "\n$" (an EOL followed by a keyword), the result will be FALSE since it is
 * more efficient to handle that special case implicitly in the calling code
 * by exiting the quick scan loop.
 * The caller must ensure that buf[0] and buf[1] refer to valid memory
 * locations.
 */
static APR_INLINE svn_boolean_t
eol_unchanged(struct translation_baton *b,
              const char *buf)
{
  /* If the first byte doesn't match, the whole EOL won't.
   * This does also handle the (certainly invalid) case that
   * eol_str would be an empty string.
   */
  if (buf[0] != b->eol_str[0])
    return FALSE;

  /* two-char EOLs must be a full match */
  if (b->eol_str_len == 2)
    return buf[1] == b->eol_str[1];

  /* The first char matches the required 1-byte EOL.
   * But maybe, buf[] contains a 2-byte EOL?
   * In that case, the second byte will be interesting
   * and not be another EOL of its own.
   */
  return !b->interesting[(unsigned char)buf[1]] || buf[0] == buf[1];
}


/* Translate eols and keywords of a 'chunk' of characters BUF of size BUFLEN
 * according to the settings and state stored in baton B.
 *
 * Write output to stream DST.
 *
 * To finish a series of chunk translations, flush all buffers by calling
 * this routine with a NULL value for BUF.
 *
 * If B->translated_eol is not NULL, then set *B->translated_eol to TRUE if
 * an end-of-line sequence was changed, otherwise leave it untouched.
 *
 * Use POOL for temporary allocations.
 */
static svn_error_t *
translate_chunk(svn_stream_t *dst,
                struct translation_baton *b,
                const char *buf,
                apr_size_t buflen,
                apr_pool_t *pool)
{
  const char *p;
  apr_size_t len;

  if (buf)
    {
      /* precalculate some oft-used values */
      const char *end = buf + buflen;
      const char *interesting = b->interesting;
      apr_size_t next_sign_off = 0;

      /* At the beginning of this loop, assume that we might be in an
       * interesting state, i.e. with data in the newline or keyword
       * buffer.  First try to get to the boring state so we can copy
       * a run of boring characters; then try to get back to the
       * interesting state by processing an interesting character,
       * and repeat. */
      for (p = buf; p < end;)
        {
          /* Try to get to the boring state, if necessary. */
          if (b->newline_off)
            {
              if (*p == '\n')
                b->newline_buf[b->newline_off++] = *p++;

              SVN_ERR(translate_newline(b->eol_str, b->eol_str_len,
                                        b->src_format,
                                        &b->src_format_len, b->newline_buf,
                                        b->newline_off, dst, b->translated_eol,
                                        b->repair));

              b->newline_off = 0;
            }
          else if (b->keyword_off && *p == '$')
            {
              svn_boolean_t keyword_matches;
              char keyword_name[SVN_KEYWORD_MAX_LEN + 1];

              /* If keyword is matched, but not correctly translated, try to
               * look for the next ending '$'. */
              b->keyword_buf[b->keyword_off++] = *p++;
              keyword_matches = match_keyword(b->keyword_buf, b->keyword_off,
                                              keyword_name, b->keywords);
              if (!keyword_matches)
                {
                  /* reuse the ending '$' */
                  p--;
                  b->keyword_off--;
                }

              if (!keyword_matches ||
                  translate_keyword(b->keyword_buf, &b->keyword_off,
                                    keyword_name, b->expand, b->keywords) ||
                  b->keyword_off >= SVN_KEYWORD_MAX_LEN)
                {
                  /* write out non-matching text or translated keyword */
                  SVN_ERR(translate_write(dst, b->keyword_buf, b->keyword_off));

                  next_sign_off = 0;
                  b->keyword_off = 0;
                }
              else
                {
                  if (next_sign_off == 0)
                    next_sign_off = b->keyword_off - 1;

                  continue;
                }
            }
          else if (b->keyword_off == SVN_KEYWORD_MAX_LEN - 1
                   || (b->keyword_off && (*p == '\r' || *p == '\n')))
            {
              if (next_sign_off > 0)
              {
                /* rolling back, continue with next '$' in keyword_buf */
                p -= (b->keyword_off - next_sign_off);
                b->keyword_off = next_sign_off;
                next_sign_off = 0;
              }
              /* No closing '$' found; flush the keyword buffer. */
              SVN_ERR(translate_write(dst, b->keyword_buf, b->keyword_off));

              b->keyword_off = 0;
            }
          else if (b->keyword_off)
            {
              b->keyword_buf[b->keyword_off++] = *p++;
              continue;
            }

          /* translate_newline will modify the baton for src_format_len==0
             or may return an error if b->repair is FALSE.  In all other
             cases, we can skip the newline translation as long as source
             EOL format and actual EOL format match.  If there is a
             mismatch, translate_newline will be called regardless of
             nl_translation_skippable.
           */
          if (b->nl_translation_skippable == svn_tristate_unknown &&
              b->src_format_len > 0)
            {
              /* test whether translate_newline may return an error */
              if (b->eol_str_len == b->src_format_len &&
                  strncmp(b->eol_str, b->src_format, b->eol_str_len) == 0)
                b->nl_translation_skippable = svn_tristate_true;
              else if (b->repair)
                b->nl_translation_skippable = svn_tristate_true;
              else
                b->nl_translation_skippable = svn_tristate_false;
            }

          /* We're in the boring state; look for interesting characters.
             Offset len such that it will become 0 in the first iteration.
           */
          len = 0 - b->eol_str_len;

          /* Look for the next EOL (or $) that actually needs translation.
             Stop there or at EOF, whichever is encountered first.
           */
          do
            {
              /* skip current EOL */
              len += b->eol_str_len;

              if (b->keywords)
                {
                  /* Check 4 bytes at once to allow for efficient pipelining
                    and to reduce loop condition overhead. */
                  while ((end - p) >= (len + 4))
                    {
                      if (interesting[(unsigned char)p[len]]
                          || interesting[(unsigned char)p[len+1]]
                          || interesting[(unsigned char)p[len+2]]
                          || interesting[(unsigned char)p[len+3]])
                        break;

                      len += 4;
                    }

                  /* Found an interesting char or EOF in the next 4 bytes.
                     Find its exact position. */
                  while ((p + len) < end
                         && !interesting[(unsigned char)p[len]])
                    ++len;
                }
              else
                {
                  /* use our optimized sub-routine to find the next EOL */
                  const char *start = p + len;
                  const char *eol
                    = svn_eol__find_eol_start((char *)start, end - start);

                  /* EOL will be NULL if we did not find a line ending */
                  len += (eol ? eol : end) - start;
                }
            }
          while (b->nl_translation_skippable ==
                   svn_tristate_true &&       /* can potentially skip EOLs */
                 (end - p) > (len + 2) &&     /* not too close to EOF */
                 eol_unchanged(b, p + len));  /* EOL format already ok */

          while ((p + len) < end && !interesting[(unsigned char)p[len]])
            len++;

          if (len)
            {
              SVN_ERR(translate_write(dst, p, len));
              p += len;
            }

          /* Set up state according to the interesting character, if any. */
          if (p < end)
            {
              switch (*p)
                {
                case '$':
                  b->keyword_buf[b->keyword_off++] = *p++;
                  break;
                case '\r':
                  b->newline_buf[b->newline_off++] = *p++;
                  break;
                case '\n':
                  b->newline_buf[b->newline_off++] = *p++;

                  SVN_ERR(translate_newline(b->eol_str, b->eol_str_len,
                                            b->src_format,
                                            &b->src_format_len,
                                            b->newline_buf,
                                            b->newline_off, dst,
                                            b->translated_eol, b->repair));

                  b->newline_off = 0;
                  break;

                }
            }
        }
    }
  else
    {
      if (b->newline_off)
        {
          SVN_ERR(translate_newline(b->eol_str, b->eol_str_len,
                                    b->src_format, &b->src_format_len,
                                    b->newline_buf, b->newline_off,
                                    dst, b->translated_eol, b->repair));
          b->newline_off = 0;
        }

      if (b->keyword_off)
        {
          SVN_ERR(translate_write(dst, b->keyword_buf, b->keyword_off));
          b->keyword_off = 0;
        }
    }

  return SVN_NO_ERROR;
}

/* Baton for use with translated stream callbacks. */
struct translated_stream_baton
{
  /* Stream to take input from (before translation) on read
     /write output to (after translation) on write. */
  svn_stream_t *stream;

  /* Input/Output translation batons to make them separate chunk streams. */
  struct translation_baton *in_baton, *out_baton;

  /* Remembers whether any write operations have taken place;
     if so, we need to flush the output chunk stream. */
  svn_boolean_t written;

  /* Buffer to hold translated read data. */
  svn_stringbuf_t *readbuf;

  /* Offset of the first non-read character in readbuf. */
  apr_size_t readbuf_off;

  /* Buffer to hold read data
     between svn_stream_read() and translate_chunk(). */
  char *buf;
#define SVN__TRANSLATION_BUF_SIZE (SVN__STREAM_CHUNK_SIZE + 1)

  /* Pool for callback iterations */
  apr_pool_t *iterpool;
};


/* Implements svn_read_fn_t. */
static svn_error_t *
translated_stream_read(void *baton,
                       char *buffer,
                       apr_size_t *len)
{
  struct translated_stream_baton *b = baton;
  apr_size_t readlen = SVN__STREAM_CHUNK_SIZE;
  apr_size_t unsatisfied = *len;
  apr_size_t off = 0;

  /* Optimization for a frequent special case. The configuration parser (and
     a few others) reads the stream one byte at a time. All the memcpy, pool
     clearing etc. imposes a huge overhead in that case. In most cases, we
     can just take that single byte directly from the read buffer.

     Since *len > 1 requires lots of code to be run anyways, we can afford
     the extra overhead of checking for *len == 1.

     See <http://mail-archives.apache.org/mod_mbox/subversion-dev/201003.mbox/%3C4B94011E.1070207@alice-dsl.de%3E>.
  */
  if (unsatisfied == 1 && b->readbuf_off < b->readbuf->len)
    {
      /* Just take it from the read buffer */
      *buffer = b->readbuf->data[b->readbuf_off++];

      return SVN_NO_ERROR;
    }

  /* Standard code path. */
  while (readlen == SVN__STREAM_CHUNK_SIZE && unsatisfied > 0)
    {
      apr_size_t to_copy;
      apr_size_t buffer_remainder;

      svn_pool_clear(b->iterpool);
      /* fill read buffer, if necessary */
      if (! (b->readbuf_off < b->readbuf->len))
        {
          svn_stream_t *buf_stream;

          svn_stringbuf_setempty(b->readbuf);
          b->readbuf_off = 0;
          SVN_ERR(svn_stream_read_full(b->stream, b->buf, &readlen));
          buf_stream = svn_stream_from_stringbuf(b->readbuf, b->iterpool);

          SVN_ERR(translate_chunk(buf_stream, b->in_baton, b->buf,
                                  readlen, b->iterpool));

          if (readlen != SVN__STREAM_CHUNK_SIZE)
            SVN_ERR(translate_chunk(buf_stream, b->in_baton, NULL, 0,
                                    b->iterpool));

          SVN_ERR(svn_stream_close(buf_stream));
        }

      /* Satisfy from the read buffer */
      buffer_remainder = b->readbuf->len - b->readbuf_off;
      to_copy = (buffer_remainder > unsatisfied)
        ? unsatisfied : buffer_remainder;
      memcpy(buffer + off, b->readbuf->data + b->readbuf_off, to_copy);
      off += to_copy;
      b->readbuf_off += to_copy;
      unsatisfied -= to_copy;
    }

  *len -= unsatisfied;

  return SVN_NO_ERROR;
}

/* Implements svn_write_fn_t. */
static svn_error_t *
translated_stream_write(void *baton,
                        const char *buffer,
                        apr_size_t *len)
{
  struct translated_stream_baton *b = baton;
  svn_pool_clear(b->iterpool);

  b->written = TRUE;
  return translate_chunk(b->stream, b->out_baton, buffer, *len, b->iterpool);
}

/* Implements svn_close_fn_t. */
static svn_error_t *
translated_stream_close(void *baton)
{
  struct translated_stream_baton *b = baton;
  svn_error_t *err = NULL;

  if (b->written)
    err = translate_chunk(b->stream, b->out_baton, NULL, 0, b->iterpool);

  err = svn_error_compose_create(err, svn_stream_close(b->stream));

  svn_pool_destroy(b->iterpool);

  return svn_error_trace(err);
}


/* svn_stream_mark_t for translation streams. */
typedef struct mark_translated_t
{
  /* Saved translation state. */
  struct translated_stream_baton saved_baton;

  /* Mark set on the underlying stream. */
  svn_stream_mark_t *mark;
} mark_translated_t;

/* Implements svn_stream_mark_fn_t. */
static svn_error_t *
translated_stream_mark(void *baton, svn_stream_mark_t **mark, apr_pool_t *pool)
{
  mark_translated_t *mt;
  struct translated_stream_baton *b = baton;

  mt = apr_palloc(pool, sizeof(*mt));
  SVN_ERR(svn_stream_mark(b->stream, &mt->mark, pool));

  /* Save translation state. */
  mt->saved_baton.in_baton = apr_pmemdup(pool, b->in_baton,
                                         sizeof(*mt->saved_baton.in_baton));
  mt->saved_baton.out_baton = apr_pmemdup(pool, b->out_baton,
                                          sizeof(*mt->saved_baton.out_baton));
  mt->saved_baton.written = b->written;
  mt->saved_baton.readbuf = svn_stringbuf_dup(b->readbuf, pool);
  mt->saved_baton.readbuf_off = b->readbuf_off;
  mt->saved_baton.buf = apr_pmemdup(pool, b->buf, SVN__TRANSLATION_BUF_SIZE);

  *mark = (svn_stream_mark_t *)mt;

  return SVN_NO_ERROR;
}

/* Implements svn_stream_seek_fn_t. */
static svn_error_t *
translated_stream_seek(void *baton, const svn_stream_mark_t *mark)
{
  struct translated_stream_baton *b = baton;

  if (mark != NULL)
    {
      const mark_translated_t *mt = (const mark_translated_t *)mark;

      /* Flush output buffer if necessary. */
      if (b->written)
        SVN_ERR(translate_chunk(b->stream, b->out_baton, NULL, 0,
                                b->iterpool));

      SVN_ERR(svn_stream_seek(b->stream, mt->mark));

      /* Restore translation state, avoiding new allocations. */
      *b->in_baton = *mt->saved_baton.in_baton;
      *b->out_baton = *mt->saved_baton.out_baton;
      b->written = mt->saved_baton.written;
      svn_stringbuf_setempty(b->readbuf);
      svn_stringbuf_appendbytes(b->readbuf, mt->saved_baton.readbuf->data,
                                mt->saved_baton.readbuf->len);
      b->readbuf_off = mt->saved_baton.readbuf_off;
      memcpy(b->buf, mt->saved_baton.buf, SVN__TRANSLATION_BUF_SIZE);
    }
  else
    {
      SVN_ERR(svn_stream_reset(b->stream));

      b->in_baton->newline_off = 0;
      b->in_baton->keyword_off = 0;
      b->in_baton->src_format_len = 0;
      b->out_baton->newline_off = 0;
      b->out_baton->keyword_off = 0;
      b->out_baton->src_format_len = 0;

      b->written = FALSE;
      svn_stringbuf_setempty(b->readbuf);
      b->readbuf_off = 0;
    }

  return SVN_NO_ERROR;
}

/* Implements svn_stream__is_buffered_fn_t. */
static svn_boolean_t
translated_stream_is_buffered(void *baton)
{
  struct translated_stream_baton *b = baton;
  return svn_stream__is_buffered(b->stream);
}

svn_error_t *
svn_subst_read_specialfile(svn_stream_t **stream,
                           const char *path,
                           apr_pool_t *result_pool,
                           apr_pool_t *scratch_pool)
{
  apr_finfo_t finfo;
  svn_string_t *buf;

  /* First determine what type of special file we are
     detranslating. */
  SVN_ERR(svn_io_stat(&finfo, path, APR_FINFO_MIN | APR_FINFO_LINK,
                      scratch_pool));

  switch (finfo.filetype) {
  case APR_REG:
    /* Nothing special to do here, just create stream from the original
       file's contents. */
    SVN_ERR(svn_stream_open_readonly(stream, path, result_pool, scratch_pool));
    break;

  case APR_LNK:
    /* Determine the destination of the link. */
    SVN_ERR(svn_io_read_link(&buf, path, scratch_pool));
    *stream = svn_stream_from_string(svn_string_createf(result_pool,
                                                        "link %s",
                                                        buf->data),
                                     result_pool);
    break;

  default:
    SVN_ERR_MALFUNCTION();
  }

  return SVN_NO_ERROR;
}

/* Same as svn_subst_stream_translated(), except for the following.
 *
 * If TRANSLATED_EOL is not NULL, then reading and/or writing to the stream
 * will set *TRANSLATED_EOL to TRUE if an end-of-line sequence was changed,
 * otherwise leave it untouched.
 */
static svn_stream_t *
stream_translated(svn_stream_t *stream,
                  const char *eol_str,
                  svn_boolean_t *translated_eol,
                  svn_boolean_t repair,
                  apr_hash_t *keywords,
                  svn_boolean_t expand,
                  apr_pool_t *result_pool)
{
  struct translated_stream_baton *baton
    = apr_palloc(result_pool, sizeof(*baton));
  svn_stream_t *s = svn_stream_create(baton, result_pool);

  /* Make sure EOL_STR and KEYWORDS are allocated in RESULT_POOL
     so they have the same lifetime as the stream. */
  if (eol_str)
    eol_str = apr_pstrdup(result_pool, eol_str);
  if (keywords)
    {
      if (apr_hash_count(keywords) == 0)
        keywords = NULL;
      else
        {
          /* deep copy the hash to make sure it's allocated in RESULT_POOL */
          apr_hash_t *copy = apr_hash_make(result_pool);
          apr_hash_index_t *hi;
          apr_pool_t *subpool;

          subpool = svn_pool_create(result_pool);
          for (hi = apr_hash_first(subpool, keywords);
               hi; hi = apr_hash_next(hi))
            {
              const void *key;
              void *val;

              apr_hash_this(hi, &key, NULL, &val);
              svn_hash_sets(copy, apr_pstrdup(result_pool, key),
                            svn_string_dup(val, result_pool));
            }
          svn_pool_destroy(subpool);

          keywords = copy;
        }
    }

  /* Setup the baton fields */
  baton->stream = stream;
  baton->in_baton
    = create_translation_baton(eol_str, translated_eol, repair, keywords,
                               expand, result_pool);
  baton->out_baton
    = create_translation_baton(eol_str, translated_eol, repair, keywords,
                               expand, result_pool);
  baton->written = FALSE;
  baton->readbuf = svn_stringbuf_create_empty(result_pool);
  baton->readbuf_off = 0;
  baton->iterpool = svn_pool_create(result_pool);
  baton->buf = apr_palloc(result_pool, SVN__TRANSLATION_BUF_SIZE);

  /* Setup the stream methods */
  svn_stream_set_read2(s, NULL /* only full read support */,
                       translated_stream_read);
  svn_stream_set_write(s, translated_stream_write);
  svn_stream_set_close(s, translated_stream_close);
  svn_stream_set_mark(s, translated_stream_mark);
  svn_stream_set_seek(s, translated_stream_seek);
  svn_stream__set_is_buffered(s, translated_stream_is_buffered);

  return s;
}

svn_stream_t *
svn_subst_stream_translated(svn_stream_t *stream,
                            const char *eol_str,
                            svn_boolean_t repair,
                            apr_hash_t *keywords,
                            svn_boolean_t expand,
                            apr_pool_t *result_pool)
{
  return stream_translated(stream, eol_str, NULL, repair, keywords, expand,
                           result_pool);
}

/* Same as svn_subst_translate_cstring2(), except for the following.
 *
 * If TRANSLATED_EOL is not NULL, then set *TRANSLATED_EOL to TRUE if an
 * end-of-line sequence was changed, or to FALSE otherwise.
 */
static svn_error_t *
translate_cstring(const char **dst,
                  svn_boolean_t *translated_eol,
                  const char *src,
                  const char *eol_str,
                  svn_boolean_t repair,
                  apr_hash_t *keywords,
                  svn_boolean_t expand,
                  apr_pool_t *pool)
{
  svn_stringbuf_t *dst_stringbuf;
  svn_stream_t *dst_stream;
  apr_size_t len = strlen(src);

  /* The easy way out:  no translation needed, just copy. */
  if (! (eol_str || (keywords && (apr_hash_count(keywords) > 0))))
    {
      *dst = apr_pstrmemdup(pool, src, len);
      return SVN_NO_ERROR;
    }

  /* Create a stringbuf and wrapper stream to hold the output. */
  dst_stringbuf = svn_stringbuf_create_empty(pool);
  dst_stream = svn_stream_from_stringbuf(dst_stringbuf, pool);

  if (translated_eol)
    *translated_eol = FALSE;

  /* Another wrapper to translate the content. */
  dst_stream = stream_translated(dst_stream, eol_str, translated_eol, repair,
                                 keywords, expand, pool);

  /* Jam the text into the destination stream (to translate it). */
  SVN_ERR(svn_stream_write(dst_stream, src, &len));

  /* Close the destination stream to flush unwritten data. */
  SVN_ERR(svn_stream_close(dst_stream));

  *dst = dst_stringbuf->data;
  return SVN_NO_ERROR;
}

svn_error_t *
svn_subst_translate_cstring2(const char *src,
                             const char **dst,
                             const char *eol_str,
                             svn_boolean_t repair,
                             apr_hash_t *keywords,
                             svn_boolean_t expand,
                             apr_pool_t *pool)
{
  return translate_cstring(dst, NULL, src, eol_str, repair, keywords, expand,
                            pool);
}

/* Given a special file at SRC, generate a textual representation of
   it in a normal file at DST.  Perform all allocations in POOL. */
/* ### this should be folded into svn_subst_copy_and_translate3 */
static svn_error_t *
detranslate_special_file(const char *src, const char *dst,
                         svn_cancel_func_t cancel_func, void *cancel_baton,
                         apr_pool_t *scratch_pool)
{
  const char *dst_tmp;
  svn_stream_t *src_stream;
  svn_stream_t *dst_stream;

  /* Open a temporary destination that we will eventually atomically
     rename into place. */
  SVN_ERR(svn_stream_open_unique(&dst_stream, &dst_tmp,
                                 svn_dirent_dirname(dst, scratch_pool),
                                 svn_io_file_del_none,
                                 scratch_pool, scratch_pool));
  SVN_ERR(svn_subst_read_specialfile(&src_stream, src,
                                     scratch_pool, scratch_pool));
  SVN_ERR(svn_stream_copy3(src_stream, dst_stream,
                           cancel_func, cancel_baton, scratch_pool));

  /* Do the atomic rename from our temporary location. */
  return svn_error_trace(svn_io_file_rename2(dst_tmp, dst, FALSE, scratch_pool));
}

/* Creates a special file DST from the "normal form" located in SOURCE.
 *
 * All temporary allocations will be done in POOL.
 */
static svn_error_t *
create_special_file_from_stream(svn_stream_t *source, const char *dst,
                                apr_pool_t *pool)
{
  svn_stringbuf_t *contents;
  svn_boolean_t eof;
  const char *identifier;
  const char *remainder;
  const char *dst_tmp;
  svn_boolean_t create_using_internal_representation = FALSE;

  SVN_ERR(svn_stream_readline(source, &contents, "\n", &eof, pool));

  /* Separate off the identifier.  The first space character delimits
     the identifier, after which any remaining characters are specific
     to the actual special file type being created. */
  identifier = contents->data;
  for (remainder = identifier; *remainder; remainder++)
    {
      if (*remainder == ' ')
        {
          remainder++;
          break;
        }
    }

  if (! strncmp(identifier, SVN_SUBST__SPECIAL_LINK_STR " ",
                sizeof(SVN_SUBST__SPECIAL_LINK_STR " ")-1))
    {
      /* For symlinks, the type specific data is just a filesystem
         path that the symlink should reference. */
      svn_error_t *err = svn_io_create_unique_link(&dst_tmp, dst, remainder,
                                                   ".tmp", pool);

      /* If we had an error, check to see if it was because symlinks are
         not supported on the platform.  If so, fall back to using the
         internal representation. */
      if (err && err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE)
        {
          svn_error_clear(err);
          create_using_internal_representation = TRUE;
        }
      else if (err)
        {
          return svn_error_trace(err);
        }
    }
  else
    {
      /* Just create a normal file using the internal special file
         representation.  We don't want a commit of an unknown special
         file type to DoS all the clients. */
      create_using_internal_representation = TRUE;
    }

  /* If nothing else worked, write out the internal representation to
     a file that can be edited by the user. */
  if (create_using_internal_representation)
    {
      svn_stream_t *new_stream;
      apr_size_t len;

      SVN_ERR(svn_stream_open_unique(&new_stream, &dst_tmp,
                                     svn_dirent_dirname(dst, pool),
                                     svn_io_file_del_none,
                                     pool, pool));

      if (!eof)
        svn_stringbuf_appendcstr(contents, "\n");
      len = contents->len;
      SVN_ERR(svn_stream_write(new_stream, contents->data, &len));
      SVN_ERR(svn_stream_copy3(svn_stream_disown(source, pool), new_stream,
                               NULL, NULL, pool));
    }

  /* Do the atomic rename from our temporary location. */
  return svn_error_trace(svn_io_file_rename2(dst_tmp, dst, FALSE, pool));
}


svn_error_t *
svn_subst_copy_and_translate4(const char *src,
                              const char *dst,
                              const char *eol_str,
                              svn_boolean_t repair,
                              apr_hash_t *keywords,
                              svn_boolean_t expand,
                              svn_boolean_t special,
                              svn_cancel_func_t cancel_func,
                              void *cancel_baton,
                              apr_pool_t *pool)
{
  svn_stream_t *src_stream;
  svn_stream_t *dst_stream;
  const char *dst_tmp;
  svn_error_t *err;
  svn_node_kind_t kind;
  svn_boolean_t path_special;

  SVN_ERR(svn_io_check_special_path(src, &kind, &path_special, pool));

  /* If this is a 'special' file, we may need to create it or
     detranslate it. */
  if (special || path_special)
    {
      if (expand)
        {
          if (path_special)
            {
              /* We are being asked to create a special file from a special
                 file.  Do a temporary detranslation and work from there. */

              /* ### woah. this section just undoes all the work we already did
                 ### to read the contents of the special file. shoot... the
                 ### svn_subst_read_specialfile even checks the file type
                 ### for us! */

              SVN_ERR(svn_subst_read_specialfile(&src_stream, src, pool, pool));
            }
          else
            {
              SVN_ERR(svn_stream_open_readonly(&src_stream, src, pool, pool));
            }

          SVN_ERR(create_special_file_from_stream(src_stream, dst, pool));

          return svn_error_trace(svn_stream_close(src_stream));
        }
      /* else !expand */

      return svn_error_trace(detranslate_special_file(src, dst,
                                                      cancel_func,
                                                      cancel_baton,
                                                      pool));
    }

  /* The easy way out:  no translation needed, just copy. */
  if (! (eol_str || (keywords && (apr_hash_count(keywords) > 0))))
    return svn_error_trace(svn_io_copy_file(src, dst, FALSE, pool));

  /* Open source file. */
  SVN_ERR(svn_stream_open_readonly(&src_stream, src, pool, pool));

  /* For atomicity, we translate to a tmp file and then rename the tmp file
     over the real destination. */
  SVN_ERR(svn_stream_open_unique(&dst_stream, &dst_tmp,
                                 svn_dirent_dirname(dst, pool),
                                 svn_io_file_del_none, pool, pool));

  dst_stream = svn_subst_stream_translated(dst_stream, eol_str, repair,
                                           keywords, expand, pool);

  /* ###: use cancel func/baton in place of NULL/NULL below. */
  err = svn_stream_copy3(src_stream, dst_stream, cancel_func, cancel_baton,
                         pool);
  if (err)
    {
      /* On errors, we have a pathname available. */
      if (err->apr_err == SVN_ERR_IO_INCONSISTENT_EOL)
        err = svn_error_createf(SVN_ERR_IO_INCONSISTENT_EOL, err,
                                _("File '%s' has inconsistent newlines"),
                                svn_dirent_local_style(src, pool));
      return svn_error_compose_create(err, svn_io_remove_file2(dst_tmp,
                                                               FALSE, pool));
    }

  /* Now that dst_tmp contains the translated data, do the atomic rename. */
  SVN_ERR(svn_io_file_rename2(dst_tmp, dst, FALSE, pool));

  /* Preserve the source file's permission bits. */
  SVN_ERR(svn_io_copy_perms(src, dst, pool));

  return SVN_NO_ERROR;
}


/*** 'Special file' stream support */

struct special_stream_baton
{
  svn_stream_t *read_stream;
  svn_stringbuf_t *write_content;
  svn_stream_t *write_stream;
  const char *path;
  apr_pool_t *pool;
};


static svn_error_t *
read_handler_special(void *baton, char *buffer, apr_size_t *len)
{
  struct special_stream_baton *btn = baton;

  if (btn->read_stream)
    /* We actually found a file to read from */
    return svn_stream_read_full(btn->read_stream, buffer, len);
  else
    return svn_error_createf(APR_ENOENT, NULL,
                             _("Can't read special file: File '%s' not found"),
                             svn_dirent_local_style(btn->path, btn->pool));
}

static svn_error_t *
write_handler_special(void *baton, const char *buffer, apr_size_t *len)
{
  struct special_stream_baton *btn = baton;

  return svn_stream_write(btn->write_stream, buffer, len);
}


static svn_error_t *
close_handler_special(void *baton)
{
  struct special_stream_baton *btn = baton;

  if (btn->write_content->len)
    {
      /* yeay! we received data and need to create a special file! */

      svn_stream_t *source = svn_stream_from_stringbuf(btn->write_content,
                                                       btn->pool);
      SVN_ERR(create_special_file_from_stream(source, btn->path, btn->pool));
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_subst_create_specialfile(svn_stream_t **stream,
                             const char *path,
                             apr_pool_t *result_pool,
                             apr_pool_t *scratch_pool)
{
  struct special_stream_baton *baton = apr_palloc(result_pool, sizeof(*baton));

  baton->path = apr_pstrdup(result_pool, path);

  /* SCRATCH_POOL may not exist after the function returns. */
  baton->pool = result_pool;

  baton->write_content = svn_stringbuf_create_empty(result_pool);
  baton->write_stream = svn_stream_from_stringbuf(baton->write_content,
                                                  result_pool);

  *stream = svn_stream_create(baton, result_pool);
  svn_stream_set_write(*stream, write_handler_special);
  svn_stream_set_close(*stream, close_handler_special);

  return SVN_NO_ERROR;
}


/* NOTE: this function is deprecated, but we cannot move it over to
   deprecated.c because it uses stuff private to this file, and it is
   not easily rebuilt in terms of "new" functions. */
svn_error_t *
svn_subst_stream_from_specialfile(svn_stream_t **stream,
                                  const char *path,
                                  apr_pool_t *pool)
{
  struct special_stream_baton *baton = apr_palloc(pool, sizeof(*baton));
  svn_error_t *err;

  baton->pool = pool;
  baton->path = apr_pstrdup(pool, path);

  err = svn_subst_read_specialfile(&baton->read_stream, path, pool, pool);

  /* File might not exist because we intend to create it upon close. */
  if (err && APR_STATUS_IS_ENOENT(err->apr_err))
    {
      svn_error_clear(err);

      /* Note: the special file is missing. the caller won't find out
         until the first read. Oh well. This function is deprecated anyways,
         so they can just deal with the weird behavior. */
      baton->read_stream = NULL;
    }

  baton->write_content = svn_stringbuf_create_empty(pool);
  baton->write_stream = svn_stream_from_stringbuf(baton->write_content, pool);

  *stream = svn_stream_create(baton, pool);
  svn_stream_set_read2(*stream, NULL /* only full read support */,
                       read_handler_special);
  svn_stream_set_write(*stream, write_handler_special);
  svn_stream_set_close(*stream, close_handler_special);

  return SVN_NO_ERROR;
}



/*** String translation */
svn_error_t *
svn_subst_translate_string2(svn_string_t **new_value,
                            svn_boolean_t *translated_to_utf8,
                            svn_boolean_t *translated_line_endings,
                            const svn_string_t *value,
                            const char *encoding,
                            svn_boolean_t repair,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
{
  const char *val_utf8;
  const char *val_utf8_lf;

  if (value == NULL)
    {
      *new_value = NULL;
      return SVN_NO_ERROR;
    }

  if (encoding && !strcmp(encoding, "UTF-8"))
    {
      val_utf8 = value->data;
    }
  else if (encoding)
    {
      SVN_ERR(svn_utf_cstring_to_utf8_ex2(&val_utf8, value->data,
                                          encoding, scratch_pool));
    }
  else
    {
      SVN_ERR(svn_utf_cstring_to_utf8(&val_utf8, value->data, scratch_pool));
    }

  if (translated_to_utf8)
    *translated_to_utf8 = (strcmp(value->data, val_utf8) != 0);

  SVN_ERR(translate_cstring(&val_utf8_lf,
                            translated_line_endings,
                            val_utf8,
                            "\n",  /* translate to LF */
                            repair,
                            NULL,  /* no keywords */
                            FALSE, /* no expansion */
                            scratch_pool));

  *new_value = svn_string_create(val_utf8_lf, result_pool);
  return SVN_NO_ERROR;
}


svn_error_t *
svn_subst_detranslate_string(svn_string_t **new_value,
                             const svn_string_t *value,
                             svn_boolean_t for_output,
                             apr_pool_t *pool)
{
  svn_error_t *err;
  const char *val_neol;
  const char *val_nlocale_neol;

  if (value == NULL)
    {
      *new_value = NULL;
      return SVN_NO_ERROR;
    }

  SVN_ERR(svn_subst_translate_cstring2(value->data,
                                       &val_neol,
                                       APR_EOL_STR,  /* 'native' eol */
                                       FALSE, /* no repair */
                                       NULL,  /* no keywords */
                                       FALSE, /* no expansion */
                                       pool));

  if (for_output)
    {
      err = svn_cmdline_cstring_from_utf8(&val_nlocale_neol, val_neol, pool);
      if (err && (APR_STATUS_IS_EINVAL(err->apr_err)))
        {
          val_nlocale_neol =
            svn_cmdline_cstring_from_utf8_fuzzy(val_neol, pool);
          svn_error_clear(err);
        }
      else if (err)
        return err;
    }
  else
    {
      err = svn_utf_cstring_from_utf8(&val_nlocale_neol, val_neol, pool);
      if (err && (APR_STATUS_IS_EINVAL(err->apr_err)))
        {
          val_nlocale_neol = svn_utf_cstring_from_utf8_fuzzy(val_neol, pool);
          svn_error_clear(err);
        }
      else if (err)
        return err;
    }

  *new_value = svn_string_create(val_nlocale_neol, pool);

  return SVN_NO_ERROR;
}
