コード例 #1
0
static svn_error_t *
test_svn_subst_translate_cstring2(apr_pool_t *pool)
{
  static const struct translate_cstring2_data_t tests[] =
    {
      /* Test the unusual case where EOL_STR is an empty string. */
      { "   \r   \n\r\n     \n\n\n", "", TRUE,
        "           " },
      /* Test the unusual case where EOL_STR is not a standard EOL string. */
      { "   \r   \n\r\n     \n\n\n", "z", TRUE,
        "   z   zz     zzz" },
      { "    \n    \n ", "buzz", FALSE,
        "    buzz    buzz " },
      { "    \r\n    \n", "buzz", TRUE ,
        "    buzz    buzz"},
      { NULL, NULL, FALSE, NULL }
    };
  const struct translate_cstring2_data_t *t;

  for (t = tests; t->source != NULL; t++)
    {
      const char *result = NULL;
      SVN_ERR(svn_subst_translate_cstring2(t->source, &result, t->eol_str,
                                           t->repair, NULL, FALSE, pool));
      SVN_TEST_STRING_ASSERT(result, t->expected_str);
    }

  return SVN_NO_ERROR;
}
コード例 #2
0
ファイル: load-fs-vtable.c プロジェクト: 2asoft/freebsd
svn_error_t *
svn_repos__adjust_mergeinfo_property(svn_string_t **new_value_p,
                                     const svn_string_t *old_value,
                                     const char *parent_dir,
                                     apr_hash_t *rev_map,
                                     svn_revnum_t oldest_dumpstream_rev,
                                     apr_int32_t older_revs_offset,
                                     svn_repos_notify_func_t notify_func,
                                     void *notify_baton,
                                     apr_pool_t *result_pool,
                                     apr_pool_t *scratch_pool)
{
  svn_string_t prop_val = *old_value;

  /* Tolerate mergeinfo with "\r\n" line endings because some
     dumpstream sources might contain as much.  If so normalize
     the line endings to '\n' and notify that we have made this
     correction. */
  if (strstr(prop_val.data, "\r"))
    {
      const char *prop_eol_normalized;

      SVN_ERR(svn_subst_translate_cstring2(prop_val.data,
                                           &prop_eol_normalized,
                                           "\n",  /* translate to LF */
                                           FALSE, /* no repair */
                                           NULL,  /* no keywords */
                                           FALSE, /* no expansion */
                                           result_pool));
      prop_val.data = prop_eol_normalized;
      prop_val.len = strlen(prop_eol_normalized);

      if (notify_func)
        {
          svn_repos_notify_t *notify
                  = svn_repos_notify_create(
                                svn_repos_notify_load_normalized_mergeinfo,
                                scratch_pool);

          notify_func(notify_baton, notify, scratch_pool);
        }
    }

  /* Renumber mergeinfo as appropriate. */
  SVN_ERR(renumber_mergeinfo_revs(new_value_p, &prop_val,
                                  rev_map, oldest_dumpstream_rev,
                                  older_revs_offset,
                                  result_pool));

  if (parent_dir)
    {
      /* Prefix the merge source paths with PARENT_DIR. */
      /* ASSUMPTION: All source paths are included in the dump stream. */
      SVN_ERR(prefix_mergeinfo_paths(new_value_p, *new_value_p,
                                     parent_dir, result_pool));
    }

  return SVN_NO_ERROR;
}
コード例 #3
0
ファイル: load-fs-vtable.c プロジェクト: ngkaho1234/freebsd
/* Adjust mergeinfo:
 *   - normalize line endings (if all CRLF, change to LF; but error if mixed);
 *   - adjust revision numbers (see renumber_mergeinfo_revs());
 *   - adjust paths (see prefix_mergeinfo_paths()).
 */
