⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subst.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 3 页
字号:
                              const char *eol_str,
                              svn_boolean_t repair,
                              const svn_subst_keywords_t *keywords,
                              svn_boolean_t expand,
                              apr_pool_t *pool)
{
  return svn_subst_copy_and_translate2 (src, dst, eol_str, repair, keywords,
                                        expand, FALSE, pool);
}


/* Given a special file at SRC, generate a textual representation of
   it in a normal file at DST.  Perform all allocations in POOL. */
static svn_error_t *
detranslate_special_file (const char *src,
                          const char *dst,
                          apr_pool_t *pool)
{
  const char *dst_tmp;
  svn_string_t *buf;
  apr_file_t *s, *d;
  svn_stream_t *src_stream, *dst_stream;
  apr_finfo_t finfo;
  
  /* First determine what type of special file we are
     detranslating. */
  SVN_ERR (svn_io_stat (&finfo, src, APR_FINFO_MIN | APR_FINFO_LINK, pool));

  /* Open a temporary destination that we will eventually atomically
     rename into place. */
  SVN_ERR (svn_io_open_unique_file (&d, &dst_tmp, dst,
                                    ".tmp", FALSE, pool));

  dst_stream = svn_stream_from_aprfile (d, pool);
  
  switch (finfo.filetype) {
  case APR_REG:
    /* Nothing special to do here, just copy the original file's
       contents. */
    SVN_ERR (svn_io_file_open (&s, src, APR_READ | APR_BUFFERED,
                               APR_OS_DEFAULT, pool));
    src_stream = svn_stream_from_aprfile (d, pool);

    SVN_ERR (svn_stream_copy (src_stream, dst_stream, pool));
    break;
  case APR_LNK:
    /* Determine the destination of the link. */
    SVN_ERR (svn_io_read_link (&buf, src, pool));

    SVN_ERR (svn_stream_printf (dst_stream, pool, "link %s",
                                buf->data));
    break;
  default:
    abort ();
  }

  SVN_ERR (svn_io_file_close (d, pool));

  /* Do the atomic rename from our temporary location. */
  SVN_ERR (svn_io_file_rename (dst_tmp, dst, pool));
  
  return SVN_NO_ERROR;
}


/* Given a file containing a repository representation of a special
   file in SRC, create the appropriate special file at location DST.
   Perform all allocations in POOL. */
static svn_error_t *
create_special_file (const char *src,
                     const char *dst,
                     apr_pool_t *pool)
{
  svn_stringbuf_t *contents;
  char *identifier, *remainder;
  const char *dst_tmp, *src_tmp = NULL;
  svn_error_t *err;
  svn_node_kind_t kind;
  svn_boolean_t is_special;

  /* Check to see if we are being asked to create a special file from
     a special file.  If so, do a temporary detranslation and work
     from there. */
  SVN_ERR (svn_io_check_special_path (src, &kind, &is_special, pool));

  if (is_special)
    {
      apr_file_t *fp;
      
      SVN_ERR (svn_io_open_unique_file (&fp, &src_tmp, dst, ".tmp", FALSE,
                                        pool));
      SVN_ERR (svn_io_file_close (fp, pool));
      SVN_ERR (detranslate_special_file (src, src_tmp, pool));
      src = src_tmp;
    }
  
  /* Read in the detranslated file. */
  SVN_ERR (svn_stringbuf_from_file (&contents, src, pool));

  /* If there was just a temporary detranslation, remove it now. */
  if (src_tmp)
    SVN_ERR (svn_io_remove_file (src_tmp, pool));
      
  /* Separate off the identifier.  The first space character delimits
     the identifier, after which any remaining characters are specific
     to the actual special device being created. */
  identifier = contents->data;
  for (remainder = identifier; *remainder; remainder++)
    {
      if (*remainder == ' ')
        {
          *remainder = '\0';
          remainder++;
          break;
        }
    }
           
  if (! strcmp (identifier, SVN_SUBST__SPECIAL_LINK_STR))
    {
      /* For symlinks, the type specific data is just a filesystem
         path that the symlink should reference. */
      err = svn_io_create_unique_link (&dst_tmp, dst, remainder,
                                       ".tmp", pool);
    }
  else
    {
      /* We should return a valid error here. */
      return svn_error_createf (SVN_ERR_UNSUPPORTED_FEATURE, NULL,
                                "Unsupported special file type '%s'",
                                identifier);
    }

  /* If we had an error, check to see if it was because this type of
     special device is not supported. */
  if (err)
    {
      if (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE)
        {
          apr_file_t *fp;
          
          svn_error_clear (err);
          /* Fall back to just copying the text-base. */
          SVN_ERR (svn_io_open_unique_file (&fp, &dst_tmp, dst, ".tmp", FALSE,
                                            pool));
          SVN_ERR (svn_io_file_close (fp, pool));
          SVN_ERR (svn_io_copy_file (src, dst_tmp, TRUE, pool));
        }
      else
        return err;
    }

  /* Do the atomic rename from our temporary location. */
  SVN_ERR (svn_io_file_rename (dst_tmp, dst, pool));

  return SVN_NO_ERROR;
}


