diff options
author | peter <peter@FreeBSD.org> | 2013-06-18 02:07:41 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2013-06-18 02:07:41 +0000 |
commit | d25dac7fcc6acc838b71bbda8916fd9665c709ab (patch) | |
tree | 135691142dc0e75a5e5d97b5074d03436435b8e0 /subversion/include/private | |
download | FreeBSD-src-d25dac7fcc6acc838b71bbda8916fd9665c709ab.zip FreeBSD-src-d25dac7fcc6acc838b71bbda8916fd9665c709ab.tar.gz |
Import trimmed svn-1.8.0-rc3
Diffstat (limited to 'subversion/include/private')
40 files changed, 10396 insertions, 0 deletions
diff --git a/subversion/include/private/README b/subversion/include/private/README new file mode 100644 index 0000000..05527e2 --- /dev/null +++ b/subversion/include/private/README @@ -0,0 +1,4 @@ +Header files in this private/ directory are for internal APIs shared +across Subversion's implementation. They are not part of the public +API, nor are they ever copied into or under the include/ directory +(e.g. by the installation process). diff --git a/subversion/include/private/ra_svn_sasl.h b/subversion/include/private/ra_svn_sasl.h new file mode 100644 index 0000000..428e20e --- /dev/null +++ b/subversion/include/private/ra_svn_sasl.h @@ -0,0 +1,86 @@ +/* + * ra_svn_sasl.h : SASL-related declarations shared between the + * ra_svn and svnserve module + * + * ==================================================================== + * 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 RA_SVN_SASL_H +#define RA_SVN_SASL_H + +#ifdef WIN32 +/* This prevents sasl.h from redefining iovec, which is always defined by APR + on win32. */ +#define STRUCT_IOVEC_DEFINED +#include <sasl.h> +#else +#include <sasl/sasl.h> +#endif + +#include <apr_errno.h> +#include <apr_pools.h> + +#include "svn_error.h" +#include "svn_ra_svn.h" + +#include "private/svn_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** The application and service name used for sasl_client_new, + * sasl_server_init, and sasl_server_new. */ +#define SVN_RA_SVN_SASL_NAME "svn" + +extern volatile svn_atomic_t svn_ra_svn__sasl_status; + +/* Initialize secprops with default values. */ +void +svn_ra_svn__default_secprops(sasl_security_properties_t *secprops); + +/* This function is called by the client and the server before + calling sasl_{client, server}_init, pool is used for allocations. */ +svn_error_t * +svn_ra_svn__sasl_common_init(apr_pool_t *pool); + +/* Sets local_addrport and remote_addrport to a string containing the + remote and local IP address and port, formatted like this: a.b.c.d;port. */ +svn_error_t * +svn_ra_svn__get_addresses(const char **local_addrport, + const char **remote_addrport, + svn_ra_svn_conn_t *conn, + apr_pool_t *pool); + +/* If a security layer was negotiated during the authentication exchange, + create an encrypted stream for conn. */ +svn_error_t * +svn_ra_svn__enable_sasl_encryption(svn_ra_svn_conn_t *conn, + sasl_conn_t *sasl_ctx, + apr_pool_t *pool); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* RA_SVN_SASL_H */ diff --git a/subversion/include/private/svn_adler32.h b/subversion/include/private/svn_adler32.h new file mode 100644 index 0000000..8c9bbd2 --- /dev/null +++ b/subversion/include/private/svn_adler32.h @@ -0,0 +1,52 @@ +/** + * @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_adler32.h + * @brief Subversion's take on Adler-32 calculation + */ + +#ifndef SVN_ADLER32_H +#define SVN_ADLER32_H + +#include <apr.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + * Return an adler32 checksum based on CHECKSUM, updated with + * DATA of size LEN. + * + * @since New in 1.7. + */ +apr_uint32_t +svn__adler32(apr_uint32_t checksum, const char *data, apr_off_t len); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* SVN_ADLER32_H */ diff --git a/subversion/include/private/svn_atomic.h b/subversion/include/private/svn_atomic.h new file mode 100644 index 0000000..187703b --- /dev/null +++ b/subversion/include/private/svn_atomic.h @@ -0,0 +1,123 @@ +/** + * @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_atomic.h + * @brief Macros and functions for atomic operations + */ + +#ifndef SVN_ATOMIC_H +#define SVN_ATOMIC_H + +#include <apr_version.h> +#include <apr_atomic.h> + +#include "svn_error.h" +#include "private/svn_dep_compat.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @name Macro definitions for atomic types and operations + * + * @note These are necessary because the apr_atomic API changed somewhat + * between apr-0.x and apr-1.x. + * @{ + */ + +/** 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. + * + * Compare the value that @a mem points to with @a cmp. If they are + * the same swap the value with @a with. + * + * @note svn_atomic_cas should not be combined with the other + * svn_atomic operations. A comment in apr_atomic.h explains + * 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 +/** @} */ + +/** + * Call an initialization function in a thread-safe manner. + * + * @a global_status must be a pointer to a global, zero-initialized + * #svn_atomic_t. @a init_func is a pointer to the function that performs + * the actual initialization. @a baton and and @a pool are passed on to the + * init_func for its use. + * + * @since New in 1.5. + */ +svn_error_t * +svn_atomic__init_once(volatile svn_atomic_t *global_status, + svn_error_t *(*init_func)(void*,apr_pool_t*), + void *baton, + apr_pool_t* pool); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_ATOMIC_H */ diff --git a/subversion/include/private/svn_auth_private.h b/subversion/include/private/svn_auth_private.h new file mode 100644 index 0000000..7a1c716 --- /dev/null +++ b/subversion/include/private/svn_auth_private.h @@ -0,0 +1,220 @@ +/** + * @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_auth_private.h + * @brief Subversion's authentication system - Internal routines + */ + +#ifndef SVN_AUTH_PRIVATE_H +#define SVN_AUTH_PRIVATE_H + +#include <apr_pools.h> +#include <apr_hash.h> + +#include "svn_types.h" +#include "svn_error.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* If you add a password type for a provider which stores + * passwords on disk in encrypted form, remember to update + * svn_auth__simple_save_creds_helper. Otherwise it will be + * assumed that your provider stores passwords in plaintext. */ +#define SVN_AUTH__SIMPLE_PASSWORD_TYPE "simple" +#define SVN_AUTH__WINCRYPT_PASSWORD_TYPE "wincrypt" +#define SVN_AUTH__KEYCHAIN_PASSWORD_TYPE "keychain" +#define SVN_AUTH__KWALLET_PASSWORD_TYPE "kwallet" +#define SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE "gnome-keyring" +#define SVN_AUTH__GPG_AGENT_PASSWORD_TYPE "gpg-agent" + +/* A function that stores in *PASSWORD (potentially after decrypting it) + the user's password. It might be obtained directly from CREDS, or + from an external store, using REALMSTRING and USERNAME as keys. + (The behavior is undefined if REALMSTRING or USERNAME are NULL.) + If NON_INTERACTIVE is set, the user must not be involved in the + retrieval process. Set *DONE to TRUE if a password was stored + in *PASSWORD, to FALSE otherwise. POOL is used for any necessary + allocation. */ +typedef svn_error_t * (*svn_auth__password_get_t) + (svn_boolean_t *done, + const char **password, + apr_hash_t *creds, + const char *realmstring, + const char *username, + apr_hash_t *parameters, + svn_boolean_t non_interactive, + apr_pool_t *pool); + +/* A function that stores PASSWORD (or some encrypted version thereof) + either directly in CREDS, or externally using REALMSTRING and USERNAME + as keys into the external store. If NON_INTERACTIVE is set, the user + must not be involved in the storage process. Set *DONE to TRUE if the + password was store, to FALSE otherwise. POOL is used for any necessary + allocation. */ +typedef svn_error_t * (*svn_auth__password_set_t) + (svn_boolean_t *done, + apr_hash_t *creds, + const char *realmstring, + const char *username, + const char *password, + apr_hash_t *parameters, + svn_boolean_t non_interactive, + apr_pool_t *pool); + +/* Use PARAMETERS and REALMSTRING to set *CREDENTIALS to a set of + pre-cached authentication credentials pulled from the simple + credential cache store identified by PASSTYPE. PASSWORD_GET is + used to obtain the password value. Allocate *CREDENTIALS from + POOL. + + NOTE: This function is a common implementation of code used by + several of the simple credential providers (the default disk cache + mechanism, Windows CryptoAPI, GNOME Keyring, etc.), typically in + their "first_creds" implementation. */ +svn_error_t * +svn_auth__simple_creds_cache_get(void **credentials, + void **iter_baton, + void *provider_baton, + apr_hash_t *parameters, + const char *realmstring, + svn_auth__password_get_t password_get, + const char *passtype, + apr_pool_t *pool); + +/* Use PARAMETERS and REALMSTRING to save CREDENTIALS in the simple + credential cache store identified by PASSTYPE. PASSWORD_SET is + used to do the actual storage. Use POOL for necessary allocations. + Set *SAVED according to whether or not the credentials were + successfully stored. + + NOTE: This function is a common implementation of code used by + several of the simple credential providers (the default disk cache + mechanism, Windows CryptoAPI, GNOME Keyring, etc.) typically in + their "save_creds" implementation. */ +svn_error_t * +svn_auth__simple_creds_cache_set(svn_boolean_t *saved, + void *credentials, + void *provider_baton, + apr_hash_t *parameters, + const char *realmstring, + svn_auth__password_set_t password_set, + const char *passtype, + apr_pool_t *pool); + +/* Implementation of svn_auth__password_get_t that retrieves + the plaintext password from CREDS when USERNAME matches the stored + credentials. */ +svn_error_t * +svn_auth__simple_password_get(svn_boolean_t *done, + const char **password, + apr_hash_t *creds, + const char *realmstring, + const char *username, + apr_hash_t *parameters, + svn_boolean_t non_interactive, + apr_pool_t *pool); + +/* Implementation of svn_auth__password_set_t that stores + the plaintext password in CREDS. */ +svn_error_t * +svn_auth__simple_password_set(svn_boolean_t *done, + apr_hash_t *creds, + const char *realmstring, + const char *username, + const char *password, + apr_hash_t *parameters, + svn_boolean_t non_interactive, + apr_pool_t *pool); + + +/* Use PARAMETERS and REALMSTRING to set *CREDENTIALS to a set of + pre-cached authentication credentials pulled from the SSL client + certificate passphrase credential cache store identified by + PASSTYPE. PASSPHRASE_GET is used to obtain the passphrase value. + Allocate *CREDENTIALS from POOL. + + NOTE: This function is a common implementation of code used by + several of the ssl client passphrase credential providers (the + default disk cache mechanism, Windows CryptoAPI, GNOME Keyring, + etc.), typically in their "first_creds" implementation. */ +svn_error_t * +svn_auth__ssl_client_cert_pw_cache_get(void **credentials, + void **iter_baton, + void *provider_baton, + apr_hash_t *parameters, + const char *realmstring, + svn_auth__password_get_t passphrase_get, + const char *passtype, + apr_pool_t *pool); + +/* Use PARAMETERS and REALMSTRING to save CREDENTIALS in the SSL + client certificate passphrase credential cache store identified by + PASSTYPE. PASSPHRASE_SET is used to do the actual storage. Use + POOL for necessary allocations. Set *SAVED according to whether or + not the credentials were successfully stored. + + NOTE: This function is a common implementation of code used by + several of the simple credential providers (the default disk cache + mechanism, Windows CryptoAPI, GNOME Keyring, etc.) typically in + their "save_creds" implementation. */ +svn_error_t * +svn_auth__ssl_client_cert_pw_cache_set(svn_boolean_t *saved, + void *credentials, + void *provider_baton, + apr_hash_t *parameters, + const char *realmstring, + svn_auth__password_set_t passphrase_set, + const char *passtype, + apr_pool_t *pool); + +/* This implements the svn_auth__password_get_t interface. + Set **PASSPHRASE to the plaintext passphrase retrieved from CREDS; + ignore other parameters. */ +svn_error_t * +svn_auth__ssl_client_cert_pw_get(svn_boolean_t *done, + const char **passphrase, + apr_hash_t *creds, + const char *realmstring, + const char *username, + apr_hash_t *parameters, + svn_boolean_t non_interactive, + apr_pool_t *pool); + +/* This implements the svn_auth__password_set_t interface. + Store PASSPHRASE in CREDS; ignore other parameters. */ +svn_error_t * +svn_auth__ssl_client_cert_pw_set(svn_boolean_t *done, + apr_hash_t *creds, + const char *realmstring, + const char *username, + const char *passphrase, + apr_hash_t *parameters, + svn_boolean_t non_interactive, + apr_pool_t *pool); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_AUTH_PRIVATE_H */ diff --git a/subversion/include/private/svn_cache.h b/subversion/include/private/svn_cache.h new file mode 100644 index 0000000..df40f7e --- /dev/null +++ b/subversion/include/private/svn_cache.h @@ -0,0 +1,486 @@ +/** + * @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_cache.h + * @brief In-memory cache implementation. + */ + + +#ifndef SVN_CACHE_H +#define SVN_CACHE_H + +#include <apr_pools.h> +#include <apr_hash.h> + +#include "svn_types.h" +#include "svn_error.h" +#include "svn_iter.h" +#include "svn_config.h" +#include "svn_string.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + +/** + * @defgroup svn_cache__support In-memory caching + * @{ + */ + +/** + * A function type for deserializing an object @a *out from the string + * @a data of length @a data_len into @a result_pool. It is legal and + * generally suggested that the deserialization will be done in-place, + * i.e. modify @a data directly and return it in @a *out. + */ +typedef svn_error_t *(*svn_cache__deserialize_func_t)(void **out, + void *data, + apr_size_t data_len, + apr_pool_t *result_pool); + +/** + * A function type for deserializing an object @a *out from the string + * @a data of length @a data_len into @a result_pool. The extra information + * @a baton passed into can be used to deserialize only a specific part or + * sub-structure or to perform any other non-modifying operation that may + * not require the whole structure to be processed. + */ +typedef svn_error_t *(*svn_cache__partial_getter_func_t)(void **out, + const void *data, + apr_size_t data_len, + void *baton, + apr_pool_t *result_pool); + +/** + * A function type for modifying an already deserialized in the @a *data + * buffer of length @a *data_len. Additional information of the modification + * to do will be provided in @a baton. The function may change the size of + * data buffer and may re-allocate it if necessary. In that case, the new + * values must be passed back in @a *data_len and @a *data, respectively. + * Allocations will be done from @a result_pool. + */ +typedef svn_error_t *(*svn_cache__partial_setter_func_t)(void **data, + apr_size_t *data_len, + void *baton, + apr_pool_t *result_pool); + +/** + * A function type for serializing an object @a in into bytes. The + * function should allocate the serialized value in @a result_pool, set + * @a *data to the serialized value, and set @a *data_len to its length. + */ +typedef svn_error_t *(*svn_cache__serialize_func_t)(void **data, + apr_size_t *data_len, + void *in, + apr_pool_t *result_pool); + +/** + * A function type for transforming or ignoring errors. @a scratch_pool may + * be used for temporary allocations. + */ +typedef svn_error_t *(*svn_cache__error_handler_t)(svn_error_t *err, + void *baton, + apr_pool_t *scratch_pool); + +/** + * A wrapper around apr_memcache_t, provided essentially so that the + * Subversion public API doesn't depend on whether or not you have + * access to the APR memcache libraries. + */ +typedef struct svn_memcache_t svn_memcache_t; + +/** + * An opaque structure representing a membuffer cache object. + */ +typedef struct svn_membuffer_t svn_membuffer_t; + +/** + * Opaque type for an in-memory cache. + */ +typedef struct svn_cache__t svn_cache__t; + +/** + * A structure containing typical statistics about a given cache instance. + * Use svn_cache__get_info() to get this data. Note that not all types + * of caches will be able to report complete and correct information. + */ +typedef struct svn_cache__info_t +{ + /** A string identifying the cache instance. Usually a copy of the @a id + * or @a prefix parameter passed to the cache constructor. + */ + const char* id; + + /** Number of getter calls (svn_cache__get() or svn_cache__get()). + */ + apr_uint64_t gets; + + /** Number of getter calls that return data. + */ + apr_uint64_t hits; + + /** Number of setter calls (svn_cache__set()). + */ + apr_uint64_t sets; + + /** Number of function calls that returned an error. + */ + apr_uint64_t failures; + + /** Size of the data currently stored in the cache. + * May be 0 if that information is not available. + */ + apr_uint64_t used_size; + + /** Amount of memory currently reserved for cached data. + * Will be equal to @a used_size if no precise information is available. + */ + apr_uint64_t data_size; + + /** Lower threshold of the total size of memory allocated to the cache and + * its index as well as management structures. The actual memory allocated + * by the cache may be larger. + */ + apr_uint64_t total_size; + + /** Number of cache entries. + * May be 0 if that information is not available. + */ + apr_uint64_t used_entries; + + /** Maximum numbers of cache entries. + * May be 0 if that information is not available. + */ + apr_uint64_t total_entries; +} svn_cache__info_t; + +/** + * Creates a new cache in @a *cache_p. This cache will use @a pool + * for all of its storage needs. The elements in the cache will be + * indexed by keys of length @a klen, which may be APR_HASH_KEY_STRING + * if they are strings. Cached values will be copied in and out of + * the cache using @a serialize_func and @a deserialize_func, respectively. + * + * The cache stores up to @a pages * @a items_per_page items at a + * time. The exact cache invalidation strategy is not defined here, + * but in general, a lower value for @a items_per_page means more + * memory overhead for the same number of items, but a higher value + * for @a items_per_page means more items are cleared at once. Both + * @a pages and @a items_per_page must be positive (though they both + * may certainly be 1). + * + * If @a thread_safe is true, and APR is compiled with threads, all + * accesses to the cache will be protected with a mutex. The @a id + * is a purely user-visible information that will allow coders to + * identify this cache instance in a #svn_cache__info_t struct. + * It does not influence the behavior of the cache itself. + * + * Note that NULL is a legitimate value for cache entries (and + * @a serialize_func will not be called on it). + * + * It is not safe for @a serialize_func nor @a deserialize_func to + * interact with the cache itself. + */ +svn_error_t * +svn_cache__create_inprocess(svn_cache__t **cache_p, + svn_cache__serialize_func_t serialize_func, + svn_cache__deserialize_func_t deserialize_func, + apr_ssize_t klen, + apr_int64_t pages, + apr_int64_t items_per_page, + svn_boolean_t thread_safe, + const char *id, + apr_pool_t *pool); + +/** + * Creates a new cache in @a *cache_p, communicating to a memcached + * process via @a memcache. The elements in the cache will be indexed + * by keys of length @a klen, which may be APR_HASH_KEY_STRING if they + * are strings. Values will be serialized for memcached using @a + * serialize_func and deserialized using @a deserialize_func. Because + * the same memcached server may cache many different kinds of values, + * @a prefix should be specified to differentiate this cache from + * other caches. @a *cache_p will be allocated in @a result_pool. + * + * If @a deserialize_func is NULL, then the data is returned as an + * svn_string_t; if @a serialize_func is NULL, then the data is + * assumed to be an svn_stringbuf_t. + * + * These caches are always thread safe. + * + * These caches do not support svn_cache__iter. + * + * If Subversion was not built with apr_memcache support, always + * raises SVN_ERR_NO_APR_MEMCACHE. + */ +svn_error_t * +svn_cache__create_memcache(svn_cache__t **cache_p, + svn_memcache_t *memcache, + svn_cache__serialize_func_t serialize_func, + svn_cache__deserialize_func_t deserialize_func, + apr_ssize_t klen, + const char *prefix, + apr_pool_t *result_pool); + +/** + * 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. + * + * 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 + * use memcache. + */ +svn_error_t * +svn_cache__make_memcache_from_config(svn_memcache_t **memcache_p, + svn_config_t *config, + apr_pool_t *result_pool); + +/** + * Creates a new membuffer cache object in @a *cache. It will contain + * up to @a total_size bytes of data, using @a directory_size bytes + * for index information and the remainder for serialized objects. + * + * Since each index entry is about 50 bytes long, 1 to 10 percent of + * the @a total_size should be allocated to the @a directory_size, + * depending on the average serialized object size. Higher percentages + * will generally result in higher hit rates and reduced conflict + * resolution overhead. + * + * The cache will be split into @a segment_count segments of equal size. + * A higher number reduces lock contention but also limits the maximum + * cachable item size. If it is not a power of two, it will be rounded + * down to next lower power of two. Also, there is an implementation + * specific upper limit and the setting will be capped there automatically. + * If the number is 0, a default will be derived from @a total_size. + * + * If access to the resulting cache object is guaranteed to be serialized, + * @a thread_safe may be set to @c FALSE for maximum performance. + * + * There is no limit on the number of threads reading a given cache segment + * concurrently. Writes, however, need an exclusive lock on the respective + * segment. @a allow_blocking_writes controls contention is handled here. + * If set to TRUE, writes will wait until the lock becomes available, i.e. + * reads should be short. If set to FALSE, write attempts will be ignored + * (no data being written to the cache) if some reader or another writer + * currently holds the segment lock. + * + * Allocations will be made in @a result_pool, in particular the data buffers. + */ +svn_error_t * +svn_cache__membuffer_cache_create(svn_membuffer_t **cache, + apr_size_t total_size, + apr_size_t directory_size, + apr_size_t segment_count, + svn_boolean_t thread_safe, + svn_boolean_t allow_blocking_writes, + apr_pool_t *result_pool); + +/** + * 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 + * are strings. Values will be serialized for the memcache using @a + * 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. + * + * If @a deserialize_func is NULL, then the data is returned as an + * svn_string_t; if @a serialize_func is NULL, then the data is + * assumed to be an svn_stringbuf_t. + * + * If @a thread_safe is true, and APR is compiled with threads, all + * accesses to the cache will be protected with a mutex, if the shared + * @a memcache has also been created with thread_safe flag set. + * + * These caches do not support svn_cache__iter. + */ +svn_error_t * +svn_cache__create_membuffer_cache(svn_cache__t **cache_p, + svn_membuffer_t *membuffer, + svn_cache__serialize_func_t serialize, + svn_cache__deserialize_func_t deserialize, + apr_ssize_t klen, + const char *prefix, + svn_boolean_t thread_safe, + apr_pool_t *result_pool); + +/** + * Sets @a handler to be @a cache's error handling routine. If any + * error is returned from a call to svn_cache__get or svn_cache__set, @a + * handler will be called with @a baton and the error, and the + * original function will return whatever error @a handler returns + * instead (possibly SVN_NO_ERROR); @a handler will receive the pool + * passed to the svn_cache_* function. @a scratch_pool is used for temporary + * allocations. + */ +svn_error_t * +svn_cache__set_error_handler(svn_cache__t *cache, + svn_cache__error_handler_t handler, + void *baton, + apr_pool_t *scratch_pool); + +/** + * Returns @c TRUE if the @a cache supports objects of the given @a size. + * There is no guarantee, that svn_cache__set() will actually store the + * respective object in that case. However, a @c FALSE return value indicates + * that an attempt to cache the item will either fail or impair the overall + * cache performance. @c FALSE will also be returned if @a cache is @c NULL. + */ +svn_boolean_t +svn_cache__is_cachable(svn_cache__t *cache, + apr_size_t size); + +#define SVN_CACHE_CONFIG_CATEGORY_MEMCACHED_SERVERS "memcached-servers" + +/** + * Fetches a value indexed by @a key from @a cache into @a *value, + * setting @a *found to TRUE iff it is in the cache and FALSE if it is + * not found. @a key may be NULL in which case @a *found will be + * FALSE. The value is copied into @a result_pool using the deserialize + * function provided to the cache's constructor. + */ +svn_error_t * +svn_cache__get(void **value, + svn_boolean_t *found, + svn_cache__t *cache, + const void *key, + apr_pool_t *result_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 + * have shorter lifetimes than the cache). @a key may be NULL in which + * case the cache will remain unchanged. + * + * If there is already a value for @a key, this will replace it. Bear + * in mind that in some circumstances this may leak memory (that is, + * the cache's copy of the previous value may not be immediately + * cleared); it is only guaranteed to not leak for caches created with + * @a items_per_page equal to 1. + */ +svn_error_t * +svn_cache__set(svn_cache__t *cache, + const void *key, + void *value, + apr_pool_t *scratch_pool); + +/** + * Iterates over the elements currently in @a cache, calling @a func + * for each one until there are no more elements or @a func returns an + * error. Uses @a scratch_pool for temporary allocations. + * + * If @a completed is not NULL, then on return - if @a func returns no + * errors - @a *completed will be set to @c TRUE. + * + * If @a func returns an error other than @c SVN_ERR_ITER_BREAK, that + * error is returned. When @a func returns @c SVN_ERR_ITER_BREAK, + * iteration is interrupted, but no error is returned and @a + * *completed is set to @c FALSE. (The error handler set by + * svn_cache__set_error_handler is not used for svn_cache__iter.) + * + * It is not legal to perform any other cache operations on @a cache + * inside @a func. + * + * svn_cache__iter is not supported by all cache implementations; see + * the svn_cache__create_* function for details. + */ +svn_error_t * +svn_cache__iter(svn_boolean_t *completed, + svn_cache__t *cache, + svn_iter_apr_hash_cb_t func, + void *baton, + apr_pool_t *scratch_pool); + +/** + * Similar to svn_cache__get() but will call a specific de-serialization + * function @a func. @a found will be set depending on whether the @a key + * has been found. Even if that reports @c TRUE, @a value may still return + * a @c NULL pointer depending on the logic inside @a func. For a @a NULL + * @a key, no data will be found. @a value will be allocated in + * @a result_pool. + */ +svn_error_t * +svn_cache__get_partial(void **value, + svn_boolean_t *found, + svn_cache__t *cache, + const void *key, + svn_cache__partial_getter_func_t func, + void *baton, + apr_pool_t *result_pool); + +/** + * Find the item identified by @a key in the @a cache. If it has been found, + * call @a func for it and @a baton to potentially modify the data. Changed + * data will be written back to the cache. If the item cannot be found, + * or if @a key is NULL, @a func does not get called. @a scratch_pool is + * used for temporary allocations. + */ +svn_error_t * +svn_cache__set_partial(svn_cache__t *cache, + const void *key, + svn_cache__partial_setter_func_t func, + void *baton, + apr_pool_t *scratch_pool); + +/** + * Collect all available usage statistics on the cache instance @a cache + * and write the data into @a info. If @a reset has been set, access + * counters will be reset right after copying the statistics info. + * @a result_pool will be used for allocations. + */ +svn_error_t * +svn_cache__get_info(svn_cache__t *cache, + svn_cache__info_t *info, + svn_boolean_t reset, + apr_pool_t *result_pool); + +/** + * Return the information given in @a info formatted as a multi-line string. + * Allocations take place in @a result_pool. + */ +svn_string_t * +svn_cache__format_info(const svn_cache__info_t *info, + apr_pool_t *result_pool); + +/* 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. + * + * @since New in 1.7. + */ +struct svn_membuffer_t * +svn_cache__get_global_membuffer_cache(void); + +/** @} */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_CACHE_H */ diff --git a/subversion/include/private/svn_client_private.h b/subversion/include/private/svn_client_private.h new file mode 100644 index 0000000..9eebc18 --- /dev/null +++ b/subversion/include/private/svn_client_private.h @@ -0,0 +1,299 @@ +/** + * @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_private.h + * @brief Subversion-internal client APIs. + */ + +#ifndef SVN_CLIENT_PRIVATE_H +#define SVN_CLIENT_PRIVATE_H + +#include <apr_pools.h> + +#include "svn_ra.h" +#include "svn_client.h" +#include "svn_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* 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) \ + ((kind) == svn_opt_revision_base || \ + (kind) == svn_opt_revision_previous || \ + (kind) == svn_opt_revision_working || \ + (kind) == svn_opt_revision_committed) \ + +/* Return true if KIND is a revision kind that the WC can supply without + * contacting the repository. Otherwise, return false. */ +#define SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(kind) \ + ((kind) == svn_opt_revision_base || \ + (kind) == svn_opt_revision_working || \ + (kind) == svn_opt_revision_committed) + +/* A location in a repository. */ +typedef struct svn_client__pathrev_t +{ + const char *repos_root_url; + const char *repos_uuid; + svn_revnum_t rev; + const char *url; +} svn_client__pathrev_t; + +/* Return a new path-rev structure, allocated in RESULT_POOL, + * initialized with deep copies of REPOS_ROOT_URL, REPOS_UUID, REV and URL. */ +svn_client__pathrev_t * +svn_client__pathrev_create(const char *repos_root_url, + const char *repos_uuid, + svn_revnum_t rev, + const char *url, + apr_pool_t *result_pool); + +/* Return a new path-rev structure, allocated in RESULT_POOL, + * initialized with deep copies of REPOS_ROOT_URL, REPOS_UUID, and REV, + * and using the repository-relative RELPATH to construct the URL. */ +svn_client__pathrev_t * +svn_client__pathrev_create_with_relpath(const char *repos_root_url, + const char *repos_uuid, + svn_revnum_t rev, + const char *relpath, + apr_pool_t *result_pool); + +/* Set *PATHREV_P to a new path-rev structure, allocated in RESULT_POOL, + * initialized with deep copies of the repository root URL and UUID from + * RA_SESSION, and of REV and URL. */ +svn_error_t * +svn_client__pathrev_create_with_session(svn_client__pathrev_t **pathrev_p, + svn_ra_session_t *ra_session, + svn_revnum_t rev, + const char *url, + apr_pool_t *result_pool); + +/* Return a deep copy of PATHREV, allocated in RESULT_POOL. */ +svn_client__pathrev_t * +svn_client__pathrev_dup(const svn_client__pathrev_t *pathrev, + apr_pool_t *result_pool); + +/* Return a deep copy of PATHREV, with a URI-encoded representation of + * RELPATH joined on to the URL. Allocate the result in RESULT_POOL. */ +svn_client__pathrev_t * +svn_client__pathrev_join_relpath(const svn_client__pathrev_t *pathrev, + const char *relpath, + apr_pool_t *result_pool); + +/* Return the repository-relative relpath of PATHREV. */ +const char * +svn_client__pathrev_relpath(const svn_client__pathrev_t *pathrev, + apr_pool_t *result_pool); + +/* Return the repository-relative fspath of PATHREV. */ +const char * +svn_client__pathrev_fspath(const svn_client__pathrev_t *pathrev, + apr_pool_t *result_pool); + +/* Given PATH_OR_URL, which contains either a working copy path or an + absolute URL, a peg revision PEG_REVISION, and a desired revision + REVISION, create an RA connection to that object as it exists in + that revision, following copy history if necessary. If REVISION is + younger than PEG_REVISION, then PATH_OR_URL will be checked to see + that it is the same node in both PEG_REVISION and REVISION. If it + is not, then @c SVN_ERR_CLIENT_UNRELATED_RESOURCES is returned. + + BASE_DIR_ABSPATH is the working copy path the ra_session corresponds + to. If provided it will be used to read and dav props. So if provided + this directory MUST match the session anchor. + + If PEG_REVISION->kind is 'unspecified', the peg revision is 'head' + for a URL or 'working' for a WC path. If REVISION->kind is + 'unspecified', the operative revision is the peg revision. + + Store the resulting ra_session in *RA_SESSION_P. Store the final + resolved location of the object in *RESOLVED_LOC_P. RESOLVED_LOC_P + may be NULL if not wanted. + + Use authentication baton cached in CTX to authenticate against the + repository. + + Use POOL for all allocations. */ +svn_error_t * +svn_client__ra_session_from_path2(svn_ra_session_t **ra_session_p, + svn_client__pathrev_t **resolved_loc_p, + const char *path_or_url, + const char *base_dir_abspath, + const svn_opt_revision_t *peg_revision, + const svn_opt_revision_t *revision, + svn_client_ctx_t *ctx, + apr_pool_t *pool); + +/* Given PATH_OR_URL, which contains either a working copy path or an + absolute URL, a peg revision PEG_REVISION, and a desired revision + REVISION, find the path at which that object exists in REVISION, + following copy history if necessary. If REVISION is younger than + PEG_REVISION, then check that PATH_OR_URL is the same node in both + PEG_REVISION and REVISION, and return @c + SVN_ERR_CLIENT_UNRELATED_RESOURCES if it is not the same node. + + If PEG_REVISION->kind is 'unspecified', the peg revision is 'head' + for a URL or 'working' for a WC path. If REVISION->kind is + 'unspecified', the operative revision is the peg revision. + + Store the actual location of the object in *RESOLVED_LOC_P. + + RA_SESSION should be an open RA session pointing at the URL of + PATH_OR_URL, or NULL, in which case this function will open its own + temporary session. + + Use authentication baton cached in CTX to authenticate against the + repository. + + Use POOL for all allocations. */ +svn_error_t * +svn_client__resolve_rev_and_url(svn_client__pathrev_t **resolved_loc_p, + svn_ra_session_t *ra_session, + const char *path_or_url, + const svn_opt_revision_t *peg_revision, + const svn_opt_revision_t *revision, + svn_client_ctx_t *ctx, + apr_pool_t *pool); + +/** Return @c SVN_ERR_ILLEGAL_TARGET if TARGETS contains a mixture of + * URLs and paths; otherwise return SVN_NO_ERROR. + * + * @since New in 1.7. + */ +svn_error_t * +svn_client__assert_homogeneous_target_type(const apr_array_header_t *targets); + + +/* Create a svn_client_status_t structure *CST for LOCAL_ABSPATH, shallow + * copying data from *STATUS wherever possible and retrieving the other values + * where needed. Perform temporary allocations in SCRATCH_POOL and allocate the + * result in RESULT_POOL + */ +svn_error_t * +svn_client__create_status(svn_client_status_t **cst, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + const svn_wc_status3_t *status, + 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(). + * + * Set *BASE_P to the location that this node was checked out at or last + * updated/switched to, regardless of any uncommitted changes (delete, + * replace and/or copy-here/move-here). + * + * If there is no base node at LOCAL_ABSPATH (such as when there is a + * locally added/copied/moved-here node that is not part of a replace), + * set *BASE_P to NULL. + */ +svn_error_t * +svn_client__wc_node_get_base(svn_client__pathrev_t **base_p, + const char *wc_abspath, + svn_wc_context_t *wc_ctx, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Get the original location of the WC node at LOCAL_ABSPATH. + * + * A pathrev_t wrapper around svn_wc__node_get_origin(). + * + * Set *ORIGIN_P to the origin of the WC node at WC_ABSPATH. If the node + * is a local copy, give the copy-from location. If the node is locally + * added or deleted, set *ORIGIN_P to NULL. + */ +svn_error_t * +svn_client__wc_node_get_origin(svn_client__pathrev_t **origin_p, + const char *wc_abspath, + svn_client_ctx_t *ctx, + 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. + * + * If URL specifies a directory, create the copy using depth DEPTH. + * + * If MAKE_PARENTS is TRUE and DST_ABSPATH doesn't have an added parent + * create missing parent directories + */ +svn_error_t * +svn_client__copy_foreign(const char *url, + const char *dst_abspath, + svn_opt_revision_t *peg_revision, + svn_opt_revision_t *revision, + svn_depth_t depth, + svn_boolean_t make_parents, + svn_boolean_t already_locked, + svn_client_ctx_t *ctx, + apr_pool_t *scratch_pool); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_CLIENT_PRIVATE_H */ diff --git a/subversion/include/private/svn_cmdline_private.h b/subversion/include/private/svn_cmdline_private.h new file mode 100644 index 0000000..ad16b66 --- /dev/null +++ b/subversion/include/private/svn_cmdline_private.h @@ -0,0 +1,228 @@ +/** + * @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_cmdline_private.h + * @brief Private functions for Subversion cmdline. + */ + +#ifndef SVN_CMDLINE_PRIVATE_H +#define SVN_CMDLINE_PRIVATE_H + +#include <apr_pools.h> +#include <apr_hash.h> + +#include "svn_string.h" +#include "svn_error.h" +#include "svn_io.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** Write a property as an XML element into @a *outstr. + * + * If @a outstr is NULL, allocate @a *outstr in @a pool; else append to + * @a *outstr, allocating in @a outstr's pool + * + * @a propname is the property name. @a propval is the property value, which + * will be encoded if it contains unsafe bytes. + * + * If @a inherited_prop is TRUE then @a propname is an inherited property, + * otherwise @a propname is an explicit property. + */ +void +svn_cmdline__print_xml_prop(svn_stringbuf_t **outstr, + const char *propname, + svn_string_t *propval, + svn_boolean_t inherited_prop, + apr_pool_t *pool); + + +/** An implementation of @c svn_auth_gnome_keyring_unlock_prompt_func_t that + * prompts the user for default GNOME Keyring password. + * + * Expects a @c svn_cmdline_prompt_baton2_t to be passed as @a baton. + * + * @since New in 1.6. + */ +svn_error_t * +svn_cmdline__auth_gnome_keyring_unlock_prompt(char **keyring_password, + const char *keyring_name, + void *baton, + apr_pool_t *pool); + +/** Container for config options parsed with svn_cmdline__parse_config_option + * + * @since New in 1.7. + */ +typedef struct svn_cmdline__config_argument_t +{ + const char *file; + const char *section; + const char *option; + const char *value; +} svn_cmdline__config_argument_t; + +/** Parser for 'FILE:SECTION:OPTION=[VALUE]'-style option arguments. + * + * Parses @a opt_arg and places its value in @a config_options, an apr array + * containing svn_cmdline__config_argument_t* elements, allocating the option + * data in @a pool + * + * @since New in 1.7. + */ +svn_error_t * +svn_cmdline__parse_config_option(apr_array_header_t *config_options, + const char *opt_arg, + apr_pool_t *pool); + +/** Sets the config options in @a config_options, an apr array containing + * @c svn_cmdline__config_argument_t* elements, to the configuration in @a cfg, + * a hash mapping of <tt>const char *</tt> configuration file names to + * @c svn_config_t *'s. Write warnings to stderr. + * + * Use @a prefix as prefix and @a argument_name in warning messages. + * + * @since New in 1.7. + */ +svn_error_t * +svn_cmdline__apply_config_options(apr_hash_t *config, + const apr_array_header_t *config_options, + const char *prefix, + const char *argument_name); + +/* Return a string allocated in POOL that is a copy of STR but with each + * line prefixed with INDENT. A line is all characters up to the first + * CR-LF, LF-CR, CR or LF, or the end of STR if sooner. */ +const char * +svn_cmdline__indent_string(const char *str, + const char *indent, + apr_pool_t *pool); + +/* Print to stdout a hash PROP_HASH that maps property names (char *) to + property values (svn_string_t *). The names are assumed to be in UTF-8 + format; the values are either in UTF-8 (the special Subversion props) or + plain binary values. + + If OUT is not NULL, then write to it rather than stdout. + + If NAMES_ONLY is true, print just names, else print names and + values. */ +svn_error_t * +svn_cmdline__print_prop_hash(svn_stream_t *out, + apr_hash_t *prop_hash, + svn_boolean_t names_only, + apr_pool_t *pool); + +/* Similar to svn_cmdline__print_prop_hash(), only output xml to *OUTSTR. + If INHERITED_PROPS is true, then PROP_HASH contains inherited properties, + otherwise PROP_HASH contains explicit properties. If *OUTSTR is NULL, + allocate it first from POOL, otherwise append to it. */ +svn_error_t * +svn_cmdline__print_xml_prop_hash(svn_stringbuf_t **outstr, + apr_hash_t *prop_hash, + svn_boolean_t names_only, + svn_boolean_t inherited_props, + apr_pool_t *pool); + + +/* Search for a text editor command in standard environment variables, + and invoke it to edit PATH. Use POOL for all allocations. + + If EDITOR_CMD is not NULL, it is the name of the external editor + command to use, overriding anything else that might determine the + editor. + + CONFIG is a hash of svn_config_t * items keyed on a configuration + category (SVN_CONFIG_CATEGORY_CONFIG et al), and may be NULL. */ +svn_error_t * +svn_cmdline__edit_file_externally(const char *path, + const char *editor_cmd, + apr_hash_t *config, + apr_pool_t *pool); + +/* Search for a text editor command in standard environment variables, + and invoke it to edit CONTENTS (using a temporary file created in + directory BASE_DIR). Return the new contents in *EDITED_CONTENTS, + or set *EDITED_CONTENTS to NULL if no edit was performed. + + If EDITOR_CMD is not NULL, it is the name of the external editor + command to use, overriding anything else that might determine the + editor. + + If TMPFILE_LEFT is NULL, the temporary file will be destroyed. + Else, the file will be left on disk, and its path returned in + *TMPFILE_LEFT. + + CONFIG is a hash of svn_config_t * items keyed on a configuration + category (SVN_CONFIG_CATEGORY_CONFIG et al), and may be NULL. + + If AS_TEXT is TRUE, recode CONTENTS and convert to native eol-style before + editing and back again afterwards. In this case, ENCODING determines the + encoding used during editing. If non-NULL, use the named encoding, else + use the system encoding. If AS_TEXT is FALSE, don't do any translation. + In that case, ENCODING is ignored. + + Use POOL for all allocations. Use PREFIX as the prefix for the + temporary file used by the editor. + + If return error, *EDITED_CONTENTS is not touched. */ +svn_error_t * +svn_cmdline__edit_string_externally(svn_string_t **edited_contents, + const char **tmpfile_left, + const char *editor_cmd, + const char *base_dir, + const svn_string_t *contents, + const char *prefix, + apr_hash_t *config, + svn_boolean_t as_text, + const char *encoding, + apr_pool_t *pool); + + +/** Wrapper for apr_getopt_init(), which see. + * + * @since New in 1.4. + */ +svn_error_t * +svn_cmdline__getopt_init(apr_getopt_t **os, + int argc, + const char *argv[], + apr_pool_t *pool); + +/* Determine whether interactive mode should be enabled, based on whether + * the user passed the --non-interactive or --force-interactive options. + * If neither option was passed, interactivity is enabled if standard + * input is connected to a terminal device. + * + * @since New in 1.8. + */ +svn_boolean_t +svn_cmdline__be_interactive(svn_boolean_t non_interactive, + svn_boolean_t force_interactive); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_CMDLINE_PRIVATE_H */ diff --git a/subversion/include/private/svn_dav_protocol.h b/subversion/include/private/svn_dav_protocol.h new file mode 100644 index 0000000..94cf069 --- /dev/null +++ b/subversion/include/private/svn_dav_protocol.h @@ -0,0 +1,68 @@ +/* + * svn_dav_protocol.h: Declarations of the protocol shared by the + * mod_dav_svn backend for httpd's mod_dav and its ra_serf RA DAV clients. + * + * ==================================================================== + * 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_DAV_PROTOCOL_H +#define SVN_DAV_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** Names for the custom HTTP REPORTs understood by mod_dav_svn, sans + namespace. */ +#define SVN_DAV__MERGEINFO_REPORT "mergeinfo-report" +#define SVN_DAV__INHERITED_PROPS_REPORT "inherited-props-report" + +/** Names for XML child elements of the custom HTTP REPORTs understood + by mod_dav_svn, sans namespace. */ +#define SVN_DAV__CREATIONDATE "creationdate" +#define SVN_DAV__MERGEINFO_ITEM "mergeinfo-item" +#define SVN_DAV__MERGEINFO_PATH "mergeinfo-path" +#define SVN_DAV__MERGEINFO_INFO "mergeinfo-info" +#define SVN_DAV__PATH "path" +#define SVN_DAV__INHERIT "inherit" +#define SVN_DAV__REVISION "revision" +#define SVN_DAV__INCLUDE_DESCENDANTS "include-descendants" +#define SVN_DAV__VERSION_NAME "version-name" +#define SVN_DAV__IPROP_ITEM "iprop-item" +#define SVN_DAV__IPROP_PATH "iprop-path" +#define SVN_DAV__IPROP_PROPNAME "iprop-propname" +#define SVN_DAV__IPROP_PROPVAL "iprop-propval" + +/** Names of XML elements attributes and tags for svn_ra_change_rev_prop2()'s + extension of PROPPATCH. */ +#define SVN_DAV__OLD_VALUE "old-value" +#define SVN_DAV__OLD_VALUE__ABSENT "absent" + +/** Helper typedef for svn_ra_change_rev_prop2() implementation. */ +typedef struct svn_dav__two_props_t { + const svn_string_t *const *old_value_p; + const svn_string_t *new_value; +} svn_dav__two_props_t; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_DAV_PROTOCOL_H */ diff --git a/subversion/include/private/svn_debug.h b/subversion/include/private/svn_debug.h new file mode 100644 index 0000000..a596ba1 --- /dev/null +++ b/subversion/include/private/svn_debug.h @@ -0,0 +1,107 @@ +/* svn_debug.h : handy little debug tools for the SVN developers + * + * ==================================================================== + * 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_DEBUG_H +#define SVN_DEBUG_H + +#ifdef SVN_DEBUG +#define SVN_DBG__PROTOTYPES +#endif + +#ifdef SVN_DBG__PROTOTYPES +#define APR_WANT_STDIO +#include <apr_want.h> +#include <apr_hash.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef SVN_DBG__PROTOTYPES +/* A few helper functions for the macros below. */ +void +svn_dbg__preamble(const char *file, long line, FILE *output); +void +svn_dbg__printf(const char *fmt, ...) + __attribute__((format(printf, 1, 2))); +void +svn_dbg__print_props(apr_hash_t *props, + const char *header_fmt, + ...) + __attribute__((format(printf, 2, 3))); +#endif + +/* Only available when SVN_DEBUG is defined (ie. svn developers). Note that + we do *not* provide replacement macros/functions for proper releases. + The debug stuff should be removed before a commit. + + ### maybe we will eventually decide to allow certain debug stuff to + ### remain in the code. at that point, we can rejigger this header. */ +#ifdef SVN_DEBUG + +/* Print to stdout. Edit this line if you need stderr. */ +#define SVN_DBG_OUTPUT stdout + + +/* Defining this symbol in the source file, BEFORE INCLUDING THIS HEADER, + will switch off the output. Calls will still be made to svn_dbg__preamble() + for breakpoints. */ +#ifdef SVN_DBG_QUIET + +#define SVN_DBG(ARGS) svn_dbg__preamble(__FILE__, __LINE__, NULL) +#define SVN_DBG_PROPS(ARGS) svn_dbg__preamble(__FILE__, __LINE__, NULL) + +#else + +/** Debug aid macro that prints the file:line of the call and printf-like + * arguments to the #SVN_DBG_OUTPUT stdio stream (#stdout by default). Typical + * usage: + * + * <pre> + * SVN_DBG(("rev=%ld kind=%s\n", revnum, svn_node_kind_to_word(kind))); + * </pre> + * + * outputs: + * + * <pre> + * DBG: kitchensink.c: 42: rev=3141592 kind=file + * </pre> + * + * Note that these output lines are filtered by our test suite automatically, + * so you don't have to worry about throwing off expected output. + */ +#define SVN_DBG(ARGS) (svn_dbg__preamble(__FILE__, __LINE__, SVN_DBG_OUTPUT), \ + svn_dbg__printf ARGS) +#define SVN_DBG_PROPS(ARGS) (svn_dbg__preamble(__FILE__, __LINE__, \ + SVN_DBG_OUTPUT), \ + svn_dbg__print_props ARGS) + +#endif + +#endif /* SVN_DEBUG */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_DEBUG_H */ diff --git a/subversion/include/private/svn_delta_private.h b/subversion/include/private/svn_delta_private.h new file mode 100644 index 0000000..4de85a9 --- /dev/null +++ b/subversion/include/private/svn_delta_private.h @@ -0,0 +1,128 @@ +/** + * @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_delta_private.h + * @brief The Subversion delta/diff/editor library - Internal routines + */ + +#ifndef SVN_DELTA_PRIVATE_H +#define SVN_DELTA_PRIVATE_H + +#include <apr_pools.h> + +#include "svn_types.h" +#include "svn_error.h" +#include "svn_delta.h" +#include "svn_editor.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +typedef svn_error_t *(*svn_delta__start_edit_func_t)( + void *baton, + svn_revnum_t base_revision); + +typedef svn_error_t *(*svn_delta__target_revision_func_t)( + void *baton, + svn_revnum_t target_revision, + apr_pool_t *scratch_pool); + +typedef svn_error_t *(*svn_delta__unlock_func_t)( + void *baton, + const char *path, + apr_pool_t *scratch_pool); + + +/* See svn_editor__insert_shims() for more information. */ +struct svn_delta__extra_baton +{ + svn_delta__start_edit_func_t start_edit; + svn_delta__target_revision_func_t target_revision; + void *baton; +}; + + +/** A temporary API to convert from a delta editor to an Ev2 editor. */ +svn_error_t * +svn_delta__editor_from_delta(svn_editor_t **editor_p, + struct svn_delta__extra_baton **exb, + svn_delta__unlock_func_t *unlock_func, + void **unlock_baton, + const svn_delta_editor_t *deditor, + void *dedit_baton, + svn_boolean_t *send_abs_paths, + const char *repos_root, + const char *base_relpath, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_delta_fetch_kind_func_t fetch_kind_func, + void *fetch_kind_baton, + svn_delta_fetch_props_func_t fetch_props_func, + void *fetch_props_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/** A temporary API to convert from an Ev2 editor to a delta editor. */ +svn_error_t * +svn_delta__delta_from_editor(const svn_delta_editor_t **deditor, + void **dedit_baton, + svn_editor_t *editor, + svn_delta__unlock_func_t unlock_func, + void *unlock_baton, + svn_boolean_t *found_abs_paths, + const char *repos_root, + const char *base_relpath, + svn_delta_fetch_props_func_t fetch_props_func, + void *fetch_props_baton, + svn_delta_fetch_base_func_t fetch_base_func, + void *fetch_base_baton, + 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. + */ +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); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_DELTA_PRIVATE_H */ diff --git a/subversion/include/private/svn_dep_compat.h b/subversion/include/private/svn_dep_compat.h new file mode 100644 index 0000000..71c0b9a --- /dev/null +++ b/subversion/include/private/svn_dep_compat.h @@ -0,0 +1,184 @@ +/** + * @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_compat.h + * @brief Compatibility macros and functions. + * @since New in 1.5.0. + */ + +#ifndef SVN_DEP_COMPAT_H +#define SVN_DEP_COMPAT_H + +#include <apr_version.h> + +#ifdef __cplusplus +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"). + * + * @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. + */ +#if !APR_VERSION_AT_LEAST(1,3,0) +#define apr_array_clear(arr) (arr)->nelts = 0 +#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. + */ +#define apr_hash_clear(ht) svn_hash__clear(ht) +#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 +#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 + * acquired under Unix. Under Windows, this will not work. So, provide + * a more portable substitute. + * + * @since New in 1.8. + */ +#ifdef WIN32 +#define SVN_LOCK_IS_BUSY(x) \ + (APR_STATUS_IS_EBUSY(x) || (x) == APR_FROM_OS_ERROR(WAIT_TIMEOUT)) +#else +#define SVN_LOCK_IS_BUSY(x) APR_STATUS_IS_EBUSY(x) +#endif + +/** + * Check at compile time if the Serf 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"). + * + * @since New in 1.5. + */ +#ifndef SERF_VERSION_AT_LEAST /* Introduced in Serf 0.1.1 */ +#define SERF_VERSION_AT_LEAST(major,minor,patch) \ +(((major) < SERF_MAJOR_VERSION) \ + || ((major) == SERF_MAJOR_VERSION && (minor) < SERF_MINOR_VERSION) \ + || ((major) == SERF_MAJOR_VERSION && (minor) == SERF_MINOR_VERSION && \ + (patch) <= SERF_PATCH_VERSION)) +#endif /* SERF_VERSION_AT_LEAST */ + +/** + * By default, if libsvn is built against one version of SQLite + * and then run using an older version, svn will error out: + * + * svn: Couldn't perform atomic initialization + * svn: SQLite compiled for 3.7.4, but running with 3.7.3 + * + * That can be annoying when building on a modern system in order + * to deploy on a less modern one. So these constants allow one + * to specify how old the system being deployed on might be. + * For example, + * + * EXTRA_CFLAGS += -DSVN_SQLITE_MIN_VERSION_NUMBER=3007003 + * EXTRA_CFLAGS += '-DSVN_SQLITE_MIN_VERSION="3.7.3"' + * + * turns on code that works around infelicities in older versions + * as far back as 3.7.3 and relaxes the check at initialization time + * to permit them. + * + * @since New in 1.8. + */ +#ifndef SVN_SQLITE_MIN_VERSION_NUMBER +#define SVN_SQLITE_MIN_VERSION_NUMBER SQLITE_VERSION_NUMBER +#define SVN_SQLITE_MIN_VERSION SQLITE_VERSION +#endif /* SVN_SQLITE_MIN_VERSION_NUMBER */ + +/** + * Check at compile time if the SQLite 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"). + * + * @since New in 1.6. + */ +#ifndef SQLITE_VERSION_AT_LEAST +#define SQLITE_VERSION_AT_LEAST(major,minor,patch) \ +((major*1000000 + minor*1000 + patch) <= SVN_SQLITE_MIN_VERSION_NUMBER) +#endif /* SQLITE_VERSION_AT_LEAST */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_DEP_COMPAT_H */ diff --git a/subversion/include/private/svn_diff_private.h b/subversion/include/private/svn_diff_private.h new file mode 100644 index 0000000..3b6e591 --- /dev/null +++ b/subversion/include/private/svn_diff_private.h @@ -0,0 +1,115 @@ +/** + * @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 + */ + + +#ifndef SVN_DIFF_PRIVATE_H +#define SVN_DIFF_PRIVATE_H + +#include <apr_pools.h> +#include <apr_tables.h> + +#include "svn_types.h" +#include "svn_io.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + +/* The separator string used below the "Index:" or similar line of + * Subversion's Unidiff-like diff format. */ +#define SVN_DIFF__EQUAL_STRING \ + "===================================================================" + +/* The separator string used below the "Properties on ..." line of + * Subversion's Unidiff-like diff format. */ +#define SVN_DIFF__UNDER_STRING \ + "___________________________________________________________________" + +/* The string used to mark a line in a hunk that doesn't end with a newline, + * when diffing a file. Intentionally not marked for translation, for wider + * interoperability with patch(1) programs. */ +#define SVN_DIFF__NO_NEWLINE_AT_END_OF_FILE \ + "\\ No newline at end of file" + +/* The string used to mark a line in a hunk that doesn't end with a newline, + * when diffing a Subversion property. */ +#define SVN_DIFF__NO_NEWLINE_AT_END_OF_PROPERTY \ + "\\ No newline at end of property" + +/* Write a unidiff "---" and "+++" header to OUTPUT_STREAM. + * + * Write "---" followed by a space and OLD_HEADER and a newline, + * then "+++" followed by a space and NEW_HEADER and a newline. + * + * The text will be encoded into HEADER_ENCODING. + */ +svn_error_t * +svn_diff__unidiff_write_header(svn_stream_t *output_stream, + const char *header_encoding, + const char *old_header, + const char *new_header, + apr_pool_t *scratch_pool); + +/* Display property changes in pseudo-Unidiff format. + * + * Write to @a outstream the changes described by @a propchanges based on + * original properties @a original_props. + * + * Write all mark-up text (headers and so on) using the character encoding + * @a encoding. + * + * ### I think the idea is: we want the output to use @a encoding, and + * we will assume the text of the user's files and the values of any + * user-defined properties are already using @a encoding, so we don't + * want to re-code the *whole* output. + * So, shouldn't we also convert all prop names and all 'svn:*' prop + * values to @a encoding, since we know those are stored in UTF-8? + * + * @a original_props is a hash mapping (const char *) property names to + * (svn_string_t *) values. @a propchanges is an array of svn_prop_t + * representing the new values for any of the properties that changed, with + * a NULL value to represent deletion. + * + * If @a pretty_print_mergeinfo is true, then describe 'svn:mergeinfo' + * property changes in a human-readable form that says what changes were + * merged or reverse merged; otherwise (or if the mergeinfo property values + * don't parse correctly) display them just like any other property. + * + * Use @a pool for temporary allocations. + */ +svn_error_t * +svn_diff__display_prop_diffs(svn_stream_t *outstream, + const char *encoding, + const apr_array_header_t *propchanges, + apr_hash_t *original_props, + svn_boolean_t pretty_print_mergeinfo, + apr_pool_t *pool); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_DIFF_PRIVATE_H */ diff --git a/subversion/include/private/svn_diff_tree.h b/subversion/include/private/svn_diff_tree.h new file mode 100644 index 0000000..597a59b --- /dev/null +++ b/subversion/include/private/svn_diff_tree.h @@ -0,0 +1,357 @@ +/** + * @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_wc.h + * @brief Generic diff handler. Replacing the old svn_wc_diff_callbacks4_t + * infrastructure + */ + +#ifndef SVN_DIFF_PROCESSOR_H +#define SVN_DIFF_PROCESSOR_H + +#include "svn_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* + * About the diff tree processor. + * + * Subversion uses two kinds of editors to describe changes. One to + * describe changes on how to *exactly* transform one tree to another tree, + * as efficiently as possible and one to describe the difference between trees + * in order to review the changes, or to allow applying them on a third tree + * which is similar to those other trees. + * + * The first case was originally handled by svn_delta_editor_t and might be + * replaced by svn_editor_t in a future version. This diff processor handles + * the other case and as such forms the layer below our diff and merge + * handling. + * + * The major difference between this and the other editors is that this diff + * always provides access to the full text and/or properties in the left and + * right tree when applicable to allow processor implementers to decide how + * to interpret changes. + * + * Originally this diff processor was not formalized explicitly, but + * informally handled by the working copy diff callbacks. These callbacks just + * provided the information to drive a unified diff and a textual merge. To go + * one step further and allow full tree conflict detection we needed a better + * defined diff handling. Instead of adding yet a few more functions and + * arguments to the already overloaded diff callbacks the api was completely + * redesigned with a few points in mind. + * + * * It must be able to drive the old callbacks interface without users + * noticing the difference (100% compatible). + * (Implemented as svn_wc__wrap_diff_callbacks()) + * + * * It should provide the information that was missing in the old interface, + * but required to close existing issues. + * + * E.g. - properties and children on deleted directories. + * - revision numbers and copyfrom information on directories. + * + * To cleanup the implementation and make it easier on diff processors to + * handle the results I also added the following constraints. + * + * * Diffs should be fully reversable: anything that is deleted should be + * available, just like something that is added. + * (Proven via svn_diff__tree_processor_reverse_create) + * ### Still in doubt if *_deleted() needs a copy_to argument, for the + * ### 99% -> 100%. + * + * * Diff processors should have an easy way to communicate that they are + * not interrested in certain expensive to obtain results. + * + * * Directories should have clear open and close events to allow adding them + * before their children, but still allowing property changes to have + * defined behavior. + * + * * Files and directories should be handled as similar as possible as in + * many cases they are just nodes in a tree. + * + * * It should be easy to create diff wrappers to apply certain transforms. + * + * During the creation an additional requirement of knowing about 'some + * absent' nodes was added, to allow the merge to work on just this processor + * api. + * + * The api describes a clean open-close walk through a tree, depending on the + * driver multiple siblings can be described at the same time, but when a + * directory is closed all descendants are done. + * + * 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!) + * + * 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 */ +typedef struct svn_diff_source_t +{ + /* Always available */ + svn_revnum_t revision; + + /* Depending on the driver available for copyfrom */ + const char *repos_relpath; +} svn_diff_source_t; + +/** + * A callback vtable invoked by our diff-editors, as they receive diffs + * from the server. 'svn diff' and 'svn merge' implement their own versions + * of this vtable. + * + * All callbacks receive the processor and at least a parent baton. Forwarding + * the processor allows future extensions to call into the old functions without + * revving the entire API. + * + * Users must call svn_diff__tree_processor_create() to allow adding new + * callbacks later. (E.g. when we decide how to add move support) These + * extensions can then just call into other callbacks. + * + * @since New in 1.8. + */ +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 */ + + /* Called before a directories children are processed. + * + * Set *SKIP_CHILDREN to TRUE, to skip calling callbacks for all + * children. + * + * Set *SKIP to TRUE to skip calling the added, deleted, changed + * or closed callback for this node only. + */ + svn_error_t * + (*dir_opened)(void **new_dir_baton, + svn_boolean_t *skip, + svn_boolean_t *skip_children, + const char *relpath, + const svn_diff_source_t *left_source, + const svn_diff_source_t *right_source, + const svn_diff_source_t *copyfrom_source, + void *parent_dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + /* Called after a directory and all its children are added + */ + svn_error_t * + (*dir_added)(const char *relpath, + const svn_diff_source_t *copyfrom_source, + const svn_diff_source_t *right_source, + /*const*/ apr_hash_t *copyfrom_props, + /*const*/ apr_hash_t *right_props, + void *dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called after all children of this node are reported as deleted. + * + * The default implementation calls dir_closed(). + */ + svn_error_t * + (*dir_deleted)(const char *relpath, + const svn_diff_source_t *left_source, + /*const*/ apr_hash_t *left_props, + void *dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called instead of dir_closed() if the properties on the directory + * were modified. + * + * The default implementation calls dir_closed(). + */ + svn_error_t * + (*dir_changed)(const char *relpath, + const svn_diff_source_t *left_source, + const svn_diff_source_t *right_source, + /*const*/ apr_hash_t *left_props, + /*const*/ apr_hash_t *right_props, + const apr_array_header_t *prop_changes, + void *dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called when a directory is closed without applying changes to + * the directory itself. + * + * When dir_changed or dir_deleted are handled by the default implementation + * they call dir_closed() + */ + svn_error_t * + (*dir_closed)(const char *relpath, + const svn_diff_source_t *left_source, + const svn_diff_source_t *right_source, + void *dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called before file_added(), file_deleted(), file_changed() and + file_closed() + */ + svn_error_t * + (*file_opened)(void **new_file_baton, + svn_boolean_t *skip, + const char *relpath, + const svn_diff_source_t *left_source, + const svn_diff_source_t *right_source, + const svn_diff_source_t *copyfrom_source, + void *dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + /* Called after file_opened() for newly added and copied files */ + svn_error_t * + (*file_added)(const char *relpath, + const svn_diff_source_t *copyfrom_source, + const svn_diff_source_t *right_source, + const char *copyfrom_file, + const char *right_file, + /*const*/ apr_hash_t *copyfrom_props, + /*const*/ apr_hash_t *right_props, + void *file_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called after file_opened() for deleted or moved away files */ + svn_error_t * + (*file_deleted)(const char *relpath, + const svn_diff_source_t *left_source, + const char *left_file, + /*const*/ apr_hash_t *left_props, + void *file_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called after file_opened() for changed files */ + svn_error_t * + (*file_changed)(const char *relpath, + const svn_diff_source_t *left_source, + const svn_diff_source_t *right_source, + const char *left_file, + const char *right_file, + /*const*/ apr_hash_t *left_props, + /*const*/ apr_hash_t *right_props, + svn_boolean_t file_modified, + const apr_array_header_t *prop_changes, + void *file_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called after file_opened() for unmodified files */ + svn_error_t * + (*file_closed)(const char *relpath, + const svn_diff_source_t *left_source, + const svn_diff_source_t *right_source, + void *file_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); + + /* Called when encountering a marker for an absent file or directory */ + svn_error_t * + (*node_absent)(const char *relpath, + void *dir_baton, + const struct svn_diff_tree_processor_t *processor, + apr_pool_t *scratch_pool); +} svn_diff_tree_processor_t; + +/** + * Create a new svn_diff_tree_processor_t instance with all functions + * set to a callback doing nothing but copying the parent baton to + * the new baton. + * + * @since New in 1.8. + */ +svn_diff_tree_processor_t * +svn_diff__tree_processor_create(void *baton, + apr_pool_t *result_pool); + +/** + * Create a new svn_diff_tree_processor_t instance with all functions setup + * to call into another svn_diff_tree_processor_t processor, but with all + * adds and deletes inverted. + * + * @since New in 1.8. + */ /* Used by libsvn clients repository diff */ +const svn_diff_tree_processor_t * +svn_diff__tree_processor_reverse_create(const svn_diff_tree_processor_t * processor, + const char *prefix_relpath, + apr_pool_t *result_pool); + +/** + * Create a new svn_diff_tree_processor_t instance with all functions setup + * to call into processor for all paths equal to and below prefix_relpath. + * + * @since New in 1.8. + */ /* Used by libsvn clients repository diff */ +const svn_diff_tree_processor_t * +svn_diff__tree_processor_filter_create(const svn_diff_tree_processor_t *processor, + const char *prefix_relpath, + apr_pool_t *result_pool); + +/** + * Create a new svn_diff_tree_processor_t instace with all function setup + * to call into processor with all adds with copyfrom information transformed + * to simple node changes. + * + * @since New in 1.8. + */ /* Used by libsvn_wc diff editor */ +const svn_diff_tree_processor_t * +svn_diff__tree_processor_copy_as_changed_create( + const svn_diff_tree_processor_t *processor, + apr_pool_t *result_pool); + + +/** + * Create a new svn_diff_tree_processor_t instance with all functions setup + * to first call into processor1 and then processor2. + * + * This function is mostly a debug and migration helper. + * + * @since New in 1.8. + */ /* Used by libsvn clients repository diff */ +const svn_diff_tree_processor_t * +svn_diff__tree_processor_tee_create(const svn_diff_tree_processor_t *processor1, + const svn_diff_tree_processor_t *processor2, + apr_pool_t *result_pool); + + +svn_diff_source_t * +svn_diff__source_create(svn_revnum_t revision, + apr_pool_t *result_pool); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_DIFF_PROCESSOR_H */ + diff --git a/subversion/include/private/svn_doxygen.h b/subversion/include/private/svn_doxygen.h new file mode 100644 index 0000000..426e3f7 --- /dev/null +++ b/subversion/include/private/svn_doxygen.h @@ -0,0 +1,32 @@ +/* + * + * 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. + * + */ + +/** + * @mainpage Subversion Documentation + * + * This documentation covers the public APIs provided by the Subversion + * libraries. It is intended mainly for programmers, both those working + * on Subversion itself, as well as developers of 3rd-party applications + * intending to use these APIs. For more information about using Subversion, + * see the Subversion Book at http://svnbook.red-bean.com/. + * + * To learn more about Subversion, please visit http://subversion.apache.org/. + */ diff --git a/subversion/include/private/svn_editor.h b/subversion/include/private/svn_editor.h new file mode 100644 index 0000000..d714bb1 --- /dev/null +++ b/subversion/include/private/svn_editor.h @@ -0,0 +1,1194 @@ +/** + * @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_editor.h + * @brief Tree editing functions and structures + */ + +#ifndef SVN_EDITOR_H +#define SVN_EDITOR_H + +#include <apr_pools.h> + +#include "svn_types.h" +#include "svn_error.h" +#include "svn_io.h" /* for svn_stream_t */ +#include "svn_delta.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/*** Temporarily private stuff (should move to svn_delta.h when Editor + V2 is made public) ***/ + +/** Callback to retrieve a node's entire set of properties. This is + * needed by the various editor shims in order to effect backwards + * compatibility. + * + * Implementations should set @a *props to the hash of properties + * associated with @a path in @a base_revision, allocating that hash + * and its contents in @a result_pool, and should use @a scratch_pool + * for temporary allocations. + * + * @a baton is an implementation-specific closure. + */ +typedef svn_error_t *(*svn_delta_fetch_props_func_t)( + apr_hash_t **props, + void *baton, + const char *path, + svn_revnum_t base_revision, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool + ); + +/** Callback to retrieve a node's kind. This is needed by the various + * editor shims in order to effect backwards compatibility. + * + * Implementations should set @a *kind to the node kind of @a path in + * @a base_revision, using @a scratch_pool for temporary allocations. + * + * @a baton is an implementation-specific closure. + */ +typedef svn_error_t *(*svn_delta_fetch_kind_func_t)( + svn_node_kind_t *kind, + void *baton, + const char *path, + svn_revnum_t base_revision, + apr_pool_t *scratch_pool + ); + +/** Callback to fetch the name of a file to use as a delta base. + * + * Implementations should set @a *filename to the name of a file + * suitable for use as a delta base for @a path in @a base_revision + * (allocating @a *filename from @a result_pool), or to @c NULL if the + * base stream is empty. @a scratch_pool is provided for temporary + * allocations. + * + * @a baton is an implementation-specific closure. + */ +typedef svn_error_t *(*svn_delta_fetch_base_func_t)( + const char **filename, + void *baton, + const char *path, + svn_revnum_t base_revision, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool + ); + +/** Collection of callbacks used for the shim code. This structure + * may grow additional fields in the future. Therefore, always use + * svn_delta_shim_callbacks_default() to allocate new instances of it. + */ +typedef struct svn_delta_shim_callbacks_t +{ + svn_delta_fetch_props_func_t fetch_props_func; + svn_delta_fetch_kind_func_t fetch_kind_func; + svn_delta_fetch_base_func_t fetch_base_func; + void *fetch_baton; +} svn_delta_shim_callbacks_t; + +/** Return a collection of default shim functions in @a result_pool. + */ +svn_delta_shim_callbacks_t * +svn_delta_shim_callbacks_default(apr_pool_t *result_pool); + + + +/** Transforming trees ("editing"). + * + * In Subversion, we have a number of occasions where we transform a tree + * from one state into another. This process is called "editing" a tree. + * + * In processing a `commit' command: + * - The client examines its working copy data to determine the set of + * changes necessary to transform its base tree into the desired target. + * - The client networking library delivers that set of changes/operations + * across the wire as an equivalent series of network requests (for + * example, to svnserve as an ra_svn protocol stream, or to an + * Apache httpd server as WebDAV commands) + * - The server receives those requests and applies the sequence of + * operations on a revision, producing a transaction representing the + * desired target. + * - The Subversion server then commits the transaction to the filesystem. + * + * In processing an `update' command, the process is reversed: + * - The Subversion server module talks to the filesystem and computes a + * set of changes necessary to bring the client's working copy up to date. + * - The server serializes this description of changes, and delivers it to + * the client. + * - The client networking library receives that reply, producing a set + * of changes/operations to alter the working copy into the revision + * requested by the update command. + * - The working copy library applies those operations to the working copy + * to align it with the requested update target. + * + * The series of changes (or operations) necessary to transform a tree from + * one state into another is passed between subsystems using this "editor" + * interface. The "receiver" edits its tree according to the operations + * described by the "driver". + * + * Note that the driver must have a perfect understanding of the tree which + * the receiver will be applying edits upon. There is no room for error here, + * and the interface embodies assumptions/requirements that the driver has + * about the targeted tree. As a result, this interface is a standardized + * mechanism of *describing* those change operations, but the intimate + * knowledge between the driver and the receiver implies some level of + * coupling between those subsystems. + * + * The set of changes, and the data necessary to describe it entirely, is + * completely unbounded. An addition of one simple 20 GB file might be well + * past the available memory of a machine processing these operations. + * As a result, the API to describe the changes is designed to be applied + * in a sequential (and relatively random-access) model. The operations + * can be streamed from the driver to the receiver, resulting in the + * receiver editing its tree to the target state defined by the driver. + * + * + * <h3>History</h3> + * + * Classically, Subversion had a notion of a "tree delta" which could be + * passed around as an independent entity. Theory implied this delta was an + * entity in its own right, to be used when and where necessary. + * Unfortunately, this theory did not work well in practice. The producer + * and consumer of these tree deltas were (and are) tightly coupled. As noted + * above, the tree delta producer needed to be *totally* aware of the tree + * that it needed to edit. So rather than telling the delta consumer how to + * edit its tree, the classic #svn_delta_editor_t interface focused + * entirely on the tree delta, an intermediate (logical) data structure + * which was unusable outside of the particular, coupled pairing of producer + * and consumer. This generation of the API forgoes the logical tree delta + * entity and directly passes the necessary edits/changes/operations from + * the producer to the consumer. In our new parlance, one subsystem "drives" + * a set of operations describing the change, and a "receiver" accepts and + * applies them to its tree. + * + * The classic interface was named #svn_delta_editor_t and was described + * idiomatically as the "editor interface". This generation of the interface + * retains the "editor" name for that reason. All notions of a "tree delta" + * structure are no longer part of this interface. + * + * The old interface was purely vtable-based and used a number of special + * editors which could be interposed between the driver and receiver. Those + * editors provided cancellation, debugging, and other various operations. + * While the "interposition" pattern is still possible with this interface, + * the most common functionality (cancellation and debugging) have been + * integrated directly into this new editor system. + * + * + * <h3>Implementation Plan</h3> + * @note This section can be removed after Ev2 is fully implemented. + * + * The delta editor is pretty engrained throughout Subversion, so attempting + * to replace it in situ is somewhat akin to performing open heart surgery + * while the patient is running a marathon. However, a viable plan should + * make things a bit easier, and help parallelize the work. + * + * In short, the following items need to be done: + * -# Implement backward compatibility wrappers ("shims") + * -# Use shims to update editor consumers to Ev2 + * -# Update editor producers to drive Ev2 + * - This will largely involve rewriting the RA layers to accept and + * send Ev2 commands + * -# Optimize consumers and producers to leverage the features of Ev2 + * + * The shims are largely self-contained, and as of this writing, are almost + * complete. They can be released without much ado. However, they do add + * <em>significant</em> performance regressions, which make releasing code + * which is half-delta-editor and half-Ev2 inadvisable. As such, the updating + * of producers and consumers to Ev2 will probably need to wait until 1.9, + * though it could be largely parallelized. + * + * + * @defgroup svn_editor The editor interface + * @{ + */ + +/** An abstract object that edits a target tree. + * + * @note The term "follow" means at any later time in the editor drive. + * Terms such as "must", "must not", "required", "shall", "shall not", + * "should", "should not", "recommended", "may", and "optional" in this + * document are to be interpreted as described in RFC 2119. + * + * @note The editor objects are *not* reentrant. The receiver should not + * directly or indirectly invoke an editor API with the same object unless + * it has been marked as explicitly supporting reentrancy during a + * receiver's callback. This limitation extends to the cancellation + * callback, too. (This limitation is due to the scratch_pool shared by + * all callbacks, and cleared after each callback; a reentrant call could + * clear the outer call's pool). Note that the code itself is reentrant, so + * there is no problem using the APIs on different editor objects. + * + * \n + * <h3>Life-Cycle</h3> + * + * - @b Create: A receiver uses svn_editor_create() to create an + * "empty" svn_editor_t. It cannot be used yet, since it still lacks + * actual callback functions. svn_editor_create() sets the + * #svn_editor_t's callback baton and scratch pool that the callback + * functions receive, as well as a cancellation callback and baton + * (see "Cancellation" below). + * + * - @b Set callbacks: The receiver calls svn_editor_setcb_many() or a + * succession of the other svn_editor_setcb_*() functions to tell + * #svn_editor_t which functions to call when driven by the various + * operations. Callback functions are implemented by the receiver and must + * adhere to the @c svn_editor_cb_*_t function types as expected by the + * svn_editor_setcb_*() functions. See: \n + * svn_editor_cb_many_t \n + * svn_editor_setcb_many() \n + * or \n + * svn_editor_setcb_add_directory() \n + * svn_editor_setcb_add_file() \n + * svn_editor_setcb_add_symlink() \n + * svn_editor_setcb_add_absent() \n + * svn_editor_setcb_alter_directory() \n + * svn_editor_setcb_alter_file() \n + * svn_editor_setcb_alter_symlink() \n + * 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() + * + * - @b Drive: The driver is provided with the completed #svn_editor_t + * instance. (It is typically passed to a generic driving + * API, which could receive the driving editor calls over the network + * by providing a proxy #svn_editor_t on the remote side.) + * The driver invokes the #svn_editor_t instance's callback functions + * according to the restrictions defined below, in order to describe the + * entire set of operations necessary to transform the receiver's tree + * into the desired target. The callbacks can be invoked using the + * svn_editor_*() functions, i.e.: \n + * svn_editor_add_directory() \n + * svn_editor_add_file() \n + * svn_editor_add_symlink() \n + * svn_editor_add_absent() \n + * svn_editor_alter_directory() \n + * svn_editor_alter_file() \n + * svn_editor_alter_symlink() \n + * 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 + * external reasons to cancel the sequence of operations. Unless it + * overrides the cancellation (denoted by #SVN_ERR_CANCELLED), the driver + * aborts the transmission by invoking the svn_editor_abort() callback. + * Exceptions to this are calls to svn_editor_complete() and + * svn_editor_abort(), which cannot be canceled externally. + * + * - @b Receive: While the driver invokes operations upon the editor, the + * receiver finds its callback functions called with the information + * to operate on its tree. Each actual callback function receives those + * arguments that the driver passed to the "driving" functions, plus these: + * - @a baton: This is the @a editor_baton pointer originally passed to + * svn_editor_create(). It may be freely used by the callback + * implementation to store information across all callbacks. + * - @a scratch_pool: This temporary pool is cleared directly after + * each callback returns. See "Pool Usage". + * \n\n + * If the receiver encounters an error within a callback, it returns an + * #svn_error_t*. The driver receives this and aborts transmission. + * + * - @b Complete/Abort: The driver will end transmission by calling \n + * svn_editor_complete() if successful, or \n + * svn_editor_abort() if an error or cancellation occurred. + * \n\n + * + * <h3>Driving Order Restrictions</h3> + * 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 + * an svn_editor_alter_directory() call must be made for its parent + * directory with the target/eventual set of children. + * + * - svn_editor_add_directory() -- Another svn_editor_add_*() call must + * follow for each child mentioned in the @a children argument of any + * svn_editor_add_directory() call. + * + * - For each node created with add_*, if its parent was created using + * svn_editor_add_directory(), then the new child node MUST have been + * mentioned in the @a children parameter of the parent's creation. + * This allows the parent directory to properly mark the child as + * "incomplete" until the child's add_* call arrives. + * + * - A path should never be referenced more than once by the add_*, alter_*, + * and delete operations (the "Once Rule"). The source path of a copy (and + * 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, + * 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. + * + * - The ancestor of an added, copied-here, moved-here, rotated, or + * modified node may not be deleted. The ancestor may not be moved + * (instead: perform the move, *then* the edits). + * + * - svn_editor_delete() must not be used to replace a path -- i.e. + * svn_editor_delete() must not be followed by an svn_editor_add_*() on + * the same path, nor by an svn_editor_copy() or svn_editor_move() with + * the same path as the copy/move target. + * + * Instead of a prior delete call, the add/copy/move callbacks should be + * called with the @a replaces_rev argument set to the revision number of + * the node at this path that is being replaced. Note that the path and + * revision number are the key to finding any other information about the + * replaced node, like node kind, etc. + * @todo say which function(s) to use. + * + * - svn_editor_delete() must not be used to move a path -- i.e. + * svn_editor_delete() must not delete the source path of a previous + * svn_editor_copy() call. Instead, svn_editor_move() must be used. + * Note: if the desired semantics is one (or more) copies, followed + * 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 + * been transmitted completely and without errors, and invoking + * svn_editor_abort() must imply that the transformation was not completed + * successfully. + * + * - If any callback invocation (besides svn_editor_complete()) returns + * with an error, the driver must invoke svn_editor_abort() and stop + * transmitting operations. + * \n\n + * + * <h3>Receiving Restrictions</h3> + * + * All callbacks must complete their handling of a path before they return. + * Since future callbacks will never reference this path again (due to the + * Once Rule), the changes can and should be completed. + * + * This restriction is not recursive -- a directory's children may remain + * incomplete until later callback calls are received. + * + * For example, an svn_editor_add_directory() call during an 'update' + * operation will create the directory itself, including its properties, + * and will complete any client notification for the directory itself. + * The immediate children of the added directory, given in @a children, + * will be recorded in the WC as 'incomplete' and will be completed in the + * course of the same operation sequence, when the corresponding callbacks + * for these items are invoked. + * \n\n + * + * <h3>Timing and State</h3> + * The calls made by the driver to alter the state in the receiver are + * based on the receiver's *current* state, which includes all prior changes + * made during the edit. + * + * Example: copy A to B; set-props on A; copy A to C. The props on C + * should reflect the updated properties of A. + * + * Example: mv A@N to B; mv C@M to A. The second move cannot be marked as + * a "replacing" move since it is not replacing A. The node at A was moved + * away. The second operation is simply moving C to the now-empty path + * known as A. + * + * <h3>Paths</h3> + * Each driver/receiver implementation of this editor interface must + * establish the expected root for all the paths sent and received via + * the callbacks' @a relpath arguments. + * + * For example, during an "update", the driver is the repository, as a + * whole. The receiver may have just a portion of that repository. Here, + * the receiver could tell the driver which repository URL the working + * copy refers to, and thus the driver could send @a relpath arguments + * that are relative to the receiver's working copy. + * + * @note Because the source of a copy may be located *anywhere* in the + * repository, editor drives should typically use the repository root + * as the negotiated root. This allows the @a src_relpath argument in + * svn_editor_copy() to specify any possible source. + * \n\n + * + * <h3>Pool Usage</h3> + * The @a result_pool passed to svn_editor_create() is used to allocate + * the #svn_editor_t instance, and thus it must not be cleared before the + * driver has finished driving the editor. + * + * The @a scratch_pool passed to each callback invocation is derived from + * the @a result_pool that was passed to svn_editor_create(). It is + * cleared directly after each single callback invocation. + * To allocate memory with a longer lifetime from within a callback + * function, you may use your own pool kept in the @a editor_baton. + * + * The @a scratch_pool passed to svn_editor_create() may be used to help + * during construction of the #svn_editor_t instance, but it is assumed to + * live only until svn_editor_create() returns. + * \n\n + * + * <h3>Cancellation</h3> + * To allow graceful interruption by external events (like a user abort), + * svn_editor_create() can be passed an #svn_cancel_func_t that is + * polled every time the driver invokes a callback, just before the + * actual editor callback implementation is invoked. If this function + * decides to return with an error, the driver will receive this error + * as if the callback function had returned it, i.e. as the result from + * calling any of the driving functions (e.g. svn_editor_add_directory()). + * As with any other error, the driver must then invoke svn_editor_abort() + * and abort the transformation sequence. See #svn_cancel_func_t. + * + * The @a cancel_baton argument to svn_editor_create() is passed + * unchanged to each poll of @a cancel_func. + * + * The cancellation function and baton are typically provided by the client + * context. + * + * + * @todo ### TODO anything missing? + * + * @since New in 1.8. + */ +typedef struct svn_editor_t svn_editor_t; + +/** The kind of the checksum to be used throughout the #svn_editor_t APIs. + * + * @note ### This may change before Ev2 is official released, so just like + * everything else in this file, please don't rely upon it until then. + */ +#define SVN_EDITOR_CHECKSUM_KIND svn_checksum_sha1 + + +/** These function types define the callback functions a tree delta consumer + * implements. + * + * Each of these "receiving" function types matches a "driving" function, + * which has the same arguments with these differences: + * + * - These "receiving" functions have a @a baton argument, which is the + * @a editor_baton originally passed to svn_editor_create(), as well as + * a @a scratch_pool argument. + * + * - The "driving" functions have an #svn_editor_t* argument, in order to + * call the implementations of the function types defined here that are + * registered with the given #svn_editor_t instance. + * + * Note that any remaining arguments for these function types are explained + * in the comment for the "driving" functions. Each function type links to + * its corresponding "driver". + * + * @see svn_editor_t, svn_editor_cb_many_t. + * + * @defgroup svn_editor_callbacks Editor callback definitions + * @{ + */ + +/** @see svn_editor_add_directory(), svn_editor_t. + * @since New in 1.8. + */ +typedef svn_error_t *(*svn_editor_cb_add_directory_t)( + void *baton, + const char *relpath, + const apr_array_header_t *children, + apr_hash_t *props, + svn_revnum_t replaces_rev, + apr_pool_t *scratch_pool); + +/** @see svn_editor_add_file(), svn_editor_t. + * @since New in 1.8. + */ +typedef svn_error_t *(*svn_editor_cb_add_file_t)( + void *baton, + const char *relpath, + const svn_checksum_t *checksum, + svn_stream_t *contents, + apr_hash_t *props, + svn_revnum_t replaces_rev, + apr_pool_t *scratch_pool); + +/** @see svn_editor_add_symlink(), svn_editor_t. + * @since New in 1.8. + */ +typedef svn_error_t *(*svn_editor_cb_add_symlink_t)( + void *baton, + const char *relpath, + const char *target, + apr_hash_t *props, + svn_revnum_t replaces_rev, + apr_pool_t *scratch_pool); + +/** @see svn_editor_add_absent(), svn_editor_t. + * @since New in 1.8. + */ +typedef svn_error_t *(*svn_editor_cb_add_absent_t)( + void *baton, + const char *relpath, + svn_node_kind_t kind, + svn_revnum_t replaces_rev, + apr_pool_t *scratch_pool); + +/** @see svn_editor_alter_directory(), svn_editor_t. + * @since New in 1.8. + */ +typedef svn_error_t *(*svn_editor_cb_alter_directory_t)( + void *baton, + const char *relpath, + svn_revnum_t revision, + const apr_array_header_t *children, + apr_hash_t *props, + apr_pool_t *scratch_pool); + +/** @see svn_editor_alter_file(), svn_editor_t. + * @since New in 1.8. + */ +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_pool_t *scratch_pool); + +/** @see svn_editor_alter_symlink(), svn_editor_t. + * @since New in 1.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_pool_t *scratch_pool); + +/** @see svn_editor_delete(), svn_editor_t. + * @since New in 1.8. + */ +typedef svn_error_t *(*svn_editor_cb_delete_t)( + void *baton, + const char *relpath, + svn_revnum_t revision, + apr_pool_t *scratch_pool); + +/** @see svn_editor_copy(), svn_editor_t. + * @since New in 1.8. + */ +typedef svn_error_t *(*svn_editor_cb_copy_t)( + void *baton, + const char *src_relpath, + svn_revnum_t src_revision, + const char *dst_relpath, + svn_revnum_t replaces_rev, + apr_pool_t *scratch_pool); + +/** @see svn_editor_move(), svn_editor_t. + * @since New in 1.8. + */ +typedef svn_error_t *(*svn_editor_cb_move_t)( + void *baton, + const char *src_relpath, + svn_revnum_t src_revision, + const char *dst_relpath, + 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. + */ +typedef svn_error_t *(*svn_editor_cb_complete_t)( + void *baton, + apr_pool_t *scratch_pool); + +/** @see svn_editor_abort(), svn_editor_t. + * @since New in 1.8. + */ +typedef svn_error_t *(*svn_editor_cb_abort_t)( + void *baton, + apr_pool_t *scratch_pool); + +/** @} */ + + +/** These functions create an editor instance so that it can be driven. + * + * @defgroup svn_editor_create Editor creation + * @{ + */ + +/** Allocate an #svn_editor_t instance from @a result_pool, store + * @a editor_baton, @a cancel_func and @a cancel_baton in the new instance + * and return it in @a editor. + * @a scratch_pool is used for temporary allocations (if any). Note that + * this is NOT the same @a scratch_pool that is passed to callback functions. + * @see svn_editor_t + * @since New in 1.8. + */ +svn_error_t * +svn_editor_create(svn_editor_t **editor, + void *editor_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/** Return an editor's private baton. + * + * In some cases, the baton is required outside of the callbacks. This + * function returns the private baton for use. + * + * @since New in 1.8. + */ +void * +svn_editor_get_baton(const svn_editor_t *editor); + + +/** Sets the #svn_editor_cb_add_directory_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_add_directory(svn_editor_t *editor, + svn_editor_cb_add_directory_t callback, + apr_pool_t *scratch_pool); + +/** Sets the #svn_editor_cb_add_file_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_add_file(svn_editor_t *editor, + svn_editor_cb_add_file_t callback, + apr_pool_t *scratch_pool); + +/** Sets the #svn_editor_cb_add_symlink_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_add_symlink(svn_editor_t *editor, + svn_editor_cb_add_symlink_t callback, + apr_pool_t *scratch_pool); + +/** Sets the #svn_editor_cb_add_absent_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_add_absent(svn_editor_t *editor, + svn_editor_cb_add_absent_t callback, + apr_pool_t *scratch_pool); + +/** Sets the #svn_editor_cb_alter_directory_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_alter_directory(svn_editor_t *editor, + svn_editor_cb_alter_directory_t callback, + apr_pool_t *scratch_pool); + +/** Sets the #svn_editor_cb_alter_file_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_alter_file(svn_editor_t *editor, + svn_editor_cb_alter_file_t callback, + apr_pool_t *scratch_pool); + +/** Sets the #svn_editor_cb_alter_symlink_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_alter_symlink(svn_editor_t *editor, + svn_editor_cb_alter_symlink_t callback, + apr_pool_t *scratch_pool); + +/** Sets the #svn_editor_cb_delete_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_delete(svn_editor_t *editor, + svn_editor_cb_delete_t callback, + apr_pool_t *scratch_pool); + +/** Sets the #svn_editor_cb_copy_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_copy(svn_editor_t *editor, + svn_editor_cb_copy_t callback, + apr_pool_t *scratch_pool); + +/** Sets the #svn_editor_cb_move_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_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). + * @see also svn_editor_setcb_many(). + * @since New in 1.8. + */ +svn_error_t * +svn_editor_setcb_complete(svn_editor_t *editor, + svn_editor_cb_complete_t callback, + apr_pool_t *scratch_pool); + +/** Sets the #svn_editor_cb_abort_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_abort(svn_editor_t *editor, + svn_editor_cb_abort_t callback, + apr_pool_t *scratch_pool); + + +/** Lists a complete set of editor callbacks. + * This is a convenience structure. + * @see svn_editor_setcb_many(), svn_editor_create(), svn_editor_t. + * @since New in 1.8. + */ +typedef struct svn_editor_cb_many_t +{ + svn_editor_cb_add_directory_t cb_add_directory; + svn_editor_cb_add_file_t cb_add_file; + svn_editor_cb_add_symlink_t cb_add_symlink; + svn_editor_cb_add_absent_t cb_add_absent; + svn_editor_cb_alter_directory_t cb_alter_directory; + svn_editor_cb_alter_file_t cb_alter_file; + svn_editor_cb_alter_symlink_t cb_alter_symlink; + 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; + +} svn_editor_cb_many_t; + +/** Sets all the callback functions in @a editor at once, according to the + * callback functions stored in @a many. + * @a scratch_pool is used for temporary allocations (if any). + * @since New in 1.8. + */ +svn_error_t * +svn_editor_setcb_many(svn_editor_t *editor, + const svn_editor_cb_many_t *many, + apr_pool_t *scratch_pool); + +/** @} */ + + +/** These functions are called by the tree delta driver to edit the target. + * + * @see svn_editor_t. + * + * @defgroup svn_editor_drive Driving the editor + * @{ + */ + +/** Drive @a editor's #svn_editor_cb_add_directory_t callback. + * + * Create a new directory at @a relpath. The immediate parent of @a relpath + * is expected to exist. + * + * For descriptions of @a props and @a replaces_rev, see + * svn_editor_add_file(). + * + * A complete listing of the immediate children of @a relpath that will be + * added subsequently is given in @a children. @a children is an array of + * const char*s, each giving the basename of an immediate child. It is an + * error to pass NULL for @a children; use an empty array to indicate + * the new directory will have no children. + * + * For all restrictions on driving the editor, see #svn_editor_t. + */ +svn_error_t * +svn_editor_add_directory(svn_editor_t *editor, + const char *relpath, + const apr_array_header_t *children, + apr_hash_t *props, + svn_revnum_t replaces_rev); + +/** Drive @a editor's #svn_editor_cb_add_file_t callback. + * + * Create a new file at @a relpath. The immediate parent of @a relpath + * is expected to exist. + * + * The file's contents are specified in @a contents which has a checksum + * matching @a checksum. Both values must be non-NULL. + * + * Set the properties of the new file to @a props, which is an + * apr_hash_t holding key-value pairs. Each key is a const char* of a + * property name, each value is a const svn_string_t*. If no properties are + * being set on the new file, @a props must be the empty hash. It is an + * error to pass NULL for @a props. + * + * If this add is expected to replace a previously existing file, symlink or + * directory at @a relpath, the revision number of the node to be replaced + * must be given in @a replaces_rev. Otherwise, @a replaces_rev must be + * #SVN_INVALID_REVNUM. Note: it is not allowed to call a "delete" followed + * by an "add" on the same path. Instead, an "add" with @a replaces_rev set + * accordingly MUST be used. + * + * For all restrictions on driving the editor, see #svn_editor_t. + * @since New in 1.8. + */ +svn_error_t * +svn_editor_add_file(svn_editor_t *editor, + const char *relpath, + const svn_checksum_t *checksum, + svn_stream_t *contents, + apr_hash_t *props, + svn_revnum_t replaces_rev); + +/** Drive @a editor's #svn_editor_cb_add_symlink_t callback. + * + * Create a new symbolic link at @a relpath, with a link target of @a + * target. The immediate parent of @a relpath is expected to exist. + * + * For descriptions of @a props and @a replaces_rev, see + * svn_editor_add_file(). + * + * For all restrictions on driving the editor, see #svn_editor_t. + * @since New in 1.8. + */ +svn_error_t * +svn_editor_add_symlink(svn_editor_t *editor, + const char *relpath, + const char *target, + apr_hash_t *props, + svn_revnum_t replaces_rev); + +/** Drive @a editor's #svn_editor_cb_add_absent_t callback. + * + * Create an "absent" node of kind @a kind at @a relpath. The immediate + * parent of @a relpath is expected to exist. + * ### TODO @todo explain "absent". + * ### JAF: What are the allowed values of 'kind'? + * + * For a description of @a replaces_rev, see svn_editor_add_file(). + * + * For all restrictions on driving the editor, see #svn_editor_t. + * @since New in 1.8. + */ +svn_error_t * +svn_editor_add_absent(svn_editor_t *editor, + const char *relpath, + svn_node_kind_t kind, + svn_revnum_t replaces_rev); + +/** Drive @a editor's #svn_editor_cb_alter_directory_t callback. + * + * Alter the properties of the directory at @a relpath. + * + * @a revision specifies the revision at which the receiver should + * expect to find this node. That is, @a relpath at the start of the + * whole edit and @a relpath at @a revision must lie within the same + * node-rev (aka location history segment). This information may be used + * to catch an attempt to alter and out-of-date directory. If the + * directory does not have a corresponding revision in the repository + * (e.g. it has not yet been committed), then @a revision should be + * #SVN_INVALID_REVNUM. + * + * If any changes to the set of children will be made in the future of + * the edit drive, then @a children MUST specify the resulting set of + * children. See svn_editor_add_directory() for the format of @a children. + * If not changes will be made, then NULL may be specified. + * + * For a description of @a props, see svn_editor_add_file(). If no changes + * to the properties will be made (ie. only future changes to the set of + * children), then @a props may be NULL. + * + * It is an error to pass NULL for both @a children and @a props. + * + * For all restrictions on driving the editor, see #svn_editor_t. + * @since New in 1.8. + */ +svn_error_t * +svn_editor_alter_directory(svn_editor_t *editor, + const char *relpath, + svn_revnum_t revision, + const apr_array_header_t *children, + apr_hash_t *props); + +/** Drive @a editor's #svn_editor_cb_alter_file_t callback. + * + * Alter the properties and/or the contents of the file at @a relpath + * with @a revision as its expected revision. See svn_editor_alter_directory() + * for more information about @a revision. + * + * If @a props is non-NULL, then the properties will be applied. + * + * If @a contents is non-NULL, then the stream will be copied to + * the file, and its checksum must match @a checksum (which must also + * be non-NULL). If @a contents is NULL, then @a checksum must also + * be NULL, and no change will be applied to the file's contents. + * + * The properties and/or the contents must be changed. It is an error to + * pass NULL for @a props, @a checksum, and @a contents. + * + * For a description of @a checksum and @a contents see + * svn_editor_add_file(). This function allows @a props to be NULL, but + * the parameter is otherwise described by svn_editor_add_file(). + * + * For all restrictions on driving the editor, see #svn_editor_t. + * @since New in 1.8. + */ +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); + +/** Drive @a editor's #svn_editor_cb_alter_symlink_t callback. + * + * Alter the properties and/or the target of the symlink at @a relpath + * with @a revision as its expected revision. See svn_editor_alter_directory() + * for more information about @a revision. + * + * If @a props is non-NULL, then the properties will be applied. + * + * If @a target is non-NULL, then the symlink's target will be updated. + * + * The properties and/or the target must be changed. It is an error to + * pass NULL for @a props and @a target. + * + * This function allows @a props to be NULL, but the parameter is + * otherwise described by svn_editor_add_file(). + * + * For all restrictions on driving the editor, see #svn_editor_t. + * @since New in 1.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); + +/** Drive @a editor's #svn_editor_cb_delete_t callback. + * + * Delete the existing node at @a relpath, expected to be identical to + * revision @a revision of that path. + * + * For all restrictions on driving the editor, see #svn_editor_t. + * @since New in 1.8. + */ +svn_error_t * +svn_editor_delete(svn_editor_t *editor, + const char *relpath, + svn_revnum_t revision); + +/** Drive @a editor's #svn_editor_cb_copy_t callback. + * + * Copy the node at @a src_relpath, expected to be identical to revision @a + * src_revision of that path, to @a dst_relpath. + * + * For a description of @a replaces_rev, see svn_editor_add_file(). + * + * @note See the general instructions on paths for this API. Since the + * @a src_relpath argument must generally be able to reference any node + * in the repository, the implication is that the editor's root must be + * the repository root. + * + * For all restrictions on driving the editor, see #svn_editor_t. + * @since New in 1.8. + */ +svn_error_t * +svn_editor_copy(svn_editor_t *editor, + const char *src_relpath, + svn_revnum_t src_revision, + const char *dst_relpath, + svn_revnum_t replaces_rev); + +/** Drive @a editor's #svn_editor_cb_move_t callback. + * + * Move the node at @a src_relpath to @a dst_relpath. + * + * @a src_revision specifies the revision at which the receiver should + * 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(). + * + * For a description of @a replaces_rev, see svn_editor_add_file(). + * + * ### what happens if one side of this move 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_move(svn_editor_t *editor, + const char *src_relpath, + svn_revnum_t src_revision, + 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. + * + * For all restrictions on driving the editor, see #svn_editor_t. + * @since New in 1.8. + */ +svn_error_t * +svn_editor_complete(svn_editor_t *editor); + +/** Drive @a editor's #svn_editor_cb_abort_t callback. + * + * Notify that the edit transmission was not successful. + * ### TODO @todo Shouldn't we add a reason-for-aborting argument? + * + * For all restrictions on driving the editor, see #svn_editor_t. + * @since New in 1.8. + */ +svn_error_t * +svn_editor_abort(svn_editor_t *editor); + +/** @} */ + +/** @} */ + +/** A temporary API which conditionally inserts a double editor shim + * into the chain of delta editors. Used for testing Editor v2. + * + * Whether or not the shims are inserted is controlled by a compile-time + * option in libsvn_delta/compat.c. + * + * @note The use of these shims and this API will likely cause all kinds + * of performance degredation. (Which is actually a moot point since they + * don't even work properly yet anyway.) + */ +svn_error_t * +svn_editor__insert_shims(const svn_delta_editor_t **deditor_out, + void **dedit_baton_out, + const svn_delta_editor_t *deditor_in, + void *dedit_baton_in, + const char *repos_root, + const char *base_dir, + svn_delta_shim_callbacks_t *shim_callbacks, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_EDITOR_H */ diff --git a/subversion/include/private/svn_eol_private.h b/subversion/include/private/svn_eol_private.h new file mode 100644 index 0000000..d2cce5c --- /dev/null +++ b/subversion/include/private/svn_eol_private.h @@ -0,0 +1,93 @@ +/** + * @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_eol_private.h + * @brief Subversion's EOL functions - Internal routines + */ + +#ifndef SVN_EOL_PRIVATE_H +#define SVN_EOL_PRIVATE_H + +#include <apr_pools.h> +#include <apr_hash.h> + +#include "svn_types.h" +#include "svn_error.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Constants used by various chunky string processing functions. + */ +#if APR_SIZEOF_VOIDP == 8 +# define SVN__LOWER_7BITS_SET 0x7f7f7f7f7f7f7f7f +# define SVN__BIT_7_SET 0x8080808080808080 +# define SVN__R_MASK 0x0a0a0a0a0a0a0a0a +# define SVN__N_MASK 0x0d0d0d0d0d0d0d0d +#else +# define SVN__LOWER_7BITS_SET 0x7f7f7f7f +# define SVN__BIT_7_SET 0x80808080 +# define SVN__R_MASK 0x0a0a0a0a +# define SVN__N_MASK 0x0d0d0d0d +#endif + +/* Generic EOL character helper routines */ + +/* Look for the start of an end-of-line sequence (i.e. CR or LF) + * in the array pointed to by @a buf , of length @a len. + * If such a byte is found, return the pointer to it, else return NULL. + * + * @since New in 1.7 + */ +char * +svn_eol__find_eol_start(char *buf, apr_size_t len); + +/* Return the first eol marker found in buffer @a buf as a NUL-terminated + * string, or NULL if no eol marker is found. Do not examine more than + * @a len bytes in @a buf. + * + * If the last valid character of @a buf is the first byte of a + * potentially two-byte eol sequence, just return that single-character + * sequence, that is, assume @a buf represents a CR-only or LF-only file. + * This is correct for callers that pass an entire file at once, and is + * no more likely to be incorrect than correct for any caller that doesn't. + * + * The returned string is statically allocated, i.e. it is NOT a pointer + * to an address within @a buf. + * + * If an eol marker is found and @a eolp is not NULL, store in @a *eolp + * the address within @a buf of the first byte of the eol marker. + * This allows callers to tell whether there might be more than one eol + * sequence in @a buf, as well as detect two-byte eol sequences that + * span buffer boundaries. + * + * @since New in 1.7 + */ +const char * +svn_eol__detect_eol(char *buf, apr_size_t len, char **eolp); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_EOL_PRIVATE_H */ diff --git a/subversion/include/private/svn_error_private.h b/subversion/include/private/svn_error_private.h new file mode 100644 index 0000000..f8bd2bc --- /dev/null +++ b/subversion/include/private/svn_error_private.h @@ -0,0 +1,54 @@ +/** + * @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_error_private.h + * @brief Subversion-internal error APIs. + */ + +#ifndef SVN_ERROR_PRIVATE_H +#define SVN_ERROR_PRIVATE_H + +#include "svn_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * Returns if @a err is a "tracing" error. + */ +svn_boolean_t +svn_error__is_tracing_link(svn_error_t *err); + +/** + * Converts a zlib error to an svn_error_t. zerr is the error code, + * function is the function name, message is an optional extra part + * of the error message and may be NULL. + */ +svn_error_t * +svn_error__wrap_zlib(int zerr, const char *function, const char *message); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_ERROR_PRIVATE_H */ diff --git a/subversion/include/private/svn_fs_private.h b/subversion/include/private/svn_fs_private.h new file mode 100644 index 0000000..20b70cd --- /dev/null +++ b/subversion/include/private/svn_fs_private.h @@ -0,0 +1,189 @@ +/* + * svn_fs_private.h: Private declarations for the filesystem layer to + * be consumed by libsvn_fs* and non-libsvn_fs* modules. + * + * ==================================================================== + * 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_FS_PRIVATE_H +#define SVN_FS_PRIVATE_H + +#include "svn_fs.h" +#include "private/svn_editor.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* The maximum length of a transaction name. The Berkeley DB backend + generates transaction names from a sequence expressed as a base 36 + number with a maximum of MAX_KEY_SIZE (currently 200) bytes. The + FSFS backend generates transaction names of the form + <rev>-<base 36-number> where the base 36 number is a sequence value + with a maximum length of MAX_KEY_SIZE bytes. The maximum length is + 212, but use 220 just to have some extra space: + 10 -> 32 bit revision number + 1 -> '-' + 200 -> 200 digit base 36 number + 1 -> '\0' + */ +#define SVN_FS__TXN_MAX_LEN 220 + +/** Retrieve the lock-tokens associated in the context @a access_ctx. + * The tokens are in a hash keyed with <tt>const char *</tt> tokens, + * and with <tt>const char *</tt> values for the paths associated. + * + * You should always use svn_fs_access_add_lock_token2() if you intend + * to use this function. The result of the function is not guaranteed + * if you use it with the deprecated svn_fs_access_add_lock_token() + * API. + * + * @since New in 1.6. */ +apr_hash_t * +svn_fs__access_get_lock_tokens(svn_fs_access_t *access_ctx); + + +/* Check whether PATH is valid for a filesystem, following (most of) the + * requirements in svn_fs.h:"Directory entry names and directory paths". + * + * Return SVN_ERR_FS_PATH_SYNTAX if PATH is not valid. + */ +svn_error_t * +svn_fs__path_valid(const char *path, apr_pool_t *pool); + + + +/** Editors + * + * ### docco + * + * @defgroup svn_fs_editor Transaction editors + * @{ + */ + +/** + * Create a new filesystem transaction, based on based on the youngest + * revision of @a fs, and return its name @a *txn_name and an @a *editor + * that can be used to make changes into it. + * + * @a flags determines transaction enforcement behaviors, and is composed + * from the constants SVN_FS_TXN_* (#SVN_FS_TXN_CHECK_OOD etc.). It is a + * property of the underlying transaction, and will not change if multiple + * editors are used to refer to that transaction (see @a autocommit, below). + * + * @note If you're building a txn for committing, you probably don't want + * to call this directly. Instead, call svn_repos__get_commit_ev2(), which + * honors the repository's hook configurations. + * + * When svn_editor_complete() is called for @a editor, internal resources + * will be cleaned and nothing more will happen. If you wish to commit the + * transaction, call svn_fs_editor_commit() instead. It is illegal to call + * both; the second call will return #SVN_ERR_FS_INCORRECT_EDITOR_COMPLETION. + * + * @see svn_fs_commit_txn() + * + * @since New in 1.8. + */ +svn_error_t * +svn_fs__editor_create(svn_editor_t **editor, + const char **txn_name, + svn_fs_t *fs, + apr_uint32_t flags, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/** + * Like svn_fs__editor_create(), but open an existing transaction + * @a txn_name and continue editing it. + * + * @since New in 1.8. + */ +svn_error_t * +svn_fs__editor_create_for(svn_editor_t **editor, + svn_fs_t *fs, + const char *txn_name, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/** + * Commit the transaction represented by @a editor. + * + * If the commit to the filesystem succeeds, then @a *revision will be set + * to the resulting revision number. Note that further errors may occur, + * as described below. If the commit process does not succeed, for whatever + * reason, then @a *revision will be set to #SVN_INVALID_REVNUM. + * + * If a conflict occurs during the commit, then @a *conflict_path will + * be set to a path that caused the conflict. #SVN_NO_ERROR will be returned. + * Callers may want to construct an #SVN_ERR_FS_CONFLICT error with a + * message that incorporates @a *conflict_path. + * + * If a non-conflict error occurs during the commit, then that error will + * be returned. + * As is standard with any Subversion API, @a revision, @a post_commit_err, + * and @a conflict_path (the OUT parameters) have an indeterminate value if + * an error is returned. + * + * If the commit completes (and a revision is returned in @a *revision), then + * it is still possible for an error to occur during the cleanup process. + * Any such error will be returned in @a *post_commit_err. The caller must + * properly use or clear that error. + * + * If svn_editor_complete() has already been called on @a editor, then + * #SVN_ERR_FS_INCORRECT_EDITOR_COMPLETION will be returned. + * + * @note After calling this function, @a editor will be marked as completed + * and no further operations may be performed on it. The underlying + * transaction will either be committed or aborted once this function is + * called. It cannot be recovered for additional work. + * + * @a result_pool will be used to allocate space for @a conflict_path. + * @a scratch_pool will be used for all temporary allocations. + * + * @note To summarize, there are three possible outcomes of this function: + * successful commit (with or without an associated @a *post_commit_err); + * failed commit due to a conflict (reported via @a *conflict_path); and + * failed commit for some other reason (reported via the returned error.) + * + * @since New in 1.8. + */ +svn_error_t * +svn_fs__editor_commit(svn_revnum_t *revision, + svn_error_t **post_commit_err, + const char **conflict_path, + svn_editor_t *editor, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/** @} */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_FS_PRIVATE_H */ diff --git a/subversion/include/private/svn_fs_util.h b/subversion/include/private/svn_fs_util.h new file mode 100644 index 0000000..eb0f024 --- /dev/null +++ b/subversion/include/private/svn_fs_util.h @@ -0,0 +1,217 @@ +/* + * svn_fs_util.h: Declarations for the APIs of libsvn_fs_util to be + * consumed by only fs_* libs. + * + * ==================================================================== + * 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_FS_UTIL_H +#define SVN_FS_UTIL_H + +#include <apr_pools.h> + +#include "svn_types.h" +#include "svn_error.h" +#include "svn_fs.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Returns whether PATH is in canonical form as defined by + svn_fs__canonicalize_abspath(). + */ +svn_boolean_t +svn_fs__is_canonical_abspath(const char *path); + +/* Return a canonicalized version of a filesystem PATH, allocated in POOL. + + While the filesystem API is pretty flexible about the incoming paths + (they must be UTF-8 with '/' as separators, but they don't have to + begin with '/', and multiple contiguous '/'s are ignored) we want any + paths that are physically stored in the underlying database to look + consistent. Specifically, absolute filesystem paths should begin with + '/', and all redundant and trailing '/' characters be removed. + + This is similar to svn_fspath__canonicalize() but doesn't treat "." + segments as special. +*/ +const char * +svn_fs__canonicalize_abspath(const char *path, apr_pool_t *pool); + +/* If EXPECT_OPEN, verify that FS refers to an open database; + otherwise, verify that FS refers to an unopened database. Return + an appropriate error if the expectation fails to match the + reality. */ +svn_error_t * +svn_fs__check_fs(svn_fs_t *fs, svn_boolean_t expect_open); + +/* An identifier for FS to be used in the text of error messages. + (Not used anywhere but in this header.) + + Note: we log the UUID, rather than (fs)->path, since some of these + errors are marshalled to the client. */ +#define svn_fs__identifier(fs) ((fs)->uuid) + +/* Constructing nice error messages for roots. */ + +/* Build an SVN_ERR_FS_NOT_FOUND error, with a detailed error text, + for PATH in ROOT. ROOT is of type svn_fs_root_t *. */ +#define SVN_FS__NOT_FOUND(root, path) ( \ + root->is_txn_root ? \ + svn_error_createf \ + (SVN_ERR_FS_NOT_FOUND, 0, \ + _("File not found: transaction '%s', path '%s'"), \ + root->txn, path) \ + : \ + svn_error_createf \ + (SVN_ERR_FS_NOT_FOUND, 0, \ + _("File not found: revision %ld, path '%s'"), \ + root->rev, path) \ + ) + + +/* Build a detailed `file already exists' message for PATH in ROOT. + ROOT is of type svn_fs_root_t *. */ +#define SVN_FS__ALREADY_EXISTS(root, path_str) ( \ + root->is_txn_root ? \ + svn_error_createf \ + (SVN_ERR_FS_ALREADY_EXISTS, 0, \ + _("File already exists: filesystem '%s', transaction '%s', path '%s'"), \ + svn_fs__identifier(root->fs), root->txn, path_str) \ + : \ + svn_error_createf \ + (SVN_ERR_FS_ALREADY_EXISTS, 0, \ + _("File already exists: filesystem '%s', revision %ld, path '%s'"), \ + svn_fs__identifier(root->fs), root->rev, path_str) \ + ) + +/* ROOT is of type svn_fs_root_t *. */ +#define SVN_FS__NOT_TXN(root) \ + svn_error_create \ + (SVN_ERR_FS_NOT_TXN_ROOT, NULL, \ + _("Root object must be a transaction root")) + +/* SVN_FS__ERR_NOT_MUTABLE: the caller attempted to change a node + outside of a transaction. FS is of type "svn_fs_t *". */ +#define SVN_FS__ERR_NOT_MUTABLE(fs, rev, path_in_repo) \ + svn_error_createf( \ + SVN_ERR_FS_NOT_MUTABLE, 0, \ + _("File is not mutable: filesystem '%s', revision %ld, path '%s'"), \ + svn_fs__identifier(fs), rev, path_in_repo) + +/* FS is of type "svn_fs_t *".*/ +#define SVN_FS__ERR_NOT_DIRECTORY(fs, path_in_repo) \ + svn_error_createf( \ + SVN_ERR_FS_NOT_DIRECTORY, 0, \ + _("'%s' is not a directory in filesystem '%s'"), \ + path_in_repo, svn_fs__identifier(fs)) + +/* FS is of type "svn_fs_t *". */ +#define SVN_FS__ERR_NOT_FILE(fs, path_in_repo) \ + svn_error_createf( \ + SVN_ERR_FS_NOT_FILE, 0, \ + _("'%s' is not a file in filesystem '%s'"), \ + path_in_repo, svn_fs__identifier(fs)) + + +/* FS is of type "svn_fs_t *", LOCK is of type "svn_lock_t *". */ +#define SVN_FS__ERR_PATH_ALREADY_LOCKED(fs, lock) \ + svn_error_createf( \ + SVN_ERR_FS_PATH_ALREADY_LOCKED, 0, \ + _("Path '%s' is already locked by user '%s' in filesystem '%s'"), \ + (lock)->path, (lock)->owner, svn_fs__identifier(fs)) + +/* FS is of type "svn_fs_t *". */ +#define SVN_FS__ERR_NO_SUCH_LOCK(fs, path_in_repo) \ + svn_error_createf( \ + SVN_ERR_FS_NO_SUCH_LOCK, 0, \ + _("No lock on path '%s' in filesystem '%s'"), \ + path_in_repo, svn_fs__identifier(fs)) + +/* FS is of type "svn_fs_t *". */ +#define SVN_FS__ERR_LOCK_EXPIRED(fs, token) \ + svn_error_createf( \ + SVN_ERR_FS_LOCK_EXPIRED, 0, \ + _("Lock has expired: lock-token '%s' in filesystem '%s'"), \ + token, svn_fs__identifier(fs)) + +/* FS is of type "svn_fs_t *". */ +#define SVN_FS__ERR_NO_USER(fs) \ + svn_error_createf( \ + SVN_ERR_FS_NO_USER, 0, \ + _("No username is currently associated with filesystem '%s'"), \ + svn_fs__identifier(fs)) + +/* SVN_FS__ERR_LOCK_OWNER_MISMATCH: trying to use a lock whose + LOCK_OWNER doesn't match the USERNAME associated with FS. + FS is of type "svn_fs_t *". */ +#define SVN_FS__ERR_LOCK_OWNER_MISMATCH(fs, username, lock_owner) \ + svn_error_createf( \ + SVN_ERR_FS_LOCK_OWNER_MISMATCH, 0, \ + _("User '%s' is trying to use a lock owned by '%s' in " \ + "filesystem '%s'"), \ + username, lock_owner, svn_fs__identifier(fs)) + +/* Return a NULL-terminated copy of the first component of PATH, + allocated in POOL. If path is empty, or consists entirely of + slashes, return the empty string. + + If the component is followed by one or more slashes, we set *NEXT_P + to point after the slashes. If the component ends PATH, we set + *NEXT_P to zero. This means: + - If *NEXT_P is zero, then the component ends the PATH, and there + are no trailing slashes in the path. + - If *NEXT_P points at PATH's terminating NULL character, then + the component returned was the last, and PATH ends with one or more + slash characters. + - Otherwise, *NEXT_P points to the beginning of the next component + of PATH. You can pass this value to next_entry_name to extract + the next component. */ +char * +svn_fs__next_entry_name(const char **next_p, + const char *path, + apr_pool_t *pool); + +/* Allocate an svn_fs_path_change2_t structure in POOL, initialize and + return it. + + Set the node_rev_id field of the created struct to NODE_REV_ID, and + change_kind to CHANGE_KIND. Set all other fields to their _unknown, + NULL or invalid value, respectively. */ +svn_fs_path_change2_t * +svn_fs__path_change_create_internal(const svn_fs_id_t *node_rev_id, + svn_fs_path_change_kind_t change_kind, + apr_pool_t *pool); + +/* Append REL_PATH (which may contain slashes) to each path that exists in + the mergeinfo INPUT, and return a new mergeinfo in *OUTPUT. Deep + copies the values. Perform all allocations in POOL. */ +svn_error_t * +svn_fs__append_to_merged_froms(svn_mergeinfo_t *output, + svn_mergeinfo_t input, + const char *rel_path, + apr_pool_t *pool); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_FS_UTIL_H */ diff --git a/subversion/include/private/svn_fspath.h b/subversion/include/private/svn_fspath.h new file mode 100644 index 0000000..01679b9 --- /dev/null +++ b/subversion/include/private/svn_fspath.h @@ -0,0 +1,175 @@ +/** + * @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_fspath.h + * @brief Implementation of path manipulation functions similar to + * those in svn_dirent_uri.h (which see for details) but for + * the private fspath class of paths. + */ + +#ifndef SVN_FSPATH_H +#define SVN_FSPATH_H + +#include <apr.h> +#include <apr_pools.h> + +#include "svn_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** Return TRUE iff @a fspath is canonical. + * @a fspath need not be canonical, of course. + * + * @since New in 1.7. + */ +svn_boolean_t +svn_fspath__is_canonical(const char *fspath); + + +/** This function is similar to svn_relpath_canonicalize(), except + * that it returns an fspath (which is essentially just a relpath + * tacked onto a leading forward slash). + * + * The returned fspath may be statically allocated or allocated from + * @a pool. + * + * This is similar to svn_fs__canonicalize_abspath() but also treats "." + * segments as special. + * + * @since New in 1.7. + */ +const char * +svn_fspath__canonicalize(const char *fspath, + apr_pool_t *pool); + +/** Return the dirname of @a fspath, defined as the path with its basename + * removed. If @a fspath is "/", return "/". + * + * Allocate the result in @a pool. + * + * @since New in 1.7. + */ +const char * +svn_fspath__dirname(const char *fspath, + apr_pool_t *pool); + +/** Return the last component of @a fspath. The returned value will have no + * slashes in it. If @a fspath is "/", return "". + * + * If @a pool is NULL, return a pointer to within @a fspath, else allocate + * the result in @a pool. + * + * @since New in 1.7. + */ +const char * +svn_fspath__basename(const char *fspath, + apr_pool_t *pool); + +/** Divide the canonical @a fspath into @a *dirpath and @a + * *base_name, allocated in @a pool. + * + * If @a dirpath or @a base_name is NULL, then don't set that one. + * + * Either @a dirpath or @a base_name may be @a fspath's own address, but they + * may not both be the same address, or the results are undefined. + * + * If @a fspath has two or more components, the separator between @a dirpath + * and @a base_name is not included in either of the new names. + * + * @since New in 1.7. + */ +void +svn_fspath__split(const char **dirpath, + const char **base_name, + const char *fspath, + apr_pool_t *result_pool); + +/** Return the fspath composed of @a fspath with @a relpath appended. + * Allocate the result in @a result_pool. + * + * @since New in 1.7. + */ +char * +svn_fspath__join(const char *fspath, + const char *relpath, + apr_pool_t *result_pool); + + +/** Return TRUE if @a fspath (with length @a len) is the root + * directory; return FALSE otherwise. + * + * @since New in 1.7. + */ +svn_boolean_t +svn_fspath__is_root(const char *fspath, + apr_size_t len); + +/** Return the relative path part of @a child_fspath that is below + * @a parent_fspath, or just "" if @a parent_fspath is equal to + * @a child_fspath. If @a child_fspath is not below @a parent_fspath + * or equal to it, return @c NULL. + * + * @since New in 1.7. + */ +const char * +svn_fspath__skip_ancestor(const char *parent_fspath, + const char *child_fspath); + +/** Return the longest common path shared by two fspaths, @a fspath1 and + * @a fspath2. If there's no common ancestor, return "/". + * + * @since New in 1.7. + */ +char * +svn_fspath__get_longest_ancestor(const char *fspath1, + const char *fspath2, + apr_pool_t *result_pool); + + + + +/** A faux fspath API used by the DAV modules to help us distinguish + * between real URI-decoded fspaths and URI-encoded URL path-portions. + */ +#define svn_urlpath__basename svn_fspath__basename +#define svn_urlpath__dirname svn_fspath__dirname +#define svn_urlpath__get_longest_ancestor svn_fspath__get_longest_ancestor +#define svn_urlpath__is_canonical svn_fspath__is_canonical +#define svn_urlpath__is_root svn_fspath__is_root +#define svn_urlpath__join svn_fspath__join +#define svn_urlpath__skip_ancestor svn_fspath__skip_ancestor +#define svn_urlpath__split svn_fspath__split + +/* Like svn_fspath__canonicalize(), but this one accepts both full + URLs and URL path-portions. */ +const char * +svn_urlpath__canonicalize(const char *uri, apr_pool_t *pool); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_FSPATH_H */ diff --git a/subversion/include/private/svn_io_private.h b/subversion/include/private/svn_io_private.h new file mode 100644 index 0000000..2fb4fa5 --- /dev/null +++ b/subversion/include/private/svn_io_private.h @@ -0,0 +1,99 @@ +/** + * @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_io_private.h + * @brief Private IO API + */ + +#ifndef SVN_IO_PRIVATE_H +#define SVN_IO_PRIVATE_H + +#include <apr.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* The flags to pass to apr_stat to check for executable and/or readonly */ +#if defined(WIN32) || defined(__OS2__) +#define SVN__APR_FINFO_EXECUTABLE (0) +#define SVN__APR_FINFO_READONLY (0) +#define SVN__APR_FINFO_MASK_OUT (APR_FINFO_PROT | APR_FINFO_OWNER) +#else +#define SVN__APR_FINFO_EXECUTABLE (APR_FINFO_PROT) +#define SVN__APR_FINFO_READONLY (APR_FINFO_PROT | APR_FINFO_OWNER) +#define SVN__APR_FINFO_MASK_OUT (0) +#endif + + +/** Set @a *executable TRUE if @a file_info is executable for the + * user, FALSE otherwise. + * + * Always returns FALSE on Windows or platforms without user support. + */ +svn_error_t * +svn_io__is_finfo_executable(svn_boolean_t *executable, + apr_finfo_t *file_info, + apr_pool_t *pool); + +/** Set @a *read_only TRUE if @a file_info is read-only for the user, + * FALSE otherwise. + */ +svn_error_t * +svn_io__is_finfo_read_only(svn_boolean_t *read_only, + apr_finfo_t *file_info, + apr_pool_t *pool); + + +/** Buffer test handler function for a generic stream. @see svn_stream_t + * and svn_stream__is_buffered(). + * + * @since New in 1.7. + */ +typedef svn_boolean_t (*svn_stream__is_buffered_fn_t)(void *baton); + +/** Set @a stream's buffer test function to @a is_buffered_fn + * + * @since New in 1.7. + */ +void +svn_stream__set_is_buffered(svn_stream_t *stream, + svn_stream__is_buffered_fn_t is_buffered_fn); + +/** 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 + * true buffering state until after the lazy open: a stream that + * initially reports as non-buffered may report as buffered later. + * + * @since New in 1.7. + */ +svn_boolean_t +svn_stream__is_buffered(svn_stream_t *stream); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* SVN_IO_PRIVATE_H */ diff --git a/subversion/include/private/svn_log.h b/subversion/include/private/svn_log.h new file mode 100644 index 0000000..bdcf32f --- /dev/null +++ b/subversion/include/private/svn_log.h @@ -0,0 +1,260 @@ +/* + * svn_log.h: Functions for assembling entries for server-side logs. + * See also tools/server-side/svn_server_log_parse.py . + * ==================================================================== + * 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_LOG_H +#define SVN_LOG_H + +#include <apr.h> +#include <apr_pools.h> +#include <apr_tables.h> + +#include "svn_types.h" +#include "svn_mergeinfo.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * Return a log string for a reparent action. + * + * @since New in 1.6. + */ +const char * +svn_log__reparent(const char *path, apr_pool_t *pool); + +/** + * Return a log string for a change-rev-prop action. + * + * @since New in 1.6. + */ +const char * +svn_log__change_rev_prop(svn_revnum_t rev, const char *name, apr_pool_t *pool); + +/** + * Return a log string for a rev-proplist action. + * + * @since New in 1.6. + */ +const char * +svn_log__rev_proplist(svn_revnum_t rev, apr_pool_t *pool); + +/** + * Return a log string for a rev-prop action. + * + * @since New in 1.6. + */ +const char * +svn_log__rev_prop(svn_revnum_t rev, const char *name, apr_pool_t *pool); + +/** + * Return a log string for a commit action. + * + * @since New in 1.6. + */ +const char * +svn_log__commit(svn_revnum_t rev, apr_pool_t *pool); + +/** + * Return a log string for a get-file action. + * + * @since New in 1.6. + */ +const char * +svn_log__get_file(const char *path, svn_revnum_t rev, + svn_boolean_t want_contents, svn_boolean_t want_props, + apr_pool_t *pool); + +/** + * Return a log string for a get-dir action. + * + * @since New in 1.6. + */ +const char * +svn_log__get_dir(const char *path, svn_revnum_t rev, + svn_boolean_t want_contents, svn_boolean_t want_props, + apr_uint64_t dirent_fields, + apr_pool_t *pool); + +/** + * Return a log string for a get-mergeinfo action. + * + * @since New in 1.6. + */ +const char * +svn_log__get_mergeinfo(const apr_array_header_t *paths, + svn_mergeinfo_inheritance_t inherit, + svn_boolean_t include_descendants, + apr_pool_t *pool); + +/** + * Return a log string for a checkout action. + * + * @since New in 1.6. + */ +const char * +svn_log__checkout(const char *path, svn_revnum_t rev, svn_depth_t depth, + apr_pool_t *pool); + +/** + * Return a log string for an update action. + * + * @since New in 1.6. + */ +const char * +svn_log__update(const char *path, svn_revnum_t rev, svn_depth_t depth, + svn_boolean_t send_copyfrom_args, + apr_pool_t *pool); + +/** + * Return a log string for a switch action. + * + * @since New in 1.6. + */ +const char * +svn_log__switch(const char *path, const char *dst_path, svn_revnum_t revnum, + svn_depth_t depth, apr_pool_t *pool); + +/** + * Return a log string for a status action. + * + * @since New in 1.6. + */ +const char * +svn_log__status(const char *path, svn_revnum_t rev, svn_depth_t depth, + apr_pool_t *pool); + +/** + * Return a log string for a diff action. + * + * @since New in 1.6. + */ +const char * +svn_log__diff(const char *path, svn_revnum_t from_revnum, + const char *dst_path, svn_revnum_t revnum, + svn_depth_t depth, svn_boolean_t ignore_ancestry, + apr_pool_t *pool); + +/** + * Return a log string for a log action. + * + * @since New in 1.6. + */ +const char * +svn_log__log(const apr_array_header_t *paths, + svn_revnum_t start, svn_revnum_t end, + int limit, svn_boolean_t discover_changed_paths, + svn_boolean_t strict_node_history, + svn_boolean_t include_merged_revisions, + const apr_array_header_t *revprops, apr_pool_t *pool); + +/** + * Return a log string for a get-locations action. + * + * @since New in 1.6. + */ +const char * +svn_log__get_locations(const char *path, svn_revnum_t peg_revision, + const apr_array_header_t *location_revisions, + apr_pool_t *pool); + +/** + * Return a log string for a get-location-segments action. + * + * @since New in 1.6. + */ +const char * +svn_log__get_location_segments(const char *path, svn_revnum_t peg_revision, + svn_revnum_t start, svn_revnum_t end, + apr_pool_t *pool); + +/** + * Return a log string for a get-file-revs action. + * + * @since New in 1.6. + */ +const char * +svn_log__get_file_revs(const char *path, svn_revnum_t start, svn_revnum_t end, + svn_boolean_t include_merged_revisions, + apr_pool_t *pool); + +/** + * Return a log string for a lock action. + * + * @since New in 1.6. + */ +const char * +svn_log__lock(const apr_array_header_t *paths, svn_boolean_t steal, + apr_pool_t *pool); + +/** + * Return a log string for an unlock action. + * + * @since New in 1.6. + */ +const char * +svn_log__unlock(const apr_array_header_t *paths, svn_boolean_t break_lock, + apr_pool_t *pool); + +/** + * Return a log string for a lock action on only one path; this is + * just a convenience wrapper around svn_log__lock(). + * + * @since New in 1.6. + */ +const char * +svn_log__lock_one_path(const char *path, svn_boolean_t steal, + apr_pool_t *pool); + +/** + * Return a log string for an unlock action on only one path; this is + * just a convenience wrapper around svn_log__unlock(). + * + * @since New in 1.6. + */ +const char * +svn_log__unlock_one_path(const char *path, svn_boolean_t break_lock, + apr_pool_t *pool); + +/** + * Return a log string for a replay action. + * + * @since New in 1.6. + */ +const char * +svn_log__replay(const char *path, svn_revnum_t rev, apr_pool_t *pool); + +/** + * Return a log string for a get-inherited-props action. + * + * @since New in 1.8. + */ +const char * +svn_log__get_inherited_props(const char *path, + svn_revnum_t rev, + apr_pool_t *pool); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_LOG_H */ diff --git a/subversion/include/private/svn_magic.h b/subversion/include/private/svn_magic.h new file mode 100644 index 0000000..b057e56 --- /dev/null +++ b/subversion/include/private/svn_magic.h @@ -0,0 +1,55 @@ +/** + * @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_magic.h + * @brief Subversion interface to libmagic. + */ + +#ifndef SVN_MAGIC_H +#define SVN_MAGIC_H + +/* An opaque struct that wraps a libmagic cookie. */ +typedef struct svn_magic__cookie_t svn_magic__cookie_t; + +/* This routine initialises libmagic. + * 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_magic__init(svn_magic__cookie_t **magic_cookie, + apr_pool_t *result_pool); + +/* Detect the mime-type of the file at LOCAL_ABSPATH using MAGIC_COOKIE. + * If the mime-type is binary return the result in *MIMETYPE. + * If the file is not a binary file or if its mime-type cannot be determined + * set *MIMETYPE to NULL. Allocate *MIMETYPE in RESULT_POOL. + * Use SCRATCH_POOL for temporary allocations. */ +svn_error_t * +svn_magic__detect_binary_mimetype(const char **mimetype, + const char *local_abspath, + svn_magic__cookie_t *magic_cookie, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +#endif /* SVN_MAGIC_H */ diff --git a/subversion/include/private/svn_mergeinfo_private.h b/subversion/include/private/svn_mergeinfo_private.h new file mode 100644 index 0000000..287515a --- /dev/null +++ b/subversion/include/private/svn_mergeinfo_private.h @@ -0,0 +1,270 @@ +/** + * @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_mergeinfo_private.h + * @brief Subversion-internal mergeinfo APIs. + */ + +#ifndef SVN_MERGEINFO_PRIVATE_H +#define SVN_MERGEINFO_PRIVATE_H + +#include <apr_pools.h> + +#include "svn_types.h" +#include "svn_error.h" +#include "svn_mergeinfo.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Set inheritability of all ranges in RANGELIST to INHERITABLE. + If RANGELIST is NULL do nothing. */ +void +svn_rangelist__set_inheritance(svn_rangelist_t *rangelist, + svn_boolean_t inheritable); + +/* Parse a rangelist from the string STR. Set *RANGELIST to the result, + * allocated in RESULT_POOL. Return an error if the rangelist is not + * well-formed (for example, if it contains invalid characters or if + * R1 >= R2 in a "R1-R2" range element). + * + * Unlike svn_mergeinfo_parse(), this does not sort the ranges into order + * or combine adjacent and overlapping ranges. + * + * The compaction can be done with svn_rangelist__combine_adjacent_ranges(). + */ +svn_error_t * +svn_rangelist__parse(svn_rangelist_t **rangelist, + const char *str, + apr_pool_t *result_pool); + +/* In-place combines adjacent ranges in a rangelist. + SCRATCH_POOL is just used for providing error messages. */ +svn_error_t * +svn_rangelist__combine_adjacent_ranges(svn_rangelist_t *rangelist, + apr_pool_t *scratch_pool); + +/* Set inheritability of all rangelists in MERGEINFO to INHERITABLE. + If MERGEINFO is NULL do nothing. If a rangelist in MERGEINFO is + NULL leave it alone. */ +void +svn_mergeinfo__set_inheritance(svn_mergeinfo_t mergeinfo, + svn_boolean_t inheritable, + apr_pool_t *scratch_pool); + +/* Return whether INFO1 and INFO2 are equal in *IS_EQUAL. + + CONSIDER_INHERITANCE determines how the rangelists in the two + hashes are compared for equality. If CONSIDER_INHERITANCE is FALSE, + then the start and end revisions of the svn_merge_range_t's being + compared are the only factors considered when determining equality. + + e.g. '/trunk: 1,3-4*,5' == '/trunk: 1,3-5' + + If CONSIDER_INHERITANCE is TRUE, then the inheritability of the + svn_merge_range_t's is also considered and must be the same for two + otherwise identical ranges to be judged equal. + + e.g. '/trunk: 1,3-4*,5' != '/trunk: 1,3-5' + '/trunk: 1,3-4*,5' == '/trunk: 1,3-4*,5' + '/trunk: 1,3-4,5' == '/trunk: 1,3-4,5' + + Use POOL for temporary allocations. */ +svn_error_t * +svn_mergeinfo__equals(svn_boolean_t *is_equal, + svn_mergeinfo_t info1, + svn_mergeinfo_t info2, + 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 + removed or MERGEINFO is NULL. */ +svn_boolean_t +svn_mergeinfo__remove_empty_rangelists(svn_mergeinfo_t mergeinfo, + apr_pool_t *pool); + +/* Make a shallow (ie, mergeinfos are not duped, or altered at all; + keys share storage) copy of IN_CATALOG in *OUT_CATALOG, removing + PREFIX_PATH from the beginning of each key in the catalog. + PREFIX_PATH and the keys of IN_CATALOG are absolute 'fspaths', + starting with '/'. It is illegal for any key to not start with + PREFIX_PATH. The keys of *OUT_CATALOG are relpaths. The new hash + and temporary values are allocated in POOL. (This is useful for + making the return value from svn_ra_get_mergeinfo relative to the + session root, say.) */ +svn_error_t * +svn_mergeinfo__remove_prefix_from_catalog(svn_mergeinfo_catalog_t *out_catalog, + svn_mergeinfo_catalog_t in_catalog, + const char *prefix_path, + apr_pool_t *pool); + +/* Make a shallow (ie, mergeinfos are not duped, or altered at all; + though keys are reallocated) copy of IN_CATALOG in *OUT_CATALOG, + adding PREFIX_PATH to the beginning of each key in the catalog. + + The new hash keys are allocated in RESULT_POOL. SCRATCH_POOL + is used for any temporary allocations.*/ +svn_error_t * +svn_mergeinfo__add_prefix_to_catalog(svn_mergeinfo_catalog_t *out_catalog, + svn_mergeinfo_catalog_t in_catalog, + const char *prefix_path, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Set *OUT_MERGEINFO to a shallow copy of MERGEINFO with the relpath + SUFFIX_RELPATH added to the end of each key path. + + Allocate *OUT_MERGEINFO and the new keys in RESULT_POOL. Use + SCRATCH_POOL for any temporary allocations. */ +svn_error_t * +svn_mergeinfo__add_suffix_to_mergeinfo(svn_mergeinfo_t *out_mergeinfo, + svn_mergeinfo_t mergeinfo, + const char *suffix_relpath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Create a string representation of CATALOG in *OUTPUT, allocated in POOL. + The hash keys of CATALOG and the merge source paths of each key's mergeinfo + are represented in sorted order as per svn_sort_compare_items_as_paths. + If CATALOG is empty or NULL then *OUTPUT->DATA is set to "\n". If SVN_DEBUG + is true, then a NULL or empty CATALOG causes *OUTPUT to be set to an + appropriate newline terminated string. If KEY_PREFIX is not NULL then + prepend KEY_PREFIX to each key (path) in *OUTPUT. if VAL_PREFIX is not + NULL then prepend VAL_PREFIX to each merge source:rangelist line in + *OUTPUT. + + Any relative merge source paths in the mergeinfo in CATALOG are converted + to absolute paths in *OUTPUT. */ +svn_error_t * +svn_mergeinfo__catalog_to_formatted_string(svn_string_t **output, + svn_mergeinfo_catalog_t catalog, + const char *key_prefix, + const char *val_prefix, + apr_pool_t *pool); + +/* Set *YOUNGEST_REV and *OLDEST_REV to the youngest and oldest revisions + found in the rangelists within MERGEINFO. Note that *OLDEST_REV is + exclusive and *YOUNGEST_REV is inclusive. If MERGEINFO is NULL or empty + set *YOUNGEST_REV and *OLDEST_REV to SVN_INVALID_REVNUM. */ +svn_error_t * +svn_mergeinfo__get_range_endpoints(svn_revnum_t *youngest_rev, + svn_revnum_t *oldest_rev, + svn_mergeinfo_t mergeinfo, + apr_pool_t *pool); + +/* Set *FILTERED_MERGEINFO to a deep copy of MERGEINFO, allocated in + RESULT_POOL, less any revision ranges that fall outside of the range + OLDEST_REV:YOUNGEST_REV (exclusive:inclusive) if INCLUDE_RANGE is true, + or less any ranges within OLDEST_REV:YOUNGEST_REV if INCLUDE_RANGE + is false. If all the rangelists mapped to a given path are filtered + then filter that path as well. If all paths are filtered or MERGEINFO is + empty or NULL then *FILTERED_MERGEINFO is set to an empty hash. + + Use SCRATCH_POOL for any temporary allocations. */ +svn_error_t * +svn_mergeinfo__filter_mergeinfo_by_ranges(svn_mergeinfo_t *filtered_mergeinfo, + svn_mergeinfo_t mergeinfo, + svn_revnum_t youngest_rev, + svn_revnum_t oldest_rev, + svn_boolean_t include_range, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Filter each mergeinfo in CATALOG as per + svn_mergeinfo__filter_mergeinfo_by_ranges() and put a deep copy of the + result in *FILTERED_CATALOG, allocated in RESULT_POOL. If any mergeinfo + is filtered to an empty hash then filter that path/mergeinfo as well. + If all mergeinfo is filtered or CATALOG is NULL then set *FILTERED_CATALOG + to an empty hash. + + Use SCRATCH_POOL for any temporary allocations. */ +svn_error_t* +svn_mergeinfo__filter_catalog_by_ranges( + svn_mergeinfo_catalog_t *filtered_catalog, + svn_mergeinfo_catalog_t catalog, + svn_revnum_t youngest_rev, + svn_revnum_t oldest_rev, + svn_boolean_t include_range, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* If MERGEINFO is non-inheritable return TRUE, return FALSE otherwise. + MERGEINFO may be NULL or empty. */ +svn_boolean_t +svn_mergeinfo__is_noninheritable(svn_mergeinfo_t mergeinfo, + apr_pool_t *scratch_pool); + +/* Return a rangelist with one svn_merge_range_t * element defined by START, + END, and INHERITABLE. The rangelist and its contents are allocated in + RESULT_POOL. */ +svn_rangelist_t * +svn_rangelist__initialize(svn_revnum_t start, + svn_revnum_t end, + svn_boolean_t inheritable, + apr_pool_t *result_pool); + +/* Adjust in-place MERGEINFO's rangelists by OFFSET. If OFFSET is negative + and would adjust any part of MERGEINFO's source revisions to 0 or less, + then those revisions are dropped. If all the source revisions for a merge + source path are dropped, then the path itself is dropped. If all merge + source paths are dropped, then *ADJUSTED_MERGEINFO is set to an empty + hash. *ADJUSTED_MERGEINFO is allocated in RESULT_POOL. SCRATCH_POOL is + used for any temporary allocations. */ +svn_error_t * +svn_mergeinfo__adjust_mergeinfo_rangelists(svn_mergeinfo_t *adjusted_mergeinfo, + svn_mergeinfo_t mergeinfo, + svn_revnum_t offset, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Translates an array SEGMENTS (of svn_location_segment_t *), like the one + returned from svn_client__repos_location_segments, into a mergeinfo + *MERGEINFO_P, allocated in POOL. + + Note: A svn_location_segment_t segment may legitimately describe only revision 0, + but there is no way to describe that using svn_mergeinfo_t. Any such + segment in SEGMENTS are ignored. */ +svn_error_t * +svn_mergeinfo__mergeinfo_from_segments(svn_mergeinfo_t *mergeinfo_p, + const apr_array_header_t *segments, + apr_pool_t *pool); + +/* Merge every rangelist in MERGEINFO into the given MERGED_RANGELIST, + * ignoring the source paths of MERGEINFO. MERGED_RANGELIST may + * initially be empty. New elements added to RANGELIST are allocated in + * RESULT_POOL. See svn_rangelist_merge2() for details of inheritability + * etc. */ +svn_error_t * +svn_rangelist__merge_many(svn_rangelist_t *merged_rangelist, + svn_mergeinfo_t mergeinfo, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_MERGEINFO_PRIVATE_H */ diff --git a/subversion/include/private/svn_mutex.h b/subversion/include/private/svn_mutex.h new file mode 100644 index 0000000..85583d3 --- /dev/null +++ b/subversion/include/private/svn_mutex.h @@ -0,0 +1,117 @@ +/** + * @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_mutex.h + * @brief Strutures and functions for mutual exclusion + */ + +#ifndef SVN_MUTEX_H +#define SVN_MUTEX_H + +#include <apr_thread_mutex.h> + +#include "svn_error.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * 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 + +/** 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. + * + * If threading is not supported by APR, this function is a no-op. + */ +svn_error_t * +svn_mutex__init(svn_mutex__t **mutex, + svn_boolean_t mutex_required, + apr_pool_t *result_pool); + +/** Acquire the @a mutex, if that has been enabled in svn_mutex__init(). + * Make sure to call svn_mutex__unlock() some time later in the same + * thread to release the mutex again. Recursive locking are not supported. + * + * @note You should use #SVN_MUTEX__WITH_LOCK instead of explicit lock + * aquisition and release. + */ +svn_error_t * +svn_mutex__lock(svn_mutex__t *mutex); + +/** Release the @a mutex, previously acquired using svn_mutex__lock() + * that has been enabled in svn_mutex__init(). + * + * Since this is often used as part of the calling function's exit + * sequence, we accept that function's current return code in @a err. + * If it is not #SVN_NO_ERROR, it will be used as the return value - + * irrespective of the possible internal failures during unlock. If @a err + * is #SVN_NO_ERROR, internal failures of this function will be + * reported in the return value. + * + * @note You should use #SVN_MUTEX__WITH_LOCK instead of explicit lock + * aquisition and release. + */ +svn_error_t * +svn_mutex__unlock(svn_mutex__t *mutex, + svn_error_t *err); + +/** Aquires the @a mutex, executes the expression @a expr and finally + * releases the @a mutex. If any of these steps fail, the function using + * this macro will return an #svn_error_t. This macro guarantees that + * the @a mutex will always be unlocked again if it got locked successfully + * by the first step. + * + * @note Prefer using this macro instead of explicit lock aquisition and + * release. + */ +#define SVN_MUTEX__WITH_LOCK(mutex, expr) \ +do { \ + svn_mutex__t *svn_mutex__m = (mutex); \ + SVN_ERR(svn_mutex__lock(svn_mutex__m)); \ + SVN_ERR(svn_mutex__unlock(svn_mutex__m, (expr))); \ +} while (0) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_MUTEX_H */ diff --git a/subversion/include/private/svn_named_atomic.h b/subversion/include/private/svn_named_atomic.h new file mode 100644 index 0000000..4efa255 --- /dev/null +++ b/subversion/include/private/svn_named_atomic.h @@ -0,0 +1,162 @@ +/** + * @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_opt_private.h b/subversion/include/private/svn_opt_private.h new file mode 100644 index 0000000..6ae67a5 --- /dev/null +++ b/subversion/include/private/svn_opt_private.h @@ -0,0 +1,156 @@ +/** + * @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_opt_private.h + * @brief Subversion-internal option parsing APIs. + */ + +#ifndef SVN_OPT_PRIVATE_H +#define SVN_OPT_PRIVATE_H + +#include <apr_pools.h> +#include <apr_tables.h> +#include <apr_getopt.h> + +#include "svn_error.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Extract the peg revision, if any, from UTF8_TARGET. + * + * If PEG_REVISION is not NULL, return the peg revision in *PEG_REVISION. + * *PEG_REVISION will be an empty string if no peg revision is found. + * Return the true target portion in *TRUE_TARGET. + * + * 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 + * point to the string "@", containing only a single character. + * + * All allocations are done in POOL. + */ +svn_error_t * +svn_opt__split_arg_at_peg_revision(const char **true_target, + const char **peg_revision, + const char *utf8_target, + apr_pool_t *pool); + +/* Attempt to transform URL_IN, which is a URL-like user input, into a + * valid URL: + * - escape IRI characters and some other non-URI characters + * - check that no back-path ("..") components are present + * - call svn_uri_canonicalize() + * URL_IN is in UTF-8 encoding and has no peg revision specifier. + * Set *URL_OUT to the result, allocated from POOL. + */ +svn_error_t * +svn_opt__arg_canonicalize_url(const char **url_out, + const char *url_in, + apr_pool_t *pool); + +/* + * Attempt to transform PATH_IN, which is a local path-like user input, into a + * valid local path: + * - Attempt to get the correct capitalization by trying to actually find + * the path specified. + * - If the path does not exist (which is valid) the given capitalization + * is used. + * - canonicalize the separator ("/") characters + * - call svn_dirent_canonicalize() + * PATH_IN is in UTF-8 encoding and has no peg revision specifier. + * Set *PATH_OUT to the result, allocated from POOL. + */ +svn_error_t * +svn_opt__arg_canonicalize_path(const char **path_out, + const char *path_in, + apr_pool_t *pool); + +/* + * Pull remaining target arguments from OS into *TARGETS_P, + * converting them to UTF-8, followed by targets from KNOWN_TARGETS + * (which might come from, for example, the "--targets" command line + * option), which are already in UTF-8. + * + * On each URL target, do some IRI-to-URI encoding and some + * auto-escaping. On each local path, canonicalize case and path + * separators. + * + * Allocate *TARGETS_P and its elements in POOL. + * + * If a path has the same name as a Subversion working copy + * administrative directory, return SVN_ERR_RESERVED_FILENAME_SPECIFIED; + * if multiple reserved paths are encountered, return a chain of + * errors, all of which are SVN_ERR_RESERVED_FILENAME_SPECIFIED. Do + * not return this type of error in a chain with any other type of + * error, and if this is the only type of error encountered, complete + * the operation before returning the error(s). + */ +svn_error_t * +svn_opt__args_to_target_array(apr_array_header_t **targets_p, + apr_getopt_t *os, + const apr_array_header_t *known_targets, + apr_pool_t *pool); + +/** + * Return a human-readable description of @a revision. The result + * will be allocated statically or from @a result_pool. + * + * @since New in 1.7. + */ +const char * +svn_opt__revision_to_string(const svn_opt_revision_t *revision, + apr_pool_t *result_pool); + +/** + * Create a revision range structure from two revisions. Return a new range + * allocated in @a result_pool with the start and end initialized to + * (deep copies of) @a *start_revision and @a *end_revision. + */ +svn_opt_revision_range_t * +svn_opt__revision_range_create(const svn_opt_revision_t *start_revision, + const svn_opt_revision_t *end_revision, + apr_pool_t *result_pool); + +/** + * Create a revision range structure from two revnums. Return a new range + * allocated in @a result_pool with the start and end kinds initialized to + * #svn_opt_revision_number and values @a start_revnum and @a end_revnum. + */ +svn_opt_revision_range_t * +svn_opt__revision_range_from_revnums(svn_revnum_t start_revnum, + svn_revnum_t end_revnum, + apr_pool_t *result_pool); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_OPT_PRIVATE_H */ diff --git a/subversion/include/private/svn_pseudo_md5.h b/subversion/include/private/svn_pseudo_md5.h new file mode 100644 index 0000000..34d5929 --- /dev/null +++ b/subversion/include/private/svn_pseudo_md5.h @@ -0,0 +1,83 @@ +/** + * @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 new file mode 100644 index 0000000..4531bcb --- /dev/null +++ b/subversion/include/private/svn_ra_private.h @@ -0,0 +1,280 @@ +/** + * @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_ra_private.h + * @brief The Subversion repository access library - Internal routines + */ + +#ifndef SVN_RA_PRIVATE_H +#define SVN_RA_PRIVATE_H + +#include <apr_pools.h> + +#include "svn_error.h" +#include "svn_ra.h" +#include "svn_delta.h" +#include "svn_editor.h" +#include "svn_io.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Return an error with code SVN_ERR_UNSUPPORTED_FEATURE, and an error + message referencing PATH_OR_URL, if the "server" pointed to by + RA_SESSION doesn't support Merge Tracking (e.g. is pre-1.5). + Perform temporary allocations in POOL. */ +svn_error_t * +svn_ra__assert_mergeinfo_capable_server(svn_ra_session_t *ra_session, + const char *path_or_url, + apr_pool_t *pool); + + +/*** Operational Locks ***/ + +/** This is a function type which allows svn_ra__get_operational_lock() + * to report lock attempt failures. If non-NULL, @a locktoken is the + * preexisting lock which prevented lock acquisition. + * + * @since New in 1.7. + */ +typedef svn_error_t *(*svn_ra__lock_retry_func_t)(void *baton, + const svn_string_t *locktoken, + apr_pool_t *pool); + +/** Acquire a lock (of sorts) on the repository associated with the + * given RA @a session, retrying as necessary up to @a num_retries + * times, and set @a *lock_string_p to the value of the acquired lock + * token. Allocate the returned token from @a pool. (See this + * function's counterpart svn_ra__release_operational_lock() for your + * lock removal needs.) + * + * @a lock_revprop_name is the name of the revision-0 property used to + * store the lock. + * + * If @a steal_lock is set, then replace any pre-existing lock on the + * repository with our own. Iff such a theft occurs and + * @a stolen_lock_p is non-NULL, set @a *stolen_lock_p to the token of + * the lock we stole. + * + * Call @a retry_func with @a retry_baton each time the retry loop + * fails to acquire a lock. + * + * Use @a cancel_func and @a cancel_baton to check for early + * cancellation. + * + * @note If the server does not support #SVN_RA_CAPABILITY_ATOMIC_REVPROPS + * (i.e., is a pre-1.7 server), then this function makes a "best effort" + * attempt to obtain the lock, but is susceptible to a race condition; see + * issue #3546. + * + * @since New in 1.7. + */ +svn_error_t * +svn_ra__get_operational_lock(const svn_string_t **lock_string_p, + const svn_string_t **stolen_lock_p, + svn_ra_session_t *session, + const char *lock_revprop_name, + svn_boolean_t steal_lock, + int num_retries, + svn_ra__lock_retry_func_t retry_func, + void *retry_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *pool); + +/** Release an operational lock (whose value is @a mylocktoken) on the + * repository associated with RA @a session. (This is the counterpart + * to svn_ra__get_operational_lock().) + * + * @a lock_revprop_name is the name of the revision-0 property used to + * store the lock. + * + * Use @a scratch_pool for temporary allocations. + * + * @since New in 1.7. + */ +svn_error_t * +svn_ra__release_operational_lock(svn_ra_session_t *session, + const char *lock_revprop_name, + const svn_string_t *mylocktoken, + apr_pool_t *scratch_pool); + +/** Register CALLBACKS to be used with the Ev2 shims in RA_SESSION. */ +svn_error_t * +svn_ra__register_editor_shim_callbacks(svn_ra_session_t *ra_session, + svn_delta_shim_callbacks_t *callbacks); + + +/* Using information from BATON, provide the (file's) pristine contents + for REPOS_RELPATH. They are returned in *CONTENTS, and correspond to + *REVISION. + + If a pristine is not available (ie. a locally-added node), then set + *CONTENTS to NULL; *REVISION will not be examined in this case. + + These are allocated in RESULT_POOL. SCRATCH_POOL can be used + for temporary allocations. */ +typedef svn_error_t *(*svn_ra__provide_base_cb_t)( + svn_stream_t **contents, + svn_revnum_t *revision, + void *baton, + const char *repos_relpath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Using information from BATON, provide the pristine properties for + REPOS_RELPATH. They are returned in *PROPS, and correspond to *REVISION. + + If properties are not available (ie. a locally-added node), then set + *PROPS to NULL; *REVISION will not be examined in this case. + + The properties are allocated in RESULT_POOL. SCRATCH_POOL can be used + for temporary allocations. */ +typedef svn_error_t *(*svn_ra__provide_props_cb_t)( + apr_hash_t **props, + svn_revnum_t *revision, + void *baton, + const char *repos_relpath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Using information from BATON, fetch the kind of REPOS_RELPATH at revision + SRC_REVISION, returning it in *KIND. + + If the kind cannot be determined, then set *KIND to svn_node_unknown. + + Temporary allocations can be made in SCRATCH_POOL. */ +typedef svn_error_t *(*svn_ra__get_copysrc_kind_cb_t)( + svn_node_kind_t *kind, + void *baton, + const char *repos_relpath, + svn_revnum_t src_revision, + apr_pool_t *scratch_pool); + + +/* Return an Ev2-based editor for performing commits. + + The editor is associated with the given SESSION, and its implied target + repository. + + REVPROPS contains all the revision properties that should be stored onto + the newly-committed revision. SVN_PROP_REVISION_AUTHOR will be set to + the username as determined by the session; overwriting any prior value + that may be present in REVPROPS. + + COMMIT_CB/BATON contain the callback to receive post-commit information. + + LOCK_TOKENS should contain all lock tokens necessary to modify paths + within the commit. If KEEP_LOCKS is FALSE, then the paths associated + with these tokens will be unlocked. + ### today, LOCK_TOKENS is session_relpath:token_value. in the future, + ### it should be repos_relpath:token_value. + + PROVIDE_BASE_CB is a callback to fetch pristine contents, used to send + an svndiff over the wire to the server. This may be NULL, indicating + pristine contents are not available (eg. URL-based operations or import). + + PROVIDE_PROPS_CB is a callback to fetch pristine properties, used to + send property deltas over the wire to the server. This may be NULL, + indicating pristine properties are not available (eg. URL-based operations + or an import). + + GET_COPYSRC_KIND_CB is a callback to determine the kind of a copy-source. + This is necessary when an Ev2/Ev1 shim is required by the RA provider, + in order to determine whether to use delta->add_directory() or the + delta->add_file() vtable entry to perform the copy. + ### unclear on impact if this is NULL. + ### this callback will disappear when "everything" is running Ev2 + + CB_BATON is the baton used/shared by the above three callbacks. + + Cancellation is handled through the callbacks provided when SESSION + is initially opened. + + *EDITOR will be allocated in RESULT_POOL, and all temporary allocations + will be performed in SCRATCH_POOL. +*/ +svn_error_t * +svn_ra__get_commit_ev2(svn_editor_t **editor, + svn_ra_session_t *session, + apr_hash_t *revprops, + svn_commit_callback2_t commit_cb, + void *commit_baton, + apr_hash_t *lock_tokens, + svn_boolean_t keep_locks, + svn_ra__provide_base_cb_t provide_base_cb, + svn_ra__provide_props_cb_t provide_props_cb, + svn_ra__get_copysrc_kind_cb_t get_copysrc_kind_cb, + void *cb_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/* Similar to #svn_ra_replay_revstart_callback_t, but with an Ev2 editor. */ +typedef svn_error_t *(*svn_ra__replay_revstart_ev2_callback_t)( + svn_revnum_t revision, + void *replay_baton, + svn_editor_t **editor, + apr_hash_t *rev_props, + apr_pool_t *pool); + +/* Similar to #svn_ra_replay_revfinish_callback_t, but with an Ev2 editor. */ +typedef svn_error_t *(*svn_ra__replay_revfinish_ev2_callback_t)( + svn_revnum_t revision, + void *replay_baton, + svn_editor_t *editor, + apr_hash_t *rev_props, + apr_pool_t *pool); + +/* Similar to svn_ra_replay_range(), but uses Ev2 versions of the callback + functions. */ +svn_error_t * +svn_ra__replay_range_ev2(svn_ra_session_t *session, + svn_revnum_t start_revision, + svn_revnum_t end_revision, + svn_revnum_t low_water_mark, + svn_boolean_t send_deltas, + svn_ra__replay_revstart_ev2_callback_t revstart_func, + svn_ra__replay_revfinish_ev2_callback_t revfinish_func, + void *replay_baton, + svn_ra__provide_base_cb_t provide_base_cb, + svn_ra__provide_props_cb_t provide_props_cb, + svn_ra__get_copysrc_kind_cb_t get_copysrc_kind_cb, + void *cb_baton, + apr_pool_t *scratch_pool); + +/* Similar to svn_ra_replay(), but with an Ev2 editor. */ +svn_error_t * +svn_ra__replay_ev2(svn_ra_session_t *session, + svn_revnum_t revision, + svn_revnum_t low_water_mark, + svn_boolean_t send_deltas, + svn_editor_t *editor, + apr_pool_t *scratch_pool); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_RA_PRIVATE_H */ diff --git a/subversion/include/private/svn_ra_svn_private.h b/subversion/include/private/svn_ra_svn_private.h new file mode 100644 index 0000000..b4294d0 --- /dev/null +++ b/subversion/include/private/svn_ra_svn_private.h @@ -0,0 +1,826 @@ +/** + * @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_ra_svn_private.h + * @brief Functions used by the server - Internal routines + */ + +#ifndef SVN_RA_SVN_PRIVATE_H +#define SVN_RA_SVN_PRIVATE_H + +#include "svn_ra_svn.h" +#include "svn_editor.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** + * Set the shim callbacks to be used by @a conn to @a shim_callbacks. + */ +svn_error_t * +svn_ra_svn__set_shim_callbacks(svn_ra_svn_conn_t *conn, + svn_delta_shim_callbacks_t *shim_callbacks); + +/** + * @defgroup ra_svn_deprecated ra_svn low-level functions + * @{ + */ + +/** Write a number over the net. + * + * Writes will be buffered until the next read or flush. + */ +svn_error_t * +svn_ra_svn__write_number(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + apr_uint64_t number); + +/** Write a string over the net. + * + * Writes will be buffered until the next read or flush. + */ +svn_error_t * +svn_ra_svn__write_string(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_string_t *str); + +/** Write a cstring over the net. + * + * Writes will be buffered until the next read or flush. + */ +svn_error_t * +svn_ra_svn__write_cstring(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *s); + +/** Write a word over the net. + * + * Writes will be buffered until the next read or flush. + */ +svn_error_t * +svn_ra_svn__write_word(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *word); + +/** 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. + * + * @since New in 1.5. + */ +svn_error_t * +svn_ra_svn__write_proplist(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + apr_hash_t *props); + +/** Begin a list. Writes will be buffered until the next read or flush. */ +svn_error_t * +svn_ra_svn__start_list(svn_ra_svn_conn_t *conn, + apr_pool_t *pool); + +/** End a list. Writes will be buffered until the next read or flush. */ +svn_error_t * +svn_ra_svn__end_list(svn_ra_svn_conn_t *conn, + apr_pool_t *pool); + +/** Flush the write buffer. + * + * Normally this shouldn't be necessary, since the write buffer is flushed + * when a read is attempted. + */ +svn_error_t * +svn_ra_svn__flush(svn_ra_svn_conn_t *conn, + apr_pool_t *pool); + +/** Write a tuple, using a printf-like interface. + * + * The format string @a fmt may contain: + * + *@verbatim + Spec Argument type Item type + ---- -------------------- --------- + n apr_uint64_t Number + r svn_revnum_t Number + s const svn_string_t * String + c const char * String + w const char * Word + b svn_boolean_t Word ("true" or "false") + ( Begin tuple + ) End tuple + ? Remaining elements optional + ! (at beginning or end) Suppress opening or closing of tuple + @endverbatim + * + * Inside the optional part of a tuple, 'r' values may be @c + * SVN_INVALID_REVNUM, 'n' values may be + * SVN_RA_SVN_UNSPECIFIED_NUMBER, and 's', 'c', and 'w' values may be + * @c NULL; in these cases no data will be written. 'b' and '(' may + * not appear in the optional part of a tuple. Either all or none of + * the optional values should be valid. + * + * (If we ever have a need for an optional boolean value, we should + * invent a 'B' specifier which stores a boolean into an int, using -1 + * for unspecified. Right now there is no need for such a thing.) + * + * Use the '!' format specifier to write partial tuples when you have + * to transmit an array or other unusual data. For example, to write + * a tuple containing a revision, an array of words, and a boolean: + * @code + SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "r(!", rev)); + for (i = 0; i < n; i++) + SVN_ERR(svn_ra_svn_write_word(conn, pool, words[i])); + SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!)b", flag)); @endcode + */ +svn_error_t * +svn_ra_svn__write_tuple(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *fmt, ...); + +/** Read an item from the network into @a *item. */ +svn_error_t * +svn_ra_svn__read_item(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_ra_svn_item_t **item); + +/** Scan data on @a conn until we find something which looks like the + * beginning of an svn server greeting (an open paren followed by a + * whitespace character). This function is appropriate for beginning + * a client connection opened in tunnel mode, since people's dotfiles + * sometimes write output to stdout. It may only be called at the + * beginning of a client connection. + */ +svn_error_t * +svn_ra_svn__skip_leading_garbage(svn_ra_svn_conn_t *conn, + apr_pool_t *pool); + +/** Parse an array of @c svn_sort__item_t structures as a tuple, using a + * printf-like interface. The format string @a fmt may contain: + * + *@verbatim + Spec Argument type Item type + ---- -------------------- --------- + n apr_uint64_t * Number + r svn_revnum_t * Number + s svn_string_t ** String + c const char ** String + w const char ** Word + b svn_boolean_t * Word ("true" or "false") + B apr_uint64_t * Word ("true" or "false") + l apr_array_header_t ** List + ( Begin tuple + ) End tuple + ? Tuple is allowed to end here + @endverbatim + * + * Note that a tuple is only allowed to end precisely at a '?', or at + * 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. + * + * 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. + */ +svn_error_t * +svn_ra_svn__parse_tuple(const apr_array_header_t *list, + apr_pool_t *pool, + const char *fmt, ...); + +/** Read a tuple from the network and parse it as a tuple, using the + * format string notation from svn_ra_svn_parse_tuple(). + */ +svn_error_t * +svn_ra_svn__read_tuple(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *fmt, ...); + +/** Parse an array of @c svn_ra_svn_item_t structures as a list of + * properties, storing the properties in a hash table. + * + * @since New in 1.5. + */ +svn_error_t * +svn_ra_svn__parse_proplist(const apr_array_header_t *list, + apr_pool_t *pool, + apr_hash_t **props); + +/** Read a command response from the network and parse it as a tuple, using + * the format string notation from svn_ra_svn_parse_tuple(). + */ +svn_error_t * +svn_ra_svn__read_cmd_response(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *fmt, ...); + +/** 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 + * command, and @a baton. Commands will be accepted until a + * terminating command is received (a command with "terminate" set in + * the command table). If a command handler returns an error wrapped + * in SVN_RA_SVN_CMD_ERR (see the @c SVN_CMD_ERR macro), the error + * will be reported to the other side of the connection and the + * command loop will continue; any other kind of error (typically a + * network or protocol error) is passed through to the caller. + * + * @since New in 1.6. + * + */ +svn_error_t * +svn_ra_svn__handle_commands2(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const svn_ra_svn_cmd_entry_t *commands, + void *baton, + svn_boolean_t error_on_disconnect); + +/** Write a successful command response over the network, using the + * same format string notation as svn_ra_svn_write_tuple(). Do not use + * partial tuples with this function; if you need to use partial + * tuples, just write out the "success" and argument tuple by hand. + */ +svn_error_t * +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. */ +svn_error_t * +svn_ra_svn__write_cmd_failure(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_error_t *err); + +/** + * @} + */ + +/** + * @defgroup svn_commands sending ra_svn commands + * @{ + */ + +/** Sets the target revision of connection @a conn to @a rev. Use @a pool + * for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_target_rev(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_revnum_t rev); + +/** Send a "open-root" command over connection @a conn. Open the + * repository root at revision @a rev and associate it with @a token. + * Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_open_root(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_revnum_t rev, + const char *token); + +/** Send a "delete-entry" command over connection @a conn. Delete the + * @a path at optional revision @a rev below @a parent_token. + * Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_delete_entry(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + svn_revnum_t rev, + const char *parent_token); + +/** Send a "add-dir" command over connection @a conn. Add a new directory + * node named @a path under the directory identified by @a parent_token. + * Associate the new directory with the given @a token. * @a copy_path + * and @a copy_rev are optional and describe the copy source. + * Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_add_dir(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + const char *parent_token, + const char *token, + const char *copy_path, + svn_revnum_t copy_rev); + +/** Send a "open-dir" command over connection @a conn. Associate to + * @a token the directory node named @a path under the directory + * identified by @a parent_token in revision @a rev. + * Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_open_dir(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + const char *parent_token, + const char *token, + svn_revnum_t rev); + +/** Send a "change-dir-prop" command over connection @a conn. Set the + * property @a name to the optional @a value on the directory identified + * to @a token. Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_change_dir_prop(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *token, + const char *name, + const svn_string_t *value); + +/** Send a "close-dir" command over connection @a conn. Identify the node + * to close with @a token. The latter will then no longer be associated + * with that node. Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_close_dir(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *token); + +/** Send a "absent-dir" command over connection @a conn. Directory node + * named @a path under the directory identified by @a parent_token is + * absent. Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_absent_dir(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + const char *parent_token); + +/** Send a "add-file" command over connection @a conn. Add a new file + * node named @a path under the directory identified by @a parent_token. + * Associate the new file with the given @a token. * @a copy_path and + * @a copy_rev are optional and describe the copy source. + * Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_add_file(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + const char *parent_token, + const char *token, + const char *copy_path, + svn_revnum_t copy_rev); + +/** Send a "open-file" command over connection @a conn. Associate to + * @a token the file node named @a path under the directory identified by + * @a parent_token in revision @a rev. + * Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_open_file(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + const char *parent_token, + const char *token, + svn_revnum_t rev); + +/** Send a "change-file-prop" command over connection @a conn. Set the + * property @a name to the optional @a value on the file identified to + * @a token. Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_change_file_prop(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *token, + const char *name, + const svn_string_t *value); + +/** Send a "close-dir" command over connection @a conn. Identify the node + * to close with @a token and provide an optional @a check_sum. The token + * will then no longer be associated with that node. + * Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_close_file(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *token, + const char *text_checksum); + +/** Send a "absent-file" command over connection @a conn. File node + * named @a path in the directory identified by @a parent_token is + * absent. Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_absent_file(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + const char *parent_token); + +/** Send a "apply-textdelta" command over connection @a conn. Starts a + * series of text deltas to be applied to the file identified by @a token. + * Optionally, specify the file's current checksum in @a base_checksum. + * Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_apply_textdelta(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *token, + const char *base_checksum); + +/** Send a "textdelta-chunk" command over connection @a conn. Apply + * textdelta @a chunk to the file identified by @a token. + * Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_textdelta_chunk(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *token, + const svn_string_t *chunk); + +/** Send a "textdelta-end" command over connection @a conn. Ends the + * series of text deltas to be applied to the file identified by @a token. + * Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_textdelta_end(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *token); + +/** Send a "close-edit" command over connection @a conn. Ends the editor + * drive (successfully). Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_close_edit(svn_ra_svn_conn_t *conn, + apr_pool_t *pool); + +/** Send a "abort-edit" command over connection @a conn. Prematurely ends + * the editor drive, e.g. due to some problem on the other side. + * Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_abort_edit(svn_ra_svn_conn_t *conn, + apr_pool_t *pool); + +/** Send a "set-path" command over connection @a conn. + * Use @a pool for allocations. + * + * @see set_path() in #svn_ra_reporter3_t for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_set_path(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + svn_revnum_t rev, + svn_boolean_t start_empty, + const char *lock_token, + svn_depth_t depth); + +/** Send a "delete-path" command over connection @a conn. + * Use @a pool for allocations. + * + * @see delete_path() in #svn_ra_reporter3_t for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_delete_path(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path); + +/** Send a "link-path" command over connection @a conn. + * Use @a pool for allocations. + * + * @see link_path() in #svn_ra_reporter3_t for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_link_path(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + const char *url, + svn_revnum_t rev, + svn_boolean_t start_empty, + const char *lock_token, + svn_depth_t depth); + +/** Send a "finish-report" command over connection @a conn. + * Use @a pool for allocations. + * + * @see finish_report() in #svn_ra_reporter3_t for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_finish_report(svn_ra_svn_conn_t *conn, + apr_pool_t *pool); + +/** Send a "abort-report" command over connection @a conn. + * Use @a pool for allocations. + * + * @see abort_report() in #svn_ra_reporter3_t for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_abort_report(svn_ra_svn_conn_t *conn, + apr_pool_t *pool); + +/** Send a "reparent" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_reparent for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_reparent(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *url); + +/** Send a "get-latest-rev" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_get_latest_revnum for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_get_latest_rev(svn_ra_svn_conn_t *conn, + apr_pool_t *pool); + +/** Send a "get-dated-rev" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_get_dated_revision for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_get_dated_rev(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + apr_time_t tm); + +/** Send a "change-rev-prop2" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_change_rev_prop2 for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_change_rev_prop2(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_revnum_t rev, + const char *name, + const svn_string_t *value, + svn_boolean_t dont_care, + const svn_string_t *old_value); + +/** Send a "change-rev-prop" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_change_rev_prop for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_change_rev_prop(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_revnum_t rev, + const char *name, + const svn_string_t *value); + +/** Send a "rev-proplist" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_rev_proplist for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_rev_proplist(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_revnum_t rev); + +/** Send a "rev-prop" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_rev_prop for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_rev_prop(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_revnum_t rev, + const char *name); + +/** Send a "get-file" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_get_file for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_get_file(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + svn_revnum_t rev, + svn_boolean_t props, + svn_boolean_t stream); + +/** Send a "update" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_do_update3 for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_update(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_revnum_t rev, + const char *target, + svn_boolean_t recurse, + svn_depth_t depth, + svn_boolean_t send_copyfrom_args, + svn_boolean_t ignore_ancestry); + +/** Send a "switch" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_do_switch3 for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_switch(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_revnum_t rev, + const char *target, + svn_boolean_t recurse, + const char *switch_url, + svn_depth_t depth, + svn_boolean_t send_copyfrom_args, + svn_boolean_t ignore_ancestry); + +/** Send a "status" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_do_status2 for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_status(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *target, + svn_boolean_t recurse, + svn_revnum_t rev, + svn_depth_t depth); + +/** Send a "diff" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_do_diff3 for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_diff(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_revnum_t rev, + const char *target, + svn_boolean_t recurse, + svn_boolean_t ignore_ancestry, + const char *versus_url, + svn_boolean_t text_deltas, + svn_depth_t depth); + +/** Send a "check-path" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_check_path for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_check_path(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + svn_revnum_t rev); + +/** Send a "stat" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_stat for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_stat(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + svn_revnum_t rev); + +/** Send a "get-file-revs" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_get_file_revs2 for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_get_file_revs(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + svn_revnum_t start, + svn_revnum_t end, + svn_boolean_t include_merged_revisions); + +/** Send a "lock" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_lock for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_lock(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + const char *comment, + svn_boolean_t steal_lock, + svn_revnum_t revnum); + +/** Send a "unlock" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_unlock for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_unlock(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + const char *token, + svn_boolean_t break_lock); + +/** Send a "get-lock" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_get_lock for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_get_lock(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path); + +/** Send a "get-locks" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_get_locks2 for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_get_locks(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + svn_depth_t depth); + +/** Send a "replay" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_replay for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_replay(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_revnum_t rev, + svn_revnum_t low_water_mark, + svn_boolean_t send_deltas); + +/** Send a "replay-range" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_replay_range for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_replay_range(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + svn_revnum_t start_revision, + svn_revnum_t end_revision, + svn_revnum_t low_water_mark, + svn_boolean_t send_deltas); + +/** Send a "get-deleted-rev" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_get_deleted_rev for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_get_deleted_rev(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + svn_revnum_t peg_revision, + svn_revnum_t end_revision); + +/** Send a "get-iprops" command over connection @a conn. + * Use @a pool for allocations. + * + * @see #svn_ra_get_inherited_props for a description. + */ +svn_error_t * +svn_ra_svn__write_cmd_get_iprops(svn_ra_svn_conn_t *conn, + apr_pool_t *pool, + const char *path, + svn_revnum_t revision); + +/** Send a "finish-replay" command over connection @a conn. + * Use @a pool for allocations. + */ +svn_error_t * +svn_ra_svn__write_cmd_finish_replay(svn_ra_svn_conn_t *conn, + apr_pool_t *pool); + +/** + * @} + */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_RA_SVN_PRIVATE_H */ diff --git a/subversion/include/private/svn_repos_private.h b/subversion/include/private/svn_repos_private.h new file mode 100644 index 0000000..8e943ae --- /dev/null +++ b/subversion/include/private/svn_repos_private.h @@ -0,0 +1,121 @@ +/** + * @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_repos_private.h + * @brief Subversion-internal repos APIs. + */ + +#ifndef SVN_REPOS_PRIVATE_H +#define SVN_REPOS_PRIVATE_H + +#include <apr_pools.h> + +#include "svn_types.h" +#include "svn_repos.h" +#include "svn_editor.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. + * + * Use @a pool for temporary allocations. + * + * @note This function is used to implement server-side validation. + * Consequently, if you make this function stricter in what it accepts, you + * (a) break svnsync'ing of existing repositories that contain now-invalid + * properties, (b) do not preclude such invalid values from entering the + * repository via tools that use the svn_fs_* API directly (possibly + * including svnadmin and svnlook). This has happened before and there + * are known (documented, but unsupported) upgrade paths in some cases. + * + * @since New in 1.7. + */ +svn_error_t * +svn_repos__validate_prop(const char *name, + const svn_string_t *value, + apr_pool_t *pool); + +/** + * Given the error @a err from svn_repos_fs_commit_txn(), return an + * string containing either or both of the svn_fs_commit_txn() error + * and the SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED wrapped error from + * the post-commit hook. Any error tracing placeholders in the error + * chain are skipped over. + * + * This function does not modify @a err. + * + * ### This method should not be necessary, but there are a few + * ### places, e.g. mod_dav_svn, where only a single error message + * ### string is returned to the caller and it is useful to have both + * ### error messages included in the message. + * + * Use @a pool to do any allocations in. + * + * @since New in 1.7. + */ +const char * +svn_repos__post_commit_error_str(svn_error_t *err, + apr_pool_t *pool); + +/* A repos version of svn_fs_type */ +svn_error_t * +svn_repos__fs_type(const char **fs_type, + const char *repos_path, + apr_pool_t *pool); + + +/* Create a commit editor for REPOS, based on REVISION. */ +svn_error_t * +svn_repos__get_commit_ev2(svn_editor_t **editor, + svn_repos_t *repos, + svn_authz_t *authz, + const char *authz_repos_name, + const char *authz_user, + apr_hash_t *revprops, + svn_commit_callback2_t commit_cb, + void *commit_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +svn_error_t * +svn_repos__replay_ev2(svn_fs_root_t *root, + const char *base_dir, + svn_revnum_t low_water_mark, + svn_editor_t *editor, + svn_repos_authz_func_t authz_read_func, + void *authz_read_baton, + apr_pool_t *scratch_pool); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_REPOS_PRIVATE_H */ diff --git a/subversion/include/private/svn_skel.h b/subversion/include/private/svn_skel.h new file mode 100644 index 0000000..5b17b21 --- /dev/null +++ b/subversion/include/private/svn_skel.h @@ -0,0 +1,236 @@ +/* svn_skel.h : interface to `skeleton' functions + * + * ==================================================================== + * 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_SKEL_H +#define SVN_SKEL_H + +#include <apr_pools.h> + +#include "svn_string.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* What is a skel? */ + +/* Subversion needs to read a lot of structured data from database + records. Instead of writing a half-dozen parsers and getting lazy + about error-checking, we define a reasonably dense, open-ended + syntax for strings and lists, and then use that for the concrete + representation of files, directories, property lists, etc. This + lets us handle all the fussy character-by-character testing and + sanity checks all in one place, allowing the users of this library + to focus on higher-level consistency. + + A `skeleton' (or `skel') is either an atom, or a list. A list may + contain zero or more elements, each of which may be an atom or a + list. + + Here's a description of the syntax of a skel: + + A "whitespace" byte is 9, 10, 12, 13, or 32 (ASCII tab, newline, + form feed, carriage return, or space). + + A "digit" byte is 48 -- 57 (ASCII digits). + + A "name" byte is 65 -- 90, or 97 -- 122 (ASCII upper- and + lower-case characters). + + An atom has one the following two forms: + - any string of bytes whose first byte is a name character, and + which contains no whitespace characters, bytes 40 (ASCII '(') or + bytes 41 (ASCII ')') (`implicit-length form'), or + - a string of digit bytes, followed by exactly one whitespace + character, followed by N bytes, where N is the value of the digit + bytes as a decimal number (`explicit-length form'). + + In the first case, the `contents' of the atom are the entire string + of characters. In the second case, the contents of the atom are + the N bytes after the count and whitespace. + + A list consists of a byte 40 (ASCII '('), followed by a series of + atoms or lists, followed by a byte 41 (ASCII ')'). There may be + zero or more whitespace characters after the '(' and before the + ')', and between any pair of elements. If two consecutive elements + are atoms, they must be separated by at least one whitespace + character. */ + + +/* The `skel' structure. */ + +/* A structure representing the results of parsing an array of bytes + as a skel. */ +struct svn_skel_t { + + /* True if the string was an atom, false if it was a list. + + If the string is an atom, DATA points to the beginning of its + contents, and LEN gives the content length, in bytes. + + If the string is a list, DATA and LEN delimit the entire body of + the list. */ + svn_boolean_t is_atom; + + const char *data; + apr_size_t len; + + /* If the string is a list, CHILDREN is a pointer to a + null-terminated linked list of skel objects representing the + elements of the list, linked through their NEXT pointers. */ + struct svn_skel_t *children; + struct svn_skel_t *next; +}; +typedef struct svn_skel_t svn_skel_t; + + + +/* Operations on skels. */ + + +/* Parse the LEN bytes at DATA as the concrete representation of a + skel, and return a skel object allocated from POOL describing its + contents. If the data is not a properly-formed SKEL object, return + zero. + + The returned skel objects point into the block indicated by DATA + and LEN; we don't copy the contents. */ +svn_skel_t *svn_skel__parse(const char *data, apr_size_t len, + apr_pool_t *pool); + + +/* Create an atom skel whose contents are the C string STR, allocated + from POOL. */ +svn_skel_t *svn_skel__str_atom(const char *str, apr_pool_t *pool); + + +/* Create an atom skel whose contents are the LEN bytes at ADDR, + allocated from POOL. */ +svn_skel_t *svn_skel__mem_atom(const void *addr, apr_size_t len, + apr_pool_t *pool); + + +/* Create an empty list skel, allocated from POOL. */ +svn_skel_t *svn_skel__make_empty_list(apr_pool_t *pool); + +/* Duplicates the skel structure SRC_SKEL and if DUP_DATA is true also the + data it references in RESULT_POOL */ +svn_skel_t *svn_skel__dup(const svn_skel_t *src_skel, svn_boolean_t dup_data, + apr_pool_t *result_pool); + + +/* Prepend SKEL to LIST. */ +void svn_skel__prepend(svn_skel_t *skel, svn_skel_t *list); + + +/* Append SKEL to LIST. Note: this must traverse the LIST, so you + generally want to use svn_skel__prepend(). + + NOTE: careful of the argument order here. */ +void svn_skel__append(svn_skel_t *list, svn_skel_t *skel); + + +/* Create an atom skel whose contents are the string representation + of the integer VALUE, allocated in RESULT_POOL, and then prepend + it to SKEL. */ +void svn_skel__prepend_int(apr_int64_t value, + svn_skel_t *skel, + apr_pool_t *result_pool); + + +/* Create an atom skel (allocated from RESULT_POOL) whose contents refer + to the string VALUE, then prepend it to SKEL. + + NOTE: VALUE must have a lifetime *at least* that of RESULT_POOL. This + function does NOT copy it into RESULT_POOL. */ +void svn_skel__prepend_str(const char *value, + svn_skel_t *skel, + apr_pool_t *result_pool); + + +/* Parse SKEL as an integer and return the result in *N. + * SCRATCH_POOL is used for temporary memory. */ +svn_error_t * +svn_skel__parse_int(apr_int64_t *n, const svn_skel_t *skel, + apr_pool_t *scratch_pool); + + +/* Return a string whose contents are a concrete representation of + SKEL. Allocate the string from POOL. */ +svn_stringbuf_t *svn_skel__unparse(const svn_skel_t *skel, apr_pool_t *pool); + + +/* Return true iff SKEL is an atom whose data is the same as STR. */ +svn_boolean_t svn_skel__matches_atom(const svn_skel_t *skel, const char *str); + + +/* Return the length of the list skel SKEL. Atoms have a length of -1. */ +int svn_skel__list_length(const svn_skel_t *skel); + + +/* Parse a `PROPLIST' SKEL into a regular hash of properties, + *PROPLIST_P, which has const char * property names, and + svn_string_t * values. Use RESULT_POOL for all allocations. */ +svn_error_t * +svn_skel__parse_proplist(apr_hash_t **proplist_p, + const svn_skel_t *skel, + apr_pool_t *result_pool); + +/* Parse a `IPROPS' SKEL into a depth-first ordered array of + svn_prop_inherited_item_t * structures *IPROPS. Use RESULT_POOL + for all allocations. */ +svn_error_t * +svn_skel__parse_iprops(apr_array_header_t **iprops, + const svn_skel_t *skel, + apr_pool_t *result_pool); + +/* Parse a `PROPLIST' SKEL looking for PROPNAME. If PROPNAME is found + then return its value in *PROVAL, allocated in RESULT_POOL. */ +svn_error_t * +svn_skel__parse_prop(svn_string_t **propval, + const svn_skel_t *skel, + const char *propname, + apr_pool_t *result_pool); + +/* Unparse a PROPLIST hash (which has const char * property names and + svn_string_t * values) into a `PROPLIST' skel *SKEL_P. Use POOL + for all allocations. */ +svn_error_t * +svn_skel__unparse_proplist(svn_skel_t **skel_p, + const apr_hash_t *proplist, + apr_pool_t *pool); + +/* Unparse INHERITED_PROPS, a depth-first ordered array of + svn_prop_inherited_item_t * structures, into a `IPROPS' skel *SKEL_P. + Use RESULT_POOL for all allocations. */ +svn_error_t * +svn_skel__unparse_iproplist(svn_skel_t **skel_p, + const apr_array_header_t *inherited_props, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_SKEL_H */ diff --git a/subversion/include/private/svn_sqlite.h b/subversion/include/private/svn_sqlite.h new file mode 100644 index 0000000..c1d640b --- /dev/null +++ b/subversion/include/private/svn_sqlite.h @@ -0,0 +1,519 @@ +/* svn_sqlite.h + * + * ==================================================================== + * 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_SQLITE_H +#define SVN_SQLITE_H + +#include <apr_pools.h> + +#include "svn_types.h" +#include "svn_checksum.h" +#include "svn_error.h" + +#include "private/svn_token.h" /* for svn_token_map_t */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Because the SQLite code can be inlined into libsvn_subre/sqlite.c, + we define accessors to its compile-time and run-time version + numbers here. */ + +/* Return the value that SQLITE_VERSION had at compile time. */ +const char *svn_sqlite__compiled_version(void); + +/* Return the value of sqlite3_libversion() at run time. */ +const char *svn_sqlite__runtime_version(void); + + +typedef struct svn_sqlite__db_t svn_sqlite__db_t; +typedef struct svn_sqlite__stmt_t svn_sqlite__stmt_t; +typedef struct svn_sqlite__context_t svn_sqlite__context_t; +typedef struct svn_sqlite__value_t svn_sqlite__value_t; + +typedef enum svn_sqlite__mode_e { + svn_sqlite__mode_readonly, /* open the database read-only */ + svn_sqlite__mode_readwrite, /* open the database read-write */ + svn_sqlite__mode_rwcreate /* open/create the database read-write */ +} svn_sqlite__mode_t; + +/* The type used for callback functions. */ +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); + + +/* Step the given statement; if it returns SQLITE_DONE, reset the statement. + Otherwise, raise an SVN error. */ +svn_error_t * +svn_sqlite__step_done(svn_sqlite__stmt_t *stmt); + +/* Step the given statement; raise an SVN error (and reset the + statement) if it doesn't return SQLITE_ROW. */ +svn_error_t * +svn_sqlite__step_row(svn_sqlite__stmt_t *stmt); + +/* Step the given statement; raise an SVN error (and reset the + statement) if it doesn't return SQLITE_DONE or SQLITE_ROW. Set + *GOT_ROW to true iff it got SQLITE_ROW. +*/ +svn_error_t * +svn_sqlite__step(svn_boolean_t *got_row, svn_sqlite__stmt_t *stmt); + +/* Perform an insert as given by the prepared and bound STMT, and set + *ROW_ID to the id of the inserted row if ROW_ID is non-NULL. + STMT will be reset prior to returning. */ +svn_error_t * +svn_sqlite__insert(apr_int64_t *row_id, svn_sqlite__stmt_t *stmt); + +/* Perform an update/delete and then return the number of affected rows. + If AFFECTED_ROWS is not NULL, then set *AFFECTED_ROWS to the + number of rows changed. + STMT will be reset prior to returning. */ +svn_error_t * +svn_sqlite__update(int *affected_rows, svn_sqlite__stmt_t *stmt); + +/* Return in *VERSION the version of the schema in DB. Use SCRATCH_POOL + for temporary allocations. */ +svn_error_t * +svn_sqlite__read_schema_version(int *version, + svn_sqlite__db_t *db, + apr_pool_t *scratch_pool); + + + +/* Open a connection in *DB to the database at PATH. Validate the schema, + creating/upgrading to LATEST_SCHEMA if needed using the instructions + in UPGRADE_SQL. The resulting DB is allocated in RESULT_POOL, and any + temporary allocations are made in SCRATCH_POOL. + + STATEMENTS is an array of strings which may eventually be executed, the + last element of which should be NULL. These strings and the array itself + are not duplicated internally, and should have a lifetime at least as long + as RESULT_POOL. + STATEMENTS itself may be NULL, in which case it has no impact. + See svn_sqlite__get_statement() for how these strings are 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__mode_t mode, const char * const statements[], + int latest_schema, const char * const *upgrade_sql, + apr_pool_t *result_pool, apr_pool_t *scratch_pool); + +/* Explicitly close the connection in DB. */ +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. */ +svn_error_t * +svn_sqlite__create_scalar_function(svn_sqlite__db_t *db, + const char *func_name, + int argc, + svn_sqlite__func_t func, + void *baton); + +/* Execute the (multiple) statements in the STATEMENTS[STMT_IDX] string. */ +svn_error_t * +svn_sqlite__exec_statements(svn_sqlite__db_t *db, int stmt_idx); + +/* Return the statement in *STMT which has been prepared from the + STATEMENTS[STMT_IDX] string, where STATEMENTS is the array that was + passed to svn_sqlite__open(). This statement is allocated in the same + pool as the DB, and will be cleaned up when DB is closed. */ +svn_error_t * +svn_sqlite__get_statement(svn_sqlite__stmt_t **stmt, svn_sqlite__db_t *db, + int stmt_idx); + + +/* --------------------------------------------------------------------- + + BINDING VALUES + +*/ + +/* Bind values to SQL parameters in STMT, according to FMT. FMT may contain: + + Spec Argument type Item type + ---- ----------------- --------- + n <none, absent> Column assignment skip + d int Number + L apr_int64_t Number + i apr_int64_t Number (deprecated format spec) + s const char * String + b const void * Blob data + apr_size_t Blob length + r svn_revnum_t Revision number + t const svn_token_map_t * Token mapping table + int Token value + + Each character in FMT maps to one SQL parameter, and one or two function + parameters, in the order they appear. +*/ +svn_error_t * +svn_sqlite__bindf(svn_sqlite__stmt_t *stmt, const char *fmt, ...); + +/* Error-handling wrapper around sqlite3_bind_int. */ +svn_error_t * +svn_sqlite__bind_int(svn_sqlite__stmt_t *stmt, int slot, int val); + +/* Error-handling wrapper around sqlite3_bind_int64. */ +svn_error_t * +svn_sqlite__bind_int64(svn_sqlite__stmt_t *stmt, int slot, + apr_int64_t val); + +/* Error-handling wrapper around sqlite3_bind_text. VAL cannot contain + zero bytes; we always pass SQLITE_TRANSIENT. */ +svn_error_t * +svn_sqlite__bind_text(svn_sqlite__stmt_t *stmt, int slot, + const char *val); + +/* Error-handling wrapper around sqlite3_bind_blob. */ +svn_error_t * +svn_sqlite__bind_blob(svn_sqlite__stmt_t *stmt, + int slot, + const void *val, + apr_size_t len); + +/* Look up VALUE in MAP, and bind the resulting token word at SLOT. */ +svn_error_t * +svn_sqlite__bind_token(svn_sqlite__stmt_t *stmt, + int slot, + const svn_token_map_t *map, + int value); + +/* Bind the value to SLOT, unless SVN_IS_VALID_REVNUM(value) is false, + in which case it binds NULL. */ +svn_error_t * +svn_sqlite__bind_revnum(svn_sqlite__stmt_t *stmt, int slot, + svn_revnum_t value); + +/* Bind a set of properties to the given slot. If PROPS is NULL, then no + binding will occur. PROPS will be stored as a serialized skel. */ +svn_error_t * +svn_sqlite__bind_properties(svn_sqlite__stmt_t *stmt, + int slot, + const apr_hash_t *props, + apr_pool_t *scratch_pool); + +/* Bind a set of inherited properties to the given slot. If INHERITED_PROPS + is NULL, then no binding will occur. INHERITED_PROPS will be stored as a + serialized skel. */ +svn_error_t * +svn_sqlite__bind_iprops(svn_sqlite__stmt_t *stmt, + int slot, + const apr_array_header_t *inherited_props, + apr_pool_t *scratch_pool); + +/* Bind a checksum's value to the given slot. If CHECKSUM is NULL, then no + binding will occur. */ +svn_error_t * +svn_sqlite__bind_checksum(svn_sqlite__stmt_t *stmt, + int slot, + const svn_checksum_t *checksum, + apr_pool_t *scratch_pool); + + +/* --------------------------------------------------------------------- + + FETCHING VALUES + +*/ + +/* Wrapper around sqlite3_column_blob and sqlite3_column_bytes. The return + value will be NULL if the column is null. + + If RESULT_POOL is not NULL, allocate the return value (if any) in it. + If RESULT_POOL is NULL, the return value will be valid until an + invocation of svn_sqlite__column_* performs a data type conversion (as + described in the SQLite documentation) or the statement is stepped or + reset or finalized. */ +const void * +svn_sqlite__column_blob(svn_sqlite__stmt_t *stmt, int column, + apr_size_t *len, apr_pool_t *result_pool); + +/* Wrapper around sqlite3_column_text. If the column is null, then the + return value will be NULL. + + If RESULT_POOL is not NULL, allocate the return value (if any) in it. + If RESULT_POOL is NULL, the return value will be valid until an + invocation of svn_sqlite__column_* performs a data type conversion (as + described in the SQLite documentation) or the statement is stepped or + reset or finalized. */ +const char * +svn_sqlite__column_text(svn_sqlite__stmt_t *stmt, int column, + apr_pool_t *result_pool); + +/* Wrapper around sqlite3_column_int64. If the column is null, then the + return value will be SVN_INVALID_REVNUM. */ +svn_revnum_t +svn_sqlite__column_revnum(svn_sqlite__stmt_t *stmt, int column); + +/* Wrapper around sqlite3_column_int64. If the column is null, then the + return value will be FALSE. */ +svn_boolean_t +svn_sqlite__column_boolean(svn_sqlite__stmt_t *stmt, int column); + +/* Wrapper around sqlite3_column_int. If the column is null, then the + return value will be 0. */ +int +svn_sqlite__column_int(svn_sqlite__stmt_t *stmt, int column); + +/* Wrapper around sqlite3_column_int64. If the column is null, then the + return value will be 0. */ +apr_int64_t +svn_sqlite__column_int64(svn_sqlite__stmt_t *stmt, int column); + +/* Fetch the word at COLUMN, look it up in the MAP, and return its value. + MALFUNCTION is thrown if the column is null or contains an unknown word. */ +int +svn_sqlite__column_token(svn_sqlite__stmt_t *stmt, + int column, + const svn_token_map_t *map); + +/* Fetch the word at COLUMN, look it up in the MAP, and return its value. + Returns NULL_VAL if the column is null. MALFUNCTION is thrown if the + column contains an unknown word. */ +int +svn_sqlite__column_token_null(svn_sqlite__stmt_t *stmt, + int column, + const svn_token_map_t *map, + int null_val); + +/* Return the column as a hash of const char * => const svn_string_t *. + If the column is null, then set *PROPS to NULL. The + results will be allocated in RESULT_POOL, and any temporary allocations + will be made in SCRATCH_POOL. */ +svn_error_t * +svn_sqlite__column_properties(apr_hash_t **props, + svn_sqlite__stmt_t *stmt, + int column, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Return the column as an array of depth-first ordered array of + svn_prop_inherited_item_t * structures. If the column is null, then + set *IPROPS to NULL. The results will be allocated in RESULT_POOL, + and any temporary allocations will be made in SCRATCH_POOL. */ +svn_error_t * +svn_sqlite__column_iprops(apr_array_header_t **iprops, + svn_sqlite__stmt_t *stmt, + int column, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Return the column as a checksum. If the column is null, then NULL will + be stored into *CHECKSUM. The result will be allocated in RESULT_POOL. */ +svn_error_t * +svn_sqlite__column_checksum(const svn_checksum_t **checksum, + svn_sqlite__stmt_t *stmt, + int column, + apr_pool_t *result_pool); + +/* Return TRUE if the result of selecting the column is null, + FALSE otherwise */ +svn_boolean_t +svn_sqlite__column_is_null(svn_sqlite__stmt_t *stmt, int column); + +/* Return the number of bytes the column uses in a text or blob representation. + 0 for NULL columns. */ +int +svn_sqlite__column_bytes(svn_sqlite__stmt_t *stmt, int column); + + +/* --------------------------------------------------------------------- */ + +#define SVN_SQLITE__INTEGER 1 +#define SVN_SQLITE__FLOAT 2 +#define SVN_SQLITE__TEXT 3 +#define SVN_SQLITE__BLOB 4 +#define SVN_SQLITE__NULL 5 + +/* */ +int +svn_sqlite__value_type(svn_sqlite__value_t *val); + +/* */ +const char * +svn_sqlite__value_text(svn_sqlite__value_t *val); + + +/* --------------------------------------------------------------------- */ + +/* */ +void +svn_sqlite__result_null(svn_sqlite__context_t *sctx); + +void +svn_sqlite__result_int64(svn_sqlite__context_t *sctx, apr_int64_t val); + + +/* --------------------------------------------------------------------- */ + + +/* Error-handling wrapper around sqlite3_finalize. */ +svn_error_t * +svn_sqlite__finalize(svn_sqlite__stmt_t *stmt); + +/* Reset STMT by calling sqlite3_reset(), and also clear any bindings to it. + + Note: svn_sqlite__get_statement() calls this function automatically if + the requested statement has been used and has not yet been reset. */ +svn_error_t * +svn_sqlite__reset(svn_sqlite__stmt_t *stmt); + + +/* Begin a transaction in DB. */ +svn_error_t * +svn_sqlite__begin_transaction(svn_sqlite__db_t *db); + +/* Like svn_sqlite__begin_transaction(), but takes out a 'RESERVED' lock + immediately, instead of using the default deferred locking scheme. */ +svn_error_t * +svn_sqlite__begin_immediate_transaction(svn_sqlite__db_t *db); + +/* Begin a savepoint in DB. */ +svn_error_t * +svn_sqlite__begin_savepoint(svn_sqlite__db_t *db); + +/* Commit the current transaction in DB if ERR is SVN_NO_ERROR, otherwise + * roll back the transaction. Return a composition of ERR and any error + * that may occur during the commit or roll-back. */ +svn_error_t * +svn_sqlite__finish_transaction(svn_sqlite__db_t *db, + svn_error_t *err); + +/* Release the current savepoint in DB if EXPR is SVN_NO_ERROR, otherwise + * roll back to the savepoint and then release it. Return a composition of + * ERR and any error that may occur during the release or roll-back. */ +svn_error_t * +svn_sqlite__finish_savepoint(svn_sqlite__db_t *db, + svn_error_t *err); + +/* Evaluate the expression EXPR within a transaction. + * + * Begin a transaction in DB; evaluate the expression EXPR, which would + * typically be a function call that does some work in DB; finally commit + * the transaction if EXPR evaluated to SVN_NO_ERROR, otherwise roll back + * the transaction. + */ +#define SVN_SQLITE__WITH_TXN(expr, db) \ + do { \ + svn_sqlite__db_t *svn_sqlite__db = (db); \ + svn_error_t *svn_sqlite__err; \ + \ + SVN_ERR(svn_sqlite__begin_transaction(svn_sqlite__db)); \ + svn_sqlite__err = (expr); \ + SVN_ERR(svn_sqlite__finish_transaction(svn_sqlite__db, svn_sqlite__err)); \ + } while (0) + +/* Callback function to for use with svn_sqlite__with_transaction(). */ +typedef svn_error_t *(*svn_sqlite__transaction_callback_t)( + void *baton, svn_sqlite__db_t *db, apr_pool_t *scratch_pool); + +/* Helper function to handle SQLite transactions. All the work done inside + CB_FUNC will be wrapped in an SQLite transaction, which will be committed + if CB_FUNC does not return an error. If any error is returned from CB_FUNC, + the transaction will be rolled back. DB and CB_BATON will be passed to + CB_FUNC. SCRATCH_POOL will be passed to the callback (NULL is valid). */ +svn_error_t * +svn_sqlite__with_transaction(svn_sqlite__db_t *db, + svn_sqlite__transaction_callback_t cb_func, + void *cb_baton, apr_pool_t *scratch_pool); + +/* Like SVN_SQLITE__WITH_TXN(), but takes out a 'RESERVED' lock + immediately, instead of using the default deferred locking scheme. */ +#define SVN_SQLITE__WITH_IMMEDIATE_TXN(expr, db) \ + do { \ + svn_sqlite__db_t *svn_sqlite__db = (db); \ + svn_error_t *svn_sqlite__err; \ + \ + SVN_ERR(svn_sqlite__begin_immediate_transaction(svn_sqlite__db)); \ + svn_sqlite__err = (expr); \ + SVN_ERR(svn_sqlite__finish_transaction(svn_sqlite__db, svn_sqlite__err)); \ + } while (0) + +/* Like svn_sqlite__with_transaction(), but takes out a 'RESERVED' lock + immediately, instead of using the default deferred locking scheme. */ +svn_error_t * +svn_sqlite__with_immediate_transaction(svn_sqlite__db_t *db, + svn_sqlite__transaction_callback_t cb_func, + void *cb_baton, + apr_pool_t *scratch_pool); + +/* Evaluate the expression EXPR within a 'savepoint'. Savepoints can be + * nested. + * + * Begin a savepoint in DB; evaluate the expression EXPR, which would + * typically be a function call that does some work in DB; finally release + * the savepoint if EXPR evaluated to SVN_NO_ERROR, otherwise roll back + * to the savepoint and then release it. + */ +#define SVN_SQLITE__WITH_LOCK(expr, db) \ + do { \ + svn_sqlite__db_t *svn_sqlite__db = (db); \ + svn_error_t *svn_sqlite__err; \ + \ + SVN_ERR(svn_sqlite__begin_savepoint(svn_sqlite__db)); \ + svn_sqlite__err = (expr); \ + SVN_ERR(svn_sqlite__finish_savepoint(svn_sqlite__db, svn_sqlite__err)); \ + } while (0) + +/* Helper function to handle several SQLite operations inside a shared lock. + This callback is similar to svn_sqlite__with_transaction(), but can be + nested (even with a transaction). + + Using this function as a wrapper around a group of operations can give a + *huge* performance boost as the shared-read lock will be shared over + multiple statements, instead of being reobtained every time, which may + require disk and/or network io, depending on SQLite's locking strategy. + + 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 + svn_sqlite__with_transaction()? + */ +svn_error_t * +svn_sqlite__with_lock(svn_sqlite__db_t *db, + svn_sqlite__transaction_callback_t cb_func, + void *cb_baton, + apr_pool_t *scratch_pool); + + +/* Hotcopy an SQLite database from SRC_PATH to DST_PATH. */ +svn_error_t * +svn_sqlite__hotcopy(const char *src_path, + const char *dst_path, + apr_pool_t *scratch_pool); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_SQLITE_H */ diff --git a/subversion/include/private/svn_string_private.h b/subversion/include/private/svn_string_private.h new file mode 100644 index 0000000..8579f4d --- /dev/null +++ b/subversion/include/private/svn_string_private.h @@ -0,0 +1,222 @@ +/** + * @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_string_private.h + * @brief Non-public string utility functions. + */ + + +#ifndef SVN_STRING_PRIVATE_H +#define SVN_STRING_PRIVATE_H + +#include "svn_string.h" /* for svn_boolean_t, svn_error_t */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup svn_string String handling + * @{ + */ + + +/** Private functions. + * + * @defgroup svn_string_private Private functions + * @{ + */ + + +/** A self-contained memory buffer of known size. + * + * Intended to be used where a single variable-sized buffer is needed + * within an iteration, a scratch pool is available and we want to + * avoid the cost of creating another pool just for the iteration. + */ +typedef struct svn_membuf_t +{ + /** The a pool from which this buffer was originally allocated, and is not + * necessarily specific to this buffer. This is used only for allocating + * more memory from when the buffer needs to grow. + */ + apr_pool_t *pool; + + /** pointer to the memory */ + void *data; + + /** total size of buffer allocated */ + apr_size_t size; +} svn_membuf_t; + + +/* Initialize a memory buffer of the given size */ +void +svn_membuf__create(svn_membuf_t *membuf, apr_size_t size, apr_pool_t *pool); + +/* Ensure that the given memory buffer has at least the given size */ +void +svn_membuf__ensure(svn_membuf_t *membuf, apr_size_t size); + +/* Resize the given memory buffer, preserving its contents. */ +void +svn_membuf__resize(svn_membuf_t *membuf, apr_size_t size); + +/* Zero-fill the given memory */ +void +svn_membuf__zero(svn_membuf_t *membuf); + +/* Zero-fill the given memory buffer up to the smaller of SIZE and the + current buffer size. */ +void +svn_membuf__nzero(svn_membuf_t *membuf, apr_size_t size); + +/* Inline implementation of svn_membuf__zero. + * Note that PMEMBUF is evaluated only once. + */ +#define SVN_MEMBUF__ZERO(pmembuf) \ + do \ + { \ + svn_membuf_t *const _m_b_f_ = (pmembuf); \ + memset(_m_b_f_->data, 0, _m_b_f_->size); \ + } \ + while(0) + +/* Inline implementation of svn_membuf__nzero + * Note that PMEMBUF and PSIZE are evaluated only once. + */ +#define SVN_MEMBUF__NZERO(pmembuf, psize) \ + do \ + { \ + svn_membuf_t *const _m_b_f_ = (pmembuf); \ + const apr_size_t _s_z_ = (psize); \ + if (_s_z_ > _m_b_f_->size) \ + memset(_m_b_f_->data, 0, _m_b_f_->size); \ + else \ + memset(_m_b_f_->data, 0, _s_z_); \ + } \ + while(0) + +#ifndef SVN_DEBUG +/* In non-debug mode, just use these inlie replacements */ +#define svn_membuf__zero(B) SVN_MEMBUF__ZERO((B)) +#define svn_membuf__nzero(B, S) SVN_MEMBUF__NZERO((B), (S)) +#endif + + +/** Returns the #svn_string_t information contained in the data and + * len members of @a strbuf. This is effectively a typecast, converting + * @a strbuf into an #svn_string_t. This first will become invalid and must + * not be accessed after this function returned. + */ +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); + +/** Number of chars needed to represent signed (19 places + sign + NUL) or + * unsigned (20 places + NUL) integers as strings. + */ +#define SVN_INT64_BUFFER_SIZE 21 + +/** Writes the @a number as 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. + */ +apr_size_t +svn__ui64toa(char * dest, apr_uint64_t number); + +/** Writes the @a number as 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. + */ +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. + */ +char * +svn__ui64toa_sep(apr_uint64_t number, char seperator, apr_pool_t *pool); + +/** Returns a decimal string for @a number allocated in @a pool. Put in + * the @a seperator at each third place. + */ +char * +svn__i64toa_sep(apr_int64_t number, char seperator, apr_pool_t *pool); + +/** + * 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 + * + * difflib.SequenceMatcher.ratio + * + * Optionally sets *RLCS to the length of the longest common + * subsequence of STRA and STRB. Using BUFFER for temporary storage, + * requires memory proportional to the length of the shorter string. + * + * The LCS algorithm used is described in, e.g., + * + * http://en.wikipedia.org/wiki/Longest_common_subsequence_problem + * + * Q: Why another LCS when we already have one in libsvn_diff? + * A: svn_diff__lcs is too heavyweight and too generic for the + * purposes of similarity testing. Whilst it would be possible + * to use a character-based tokenizer with it, we really only need + * the *length* of the LCS for the similarity score, not all the + * other information that svn_diff__lcs produces in order to + * make printing diffs possible. + * + * Q: Is there a limit on the length of the string parameters? + * A: Only available memory. But note that the LCS algorithm used + * has O(strlen(STRA) * strlen(STRB)) worst-case performance, + * so do keep a rein on your enthusiasm. + */ +unsigned int +svn_cstring__similarity(const char *stra, const char *strb, + svn_membuf_t *buffer, apr_size_t *rlcs); + +/** + * Like svn_cstring__similarity, but accepts svn_string_t's instead + * of NUL-terminated character strings. + */ +unsigned int +svn_string__similarity(const svn_string_t *stringa, + const svn_string_t *stringb, + svn_membuf_t *buffer, apr_size_t *rlcs); + + +/** @} */ + +/** @} */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_STRING_PRIVATE_H */ diff --git a/subversion/include/private/svn_subr_private.h b/subversion/include/private/svn_subr_private.h new file mode 100644 index 0000000..a45e664 --- /dev/null +++ b/subversion/include/private/svn_subr_private.h @@ -0,0 +1,340 @@ +/* + * svn_subr_private.h : private definitions from libsvn_subr + * + * ==================================================================== + * 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_SUBR_PRIVATE_H +#define SVN_SUBR_PRIVATE_H + +#include "svn_types.h" +#include "svn_io.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** Spill-to-file Buffers + * + * @defgroup svn_spillbuf_t Spill-to-file Buffers + * @{ + */ + +/** A buffer that collects blocks of content, possibly using a file. + * + * The spill-buffer is created with two basic parameters: the size of the + * blocks that will be written into the spill-buffer ("blocksize"), and + * the (approximate) maximum size that will be allowed in memory ("maxsize"). + * Once the maxsize is reached, newly written content will be "spilled" + * into a temporary file. + * + * When writing, content will be buffered into memory unless a given write + * will cause the amount of in-memory content to exceed the specified + * maxsize. At that point, the file is created, and the content will be + * written to that file. + * + * To read information back out of a spill buffer, there are two approaches + * available to the application: + * + * *) reading blocks using svn_spillbuf_read() (a "pull" model) + * *) having blocks passed to a callback via svn_spillbuf_process() + * (a "push" model to your application) + * + * In both cases, the spill-buffer will provide you with a block of N bytes + * that you must fully consume before asking for more data. The callback + * style provides for a "stop" parameter to temporarily pause the reading + * until another read is desired. The two styles of reading may be mixed, + * as the caller desires. Generally, N will be the blocksize, and will be + * less when the end of the content is reached. + * + * For a more stream-oriented style of reading, where the caller specifies + * the number of bytes to read into a caller-provided buffer, please see + * svn_spillbuf_reader_t. That overlaid type will cause more memory copies + * to be performed (whereas the bare spill-buffer type hands you a buffer + * to consume). + * + * Writes may be interleaved with reading, and content will be returned + * in a FIFO manner. Thus, if content has been placed into the spill-buffer + * you will always read the earliest-written data, and any newly-written + * content will be appended to the buffer. + * + * Note: the file is created in the same pool where the spill-buffer was + * created. If the content is completely read from that file, it will be + * closed and deleted. Should writing further content cause another spill + * file to be created, that will increase the size of the pool. There is + * no bound on the amount of file-related resources that may be consumed + * from the pool. It is entirely related to the read/write pattern and + * whether spill files are repeatedly created. + */ +typedef struct svn_spillbuf_t svn_spillbuf_t; + + +/* Create a spill buffer. */ +svn_spillbuf_t * +svn_spillbuf__create(apr_size_t blocksize, + apr_size_t maxsize, + 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); + + +/* Write some data into the spill buffer. */ +svn_error_t * +svn_spillbuf__write(svn_spillbuf_t *buf, + const char *data, + apr_size_t len, + apr_pool_t *scratch_pool); + + +/* Read a block of memory from the spill buffer. @a *data will be set to + NULL if no content remains. Otherwise, @a data and @a len will point to + data that must be fully-consumed by the caller. This data will remain + valid until another call to svn_spillbuf_write(), svn_spillbuf_read(), + or svn_spillbuf_process(), or if the spill buffer's pool is cleared. */ +svn_error_t * +svn_spillbuf__read(const char **data, + apr_size_t *len, + svn_spillbuf_t *buf, + apr_pool_t *scratch_pool); + + +/* Callback for reading content out of the spill buffer. Set @a stop if + you want to stop the processing (and will call svn_spillbuf_process + again, at a later time). */ +typedef svn_error_t * (*svn_spillbuf_read_t)(svn_boolean_t *stop, + void *baton, + const char *data, + apr_size_t len, + apr_pool_t *scratch_pool); + + +/* Process the content stored in the spill buffer. @a exhausted will be + set to TRUE if all of the content is processed by @a read_func. This + function may return early if the callback returns TRUE for its 'stop' + parameter. */ +svn_error_t * +svn_spillbuf__process(svn_boolean_t *exhausted, + svn_spillbuf_t *buf, + svn_spillbuf_read_t read_func, + void *read_baton, + apr_pool_t *scratch_pool); + + +/** Classic stream reading layer on top of spill-buffers. + * + * This type layers upon a spill-buffer to enable a caller to read a + * specified number of bytes into the caller's provided buffer. This + * implies more memory copies than the standard spill-buffer reading + * interface, but is sometimes required by spill-buffer users. + */ +typedef struct svn_spillbuf_reader_t svn_spillbuf_reader_t; + + +/* Create a spill-buffer and a reader for it. */ +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 + contains content. + + If @a len is zero, then SVN_ERR_INCORRECT_PARAMS is returned. */ +svn_error_t * +svn_spillbuf__reader_read(apr_size_t *amt, + svn_spillbuf_reader_t *reader, + char *data, + apr_size_t len, + apr_pool_t *scratch_pool); + + +/* Read a single character from @a reader, and place it in @a c. If there + is no content in the spill-buffer, then SVN_ERR_STREAM_UNEXPECTED_EOF + is returned. */ +svn_error_t * +svn_spillbuf__reader_getc(char *c, + svn_spillbuf_reader_t *reader, + apr_pool_t *scratch_pool); + + +/* Write @a len bytes from @a data into the spill-buffer in @a reader. */ +svn_error_t * +svn_spillbuf__reader_write(svn_spillbuf_reader_t *reader, + const char *data, + apr_size_t len, + 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. */ +svn_stream_t * +svn_stream__from_spillbuf(apr_size_t blocksize, + apr_size_t maxsize, + apr_pool_t *result_pool); + +/** @} */ + +/** + * Internal function for creating a MD5 checksum from a binary digest. + * + * @since New in 1.8 + */ +svn_checksum_t * +svn_checksum__from_digest_md5(const unsigned char *digest, + apr_pool_t *result_pool); + +/** + * Internal function for creating a SHA1 checksum from a binary + * digest. + * + * @since New in 1.8 + */ +svn_checksum_t * +svn_checksum__from_digest_sha1(const unsigned char *digest, + apr_pool_t *result_pool); + + +/** + * @defgroup svn_hash_support Hash table serialization support + * @{ + */ + +/*----------------------------------------------------*/ + +/** + * @defgroup svn_hash_misc Miscellaneous hash APIs + * @{ + */ + +/** @} */ + + +/** + * @defgroup svn_hash_getters Specialized getter APIs for hashes + * @{ + */ + +/** Find the value of a @a key in @a hash, return the value. + * + * If @a hash is @c NULL or if the @a key cannot be found, the + * @a default_value will be returned. + * + * @since New in 1.7. + */ +const char * +svn_hash__get_cstring(apr_hash_t *hash, + const char *key, + const char *default_value); + +/** Like svn_hash_get_cstring(), but for boolean values. + * + * Parses the value as a boolean value. The recognized representations + * are 'TRUE'/'FALSE', 'yes'/'no', 'on'/'off', '1'/'0'; case does not + * matter. + * + * @since New in 1.7. + */ +svn_boolean_t +svn_hash__get_bool(apr_hash_t *hash, + const char *key, + svn_boolean_t default_value); + +/** @} */ + +/** + * @defgroup svn_hash_create Create optimized APR hash tables + * @{ + */ + +/** Returns a hash table, allocated in @a pool, with the same ordering of + * elements as APR 1.4.5 or earlier (using apr_hashfunc_default) but uses + * a faster hash function implementation. + * + * @since New in 1.8. + */ +apr_hash_t * +svn_hash__make(apr_pool_t *pool); + +/** @} */ + +/** @} */ + + +/** Apply the changes described by @a prop_changes to @a original_props and + * return the result. The inverse of svn_prop_diffs(). + * + * Allocate the resulting hash from @a pool, but allocate its keys and + * values from @a pool and/or by reference to the storage of the inputs. + * + * Note: some other APIs use an array of pointers to svn_prop_t. + * + * @since New in 1.8. + */ +apr_hash_t * +svn_prop__patch(const apr_hash_t *original_props, + const apr_array_header_t *prop_changes, + apr_pool_t *pool); + + +/** + * @defgroup svn_version Version number dotted triplet parsing + * @{ + */ + +/* Set @a *version to a version structure parsed from the version + * string representation in @a version_string. Return + * @c SVN_ERR_MALFORMED_VERSION_STRING if the string fails to parse + * cleanly. + * + * @since New in 1.8. + */ +svn_error_t * +svn_version__parse_version_string(svn_version_t **version, + const char *version_string, + apr_pool_t *result_pool); + +/* Return true iff @a version represents a version number of at least + * the level represented by @a major, @a minor, and @a patch. + * + * @since New in 1.8. + */ +svn_boolean_t +svn_version__at_least(svn_version_t *version, + int major, + int minor, + int patch); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_SUBR_PRIVATE_H */ diff --git a/subversion/include/private/svn_temp_serializer.h b/subversion/include/private/svn_temp_serializer.h new file mode 100644 index 0000000..7a007c3 --- /dev/null +++ b/subversion/include/private/svn_temp_serializer.h @@ -0,0 +1,207 @@ +/** + * @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_temp_serializer.h + * @brief Helper API for serializing _temporarily_ data structures. + * + * @note This API is intended for efficient serialization and duplication + * of temporary, e.g. cached, data structures ONLY. It is not + * suitable for persistent data. + */ + +#ifndef SVN_TEMP_SERIALIZER_H +#define SVN_TEMP_SERIALIZER_H + +#include "svn_string.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* forward declaration */ +struct svn_stringbuf_t; + +/** + * The amount of extra memory allocated by #svn_temp_serializer__init for + * the internal buffer in addition to its suggested_buffer_size parameter. + * To allocate a 512 buffer, including overhead, just specify a size of + * 512 - SVN_TEMP_SERIALIZER__OVERHEAD. + */ +#define SVN_TEMP_SERIALIZER__OVERHEAD (sizeof(svn_stringbuf_t) + 1) + +/** + * Opaque structure controlling the serialization process and holding the + * intermediate as well as final results. + */ +typedef struct svn_temp_serializer__context_t svn_temp_serializer__context_t; + +/** + * Begin the serialization process for the @a source_struct and all objects + * referenced from it. @a struct_size must match the result of @c sizeof() + * of the actual structure. Due to the generic nature of the init function + * we can't determine the structure size as part of the function. + * + * It is possible to specify a @c NULL source_struct in which case the first + * call to svn_temp_serializer__push() will provide the root struct. + * Alternatively, one may even call svn_temp_serializer__add_string() + * but there is generally no point in doing so because the result will be + * simple string object in a #svn_stringbuf_t. + * + * You may suggest a larger initial buffer size in @a suggested_buffer_size + * to minimize the number of internal buffer re-allocations during the + * serialization process. All allocations will be made from @a pool. + * + * Pointers within the structure will be replaced by their serialized + * representation when the respective strings or sub-structures get + * serialized. This scheme allows only for tree-like, i.e. non-circular + * data structures. + * + * @return the serialization context. + */ +svn_temp_serializer__context_t * +svn_temp_serializer__init(const void *source_struct, + apr_size_t struct_size, + apr_size_t suggested_buffer_size, + apr_pool_t *pool); + +/** + * Continue the serialization process of the @a source_struct that has + * already been serialized to @a buffer but contains references to new + * objects yet to serialize. I.e. this function allows you to append + * data to serialized structures returned by svn_temp_serializer__get(). + * + * The current size of the serialized data is given in @a currently_used. + * If the allocated data buffer is actually larger, you may specifiy that + * size in @a currently_allocated to prevent unnecessary re-allocations. + * Otherwise, set it to 0. + * + * All allocations will be made from @a pool. + * + * Please note that only sub-structures of @a source_struct may be added. + * To add item referenced from other parts of the buffer, serialize from + * @a source_struct first, get the result from svn_temp_serializer__get() + * and call svn_temp_serializer__init_append for the next part. + * + * @return the serialization context. + */ +svn_temp_serializer__context_t * +svn_temp_serializer__init_append(void *buffer, + void *source_struct, + apr_size_t currently_used, + apr_size_t currently_allocated, + apr_pool_t *pool); + +/** + * Begin serialization of 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. + * + * Only in case that svn_temp_serializer__init() has not been provided + * with a root structure and this is the first call after the initialization, + * @a source_struct will point to a reference to the root structure instead + * of being related to some other. + * + * Sub-structures and strings will be added in a FIFO fashion. If you need + * add further sub-structures on the same level, you need to call + * svn_serializer__pop() to realign the serialization context. + */ +void +svn_temp_serializer__push(svn_temp_serializer__context_t *context, + const void * const * source_struct, + apr_size_t struct_size); + +/** + * End the serialization of the current sub-structure. The serialization + * @a context will be focused back on the parent structure. You may then + * add further sub-structures starting from that level. + * + * It is not necessary to call this function just for symmetry at the end + * of the serialization process. + */ +void +svn_temp_serializer__pop(svn_temp_serializer__context_t *context); + +/** + * 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 + * serialized structure can be established. + * + * Only in case that svn_temp_serializer__init() has not been provided + * with a root structure and this is the first call after the initialization, + * @a s will not be related to some struct. + */ +void +svn_temp_serializer__add_string(svn_temp_serializer__context_t *context, + const char * const * s); + +/** + * Set the serialized representation of the pointer @a ptr inside the + * current structure within the serialization @a context to @c NULL. + * This is particularly useful if the pointer is not @c NULL in the + * source structure. + */ +void +svn_temp_serializer__set_null(svn_temp_serializer__context_t *context, + const void * const * ptr); + +/** + * @return the number of bytes currently used in the serialization buffer + * of the given serialization @a context. + */ +apr_size_t +svn_temp_serializer__get_length(svn_temp_serializer__context_t *context); + +/** + * @return a reference to the data buffer containing the data serialialized + * so far in the given serialization @a context. + */ +struct svn_stringbuf_t * +svn_temp_serializer__get(svn_temp_serializer__context_t *context); + +/** + * Deserialization is straightforward: just copy the serialized buffer to + * a natively aligned memory location (APR pools will take care of that + * automatically) and resolve all pointers to sub-structures. + * + * To do the latter, call this function for each of these pointers, giving + * the start address of the copied buffer in @a buffer and a reference to + * the pointer to resolve in @a ptr. + */ +void +svn_temp_deserializer__resolve(void *buffer, void **ptr); + +/** + * Similar to svn_temp_deserializer__resolve() but instead of modifying + * the buffer content, the resulting pointer is passed back to the caller + * as the return value. + */ +const void * +svn_temp_deserializer__ptr(const void *buffer, const void *const *ptr); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_TEMP_SERIALIZER_H */ diff --git a/subversion/include/private/svn_token.h b/subversion/include/private/svn_token.h new file mode 100644 index 0000000..c7c1c2c --- /dev/null +++ b/subversion/include/private/svn_token.h @@ -0,0 +1,98 @@ +/* svn_token.h : value/string-token functions + * + * ==================================================================== + * 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_TOKEN_H +#define SVN_TOKEN_H + + +#include "svn_error.h" + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/** A mapping between a string STR and an enumeration value VAL. + * + * Maps are an array of these, terminated with a struct where STR == NULL. + */ +typedef struct svn_token_map_t +{ + const char *str; + int val; +} svn_token_map_t; + + +/* A value used by some token functions to indicate an unrecognized token. */ +#define SVN_TOKEN_UNKNOWN (-9999) + + +/* Return the string form of the given VALUE as found in MAP. If the value + is not recognized, then a MALFUNCTION will occur. */ +const char * +svn_token__to_word(const svn_token_map_t *map, + int value); + + +/* NOTE: in the following functions, if WORD is NULL, then SVN_TOKEN_UNKNOWN + will be returned, or will cause the appropriate MALFUNCTION or ERROR. */ + +/* Return the integer value of the given token WORD, as found in MAP. If the + string is not recognized, then a MALFUNCTION will occur. + + Note: this function is for persisted string values. Because this function + will throw a MALFUNCTION, it should not be used for network input or + user input. */ +int +svn_token__from_word_strict(const svn_token_map_t *map, + const char *word); + + +/* Store the integer value of WORD into *VALUE. If the string is not + recognized, then SVN_ERR_BAD_TOKEN is returned. */ +svn_error_t * +svn_token__from_word_err(int *value, + const svn_token_map_t *map, + const char *word); + + +/* Return the integer value of the given token WORD as found in MAP. If the + string is not recognized, then SVN_TOKEN_UNKNOWN will be returned. */ +int +svn_token__from_word(const svn_token_map_t *map, + const char *word); + + +/* Return the integer value of the given token WORD/LEN as found in MAP. If + the string is not recognized, then SVN_TOKEN_UNKNOWN will be returned. */ +int +svn_token__from_mem(const svn_token_map_t *map, + const char *word, + apr_size_t len); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_TOKEN_H */ diff --git a/subversion/include/private/svn_utf_private.h b/subversion/include/private/svn_utf_private.h new file mode 100644 index 0000000..9f5a4ad --- /dev/null +++ b/subversion/include/private/svn_utf_private.h @@ -0,0 +1,87 @@ +/** + * @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_utf_private.h + * @brief UTF validation routines + */ + +#ifndef SVN_UTF_PRIVATE_H +#define SVN_UTF_PRIVATE_H + +#include <apr.h> +#include <apr_pools.h> + +#include "svn_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Return TRUE if the string SRC of length LEN is a valid UTF-8 encoding + * according to the rules laid down by the Unicode 4.0 standard, FALSE + * otherwise. This function is faster than svn_utf__last_valid(). + */ +svn_boolean_t +svn_utf__is_valid(const char *src, apr_size_t len); + +/* As for svn_utf__is_valid but SRC is NULL terminated. */ +svn_boolean_t +svn_utf__cstring_is_valid(const char *src); + +/* Return a pointer to the first character after the last valid UTF-8 + * potentially multi-byte character in the string SRC of length LEN. + * Validity of bytes from SRC to SRC+LEN-1, inclusively, is checked. + * If SRC is a valid UTF-8, the return value will point to the byte SRC+LEN, + * otherwise it will point to the start of the first invalid character. + * In either case all the characters between SRC and the return pointer - 1, + * inclusively, are valid UTF-8. + * + * See also svn_utf__is_valid(). + */ +const char * +svn_utf__last_valid(const char *src, apr_size_t len); + +/* As for svn_utf__last_valid but uses a different implementation without + lookup tables. It avoids the table memory use (about 400 bytes) but the + function is longer (about 200 bytes extra) and likely to be slower when + the string is valid. If the string is invalid this function may be + faster since it returns immediately rather than continuing to the end of + the string. The main reason this function exists is to test the table + driven implementation. */ +const char * +svn_utf__last_valid2(const char *src, apr_size_t len); + +const char * +svn_utf__cstring_from_utf8_fuzzy(const char *src, + apr_pool_t *pool, + svn_error_t *(*convert_from_utf8) + (const char **, + const char *, + apr_pool_t *)); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_UTF_PRIVATE_H */ diff --git a/subversion/include/private/svn_wc_private.h b/subversion/include/private/svn_wc_private.h new file mode 100644 index 0000000..fce42b0 --- /dev/null +++ b/subversion/include/private/svn_wc_private.h @@ -0,0 +1,1847 @@ +/** + * @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_wc_private.h + * @brief The Subversion Working Copy Library - Internal routines + * + * Requires: + * - A working copy + * + * Provides: + * - Ability to manipulate working copy's versioned data. + * - Ability to manipulate working copy's administrative files. + * + * Used By: + * - Clients. + */ + +#ifndef SVN_WC_PRIVATE_H +#define SVN_WC_PRIVATE_H + +#include "svn_types.h" +#include "svn_wc.h" +#include "private/svn_diff_tree.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* Return TRUE iff CLHASH (a hash whose keys are const char * + changelist names) is NULL or if LOCAL_ABSPATH is part of a changelist in + CLHASH. */ +svn_boolean_t +svn_wc__changelist_match(svn_wc_context_t *wc_ctx, + const char *local_abspath, + const apr_hash_t *clhash, + apr_pool_t *scratch_pool); + +/* Like svn_wc_get_update_editorX and svn_wc_get_status_editorX, but only + allows updating a file external LOCAL_ABSPATH. + + Since this only deals with files, the WCROOT_IPROPS argument in + svn_wc_get_update_editorX and svn_wc_get_status_editorX (hashes mapping + const char * absolute working copy paths, which are working copy roots, to + depth-first ordered arrays of svn_prop_inherited_item_t * structures) is + simply IPROPS here, a depth-first ordered arrays of + svn_prop_inherited_item_t * structs. */ +svn_error_t * +svn_wc__get_file_external_editor(const svn_delta_editor_t **editor, + void **edit_baton, + svn_revnum_t *target_revision, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + const char *wri_abspath, + const char *url, + const char *repos_root_url, + const char *repos_uuid, + apr_array_header_t *iprops, + svn_boolean_t use_commit_times, + const char *diff3_cmd, + const apr_array_header_t *preserved_exts, + const char *record_ancestor_abspath, + 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, + void *notify_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Like svn_wc_crawl_revisionsX, but only supports updating a file external + LOCAL_ABSPATH which may or may not exist yet. */ +svn_error_t * +svn_wc__crawl_file_external(svn_wc_context_t *wc_ctx, + const char *local_abspath, + const svn_ra_reporter3_t *reporter, + void *report_baton, + svn_boolean_t restore_files, + svn_boolean_t use_commit_times, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *scratch_pool); + +/* Check if LOCAL_ABSPATH is an external in the working copy identified + by WRI_ABSPATH. If not return SVN_ERR_WC_PATH_NOT_FOUND. + + If it is an external return more information on this external. + + If IGNORE_ENOENT, then set *external_kind to svn_node_none, when + LOCAL_ABSPATH is not an external instead of returning an error. + + Here is an overview of how DEFINING_REVISION and + DEFINING_OPERATIONAL_REVISION would be set for which kinds of externals + definitions: + + svn:externals line DEFINING_REV. DEFINING_OP._REV. + + ^/foo@2 bar 2 2 + -r1 ^/foo@2 bar 1 2 + -r1 ^/foo bar 1 SVN_INVALID_REVNUM + ^/foo bar SVN_INVALID_REVNUM SVN_INVALID_REVNUM + ^/foo@HEAD bar SVN_INVALID_REVNUM SVN_INVALID_REVNUM + -rHEAD ^/foo bar -- not a valid externals definition -- +*/ +svn_error_t * +svn_wc__read_external_info(svn_node_kind_t *external_kind, + const char **defining_abspath, + const char **defining_url, + svn_revnum_t *defining_operational_revision, + svn_revnum_t *defining_revision, + svn_wc_context_t *wc_ctx, + const char *wri_abspath, + const char *local_abspath, + svn_boolean_t ignore_enoent, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** See svn_wc__committable_externals_below(). */ +typedef struct svn_wc__committable_external_info_t { + + /* The local absolute path where the external should be checked out. */ + const char *local_abspath; + + /* The relpath part of the source URL the external should be checked out + * from. */ + const char *repos_relpath; + + /* The root URL part of the source URL the external should be checked out + * from. */ + const char *repos_root_url; + + /* Set to either svn_node_file or svn_node_dir. */ + svn_node_kind_t kind; + +} svn_wc__committable_external_info_t; + +/* Add svn_wc__committable_external_info_t* items to *EXTERNALS, describing + * 'committable' externals checked out below LOCAL_ABSPATH. Recursively find + * all nested externals (externals defined inside externals). + * + * In this context, a 'committable' external belongs to the same repository as + * LOCAL_ABSPATH, is not revision-pegged and is currently checked out in the + * WC. (Local modifications are not tested for.) + * + * *EXTERNALS must be initialized either to NULL or to a pointer created with + * apr_array_make(..., sizeof(svn_wc__committable_external_info_t *)). If + * *EXTERNALS is initialized to NULL, an array will be allocated from + * RESULT_POOL as necessary. If no committable externals are found, + * *EXTERNALS is left unchanged. + * + * DEPTH limits the recursion below LOCAL_ABSPATH. + * + * This function will not find externals defined in some parent WC above + * LOCAL_ABSPATH's WC-root. + * + * ###TODO: Add a WRI_ABSPATH (wc root indicator) separate from LOCAL_ABSPATH, + * to allow searching any wc-root for externals under LOCAL_ABSPATH, not only + * LOCAL_ABSPATH's most immediate wc-root. */ +svn_error_t * +svn_wc__committable_externals_below(apr_array_header_t **externals, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_depth_t depth, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Gets a mapping from const char * local abspaths of externals to the const + char * local abspath of where they are defined for all externals defined + at or below LOCAL_ABSPATH. + + ### Returns NULL in *EXTERNALS until we bumped to format 29. + + Allocate the result in RESULT_POOL and perform temporary allocations in + SCRATCH_POOL. */ +svn_error_t * +svn_wc__externals_defined_below(apr_hash_t **externals, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/* Registers a new external at LOCAL_ABSPATH in the working copy containing + DEFINING_ABSPATH. + + The node is registered as defined on DEFINING_ABSPATH (must be an ancestor + of LOCAL_ABSPATH) of kind KIND. + + The external is registered as from repository REPOS_ROOT_URL with uuid + REPOS_UUID and the defining relative path REPOS_RELPATH. + + If the revision of the node is locked OPERATIONAL_REVISION and REVISION + are the peg and normal revision; otherwise their value is + SVN_INVALID_REVNUM. + + ### Only KIND svn_node_dir is supported. + + Perform temporary allocations in SCRATCH_POOL. + */ +svn_error_t * +svn_wc__external_register(svn_wc_context_t *wc_ctx, + const char *defining_abspath, + const char *local_abspath, + svn_node_kind_t kind, + const char *repos_root_url, + const char *repos_uuid, + const char *repos_relpath, + svn_revnum_t operational_revision, + svn_revnum_t revision, + apr_pool_t *scratch_pool); + +/* Remove the external at LOCAL_ABSPATH from the working copy identified by + WRI_ABSPATH using WC_CTX. + + If DECLARATION_ONLY is TRUE, only remove the registration and leave the + on-disk structure untouched. + + If not NULL, call CANCEL_FUNC with CANCEL_BATON to allow canceling while + removing the working copy files. + + ### This function wraps svn_wc_remove_from_revision_control2(). + */ +svn_error_t * +svn_wc__external_remove(svn_wc_context_t *wc_ctx, + const char *wri_abspath, + const char *local_abspath, + svn_boolean_t declaration_only, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool); + +/* Gather all svn:externals property values from the actual properties on + directories below LOCAL_ABSPATH as a mapping of const char *local_abspath + to const char * values. + + Use DEPTH as how it would be used to limit the externals property results + on update. (So any depth < infinity will only read svn:externals on + LOCAL_ABSPATH itself) + + If DEPTHS is not NULL, set *depths to an apr_hash_t* mapping the same + local_abspaths to the const char * ambient depth of the node. + + Allocate the result in RESULT_POOL and perform temporary allocations in + SCRATCH_POOL. */ +svn_error_t * +svn_wc__externals_gather_definitions(apr_hash_t **externals, + apr_hash_t **ambient_depths, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_depth_t depth, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Close the DB for LOCAL_ABSPATH. Perform temporary allocations in + SCRATCH_POOL. + + Wraps svn_wc__db_drop_root(). */ +svn_error_t * +svn_wc__close_db(const char *external_abspath, + svn_wc_context_t *wc_ctx, + apr_pool_t *scratch_pool); + +/** Set @a *tree_conflict to a newly allocated @c + * svn_wc_conflict_description_t structure describing the tree + * conflict state of @a victim_abspath, or to @c NULL if @a victim_abspath + * is not in a state of tree conflict. @a wc_ctx is a working copy context + * used to access @a victim_path. Allocate @a *tree_conflict in @a result_pool, + * use @a scratch_pool for temporary allocations. + */ +svn_error_t * +svn_wc__get_tree_conflict(const svn_wc_conflict_description2_t **tree_conflict, + svn_wc_context_t *wc_ctx, + const char *victim_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** Record the tree conflict described by @a conflict in the WC for + * @a conflict->local_abspath. Use @a scratch_pool for all temporary + * allocations. + * + * Returns an SVN_ERR_WC_PATH_UNEXPECTED_STATUS error when + * CONFLICT->LOCAL_ABSPATH is already tree conflicted. + * + * ### This function can't set moved_away, moved_here conflicts for + * any operation, except merges. + */ +svn_error_t * +svn_wc__add_tree_conflict(svn_wc_context_t *wc_ctx, + const svn_wc_conflict_description2_t *conflict, + apr_pool_t *scratch_pool); + +/* Remove any tree conflict on victim @a victim_abspath using @a wc_ctx. + * (If there is no such conflict recorded, do nothing and return success.) + * + * Do all temporary allocations in @a scratch_pool. + */ +svn_error_t * +svn_wc__del_tree_conflict(svn_wc_context_t *wc_ctx, + const char *victim_abspath, + apr_pool_t *scratch_pool); + +/** Check whether LOCAL_ABSPATH has a parent directory that knows about its + * existence. Set *IS_WCROOT to FALSE if a parent is found, and to TRUE + * if there is no such parent. + * + * Like svn_wc_is_wc_root2(), but doesn't consider switched subdirs or + * deleted entries as working copy roots. + */ +svn_error_t * +svn_wc__is_wcroot(svn_boolean_t *is_wcroot, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *scratch_pool); + + +/** Set @a *wcroot_abspath to the local abspath of the root of the + * working copy in which @a local_abspath resides. + */ +svn_error_t * +svn_wc__get_wcroot(const char **wcroot_abspath, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * The following are temporary APIs to aid in the transition from wc-1 to + * wc-ng. Use them for new development now, but they may be disappearing + * 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 + * code in libsvn_client/ctx.c + * + * Allocate the result in RESULT_POOL. + */ +svn_wc_conflict_description_t * +svn_wc__cd2_to_cd(const svn_wc_conflict_description2_t *conflict, + apr_pool_t *result_pool); + + +/* + * Convert from svn_wc_status3_t to svn_wc_status2_t. + * Allocate the result in RESULT_POOL. + */ +svn_error_t * +svn_wc__status2_from_3(svn_wc_status2_t **status, + const svn_wc_status3_t *old_status, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + 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'. + * + * 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 + * deleted directory that existed at @a dir_abspath if that directory is now + * sheduled to be replaced by the working node at @a dir_abspath. + * + * Allocate @a *children in @a result_pool. Use @a wc_ctx to access the + * working copy, and @a scratch_pool for all temporary allocations. + */ +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. + */ +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); + + +/** + * Fetch the repository information for the working version + * of the node at @a local_abspath into @a *revision, @a *repos_relpath, + * @a *repos_root_url and @a *repos_uuid. Use @a wc_ctx to access the working + * copy. Allocate results in @a result_pool. + * + * @a *revision will be set to SVN_INVALID_REVNUM for any shadowed node (including + * added and deleted nodes). All other output values will be set to the current + * values or those they would have after a commit. + * + * All output argument may be NULL, indicating no interest. + */ +svn_error_t * +svn_wc__node_get_repos_info(svn_revnum_t *revision, + const char **repos_relpath, + const char **repos_root_url, + const char **repos_uuid, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + 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 + * for temporary allocations. Any of the return pointers may be @c NULL, in + * which case they are not set. + * + * 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_changed_info(svn_revnum_t *changed_rev, + apr_time_t *changed_date, + const char **changed_author, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/** + * Set @a *url to the corresponding url for @a local_abspath, using @a wc_ctx. + * If the node is added, return the url it will have in the repository. + * + * 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_url(const char **url, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Retrieves the origin of the node as it is known in the repository. For + * a copied node this retrieves where the node is copied from, for an added + * node this returns NULL/INVALID outputs, and for any other node this + * retrieves the repository location. + * + * All output arguments may be NULL. + * + * If @a is_copy is not NULL, sets @a *is_copy to TRUE if the origin is a copy + * of the original node. + * + * 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 @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 + * a root by itself, @a *copy_root_abspath will match @a local_abspath (but + * won't necessarily point to the same string in memory). + * + * If @a scan_deleted is TRUE, determine the origin of the deleted node. If + * @a scan_deleted is FALSE, return NULL, SVN_INVALID_REVNUM or FALSE for + * deleted nodes. + * + * Allocate the result in @a result_pool. Perform temporary allocations in + * @a scratch_pool */ +svn_error_t * +svn_wc__node_get_origin(svn_boolean_t *is_copy, + svn_revnum_t *revision, + const char **repos_relpath, + const char **repos_root_url, + const char **repos_uuid, + const char **copy_root_abspath, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t scan_deleted, + apr_pool_t *result_pool, + 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 + * @a *server_excluded to TRUE when @a local_abspath has status + * svn_wc__db_status_server_excluded. Otherwise set these values to FALSE. + * If @a base_only is TRUE then only the base node will be examined, + * otherwise the current base or working node will be examined. + * + * If a value is not interesting you can pass #NULL. + * + * 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_not_present(svn_boolean_t *not_present, + svn_boolean_t *user_excluded, + svn_boolean_t *server_excluded, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t base_only, + apr_pool_t *scratch_pool); + +/** + * Set @a *is_added to whether @a local_abspath is added, 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. + * + * NOTE: "added" in this sense, means it was added, copied-here, or + * moved-here. This function provides NO information on whether this + * addition has replaced another node. + * + * To be clear, this does NOT correspond to svn_wc_schedule_add. + */ +svn_error_t * +svn_wc__node_is_added(svn_boolean_t *is_added, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *scratch_pool); + +/** + * Set @a *has_working to whether @a local_abspath has a working node (which + * might shadow BASE nodes) + * + * This is a check similar to status = added or status = deleted. + */ +svn_error_t * +svn_wc__node_has_working(svn_boolean_t *has_working, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *scratch_pool); + + +/** + * Get the repository location of the base node at @a local_abspath. + * + * Set *REVISION, *REPOS_RELPATH, *REPOS_ROOT_URL *REPOS_UUID and *LOCK_TOKEN + * to the location that this node was checked out at or last updated/switched + * to, regardless of any uncommitted changes (delete, replace and/or copy-here/ + * move-here). + * + * If there is no BASE node at @a local_abspath or if @a show_hidden is FALSE, + * no status 'normal' or 'incomplete' BASE node report + * SVN_ERR_WC_PATH_NOT_FOUND, or if @a ignore_enoent is TRUE, @a kind + * svn_node_unknown, @a revision SVN_INVALID_REVNUM and all other values NULL. + * + * All output arguments may be NULL. + * + * Allocate the results in @a result_pool. Perform temporary allocations in + * @a scratch_pool. + */ +svn_error_t * +svn_wc__node_get_base(svn_node_kind_t *kind, + svn_revnum_t *revision, + const char **repos_relpath, + const char **repos_root_url, + const char **repos_uuid, + const char **lock_token, + 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); + + +/* Get the working revision 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. + * + * This function is meant as a temporary solution for using the old-style + * semantics of entries. It will handle any uncommitted changes (delete, + * replace and/or copy-here/move-here). + * + * For a delete the @a revision is the BASE node of the operation root, e.g + * the path that was deleted. But if the delete is below an add, the + * revision is set to SVN_INVALID_REVNUM. For an add, copy or move we return + * SVN_INVALID_REVNUM. In case of a replacement, we return the BASE + * revision. + * + * The @a changed_rev is set to the latest committed change to @a + * local_abspath before or equal to @a revision, unless the node is + * copied-here or moved-here. Then it is the revision of the latest committed + * change before or equal to the copyfrom_rev. NOTE, that we use + * SVN_INVALID_REVNUM for a scheduled copy or move. + * + * The @a changed_date and @a changed_author are the ones associated with @a + * changed_rev. + */ +svn_error_t * +svn_wc__node_get_pre_ng_status_data(svn_revnum_t *revision, + svn_revnum_t *changed_rev, + apr_time_t *changed_date, + const char **changed_author, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Acquire a recursive write lock for @a local_abspath. If @a lock_anchor + * is true, determine if @a local_abspath has an anchor that should be locked + * instead; otherwise, @a local_abspath must be a versioned directory. + * Store the obtained lock in @a wc_ctx. + * + * If @a lock_root_abspath is not NULL, store the root of the lock in + * @a *lock_root_abspath. If @a lock_root_abspath is NULL, then @a + * lock_anchor must be FALSE. + * + * Returns @c SVN_ERR_WC_LOCKED if an existing lock is encountered, in + * which case any locks acquired will have been released. + * + * If @a lock_anchor is TRUE and @a lock_root_abspath is not NULL, @a + * lock_root_abspath will be set even when SVN_ERR_WC_LOCKED is returned. + */ +svn_error_t * +svn_wc__acquire_write_lock(const char **lock_root_abspath, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t lock_anchor, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/** + * Recursively release write locks for @a local_abspath, using @a wc_ctx + * for working copy access. Only locks held by @a wc_ctx are released. + * Locks are not removed if work queue items are present. + * + * If @a local_abspath is not the root of an owned SVN_ERR_WC_NOT_LOCKED + * is returned. + */ +svn_error_t * +svn_wc__release_write_lock(svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *scratch_pool); + +/** A callback invoked by the svn_wc__call_with_write_lock() function. */ +typedef svn_error_t *(*svn_wc__with_write_lock_func_t)(void *baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/** Call function @a func while holding a write lock on + * @a local_abspath. The @a baton, and @a result_pool and + * @a scratch_pool, is passed @a func. + * + * If @a lock_anchor is TRUE, determine if @a local_abspath has an anchor + * that should be locked instead. + * + * Use @a wc_ctx for working copy access. + * The lock is guaranteed to be released after @a func returns. + */ +svn_error_t * +svn_wc__call_with_write_lock(svn_wc__with_write_lock_func_t func, + void *baton, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t lock_anchor, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** Evaluate the expression @a expr while holding a write lock on + * @a local_abspath. + * + * @a expr must yield an (svn_error_t *) error code. If the error code + * is not #SVN_NO_ERROR, cause the function using this macro to return + * the error to its caller. + * + * If @a lock_anchor is TRUE, determine if @a local_abspath has an anchor + * that should be locked instead. + * + * Use @a wc_ctx for working copy access. + * + * The lock is guaranteed to be released after evaluating @a expr. + */ +#define SVN_WC__CALL_WITH_WRITE_LOCK(expr, wc_ctx, local_abspath, \ + lock_anchor, scratch_pool) \ + do { \ + svn_error_t *svn_wc__err1, *svn_wc__err2; \ + const char *svn_wc__lock_root_abspath; \ + SVN_ERR(svn_wc__acquire_write_lock(&svn_wc__lock_root_abspath, wc_ctx, \ + local_abspath, lock_anchor, \ + scratch_pool, scratch_pool)); \ + svn_wc__err1 = (expr); \ + svn_wc__err2 = svn_wc__release_write_lock( \ + wc_ctx, svn_wc__lock_root_abspath, scratch_pool); \ + SVN_ERR(svn_error_compose_create(svn_wc__err1, svn_wc__err2)); \ + } 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 + * the bowels of libsvn_wc which don't include svn_client.h. + * + * @since New in 1.7. */ +typedef svn_error_t *(*svn_wc__proplist_receiver_t)(void *baton, + const char *local_abspath, + apr_hash_t *props, + apr_pool_t *scratch_pool); + +/** Call @a receiver_func, passing @a receiver_baton, an absolute path, and + * a hash table mapping <tt>const char *</tt> names onto <tt>const + * svn_string_t *</tt> values for all the regular properties of the node + * at @a local_abspath and any node beneath @a local_abspath within the + * specified @a depth. @a receiver_fun must not be NULL. + * + * If @a propname is not NULL, the passed hash table will only contain + * the property @a propname. + * + * If @a pristine is not @c TRUE, and @a base_props is FALSE show local + * modifications to the properties. + * + * If a node has no properties, @a receiver_func is not called for the node. + * + * If @a changelists are non-NULL and non-empty, filter by them. + * + * Use @a wc_ctx to access the working copy, and @a scratch_pool for + * temporary allocations. + * + * If the node at @a local_abspath does not exist, + * #SVN_ERR_WC_PATH_NOT_FOUND is returned. + * + * @since New in 1.7. + */ +svn_error_t * +svn_wc__prop_list_recursive(svn_wc_context_t *wc_ctx, + const char *local_abspath, + const char *propname, + svn_depth_t depth, + svn_boolean_t pristine, + const apr_array_header_t *changelists, + svn_wc__proplist_receiver_t receiver_func, + void *receiver_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool); + +/** + * Set @a *inherited_props to a depth-first ordered array of + * #svn_prop_inherited_item_t * structures representing the properties + * inherited by @a local_abspath from the ACTUAL tree above + * @a local_abspath (looking through to the WORKING or BASE tree as + * required), up to and including the root of the working copy and + * any cached inherited properties inherited by the root. + * + * The #svn_prop_inherited_item_t->path_or_url members of the + * #svn_prop_inherited_item_t * structures in @a *inherited_props are + * paths relative to the repository root URL for cached inherited + * properties and absolute working copy paths otherwise. + * + * Allocate @a *inherited_props in @a result_pool. Use @a scratch_pool + * for temporary allocations. + */ +svn_error_t * +svn_wc__get_iprops(apr_array_header_t **inherited_props, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + const char *propname, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** Obtain a mapping of const char * local_abspaths to const svn_string_t* + * property values in *VALUES, of all PROPNAME properties on LOCAL_ABSPATH + * and its descendants. + * + * Allocate the result in RESULT_POOL, and perform temporary allocations in + * SCRATCH_POOL. + */ +svn_error_t * +svn_wc__prop_retrieve_recursive(apr_hash_t **values, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + const char *propname, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Set @a *iprops_paths to a hash mapping const char * absolute working + * copy paths to the nodes repository root relative path for each path + * in the working copy at or below @a local_abspath, limited by @a depth, + * that has cached inherited properties for the base node of the path. + * + * Allocate @a *iprop_paths + * in @a result_pool. Use @a scratch_pool for temporary allocations. + */ +svn_error_t * +svn_wc__get_cached_iprop_children(apr_hash_t **iprop_paths, + svn_depth_t depth, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/** + * For use by entries.c and entries-dump.c to read old-format working copies. + */ +svn_error_t * +svn_wc__read_entries_old(apr_hash_t **entries, + const char *dir_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** + * Recursively clear the dav cache (wcprops) in @a wc_ctx for the tree + * rooted at @a local_abspath. + */ +svn_error_t * +svn_wc__node_clear_dav_cache_recursive(svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *scratch_pool); + +/** + * Set @a lock_tokens to a hash mapping <tt>const char *</tt> URL + * to <tt>const char *</tt> lock tokens for every path at or under + * @a local_abspath in @a wc_ctx which has such a lock token set on it. + * Allocate the hash and all items therein from @a result_pool. + */ +svn_error_t * +svn_wc__node_get_lock_tokens_recursive(apr_hash_t **lock_tokens, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Set @a *min_revision and @a *max_revision to the lowest and highest revision + * numbers found within @a local_abspath, using context @a wc_ctx. + * If @a committed is TRUE, set @a *min_revision and @a *max_revision + * to the lowest and highest comitted (i.e. "last changed") revision numbers, + * respectively. Use @a scratch_pool for temporary allocations. + * + * Either of MIN_REVISION and MAX_REVISION may be passed as NULL if + * the caller doesn't care about that return value. + * + * 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(). */ +svn_error_t * +svn_wc__min_max_revisions(svn_revnum_t *min_revision, + svn_revnum_t *max_revision, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t committed, + apr_pool_t *scratch_pool); + +/* Indicate in @a is_switched whether any node beneath @a local_abspath + * is switched, using context @a wc_ctx. + * Use @a scratch_pool for temporary allocations. + * + * If @a trail_url is non-NULL, use it to determine if @a local_abspath itself + * is switched. It should be any trailing portion of @a local_abspath's + * expected URL, long enough to include any parts that the caller considers + * might be changed by a switch. If it does not match the end of + * @a local_abspath's actual URL, then report a "switched" status. + * + * 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(). */ +svn_error_t * +svn_wc__has_switched_subtrees(svn_boolean_t *is_switched, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + const char *trail_url, + apr_pool_t *scratch_pool); + +/* Set @a *excluded_subtrees to a hash mapping <tt>const char *</tt> + * local * absolute paths to <tt>const char *</tt> local absolute paths for + * every path under @a local_abspath in @a wc_ctx which are excluded + * by the server (e.g. because of authz) or the users. + * If no excluded paths are found then @a *server_excluded_subtrees + * is set to @c NULL. + * Allocate the hash and all items therein from @a result_pool. + */ +svn_error_t * +svn_wc__get_excluded_subtrees(apr_hash_t **server_excluded_subtrees, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* 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(). */ +svn_error_t * +svn_wc__has_local_mods(svn_boolean_t *is_modified, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool); + +/* Renames a working copy from @a from_abspath to @a dst_abspath and makes sure + open handles are closed to allow this on all platforms. + + Summary: This avoids a file lock problem on wc.db on Windows, that is + triggered by libsvn_client'ss copy to working copy code. */ +svn_error_t * +svn_wc__rename_wc(svn_wc_context_t *wc_ctx, + const char *from_abspath, + const char *dst_abspath, + apr_pool_t *scratch_pool); + +/* Set *TMPDIR_ABSPATH to a directory that is suitable for temporary + files which may need to be moved (atomically and same-device) into + the working copy indicated by WRI_ABSPATH. */ +svn_error_t * +svn_wc__get_tmpdir(const char **tmpdir_abspath, + svn_wc_context_t *wc_ctx, + const char *wri_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Gets information needed by the commit harvester. + * + * ### Currently this API is work in progress and is designed for just this + * ### caller. It is certainly possible (and likely) that this function and + * ### it's caller will eventually move into a wc and maybe wc_db api. + */ +svn_error_t * +svn_wc__node_get_commit_status(svn_boolean_t *added, + svn_boolean_t *deleted, + svn_boolean_t *is_replace_root, + svn_boolean_t *is_op_root, + svn_revnum_t *revision, + svn_revnum_t *original_revision, + const char **original_repos_relpath, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Gets the md5 checksum for the pristine file identified by a sha1_checksum in the + working copy identified by wri_abspath. + + Wraps svn_wc__db_pristine_get_md5(). + */ +svn_error_t * +svn_wc__node_get_md5_from_sha1(const svn_checksum_t **md5_checksum, + svn_wc_context_t *wc_ctx, + const char *wri_abspath, + const svn_checksum_t *sha1_checksum, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Like svn_wc_get_pristine_contents2(), but keyed on the CHECKSUM + rather than on the local absolute path of the working file. + WRI_ABSPATH is any versioned path of the working copy in whose + pristine database we'll be looking for these contents. */ +svn_error_t * +svn_wc__get_pristine_contents_by_checksum(svn_stream_t **contents, + svn_wc_context_t *wc_ctx, + const char *wri_abspath, + const svn_checksum_t *checksum, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* Gets an array of const char *repos_relpaths of descendants of LOCAL_ABSPATH, + * which must be the op root of an addition, copy or move. The descendants + * returned are at the same op_depth, but are to be deleted by the commit + * processing because they are not present in the local copy. + */ +svn_error_t * +svn_wc__get_not_present_descendants(const apr_array_header_t **descendants, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/* Checks a node LOCAL_ABSPATH in WC_CTX for several kinds of obstructions + * for tasks like merge processing. + * + * If a node is not obstructed it sets *OBSTRUCTION_STATE to + * svn_wc_notify_state_inapplicable. If a node is obstructed or when its + * direct parent does not exist or is deleted return _state_obstructed. When + * a node doesn't exist but should exist return svn_wc_notify_state_missing. + * + * A node is also obstructed if it is marked excluded or server-excluded or when + * an unversioned file or directory exists. And if NO_WCROOT_CHECK is FALSE, + * the root of a working copy is also obstructed; this to allow detecting + * obstructing working copies. + * + * If KIND is not NULL, set *KIND to the kind of node registered in the working + * copy, or SVN_NODE_NONE if the node doesn't + * + * If DELETED is not NULL, set *DELETED to TRUE if the node is marked as + * deleted in the working copy. + * + * If EXCLUDED is not NULL, set *EXCLUDED to TRUE if the node is marked as + * user or server excluded. + * + * If PARENT_DEPTH is not NULL, set *PARENT_DEPTH to the depth stored on the + * parent. (Set to svn_depth_unknown if LOCAL_ABSPATH itself exists as node) + * + * All output arguments except OBSTRUCTION_STATE can be NULL to ommit the + * result. + * + * This function performs temporary allocations in SCRATCH_POOL. + */ +svn_error_t * +svn_wc__check_for_obstructions(svn_wc_notify_state_t *obstruction_state, + svn_node_kind_t *kind, + svn_boolean_t *deleted, + svn_boolean_t *excluded, + svn_depth_t *parent_depth, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_boolean_t no_wcroot_check, + apr_pool_t *scratch_pool); + + +/** + * A structure which describes various system-generated metadata about + * a working-copy path or URL. + * + * @note Fields may be added to the end of this structure in future + * versions. Therefore, users shouldn't allocate structures of this + * type, to preserve binary compatibility. + * + * @since New in 1.7. + */ +typedef struct svn_wc__info2_t +{ + /** Where the item lives in the repository. */ + const char *URL; + + /** The root URL of the repository. */ + const char *repos_root_URL; + + /** The repository's UUID. */ + const char *repos_UUID; + + /** The revision of the object. If the target is a working-copy + * path, then this is its current working revision number. If the target + * is a URL, then this is the repository revision that it lives in. */ + svn_revnum_t rev; + + /** The node's kind. */ + svn_node_kind_t kind; + + /** The size of the file in the repository (untranslated, + * e.g. without adjustment of line endings and keyword + * expansion). Only applicable for file -- not directory -- URLs. + * For working copy paths, @a size will be #SVN_INVALID_FILESIZE. */ + svn_filesize_t size; + + /** The last revision in which this object changed. */ + svn_revnum_t last_changed_rev; + + /** The date of the last_changed_rev. */ + apr_time_t last_changed_date; + + /** The author of the last_changed_rev. */ + const char *last_changed_author; + + /** An exclusive lock, if present. Could be either local or remote. */ + svn_lock_t *lock; + + /* Possible information about the working copy, NULL if not valid. */ + struct svn_wc_info_t *wc_info; + +} svn_wc__info2_t; + +/** The callback invoked by info retrievers. Each invocation + * describes @a local_abspath with the information present in @a info. + * Use @a scratch_pool for all temporary allocation. + * + * @since New in 1.7. + */ +typedef svn_error_t *(*svn_wc__info_receiver2_t)(void *baton, + const char *local_abspath, + const svn_wc__info2_t *info, + apr_pool_t *scratch_pool); + +/* Walk the children of LOCAL_ABSPATH and push svn_wc__info2_t's through + RECEIVER/RECEIVER_BATON. Honor DEPTH while crawling children, and + filter the pushed items against CHANGELISTS. + + If FETCH_EXCLUDED is TRUE, also fetch excluded nodes. + If FETCH_ACTUAL_ONLY is TRUE, also fetch actual-only nodes. */ +svn_error_t * +svn_wc__get_info(svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_depth_t depth, + svn_boolean_t fetch_excluded, + svn_boolean_t fetch_actual_only, + const apr_array_header_t *changelists, + svn_wc__info_receiver2_t receiver, + void *receiver_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool); + +/* Alternative version of svn_wc_delete4(). + * It can delete multiple TARGETS more efficiently (within a single sqlite + * transaction per working copy), but lacks support for moves. + * + * ### Inconsistency: if DELETE_UNVERSIONED_TARGET is FALSE and a target is + * unversioned, svn_wc__delete_many() will continue whereas + * svn_wc_delete4() will throw an error. + */ +svn_error_t * +svn_wc__delete_many(svn_wc_context_t *wc_ctx, + const apr_array_header_t *targets, + svn_boolean_t keep_local, + svn_boolean_t delete_unversioned_target, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *scratch_pool); + + +/* If the node at LOCAL_ABSPATH was moved away set *MOVED_TO_ABSPATH to + * the absolute path of the copied move-target node, and *COPY_OP_ROOT_ABSPATH + * to the absolute path of the root node of the copy operation. + * + * If the node was not moved, set *MOVED_TO_ABSPATH and *COPY_OP_ROOT_ABSPATH + * to NULL. + * + * Either MOVED_TO_ABSPATH or OP_ROOT_ABSPATH may be NULL to indicate + * that the caller is not interested in the result. + */ +svn_error_t * +svn_wc__node_was_moved_away(const char **moved_to_abspath, + const char **copy_op_root_abspath, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* If the node at LOCAL_ABSPATH was moved here set *MOVED_FROM_ABSPATH to + * the absolute path of the deleted move-source node, and set + * *DELETE_OP_ROOT_ABSPATH to the absolute path of the root node of the + * delete operation. + * + * If the node was not moved, set *MOVED_FROM_ABSPATH and + * *DELETE_OP_ROOT_ABSPATH to NULL. + * + * Either MOVED_FROM_ABSPATH or OP_ROOT_ABSPATH may be NULL to indicate + * that the caller is not interested in the result. + */ +svn_error_t * +svn_wc__node_was_moved_here(const char **moved_from_abspath, + const char **delete_op_root_abspath, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/* During an upgrade to wc-ng, supply known details about an existing + * external. The working copy will suck in and store the information supplied + * about the existing external at @a local_abspath. */ +svn_error_t * +svn_wc__upgrade_add_external_info(svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_node_kind_t kind, + const char *def_local_abspath, + const char *repos_relpath, + const char *repos_root_url, + const char *repos_uuid, + svn_revnum_t def_peg_revision, + svn_revnum_t def_revision, + apr_pool_t *scratch_pool); + +/* If the URL for @a item is relative, then using the repository root + URL @a repos_root_url and the parent directory URL @parent_dir_url, + resolve it into an absolute URL and save it in @a *resolved_url. + + Regardless if the URL is absolute or not, if there are no errors, + the URL returned in @a *resolved_url will be canonicalized. + + The following relative URL formats are supported: + + ../ relative to the parent directory of the external + ^/ relative to the repository root + // relative to the scheme + / relative to the server's hostname + + The ../ and ^/ relative URLs may use .. to remove path elements up + to the server root. + + The external URL should not be canonicalized before calling this function, + as otherwise the scheme relative URL '//host/some/path' would have been + canonicalized to '/host/some/path' and we would not be able to match on + the leading '//'. */ +svn_error_t * +svn_wc__resolve_relative_external_url(const char **resolved_url, + const svn_wc_external_item2_t *item, + const char *repos_root_url, + const char *parent_dir_url, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/** + * Set @a *editor and @a *edit_baton to an editor that generates + * #svn_wc_status3_t structures and sends them through @a status_func / + * @a status_baton. @a anchor_abspath is a working copy directory + * directory which will be used as the root of our editor. If @a + * target_basename is not "", it represents a node in the @a anchor_abspath + * which is the subject of the editor drive (otherwise, the @a + * anchor_abspath is the subject). + * + * If @a set_locks_baton is non-@c NULL, it will be set to a baton that can + * be used in a call to the svn_wc_status_set_repos_locks() function. + * + * Callers drive this editor to describe working copy out-of-dateness + * with respect to the repository. If this information is not + * available or not desired, callers should simply call the + * close_edit() function of the @a editor vtable. + * + * If the editor driver calls @a editor's set_target_revision() vtable + * function, then when the edit drive is completed, @a *edit_revision + * will contain the revision delivered via that interface. + * + * 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 depth is #svn_depth_empty, a status structure will + * be returned for the target only; if #svn_depth_files, for the + * target and its immediate file children; if + * #svn_depth_immediates, for the target and its immediate + * children; if #svn_depth_infinity, for the target and + * everything underneath it, fully recursively. + * + * If @a depth is #svn_depth_unknown, take depths from the + * working copy and behave as above in each directory's case. + * + * If the given @a depth is incompatible with the depth found in a + * working copy directory, the found depth always governs. + * + * If @a no_ignore is set, statuses that would typically be ignored + * will instead be reported. + * + * @a ignore_patterns is an array of file patterns matching + * unversioned files to ignore for the purposes of status reporting, + * or @c NULL if the default set of ignorable file patterns should be used. + * + * If @a cancel_func is non-NULL, call it with @a cancel_baton while building + * the @a statushash to determine if the client has canceled the operation. + * + * If @a depth_as_sticky is set handle @a depth like when depth_is_sticky is + * passed for updating. This will show excluded nodes show up as added in the + * repository. + * + * If @a server_performs_filtering is TRUE, assume that the server handles + * the ambient depth filtering, so this doesn't have to be handled in the + * editor. + * + * Allocate the editor itself in @a result_pool, and use @a scratch_pool + * for temporary allocations. The editor will do its temporary allocations + * in a subpool of @a result_pool. + * + * @since New in 1.8. + */ +svn_error_t * +svn_wc__get_status_editor(const svn_delta_editor_t **editor, + void **edit_baton, + void **set_locks_baton, + svn_revnum_t *edit_revision, + svn_wc_context_t *wc_ctx, + const char *anchor_abspath, + const char *target_basename, + svn_depth_t depth, + svn_boolean_t get_all, + svn_boolean_t no_ignore, + svn_boolean_t depth_as_sticky, + svn_boolean_t server_performs_filtering, + const apr_array_header_t *ignore_patterns, + svn_wc_status_func4_t status_func, + void *status_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/** + * Set @a *editor and @a *edit_baton to an editor and baton for updating a + * working copy. + * + * @a anchor_abspath is a local working copy directory, with a fully recursive + * write lock in @a wc_ctx, which will be used as the root of our editor. + * + * @a target_basename is the entry in @a anchor_abspath that will actually be + * updated, or the empty string if all of @a anchor_abspath should be updated. + * + * The editor invokes @a notify_func with @a notify_baton as the update + * progresses, if @a notify_func is non-NULL. + * + * If @a cancel_func is non-NULL, the editor will invoke @a cancel_func with + * @a cancel_baton as the update progresses to see if it should continue. + * + * If @a conflict_func is non-NULL, then invoke it with @a + * conflict_baton whenever a conflict is encountered, giving the + * callback a chance to resolve the conflict before the editor takes + * more drastic measures (such as marking a file conflicted, or + * bailing out of the update). + * + * If @a external_func is non-NULL, then invoke it with @a external_baton + * whenever external changes are encountered, giving the callback a chance + * to store the external information for processing. + * + * If @a diff3_cmd is non-NULL, then use it as the diff3 command for + * any merging; otherwise, use the built-in merge code. + * + * @a preserved_exts is an array of filename patterns which, when + * matched against the extensions of versioned files, determine for + * which such files any related generated conflict files will preserve + * the original file's extension as their own. If a file's extension + * does not match any of the patterns in @a preserved_exts (which is + * certainly the case if @a preserved_exts is @c NULL or empty), + * generated conflict files will carry Subversion's custom extensions. + * + * @a target_revision is a pointer to a revision location which, after + * successful completion of the drive of this editor, will be + * populated with the revision to which the working copy was updated. + * + * @a wcroot_iprops is a hash mapping const char * absolute working copy + * paths which are working copy roots (at or under the target within the + * constraints dictated by @a depth) to depth-first ordered arrays of + * svn_prop_inherited_item_t * structures which represent the inherited + * properties for the base of those paths at @a target_revision. After a + * successful drive of this editor, the base nodes for these paths will + * have their inherited properties cache updated with the values from + * @a wcroot_iprops. + * + * If @a use_commit_times is TRUE, then all edited/added files will + * have their working timestamp set to the last-committed-time. If + * FALSE, the working files will be touched with the 'now' time. + * + * If @a allow_unver_obstructions is TRUE, then allow unversioned + * obstructions when adding a path. + * + * If @a adds_as_modification is TRUE, a local addition at the same path + * as an incoming addition of the same node kind results in a normal node + * with a possible local modification, instead of a tree conflict. + * + * If @a depth is #svn_depth_infinity, update fully recursively. + * Else if it is #svn_depth_immediates, update the uppermost + * directory, its file entries, and the presence or absence of + * subdirectories (but do not descend into the subdirectories). + * Else if it is #svn_depth_files, update the uppermost directory + * and its immediate file entries, but not subdirectories. + * Else if it is #svn_depth_empty, update exactly the uppermost + * target, and don't touch its entries. + * + * If @a depth_is_sticky is set and @a depth is not + * #svn_depth_unknown, then in addition to updating PATHS, also set + * their sticky ambient depth value to @a depth. + * + * If @a server_performs_filtering is TRUE, assume that the server handles + * the ambient depth filtering, so this doesn't have to be handled in the + * editor. + * + * If @a clean_checkout is TRUE, assume that we are checking out into an + * empty directory, and so bypass a number of conflict checks that are + * unnecessary in this case. + * + * If @a fetch_dirents_func is not NULL, the update editor may call this + * callback, when asked to perform a depth restricted update. It will do this + * before returning the editor to allow using the primary ra session for this. + * + * @since New in 1.8. + */ +svn_error_t * +svn_wc__get_update_editor(const svn_delta_editor_t **editor, + void **edit_baton, + svn_revnum_t *target_revision, + svn_wc_context_t *wc_ctx, + const char *anchor_abspath, + const char *target_basename, + apr_hash_t *wcroot_iprops, + svn_boolean_t use_commit_times, + svn_depth_t depth, + svn_boolean_t depth_is_sticky, + svn_boolean_t allow_unver_obstructions, + svn_boolean_t adds_as_modification, + svn_boolean_t server_performs_filtering, + svn_boolean_t clean_checkout, + const char *diff3_cmd, + const apr_array_header_t *preserved_exts, + svn_wc_dirents_func_t fetch_dirents_func, + void *fetch_dirents_baton, + svn_wc_conflict_resolver_func2_t conflict_func, + void *conflict_baton, + svn_wc_external_update_t external_func, + void *external_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/** + * A variant of svn_wc__get_update_editor(). + * + * Set @a *editor and @a *edit_baton to an editor and baton for "switching" + * a working copy to a new @a switch_url. (Right now, this URL must be + * within the same repository that the working copy already comes + * from.) @a switch_url must not be @c NULL. + * + * All other parameters behave as for svn_wc__get_update_editor(). + * + * @since New in 1.8. + */ +svn_error_t * +svn_wc__get_switch_editor(const svn_delta_editor_t **editor, + void **edit_baton, + svn_revnum_t *target_revision, + svn_wc_context_t *wc_ctx, + const char *anchor_abspath, + const char *target_basename, + const char *switch_url, + apr_hash_t *wcroot_iprops, + svn_boolean_t use_commit_times, + svn_depth_t depth, + svn_boolean_t depth_is_sticky, + svn_boolean_t allow_unver_obstructions, + svn_boolean_t server_performs_filtering, + const char *diff3_cmd, + const apr_array_header_t *preserved_exts, + svn_wc_dirents_func_t fetch_dirents_func, + void *fetch_dirents_baton, + svn_wc_conflict_resolver_func2_t conflict_func, + void *conflict_baton, + svn_wc_external_update_t external_func, + void *external_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + + +/** + * Return an @a editor/@a edit_baton for diffing a working copy against the + * repository. The editor is allocated in @a result_pool; temporary + * calculations are performed in @a scratch_pool. + * + * This editor supports diffing either the actual files and properties in the + * working copy (when @a use_text_base is #FALSE), or the current pristine + * information (when @a use_text_base is #TRUE) against the editor driver. + * + * @a anchor_abspath/@a target represent the base of the hierarchy to be + * compared. The diff callback paths will be relative to this path. + * + * 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. + * + * 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 + * and for top-level file entries as well (if any). If + * #svn_depth_immediates, do the same as #svn_depth_files but also diff + * top-level subdirectories at #svn_depth_empty. If #svn_depth_infinity, + * then diff fully recursively. If @a depth is #svn_depth_unknown, then... + * + * ### ... then the @a server_performs_filtering option is meaningful. + * ### But what does this depth mean exactly? Something about 'ambient' + * ### depth? How does it compare with depth 'infinity'? + * + * @a ignore_ancestry determines whether paths that have discontinuous node + * ancestry are treated as delete/add or as simple modifications. If + * @a ignore_ancestry is @c FALSE, then any discontinuous node ancestry will + * result in the diff given as a full delete followed by an add. + * + * @a show_copies_as_adds determines whether paths added with history will + * appear as a diff against their copy source, or whether such paths will + * appear as if they were newly added in their entirety. + * + * If @a use_git_diff_format is TRUE, copied paths will be treated as added + * 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. + * + * 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. + * + * @a changelist_filter is an array of <tt>const char *</tt> changelist + * names, used as a restrictive filter on items whose differences are + * reported; that is, don't generate diffs about any item unless + * it's a member of one of those changelists. If @a changelist_filter is + * empty (or altogether @c NULL), no changelist filtering occurs. + * + * If @a server_performs_filtering is TRUE, assume that the server handles + * the ambient depth filtering, so this doesn't have to be handled in the + * editor. + * + * + * A diagram illustrating how this function is used. + * + * Steps 1 and 2 create the chain; step 3 drives it. + * + * 1. svn_wc__get_diff_editor(diff_cbs) + * | ^ + * 2. svn_ra_do_diff3(editor) | | + * | ^ | | + * v | v | + * +----------+ +----------+ +----------+ + * | | | | | | + * +--> | reporter | ----> | editor | ----> | diff_cbs | ----> text + * | | | | | | | out + * | +----------+ +----------+ +----------+ + * | + * 3. svn_wc_crawl_revisions5(WC,reporter) + * + * + * @since New in 1.8. + */ +svn_error_t * +svn_wc__get_diff_editor(const svn_delta_editor_t **editor, + void **edit_baton, + svn_wc_context_t *wc_ctx, + const char *anchor_abspath, + 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, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + +/** Callback for the svn_diff_tree_processor_t wrapper, to allow handling + * notifications like how the repos diff in libsvn_client does. + * + * Probably only necessary while transitioning to svn_diff_tree_processor_t + */ +typedef svn_error_t * + (*svn_wc__diff_state_handle_t)(svn_boolean_t tree_conflicted, + svn_wc_notify_state_t *state, + svn_wc_notify_state_t *prop_state, + const char *relpath, + svn_node_kind_t kind, + svn_boolean_t before_op, + svn_boolean_t for_add, + svn_boolean_t for_delete, + void *state_baton, + apr_pool_t *scratch_pool); + +/** Callback for the svn_diff_tree_processor_t wrapper, to allow handling + * notifications like how the repos diff in libsvn_client does. + * + * Probably only necessary while transitioning to svn_diff_tree_processor_t + */ +typedef svn_error_t * + (*svn_wc__diff_state_close_t)(const char *relpath, + svn_node_kind_t kind, + void *state_baton, + apr_pool_t *scratch_pool); + +/** Callback for the svn_diff_tree_processor_t wrapper, to allow handling + * absent nodes. + * + * Probably only necessary while transitioning to svn_diff_tree_processor_t + */ +typedef svn_error_t * + (*svn_wc__diff_state_absent_t)(const char *relpath, + void *state_baton, + apr_pool_t *scratch_pool); + +/** Obtains a diff processor that will drive the diff callbacks when it + * is invoked. + */ +svn_error_t * +svn_wc__wrap_diff_callbacks(const svn_diff_tree_processor_t **diff_processor, + const svn_wc_diff_callbacks4_t *callbacks, + void *callback_baton, + svn_boolean_t walk_deleted_dirs, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + +/** + * Assuming @a local_abspath itself or any of its children are under version + * control or a tree conflict victim and in a state of conflict, take these + * nodes out of this state. + * + * If @a resolve_text is TRUE then any text conflict is resolved, + * if @a resolve_tree is TRUE then any tree conflicts are resolved. + * If @a resolve_prop is set to "" all property conflicts are resolved, + * if it is set to any other string value, conflicts on that specific + * property are resolved and when resolve_prop is NULL, no property + * conflicts are resolved. + * + * If @a depth is #svn_depth_empty, act only on @a local_abspath; if + * #svn_depth_files, resolve @a local_abspath and its conflicted file + * children (if any); if #svn_depth_immediates, resolve @a local_abspath + * and all its immediate conflicted children (both files and directories, + * if any); if #svn_depth_infinity, resolve @a local_abspath and every + * conflicted file or directory anywhere beneath it. + * + * If @a conflict_choice is #svn_wc_conflict_choose_base, resolve the + * conflict with the old file contents; if + * #svn_wc_conflict_choose_mine_full, use the original working contents; + * if #svn_wc_conflict_choose_theirs_full, the new contents; and if + * #svn_wc_conflict_choose_merged, don't change the contents at all, + * just remove the conflict status, which is the pre-1.5 behavior. + * + * If @a conflict_choice is #svn_wc_conflict_choose_unspecified, invoke the + * @a conflict_func with the @a conflict_baton argument to obtain a + * resolution decision for each conflict. + * + * #svn_wc_conflict_choose_theirs_conflict and + * #svn_wc_conflict_choose_mine_conflict are not legal for binary + * files or properties. + * + * @a wc_ctx is a working copy context, with a write lock, for @a + * local_abspath. + * + * The implementation details are opaque, as our "conflicted" criteria + * might change over time. (At the moment, this routine removes the + * three fulltext 'backup' files and any .prej file created in a conflict, + * and modifies @a local_abspath's entry.) + * + * If @a local_abspath is not under version control and not a tree + * conflict, return #SVN_ERR_ENTRY_NOT_FOUND. If @a path isn't in a + * state of conflict to begin with, do nothing, and return #SVN_NO_ERROR. + * + * If @c local_abspath was successfully taken out of a state of conflict, + * report this information to @c notify_func (if non-@c NULL.) If only + * text, only property, or only tree conflict resolution was requested, + * and it was successful, then success gets reported. + * + * Temporary allocations will be performed in @a scratch_pool. + * + * @since New in 1.8. + */ +svn_error_t * +svn_wc__resolve_conflicts(svn_wc_context_t *wc_ctx, + const char *local_abspath, + svn_depth_t depth, + svn_boolean_t resolve_text, + const char *resolve_prop, + svn_boolean_t resolve_tree, + svn_wc_conflict_choice_t conflict_choice, + 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, + void *notify_baton, + apr_pool_t *scratch_pool); + +/** + * Move @a src_abspath to @a dst_abspath, by scheduling @a dst_abspath + * for addition to the repository, remembering the history. Mark @a src_abspath + * as deleted after moving.@a wc_ctx is used for accessing the working copy and + * must contain a write lock for the parent directory of @a src_abspath and + * @a dst_abspath. + * + * If @a metadata_only is TRUE then this is a database-only operation and + * the working directories and files are not changed. + * + * @a src_abspath must be a file or directory under version control; + * the parent of @a dst_abspath must be a directory under version control + * in the same working copy; @a dst_abspath will be the name of the copied + * item, and it must not exist already if @a metadata_only is FALSE. Note that + * when @a src points to a versioned file, the working file doesn't + * necessarily exist in which case its text-base is used instead. + * + * If @a allow_mixed_revisions is @c FALSE, #SVN_ERR_WC_MIXED_REVISIONS + * will be raised if the move source is a mixed-revision subtree. + * If @a allow_mixed_revisions is TRUE, a mixed-revision move source is + * allowed but the move will degrade to a copy and a delete without local + * move tracking. This parameter should be set to FALSE except where backwards + * compatibility to svn_wc_move() is required. + * + * If @a cancel_func is non-NULL, call it with @a cancel_baton at + * various points during the operation. If it returns an error + * (typically #SVN_ERR_CANCELLED), return that error immediately. + * + * If @a notify_func is non-NULL, call it with @a notify_baton and the path + * of the root node (only) of the destination. + * + * Use @a scratch_pool for temporary allocations. + * + * @since New in 1.8. + */ +svn_error_t * +svn_wc__move2(svn_wc_context_t *wc_ctx, + const char *src_abspath, + const char *dst_abspath, + svn_boolean_t metadata_only, + svn_boolean_t allow_mixed_revisions, + svn_cancel_func_t cancel_func, + void *cancel_baton, + svn_wc_notify_func2_t notify_func, + void *notify_baton, + apr_pool_t *scratch_pool); + + +/* During merge when we encounter added directories, we add them using + svn_wc_add4(), recording its original location, etc. But at that time + we don't have its original properties. This function allows updating the + BASE properties of such a special added node, but only before it receives + other changes. + + NEW_ORIGINAL_PROPS is a new set of properties, including entry props that + will be applied to LOCAL_ABSPATH as pristine properties. + + The copyfrom_* arguments are used to verify (some of) the assumptions of + this function */ +svn_error_t * +svn_wc__complete_directory_add(svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_hash_t *new_original_props, + const char *copyfrom_url, + svn_revnum_t copyfrom_rev, + apr_pool_t *scratch_pool); + + +/* Acquire a write lock on LOCAL_ABSPATH or an ancestor that covers + all possible paths affected by resolving the conflicts in the tree + LOCAL_ABSPATH. Set *LOCK_ROOT_ABSPATH to the path of the lock + obtained. */ +svn_error_t * +svn_wc__acquire_write_lock_for_resolve(const char **lock_root_abspath, + svn_wc_context_t *wc_ctx, + const char *local_abspath, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SVN_WC_PRIVATE_H */ |