1 /*
2  * ====================================================================
3  *    Licensed to the Apache Software Foundation (ASF) under one
4  *    or more contributor license agreements.  See the NOTICE file
5  *    distributed with this work for additional information
6  *    regarding copyright ownership.  The ASF licenses this file
7  *    to you under the Apache License, Version 2.0 (the
8  *    "License"); you may not use this file except in compliance
9  *    with the License.  You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *    Unless required by applicable law or agreed to in writing,
14  *    software distributed under the License is distributed on an
15  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  *    KIND, either express or implied.  See the License for the
17  *    specific language governing permissions and limitations
18  *    under the License.
19  * ====================================================================
20  *
21  * core.i: SWIG module interface file for libsvn_subr, a few pieces of
22  *   APR functionality, and anything else that does not fit into any
23  *   of the more specific module files.
24  */
25 
26 %include svn_global.swg
27 
28 #if defined(SWIGPYTHON)
29 %module(package="libsvn", moduleimport=SVN_PYTHON_MODULEIMPORT) core
30 #elif defined(SWIGPERL)
31 %module "SVN::_Core"
32 #elif defined(SWIGRUBY)
33 %module "svn::ext::core"
34 #endif
35 
36 %{
37 #include <apr.h>
38 #include <apr_general.h>
39 
40 #include <apr_md5.h>
41 #include "svn_diff.h"
42 #include "svn_private_config.h"
43 %}
44 
45 #ifdef SWIGRUBY
46 %{
47 #include <apu.h>
48 #include <apr_xlate.h>
49 %}
50 #endif
51 
52 /* ### for now, let's ignore this thing. */
53 %ignore svn_prop_t;
54 
55 /* -----------------------------------------------------------------------
56    The following struct members have to be read-only because otherwise
57    strings assigned to then would never be freed, resulting in memory
58    leaks. This prevents the swig warning "Warning(451): Setting const
59    char * member may leak memory."
60 */
61 %immutable svn_log_changed_path_t::copyfrom_path;
62 %immutable svn_dirent_t::last_author;
63 %immutable svn_error_t::message;
64 %immutable svn_error_t::file;
65 
66 /* -----------------------------------------------------------------------
67    completely ignore a number of functions. the presumption is that the
68    scripting language already has facilities for these things (or they
69    are relatively trivial).
70 */
71 
72 /* svn_io.h: We cherry-pick certain functions from this file. To aid in this,
73  * EVERY function in the file is listed in the order it appears, and is either
74  * %ignore-d, or present as a comment, explicitly documenting that we wrap it.
75  */
76 
77 %ignore svn_io_check_path;
78 %ignore svn_io_check_special_path;
79 %ignore svn_io_check_resolved_path;
80 /* This is useful for implementing svn_ra_callbacks_t->open_tmp_file */
81 // svn_io_open_unique_file2
82 // svn_io_open_unique_file
83 %ignore svn_io_create_unique_link;
84 %ignore svn_io_read_link;
85 %ignore svn_io_temp_dir;
86 %ignore svn_io_copy_file;
87 %ignore svn_io_copy_link;
88 %ignore svn_io_copy_dir_recursively;
89 %ignore svn_io_make_dir_recursively;
90 %ignore svn_io_dir_empty;
91 %ignore svn_io_append_file;
92 %ignore svn_io_set_file_read_only;
93 %ignore svn_io_set_file_read_write;
94 %ignore svn_io_set_file_read_write_carefully;
95 %ignore svn_io_set_file_executable;
96 %ignore svn_io_is_file_executable;
97 %ignore svn_io_read_length_line;
98 %ignore svn_io_file_affected_time;
99 %ignore svn_io_set_file_affected_time;
100 %ignore svn_io_filesizes_different_p;
101 // svn_io_file_checksum
102 // svn_io_files_contents_same_p
103 %ignore svn_io_file_create;
104 %ignore svn_io_file_lock;
105 %ignore svn_io_file_lock2;
106 %ignore svn_io_file_flush_to_disk;
107 %ignore svn_io_dir_file_copy;
108 
109 /* Not useful from scripting languages. Custom streams should be achieved
110  * by passing a scripting language native stream into a svn_stream_t *
111  * parameter, and letting a typemap using svn_swig_xx_make_stream() take
112  * care of the details. */
113 %ignore svn_stream_create;
114 %ignore svn_stream_set_baton;
115 %ignore svn_stream_set_read;
116 %ignore svn_stream_set_write;
117 %ignore svn_stream_set_close;
118 
119 /* The permitted svn_stream and svn_stringbuf functions could possibly
120  * be used by a script, in conjunction with other APIs which return or
121  * accept streams. This requires that the relevant language's custom
122  * svn_stream_t wrapping code does not obstruct this usage. */
123 // svn_stream_empty
124 // svn_stream_disown
125 // svn_stream_from_aprfile2
126 // svn_stream_from_aprfile
127 // svn_stream_for_stdout
128 // svn_stream_from_stringbuf
129 // svn_stream_compressed
130 /* svn_stream_checksummed would require special attention to wrap, because
131  * of the read_digest and write_digest parameters. */
132 %ignore svn_stream_checksummed;
133 // svn_stream_read
134 // svn_stream_write
135 // svn_stream_close
136 
137 /* Scripts can do the printf, then write to a stream.
138  * We can't really handle the variadic, so ignore it. */
139 %ignore svn_stream_printf;
140 %ignore svn_stream_printf_from_utf8;
141 
142 // svn_stream_readline
143 // svn_stream_copy
144 // svn_stream_contents_same
145 // svn_stringbuf_from_file
146 // svn_stringbuf_from_aprfile
147 
148 #ifndef SWIGPYTHON
149 /* These functions are useful in Python, because they allow you to
150  * easily delete files which are marked as read-only on Windows. */
151 %ignore svn_io_remove_file;
152 %ignore svn_io_remove_dir;
153 #endif
154 %ignore svn_io_get_dir_filenames;
155 %ignore svn_io_get_dirents2;
156 %ignore svn_io_get_dirents;
157 %ignore svn_io_dir_walk;
158 %ignore svn_io_start_cmd;
159 %ignore svn_io_wait_for_cmd;
160 %ignore svn_io_run_cmd;
161 %ignore svn_io_run_diff;
162 %ignore svn_io_run_diff3_2;
163 %ignore svn_io_run_diff3;
164 // svn_io_detect_mimetype
165 %ignore svn_io_file_open;
166 %ignore svn_io_file_close;
167 %ignore svn_io_file_getc;
168 %ignore svn_io_file_info_get;
169 %ignore svn_io_file_read;
170 %ignore svn_io_file_read_full;
171 %ignore svn_io_file_seek;
172 %ignore svn_io_file_write;
173 %ignore svn_io_file_write_full;
174 %ignore svn_io_stat;
175 %ignore svn_io_file_rename;
176 %ignore svn_io_file_move;
177 %ignore svn_io_dir_make;
178 %ignore svn_io_dir_make_hidden;
179 %ignore svn_io_dir_make_sgid;
180 %ignore svn_io_dir_open;
181 %ignore svn_io_dir_remove_nonrecursive;
182 %ignore svn_io_dir_read;
183 %ignore svn_io_read_version_file;
184 %ignore svn_io_write_version_file;
185 
186 /* svn_path.h: We cherry-pick certain functions from this file. To aid in this,
187  * EVERY function in the file is listed in the order it appears, and is either
188  * %ignore-d, or present as a comment, explicitly documenting that we wrap it.
189  */
190 // svn_path_internal_style;
191 // svn_path_local_style;
192 %ignore svn_path_join;
193 %ignore svn_path_join_many;
194 %ignore svn_path_basename;
195 %ignore svn_path_dirname;
196 %ignore svn_path_component_count;
197 %ignore svn_path_add_component;
198 %ignore svn_path_remove_component;
199 %ignore svn_path_remove_components;
200 %ignore svn_path_split;
201 // svn_path_is_empty;
202 // svn_path_canonicalize;
203 // svn_path_compare_paths;
204 // svn_path_get_longest_ancestor;
205 %ignore svn_path_get_absolute;
206 %ignore svn_path_split_if_file;
207 %ignore svn_path_condense_targets;
208 %ignore svn_path_remove_redundancies;
209 %ignore svn_path_decompose;
210 %ignore svn_path_compose;
211 %ignore svn_path_is_single_path_component;
212 %ignore svn_path_is_backpath_present;
213 %ignore svn_path_is_child;
214 %ignore svn_path_is_ancestor;
215 %ignore svn_path_check_valid;
216 // svn_path_is_url;
217 // svn_path_is_uri_safe;
218 %ignore svn_path_uri_encode;
219 %ignore svn_path_uri_decode;
220 %ignore svn_path_url_add_component;
221 %ignore svn_path_uri_from_iri;
222 %ignore svn_path_uri_autoescape;
223 %ignore svn_path_cstring_from_utf8;
224 %ignore svn_path_cstring_to_utf8;
225 
226 /* svn_dirent_uri.h: SWIG can't digest these functions yet, so ignore them
227  * for now. TODO: make them work.
228  */
229 %ignore svn_dirent_join_many;
230 %ignore svn_dirent_condense_targets;
231 %ignore svn_uri_condense_targets;
232 %ignore svn_dirent_is_under_root;
233 
234 /* Other files */
235 
236 /* Ignore platform-specific auth functions */
237 %ignore svn_auth_get_keychain_simple_provider;
238 %ignore svn_auth_get_keychain_ssl_client_cert_pw_provider;
239 %ignore svn_auth_get_windows_simple_provider;
240 %ignore svn_auth_get_windows_ssl_server_trust_provider;
241 %ignore svn_auth_gnome_keyring_version;
242 %ignore svn_auth_get_gnome_keyring_simple_provider;
243 %ignore svn_auth_get_gnome_keyring_ssl_client_cert_pw_provider;
244 %ignore svn_auth_kwallet_version;
245 %ignore svn_auth_get_kwallet_simple_provider;
246 %ignore svn_auth_get_kwallet_ssl_client_cert_pw_provider;
247 %ignore svn_auth_get_gpg_agent_simple_provider;
248 
249 /* bad pool convention */
250 %ignore svn_opt_print_generic_help;
251 
252 %ignore svn_opt_args_to_target_array;
253 
254 /* svn_cmdline.h */
255 %ignore svn_cmdline_auth_plaintext_passphrase_prompt;
256 %ignore svn_cmdline_auth_plaintext_prompt;
257 %ignore svn_cmdline_auth_simple_prompt;
258 %ignore svn_cmdline_auth_ssl_client_cert_prompt;
259 %ignore svn_cmdline_auth_ssl_client_cert_pw_prompt;
260 %ignore svn_cmdline_auth_ssl_server_trust_prompt;
261 %ignore svn_cmdline_auth_username_prompt;
262 %ignore svn_cmdline_cstring_from_utf8;
263 %ignore svn_cmdline_cstring_from_utf8_fuzzy;
264 %ignore svn_cmdline_cstring_to_utf8;
265 %ignore svn_cmdline_fflush;
266 %ignore svn_cmdline_fprintf;
267 %ignore svn_cmdline_fputs;
268 %ignore svn_cmdline_handle_exit_error;
269 %ignore svn_cmdline_output_encoding;
270 %ignore svn_cmdline_path_local_style_from_utf8;
271 %ignore svn_cmdline_printf;
272 %ignore svn_cmdline_prompt_baton2_t;
273 %ignore svn_cmdline_prompt_baton_t;
274 %ignore svn_cmdline_prompt_user2;
275 %ignore svn_cmdline_prompt_user;
276 %ignore svn_cmdline_setup_auth_baton;
277 
278 /* Ugliness because the constants are typedefed and SWIG ignores them
279    as a result. */
280 %constant svn_revnum_t SWIG_SVN_INVALID_REVNUM = -1;
281 %constant svn_revnum_t SWIG_SVN_IGNORED_REVNUM = -1;
282 
283 /* -----------------------------------------------------------------------
284    input rangelist
285 */
286 %apply svn_rangelist_t *RANGELIST {
287   svn_rangelist_t *rangeinput,
288   const svn_rangelist_t *rangelist,
289   svn_rangelist_t *from,
290   svn_rangelist_t *to,
291   svn_rangelist_t *changes,
292   svn_rangelist_t *eraser,
293   svn_rangelist_t *whiteboard,
294   svn_rangelist_t *rangelist1,
295   svn_rangelist_t *rangelist2
296 }
297 
298 /* -----------------------------------------------------------------------
299    output rangelist
300 */
301 %apply svn_rangelist_t **RANGELIST {
302   svn_rangelist_t **rangelist,
303   svn_rangelist_t **inheritable_rangelist,
304   svn_rangelist_t **deleted,
305   svn_rangelist_t **added,
306   svn_rangelist_t **output
307 }
308 
309 /* -----------------------------------------------------------------------
310    input and output rangelist
311 */
312 %apply svn_rangelist_t **RANGELIST_INOUT {
313   svn_rangelist_t **rangelist_inout
314 }
315 
316 /* -----------------------------------------------------------------------
317    input mergeinfo hash
318 */
319 %apply apr_hash_t *MERGEINFO {
320    apr_hash_t *mergefrom,
321    apr_hash_t *mergeto,
322    apr_hash_t *mergein1,
323    apr_hash_t *mergein2,
324    apr_hash_t *mergeinfo,
325    apr_hash_t *mergeinput,
326    apr_hash_t *eraser,
327    apr_hash_t *whiteboard,
328    apr_hash_t *changes
329 }
330 
331 /* -----------------------------------------------------------------------
332    output mergeinfo
333 */
334 
335 #if defined(SWIGPYTHON) || defined(SWIGRUBY)
336 %apply apr_hash_t **MERGEINFO_INOUT {
337     apr_hash_t **mergeinfo_inout
338 }
339 
340 %apply apr_hash_t **MERGEINFO {
341     apr_hash_t **mergeinfo,
342     apr_hash_t **inheritable_mergeinfo,
343     apr_hash_t **deleted,
344     apr_hash_t **added
345 }
346 #endif
347 
348 /* -----------------------------------------------------------------------
349    output mergeinfo hash
350 */
351 
352 #if defined(SWIGRUBY) || defined(SWIGPYTHON)
353 %apply apr_hash_t **MERGEINFO_CATALOG {
354   apr_hash_t **catalog
355 };
356 #endif
357 
358 /* -----------------------------------------------------------------------
359    allowable null values
360 */
361 %apply const char *MAY_BE_NULL {
362     /* svn_config_get */
363     const char *default_value,
364     /* svn_config_read_auth_data */
365     const char *config_dir,
366     /* svn_config_get_user_config_path */
367     const char *fname,
368     /* svn_diff_file_output_merge */
369     const char *conflict_original,
370     const char *conflict_modified,
371     const char *conflict_latest,
372     const char *conflict_separator,
373     /* svn_cmdline_create_auth_baton */
374     const char *username,
375     const char *password
376 };
377 
378 /* -----------------------------------------------------------------------
379    fix up the svn_stream_read() ptr/len arguments
380 */
381 #ifdef SWIGPYTHON
382 %typemap(in) (char *buffer, apr_size_t *len) ($*2_type temp) {
383     if (PyLong_Check($input)) {
384         temp = PyLong_AsUnsignedLong($input);
385     }
386 %#if IS_PY3 != 1
387     else if (PyInt_Check($input)) {
388         /* wish there was a PyInt_AsUnsignedLong but there isn't
389            the mask version doesn't do bounds checking for us.
390            I can't see a good way to do the bounds checking ourselves
391            so just stick our head in the sand.  With Python3 this
392            problem goes away because PyInt is gone anyway. */
393         temp = PyInt_AsUnsignedLongMask($input);
394     }
395 %#endif
396     else {
397         PyErr_SetString(PyExc_TypeError,
398                         "expecting an integer for the buffer size");
399         SWIG_fail;
400     }
401     $1 = malloc(temp);
402     $2 = ($2_ltype)&temp;
403 }
404 #endif
405 #ifdef SWIGPERL
406 %typemap(in) (char *buffer, apr_size_t *len) ($*2_type temp) {
407     temp = SvIV($input);
408     $1 = malloc(temp);
409     $2 = ($2_ltype)&temp;
410 }
411 #endif
412 #ifdef SWIGRUBY
413 %typemap(in) (char *buffer, apr_size_t *len) ($*2_type temp) {
414     temp = NUM2LONG($input);
415     $1 = malloc(temp);
416     $2 = ($2_ltype)&temp;
417 }
418 #endif
419 
420 /* ### need to use freearg or somesuch to ensure the string is freed.
421    ### watch out for 'return' anywhere in the binding code. */
422 
423 #ifdef SWIGPYTHON
424 %typemap(argout) (char *buffer, apr_size_t *len) {
425   %append_output(PyBytes_FromStringAndSize($1, *$2));
426   free($1);
427 }
428 #endif
429 #ifdef SWIGPERL
430 %typemap(argout) (char *buffer, apr_size_t *len) {
431   %append_output(sv_2mortal(newSVpvn($1, *$2)));
432   free($1);
433 }
434 #endif
435 #ifdef SWIGRUBY
436 %typemap(argout) (char *buffer, apr_size_t *len) {
437   %append_output(*$2 == 0 ? Qnil : rb_str_new($1, *$2));
438   free($1);
439 }
440 #endif
441 
442 /* -----------------------------------------------------------------------
443    fix up the svn_stream_write() ptr/len arguments
444 */
445 #ifdef SWIGPYTHON
446 %typemap(in) (const char *data, apr_size_t *len) ($*2_type temp) {
447     Py_ssize_t length;
448     if (PyBytes_Check($input)) {
449         if (PyBytes_AsStringAndSize($input, (char **)&$1, &length) == -1) {
450             SWIG_fail;
451         }
452     }
453     else if (PyUnicode_Check($input)) {
454         $1 = (char *)PyStr_AsUTF8AndSize($input, &length);
455         if (PyErr_Occurred()) {
456             SWIG_fail;
457         }
458     }
459     else {
460         PyErr_SetString(PyExc_TypeError,
461                         "expecting a bytes or str object for the buffer");
462         SWIG_fail;
463     }
464     temp = ($*2_type)length;
465     $2 = ($2_ltype)&temp;
466 }
467 #endif
468 #ifdef SWIGPERL
469 %typemap(in) (const char *data, apr_size_t *len) ($*2_type temp) {
470     $1 = SvPV($input, temp);
471     $2 = ($2_ltype)&temp;
472 }
473 #endif
474 #ifdef SWIGRUBY
475 %typemap(in) (const char *data, apr_size_t *len) ($*2_type temp)
476 {
477   $1 = StringValuePtr($input);
478   temp = RSTRING_LEN($input);
479   $2 = ($2_ltype)&temp;
480 }
481 #endif
482 
483 #ifdef SWIGPYTHON
484 %typemap(argout) (const char *data, apr_size_t *len) {
485   %append_output(PyInt_FromLong(*$2));
486 }
487 #endif
488 
489 #ifdef SWIGPERL
490 %typemap(argout) (const char *data, apr_size_t *len) {
491   %append_output(sv_2mortal(newSViv(*$2)));
492 }
493 #endif
494 
495 #ifdef SWIGRUBY
496 %typemap(argout) (const char *data, apr_size_t *len) {
497   %append_output(LONG2NUM(*$2));
498 }
499 #endif
500 
501 /* -----------------------------------------------------------------------
502    auth parameter set/get
503 */
504 
505 /* set */
506 #ifdef SWIGPYTHON
507 %typemap(in) const void *value
508   (apr_pool_t *_global_pool = NULL, PyObject *_global_py_pool = NULL)
509 {
510     if (_global_pool == NULL)
511     {
512        if (svn_swig_py_get_parent_pool(args, $descriptor(apr_pool_t *),
513                                      &_global_py_pool, &_global_pool))
514        SWIG_fail;
515     }
516 
517     if (PyBytes_Check($input)) {
518         const char *value = PyBytes_AsString($input);
519         $1 = apr_pstrdup(_global_pool, value);
520     }
521     else if (PyLong_Check($input)) {
522         $1 = apr_palloc(_global_pool, sizeof(apr_uint32_t));
523         *((apr_uint32_t *)$1) = PyLong_AsLong($input);
524     }
525     else if (PyInt_Check($input)) {
526         $1 = apr_palloc(_global_pool, sizeof(apr_uint32_t));
527         *((apr_uint32_t *)$1) = PyInt_AsLong($input);
528     }
529     else if ($input == Py_None) {
530         $1 = NULL;
531     }
532     else if (svn_swig_py_convert_ptr($input, (void **)&$1,
533                                      $descriptor(svn_auth_ssl_server_cert_info_t *)) == 0) {
534     }
535     else {
536         PyErr_SetString(PyExc_TypeError, "not a known type");
537         SWIG_fail;
538     }
539 }
540 #endif
541 
542 #ifdef SWIGPERL
543 %typemap(in) const void *value
544   (apr_pool_t *_global_pool = NULL)
545 {
546     if (!SvOK($input) || $input == &PL_sv_undef) {
547         $1 = NULL;
548     }
549     else if (SvPOK($input)) {
550         if (_global_pool == NULL) {
551             _global_pool = svn_swig_pl_make_pool((SV *)NULL);
552             SPAGAIN;
553         }
554         $1 = apr_pstrdup(_global_pool, SvPV_nolen($input));
555     }
556     else {
557         croak("Value is not a string (or undef)");
558     }
559 }
560 #endif
561 
562 /*
563   - all values are converted to char*
564   - assume the first argument is Ruby object for svn_auth_baton_t*
565 */
566 #ifdef SWIGRUBY
567 %typemap(in) const void *value
568 {
569   if (NIL_P($input)) {
570     $1 = (void *)NULL;
571   } else {
572     VALUE _rb_pool;
573     apr_pool_t *_global_pool;
574     char *value = StringValuePtr($input);
575 
576     svn_swig_rb_get_pool(1, argv, Qnil, &_rb_pool, &_global_pool);
577     $1 = (void *)apr_pstrdup(_global_pool, value);
578   }
579 }
580 #endif
581 
582 /* get */
583 /* assume the value is char* */
584 #ifdef SWIGRUBY
585 %typemap(out) const void *
586 {
587   char *value = $1;
588   if (value) {
589     $result = rb_str_new2(value);
590   } else {
591     $result = Qnil;
592   }
593 }
594 #endif
595 
596 #ifndef SWIGRUBY
597 %ignore svn_auth_get_parameter;
598 #endif
599 
600 /* -----------------------------------------------------------------------
601    svn_io_parse_mimetypes_file()
602 */
603 
604 #ifdef SWIGRUBY
605 %apply apr_hash_t **HASH_CSTRING {
606     apr_hash_t **type_map
607 }
608 #endif
609 
610 /* -----------------------------------------------------------------------
611    svn_io_detect_mimetype2()
612 */
613 
614 %apply apr_hash_t *HASH_CSTRING {
615     apr_hash_t *mimetype_map
616 }
617 
618 /* -----------------------------------------------------------------------
619    describe how to pass a FILE* as a parameter (svn_stream_from_stdio)
620 */
621 #ifdef SWIGPYTHON
622 %typemap(in) FILE * {
623     $1 = svn_swig_py_as_file($input);
624     if ($1 == NULL) {
625         PyErr_SetString(PyExc_ValueError, "Must pass in a valid file object");
626         SWIG_fail;
627     }
628 }
629 #endif
630 #ifdef SWIGPERL
631 %typemap(in) FILE * {
632     $1 = PerlIO_exportFILE (IoIFP (sv_2io ($input)), NULL);
633 }
634 #endif
635 
636 /* -----------------------------------------------------------------------
637    wrap some specific APR functionality
638 */
639 
640 apr_status_t apr_initialize(void);
641 void apr_terminate(void);
642 
643 apr_status_t apr_time_ansi_put(apr_time_t *result, time_t input);
644 
645 void apr_pool_destroy(apr_pool_t *p);
646 void apr_pool_clear(apr_pool_t *p);
647 
648 apr_status_t apr_file_open_stdout (apr_file_t **out, apr_pool_t *pool);
649 apr_status_t apr_file_open_stderr (apr_file_t **out, apr_pool_t *pool);
650 
651 /* Allow parsing of apr_errno.h without parsing apr.h. */
652 #define APR_DECLARE(x) x
653 /* Not wrapped, use svn_strerror instead. */
654 %ignore apr_strerror;
655 /* Wrap the APR status and error codes. */
656 /* Sigh, or not. This would mean actually having access to apr_errno.h at
657    wrapper generation time, which, when rolling tarballs, the include paths
658    are not currently set up to give us. FIXME. So, instead, we replicate
659    one important typedef here instead.
660 %include apr_errno.h
661 */
662 typedef int apr_status_t;
663 
664 /* Make possible to parse the SVN_VER_NUM definition. */
665 #define APR_STRINGIFY_HELPER(n) #n
666 #define APR_STRINGIFY(n) APR_STRINGIFY_HELPER(n)
667 
668 /* -----------------------------------------------------------------------
669    pool functions renaming since swig doesn't take care of the #define's
670 */
671 %rename (svn_pool_create) svn_pool_create_ex;
672 %ignore svn_pool_create_ex_debug;
673 %typemap(default) apr_allocator_t *allocator {
674     $1 = NULL;
675 }
676 
677 /* -----------------------------------------------------------------------
678    Default pool handling for perl.
679 */
680 #ifdef SWIGPERL
681 apr_pool_t *current_pool;
682 
683 %{
684 
685 /* ### Eventually this should go away. This is not thread safe and a very
686    ### good example on HOW NOT TO USE pools */
687 static apr_pool_t *current_pool = 0;
688 
689 static apr_pool_t *
core_get_current_pool(void)690 core_get_current_pool (void)
691 {
692   return current_pool;
693 }
694 
695 static void
core_set_current_pool(apr_pool_t * pool)696 core_set_current_pool (apr_pool_t *pool)
697 {
698   current_pool = pool;
699 }
700 
701 %}
702 
703 #endif
704 
705 /* -----------------------------------------------------------------------
706    wrap config functions
707 */
708 
709 #ifdef SWIGPERL
710 %callback_typemap(svn_config_enumerator_t callback, void *baton,
711                   ,
712                   svn_swig_pl_thunk_config_enumerator,
713                   )
714 #endif
715 
716 #ifndef SWIGPERL
717 %callback_typemap(svn_config_enumerator2_t callback, void *baton,
718                   svn_swig_py_config_enumerator2,
719                   ,
720                   svn_swig_rb_config_enumerator)
721 
722 %callback_typemap(svn_config_section_enumerator2_t callback, void *baton,
723                   svn_swig_py_config_section_enumerator2,
724                   ,
725                   svn_swig_rb_config_section_enumerator)
726 #endif
727 
728 /* -----------------------------------------------------------------------
729   thunk the various authentication prompt functions.
730   PERL NOTE: store the inputed SV in _global_callback for use in the
731              later argout typemap
732 */
733 #ifdef SWIGPERL
734 %define %authprompt_callback_typemap(AuthType)
735 %typemap(in) (svn_auth_ ## AuthType ## _prompt_func_t prompt_func,
736               void *prompt_baton) {
737   $1 = svn_swig_pl_thunk_ ## AuthType ## _prompt;
738   $2 = $input;
739   _global_callback = $input;
740 }
741 %enddef
742 #else
743 %define %authprompt_callback_typemap(AuthType)
744 %callback_typemap(svn_auth_ ## AuthType ## _prompt_func_t prompt_func,
745                   void *prompt_baton,
746                   svn_swig_py_auth_ ## AuthType ## _prompt_func,,
747                   svn_swig_rb_auth_ ## AuthType ## _prompt_func)
748 %enddef
749 #endif
750 
751 %authprompt_callback_typemap(simple)
752 %authprompt_callback_typemap(username)
753 %authprompt_callback_typemap(ssl_server_trust)
754 %authprompt_callback_typemap(ssl_client_cert)
755 %authprompt_callback_typemap(ssl_client_cert_pw)
756 %authprompt_callback_typemap(gnome_keyring_unlock)
757 
758 #ifdef SWIGPYTHON
759 /* pl and rb aren't yet implemented */
760 %callback_typemap_maybenull(svn_config_auth_walk_func_t walk_func,
761                             void *walk_baton,
762                             svn_swig_py_config_auth_walk_func,
763                             svn_swig_pl_config_auth_walk_func,
764                             svn_swig_rb_config_auth_walk_func)
765 #endif
766 
767 /* -----------------------------------------------------------------------
768  * For all the various functions that set a callback baton create a reference
769  * for the baton (which in this case is an SV pointing to the callback)
770  * and make that a return from the function.  The perl side should
771  * then store the return in the object the baton is attached to.
772  * If the function already returns a value then this value is follows that
773  * function.  In the case of the prompt functions auth_open_helper in Core.pm
774  * is used to split up these values.
775 */
776 #ifdef SWIGPERL
777 %typemap(argout) void *CALLBACK_BATON (SV * _global_callback) {
778   /* callback baton */
779   %append_output(sv_2mortal(newRV_inc(_global_callback)));
780 }
781 
782 %typemap(in) void *CALLBACK_BATON (SV * _global_callback) {
783   _global_callback = $input;
784   $1 = (void *) _global_callback;
785 }
786 
787 %apply void *CALLBACK_BATON {
788   void *prompt_baton
789 };
790 #endif
791 
792 
793 /* -----------------------------------------------------------------------
794    These APIs take an "inout" parameter that necessitates more careful
795    definition.
796 */
797 %ignore svn_mergeinfo_merge;
798 %ignore svn_mergeinfo_sort;
799 %ignore svn_rangelist_merge;
800 %ignore svn_rangelist_reverse;
801 
802 #ifdef SWIGRUBY
803 %ignore svn_auth_open;
804 %ignore svn_diff_file_options_create;
805 %ignore svn_create_commit_info;
806 %ignore svn_commit_info_dup;
807 
808 %ignore svn_opt_args_to_target_array2;
809 %ignore svn_opt_args_to_target_array3;
810 %ignore svn_opt_parse_num_args;
811 %ignore svn_opt_parse_all_args;
812 #endif
813 
814 #ifdef SWIGPYTHON
815 /* The auth baton depends on the providers, so we preserve a
816    reference to them inside the wrapper. This way, if all external
817    references to the providers are gone, they will still be alive,
818    keeping the baton valid.
819  */
820 %feature("pythonappend") svn_auth_open %{
821   val.__dict__["_deps"] = list(args[0])
822 %}
823 #endif
824 
825 /* ----------------------------------------------------------------------- */
826 
827 %include svn_error_codes_h.swg
828 %include svn_time_h.swg
829 %include svn_types_impl_h.swg
830 %include svn_types_h.swg
831 %include svn_pools_h.swg
832 %include svn_version_h.swg
833 
834 /* The constant SVN_PROP_REVISION_ALL_PROPS is a C fragment, not a single
835    data value, so the SWIG parser will raise a 305 warning if we don't
836    suppress it. */
837 #pragma SWIG nowarn=305
838 %include svn_props_h.swg
839 #pragma SWIG nowarn=+305
840 
841 %include svn_opt_impl_h.swg
842 %include svn_opt_h.swg
843 %include svn_cmdline_h.swg
844 %include svn_auth_h.swg
845 %include svn_config_h.swg
846 %include svn_utf_h.swg
847 %include svn_nls_h.swg
848 %include svn_path_h.swg
849 %include svn_dirent_uri_h.swg
850 %include svn_mergeinfo_h.swg
851 %include svn_io_h.swg
852 %include svn_checksum_h.swg
853 %include svn_cache_config_h.swg
854 
855 
856 
857 %inline %{
858 /* Helper function to set the gnome-keyring unlock prompt function. This
859  * C function accepts an auth baton, a function and a prompt baton, but
860  * the below callback_typemap uses both the function and the prompt
861  * baton, so the resulting binding has just two arguments: The auth
862  * baton and the prompt function.
863  * The prompt function should again have two arguments: The keyring name
864  * (string) and a pool (except for the ruby version, which doesn't have
865  * the pool argument). It should return the entered password (string).
866  * This binding generated for this function generates a reference to the
867  * prompt function that was passed into this. The caller should store
868  * that reference somewhere, to prevent the function from being garbage
869  * collected...
870  */
svn_auth_set_gnome_keyring_unlock_prompt_func(svn_auth_baton_t * ab,svn_auth_gnome_keyring_unlock_prompt_func_t prompt_func,void * prompt_baton)871 static void svn_auth_set_gnome_keyring_unlock_prompt_func(svn_auth_baton_t *ab,
872                                                           svn_auth_gnome_keyring_unlock_prompt_func_t prompt_func,
873                                                           void *prompt_baton) {
874     svn_auth_set_parameter(ab, SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC,
875                            prompt_func);
876     svn_auth_set_parameter(ab, SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_BATON,
877                            prompt_baton);
878 }
879 %}
880 
881 #if defined(SWIGPERL) || defined(SWIGRUBY)
882 %include svn_md5_h.swg
883 #endif
884 
885 #ifdef SWIGPERL
886 /* The apr_file_t* 'in' typemap can't cope with struct members, and there
887    is no reason to change this one. */
888 %immutable svn_patch_t::patch_file;
889 
890 %include svn_diff_h.swg
891 %include svn_error_h.swg
892 
893 %{
894 #include "svn_private_config.h"
895 %}
896 %init %{
897   svn_swig_pl__bind_current_pool_fns(&core_get_current_pool,
898                                      &core_set_current_pool);
899 %}
900 #endif
901 
902 #ifdef SWIGPYTHON
903 
904 void svn_swig_py_set_application_pool(PyObject *py_pool, apr_pool_t *pool);
905 void svn_swig_py_clear_application_pool();
906 
907 %init %{
908 /* Theoretically, we should be checking for errors here,
909    but I do not know of any useful way to signal an error to Python
910    from within a module initialization function. */
911 svn_swig_py_initialize();
912 %}
913 
914 /* Proxy classes for APR classes */
915 %include proxy_apr.swg
916 
917 #endif
918 
919 #ifdef SWIGRUBY
920 %init %{
921   svn_swig_rb_initialize();
922 
923   rb_define_const(mCore, "SVN_ALLOCATOR_MAX_FREE_UNLIMITED",
924                   UINT2NUM(APR_ALLOCATOR_MAX_FREE_UNLIMITED));
925 %}
926 
927 %header %{
928 static void apr_pool_wrapper_destroy(apr_pool_wrapper_t *self);
929 static void apr_pool_wrapper_destroy_children(apr_pool_wrapper_t *self);
930 static void apr_pool_wrapper_remove_from_parent(apr_pool_wrapper_t *self);
931 %}
932 
933 /* Dummy declaration */
934 struct apr_pool_wrapper_t
935 {
936 };
937 
938 /* Leave memory administration to ruby's GC */
939 %extend apr_pool_wrapper_t
940 {
destroy(VALUE object)941   static void destroy(VALUE object) {
942     svn_swig_rb_destroy_internal_pool(object);
943   }
944 
set_default_max_free_size(apr_size_t size)945   static void set_default_max_free_size(apr_size_t size) {
946     apr_allocator_max_free_set(svn_swig_rb_allocator(), size);
947   }
948 
apr_pool_wrapper_t(apr_pool_wrapper_t * parent)949   apr_pool_wrapper_t(apr_pool_wrapper_t *parent) {
950     apr_pool_wrapper_t *self;
951     apr_pool_t *parent_pool;
952 
953     self = ALLOC(apr_pool_wrapper_t);
954     if (parent) {
955       parent_pool = parent->pool;
956       APR_ARRAY_PUSH(parent->children, apr_pool_wrapper_t *) = self;
957     } else {
958       parent_pool = svn_swig_rb_pool();
959     }
960     self->pool = svn_pool_create_ex(parent_pool, NULL);
961     self->destroyed = FALSE;
962     self->parent = parent;
963     self->children = apr_array_make(self->pool, 0,
964                                     sizeof(apr_pool_wrapper_t *));
965     return self;
966   }
967 
~apr_pool_wrapper_t()968   ~apr_pool_wrapper_t() {
969     apr_pool_wrapper_destroy(self);
970     xfree(self);
971   }
972 
set_max_free_size(apr_size_t size)973   void set_max_free_size(apr_size_t size) {
974     apr_allocator_t *allocator;
975 
976     allocator = apr_pool_allocator_get(self->pool);
977     apr_allocator_max_free_set(allocator, size);
978   }
979 
_destroy(void)980   void _destroy(void) {
981     apr_pool_wrapper_destroy(self);
982   }
983 };
984 
985 %ignore apr_pool_wrapper_destroy;
986 %ignore apr_pool_wrapper_destroy_children;
987 %ignore apr_pool_wrapper_remove_from_parent;
988 %inline %{
989 static void
apr_pool_wrapper_destroy(apr_pool_wrapper_t * self)990 apr_pool_wrapper_destroy(apr_pool_wrapper_t *self)
991 {
992   if (!self->destroyed) {
993     self->destroyed = TRUE;
994     apr_pool_wrapper_destroy_children(self);
995     apr_pool_wrapper_remove_from_parent(self);
996     apr_pool_destroy(self->pool);
997   }
998 }
999 
1000 static void
apr_pool_wrapper_destroy_children(apr_pool_wrapper_t * self)1001 apr_pool_wrapper_destroy_children(apr_pool_wrapper_t *self)
1002 {
1003   apr_pool_wrapper_t **child;
1004 
1005   while ((child = apr_array_pop(self->children))) {
1006     if (*child) {
1007       apr_pool_wrapper_destroy(*child);
1008     }
1009   }
1010 }
1011 
1012 static void
apr_pool_wrapper_remove_from_parent(apr_pool_wrapper_t * self)1013 apr_pool_wrapper_remove_from_parent(apr_pool_wrapper_t *self)
1014 {
1015   if (self->parent) {
1016     apr_pool_wrapper_t *child;
1017     int i, len;
1018 
1019     len = self->parent->children->nelts;
1020     for (i = 0; i < len; i++) {
1021       child = APR_ARRAY_IDX(self->parent->children, i, apr_pool_wrapper_t *);
1022       if (child == self) {
1023         APR_ARRAY_IDX(self->parent->children, i, apr_pool_wrapper_t *) = NULL;
1024         self->parent = NULL;
1025         break;
1026       }
1027     }
1028   }
1029 }
1030 %}
1031 
1032 /* Dummy declaration */
1033 struct svn_stream_t
1034 {
1035 };
1036 
1037 %extend svn_stream_t
1038 {
svn_stream_t(VALUE io)1039   svn_stream_t(VALUE io) {
1040     return svn_swig_rb_make_stream(io);
1041   };
1042 
~svn_stream_t()1043   ~svn_stream_t() {
1044   };
1045 }
1046 
1047 /* Dummy declaration */
1048 struct svn_auth_baton_t
1049 {
1050 };
1051 
1052 %extend svn_auth_baton_t
1053 {
svn_auth_baton_t(apr_array_header_t * providers,apr_pool_t * pool)1054   svn_auth_baton_t(apr_array_header_t *providers, apr_pool_t *pool) {
1055     svn_auth_baton_t *self;
1056     svn_auth_open(&self, providers, pool);
1057     return self;
1058   };
1059 
~svn_auth_baton_t()1060   ~svn_auth_baton_t() {
1061   };
1062 }
1063 
1064 %extend svn_diff_file_options_t
1065 {
svn_diff_file_options_t(apr_pool_t * pool)1066   svn_diff_file_options_t(apr_pool_t *pool) {
1067     return svn_diff_file_options_create(pool);
1068   };
1069 
~svn_diff_file_options_t()1070   ~svn_diff_file_options_t() {
1071   };
1072 }
1073 
1074 %extend svn_commit_info_t
1075 {
svn_commit_info_t(apr_pool_t * pool)1076   svn_commit_info_t(apr_pool_t *pool) {
1077     return svn_create_commit_info(pool);
1078   };
1079 
~svn_commit_info_t()1080   ~svn_commit_info_t() {
1081   };
1082 
dup(apr_pool_t * pool)1083   svn_commit_info_t *dup(apr_pool_t *pool) {
1084     return svn_commit_info_dup(self, pool);
1085   };
1086 }
1087 
1088 %extend svn_merge_range_t
1089 {
svn_merge_range_t(svn_revnum_t start,svn_revnum_t end,svn_boolean_t inheritable,apr_pool_t * pool)1090   svn_merge_range_t(svn_revnum_t start, svn_revnum_t end,
1091                     svn_boolean_t inheritable, apr_pool_t *pool) {
1092     svn_merge_range_t *self;
1093     self = apr_palloc(pool, sizeof(svn_merge_range_t));
1094     self->start = start;
1095     self->end = end;
1096     self->inheritable = inheritable;
1097     return self;
1098   };
1099 
~svn_merge_range_t()1100   ~svn_merge_range_t() {
1101   };
1102 
dup(apr_pool_t * pool)1103   svn_merge_range_t *dup(apr_pool_t *pool) {
1104     return svn_merge_range_dup(self, pool);
1105   };
1106 }
1107 
1108 %include svn_diff_h.swg
1109 
1110 %inline %{
1111 static VALUE
svn_default_charset(void)1112 svn_default_charset(void)
1113 {
1114   return PTR2NUM(APR_DEFAULT_CHARSET);
1115 }
1116 
1117 static VALUE
svn_locale_charset(void)1118 svn_locale_charset(void)
1119 {
1120   return PTR2NUM(APR_LOCALE_CHARSET);
1121 }
1122 
1123 /* prompt providers return baton for protecting GC */
1124 static VALUE
svn_swig_rb_auth_get_simple_prompt_provider(svn_auth_provider_object_t ** provider,svn_auth_simple_prompt_func_t prompt_func,void * prompt_baton,int retry_limit,apr_pool_t * pool)1125 svn_swig_rb_auth_get_simple_prompt_provider(
1126   svn_auth_provider_object_t **provider,
1127   svn_auth_simple_prompt_func_t prompt_func,
1128   void *prompt_baton,
1129   int retry_limit,
1130   apr_pool_t *pool)
1131 {
1132   svn_auth_get_simple_prompt_provider(provider, prompt_func, prompt_baton,
1133                                       retry_limit, pool);
1134   return rb_ary_new3(1, (VALUE)prompt_baton);
1135 }
1136 
1137 static VALUE
svn_swig_rb_auth_get_ssl_client_cert_prompt_provider(svn_auth_provider_object_t ** provider,svn_auth_ssl_client_cert_prompt_func_t prompt_func,void * prompt_baton,int retry_limit,apr_pool_t * pool)1138 svn_swig_rb_auth_get_ssl_client_cert_prompt_provider(
1139   svn_auth_provider_object_t **provider,
1140   svn_auth_ssl_client_cert_prompt_func_t prompt_func,
1141   void *prompt_baton,
1142   int retry_limit,
1143   apr_pool_t *pool)
1144 {
1145   svn_auth_get_ssl_client_cert_prompt_provider(provider, prompt_func,
1146                                                prompt_baton, retry_limit,
1147                                                pool);
1148   return rb_ary_new3(1, (VALUE)prompt_baton);
1149 }
1150 
1151 static VALUE
svn_swig_rb_auth_get_ssl_client_cert_pw_prompt_provider(svn_auth_provider_object_t ** provider,svn_auth_ssl_client_cert_pw_prompt_func_t prompt_func,void * prompt_baton,int retry_limit,apr_pool_t * pool)1152 svn_swig_rb_auth_get_ssl_client_cert_pw_prompt_provider(
1153   svn_auth_provider_object_t **provider,
1154   svn_auth_ssl_client_cert_pw_prompt_func_t prompt_func,
1155   void *prompt_baton,
1156   int retry_limit,
1157   apr_pool_t *pool)
1158 {
1159   svn_auth_get_ssl_client_cert_pw_prompt_provider(provider, prompt_func,
1160                                                   prompt_baton, retry_limit,
1161                                                   pool);
1162   return rb_ary_new3(1, (VALUE)prompt_baton);
1163 }
1164 
1165 static VALUE
svn_swig_rb_auth_get_ssl_server_trust_prompt_provider(svn_auth_provider_object_t ** provider,svn_auth_ssl_server_trust_prompt_func_t prompt_func,void * prompt_baton,apr_pool_t * pool)1166 svn_swig_rb_auth_get_ssl_server_trust_prompt_provider(
1167   svn_auth_provider_object_t **provider,
1168   svn_auth_ssl_server_trust_prompt_func_t prompt_func,
1169   void *prompt_baton,
1170   apr_pool_t *pool)
1171 {
1172   svn_auth_get_ssl_server_trust_prompt_provider(provider, prompt_func,
1173                                                 prompt_baton, pool);
1174   return rb_ary_new3(1, (VALUE)prompt_baton);
1175 }
1176 
1177 static VALUE
svn_swig_rb_auth_get_username_prompt_provider(svn_auth_provider_object_t ** provider,svn_auth_username_prompt_func_t prompt_func,void * prompt_baton,int retry_limit,apr_pool_t * pool)1178 svn_swig_rb_auth_get_username_prompt_provider(
1179   svn_auth_provider_object_t **provider,
1180   svn_auth_username_prompt_func_t prompt_func,
1181   void *prompt_baton,
1182   int retry_limit,
1183   apr_pool_t *pool)
1184 {
1185   svn_auth_get_username_prompt_provider(provider, prompt_func, prompt_baton,
1186                                         retry_limit, pool);
1187   return rb_ary_new3(1, (VALUE)prompt_baton);
1188 }
1189 %}
1190 #endif
1191 
1192 #if defined(SWIGPYTHON) || defined(SWIGRUBY)
1193 %inline %{
1194 static svn_error_t *
svn_swig_mergeinfo_merge(apr_hash_t ** mergeinfo_inout,apr_hash_t * changes,apr_pool_t * pool)1195 svn_swig_mergeinfo_merge(apr_hash_t **mergeinfo_inout,
1196                          apr_hash_t *changes,
1197                          apr_pool_t *pool)
1198 {
1199   return svn_mergeinfo_merge(*mergeinfo_inout, changes, pool);
1200 }
1201 
1202 static svn_error_t *
svn_swig_mergeinfo_sort(apr_hash_t ** mergeinfo_inout,apr_pool_t * pool)1203 svn_swig_mergeinfo_sort(apr_hash_t **mergeinfo_inout, apr_pool_t *pool)
1204 {
1205   return svn_mergeinfo_sort(*mergeinfo_inout, pool);
1206 }
1207 
1208 static svn_error_t *
svn_swig_rangelist_merge(svn_rangelist_t ** rangelist_inout,svn_rangelist_t * changes,apr_pool_t * pool)1209 svn_swig_rangelist_merge(svn_rangelist_t **rangelist_inout,
1210                          svn_rangelist_t *changes,
1211                          apr_pool_t *pool)
1212 {
1213   return svn_rangelist_merge(rangelist_inout, changes, pool);
1214 }
1215 
1216 static svn_error_t *
svn_swig_rangelist_reverse(svn_rangelist_t ** rangelist_inout,apr_pool_t * pool)1217 svn_swig_rangelist_reverse(svn_rangelist_t **rangelist_inout,
1218                            apr_pool_t *pool)
1219 {
1220   return svn_rangelist_reverse(*rangelist_inout, pool);
1221 }
1222 %}
1223 #endif
1224