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

📄 util.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * util.c: Subversion command line client utility functions. Any
 * functions that need to be shared across subcommands should be put
 * in here.
 *
 * ====================================================================
 * Copyright (c) 2000-2004 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */

/* ==================================================================== */



/*** Includes. ***/

#include <string.h>
#include <ctype.h>
#include <assert.h>

#include <apr_strings.h>
#include <apr_tables.h>
#include <apr_general.h>
#include <apr_lib.h>

#include "svn_wc.h"
#include "svn_client.h"
#include "svn_cmdline.h"
#include "svn_string.h"
#include "svn_path.h"
#include "svn_delta.h"
#include "svn_error.h"
#include "svn_io.h"
#include "svn_pools.h"
#include "svn_utf.h"
#include "svn_subst.h"
#include "svn_config.h"
#include "svn_private_config.h"
#include "cl.h"




svn_error_t *
svn_cl__print_commit_info (svn_client_commit_info_t *commit_info,
                           apr_pool_t *pool)
{
  if ((commit_info) 
      && (SVN_IS_VALID_REVNUM (commit_info->revision)))
    SVN_ERR (svn_cmdline_printf (pool, _("\nCommitted revision %ld.\n"),
                                 commit_info->revision));

  return SVN_NO_ERROR;
}


svn_error_t *
svn_cl__edit_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 *prefix,
                         apr_hash_t *config,
                         svn_boolean_t as_text,
                         const char *encoding,
                         apr_pool_t *pool)
{
  const char *editor = NULL;
  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;
  struct svn_config_t *cfg;

  /* Look for the Subversion specific environment variable. */
  editor = getenv ("SVN_EDITOR");

  /* If not found then fall back on the config file. */
  if (! editor)
    {
      cfg = config ? apr_hash_get (config, SVN_CONFIG_CATEGORY_CONFIG, 
                                   APR_HASH_KEY_STRING) : NULL;
      svn_config_get (cfg, &editor, SVN_CONFIG_SECTION_HELPERS, 
                      SVN_CONFIG_OPTION_EDITOR_CMD, NULL);
    }

  /* If not found yet then try general purpose environment variables. */
  if (! editor)
    editor = getenv ("VISUAL");
  if (! editor)
    editor = getenv ("EDITOR");

#ifdef SVN_CLIENT_EDITOR
  /* If still not found then fall back on the hard-coded default. */
  if (! editor)
    editor = SVN_CLIENT_EDITOR;
#endif

  /* Override further with the editor specified on the command line
     via --editor-cmd, if any. */
  if (editor_cmd)
    editor = editor_cmd;

  /* Abort if there is no editor specified */
  if (! editor)
    return svn_error_create 
      (SVN_ERR_CL_NO_EXTERNAL_EDITOR, NULL,
       _("None of the environment variables SVN_EDITOR, VISUAL or EDITOR is "
         "set, and no 'editor-cmd' run-time configuration option was found"));

  /* Convert file contents from UTF-8/LF if desired. */
  if (as_text)
    {
      const char *translated;
      SVN_ERR (svn_subst_translate_cstring (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_ex (&translated_contents->data,
                                               translated, encoding, NULL,
                                               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 that starts with
     PREFIX. */
  err = svn_io_open_unique_file (&tmp_file, &tmpfile_name,
                                 prefix, ".tmp", FALSE, 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 | APR_FINFO_SIZE, pool);
  if (apr_err)
    {
      err = svn_error_wrap_apr (apr_err, _("Can't stat '%s'"), tmpfile_name);
      goto cleanup;
    }

  /* Now, run 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);
  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_file (&edited_contents_s, tmpfile_name, pool);
      if (err)
        goto cleanup;

      *edited_contents = svn_string_create_from_buf (edited_contents_s, pool);

      /* Translate back to UTF8/LF if desired. */
      if (as_text)
        {
          err = svn_subst_translate_string (edited_contents, *edited_contents,
                                            encoding, pool);
          if (err)
            goto cleanup;
        }
    }
  else
    {
      /* No edits seem to have been made */
      *edited_contents = NULL;
    }

  /* If the caller wants us to leave the file around, return the path
     of the file we used, and make a note not to destroy it.  */
  if (tmpfile_left)
    {
      *tmpfile_left = svn_path_join (base_dir, tmpfile_name, pool);
      remove_file = FALSE;
    }
  
 cleanup:
  if (remove_file)
    {
      /* Remove the file from disk.  */
      err2 = svn_io_remove_file (tmpfile_name, pool);

      /* Only report remove error if there was no previous error. */
      if (! err && err2)
        err = 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_error (svn_error_wrap_apr
                        (apr_err, _("Can't restore working directory")),
                        stderr, TRUE /* fatal */);
    }

  return err;
}


struct log_msg_baton
{
  const char *editor_cmd;  /* editor specified via --editor-cmd, else NULL */
  const char *message;  /* the message. */
  const char *message_encoding; /* the locale/encoding of the message. */
  const char *base_dir; /* the base directory for an external edit. UTF-8! */
  const char *tmpfile_left; /* the tmpfile left by an external edit. UTF-8! */
  apr_hash_t *config; /* client configuration hash */
  apr_pool_t *pool; /* a pool. */
};


svn_error_t *
svn_cl__make_log_msg_baton (void **baton,
                            svn_cl__opt_state_t *opt_state,
                            const char *base_dir /* UTF-8! */,

⌨️ 快捷键说明

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