svn_error_t *
svn_subst_copy_and_translate2 (const char *src,
                               const char *dst,
                               const char *eol_str,
                               svn_boolean_t repair,
                               const svn_subst_keywords_t *keywords,
                               svn_boolean_t expand,
                               svn_boolean_t special,
                               apr_pool_t *pool)
{
  const char *dst_tmp = NULL;
  svn_stream_t *src_stream, *dst_stream;
  apr_file_t *s = NULL, *d = NULL;  /* init to null important for APR */
  svn_error_t *err;
  apr_pool_t *subpool;
  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)
        SVN_ERR (create_special_file (src, dst, pool));
      else
        SVN_ERR (detranslate_special_file (src, dst, pool));
      
      return SVN_NO_ERROR;
    }

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

  subpool = svn_pool_create (pool);

  /* Open source file. */
  err = svn_io_file_open (&s, src, APR_READ | APR_BUFFERED,
                          APR_OS_DEFAULT, subpool);
  if (err)
    goto error;

  /* For atomicity, we translate to a tmp file and
     then rename the tmp file over the real destination. */

  err = svn_io_open_unique_file (&d, &dst_tmp, dst,
                                 ".tmp", FALSE, subpool);

  /* Move the file name to a more permanent pool. */
  if (dst_tmp)
    dst_tmp = apr_pstrdup(pool, dst_tmp);

  if (err)
    goto error;

  /* Now convert our two open files into streams. */
  src_stream = svn_stream_from_aprfile (s, subpool);
  dst_stream = svn_stream_from_aprfile (d, subpool);

  /* Translate src stream into dst stream. */
  err = svn_subst_translate_stream (src_stream, dst_stream,
                                    eol_str, repair, keywords, expand);
  if (err)
    {
      if (err->apr_err == SVN_ERR_IO_INCONSISTENT_EOL)
        err = svn_error_createf 
          (SVN_ERR_IO_INCONSISTENT_EOL, err,
           _("File '%s' has inconsistent newlines"), src);
      goto error;
    }

  /* clean up nicely. */
  err = svn_stream_close (src_stream);
  if (err)
    goto error;

  err = svn_stream_close (dst_stream);
  if (err)
    goto error;

  err = svn_io_file_close (s, subpool);
  if (err)
    goto error;

  err = svn_io_file_close (d, subpool);
  if (err)
    goto error;

  /* Now that dst_tmp contains the translated data, do the atomic rename. */
  err = svn_io_file_rename (dst_tmp, dst, subpool);
  if (err)
    goto error;

  svn_pool_destroy (subpool);
  return SVN_NO_ERROR;

 error:
  svn_pool_destroy (subpool);   /* Make sure all files are closed first. */
  if (dst_tmp)
    svn_error_clear (svn_io_remove_file (dst_tmp, pool));
  return err;
}



svn_error_t *
svn_subst_translate_string (svn_string_t **new_value,
                            const svn_string_t *value,
                            const char *encoding,
                            apr_pool_t *pool)
{
  const char *val_utf8;
  const char *val_utf8_lf;

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

  if (encoding)
    {
      SVN_ERR (svn_utf_cstring_to_utf8_ex (&val_utf8, value->data,
                                           encoding, NULL, pool));
    }
  else
    {
      SVN_ERR (svn_utf_cstring_to_utf8 (&val_utf8, value->data, pool));
    }

  SVN_ERR (svn_subst_translate_cstring (val_utf8,
                                        &val_utf8_lf,
                                        "\n",  /* translate to LF */
                                        FALSE, /* no repair */
                                        NULL,  /* no keywords */
                                        FALSE, /* no expansion */
                                        pool));
  
  *new_value = svn_string_create (val_utf8_lf, 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_cstring (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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -