/* Implement svn_repos_path_change_receiver_t. * Convert CHANGE and add it to the CHANGES list in *BATON. */ static svn_error_t * log4_path_change_receiver(void *baton, svn_repos_path_change_t *change, apr_pool_t *scratch_pool) { log_entry_receiver_baton_t *b = baton; svn_log_changed_path2_t *change_copy; const char *path = apr_pstrmemdup(b->changes_pool, change->path.data, change->path.len); /* Create a deep copy of the temporary CHANGE struct. */ change_copy = svn_log_changed_path2_create(b->changes_pool); change_copy->action = path_change_kind_to_char(change->change_kind); if (change->copyfrom_path) change_copy->copyfrom_path = apr_pstrdup(b->changes_pool, change->copyfrom_path); change_copy->copyfrom_rev = change->copyfrom_rev; change_copy->node_kind = change->node_kind; change_copy->text_modified = change->text_mod ? svn_tristate_true : svn_tristate_false; change_copy->props_modified = change->prop_mod ? svn_tristate_true : svn_tristate_false; /* Auto-create the CHANGES container (happens for each first change * in any revison. */ if (b->changes == NULL) b->changes = svn_hash__make(b->changes_pool); /* Add change to per-revision collection. */ apr_hash_set(b->changes, path, change->path.len, change_copy); return SVN_NO_ERROR; }
/* Record ACTION on the path in CDATA into PATHS. Other properties about the action are pulled from ATTRS. */ static svn_error_t * collect_path(apr_hash_t *paths, char action, const svn_string_t *cdata, apr_hash_t *attrs) { apr_pool_t *result_pool = apr_hash_pool_get(paths); svn_log_changed_path2_t *lcp; const char *copyfrom_path; const char *copyfrom_rev; const char *path; lcp = svn_log_changed_path2_create(result_pool); lcp->action = action; lcp->copyfrom_rev = SVN_INVALID_REVNUM; /* COPYFROM_* are only recorded for ADDED_PATH and REPLACED_PATH. */ copyfrom_path = apr_hash_get(attrs, "copyfrom-path", APR_HASH_KEY_STRING); copyfrom_rev = apr_hash_get(attrs, "copyfrom-rev", APR_HASH_KEY_STRING); if (copyfrom_path && copyfrom_rev) { svn_revnum_t rev = SVN_STR_TO_REV(copyfrom_rev); if (SVN_IS_VALID_REVNUM(rev)) { lcp->copyfrom_path = apr_pstrdup(result_pool, copyfrom_path); lcp->copyfrom_rev = rev; } } lcp->node_kind = svn_node_kind_from_word(apr_hash_get( attrs, "node-kind", APR_HASH_KEY_STRING)); lcp->text_modified = svn_tristate__from_word(apr_hash_get( attrs, "text-mods", APR_HASH_KEY_STRING)); lcp->props_modified = svn_tristate__from_word(apr_hash_get( attrs, "prop-mods", APR_HASH_KEY_STRING)); path = apr_pstrmemdup(result_pool, cdata->data, cdata->len); apr_hash_set(paths, path, APR_HASH_KEY_STRING, lcp); return SVN_NO_ERROR; }
/* * This implements the `svn_ra_neon__xml_startelm_cb' prototype. */ static svn_error_t * log_start_element(int *elem, void *baton, int parent, const char *nspace, const char *name, const char **atts) { const char *copyfrom_path, *copyfrom_revstr; svn_revnum_t copyfrom_rev; struct log_baton *lb = baton; static const svn_ra_neon__xml_elm_t log_report_elements[] = { { SVN_XML_NAMESPACE, "log-report", ELEM_log_report, 0 }, { SVN_XML_NAMESPACE, "log-item", ELEM_log_item, 0 }, { SVN_XML_NAMESPACE, "date", ELEM_log_date, SVN_RA_NEON__XML_CDATA }, { SVN_XML_NAMESPACE, "added-path", ELEM_added_path, SVN_RA_NEON__XML_CDATA }, { SVN_XML_NAMESPACE, "deleted-path", ELEM_deleted_path, SVN_RA_NEON__XML_CDATA }, { SVN_XML_NAMESPACE, "modified-path", ELEM_modified_path, SVN_RA_NEON__XML_CDATA }, { SVN_XML_NAMESPACE, "replaced-path", ELEM_replaced_path, SVN_RA_NEON__XML_CDATA }, { SVN_XML_NAMESPACE, "revprop", ELEM_revprop, SVN_RA_NEON__XML_CDATA }, { "DAV:", SVN_DAV__VERSION_NAME, ELEM_version_name, SVN_RA_NEON__XML_CDATA }, { "DAV:", "creator-displayname", ELEM_creator_displayname, SVN_RA_NEON__XML_CDATA }, { "DAV:", "comment", ELEM_comment, SVN_RA_NEON__XML_CDATA }, { SVN_XML_NAMESPACE, "has-children", ELEM_has_children, SVN_RA_NEON__XML_CDATA }, { SVN_XML_NAMESPACE, "subtractive-merge", ELEM_subtractive_merge, SVN_RA_NEON__XML_CDATA }, { NULL } }; const svn_ra_neon__xml_elm_t *elm = svn_ra_neon__lookup_xml_elem(log_report_elements, nspace, name); *elem = elm ? elm->id : SVN_RA_NEON__XML_DECLINE; if (!elm) return SVN_NO_ERROR; switch (elm->id) { case ELEM_creator_displayname: case ELEM_log_date: case ELEM_version_name: case ELEM_added_path: case ELEM_replaced_path: case ELEM_deleted_path: case ELEM_modified_path: case ELEM_revprop: case ELEM_comment: lb->want_cdata = lb->cdata; svn_stringbuf_setempty(lb->cdata); if (elm->id == ELEM_revprop) { lb->revprop_name = apr_pstrdup(lb->subpool, svn_xml_get_attr_value("name", atts)); if (lb->revprop_name == NULL) return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Missing name attr in revprop element")); } break; case ELEM_has_children: lb->log_entry->has_children = TRUE; break; case ELEM_subtractive_merge: lb->log_entry->subtractive_merge = TRUE; break; default: lb->want_cdata = NULL; break; } switch (elm->id) { case ELEM_added_path: case ELEM_replaced_path: case ELEM_deleted_path: case ELEM_modified_path: lb->this_path_item = svn_log_changed_path2_create(lb->subpool); lb->this_path_item->node_kind = svn_node_kind_from_word( svn_xml_get_attr_value("node-kind", atts)); lb->this_path_item->copyfrom_rev = SVN_INVALID_REVNUM; lb->this_path_item->text_modified = svn_tristate__from_word( svn_xml_get_attr_value("text-mods", atts)); lb->this_path_item->props_modified = svn_tristate__from_word( svn_xml_get_attr_value("prop-mods", atts)); /* See documentation for `svn_repos_node_t' in svn_repos.h, and `svn_log_changed_path_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_NO_ERROR; }