Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8C804D92F for ; Tue, 26 Jun 2012 19:31:08 +0000 (UTC) Received: (qmail 79843 invoked by uid 500); 26 Jun 2012 19:31:08 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 79801 invoked by uid 500); 26 Jun 2012 19:31:08 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 79792 invoked by uid 99); 26 Jun 2012 19:31:08 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Jun 2012 19:31:08 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Jun 2012 19:30:59 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 2098E2388C31; Tue, 26 Jun 2012 19:30:14 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1354186 [11/33] - in /subversion/branches/inheritable-props: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/server-side/ notes/ notes/api-errata/1.8/ notes/directory-i... Date: Tue, 26 Jun 2012 19:28:22 -0000 To: commits@subversion.apache.org From: pburba@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120626193014.2098E2388C31@eris.apache.org> Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/key-gen.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/key-gen.c?rev=1354186&r1=1354185&r2=1354186&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/key-gen.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/key-gen.c Tue Jun 26 19:26:49 2012 @@ -60,7 +60,7 @@ svn_fs_fs__add_keys(const char *key1, co carry = val / 36; val = val % 36; - buf[i3++] = (val <= 9) ? (val + '0') : (val - 10 + 'a'); + buf[i3++] = (char)((val <= 9) ? (val + '0') : (val - 10 + 'a')); if (i1>=0) i1--; @@ -115,7 +115,7 @@ svn_fs_fs__next_key(const char *this, ap if (c == '9') next[i] = 'a'; else - next[i] = c + 1; + next[i] = ++c; } } else Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/lock.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/lock.c?rev=1354186&r1=1354185&r2=1354186&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/lock.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/lock.c Tue Jun 26 19:26:49 2012 @@ -477,23 +477,31 @@ delete_lock(svn_fs_t *fs, /* Set *LOCK_P to the lock for PATH in FS. HAVE_WRITE_LOCK should be TRUE if the caller (or one of its callers) has taken out the - repository-wide write lock, FALSE otherwise. Use POOL for - allocations. */ + repository-wide write lock, FALSE otherwise. If MUST_EXIST is + not set, the function will simply return NULL in *LOCK_P instead + of creating an SVN_FS__ERR_NO_SUCH_LOCK error in case the lock + was not found (much faster). Use POOL for allocations. */ static svn_error_t * get_lock(svn_lock_t **lock_p, svn_fs_t *fs, const char *path, svn_boolean_t have_write_lock, + svn_boolean_t must_exist, apr_pool_t *pool) { - svn_lock_t *lock; + svn_lock_t *lock = NULL; const char *digest_path; + svn_node_kind_t kind; SVN_ERR(digest_path_from_path(&digest_path, fs->path, path, pool)); + SVN_ERR(svn_io_check_path(digest_path, &kind, pool)); + + *lock_p = NULL; + if (kind != svn_node_none) + SVN_ERR(read_digest_file(NULL, &lock, fs->path, digest_path, pool)); - SVN_ERR(read_digest_file(NULL, &lock, fs->path, digest_path, pool)); if (! lock) - return SVN_FS__ERR_NO_SUCH_LOCK(fs, path, pool); + return must_exist ? SVN_FS__ERR_NO_SUCH_LOCK(fs, path) : SVN_NO_ERROR; /* Don't return an expired lock. */ if (lock->expiration_date && (apr_time_now() > lock->expiration_date)) @@ -502,8 +510,7 @@ get_lock(svn_lock_t **lock_p, Read operations shouldn't change the filesystem. */ if (have_write_lock) SVN_ERR(delete_lock(fs, lock, pool)); - *lock_p = NULL; - return SVN_FS__ERR_LOCK_EXPIRED(fs, lock->token, pool); + return SVN_FS__ERR_LOCK_EXPIRED(fs, lock->token); } *lock_p = lock; @@ -525,7 +532,7 @@ get_lock_helper(svn_fs_t *fs, svn_lock_t *lock; svn_error_t *err; - err = get_lock(&lock, fs, path, have_write_lock, pool); + err = get_lock(&lock, fs, path, have_write_lock, FALSE, pool); /* We've deliberately decided that this function doesn't tell the caller *why* the lock is unavailable. */ @@ -648,7 +655,11 @@ walk_locks(svn_fs_t *fs, svn_boolean_t have_write_lock, apr_pool_t *pool) { - struct walk_locks_baton wlb = { get_locks_func, get_locks_baton, fs }; + struct walk_locks_baton wlb; + + wlb.get_locks_func = get_locks_func; + wlb.get_locks_baton = get_locks_baton; + wlb.fs = fs; SVN_ERR(walk_digest_files(fs->path, digest_path, locks_walker, &wlb, have_write_lock, pool)); return SVN_NO_ERROR; @@ -766,7 +777,7 @@ lock_body(void *baton, apr_pool_t *pool) SVN_ERR(lb->fs->vtable->revision_root(&root, lb->fs, youngest, pool)); SVN_ERR(svn_fs_fs__check_path(&kind, root, lb->path, pool)); if (kind == svn_node_dir) - return SVN_FS__ERR_NOT_FILE(lb->fs, lb->path, pool); + return SVN_FS__ERR_NOT_FILE(lb->fs, lb->path); /* While our locking implementation easily supports the locking of nonexistent paths, we deliberately choose not to allow such madness. */ @@ -786,7 +797,7 @@ lock_body(void *baton, apr_pool_t *pool) /* We need to have a username attached to the fs. */ if (!lb->fs->access_ctx || !lb->fs->access_ctx->username) - return SVN_FS__ERR_NO_USER(lb->fs, pool); + return SVN_FS__ERR_NO_USER(lb->fs); /* Is the caller attempting to lock an out-of-date working file? */ if (SVN_IS_VALID_REVNUM(lb->current_rev)) @@ -832,7 +843,7 @@ lock_body(void *baton, apr_pool_t *pool) if (! lb->steal_lock) { /* Sorry, the path is already locked. */ - return SVN_FS__ERR_PATH_ALREADY_LOCKED(lb->fs, existing_lock, pool); + return SVN_FS__ERR_PATH_ALREADY_LOCKED(lb->fs, existing_lock); } else { @@ -881,23 +892,23 @@ unlock_body(void *baton, apr_pool_t *poo svn_lock_t *lock; /* This could return SVN_ERR_FS_BAD_LOCK_TOKEN or SVN_ERR_FS_LOCK_EXPIRED. */ - SVN_ERR(get_lock(&lock, ub->fs, ub->path, TRUE, pool)); + SVN_ERR(get_lock(&lock, ub->fs, ub->path, TRUE, TRUE, pool)); /* Unless breaking the lock, we do some checks. */ if (! ub->break_lock) { /* Sanity check: the incoming token should match lock->token. */ if (strcmp(ub->token, lock->token) != 0) - return SVN_FS__ERR_NO_SUCH_LOCK(ub->fs, lock->path, pool); + return SVN_FS__ERR_NO_SUCH_LOCK(ub->fs, lock->path); /* There better be a username attached to the fs. */ if (! (ub->fs->access_ctx && ub->fs->access_ctx->username)) - return SVN_FS__ERR_NO_USER(ub->fs, pool); + return SVN_FS__ERR_NO_USER(ub->fs); /* And that username better be the same as the lock's owner. */ if (strcmp(ub->fs->access_ctx->username, lock->owner) != 0) return SVN_FS__ERR_LOCK_OWNER_MISMATCH( - ub->fs, ub->fs->access_ctx->username, lock->owner, pool); + ub->fs, ub->fs->access_ctx->username, lock->owner); } /* Remove lock and lock token files. */ Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache-db.sql URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache-db.sql?rev=1354186&r1=1354185&r2=1354186&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache-db.sql (original) +++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/rep-cache-db.sql Tue Jun 26 19:26:49 2012 @@ -41,25 +41,19 @@ SELECT revision, offset, size, expanded_ FROM rep_cache WHERE hash = ?1 - -- STMT_SET_REP INSERT OR FAIL INTO rep_cache (hash, revision, offset, size, expanded_size) VALUES (?1, ?2, ?3, ?4, ?5) - -- STMT_GET_REPS_FOR_RANGE SELECT hash, revision, offset, size, expanded_size FROM rep_cache WHERE revision >= ?1 AND revision <= ?2 - -- STMT_GET_MAX_REV SELECT MAX(revision) FROM rep_cache - -- STMT_DEL_REPS_YOUNGER_THAN_REV DELETE FROM rep_cache WHERE revision > ?1 - - Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.c?rev=1354186&r1=1354185&r2=1354186&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.c Tue Jun 26 19:26:49 2012 @@ -30,6 +30,7 @@ #include "private/svn_fs_util.h" #include "private/svn_temp_serializer.h" +#include "private/svn_subr_private.h" #include "temp_serializer.h" @@ -47,16 +48,16 @@ encode_number(apr_int64_t number, char * if (number < 0) { number = -number; - *key_buffer = (number & 63) + ' ' + 65; + *key_buffer = (char)((number & 63) + ' ' + 65); } else - *key_buffer = (number & 63) + ' ' + 1; + *key_buffer = (char)((number & 63) + ' ' + 1); number /= 64; /* write 7 bits / byte until no significant bits are left */ while (number) { - *++key_buffer = (number & 127) + ' ' + 1; + *++key_buffer = (char)((number & 127) + ' ' + 1); number /= 128; } @@ -359,7 +360,7 @@ serialize_dir(apr_hash_t *entries, apr_p static apr_hash_t * deserialize_dir(void *buffer, hash_data_t *hash_data, apr_pool_t *pool) { - apr_hash_t *result = apr_hash_make(pool); + apr_hash_t *result = svn_hash__make(pool); apr_size_t i; apr_size_t count; svn_fs_dirent_t *entry; @@ -678,7 +679,7 @@ svn_fs_fs__deserialize_properties(void * apr_size_t data_len, apr_pool_t *pool) { - apr_hash_t *hash = apr_hash_make(pool); + apr_hash_t *hash = svn_hash__make(pool); properties_data_t *properties = (properties_data_t *)data; size_t i; @@ -931,7 +932,7 @@ svn_fs_fs__extract_dir_entry(void **out, svn_temp_deserializer__ptr(entries, (const void *const *)&entries[pos]); /* Entries have been serialized one-by-one, each time including all - * nestes structures and strings. Therefore, they occupy a single + * nested structures and strings. Therefore, they occupy a single * block of memory whose end-offset is either the beginning of the * next entry or the end of the buffer */ Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c?rev=1354186&r1=1354185&r2=1354186&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/tree.c Tue Jun 26 19:26:49 2012 @@ -360,7 +360,7 @@ mutable_root_node(dag_node_t **node_p, return svn_fs_fs__dag_clone_root(node_p, root->fs, root->txn, pool); else /* If it's not a transaction root, we can't change its contents. */ - return SVN_FS__ERR_NOT_MUTABLE(root->fs, root->rev, error_path, pool); + return SVN_FS__ERR_NOT_MUTABLE(root->fs, root->rev, error_path); } @@ -697,7 +697,7 @@ open_path(parent_path_t **parent_path_p, /* The path isn't finished yet; we'd better be in a directory. */ if (svn_fs_fs__dag_node_kind(child) != svn_node_dir) - SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, path_so_far, iterpool), + SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, path_so_far), apr_psprintf(iterpool, _("Failure opening '%s'"), path)); rest = next; @@ -1880,7 +1880,7 @@ fs_make_dir(svn_fs_root_t *root, /* If there's already a sub-directory by that name, complain. This also catches the case of trying to make a subdirectory named `/'. */ if (parent_path->node) - return SVN_FS__ALREADY_EXISTS(root, path, pool); + return SVN_FS__ALREADY_EXISTS(root, path); /* Create the subdirectory. */ SVN_ERR(make_path_mutable(root, parent_path->parent, path, pool)); @@ -1968,17 +1968,7 @@ fs_same_p(svn_boolean_t *same_p, svn_fs_t *fs2, apr_pool_t *pool) { - const char *uuid1; - const char *uuid2; - - /* Random thought: if fetching UUIDs to compare filesystems is too - expensive, one solution would be to cache the UUID in each fs - object (copying the UUID into fs->pool, of course). */ - - SVN_ERR(fs1->vtable->get_uuid(fs1, &uuid1, pool)); - SVN_ERR(fs2->vtable->get_uuid(fs2, &uuid2, pool)); - - *same_p = ! strcmp(uuid1, uuid2); + *same_p = ! strcmp(fs1->uuid, fs2->uuid); return SVN_NO_ERROR; } @@ -2225,7 +2215,7 @@ fs_make_file(svn_fs_root_t *root, /* If there's already a file by that name, complain. This also catches the case of trying to make a file named `/'. */ if (parent_path->node) - return SVN_FS__ALREADY_EXISTS(root, path, pool); + return SVN_FS__ALREADY_EXISTS(root, path); /* Check (non-recursively) to see if path is locked; if so, check that we can use it. */ Modified: subversion/branches/inheritable-props/subversion/libsvn_ra/compat.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra/compat.c?rev=1354186&r1=1354185&r2=1354186&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_ra/compat.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_ra/compat.c Tue Jun 26 19:26:49 2012 @@ -757,8 +757,9 @@ svn_ra__file_revs_from_log(svn_ra_sessio /* Compute and send delta if client asked for it. */ if (delta_handler) { - /* Get the content delta. */ - svn_txdelta(&delta_stream, last_stream, stream, lastpool); + /* Get the content delta. Don't calculate checksums as we don't + * use them. */ + svn_txdelta2(&delta_stream, last_stream, stream, FALSE, lastpool); /* And send. */ SVN_ERR(svn_txdelta_send_txstream(delta_stream, delta_handler, Modified: subversion/branches/inheritable-props/subversion/libsvn_ra/debug_reporter.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra/debug_reporter.c?rev=1354186&r1=1354185&r2=1354186&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_ra/debug_reporter.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_ra/debug_reporter.c Tue Jun 26 19:26:49 2012 @@ -95,7 +95,7 @@ finish_report(void *report_baton, apr_pool_t *pool) { struct report_baton *rb = report_baton; - SVN_ERR(svn_stream_printf(rb->out, pool, "finish_report()\n")); + SVN_ERR(svn_stream_puts(rb->out, "finish_report()\n")); SVN_ERR(rb->wrapped_reporter->finish_report(rb->wrapped_report_baton, pool)); return SVN_NO_ERROR; } @@ -105,7 +105,7 @@ abort_report(void *report_baton, apr_pool_t *pool) { struct report_baton *rb = report_baton; - SVN_ERR(svn_stream_printf(rb->out, pool, "abort_report()\n")); + SVN_ERR(svn_stream_puts(rb->out, "abort_report()\n")); SVN_ERR(rb->wrapped_reporter->abort_report(rb->wrapped_report_baton, pool)); return SVN_NO_ERROR; } Propchange: subversion/branches/inheritable-props/subversion/libsvn_ra/editor.c ------------------------------------------------------------------------------ svn:eol-style = native Modified: subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c?rev=1354186&r1=1354185&r2=1354186&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.c Tue Jun 26 19:26:49 2012 @@ -53,20 +53,6 @@ #include "svn_private_config.h" -/* ### This file maps URL schemes to particular RA libraries. - ### Currently, the only pair of RA libraries which support the same - ### protocols are neon and serf. svn_ra_open3 makes the assumption - ### that this is the case; that their 'schemes' fields are both - ### dav_schemes; and that "neon" is listed first. - - ### Users can choose which dav library to use with the http-library - ### preference in .subversion/servers; however, it is ignored by - ### any code which uses the pre-1.2 API svn_ra_get_ra_library - ### instead of svn_ra_open. */ - -#if defined(SVN_HAVE_NEON) && defined(SVN_HAVE_SERF) -#define CHOOSABLE_DAV_MODULE -#endif /* These are the URI schemes that the respective libraries *may* support. @@ -88,15 +74,6 @@ static const struct ra_lib_defn { svn_ra_init_func_t compat_initfunc; } ra_libraries[] = { { - "neon", - dav_schemes, -#ifdef SVN_LIBSVN_CLIENT_LINKS_RA_NEON - svn_ra_neon__init, - svn_ra_dav_init -#endif - }, - - { "svn", svn_schemes, #ifdef SVN_LIBSVN_CLIENT_LINKS_RA_SVN @@ -416,8 +393,7 @@ svn_error_t *svn_ra_open4(svn_ra_session SVN_CONFIG_OPTION_HTTP_LIBRARY, DEFAULT_HTTP_LIBRARY); - if (strcmp(http_library, "neon") != 0 && - strcmp(http_library, "serf") != 0) + if (strcmp(http_library, "serf") != 0) return svn_error_createf(SVN_ERR_BAD_CONFIG_VALUE, NULL, _("Invalid config: unknown HTTP library " "'%s'"), @@ -1046,6 +1022,8 @@ svn_error_t *svn_ra_do_diff3(svn_ra_sess void *diff_baton, apr_pool_t *pool) { + SVN_ERR_ASSERT(svn_path_is_empty(diff_target) + || svn_path_is_single_path_component(diff_target)); return session->vtable->do_diff(session, reporter, report_baton, revision, diff_target, @@ -1311,6 +1289,17 @@ svn_error_t *svn_ra_replay(svn_ra_sessio } svn_error_t * +svn_ra__replay_ev2(svn_ra_session_t *session, + svn_revnum_t revision, + svn_revnum_t low_water_mark, + svn_boolean_t send_deltas, + svn_editor_t *editor, + apr_pool_t *scratch_pool) +{ + SVN__NOT_IMPLEMENTED(); +} + +svn_error_t * svn_ra_replay_range(svn_ra_session_t *session, svn_revnum_t start_revision, svn_revnum_t end_revision, @@ -1363,6 +1352,20 @@ svn_ra_replay_range(svn_ra_session_t *se return err; } +svn_error_t * +svn_ra__replay_range_ev2(svn_ra_session_t *session, + svn_revnum_t start_revision, + svn_revnum_t end_revision, + svn_revnum_t low_water_mark, + svn_boolean_t send_deltas, + svn_ra__replay_revstart_ev2_callback_t revstart_func, + svn_ra__replay_revfinish_ev2_callback_t revfinish_func, + void *replay_baton, + apr_pool_t *scratch_pool) +{ + SVN__NOT_IMPLEMENTED(); +} + svn_error_t *svn_ra_has_capability(svn_ra_session_t *session, svn_boolean_t *has, const char *capability, @@ -1398,8 +1401,7 @@ svn_ra_get_deleted_rev(svn_ra_session_t end_revision, revision_deleted, pool); - if (err && (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE /* serf */ - || err->apr_err == SVN_ERR_RA_NOT_IMPLEMENTED)) /* neon */ + if (err && (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE)) { svn_error_clear(err); Modified: subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.h URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.h?rev=1354186&r1=1354185&r2=1354186&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.h (original) +++ subversion/branches/inheritable-props/subversion/libsvn_ra/ra_loader.h Tue Jun 26 19:26:49 2012 @@ -360,9 +360,6 @@ svn_error_t *svn_ra_local__init(const sv svn_error_t *svn_ra_svn__init(const svn_version_t *loader_version, const svn_ra__vtable_t **vtable, apr_pool_t *pool); -svn_error_t *svn_ra_neon__init(const svn_version_t *loader_version, - const svn_ra__vtable_t **vtable, - apr_pool_t *pool); svn_error_t *svn_ra_serf__init(const svn_version_t *loader_version, const svn_ra__vtable_t **vtable, apr_pool_t *pool); Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_serf/blame.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_serf/blame.c?rev=1354186&r1=1354185&r2=1354186&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_ra_serf/blame.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_ra_serf/blame.c Tue Jun 26 19:26:49 2012 @@ -22,9 +22,6 @@ */ #include - -#include - #include #include "svn_pools.h" @@ -49,7 +46,7 @@ * This enum represents the current state of our XML parsing for a REPORT. */ typedef enum blame_state_e { - NONE = 0, + INITIAL = 0, FILE_REVS_REPORT, FILE_REV, REV_PROP, @@ -59,40 +56,6 @@ typedef enum blame_state_e { TXDELTA } blame_state_e; -typedef struct blame_info_t { - /* Current pool. */ - apr_pool_t *pool; - - /* our suspicious file */ - const char *path; - - /* the intended suspect */ - svn_revnum_t rev; - - /* Hashtable of revision properties */ - apr_hash_t *rev_props; - - /* Added and removed properties (svn_prop_t*'s) */ - apr_array_header_t *prop_diffs; - - /* txdelta */ - svn_txdelta_window_handler_t txdelta; - void *txdelta_baton; - - /* returned txdelta stream */ - svn_stream_t *stream; - - /* Is this property base64-encoded? */ - svn_boolean_t prop_base64; - - /* The currently collected value as we build it up */ - const char *prop_name; - svn_stringbuf_t *prop_value; - - /* Merged revision flag */ - svn_boolean_t merged_revision; - -} blame_info_t; typedef struct blame_context_t { /* pool passed to get_file_revs */ @@ -104,272 +67,213 @@ typedef struct blame_context_t { svn_revnum_t end; svn_boolean_t include_merged_revisions; - /* are we done? */ - svn_boolean_t done; - /* blame handler and baton */ svn_file_rev_handler_t file_rev; void *file_rev_baton; + + /* As we parse each FILE_REV, we collect data in these variables: + property changes and new content. STREAM is valid when we're + in the TXDELTA state, processing the incoming cdata. */ + apr_hash_t *rev_props; + apr_array_header_t *prop_diffs; + apr_pool_t *state_pool; /* put property stuff in here */ + + svn_stream_t *stream; + } blame_context_t; - -static blame_info_t * -push_state(svn_ra_serf__xml_parser_t *parser, - blame_context_t *blame_ctx, - blame_state_e state) -{ - svn_ra_serf__xml_push_state(parser, state); - if (state == FILE_REV) - { - blame_info_t *info; +#define D_ "DAV:" +#define S_ SVN_XML_NAMESPACE +static const svn_ra_serf__xml_transition_t blame_ttable[] = { + { INITIAL, S_, "file-revs-report", FILE_REVS_REPORT, + FALSE, { NULL }, FALSE }, - info = apr_pcalloc(parser->state->pool, sizeof(*info)); + { FILE_REVS_REPORT, S_, "file-rev", FILE_REV, + FALSE, { "path", "rev", NULL }, TRUE }, - info->pool = parser->state->pool; + { FILE_REV, S_, "rev-prop", REV_PROP, + TRUE, { "name", "?encoding", NULL }, TRUE }, - info->rev = SVN_INVALID_REVNUM; + { FILE_REV, S_, "set-prop", SET_PROP, + TRUE, { "name", "?encoding", NULL }, TRUE }, - info->rev_props = apr_hash_make(info->pool); - info->prop_diffs = apr_array_make(info->pool, 0, sizeof(svn_prop_t)); + { FILE_REV, S_, "remove-prop", REMOVE_PROP, + FALSE, { "name", NULL }, TRUE }, - info->prop_value = svn_stringbuf_create_empty(info->pool); + { FILE_REV, S_, "merged-revision", MERGED_REVISION, + FALSE, { NULL }, TRUE }, - parser->state->private = info; - } + { FILE_REV, S_, "txdelta", TXDELTA, + FALSE, { NULL }, TRUE }, - return parser->state->private; -} + { 0 } +}; -static const svn_string_t * -create_propval(blame_info_t *info) +/* Conforms to svn_ra_serf__xml_opened_t */ +static svn_error_t * +blame_opened(svn_ra_serf__xml_estate_t *xes, + void *baton, + int entered_state, + const svn_ra_serf__dav_props_t *tag, + apr_pool_t *scratch_pool) { - if (info->prop_base64) + blame_context_t *blame_ctx = baton; + + if (entered_state == FILE_REV) { - const svn_string_t *morph; + apr_pool_t *state_pool = svn_ra_serf__xml_state_pool(xes); - morph = svn_stringbuf__morph_into_string(info->prop_value); -#ifdef SVN_DEBUG - info->prop_value = NULL; /* morph killed the stringbuf. */ -#endif - return svn_base64_decode_string(morph, info->pool); + /* Child elements will store properties in these structures. */ + blame_ctx->rev_props = apr_hash_make(state_pool); + blame_ctx->prop_diffs = apr_array_make(state_pool, + 5, sizeof(svn_prop_t)); + blame_ctx->state_pool = state_pool; + + /* Clear this, so we can detect the absence of a TXDELTA. */ + blame_ctx->stream = NULL; + } + else if (entered_state == TXDELTA) + { + apr_pool_t *state_pool = svn_ra_serf__xml_state_pool(xes); + apr_hash_t *gathered = svn_ra_serf__xml_gather_since(xes, FILE_REV); + const char *path; + const char *rev; + const char *merged_revision; + svn_txdelta_window_handler_t txdelta; + void *txdelta_baton; + + path = apr_hash_get(gathered, "path", APR_HASH_KEY_STRING); + rev = apr_hash_get(gathered, "rev", APR_HASH_KEY_STRING); + merged_revision = apr_hash_get(gathered, + "merged-revision", APR_HASH_KEY_STRING); + + SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton, + path, SVN_STR_TO_REV(rev), + blame_ctx->rev_props, + merged_revision != NULL, + &txdelta, &txdelta_baton, + blame_ctx->prop_diffs, + state_pool)); + + blame_ctx->stream = svn_base64_decode(svn_txdelta_parse_svndiff( + txdelta, txdelta_baton, + TRUE /* error_on_early_close */, + state_pool), + state_pool); } - return svn_string_create_from_buf(info->prop_value, info->pool); + return SVN_NO_ERROR; } + +/* Conforms to svn_ra_serf__xml_closed_t */ static svn_error_t * -start_blame(svn_ra_serf__xml_parser_t *parser, - svn_ra_serf__dav_props_t name, - const char **attrs, - apr_pool_t *scratch_pool) +blame_closed(svn_ra_serf__xml_estate_t *xes, + void *baton, + int leaving_state, + const svn_string_t *cdata, + apr_hash_t *attrs, + apr_pool_t *scratch_pool) { - blame_context_t *blame_ctx = parser->user_data; - blame_state_e state; + blame_context_t *blame_ctx = baton; - state = parser->state->current_state; + if (leaving_state == FILE_REV) + { + /* Note that we test STREAM, but any pointer is currently invalid. + It was closed when left the TXDELTA state. */ + if (blame_ctx->stream == NULL) + { + const char *path; + const char *rev; + + path = apr_hash_get(attrs, "path", APR_HASH_KEY_STRING); + rev = apr_hash_get(attrs, "rev", APR_HASH_KEY_STRING); - if (state == NONE && strcmp(name.name, "file-revs-report") == 0) + /* Send a "no content" notification. */ + SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton, + path, SVN_STR_TO_REV(rev), + blame_ctx->rev_props, + FALSE /* result_of_merge */, + NULL, NULL, /* txdelta / baton */ + blame_ctx->prop_diffs, + scratch_pool)); + } + } + else if (leaving_state == MERGED_REVISION) { - push_state(parser, blame_ctx, FILE_REVS_REPORT); + svn_ra_serf__xml_note(xes, FILE_REV, "merged-revision", "*"); } - else if (state == FILE_REVS_REPORT && - strcmp(name.name, "file-rev") == 0) + else if (leaving_state == TXDELTA) { - blame_info_t *info; - - info = push_state(parser, blame_ctx, FILE_REV); - - info->path = apr_pstrdup(info->pool, - svn_xml_get_attr_value("path", attrs)); - info->rev = SVN_STR_TO_REV(svn_xml_get_attr_value("rev", attrs)); + SVN_ERR(svn_stream_close(blame_ctx->stream)); } - else if (state == FILE_REV) + else { - blame_info_t *info; - const char *enc; + const char *name; + const svn_string_t *value; - info = parser->state->private; + SVN_ERR_ASSERT(leaving_state == REV_PROP + || leaving_state == SET_PROP + || leaving_state == REMOVE_PROP); - if (strcmp(name.name, "rev-prop") == 0) - { - push_state(parser, blame_ctx, REV_PROP); - } - else if (strcmp(name.name, "set-prop") == 0) - { - push_state(parser, blame_ctx, SET_PROP); - } - if (strcmp(name.name, "remove-prop") == 0) - { - push_state(parser, blame_ctx, REMOVE_PROP); - } - else if (strcmp(name.name, "merged-revision") == 0) + name = apr_pstrdup(blame_ctx->state_pool, + apr_hash_get(attrs, "name", APR_HASH_KEY_STRING)); + + if (leaving_state == REMOVE_PROP) { - push_state(parser, blame_ctx, MERGED_REVISION); + value = NULL; } - else if (strcmp(name.name, "txdelta") == 0) + else { - SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton, - info->path, info->rev, - info->rev_props, info->merged_revision, - &info->txdelta, &info->txdelta_baton, - info->prop_diffs, info->pool)); - - info->stream = svn_base64_decode - (svn_txdelta_parse_svndiff(info->txdelta, info->txdelta_baton, - TRUE, info->pool), info->pool); - - push_state(parser, blame_ctx, TXDELTA); - } + const char *encoding = apr_hash_get(attrs, + "encoding", APR_HASH_KEY_STRING); - state = parser->state->current_state; - - switch (state) - { - case REV_PROP: - case SET_PROP: - case REMOVE_PROP: - info->prop_name = apr_pstrdup(info->pool, - svn_xml_get_attr_value("name", attrs)); - svn_stringbuf_setempty(info->prop_value); - - enc = svn_xml_get_attr_value("encoding", attrs); - if (enc && strcmp(enc, "base64") == 0) - { - info->prop_base64 = TRUE; - } + if (encoding && strcmp(encoding, "base64") == 0) + value = svn_base64_decode_string(cdata, blame_ctx->state_pool); else - { - info->prop_base64 = FALSE; - } - break; - case MERGED_REVISION: - info->merged_revision = TRUE; - break; - default: - break; + value = svn_string_dup(cdata, blame_ctx->state_pool); } - } - - return SVN_NO_ERROR; -} -static svn_error_t * -end_blame(svn_ra_serf__xml_parser_t *parser, - svn_ra_serf__dav_props_t name, - apr_pool_t *scratch_pool) -{ - blame_context_t *blame_ctx = parser->user_data; - blame_state_e state; - blame_info_t *info; - - state = parser->state->current_state; - info = parser->state->private; - - if (state == NONE) - { - return SVN_NO_ERROR; - } - - if (state == FILE_REVS_REPORT && - strcmp(name.name, "file-revs-report") == 0) - { - svn_ra_serf__xml_pop_state(parser); - } - else if (state == FILE_REV && - strcmp(name.name, "file-rev") == 0) - { - /* no file changes. */ - if (!info->stream) + if (leaving_state == REV_PROP) { - SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton, - info->path, info->rev, - info->rev_props, FALSE, - NULL, NULL, - info->prop_diffs, info->pool)); + apr_hash_set(blame_ctx->rev_props, name, APR_HASH_KEY_STRING, value); } - svn_ra_serf__xml_pop_state(parser); - } - else if (state == REV_PROP && - strcmp(name.name, "rev-prop") == 0) - { - apr_hash_set(info->rev_props, - info->prop_name, APR_HASH_KEY_STRING, - create_propval(info)); - - svn_ra_serf__xml_pop_state(parser); - } - else if ((state == SET_PROP && - strcmp(name.name, "set-prop") == 0) || - (state == REMOVE_PROP && - strcmp(name.name, "remove-prop") == 0)) - { - svn_prop_t *prop = apr_array_push(info->prop_diffs); - prop->name = info->prop_name; - prop->value = create_propval(info); - - svn_ra_serf__xml_pop_state(parser); - } - else if (state == MERGED_REVISION && - strcmp(name.name, "merged-revision") == 0) - { - svn_ra_serf__xml_pop_state(parser); - } - else if (state == TXDELTA && - strcmp(name.name, "txdelta") == 0) - { - SVN_ERR(svn_stream_close(info->stream)); + else + { + svn_prop_t *prop = apr_array_push(blame_ctx->prop_diffs); - svn_ra_serf__xml_pop_state(parser); + prop->name = name; + prop->value = value; + } } return SVN_NO_ERROR; } + +/* Conforms to svn_ra_serf__xml_cdata_t */ static svn_error_t * -cdata_blame(svn_ra_serf__xml_parser_t *parser, +blame_cdata(svn_ra_serf__xml_estate_t *xes, + void *baton, + int current_state, const char *data, apr_size_t len, apr_pool_t *scratch_pool) { - blame_context_t *blame_ctx = parser->user_data; - blame_state_e state; - blame_info_t *info; - - UNUSED_CTX(blame_ctx); - - state = parser->state->current_state; - info = parser->state->private; - - if (state == NONE) - { - return SVN_NO_ERROR; - } + blame_context_t *blame_ctx = baton; - switch (state) + if (current_state == TXDELTA) { - case REV_PROP: - case SET_PROP: - svn_stringbuf_appendbytes(info->prop_value, data, len); - break; - case TXDELTA: - if (info->stream) - { - apr_size_t ret_len; - - ret_len = len; - - SVN_ERR(svn_stream_write(info->stream, data, &ret_len)); - } - break; - default: - break; + SVN_ERR(svn_stream_write(blame_ctx->stream, data, &len)); + /* Ignore the returned LEN value. */ } return SVN_NO_ERROR; } + /* Implements svn_ra_serf__request_body_delegate_t */ static svn_error_t * create_file_revs_body(serf_bucket_t **body_bkt, @@ -426,9 +330,8 @@ svn_ra_serf__get_file_revs(svn_ra_sessio blame_context_t *blame_ctx; svn_ra_serf__session_t *session = ra_session->priv; svn_ra_serf__handler_t *handler; - svn_ra_serf__xml_parser_t *parser_ctx; - const char *relative_url, *basecoll_url, *req_url; - int status_code; + svn_ra_serf__xml_context_t *xmlctx; + const char *req_url; svn_error_t *err; blame_ctx = apr_pcalloc(pool, sizeof(*blame_ctx)); @@ -439,14 +342,19 @@ svn_ra_serf__get_file_revs(svn_ra_sessio blame_ctx->start = start; blame_ctx->end = end; blame_ctx->include_merged_revisions = include_merged_revisions; - blame_ctx->done = FALSE; - - SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session, - NULL, session->session_url.path, - end, NULL, pool)); - req_url = svn_path_url_add_component2(basecoll_url, relative_url, pool); - handler = apr_pcalloc(pool, sizeof(*handler)); + SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */, + session, NULL /* conn */, + NULL /* url */, end, + pool, pool)); + + xmlctx = svn_ra_serf__xml_context_create(blame_ttable, + blame_opened, + blame_closed, + blame_cdata, + blame_ctx, + pool); + handler = svn_ra_serf__create_expat_handler(xmlctx, pool); handler->method = "REPORT"; handler->path = req_url; @@ -456,27 +364,12 @@ svn_ra_serf__get_file_revs(svn_ra_sessio handler->conn = session->conns[0]; handler->session = session; - parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx)); - - parser_ctx->pool = pool; - parser_ctx->user_data = blame_ctx; - parser_ctx->start = start_blame; - parser_ctx->end = end_blame; - parser_ctx->cdata = cdata_blame; - parser_ctx->done = &blame_ctx->done; - parser_ctx->status_code = &status_code; - - handler->response_handler = svn_ra_serf__handle_xml_parser; - handler->response_baton = parser_ctx; - - svn_ra_serf__request_create(handler); - - err = svn_ra_serf__context_run_wait(&blame_ctx->done, session, pool); + err = svn_ra_serf__context_run_one(handler, pool); err = svn_error_compose_create( - svn_ra_serf__error_on_status(status_code, + svn_ra_serf__error_on_status(handler->sline.code, handler->path, - parser_ctx->location), + handler->location), err); return svn_error_trace(err);