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

📄 diff.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * diff.c: comparing and merging * * ==================================================================== * Copyright (c) 2000-2006 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 <apr_strings.h>#include <apr_pools.h>#include <apr_hash.h>#include "svn_wc.h"#include "svn_delta.h"#include "svn_diff.h"#include "svn_client.h"#include "svn_string.h"#include "svn_error.h"#include "svn_path.h"#include "svn_io.h"#include "svn_utf.h"#include "svn_pools.h"#include "svn_config.h"#include "svn_props.h"#include "svn_time.h"#include "client.h"#include <assert.h>#include "svn_private_config.h"/* * Constant separator strings */static const char equal_string[] =   "===================================================================";static const char under_string[] =  "___________________________________________________________________";/*-----------------------------------------------------------------*//* Utilities *//* Wrapper for apr_file_printf(), which see.  FORMAT is a utf8-encoded   string after it is formatted, so this function can convert it to   ENCODING before printing. */static svn_error_t *file_printf_from_utf8(apr_file_t *fptr, const char *encoding,                      const char *format, ...)  __attribute__ ((format(printf, 3, 4)));static svn_error_t *file_printf_from_utf8(apr_file_t *fptr, const char *encoding,                      const char *format, ...){  va_list ap;  const char *buf, *buf_apr;  va_start(ap, format);  buf = apr_pvsprintf(apr_file_pool_get(fptr), format, ap);   va_end(ap);  SVN_ERR(svn_utf_cstring_from_utf8_ex2(&buf_apr, buf, encoding,                                        apr_file_pool_get(fptr)));  return svn_io_file_write_full(fptr, buf_apr, strlen(buf_apr),                                 NULL, apr_file_pool_get(fptr));}/* A helper func that writes out verbal descriptions of property diffs   to FILE.   Of course, the apr_file_t will probably be the 'outfile'   passed to svn_client_diff3, which is probably stdout. */static svn_error_t *display_prop_diffs(const apr_array_header_t *propchanges,                   apr_hash_t *original_props,                   const char *path,                   const char *encoding,                   apr_file_t *file,                   apr_pool_t *pool){  int i;  SVN_ERR(file_printf_from_utf8(file, encoding,                                _("%sProperty changes on: %s%s"),                                APR_EOL_STR,                                svn_path_local_style(path, pool),                                APR_EOL_STR));  SVN_ERR(file_printf_from_utf8(file, encoding, "%s" APR_EOL_STR,                                under_string));  for (i = 0; i < propchanges->nelts; i++)    {      const svn_prop_t *propchange        = &APR_ARRAY_IDX(propchanges, i, svn_prop_t);      const svn_string_t *original_value;      if (original_props)        original_value = apr_hash_get(original_props,                                       propchange->name, APR_HASH_KEY_STRING);      else        original_value = NULL;      /* If the property doesn't exist on either side, or if it exists         with the same value, skip it.  */      if ((! (original_value || propchange->value))          || (original_value && propchange->value               && svn_string_compare(original_value, propchange->value)))        continue;            SVN_ERR(file_printf_from_utf8(file, encoding, _("Name: %s%s"),                                    propchange->name, APR_EOL_STR));      /* For now, we have a rather simple heuristic: if this is an         "svn:" property, then assume the value is UTF-8 and must         therefore be converted before printing.  Otherwise, just         print whatever's there and hope for the best. */      {        svn_boolean_t val_is_utf8 = svn_prop_is_svn_prop(propchange->name);                if (original_value != NULL)          {            if (val_is_utf8)              {                SVN_ERR(file_printf_from_utf8                        (file, encoding,                         "   - %s" APR_EOL_STR, original_value->data));              }            else              {                /* ### todo: check for error? */                apr_file_printf                  (file, "   - %s" APR_EOL_STR, original_value->data);              }          }                if (propchange->value != NULL)          {            if (val_is_utf8)              {                SVN_ERR(file_printf_from_utf8                        (file, encoding, "   + %s" APR_EOL_STR,                         propchange->value->data));              }            else              {                /* ### todo: check for error? */                apr_file_printf(file, "   + %s" APR_EOL_STR,                                propchange->value->data);              }          }      }    }  /* ### todo [issue #1533]: Use file_printf_from_utf8() to convert this     to native encoding, at least conditionally?  Or is it better to     have under_string always output the same eol, so programs can     find it consistently?  Also, what about checking for error? */  apr_file_printf(file, APR_EOL_STR);  return SVN_NO_ERROR;}/* Return SVN_ERR_UNSUPPORTED_FEATURE if URL's scheme does not   match the scheme of the url for ADM_ACCESS's path; return   SVN_ERR_BAD_URL if no scheme can be found for one or both urls;   otherwise return SVN_NO_ERROR.  Use ADM_ACCESS's pool for   temporary allocation. */static svn_error_t *check_scheme_match(svn_wc_adm_access_t *adm_access, const char *url){  const char *path = svn_wc_adm_access_path(adm_access);  apr_pool_t *pool = svn_wc_adm_access_pool(adm_access);  const svn_wc_entry_t *ent;  const char *idx1, *idx2;    SVN_ERR(svn_wc_entry(&ent, path, adm_access, TRUE, pool));    idx1 = strchr(url, ':');  idx2 = strchr(ent->url, ':');  if ((idx1 == NULL) && (idx2 == NULL))    {      return svn_error_createf        (SVN_ERR_BAD_URL, NULL,         _("URLs have no scheme ('%s' and '%s')"), url, ent->url);    }  else if (idx1 == NULL)    {      return svn_error_createf        (SVN_ERR_BAD_URL, NULL,         _("URL has no scheme: '%s'"), url);    }  else if (idx2 == NULL)    {      return svn_error_createf        (SVN_ERR_BAD_URL, NULL,         _("URL has no scheme: '%s'"), ent->url);    }  else if (((idx1 - url) != (idx2 - ent->url))           || (strncmp(url, ent->url, idx1 - url) != 0))    {      return svn_error_createf        (SVN_ERR_UNSUPPORTED_FEATURE, NULL,         _("Access scheme mixtures not yet supported ('%s' and '%s')"),         url, ent->url);    }  /* else */  return SVN_NO_ERROR;}/*-----------------------------------------------------------------*//*** Callbacks for 'svn diff', invoked by the repos-diff editor. ***/struct diff_cmd_baton {  const apr_array_header_t *options;  apr_pool_t *pool;  apr_file_t *outfile;  apr_file_t *errfile;  const char *header_encoding;  /* The original targets passed to the diff command.  We may need     these to construct distinctive diff labels when comparing the     same relative path in the same revision, under different anchors     (for example, when comparing a trunk against a branch). */  const char *orig_path_1;  const char *orig_path_2;  /* These are the numeric representations of the revisions passed to     svn_client_diff3, either may be SVN_INVALID_REVNUM.  We need these     because some of the svn_wc_diff_callbacks2_t don't get revision     arguments.     ### Perhaps we should change the callback signatures and eliminate     ### these?  */  svn_revnum_t revnum1;  svn_revnum_t revnum2;  /* Client config hash (may be NULL). */  apr_hash_t *config;  /* Set this if you want diff output even for binary files. */  svn_boolean_t force_binary;  /* Set this flag if you want diff_file_changed to output diffs     unconditionally, even if the diffs are empty. */  svn_boolean_t force_empty;};/* Generate a label for the diff output for file PATH at revision REVNUM.   If REVNUM is invalid then it is assumed to be the current working   copy.  Assumes the paths are already in the desired style (local   vs internal).  Allocate the label in POOL. */static const char *diff_label(const char *path,           svn_revnum_t revnum,           apr_pool_t *pool){  const char *label;  if (revnum != SVN_INVALID_REVNUM)    label = apr_psprintf(pool, _("%s\t(revision %ld)"), path, revnum);  else    label = apr_psprintf(pool, _("%s\t(working copy)"), path);  return label;}/* A svn_wc_diff_callbacks2_t function.  Used for both file and directory   property diffs. */static svn_error_t *diff_props_changed(svn_wc_adm_access_t *adm_access,                   svn_wc_notify_state_t *state,                   const char *path,                   const apr_array_header_t *propchanges,                   apr_hash_t *original_props,                   void *diff_baton){  struct diff_cmd_baton *diff_cmd_baton = diff_baton;  apr_array_header_t *props;  apr_pool_t *subpool = svn_pool_create(diff_cmd_baton->pool);  SVN_ERR(svn_categorize_props(propchanges, NULL, NULL, &props, subpool));  if (props->nelts > 0)    SVN_ERR(display_prop_diffs(props, original_props, path,                               diff_cmd_baton->header_encoding,                               diff_cmd_baton->outfile, subpool));  if (state)    *state = svn_wc_notify_state_unknown;  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}/* Show differences between TMPFILE1 and TMPFILE2. PATH, REV1, and REV2 are   used in the headers to indicate the file and revisions.  If either   MIMETYPE1 or MIMETYPE2 indicate binary content, don't show a diff,   but instread print a warning message. */static svn_error_t *diff_content_changed(const char *path,                     const char *tmpfile1,                     const char *tmpfile2,                     svn_revnum_t rev1,                     svn_revnum_t rev2,                     const char *mimetype1,                     const char *mimetype2,                     void *diff_baton){  struct diff_cmd_baton *diff_cmd_baton = diff_baton;  const char *diff_cmd = NULL;  const char **args = NULL;  int nargs, exitcode;  apr_pool_t *subpool = svn_pool_create(diff_cmd_baton->pool);  svn_stream_t *os;  apr_file_t *errfile = diff_cmd_baton->errfile;  const char *label1, *label2;  svn_boolean_t mt1_binary = FALSE, mt2_binary = FALSE;  const char *path1, *path2;  int i;  /* Get a stream from our output file. */  os = svn_stream_from_aprfile(diff_cmd_baton->outfile, subpool);   /* Assemble any option args. */  nargs = diff_cmd_baton->options->nelts;  if (nargs)    {      args = apr_palloc(subpool, nargs * sizeof(char *));      for (i = 0; i < diff_cmd_baton->options->nelts; i++)        {          args[i] =             ((const char **)(diff_cmd_baton->options->elts))[i];        }      assert(i == nargs);    }  /* Generate the diff headers. */  /* ### Holy cow.  Due to anchor/target weirdness, we can't     simply join diff_cmd_baton->orig_path_1 with path, ditto for     orig_path_2.  That will work when they're directory URLs, but     not for file URLs.  Nor can we just use anchor1 and anchor2

⌨️ 快捷键说明

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