static svn_error_t *
adjust_mergeinfo_property(struct revision_baton *rb,
                          svn_string_t **new_value_p,
                          const svn_string_t *old_value,
                          apr_pool_t *result_pool)
{
  struct parse_baton *pb = rb->pb;
  svn_string_t prop_val = *old_value;

  /* Tolerate mergeinfo with "\r\n" line endings because some
     dumpstream sources might contain as much.  If so normalize
     the line endings to '\n' and make a notification to
     PARSE_BATON->FEEDBACK_STREAM that we have made this
     correction. */
  if (strstr(prop_val.data, "\r"))
    {
      const char *prop_eol_normalized;

      SVN_ERR(svn_subst_translate_cstring2(prop_val.data,
                                           &prop_eol_normalized,
                                           "\n",  /* translate to LF */
                                           FALSE, /* no repair */
                                           NULL,  /* no keywords */
                                           FALSE, /* no expansion */
                                           result_pool));
      prop_val.data = prop_eol_normalized;
      prop_val.len = strlen(prop_eol_normalized);

      if (pb->notify_func)
        {
          /* ### TODO: Use proper scratch pool instead of pb->notify_pool */
          svn_repos_notify_t *notify
                  = svn_repos_notify_create(
                                svn_repos_notify_load_normalized_mergeinfo,
                                pb->notify_pool);

          pb->notify_func(pb->notify_baton, notify, pb->notify_pool);
          svn_pool_clear(pb->notify_pool);
        }
    }

  /* Renumber mergeinfo as appropriate. */
  SVN_ERR(renumber_mergeinfo_revs(new_value_p, &prop_val, rb,
                                  result_pool));
  if (pb->parent_dir)
    {
      /* Prefix the merge source paths with PB->parent_dir. */
      /* ASSUMPTION: All source paths are included in the dump stream. */
      SVN_ERR(prefix_mergeinfo_paths(new_value_p, *new_value_p,
                                     pb->parent_dir, result_pool));
    }

  return SVN_NO_ERROR;
}
コード例 #4
0
ファイル: deprecated.c プロジェクト: Alkzndr/freebsd
svn_error_t *
svn_subst_translate_cstring(const char *src,
                            const char **dst,
                            const char *eol_str,
                            svn_boolean_t repair,
                            const svn_subst_keywords_t *keywords,
                            svn_boolean_t expand,
                            apr_pool_t *pool)
{
  apr_hash_t *kh = kwstruct_to_kwhash(keywords, pool);

  return svn_error_trace(svn_subst_translate_cstring2(src, dst, eol_str,
                                                      repair, kh, expand,
                                                      pool));
}
コード例 #5
0
ファイル: util.c プロジェクト: ChaosJohn/freebsd
svn_error_t *
svn_rdump__normalize_prop(const char *name,
                          const svn_string_t **value,
                          apr_pool_t *result_pool)
{
  if (svn_prop_needs_translation(name))
    {
      const char *cstring;

      SVN_ERR(svn_subst_translate_cstring2((*value)->data, &cstring,
                                           "\n", TRUE,
                                           NULL, FALSE,
                                           result_pool));

      *value = svn_string_create(cstring, result_pool);
    }
  return SVN_NO_ERROR;
}
コード例 #6
0
ファイル: propget-cmd.c プロジェクト: Distrotech/subversion
/* Print the properties in PROPS to the stream OUT. PROPS is a hash mapping
 * (const char *) path to (svn_string_t) property value.
 * If IS_URL is true, all paths are URLs, else all paths are local paths.
 * PNAME_UTF8 is the property name of all the properties.
 * If PRINT_FILENAMES is true, print the item's path before each property.
 * If OMIT_NEWLINE is true, don't add a newline at the end of each property.
 * If LIKE_PROPLIST is true, print everything in a more verbose format
 * like "svn proplist -v" does.
 * */
