diff options
Diffstat (limited to 'subversion/include/private')
35 files changed, 2820 insertions, 627 deletions
diff --git a/subversion/include/private/svn_atomic.h b/subversion/include/private/svn_atomic.h index 187703b..6a6b2dc 100644 --- a/subversion/include/private/svn_atomic.h +++ b/subversion/include/private/svn_atomic.h @@ -46,39 +46,19 @@ extern "C" { */ /** The type used by all the other atomic operations. */ -#if APR_VERSION_AT_LEAST(1, 0, 0) #define svn_atomic_t apr_uint32_t -#else -#define svn_atomic_t apr_atomic_t -#endif /** Atomically read an #svn_atomic_t from memory. */ -#if APR_VERSION_AT_LEAST(1, 0, 0) #define svn_atomic_read(mem) apr_atomic_read32((mem)) -#else -#define svn_atomic_read(mem) apr_atomic_read((mem)) -#endif /** Atomically set an #svn_atomic_t in memory. */ -#if APR_VERSION_AT_LEAST(1, 0, 0) #define svn_atomic_set(mem, val) apr_atomic_set32((mem), (val)) -#else -#define svn_atomic_set(mem, val) apr_atomic_set((mem), (val)) -#endif /** Atomically increment an #svn_atomic_t. */ -#if APR_VERSION_AT_LEAST(1, 0, 0) #define svn_atomic_inc(mem) apr_atomic_inc32(mem) -#else -#define svn_atomic_inc(mem) apr_atomic_inc(mem) -#endif /** Atomically decrement an #svn_atomic_t. */ -#if APR_VERSION_AT_LEAST(1, 0, 0) #define svn_atomic_dec(mem) apr_atomic_dec32(mem) -#else -#define svn_atomic_dec(mem) apr_atomic_dec(mem) -#endif /** * Atomic compare-and-swap. @@ -91,13 +71,8 @@ extern "C" { * that on some platforms, the CAS function is implemented in a * way that is incompatible with the other atomic operations. */ -#if APR_VERSION_AT_LEAST(1, 0, 0) #define svn_atomic_cas(mem, with, cmp) \ apr_atomic_cas32((mem), (with), (cmp)) -#else -#define svn_atomic_cas(mem, with, cmp) \ - apr_atomic_cas((mem), (with), (cmp)) -#endif /** @} */ /** diff --git a/subversion/include/private/svn_auth_private.h b/subversion/include/private/svn_auth_private.h index 6c32688..89146b9 100644 --- a/subversion/include/private/svn_auth_private.h +++ b/subversion/include/private/svn_auth_private.h @@ -231,6 +231,16 @@ svn_auth__ssl_client_cert_pw_set(svn_boolean_t *done, svn_boolean_t non_interactive, apr_pool_t *pool); +/* Apply the specified configuration for connecting with SERVER_NAME + to the auth baton */ +svn_error_t * +svn_auth__make_session_auth(svn_auth_baton_t **session_auth_baton, + const svn_auth_baton_t *auth_baton, + apr_hash_t *config, + const char *server_name, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + #if (defined(WIN32) && !defined(__MINGW32__)) || defined(DOXYGEN) /** * Set @a *provider to an authentication provider that implements diff --git a/subversion/include/private/svn_cache.h b/subversion/include/private/svn_cache.h index 08d2f09..166295d 100644 --- a/subversion/include/private/svn_cache.h +++ b/subversion/include/private/svn_cache.h @@ -173,6 +173,12 @@ typedef struct svn_cache__info_t * May be 0 if that information is not available. */ apr_uint64_t total_entries; + + /** Number of index buckets with the given number of entries. + * Bucket sizes larger than the array will saturate into the + * highest array index. + */ + apr_uint64_t histogram[32]; } svn_cache__info_t; /** @@ -251,7 +257,8 @@ svn_cache__create_memcache(svn_cache__t **cache_p, * Given @a config, returns an APR memcached interface in @a * *memcache_p allocated in @a result_pool if @a config contains entries in * the SVN_CACHE_CONFIG_CATEGORY_MEMCACHED_SERVERS section describing - * memcached servers; otherwise, sets @a *memcache_p to NULL. + * memcached servers; otherwise, sets @a *memcache_p to NULL. Use + * @a scratch_pool for temporary allocations. * * If Subversion was not built with apr_memcache_support, then raises * SVN_ERR_NO_APR_MEMCACHE if and only if @a config is configured to @@ -260,7 +267,8 @@ svn_cache__create_memcache(svn_cache__t **cache_p, svn_error_t * svn_cache__make_memcache_from_config(svn_memcache_t **memcache_p, svn_config_t *config, - apr_pool_t *result_pool); + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); /** * Creates a new membuffer cache object in @a *cache. It will contain @@ -303,6 +311,33 @@ svn_cache__membuffer_cache_create(svn_membuffer_t **cache, apr_pool_t *result_pool); /** + * @defgroup Standard priority classes for #svn_cache__create_membuffer_cache. + * @{ + */ + +/** + * Data in this priority class should not be removed from the cache unless + * absolutely necessary. Use of this should be very restricted. + */ +#define SVN_CACHE__MEMBUFFER_HIGH_PRIORITY 10000 + +/** + * Data in this priority class has a good chance to remain in cache unless + * there is more data in this class than the cache's capacity. Use of this + * as the default for all information that is costly to fetch from disk. + */ +#define SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY 1000 + +/** + * Data in this priority class will be removed as soon as the cache starts + * filling up. Use of this for ephemeral data that can easily be acquired + * again from other sources. + */ +#define SVN_CACHE__MEMBUFFER_LOW_PRIORITY 100 + +/** @} */ + +/** * Creates a new cache in @a *cache_p, storing the data in a potentially * shared @a membuffer object. The elements in the cache will be indexed * by keys of length @a klen, which may be APR_HASH_KEY_STRING if they @@ -310,7 +345,10 @@ svn_cache__membuffer_cache_create(svn_membuffer_t **cache, * serialize_func and deserialized using @a deserialize_func. Because * the same memcache object may cache many different kinds of values * form multiple caches, @a prefix should be specified to differentiate - * this cache from other caches. @a *cache_p will be allocated in @a result_pool. + * this cache from other caches. All entries written through this cache + * interface will be assigned into the given @a priority class. @a *cache_p + * will be allocated in @a result_pool. @a scratch_pool is used for + * temporary allocations. * * If @a deserialize_func is NULL, then the data is returned as an * svn_stringbuf_t; if @a serialize_func is NULL, then the data is @@ -329,8 +367,10 @@ svn_cache__create_membuffer_cache(svn_cache__t **cache_p, svn_cache__deserialize_func_t deserialize, apr_ssize_t klen, const char *prefix, + apr_uint32_t priority, svn_boolean_t thread_safe, - apr_pool_t *result_pool); + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); /** * Sets @a handler to be @a cache's error handling routine. If any @@ -375,6 +415,18 @@ svn_cache__get(void **value, apr_pool_t *result_pool); /** + * Looks for an entry indexed by @a key in @a cache, setting @a *found + * to TRUE if an entry has been found and FALSE otherwise. @a key may be + * NULL in which case @a *found will be FALSE. Temporary allocations will + * be made from @a scratch_pool. + */ +svn_error_t * +svn_cache__has_key(svn_boolean_t *found, + svn_cache__t *cache, + const void *key, + apr_pool_t *scratch_pool); + +/** * Stores the value @a value under the key @a key in @a cache. Uses @a * scratch_pool for temporary allocations. The cache makes copies of * @a key and @a value if necessary (that is, @a key and @a value may @@ -465,13 +517,16 @@ svn_cache__get_info(svn_cache__t *cache, /** * Return the information given in @a info formatted as a multi-line string. - * Allocations take place in @a result_pool. + * If @a access_only has been set, size and fill-level statistics will be + * omitted. Allocations take place in @a result_pool. */ svn_string_t * svn_cache__format_info(const svn_cache__info_t *info, + svn_boolean_t access_only, apr_pool_t *result_pool); -/* Access the process-global (singleton) membuffer cache. The first call +/** + * Access the process-global (singleton) membuffer cache. The first call * will automatically allocate the cache using the current cache config. * NULL will be returned if the desired cache size is 0. * @@ -480,6 +535,22 @@ svn_cache__format_info(const svn_cache__info_t *info, struct svn_membuffer_t * svn_cache__get_global_membuffer_cache(void); +/** + * Return total access and size stats over all membuffer caches as they + * share the underlying data buffer. The result will be allocated in POOL. + */ +svn_cache__info_t * +svn_cache__membuffer_get_global_info(apr_pool_t *pool); + +/** + * Remove all current contents from CACHE. + * + * NOTE: In a multi-threaded environment, new contents may have been put + * into the cache by the time this function returns. + */ +svn_error_t * +svn_cache__membuffer_clear(svn_membuffer_t *cache); + /** @} */ diff --git a/subversion/include/private/svn_client_mtcc.h b/subversion/include/private/svn_client_mtcc.h new file mode 100644 index 0000000..fe670b0 --- /dev/null +++ b/subversion/include/private/svn_client_mtcc.h @@ -0,0 +1,226 @@ +/** + * @copyright + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * @endcopyright + * + * @file svn_client_mtcc.h + * @brief Subversion multicommand client support + * + * Requires: The working copy library and client library. + * Provides: High level multicommand api. + * Used By: Client programs, svnmucc. + */ + +#ifndef SVN_CLIENT_MTCC_H +#define SVN_CLIENT_MTCC_H + +#include "svn_client.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + * + * @defgroup clnt_mtcc Multi Command Context related functions + * + * @{ + * + */ + +/** This is a structure which stores a list of repository commands + * that can be played to a repository as a single operation + * + * Use svn_client__mtcc_create() to create instances + * + * @since New in 1.9. + */ +typedef struct svn_client__mtcc_t svn_client__mtcc_t; + +/** Creates a new multicommand context for an operation on @a anchor_url and + * its descendants. + * + * Allocate the context in @a result_pool and perform temporary allocations in + * @a scratch_pool. + * + * @since New in 1.9. + */ +svn_error_t * +svn_client__mtcc_create(svn_client__mtcc_t **mtcc, + const char *anchor_url, + svn_revnum_t base_revision, + svn_client_ctx_t *ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** Adds a file add operation of @a relpath to @a mtcc. If @a src_checksum + * is not null it will be provided to the repository to verify if the file + * was transferred successfully. + * + * Perform temporary allocations in @a scratch_pool. + * + * @note The current implementation keeps @a src_stream open until @a mtcc + * is committed. + * + * @since New in 1.9. + */ +svn_error_t * +svn_client__mtcc_add_add_file(const char *relpath, + svn_stream_t *src_stream, + const svn_checksum_t *src_checksum, + svn_client__mtcc_t *mtcc, + apr_pool_t *scratch_pool); + +/** Adds a copy operation of the node @a src_relpath at revision @a revision + * to @a dst_relpath to @a mtcc. + * + * Perform temporary allocations in @a scratch_pool. + * + * @since New in 1.9. + */ +svn_error_t * +svn_client__mtcc_add_copy(const char *src_relpath, + svn_revnum_t revision, + const char *dst_relpath, + svn_client__mtcc_t *mtcc, + apr_pool_t *scratch_pool); + +/** Adds a delete of @a relpath to @a mtcc. + * + * Perform temporary allocations in @a scratch_pool. + * + * @since New in 1.9. + */ +svn_error_t * +svn_client__mtcc_add_delete(const char *relpath, + svn_client__mtcc_t *mtcc, + apr_pool_t *scratch_pool); + +/** Adds an mkdir operation of @a relpath to @a mtcc. + * + * Perform temporary allocations in @a scratch_pool. + * + * @since New in 1.9. + */ +svn_error_t * +svn_client__mtcc_add_mkdir(const char *relpath, + svn_client__mtcc_t *mtcc, + apr_pool_t *scratch_pool); + + +/** Adds a move operation of the node @a src_relpath to @a dst_relpath to + * @a mtcc. + * + * Perform temporary allocations in @a scratch_pool. + * + * @since New in 1.9. + */ +svn_error_t * +svn_client__mtcc_add_move(const char *src_relpath, + const char *dst_relpath, + svn_client__mtcc_t *mtcc, + apr_pool_t *scratch_pool); + +/** Adds a propset operation for the property @a propname to @a propval + * (which can be NULL for a delete) on @a relpath to @a mtcc. + * + * If @a skip_checks is not FALSE Subversion defined properties are verified + * for correctness like svn_client_propset_remote() + * + * Perform temporary allocations in @a scratch_pool. + * + * @since New in 1.9. + */ +svn_error_t * +svn_client__mtcc_add_propset(const char *relpath, + const char *propname, + const svn_string_t *propval, + svn_boolean_t skip_checks, + svn_client__mtcc_t *mtcc, + apr_pool_t *scratch_pool); + + +/** Adds an update file operation for @a relpath to @a mtcc. + * + * The final version of the file is provided with @a src_stream. If @a + * src_checksum is provided it will be provided to the repository to verify + * the final result. + * + * If @a base_checksum is provided it will be used by the repository to verify + * if the base file matches this checksum. + * + * If @a base_stream is not NULL only the binary diff from @a base_stream to + * @a src_stream is written to the repository. + * + * Perform temporary allocations in @a scratch_pool. + * + * @note Callers should assume that the mtcc requires @a src_stream and @a + * base_stream to be valid until @a mtcc is committed. + * + * @since New in 1.9. + */ +svn_error_t * +svn_client__mtcc_add_update_file(const char *relpath, + svn_stream_t *src_stream, + const svn_checksum_t *src_checksum, + svn_stream_t *base_stream, + const svn_checksum_t *base_checksum, + svn_client__mtcc_t *mtcc, + apr_pool_t *scratch_pool); + +/** Obtains the kind of node at @a relpath in the current state of @a mtcc. + * This value might be from the cache (in case of modifications, copies) + * or fetched from the repository. + * + * If @a check_repository is TRUE, verify the node type with the repository at + * least once and cache the result for further checks. + * + * When a node does not exist this functions sets @a *kind to @c svn_node_node. + * + * @since New in 1.9. + */ +svn_error_t * +svn_client__mtcc_check_path(svn_node_kind_t *kind, + const char *relpath, + svn_boolean_t check_repository, + svn_client__mtcc_t *mtcc, + apr_pool_t *scratch_pool); + +/** Commits all operations stored in @a mtcc as a new revision and destroys + * @a mtcc. + * + * @since New in 1.9. + */ +svn_error_t * +svn_client__mtcc_commit(apr_hash_t *revprop_table, + svn_commit_callback2_t commit_callback, + void *commit_baton, + svn_client__mtcc_t *mtcc, + apr_pool_t *scratch_pool); + + +/** @} end group: Multi Command Context related functions */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_CLIENT_MTCC_H */ diff --git a/subversion/include/private/svn_client_private.h b/subversion/include/private/svn_client_private.h index 91ea647..892fc4b 100644 --- a/subversion/include/private/svn_client_private.h +++ b/subversion/include/private/svn_client_private.h @@ -33,11 +33,58 @@ #include "svn_client.h" #include "svn_types.h" +#include "private/svn_diff_tree.h" + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +/* Set *REVNUM to the revision number identified by REVISION. + + If REVISION->kind is svn_opt_revision_number, just use + REVISION->value.number, ignoring LOCAL_ABSPATH and RA_SESSION. + + Else if REVISION->kind is svn_opt_revision_committed, + svn_opt_revision_previous, or svn_opt_revision_base, or + svn_opt_revision_working, then the revision can be identified + purely based on the working copy's administrative information for + LOCAL_ABSPATH, so RA_SESSION is ignored. If LOCAL_ABSPATH is not + under revision control, return SVN_ERR_UNVERSIONED_RESOURCE, or if + LOCAL_ABSPATH is null, return SVN_ERR_CLIENT_VERSIONED_PATH_REQUIRED. + + Else if REVISION->kind is svn_opt_revision_date or + svn_opt_revision_head, then RA_SESSION is used to retrieve the + revision from the repository (using REVISION->value.date in the + former case), and LOCAL_ABSPATH is ignored. If RA_SESSION is null, + return SVN_ERR_CLIENT_RA_ACCESS_REQUIRED. + + Else if REVISION->kind is svn_opt_revision_unspecified, set + *REVNUM to SVN_INVALID_REVNUM. + + If YOUNGEST_REV is non-NULL, it is an in/out parameter. If + *YOUNGEST_REV is valid, use it as the youngest revision in the + repository (regardless of reality) -- don't bother to lookup the + true value for HEAD, and don't return any value in *REVNUM greater + than *YOUNGEST_REV. If *YOUNGEST_REV is not valid, and a HEAD + lookup is required to populate *REVNUM, then also populate + *YOUNGEST_REV with the result. This is useful for making multiple + serialized calls to this function with a basically static view of + the repository, avoiding race conditions which could occur between + multiple invocations with HEAD lookup requests. + + Else return SVN_ERR_CLIENT_BAD_REVISION. + + Use SCRATCH_POOL for any temporary allocation. */ +svn_error_t * +svn_client__get_revision_number(svn_revnum_t *revnum, + svn_revnum_t *youngest_rev, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_ra_session_t *ra_session, + const svn_opt_revision_t *revision, + apr_pool_t *scratch_pool); + /* Return true if KIND is a revision kind that is dependent on the working * copy. Otherwise, return false. */ #define SVN_CLIENT__REVKIND_NEEDS_WC(kind) \ @@ -200,29 +247,6 @@ svn_client__create_status(svn_client_status_t **cst, apr_pool_t *result_pool, apr_pool_t *scratch_pool); -/* Set *ANCESTOR_URL and *ANCESTOR_REVISION to the URL and revision, - * respectively, of the youngest common ancestor of the two locations - * PATH_OR_URL1@REV1 and PATH_OR_URL2@REV2. Set *ANCESTOR_RELPATH to - * NULL and *ANCESTOR_REVISION to SVN_INVALID_REVNUM if they have no - * common ancestor. This function assumes that PATH_OR_URL1@REV1 and - * PATH_OR_URL2@REV2 both refer to the same repository. - * - * Use the authentication baton cached in CTX to authenticate against - * the repository. - * - * See also svn_client__get_youngest_common_ancestor(). - */ -svn_error_t * -svn_client__youngest_common_ancestor(const char **ancestor_url, - svn_revnum_t *ancestor_rev, - const char *path_or_url1, - const svn_opt_revision_t *revision1, - const char *path_or_url2, - const svn_opt_revision_t *revision2, - svn_client_ctx_t *ctx, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool); - /* Get the repository location of the base node at LOCAL_ABSPATH. * * A pathrev_t wrapper around svn_wc__node_get_base(). @@ -257,20 +281,6 @@ svn_client__wc_node_get_origin(svn_client__pathrev_t **origin_p, apr_pool_t *result_pool, apr_pool_t *scratch_pool); -/* Produce a diff with depth DEPTH between two files or two directories at - * LOCAL_ABSPATH1 and LOCAL_ABSPATH2, using the provided diff callbacks to - * show changes in files. The files and directories involved may be part of - * a working copy or they may be unversioned. For versioned files, show - * property changes, too. */ -svn_error_t * -svn_client__arbitrary_nodes_diff(const char *local_abspath1, - const char *local_abspath2, - svn_depth_t depth, - const svn_wc_diff_callbacks4_t *callbacks, - void *callback_baton, - svn_client_ctx_t *ctx, - apr_pool_t *scratch_pool); - /* Copy the file or directory on URL in some repository to DST_ABSPATH, * copying node information and properties. Resolve URL using PEG_REV and * REVISION. diff --git a/subversion/include/private/svn_cmdline_private.h b/subversion/include/private/svn_cmdline_private.h index ad16b66..f21a5d2 100644 --- a/subversion/include/private/svn_cmdline_private.h +++ b/subversion/include/private/svn_cmdline_private.h @@ -88,11 +88,15 @@ typedef struct svn_cmdline__config_argument_t * containing svn_cmdline__config_argument_t* elements, allocating the option * data in @a pool * + * [Since 1.9/1.10:] If the file, section, or option value is not recognized, + * warn to @c stderr, using @a prefix as in svn_handle_warning2(). + * * @since New in 1.7. */ svn_error_t * svn_cmdline__parse_config_option(apr_array_header_t *config_options, const char *opt_arg, + const char *prefix, apr_pool_t *pool); /** Sets the config options in @a config_options, an apr array containing @@ -220,6 +224,20 @@ svn_boolean_t svn_cmdline__be_interactive(svn_boolean_t non_interactive, svn_boolean_t force_interactive); +/* Parses the argument value of '--trust-server-cert-failures' OPT_ARG into + * the expected booleans for passing to svn_cmdline_create_auth_baton2() + * + * @since New in 1.9. + */ +svn_error_t * +svn_cmdline__parse_trust_options( + svn_boolean_t *trust_server_cert_unknown_ca, + svn_boolean_t *trust_server_cert_cn_mismatch, + svn_boolean_t *trust_server_cert_expired, + svn_boolean_t *trust_server_cert_not_yet_valid, + svn_boolean_t *trust_server_cert_other_failure, + const char *opt_arg, + apr_pool_t *scratch_pool); #ifdef __cplusplus } diff --git a/subversion/include/private/svn_delta_private.h b/subversion/include/private/svn_delta_private.h index 4de85a9..260327c 100644 --- a/subversion/include/private/svn_delta_private.h +++ b/subversion/include/private/svn_delta_private.h @@ -101,25 +101,12 @@ svn_delta__delta_from_editor(const svn_delta_editor_t **deditor, struct svn_delta__extra_baton *exb, apr_pool_t *pool); -/** - * Get the data from IN, compress it according to the specified - * COMPRESSION_LEVEL and write the result to OUT. - * SVN_DELTA_COMPRESSION_LEVEL_NONE is valid for COMPRESSION_LEVEL. - */ +/** Read the txdelta window header from @a stream and return the total + length of the unparsed window data in @a *window_len. */ svn_error_t * -svn__compress(svn_string_t *in, - svn_stringbuf_t *out, - int compression_level); - -/** - * Get the compressed data from IN, decompress it and write the result to - * OUT. Return an error if the decompressed size is larger than LIMIT. - */ -svn_error_t * -svn__decompress(svn_string_t *in, - svn_stringbuf_t *out, - apr_size_t limit); - +svn_txdelta__read_raw_window_len(apr_size_t *window_len, + svn_stream_t *stream, + apr_pool_t *pool); #ifdef __cplusplus } diff --git a/subversion/include/private/svn_dep_compat.h b/subversion/include/private/svn_dep_compat.h index 108b67c..729cf7e 100644 --- a/subversion/include/private/svn_dep_compat.h +++ b/subversion/include/private/svn_dep_compat.h @@ -20,7 +20,7 @@ * ==================================================================== * @endcopyright * - * @file svn_compat.h + * @file svn_dep_compat.h * @brief Compatibility macros and functions. * @since New in 1.5.0. */ @@ -35,71 +35,30 @@ extern "C" { #endif /* __cplusplus */ /** - * Check at compile time if the APR version is at least a certain - * level. - * @param major The major version component of the version checked - * for (e.g., the "1" of "1.3.0"). - * @param minor The minor version component of the version checked - * for (e.g., the "3" of "1.3.0"). - * @param patch The patch level component of the version checked - * for (e.g., the "0" of "1.3.0"). + * We assume that 'int' and 'unsigned' are at least 32 bits wide. + * This also implies that long (rev numbers) is 32 bits or wider. * - * @since New in 1.5. - */ -#ifndef APR_VERSION_AT_LEAST /* Introduced in APR 1.3.0 */ -#define APR_VERSION_AT_LEAST(major,minor,patch) \ -(((major) < APR_MAJOR_VERSION) \ - || ((major) == APR_MAJOR_VERSION && (minor) < APR_MINOR_VERSION) \ - || ((major) == APR_MAJOR_VERSION && (minor) == APR_MINOR_VERSION && \ - (patch) <= APR_PATCH_VERSION)) -#endif /* APR_VERSION_AT_LEAST */ - -/** - * If we don't have a recent enough APR, emulate the behavior of the - * apr_array_clear() API. + * @since New in 1.9. */ -#if !APR_VERSION_AT_LEAST(1,3,0) -#define apr_array_clear(arr) (arr)->nelts = 0 +#if defined(APR_HAVE_LIMITS_H) \ + && !defined(SVN_ALLOW_SHORT_INTS) \ + && (INT_MAX < 0x7FFFFFFFl) +#error int is shorter than 32 bits and may break Subversion. Define SVN_ALLOW_SHORT_INTS to skip this check. #endif -#if !APR_VERSION_AT_LEAST(1,3,0) -/* Equivalent to the apr_hash_clear() function in APR >= 1.3.0. Used to - * implement the 'apr_hash_clear' macro if the version of APR that - * we build against does not provide the apr_hash_clear() function. */ -void svn_hash__clear(struct apr_hash_t *ht); - /** - * If we don't have a recent enough APR, emulate the behavior of the - * apr_hash_clear() API. + * We assume that 'char' is 8 bits wide. The critical interfaces are + * our repository formats and RA encodings. E.g. a 32 bit wide char may + * mess up UTF8 parsing, how we interpret size values etc. + * + * @since New in 1.9. */ -#define apr_hash_clear(ht) svn_hash__clear(ht) +#if defined(CHAR_BIT) \ + && !defined(SVN_ALLOW_NON_8_BIT_CHARS) \ + && (CHAR_BIT != 8) +#error char is not 8 bits and may break Subversion. Define SVN_ALLOW_NON_8_BIT_CHARS to skip this check. #endif -#if !APR_VERSION_AT_LEAST(1,0,0) -#define APR_UINT64_C(val) UINT64_C(val) -#define APR_FPROT_OS_DEFAULT APR_OS_DEFAULT -#define apr_hash_make_custom(pool,hash_func) apr_hash_make(pool) -#endif - -#if !APR_VERSION_AT_LEAST(1,3,0) -#define APR_UINT16_MAX 0xFFFFU -#define APR_INT16_MAX 0x7FFF -#define APR_INT16_MIN (-APR_INT16_MAX-1) -#define APR_UINT32_MAX 0xFFFFFFFFU -#define APR_INT32_MAX 0x7FFFFFFF -#define APR_INT32_MIN (-APR_INT32_MAX-1) -#define APR_UINT64_MAX APR_UINT64_C(0xFFFFFFFFFFFFFFFF) -#define APR_INT64_MAX APR_INT64_C(0x7FFFFFFFFFFFFFFF) -#define APR_INT64_MIN (-APR_INT64_MAX-1) -#define APR_SIZE_MAX (~(apr_size_t)0) - -#if APR_SIZEOF_VOIDP == 8 -typedef apr_uint64_t apr_uintptr_t; -#else -typedef apr_uint32_t apr_uintptr_t; -#endif -#endif /* !APR_VERSION_AT_LEAST(1,3,0) */ - /** * Work around a platform dependency issue. apr_thread_rwlock_trywrlock() * will make APR_STATUS_IS_EBUSY() return TRUE if the lock could not be @@ -115,6 +74,19 @@ typedef apr_uint32_t apr_uintptr_t; #define SVN_LOCK_IS_BUSY(x) APR_STATUS_IS_EBUSY(x) #endif +/** + * APR keeps a few interesting defines hidden away in its private + * headers apr_arch_file_io.h, so we redefined them here. + * + * @since New in 1.9 + */ +#ifndef APR_FREADONLY +#define APR_FREADONLY 0x10000000 +#endif +#ifndef APR_OPENINFO +#define APR_OPENINFO 0x00100000 +#endif + #if !APR_VERSION_AT_LEAST(1,4,0) #ifndef apr_time_from_msec #define apr_time_from_msec(msec) ((apr_time_t)(msec) * 1000) diff --git a/subversion/include/private/svn_diff_private.h b/subversion/include/private/svn_diff_private.h index bb17c17..48b4d52 100644 --- a/subversion/include/private/svn_diff_private.h +++ b/subversion/include/private/svn_diff_private.h @@ -97,6 +97,9 @@ svn_diff__unidiff_write_header(svn_stream_t *output_stream, * merged or reverse merged; otherwise (or if the mergeinfo property values * don't parse correctly) display them just like any other property. * + * Pass @a context_size, @a cancel_func and @a cancel_baton to the diff + * output functions. + * * Use @a scratch_pool for temporary allocations. */ svn_error_t * @@ -105,6 +108,9 @@ svn_diff__display_prop_diffs(svn_stream_t *outstream, const apr_array_header_t *propchanges, apr_hash_t *original_props, svn_boolean_t pretty_print_mergeinfo, + int context_size, + svn_cancel_func_t cancel_func, + void *cancel_baton, apr_pool_t *scratch_pool); diff --git a/subversion/include/private/svn_diff_tree.h b/subversion/include/private/svn_diff_tree.h index 8cd4c0e..4554da2 100644 --- a/subversion/include/private/svn_diff_tree.h +++ b/subversion/include/private/svn_diff_tree.h @@ -103,18 +103,22 @@ extern "C" { * Note that it is possible for nodes to be described as a delete followed by * an add at the same place within one parent. (Iff the diff is reversed you * can see an add followed by a delete!) + * ### "An add followed by a delete" sounds wrong. * * The directory batons live between the open and close events of a directory * and are thereby guaranteed to outlive the batons of their descendants. */ /* Describes the source of a merge */ +/* ### You mean a diff? + * ### How come many users don't set the 'repos_relpath' field? */ typedef struct svn_diff_source_t { /* Always available */ svn_revnum_t revision; /* Depending on the driver available for copyfrom */ + /* ### What? */ const char *repos_relpath; } svn_diff_source_t; @@ -137,9 +141,10 @@ typedef struct svn_diff_tree_processor_t { /** The value passed to svn_diff__tree_processor_create() as BATON. */ - void *baton; /* To avoid an additional in some places */ + void *baton; /* To avoid an additional in some places + * ### What? */ - /* Called before a directories children are processed. + /* Called before a directory's children are processed. * * Set *SKIP_CHILDREN to TRUE, to skip calling callbacks for all * children. @@ -319,7 +324,7 @@ svn_diff__tree_processor_filter_create(const svn_diff_tree_processor_t *processo apr_pool_t *result_pool); /** - * Create a new svn_diff_tree_processor_t instace with all function setup + * Create a new svn_diff_tree_processor_t instance with all function setup * to call into processor with all adds with copyfrom information transformed * to simple node changes. * diff --git a/subversion/include/private/svn_editor.h b/subversion/include/private/svn_editor.h index d714bb1..aa8a2ac 100644 --- a/subversion/include/private/svn_editor.h +++ b/subversion/include/private/svn_editor.h @@ -270,7 +270,6 @@ svn_delta_shim_callbacks_default(apr_pool_t *result_pool); * svn_editor_setcb_delete() \n * svn_editor_setcb_copy() \n * svn_editor_setcb_move() \n - * svn_editor_setcb_rotate() \n * svn_editor_setcb_complete() \n * svn_editor_setcb_abort() * @@ -293,7 +292,6 @@ svn_delta_shim_callbacks_default(apr_pool_t *result_pool); * svn_editor_delete() \n * svn_editor_copy() \n * svn_editor_move() \n - * svn_editor_rotate() * \n\n * Just before each callback invocation is carried out, the @a cancel_func * that was passed to svn_editor_create() is invoked to poll any @@ -325,7 +323,7 @@ svn_delta_shim_callbacks_default(apr_pool_t *result_pool); * In order to reduce complexity of callback receivers, the editor callbacks * must be driven in adherence to these rules: * - * - If any path is added (with add_*) or deleted/moved/rotated, then + * - If any path is added (with add_*) or deleted/moved, then * an svn_editor_alter_directory() call must be made for its parent * directory with the target/eventual set of children. * @@ -344,15 +342,13 @@ svn_delta_shim_callbacks_default(apr_pool_t *result_pool); * its children, if a directory) may be copied many times, and are * otherwise subject to the Once Rule. The destination path of a copy * or move may have alter_* operations applied, but not add_* or delete. - * If the destination path of a copy, move, or rotate is a directory, + * If the destination path of a copy or move is a directory, * then its children are subject to the Once Rule. The source path of * a move (and its child paths) may be referenced in add_*, or as the * destination of a copy (where these new or copied nodes are subject - * to the Once Rule). Paths listed in a rotation are both sources and - * destinations, so they may not be referenced again in an add_* or a - * deletion; these paths may have alter_* operations applied. + * to the Once Rule). * - * - The ancestor of an added, copied-here, moved-here, rotated, or + * - The ancestor of an added, copied-here, moved-here, or * modified node may not be deleted. The ancestor may not be moved * (instead: perform the move, *then* the edits). * @@ -375,10 +371,6 @@ svn_delta_shim_callbacks_default(apr_pool_t *result_pool); * by a delete... that is fine. It is simply that svn_editor_move() * should be used to describe a semantic move. * - * - Paths mentioned in svn_editor_rotate() may have their properties - * and contents edited (via alter_* calls) by a previous or later call, - * but they may not be subject to a later move, rotate, or deletion. - * * - One of svn_editor_complete() or svn_editor_abort() must be called * exactly once, which must be the final call the driver invokes. * Invoking svn_editor_complete() must imply that the set of changes has @@ -573,9 +565,9 @@ typedef svn_error_t *(*svn_editor_cb_alter_file_t)( void *baton, const char *relpath, svn_revnum_t revision, - apr_hash_t *props, const svn_checksum_t *checksum, svn_stream_t *contents, + apr_hash_t *props, apr_pool_t *scratch_pool); /** @see svn_editor_alter_symlink(), svn_editor_t. @@ -585,8 +577,8 @@ typedef svn_error_t *(*svn_editor_cb_alter_symlink_t)( void *baton, const char *relpath, svn_revnum_t revision, - apr_hash_t *props, const char *target, + apr_hash_t *props, apr_pool_t *scratch_pool); /** @see svn_editor_delete(), svn_editor_t. @@ -620,15 +612,6 @@ typedef svn_error_t *(*svn_editor_cb_move_t)( svn_revnum_t replaces_rev, apr_pool_t *scratch_pool); -/** @see svn_editor_rotate(), svn_editor_t. - * @since New in 1.8. - */ -typedef svn_error_t *(*svn_editor_cb_rotate_t)( - void *baton, - const apr_array_header_t *relpaths, - const apr_array_header_t *revisions, - apr_pool_t *scratch_pool); - /** @see svn_editor_complete(), svn_editor_t. * @since New in 1.8. */ @@ -790,17 +773,6 @@ svn_editor_setcb_move(svn_editor_t *editor, svn_editor_cb_move_t callback, apr_pool_t *scratch_pool); -/** Sets the #svn_editor_cb_rotate_t callback in @a editor - * to @a callback. - * @a scratch_pool is used for temporary allocations (if any). - * @see also svn_editor_setcb_many(). - * @since New in 1.8. - */ -svn_error_t * -svn_editor_setcb_rotate(svn_editor_t *editor, - svn_editor_cb_rotate_t callback, - apr_pool_t *scratch_pool); - /** Sets the #svn_editor_cb_complete_t callback in @a editor * to @a callback. * @a scratch_pool is used for temporary allocations (if any). @@ -841,7 +813,6 @@ typedef struct svn_editor_cb_many_t svn_editor_cb_delete_t cb_delete; svn_editor_cb_copy_t cb_copy; svn_editor_cb_move_t cb_move; - svn_editor_cb_rotate_t cb_rotate; svn_editor_cb_complete_t cb_complete; svn_editor_cb_abort_t cb_abort; @@ -1020,9 +991,9 @@ svn_error_t * svn_editor_alter_file(svn_editor_t *editor, const char *relpath, svn_revnum_t revision, - apr_hash_t *props, const svn_checksum_t *checksum, - svn_stream_t *contents); + svn_stream_t *contents, + apr_hash_t *props); /** Drive @a editor's #svn_editor_cb_alter_symlink_t callback. * @@ -1047,8 +1018,8 @@ svn_error_t * svn_editor_alter_symlink(svn_editor_t *editor, const char *relpath, svn_revnum_t revision, - apr_hash_t *props, - const char *target); + const char *target, + apr_hash_t *props); /** Drive @a editor's #svn_editor_cb_delete_t callback. * @@ -1093,7 +1064,7 @@ svn_editor_copy(svn_editor_t *editor, * expect to find this node. That is, @a src_relpath at the start of * the whole edit and @a src_relpath at @a src_revision must lie within * the same node-rev (aka history-segment). This is just like the - * revisions specified to svn_editor_delete() and svn_editor_rotate(). + * revisions specified to svn_editor_delete(). * * For a description of @a replaces_rev, see svn_editor_add_file(). * @@ -1110,36 +1081,6 @@ svn_editor_move(svn_editor_t *editor, const char *dst_relpath, svn_revnum_t replaces_rev); -/** Drive @a editor's #svn_editor_cb_rotate_t callback. - * - * Perform a rotation among multiple nodes in the target tree. - * - * The @a relpaths and @a revisions arrays (pair-wise) specify nodes in the - * tree which are located at a path and expected to be at a specific - * revision. These nodes are simultaneously moved in a rotation pattern. - * For example, the node at index 0 of @a relpaths and @a revisions will - * be moved to the relpath specified at index 1 of @a relpaths. The node - * at index 1 will be moved to the location at index 2. The node at index - * N-1 will be moved to the relpath specified at index 0. - * - * The simplest form of this operation is to swap nodes A and B. One may - * think to move A to a temporary location T, then move B to A, then move - * T to B. However, this last move violations the Once Rule by moving T - * (which had already by edited by the move from A). In order to keep the - * restrictions against multiple moves of a single node, the rotation - * operation is needed for certain types of tree edits. - * - * ### what happens if one of the paths of the rotation is not "within" the - * ### receiver's set of paths? - * - * For all restrictions on driving the editor, see #svn_editor_t. - * @since New in 1.8. - */ -svn_error_t * -svn_editor_rotate(svn_editor_t *editor, - const apr_array_header_t *relpaths, - const apr_array_header_t *revisions); - /** Drive @a editor's #svn_editor_cb_complete_t callback. * * Send word that the edit has been completed successfully. diff --git a/subversion/include/private/svn_error_private.h b/subversion/include/private/svn_error_private.h index f8bd2bc..2d35bc6 100644 --- a/subversion/include/private/svn_error_private.h +++ b/subversion/include/private/svn_error_private.h @@ -37,7 +37,7 @@ extern "C" { * Returns if @a err is a "tracing" error. */ svn_boolean_t -svn_error__is_tracing_link(svn_error_t *err); +svn_error__is_tracing_link(const svn_error_t *err); /** * Converts a zlib error to an svn_error_t. zerr is the error code, diff --git a/subversion/include/private/svn_fs_fs_private.h b/subversion/include/private/svn_fs_fs_private.h new file mode 100644 index 0000000..59aede1 --- /dev/null +++ b/subversion/include/private/svn_fs_fs_private.h @@ -0,0 +1,355 @@ +/** + * @copyright + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * @endcopyright + * + * @file svn_fs_fs_private.h + * @brief Private API for tools that access FSFS internals and can't use + * the svn_fs_t API for that. + */ + + +#ifndef SVN_FS_FS_PRIVATE_H +#define SVN_FS_FS_PRIVATE_H + +#include <apr_pools.h> +#include <apr_hash.h> + +#include "svn_types.h" +#include "svn_error.h" +#include "svn_fs.h" +#include "svn_iter.h" +#include "svn_config.h" +#include "svn_string.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + +/* Description of one large representation. It's content will be reused / + * overwritten when it gets replaced by an even larger representation. + */ +typedef struct svn_fs_fs__large_change_info_t +{ + /* size of the (deltified) representation */ + apr_uint64_t size; + + /* Revision of the representation. SVN_INVALID_REVNUM for unused entries. */ + svn_revnum_t revision; + + /* node path. "" for unused instances */ + svn_stringbuf_t *path; +} svn_fs_fs__large_change_info_t; + +/* Container for the largest representations found so far. The capacity + * is fixed and entries will be inserted by reusing the last one and + * reshuffling the entry pointers. + */ +typedef struct svn_fs_fs__largest_changes_t +{ + /* number of entries allocated in CHANGES */ + apr_size_t count; + + /* size of the smallest change */ + apr_uint64_t min_size; + + /* changes kept in this struct */ + svn_fs_fs__large_change_info_t **changes; +} svn_fs_fs__largest_changes_t; + +/* Information we gather per size bracket. + */ +typedef struct svn_fs_fs__histogram_line_t +{ + /* number of item that fall into this bracket */ + apr_uint64_t count; + + /* sum of values in this bracket */ + apr_uint64_t sum; +} svn_fs_fs__histogram_line_t; + +/* A histogram of 64 bit integer values. + */ +typedef struct svn_fs_fs__histogram_t +{ + /* total sum over all brackets */ + svn_fs_fs__histogram_line_t total; + + /* one bracket per binary step. + * line[i] is the 2^(i-1) <= x < 2^i bracket */ + svn_fs_fs__histogram_line_t lines[64]; +} svn_fs_fs__histogram_t; + +/* Information we collect per file ending. + */ +typedef struct svn_fs_fs__extension_info_t +{ + /* file extension, including leading "." + * "(none)" in the container for files w/o extension. */ + const char *extension; + + /* histogram of representation sizes */ + svn_fs_fs__histogram_t rep_histogram; + + /* histogram of sizes of changed files */ + svn_fs_fs__histogram_t node_histogram; +} svn_fs_fs__extension_info_t; + +/* Compression statistics we collect over a given set of representations. + */ +typedef struct svn_fs_fs__rep_pack_stats_t +{ + /* number of representations */ + apr_uint64_t count; + + /* total size after deltification (i.e. on disk size) */ + apr_uint64_t packed_size; + + /* total size after de-deltification (i.e. plain text size) */ + apr_uint64_t expanded_size; + + /* total on-disk header size */ + apr_uint64_t overhead_size; +} svn_fs_fs__rep_pack_stats_t; + +/* Statistics we collect over a given set of representations. + * We group them into shared and non-shared ("unique") reps. + */ +typedef struct svn_fs_fs__representation_stats_t +{ + /* stats over all representations */ + svn_fs_fs__rep_pack_stats_t total; + + /* stats over those representations with ref_count == 1 */ + svn_fs_fs__rep_pack_stats_t uniques; + + /* stats over those representations with ref_count > 1 */ + svn_fs_fs__rep_pack_stats_t shared; + + /* sum of all ref_counts */ + apr_uint64_t references; + + /* sum of ref_count * expanded_size, + * i.e. total plaintext content if there was no rep sharing */ + apr_uint64_t expanded_size; +} svn_fs_fs__representation_stats_t; + +/* Basic statistics we collect over a given set of noderevs. + */ +typedef struct svn_fs_fs__node_stats_t +{ + /* number of noderev structs */ + apr_uint64_t count; + + /* their total size on disk (structs only) */ + apr_uint64_t size; +} svn_fs_fs__node_stats_t; + +/* Comprises all the information needed to create the output of the + * 'svnfsfs stats' command. + */ +typedef struct svn_fs_fs__stats_t +{ + /* sum total of all rev / pack file sizes in bytes */ + apr_uint64_t total_size; + + /* number of revisions in the repository */ + apr_uint64_t revision_count; + + /* total number of changed paths */ + apr_uint64_t change_count; + + /* sum of all changed path list sizes on disk in bytes */ + apr_uint64_t change_len; + + /* stats on all representations */ + svn_fs_fs__representation_stats_t total_rep_stats; + + /* stats on all file text representations */ + svn_fs_fs__representation_stats_t file_rep_stats; + + /* stats on all directory text representations */ + svn_fs_fs__representation_stats_t dir_rep_stats; + + /* stats on all file prop representations */ + svn_fs_fs__representation_stats_t file_prop_rep_stats; + + /* stats on all directory prop representations */ + svn_fs_fs__representation_stats_t dir_prop_rep_stats; + + /* size and count summary over all noderevs */ + svn_fs_fs__node_stats_t total_node_stats; + + /* size and count summary over all file noderevs */ + svn_fs_fs__node_stats_t file_node_stats; + + /* size and count summary over all directory noderevs */ + svn_fs_fs__node_stats_t dir_node_stats; + + /* the biggest single contributors to repo size */ + svn_fs_fs__largest_changes_t *largest_changes; + + /* histogram of representation sizes */ + svn_fs_fs__histogram_t rep_size_histogram; + + /* histogram of sizes of changed nodes */ + svn_fs_fs__histogram_t node_size_histogram; + + /* histogram of representation sizes */ + svn_fs_fs__histogram_t added_rep_size_histogram; + + /* histogram of sizes of changed nodes */ + svn_fs_fs__histogram_t added_node_size_histogram; + + /* histogram of unused representations */ + svn_fs_fs__histogram_t unused_rep_histogram; + + /* histogram of sizes of changed files */ + svn_fs_fs__histogram_t file_histogram; + + /* histogram of sizes of file representations */ + svn_fs_fs__histogram_t file_rep_histogram; + + /* histogram of sizes of changed file property sets */ + svn_fs_fs__histogram_t file_prop_histogram; + + /* histogram of sizes of file property representations */ + svn_fs_fs__histogram_t file_prop_rep_histogram; + + /* histogram of sizes of changed directories (in bytes) */ + svn_fs_fs__histogram_t dir_histogram; + + /* histogram of sizes of directories representations */ + svn_fs_fs__histogram_t dir_rep_histogram; + + /* histogram of sizes of changed directories property sets */ + svn_fs_fs__histogram_t dir_prop_histogram; + + /* histogram of sizes of directories property representations */ + svn_fs_fs__histogram_t dir_prop_rep_histogram; + + /* extension -> svn_fs_fs__extension_info_t* map */ + apr_hash_t *by_extension; +} svn_fs_fs__stats_t; + + +/* Scan all contents of the repository FS and return statistics in *STATS, + * allocated in RESULT_POOL. Report progress through PROGRESS_FUNC with + * PROGRESS_BATON, if PROGRESS_FUNC is not NULL. + * Use SCRATCH_POOL for temporary allocations. + */ +svn_error_t * +svn_fs_fs__get_stats(svn_fs_fs__stats_t **stats, + svn_fs_t *fs, + svn_fs_progress_notify_func_t progress_func, + void *progress_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Node-revision IDs in FSFS consist of 3 of sub-IDs ("parts") that consist + * of a creation REVISION number and some revision- / transaction-local + * counter value (NUMBER). Old-style ID parts use global counter values. + * + * The parts are: node_id, copy_id and txn_id for in-txn IDs as well as + * node_id, copy_id and rev_offset for in-revision IDs. This struct the + * data structure used for each of those parts. + */ +typedef struct svn_fs_fs__id_part_t +{ + /* SVN_INVALID_REVNUM for txns -> not a txn, COUNTER must be 0. + SVN_INVALID_REVNUM for others -> not assigned to a revision, yet. + 0 for others -> old-style ID or the root in rev 0. */ + svn_revnum_t revision; + + /* sub-id value relative to REVISION. Its interpretation depends on + the part itself. In rev_item, it is the index_index value, in others + it represents a unique counter value. */ + apr_uint64_t number; +} svn_fs_fs__id_part_t; + +/* (user visible) entry in the phys-to-log index. It describes a section + * of some packed / non-packed rev file as containing a specific item. + * There must be no overlapping / conflicting entries. + */ +typedef struct svn_fs_fs__p2l_entry_t +{ + /* offset of the first byte that belongs to the item */ + apr_off_t offset; + + /* length of the item in bytes */ + apr_off_t size; + + /* type of the item (see SVN_FS_FS__ITEM_TYPE_*) defines */ + apr_uint32_t type; + + /* modified FNV-1a checksum. 0 if unknown checksum */ + apr_uint32_t fnv1_checksum; + + /* item in that block */ + svn_fs_fs__id_part_t item; +} svn_fs_fs__p2l_entry_t; + + +/* Callback function type receiving a single P2L index ENTRY, a user + * provided BATON and a SCRATCH_POOL for temporary allocations. + * ENTRY's lifetime may end when the callback returns. + */ +typedef svn_error_t * +(*svn_fs_fs__dump_index_func_t)(const svn_fs_fs__p2l_entry_t *entry, + void *baton, + apr_pool_t *scratch_pool); + +/* Read the P2L index for the rev / pack file containing REVISION in FS. + * For each index entry, invoke CALLBACK_FUNC with CALLBACK_BATON. + * If not NULL, call CANCEL_FUNC with CANCEL_BATON from time to time. + * Use SCRATCH_POOL for temporary allocations. + */ +svn_error_t * +svn_fs_fs__dump_index(svn_fs_t *fs, + svn_revnum_t revision, + svn_fs_fs__dump_index_func_t callback_func, + void *callback_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool); + + +/* Rewrite the respective index information of the rev / pack file in FS + * containing REVISION and use the svn_fs_fs__p2l_entry_t * array ENTRIES + * as the new index contents. Allocate temporaries from SCRATCH_POOL. + * + * Note that this becomes a no-op if ENTRIES is empty. You may use a zero- + * sized empty entry instead. + */ +svn_error_t * +svn_fs_fs__load_index(svn_fs_t *fs, + svn_revnum_t revision, + apr_array_header_t *entries, + apr_pool_t *scratch_pool); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_FS_FS_PRIVATE_H */ diff --git a/subversion/include/private/svn_fs_private.h b/subversion/include/private/svn_fs_private.h index 20b70cd..5bd89c0 100644 --- a/subversion/include/private/svn_fs_private.h +++ b/subversion/include/private/svn_fs_private.h @@ -179,6 +179,23 @@ svn_fs__editor_commit(svn_revnum_t *revision, apr_pool_t *scratch_pool); +/** Set @a *mergeinfo to the mergeinfo for @a path in @a root. + * + * If there is no mergeinfo, set @a *mergeinfo to NULL. + * + * See svn_fs_get_mergeinfo2() but for the meanings of @a inherit and + * @a adjust_inheritable_mergeinfo and other details. + */ +svn_error_t * +svn_fs__get_mergeinfo_for_path(svn_mergeinfo_t *mergeinfo, + svn_fs_root_t *root, + const char *path, + svn_mergeinfo_inheritance_t inherit, + svn_boolean_t adjust_inherited_mergeinfo, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + /** @} */ diff --git a/subversion/include/private/svn_fs_util.h b/subversion/include/private/svn_fs_util.h index eb0f024..c9f74a1 100644 --- a/subversion/include/private/svn_fs_util.h +++ b/subversion/include/private/svn_fs_util.h @@ -29,12 +29,17 @@ #include "svn_types.h" #include "svn_error.h" +#include "svn_version.h" #include "svn_fs.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +/* Get libsvn_fs_util version information. */ +const svn_version_t * +svn_fs_util__version(void); + /* Returns whether PATH is in canonical form as defined by svn_fs__canonicalize_abspath(). */ @@ -210,6 +215,26 @@ svn_fs__append_to_merged_froms(svn_mergeinfo_t *output, const char *rel_path, apr_pool_t *pool); +/* Given the FS creation options in CONFIG, return the oldest version that + we shall be compatible with in *COMPATIBLE_VERSION. The patch level + is always set to 0 and the tag to "". Allocate the result in POOL. + + Note that the result will always be compatible to the current tool + version, i.e. will be a version number not more recent than this tool. */ +svn_error_t * +svn_fs__compatible_version(svn_version_t **compatible_version, + apr_hash_t *config, + apr_pool_t *pool); + +/* Compare the property lists A and B using POOL for temporary allocations. + Return true iff both lists contain the same properties with the same + values. A and B may be NULL in which case they will be equal to and + empty list. */ +svn_boolean_t +svn_fs__prop_lists_equal(apr_hash_t *a, + apr_hash_t *b, + apr_pool_t *pool); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/subversion/include/private/svn_io_private.h b/subversion/include/private/svn_io_private.h index 239cd6e..814c27a 100644 --- a/subversion/include/private/svn_io_private.h +++ b/subversion/include/private/svn_io_private.h @@ -44,6 +44,15 @@ extern "C" { #define SVN__APR_FINFO_MASK_OUT (0) #endif +/* 90% of the lines we encounter will be less than this many chars. + * + * Line-based functions like svn_stream_readline should fetch data in + * blocks no longer than this. Although using a larger prefetch size is + * not illegal and must not break any functionality, it may be + * significantly less efficient in certain situations. + */ +#define SVN__LINE_CHUNK_SIZE 80 + /** Set @a *executable TRUE if @a file_info is executable for the * user, FALSE otherwise. @@ -64,6 +73,18 @@ svn_io__is_finfo_read_only(svn_boolean_t *read_only, apr_pool_t *pool); +/** + * Lock file at @a lock_file. If that file does not exist, create an empty + * file. + * + * Lock will be automatically released when @a pool is cleared or destroyed. + * Use @a pool for memory allocations. + */ +svn_error_t * +svn_io__file_lock_autocreate(const char *lock_file, + apr_pool_t *pool); + + /** Buffer test handler function for a generic stream. @see svn_stream_t * and svn_stream__is_buffered(). * @@ -81,7 +102,7 @@ svn_stream__set_is_buffered(svn_stream_t *stream, /** Return whether this generic @a stream uses internal buffering. * This may be used to work around subtle differences between buffered - * an non-buffered APR files. A lazy-open stream cannot report the + * and non-buffered APR files. A lazy-open stream cannot report the * true buffering state until after the lazy open: a stream that * initially reports as non-buffered may report as buffered later. * @@ -96,6 +117,82 @@ svn_stream__is_buffered(svn_stream_t *stream); apr_file_t * svn_stream__aprfile(svn_stream_t *stream); +/* Creates as *INSTALL_STREAM a stream that once completed can be installed + using Windows checkouts much slower than Unix. + + While writing the stream is temporarily stored in TMP_ABSPATH. + */ +svn_error_t * +svn_stream__create_for_install(svn_stream_t **install_stream, + const char *tmp_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Installs a stream created with svn_stream__create_for_install in its final + location FINAL_ABSPATH, potentially using platform specific optimizations. + + If MAKE_PARENTS is TRUE, this function will create missing parent + directories if needed. + */ +svn_error_t * +svn_stream__install_stream(svn_stream_t *install_stream, + const char *final_abspath, + svn_boolean_t make_parents, + apr_pool_t *scratch_pool); + +/* Deletes the install stream (when installing is not necessary after all) */ +svn_error_t * +svn_stream__install_delete(svn_stream_t *install_stream, + apr_pool_t *scratch_pool); + +/* Optimized apr_file_stat / apr_file_info_get operating on a closed + install stream */ +svn_error_t * +svn_stream__install_get_info(apr_finfo_t *finfo, + svn_stream_t *install_stream, + apr_int32_t wanted, + apr_pool_t *scratch_pool); + + +#if defined(WIN32) + +/* ### Move to something like io.h or subr.h, to avoid making it + part of the DLL api */ + +/* This is semantically the same as the APR utf8_to_unicode_path + function, but reimplemented here because APR does not export it. + + Note that this function creates "\\?\" paths so the resulting path + can only be used for WINAPI functions that explicitly document support + for this kind of paths. Newer Windows functions (Vista+) that support + long paths directly DON'T want this kind of escaping. + */ +svn_error_t* +svn_io__utf8_to_unicode_longpath(const WCHAR **result, + const char *source, + apr_pool_t *result_pool); + +/* This Windows-specific function marks the file to be deleted on close using + an existing file handle. It can be used to avoid having to reopen the file + as part of the delete handling. Return SVN_ERR_UNSUPPORTED_FEATURE if + delete on close operation is not supported by OS. */ +svn_error_t * +svn_io__win_delete_file_on_close(apr_file_t *file, + const char *path, + apr_pool_t *pool); + +/* This Windows-specific function renames the file using an existing file + handle. It can be used to avoid having to reopen the file as part of the + rename operation. Return SVN_ERR_UNSUPPORTED_FEATURE if renaming open + file is not supported by OS.*/ +svn_error_t * +svn_io__win_rename_open_file(apr_file_t *file, + const char *from_path, + const char *to_path, + apr_pool_t *pool); + +#endif /* WIN32 */ + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/subversion/include/private/svn_log.h b/subversion/include/private/svn_log.h index bdcf32f..1ad8d55 100644 --- a/subversion/include/private/svn_log.h +++ b/subversion/include/private/svn_log.h @@ -204,7 +204,7 @@ svn_log__get_file_revs(const char *path, svn_revnum_t start, svn_revnum_t end, * @since New in 1.6. */ const char * -svn_log__lock(const apr_array_header_t *paths, svn_boolean_t steal, +svn_log__lock(apr_hash_t *targets, svn_boolean_t steal, apr_pool_t *pool); /** @@ -213,7 +213,7 @@ svn_log__lock(const apr_array_header_t *paths, svn_boolean_t steal, * @since New in 1.6. */ const char * -svn_log__unlock(const apr_array_header_t *paths, svn_boolean_t break_lock, +svn_log__unlock(apr_hash_t *targets, svn_boolean_t break_lock, apr_pool_t *pool); /** diff --git a/subversion/include/private/svn_magic.h b/subversion/include/private/svn_magic.h index b057e56..2e5fafd 100644 --- a/subversion/include/private/svn_magic.h +++ b/subversion/include/private/svn_magic.h @@ -30,14 +30,16 @@ /* An opaque struct that wraps a libmagic cookie. */ typedef struct svn_magic__cookie_t svn_magic__cookie_t; -/* This routine initialises libmagic. +/* This routine initialises libmagic. CONFIG is a config hash and + * may be NULL. * Upon success a new *MAGIC_COOKIE is allocated in RESULT_POOL. * On failure *MAGIC_COOKIE is set to NULL. * All resources used by libmagic are freed by a cleanup handler * installed on RESULT_POOL, i.e. *MAGIC_COOKIE becomes invalid when * the pool is cleared! */ -void +svn_error_t * svn_magic__init(svn_magic__cookie_t **magic_cookie, + apr_hash_t *config, apr_pool_t *result_pool); /* Detect the mime-type of the file at LOCAL_ABSPATH using MAGIC_COOKIE. diff --git a/subversion/include/private/svn_mergeinfo_private.h b/subversion/include/private/svn_mergeinfo_private.h index b8748f4..716d0c9 100644 --- a/subversion/include/private/svn_mergeinfo_private.h +++ b/subversion/include/private/svn_mergeinfo_private.h @@ -119,13 +119,13 @@ svn_mergeinfo__equals(svn_boolean_t *is_equal, svn_boolean_t consider_inheritance, apr_pool_t *pool); -/* Examine MERGEINFO, removing all paths from the hash which map to - empty rangelists. POOL is used only to allocate the apr_hash_index_t - iterator. Returns TRUE if any paths were removed and FALSE if none were +/* Remove all paths from MERGEINFO which map to empty rangelists. + + Return TRUE if any paths were removed and FALSE if none were removed or MERGEINFO is NULL. */ svn_boolean_t svn_mergeinfo__remove_empty_rangelists(svn_mergeinfo_t mergeinfo, - apr_pool_t *pool); + apr_pool_t *scratch_pool); /* Make a shallow (ie, mergeinfos are not duped, or altered at all; keys share storage) copy of IN_CATALOG in *OUT_CATALOG, removing diff --git a/subversion/include/private/svn_mutex.h b/subversion/include/private/svn_mutex.h index c647697..c04820b 100644 --- a/subversion/include/private/svn_mutex.h +++ b/subversion/include/private/svn_mutex.h @@ -39,27 +39,23 @@ extern "C" { * This is a simple wrapper around @c apr_thread_mutex_t and will be a * valid identifier even if APR does not support threading. */ -#if APR_HAS_THREADS /** A mutex for synchronization between threads. It may be NULL, in * which case no synchronization will take place. The latter is useful * when implementing some functionality with optional synchronization. */ -typedef apr_thread_mutex_t svn_mutex__t; - -#else - -/** Dummy definition. The content will never be actually accessed. - */ -typedef void svn_mutex__t; - -#endif +typedef struct svn_mutex__t svn_mutex__t; /** Initialize the @a *mutex. If @a mutex_required is TRUE, the mutex will * actually be created with a lifetime defined by @a result_pool. Otherwise, * the pointer will be set to @c NULL and svn_mutex__lock() as well as * svn_mutex__unlock() will be no-ops. * + * We don't support recursive locks, i.e. a thread may not acquire the same + * mutex twice without releasing it in between. Attempts to lock a mutex + * recursively will cause lock ups and other undefined behavior on some + * systems. + * * If threading is not supported by APR, this function is a no-op. */ svn_error_t * diff --git a/subversion/include/private/svn_named_atomic.h b/subversion/include/private/svn_named_atomic.h deleted file mode 100644 index 4efa255..0000000 --- a/subversion/include/private/svn_named_atomic.h +++ /dev/null @@ -1,162 +0,0 @@ -/** - * @copyright - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * @endcopyright - * - * @file svn_named_atomics.h - * @brief Structures and functions for machine-wide named atomics. - * These atomics store 64 bit signed integer values and provide - * a number of basic operations on them. Instead of an address, - * these atomics are identified by strings / names. We also support - * namespaces - mainly to separate debug from production data. - */ - -#ifndef SVN_NAMED_ATOMICS_H -#define SVN_NAMED_ATOMICS_H - -#include "svn_error.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** An opaque structure that represents a namespace, i.e. a container - * for named atomics. - */ -typedef struct svn_atomic_namespace__t svn_atomic_namespace__t; - -/** An opaque structure that represents a named, system-wide visible - * 64 bit integer with atomic access routines. - */ -typedef struct svn_named_atomic__t svn_named_atomic__t; - -/** Maximum length of the name of any atomic (excluding the terminal NUL). - */ -#define SVN_NAMED_ATOMIC__MAX_NAME_LENGTH 30 - -/** Returns #FALSE when named atomics are not available to our process - * and svn_atomic_namespace__create is likely to fail. - * - * @note The actual check will be performed only once and later - * changes in process privileges will not reflect in the outcome of future - * calls to this function. - */ -svn_boolean_t -svn_named_atomic__is_supported(void); - -/** Returns #TRUE on platforms that don't need expensive synchronization - * objects to serialize access to named atomics. If this returns #FALSE, - * reading from or modifying a #svn_named_atomic__t may be as expensive - * as a file system operation. - */ -svn_boolean_t -svn_named_atomic__is_efficient(void); - -/** Create a namespace (i.e. access object) with the given @a name and - * return it in @a *ns. - * - * Multiple access objects with the same name may be created. They access - * the same shared memory region but have independent lifetimes. - * - * The access object will be allocated in @a result_pool and atomics gotten - * from this object will become invalid when the pool is being cleared. - */ -svn_error_t * -svn_atomic_namespace__create(svn_atomic_namespace__t **ns, - const char *name, - apr_pool_t *result_pool); - -/** Removes persistent data structures (files in particular) that got - * created for the namespace given by @a name. Use @a pool for temporary - * allocations. - * - * @note You must not call this while the respective namespace is still - * in use. Calling this multiple times for the same namespace is safe. - */ -svn_error_t * -svn_atomic_namespace__cleanup(const char *name, - apr_pool_t *pool); - -/** Find the atomic with the specified @a name in namespace @a ns and - * return it in @a *atomic. If no object with that name can be found, the - * behavior depends on @a auto_create. If it is @c FALSE, @a *atomic will - * be set to @c NULL. Otherwise, a new atomic will be created, its value - * set to 0 and the access structure be returned in @a *atomic. - * - * Note that @a name must not exceed #SVN_NAMED_ATOMIC__MAX_NAME_LENGTH - * characters and an error will be returned if the specified name is longer - * than supported. - * - * @note The lifetime of the atomic object is bound to the lifetime - * of the @a ns object, i.e. the pool the latter was created in. - * The data in the namespace persists as long as at least one process - * holds an #svn_atomic_namespace__t object corresponding to it. - */ -svn_error_t * -svn_named_atomic__get(svn_named_atomic__t **atomic, - svn_atomic_namespace__t *ns, - const char *name, - svn_boolean_t auto_create); - -/** Read the @a atomic and return its current @a *value. - * An error will be returned if @a atomic is @c NULL. - */ -svn_error_t * -svn_named_atomic__read(apr_int64_t *value, - svn_named_atomic__t *atomic); - -/** Set the data in @a atomic to @a new_value and return its old content - * in @a *old_value. @a old_value may be NULL. - * - * An error will be returned if @a atomic is @c NULL. - */ -svn_error_t * -svn_named_atomic__write(apr_int64_t *old_value, - apr_int64_t new_value, - svn_named_atomic__t *atomic); - -/** Add @a delta to the data in @a atomic and return its new value in - * @a *new_value. @a new_value may be null. - * - * An error will be returned if @a atomic is @c NULL. - */ -svn_error_t * -svn_named_atomic__add(apr_int64_t *new_value, - apr_int64_t delta, - svn_named_atomic__t *atomic); - -/** If the current data in @a atomic equals @a comperand, set it to - * @a new_value. Return the initial value in @a *old_value. - * @a old_value may be NULL. - * - * An error will be returned if @a atomic is @c NULL. - */ -svn_error_t * -svn_named_atomic__cmpxchg(apr_int64_t *old_value, - apr_int64_t new_value, - apr_int64_t comperand, - svn_named_atomic__t *atomic); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* SVN_NAMED_ATOMICS_H */ diff --git a/subversion/include/private/svn_object_pool.h b/subversion/include/private/svn_object_pool.h new file mode 100644 index 0000000..7a9383e --- /dev/null +++ b/subversion/include/private/svn_object_pool.h @@ -0,0 +1,154 @@ +/** + * @copyright + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * @endcopyright + * + * @file svn_object_pool.h + * @brief multithreaded object pool API + * + * This is the core data structure behind various object pools. It + * provides a thread-safe associative container for object instances of + * the same type. + * + * Memory and lifetime management for the objects are handled by the pool. + * Reference counting takes care that neither objects nor the object pool + * get actually destroyed while other parts depend on them. All objects + * are thought to be recycle-able and live in their own root memory pools + * making them (potentially) safe to be used from different threads. + * Currently unused objects may be kept around for a while and returned + * by the next lookup. + * + * Two modes are supported: shared use and exclusive use. In shared mode, + * any object can be handed out to multiple users and in potentially + * different threads at the same time. In exclusive mode, the same object + * will only be referenced at most once. + * + * Object creation and access must be provided outside this structure. + * In particular, the using container will usually wrap the actual object + * in a meta-data struct containing key information etc and must provide + * getters and setters for those wrapper structs. + */ + + + +#ifndef SVN_OBJECT_POOL_H +#define SVN_OBJECT_POOL_H + +#include <apr.h> /* for apr_int64_t */ +#include <apr_pools.h> /* for apr_pool_t */ +#include <apr_hash.h> /* for apr_hash_t */ + +#include "svn_types.h" + +#include "private/svn_mutex.h" +#include "private/svn_string_private.h" + + + +/* The opaque object container type. */ +typedef struct svn_object_pool__t svn_object_pool__t; + +/* Extract the actual object from the WRAPPER using optional information + * from BATON (provided through #svn_object_pool__lookup) and return it. + * The result will be used with POOL and must remain valid throughout + * POOL's lifetime. + * + * It is legal to return a copy, allocated in POOL, of the wrapped object. + */ +typedef void * (* svn_object_pool__getter_t)(void *wrapper, + void *baton, + apr_pool_t *pool); + +/* Copy the information from the SOURCE object wrapper into the already + * existing *TARGET object wrapper using POOL for allocations and BATON + * for optional context (provided through #svn_object_pool__insert). + */ +typedef svn_error_t * (* svn_object_pool__setter_t)(void **target, + void *source, + void *baton, + apr_pool_t *pool); + +/* Create a new object pool in POOL and return it in *OBJECT_POOL. + * Objects will be extracted using GETTER and updated using SETTER. Either + * one (or both) may be NULL and the default implementation assumes that + * wrapper == object and updating is a no-op. + * + * If THREAD_SAFE is not set, neither the object pool nor the object + * references returned from it may be accessed from multiple threads. + * + * It is not legal to call any API on the object pool after POOL got + * cleared or destroyed. However, existing object references handed out + * from the object pool remain valid and will keep the internal pool data + * structures alive for as long as such object references exist. + */ +svn_error_t * +svn_object_pool__create(svn_object_pool__t **object_pool, + svn_object_pool__getter_t getter, + svn_object_pool__setter_t setter, + svn_boolean_t thread_safe, + apr_pool_t *pool); + +/* Return the root pool containing the OBJECT_POOL and all sub-structures. + */ +apr_pool_t * +svn_object_pool__new_wrapper_pool(svn_object_pool__t *object_pool); + +/* Return the mutex used to serialize all OBJECT_POOL access. + */ +svn_mutex__t * +svn_object_pool__mutex(svn_object_pool__t *object_pool); + +/* Return the number of object instances (used or unused) in OBJECT_POOL. + */ +unsigned +svn_object_pool__count(svn_object_pool__t *object_pool); + +/* In OBJECT_POOL, look for an available object by KEY and return a + * reference to it in *OBJECT. If none can be found, *OBJECT will be NULL. + * BATON will be passed to OBJECT_POOL's getter function. The reference + * will be returned when *RESULT_POOL gets cleaned up or destroyed. + */ +svn_error_t * +svn_object_pool__lookup(void **object, + svn_object_pool__t *object_pool, + svn_membuf_t *key, + void *baton, + apr_pool_t *result_pool); + +/* Store the wrapped object WRAPPER under KEY in OBJECT_POOL and return + * a reference to the object in *OBJECT (just like lookup). + * + * The object must have been created in WRAPPER_POOL and the latter must + * be a sub-pool of OBJECT_POOL's root POOL (see #svn_object_pool__pool). + * + * BATON will be passed to OBJECT_POOL's setter and getter functions. + * The reference will be returned when *RESULT_POOL gets cleaned up or + * destroyed. + */ +svn_error_t * +svn_object_pool__insert(void **object, + svn_object_pool__t *object_pool, + const svn_membuf_t *key, + void *wrapper, + void *baton, + apr_pool_t *wrapper_pool, + apr_pool_t *result_pool); + +#endif /* SVN_OBJECT_POOL_H */ diff --git a/subversion/include/private/svn_opt_private.h b/subversion/include/private/svn_opt_private.h index 6ae67a5..89e7227 100644 --- a/subversion/include/private/svn_opt_private.h +++ b/subversion/include/private/svn_opt_private.h @@ -46,10 +46,6 @@ extern "C" { * UTF8_TARGET need not be canonical. *TRUE_TARGET will not be canonical * unless UTF8_TARGET is. * - * It is an error if *TRUE_TARGET results in the empty string after the - * split, which happens in case UTF8_TARGET has a leading '@' character - * with no additional '@' characters to escape the first '@'. - * * Note that *PEG_REVISION will still contain the '@' symbol as the first * character if a peg revision was found. If a trailing '@' symbol was * used to escape other '@' characters in UTF8_TARGET, *PEG_REVISION will diff --git a/subversion/include/private/svn_packed_data.h b/subversion/include/private/svn_packed_data.h new file mode 100644 index 0000000..6faf0dd --- /dev/null +++ b/subversion/include/private/svn_packed_data.h @@ -0,0 +1,255 @@ +/* packed_data.h : Interface to the packed binary stream data structure + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ + +#ifndef SVN_PACKED_DATA_H +#define SVN_PACKED_DATA_H + +#include "svn_string.h" +#include "svn_io.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* This API provides Yet Another Serialization Framework. + * + * It is geared towards efficiently encoding collections of structured + * binary data (e.g. an array of noderev objects). The basic idea is to + * transform them into hierarchies of streams with each stream usually + * corresponding to a single attribute in the original data structures. + * The user is free model the mapping structure <-> streams mapping as she + * sees fit. + * + * With all data inside the same (sub-)stream carrying similar attribute + * values, the whole stream lends itself to data compression. Strings / + * plain byte sequences will be stored as is. Numbers use a 7b/8b encoding + * scheme to eliminate leading zeros. Because values are often dependent + * (increasing offsets, roughly similar revision number, etc.), streams + * can be configured as storing (hopefully shorter) deltas instead of the + * original value. + * + * Two stream types are provided: integer and byte streams. While the + * first store 64 bit integers only and can be configured to assume + * signed and / or deltifyable data, the second will store arbitrary + * byte sequences including their length. At the root level, you may + * create an arbitrary number of integer and byte streams. Any stream + * may have an arbitrary number of sub-streams of the same kind. You + * should create the full stream hierarchy before writing any data to it. + * + * As a convenience, when an integer stream has sub-streams, you may write + * to the parent stream instead of all sub-streams individually and the + * values will be passed down automatically in a round-robin fashion. + * Reading from the parent stream is similarly supported. + * + * When all data has been added to the stream, it can be written to an + * ordinary svn_stream_t. First, we write a description of the stream + * structure (types, sub-streams, sizes and configurations) followed by + * zlib compressed stream content. For each top-level stream, all sub- + * stream data will be concatenated and then compressed as a single block. + * To maximize the effect of this, make sure all data in that stream + * hierarchy has a similar value distribution. + * + * Reading data starts with an svn_stream_t and automatically recreates + * the stream hierarchies. You only need to extract data from it in the + * same order as you wrote it. + * + * Although not enforced programmatically, you may either only write to a + * stream hierarchy or only read from it but you cannot do both on the + * same data structure. + */ + + + +/* We pack / unpack integers en block to minimize calling and setup overhead. + * This is the number of integers we put into a buffer before writing them + * them to / after reading them from the 7b/8b stream. Under 64 bits, this + * value creates a 128 byte data structure (14 + 2 integers, 8 bytes each). + */ +#define SVN__PACKED_DATA_BUFFER_SIZE 14 + + +/* Data types. */ + +/* Opaque type for the root object. + */ +typedef struct svn_packed__data_root_t svn_packed__data_root_t; + +/* Opaque type for byte streams. + */ +typedef struct svn_packed__byte_stream_t svn_packed__byte_stream_t; + +/* Semi-opaque type for integer streams. We expose the unpacked buffer + * to allow for replacing svn_packed__add_uint and friends by macros. + */ +typedef struct svn_packed__int_stream_t +{ + /* pointer to the remainder of the data structure */ + void *private_data; + + /* number of value entries in BUFFER */ + apr_size_t buffer_used; + + /* unpacked integers (either yet to be packed or pre-fetched from the + * packed buffers). Only the first BUFFER_USED entries are valid. */ + apr_uint64_t buffer[SVN__PACKED_DATA_BUFFER_SIZE]; +} svn_packed__int_stream_t; + + +/* Writing data. */ + +/* Return a new serialization root object, allocated in POOL. + */ +svn_packed__data_root_t * +svn_packed__data_create_root(apr_pool_t *pool); + +/* Create and return a new top-level integer stream in ROOT. If signed, + * negative numbers will be put into that stream, SIGNED_INTS should be + * TRUE as a more efficient encoding will be used in that case. Set + * DIFF to TRUE if you expect the difference between consecutive numbers + * to be much smaller (~100 times) than the actual numbers. + */ +svn_packed__int_stream_t * +svn_packed__create_int_stream(svn_packed__data_root_t *root, + svn_boolean_t diff, + svn_boolean_t signed_ints); + +/* Create and return a sub-stream to the existing integer stream PARENT. + * If signed, negative numbers will be put into that stream, SIGNED_INTS + * should be TRUE as a more efficient encoding will be used in that case. + * Set DIFF to TRUE if you expect the difference between consecutive numbers + * to be much smaller (~100 times) than the actual numbers. + */ +svn_packed__int_stream_t * +svn_packed__create_int_substream(svn_packed__int_stream_t *parent, + svn_boolean_t diff, + svn_boolean_t signed_ints); + +/* Create and return a new top-level byte sequence stream in ROOT. + */ +svn_packed__byte_stream_t * +svn_packed__create_bytes_stream(svn_packed__data_root_t *root); + +/* Write the unsigned integer VALUE to STEAM. + */ +void +svn_packed__add_uint(svn_packed__int_stream_t *stream, + apr_uint64_t value); + +/* Write the signed integer VALUE to STEAM. + */ +void +svn_packed__add_int(svn_packed__int_stream_t *stream, + apr_int64_t value); + +/* Write the sequence stating at DATA containing LEN bytes to STEAM. + */ +void +svn_packed__add_bytes(svn_packed__byte_stream_t *stream, + const char *data, + apr_size_t len); + +/* Write all contents of ROOT (including all sub-streams) to STREAM. + * Use SCRATCH_POOL for temporary allocations. + */ +svn_error_t * +svn_packed__data_write(svn_stream_t *stream, + svn_packed__data_root_t *root, + apr_pool_t *scratch_pool); + + +/* Reading data. */ + +/* Return the first integer stream in ROOT. Returns NULL in case there + * aren't any. + */ +svn_packed__int_stream_t * +svn_packed__first_int_stream(svn_packed__data_root_t *root); + +/* Return the first byte sequence stream in ROOT. Returns NULL in case + * there aren't any. + */ +svn_packed__byte_stream_t * +svn_packed__first_byte_stream(svn_packed__data_root_t *root); + +/* Return the next (sibling) integer stream to STREAM. Returns NULL in + * case there isn't any. + */ +svn_packed__int_stream_t * +svn_packed__next_int_stream(svn_packed__int_stream_t *stream); + +/* Return the next (sibling) byte sequence stream to STREAM. Returns NULL + * in case there isn't any. + */ +svn_packed__byte_stream_t * +svn_packed__next_byte_stream(svn_packed__byte_stream_t *stream); + +/* Return the first sub-stream of STREAM. Returns NULL in case there + * isn't any. + */ +svn_packed__int_stream_t * +svn_packed__first_int_substream(svn_packed__int_stream_t *stream); + +/* Return the number of integers left to read from STREAM. + */ +apr_size_t +svn_packed__int_count(svn_packed__int_stream_t *stream); + +/* Return the number of bytes left to read from STREAM. + */ +apr_size_t +svn_packed__byte_count(svn_packed__byte_stream_t *stream); + +/* Return the next number from STREAM as unsigned integer. Returns 0 when + * reading beyond the end of the stream. + */ +apr_uint64_t +svn_packed__get_uint(svn_packed__int_stream_t *stream); + +/* Return the next number from STREAM as signed integer. Returns 0 when + * reading beyond the end of the stream. + */ +apr_int64_t +svn_packed__get_int(svn_packed__int_stream_t *stream); + +/* Return the next byte sequence from STREAM and set *LEN to the length + * of that sequence. Sets *LEN to 0 when reading beyond the end of the + * stream. + */ +const char * +svn_packed__get_bytes(svn_packed__byte_stream_t *stream, + apr_size_t *len); + +/* Allocate a new packed data root in RESULT_POOL, read its structure and + * stream contents from STREAM and return it in *ROOT_P. Use SCRATCH_POOL + * for temporary allocations. + */ +svn_error_t * +svn_packed__data_read(svn_packed__data_root_t **root_p, + svn_stream_t *stream, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_PACKED_DATA_H */ diff --git a/subversion/include/private/svn_pseudo_md5.h b/subversion/include/private/svn_pseudo_md5.h deleted file mode 100644 index 34d5929..0000000 --- a/subversion/include/private/svn_pseudo_md5.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * @copyright - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * @endcopyright - * - * @file svn_pseudo_md5.h - * @brief Subversion hash sum calculation for runtime data (only) - */ - -#ifndef SVN_PSEUDO_MD5_H -#define SVN_PSEUDO_MD5_H - -#include <apr.h> /* for apr_uint32_t */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -/** - * Calculates a hash sum for 15 bytes in @a x and returns it in @a digest. - * The most significant byte in @a x must be 0 (independent of being on a - * little or big endian machine). - * - * @note Use for runtime data hashing only. - * - * @note The output is NOT an MD5 digest shares has the same basic - * cryptographic properties. Collisions with proper MD5 on the same - * or other input data is equally unlikely as any MD5 collision. - */ -void svn__pseudo_md5_15(apr_uint32_t digest[4], - const apr_uint32_t x[4]); - -/** - * Calculates a hash sum for 31 bytes in @a x and returns it in @a digest. - * The most significant byte in @a x must be 0 (independent of being on a - * little or big endian machine). - * - * @note Use for runtime data hashing only. - * - * @note The output is NOT an MD5 digest shares has the same basic - * cryptographic properties. Collisions with proper MD5 on the same - * or other input data is equally unlikely as any MD5 collision. - */ -void svn__pseudo_md5_31(apr_uint32_t digest[4], - const apr_uint32_t x[8]); - -/** - * Calculates a hash sum for 63 bytes in @a x and returns it in @a digest. - * The most significant byte in @a x must be 0 (independent of being on a - * little or big endian machine). - * - * @note Use for runtime data hashing only. - * - * @note The output is NOT an MD5 digest shares has the same basic - * cryptographic properties. Collisions with proper MD5 on the same - * or other input data is equally unlikely as any MD5 collision. - */ -void svn__pseudo_md5_63(apr_uint32_t digest[4], - const apr_uint32_t x[16]); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* SVN_PSEUDO_MD5_H */ diff --git a/subversion/include/private/svn_ra_private.h b/subversion/include/private/svn_ra_private.h index accca3d..1afa071 100644 --- a/subversion/include/private/svn_ra_private.h +++ b/subversion/include/private/svn_ra_private.h @@ -39,6 +39,33 @@ extern "C" { #endif /* __cplusplus */ + + +/** + * Open a new ra session @a *new_session to the same repository as an existing + * ra session @a old_session, copying the callbacks, auth baton, etc. from the + * old session. This essentially limits the lifetime of the new, duplicated + * session to the lifetime of the old session. If the new session should + * outlive the new session, creating a new session using svn_ra_open4() is + * recommended. + * + * If @a session_url is not NULL, parent the new session at session_url. Note + * that @a session_url MUST BE in the same repository as @a old_session or an + * error will be returned. When @a session_url NULL the same session root + * will be used. + * + * Allocate @a new_session in @a result_pool. Perform temporary allocations + * in @a scratch_pool. + * + * @since New in 1.9. + */ +svn_error_t * +svn_ra__dup_session(svn_ra_session_t **new_session, + svn_ra_session_t *old_session, + const char *session_url, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + /* Equivalent to svn_ra__assert_capable_server() for SVN_RA_CAPABILITY_MERGEINFO. */ svn_error_t * diff --git a/subversion/include/private/svn_ra_svn_private.h b/subversion/include/private/svn_ra_svn_private.h index b4294d0..bc2fa45 100644 --- a/subversion/include/private/svn_ra_svn_private.h +++ b/subversion/include/private/svn_ra_svn_private.h @@ -43,6 +43,12 @@ svn_ra_svn__set_shim_callbacks(svn_ra_svn_conn_t *conn, svn_delta_shim_callbacks_t *shim_callbacks); /** + * Return the memory pool used to allocate @a conn. + */ +apr_pool_t * +svn_ra_svn__get_pool(svn_ra_svn_conn_t *conn); + +/** * @defgroup ra_svn_deprecated ra_svn low-level functions * @{ */ @@ -83,6 +89,15 @@ svn_ra_svn__write_word(svn_ra_svn_conn_t *conn, apr_pool_t *pool, const char *word); +/** Write a boolean over the net. + * + * Writes will be buffered until the next read or flush. + */ +svn_error_t * +svn_ra_svn__write_boolean(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_boolean_t value); + /** Write a list of properties over the net. @a props is allowed to be NULL, * in which case an empty list will be written out. * @@ -186,6 +201,7 @@ svn_ra_svn__skip_leading_garbage(svn_ra_svn_conn_t *conn, w const char ** Word b svn_boolean_t * Word ("true" or "false") B apr_uint64_t * Word ("true" or "false") + 3 svn_tristate_t * Word ("true" or "false") l apr_array_header_t ** List ( Begin tuple ) End tuple @@ -196,14 +212,18 @@ svn_ra_svn__skip_leading_garbage(svn_ra_svn_conn_t *conn, * the end of the specification. So if @a fmt is "c?cc" and @a list * contains two elements, an error will result. * - * 'B' is similar to 'b', but may be used in the optional tuple specification. - * It returns TRUE, FALSE, or SVN_RA_SVN_UNSPECIFIED_NUMBER. + * '3' is similar to 'b', but may be used in the optional tuple specification. + * It returns #svn_tristate_true, #svn_tristate_false or #svn_tristate_unknown. + * + * 'B' is similar to '3', but it returns @c TRUE, @c FALSE, or + * #SVN_RA_SVN_UNSPECIFIED_NUMBER. 'B' is deprecated; new code should + * use '3' instead. * * If an optional part of a tuple contains no data, 'r' values will be - * set to @c SVN_INVALID_REVNUM, 'n' and 'B' values will be set to - * SVN_RA_SVN_UNSPECIFIED_NUMBER, and 's', 'c', 'w', and 'l' values - * will be set to @c NULL. 'b' may not appear inside an optional - * tuple specification; use 'B' instead. + * set to @c SVN_INVALID_REVNUM; 'n' and 'B' values will be set to + * #SVN_RA_SVN_UNSPECIFIED_NUMBER; 's', 'c', 'w', and 'l' values + * will be set to @c NULL; and '3' values will be set to #svn_tristate_unknown + * 'b' may not appear inside an optional tuple specification; use '3' instead. */ svn_error_t * svn_ra_svn__parse_tuple(const apr_array_header_t *list, @@ -236,6 +256,33 @@ svn_ra_svn__read_cmd_response(svn_ra_svn_conn_t *conn, apr_pool_t *pool, const char *fmt, ...); +/** Check the receive buffer and socket of @a conn whether there is some + * unprocessed incoming data without waiting for new data to come in. + * If data is found, set @a *has_command to TRUE. If the connection does + * not contain any more data and has been closed, set @a *terminated to + * TRUE. + */ +svn_error_t * +svn_ra_svn__has_command(svn_boolean_t *has_command, + svn_boolean_t *terminated, + svn_ra_svn_conn_t *conn, + apr_pool_t *pool); + +/** Accept a single command from @a conn and handle them according + * to @a cmd_hash. Command handlers will be passed @a conn, @a pool, + * the parameters of the command, and @a baton. @a *terminate will be + * set if either @a error_on_disconnect is FALSE and the connection got + * closed, or if the command being handled has the "terminate" flag set + * in the command table. + */ +svn_error_t * +svn_ra_svn__handle_command(svn_boolean_t *terminate, + apr_hash_t *cmd_hash, + void *baton, + svn_ra_svn_conn_t *conn, + svn_boolean_t error_on_disconnect, + apr_pool_t *pool); + /** Accept commands over the network and handle them according to @a * commands. Command handlers will be passed @a conn, a subpool of @a * pool (cleared after each command is handled), the parameters of the @@ -267,11 +314,13 @@ svn_ra_svn__write_cmd_response(svn_ra_svn_conn_t *conn, apr_pool_t *pool, const char *fmt, ...); -/** Write an unsuccessful command response over the network. */ +/** Write an unsuccessful command response over the network. + * + * @note This does not clear @a err. */ svn_error_t * svn_ra_svn__write_cmd_failure(svn_ra_svn_conn_t *conn, apr_pool_t *pool, - svn_error_t *err); + const svn_error_t *err); /** * @} @@ -563,7 +612,11 @@ svn_ra_svn__write_cmd_get_dated_rev(svn_ra_svn_conn_t *conn, /** Send a "change-rev-prop2" command over connection @a conn. * Use @a pool for allocations. * - * @see #svn_ra_change_rev_prop2 for a description. + * If @a dont_care is false then check that the old value matches + * @a old_value. If @a dont_care is true then do not check the old + * value; in this case @a old_value must be NULL. + * + * @see #svn_ra_change_rev_prop2 for the rest of the description. */ svn_error_t * svn_ra_svn__write_cmd_change_rev_prop2(svn_ra_svn_conn_t *conn, @@ -819,6 +872,77 @@ svn_ra_svn__write_cmd_finish_replay(svn_ra_svn_conn_t *conn, /** * @} */ + +/** + * @defgroup svn_send_data sending data structures over ra_svn + * @{ + */ + +/** Send a changed path (as part of transmitting a log entry) over connection + * @a conn. Use @a pool for allocations. + * + * @see svn_log_changed_path2_t for a description of the other parameters. + */ +svn_error_t * +svn_ra_svn__write_data_log_changed_path(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + char action, + const char *copyfrom_path, + svn_revnum_t copyfrom_rev, + svn_node_kind_t node_kind, + svn_boolean_t text_modified, + svn_boolean_t props_modified); + +/** Send a the details of a log entry (as part of transmitting a log entry + * and without revprops and changed paths) over connection @a conn. + * Use @a pool for allocations. + * + * @a author, @a date and @a message have been extracted and removed from + * the revprops to follow. @a has_children is taken directly from the + * #svn_log_entry_t struct. @a revision is too, except when it equals + * #SVN_INVALID_REVNUM. In that case, @a revision must be 0 and + * @a invalid_revnum be set to TRUE. @a revprop_count is the number of + * revprops that will follow in the revprops list. + */ +svn_error_t * +svn_ra_svn__write_data_log_entry(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_revnum_t revision, + const svn_string_t *author, + const svn_string_t *date, + const svn_string_t *message, + svn_boolean_t has_children, + svn_boolean_t invalid_revnum, + unsigned revprop_count); + +/** + * @} + */ + +/** + * @defgroup svn_read_data reading data structures from ra_svn + * @{ + */ + +/** Take the data tuple ITEMS received over ra_svn and convert it to the + * a changed path (as part of receiving a log entry). + * + * @see svn_log_changed_path2_t for a description of the output parameters. + */ +svn_error_t * +svn_ra_svn__read_data_log_changed_entry(const apr_array_header_t *items, + svn_string_t **cpath, + const char **action, + const char **copy_path, + svn_revnum_t *copy_rev, + const char **kind_str, + apr_uint64_t *text_mods, + apr_uint64_t *prop_mods); +/** + * @} + */ + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/subversion/include/private/svn_repos_private.h b/subversion/include/private/svn_repos_private.h index 09e4037..c5a232f 100644 --- a/subversion/include/private/svn_repos_private.h +++ b/subversion/include/private/svn_repos_private.h @@ -32,16 +32,30 @@ #include "svn_types.h" #include "svn_repos.h" #include "svn_editor.h" +#include "svn_config.h" + +#include "private/svn_string_private.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -/** Validate that property @a name is valid for use in a Subversion - * repository; return @c SVN_ERR_REPOS_BAD_ARGS if it isn't. For some - * "svn:" properties, also validate the @a value, and return - * @c SVN_ERR_BAD_PROPERTY_VALUE if it is not valid. +/** Validate that property @a name with @a value is valid (as an addition + * or edit or deletion) in a Subversion repository. Return an error if not. + * + * If @a value is NULL, return #SVN_NO_ERROR to indicate that any property + * may be deleted, even an invalid one. Otherwise, if the @a name is not + * of kind #svn_prop_regular_kind (see #svn_prop_kind_t), return + * #SVN_ERR_REPOS_BAD_ARGS. Otherwise, for some "svn:" properties, also + * perform some validations on the @a value (e.g., for such properties, + * typically the @a value must be in UTF-8 with LF linefeeds), and return + * #SVN_ERR_BAD_PROPERTY_VALUE if it is not valid. + * + * Validations may be added in future releases, for example, for + * newly-added #SVN_PROP_PREFIX properties. However, user-defined + * (non-#SVN_PROP_PREFIX) properties will never have their @a value + * validated in any way. * * Use @a pool for temporary allocations. * @@ -113,10 +127,260 @@ svn_repos__replay_ev2(svn_fs_root_t *root, void *authz_read_baton, apr_pool_t *scratch_pool); -/* A private addition to svn_repos_notify_warning_t. */ -#define svn_repos__notify_warning_invalid_mergeinfo \ - ((svn_repos_notify_warning_t)(-1)) +/* Given a PATH which might be a relative repo URL (^/), an absolute + * local repo URL (file://), an absolute path outside of the repo + * or a location in the Windows registry. + * + * Retrieve the configuration data that PATH points at and parse it into + * CFG_P allocated in POOL. + * + * If PATH cannot be parsed as a config file then an error is returned. The + * contents of CFG_P is then undefined. If MUST_EXIST is TRUE, a missing + * authz file is also an error. The CASE_SENSITIVE controls the lookup + * behavior for section and option names alike. + * + * REPOS_ROOT points at the root of the repos you are + * going to apply the authz against, can be NULL if you are sure that you + * don't have a repos relative URL in PATH. */ +svn_error_t * +svn_repos__retrieve_config(svn_config_t **cfg_p, + const char *path, + svn_boolean_t must_exist, + svn_boolean_t case_sensitive, + apr_pool_t *pool); + +/** + * @defgroup svn_config_pool Configuration object pool API + * @{ + */ + +/* Opaque thread-safe factory and container for configuration objects. + * + * Instances handed out are read-only and may be given to multiple callers + * from multiple threads. Configuration objects no longer referenced by + * any user may linger for a while before being cleaned up. + */ +typedef struct svn_repos__config_pool_t svn_repos__config_pool_t; + +/* Create a new configuration pool object with a lifetime determined by + * POOL and return it in *CONFIG_POOL. + * + * The THREAD_SAFE flag indicates whether the pool actually needs to be + * thread-safe and POOL must be also be thread-safe if this flag is set. + */ +svn_error_t * +svn_repos__config_pool_create(svn_repos__config_pool_t **config_pool, + svn_boolean_t thread_safe, + apr_pool_t *pool); +/* Set *CFG to a read-only reference to the current contents of the + * configuration specified by PATH. If the latter is a URL, we read the + * data from a local repository. CONFIG_POOL will store the configuration + * and make further callers use the same instance if the content matches. + * If KEY is not NULL, *KEY will be set to a unique ID - if available. + * + * If MUST_EXIST is TRUE, a missing config file is also an error, *CFG + * is otherwise simply NULL. The CASE_SENSITIVE controls the lookup + * behavior for section and option names alike. + * + * PREFERRED_REPOS is only used if it is not NULL and PATH is a URL. + * If it matches the URL, access the repository through this object + * instead of creating a new repo instance. Note that this might not + * return the latest content. + * + * POOL determines the minimum lifetime of *CFG (may remain cached after + * release) but must not exceed the lifetime of the pool provided to + * #svn_repos__config_pool_create. + */ +svn_error_t * +svn_repos__config_pool_get(svn_config_t **cfg, + svn_membuf_t **key, + svn_repos__config_pool_t *config_pool, + const char *path, + svn_boolean_t must_exist, + svn_boolean_t case_sensitive, + svn_repos_t *preferred_repos, + apr_pool_t *pool); + +/** @} */ + +/** + * @defgroup svn_authz_pool Authz object pool API + * @{ + */ + +/* Opaque thread-safe factory and container for authorization objects. + * + * Instances handed out are read-only and may be given to multiple callers + * from multiple threads. Authorization objects no longer referenced by + * any user may linger for a while before being cleaned up. + */ +typedef struct svn_repos__authz_pool_t svn_repos__authz_pool_t; + +/* Create a new authorization pool object with a lifetime determined by + * POOL and return it in *AUTHZ_POOL. CONFIG_POOL will be the common + * source for the configuration data underlying the authz objects and must + * remain valid at least until POOL cleanup. + * + * The THREAD_SAFE flag indicates whether the pool actually needs to be + * thread-safe and POOL must be also be thread-safe if this flag is set. + */ +svn_error_t * +svn_repos__authz_pool_create(svn_repos__authz_pool_t **authz_pool, + svn_repos__config_pool_t *config_pool, + svn_boolean_t thread_safe, + apr_pool_t *pool); + +/* Set *AUTHZ_P to a read-only reference to the current contents of the + * authorization specified by PATH and GROUPS_PATH. If these are URLs, + * we read the data from a local repository (see #svn_repos_authz_read2). + * AUTHZ_POOL will store the authz data and make further callers use the + * same instance if the content matches. + * + * If MUST_EXIST is TRUE, a missing config file is also an error, *AUTHZ_P + * is otherwise simply NULL. + * + * PREFERRED_REPOS is only used if it is not NULL and PATH is a URL. + * If it matches the URL, access the repository through this object + * instead of creating a new repo instance. Note that this might not + * return the latest content. + * + * POOL determines the minimum lifetime of *AUTHZ_P (may remain cached + * after release) but must not exceed the lifetime of the pool provided to + * svn_repos__authz_pool_create. + */ +svn_error_t * +svn_repos__authz_pool_get(svn_authz_t **authz_p, + svn_repos__authz_pool_t *authz_pool, + const char *path, + const char *groups_path, + svn_boolean_t must_exist, + svn_repos_t *preferred_repos, + apr_pool_t *pool); + +/** @} */ + +/* Adjust mergeinfo paths and revisions in ways that are useful when loading + * a dump stream. + * + * Set *NEW_VALUE_P to an adjusted version of the mergeinfo property value + * supplied in OLD_VALUE, with the following adjustments. + * + * - Normalize line endings: if all CRLF, change to LF; but error if + * mixed. If this normalization is performed, send a notification type + * svn_repos_notify_load_normalized_mergeinfo to NOTIFY_FUNC/NOTIFY_BATON. + * + * - Prefix all the merge source paths with PARENT_DIR, if not null. + * + * - Adjust any mergeinfo revisions not older than OLDEST_DUMPSTREAM_REV + * by using REV_MAP which maps (svn_revnum_t) old rev to (svn_revnum_t) + * new rev. + * + * - Adjust any mergeinfo revisions older than OLDEST_DUMPSTREAM_REV by + * (-OLDER_REVS_OFFSET), dropping any revisions that become <= 0. + * + * Allocate *NEW_VALUE_P in RESULT_POOL. + */ +svn_error_t * +svn_repos__adjust_mergeinfo_property(svn_string_t **new_value_p, + const svn_string_t *old_value, + const char *parent_dir, + apr_hash_t *rev_map, + svn_revnum_t oldest_dumpstream_rev, + apr_int32_t older_revs_offset, + svn_repos_notify_func_t notify_func, + void *notify_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* A (nearly) opaque representation of an ordered list of header lines. + */ +typedef struct apr_array_header_t svn_repos__dumpfile_headers_t; + +/* Create an empty set of headers. + */ +svn_repos__dumpfile_headers_t * +svn_repos__dumpfile_headers_create(apr_pool_t *pool); + +/* Push the header (KEY, VAL) onto HEADERS. + * + * Duplicate the key and value into HEADERS's pool. + */ +void +svn_repos__dumpfile_header_push(svn_repos__dumpfile_headers_t *headers, + const char *key, + const char *val); + +/* Push the header (KEY, val = VAL_FMT ...) onto HEADERS. + * + * Duplicate the key and value into HEADERS's pool. + */ +void +svn_repos__dumpfile_header_pushf(svn_repos__dumpfile_headers_t *headers, + const char *key, + const char *val_fmt, + ...) + __attribute__((format(printf, 3, 4))); + +/* Write to STREAM the headers in HEADERS followed by a blank line. + */ +svn_error_t * +svn_repos__dump_headers(svn_stream_t *stream, + svn_repos__dumpfile_headers_t *headers, + apr_pool_t *scratch_pool); + +/* Write a revision record to DUMP_STREAM for revision REVISION with revision + * properies REVPROPS, creating appropriate headers. + * + * Include all of the headers in EXTRA_HEADERS (if non-null), ignoring + * the revision number header and the three content length headers (which + * will be recreated as needed). EXTRA_HEADERS maps (char *) key to + * (char *) value. + * + * REVPROPS maps (char *) key to (svn_string_t *) value. + * + * Iff PROPS_SECTION_ALWAYS is true, include a prop content section (and + * corresponding header) even when REVPROPS is empty. This option exists + * to support a historical difference between svndumpfilter and svnadmin + * dump. + * + * Finally write another blank line. + */ +svn_error_t * +svn_repos__dump_revision_record(svn_stream_t *dump_stream, + svn_revnum_t revision, + apr_hash_t *extra_headers, + apr_hash_t *revprops, + svn_boolean_t props_section_always, + apr_pool_t *scratch_pool); + +/* Output node headers and props. + * + * Output HEADERS, content length headers, blank line, and + * then PROPS_STR (if non-null) to DUMP_STREAM. + * + * HEADERS is an array of headers as struct {const char *key, *val;}. + * Write them all in the given order. + * + * PROPS_STR is the property content block, including a terminating + * 'PROPS_END\n' line. Iff PROPS_STR is non-null, write a + * Prop-content-length header and the prop content block. + * + * Iff HAS_TEXT is true, write a Text-content length, using the value + * TEXT_CONTENT_LENGTH. + * + * Write a Content-length header, its value being the sum of the + * Prop- and Text- content length headers, if props and/or text are present + * or if CONTENT_LENGTH_ALWAYS is true. + */ +svn_error_t * +svn_repos__dump_node_record(svn_stream_t *dump_stream, + svn_repos__dumpfile_headers_t *headers, + svn_stringbuf_t *props_str, + svn_boolean_t has_text, + svn_filesize_t text_content_length, + svn_boolean_t content_length_always, + apr_pool_t *scratch_pool); #ifdef __cplusplus } diff --git a/subversion/include/private/svn_sorts_private.h b/subversion/include/private/svn_sorts_private.h new file mode 100644 index 0000000..c358513 --- /dev/null +++ b/subversion/include/private/svn_sorts_private.h @@ -0,0 +1,227 @@ +/** + * @copyright + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * @endcopyright + * + * @file svn_sorts_private.h + * @brief all sorts of sorts. + */ + + +#ifndef SVN_SORTS_PRIVATE_H +#define SVN_SORTS_PRIVATE_H + +#include "../svn_sorts.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + +/** This structure is used to hold a key/value from a hash table. + * @note Private. For use by Subversion's own code only. See issue #1644. + */ +struct svn_sort__item_t { + /** pointer to the key */ + const void *key; + + /** size of the key */ + apr_ssize_t klen; + + /** pointer to the value */ + void *value; +}; + +/** Sort @a ht according to its keys, return an @c apr_array_header_t + * containing @c svn_sort__item_t structures holding those keys and values + * (i.e. for each @c svn_sort__item_t @a item in the returned array, + * @a item->key and @a item->size are the hash key, and @a item->value points to + * the hash value). + * + * Storage is shared with the original hash, not copied. + * + * @a comparison_func should take two @c svn_sort__item_t's and return an + * integer greater than, equal to, or less than 0, according as the first item + * is greater than, equal to, or less than the second. + * + * @note Private. For use by Subversion's own code only. See issue #1644. + * + * @note This function and the @c svn_sort__item_t should go over to APR. + */ +apr_array_header_t * +svn_sort__hash(apr_hash_t *ht, + int (*comparison_func)(const svn_sort__item_t *, + const svn_sort__item_t *), + apr_pool_t *pool); + +/* Sort APR array @a array using ordering defined by @a comparison_func. + * @a comparison_func is defined as for the C stdlib function qsort(). + */ +void +svn_sort__array(apr_array_header_t *array, + int (*comparison_func)(const void *, + const void *)); + +/* Return the lowest index at which the element @a *key should be inserted into + * the array @a array, according to the ordering defined by @a compare_func. + * The array must already be sorted in the ordering defined by @a compare_func. + * @a compare_func is defined as for the C stdlib function bsearch(); the + * @a key will always passed to it as the second parameter. + * + * @note Private. For use by Subversion's own code only. + */ +int +svn_sort__bsearch_lower_bound(const apr_array_header_t *array, + const void *key, + int (*compare_func)(const void *, const void *)); + +/* Find the lowest index at which the element @a *key should be inserted into + * the array @a array, according to the ordering defined by @a compare_func. + * The array must already be sorted in the ordering defined by @a compare_func. + * @a compare_func is defined as for the C stdlib function bsearch(); the + * @a key will always passed to it as the second parameter. + * + * Returns a reference to the array element at the insertion location if + * that matches @a key and return NULL otherwise. If you call this function + * multiple times for the same array and expect the results to often be + * consecutive array elements, provide @a hint. It should be initialized + * with -1 for the first call and receives the array index if the returned + * element. If the return value is NULL, @a *hint is the location where + * the respective key would be inserted. + * + * @note Private. For use by Subversion's own code only. + */ +void * +svn_sort__array_lookup(const apr_array_header_t *array, + const void *key, + int *hint, + int (*compare_func)(const void *, const void *)); + + +/* Insert a shallow copy of @a *new_element into the array @a array at the index + * @a insert_index, growing the array and shuffling existing elements along to + * make room. + * + * @note Private. For use by Subversion's own code only. + */ +void +svn_sort__array_insert(apr_array_header_t *array, + const void *new_element, + int insert_index); + + +/* Remove @a elements_to_delete elements starting at @a delete_index from the + * array @a arr. If @a delete_index is not a valid element of @a arr, + * @a elements_to_delete is not greater than zero, or + * @a delete_index + @a elements_to_delete is greater than @a arr->nelts, + * then do nothing. + * + * @note Private. For use by Subversion's own code only. + */ +void +svn_sort__array_delete(apr_array_header_t *arr, + int delete_index, + int elements_to_delete); + +/* Reverse the order of elements in @a array, in place. + * + * @note Private. For use by Subversion's own code only. + */ +void +svn_sort__array_reverse(apr_array_header_t *array, + apr_pool_t *scratch_pool); + +/** Priority queues. + * + * @defgroup svn_priority_queue__t Priority Queues + * @{ + */ + +/** + * We implement priority queues on top of existing ELEMENTS arrays. They + * provide us with memory management and very basic element type information. + * + * The extraction order is being defined by a comparison function similar + * to the ones used with qsort. The first element in the queue is always + * on with COMPARISON_FUNC(first,element) <= 0, for all elements in the + * queue. + */ + +/** + * Opaque data type for priority queues. + */ +typedef struct svn_priority_queue__t svn_priority_queue__t; + +/** + * Return a priority queue containing all provided @a elements and prioritize + * them according to @a compare_func. + * + * @note The priority queue will use the existing @a elements array for data + * storage. So, you must not manipulate that array while using the queue. + * Also, the lifetime of the queue is bound to that of the array. + */ +svn_priority_queue__t * +svn_priority_queue__create(apr_array_header_t *elements, + int (*compare_func)(const void *, const void *)); + +/** + * Returns the number of elements in the @a queue. + */ +apr_size_t +svn_priority_queue__size(svn_priority_queue__t *queue); + +/** + * Returns a reference to the first element in the @a queue. The queue + * contents remains unchanged. If the @a queue is empty, #NULL will be + * returned. + */ +void * +svn_priority_queue__peek(svn_priority_queue__t *queue); + +/** + * Notify the @a queue after modifying the first item as returned by + * #svn_priority_queue__peek. + */ +void +svn_priority_queue__update(svn_priority_queue__t *queue); + +/** + * Remove the first element from the @a queue. This is a no-op for empty + * queues. + */ +void +svn_priority_queue__pop(svn_priority_queue__t *queue); + +/** + * Append the new @a element to the @a queue. @a element must neither be + * #NULL nor the first element as returned by #svn_priority_queue__peek. + */ +void +svn_priority_queue__push(svn_priority_queue__t *queue, const void *element); + +/** @} */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_SORTS_PRIVATE_H */ diff --git a/subversion/include/private/svn_sqlite.h b/subversion/include/private/svn_sqlite.h index 4c03e19..4c6cb97 100644 --- a/subversion/include/private/svn_sqlite.h +++ b/subversion/include/private/svn_sqlite.h @@ -63,7 +63,7 @@ typedef enum svn_sqlite__mode_e { typedef svn_error_t *(*svn_sqlite__func_t)(svn_sqlite__context_t *sctx, int argc, svn_sqlite__value_t *values[], - apr_pool_t *scatch_pool); + void *baton); /* Step the given statement; if it returns SQLITE_DONE, reset the statement. @@ -117,12 +117,16 @@ svn_sqlite__read_schema_version(int *version, STATEMENTS itself may be NULL, in which case it has no impact. See svn_sqlite__get_statement() for how these strings are used. + TIMEOUT defines the SQLite busy timeout, values <= 0 cause a Subversion + default to be used. + The statements will be finalized and the SQLite database will be closed when RESULT_POOL is cleaned up. */ svn_error_t * -svn_sqlite__open(svn_sqlite__db_t **db, const char *repos_path, +svn_sqlite__open(svn_sqlite__db_t **db, const char *path, svn_sqlite__mode_t mode, const char * const statements[], int latest_schema, const char * const *upgrade_sql, + apr_int32_t timeout, apr_pool_t *result_pool, apr_pool_t *scratch_pool); /* Explicitly close the connection in DB. */ @@ -130,11 +134,16 @@ svn_error_t * svn_sqlite__close(svn_sqlite__db_t *db); /* Add a custom function to be used with this database connection. The data - in BATON should live at least as long as the connection in DB. */ + in BATON should live at least as long as the connection in DB. + + Pass TRUE if the result of the function is constant within a statement with + a specific set of argument values and FALSE if not (or when in doubt). When + TRUE newer Sqlite versions use this knowledge for query optimizations. */ svn_error_t * svn_sqlite__create_scalar_function(svn_sqlite__db_t *db, const char *func_name, int argc, + svn_boolean_t deterministic, svn_sqlite__func_t func, void *baton); @@ -345,6 +354,11 @@ svn_sqlite__column_is_null(svn_sqlite__stmt_t *stmt, int column); int svn_sqlite__column_bytes(svn_sqlite__stmt_t *stmt, int column); +/* When Subversion is compiled in maintainer mode: enables the sqlite error + logging to SVN_DBG_OUTPUT. */ +void +svn_sqlite__dbg_enable_errorlog(void); + /* --------------------------------------------------------------------- */ @@ -372,6 +386,9 @@ svn_sqlite__result_null(svn_sqlite__context_t *sctx); void svn_sqlite__result_int64(svn_sqlite__context_t *sctx, apr_int64_t val); +void +svn_sqlite__result_error(svn_sqlite__context_t *sctx, const char *msg, int num); + /* --------------------------------------------------------------------- */ @@ -522,7 +539,7 @@ svn_sqlite__with_immediate_transaction(svn_sqlite__db_t *db, SCRATCH_POOL will be passed to the callback (NULL is valid). ### Since we now require SQLite >= 3.6.18, this function has the effect of - always behaving like a defered transaction. Can it be combined with + always behaving like a deferred transaction. Can it be combined with svn_sqlite__with_transaction()? */ svn_error_t * @@ -538,6 +555,9 @@ svn_sqlite__hotcopy(const char *src_path, const char *dst_path, apr_pool_t *scratch_pool); +/* Backported version of SVN_ERR_SQLITE_ROLLBACK_FAILED. */ +#define SVN_SQLITE__ERR_ROLLBACK_FAILED (SVN_ERR_MISC_CATEGORY_START + 44) + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/subversion/include/private/svn_string_private.h b/subversion/include/private/svn_string_private.h index 8579f4d..2f16273 100644 --- a/subversion/include/private/svn_string_private.h +++ b/subversion/include/private/svn_string_private.h @@ -131,10 +131,13 @@ svn_membuf__nzero(svn_membuf_t *membuf, apr_size_t size); svn_string_t * svn_stringbuf__morph_into_string(svn_stringbuf_t *strbuf); -/** Like apr_strtoff but provided here for backward compatibility - * with APR 0.9 */ -apr_status_t -svn__strtoff(apr_off_t *offset, const char *buf, char **end, int base); +/** Like strtoul but with a fixed base of 10 and without overflow checks. + * This allows the compiler to generate massively faster (4x on 64bit LINUX) + * code. Overflow checks may be added on the caller side where you might + * want to test for a more specific value range anyway. + */ +unsigned long +svn__strtoul(const char *buffer, const char **end); /** Number of chars needed to represent signed (19 places + sign + NUL) or * unsigned (20 places + NUL) integers as strings. @@ -156,22 +159,55 @@ apr_size_t svn__i64toa(char * dest, apr_int64_t number); /** Returns a decimal string for @a number allocated in @a pool. Put in - * the @a seperator at each third place. + * the @a separator at each third place. */ char * -svn__ui64toa_sep(apr_uint64_t number, char seperator, apr_pool_t *pool); +svn__ui64toa_sep(apr_uint64_t number, char separator, apr_pool_t *pool); /** Returns a decimal string for @a number allocated in @a pool. Put in - * the @a seperator at each third place. + * the @a separator at each third place. */ char * -svn__i64toa_sep(apr_int64_t number, char seperator, apr_pool_t *pool); +svn__i64toa_sep(apr_int64_t number, char separator, apr_pool_t *pool); + + +/** Writes the @a number as base36-encoded string into @a dest. The latter + * must provide space for at least #SVN_INT64_BUFFER_SIZE characters. + * Returns the number chars written excluding the terminating NUL. + * + * @note The actual maximum buffer requirement is much shorter than + * #SVN_INT64_BUFFER_SIZE but introducing yet another constant is only + * marginally useful and may open the door to security issues when e.g. + * switching between base10 and base36 encoding. + */ +apr_size_t +svn__ui64tobase36(char *dest, apr_uint64_t number); + +/** Returns the value of the base36 encoded unsigned integer starting at + * @a source. If @a next is not NULL, @a *next will be set to the first + * position after the integer. + * + * The data in @a source will be considered part of the number to parse + * as long as the characters are within the base36 range. If there are + * no such characters to begin with, 0 is returned. Inputs with more than + * #SVN_INT64_BUFFER_SIZE digits will not be fully parsed, i.e. the value + * of @a *next as well as the return value are undefined. + */ +apr_uint64_t +svn__base36toui64(const char **next, const char *source); + +/** + * The upper limit of the similarity range returned by + * svn_cstring__similarity() and svn_string__similarity(). + */ +#define SVN_STRING__SIM_RANGE_MAX 1000000 /** * Computes the similarity score of STRA and STRB. Returns the ratio * of the length of their longest common subsequence and the average - * length of the strings, normalized to the range [0..1000]. - * The result is equivalent to Python's + * length of the strings, normalized to the range + * [0..SVN_STRING__SIM_RANGE_MAX]. The result is equivalent to + * Python's * * difflib.SequenceMatcher.ratio * @@ -196,7 +232,7 @@ svn__i64toa_sep(apr_int64_t number, char seperator, apr_pool_t *pool); * has O(strlen(STRA) * strlen(STRB)) worst-case performance, * so do keep a rein on your enthusiasm. */ -unsigned int +apr_size_t svn_cstring__similarity(const char *stra, const char *strb, svn_membuf_t *buffer, apr_size_t *rlcs); @@ -204,12 +240,82 @@ svn_cstring__similarity(const char *stra, const char *strb, * Like svn_cstring__similarity, but accepts svn_string_t's instead * of NUL-terminated character strings. */ -unsigned int +apr_size_t svn_string__similarity(const svn_string_t *stringa, const svn_string_t *stringb, svn_membuf_t *buffer, apr_size_t *rlcs); +/* Return the lowest position at which A and B differ. If no difference + * can be found in the first MAX_LEN characters, MAX_LEN will be returned. + */ +apr_size_t +svn_cstring__match_length(const char *a, + const char *b, + apr_size_t max_len); + +/* Return the number of bytes before A and B that don't differ. If no + * difference can be found in the first MAX_LEN characters, MAX_LEN will + * be returned. Please note that A-MAX_LEN and B-MAX_LEN must both be + * valid addresses. + */ +apr_size_t +svn_cstring__reverse_match_length(const char *a, + const char *b, + apr_size_t max_len); + +/** @} */ + +/** Prefix trees. + * + * Prefix trees allow for a space-efficient representation of a set of path- + * like strings, i.e. those that share common prefixes. Any given string + * value will be stored only once, i.e. two strings stored in the same tree + * are equal if and only if the point to the same #svn_prefix_string__t. + * + * @defgroup svn_prefix_string Strings in prefix trees. +* @{ + */ + +/** + * Opaque data type for prefix-tree-based strings. + */ +typedef struct svn_prefix_string__t svn_prefix_string__t; + +/** + * Opaque data type representing a prefix tree + */ +typedef struct svn_prefix_tree__t svn_prefix_tree__t; + +/** + * Return a new prefix tree allocated in @a pool. + */ +svn_prefix_tree__t * +svn_prefix_tree__create(apr_pool_t *pool); + +/** + * Return a string with the value @a s stored in @a tree. If no such string + * exists yet, add it automatically. + */ +svn_prefix_string__t * +svn_prefix_string__create(svn_prefix_tree__t *tree, + const char *s); + +/** + * Return the contents of @a s as a new string object allocated in @a pool. + */ +svn_string_t * +svn_prefix_string__expand(const svn_prefix_string__t *s, + apr_pool_t *pool); + +/** + * Compare the two strings @a lhs and @a rhs that must be part of the same + * tree. + */ +int +svn_prefix_string__compare(const svn_prefix_string__t *lhs, + const svn_prefix_string__t *rhs); + /** @} */ /** @} */ diff --git a/subversion/include/private/svn_subr_private.h b/subversion/include/private/svn_subr_private.h index 30fbbf2..095d71c 100644 --- a/subversion/include/private/svn_subr_private.h +++ b/subversion/include/private/svn_subr_private.h @@ -26,7 +26,7 @@ #include "svn_types.h" #include "svn_io.h" -#include "svn_version.h" +#include "svn_config.h" #ifdef __cplusplus @@ -95,11 +95,32 @@ svn_spillbuf__create(apr_size_t blocksize, apr_size_t maxsize, apr_pool_t *result_pool); +/* Create a spill buffer, with extra parameters. */ +svn_spillbuf_t * +svn_spillbuf__create_extended(apr_size_t blocksize, + apr_size_t maxsize, + svn_boolean_t delete_on_close, + svn_boolean_t spill_all_contents, + const char* dirpath, + apr_pool_t *result_pool); /* Determine how much content is stored in the spill buffer. */ svn_filesize_t svn_spillbuf__get_size(const svn_spillbuf_t *buf); +/* Determine how much content the spill buffer is caching in memory. */ +svn_filesize_t +svn_spillbuf__get_memory_size(const svn_spillbuf_t *buf); + +/* Retrieve the name of the spill file. The returned value can be NULL + if the file has not been created yet. */ +const char * +svn_spillbuf__get_filename(const svn_spillbuf_t *buf); + +/* Retrieve the handle of the spill file. The returned value can be + NULL if the file has not been created yet. */ +apr_file_t * +svn_spillbuf__get_file(const svn_spillbuf_t *buf); /* Write some data into the spill buffer. */ svn_error_t * @@ -153,13 +174,13 @@ svn_spillbuf__process(svn_boolean_t *exhausted, typedef struct svn_spillbuf_reader_t svn_spillbuf_reader_t; -/* Create a spill-buffer and a reader for it. */ +/* Create a spill-buffer and a reader for it, using the same arguments as + svn_spillbuf__create(). */ svn_spillbuf_reader_t * svn_spillbuf__reader_create(apr_size_t blocksize, apr_size_t maxsize, apr_pool_t *result_pool); - /* Read @a len bytes from @a reader into @a data. The number of bytes actually read is stored in @a amt. If the content is exhausted, then @a amt is set to zero. It will always be non-zero if the spill-buffer @@ -191,17 +212,23 @@ svn_spillbuf__reader_write(svn_spillbuf_reader_t *reader, apr_pool_t *scratch_pool); -/* Return a stream built on top of a spillbuf, using the same arguments as - svn_spillbuf__create(). This stream can be used for reading and writing, - but implements the same basic sematics of a spillbuf for the underlying - storage. */ +/* Return a stream built on top of a spillbuf. + + This stream can be used for reading and writing, but implements the + same basic semantics of a spillbuf for the underlying storage. */ svn_stream_t * -svn_stream__from_spillbuf(apr_size_t blocksize, - apr_size_t maxsize, +svn_stream__from_spillbuf(svn_spillbuf_t *buf, apr_pool_t *result_pool); /** @} */ +/*----------------------------------------------------*/ + +/** + * @defgroup svn_checksum_private Checksumming helper APIs + * @{ + */ + /** * Internal function for creating a MD5 checksum from a binary digest. * @@ -221,6 +248,76 @@ svn_checksum_t * svn_checksum__from_digest_sha1(const unsigned char *digest, apr_pool_t *result_pool); +/** + * Internal function for creating a 32 bit FNV-1a checksum from a binary + * digest. + * + * @since New in 1.9 + */ +svn_checksum_t * +svn_checksum__from_digest_fnv1a_32(const unsigned char *digest, + apr_pool_t *result_pool); + +/** + * Internal function for creating a modified 32 bit FNV-1a checksum from + * a binary digest. + * + * @since New in 1.9 + */ +svn_checksum_t * +svn_checksum__from_digest_fnv1a_32x4(const unsigned char *digest, + apr_pool_t *result_pool); + + +/** + * Return a stream that calculates a checksum of type @a kind over all + * data written to the @a inner_stream. When the returned stream gets + * closed, write the checksum to @a *checksum. + * Allocate the result in @a pool. + * + * @note The stream returned only supports #svn_stream_write and + * #svn_stream_close. + */ +svn_stream_t * +svn_checksum__wrap_write_stream(svn_checksum_t **checksum, + svn_stream_t *inner_stream, + svn_checksum_kind_t kind, + apr_pool_t *pool); + +/** + * Return a stream that calculates a 32 bit modified FNV-1a checksum + * over all data written to the @a inner_stream and writes the digest + * to @a *digest when the returned stream gets closed. + * Allocate the stream in @a pool. + */ +svn_stream_t * +svn_checksum__wrap_write_stream_fnv1a_32x4(apr_uint32_t *digest, + svn_stream_t *inner_stream, + apr_pool_t *pool); + +/** + * Return a 32 bit FNV-1a checksum for the first @a len bytes in @a input. + * + * @since New in 1.9 + */ +apr_uint32_t +svn__fnv1a_32(const void *input, apr_size_t len); + +/** + * Return a 32 bit modified FNV-1a checksum for the first @a len bytes in + * @a input. + * + * @note This is a proprietary checksumming algorithm based FNV-1a with + * approximately the same strength. It is up to 4 times faster + * than plain FNV-1a for longer data blocks. + * + * @since New in 1.9 + */ +apr_uint32_t +svn__fnv1a_32x4(const void *input, apr_size_t len); + +/** @} */ + /** * @defgroup svn_hash_support Hash table serialization support @@ -285,6 +382,54 @@ svn_hash__make(apr_pool_t *pool); /** @} */ +/** + * @defgroup svn_hash_read Reading serialized hash tables + * @{ + */ + +/** Struct that represents a key value pair read from a serialized hash + * representation. There are special cases that can also be represented: + * a #NULL @a key signifies the end of the hash, a #NULL @a val for non- + * NULL keys is only possible in incremental mode describes a deletion. + * + * @since New in 1.9. + */ +typedef struct svn_hash__entry_t +{ + /** 0-terminated Key. #NULL if this contains no data at all because we + * encountered the end of the hash. */ + char *key; + + /** Length of @a key. Must be 0 if @a key is #NULL. */ + apr_size_t keylen; + + /** 0-terminated value stored with the key. If this is #NULL for a + * non-NULL @a key, then this means that the key shall be removed from + * the hash (only used in incremental mode). Must be #NULL if @a key is + * #NULL. */ + char *val; + + /** Length of @a val. Must be 0 if @a val is #NULL. */ + apr_size_t vallen; +} svn_hash__entry_t; + +/** Reads a single key-value pair from @a stream and returns it in the + * caller-provided @a *entry (members don't need to be pre-initialized). + * @a pool is used to allocate members of @a *entry and for tempoaries. + * + * @see #svn_hash_read2 for more details. + * + * @since New in 1.9. + */ +svn_error_t * +svn_hash__read_entry(svn_hash__entry_t *entry, + svn_stream_t *stream, + const char *terminator, + svn_boolean_t incremental, + apr_pool_t *pool); + +/** @} */ + /** @} */ @@ -332,20 +477,230 @@ svn_version__at_least(svn_version_t *version, int minor, int patch); -/** Like svn_ver_check_list(), but with a @a comparator parameter. - * Private backport of svn_ver_check_list2() from trunk. +/** @} */ + +/** + * @defgroup svn_compress Data (de-)compression API + * @{ + */ + +/* This is at least as big as the largest size of an integer that + svn__encode_uint() can generate; it is sufficient for creating buffers + for it to write into. This assumes that integers are at most 64 bits, + and so 10 bytes (with 7 bits of information each) are sufficient to + represent them. */ +#define SVN__MAX_ENCODED_UINT_LEN 10 + +/* Compression method parameters for svn__encode_uint. */ + +/* No compression (but a length prefix will still be added to the buffer) */ +#define SVN__COMPRESSION_NONE 0 + +/* Fastest, least effective compression method & level provided by zlib. */ +#define SVN__COMPRESSION_ZLIB_MIN 1 + +/* Default compression method & level provided by zlib. */ +#define SVN__COMPRESSION_ZLIB_DEFAULT 5 + +/* Slowest, best compression method & level provided by zlib. */ +#define SVN__COMPRESSION_ZLIB_MAX 9 + +/* Encode VAL into the buffer P using the variable-length 7b/8b unsigned + integer format. Return the incremented value of P after the + encoded bytes have been written. P must point to a buffer of size + at least SVN__MAX_ENCODED_UINT_LEN. + + This encoding uses the high bit of each byte as a continuation bit + and the other seven bits as data bits. High-order data bits are + encoded first, followed by lower-order bits, so the value can be + reconstructed by concatenating the data bits from left to right and + interpreting the result as a binary number. Examples (brackets + denote byte boundaries, spaces are for clarity only): + + 1 encodes as [0 0000001] + 33 encodes as [0 0100001] + 129 encodes as [1 0000001] [0 0000001] + 2000 encodes as [1 0001111] [0 1010000] +*/ +unsigned char * +svn__encode_uint(unsigned char *p, apr_uint64_t val); + +/* Decode an unsigned 7b/8b-encoded integer into *VAL and return a pointer + to the byte after the integer. The bytes to be decoded live in the + range [P..END-1]. If these bytes do not contain a whole encoded + integer, return NULL; in this case *VAL is undefined. + + See the comment for svn__encode_uint() earlier in this file for more + detail on the encoding format. */ +const unsigned char * +svn__decode_uint(apr_uint64_t *val, + const unsigned char *p, + const unsigned char *end); + +/* Get the data from IN, compress it according to the specified + * COMPRESSION_METHOD and write the result to OUT. + * SVN__COMPRESSION_NONE is valid for COMPRESSION_METHOD. + */ +svn_error_t * +svn__compress(svn_stringbuf_t *in, + svn_stringbuf_t *out, + int compression_method); + +/* Get the compressed data from IN, decompress it and write the result to + * OUT. Return an error if the decompressed size is larger than LIMIT. + */ +svn_error_t * +svn__decompress(svn_stringbuf_t *in, + svn_stringbuf_t *out, + apr_size_t limit); + +/** @} */ + +/** + * @defgroup svn_root_pools Recycle-able root pools API + * @{ + */ + +/* Opaque thread-safe container for unused / recylcleable root pools. + * + * Recyling root pools (actually, their allocators) circumvents a + * scalability bottleneck in the OS memory management when multi-threaded + * applications frequently create and destroy allocators. + */ +typedef struct svn_root_pools__t svn_root_pools__t; + +/* Create a new root pools container and return it in *POOLS. */ svn_error_t * -svn_ver__check_list2(const svn_version_t *my_version, - const svn_version_checklist_t *checklist, - svn_boolean_t (*comparator)(const svn_version_t *, - const svn_version_t *)); +svn_root_pools__create(svn_root_pools__t **pools); + +/* Return a currently unused pool from POOLS. If POOLS is empty, create a + * new root pool and return that. The pool returned is not thread-safe. + */ +apr_pool_t * +svn_root_pools__acquire_pool(svn_root_pools__t *pools); -/** To minimize merge churn in callers, alias the trunk name privately. */ -#define svn_ver_check_list2 svn_ver__check_list2 +/* Clear and release the given root POOL and put it back into POOLS. + * If that fails, destroy POOL. + */ +void +svn_root_pools__release_pool(apr_pool_t *pool, + svn_root_pools__t *pools); /** @} */ +/** + * @defgroup svn_config_private Private configuration handling API + * @{ + */ + +/* Future attempts to modify CFG will trigger an assertion. */ +void +svn_config__set_read_only(svn_config_t *cfg, + apr_pool_t *scratch_pool); + +/* Return TRUE, if CFG cannot be modified. */ +svn_boolean_t +svn_config__is_read_only(svn_config_t *cfg); + +/* Return TRUE, if OPTION in SECTION in CFG exists and does not require + * further expansion (due to either containing no placeholders or already + * having been expanded). */ +svn_boolean_t +svn_config__is_expanded(svn_config_t *cfg, + const char *section, + const char *option); + +/* Return a shallow copy of SCR in POOL. If SRC is read-only, different + * shallow copies may be used from different threads. + * + * Any single r/o svn_config_t or shallow copy is not thread-safe because + * it contains shared buffers for tempoary data. + */ +svn_config_t * +svn_config__shallow_copy(svn_config_t *src, + apr_pool_t *pool); + +/* Add / replace SECTION in TARGET with the same section from SOURCE by + * simply adding a reference to it. If TARGET is read-only, the sections + * list in target gets duplicated before the modification. + * + * This is an API tailored for use by the svn_repos__authz_pool_t API to + * prevent breach of encapsulation. + */ +void +svn_config__shallow_replace_section(svn_config_t *target, + svn_config_t *source, + const char *section); + +/* Allocate *CFG_HASH and populate it with default, empty, + * svn_config_t for the configuration categories (@c + * SVN_CONFIG_CATEGORY_SERVERS, @c SVN_CONFIG_CATEGORY_CONFIG, etc.). + * This returns a hash equivalent to svn_config_get_config when the + * config files are empty. + */ +svn_error_t * +svn_config__get_default_config(apr_hash_t **cfg_hash, + apr_pool_t *pool); + +/** @} */ + + +/** + * @defgroup svn_bit_array Packed bit array handling API + * @{ + */ + +/* This opaque data struct is an alternative to an INT->VOID hash. + * + * Technically, it is an automatically growing packed bit array. + * All indexes not previously set are implicitly 0 and setting it will + * grow the array as needed. + */ +typedef struct svn_bit_array__t svn_bit_array__t; + +/* Return a new bit array allocated in POOL. MAX is a mere hint for + * the initial size of the array in bits. + */ +svn_bit_array__t * +svn_bit_array__create(apr_size_t max, + apr_pool_t *pool); + +/* Set bit at index IDX in ARRAY to VALUE. If necessary, grow the + * underlying data buffer, i.e. any IDX is valid unless we run OOM. + */ +void +svn_bit_array__set(svn_bit_array__t *array, + apr_size_t idx, + svn_boolean_t value); + +/* Get the bit value at index IDX in ARRAY. Bits not previously accessed + * are implicitly 0 (or FALSE). That implies IDX can never be out-of-range. + */ +svn_boolean_t +svn_bit_array__get(svn_bit_array__t *array, + apr_size_t idx); + +/* Return the global pool used by the DSO loader, this may be NULL if + no DSOs have been loaded. */ +apr_pool_t * +svn_dso__pool(void); + +/** @} */ + + +/* Return the xml (expat) version we compiled against. */ +const char *svn_xml__compiled_version(void); + +/* Return the xml (expat) version we run against. */ +const char *svn_xml__runtime_version(void); + +/* Return the zlib version we compiled against. */ +const char *svn_zlib__compiled_version(void); + +/* Return the zlib version we run against. */ +const char *svn_zlib__runtime_version(void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/subversion/include/private/svn_temp_serializer.h b/subversion/include/private/svn_temp_serializer.h index 7a007c3..dd2e047 100644 --- a/subversion/include/private/svn_temp_serializer.h +++ b/subversion/include/private/svn_temp_serializer.h @@ -143,6 +143,22 @@ void svn_temp_serializer__pop(svn_temp_serializer__context_t *context); /** + * Serialize a referenced sub-structure within the serialization + * @a context. @a source_struct must be a reference to the + * pointer in the original parent structure so that the correspondence in + * the serialized structure can be established. @a struct_size must match + * the result of @c sizeof() of the actual structure. + * + * This function is equivalent but more efficient than calling + * #svn_temp_serializer__push() immediately followed by + * #svn_temp_serializer__pop(). + */ +void +svn_temp_serializer__add_leaf(svn_temp_serializer__context_t *context, + const void * const * source_struct, + apr_size_t struct_size); + +/** * Serialize a string referenced from the current structure within the * serialization @a context. @a s must be a reference to the @c char* * pointer in the original structure so that the correspondence in the diff --git a/subversion/include/private/svn_utf_private.h b/subversion/include/private/svn_utf_private.h index 9f5a4ad..4584944 100644 --- a/subversion/include/private/svn_utf_private.h +++ b/subversion/include/private/svn_utf_private.h @@ -21,7 +21,7 @@ * @endcopyright * * @file svn_utf_private.h - * @brief UTF validation routines + * @brief UTF validation and normalization routines */ #ifndef SVN_UTF_PRIVATE_H @@ -31,6 +31,8 @@ #include <apr_pools.h> #include "svn_types.h" +#include "svn_string.h" +#include "svn_string_private.h" #ifdef __cplusplus extern "C" { @@ -71,6 +73,18 @@ svn_utf__last_valid(const char *src, apr_size_t len); const char * svn_utf__last_valid2(const char *src, apr_size_t len); +/* Copy LENGTH bytes of SRC, converting characters as follows: + - Pass characters from the ASCII subset to the result + - Strip all combining marks from the string + - Represent other valid Unicode chars as {U+XXXX} + - Replace invalid Unicode chars with {U?XXXX} + - Represent chars that are not valid UTF-8 as ?\XX + - Replace codes outside the Unicode range with a sequence of ?\XX + - Represent the null byte as \0 + Allocate the result in POOL. */ +const char * +svn_utf__fuzzy_escape(const char *src, apr_size_t length, apr_pool_t *pool); + const char * svn_utf__cstring_from_utf8_fuzzy(const char *src, apr_pool_t *pool, @@ -80,6 +94,166 @@ svn_utf__cstring_from_utf8_fuzzy(const char *src, apr_pool_t *)); +#if defined(WIN32) +/* On Windows: Convert the UTF-8 string SRC to UTF-16. + If PREFIX is not NULL, prepend it to the converted result. + The result, if not empty, will be allocated in RESULT_POOL. */ +svn_error_t * +svn_utf__win32_utf8_to_utf16(const WCHAR **result, + const char *src, + const WCHAR *prefix, + apr_pool_t *result_pool); + +/* On Windows: Convert the UTF-16 string SRC to UTF-8. + If PREFIX is not NULL, prepend it to the converted result. + The result, if not empty, will be allocated in RESULT_POOL. */ +svn_error_t * +svn_utf__win32_utf16_to_utf8(const char **result, + const WCHAR *src, + const char *prefix, + apr_pool_t *result_pool); +#endif /* WIN32*/ + + +/* A constant used for many length parameters in the utf8proc wrappers + * to indicate that the length of a string is unknonw. */ +#define SVN_UTF__UNKNOWN_LENGTH ((apr_size_t) -1) + + +/* Compare two UTF-8 strings, ignoring normalization, using buffers + * BUF1 and BUF2 for temporary storage. If either of LEN1 or LEN2 is + * SVN_UTF__UNKNOWN_LENGTH, assume the associated string is + * null-terminated; otherwise, consider the string only up to the + * given length. + * + * Return compare value in *RESULT. + */ +svn_error_t * +svn_utf__normcmp(int *result, + const char *str1, apr_size_t len1, + const char *str2, apr_size_t len2, + svn_membuf_t *buf1, svn_membuf_t *buf2); + +/* Normalize the UTF-8 string STR to form C, using BUF for temporary + * storage. If LEN is SVN_UTF__UNKNOWN_LENGTH, assume STR is + * null-terminated; otherwise, consider the string only up to the + * given length. + * + * Return the normalized string in *RESULT, which shares storage with + * BUF and is valid only until the next time BUF is modified. + * + * A returned error may indicate that STRING contains invalid UTF-8 or + * invalid Unicode codepoints. + */ +svn_error_t* +svn_utf__normalize(const char **result, + const char *str, apr_size_t len, + svn_membuf_t *buf); + +/* Check if STRING is a valid, NFC-normalized UTF-8 string. Note that + * a FALSE return value may indicate that STRING is not valid UTF-8 at + * all. + * + * Use SCRATCH_POOL for temporary allocations. + */ +svn_boolean_t +svn_utf__is_normalized(const char *string, apr_pool_t *scratch_pool); + +/* Encode an UCS-4 string to UTF-8, placing the result into BUFFER. + * While utf8proc does have a similar function, it does more checking + * and processing than we want here; this function does not attempt + * any normalizations but just encodes the individual code points. + * The encoded string will always be NUL-terminated. + * + * Return the length of the result (excluding the NUL terminator) in + * *result_length. + * + * A returned error indicates that a codepoint is invalid. + */ +svn_error_t * +svn_utf__encode_ucs4_string(svn_membuf_t *buffer, + const apr_int32_t *ucs4str, + apr_size_t length, + apr_size_t *result_length); + +/* Pattern matching similar to the the SQLite LIKE and GLOB + * operators. PATTERN, KEY and ESCAPE must all point to UTF-8 + * strings. Furthermore, ESCAPE, if provided, must be a character from + * the ASCII subset. + * + * If any of PATTERN_LEN, STRING_LEN or ESCAPE_LEN are + * SVN_UTF__UNKNOWN_LENGTH, assume the associated string is + * null-terminated; otherwise, consider the string only up to the + * given length. + * + * Use buffers PATTERN_BUF, STRING_BUF and TEMP_BUF for temporary storage. + * + * If SQL_LIKE is true, interpret PATTERN as a pattern used by the SQL + * LIKE operator and notice ESCAPE. Otherwise it's a Unix fileglob + * pattern, and ESCAPE must be NULL. + * + * Set *MATCH to the result of the comparison. +*/ +svn_error_t * +svn_utf__glob(svn_boolean_t *match, + const char *pattern, apr_size_t pattern_len, + const char *string, apr_size_t string_len, + const char *escape, apr_size_t escape_len, + svn_boolean_t sql_like, + svn_membuf_t *pattern_buf, + svn_membuf_t *string_buf, + svn_membuf_t *temp_buf); + +/* Return the compiled version of the wrapped utf8proc library. */ +const char * +svn_utf__utf8proc_compiled_version(void); + +/* Return the runtime version of the wrapped utf8proc library. */ +const char * +svn_utf__utf8proc_runtime_version(void); + +/* Convert an UTF-16 (or UCS-2) string to UTF-8, returning the pointer + * in RESULT. If BIG_ENDIAN is set, then UTF16STR is big-endian; + * otherwise, it's little-endian. + * + * If UTF16LEN is SVN_UTF__UNKNOWN_LENGTH, then UTF16STR must be + * terminated with a zero; otherwise, it is the number of 16-bit codes + * to convert, and the source string may contain NUL values. + * + * Allocate RESULT in RESULT_POOL and use SCRATCH_POOL for + * intermediate allocation. + * + * This function combines UTF-16 surrogate pairs into single code + * points, but will leave single lead or trail surrogates unchanged. + */ +svn_error_t * +svn_utf__utf16_to_utf8(const svn_string_t **result, + const apr_uint16_t *utf16str, + apr_size_t utf16len, + svn_boolean_t big_endian, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Convert an UTF-32 string to UTF-8, returning the pointer in + * RESULT. If BIG_ENDIAN is set, then UTF32STR is big-endian; + * otherwise, it's little-endian. + * + * If UTF32LEN is SVN_UTF__UNKNOWN_LENGTH, then UTF32STR must be + * terminated with a zero; otherwise, it is the number of 32-bit codes + * to convert, and the source string may contain NUL values. + * + * Allocate RESULT in RESULT_POOL and use SCRATCH_POOL for + * intermediate allocation. + */ +svn_error_t * +svn_utf__utf32_to_utf8(const svn_string_t **result, + const apr_int32_t *utf32str, + apr_size_t utf32len, + svn_boolean_t big_endian, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/subversion/include/private/svn_wc_private.h b/subversion/include/private/svn_wc_private.h index fce42b0..28d2247 100644 --- a/subversion/include/private/svn_wc_private.h +++ b/subversion/include/private/svn_wc_private.h @@ -82,8 +82,6 @@ svn_wc__get_file_external_editor(const svn_delta_editor_t **editor, const char *recorded_url, const svn_opt_revision_t *recorded_peg_rev, const svn_opt_revision_t *recorded_rev, - svn_wc_conflict_resolver_func2_t conflict_func, - void *conflict_baton, svn_cancel_func_t cancel_func, void *cancel_baton, svn_wc_notify_func2_t notify_func, @@ -354,7 +352,6 @@ svn_wc__get_wcroot(const char **wcroot_abspath, * before the 1.7 release. */ - /* * Convert from svn_wc_conflict_description2_t to * svn_wc_conflict_description_t. This is needed by some backwards-compat @@ -370,7 +367,11 @@ svn_wc__cd2_to_cd(const svn_wc_conflict_description2_t *conflict, /* * Convert from svn_wc_status3_t to svn_wc_status2_t. * Allocate the result in RESULT_POOL. + * + * Deprecated because svn_wc_status2_t is deprecated and the only + * calls are from other deprecated functions. */ +SVN_DEPRECATED svn_error_t * svn_wc__status2_from_3(svn_wc_status2_t **status, const svn_wc_status3_t *old_status, @@ -379,15 +380,13 @@ svn_wc__status2_from_3(svn_wc_status2_t **status, apr_pool_t *result_pool, apr_pool_t *scratch_pool); - /** * Set @a *children to a new array of the immediate children of the working * node at @a dir_abspath. The elements of @a *children are (const char *) * absolute paths. * - * Include children that are scheduled for deletion. Iff @a show_hidden - * is true, also include children that are 'excluded' or 'server-excluded' or - * 'not-present'. + * Include children that are scheduled for deletion, but not those that + * are excluded, server-excluded or not-present. * * Return every path that refers to a child of the working node at * @a dir_abspath. Do not include a path just because it was a child of a @@ -401,24 +400,20 @@ svn_error_t * svn_wc__node_get_children_of_working_node(const apr_array_header_t **children, svn_wc_context_t *wc_ctx, const char *dir_abspath, - svn_boolean_t show_hidden, apr_pool_t *result_pool, apr_pool_t *scratch_pool); /** - * Like svn_wc__node_get_children_of_working_node(), except also include any - * path that was a child of a deleted directory that existed at - * @a dir_abspath, even if that directory is now scheduled to be replaced by - * the working node at @a dir_abspath. + * Gets the immediate 'not-present' children of a node. + * + * #### Needed during 'svn cp WC URL' to handle mixed revision cases */ svn_error_t * -svn_wc__node_get_children(const apr_array_header_t **children, - svn_wc_context_t *wc_ctx, - const char *dir_abspath, - svn_boolean_t show_hidden, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool); - +svn_wc__node_get_not_present_children(const apr_array_header_t **children, + svn_wc_context_t *wc_ctx, + const char *dir_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); /** * Fetch the repository information for the working version @@ -442,18 +437,6 @@ svn_wc__node_get_repos_info(svn_revnum_t *revision, apr_pool_t *result_pool, apr_pool_t *scratch_pool); - - -/** - * Get the depth of @a local_abspath using @a wc_ctx. If @a local_abspath is - * not in the working copy, return @c SVN_ERR_WC_PATH_NOT_FOUND. - */ -svn_error_t * -svn_wc__node_get_depth(svn_depth_t *depth, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *scratch_pool); - /** * Get the changed revision, date and author for @a local_abspath using @a * wc_ctx. Allocate the return values in @a result_pool; use @a scratch_pool @@ -501,6 +484,8 @@ svn_wc__node_get_url(const char **url, * If not NULL, sets @a revision, @a repos_relpath, @a repos_root_url and * @a repos_uuid to the original (if a copy) or their current values. * + * If not NULL, set @a depth, to the recorded depth on @a local_abspath. + * * If @a copy_root_abspath is not NULL, and @a *is_copy indicates that the * node was copied, set @a *copy_root_abspath to the local absolute path of * the root of the copied subtree containing the node. If the copied node is @@ -519,6 +504,7 @@ svn_wc__node_get_origin(svn_boolean_t *is_copy, const char **repos_relpath, const char **repos_root_url, const char **repos_uuid, + svn_depth_t *depth, const char **copy_root_abspath, svn_wc_context_t *wc_ctx, const char *local_abspath, @@ -527,38 +513,6 @@ svn_wc__node_get_origin(svn_boolean_t *is_copy, apr_pool_t *scratch_pool); /** - * Set @a *is_deleted to TRUE if @a local_abspath is deleted, using - * @a wc_ctx. If @a local_abspath is not in the working copy, return - * @c SVN_ERR_WC_PATH_NOT_FOUND. Use @a scratch_pool for all temporary - * allocations. - */ -svn_error_t * -svn_wc__node_is_status_deleted(svn_boolean_t *is_deleted, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *scratch_pool); - -/** - * Set @a *deleted_ancestor_abspath to the root of the delete operation - * that deleted @a local_abspath. If @a local_abspath itself was deleted - * and has no deleted ancestor, @a *deleted_ancestor_abspath will equal - * @a local_abspath. If @a local_abspath was not deleted, - * set @a *deleted_ancestor_abspath to @c NULL. - * - * A node is considered 'deleted' if it is deleted or moved-away, and is - * not replaced. - * - * @a *deleted_ancestor_abspath is allocated in @a result_pool. - * Use @a scratch_pool for all temporary allocations. - */ -svn_error_t * -svn_wc__node_get_deleted_ancestor(const char **deleted_ancestor_abspath, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *result_pool, - apr_pool_t *scratch_pool); - -/** * Set @a *not_present to TRUE when @a local_abspath has status * svn_wc__db_status_not_present. Set @a *user_excluded to TRUE when * @a local_abspath has status svn_wc__db_status_excluded. Set @@ -641,7 +595,6 @@ svn_wc__node_get_base(svn_node_kind_t *kind, svn_wc_context_t *wc_ctx, const char *local_abspath, svn_boolean_t ignore_enoent, - svn_boolean_t show_hidden, apr_pool_t *result_pool, apr_pool_t *scratch_pool); @@ -771,20 +724,6 @@ svn_wc__call_with_write_lock(svn_wc__with_write_lock_func_t func, } while (0) -/** - * Calculates the schedule and copied status of a node as that would - * have been stored in an svn_wc_entry_t instance. - * - * If not @c NULL, @a schedule and @a copied are set to their calculated - * values. - */ -svn_error_t * -svn_wc__node_get_schedule(svn_wc_schedule_t *schedule, - svn_boolean_t *copied, - svn_wc_context_t *wc_ctx, - const char *local_abspath, - apr_pool_t *scratch_pool); - /** A callback invoked by svn_wc__prop_list_recursive(). * It is equivalent to svn_proplist_receiver_t declared in svn_client.h, * but kept private within the svn_wc__ namespace because it is used within @@ -978,15 +917,17 @@ svn_wc__get_excluded_subtrees(apr_hash_t **server_excluded_subtrees, /* Indicate in @a *is_modified whether the working copy has local * modifications, using context @a wc_ctx. - * Use @a scratch_pool for temporary allocations. * - * This function provides a subset of the functionality of - * svn_wc_revision_status2() and is more efficient if the caller - * doesn't need all information returned by svn_wc_revision_status2(). */ + * If IGNORE_UNVERSIONED, unversioned paths inside the tree rooted by + * LOCAL_ABSPATH are not seen as a change, otherwise they are. + * (svn:ignored paths are always ignored) + * + * Use @a scratch_pool for temporary allocations. */ svn_error_t * svn_wc__has_local_mods(svn_boolean_t *is_modified, svn_wc_context_t *wc_ctx, const char *local_abspath, + svn_boolean_t ignore_unversioned, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *scratch_pool); @@ -1294,6 +1235,44 @@ svn_wc__resolve_relative_external_url(const char **resolved_url, apr_pool_t *result_pool, apr_pool_t *scratch_pool); +typedef enum svn_wc__external_description_format_t +{ + /* LOCALPATH [-r PEG] URL */ + svn_wc__external_description_format_1 = 0, + + /* [-r REV] URL[@PEG] LOCALPATH, introduced in Subversion 1.5 */ + svn_wc__external_description_format_2 +} svn_wc__external_description_format_t; + +/* Additional information about what the external's parser has parsed. */ +typedef struct svn_wc__externals_parser_info_t +{ + /* The syntax format used by the external description. */ + svn_wc__external_description_format_t format; + + /* The string used for defining the operative revision, i.e. + "-rN", "-rHEAD", or "-r{DATE}". + NULL if revision was not given. */ + const char *rev_str; + + /* The string used for defining the peg revision (equals rev_str in + format 1, is "@N", or "@HEAD" or "@{DATE}" in format 2). + NULL if peg revision was not given. */ + const char *peg_rev_str; + +} svn_wc__externals_parser_info_t; + +/* Like svn_wc_parse_externals_description3() but returns an additional array + * with elements of type svn_wc__externals_parser_info_t in @a *parser_infos_p. + * @a parser_infos_p may be NULL if not required by the caller. + */ +svn_error_t * +svn_wc__parse_externals_description(apr_array_header_t **externals_p, + apr_array_header_t **parser_infos_p, + const char *defining_directory, + const char *desc, + svn_boolean_t canonicalize_url, + apr_pool_t *pool); /** * Set @a *editor and @a *edit_baton to an editor that generates @@ -1318,8 +1297,8 @@ svn_wc__resolve_relative_external_url(const char **resolved_url, * * Assuming the target is a directory, then: * - * - If @a get_all is FALSE, then only locally-modified entries will be - * returned. If TRUE, then all entries will be returned. + * - If @a get_all is @c FALSE, then only locally-modified entries will be + * returned. If @c TRUE, then all entries will be returned. * * - If @a depth is #svn_depth_empty, a status structure will * be returned for the target only; if #svn_depth_files, for the @@ -1334,6 +1313,9 @@ svn_wc__resolve_relative_external_url(const char **resolved_url, * If the given @a depth is incompatible with the depth found in a * working copy directory, the found depth always governs. * + * If @a check_working_copy is not set, do not scan the working copy + * for local modifications, taking only the BASE tree into account. + * * If @a no_ignore is set, statuses that would typically be ignored * will instead be reported. * @@ -1368,6 +1350,7 @@ svn_wc__get_status_editor(const svn_delta_editor_t **editor, const char *target_basename, svn_depth_t depth, svn_boolean_t get_all, + svn_boolean_t check_working_copy, svn_boolean_t no_ignore, svn_boolean_t depth_as_sticky, svn_boolean_t server_performs_filtering, @@ -1557,7 +1540,7 @@ svn_wc__get_switch_editor(const svn_delta_editor_t **editor, * Diffs will be reported as valid relpaths, with @a anchor_abspath being * the root (""). * - * @a callbacks/@a callback_baton is the callback table to use. + * @a diff_processor will retrieve the diff report. * * If @a depth is #svn_depth_empty, just diff exactly @a target or * @a anchor_path if @a target is empty. If #svn_depth_files then do the same @@ -1583,8 +1566,12 @@ svn_wc__get_switch_editor(const svn_delta_editor_t **editor, * if they weren't modified after being copied. This allows the callbacks * to generate appropriate --git diff headers for such files. * - * Normally, the difference from repository->working_copy is shown. - * If @a reverse_order is TRUE, then show working_copy->repository diffs. + * Normally, the difference from repository->working_copy is shown. If + * @a reverse_order is TRUE, then we want to show working_copy->repository + * diffs. Most of the reversal is done by the caller; here we just swap the + * order of reporting a replacement so that the local addition is reported + * before the remote delete. (The caller's diff processor can then transform + * adds into deletes and deletes into adds, but it can't reorder the output.) * * If @a cancel_func is non-NULL, it will be used along with @a cancel_baton * to periodically check if the client has canceled the operation. @@ -1628,14 +1615,11 @@ svn_wc__get_diff_editor(const svn_delta_editor_t **editor, const char *target, svn_depth_t depth, svn_boolean_t ignore_ancestry, - svn_boolean_t show_copies_as_adds, - svn_boolean_t use_git_diff_format, svn_boolean_t use_text_base, svn_boolean_t reverse_order, svn_boolean_t server_performs_filtering, const apr_array_header_t *changelist_filter, - const svn_wc_diff_callbacks4_t *callbacks, - void *callback_baton, + const svn_diff_tree_processor_t *diff_processor, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *result_pool, @@ -1840,6 +1824,29 @@ svn_wc__acquire_write_lock_for_resolve(const char **lock_root_abspath, const char *local_abspath, apr_pool_t *result_pool, apr_pool_t *scratch_pool); + +/* The implemementation of svn_wc_diff6(), but reporting to a diff processor + * + * If ROOT_RELPATH is not NULL, set *ROOT_RELPATH to the target of the diff + * within the diff namespace. ("" or a single path component). + * + * If ROOT_IS_FILE is NOT NULL set it + * the first processor call. (The anchor is LOCAL_ABSPATH or an ancestor of it) + */ +svn_error_t * +svn_wc__diff7(const char **root_relpath, + svn_boolean_t *root_is_dir, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_depth_t depth, + svn_boolean_t ignore_ancestry, + const apr_array_header_t *changelist_filter, + const svn_diff_tree_processor_t *diff_processor, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + #ifdef __cplusplus } #endif /* __cplusplus */ |