log.c

来自「linux subdivision ying gai ke yi le ba」· C语言 代码 · 共 434 行 · 第 1/2 页

C
434
字号
/*
 * log.c :  routines for requesting and parsing log reports
 *
 * ====================================================================
 * 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/.
 * ====================================================================
 */



#define APR_WANT_STRFUNC
#include <apr_want.h> /* for strcmp() */

#include <apr_pools.h>
#include <apr_tables.h>
#include <apr_strings.h>
#include <apr_portable.h>
#include <apr_xml.h>

#include <ne_socket.h>
#include <ne_basic.h>
#include <ne_utils.h>
#include <ne_basic.h>
#include <ne_207.h>
#include <ne_props.h>
#include <ne_xml.h>

#include "svn_error.h"
#include "svn_pools.h"
#include "svn_delta.h"
#include "svn_io.h"
#include "svn_ra.h"
#include "svn_path.h"
#include "svn_xml.h"

#include "ra_dav.h"



/*** Code ***/

/* Userdata for the Neon XML element callbacks. */
struct log_baton
{
  /* Allocate log message information.
   * NOTE: this pool may be cleared multiple times as log messages are
   * received.
   */
  apr_pool_t *subpool;

  /* Information about each log item in turn. */
  svn_revnum_t revision;
  const char *author;
  const char *date;
  const char *msg;

  /* Keys are the paths changed in this commit, allocated in SUBPOOL;
     the table itself is also allocated in SUBPOOL.  If this table is
     NULL, no changed paths were indicated -- which doesn't mean no
     paths were changed, just means that this log invocation didn't
     ask for them to be reported. */
  apr_hash_t *changed_paths;

  /* The current changed path item. */
  svn_log_changed_path_t *this_path_item;

  /* Client's callback, invoked on the above fields when the end of an
     item is seen. */
  svn_log_message_receiver_t receiver;
  void *receiver_baton;

  /* If `receiver' returns error, it is stored here. */
  svn_error_t *err;
};


/* Prepare LB to start accumulating the next log item, by wiping all
 * information related to the previous item and clearing the pool in
 * which they were allocated.  Do not touch any stored error, however.
 */
static void
reset_log_item (struct log_baton *lb)
{
  lb->revision      = SVN_INVALID_REVNUM;
  lb->author        = NULL;
  lb->date          = NULL;
  lb->msg           = NULL;
  lb->changed_paths = NULL;

  svn_pool_clear (lb->subpool);
}


/*
 * This implements the `svn_ra_dav__xml_validate_cb' prototype.
 */
static int
log_validate(void *userdata, svn_ra_dav__xml_elmid parent,
             svn_ra_dav__xml_elmid child)
{
  /* ### todo */
  return SVN_RA_DAV__XML_VALID;
}


static const char *get_attr(const char **atts, const char *which)
{
  for (; atts && *atts; atts += 2)
    if (strcmp(*atts, which) == 0)
      return atts[1];
  return NULL;
}

/*
 * This implements the `svn_ra_dav__xml_startelm_cb' prototype.
 */
static int
log_start_element(void *userdata,
                  const svn_ra_dav__xml_elm_t *elm,
                  const char **atts)
{
  struct log_baton *lb = userdata;
  const char *copyfrom_path, *copyfrom_revstr;
  svn_revnum_t copyfrom_rev;

  switch (elm->id)
    {
    case ELEM_added_path:
    case ELEM_replaced_path:
    case ELEM_deleted_path:
    case ELEM_modified_path:
      lb->this_path_item = apr_pcalloc(lb->subpool, 
                                       sizeof(*(lb->this_path_item)));
      lb->this_path_item->copyfrom_rev = SVN_INVALID_REVNUM;

      /* See documentation for `svn_repos_node_t' in svn_repos.h,
         and `svn_log_message_receiver_t' in svn_types.h, for more
         about these action codes. */
      if ((elm->id == ELEM_added_path) || (elm->id == ELEM_replaced_path))
        {
          lb->this_path_item->action 
            = (elm->id == ELEM_added_path) ? 'A' : 'R';
          copyfrom_path = get_attr(atts, "copyfrom-path");
          copyfrom_revstr = get_attr(atts, "copyfrom-rev");
          if (copyfrom_path && copyfrom_revstr
              && (SVN_IS_VALID_REVNUM
                  (copyfrom_rev = SVN_STR_TO_REV (copyfrom_revstr))))
            {
              lb->this_path_item->copyfrom_path = apr_pstrdup(lb->subpool,
                                                              copyfrom_path);
              lb->this_path_item->copyfrom_rev = copyfrom_rev;
            }
        }
      else if (elm->id == ELEM_deleted_path)
        {
          lb->this_path_item->action = 'D';
        }
      else
        {
          lb->this_path_item->action = 'M';
        }
      break;

    default:
      lb->this_path_item = NULL;
      break;
    }
  return SVN_RA_DAV__XML_VALID;
}


/*
 * This implements the `svn_ra_dav__xml_endelm_cb' prototype.
 */
static int
log_end_element(void *userdata,
                const svn_ra_dav__xml_elm_t *elm,
                const char *cdata)
{
  struct log_baton *lb = userdata;

  switch (elm->id)
    {
    case ELEM_version_name:
      lb->revision = SVN_STR_TO_REV (cdata);
      break;
    case ELEM_creator_displayname:
      lb->author = apr_pstrdup (lb->subpool, cdata);
      break;
    case ELEM_log_date:
      lb->date = apr_pstrdup (lb->subpool, cdata);
      break;
    case ELEM_added_path:
    case ELEM_replaced_path:
    case ELEM_deleted_path:
    case ELEM_modified_path:
      {
        char *path = apr_pstrdup (lb->subpool, cdata);
        if (! lb->changed_paths)
          lb->changed_paths = apr_hash_make(lb->subpool);
        apr_hash_set(lb->changed_paths, path, APR_HASH_KEY_STRING, 
                     lb->this_path_item);
        break;
      }
    case ELEM_comment:
      lb->msg = apr_pstrdup (lb->subpool, cdata);
      break;

⌨️ 快捷键说明

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