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

📄 diff-cmd.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
字号:
/* * diff-cmd.c -- Display context diff of a file * * ==================================================================== * 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 "svn_pools.h"#include "svn_client.h"#include "svn_string.h"#include "svn_path.h"#include "svn_error.h"#include "svn_types.h"#include "svn_cmdline.h"#include "cl.h"#include "svn_private_config.h"/*** Code. ***//* Convert KIND into a single character for display to the user. */static chartext_mod_char(svn_client_diff_summarize_kind_t kind){  switch (kind)    {      case svn_client_diff_summarize_kind_modified:        return 'M';      case svn_client_diff_summarize_kind_added:        return 'A';      case svn_client_diff_summarize_kind_deleted:        return 'D';      default:        return ' ';    }}/* Print summary information about a given change, implements the * svn_client_diff_summarize_func_t interface. */static svn_error_t *summarize_func(const svn_client_diff_summarize_t *summary,               void *baton,               apr_pool_t *pool){  const char *path = baton;  /* Tack on the target path, so we can differentiate between different parts   * of the output when we're given multiple targets. */  path = svn_path_join(path, summary->path, pool);  /* Convert non-urls to local style, so that things like "" show up as "." */  if (! svn_path_is_url(path))    path = svn_path_local_style(path, pool);  /* Note: This output format tries to look like the output of 'svn status',   *       thus the blank spaces where information that is not relevant to   *       a diff summary would go. */  SVN_ERR(svn_cmdline_printf(pool,                             "%c%c     %s\n",                             text_mod_char(summary->summarize_kind),                             summary->prop_changed ? 'M' : ' ',                             path));  SVN_ERR(svn_cmdline_fflush(stdout));  return SVN_NO_ERROR;}/* An svn_opt_subcommand_t to handle the 'diff' command.   This implements the `svn_opt_subcommand_t' interface. */svn_error_t *svn_cl__diff(apr_getopt_t *os,             void *baton,             apr_pool_t *pool){  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;  apr_array_header_t *options;  apr_array_header_t *targets;  apr_file_t *outfile, *errfile;  apr_status_t status;  const char *old_target, *new_target;  apr_pool_t *iterpool;  svn_boolean_t pegged_diff = FALSE;  int i;  /* Fall back to "" to get options initialized either way. */  {    const char *optstr = opt_state->extensions ? opt_state->extensions : "";    options = svn_cstring_split(optstr, " \t\n\r", TRUE, pool);  }  /* Get an apr_file_t representing stdout and stderr, which is where     we'll have the external 'diff' program print to. */  if ((status = apr_file_open_stdout(&outfile, pool)))    return svn_error_wrap_apr(status, _("Can't open stdout"));  if ((status = apr_file_open_stderr(&errfile, pool)))    return svn_error_wrap_apr(status, _("Can't open stderr"));  SVN_ERR(svn_opt_args_to_target_array2(&targets, os,                                        opt_state->targets, pool));  if (! opt_state->old_target && ! opt_state->new_target      && (targets->nelts == 2)      && svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *))      && svn_path_is_url(APR_ARRAY_IDX(targets, 1, const char *))      && opt_state->start_revision.kind == svn_opt_revision_unspecified      && opt_state->end_revision.kind == svn_opt_revision_unspecified)    {      /* The 'svn diff OLD_URL[@OLDREV] NEW_URL[@NEWREV]' case matches. */      SVN_ERR(svn_opt_parse_path(&opt_state->start_revision, &old_target,                                 APR_ARRAY_IDX(targets, 0, const char *),                                 pool));      SVN_ERR(svn_opt_parse_path(&opt_state->end_revision, &new_target,                                 APR_ARRAY_IDX(targets, 1, const char *),                                 pool));      targets->nelts = 0;            if (opt_state->start_revision.kind == svn_opt_revision_unspecified)        opt_state->start_revision.kind = svn_opt_revision_head;      if (opt_state->end_revision.kind == svn_opt_revision_unspecified)        opt_state->end_revision.kind = svn_opt_revision_head;    }  else if (opt_state->old_target)    {      apr_array_header_t *tmp, *tmp2;      svn_opt_revision_t old_rev, new_rev;            /* The 'svn diff --old=OLD[@OLDREV] [--new=NEW[@NEWREV]]         [PATH...]' case matches. */      tmp = apr_array_make(pool, 2, sizeof(const char *));      APR_ARRAY_PUSH(tmp, const char *) = (opt_state->old_target);      APR_ARRAY_PUSH(tmp, const char *) = (opt_state->new_target                                            ? opt_state->new_target                                           : APR_ARRAY_IDX(tmp, 0,                                                           const char *));      SVN_ERR(svn_opt_args_to_target_array2(&tmp2, os, tmp, pool));      SVN_ERR(svn_opt_parse_path(&old_rev, &old_target,                                 APR_ARRAY_IDX(tmp2, 0, const char *),                                 pool));      if (old_rev.kind != svn_opt_revision_unspecified)        opt_state->start_revision = old_rev;      SVN_ERR(svn_opt_parse_path(&new_rev, &new_target,                                 APR_ARRAY_IDX(tmp2, 1, const char *),                                 pool));      if (new_rev.kind != svn_opt_revision_unspecified)        opt_state->end_revision = new_rev;      if (opt_state->start_revision.kind == svn_opt_revision_unspecified)        opt_state->start_revision.kind = svn_path_is_url(old_target)          ? svn_opt_revision_head : svn_opt_revision_base;            if (opt_state->end_revision.kind == svn_opt_revision_unspecified)        opt_state->end_revision.kind = svn_path_is_url(new_target)          ? svn_opt_revision_head : svn_opt_revision_working;    }  else if (opt_state->new_target)    {      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,                              _("'--new' option only valid with "                                "'--old' option"));    }  else    {      svn_boolean_t working_copy_present = FALSE, url_present = FALSE;            /* The 'svn diff [-r N[:M]] [TARGET[@REV]...]' case matches. */      /* Here each target is a pegged object. Find out the starting         and ending paths for each target. */      svn_opt_push_implicit_dot_target(targets, pool);      old_target = "";      new_target = "";      /* Check to see if at least one of our paths is a working copy         path. */      for (i = 0; i < targets->nelts; ++i)        {          const char *path = APR_ARRAY_IDX(targets, i, const char *);          if (! svn_path_is_url(path))            working_copy_present = TRUE;          else            url_present = TRUE;        }      if (url_present && working_copy_present)        return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,                                 _("Target lists to diff may not contain "                                   "both working copy paths and URLs"));                if (opt_state->start_revision.kind == svn_opt_revision_unspecified          && working_copy_present)          opt_state->start_revision.kind = svn_opt_revision_base;      if (opt_state->end_revision.kind == svn_opt_revision_unspecified)        opt_state->end_revision.kind = working_copy_present          ? svn_opt_revision_working : svn_opt_revision_head;      /* Determine if we need to do pegged diffs. */      if ((opt_state->start_revision.kind != svn_opt_revision_base           && opt_state->start_revision.kind != svn_opt_revision_working)          || (opt_state->end_revision.kind != svn_opt_revision_base              && opt_state->end_revision.kind != svn_opt_revision_working))        pegged_diff = TRUE;    }  svn_opt_push_implicit_dot_target(targets, pool);  iterpool = svn_pool_create(pool);  for (i = 0; i < targets->nelts; ++i)    {      const char *path = APR_ARRAY_IDX(targets, i, const char *);      const char *target1, *target2;      svn_pool_clear(iterpool);      if (! pegged_diff)        {          target1 = svn_path_join(old_target, path, iterpool);          target2 = svn_path_join(new_target, path, iterpool);          if (opt_state->summarize)            SVN_ERR(svn_client_diff_summarize                    (target1,                     &opt_state->start_revision,                     target2,                     &opt_state->end_revision,                     opt_state->nonrecursive ? FALSE : TRUE,                     opt_state->notice_ancestry ? FALSE : TRUE,                     summarize_func,                     (void *) target1,                     ((svn_cl__cmd_baton_t *)baton)->ctx,                     iterpool));          else                      SVN_ERR(svn_client_diff3                    (options,                     target1,                     &(opt_state->start_revision),                     target2,                     &(opt_state->end_revision),                     opt_state->nonrecursive ? FALSE : TRUE,                     opt_state->notice_ancestry ? FALSE : TRUE,                     opt_state->no_diff_deleted,                     opt_state->force,                     svn_cmdline_output_encoding(pool),                     outfile,                     errfile,                     ((svn_cl__cmd_baton_t *)baton)->ctx,                     iterpool));        }      else        {          const char *truepath;          svn_opt_revision_t peg_revision;                    /* First check for a peg revision. */          SVN_ERR(svn_opt_parse_path(&peg_revision, &truepath, path,                                      iterpool));          /* Set the default peg revision if one was not specified. */          if (peg_revision.kind == svn_opt_revision_unspecified)            peg_revision.kind = svn_path_is_url(path)              ? svn_opt_revision_head : svn_opt_revision_working;          if (opt_state->summarize)            SVN_ERR(svn_client_diff_summarize_peg                    (truepath,                     &peg_revision,                     &opt_state->start_revision,                     &opt_state->end_revision,                     opt_state->nonrecursive ? FALSE : TRUE,                     opt_state->notice_ancestry ? FALSE : TRUE,                     summarize_func,                     (void *) truepath,                     ((svn_cl__cmd_baton_t *)baton)->ctx,                     iterpool));          else            SVN_ERR(svn_client_diff_peg3                    (options,                     truepath,                     &peg_revision,                     &opt_state->start_revision,                     &opt_state->end_revision,                     opt_state->nonrecursive ? FALSE : TRUE,                     opt_state->notice_ancestry ? FALSE : TRUE,                     opt_state->no_diff_deleted,                     opt_state->force,                     svn_cmdline_output_encoding(pool),                     outfile,                     errfile,                     ((svn_cl__cmd_baton_t *)baton)->ctx,                     iterpool));        }    }  svn_pool_destroy(iterpool);  return SVN_NO_ERROR;}

⌨️ 快捷键说明

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