static svn_error_t *
print_properties(svn_stream_t *out,
                 svn_boolean_t is_url,
                 const char *pname_utf8,
                 apr_hash_t *props,
                 svn_boolean_t print_filenames,
                 svn_boolean_t omit_newline,
                 svn_boolean_t like_proplist,
                 apr_pool_t *pool)
{
  apr_array_header_t *sorted_props;
  int i;
  apr_pool_t *iterpool = svn_pool_create(pool);
  const char *path_prefix;

  SVN_ERR(svn_dirent_get_absolute(&path_prefix, "", pool));

  sorted_props = svn_sort__hash(props, svn_sort_compare_items_as_paths, pool);
  for (i = 0; i < sorted_props->nelts; i++)
    {
      svn_sort__item_t item = APR_ARRAY_IDX(sorted_props, i, svn_sort__item_t);
      const char *filename = item.key;
      svn_string_t *propval = item.value;

      svn_pool_clear(iterpool);

      if (print_filenames)
        {
          const char *header;

          /* Print the file name. */

          if (! is_url)
            filename = svn_cl__local_style_skip_ancestor(path_prefix, filename,
                                                         iterpool);

          /* In verbose mode, print exactly same as "proplist" does;
           * otherwise, print a brief header. */
          header = apr_psprintf(iterpool, like_proplist
                                ? _("Properties on '%s':\n")
                                : "%s - ", filename);
          SVN_ERR(svn_cmdline_cstring_from_utf8(&header, header, iterpool));
          SVN_ERR(svn_subst_translate_cstring2(header, &header,
                                               APR_EOL_STR,  /* 'native' eol */
                                               FALSE, /* no repair */
                                               NULL,  /* no keywords */
                                               FALSE, /* no expansion */
                                               iterpool));
          SVN_ERR(stream_write(out, header, strlen(header)));
        }

      if (like_proplist)
        {
          /* Print the property name and value just as "proplist -v" does */
          apr_hash_t *hash = apr_hash_make(iterpool);

          apr_hash_set(hash, pname_utf8, APR_HASH_KEY_STRING, propval);
          SVN_ERR(svn_cl__print_prop_hash(out, hash, FALSE, iterpool));
        }
      else
        {
          /* If this is a special Subversion property, it is stored as
             UTF8, so convert to the native format. */
          if (svn_prop_needs_translation(pname_utf8))
            SVN_ERR(svn_subst_detranslate_string(&propval, propval,
                                                 TRUE, iterpool));

          SVN_ERR(stream_write(out, propval->data, propval->len));

          if (! omit_newline)
            SVN_ERR(stream_write(out, APR_EOL_STR,
                                 strlen(APR_EOL_STR)));
        }
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}
コード例 #7
0
ファイル: util.c プロジェクト: Distrotech/subversion
svn_error_t *
svn_cl__edit_string_externally(svn_string_t **edited_contents /* UTF-8! */,
                               const char **tmpfile_left /* UTF-8! */,
                               const char *editor_cmd,
                               const char *base_dir /* UTF-8! */,
                               const svn_string_t *contents /* UTF-8! */,
                               const char *filename,
                               apr_hash_t *config,
                               svn_boolean_t as_text,
                               const char *encoding,
                               apr_pool_t *pool)
{
  const char *editor;
  const char *cmd;
  apr_file_t *tmp_file;
  const char *tmpfile_name;
  const char *tmpfile_native;
  const char *tmpfile_apr, *base_dir_apr;
  svn_string_t *translated_contents;
  apr_status_t apr_err, apr_err2;
  apr_size_t written;
  apr_finfo_t finfo_before, finfo_after;
  svn_error_t *err = SVN_NO_ERROR, *err2;
  char *old_cwd;
  int sys_err;
  svn_boolean_t remove_file = TRUE;

  SVN_ERR(find_editor_binary(&editor, editor_cmd, config));

  /* Convert file contents from UTF-8/LF if desired. */
  if (as_text)
    {
      const char *translated;
      SVN_ERR(svn_subst_translate_cstring2(contents->data, &translated,
                                           APR_EOL_STR, FALSE,
                                           NULL, FALSE, pool));
      translated_contents = svn_string_create("", pool);
      if (encoding)
        SVN_ERR(svn_utf_cstring_from_utf8_ex2(&translated_contents->data,
                                              translated, encoding, pool));
      else
        SVN_ERR(svn_utf_cstring_from_utf8(&translated_contents->data,
                                          translated, pool));
      translated_contents->len = strlen(translated_contents->data);
    }
  else
    translated_contents = svn_string_dup(contents, pool);

  /* Move to BASE_DIR to avoid getting characters that need quoting
     into tmpfile_name */
  apr_err = apr_filepath_get(&old_cwd, APR_FILEPATH_NATIVE, pool);
  if (apr_err)
    return svn_error_wrap_apr(apr_err, _("Can't get working directory"));

  /* APR doesn't like "" directories */
  if (base_dir[0] == '\0')
    base_dir_apr = ".";
  else
    SVN_ERR(svn_path_cstring_from_utf8(&base_dir_apr, base_dir, pool));
  apr_err = apr_filepath_set(base_dir_apr, pool);
  if (apr_err)
    {
      return svn_error_wrap_apr
        (apr_err, _("Can't change working directory to '%s'"), base_dir);
    }

  /*** From here on, any problems that occur require us to cd back!! ***/

  /* Ask the working copy for a temporary file named FILENAME-something. */
  err = svn_io_open_uniquely_named(&tmp_file, &tmpfile_name,
                                   "" /* dirpath */,
                                   filename,
                                   ".tmp",
                                   svn_io_file_del_none, pool, pool);

  if (err && (APR_STATUS_IS_EACCES(err->apr_err) || err->apr_err == EROFS))
    {
      const char *temp_dir_apr;

      svn_error_clear(err);

      SVN_ERR(svn_io_temp_dir(&base_dir, pool));

      SVN_ERR(svn_path_cstring_from_utf8(&temp_dir_apr, base_dir, pool));
      apr_err = apr_filepath_set(temp_dir_apr, pool);
      if (apr_err)
        {
          return svn_error_wrap_apr
            (apr_err, _("Can't change working directory to '%s'"), base_dir);
        }

      err = svn_io_open_uniquely_named(&tmp_file, &tmpfile_name,
                                       "" /* dirpath */,
                                       filename,
                                       ".tmp",
                                       svn_io_file_del_none, pool, pool);
    }

  if (err)
    goto cleanup2;

  /*** From here on, any problems that occur require us to cleanup
       the file we just created!! ***/

  /* Dump initial CONTENTS to TMP_FILE. */
  apr_err = apr_file_write_full(tmp_file, translated_contents->data,
                                translated_contents->len, &written);

  apr_err2 = apr_file_close(tmp_file);
  if (! apr_err)
    apr_err = apr_err2;

  /* Make sure the whole CONTENTS were written, else return an error. */
  if (apr_err)
    {
      err = svn_error_wrap_apr(apr_err, _("Can't write to '%s'"),
                               tmpfile_name);
      goto cleanup;
    }

  err = svn_path_cstring_from_utf8(&tmpfile_apr, tmpfile_name, pool);
  if (err)
    goto cleanup;

  /* Get information about the temporary file before the user has
     been allowed to edit its contents. */
  apr_err = apr_stat(&finfo_before, tmpfile_apr,
                     APR_FINFO_MTIME, pool);
  if (apr_err)
    {
      err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
      goto cleanup;
    }

  /* Backdate the file a little bit in case the editor is very fast
     and doesn't change the size.  (Use two seconds, since some
     filesystems have coarse granularity.)  It's OK if this call
     fails, so we don't check its return value.*/
  apr_file_mtime_set(tmpfile_apr, finfo_before.mtime - 2000, pool);

  /* Stat it again to get the mtime we actually set. */
  apr_err = apr_stat(&finfo_before, tmpfile_apr,
                     APR_FINFO_MTIME | APR_FINFO_SIZE, pool);
  if (apr_err)
    {
      err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
      goto cleanup;
    }

  /* Prepare the editor command line.  */
  err = svn_utf_cstring_from_utf8(&tmpfile_native, tmpfile_name, pool);
  if (err)
    goto cleanup;
  cmd = apr_psprintf(pool, "%s %s", editor, tmpfile_native);

  /* If the caller wants us to leave the file around, return the path
     of the file we'll use, and make a note not to destroy it.  */
  if (tmpfile_left)
    {
      *tmpfile_left = svn_dirent_join(base_dir, tmpfile_name, pool);
      remove_file = FALSE;
    }

  /* Now, run the editor command line.  */
  sys_err = system(cmd);
  if (sys_err != 0)
    {
      /* Extracting any meaning from sys_err is platform specific, so just
         use the raw value. */
      err =  svn_error_createf(SVN_ERR_EXTERNAL_PROGRAM, NULL,
                               _("system('%s') returned %d"), cmd, sys_err);
      goto cleanup;
    }

  /* Get information about the temporary file after the assumed editing. */
  apr_err = apr_stat(&finfo_after, tmpfile_apr,
                     APR_FINFO_MTIME | APR_FINFO_SIZE, pool);
  if (apr_err)
    {
      err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
      goto cleanup;
    }

  /* If the file looks changed... */
  if ((finfo_before.mtime != finfo_after.mtime) ||
      (finfo_before.size != finfo_after.size))
    {
      svn_stringbuf_t *edited_contents_s;
      err = svn_stringbuf_from_file2(&edited_contents_s, tmpfile_name, pool);
      if (err)
        goto cleanup;

      *edited_contents = svn_stringbuf__morph_into_string(edited_contents_s);

      /* Translate back to UTF8/LF if desired. */
      if (as_text)
        {
          err = svn_subst_translate_string2(edited_contents, FALSE, FALSE,
                                            *edited_contents, encoding, FALSE,
                                            pool, pool);
          if (err)
            {
              err = svn_error_quick_wrap
                (err,
                 _("Error normalizing edited contents to internal format"));
              goto cleanup;
            }
        }
    }
  else
    {
      /* No edits seem to have been made */
      *edited_contents = NULL;
    }

 cleanup:
  if (remove_file)
    {
      /* Remove the file from disk.  */
      err2 = svn_io_remove_file2(tmpfile_name, FALSE, pool);

      /* Only report remove error if there was no previous error. */
      if (! err && err2)
        err = err2;
      else
        svn_error_clear(err2);
    }

 cleanup2:
  /* If we against all probability can't cd back, all further relative
     file references would be screwed up, so we have to abort. */
  apr_err = apr_filepath_set(old_cwd, pool);
  if (apr_err)
    {
      svn_handle_error2(svn_error_wrap_apr
                        (apr_err, _("Can't restore working directory")),
                        stderr, TRUE /* fatal */, "svn: ");
    }

  return svn_error_trace(err);
}