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 * svn_types.swg: This is the main file of the Subversion typemap 22 * library. Certain categories of typemaps are removed into child 23 * files that are then %included into this one, solely to promote 24 * code comprehensibility by grouping related parts. 25 */ 26 27%include apr.swg 28%include svn_string.swg 29%include svn_containers.swg 30 31/* ----------------------------------------------------------------------- 32 Generic handling for "type **" parameters. Almost all such parameters 33 are OUTPUT parameters. Handling is as follows: 34 - "in" typemap which allocates storage for a pointer, and points the 35 argument to that storage. 36 - Default "argout" typemap which complains at compile time, and raises 37 an exception at runtime. 38 - OUTPARAM "argout" typemap which wraps (SWIG_NewPointerObj) a C 39 pointer for return to the scripting language. 40 - Application of the OUTPARAM typemap to those types for which it makes 41 sense (key examples for which it does not are strings, arrays, and 42 hashes - which need to be turned into their scripting language 43 equivalent). 44 Known instances of "type **" which are *not* OUTPUT parameters are: 45 - svn_stream_checksummed(..., const unsigned char **read_digest, 46 const unsigned char **write_digest, ...) 47 - svn_*_change_rev_prop2(..., const svn_string_t *const *old_value_p, ...) 48*/ 49%typemap(in, numinputs=0) SWIGTYPE ** ($*1_ltype temp) "$1 = &temp;"; 50 51/* We have a long standing bug where svn_client_commit_info_t and 52 svn_commit_info_t output parameters are not properly initialized to NULL 53 when there is nothing to commit. This is a workaround. Yes, it is 54 unspeakably evil that this was not just fixed at source when it was 55 discovered initially. */ 56%typemap(in, numinputs=0) BAD_OUTPUT_INIT_HACK ** ($*1_ltype temp = NULL) 57 "$1 = &temp;"; 58%apply BAD_OUTPUT_INIT_HACK ** { 59 svn_commit_info_t **, 60 svn_client_commit_info_t ** 61}; 62 63%typemap(argout,warning="900:FIXME: Missing argout typemap") SWIGTYPE ** { 64 /* FIXME: Missing argout typemap: $symname arg $argnum ($1_type) */ 65#if defined(SWIGRUBY) && SWIG_VERSION <= 0x010329 66 /* Ruby fails to define $symname. */ 67 SWIG_exception(SWIG_ValueError, "Function is not implemented yet"); 68#else 69 SWIG_exception(SWIG_ValueError, "$symname is not implemented yet"); 70#endif 71} 72 73%typemap(in,warning="901:FIXME: Missing old_value_p typemap") const svn_string_t *const *old_value_p { 74#if defined(SWIGRUBY) && SWIG_VERSION <= 0x010329 75 /* Ruby fails to define $symname. */ 76 SWIG_exception(SWIG_ValueError, "Function is not implemented yet"); 77#else 78 SWIG_exception(SWIG_ValueError, "$symname is not implemented yet"); 79#endif 80} 81 82#ifdef SWIGPYTHON 83%typemap(argout) SWIGTYPE **OUTPARAM { 84 %append_output(svn_swig_py_new_pointer_obj(*$1, $*1_descriptor, 85 _global_py_pool, args)); 86} 87#else 88%typemap(argout) SWIGTYPE **OUTPARAM { 89 %append_output(SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); 90} 91#endif 92 93%apply SWIGTYPE **OUTPARAM { 94 /* apr */ 95 apr_file_t **, 96 apr_hash_t **, 97 /* svn_types.h */ 98 svn_commit_info_t **, 99 svn_dirent_t **, 100 svn_lock_t **, 101 svn_stream_t **, 102 svn_commit_callback2_t *, 103 void **callback2_baton, 104 /* core */ 105 svn_auth_baton_t **, 106 svn_auth_cred_simple_t **cred, 107 svn_auth_cred_username_t **cred, 108 svn_auth_cred_ssl_client_cert_pw_t **cred, 109 svn_auth_cred_ssl_client_cert_t **cred, 110 svn_auth_cred_ssl_server_trust_t **cred, 111 svn_auth_iterstate_t **, 112 svn_auth_provider_object_t **, 113 svn_config_t **, 114 svn_diff_t **, 115 svn_patch_file_t **, 116 svn_patch_t **, 117 void **credentials, 118 void **iter_baton, 119 void **token, 120 /* svn_checksum */ 121 svn_checksum_t **, 122 /* svn_client */ 123 svn_client_commit_info_t **, 124 svn_client_conflict_t **, 125 svn_client_conflict_option_t **, 126 svn_client_ctx_t **, 127 const svn_client_commit_item3_t **, 128 svn_client__shelf_t **, 129 svn_client__shelf_version_t **, 130 /* svn_delta */ 131 const svn_delta_editor_t **, 132 svn_txdelta_stream_t **, 133 svn_txdelta_window_t **, 134#ifndef SWIGPYTHON 135 /* Python wraps this as a CALLABLE_CALLBACK instead */ 136 svn_txdelta_window_handler_t *, 137#endif 138 void **handler_baton, 139 void **handler2_baton, 140 void **root_baton, 141 void **child_baton, 142 void **file_baton, 143 void **edit_baton, 144 void **dir_baton, 145 /* svn_fs */ 146 svn_fs_t **, 147 svn_fs_access_t **, 148 svn_fs_history_t **, 149 svn_fs_id_t **, 150 svn_fs_root_t **, 151 svn_fs_txn_t **, 152 void **contents_baton_p, 153 /* svn_io */ 154 svn_io_dirent2_t **, 155 svn_stream_mark_t **, 156 /* svn_ra */ 157 svn_ra_callbacks2_t **, 158 svn_ra_plugin_t **, 159 const svn_ra_reporter_t **, 160 const svn_ra_reporter2_t **, 161 const svn_ra_reporter3_t **, 162 svn_ra_session_t **, 163 void **delta_baton, 164 void **report_baton, 165 void **ra_baton, 166 void **session_baton, 167 /* svn_repos */ 168 svn_authz_t **, 169 svn_repos_t **, 170 const svn_repos_parse_fns3_t **, 171 const svn_repos_parser_fns2_t **, 172 const svn_repos_parser_fns_t **, 173 void **parse_baton, 174 void **revision_baton, 175 void **node_baton, 176 /* svn_wc */ 177 svn_wc_adm_access_t **, 178 svn_wc_external_item2_t **, 179 svn_wc_entry_t **, 180 svn_wc_revision_status_t **, 181 svn_wc_status_t **, 182 svn_wc_status2_t **, 183 svn_wc_committed_queue_t **, 184#ifdef SWIGRUBY 185 /* Only tested for Ruby */ 186 svn_wc_context_t **, 187#endif 188 void **set_locks_baton 189}; 190 191#ifdef SWIGRUBY 192%typemap(argout) SWIGTYPE **OUTPARAM_WITH_BLOCK { 193 VALUE tmp; 194 tmp = SWIG_NewPointerObj(*$1, $*1_descriptor, 0); 195 if (rb_block_given_p()) { 196 rb_yield(tmp); 197 svn_swig_rb_destroy_pool(_global_svn_swig_rb_pool); 198 DATA_PTR(tmp) = NULL; 199 } else { 200 %append_output(tmp); 201 } 202} 203 204%apply SWIGTYPE **OUTPARAM_WITH_BLOCK { 205 /* svn_fs */ 206 svn_fs_t **, 207 /* svn_repos */ 208 svn_repos_t ** 209}; 210#endif 211 212 213/* ----------------------------------------------------------------------- 214 Check whether fs/repos was closed or not. 215*/ 216#ifdef SWIGRUBY 217%define %raise_if_null(TYPE) 218%typemap(check) svn_ ## TYPE ## _t * 219{ 220 if (!$1) { 221 svn_swig_rb_raise_svn_ ## TYPE ## _already_close(); 222 } 223} 224%enddef 225 226%raise_if_null(fs); 227%raise_if_null(repos); 228 229%define %define_close_related_methods(TYPE) 230%ignore svn_ ## TYPE ## _swig_rb_close; 231%ignore svn_ ## TYPE ## _swig_rb_closed; 232 233%inline %{ 234static VALUE 235svn_ ## TYPE ## _swig_rb_close(VALUE self) 236{ 237 if (!DATA_PTR(self)) { 238 svn_swig_rb_raise_svn_ ## TYPE ## _already_close(); 239 } 240 241 svn_swig_rb_destroy_internal_pool(self); 242 DATA_PTR(self) = NULL; 243 244 return Qnil; 245} 246 247static VALUE 248svn_ ## TYPE ## _swig_rb_closed(VALUE self) 249{ 250 return DATA_PTR(self) ? Qfalse : Qtrue; 251} 252%} 253 254%init %{ 255 { 256 VALUE cSvn ## TYPE; 257 cSvn ## TYPE = rb_const_get(_mSWIG, rb_intern("TYPE_p_svn_" #TYPE "_t")); 258 rb_define_method(cSvn ## TYPE, "close", 259 svn_ ## TYPE ## _swig_rb_close, 0); 260 rb_define_method(cSvn ## TYPE, "closed?", 261 svn_ ## TYPE ## _swig_rb_closed, 0); 262 } 263%} 264%enddef 265#endif 266 267/* ----------------------------------------------------------------------- 268 %apply-ing of typemaps 269*/ 270 271%apply int *OUTPUT { 272 int *, 273 svn_boolean_t *, 274 enum svn_wc_merge_outcome_t * 275}; 276%apply long *OUTPUT { svn_revnum_t *, svn_node_kind_t * }; 277%apply long long *OUTPUT { svn_filesize_t * } 278 279/* ----------------------------------------------------------------------- 280 Generic macros for callback typemaps 281*/ 282 283#ifdef SWIGPYTHON 284%define %callback_typemap(CallbackFunction, CallbackBaton, 285 PythonThunk, PerlThunk, RubyThunk) 286%typemap(in) (CallbackFunction, CallbackBaton) { 287 $1 = ($1_ltype) PythonThunk; 288 $2 = $input; 289} 290%enddef 291%define %callback_typemap_maybenull(CallbackFunction, CallbackBaton, 292 PythonThunk, PerlThunk, RubyThunk) 293%typemap(in) (CallbackFunction, CallbackBaton) { 294 /* FIXME: Handle the NULL case. */ 295 $1 = ($1_ltype) PythonThunk; 296 $2 = $input; 297} 298%enddef 299#endif 300 301#ifdef SWIGPERL 302%define %callback_typemap(CallbackFunction, CallbackBaton, 303 PythonThunk, PerlThunk, RubyThunk) 304%typemap(in) (CallbackFunction, CallbackBaton) { 305 $1 = ($1_ltype) PerlThunk; 306 $2 = $input; 307} 308%enddef 309%define %callback_typemap_maybenull(CallbackFunction, CallbackBaton, 310 PythonThunk, PerlThunk, RubyThunk) 311%typemap(in) (CallbackFunction, CallbackBaton) { 312 if (SvOK($input)) { 313 $1 = ($1_ltype) PerlThunk; 314 $2 = $input; 315 } else { 316 $1 = ($1_ltype) NULL; 317 $2 = NULL; 318 } 319} 320%enddef 321#endif 322 323#ifdef SWIGRUBY 324%define %callback_typemap(CallbackFunction, CallbackBaton, 325 PythonThunk, PerlThunk, RubyThunk) 326%typemap(in) (CallbackFunction, CallbackBaton) { 327 $1 = ($1_ltype) RubyThunk; 328 $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); 329} 330%enddef 331%define %callback_typemap_maybenull(CallbackFunction, CallbackBaton, 332 PythonThunk, PerlThunk, RubyThunk) 333%typemap(in) (CallbackFunction, CallbackBaton) { 334 if (NIL_P($input)) { 335 $1 = ($1_ltype) NULL; 336 $2 = NULL; 337 } else { 338 $1 = ($1_ltype) RubyThunk; 339 $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); 340 } 341} 342%enddef 343#endif 344 345/* ----------------------------------------------------------------------- 346 Create a typemap for specifying string args that may be NULL. 347*/ 348#ifdef SWIGPYTHON 349%typemap(in) const char *MAY_BE_NULL 350{ 351 $1 = svn_swig_py_string_to_cstring($input, TRUE, "$symname", "$1_name"); 352 if (PyErr_Occurred()) SWIG_fail; 353} 354#endif 355 356#ifdef SWIGPERL 357%apply const char * { const char *MAY_BE_NULL }; 358#endif 359 360#ifdef SWIGRUBY 361%typemap(in) const char *MAY_BE_NULL 362{ 363 if (NIL_P($input)) { 364 $1 = NULL; 365 } else { 366 $1 = StringValuePtr($input); 367 } 368} 369 370%typemap(in) const char *NOT_NULL 371{ 372 $1 = StringValueCStr($input); 373} 374 375%typemap(out) const char * 376{ 377 if ($1) { 378 $result = rb_str_new2($1); 379 } else { 380 $result = Qnil; 381 } 382} 383#endif 384 385/* ----------------------------------------------------------------------- 386 const char *header_encoding 387 svn_diff_file_output_unified2 388 svn_client_diff3 389*/ 390#ifdef SWIGRUBY 391%typemap(in) const char *header_encoding 392{ 393 $1 = NULL; 394 395 if (NIL_P($input)) { 396 } else if (TYPE($input) == T_FIXNUM) { 397 $1 = (char *)NUM2INT($input); 398 if (!($1 == APR_LOCALE_CHARSET || $1 == APR_DEFAULT_CHARSET)) { 399 $1 = NULL; 400 } 401 } else { 402 $1 = StringValuePtr($input); 403 } 404 405 if (!$1) { 406 $1 = (char *)APR_LOCALE_CHARSET; 407 } 408} 409#endif 410 411/* ----------------------------------------------------------------------- 412 Define a more refined 'memberin' typemap for 'const char *' members. This 413 is used in place of the 'char *' handler defined automatically. 414 415 We need to do the free/malloc/strcpy special because of the const 416*/ 417%typemap(memberin) const char * { 418 apr_size_t len = strlen($input) + 1; 419 char *copied; 420 if ($1) free((char *)$1); 421 copied = malloc(len); 422 memcpy(copied, $input, len); 423 $1 = copied; 424} 425 426/* ----------------------------------------------------------------------- 427 Specify how svn_error_t returns are turned into exceptions. 428*/ 429#ifdef SWIGPYTHON 430%typemap(out) svn_error_t * { 431 if ($1 != NULL) { 432 if ($1->apr_err != SVN_ERR_SWIG_PY_EXCEPTION_SET) 433 svn_swig_py_svn_exception($1); 434 else 435 svn_error_clear($1); 436 SWIG_fail; 437 } 438 Py_INCREF(Py_None); 439 $result = Py_None; 440} 441#endif 442 443#ifdef SWIGPERL 444%typemap(out) svn_error_t * { 445 if ($1) { 446 SV *exception_handler = perl_get_sv ("SVN::Error::handler", FALSE); 447 448 if (SvOK(exception_handler)) { 449 SV *callback_result; 450 451 PUTBACK; 452 svn_swig_pl_callback_thunk (CALL_SV, exception_handler, 453 &callback_result, "S", $1, 454 $1_descriptor); 455 SPAGAIN; 456 } else { 457 $result = SWIG_NewPointerObj($1, $1_descriptor, 0); 458 argvi++; 459 } 460 } 461} 462#endif 463 464#ifdef SWIGRUBY 465%typemap(out) svn_error_t * 466{ 467 if ($1) { 468 svn_swig_rb_destroy_pool(_global_svn_swig_rb_pool); 469 svn_swig_rb_pop_pool(_global_svn_swig_rb_pool); 470 svn_swig_rb_handle_svn_error($1); 471 } 472 $result = Qnil; 473} 474#endif 475 476/* ----------------------------------------------------------------------- 477 Define a general ptr/len typemap. This takes a single script argument 478 and expands it into a ptr/len pair for the native call. 479*/ 480#ifdef SWIGPYTHON 481%typemap(in) (const char *PTR, apr_size_t LEN) { 482 Py_ssize_t pyStrLen; 483 if (!PyBytes_Check($input)) { 484 PyErr_SetString(PyExc_TypeError, "expecting a bytes"); 485 SWIG_fail; 486 } 487 if (PyBytes_AsStringAndSize($input, &$1, &pyStrLen) == -1) { 488 SWIG_fail; 489 } 490 $2 = pyStrLen; 491} 492#endif 493 494#ifdef SWIGPERL 495%typemap(in) (const char *PTR, apr_size_t LEN) { 496 if (SvPOK($input)) { 497 $1 = SvPV($input, $2); 498 } else { 499 /* set to 0 to avoid warning */ 500 $1 = 0; 501 $2 = 0; 502 SWIG_croak("Expecting a string"); 503 } 504} 505#endif 506 507#ifdef SWIGRUBY 508%typemap(in) (const char *PTR, apr_size_t LEN) 509{ 510 if (!RTEST(rb_obj_is_kind_of($input, rb_cString))) { 511 rb_raise(rb_eArgError, "Expecting a string"); 512 } 513 $1 = StringValuePtr($input); 514 $2 = RSTRING_LEN(StringValue($input)); 515} 516#endif 517 518%apply (const char *PTR, apr_size_t LEN) { 519 (const char *data, apr_size_t len) 520} 521 522/* ----------------------------------------------------------------------- 523 Handle retrieving the error message from svn_strerror 524*/ 525 526#ifdef SWIGPERL 527%typemap(in,numinputs=0) (char *buf, apr_size_t bufsize) ( char temp[128] ) { 528 memset (temp,0,128); /* paranoia */ 529 $1 = temp; 530 $2 = 128; 531} 532#endif 533 534/* ----------------------------------------------------------------------- 535 Define a generic arginit mapping for pools. 536*/ 537 538#ifdef SWIGPYTHON 539 540%typemap(in) POINTER_TYPES 541{ 542 $1 = ($1_ltype)svn_swig_py_must_get_ptr($input, $descriptor, $svn_argnum); 543 if (PyErr_Occurred()) { 544 SWIG_fail; 545 } 546} 547 548%typemap(out) POINTER_TYPES 549 "$result = svn_swig_py_new_pointer_obj((void*)($1), $descriptor, 550 _global_py_pool, args);"; 551 552%apply POINTER_TYPES { void *, SWIGTYPE *, SWIGTYPE [] }; 553 554%typemap(default, noblock=1) apr_pool_t 555 *(apr_pool_t *_global_pool = NULL, PyObject *_global_py_pool = NULL) 556{ 557 if (svn_swig_py_get_pool_arg(args, $descriptor, 558 &_global_py_pool, &_global_pool)) 559 SWIG_fail; 560 $1 = _global_pool; 561} 562 563%typemap(in, noblock=1) apr_pool_t * { 564 /* Verify that the user supplied a valid pool */ 565 if ($input != Py_None && $input != _global_py_pool) { 566 SWIG_Python_TypeError(SWIG_TypePrettyName($descriptor), $input); 567 SWIG_arg_fail($svn_argnum); 568 SWIG_fail; 569 } 570} 571 572%typemap(freearg) apr_pool_t * { 573 Py_XDECREF(_global_py_pool); 574} 575#endif 576 577#ifdef SWIGPERL 578%typemap(in) apr_pool_t *pool ""; 579%typemap(default) apr_pool_t *pool(apr_pool_t *_global_pool) { 580 _global_pool = $1 = svn_swig_pl_make_pool (ST(items-1)); 581 SPAGAIN; 582} 583#endif 584#ifdef SWIGRUBY 585%typemap(in) apr_pool_t *pool ""; 586%typemap(default) apr_pool_t *pool 587 (VALUE _global_svn_swig_rb_pool, apr_pool_t *_global_pool) 588{ 589 svn_swig_rb_get_pool(argc, argv, self, &_global_svn_swig_rb_pool, &$1); 590 _global_pool = $1; 591 svn_swig_rb_push_pool(_global_svn_swig_rb_pool); 592} 593 594%typemap(default) (svn_client_ctx_t *ctx, apr_pool_t *pool) 595 (VALUE _global_svn_swig_rb_pool, apr_pool_t *_global_pool) 596{ 597 int adjusted_argc = argc; 598 VALUE *adjusted_argv = argv; 599 600 svn_swig_rb_adjust_arg_for_client_ctx_and_pool(&adjusted_argc, 601 &adjusted_argv); 602 svn_swig_rb_get_pool(adjusted_argc, adjusted_argv, self, 603 &_global_svn_swig_rb_pool, &$2); 604 _global_pool = $2; 605 svn_swig_rb_push_pool(_global_svn_swig_rb_pool); 606} 607 608%typemap(freearg) apr_pool_t *pool 609{ 610 VALUE target; 611 target = _global_vresult_address == &vresult ? self : vresult; 612 if (!svn_swig_rb_set_pool(target, _global_svn_swig_rb_pool)) 613 svn_swig_rb_destroy_pool(_global_svn_swig_rb_pool); 614 svn_swig_rb_pop_pool(_global_svn_swig_rb_pool); 615} 616#endif 617 618#ifdef SWIGPERL 619%apply apr_pool_t *pool { 620 apr_pool_t *dir_pool, 621 apr_pool_t *file_pool, 622 apr_pool_t *node_pool, 623 apr_pool_t *result_pool, 624 apr_pool_t *scratch_pool 625}; 626#endif 627 628#ifdef SWIGRUBY 629%apply apr_pool_t *pool { 630 apr_pool_t *dir_pool, 631 apr_pool_t *file_pool, 632 apr_pool_t *node_pool, 633 apr_pool_t *result_pool, 634 apr_pool_t *scratch_pool 635}; 636#endif 637 638/* ----------------------------------------------------------------------- 639 * The CALLABLE_CALLBACK typemap wraps callback types as objects which 640 * can be called directly from Python. header_wrappers.py automatically 641 * tags all callback types (in Python) with this callback. 642 * 643 * header_wrappers.py also generates a '__call__' function for the 644 * callback objects, using the funcptr_proxy macro. See proxy.swg 645 */ 646 647#ifdef SWIGPYTHON 648 649/* Allocate memory for a pointer to the function pointer. */ 650%typemap(in, numinputs=0) CALLABLE_CALLBACK * 651 (apr_pool_t *_global_pool = NULL, PyObject *_global_py_pool = NULL) 652{ 653 if (_global_pool == NULL) 654 { 655 if (svn_swig_py_get_parent_pool(args, $descriptor(apr_pool_t *), 656 &_global_py_pool, &_global_pool)) 657 SWIG_fail; 658 } 659 $1 = ($ltype) apr_pcalloc(_global_pool, sizeof($*ltype)); 660 if ($1 == NULL) SWIG_fail; 661} 662 663 664/* Return a pointer to the function pointer. 665 * This level of indirection makes it easier for SWIG to treat 666 * this callback like an object (which can be extended using SWIG). 667 */ 668 669%typemap(argout) CALLABLE_CALLBACK * { 670 %append_output(svn_swig_py_new_pointer_obj($1, $descriptor, 671 _global_py_pool, args)); 672} 673 674/* Convert the pointer to a function pointer back into a regular 675 * function pointer 676 */ 677 678%typemap(in) CALLABLE_CALLBACK { 679 $<ype tmp = 680 svn_swig_py_must_get_ptr($input, $&descriptor, $svn_argnum); 681 if (tmp == NULL || PyErr_Occurred()) { 682 SWIG_fail; 683 } 684 $1 = *tmp; 685} 686 687/* Ensure that return values use a level of indirection. 688 * 689 * Allocate space on the heap for a pointer to the callback. 690 * The memory gets freed when the return value itself is 691 * freed. 692 */ 693 694%typemap(out) CALLABLE_CALLBACK { 695 PyObject *py_pool = NULL; 696 apr_pool_t *pool = NULL; 697 698 if (svn_swig_py_get_parent_pool(args, $descriptor(apr_pool_t *), 699 &py_pool, &pool)) 700 SWIG_fail; 701 if ($1 == NULL) { 702 $result = Py_None; 703 Py_INCREF($result); 704 } else { 705 $<ype tmp = apr_palloc(pool, sizeof($ltype)); 706 if (tmp == NULL) { 707 SWIG_fail; 708 } 709 *tmp = ($ltype) $1; 710 $result = svn_swig_py_new_pointer_obj(tmp, $&1_descriptor, 711 py_pool, args); 712 } 713} 714 715 716/* Ensure that constant callbacks use a level of indirection. 717 * 718 * Allocate space on the heap for a pointer to the callback. 719 * Since this constant is always in scope, we don't need to 720 * worry about ever freeing the memory. 721 */ 722 723%typemap(constcode) CALLABLE_CALLBACK { 724 725 $<ype tmp = malloc(sizeof($ltype)); 726 *tmp = ($ltype) $value; 727 728 %set_constant("$symname", 729 svn_swig_py_new_pointer_obj(tmp, $&descriptor, NULL, NULL) 730 ); 731 732} 733 734#endif 735 736/* ----------------------------------------------------------------------- 737 Callback: svn_log_message_receiver_t 738 svn_client_log() 739 svn_ra get_log() 740 svn_repos_get_logs() 741*/ 742 743%callback_typemap(svn_log_message_receiver_t receiver, void *receiver_baton, 744 svn_swig_py_log_receiver, 745 svn_swig_pl_thunk_log_receiver, 746 svn_swig_rb_log_receiver) 747 748/* ----------------------------------------------------------------------- 749 Callback: svn_log_entry_receiver_t 750 svn_client_log4() 751 svn_ra_get_log2() 752 svn_repos_get_logs4() 753*/ 754 755%callback_typemap(svn_log_entry_receiver_t receiver, void *receiver_baton, 756 svn_swig_py_log_entry_receiver, 757 svn_swig_pl_thunk_log_entry_receiver, 758 svn_swig_rb_log_entry_receiver) 759 760/* ----------------------------------------------------------------------- 761 Callback: svn_commit_callback_t 762 svn_ra get_commit_editor() 763 svn_repos_get_commit_editor() 764*/ 765 766#ifdef SWIGPERL 767%typemap(in) (svn_commit_callback_t callback, void *callback_baton) { 768 $1 = svn_swig_pl_thunk_commit_callback; 769 $2 = (void *)$input; 770 svn_swig_pl_hold_ref_in_pool (_global_pool, $input); 771}; 772#endif 773 774#ifdef SWIGRUBY 775%typemap(in) (svn_commit_callback_t callback, void *callback_baton) 776{ 777 $1 = svn_swig_rb_commit_callback; 778 $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); 779}; 780 781%typemap(argout) (svn_commit_callback_t callback, void *callback_baton) 782{ 783 svn_swig_rb_set_baton($result, (VALUE)$2); 784}; 785#endif 786 787#ifdef SWIGPYTHON 788%typemap(in) (svn_commit_callback_t callback, void *callback_baton) 789{ 790 $1 = svn_swig_py_commit_callback; 791 $2 = (void *)$input; 792} 793#endif 794 795/* ----------------------------------------------------------------------- 796 Callback: svn_commit_callback2_t 797 svn_ra get_commit_editor2() 798 svn_repos_get_commit_editor4() 799 svn_client_mkdir4() 800 svn_client_delete4() 801 svn_client_import4() 802 svn_client_commit5() 803 svn_client_copy6() 804 svn_client_move6() 805 svn_client_propset_remote() 806*/ 807 808#ifdef SWIGPERL 809%typemap(in) (svn_commit_callback2_t commit_callback, void *commit_baton) { 810 $1 = svn_swig_pl_thunk_commit_callback2; 811 $2 = (void *)$input; 812 svn_swig_pl_hold_ref_in_pool (_global_pool, $input); 813}; 814#endif 815 816#ifdef SWIGRUBY 817%typemap(in) (svn_commit_callback2_t commit_callback, void *commit_baton) 818{ 819 $1 = svn_swig_rb_commit_callback2; 820 $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); 821}; 822 823%typemap(argout) (svn_commit_callback2_t commit_callback, void *commit_baton) 824{ 825 svn_swig_rb_set_baton($result, (VALUE)$2); 826}; 827#endif 828 829#ifdef SWIGPYTHON 830%typemap(in) (svn_commit_callback2_t commit_callback, void *commit_baton) 831{ 832 $1 = svn_swig_py_commit_callback2; 833 $2 = (void *)$input; 834} 835#endif 836 837/* ----------------------------------------------------------------------- 838 Callback: svn_cancel_func_t 839*/ 840 841%callback_typemap(svn_cancel_func_t cancel_func, void *cancel_baton, 842 svn_swig_py_cancel_func, 843 svn_swig_pl_cancel_func, 844 svn_swig_rb_cancel_func) 845 846#ifdef SWIGRUBY 847%typemap(argout) (svn_cancel_func_t cancel_func, void *cancel_baton) 848{ 849 svn_swig_rb_set_baton($result, (VALUE)$2); 850}; 851#endif 852 853#ifdef SWIGRUBY 854%typemap(in) (svn_wc_conflict_resolver_func_t conflict_func, void *conflict_baton) 855{ 856 $1 = svn_swig_rb_conflict_resolver_func; 857 $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); 858} 859 860%typemap(argout) (svn_wc_conflict_resolver_func_t conflict_func, void *conflict_baton) 861{ 862 svn_swig_rb_set_baton($result, (VALUE)$2); 863}; 864#endif 865 866#ifdef SWIGRUBY 867%typemap(in) (svn_wc_get_file_t fetch_func, void *fetch_baton) 868{ 869 /* ### TODO(rb support fetch_fun): implement 870 $1 = svn_swig_rb_fetch_func; 871 $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); 872 */ 873 $1 = NULL; 874 $2 = NULL; 875} 876 877%typemap(argout) (svn_wc_get_file_t fetch_func, void *fetch_baton) 878{ 879 svn_swig_rb_set_baton($result, (VALUE)$2); 880}; 881#endif 882 883/* ----------------------------------------------------------------------- 884 Callback: svn_info_receiver_t 885*/ 886 887#ifdef SWIGPERL 888%typemap(in) (svn_info_receiver_t receiver, void *receiver_baton) 889{ 890 $1 = svn_swig_pl_info_receiver; 891 $2 = (void *)$input; 892} 893#endif 894 895#ifdef SWIGRUBY 896%typemap(in) (svn_info_receiver_t receiver, void *receiver_baton) 897{ 898 $1 = svn_swig_rb_info_receiver; 899 $2 = (void *)svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); 900} 901#endif 902 903/* ----------------------------------------------------------------------- 904 Callback: svn_repos_freeze_func_t 905*/ 906#ifdef SWIGPYTHON 907%typemap(in) (svn_repos_freeze_func_t freeze_func, void *freeze_baton) 908{ 909 $1 = svn_swig_py_repos_freeze_func; 910 $2 = (void *)$input; 911} 912#endif 913 914/* ----------------------------------------------------------------------- 915 Callback: svn_fs_freeze_func_t 916*/ 917#ifdef SWIGPYTHON 918%typemap(in) (svn_fs_freeze_func_t freeze_func, void *freeze_baton) 919{ 920 $1 = svn_swig_py_fs_freeze_func; 921 $2 = (void *)$input; 922} 923#endif 924 925/* ----------------------------------------------------------------------- 926 Callback: svn_proplist_receiver2_t 927*/ 928#ifdef SWIGPYTHON 929%typemap(in) (svn_proplist_receiver2_t receiver, void *receiver_baton) 930{ 931 $1 = svn_swig_py_proplist_receiver2; 932 $2 = (void *)$input; 933} 934#endif 935 936/* ----------------------------------------------------------------------- 937 Callback: svn_fs_warning_callback_t 938*/ 939 940#ifdef SWIGRUBY 941%typemap(in) (svn_fs_warning_callback_t warning, void *warning_baton) 942{ 943 VALUE baton = svn_swig_rb_make_baton($input, _global_svn_swig_rb_pool); 944 svn_swig_rb_fs_warning_callback_baton_register(baton, _global_pool); 945 $1 = svn_swig_rb_fs_warning_callback; 946 $2 = (void *)baton; 947} 948#endif 949#ifdef SWIGPERL 950%ignore svn_fs_set_warning_func; 951#endif 952#ifdef SWIGPYTHON 953%ignore svn_fs_set_warning_func; 954#endif 955 956/* ----------------------------------------------------------------------- 957 svn_stream_t interoperability with language native io handles 958*/ 959 960#ifdef SWIGPYTHON 961%typemap(in) svn_stream_t *WRAPPED_STREAM { 962 if ($input == Py_None) { 963 $1 = NULL; 964 } 965 else { 966 $1 = svn_swig_py_make_stream ($input, _global_pool); 967 if ($1 == NULL) { 968 SWIG_fail; 969 } 970 } 971} 972#endif 973 974#ifdef SWIGPERL 975%typemap(in) svn_stream_t * { 976 svn_swig_pl_make_stream (&$1, $input); 977 SPAGAIN; 978} 979 980%typemap(out) svn_stream_t * { 981 SV* tmp; 982 PUTBACK; 983 tmp = svn_swig_pl_from_stream ($1); 984 SPAGAIN; 985 $result = tmp; 986 argvi++; 987} 988 989%typemap(argout) svn_stream_t ** { 990 SV *tmp; 991 PUTBACK; 992 tmp = svn_swig_pl_from_stream(*$1); 993 SPAGAIN; 994 %append_output(tmp); 995} 996#endif 997 998#ifdef SWIGRUBY 999%typemap(in) svn_stream_t * { 1000 $1 = svn_swig_rb_make_stream($input); 1001} 1002 1003%typemap(in) svn_stream_t *MAY_BE_NULL { 1004 if (NIL_P($input)) { 1005 $1 = NULL; 1006 } else { 1007 $1 = svn_swig_rb_make_stream($input); 1008 } 1009} 1010#endif 1011 1012/* ----------------------------------------------------------------------- 1013 Mapper to automatically turn Python objects into void* batons on assignment 1014*/ 1015 1016#ifdef SWIGPYTHON 1017 1018%typemap(in) void *PY_AS_VOID { 1019 if ($input == Py_None) { 1020 $1 = NULL; 1021 } else if (SWIG_ConvertPtr($input, (void **) &$1, 0, 0) == -1) { 1022 $1 = (void *) $input; 1023 PyErr_Clear(); 1024 } 1025} 1026 1027 1028%typemap(out) void *PY_AS_VOID { 1029 PyObject *ownerObj = obj0; 1030 PyObject *members = PyObject_GetAttrString(ownerObj, "_members"); 1031 1032 $result = NULL; 1033 if (members != NULL) { 1034 $result = PyDict_GetItemString(members, "$1_name"); 1035 Py_XINCREF($result); 1036 Py_DECREF(members); 1037 } 1038 1039 if ($result == NULL) { 1040 if ($1 == NULL) { 1041 $result = Py_None; 1042 Py_INCREF($result); 1043 } else { 1044 /* We don't know the type of this reference, so we'll have to 1045 * treat it as an opaque void pointer. 1046 */ 1047 $result = svn_swig_py_new_pointer_obj($1, $descriptor, 1048 _global_py_pool, args); 1049 } 1050 } 1051 1052} 1053 1054#endif 1055 1056/* ----------------------------------------------------------------------- 1057 MD5 Digest Parameters: in the Subversion C API, there are: 1058 - 'char' digests, which are hexadecimal-encoded strings. 1059 - 'unsigned char' digests, which are raw blocks of bytes. 1060 This section of typemaps relates to the second variety. 1061 The number of subtly different forms in which these appear in our 1062 APIs is absolutely scary, and we desperately must introduce some sanity 1063 when we do Subversion 2.0. 1064 1065 Function Parameters (Category 1): 1066 1067 'unsigned char digest[]' 1068 'unsigned char *digest': 1069 1070 Output parameter in: svn_fs_file_md5_checksum(), svn_io_file_checksum(), 1071 svn_wc_transmit_text_deltas2() 1072 1073 *but* appears as an input parameter in svn_base64_from_md5() - 1074 practically, this means that svn_base64_from_md5 is in error, and 1075 should be using 'const unsigned char digest[]', but fortunately, we 1076 do not wrap the svn_base64_* APIs, so do not have to care here. 1077 1078 1079 (Category 2): 1080 1081 There is no category 2! 1082 1083 1084 Function Parameters (No typemaps): 1085 1086 'const unsigned char **read_digest' (also, 'write_digest'): 1087 These are *delayed* output parameters in svn_stream_checksummed(). 1088 Would be quite complex to wrap, so this function is %ignore-d in the 1089 svn_io.h cherrypicking section. 1090 1091 'unsigned char *result_digest' 1092 This parameter serves as a buffer for the digest results of 1093 svn_txdelta_apply. As you supply data to this function via 1094 the handler callback, this digest gets filled. Since 1095 filling of this buffer is delayed, it is quite difficult 1096 to wrap. 1097 1098 FIXME: Both Ruby and Perl have broken typemaps for result_digest. 1099 The Python bindings ignore this parameter altogether. 1100 1101 Function Parameters (Category 3): 1102 1103 'const unsigned char digest[]' (also, 'd1', 'd2'): 1104 'const unsigned char *digest': 1105 Input parameters in: 1106 svn_md5_digest_to_cstring_display() 1107 svn_md5_digest_to_cstring() 1108 svn_md5_digests_match() 1109 1110 Function return values (Category 4): 1111 1112 'const unsigned char *' in svn_txdelta_md5_digest() 1113*/ 1114 1115/* Category 1 */ 1116 1117%typemap(in, numinputs=0) unsigned char digest[ANY] 1118 ($*1_type temp[APR_MD5_DIGESTSIZE]) "$1 = temp;"; 1119 1120#ifdef SWIGPYTHON 1121%typemap(argout) unsigned char digest[ANY] 1122{ 1123 %append_output(PyBytes_FromStringAndSize((const char *)$1, APR_MD5_DIGESTSIZE)); 1124} 1125#endif 1126 1127#ifdef SWIGPERL 1128%typemap(argout) unsigned char digest[ANY] { 1129 %append_output(sv_2mortal(newSVpv(svn_md5_digest_to_cstring($1, 1130 _global_pool), 1131 0))); 1132} 1133#endif 1134#ifdef SWIGRUBY 1135%typemap(argout) unsigned char digest[ANY] { 1136 char *digest_string = (char *)svn_md5_digest_to_cstring($1, _global_pool); 1137 %append_output(rb_str_new2(digest_string ? digest_string : "")); 1138} 1139#endif 1140 1141%apply unsigned char digest[ANY] { unsigned char *digest }; 1142 1143#ifdef SWIGRUBY 1144/* 1145 * Skip the md5sum 1146 * FIXME: Wrap the md5sum 1147 */ 1148%typemap(in, numinputs=0) unsigned char *result_digest 1149 "$1 = NULL;"; 1150#endif 1151 1152#ifdef SWIGPYTHON 1153/* 1154 * Skip the md5sum 1155 * FIXME: Wrap the md5sum 1156 */ 1157%typemap(in, numinputs=0) unsigned char *result_digest 1158 ($*1_type temp[APR_MD5_DIGESTSIZE]) "$1 = NULL;"; 1159#endif 1160 1161#ifdef SWIGPERL 1162%typemap(in, numinputs=0) unsigned char *result_digest { 1163 $1 = (unsigned char *)apr_palloc(_global_pool, APR_MD5_DIGESTSIZE); 1164} 1165 1166%typemap(argout) unsigned char *result_digest { 1167 SV *tmp; 1168 PUTBACK; 1169 tmp = svn_swig_pl_from_md5($1); 1170 SPAGAIN; 1171 %append_output(tmp); 1172} 1173#endif 1174 1175/* Category 3 */ 1176 1177/* Override the non-const typemaps defined for category 1, which would 1178 otherwise apply by default, and contribute nonsensical wrappings. */ 1179%typemap(in) const unsigned char digest[], const unsigned char *digest ""; 1180%typemap(argout) const unsigned char digest[], const unsigned char *digest ""; 1181 1182/* FIXME: There is a lot of coverage missing here */ 1183 1184#ifdef SWIGPERL 1185%typemap(in) const unsigned char digest[] { 1186 SWIG_ConvertPtr($input, (void **)&$1, $1_descriptor, 0); 1187} 1188#endif 1189 1190#ifdef SWIGPYTHON 1191/* ### Verify if this should use '[]' like perl and ruby */ 1192%typemap(in) const unsigned char *digest { 1193 if ($input == Py_None) { 1194 $1 = NULL; 1195 } else { 1196 $1 = (unsigned char *) PyBytes_AsString($input); 1197 if ($1 == NULL) SWIG_fail; 1198 } 1199} 1200#endif 1201 1202#ifdef SWIGRUBY 1203%typemap(in) const unsigned char digest[] 1204{ 1205 if (NIL_P($input)) { 1206 $1 = NULL; 1207 } else if (RSTRING_LEN($input) != APR_MD5_DIGESTSIZE) { 1208 rb_raise(rb_eArgError, "digest size (%d) must be %d", 1209 RSTRING_LEN($input), APR_MD5_DIGESTSIZE); 1210 } else { 1211 $1 = ($1_ltype)StringValuePtr($input); 1212 } 1213} 1214#endif 1215 1216/* Category 4 */ 1217/* FIXME: Write a typemap for category 4 */ 1218 1219/* ----------------------------------------------------------------------- 1220 useful convertors for svn_opt_revision_t 1221*/ 1222#ifdef SWIGPERL 1223%typemap(in) svn_opt_revision_t * 1224 (svn_opt_revision_t rev, apr_pool_t *_global_pool = NULL) 1225{ 1226 if (_global_pool == NULL) { 1227 _global_pool = svn_swig_pl_make_pool((SV *)NULL); 1228 SPAGAIN; 1229 } 1230 $1 = svn_swig_pl_set_revision(&rev, $input, TRUE, _global_pool); 1231} 1232#endif 1233 1234#ifdef SWIGRUBY 1235%typemap(in) svn_opt_revision_t * (svn_opt_revision_t rev) { 1236 $1 = &rev; 1237 svn_swig_rb_set_revision(&rev, $input); 1238} 1239#endif 1240 1241/* ----------------------------------------------------------------------- 1242 useful convertors for svn_depth_t 1243*/ 1244 1245#ifdef SWIGRUBY 1246%typemap(in) svn_depth_t { 1247 $1 = svn_swig_rb_to_depth($input); 1248} 1249#endif 1250 1251 1252/* ----------------------------------------------------------------------- 1253 useful convertors for svn_mergeinfo_inheritance_t 1254*/ 1255 1256#ifdef SWIGRUBY 1257%typemap(in) svn_mergeinfo_inheritance_t { 1258 $1 = svn_swig_rb_to_mergeinfo_inheritance($input); 1259} 1260#endif 1261 1262 1263/* ----------------------------------------------------------------------- 1264 useful convertors for svn_merge_range_inheritance_t 1265*/ 1266 1267#ifdef SWIGRUBY 1268%typemap(in) svn_merge_range_inheritance_t { 1269 $1 = svn_swig_rb_to_merge_range_inheritance($input); 1270} 1271#endif 1272 1273 1274/* ----------------------------------------------------------------------- 1275 Special boolean mapping for ruby. 1276*/ 1277 1278#ifdef SWIGRUBY 1279%typemap(in) svn_boolean_t "$1 = RTEST($input);"; 1280%typemap(out) svn_boolean_t "$result = $1 ? Qtrue : Qfalse;"; 1281 1282%typemap(in, numinputs=0) svn_boolean_t * (svn_boolean_t temp) "$1 = &temp;"; 1283%typemap(argout) svn_boolean_t * { 1284 %append_output(*$1 ? Qtrue : Qfalse); 1285} 1286#endif 1287 1288/* ----------------------------------------------------------------------- 1289 Filename to temporary file mapping for ruby. 1290*/ 1291 1292#ifdef SWIGRUBY 1293%typemap(argout) const char **TO_TEMP_FILE 1294{ 1295 %append_output(svn_swig_rb_filename_to_temp_file(*$1)); 1296} 1297#endif 1298 1299/* ----------------------------------------------------------------------- 1300 Handle python thread locking. 1301 1302 Swig doesn't allow us to specify a language in the %exception command, 1303 so we have to use #ifdefs for the python-specific parts. 1304*/ 1305 1306%exception { 1307#ifdef SWIGPYTHON 1308 svn_swig_py_release_py_lock(); 1309#endif 1310 $action 1311#ifdef SWIGPYTHON 1312 svn_swig_py_acquire_py_lock(); 1313#endif 1314} 1315