📄 log.c
字号:
/* * log.c : routines for requesting and parsing log reports * * ==================================================================== * Copyright (c) 2000-2005 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_xml.h>#include <ne_socket.h>#include "svn_error.h"#include "svn_pools.h"#include "svn_path.h"#include "svn_xml.h"#include "../libsvn_ra/ra_loader.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; int limit; int count; /* If we're in backwards compatibility mode for the svn log --limit stuff, we need to be able to bail out while parsing log messages. The way we do that is returning an error to neon, but we need to be able to tell that the error we returned wasn't actually a problem, so if this is TRUE it means we can safely ignore that error and return success. */ svn_boolean_t limit_compat_bailout; /* 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 voidreset_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 intlog_validate(void *userdata, svn_ra_dav__xml_elmid parent, svn_ra_dav__xml_elmid child){ /* ### todo */ return SVN_RA_DAV__XML_VALID;}/* * This implements the `svn_ra_dav__xml_startelm_cb' prototype. */static intlog_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 = svn_xml_get_attr_value("copyfrom-path", atts); copyfrom_revstr = svn_xml_get_attr_value("copyfrom-rev", atts); 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 intlog_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; case ELEM_log_item: { svn_error_t *err; /* Compatability cruft so that we can provide limit functionality even if the server doesn't support it. If we've seen as many log entries as we're going to show just error out of the XML parser so we can avoid having to parse the remaining XML, but set lb->err to SVN_NO_ERROR so no error will end up being shown to the user. */ if (lb->limit && (++lb->count > lb->limit)) { lb->err = SVN_NO_ERROR; lb->limit_compat_bailout = TRUE; return SVN_RA_DAV__XML_INVALID; } err = (*(lb->receiver))(lb->receiver_baton, lb->changed_paths, lb->revision, lb->author, lb->date, lb->msg, lb->subpool);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -