]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/subversion/subversion/include/private/svn_subr_private.h
MFC r275385 (by bapt):
[FreeBSD/stable/10.git] / contrib / subversion / subversion / include / private / svn_subr_private.h
1 /*
2  * svn_subr_private.h : private definitions from libsvn_subr
3  *
4  * ====================================================================
5  *    Licensed to the Apache Software Foundation (ASF) under one
6  *    or more contributor license agreements.  See the NOTICE file
7  *    distributed with this work for additional information
8  *    regarding copyright ownership.  The ASF licenses this file
9  *    to you under the Apache License, Version 2.0 (the
10  *    "License"); you may not use this file except in compliance
11  *    with the License.  You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  *    Unless required by applicable law or agreed to in writing,
16  *    software distributed under the License is distributed on an
17  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18  *    KIND, either express or implied.  See the License for the
19  *    specific language governing permissions and limitations
20  *    under the License.
21  * ====================================================================
22  */
23
24 #ifndef SVN_SUBR_PRIVATE_H
25 #define SVN_SUBR_PRIVATE_H
26
27 #include "svn_types.h"
28 #include "svn_io.h"
29 #include "svn_config.h"
30
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif /* __cplusplus */
35
36
37 /** Spill-to-file Buffers
38  *
39  * @defgroup svn_spillbuf_t Spill-to-file Buffers
40  * @{
41  */
42
43 /** A buffer that collects blocks of content, possibly using a file.
44  *
45  * The spill-buffer is created with two basic parameters: the size of the
46  * blocks that will be written into the spill-buffer ("blocksize"), and
47  * the (approximate) maximum size that will be allowed in memory ("maxsize").
48  * Once the maxsize is reached, newly written content will be "spilled"
49  * into a temporary file.
50  *
51  * When writing, content will be buffered into memory unless a given write
52  * will cause the amount of in-memory content to exceed the specified
53  * maxsize. At that point, the file is created, and the content will be
54  * written to that file.
55  *
56  * To read information back out of a spill buffer, there are two approaches
57  * available to the application:
58  *
59  *   *) reading blocks using svn_spillbuf_read() (a "pull" model)
60  *   *) having blocks passed to a callback via svn_spillbuf_process()
61  *      (a "push" model to your application)
62  *
63  * In both cases, the spill-buffer will provide you with a block of N bytes
64  * that you must fully consume before asking for more data. The callback
65  * style provides for a "stop" parameter to temporarily pause the reading
66  * until another read is desired. The two styles of reading may be mixed,
67  * as the caller desires. Generally, N will be the blocksize, and will be
68  * less when the end of the content is reached.
69  *
70  * For a more stream-oriented style of reading, where the caller specifies
71  * the number of bytes to read into a caller-provided buffer, please see
72  * svn_spillbuf_reader_t. That overlaid type will cause more memory copies
73  * to be performed (whereas the bare spill-buffer type hands you a buffer
74  * to consume).
75  *
76  * Writes may be interleaved with reading, and content will be returned
77  * in a FIFO manner. Thus, if content has been placed into the spill-buffer
78  * you will always read the earliest-written data, and any newly-written
79  * content will be appended to the buffer.
80  *
81  * Note: the file is created in the same pool where the spill-buffer was
82  * created. If the content is completely read from that file, it will be
83  * closed and deleted. Should writing further content cause another spill
84  * file to be created, that will increase the size of the pool. There is
85  * no bound on the amount of file-related resources that may be consumed
86  * from the pool. It is entirely related to the read/write pattern and
87  * whether spill files are repeatedly created.
88  */
89 typedef struct svn_spillbuf_t svn_spillbuf_t;
90
91
92 /* Create a spill buffer.  */
93 svn_spillbuf_t *
94 svn_spillbuf__create(apr_size_t blocksize,
95                      apr_size_t maxsize,
96                      apr_pool_t *result_pool);
97
98 /* Create a spill buffer, with extra parameters.  */
99 svn_spillbuf_t *
100 svn_spillbuf__create_extended(apr_size_t blocksize,
101                               apr_size_t maxsize,
102                               svn_boolean_t delete_on_close,
103                               svn_boolean_t spill_all_contents,
104                               const char* dirpath,
105                               apr_pool_t *result_pool);
106
107 /* Determine how much content is stored in the spill buffer.  */
108 svn_filesize_t
109 svn_spillbuf__get_size(const svn_spillbuf_t *buf);
110
111 /* Determine how much content the spill buffer is caching in memory.  */
112 svn_filesize_t
113 svn_spillbuf__get_memory_size(const svn_spillbuf_t *buf);
114
115 /* Retrieve the name of the spill file. The returned value can be NULL
116    if the file has not been created yet. */
117 const char *
118 svn_spillbuf__get_filename(const svn_spillbuf_t *buf);
119
120 /* Retrieve the handle of the spill file. The returned value can be
121    NULL if the file has not been created yet. */
122 apr_file_t *
123 svn_spillbuf__get_file(const svn_spillbuf_t *buf);
124
125 /* Write some data into the spill buffer.  */
126 svn_error_t *
127 svn_spillbuf__write(svn_spillbuf_t *buf,
128                     const char *data,
129                     apr_size_t len,
130                     apr_pool_t *scratch_pool);
131
132
133 /* Read a block of memory from the spill buffer. @a *data will be set to
134    NULL if no content remains. Otherwise, @a data and @a len will point to
135    data that must be fully-consumed by the caller. This data will remain
136    valid until another call to svn_spillbuf_write(), svn_spillbuf_read(),
137    or svn_spillbuf_process(), or if the spill buffer's pool is cleared.  */
138 svn_error_t *
139 svn_spillbuf__read(const char **data,
140                    apr_size_t *len,
141                    svn_spillbuf_t *buf,
142                    apr_pool_t *scratch_pool);
143
144
145 /* Callback for reading content out of the spill buffer. Set @a stop if
146    you want to stop the processing (and will call svn_spillbuf_process
147    again, at a later time).  */
148 typedef svn_error_t * (*svn_spillbuf_read_t)(svn_boolean_t *stop,
149                                              void *baton,
150                                              const char *data,
151                                              apr_size_t len,
152                                              apr_pool_t *scratch_pool);
153
154
155 /* Process the content stored in the spill buffer. @a exhausted will be
156    set to TRUE if all of the content is processed by @a read_func. This
157    function may return early if the callback returns TRUE for its 'stop'
158    parameter.  */
159 svn_error_t *
160 svn_spillbuf__process(svn_boolean_t *exhausted,
161                       svn_spillbuf_t *buf,
162                       svn_spillbuf_read_t read_func,
163                       void *read_baton,
164                       apr_pool_t *scratch_pool);
165
166
167 /** Classic stream reading layer on top of spill-buffers.
168  *
169  * This type layers upon a spill-buffer to enable a caller to read a
170  * specified number of bytes into the caller's provided buffer. This
171  * implies more memory copies than the standard spill-buffer reading
172  * interface, but is sometimes required by spill-buffer users.
173  */
174 typedef struct svn_spillbuf_reader_t svn_spillbuf_reader_t;
175
176
177 /* Create a spill-buffer and a reader for it, using the same arguments as
178    svn_spillbuf__create().  */
179 svn_spillbuf_reader_t *
180 svn_spillbuf__reader_create(apr_size_t blocksize,
181                             apr_size_t maxsize,
182                             apr_pool_t *result_pool);
183
184 /* Read @a len bytes from @a reader into @a data. The number of bytes
185    actually read is stored in @a amt. If the content is exhausted, then
186    @a amt is set to zero. It will always be non-zero if the spill-buffer
187    contains content.
188
189    If @a len is zero, then SVN_ERR_INCORRECT_PARAMS is returned.  */
190 svn_error_t *
191 svn_spillbuf__reader_read(apr_size_t *amt,
192                           svn_spillbuf_reader_t *reader,
193                           char *data,
194                           apr_size_t len,
195                           apr_pool_t *scratch_pool);
196
197
198 /* Read a single character from @a reader, and place it in @a c. If there
199    is no content in the spill-buffer, then SVN_ERR_STREAM_UNEXPECTED_EOF
200    is returned.  */
201 svn_error_t *
202 svn_spillbuf__reader_getc(char *c,
203                           svn_spillbuf_reader_t *reader,
204                           apr_pool_t *scratch_pool);
205
206
207 /* Write @a len bytes from @a data into the spill-buffer in @a reader.  */
208 svn_error_t *
209 svn_spillbuf__reader_write(svn_spillbuf_reader_t *reader,
210                            const char *data,
211                            apr_size_t len,
212                            apr_pool_t *scratch_pool);
213
214
215 /* Return a stream built on top of a spillbuf.
216
217    This stream can be used for reading and writing, but implements the
218    same basic semantics of a spillbuf for the underlying storage. */
219 svn_stream_t *
220 svn_stream__from_spillbuf(svn_spillbuf_t *buf,
221                           apr_pool_t *result_pool);
222
223 /** @} */
224
225 /*----------------------------------------------------*/
226
227 /**
228  * @defgroup svn_checksum_private Checksumming helper APIs
229  * @{
230  */
231
232 /**
233  * Internal function for creating a MD5 checksum from a binary digest.
234  *
235  * @since New in 1.8
236  */
237 svn_checksum_t *
238 svn_checksum__from_digest_md5(const unsigned char *digest,
239                               apr_pool_t *result_pool);
240
241 /**
242  * Internal function for creating a SHA1 checksum from a binary
243  * digest.
244  *
245  * @since New in 1.8
246  */
247 svn_checksum_t *
248 svn_checksum__from_digest_sha1(const unsigned char *digest,
249                                apr_pool_t *result_pool);
250
251 /**
252  * Internal function for creating a 32 bit FNV-1a checksum from a binary
253  * digest.
254  *
255  * @since New in 1.9
256  */
257 svn_checksum_t *
258 svn_checksum__from_digest_fnv1a_32(const unsigned char *digest,
259                                    apr_pool_t *result_pool);
260
261 /**
262  * Internal function for creating a modified 32 bit FNV-1a checksum from
263  * a binary digest.
264  *
265  * @since New in 1.9
266  */
267 svn_checksum_t *
268 svn_checksum__from_digest_fnv1a_32x4(const unsigned char *digest,
269                                      apr_pool_t *result_pool);
270
271
272 /**
273  * Return a stream that calculates a checksum of type @a kind over all
274  * data written to the @a inner_stream.  When the returned stream gets
275  * closed, write the checksum to @a *checksum.
276  * Allocate the result in @a pool.
277  *
278  * @note The stream returned only supports #svn_stream_write and
279  * #svn_stream_close.
280  */
281 svn_stream_t *
282 svn_checksum__wrap_write_stream(svn_checksum_t **checksum,
283                                 svn_stream_t *inner_stream,
284                                 svn_checksum_kind_t kind,
285                                 apr_pool_t *pool);
286
287 /**
288  * Return a stream that calculates a 32 bit modified FNV-1a checksum
289  * over all data written to the @a inner_stream and writes the digest
290  * to @a *digest when the returned stream gets closed.
291  * Allocate the stream in @a pool.
292  */
293 svn_stream_t *
294 svn_checksum__wrap_write_stream_fnv1a_32x4(apr_uint32_t *digest,
295                                            svn_stream_t *inner_stream,
296                                            apr_pool_t *pool);
297
298 /**
299  * Return a 32 bit FNV-1a checksum for the first @a len bytes in @a input.
300  *
301  * @since New in 1.9
302  */
303 apr_uint32_t
304 svn__fnv1a_32(const void *input, apr_size_t len);
305
306 /**
307  * Return a 32 bit modified FNV-1a checksum for the first @a len bytes in
308  * @a input.
309  *
310  * @note This is a proprietary checksumming algorithm based FNV-1a with
311  *       approximately the same strength.  It is up to 4 times faster
312  *       than plain FNV-1a for longer data blocks.
313  *
314  * @since New in 1.9
315  */
316 apr_uint32_t
317 svn__fnv1a_32x4(const void *input, apr_size_t len);
318
319 /** @} */
320
321
322 /**
323  * @defgroup svn_hash_support Hash table serialization support
324  * @{
325  */
326
327 /*----------------------------------------------------*/
328
329 /**
330  * @defgroup svn_hash_misc Miscellaneous hash APIs
331  * @{
332  */
333
334 /** @} */
335
336
337 /**
338  * @defgroup svn_hash_getters Specialized getter APIs for hashes
339  * @{
340  */
341
342 /** Find the value of a @a key in @a hash, return the value.
343  *
344  * If @a hash is @c NULL or if the @a key cannot be found, the
345  * @a default_value will be returned.
346  *
347  * @since New in 1.7.
348  */
349 const char *
350 svn_hash__get_cstring(apr_hash_t *hash,
351                       const char *key,
352                       const char *default_value);
353
354 /** Like svn_hash_get_cstring(), but for boolean values.
355  *
356  * Parses the value as a boolean value. The recognized representations
357  * are 'TRUE'/'FALSE', 'yes'/'no', 'on'/'off', '1'/'0'; case does not
358  * matter.
359  *
360  * @since New in 1.7.
361  */
362 svn_boolean_t
363 svn_hash__get_bool(apr_hash_t *hash,
364                    const char *key,
365                    svn_boolean_t default_value);
366
367 /** @} */
368
369 /**
370  * @defgroup svn_hash_create Create optimized APR hash tables
371  * @{
372  */
373
374 /** Returns a hash table, allocated in @a pool, with the same ordering of
375  * elements as APR 1.4.5 or earlier (using apr_hashfunc_default) but uses
376  * a faster hash function implementation.
377  *
378  * @since New in 1.8.
379  */
380 apr_hash_t *
381 svn_hash__make(apr_pool_t *pool);
382
383 /** @} */
384
385 /**
386  * @defgroup svn_hash_read Reading serialized hash tables
387  * @{
388  */
389
390 /** Struct that represents a key value pair read from a serialized hash
391  * representation.  There are special cases that can also be represented:
392  * a #NULL @a key signifies the end of the hash, a #NULL @a val for non-
393  * NULL keys is only possible in incremental mode describes a deletion.
394  *
395  * @since New in 1.9.
396  */
397 typedef struct svn_hash__entry_t
398 {
399   /** 0-terminated Key.  #NULL if this contains no data at all because we
400    * encountered the end of the hash. */
401   char *key;
402
403   /** Length of @a key.  Must be 0 if @a key is #NULL. */
404   apr_size_t keylen;
405
406   /** 0-terminated value stored with the key.  If this is #NULL for a
407    * non-NULL @a key, then this means that the key shall be removed from
408    * the hash (only used in incremental mode).  Must be #NULL if @a key is
409    * #NULL. */
410   char *val;
411
412   /** Length of @a val.  Must be 0 if @a val is #NULL. */
413   apr_size_t vallen;
414 } svn_hash__entry_t;
415
416 /** Reads a single key-value pair from @a stream and returns it in the
417  * caller-provided @a *entry (members don't need to be pre-initialized).
418  * @a pool is used to allocate members of @a *entry and for tempoaries.
419  *
420  * @see #svn_hash_read2 for more details.
421  *
422  * @since New in 1.9.
423  */
424 svn_error_t *
425 svn_hash__read_entry(svn_hash__entry_t *entry,
426                      svn_stream_t *stream,
427                      const char *terminator,
428                      svn_boolean_t incremental,
429                      apr_pool_t *pool);
430
431 /** @} */
432
433 /** @} */
434
435
436 /** Apply the changes described by @a prop_changes to @a original_props and
437  * return the result.  The inverse of svn_prop_diffs().
438  *
439  * Allocate the resulting hash from @a pool, but allocate its keys and
440  * values from @a pool and/or by reference to the storage of the inputs.
441  *
442  * Note: some other APIs use an array of pointers to svn_prop_t.
443  *
444  * @since New in 1.8.
445  */
446 apr_hash_t *
447 svn_prop__patch(const apr_hash_t *original_props,
448                 const apr_array_header_t *prop_changes,
449                 apr_pool_t *pool);
450
451
452 /**
453  * @defgroup svn_version Version number dotted triplet parsing
454  * @{
455  */
456
457 /* Set @a *version to a version structure parsed from the version
458  * string representation in @a version_string.  Return
459  * @c SVN_ERR_MALFORMED_VERSION_STRING if the string fails to parse
460  * cleanly.
461  *
462  * @since New in 1.8.
463  */
464 svn_error_t *
465 svn_version__parse_version_string(svn_version_t **version,
466                                   const char *version_string,
467                                   apr_pool_t *result_pool);
468
469 /* Return true iff @a version represents a version number of at least
470  * the level represented by @a major, @a minor, and @a patch.
471  *
472  * @since New in 1.8.
473  */
474 svn_boolean_t
475 svn_version__at_least(svn_version_t *version,
476                       int major,
477                       int minor,
478                       int patch);
479
480 /** @} */
481
482 /**
483  * @defgroup svn_compress Data (de-)compression API
484  * @{
485  */
486
487 /* This is at least as big as the largest size of an integer that
488    svn__encode_uint() can generate; it is sufficient for creating buffers
489    for it to write into.  This assumes that integers are at most 64 bits,
490    and so 10 bytes (with 7 bits of information each) are sufficient to
491    represent them. */
492 #define SVN__MAX_ENCODED_UINT_LEN 10
493
494 /* Compression method parameters for svn__encode_uint. */
495
496 /* No compression (but a length prefix will still be added to the buffer) */
497 #define SVN__COMPRESSION_NONE         0
498
499 /* Fastest, least effective compression method & level provided by zlib. */
500 #define SVN__COMPRESSION_ZLIB_MIN     1
501
502 /* Default compression method & level provided by zlib. */
503 #define SVN__COMPRESSION_ZLIB_DEFAULT 5
504
505 /* Slowest, best compression method & level provided by zlib. */
506 #define SVN__COMPRESSION_ZLIB_MAX     9
507
508 /* Encode VAL into the buffer P using the variable-length 7b/8b unsigned
509    integer format.  Return the incremented value of P after the
510    encoded bytes have been written.  P must point to a buffer of size
511    at least SVN__MAX_ENCODED_UINT_LEN.
512
513    This encoding uses the high bit of each byte as a continuation bit
514    and the other seven bits as data bits.  High-order data bits are
515    encoded first, followed by lower-order bits, so the value can be
516    reconstructed by concatenating the data bits from left to right and
517    interpreting the result as a binary number.  Examples (brackets
518    denote byte boundaries, spaces are for clarity only):
519
520            1 encodes as [0 0000001]
521           33 encodes as [0 0100001]
522          129 encodes as [1 0000001] [0 0000001]
523         2000 encodes as [1 0001111] [0 1010000]
524 */
525 unsigned char *
526 svn__encode_uint(unsigned char *p, apr_uint64_t val);
527
528 /* Decode an unsigned 7b/8b-encoded integer into *VAL and return a pointer
529    to the byte after the integer.  The bytes to be decoded live in the
530    range [P..END-1].  If these bytes do not contain a whole encoded
531    integer, return NULL; in this case *VAL is undefined.
532
533    See the comment for svn__encode_uint() earlier in this file for more
534    detail on the encoding format.  */
535 const unsigned char *
536 svn__decode_uint(apr_uint64_t *val,
537                  const unsigned char *p,
538                  const unsigned char *end);
539
540 /* Get the data from IN, compress it according to the specified
541  * COMPRESSION_METHOD and write the result to OUT.
542  * SVN__COMPRESSION_NONE is valid for COMPRESSION_METHOD.
543  */
544 svn_error_t *
545 svn__compress(svn_stringbuf_t *in,
546               svn_stringbuf_t *out,
547               int compression_method);
548
549 /* Get the compressed data from IN, decompress it and write the result to
550  * OUT.  Return an error if the decompressed size is larger than LIMIT.
551  */
552 svn_error_t *
553 svn__decompress(svn_stringbuf_t *in,
554                 svn_stringbuf_t *out,
555                 apr_size_t limit);
556
557 /** @} */
558
559 /**
560  * @defgroup svn_root_pools Recycle-able root pools API
561  * @{
562  */
563
564 /* Opaque thread-safe container for unused / recylcleable root pools.
565  *
566  * Recyling root pools (actually, their allocators) circumvents a
567  * scalability bottleneck in the OS memory management when multi-threaded
568  * applications frequently create and destroy allocators.
569  */
570 typedef struct svn_root_pools__t svn_root_pools__t;
571
572 /* Create a new root pools container and return it in *POOLS.
573  */
574 svn_error_t *
575 svn_root_pools__create(svn_root_pools__t **pools);
576
577 /* Return a currently unused pool from POOLS.  If POOLS is empty, create a
578  * new root pool and return that.  The pool returned is not thread-safe.
579  */
580 apr_pool_t *
581 svn_root_pools__acquire_pool(svn_root_pools__t *pools);
582
583 /* Clear and release the given root POOL and put it back into POOLS.
584  * If that fails, destroy POOL.
585  */
586 void
587 svn_root_pools__release_pool(apr_pool_t *pool,
588                              svn_root_pools__t *pools);
589
590 /** @} */
591
592 /**
593  * @defgroup svn_config_private Private configuration handling API
594  * @{
595  */
596
597 /* Future attempts to modify CFG will trigger an assertion. */
598 void
599 svn_config__set_read_only(svn_config_t *cfg,
600                           apr_pool_t *scratch_pool);
601
602 /* Return TRUE, if CFG cannot be modified. */
603 svn_boolean_t
604 svn_config__is_read_only(svn_config_t *cfg);
605
606 /* Return TRUE, if OPTION in SECTION in CFG exists and does not require
607  * further expansion (due to either containing no placeholders or already
608  * having been expanded). */
609 svn_boolean_t
610 svn_config__is_expanded(svn_config_t *cfg,
611                         const char *section,
612                         const char *option);
613
614 /* Return a shallow copy of SCR in POOL.  If SRC is read-only, different
615  * shallow copies may be used from different threads.
616  *
617  * Any single r/o svn_config_t or shallow copy is not thread-safe because
618  * it contains shared buffers for tempoary data.
619  */
620 svn_config_t *
621 svn_config__shallow_copy(svn_config_t *src,
622                          apr_pool_t *pool);
623
624 /* Add / replace SECTION in TARGET with the same section from SOURCE by
625  * simply adding a reference to it.  If TARGET is read-only, the sections
626  * list in target gets duplicated before the modification.
627  *
628  * This is an API tailored for use by the svn_repos__authz_pool_t API to
629  * prevent breach of encapsulation.
630  */
631 void
632 svn_config__shallow_replace_section(svn_config_t *target,
633                                     svn_config_t *source,
634                                     const char *section);
635
636 /* Allocate *CFG_HASH and populate it with default, empty,
637  * svn_config_t for the configuration categories (@c
638  * SVN_CONFIG_CATEGORY_SERVERS, @c SVN_CONFIG_CATEGORY_CONFIG, etc.).
639  * This returns a hash equivalent to svn_config_get_config when the
640  * config files are empty.
641  */
642 svn_error_t *
643 svn_config__get_default_config(apr_hash_t **cfg_hash,
644                                apr_pool_t *pool);
645
646 /** @} */
647
648
649 /**
650  * @defgroup svn_bit_array Packed bit array handling API
651  * @{
652  */
653
654 /* This opaque data struct is an alternative to an INT->VOID hash.
655  *
656  * Technically, it is an automatically growing packed bit array.
657  * All indexes not previously set are implicitly 0 and setting it will
658  * grow the array as needed.
659  */
660 typedef struct svn_bit_array__t svn_bit_array__t;
661
662 /* Return a new bit array allocated in POOL.  MAX is a mere hint for
663  * the initial size of the array in bits.
664  */
665 svn_bit_array__t *
666 svn_bit_array__create(apr_size_t max,
667                       apr_pool_t *pool);
668
669 /* Set bit at index IDX in ARRAY to VALUE.  If necessary, grow the
670  * underlying data buffer, i.e. any IDX is valid unless we run OOM.
671  */
672 void
673 svn_bit_array__set(svn_bit_array__t *array,
674                    apr_size_t idx,
675                    svn_boolean_t value);
676
677 /* Get the bit value at index IDX in ARRAY.  Bits not previously accessed
678  * are implicitly 0 (or FALSE).  That implies IDX can never be out-of-range.
679  */
680 svn_boolean_t
681 svn_bit_array__get(svn_bit_array__t *array,
682                    apr_size_t idx);
683
684 /* Return the global pool used by the DSO loader, this may be NULL if
685    no DSOs have been loaded. */
686 apr_pool_t *
687 svn_dso__pool(void);
688
689 /** @} */
690
691
692 /* Return the xml (expat) version we compiled against. */
693 const char *svn_xml__compiled_version(void);
694
695 /* Return the xml (expat) version we run against. */
696 const char *svn_xml__runtime_version(void);
697
698 /* Return the zlib version we compiled against. */
699 const char *svn_zlib__compiled_version(void);
700
701 /* Return the zlib version we run against. */
702 const char *svn_zlib__runtime_version(void);
703
704 #ifdef __cplusplus
705 }
706 #endif /* __cplusplus */
707
708 #endif /* SVN_SUBR_PRIVATE_H */