1SVN-fs-dump-format-version: 2 2 3UUID: 2b9a0b3d-7cd0-0310-85b4-80501935bfcd 4 5Revision-number: 0 6Prop-content-length: 56 7Content-length: 56 8 9K 8 10svn:date 11V 27 122004-01-09T14:02:28.825238Z 13PROPS-END 14 15Revision-number: 1 16Prop-content-length: 121 17Content-length: 121 18 19K 7 20svn:log 21V 20 22* Import demo files. 23K 10 24svn:author 25V 6 26plasma 27K 8 28svn:date 29V 27 302004-01-09T14:09:25.408100Z 31PROPS-END 32 33Node-path: SubversionSlideBasic.kwiki.txt 34Node-kind: file 35Node-action: add 36Prop-content-length: 10 37Text-content-length: 7393 38Text-content-md5: 51fc7a571f03c5dfec5c72760bb26c81 39Content-length: 7403 40 41PROPS-END 42[&SLIDESHOW_SELECTOR] 43---- 44[&title Subversion ��¦�g] 45== ��²���y�{ == 46 47* ²�z�������� 48* ²�z CVS 49* Subversion ���S�� 50* ���� Subversion �`�Ϋ��O 51* �X�ֻP�аO 52---- 53== ������ݭn�������� == 54 55* �O��L�h����� 56* �W�߶}�o���Ŷ� 57* �o�i�W�ߪ��Ŷ� 58---- 59== CVS �����I == 60 61* ���� 62* �R�O�C�ﶵ 63* �e��ä��O���i���Ϊ� 64* ���䴩��W 65* �S���ؿ���� 66---- 67== Subversion? == 68 69* ��������t�� 70* ���� CVS ���[�c 71* �������]�p 72* �ΨӨ��N CVS 73* ��n�� CVS 74* �ۥѪ��}�X 75---- 76== Subversion ���S�� == 77 78* �@�P���ϥΪ̬ɭ� 79* �ؿ��������� 80* ���i���Ϊ��e�� 81* �ǤJ��������y�z��� 82* �h�غ����q�T��� 83* ��Ϊ��G�i���ƳB�z 84* ���IJv������P�аO 85* ���Ī������ǿ� 86* Hackability 87---- 88== Subversion �S�����\�� == 89 90* �ɮO�d (cvs edit, watch) 91* Merge point 92* �ɮӧO������ 93* �������ɮw 94* I18N, L10N 95---- 96== ���o�P�w�� Subversion == 97 98* �� http://subversion.tigris.org ���o���X 99* ���p�{���w 100** APR 0.95 �H�W 101** Neon 0.24.4 102** Berkeley DB 4.0 �H�W (��ij 4.2.50) 103** Apache Web Server 2.0.48 (optional) 104** Python (optional) 105** Perl (optional) 106* FreeBSD �t�Ϊ� ports/devel/subversion 107* �b http://subversion.tigris.org ��䥦���x�W���i������ 108---- 109== TortoiseSVN == 110 111* Windows ���x�W�̦h�H���˥Τ�� 112* �P�ɮ��`��X�b�@�_ 113* �i�P�����X�}�����Ҥ@�P�ϥ� 114* ����: http://tortoisesvn.tigris.org/ 115---- 116== Subversion ���� == 117* �Τ�� 118** svn 119** svnversion 120* ���A���� 121** svnadmin 122** svnlook 123** svnserve 124** mod_dav_svn (optional) 125---- 126== �ɮw�P�q�� == 127 128* �����ɮרt�� 129* �q���O�ɮw���ַ� 130[&img /~plasma/img/ch02dia7.png] 131* ���쪺�q�� 132* �q������r 133** HEAD 134** BASE 135** COMMITTED 136** PREV 137* ��@�q���� 138 --revision 1234 139 -r 1234 140* �q�����d�� 141 --revision 1234:5678 142 -r 1234:5678 143---- 144== svn �R�O�C�{�� == 145svn: �ϥΪ̻P�ɮw���������� 146* �ʧ@�ؼХi�� URL �� ���| 147** ���|�@�Ϊ���H�O�u�@�ƥ� 148** URL �u�@����H�O�ɮw 149* �R�O�C�ﶵ������Ҧb��m�v�T 150* �����ۤv: help 151* URL �i� schema: 152** file:// 153** http:// 154** https:// 155** svn:// 156** svn+ssh:// 157---- 158== svnadmin �R�O�C�{�� == 159svnadmin: �����ޱ� Subversion ���ɮw 160* create: �إ��ɮw 161* dump: �N�ɮw�ɦL�ܤ�r�� 162* load: �ۤ�r�ɸ��J���ɮw 163---- 164== �u�@�y�{ == 165* �פJ���ɮw 166* ���X�u�@�ƥ� 167* ��s�u�@�ƥ� 168* �s��B��� 169* �˵���� 170* �^�_��� 171* �e���� 172---- 173== �פJ���ɮw == 174* �פJ�ثe���u�@�ؿ����ɮw 175 % svn import http://repo.host/repos/project/trunk 176* �פJ���w���ؿ����ɮw 177 % svn import proj http://repo.host/repos/project/trunk 178---- 179== ���X�u�@�ƥ� == 180* ���X�u�@�ƥ� 181 % svn checkout http://svn.collab.net/repos/svn/trunk 182* ���X�u�@�ƥ��ܫ��w���ؿ� 183 % svn checkout http://svn.collab.net/repos/svn/trunk svn 184* [=.svn] �z�ؿ� 185** �ǤJ����������ت���� 186** �ǤJ����������ت����㥼����ɮ� 187---- 188== ��s�u�@�ƥ� == 189* ��s�u�@�ƥ� 190** �N�Ҧ����ؿ��P�ɮק�s�̷ܳs���q�� 191 % svn update 192** �N�Ҧ����ؿ��P�ɮק�s�ܬY�Ӹ��ª��q�� 193 % svn update -r 1345 194** �u�n svn-doc.el �Y�ӧ�Ѫ����� 195 % svn update -r 999 svn-doc.el 196* ��s���ͪ����G 197;;[=A] : �w�w�s�W���ɮw. 198;;[=M] : �ɮת����e�w�Q���. 199;;[=D] : �w�w�n���ɮw�R��. 200;;[=?] : ���ǤJ��������. 201;;[=!] : �����w�ǤJ��������, ���O�����F. 202;;[=~] : ���P���O������. 203;;[=C] : �Ĭ�. 204---- 205== ����ɮ� == 206* �ϥΤ�r�s�边 207* �ϥιϧνs�边 208* �ϥ��H�K����s�边 209* �s�W�{�����ؿ����ɮ� 210 % svn add newfile.txt 211* �R���{�����ؿ����ɮ� 212 % svn rm bye.txt 213* �ƻs�ؿ����ɮ� 214 % svn copy foo.txt bar.txt 215* �h���ؿ����ɮ� 216 % svn move baz.txt buz.txt 217---- 218== �˵���� (I) == 219* [=svn status] 220 221 $ svn status 222 L ./abc.c # svn �b .svn �ؿ���, �� abc.c ����w 223 M ./bar.c # bar.c �����e, �����a�ݪ��ܧ� 224 M ./baz.c # baz.c �w�ܧ�F�ʽ�, ���O�S�����e����� 225 ? ./foo.o # svn �å��z foo.o 226 ! ./some_dir # svn �z��, ���O���O�����F, �N�O������ 227 ~ ./qux # �ǤJ�z���O�ؿ�, ���O�o�̬O�ɮ�, �άO�ۤϪ����p 228 A + ./moved_dir # �s�W����, �åH�ӷ������v����������v���� 229 M + ./moved_dir/README # �s�W����, �ϥΨӷ������v����, �A�[�W���a��� 230 D ./stuff/fish.c # ���ɮפw�w�w�n�Q�R�� 231 A ./stuff/loot/bloo.h # ���ɮפw�w�w�n�Q�s�W 232 C ./stuff/loot/lump.c # �o���ɮצ��]��s�Ӳ��ͪ��Ĭ� 233 S ./stuff/squawk # �o���ɮשΥؿ��w��������� 234 235---- 236== �˵���� (II) == 237** [=svn status]: �[�W -v ��ܧ�h����T 238 239 $ svn status --verbose 240 M 44 23 sally ./README 241 44 30 sally ./INSTALL 242 M 44 20 harry ./bar.c 243 44 18 ira ./stuff 244 44 35 harry ./stuff/trout.c 245 D 44 19 ira ./stuff/fish.c 246 44 21 sally ./stuff/things 247 A 0 ? ? ./stuff/things/bloo.h 248 44 36 harry ./stuff/things/gloo.c 249 250*** ��ܭq���s�� 251*** ��ܧ���ɮת��H 252---- 253== �˵���� (III) == 254* �˵��A����� 255** svn diff: ��ܩҧ@����� 256*** �s�ʽ誺��ʤ]�|��� 257*** ��ܩҦ����a�u�@�ƥ����ؿ��P�ɮt�� 258 % svn diff 259*** ����ɮw�� 3 ���q���� foo.pl �P�u�@�ƥ��� foo.pl �������t�� 260 % svn diff -r 3 foo.pl 261*** ����ɮw���� foo.pl �� 2 ���P 3 ���q���������t��, �L�ݦs�����a�ƥ� 262 % svn diff -r 2:3 foo.pl 263---- 264== �^�_��� == 265* �^�_�Y�ɮת���� 266** �������ݭn���� 267 % svn revert foo.pl 268---- 269== �e���� == 270* �e��ڭ̩ҧ@����� 271 % svn commit 272* �b�R�O�C���Ѱe��T�� 273 % svn commit -m "Commit log message" 274* �e�椧��, �u�@�ƥ��ؿ����|�۰ʧ�s 275---- 276== ����r�i�} == 277* �p��ϥ�����r�i�} 278** �]�w�ɮת��ʽ� 279 % svn propset svn:keywords Id foo.pl 280** �i�ϥΪ�����r 281*** URL, HeadURL 282*** Author, LastChangedBy 283*** Date, LastChangedDate 284*** Rev, LastChangedRevision 285*** Id 286---- 287== �ɮw�ؿ��[�c == 288 289* ��@ 290 /repos/project1/trunk 291 /repos/project1/branches 292 /repos/project1/tags 293 /repos/project2/trunk 294 /repos/project2/branches 295 /repos/project2/tags 296* ��G 297 /repos/trunk/project1 298 /repos/trunk/project2 299 /repos/branches/project1 300 /repos/branches/project2 301 /repos/tags/project1 302 /repos/tags/project2 303---- 304== �аO�P���� == 305 306* �G���ƥ� 307** �t�ܧ� 308** �u�O�s���Ӥw 309* �аO�P����N�u�O�ƻs�Ӥw 310 % svn cp http://svn.host/repos/proj/trunk \ 311 http://svn.host/repos/proj/branches/add-new-features 312 % svn cp http://svn.host/repos/proj/trunk \ 313 http://svn.host/repos/proj/tags/0.0.1 314* �аO�P���䪺�t�O 315** �аO���A��� 316** ����N�����t�@��o�i�u 317---- 318== �ϥΤ��� == 319 320* �����ϥ� checkout �R�O 321** �����ϥΤ���ؿ� 322 % svn co http://svn.host/repos/proj/branches/add-new-features 323** �t����w����ؿ� 324 % svn co http://svn.host/repos/proj/branches/add-new-features proj 325* �w���D���䪺�u�@�ƥ� 326** �ϥ� svn switch 327 % svn switch http://svn.host/repos/proj/branches/add-new-features 328---- 329== �X�֤��� == 330 331* ����u�@�w����, �ӦX�֦^�D�o�i�u 332* �ϥ� merge �R�O 333* �̱`�Ǫ����~ 334 % svn merge \ 335 http://svn.host/repos/proj/branches/add-new-features \ 336 http://svn.host/repos/proj/trunk 337* ���T���@�k 338 % svn merge -r REV1:REV2 \ 339 http://svn.host/repos/proj/branches/add-new-features 340---- 341== �Ĭ� == 342 343* �L�k���T�L�~�X�� 344* ���ͤT���B�~���ɮ� 345** ����b�u�@�ƥ����� 346** �b�X�֨ӷ��� 347** �b�X�֥ؼЪ� 348* �L�k�i��e�� 349* �������ѨM�Ĭ� 350* �ϥ� resolved ���O 351 % svn resolved foo.pl 352---- 353== �ѦҺ��� == 354 355* Subversion ����: http://subversion.tigris.org 356* TortoiseSVN ����: http://tortoisesvn.tigris.org 357* Subversion Book: http://svnbook.red-bean.com/ 358* Subversion Book ��Ķ��: http://freebsd.sinica.edu.tw/~plasma/svnbook/ 359 360 361Node-path: SubversionSlideRepo.kwiki.txt 362Node-kind: file 363Node-action: add 364Prop-content-length: 10 365Text-content-length: 2233 366Text-content-md5: abaf1ff8e01ca7d5ac9ef2b6cee2c9b4 367Content-length: 2243 368 369PROPS-END 370[&SLIDESHOW_SELECTOR] 371---- 372[&title Subversion �ɮw�z] 373== �ɮw�z == 374 375* svnadmin �R�O�C�{�� 376* �P�ɮw�b�P�@�x�����W 377* �ؿ��Ҭ����|, �S�� URL 378---- 379== �ɮw�ɮ[�c == 380 381* �ɮw�����e 382 README.txt # ��r�� 383 conf # �]�t�]�w�ɪ��ؿ� 384 dav # �� Apache mod_dav �ϥΪ��ؿ� 385 db # ��Ʈw�ؿ� 386 format # �]�t�ɮw�榡��������r�� 387 hooks # �]�t���ĵ{�����ؿ� 388 locks # �Ѹ�Ʈw����w�ϥΪ��ؿ� 389---- 390== �ɮw�v�� == 391 392* �g�J�ɮw�ݦ��g�J�v�� 393* Ū���ɮw�ݦ��g�J�v�� 394* ��ij�@�k 395** �إߦW�� svn ���ϥΪ̻P�s�� 396** �ɮw�ؿ��]���ӨϥΪ̻P�s�եiŪ�g 397* umask 398** �s���ɮw���H 002 ���� 399 400---- 401== �`�Ϋ��O == 402 403* �إ��ɮw 404 % svnadmin create SVN_ROOT 405* �ɦL�ɮw���e 406 % svnadmin dump SVN_ROOT > repos.dump 407* ���J�ɦL�ɤ��e 408 % svnadmin load SVN_ROOT < repos.dump 409* �C�X�L�Ϊ�����ɬ����� 410 % svnadmin list-unused-dblogs SVN_ROOT 411* �ץ��ɮw���D 412 % svn recover 413---- 414== ���ĵ{�� == 415 416* �]�ɮw���ƥ��IJ�o 417* ���ɮw�������W���� 418* ��@������ 419** start-commit 420** pre-commit 421** post-commit 422** pre-revprop-change 423** post-revprop-change 424---- 425== �ƥ� == 426 427* ����ƥ� 428** svnadmin dump 429* �Y�ɳƥ� 430** svnadmin hotcopy 431* �^�s 432** svnadmin load 433---- 434== �}��ܺ��� == 435 436* �ϥ� Apache 437** �\��j�j 438** �i�H�M Apache �Ҳը�P�ϥ� 439* �ϥ� svnserve 440** �M�ݦ��A�� 441** �ϥ�²�� 442* �ϥ� svnserve + ssh 443** �ϥ�²�� 444** �w�� 445** �� ssh �b���Y�i�ϥ� 446---- 447== �ϥ� Apache == 448 449* �ϥ� mod_dav_svn 450* �]�w�ɽd�� (�@) 451 452 LoadModule dav_svn_module modules/mod_dav_svn.so 453 <Location /repos>> 454 DAV svn 455 SVNPath /absolute/path/to/repository 456 </Location> 457 458* �]�w�ɽd�� (�G) 459 460 LoadModule dav_svn_module modules/mod_dav_svn.so 461 <Location /repos>> 462 DAV svn 463 SVNParentPath /usr/local/svn 464 </Location> 465 466* �]�w�ɽd�� (�T) 467 468 469 LoadModule dav_svn_module modules/mod_dav_svn.so 470 <Location /svn> 471 DAV svn 472 SVNParentPath /usr/local/svn 473 AuthType Basic 474 AuthName "Subversion repository" 475 AuthUserFile /path/to/users/file 476 <LimitExcept GET PROPFIND OPTIONS REPORT> 477 Require valid-user 478 </LimitExcept> 479 </Location> 480---- 481== �ϥ� svnserve == 482 483* �ϥ� port 3690 484* �������� 485 svnserve -d 486* �z�L inetd 487* �����ϥΧ�����| 488* �i�z�L -r ������|�d�� 489---- 490== �z�L SSH == 491 492* �u�n�� SSH �Y�i 493* ���O�����ϥΧ�����| 494 495 496Revision-number: 2 497Prop-content-length: 121 498Content-length: 121 499 500K 7 501svn:log 502V 20 503Add a new text file. 504K 10 505svn:author 506V 6 507plasma 508K 8 509svn:date 510V 27 5112004-01-09T14:25:59.606510Z 512PROPS-END 513 514Node-path: lines.txt 515Node-kind: file 516Node-action: add 517Prop-content-length: 10 518Text-content-length: 5 519Text-content-md5: 2145971cf82058b108229a3a2e3bff35 520Content-length: 15 521 522PROPS-END 523foo 524 525 526Revision-number: 3 527Prop-content-length: 113 528Content-length: 113 529 530K 7 531svn:log 532V 12 533* more line. 534K 10 535svn:author 536V 6 537plasma 538K 8 539svn:date 540V 27 5412004-01-10T03:30:34.074309Z 542PROPS-END 543 544Node-path: lines.txt 545Node-kind: file 546Node-action: change 547Text-content-length: 12 548Text-content-md5: d8acd5d90b730b50006b9cee2b8f879f 549Content-length: 12 550 551foo 552bar 553 554 555 556Revision-number: 4 557Prop-content-length: 130 558Content-length: 130 559 560K 7 561svn:log 562V 29 563* Subversion SIG commit demo. 564K 10 565svn:author 566V 6 567plasma 568K 8 569svn:date 570V 27 5712004-01-10T03:55:21.959253Z 572PROPS-END 573 574Node-path: lines.txt 575Node-kind: file 576Node-action: change 577Text-content-length: 15 578Text-content-md5: a2ead3516dd1be4a3c7f45716c0a0eb7 579Content-length: 15 580 581foo 582bar 583baz 584 585 586Node-path: svn.txt 587Node-kind: file 588Node-action: add 589Prop-content-length: 10 590Text-content-length: 10 591Text-content-md5: 3dbec9c1b92200eb56349835275e00b9 592Content-length: 20 593 594PROPS-END 595foo 596bar 597 598 599Revision-number: 5 600Prop-content-length: 119 601Content-length: 119 602 603K 7 604svn:log 605V 18 606* Set Id property. 607K 10 608svn:author 609V 6 610plasma 611K 8 612svn:date 613V 27 6142004-01-10T04:04:21.780028Z 615PROPS-END 616 617Node-path: lines.txt 618Node-kind: file 619Node-action: change 620Prop-content-length: 35 621Text-content-length: 23 622Text-content-md5: 130237c4c01b4deea15c662b9ac9a65c 623Content-length: 58 624 625K 12 626svn:keywords 627V 2 628Id 629PROPS-END 630# $Id$ 631foo 632bar 633baz 634 635 636Revision-number: 6 637Prop-content-length: 124 638Content-length: 124 639 640K 7 641svn:log 642V 23 643* Ready for conflict!!! 644K 10 645svn:author 646V 6 647plasma 648K 8 649svn:date 650V 27 6512004-01-10T05:31:02.693444Z 652PROPS-END 653 654Node-path: lines.txt 655Node-kind: file 656Node-action: change 657Text-content-length: 35 658Text-content-md5: 21efbf723aa38d52b5c46223699a94da 659Content-length: 35 660 661# $Id$ 662foo 663bar 664baz 665subversion 666 667 668Revision-number: 7 669Prop-content-length: 121 670Content-length: 121 671 672K 7 673svn:log 674V 20 675* Conflict resolved. 676K 10 677svn:author 678V 6 679plasma 680K 8 681svn:date 682V 27 6832004-01-10T05:37:04.015674Z 684PROPS-END 685 686Node-path: lines.txt 687Node-kind: file 688Node-action: change 689Text-content-length: 42 690Text-content-md5: ca09a5ce149a8d6b2e8023b37964f683 691Content-length: 42 692 693# $Id$ 694foo 695bar 696baz 697subversion SIG. 698 699 700 701Revision-number: 8 702Prop-content-length: 125 703Content-length: 125 704 705K 7 706svn:log 707V 24 708* Make a copy of svn.txt 709K 10 710svn:author 711V 6 712plasma 713K 8 714svn:date 715V 27 7162004-01-16T09:08:16.754407Z 717PROPS-END 718 719Node-path: svn.copy.txt 720Node-kind: file 721Node-action: add 722Node-copyfrom-rev: 7 723Node-copyfrom-path: svn.txt 724 725 726Revision-number: 9 727Prop-content-length: 119 728Content-length: 119 729 730K 7 731svn:log 732V 18 733* Add a new layer. 734K 10 735svn:author 736V 6 737plasma 738K 8 739svn:date 740V 27 7412004-01-16T16:04:26.218350Z 742PROPS-END 743 744Node-path: dir 745Node-kind: dir 746Node-action: add 747Prop-content-length: 10 748Content-length: 10 749 750PROPS-END 751 752 753Node-path: dir/lines.txt 754Node-kind: file 755Node-action: add 756Prop-content-length: 10 757Text-content-length: 9 758Text-content-md5: 72f9e5fd3a2e61fcf3542092edc7cab8 759Content-length: 19 760 761PROPS-END 762FOO 763BAR 764 765 766 767Revision-number: 10 768Prop-content-length: 119 769Content-length: 119 770 771K 7 772svn:log 773V 18 774* make a dir copy. 775K 10 776svn:author 777V 6 778plasma 779K 8 780svn:date 781V 27 7822004-01-16T17:30:22.602262Z 783PROPS-END 784 785Node-path: new_dir 786Node-kind: dir 787Node-action: add 788Node-copyfrom-rev: 9 789Node-copyfrom-path: dir 790 791 792Revision-number: 11 793Prop-content-length: 126 794Content-length: 126 795 796K 7 797svn:log 798V 25 799* multiple levels of dir. 800K 10 801svn:author 802V 6 803plasma 804K 8 805svn:date 806V 27 8072004-01-16T18:00:04.871383Z 808PROPS-END 809 810Node-path: deep 811Node-kind: dir 812Node-action: add 813Prop-content-length: 10 814Content-length: 10 815 816PROPS-END 817 818 819Node-path: deep/more_deep 820Node-kind: dir 821Node-action: add 822Prop-content-length: 10 823Content-length: 10 824 825PROPS-END 826 827 828Node-path: deep/more_deep/dir 829Node-kind: dir 830Node-action: add 831Node-copyfrom-rev: 9 832Node-copyfrom-path: dir 833 834 835Revision-number: 12 836Prop-content-length: 140 837Content-length: 140 838 839K 7 840svn:log 841V 39 842* Rename svn.copy.txt to svn.clone.txt. 843K 10 844svn:author 845V 6 846plasma 847K 8 848svn:date 849V 27 8502004-01-17T05:34:59.211765Z 851PROPS-END 852 853Node-path: svn.clone.txt 854Node-kind: file 855Node-action: add 856Node-copyfrom-rev: 8 857Node-copyfrom-path: svn.copy.txt 858 859 860Node-path: svn.copy.txt 861Node-action: delete 862 863 864Revision-number: 13 865Prop-content-length: 132 866Content-length: 132 867 868K 7 869svn:log 870V 31 871* Made a change to copied file. 872K 10 873svn:author 874V 6 875plasma 876K 8 877svn:date 878V 27 8792004-01-18T15:48:29.564987Z 880PROPS-END 881 882Node-path: svn.clone.txt 883Node-kind: file 884Node-action: change 885Text-content-length: 17 886Text-content-md5: 3711a1d13b1345f49965c494ff91624f 887Content-length: 17 888 889foo 890bar 891baz 892 893 894 895Revision-number: 14 896Prop-content-length: 146 897Content-length: 146 898 899K 7 900svn:log 901V 45 902* Made a change to a file in deep copied dir. 903K 10 904svn:author 905V 6 906plasma 907K 8 908svn:date 909V 27 9102004-01-18T15:57:11.896860Z 911PROPS-END 912 913Node-path: deep/more_deep/dir/lines.txt 914Node-kind: file 915Node-action: change 916Text-content-length: 13 917Text-content-md5: c08ae19747de7e34ba9a6a9319522437 918Content-length: 13 919 920FOO 921BAR 922BAZ 923 924 925 926Revision-number: 15 927Prop-content-length: 141 928Content-length: 141 929 930K 7 931svn:log 932V 40 933* Move a deep directory to another name. 934K 10 935svn:author 936V 6 937plasma 938K 8 939svn:date 940V 27 9412004-01-18T16:08:49.545001Z 942PROPS-END 943 944Node-path: deep/more_deep/new_dir 945Node-kind: dir 946Node-action: add 947Node-copyfrom-rev: 13 948Node-copyfrom-path: deep/more_deep/dir 949 950 951Node-path: deep/more_deep/new_dir/lines.txt 952Node-kind: file 953Node-action: delete 954 955Node-path: deep/more_deep/new_dir/lines.txt 956Node-kind: file 957Node-action: add 958Node-copyfrom-rev: 14 959Node-copyfrom-path: deep/more_deep/dir/lines.txt 960 961 962 963 964Node-path: deep/more_deep/dir 965Node-action: delete 966 967 968Revision-number: 16 969Prop-content-length: 147 970Content-length: 147 971 972K 7 973svn:log 974V 46 975* Made a change to a file in a deep directory. 976K 10 977svn:author 978V 6 979plasma 980K 8 981svn:date 982V 27 9832004-01-18T16:09:54.116527Z 984PROPS-END 985 986Node-path: deep/more_deep/new_dir/lines.txt 987Node-kind: file 988Node-action: change 989Text-content-length: 17 990Text-content-md5: 17deba5591ff45fdfdc5a2382f9a2cda 991Content-length: 17 992 993FOO 994BAR 995BAZ 996BUZ 997 998 999 1000Revision-number: 17 1001Prop-content-length: 151 1002Content-length: 151 1003 1004K 7 1005svn:log 1006V 50 1007* Move a directory, modify a file withint the dir. 1008K 10 1009svn:author 1010V 6 1011plasma 1012K 8 1013svn:date 1014V 27 10152004-01-18T16:19:18.836664Z 1016PROPS-END 1017 1018Node-path: deep/more_deep/another_new_dir 1019Node-kind: dir 1020Node-action: add 1021Node-copyfrom-rev: 16 1022Node-copyfrom-path: deep/more_deep/new_dir 1023 1024 1025Node-path: deep/more_deep/another_new_dir/lines.txt 1026Node-kind: file 1027Node-action: change 1028Text-content-length: 21 1029Text-content-md5: 1ef9a433976ba9435db98a55dd956b21 1030Content-length: 21 1031 1032FOO 1033BAR 1034BAZ 1035BUZ 1036BZZ 1037 1038 1039 1040Node-path: deep/more_deep/new_dir 1041Node-action: delete 1042 1043 1044Revision-number: 18 1045Prop-content-length: 117 1046Content-length: 117 1047 1048K 7 1049svn:log 1050V 16 1051* Made a change. 1052K 10 1053svn:author 1054V 6 1055plasma 1056K 8 1057svn:date 1058V 27 10592004-01-18T16:21:18.608747Z 1060PROPS-END 1061 1062Node-path: deep/more_deep/another_new_dir/lines.txt 1063Node-kind: file 1064Node-action: change 1065Text-content-length: 27 1066Text-content-md5: 5f0fe922acbbb8ae99344d44f1c62757 1067Content-length: 27 1068 1069FOO 1070BAR 1071BAZ 1072BUZ 1073BZZ 1074ERROR 1075 1076 1077 1078Revision-number: 19 1079Prop-content-length: 121 1080Content-length: 121 1081 1082K 7 1083svn:log 1084V 20 1085* Simulate a branch. 1086K 10 1087svn:author 1088V 6 1089plasma 1090K 8 1091svn:date 1092V 27 10932004-01-19T14:18:57.105904Z 1094PROPS-END 1095 1096Node-path: another_deep 1097Node-kind: dir 1098Node-action: add 1099Node-copyfrom-rev: 18 1100Node-copyfrom-path: deep 1101 1102 1103Revision-number: 20 1104Prop-content-length: 184 1105Content-length: 184 1106 1107K 7 1108svn:log 1109V 83 1110* Situation for new dir, copied a dir within, then modify a file in the lowest dir. 1111K 10 1112svn:author 1113V 6 1114plasma 1115K 8 1116svn:date 1117V 27 11182004-01-20T00:51:58.906233Z 1119PROPS-END 1120 1121Node-path: another_dir 1122Node-kind: dir 1123Node-action: add 1124Prop-content-length: 10 1125Content-length: 10 1126 1127PROPS-END 1128 1129 1130Node-path: another_dir/dir 1131Node-kind: dir 1132Node-action: add 1133Node-copyfrom-rev: 19 1134Node-copyfrom-path: dir 1135 1136 1137Node-path: another_dir/dir/lines.txt 1138Node-kind: file 1139Node-action: change 1140Text-content-length: 13 1141Text-content-md5: c08ae19747de7e34ba9a6a9319522437 1142Content-length: 13 1143 1144FOO 1145BAR 1146BAZ 1147 1148 1149 1150Revision-number: 21 1151Prop-content-length: 148 1152Content-length: 148 1153 1154K 7 1155svn:log 1156V 47 1157* remove previous rev. the test case is wrong. 1158K 10 1159svn:author 1160V 6 1161plasma 1162K 8 1163svn:date 1164V 27 11652004-01-20T00:54:03.722689Z 1166PROPS-END 1167 1168Node-path: another_dir 1169Node-action: delete 1170 1171 1172Revision-number: 22 1173Prop-content-length: 187 1174Content-length: 187 1175 1176K 7 1177svn:log 1178V 86 1179* A test case. New dir, add a copied path within, then edit a file in 3 level of dir. 1180K 10 1181svn:author 1182V 6 1183plasma 1184K 8 1185svn:date 1186V 27 11872004-01-20T01:02:27.855682Z 1188PROPS-END 1189 1190Node-path: another_dir 1191Node-kind: dir 1192Node-action: add 1193Prop-content-length: 10 1194Content-length: 10 1195 1196PROPS-END 1197 1198 1199Node-path: another_dir/more_deep 1200Node-kind: dir 1201Node-action: add 1202Node-copyfrom-rev: 19 1203Node-copyfrom-path: another_deep/more_deep 1204 1205 1206Node-path: another_dir/more_deep/another_new_dir/lines.txt 1207Node-kind: file 1208Node-action: change 1209Text-content-length: 32 1210Text-content-md5: 3211cbe8eb62b72a8401a139b67398ac 1211Content-length: 32 1212 1213FOO 1214BAR 1215BAZ 1216BUZ 1217BZZ 1218ERROR 1219MILK 1220 1221 1222 1223Revision-number: 23 1224Prop-content-length: 147 1225Content-length: 147 1226 1227K 7 1228svn:log 1229V 46 1230* import a directory large enough to do tests. 1231K 10 1232svn:author 1233V 6 1234plasma 1235K 8 1236svn:date 1237V 27 12382004-01-23T05:11:01.783505Z 1239PROPS-END 1240 1241Node-path: svnperl 1242Node-kind: dir 1243Node-action: add 1244Prop-content-length: 10 1245Content-length: 10 1246 1247PROPS-END 1248 1249 1250Node-path: svnperl/INSTALL 1251Node-kind: file 1252Node-action: add 1253Prop-content-length: 10 1254Text-content-length: 7648 1255Text-content-md5: 6fd4b903d76a7db18385509f333bc072 1256Content-length: 7658 1257 1258PROPS-END 1259 -*-text-*- 1260 1261BUILDING SWIG BINDINGS FOR SVN ON UNIX 1262 1263 1264Step 1: Build & install the proper version of SWIG (which is 1265 currently swig 1.3.16). 1266 1267 * Go to http://www.swig.org/, download the sourceball, unpack. 1268 1269 * In the SWIG-X.X.X directory, run ./configure. 1270 1271 If you plan to build the python bindings, and have a system 1272 with more than one version of python installed, you may need 1273 to pass 1274 1275 --with-python=/path/to/correct/python/binary 1276 1277 to the configure script. You certainly don't want to use any 1278 version of python older than 2.0. 1279 1280 * run 'make && make install' 1281 1282 * To verify you have the goodz installed, check that these things 1283 were created, assuming your $PREFIX was /usr/local/lib: 1284 1285 - /usr/local/lib/swig1.3/*.i 1286 - /usr/local/lib/libswig*.so 1287 - /usr/local/bin/swig 1288 1289 In particular, you want to make sure that libswig_py.so was 1290 built and installed, since the python bindings are the most-used 1291 ones at the moment. 1292 1293 1294Step 2: Build and Install Subversion. 1295 1296 See Subversion's own INSTALL file for details. 1297 1298 Make sure that Subversion's ./configure script sees your installed SWIG! 1299 It tries to detect SWIG near the very end of its output. 1300 1301 If Subversion's ./configure finds a SWIG that it's happy with, then 1302 it will build a special glue library to link svn to the swig-python 1303 bindings: libsvn_swig_py.so (as well as any other languages). 1304 1305 1306Step 3: Install Specific Language Bindings 1307 1308* Python 1309 1310 1. Run 'make swig-py' from the top of the 1311 Subversion source tree. This will invoke SWIG on the *.i 1312 files, resulting in a collection of .c source files. It will 1313 then compile and link those .c files into Python libraries. 1314 1315 2. Run 'make install-swig-py' (as root, typically) 1316 from the top of the Subversion source tree. This will copy 1317 your new Python libraries into the appropriate system location. 1318 1319 Note: If you don't have access to install to python's site-packages 1320 directory, you can have the python modules install to your home 1321 directory. You can do this by running 1322 'make install-swig-py swig_pydir=~'. 1323 1324 Note: If you want to install to an alternate prefix (usually only 1325 if you are building packages), you can supply the prefix here. An 1326 example of doing this for building rpms looks like 1327 'make install-swig-py DESTDIR=$RPM_BUILD_ROOT/usr'. 1328 1329 3. Make sure that whatever directory the bindings got installed in 1330 is in your PYTHONPATH. That directory depends on how you 1331 installed; a typical location is /usr/local/lib/svn-python/, 1332 see http://subversion.tigris.org/issues/show_bug.cgi?id=1125 1333 for some imminent improvements to the install process. 1334 1335* Perl 1336 1337 The build process of the Perl bindings is not yet tightly 1338 integrated with subversion's build system. It is using the standard 1339 way for building and installing perl extentions. You will have to 1340 install subversion before building and using it. Perl 5.8.0 is 1341 required. 1342 1343 1. Run `make swig-pl-lib' from the top of the 1344 Subversion source tree. 1345 1346 2. Go to subversion/bindings/swig/perl and run 1347 `env APR_CONFIG=/path/to/apr-config perl Makefile.PL'. 1348 1349 3. run `make all test'. 1350 1351 4. to install, run `make install-swig-pl-lib' from the top of the 1352 Subversion source tree, and `make install' from the perl 1353 directory. 1354 1355* Java 1356 1357 The Java bindings are still under development, and have not yet 1358 reached a functional state. You can attempt to build them by 1359 running 'make swig-java' from the top level of the Subversion 1360 source tree. 1361 1362 1363BUILDING SWIG BINDINGS FOR SVN ON WINDOWS 1364 1365 1366 1. Install SWIG. Download the SWIG Windows zipfile (it's the same as the 1367 source tarball except that it also includes a copy of swig.exe) from 1368 1369 http://www.swig.org/ 1370 1371 and extract it somewhere, like C:\Program Files. 1372 1373 2. Install whatever languages you want to build runtimes for. Windows 1374 versions of Python, Perl, and Java are available from: 1375 1376 http://www.python.org/ 1377 http://www.activestate.com/ActivePerl/ 1378 http://java.sun.com/j2se/ 1379 1380 3. Configure Visual C++ with paths to swig.exe and language specific 1381 libraries. In Visual C++ 6, go to Tools -> Options -> Directories. 1382 In Visual C++ .NET, go to Tools -> Options -> Projects 1383 -> VC++ Directories. 1384 1385 Add the following paths: 1386 1387 Executable Directories: 1388 1389 Path to swig.exe 1390 (for example, C:\Program Files\SWIG-1.3.19) 1391 1392 Library Directories: 1393 1394 For Python, path to python##.lib 1395 (for example, C:\Program Files\Python22\libs) 1396 1397 For Perl, path to perl##.lib 1398 (for example, C:\Program Files\Perl\lib\CORE) 1399 1400 For Java, path to jvm.lib library 1401 (for example C:\Program Files\j2sdk1.4.2\lib) 1402 1403 Include Directories: 1404 1405 For Python, path to Python.h 1406 (for example, C:\Program Files\Python22\include) 1407 1408 For Perl, path to perl.h 1409 (for example, C:\Program Files\Perl\lib\CORE) 1410 1411 For Java, path to JNI headers, 1412 (for example, C:\Program Files\j2sdk1.4.2\include) 1413 1414 Also for Java, path to JNI Windows headers, 1415 (for example, C:\Program Files\j2sdk1.4.2\include\win32) 1416 1417 4. If you haven't already built Subversion, you should do so now. 1418 Instructions are in the main INSTALL file. At the very least, 1419 you need to run gen-make.py to generate Visual Studio project 1420 files. 1421 1422 5. Build the bindings. Open the Subversion workspace in Visual C++ 1423 (subversion_msvc.dsw or subversion_vcnet.sln) and build one or more 1424 of the following projects: 1425 1426 __SWIG_PYTHON__ 1427 __SWIG_PERL__ 1428 __SWIG_JAVA__ 1429 1430 6. Install the bindings. The procedure varies depending on the language. 1431 1432 For Python, create two folders: 1433 1434 <PYTHON>\Lib\site-packages\svn 1435 <PYTHON>\Lib\site-packages\libsvn 1436 1437 Copy subversion\bindings\swig\python\svn\*.py into the svn folder. 1438 Copy subversion\bindings\swig\python\*.py and 1439 Release\subversion\bindings\swig\python\*.dll into the libsvn folder. 1440 1441 Optionally, you can run the following commands to compile the Python 1442 sources into bytecode: 1443 1444 python <PYTHON>\lib\compileall.py <PYTHON>\Lib\site-packages\svn 1445 python <PYTHON>\lib\compileall.py <PYTHON>\Lib\site-packages\libsvn 1446 1447 This can make the modules load faster for users without write access 1448 to the site-packages directory. 1449 1450 For Perl, ??? 1451 For Java, ??? 1452 1453 1454TESTING AND USING SWIG BINDINGS 1455 1456* Python 1457 1458 1. Verify that an 'svn' package has been installed correctly. You can 1459 do this by running Python via 'python -c "from svn import client"'. 1460 1461 2. Try some demo programs. From the top of your svn working copy, 1462 cd tools/examples/ and try running 'svnlook.py'. 1463 1464 3. Start writing your own scripts. Use the Subversion API definitions 1465 and descriptions in: 1466 1467 subversion/include/svn_client.h 1468 subversion/include/svn_delta.h 1469 subversion/include/svn_fs.h 1470 subversion/include/svn_ra.h 1471 subversion/include/svn_repos.h 1472 subversion/include/svn_wc.h 1473 1474* Perl 1475 1476 The perl bindings are using the standard module testing facilities 1477 to do regression tests. Simply run make test as described in the 1478 install section. 1479 1480* Java 1481 1482 1483Node-path: svnperl/README 1484Node-kind: file 1485Node-action: add 1486Prop-content-length: 10 1487Text-content-length: 2313 1488Text-content-md5: e0377d3a634bab69f63f654c44f62f33 1489Content-length: 2323 1490 1491PROPS-END 1492 -*-text-*- 1493 1494 1495==> For instructions on how to get swig bindings working, read the 1496 INSTALL file in this directory. 1497 1498 1499SVN HEADER -> SWIG MODULE 1500------------------------- 1501 1502Subversion has a bunch of includes files, some are interesting for 1503wrapping with language bindings, and others which are simple type 1504declarations and constants. Below is the table which maps each header 1505to its disposition: 1506 1507INCLUDE SWIG MODULE NAME 1508svn_base64.h (1) 1509svn_client.h _client 1510svn_config.h ? 1511svn_delta.h _delta 1512svn_error.h (2) 1513svn_error_codes.h (2) 1514svn_fs.h _fs 1515svn_hash.h (1) 1516svn_io.h (4) (only stream functions) 1517svn_path.h (1) 1518svn_pools.h (4) (only pool manipulation) 1519svn_quoprint.h (1) 1520svn_ra.h _ra 1521svn_repos.h _repos 1522svn_sorts.h (1) 1523svn_string.h (3) 1524svn_test.h (2) 1525svn_time.h (1) 1526svn_types.h (3) 1527svn_version.h (4) (some symbols) 1528svn_wc.h _wc 1529svn_xml.h (1) 1530 1531apr*.h (3) 1532 1533n/a _util 1534 1535(1) it is assumed that the binding languages will provide this 1536 functionality separately. 1537 ### HELP: Java does not provide base-64 natively. Should we wrap 1538 ### SVN's with SWIG, or include a stand-alone ASF implementation 1539 ### (such as from Jakarta Commons Codec)? 1540(2) no significant/interesting functionality to export 1541(3) only the types are exported; a SWIG interface file is present 1542(4) limited symbols/functionality exported via the _util module 1543 1544 1545NOTE: the bindings code is being developed using SWIG 1.3.16. Earlier 1546versions of SWIG will simply *not* work. 1547 1548 1549 1550 1551SWIG MODULES 1552------------ 1553 1554We will produce a number of modules/classes, expecting the binding 1555languages to organize these into a package, and present the Subversion 1556libraries' API in a manner familiar to programmers of a given 1557language. For instance, the Python bindings are handled as follows: 1558 1559svn.client 1560svn.delta 1561svn.error 1562svn.fs 1563svn.io 1564svn.ra 1565svn.wc 1566 1567 1568 1569 1570THUNK EDITORS 1571------------- 1572 1573"Thunk" is Windows programming term describing a "go between." Our 1574SWIG bindings generally implement editors in C which delegate to the 1575language-specific extension API (e.g. its C API for Python, JNI for 1576Java, etc.). This transitional object implements a Subversion editor 1577interface, allowing it to be passed between its native library code 1578and the runtime of the language which the bindings were written for. 1579 1580 1581Node-path: svnperl/apr.i 1582Node-kind: file 1583Node-action: add 1584Prop-content-length: 10 1585Text-content-length: 6648 1586Text-content-md5: 17ca72cdc920b97091a6e9a58063fe35 1587Content-length: 6658 1588 1589PROPS-END 1590/* 1591 * apr.i : SWIG interface file for selected APR types 1592 * 1593 * ==================================================================== 1594 * Copyright (c) 2000-2003 CollabNet. All rights reserved. 1595 * 1596 * This software is licensed as described in the file COPYING, which 1597 * you should have received as part of this distribution. The terms 1598 * are also available at http://subversion.tigris.org/license-1.html. 1599 * If newer versions of this license are posted there, you may use a 1600 * newer version instead, at your option. 1601 * 1602 * This software consists of voluntary contributions made by many 1603 * individuals. For exact contribution history, see the revision 1604 * history and logs, available at http://subversion.tigris.org/. 1605 * ==================================================================== 1606 */ 1607 1608/* This is the interface for the APR headers. This is not built as a module 1609 because we aren't going to wrap the APR functions. Thus, we only define 1610 the various types in here, as necessary. 1611 1612 Actually, core.i wraps a few, key functions. 1613*/ 1614 1615%include typemaps.i 1616 1617/* This is default in SWIG 1.3.17 and is a really good idea */ 1618%typemap(javagetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ 1619 protected static long getCPtr($javaclassname obj) { 1620 return (obj == null) ? 0 : obj.swigCPtr; 1621 } 1622%} 1623 1624/* ----------------------------------------------------------------------- */ 1625 1626/* define an OUTPUT typemap for 'apr_off_t *'. for now, we'll treat it as 1627 a 'long' even if that isn't entirely correct... */ 1628 1629%typemap(python,in,numinputs=0) apr_off_t * (apr_off_t temp) 1630 "$1 = &temp;"; 1631 1632%typemap(python,argout,fragment="t_output_helper") apr_off_t * 1633 "$result = t_output_helper($result,PyInt_FromLong((long) (*$1)));"; 1634 1635%typemap(perl5,argout) apr_off_t * { 1636 /* ### FIXME-perl apr_off_t out*/ 1637} 1638 1639/* ----------------------------------------------------------------------- */ 1640 1641%include apr.h 1642 1643/* ### be nice to have all the error values and macros. there are some 1644 ### problems including this file, tho. SWIG isn't smart enough with some 1645 ### of the preprocessing and thinks there is a macro redefinition */ 1646//%include apr_errno.h 1647typedef int apr_status_t; 1648 1649/* ### seems that SWIG isn't picking up the definition of size_t */ 1650typedef unsigned long size_t; 1651 1652/* Define the time type (rather than picking up all of apr_time.h) */ 1653typedef apr_int64_t apr_time_t; 1654 1655typedef apr_int32_t time_t; 1656 1657/* ----------------------------------------------------------------------- 1658 handle the mappings for apr_time_t 1659 1660 Note: we don't generalize this to 'long long' since SWIG is starting 1661 to handle that. 1662*/ 1663 1664%apply long long { apr_time_t }; 1665 1666/* 'apr_time_t *' will always be an OUTPUT parameter */ 1667%typemap(in,numinputs=0) apr_time_t * (apr_time_t temp) 1668 "$1 = &temp;"; 1669 1670%typemap(python,argout,fragment="t_output_helper") apr_time_t * 1671 "$result = t_output_helper($result, PyLong_FromLongLong(*$1));"; 1672 1673%typemap(java,argout) apr_time_t * { 1674 /* FIXME: What goes here? */ 1675} 1676 1677%typemap(perl5,argout) apr_time_t * { 1678 /* ### FIXME-perl apr_time_t out */ 1679} 1680/* ----------------------------------------------------------------------- 1681 create some INOUT typemaps for apr_size_t 1682*/ 1683 1684%apply unsigned long *INOUT { apr_size_t *INOUT }; 1685 1686%typemap(python,in) apr_size_t *INOUT (apr_size_t temp) { 1687 temp = (apr_size_t) PyInt_AsLong($input); 1688 $1 = &temp; 1689} 1690%typemap(java,in) apr_size_t *INOUT (apr_size_t temp) { 1691 temp = (apr_size_t) JCALL2(CallLongMethod, jenv, $input, svn_swig_java_mid_long_longvalue); 1692 $1 = &temp; 1693} 1694 1695%typemap(perl5,in) apr_size_t *INOUT (apr_size_t temp) { 1696 temp = (apr_size_t) SvIV($input); 1697 $1 = &temp; 1698} 1699/* ----------------------------------------------------------------------- 1700 create an OUTPUT argument typemap for an apr_hash_t ** 1701*/ 1702 1703%typemap(python,in,numinputs=0) apr_hash_t **OUTPUT (apr_hash_t *temp) 1704 "$1 = &temp;"; 1705 1706%typemap(perl5,in,numinputs=0) apr_hash_t **OUTPUT (apr_hash_t *temp) 1707 "$1 = &temp;"; 1708 1709/* ----------------------------------------------------------------------- 1710 create an OUTPUT argument defn for an apr_hash_t ** which is storing 1711 property values 1712*/ 1713 1714%typemap(python,in,numinputs=0) apr_hash_t **PROPHASH = apr_hash_t **OUTPUT; 1715%typemap(python,argout) apr_hash_t **PROPHASH { 1716 /* toss prior result, get new result from the hash */ 1717 Py_DECREF($result); 1718 $result = svn_swig_py_prophash_to_dict(*$1); 1719} 1720 1721/* ----------------------------------------------------------------------- 1722 Handle an apr_hash_t ** in Java 1723*/ 1724 1725%typemap(jni) apr_hash_t ** "jobject" 1726%typemap(jtype) apr_hash_t ** "java.util.Map" 1727%typemap(jstype) apr_hash_t ** "java.util.Map" 1728%typemap(javain) apr_hash_t ** "$javainput" 1729 1730%typemap(javaout) apr_hash_t ** { 1731 return $jnicall; 1732 } 1733 1734%typemap(java,in) apr_hash_t **(apr_hash_t *temp){ 1735 $1 = &temp; 1736} 1737 1738%typemap(java,out) apr_hash_t ** { 1739 svn_swig_java_add_to_map(jenv, *$1, $input); 1740} 1741 1742%typemap(java,argout) apr_hash_t ** { 1743 svn_swig_java_add_to_map(jenv, *$1, $input); 1744} 1745 1746%typemap(java,argout) apr_hash_t **PROPHASH { 1747 svn_swig_java_add_to_map(jenv, *$1, $input); 1748} 1749 1750/* ----------------------------------------------------------------------- 1751 Handle an apr_array_header_t * in Java 1752*/ 1753 1754%typemap(jni) apr_array_header_t * "jobject" 1755%typemap(jtype) apr_array_header_t * "java.util.List" 1756%typemap(jstype) apr_array_header_t * "java.util.List" 1757%typemap(javain) apr_array_header_t * "$javainput" 1758 1759%typemap(javaout) apr_array_header_t * { 1760 return $jnicall; 1761 } 1762 1763%typemap(java, argout) apr_array_header_t * { 1764 svn_swig_java_add_to_list(jenv, $1, $input); 1765} 1766 1767%typemap(perl5,in,numinputs=0) apr_hash_t **PROPHASH = apr_hash_t **OUTPUT; 1768%typemap(perl5,argout) apr_hash_t **PROPHASH { 1769 $result = svn_swig_pl_prophash_to_hash(*$1); 1770 argvi++; 1771} 1772/* ----------------------------------------------------------------------- 1773 handle apr_file_t * 1774*/ 1775 1776%typemap(python, in) apr_file_t * { 1777 $1 = svn_swig_py_make_file($input, _global_pool); 1778} 1779 1780%typemap(perl5, in) apr_file_t * { 1781 $1 = svn_swig_pl_make_file($input, _global_pool); 1782} 1783 1784/* ----------------------------------------------------------------------- 1785 apr_file_t ** is always an OUT param 1786*/ 1787 1788%typemap(in, numinputs=0) apr_file_t ** (apr_file_t *temp) 1789 "$1 = &temp;"; 1790 1791%typemap(python,argout,fragment="t_output_helper") apr_file_t ** 1792 "$result = t_output_helper( 1793 $result, 1794 SWIG_NewPointerObj(*$1, $*1_descriptor, 0));"; 1795 1796%typemap(perl5, argout) apr_file_t ** { 1797 ST(argvi) = sv_newmortal(); 1798 SWIG_MakePtr(ST(argvi++), (void *)*$1, $*1_descriptor,0); 1799} 1800 1801/* ----------------------------------------------------------------------- */ 1802 1803 1804Node-path: svnperl/core.i 1805Node-kind: file 1806Node-action: add 1807Prop-content-length: 10 1808Text-content-length: 10691 1809Text-content-md5: 003fc58b1e75978efa6921d3eeccac0b 1810Content-length: 10701 1811 1812PROPS-END 1813/* 1814 * core.i : SWIG interface file for various core SVN and APR components 1815 * 1816 * ==================================================================== 1817 * Copyright (c) 2000-2003 CollabNet. All rights reserved. 1818 * 1819 * This software is licensed as described in the file COPYING, which 1820 * you should have received as part of this distribution. The terms 1821 * are also available at http://subversion.tigris.org/license-1.html. 1822 * If newer versions of this license are posted there, you may use a 1823 * newer version instead, at your option. 1824 * 1825 * This software consists of voluntary contributions made by many 1826 * individuals. For exact contribution history, see the revision 1827 * history and logs, available at http://subversion.tigris.org/. 1828 * ==================================================================== 1829 */ 1830 1831%module core 1832 1833%include typemaps.i 1834 1835%{ 1836#include "svn_opt.h" 1837%} 1838 1839/* ----------------------------------------------------------------------- 1840 include svn_types.h early. other .i files will import svn_types.i which 1841 then includes svn_types.h, making further includes get skipped. we want 1842 to actually generate wrappers, so manage svn_types.h right here. 1843*/ 1844 1845/* ### for now, let's ignore this thing. */ 1846%ignore svn_prop_t; 1847 1848/* ----------------------------------------------------------------------- 1849 The following struct members have to be read-only because otherwise 1850 strings assigned to then would never be freed, resulting in memory 1851 leaks. This prevents the swig warning "Warning(451): Setting const 1852 char * member may leak memory." 1853*/ 1854%immutable svn_log_changed_path_t::copyfrom_path; 1855%immutable svn_dirent::last_author; 1856%immutable svn_error::message; 1857%immutable svn_error::file; 1858 1859%include svn_types.h 1860 1861 1862/* ----------------------------------------------------------------------- 1863 moving along... 1864*/ 1865%import apr.i 1866%import svn_types.i 1867%import svn_string.i 1868 1869/* ----------------------------------------------------------------------- 1870 completely ignore a number of functions. the presumption is that the 1871 scripting language already has facilities for these things (or they 1872 are relatively trivial). 1873*/ 1874%ignore svn_io_check_path; 1875%ignore svn_io_check_resolved_path; 1876%ignore svn_io_copy_file; 1877%ignore svn_io_copy_dir_recursively; 1878%ignore svn_io_append_file; 1879%ignore svn_io_read_length_line; 1880%ignore svn_io_file_affected_time; 1881%ignore svn_io_fd_from_file; 1882%ignore svn_io_get_dirents; 1883%ignore svn_io_run_cmd; 1884%ignore svn_io_remove_file; 1885%ignore svn_io_remove_dir; 1886%ignore svn_io_make_dir_recursively; 1887%ignore svn_io_set_file_read_only; 1888%ignore svn_io_set_file_read_write; 1889%ignore svn_io_set_file_executable; 1890%ignore svn_io_filesizes_different_p; 1891%ignore svn_io_file_printf; 1892 1893%ignore apr_check_dir_empty; 1894 1895/* bad pool convention */ 1896%ignore svn_opt_print_generic_help; 1897 1898/* scripts can do the printf, then write to a stream. we can't really 1899 handle the variadic, so ignore it. */ 1900%ignore svn_stream_printf; 1901 1902 1903/* ----------------------------------------------------------------------- 1904 these types (as 'type **') will always be an OUT param 1905*/ 1906%apply SWIGTYPE **OUTPARAM { 1907 svn_auth_baton_t **, svn_diff_t ** 1908} 1909 1910/* ----------------------------------------------------------------------- 1911 apr_size_t * is always an IN/OUT parameter in svn_io.h 1912*/ 1913%apply apr_size_t *INOUT { apr_size_t * }; 1914 1915/* ----------------------------------------------------------------------- 1916 handle the MIME type return value of svn_io_detect_mimetype() 1917*/ 1918%apply const char **OUTPUT { const char ** }; 1919 1920/* ----------------------------------------------------------------------- 1921 handle the providers array as an input type. 1922*/ 1923%typemap(python, in) apr_array_header_t *providers { 1924 svn_auth_provider_object_t *provider; 1925 int targlen; 1926 if (!PySequence_Check($input)) { 1927 PyErr_SetString(PyExc_TypeError, "not a sequence"); 1928 return NULL; 1929 } 1930 targlen = PySequence_Length($input); 1931 $1 = apr_array_make(_global_pool, targlen, sizeof(provider)); 1932 ($1)->nelts = targlen; 1933 while (targlen--) { 1934 SWIG_ConvertPtr(PySequence_GetItem($input, targlen), 1935 (void **)&provider, 1936 $descriptor(svn_auth_provider_object_t *), 1937 SWIG_POINTER_EXCEPTION | 0); 1938 APR_ARRAY_IDX($1, targlen, svn_auth_provider_object_t *) = provider; 1939 } 1940} 1941 1942/* ----------------------------------------------------------------------- 1943 fix up the svn_stream_read() ptr/len arguments 1944*/ 1945%typemap(python, in) (char *buffer, apr_size_t *len) ($*2_type temp) { 1946 if (!PyInt_Check($input)) { 1947 PyErr_SetString(PyExc_TypeError, 1948 "expecting an integer for the buffer size"); 1949 return NULL; 1950 } 1951 temp = PyInt_AsLong($input); 1952 if (temp < 0) { 1953 PyErr_SetString(PyExc_ValueError, 1954 "buffer size must be a positive integer"); 1955 return NULL; 1956 } 1957 $1 = malloc(temp); 1958 $2 = ($2_ltype)&temp; 1959} 1960%typemap(perl5, in) (char *buffer, apr_size_t *len) ($*2_type temp) { 1961 temp = SvIV($input); 1962 $1 = malloc(temp); 1963 $2 = ($2_ltype)&temp; 1964} 1965 1966/* ### need to use freearg or somesuch to ensure the string is freed. 1967 ### watch out for 'return' anywhere in the binding code. */ 1968 1969%typemap(python, argout, fragment="t_output_helper") (char *buffer, apr_size_t *len) { 1970 $result = t_output_helper($result, PyString_FromStringAndSize($1, *$2)); 1971 free($1); 1972} 1973%typemap(perl5, argout) (char *buffer, apr_size_t *len) { 1974 $result = sv_newmortal(); 1975 sv_setpvn ($result, $1, *$2); 1976 free($1); 1977 argvi++; 1978} 1979 1980/* ----------------------------------------------------------------------- 1981 fix up the svn_stream_write() ptr/len arguments 1982*/ 1983%typemap(python, in) (const char *data, apr_size_t *len) ($*2_type temp) { 1984 if (!PyString_Check($input)) { 1985 PyErr_SetString(PyExc_TypeError, 1986 "expecting a string for the buffer"); 1987 return NULL; 1988 } 1989 $1 = PyString_AS_STRING($input); 1990 temp = PyString_GET_SIZE($input); 1991 $2 = ($2_ltype)&temp; 1992} 1993%typemap(perl5, in) (const char *data, apr_size_t *len) ($*2_type temp) { 1994 $1 = SvPV($input, temp); 1995 $2 = ($2_ltype)&temp; 1996} 1997 1998%typemap(python, argout, fragment="t_output_helper") (const char *data, apr_size_t *len) { 1999 $result = t_output_helper($result, PyInt_FromLong(*$2)); 2000} 2001 2002%typemap(perl5, argout, fragment="t_output_helper") (const char *data, apr_size_t *len) { 2003 $result = newSViv(*$2); 2004 2005} 2006 2007/* auth provider convertors */ 2008 2009%typemap(perl5, in) apr_array_header_t *providers { 2010 $1 = (apr_array_header_t *) svn_swig_pl_objs_to_array($input, SWIGTYPE_p_svn_auth_provider_object_t, _global_pool); 2011} 2012 2013 2014/* ----------------------------------------------------------------------- 2015 describe how to pass a FILE* as a parameter (svn_stream_from_stdio) 2016*/ 2017%typemap(python, in) FILE * { 2018 $1 = PyFile_AsFile($input); 2019 if ($1 == NULL) { 2020 PyErr_SetString(PyExc_ValueError, "Must pass in a valid file object"); 2021 return NULL; 2022 } 2023} 2024%typemap(perl5, in) FILE * { 2025 dSP ; 2026 int count, fd ; 2027 2028 ENTER ; 2029 SAVETMPS; 2030 2031 PUSHMARK(SP) ; 2032 XPUSHs($input); 2033 PUTBACK ; 2034 2035 count = call_pv("fileno", G_SCALAR); 2036 SPAGAIN ; 2037 2038 if (count != 1) 2039 croak("Big trouble\n") ; 2040 2041 if (fd = POPi < 0) 2042 croak("not an accessible filehandle"); 2043 2044 $1 = fdopen (fd, "r+"); 2045 2046 PUTBACK ; 2047 FREETMPS ; 2048 LEAVE ; 2049} 2050 2051/* ----------------------------------------------------------------------- 2052 the second argument to svn_parse_date is unused: always pass NULL 2053*/ 2054 2055%typemap(python,in,numinputs=0) struct getdate_time *now { 2056 $1 = NULL; 2057} 2058 2059/* ignore the related structure */ 2060/* ### hmm... this structure isn't namespace protected?! */ 2061%ignore getdate_time; 2062 2063/* ----------------------------------------------------------------------- 2064 wrap some specific APR functionality 2065*/ 2066 2067apr_status_t apr_initialize(void); 2068void apr_terminate(void); 2069 2070apr_status_t apr_time_ansi_put(apr_time_t *result, time_t input); 2071 2072void apr_pool_destroy(apr_pool_t *p); 2073void apr_pool_clear(apr_pool_t *p); 2074 2075apr_status_t *apr_file_open_stdout (apr_file_t **out, apr_pool_t *pool); 2076apr_status_t *apr_file_open_stderr (apr_file_t **out, apr_pool_t *pool); 2077 2078/* ----------------------------------------------------------------------- 2079 pool functions renaming since swig doesn't take care of the #define's 2080*/ 2081%rename (svn_pool_create) svn_pool_create_ex; 2082%ignore svn_pool_create_ex_debug; 2083%typemap(default) apr_allocator_t *allocator { 2084 $1 = NULL; 2085} 2086 2087/* ----------------------------------------------------------------------- 2088 Default pool handling for perl. 2089*/ 2090#ifdef SWIGPERL 2091apr_pool_t *current_pool; 2092#endif 2093 2094/* ----------------------------------------------------------------------- 2095 wrap config functions 2096*/ 2097 2098%typemap(perl5,in,numinputs=0) apr_hash_t **cfg_hash = apr_hash_t **OUTPUT; 2099%typemap(perl5,argout) apr_hash_t **cfg_hash { 2100 ST(argvi++) = svn_swig_pl_convert_hash(*$1, SWIGTYPE_p_svn_config_t); 2101} 2102 2103%typemap(python,in,numinputs=0) apr_hash_t **cfg_hash = apr_hash_t **OUTPUT; 2104%typemap(python,argout,fragment="t_output_helper") apr_hash_t **cfg_hash { 2105 $result = t_output_helper( 2106 $result, 2107 SWIG_NewPointerObj(*$1, SWIGTYPE_p_apr_hash_t, 0)); 2108} 2109 2110/* Allow None to be passed as config_dir argument */ 2111%typemap(python,in,parse="z") const char *config_dir ""; 2112 2113#ifdef SWIGPYTHON 2114PyObject *svn_swig_py_exception_type(void); 2115#endif 2116 2117 2118/* ----------------------------------------------------------------------- */ 2119 2120%include svn_types.h 2121%include svn_pools.h 2122%include svn_version.h 2123%include svn_time.h 2124%include svn_props.h 2125%include svn_opt.h 2126%include svn_auth.h 2127%include svn_config.h 2128%include svn_version.h 2129%include svn_error_codes.h 2130 2131 2132/* SWIG won't follow through to APR's defining this to be empty, so we 2133 need to do it manually, before SWIG sees this in svn_io.h. */ 2134#define __attribute__(x) 2135 2136%include svn_io.h 2137 2138#ifdef SWIGPERL 2139%include svn_diff.h 2140#endif 2141 2142%{ 2143#include <apr.h> 2144#include <apr_general.h> 2145 2146#include "svn_io.h" 2147#include "svn_pools.h" 2148#include "svn_version.h" 2149#include "svn_time.h" 2150#include "svn_props.h" 2151#include "svn_opt.h" 2152#include "svn_auth.h" 2153#include "svn_config.h" 2154#include "svn_version.h" 2155#include "svn_md5.h" 2156#include "svn_diff.h" 2157#include "svn_error_codes.h" 2158 2159#ifdef SWIGPYTHON 2160#include "swigutil_py.h" 2161#endif 2162 2163#ifdef SWIGJAVA 2164#include "swigutil_java.h" 2165#endif 2166 2167#ifdef SWIGPERL 2168#include "swigutil_pl.h" 2169#endif 2170%} 2171 2172#ifdef SWIGPYTHON 2173%init %{ 2174/* This is a hack. I dunno if we can count on SWIG calling the module "m" */ 2175PyModule_AddObject(m, "SubversionException", 2176 svn_swig_py_register_exception()); 2177%} 2178 2179%pythoncode %{ 2180SubversionException = _core.SubversionException 2181%} 2182#endif 2183 2184Node-path: svnperl/java 2185Node-kind: dir 2186Node-action: add 2187Prop-content-length: 10 2188Content-length: 10 2189 2190PROPS-END 2191 2192 2193Node-path: svnperl/java/README 2194Node-kind: file 2195Node-action: add 2196Prop-content-length: 10 2197Text-content-length: 68 2198Text-content-md5: 78bbe491b38ccd5f68a483ef5d269e46 2199Content-length: 78 2200 2201PROPS-END 2202Subversion's SWIG/Java bindings support JDK version 1.2 and higher. 2203 2204 2205Node-path: svnperl/java/org 2206Node-kind: dir 2207Node-action: add 2208Prop-content-length: 10 2209Content-length: 10 2210 2211PROPS-END 2212 2213 2214Node-path: svnperl/java/org/tigris 2215Node-kind: dir 2216Node-action: add 2217Prop-content-length: 10 2218Content-length: 10 2219 2220PROPS-END 2221 2222 2223Node-path: svnperl/java/org/tigris/subversion 2224Node-kind: dir 2225Node-action: add 2226Prop-content-length: 10 2227Content-length: 10 2228 2229PROPS-END 2230 2231 2232Node-path: svnperl/java/org/tigris/subversion/client 2233Node-kind: dir 2234Node-action: add 2235Prop-content-length: 10 2236Content-length: 10 2237 2238PROPS-END 2239 2240 2241Node-path: svnperl/java/org/tigris/subversion/client/StandardClient.java 2242Node-kind: file 2243Node-action: add 2244Prop-content-length: 10 2245Text-content-length: 4048 2246Text-content-md5: feffc12182847e1bf2905e7698c0e937 2247Content-length: 4058 2248 2249PROPS-END 2250package org.tigris.subversion.client; 2251 2252/* 2253 * ==================================================================== 2254 * Copyright (c) 2000-2003 CollabNet. All rights reserved. 2255 * 2256 * This software is licensed as described in the file COPYING, which 2257 * you should have received as part of this distribution. The terms 2258 * are also available at http://subversion.tigris.org/license-1.html. 2259 * If newer versions of this license are posted there, you may use a 2260 * newer version instead, at your option. 2261 * 2262 * This software consists of voluntary contributions made by many 2263 * individuals. For exact contribution history, see the revision 2264 * history and logs, available at http://subversion.tigris.org/. 2265 * ==================================================================== 2266 */ 2267 2268import java.io.File; 2269import java.io.OutputStream; 2270import java.util.List; 2271 2272import org.tigris.subversion.SubversionException; 2273import org.tigris.subversion.auth.AuthProvider; 2274import org.tigris.subversion.opt.OptRevision; 2275import org.tigris.subversion.util.NativeResources; 2276import org.tigris.subversion.wc.Notifier; 2277 2278import org.tigris.subversion.swig.client; 2279import org.tigris.subversion.swig.svn_client_ctx_t; 2280import org.tigris.subversion.swig.SWIGTYPE_p_apr_file_t; 2281import org.tigris.subversion.swig.SWIGTYPE_p_apr_pool_t; 2282import org.tigris.subversion.swig.SWIGTYPE_p_svn_opt_revision_t; 2283 2284/** 2285 * A SWIG-based implementation of the {@link Client} interface. 2286 * 2287 * @since Subversion 0.31 2288 */ 2289public class StandardClient 2290 implements Client 2291{ 2292 static 2293 { 2294 NativeResources.getInstance().initialize(); 2295 } 2296 2297 /** 2298 * @see Client#getSimplePromptProvider 2299 */ 2300 public AuthProvider getSimplePromptProvider(ClientPrompt prompt, 2301 int retryLimit) 2302 { 2303 throw new RuntimeException("Not implemented"); 2304 } 2305 2306 /** 2307 * @see Client#getUsernamePromptProvider 2308 */ 2309 public AuthProvider getUsernamePromptProvider(ClientPrompt prompt, 2310 int retryLimit) 2311 { 2312 throw new RuntimeException("Not implemented"); 2313 } 2314 2315 /** 2316 * @see Client#getNotifier 2317 */ 2318 public Notifier getNotifier() 2319 { 2320 throw new RuntimeException("Not implemented"); 2321 } 2322 2323 /** 2324 * @see Client#getCommitLogReceiver 2325 */ 2326 public LogMessageReceiver getCommitLogReceiver() 2327 { 2328 throw new RuntimeException("Not implemented"); 2329 } 2330 2331 /** 2332 * @see Client#checkout 2333 */ 2334 public void checkout(String url, File path, Object revision, 2335 boolean recurse) 2336 throws SubversionException 2337 { 2338 throw new RuntimeException("Not implemented"); 2339 } 2340 2341 /** 2342 * @see Client#diff 2343 */ 2344 public void diff(List diffOptions, String path1, OptRevision revision1, 2345 String path2, OptRevision revision2, boolean recurse, 2346 boolean ignoreAncestry, boolean noDiffDeleted, 2347 OutputStream output, OutputStream error) 2348 throws SubversionException 2349 { 2350 // FIXME: How do I instantiate one of these? 2351 svn_client_ctx_t clientCtx = null; 2352 2353 // FIXME: Temporary placeholder for revision1 and revision2. 2354 SWIGTYPE_p_svn_opt_revision_t dummy = null; 2355 2356 SubversionException e = 2357 client.svn_client_diff((String []) diffOptions.toArray 2358 (new String[diffOptions.size()]), path1, 2359 dummy /*revision1*/, path2, 2360 dummy /*revision2*/, recurse, 2361 ignoreAncestry, noDiffDeleted, 2362 // TODO: Need type conversion for 2363 // output and error. 2364 (SWIGTYPE_p_apr_file_t) null, 2365 (SWIGTYPE_p_apr_file_t) null, clientCtx, 2366 (SWIGTYPE_p_apr_pool_t) null); 2367 if (e != null) 2368 { 2369 throw e; 2370 } 2371 } 2372} 2373 2374 2375Node-path: svnperl/java/org/tigris/subversion/util 2376Node-kind: dir 2377Node-action: add 2378Prop-content-length: 10 2379Content-length: 10 2380 2381PROPS-END 2382 2383 2384Node-path: svnperl/java/org/tigris/subversion/util/NativeResources.java 2385Node-kind: file 2386Node-action: add 2387Prop-content-length: 10 2388Text-content-length: 3833 2389Text-content-md5: eaf22bc9d4f42fc50ef24bf26cca1693 2390Content-length: 3843 2391 2392PROPS-END 2393package org.tigris.subversion.util; 2394 2395/* 2396 * ==================================================================== 2397 * Copyright (c) 2000-2003 CollabNet. All rights reserved. 2398 * 2399 * This software is licensed as described in the file COPYING, which 2400 * you should have received as part of this distribution. The terms 2401 * are also available at http://subversion.tigris.org/license-1.html. 2402 * If newer versions of this license are posted there, you may use a 2403 * newer version instead, at your option. 2404 * 2405 * This software consists of voluntary contributions made by many 2406 * individuals. For exact contribution history, see the revision 2407 * history and logs, available at http://subversion.tigris.org/. 2408 * ==================================================================== 2409 */ 2410 2411import org.tigris.subversion.swig.core; 2412import org.tigris.subversion.swig.SWIGTYPE_p_apr_pool_t; 2413import org.tigris.subversion.swig.SWIGTYPE_p_apr_allocator_t; 2414 2415/** 2416 * Handles operations involving the native libraries composing 2417 * Subversion's implementation. 2418 * 2419 * @since Subversion 0.31 2420 */ 2421public class NativeResources 2422{ 2423 private static NativeResources instance; 2424 static 2425 { 2426 String className = System.getProperty(NativeResources.class.getName()); 2427 if (className != null && className.length() > 0) 2428 { 2429 try 2430 { 2431 Class c = Class.forName(className); 2432 instance = (NativeResources) c.newInstance(); 2433 } 2434 catch (Exception useDefault) 2435 { 2436 // Likely an UnsatisfiedLinkError. 2437 System.err.println("NativeResources '" + className + '\'' + 2438 " not available, falling back to '" + 2439 NativeResources.class.getName() + '\''); 2440 } 2441 } 2442 2443 if (instance == null) 2444 { 2445 instance = new NativeResources(); 2446 } 2447 } 2448 2449 /** 2450 * Whether the native libraries have been loaded and initialized. 2451 */ 2452 protected boolean isInitialized = false; 2453 2454 /** 2455 * The APR pool used for native code memory management. 2456 */ 2457 private SWIGTYPE_p_apr_pool_t pool; 2458 2459 /** 2460 * Returns the single instance of this class for this 2461 * <code>ClassLoader</code> tree. 2462 */ 2463 public static NativeResources getInstance() 2464 { 2465 return instance; 2466 } 2467 2468 /** 2469 * Default constructor, scoped to prevent direct instantiation. 2470 * @see #getInstance() 2471 */ 2472 protected NativeResources() 2473 { 2474 } 2475 2476 /** 2477 * Loads and initializes the native libraries used by this 2478 * instance. 2479 */ 2480 public synchronized void initialize() 2481 { 2482 if (this.isInitialized) 2483 { 2484 return; 2485 } 2486 2487 // Load the SWIG-based JNI bindings. 2488 System.loadLibrary("swigjava"); 2489 2490 // Initialize the Apache Portable Runtime used by Subversion's 2491 // C implementation. 2492 core.apr_initialize(); 2493 2494 System.out.println("Allocating parent pool"); 2495 this.pool = core.svn_pool_create((SWIGTYPE_p_apr_pool_t) null, 2496 (SWIGTYPE_p_apr_allocator_t) null); 2497 2498 this.isInitialized = true; 2499 } 2500 2501 public Object getMemoryManager() 2502 { 2503 return pool; 2504 } 2505 2506 /** 2507 * Unloads and un-initializes the native libraries used by this 2508 * instance. 2509 */ 2510 public synchronized void uninitialize() 2511 { 2512 System.out.println("Destroying parent pool"); 2513 core.apr_pool_destroy(this.pool); 2514 2515 core.apr_terminate(); 2516 2517 this.isInitialized = false; 2518 } 2519 2520 /** 2521 * @see #uninitialize 2522 */ 2523 protected void finalize() 2524 throws Throwable 2525 { 2526 try 2527 { 2528 super.finalize(); 2529 } 2530 finally 2531 { 2532 uninitialize(); 2533 } 2534 } 2535} 2536 2537 2538Node-path: svnperl/perl 2539Node-kind: dir 2540Node-action: add 2541Prop-content-length: 10 2542Content-length: 10 2543 2544PROPS-END 2545 2546 2547Node-path: svnperl/perl/Base.pm 2548Node-kind: file 2549Node-action: add 2550Prop-content-length: 35 2551Text-content-length: 3205 2552Text-content-md5: 3f435f0f269a582ed14eceb38e0109a9 2553Content-length: 3240 2554 2555K 12 2556svn:keywords 2557V 2 2558Id 2559PROPS-END 2560package SVN::Base; 2561 2562=head1 NAME 2563 2564SVN::Base - Base class for importing symbols for svn modules 2565 2566=head1 SYNOPSIS 2567 2568 # Load the svn_ra_* functions into the SVN::Ra namespace. 2569 pacakge SVN::Ra; 2570 use SVN::Base qw(Ra svn_ra_); 2571 2572 # Load svn_config_t structure accessors in the magic namcespace 2573 # provided by swig, so we could use it returned by other functions 2574 package _p_svn_config_t; 2575 use SVN::Base qw(Core svn_config_); 2576 2577=head1 DESCRIPTION 2578 2579SVN::Base is a module importing the subversion perl bindings raw 2580symbols created by swig, into proper namespace and make them easier to 2581use. 2582 2583It will also find the accessors for members of a C struct, create an 2584simpler accessor function like C<$data-E<gt>field()> and 2585C<$data-E<gt>field($new_value)>. 2586 2587Once you understand the convention of subversion functions in perl 2588bindings, you could look at the subversion api and write them in perl. 2589The API is available in the source header files or online at 2590http://svn.collab.net/svn-doxygen/. 2591 2592=head1 INTERNALS 2593 2594The perl bindings of swig wraps raw functions into different perl 2595modules, for example, SVN::_Core, SVN::_Repos. Upon import, SVN::Base 2596bootstrap the requested module if it's not yet loaded, and iterate 2597over the symbols provided in that module, it them puts the function 2598with prefix trimmed in the namespace of the caller for this import. 2599 2600The 3rd through the last parameter is a list of symbol endings that 2601you wish for SVN::Base not to import into your namespace. This is useful 2602for cases where you may want to import certaion symbols differently than 2603normally. 2604 2605=head1 CAVEATS 2606 2607SVN::Base consider a function as structure member accessor if it is 2608postfixed ``_get'' or ``_set''. Real functions with this postfixes 2609will need extra handling. 2610 2611=cut 2612 2613sub import { 2614 my (undef, $pkg, $prefix, @ignore) = @_; 2615 no warnings 'uninitialized'; 2616 unless (${"SVN::_${pkg}::ISA"}[0] eq 'DynaLoader') { 2617 @{"SVN::_${pkg}::ISA"} = qw(DynaLoader); 2618 eval qq' 2619package SVN::_$pkg; 2620require DynaLoader; 2621bootstrap SVN::_$pkg; 26221; 2623 ' or die $@; 2624 }; 2625 2626 my $caller = caller(0); 2627 2628 SYMBOL: for (keys %{"SVN::_${pkg}::"}) { 2629 my $name = $_; 2630 next unless s/^$prefix//i; 2631 foreach my $ignored_symbol (@ignore) { 2632 next SYMBOL if ("$prefix$ignored_symbol" eq $name); 2633 } 2634 2635 # insert the accessor 2636 if (m/(.*)_get$/) { 2637 my $member = $1; 2638 *{"${caller}::$1"} = sub { 2639 &{"SVN::_${pkg}::${prefix}${member}_". 2640 (@_ > 1 ? 'set' : 'get')} (@_) 2641 } 2642 } 2643 elsif (m/(.*)_set$/) { 2644 } 2645 else { 2646 *{"${caller}::$_"} = ${"SVN::_${pkg}::"}{$name}; 2647 } 2648 } 2649 2650} 2651 2652=head1 AUTHORS 2653 2654Chia-liang Kao E<lt>clkao@clkao.orgE<gt> 2655 2656=head1 COPYRIGHT 2657 2658Copyright (c) 2003 CollabNet. All rights reserved. 2659 2660This software is licensed as described in the file COPYING, which you 2661should have received as part of this distribution. The terms are also 2662available at http://subversion.tigris.org/license-1.html. If newer 2663versions of this license are posted there, you may use a newer version 2664instead, at your option. 2665 2666This software consists of voluntary contributions made by many 2667individuals. For exact contribution history, see the revision history 2668and logs, available at http://subversion.tigris.org/. 2669 2670=cut 2671 26721; 2673 2674 2675Node-path: svnperl/perl/Client.pm 2676Node-kind: file 2677Node-action: add 2678Prop-content-length: 35 2679Text-content-length: 15544 2680Text-content-md5: a70873df186fb9dda0c7b4f102f58e78 2681Content-length: 15579 2682 2683K 12 2684svn:keywords 2685V 2 2686Id 2687PROPS-END 2688use SVN::Core; 2689 2690package SVN::Client; 2691use SVN::Base(qw(Client svn_client_ checkout update switch add mkdir delete 2692 commit status log blame diff merge cleanup relocate 2693 revert resolved copy move revprop_set propset 2694 proplist revvprop_list export ls cat import)); 2695 2696=head1 NAME 2697 2698SVN::Client - Subversion client functions 2699 2700=head1 SYNOPSIS 2701 2702 use SVN::Client; 2703 my $ctx = new SVN::Client( 2704 auth => [SVN::Client::get_simple_provider(), 2705 SVN::Client::get_simple_prompt_provider(\&simple_prompt,2), 2706 SVN::Client::get_username_provider()] 2707 ); 2708 2709 $ctx->cat (\*STDOUT, 'http://svn.collab.net/repos/svn/trunk/README', 2710 'HEAD'); 2711 2712 sub simple_prompt { 2713 my $cred = shift; 2714 my $realm = shift; 2715 my $default_username = shift; 2716 my $may_save = shift; 2717 my $pool = shift; 2718 2719 print "Enter authentication info for realm: $realm\n"; 2720 print "Username: "; 2721 my $username = <>; 2722 chop($username); 2723 $cred->username($username); 2724 print "Password: "; 2725 my $password = <>; 2726 chomp($password); 2727 $cred->password($password); 2728 } 2729 2730=head1 DESCRIPTION 2731 2732SVN::Client wraps the highest level of functions provided by 2733subversion to accomplish specific tasks in an object oriented API. 2734Methods are similar to the functions provided by the C API and 2735as such the documentation for it may be helpful in understanding 2736this interface. 2737 2738There are a few notable differences from the C API. Most C function 2739calls take a svn_client_ctx_t pointer as the next to last parameter. 2740The perl method calls take a SVN::Client object as the first parameter. 2741This allows method call invocation of the methods to be possible. 2742 2743Many of the C API calls also take a apr_pool_t pointer as their last 2744argument. The Perl bindings generally deal with this for you and 2745you do not need to pass a pool parameter. However, you may still 2746pass a pool parameter as the last parameter to override the automatic 2747handling of this for you. 2748 2749Users of this interface should not directly manipulate the underlying hash 2750values but should use the respective attribute methods. Many of these 2751attribute methods do other things, especially when setting an attribute, 2752besides simply manipulating the value in the hash. 2753 2754=head1 METHODS 2755 2756The following methods are available: 2757 2758=over 4 2759 2760=item $ctx = SVN::Client->new( %options ); 2761 2762This class method constructs a new C<SVN::Client> object and returns 2763a reference to it. 2764 2765Key/value pair arguments may be provided to set up the initial state 2766of the user agent. The following methods correspond to attribute 2767methods described below: 2768 2769 KEY DEFAULT 2770 ---------- ---------------------------------------- 2771 config Hash containing the config from the 2772 default subversion config file location. 2773 2774 auth auth_baton intiated to provide the 2775 provider that read cached authentication 2776 options from the subversion config only. 2777 2778 pool A new pool is created for the context. 2779 2780=cut 2781 2782sub new 2783{ 2784 my $class = shift; 2785 my $self = bless {}, $class; 2786 my %args = @_; 2787 2788 $self->{'ctx'} = SVN::_Client::new_svn_client_ctx_t (); 2789 2790 if (defined($args{'auth'})) 2791 { 2792 $self->auth($args{'auth'}); 2793 } else { 2794 $self->auth([SVN::Client::get_username_provider(), 2795 SVN::Client::get_simple_provider(), 2796 SVN::Client::get_ssl_server_trust_file_provider(), 2797 SVN::Client::get_ssl_client_cert_file_provider(), 2798 SVN::Client::get_ssl_client_cert_pw_file_provider(), 2799 ]); 2800 } 2801 2802 { 2803 my $pool_type = ref($args{'pool'}); 2804 if ($pool_type eq 'SVN::Pool' || 2805 $pool_type eq '_p_apr_pool_t') 2806 { 2807 $self->{'pool'} = $args{'pool'}; 2808 } else { 2809 $self->{'pool'} = new SVN::Pool(); 2810 } 2811 } 2812 2813 # If we're passed a config use it, otherwise get the default 2814 # config. 2815 if (defined($args{'config'})) 2816 { 2817 if (ref($args{'config'}) eq 'HASH') 2818 { 2819 $self->config($args{'config'}); 2820 } 2821 } else { 2822 $self->config(SVN::Core::config_get_config(undef)); 2823 } 2824 return $self; 2825} 2826 2827=item $ctx->cat(\*FILEHANDLE, path_or_url, revision, pool); 2828 2829Outputs the content of the file identified by path_or_url and revision to the 2830FILEHANDLE. FILEHANLDE is a reference to a filehandle. revision should be a 2831number or 'HEAD'. pool is an optional parameter. 2832 2833=cut 2834 2835# import methods into our name space and wrap them in a closure 2836# to support method calling style $ctx->log() 2837foreach my $function (qw(checkout update switch add mkdir delete commit 2838 status log blame diff merge cleanup relocate 2839 revert resolved copy move revprop_set propset 2840 proplist revvprop_list export ls cat import)) 2841{ 2842 2843 my $real_function = \&{"SVN::_Client::svn_client_$function"}; 2844 *{"SVN::Client::$function"} = sub 2845 { 2846 # Allows import to work while not breaking use SVN::Client. 2847 if ($function eq 'import') 2848 { 2849 if (ref($_[$[]) ne 'SVN::Client') 2850 { 2851 return; 2852 } 2853 } 2854 2855 my $self = shift; 2856 my @args; 2857 2858 if (ref($_[$#_]) eq '_p_apr_pool_t') 2859 { 2860 # if we got a pool pased to us we need to 2861 # leave it off until we add the ctx first 2862 # so we push only the first arg to the next 2863 # to last arg. 2864 push @args, @_[$[ .. ($#_ - 1)]; 2865 unless ($function eq 'propset') 2866 { 2867 # propset doesn't take a ctx argument 2868 push @args, $self->{'ctx'}; 2869 } 2870 push @args, $_[$#_]; 2871 } else { 2872 push @args, @_; 2873 unless ($function eq 'propset') 2874 { 2875 push @args,$self->{'ctx'}; 2876 } 2877 if (defined($self->{'pool'}) && 2878 ref($self->{'pool'}) eq '_p_apr_pool_t') 2879 { 2880 # allow the pool entry in the SVN::Client 2881 # object to override the default pool. 2882 push @args, $self->{'pool'}; 2883 } 2884 } 2885 return $real_function->(@args); 2886 } 2887} 2888 2889=head1 ATTRIBUTE METHODS 2890 2891The following attribute methods are provided that allow you to set various 2892configuration or retrieve it. They all take value(s) to set the attribute and 2893return the new value of the attribute or no paremeters which reuturns the 2894current value. 2895 2896=item $ctx->auth(SVN::Client::get_username_provider()); 2897 2898Provides access the auth_baton in the svn_client_ctx_t attached to the 2899SVN::Client object. 2900 2901This method will accept an array or array ref of values returned from the 2902authentication provider functions see L</"AUTHENTICATION PROVIDERS">. Which it 2903will convert to an auth_baton for you. This is the preferred method of setting 2904the auth_baton. 2905 2906It will also accept a scalar that references a _p_svn_auth_baton_t such as 2907those returned from SVN::Core::auth_open and SVN::Core::auth_open_helper. 2908 2909=cut 2910 2911sub auth 2912{ 2913 my $self = shift; 2914 my $args; 2915 if (scalar(@_) == 0) 2916 { 2917 return $self->{'ctx'}->auth_baton(); 2918 } elsif (scalar(@_) > 1) { 2919 $args = \@_; 2920 } else { 2921 $args = shift; 2922 if (ref($args) eq '_p_svn_auth_baton_t') 2923 { 2924 # 1 arg as an auth_baton so just set 2925 # the baton. 2926 $self->{'ctx'}->auth_baton($args); 2927 return $self->{'ctx'}->auth_baton(); 2928 } 2929 } 2930 2931 my ($auth_baton,$callbacks) = SVN::Core::auth_open_helper($args); 2932 $self->{'auth_provider_callbacks'} = $callbacks; 2933 $self->{'ctx'}->auth_baton($auth_baton); 2934 return $self->{'ctx'}->auth_baton(); 2935} 2936 2937=item $ctx->pool(new SVN::Pool); 2938 2939Method that sets or gets the pool that is passed to method calls requiring a 2940pool but that you didn't pass one. 2941 2942See L<SVN::Core> for more information about how pools are managed 2943in this interface. 2944 2945=cut 2946 2947sub pool 2948{ 2949 my $self = shift; 2950 2951 if (scalar(@_) == 0) 2952 { 2953 $self->{'pool'}; 2954 } else { 2955 return $self->{'pool'} = shift; 2956 } 2957} 2958 2959=item $ctx->config(SVN::Core::config_get_config(undef)); 2960 2961Method that allows access to the config member of the svn_client_ctx_t. 2962Accepts a perl hash to set, which is what functions like 2963SVN::Core:config_get_config() will return. 2964 2965It will return a _p_arp_hash_t scalar. THis is a temporary 2966situation. The return value is not particular useful. In 2967the future, this value will be tied to the actual hash used 2968by the C API. 2969 2970=cut 2971 2972sub config 2973{ 2974 my $self = shift; 2975 if (scalar(@_) == 0) { 2976 return $self->{'ctx'}->config(); 2977 } else { 2978 $self->{'ctx'}->config(shift); 2979 return $self->{'ctx'}->config(); 2980 } 2981} 2982 2983 2984=head1 AUTHENTICATION PROVIDERS 2985 2986The following functions get authentication providers for you. 2987They come in two forms. Standard or File versions, which look 2988for authentication information in the subversion configuration 2989directory that was previously cached, or Prompt versions which 2990call a subroutine to allow you to prompt the user for the 2991information. 2992 2993The functions that return the provider objects for prompt style providers 2994take a reference to a perl subroutine to use for the callback. The first 2995parameter each of these subroutines receive is a credential object. The 2996subroutines return the response by setting members of that object. Members 2997may be set like so: $cred->username("breser"); These functions and credential 2998objects always have a may_save member which specifies if the authentication 2999data will be cached. 3000 3001The providers are as follows: 3002 3003 NAME WHAT IT HANDLES 3004 ---------------- ---------------------------------------- 3005 simple username and password pairs 3006 3007 username username only 3008 3009 ssl_server_trust server certificates and failures 3010 authenticating them 3011 3012 ssl_client_cert client side certificate files 3013 3014 ssl_client_cert_pw password for a client side certificate file. 3015 3016 3017=over 4 3018 3019=item SVN::Client::get_simple_provider 3020 3021Returns a simple provider that returns information from previously cached 3022sessions. Takes no parameters or one pool parameter. 3023 3024=item SVN::Client::get_simple_prompt_provider 3025 3026Returns a simple provider that prompts the user via a callback. Takes two or 3027three parameters, the first is the callback subroutine, the 2nd is the number 3028of retries to allow, the 3rd is optionally a pool. The subroutine gets called 3029with the following parameters. A svn_auth_cred_simple object, a realm string, 3030a default username, may_save, and a pool. The svn_auth_cred_simple has the 3031following members: username, password, and may_save. 3032 3033=item SVN::Client::get_username_provider 3034 3035Returns a username provider that returns information from a previously cached 3036sessions. Takes no parameters or one pool parameter. 3037 3038=item SVN::Client::get_username_prompt_provider 3039 3040Returns a username provider that prompts the user via a callback. Takes two or 3041three parameters, the first is the callback subroutine, the 2nd is the number 3042of retries to allow, the 3rd is optionally a pool. The subroutine gets called 3043with the following parameters. A svn_auth_cred_username object, a realm 3044string, a default username, may_save, and a pool. The svn_auth_cred_username 3045has the following members: username and may_save. 3046 3047=item SVN::Client::get_ssl_server_trust_file_provider 3048 3049Returns a server trust provider that returns infromation from previously 3050cached sessions. Takes no parameters or optionally a pool parameter. 3051 3052=item SVN::Client::get_ssl_server_trust_prompt_provider 3053 3054Returns a server trust provider that prompts the user via a callback. Takes 3055one or two parameters the callback subroutine and optionally a pool parameter. 3056The subroutine gets called with the following parameters. A 3057svn_auth_cred_ssl_server_trust object, a realm string, an integer specifiying 3058how the certificate failed authentication, a cert info object, may_save, and a 3059pool. The svn_auth_cred_ssl_server_trust object has the following members: 3060may_save and accepted_failures. The svn_ssl_cert_info object has the following 3061members (and behaves just like cred objects though you can't modify it): 3062hostname, fingerprint, valid_from, valid_until, issuer_dname, ascii_cert. 3063 3064The masks used for determaning the failures are in SVN::_Core and are named: 3065 3066$SVN::_Core::SVN_AUTH_SSL_NOTYETVALID 3067$SVN::_Core::SVN_AUTH_SSL_EXPIRED 3068$SVN::_Core::SVN_AUTH_SSL_CNMISMATCH 3069$SVN::_Core::SVN_AUTH_SSL_UNKNOWNCA 3070$SVN::_Core::SVN_AUTH_SSL_OTHER 3071 3072You reply by setting the accepted_failures of the cred object with an integer 3073of the values for what you want to accept bitwise anded together. 3074 3075=item SVN::Client::get_ssl_cert_file_provider 3076 3077Returns a client certificate provider that returns infromation from previously 3078cached sessions. Takes no parameters or optionally a pool parameter. 3079 3080=item SVN::Client::get_ssl_cert_prompt_provider 3081 3082Returns a client certificate provider that prompts the user via a callback. 3083Takes two or three parameters, the first is the callback subroutine, the 2nd is 3084the number of retries to allow, the 3rd is optionally a pool parameter. The 3085subroutine gets called with the following parameters. A 3086svn_auth_cred_ssl_client_cert object, a realm string, may_save, and a pool. 3087The svn_auth_cred_ssl_client_cert the following members: cert_file and 3088may_save. 3089 3090=item SVN::Client::get_ssl_cert_pw_file_provider 3091 3092Returns a client certificate password provider that returns infromation from 3093previously cached sessions. Takes no parameters or optionally a pool 3094paramater. 3095 3096=item SVN::Client::get_ssl_cert_pw_prompt_provider 3097 3098Returns a client certificate passowrd provider that prompts the user via a 3099callback. Takes two or three parameters, the first is the callback subroutine, 3100the 2nd is the number of retries to allow, the 3rd is optionally a pool 3101parameter. The subroutine gets called with the following parameters. A 3102svn_auth_cred_ssl_client_cert_pw object, a realm string, may_save, and a pool. 3103The svn_auth_cred_ssl_client_cert_pw has the following members: password and 3104may_save. 3105 3106=cut 3107 3108package _p_svn_client_commit_info_t; 3109use SVN::Base qw(Client svn_client_commit_info_t_); 3110 3111package _p_svn_client_commit_item_t; 3112use SVN::Base qw(Client svn_client_commit_item_t_); 3113 3114package _p_svn_client_ctx_t; 3115use SVN::Base qw(Client svn_client_ctx_t_); 3116 3117package _p_svn_client_proplist_item_t; 3118use SVN::Base qw(Client svn_client_proplist_item_t_); 3119 3120=head1 TODO 3121 3122* Complete documentation 3123 3124* Support for the notify callback. 3125 3126* Support for the log_msg callback. 3127 3128* Better support for the config. 3129 3130* More unit tests. 3131 3132=head1 AUTHORS 3133 3134Chia-liang Kao E<lt>clkao@clkao.orgE<gt> 3135Ben Reser E<lt>ben@reser.orgE<gt> 3136 3137=head1 COPYRIGHT 3138 3139Copyright (c) 2003 CollabNet. All rights reserved. 3140 3141This software is licensed as described in the file COPYING, which you 3142should have received as part of this distribution. The terms are also 3143available at http://subversion.tigris.org/license-1.html. If newer 3144versions of this license are posted there, you may use a newer version 3145instead, at your option. 3146 3147This software consists of voluntary contributions made by many 3148individuals. For exact contribution history, see the revision history 3149and logs, available at http://subversion.tigris.org/. 3150 3151=cut 3152 31531; 3154 3155 3156Node-path: svnperl/perl/Core.pm 3157Node-kind: file 3158Node-action: add 3159Prop-content-length: 35 3160Text-content-length: 10213 3161Text-content-md5: 5f220f02b6616942c8fc26216d362a32 3162Content-length: 10248 3163 3164K 12 3165svn:keywords 3166V 2 3167Id 3168PROPS-END 3169package SVN::Core; 3170use SVN::Base qw(Core svn_); 3171$VERSION = "$VER_MAJOR.$VER_MINOR.$VER_MICRO"; 3172use strict; 3173 3174=head1 NAME 3175 3176SVN::Core - Core module of the subversion perl bindings 3177 3178=head1 SYNOPSIS 3179 3180 require SVN::Core; # does apr_initialize and cleanup for you 3181 3182 # create a root pool and set it as default pool for later use 3183 my $pool = SVN::Pool->new_default; 3184 3185 sub something { 3186 # create a subpool of the current default pool 3187 my $pool = SVN::Pool->new_default_sub; 3188 # some svn operations... 3189 3190 # $pool gets destroyed and the previous default pool 3191 # is restored when $pool's lexical scope ends 3192 } 3193 3194 # svn_stream_t as native perl io handle 3195 my $stream = $txn->root->apply_text('trunk/filea', undef); 3196 print $stream $text; 3197 close $stream; 3198 3199 # native perl io handle as svn_stream_t 3200 SVN::Repos::dump_fs($repos, \*STDOUT, \*STDERR, 3201 0, $repos->fs->youngest_rev, 0); 3202 3203=head1 DESCRIPTION 3204 3205SVN::Core implements higher level functions of fundamental subversion 3206functions. 3207 3208=head1 FUNCTIONS 3209 3210=over 4 3211 3212=cut 3213 3214BEGIN { 3215 SVN::_Core::apr_initialize; 3216 3217} 3218 3219END { 3220 SVN::_Core::apr_terminate; 3221} 3222 3223=item SVN::Core::auth_open([auth provider array]); 3224 3225Takes a reference to an array of authentication providers 3226and returns an auth_baton. If you use prompt providers 3227you can not use this function, but need to use the 3228auth_open_helper. 3229 3230=item SVN::Core::auth_open_helper([auth provider array); 3231 3232Prompt providers return two values instead of one. The 32332nd paramaeter is a reference to whatever was passed into 3234them as the callback. auth_open_helper splits up these 3235arguments, passing the provider objects into auth_open 3236which gives it an auth_baton and putting the other 3237ones in an array. The first return value of this 3238function is the auth_baton, the second is a reference 3239to an array containing the references to the callbacks. 3240 3241These callback arrays should be stored in the object 3242the auth_baton is attached to. 3243 3244=cut 3245 3246sub auth_open_helper { 3247 my $args = shift; 3248 my (@auth_providers,@auth_callbacks); 3249 3250 foreach my $arg (@{$args}) { 3251 if (ref($arg) eq '_p_svn_auth_provider_object_t') { 3252 push @auth_providers, $arg; 3253 } else { 3254 push @auth_callbacks, $arg; 3255 } 3256 } 3257 my $auth_baton = SVN::Core::auth_open(\@auth_providers); 3258 return ($auth_baton,\@auth_callbacks); 3259} 3260 3261package _p_svn_stream_t; 3262use SVN::Base qw(Core svn_stream_); 3263 3264package SVN::Stream; 3265use IO::Handle; 3266our @ISA = qw(IO::Handle); 3267 3268=head1 OTHER OBJECTS 3269 3270=over 4 3271 3272=head2 svn_stream_t - SVN::Stream 3273 3274You can use native perl io handles (including io globs) as 3275svn_stream_t in subversion functions. Returned svn_stream_t are also 3276translated into perl io handles, so you could access them with regular 3277print, read, etc. 3278 3279Note that some functions takes a stream to read or write, while it 3280does not close it but still hold the reference to the handle. In this case 3281the handle won't be destroyed properly. You should always use correct 3282default pool before calling such functions. 3283 3284=cut 3285 3286use Symbol (); 3287 3288sub new 3289{ 3290 my $class = shift; 3291 my $self = bless Symbol::gensym(), ref($class) || $class; 3292 tie *$self, $self; 3293 *$self->{svn_stream} = shift; 3294 $self; 3295} 3296 3297sub svn_stream { 3298 my $self = shift; 3299 *$self->{svn_stream}; 3300} 3301 3302sub TIEHANDLE 3303{ 3304 return $_[0] if ref($_[0]); 3305 my $class = shift; 3306 my $self = bless Symbol::gensym(), $class; 3307 *$self->{svn_stream} = shift; 3308 $self; 3309} 3310 3311sub CLOSE 3312{ 3313 my $self = shift; 3314 *$self->{svn_stream}->close 3315 if *$self->{svn_stream}; 3316 undef *$self->{svn_stream}; 3317} 3318 3319sub GETC 3320{ 3321 my $self = shift; 3322 my $buf; 3323 return $buf if $self->read($buf, 1); 3324 return undef; 3325} 3326 3327sub print 3328{ 3329 my $self = shift; 3330 $self->WRITE ($_[0], length ($_[0])); 3331} 3332 3333sub PRINT 3334{ 3335 my $self = shift; 3336 if (defined $\) { 3337 if (defined $,) { 3338 $self->print(join($,, @_).$\); 3339 } else { 3340 $self->print(join("",@_).$\); 3341 } 3342 } else { 3343 if (defined $,) { 3344 $self->print(join($,, @_)); 3345 } else { 3346 $self->print(join("",@_)); 3347 } 3348 } 3349} 3350 3351sub PRINTF 3352{ 3353 my $self = shift; 3354 my $fmt = shift; 3355 $self->print(sprintf($fmt, @_)); 3356} 3357 3358sub getline 3359{ 3360 my $self = shift; 3361 *$self->{pool} ||= SVN::Core::pool_create (undef); 3362 my ($buf, $eof) = *$self->{svn_stream}->readline ($/, *$self->{pool}); 3363 return undef if $eof && !$buf; 3364 return $eof ? $buf : $buf.$/; 3365} 3366 3367sub getlines 3368{ 3369 die "getlines() called in scalar context\n" unless wantarray; 3370 my $self = shift; 3371 my($line, @lines); 3372 push @lines, $line while defined($line = $self->getline); 3373 return @lines; 3374} 3375 3376sub READLINE 3377{ 3378 my $self = shift; 3379 unless (defined $/) { 3380 my $buf = ''; 3381 while (my $chunk = *$self->{svn_stream}->read 3382 ($SVN::Core::STREAM_CHUNK_SIZE)) { 3383 $buf .= $chunk; 3384 } 3385 return $buf; 3386 } 3387 elsif (ref $/) { 3388 return *$self->{svn_stream}->read (${$/}) || undef; 3389 } 3390 return wantarray ? $self->getlines : $self->getline; 3391} 3392 3393sub READ { 3394 my $self = shift; 3395 my $len = $_[1]; 3396 if (@_ > 2) { # read offset 3397 substr($_[0],$_[2]) = *$self->{svn_stream}->read ($len); 3398 } else { 3399 $_[0] = *$self->{svn_stream}->read ($len); 3400 } 3401 return $len; 3402} 3403 3404sub WRITE { 3405 my $self = shift; 3406 my $slen = length($_[0]); 3407 my $len = $slen; 3408 my $off = 0; 3409 3410 if (@_ > 1) { 3411 $len = $_[1] if $_[1] < $len; 3412 if (@_ > 2) { 3413 $off = $_[2] || 0; 3414 die "Offset outside string" if $off > $slen; 3415 if ($off < 0) { 3416 $off += $slen; 3417 die "Offset outside string" if $off < 0; 3418 } 3419 my $rem = $slen - $off; 3420 $len = $rem if $rem < $len; 3421 } 3422 *$self->{svn_stream}->write (substr ($_[0], $off, $len)); 3423 } 3424 return $len; 3425} 3426 3427*close = \&CLOSE; 3428 3429sub FILENO { 3430 return undef; # XXX perlfunc says this means the file is closed 3431} 3432 3433sub DESTROY { 3434 my $self = shift; 3435 $self->close; 3436} 3437 3438package _p_apr_pool_t; 3439 3440my %WRAPPED; 3441 3442sub default { 3443 my ($pool) = @_; 3444 my $pobj = SVN::Pool->_wrap ($$pool); 3445 $WRAPPED{$pool} = $pobj; 3446 $pobj->default; 3447} 3448 3449sub DESTROY { 3450 my ($pool) = @_; 3451 delete $WRAPPED{$pool}; 3452} 3453 3454package SVN::Pool; 3455use SVN::Base qw/Core svn_pool_/; 3456 3457=back 3458 3459=over 4 3460 3461=head2 svn_pool_t - SVN::Pool 3462 3463The perl bindings significantly simplify the usage of pools, without 3464making them not manually adjustable. 3465 3466Functions requiring pool as the last argument (which are, almost all 3467of the subversion functions), the pool is optionally. the default pool 3468is used if it is omitted. If default pool is not set, a new root pool 3469will be created and set as default automatically when the first 3470function requiring a default pool is called. 3471 3472For callback functions providing pool to your subroutine, you could 3473also use $pool->default to make it the default pool in the scope. 3474 3475=head3 Methods 3476 3477=over 3478 3479=item new ([$parent]) 3480 3481Create a new pool. The pool is a root pool if $parent is not supplied. 3482 3483=item new_default ([$parent]) 3484 3485Create a new pool. The pool is a root pool if $parent is not supplied. 3486Set the new pool as default pool. 3487 3488=item new_default_sub 3489 3490Create a new subpool of the current default pool, and set the 3491resulting pool as new default pool. 3492 3493=item clear 3494 3495Clear the pool. 3496 3497=item destroy 3498 3499Destroy the pool. if the pool is the default pool, restore the 3500previous default pool as default. This is normally called 3501automatically when the SVN::Pool object is no longer used and 3502destroyed by the perl garbage collector. 3503 3504=back 3505 3506=cut 3507 3508no strict 'refs'; 3509*{"apr_pool_$_"} = *{"SVN::_Core::apr_pool_$_"} 3510 for qw/clear destroy/; 3511 3512my @POOLSTACK; 3513 3514sub new { 3515 my ($class, $parent) = @_; 3516 $parent = $$parent if ref ($parent) eq 'SVN::Pool'; 3517 my $self = bless \create ($parent), $class; 3518 return $self; 3519} 3520 3521sub new_default_sub { 3522 my $parent = ref ($_[0]) ? ${+shift} : $SVN::_Core::current_pool; 3523 my $self = SVN::Pool->new_default ($parent); 3524 return $self; 3525} 3526 3527sub new_default { 3528 my $self = new(@_); 3529 $self->default; 3530 return $self; 3531} 3532 3533sub default { 3534 my $self = shift; 3535 push @POOLSTACK, $SVN::_Core::current_pool 3536 unless $$SVN::_Core::current_pool == 0; 3537 $SVN::_Core::current_pool = $$self; 3538} 3539 3540sub clear { 3541 my $self = shift; 3542 apr_pool_clear ($$self); 3543} 3544 3545my $globaldestroy; 3546 3547END { 3548 $globaldestroy = 1; 3549} 3550 3551my %WRAPPOOL; 3552 3553# Create a cloned _p_apr_pool_t pointing to the same apr_pool_t 3554# but on different address. this allows pools that are from C 3555# to have proper lifetime. 3556sub _wrap { 3557 my ($class, $rawpool) = @_; 3558 my $pool = \$rawpool; 3559 bless $pool, '_p_apr_pool_t'; 3560 my $npool = \$pool; 3561 bless $npool, $class; 3562 $WRAPPOOL{$npool} = 1; 3563 $npool; 3564} 3565 3566sub DESTROY { 3567 return if $globaldestroy; 3568 my $self = shift; 3569 if ($$self eq $SVN::_Core::current_pool) { 3570 $SVN::_Core::current_pool = pop @POOLSTACK; 3571 } 3572 if (exists $WRAPPOOL{$self}) { 3573 delete $WRAPPOOL{$self}; 3574 } 3575 else { 3576 apr_pool_destroy ($$self) 3577 } 3578} 3579 3580package _p_svn_log_changed_path_t; 3581use SVN::Base qw(Core svn_log_changed_path_t_); 3582 3583=head2 svn_log_changed_path_t 3584 3585=cut 3586 3587package SVN::Node; 3588use SVN::Base qw(Core svn_node_); 3589 3590=head2 svn_node_kind_t - SVN::Node 3591 3592=cut 3593 3594package _p_svn_opt_revision_t; 3595use SVN::Base qw(Core svn_opt_revision_t_); 3596 3597=head2 svn_opt_revision_t 3598 3599=cut 3600 3601package _p_svn_opt_revision_t_value; 3602use SVN::Base qw(Core svn_opt_revision_t_value_); 3603 3604package _p_svn_config_t; 3605use SVN::Base qw(Core svn_config_); 3606 3607package _p_svn_dirent_t; 3608use SVN::Base qw(Core svn_dirent_t_); 3609 3610=head2 svn_config_t 3611 3612=cut 3613 3614=head1 AUTHORS 3615 3616Chia-liang Kao E<lt>clkao@clkao.orgE<gt> 3617 3618=head1 COPYRIGHT 3619 3620Copyright (c) 2003 CollabNet. All rights reserved. 3621 3622This software is licensed as described in the file COPYING, which you 3623should have received as part of this distribution. The terms are also 3624available at http://subversion.tigris.org/license-1.html. If newer 3625versions of this license are posted there, you may use a newer version 3626instead, at your option. 3627 3628This software consists of voluntary contributions made by many 3629individuals. For exact contribution history, see the revision history 3630and logs, available at http://subversion.tigris.org/. 3631 3632=cut 3633 36341; 3635 3636 3637Node-path: svnperl/perl/Delta.pm 3638Node-kind: file 3639Node-action: add 3640Prop-content-length: 35 3641Text-content-length: 4811 3642Text-content-md5: e2d7d421818608204778613ee11fa6da 3643Content-length: 4846 3644 3645K 12 3646svn:keywords 3647V 2 3648Id 3649PROPS-END 3650package SVN::Delta; 3651use strict; 3652use SVN::Base qw(Delta svn_delta_); 3653 3654=head1 NAME 3655 3656SVN::Delta - Subversion delta functions 3657 3658=head1 SYNOPSIS 3659 3660 require SVN::Core; 3661 require SVN::Repos; 3662 require SVN::Delta; 3663 3664 # driving an editor 3665 my $editor = SVN::Delta::Editor-> 3666 new(SVN::Repos::get_commit_editor($repos, "file://$repospath", 3667 '/', 'root', 'FOO', \&committed)); 3668 3669 my $rootbaton = $editor->open_root(0); 3670 3671 my $fbaton = $editor->add_file ('filea', $rootbaton, 3672 undef, -1); 3673 3674 my $ret = $editor->apply_textdelta ($fbaton, undef); 3675 SVN::TxDelta::send_string("FILEA CONTENT", @$ret); 3676 3677 # implement an editor in perl 3678 SVN::Repos::dir_delta($root1, $path, undef, 3679 $root2, $path, 3680 SVN::Delta::Editor->new(_debug=>1), 3681 1, 1, 0, 1 3682 3683=head1 DESCRIPTION 3684 3685SVN::Delta wraps delta related function in subversion. The most 3686important one is SVN::Delta::Editor, the interface for describing tree 3687deltas. by default SVN::Delta::Editor relays method calls to its 3688internal member C<_editor>, which could either be an editor in C (such 3689as the one you get from get_commit_editor), or another 3690SVN::Delta::Editor object. 3691 3692=head1 SVN::Delta::Editor 3693 3694=head2 Driving Editors 3695 3696If you want to drive a native editor (such as commit_editor obtained 3697by SVN::Repos::get_commit_editor), create a SVN::Delta::Editor object 3698with the native editor/baton pair. The object will then be ready to 3699use and its method calls will be relayed to the native editor. 3700 3701=head2 Implementing Editors 3702 3703If you want to implement an editor, subclass SVN::Delta::Editor and 3704implement the editors callbacks. see the METHODS section below. 3705 3706=head2 CONSTRUCTOR - new (...) 3707 3708=over 3709 3710=item new ($editor, $editor_baton) 3711 3712Link to the native editor 3713 3714=back 3715 3716You can also pass a hash array to new: 3717 3718=over 3719 3720=item _debug 3721 3722Turn on debug. 3723 3724=item _editor 3725 3726An arrayref of the editor/baton pair or another SVN::Delta::Editor 3727object to link with. 3728 3729=back 3730 3731=head2 METHODS 3732 3733Please consult the svn_delta.h section in the Subversion API. Member 3734functions of svn_delta_editor_t could be called as methods of 3735SVN::Delta::Editor objects, with the edit_baton omitted. The pool is 3736also optional. 3737 3738If you are subclassing, the methods take exactly the same arguments as 3739the member functions (note tht void ** are returned data though as 3740throughout the perl bindings), with the edit_baton omitted. 3741 3742=cut 3743 3744package SVN::TxDelta; 3745use SVN::Base qw(Delta svn_txdelta_); 3746 3747*new = *SVN::_Delta::svn_txdelta; 3748 3749package _p_svn_txdelta_op_t; 3750use SVN::Base qw(Delta svn_txdelta_op_t_); 3751 3752package _p_svn_txdelta_window_t; 3753use SVN::Base qw(Delta svn_txdelta_window_t_); 3754 3755package SVN::Delta::Editor; 3756use SVN::Base qw(Delta svn_delta_editor_); 3757use Carp; 3758 3759*invoke_set_target_revision = *SVN::_Delta::svn_delta_editor_invoke_set_target_revision; 3760 3761sub convert_editor { 3762 my $self = shift; 3763 $self->{_editor} = $_[0], return 1 3764 if UNIVERSAL::isa ($_[0], __PACKAGE__); 3765 if (ref($_[0]) && $_[0]->isa('_p_svn_delta_editor_t')) { 3766 @{$self}{qw/_editor _baton/} = @_; 3767 return 1; 3768 } 3769 return 0; 3770} 3771 3772sub new { 3773 my $class = shift; 3774 my $self = bless {}, $class; 3775 3776 unless ($self->convert_editor(@_)) { 3777 %$self = @_; 3778 $self->convert_editor (@{$self->{_editor}}) 3779 if $self->{_editor}; 3780 } 3781 3782 warn "debug" if $self->{_debug}; 3783 3784 return $self; 3785} 3786 3787our $AUTOLOAD; 3788 3789sub AUTOLOAD { 3790 no warnings 'uninitialized'; 3791 warn "$AUTOLOAD: ".join(',',@_) if $_[0]->{_debug}; 3792 return unless $_[0]->{_editor}; 3793 my $class = ref($_[0]); 3794 my $func = $AUTOLOAD; 3795 $func =~ s/^${class}::(SUPER::)?//; 3796 return if $func =~ m/^[A-Z]/; 3797 3798 my %ebaton = ( set_target_revision => 1, 3799 open_root => 1, 3800 close_edit => 1, 3801 abort_edit => 1, 3802 ); 3803 3804 my $self = shift; 3805 no strict 'refs'; 3806 3807 my @ret = UNIVERSAL::isa ($self->{_editor}, __PACKAGE__) ? 3808 $self->{_editor}->$func (@_) : 3809 eval { &{"invoke_$func"}($self->{_editor}, 3810 $ebaton{$func} ? $self->{_baton} : (), @_) }; 3811 3812 confess $@ if $@; 3813 3814 return $#ret == 0 ? $ret[0] : [@ret]; 3815} 3816 3817=head1 BUGS 3818 3819Functions returning editor/baton pair should really be typemapped to a 3820SVN::Delta::Editor object. 3821 3822=head1 AUTHORS 3823 3824Chia-liang Kao E<lt>clkao@clkao.orgE<gt> 3825 3826=head1 COPYRIGHT 3827 3828Copyright (c) 2003 CollabNet. All rights reserved. 3829 3830This software is licensed as described in the file COPYING, which you 3831should have received as part of this distribution. The terms are also 3832available at http://subversion.tigris.org/license-1.html. If newer 3833versions of this license are posted there, you may use a newer version 3834instead, at your option. 3835 3836This software consists of voluntary contributions made by many 3837individuals. For exact contribution history, see the revision history 3838and logs, available at http://subversion.tigris.org/. 3839 3840=cut 3841 38421; 3843 3844 3845Node-path: svnperl/perl/Fs.pm 3846Node-kind: file 3847Node-action: add 3848Prop-content-length: 35 3849Text-content-length: 1054 3850Text-content-md5: bb24b9f8e0a5fff691959391602d29e7 3851Content-length: 1089 3852 3853K 12 3854svn:keywords 3855V 2 3856Id 3857PROPS-END 3858package SVN::Fs; 3859use SVN::Base qw(Fs svn_fs_); 3860 3861package _p_svn_fs_t; 3862 3863our @methods = qw/youngest_rev revision_root revision_prop revision_proplist 3864 change_rev_prop list_transactions open_txn begin_txn 3865 get_uuid set_uuid/; 3866 3867for (@methods) { 3868 *{$_} = *{"SVN::Fs::$_"}; 3869} 3870 3871package _p_svn_fs_root_t; 3872 3873our @methods = qw/apply_textdelta apply_text change_node_prop 3874 check_path close_root copied_from copy 3875 dir_entries delete file_contents 3876 file_length file_md5_checksum is_dir is_file 3877 is_revision_root is_txn_root make_dir make_file 3878 node_created_rev node_history node_id node_prop 3879 node_proplist paths_changed revision_link 3880 revision_root_revision/; 3881 3882*fs = *{"SVN::Fs::root_fs"}; 3883 3884for (@methods) { 3885 *{$_} = *{"SVN::Fs::$_"}; 3886} 3887 3888package _p_svn_fs_history_t; 3889use SVN::Base qw/Fs svn_fs_history_/; 3890 3891package _p_svn_fs_txn_t; 3892use SVN::Base qw/Fs svn_fs_txn_/; 3893 3894*commit = *SVN::Fs::commit_txn; 3895*abort = *SVN::Fs::abort_txn; 3896*change_prop = *SVN::Fs::change_txn_prop; 3897 3898package _p_svn_fs_dirent_t; 3899use SVN::Base qw(Fs svn_fs_dirent_t_); 3900 39011; 3902 3903 3904Node-path: svnperl/perl/Makefile.PL 3905Node-kind: file 3906Node-action: add 3907Prop-content-length: 10 3908Text-content-length: 2865 3909Text-content-md5: b8e2bb8ac1968bb404080572d7beac97 3910Content-length: 2875 3911 3912PROPS-END 3913#!/usr/bin/perl 3914use ExtUtils::MakeMaker; 3915 3916my @modules = qw/client delta fs ra repos wc/; 3917my @ldpaths = ('../.libs', 3918 map {"../../../libsvn_$_/.libs"} (@modules, qw/diff subr/)); 3919my @ldmodules = map {"-lsvn_$_-1"} (@modules, qw/diff subr/); 3920 3921my $apr_config = $ENV{APR_CONFIG} || '/usr/local/lib/apache2/apr-config'; 3922$apr_config = 'apr-config' unless -e $apr_config; 3923 3924my $apr_shlib_path_var = `$apr_config --shlib-path-var`; 3925my $apr_cflags = `$apr_config --includes`; 3926my $apr_ldflags = `$apr_config --cflags --link-ld --libs` 3927 if $^O eq 'darwin'; 3928 3929chomp $apr_shlib_path_var; 3930chomp $apr_cflags; 3931chomp $apr_ldflags; 3932 3933my %config = ( 3934 ABSTRACT => 'Perl bindings for Subversion', 3935 CCFLAGS => join(' ', $apr_cflags, `perl -MExtUtils::Embed -e ccopts`, 3936 ' -I.. -I../../../include -g'), 3937 OBJECT => q/$(O_FILES)/, 3938 dynamic_lib => { 3939 OTHERLDFLAGS => join(' ', $apr_ldflags, (map {"-L$_"} @ldpaths), 3940 @ldmodules, '-lsvn_swig_perl-1', 3941 `swig -perl -ldflags`), 3942 }, 3943); 3944 3945sub perlish { 3946 local $_ = $_[0]; 3947 s/^(\w)/\U$1/; 3948 $_; 3949} 3950 3951WriteMakefile(%config, NAME => 'SVN::_Core', C => ['core.c'], 3952 PM => {map { ("$_.pm" => "\$(INST_LIBDIR)/$_.pm") } 3953 map { perlish $_ } 3954 ('base', 'core', @modules)}, 3955 clean => { FILES => "*.hi *.c *.bs". 3956 join(' Makefile.','',@modules) } 3957 ); 3958 3959for (@modules) { 3960 WriteMakefile(%config, 3961 MAKEFILE=> "Makefile.$_", 3962 NAME => "SVN::_".perlish($_), 3963 C => ["svn_$_.c"], 3964 ); 3965} 3966 3967# the dependencies need to be fixed 3968 3969sub MY::postamble { 3970 package MY ; 3971 return join('', "all :: modules\ntest :: modules\ninstall :: modules\n\n", 3972 "par :: all\n\t", 3973 q{perl -MPAR::Dist -e"blib_to_par(name=>'SVN',version=>'`perl -Mblib -MSVN::Core -e'print $$SVN::Core::VERSION'`')"},"\n\n", 3974 # h2i 3975 "ra_plugin.hi: ../../../include/svn_ra.h\n\tperl h2i.pl ../../../include/svn_ra.h svn_ra_plugin_t > \$@\n\n", 3976 "ra_reporter.hi: ../../../include/svn_ra.h\n\tperl h2i.pl ../../../include/svn_ra.h svn_ra_reporter_t > \$@\n\n", 3977 "delta_editor.hi: ../../../include/svn_delta.h\n\tperl h2i.pl ../../../include/svn_delta.h svn_delta_editor_t > \$@\n\n", 3978 "modules :: ",(map { " svn_$_.c"} @modules),"\n", 3979 (map {"\tmake -f Makefile.$_\n"} @modules), 3980 "\t\$(NOECHO) \$(TOUCH) \$\@", 3981 # swig 3982 "\ncore.c :: ../core.i\n", 3983 "\tswig -c -nopm -perl -I.. -I../../../include $apr_cflags -module SVN::_Core -o core.c ../core.i\n", 3984 (map {"\nsvn_$_.c : ../svn_$_.i ra_plugin.hi ra_reporter.hi delta_editor.hi\n". 3985 "\tswig -c -nopm -perl -I.. -I../../../include $apr_cflags -module SVN::_".main::perlish($_)." -o svn_$_.c ../svn_$_.i\n"} 3986 @modules), 3987 "\nFULLPERLRUN=$apr_shlib_path_var=",join(':',@ldpaths), 3988 " \$(FULLPERL)\n", 3989 ); 3990} 3991 3992 3993Node-path: svnperl/perl/Ra.pm 3994Node-kind: file 3995Node-action: add 3996Prop-content-length: 35 3997Text-content-length: 5018 3998Text-content-md5: 595de361710e4ae2daa1a89400add203 3999Content-length: 5053 4000 4001K 12 4002svn:keywords 4003V 2 4004Id 4005PROPS-END 4006package SVN::Ra; 4007use SVN::Base qw(Ra svn_ra_); 4008 4009=head1 NAME 4010 4011SVN::Ra - Subversion remote acess functions 4012 4013=head1 SYNOPSIS 4014 4015 require SVN::Core; 4016 require SVN::Ra; 4017 my $ra = SVN::Ra->new ('file:///tmp/svmtest'); 4018 print $ra->get_latest_revnum (); 4019 4020 4021=head1 DESCRIPTION 4022 4023SVN::Ra wraps the object-oriented svn_ra_plugin_t functions. 4024 4025=head1 SVN::Ra 4026 4027=head2 CONSTRUCTOR - new (...) 4028 4029The method creates an RA object and calls C<open> for it. It takes a 4030hash array as parameter. if there's only one argument supplied, it's 4031used as the url. valid keys are: 4032 4033=over 4034 4035=item url 4036 4037=item auth 4038 4039An auth_baton could be given to the SVN::RA object. Deafult to a 4040auth_provider with a username_provider. See L<SVN::Client> for how to 4041create auth_baton. 4042 4043=item pool 4044 4045The pool for the ra session to use, and also the member functions will 4046be called with this pool. Default to a newly created root pool. 4047 4048=item config 4049 4050The config hash that could be obtained by SVN::Core::config_get_config(undef). 4051 4052=item callback 4053 4054The ra_callback namespace to use. Default to SVN::Ra::Callback. 4055 4056=back 4057 4058=head2 METHODS 4059 4060Please consult the svn_ra.h section in the Subversion API. Member 4061functions of svn_ra_plugin_t could be called as methods of SVN::Ra 4062objects, with the session_baton and pool omitted. 4063 4064=cut 4065 4066use strict; 4067require SVN::Client; 4068 4069my $ralib = init_ra_libs; 4070 4071our $AUTOLOAD; 4072 4073sub AUTOLOAD { 4074 my $class = ref($_[0]); 4075 $AUTOLOAD =~ s/^${class}::(SUPER::)?//; 4076 return if $AUTOLOAD =~ m/^[A-Z]/; 4077 4078 my $self = shift; 4079 no strict 'refs'; 4080 4081 die "no such method $AUTOLOAD" 4082 unless $self->can("plugin_invoke_$AUTOLOAD"); 4083 4084 my @ret = &{"plugin_invoke_$AUTOLOAD"}(@{$self}{qw/ra session/}, @_, 4085 $self->{pool}); 4086 4087 return $ret[0] unless $#ret; 4088 4089 return ($AUTOLOAD eq 'get_commit_editor') ? @ret : 4090 bless [@ret], 'SVN::Ra::Reporter'; 4091} 4092 4093sub new { 4094 my $class = shift; 4095 my $self = bless {}, $class; 4096 %$self = $#_ ? @_ : (url => $_[0]); 4097 4098 if (defined($self->{auth})) { 4099 if (ref($self->{auth}) ne '_p_svn_auth_baton_t') { 4100 # If the auth is already set to a auth_baton ignore it 4101 # otherwise make an auth_baton and store the callbacks 4102 my ($auth_baton,$auth_callbacks) = 4103 SVN::Core::auth_open_helper($self->{auth}); 4104 $self->{auth} = $auth_baton; 4105 $self->{auth_provider_callbacks} = $auth_callbacks; 4106 } 4107 } else { 4108 # no callback to worry about with a username provider so just call 4109 # auth_open directly 4110 $self->{auth} = SVN::Core::auth_open( 4111 [SVN::Client::get_username_provider()]); 4112 } 4113 4114 my $pool = $self->{pool} ||= SVN::Core::pool_create(undef); 4115 4116 $self->{ra} = get_ra_library ($ralib, $self->{url}); 4117 my $callback = 'SVN::Ra::Callbacks'; 4118 4119 # custom callback namespace 4120 if ($self->{callback} && !ref($self->{callback})) { 4121 $callback = $self->{callback}; 4122 undef $self->{callback}; 4123 } 4124 $self->{callback} ||= $callback->new(auth => $self->{auth}, 4125 pool => $pool), 4126 4127 $self->{session} = plugin_invoke_open 4128 ($self->{ra}, $self->{url}, $self->{callback}, 4129 $self->{config} || {}, $pool); 4130 4131 return $self; 4132} 4133 4134sub DESTROY { 4135 4136} 4137 4138package SVN::Ra::Reporter; 4139use SVN::Base qw(Ra svn_ra_reporter_); 4140 4141=head1 SVN::Ra::Reporter 4142 4143the SVN::Ra methods: do_diff, do_status, do_switch, do_update, returns 4144a SVN::Ra::Reporter object as a wrapper of svn_ra_reporter_t. You can 4145use the member functions of it as methods of SVN::Ra::Reporter, with 4146the reporter_baton omitted. 4147 4148=cut 4149 4150our $AUTOLOAD; 4151sub AUTOLOAD { 4152 my $class = ref($_[0]); 4153 $AUTOLOAD =~ s/^${class}::(SUPER::)?//; 4154 return if $AUTOLOAD =~ m/^[A-Z]/; 4155 4156 my $self = shift; 4157 no strict 'refs'; 4158 4159 die "no such method $AUTOLOAD" 4160 unless $self->can("invoke_$AUTOLOAD"); 4161 4162 &{"invoke_$AUTOLOAD"}(@$self, @_); 4163} 4164 4165package SVN::Ra::Callbacks; 4166 4167=head1 SVN::Ra::Callbacks 4168 4169This is the wrapper class for svn_ra_callback_t. To supply custom 4170callback to SVN::Ra, subclass this class and override the member 4171functions. 4172 4173=cut 4174 4175require SVN::Core; 4176 4177sub new { 4178 my $class = shift; 4179 my $self = bless {}, $class; 4180 %$self = @_; 4181 return $self; 4182} 4183 4184sub open_tmp_file { 4185 my $self = shift; 4186 my ($fd, $name) = SVN::Core::io_open_unique_file 4187 ('/tmp/foobar', 'tmp', 1, $self->{pool}); 4188 return $fd; 4189} 4190 4191sub get_wc_prop { 4192 return undef; 4193} 4194 4195=head1 AUTHORS 4196 4197Chia-liang Kao E<lt>clkao@clkao.orgE<gt> 4198 4199=head1 COPYRIGHT 4200 4201Copyright (c) 2003 CollabNet. All rights reserved. 4202 4203This software is licensed as described in the file COPYING, which you 4204should have received as part of this distribution. The terms are also 4205available at http://subversion.tigris.org/license-1.html. If newer 4206versions of this license are posted there, you may use a newer version 4207instead, at your option. 4208 4209This software consists of voluntary contributions made by many 4210individuals. For exact contribution history, see the revision history 4211and logs, available at http://subversion.tigris.org/. 4212 4213=cut 4214 42151; 4216 4217 4218Node-path: svnperl/perl/Repos.pm 4219Node-kind: file 4220Node-action: add 4221Prop-content-length: 35 4222Text-content-length: 1837 4223Text-content-md5: ad396b19e157c02aba5b998d30ca746e 4224Content-length: 1872 4225 4226K 12 4227svn:keywords 4228V 2 4229Id 4230PROPS-END 4231package SVN::Repos; 4232use SVN::Base qw(Repos svn_repos_); 4233use strict; 4234 4235=head1 NAME 4236 4237SVN::Repos - Subversion repository functions 4238 4239=head1 SYNOPSIS 4240 4241 require SVN::Core; 4242 require SVN::Repos; 4243 require SVN::Fs; 4244 4245 my $repos = SVN::Repos::open ('/path/to/repos'); 4246 print $repos->fs->youngest_rev; 4247 4248=head1 DESCRIPTION 4249 4250SVN::Repos wraps the functions in svn_repos.h. The actual namespace 4251for repos object is _p_svn_repos_t. 4252 4253=head2 CONSTRUCTORS 4254 4255=over 4256 4257=item open ($path) 4258 4259=item create ($path, undef, undef, $config, $fs_config) 4260 4261=back 4262 4263=head2 METHODS 4264 4265Please consult the svn_repos.h section in the Subversion 4266API. Functions taking svn_repos_t * as the first inbound argument 4267could be used as methods of the object returned by open or create. 4268 4269=cut 4270 4271package _p_svn_repos_t; 4272 4273my @methods = qw/fs get_logs get_commit_editor path db_env lock_dir 4274 db_lockfile hook_dir start_commit_hook 4275 pre_commit_hook post_commit_hook 4276 pre_revprop_change_hook post_revprop_change_hook 4277 dated_revision fs_commit_txn fs_begin_txn_for_commit 4278 fs_begin_txn_for_update fs_change_rev_prop 4279 node_editor dump_fs load_fs get_fs_build_parser/; 4280 4281no strict 'refs'; 4282for (@methods) { 4283 *{$_} = *{"SVN::Repos::$_"}; 4284} 4285 4286=head1 AUTHORS 4287 4288Chia-liang Kao E<lt>clkao@clkao.orgE<gt> 4289 4290=head1 COPYRIGHT 4291 4292Copyright (c) 2003 CollabNet. All rights reserved. 4293 4294This software is licensed as described in the file COPYING, which you 4295should have received as part of this distribution. The terms are also 4296available at http://subversion.tigris.org/license-1.html. If newer 4297versions of this license are posted there, you may use a newer version 4298instead, at your option. 4299 4300This software consists of voluntary contributions made by many 4301individuals. For exact contribution history, see the revision history 4302and logs, available at http://subversion.tigris.org/. 4303 4304=cut 4305 43061; 4307 4308 4309Node-path: svnperl/perl/Wc.pm 4310Node-kind: file 4311Node-action: add 4312Prop-content-length: 35 4313Text-content-length: 225 4314Text-content-md5: 05c653fa220e1caaef95bd0ea02f72e8 4315Content-length: 260 4316 4317K 12 4318svn:keywords 4319V 2 4320Id 4321PROPS-END 4322package SVN::Wc; 4323use SVN::Base qw(Wc svn_wc_); 4324 4325package _p_svn_wc_t; 4326 4327package _p_svn_wc_entry_t; 4328# still need to check if the function prototype allows it to be called 4329# as method. 4330use SVN::Base qw(Wc svn_wc_entry_t_); 4331 4332 4333 43341; 4335 4336 4337Node-path: svnperl/perl/h2i.pl 4338Node-kind: file 4339Node-action: add 4340Prop-content-length: 35 4341Text-content-length: 1504 4342Text-content-md5: 50be9fb241252dce05606bf5d693045f 4343Content-length: 1539 4344 4345K 12 4346svn:keywords 4347V 2 4348Id 4349PROPS-END 4350# $Revision: #7 $ $Change: 7549 $ $DateTime: 2003/08/15 10:56:21 $ 4351# extract member function from c header as invoker functions 4352# by Autrijus Tang 4353 4354use 5.008; 4355 4356my $file = shift or die "Usage: $^X $0 svn_ra.h svn_ra_reporter_t\n"; 4357my $lines = ''; 4358 4359while (my $s = shift) { 4360 my $out = ''; 4361 my $n = uc($s); $n =~ s/_T$//; $n =~ s/.*_//; 4362 my $prefix = $s; chop $prefix; 4363 my ($rv, $func, $args); 4364 4365 open FILE, $file or die $!; 4366 my $temp = join('', <FILE>); 4367 $temp =~ s/^(typedef struct)(\n\{[^}]+\}\s+(\w+);)/$1 $3$2/ms; 4368 close FILE; 4369 open FILE, '<', \$temp; 4370 while (<FILE>) { 4371 next if 1 .. /^typedef struct $s/; 4372 next if /^{$/; 4373 next if m{^\s*/\*} .. m{\*/\s*$}; 4374 last if /^\s*}\s+/; 4375 $lines .= $_; 4376 next unless /^\s*$/; 4377 (($lines = ''), next) unless $lines =~ /\s*(\w+)\s*\W+(\w+)\W+\(([^)]+)/; # only care about functions 4378 ($rv, $func, $args) = ($1, $2, $3); 4379 4380 print "$rv *${prefix}invoke_$func (\n"; 4381 print " $s *\L$n\E,\n"; 4382 print join(",\n", map " $_", split(/\s*,\s*/, $args)); 4383 print "\n);\n\n"; 4384 4385 $out .= "${n}_INVOKER($func, $args)\n"; 4386 $args = join( 4387 ', ', 4388 map { s/^.*?(\w+)$/$1/; $_ } 4389 split(/\s*,\s*/, $args) 4390 ); 4391 $out .= "${n}_INVOKER_FUNC($func, $args);\n\n"; 4392 $lines = ''; 4393 } 4394 4395 print "%{\n"; 4396 print " 4397#define ${n}_INVOKER(method, ...) \\ 4398 $rv *${prefix}invoke_ ## method \\ 4399 (const $s *\L$n\E, __VA_ARGS__) 4400 4401#define ${n}_INVOKER_FUNC(method, ...) \\ 4402 { return \L${n}\E->method (__VA_ARGS__); } 4403 4404"; 4405 print $out; 4406 print "%}\n\n"; 4407} 4408 4409 4410 4411Node-path: svnperl/perl/t 4412Node-kind: dir 4413Node-action: add 4414Prop-content-length: 10 4415Content-length: 10 4416 4417PROPS-END 4418 4419 4420Node-path: svnperl/perl/t/0use.t 4421Node-kind: file 4422Node-action: add 4423Prop-content-length: 10 4424Text-content-length: 235 4425Text-content-md5: 607637d571241eb55c2aa0cdb59c27f6 4426Content-length: 245 4427 4428PROPS-END 4429#!/usr/bin/perl -w 4430 4431use Test::More tests => 7; 4432use strict; 4433BEGIN { 4434require_ok 'SVN::Core'; 4435require_ok 'SVN::Repos'; 4436require_ok 'SVN::Fs'; 4437require_ok 'SVN::Delta'; 4438require_ok 'SVN::Ra'; 4439require_ok 'SVN::Wc'; 4440require_ok 'SVN::Client'; 4441} 4442 4443 4444Node-path: svnperl/perl/t/1repos.t 4445Node-kind: file 4446Node-action: add 4447Prop-content-length: 10 4448Text-content-length: 1917 4449Text-content-md5: 5b32576446a28fe3c4d8ec7863701605 4450Content-length: 1927 4451 4452PROPS-END 4453#!/usr/bin/perl -w 4454 4455use Test::More qw(no_plan); 4456use strict; 4457 4458require SVN::Core; 4459require SVN::Repos; 4460require SVN::Fs; 4461require SVN::Delta; 4462 4463my $repospath = "/tmp/svn-$$"; 4464 4465my $repos; 4466 4467ok($repos = SVN::Repos::create("$repospath", undef, undef, undef, undef), 4468 "create repository at $repospath"); 4469 4470my $fs = $repos->fs; 4471 4472sub committed { 4473 diag "committed ".join(',',@_); 4474} 4475 4476my $editor = SVN::Delta::Editor-> 4477 new(SVN::Repos::get_commit_editor($repos, "file://$repospath", 4478 '/', 'root', 'FOO', \&committed)); 4479 4480my $rootbaton = $editor->open_root(0); 4481 4482my $dirbaton = $editor->add_directory ('trunk', $rootbaton, undef, 0); 4483 4484my $fbaton = $editor->add_file ('trunk/filea', $dirbaton, undef, -1); 4485 4486my $ret = $editor->apply_textdelta ($fbaton, undef); 4487 4488SVN::TxDelta::send_string("FILEA CONTENT", @$ret); 4489 4490$editor->close_edit(); 4491 4492cmp_ok($fs->youngest_rev, '==', 1); 4493{ 4494$editor = SVN::Delta::Editor-> 4495 new (SVN::Repos::get_commit_editor($repos, "file://$repospath", 4496 '/', 'root', 'FOO', \&committed)); 4497my $rootbaton = $editor->open_root(1); 4498 4499my $dirbaton = $editor->add_directory ('tags', $rootbaton, undef, 1); 4500my $subdirbaton = $editor->add_directory ('tags/foo', $dirbaton, 4501 "file://$repospath/trunk", 1); 4502 4503$editor->close_edit(); 4504} 4505cmp_ok($fs->youngest_rev, '==', 2); 4506 4507my @history; 4508 4509SVN::Repos::history ($fs, 'tags/foo/filea', 4510 sub {push @history, [@_[0,1]]}, 0, 2, 1); 4511 4512is_deeply (\@history, [['/tags/foo/filea',2],['/trunk/filea',1]], 4513 'repos_history'); 4514 4515{ 4516$editor = SVN::Delta::Editor-> 4517 new (SVN::Repos::get_commit_editor($repos, "file://$repospath", 4518 '/', 'root', 'FOO', \&committed)); 4519 4520my $rootbaton = $editor->open_root(2); 4521$editor->delete_entry('tags', 2, $rootbaton); 4522 4523$editor->close_edit(); 4524} 4525 4526cmp_ok($fs->youngest_rev, '==', 3); 4527 4528END { 4529diag "cleanup"; 4530print `svn cat file://$repospath/trunk/filea`; 4531print `svn log -v file://$repospath`; 4532`rm -rf $repospath`; 4533} 4534 4535 4536Node-path: svnperl/perl/t/2fs.t 4537Node-kind: file 4538Node-action: add 4539Prop-content-length: 10 4540Text-content-length: 1314 4541Text-content-md5: 3f58293e2c63dff0313f28644caaef47 4542Content-length: 1324 4543 4544PROPS-END 4545#!/usr/bin/perl -w 4546 4547use Test::More qw(no_plan); 4548use strict; 4549 4550require SVN::Core; 4551require SVN::Repos; 4552require SVN::Fs; 4553 4554my $repospath = "/tmp/svn-$$"; 4555 4556my $repos; 4557 4558ok($repos = SVN::Repos::create("$repospath", undef, undef, undef, undef), 4559 "create repository at $repospath"); 4560 4561my $fs = $repos->fs; 4562 4563cmp_ok($fs->youngest_rev, '==', 0, 4564 "new repository start with rev 0"); 4565 4566my $txn = $fs->begin_txn($fs->youngest_rev); 4567 4568my $txns = $fs->list_transactions; 4569ok(eq_array($fs->list_transactions, [$txn->name]), 'list transaction'); 4570 4571$txn->root->make_dir('trunk'); 4572 4573my $path = 'trunk/filea'; 4574my $text = "this is just a test\n"; 4575$txn->root->make_file('trunk/filea'); 4576{ 4577my $stream = $txn->root->apply_text('trunk/filea', undef); 4578print $stream $text; 4579close $stream; 4580} 4581$txn->commit; 4582 4583cmp_ok($fs->youngest_rev, '==', 1, 'revision increased'); 4584 4585my $root = $fs->revision_root ($fs->youngest_rev); 4586 4587cmp_ok($root->check_path($path), '==', $SVN::Node::file); 4588ok (!$root->is_dir($path)); 4589ok ($root->is_file($path)); 4590{ 4591my $stream = $root->file_contents ($path); 4592local $/; 4593is(<$stream>, $text, 'content verified'); 4594is($root->file_md5_checksum ($path), 'dd2314129f81675e95b940ff94ddc935', 4595 'md5 verified'); 4596} 4597 4598is ($fs->revision_prop(1, 'not:exists'), undef, 'nonexisting property'); 4599 4600END { 4601diag "cleanup"; 4602`rm -rf $repospath`; 4603} 4604 4605 4606Node-path: svnperl/perl/t/3client.t 4607Node-kind: file 4608Node-action: add 4609Prop-content-length: 10 4610Text-content-length: 717 4611Text-content-md5: ab0e387baeadbcd6ac3db4f898f9b33a 4612Content-length: 727 4613 4614PROPS-END 4615#!/usr/bin/perl -w 4616 4617use Test::More qw(no_plan); 4618use strict; 4619 4620require SVN::Core; 4621require SVN::Repos; 4622require SVN::Client; 4623 4624my $repospath = "/tmp/svn-$$"; 4625my $reposurl = "file://$repospath"; 4626my $wcpath = "/tmp/svn-wc-$$"; 4627 4628# This is ugly to create the test repo with SVN::Repos, but 4629# it seems to be the most reliable way. 4630ok(SVN::Repos::create("$repospath", undef, undef, undef, undef), 4631 "create repository at $repospath"); 4632 4633my $ctx = SVN::Client->new; 4634isa_ok($ctx,'SVN::Client','Client Object'); 4635 4636my $ci_dir1 = $ctx->mkdir(["$reposurl/dir1"]); 4637isa_ok($ci_dir1,'_p_svn_client_commit_info_t'); 4638is($ci_dir1->revision,1,'commit info revision equals 1'); 4639 4640END { 4641diag "cleanup"; 4642`rm -rf $repospath`; 4643#`rm -rf $wcpath`; 4644} 4645 4646 4647Node-path: svnperl/perl/t/4pool.t 4648Node-kind: file 4649Node-action: add 4650Prop-content-length: 10 4651Text-content-length: 1253 4652Text-content-md5: a35f31f926bb1a11f36e0a6fe3f6c557 4653Content-length: 1263 4654 4655PROPS-END 4656#!/usr/bin/perl 4657use strict; 4658use Test::More qw(no_plan); 4659 4660require SVN::Core; 4661require SVN::Repos; 4662require SVN::Fs; 4663require SVN::Delta; 4664 4665package TestEditor; 4666our @ISA = qw(SVN::Delta::Editor); 4667 4668sub add_directory { 4669 my ($self, $path, undef, undef, undef, $pool) = @_; 4670 $pool->default; 4671 main::is_pool_default ($pool, 'default pool from c calls'); 4672} 4673 4674package main; 4675sub is_pool_default { 4676 my ($pool, $text) = @_; 4677 is (ref ($pool) eq 'SVN::Pool' ? $$$pool : $$pool, 4678 $$SVN::_Core::current_pool, $text); 4679} 4680 4681my $repospath = "/tmp/svn-$$"; 4682 4683my $repos; 4684 4685ok($repos = SVN::Repos::create("$repospath", undef, undef, undef, undef), 4686 "create repository at $repospath"); 4687 4688my $fs = $repos->fs; 4689 4690my $pool = SVN::Pool->new_default; 4691 4692is_pool_default ($pool, 'default pool'); 4693 4694{ 4695 my $spool = SVN::Pool->new_default_sub; 4696 is_pool_default ($spool, 'lexical default pool default'); 4697} 4698 4699is_pool_default ($pool, 'lexical default pool destroyed'); 4700 4701my $root = $fs->revision_root (0); 4702 4703my $txn = $fs->begin_txn(0); 4704 4705$txn->root->make_dir('trunk'); 4706 4707$txn->commit; 4708 4709 4710SVN::Repos::dir_delta ($root, '', '', 4711 $fs->revision_root (1), '', 4712 TestEditor->new(), 4713 undef, 1, 1, 0, 1); 4714 4715 4716is_pool_default ($pool, 'default pool from c calls destroyed'); 4717 4718 4719Node-path: svnperl/python 4720Node-kind: dir 4721Node-action: add 4722Prop-content-length: 10 4723Content-length: 10 4724 4725PROPS-END 4726 4727 4728Node-path: svnperl/python/__init__.py 4729Node-kind: file 4730Node-action: add 4731Prop-content-length: 10 4732Text-content-length: 700 4733Text-content-md5: 5906faec481c0abf272f9daf099d2020 4734Content-length: 710 4735 4736PROPS-END 4737# 4738# __init__.py: defines this directory as the 'libsvn' package. 4739# 4740# Subversion is a tool for revision control. 4741# See http://subversion.tigris.org for more information. 4742# 4743# ==================================================================== 4744# Copyright (c) 2000-2004 CollabNet. All rights reserved. 4745# 4746# This software is licensed as described in the file COPYING, which 4747# you should have received as part of this distribution. The terms 4748# are also available at http://subversion.tigris.org/license-1.html. 4749# If newer versions of this license are posted there, you may use a 4750# newer version instead, at your option. 4751# 4752###################################################################### 4753# 4754 4755 4756Node-path: svnperl/python/svn 4757Node-kind: dir 4758Node-action: add 4759Prop-content-length: 10 4760Content-length: 10 4761 4762PROPS-END 4763 4764 4765Node-path: svnperl/python/svn/__init__.py 4766Node-kind: file 4767Node-action: add 4768Prop-content-length: 10 4769Text-content-length: 697 4770Text-content-md5: f50eb664847daeae8f40632ea0c558de 4771Content-length: 707 4772 4773PROPS-END 4774# 4775# __init__.py: defines this directory as the 'svn' package. 4776# 4777# Subversion is a tool for revision control. 4778# See http://subversion.tigris.org for more information. 4779# 4780# ==================================================================== 4781# Copyright (c) 2000-2004 CollabNet. All rights reserved. 4782# 4783# This software is licensed as described in the file COPYING, which 4784# you should have received as part of this distribution. The terms 4785# are also available at http://subversion.tigris.org/license-1.html. 4786# If newer versions of this license are posted there, you may use a 4787# newer version instead, at your option. 4788# 4789###################################################################### 4790# 4791 4792 4793Node-path: svnperl/python/svn/client.py 4794Node-kind: file 4795Node-action: add 4796Prop-content-length: 10 4797Text-content-length: 628 4798Text-content-md5: a886a5310794de93a536700e3d7dbf09 4799Content-length: 638 4800 4801PROPS-END 4802# 4803# client.py : various utilities for interacting with the _client module 4804# 4805###################################################################### 4806# 4807# Copyright (c) 2000-2004 CollabNet. All rights reserved. 4808# 4809# This software is licensed as described in the file COPYING, which 4810# you should have received as part of this distribution. The terms 4811# are also available at http://subversion.tigris.org/license-1.html. 4812# If newer versions of this license are posted there, you may use a 4813# newer version instead, at your option. 4814# 4815###################################################################### 4816# 4817 4818from libsvn.client import * 4819 4820 4821Node-path: svnperl/python/svn/core.py 4822Node-kind: file 4823Node-action: add 4824Prop-content-length: 10 4825Text-content-length: 2162 4826Text-content-md5: 5ee70d27545e80ff6ada6cecf2bf7e88 4827Content-length: 2172 4828 4829PROPS-END 4830# 4831# svn.core: public Python interface for core compontents 4832# 4833# Subversion is a tool for revision control. 4834# See http://subversion.tigris.org for more information. 4835# 4836# ==================================================================== 4837# Copyright (c) 2000-2004 CollabNet. All rights reserved. 4838# 4839# This software is licensed as described in the file COPYING, which 4840# you should have received as part of this distribution. The terms 4841# are also available at http://subversion.tigris.org/license-1.html. 4842# If newer versions of this license are posted there, you may use a 4843# newer version instead, at your option. 4844# 4845###################################################################### 4846# 4847 4848# bring all the symbols up into this module 4849### in the future, we may want to limit this, rename things, etc 4850from libsvn.core import * 4851 4852def run_app(func, *args, **kw): 4853 '''Run a function as an "APR application". 4854 4855 APR is initialized, and an application pool is created. Cleanup is 4856 performed as the function exits (normally or via an exception. 4857 ''' 4858 apr_initialize() 4859 try: 4860 pool = svn_pool_create(None) 4861 try: 4862 return apply(func, (pool,) + args, kw) 4863 finally: 4864 svn_pool_destroy(pool) 4865 finally: 4866 apr_terminate() 4867 4868# some minor patchups 4869svn_pool_destroy = apr_pool_destroy 4870svn_pool_clear = apr_pool_clear 4871 4872class Stream: 4873 def __init__(self, stream): 4874 self._stream = stream 4875 4876 def read(self, amt=None): 4877 if amt is None: 4878 # read the rest of the stream 4879 chunks = [ ] 4880 while 1: 4881 data = svn_stream_read(self._stream, SVN_STREAM_CHUNK_SIZE) 4882 if not data: 4883 break 4884 chunks.append(data) 4885 return ''.join(chunks) 4886 4887 # read the amount specified 4888 return svn_stream_read(self._stream, int(amt)) 4889 4890 def write(self, buf): 4891 ### what to do with the amount written? (the result value) 4892 svn_stream_write(self._stream, buf) 4893 4894def secs_from_timestr(svn_datetime, pool): 4895 aprtime = svn_time_from_cstring(svn_datetime, pool) 4896 4897 # ### convert to a time_t; this requires intimate knowledge of 4898 # ### the apr_time_t type 4899 # ### aprtime is microseconds; turn it into seconds 4900 return aprtime / 1000000 4901 4902 4903Node-path: svnperl/python/svn/delta.py 4904Node-kind: file 4905Node-action: add 4906Prop-content-length: 10 4907Text-content-length: 1732 4908Text-content-md5: 42229ac841a613e1758d90a99841e5d1 4909Content-length: 1742 4910 4911PROPS-END 4912# 4913# delta.py : various utilities for interacting with the _delta module 4914# 4915###################################################################### 4916# 4917# Copyright (c) 2000-2004 CollabNet. All rights reserved. 4918# 4919# This software is licensed as described in the file COPYING, which 4920# you should have received as part of this distribution. The terms 4921# are also available at http://subversion.tigris.org/license-1.html. 4922# If newer versions of this license are posted there, you may use a 4923# newer version instead, at your option. 4924# 4925###################################################################### 4926# 4927 4928from libsvn.delta import * 4929 4930class Editor: 4931 4932 def set_target_revision(self, target_revision): 4933 pass 4934 4935 def open_root(self, base_revision, dir_pool): 4936 return None 4937 4938 def delete_entry(self, path, revision, parent_baton, pool): 4939 pass 4940 4941 def add_directory(self, path, parent_baton, 4942 copyfrom_path, copyfrom_revision, dir_pool): 4943 return None 4944 4945 def open_directory(self, path, parent_baton, base_revision, dir_pool): 4946 return None 4947 4948 def change_dir_prop(self, dir_baton, name, value, pool): 4949 pass 4950 4951 def close_directory(self, dir_baton): 4952 pass 4953 4954 def add_file(self, path, parent_baton, 4955 copyfrom_path, copyfrom_revision, file_pool): 4956 return None 4957 4958 def open_file(self, path, parent_baton, base_revision, file_pool): 4959 return None 4960 4961 def apply_textdelta(self, file_baton, base_checksum): 4962 return None 4963 4964 def change_file_prop(self, file_baton, name, value, pool): 4965 pass 4966 4967 def close_file(self, text_checksum, file_baton): 4968 pass 4969 4970 def close_edit(self): 4971 pass 4972 4973 def abort_edit(self): 4974 pass 4975 4976 4977def make_editor(editor, pool): 4978 return svn_swig_py_make_editor(editor, pool) 4979 4980 4981Node-path: svnperl/python/svn/fs.py 4982Node-kind: file 4983Node-action: add 4984Prop-content-length: 10 4985Text-content-length: 5847 4986Text-content-md5: 3b01d8850c6b4a33543d88b677fa871a 4987Content-length: 5857 4988 4989PROPS-END 4990# 4991# svn.fs: public Python FS interface 4992# 4993# Subversion is a tool for revision control. 4994# See http://subversion.tigris.org for more information. 4995# 4996# ==================================================================== 4997# Copyright (c) 2000-2004 CollabNet. All rights reserved. 4998# 4999# This software is licensed as described in the file COPYING, which 5000# you should have received as part of this distribution. The terms 5001# are also available at http://subversion.tigris.org/license-1.html. 5002# If newer versions of this license are posted there, you may use a 5003# newer version instead, at your option. 5004# 5005###################################################################### 5006# 5007 5008### hide these names? 5009import tempfile 5010import os 5011import sys 5012import popen2 5013import string 5014import re 5015 5016import libsvn.fs 5017import core 5018 5019# copy the wrapper functions out of the extension module, dropping the 5020# 'svn_fs_' prefix. 5021# XXX this might change in the future once we have a consistent naming 5022# scheme 5023for name in dir(libsvn.fs): 5024 if name[:7] == 'svn_fs_': 5025 vars()[name[7:]] = getattr(libsvn.fs, name) 5026 5027# we don't want these symbols exported 5028del name, libsvn 5029 5030def entries(root, path, pool): 5031 "Call dir_entries returning a dictionary mappings names to IDs." 5032 e = dir_entries(root, path, pool) 5033 for name, entry in e.items(): 5034 e[name] = dirent_t_id_get(entry) 5035 return e 5036 5037 5038class FileDiff: 5039 def __init__(self, root1, path1, root2, path2, pool, diffoptions=[]): 5040 assert path1 or path2 5041 5042 self.tempfile1 = None 5043 self.tempfile2 = None 5044 5045 self.root1 = root1 5046 self.path1 = path1 5047 self.root2 = root2 5048 self.path2 = path2 5049 self.diffoptions = diffoptions 5050 5051 # the caller can't manage this pool very well given our indirect use 5052 # of it. so we'll create a subpool and clear it at "proper" times. 5053 self.pool = core.svn_pool_create(pool) 5054 5055 def either_binary(self): 5056 "Return true if either of the files are binary." 5057 if self.path1 is not None: 5058 prop = node_prop(self.root1, self.path1, core.SVN_PROP_MIME_TYPE, 5059 self.pool) 5060 if prop and core.svn_mime_type_is_binary(prop): 5061 return 1 5062 if self.path2 is not None: 5063 prop = node_prop(self.root2, self.path2, core.SVN_PROP_MIME_TYPE, 5064 self.pool) 5065 if prop and core.svn_mime_type_is_binary(prop): 5066 return 1 5067 return 0 5068 5069 def _dump_contents(self, file, root, path, pool): 5070 fp = open(file, 'w+') 5071 if path is not None: 5072 stream = file_contents(root, path, pool) 5073 try: 5074 while 1: 5075 chunk = core.svn_stream_read(stream, core.SVN_STREAM_CHUNK_SIZE) 5076 if not chunk: 5077 break 5078 fp.write(chunk) 5079 finally: 5080 core.svn_stream_close(stream) 5081 fp.close() 5082 5083 5084 def get_files(self): 5085 if self.tempfile1: 5086 # no need to do more. we ran this already. 5087 return self.tempfile1, self.tempfile2 5088 5089 # Make tempfiles, and dump the file contents into those tempfiles. 5090 self.tempfile1 = tempfile.mktemp() 5091 self.tempfile2 = tempfile.mktemp() 5092 5093 self._dump_contents(self.tempfile1, self.root1, self.path1, self.pool) 5094 core.svn_pool_clear(self.pool) 5095 self._dump_contents(self.tempfile2, self.root2, self.path2, self.pool) 5096 core.svn_pool_clear(self.pool) 5097 5098 return self.tempfile1, self.tempfile2 5099 5100 def get_pipe(self): 5101 self.get_files() 5102 5103 # use an array for the command to avoid the shell and potential 5104 # security exposures 5105 cmd = ["diff"] \ 5106 + self.diffoptions \ 5107 + [self.tempfile1, self.tempfile2] 5108 5109 # the windows implementation of popen2 requires a string 5110 if sys.platform == "win32": 5111 cmd = _escape_msvcrt_shell_command(cmd) 5112 5113 # open the pipe, forget the end for writing to the child (we won't), 5114 # and then return the file object for reading from the child. 5115 fromchild, tochild = popen2.popen2(cmd) 5116 tochild.close() 5117 return fromchild 5118 5119 def __del__(self): 5120 # it seems that sometimes the files are deleted, so just ignore any 5121 # failures trying to remove them 5122 if self.tempfile1 is not None: 5123 try: 5124 os.remove(self.tempfile1) 5125 except OSError: 5126 pass 5127 if self.tempfile2 is not None: 5128 try: 5129 os.remove(self.tempfile2) 5130 except OSError: 5131 pass 5132 5133def _escape_msvcrt_shell_command(argv): 5134 """Flatten a list of command line arguments into a command string. 5135 5136 The resulting command string is expected to be passed to the system shell 5137 (cmd.exe) which os functions like popen() and system() invoke internally. 5138 5139 The command line will be broken up correctly by Windows programs linked 5140 with the Microsoft C runtime. (Programs using other runtimes like Cygwin 5141 parse their command lines differently). 5142 """ 5143 5144 # According cmd's usage notes (cmd /?), it parses the command line by 5145 # "seeing if the first character is a quote character and if so, stripping 5146 # the leading character and removing the last quote character." 5147 # So to prevent the argument string from being changed we add an extra set 5148 # of quotes around it here. 5149 return '"' + string.join(map(_escape_msvcrt_shell_arg, argv), " ") + '"' 5150 5151def _escape_msvcrt_shell_arg(arg): 5152 """Escape a command line argument. 5153 5154 This escapes a command line argument to be passed to an MSVCRT program 5155 via the shell (cmd.exe). It uses shell escapes as well as escapes for 5156 MSVCRT. 5157 """ 5158 5159 # The (very strange) parsing rules used by the C runtime library are 5160 # described at: 5161 # http://msdn.microsoft.com/library/en-us/vclang/html/_pluslang_Parsing_C.2b2b_.Command.2d.Line_Arguments.asp 5162 5163 # double up slashes, but only if they are followed by a quote character 5164 arg = re.sub(_re_slashquote, r'\1\1\2', arg) 5165 5166 # surround by quotes and escape quotes inside 5167 arg = '"' + string.replace(arg, '"', '"^""') + '"' 5168 5169 return arg 5170 5171_re_slashquote = re.compile(r'(\\+)(\"|$)') 5172 5173 5174Node-path: svnperl/python/svn/ra.py 5175Node-kind: file 5176Node-action: add 5177Prop-content-length: 10 5178Text-content-length: 616 5179Text-content-md5: c7f4b4e1d0c720e1a9a401c22ccd7697 5180Content-length: 626 5181 5182PROPS-END 5183# 5184# ra.py : various utilities for interacting with the _ra module 5185# 5186###################################################################### 5187# 5188# Copyright (c) 2000-2004 CollabNet. All rights reserved. 5189# 5190# This software is licensed as described in the file COPYING, which 5191# you should have received as part of this distribution. The terms 5192# are also available at http://subversion.tigris.org/license-1.html. 5193# If newer versions of this license are posted there, you may use a 5194# newer version instead, at your option. 5195# 5196###################################################################### 5197# 5198 5199from libsvn.ra import * 5200 5201 5202Node-path: svnperl/python/svn/repos.py 5203Node-kind: file 5204Node-action: add 5205Prop-content-length: 10 5206Text-content-length: 7690 5207Text-content-md5: 5b73f75c0f3ba099ce5d64c9dbe1907a 5208Content-length: 7700 5209 5210PROPS-END 5211# 5212# repos.py : various utilities for interacting with the _repos module 5213# 5214###################################################################### 5215# 5216# Copyright (c) 2000-2004 CollabNet. All rights reserved. 5217# 5218# This software is licensed as described in the file COPYING, which 5219# you should have received as part of this distribution. The terms 5220# are also available at http://subversion.tigris.org/license-1.html. 5221# If newer versions of this license are posted there, you may use a 5222# newer version instead, at your option. 5223# 5224###################################################################### 5225# 5226 5227### hide these names? 5228import string 5229import svn.fs 5230import svn.core 5231import svn.delta 5232 5233from libsvn.repos import * 5234 5235 5236class ChangedPath: 5237 __slots__ = [ 'item_kind', 'prop_changes', 'text_changed', 5238 'base_path', 'base_rev', 'path', 'added', 5239 ] 5240 def __init__(self, 5241 item_kind, prop_changes, text_changed, base_path, base_rev, 5242 path, added): 5243 self.item_kind = item_kind 5244 self.prop_changes = prop_changes 5245 self.text_changed = text_changed 5246 self.base_path = base_path 5247 self.base_rev = base_rev 5248 self.path = path 5249 5250 ### it would be nice to avoid this flag. however, without it, it would 5251 ### be quite difficult to distinguish between a change to the previous 5252 ### revision (which has a base_path/base_rev) and a copy from some 5253 ### other path/rev. a change in path is obviously add-with-history, 5254 ### but the same path could be a change to the previous rev or a restore 5255 ### of an older version. when it is "change to previous", I'm not sure 5256 ### if the rev is always repos.rev - 1, or whether it represents the 5257 ### created or time-of-checkout rev. so... we use a flag (for now) 5258 self.added = added 5259 5260 5261class RevisionChangeCollector(svn.delta.Editor): 5262 5263 # BATON FORMAT: [path, base_path, base_rev] 5264 5265 def __init__(self, fs_ptr, rev, pool): 5266 self.fs_ptr = fs_ptr 5267 self.rev = rev 5268 self.changes = { } # path -> ChangedPathEntry() 5269 self.roots = { } # revision -> svn_fs_root_t 5270 self.pool = pool 5271 5272 def _make_base_path(self, parent_path, path): 5273 idx = string.rfind(path, '/') 5274 if idx == -1: 5275 return parent_path + '/' + path 5276 return parent_path + path[idx:] 5277 5278 def _get_root(self, rev): 5279 try: 5280 return self.roots[rev] 5281 except KeyError: 5282 pass 5283 root = self.roots[rev] = svn.fs.revision_root(self.fs_ptr, rev, self.pool) 5284 return root 5285 5286 def open_root(self, base_revision, dir_pool): 5287 return ('', '', self.rev - 1) # dir_baton 5288 5289 def delete_entry(self, path, revision, parent_baton, pool): 5290 base_path = self._make_base_path(parent_baton[1], path) 5291 if svn.fs.is_dir(self._get_root(parent_baton[2]), base_path, pool): 5292 item_type = svn.core.svn_node_dir 5293 else: 5294 item_type = svn.core.svn_node_file 5295 self.changes[path] = ChangedPath(item_type, 5296 False, 5297 False, 5298 base_path, 5299 parent_baton[2], # base_rev 5300 None, # (new) path 5301 False, # added 5302 ) 5303 5304 def add_directory(self, path, parent_baton, 5305 copyfrom_path, copyfrom_revision, dir_pool): 5306 self.changes[path] = ChangedPath(svn.core.svn_node_dir, 5307 False, 5308 False, 5309 copyfrom_path, # base_path 5310 copyfrom_revision, # base_rev 5311 path, # path 5312 True, # added 5313 ) 5314 if copyfrom_path and (copyfrom_revision != -1): 5315 base_path = copyfrom_path 5316 else: 5317 base_path = path 5318 base_rev = copyfrom_revision 5319 return (path, base_path, base_rev) # dir_baton 5320 5321 def open_directory(self, path, parent_baton, base_revision, dir_pool): 5322 base_path = self._make_base_path(parent_baton[1], path) 5323 return (path, base_path, parent_baton[2]) # dir_baton 5324 5325 def change_dir_prop(self, dir_baton, name, value, pool): 5326 dir_path = dir_baton[0] 5327 if self.changes.has_key(dir_path): 5328 self.changes[dir_path].prop_changes = True 5329 else: 5330 # can't be added or deleted, so this must be CHANGED 5331 self.changes[dir_path] = ChangedPath(svn.core.svn_node_dir, 5332 True, 5333 False, 5334 dir_baton[1], # base_path 5335 dir_baton[2], # base_rev 5336 dir_path, # path 5337 False, # added 5338 ) 5339 5340 def add_file(self, path, parent_baton, 5341 copyfrom_path, copyfrom_revision, file_pool): 5342 self.changes[path] = ChangedPath(svn.core.svn_node_file, 5343 False, 5344 False, 5345 copyfrom_path, # base_path 5346 copyfrom_revision, # base_rev 5347 path, # path 5348 True, # added 5349 ) 5350 if copyfrom_path and (copyfrom_revision != -1): 5351 base_path = copyfrom_path 5352 else: 5353 base_path = path 5354 base_rev = copyfrom_revision 5355 return (path, base_path, base_rev) # file_baton 5356 5357 def open_file(self, path, parent_baton, base_revision, file_pool): 5358 base_path = self._make_base_path(parent_baton[1], path) 5359 return (path, base_path, parent_baton[2]) # file_baton 5360 5361 def apply_textdelta(self, file_baton, base_checksum): 5362 file_path = file_baton[0] 5363 if self.changes.has_key(file_path): 5364 self.changes[file_path].text_changed = True 5365 else: 5366 # an add would have inserted a change record already, and it can't 5367 # be a delete with a text delta, so this must be a normal change. 5368 self.changes[file_path] = ChangedPath(svn.core.svn_node_file, 5369 False, 5370 True, 5371 file_baton[1], # base_path 5372 file_baton[2], # base_rev 5373 file_path, # path 5374 False, # added 5375 ) 5376 5377 # no handler 5378 return None 5379 5380 def change_file_prop(self, file_baton, name, value, pool): 5381 file_path = file_baton[0] 5382 if self.changes.has_key(file_path): 5383 self.changes[file_path].prop_changes = True 5384 else: 5385 # an add would have inserted a change record already, and it can't 5386 # be a delete with a prop change, so this must be a normal change. 5387 self.changes[file_path] = ChangedPath(svn.core.svn_node_file, 5388 True, 5389 False, 5390 file_baton[1], # base_path 5391 file_baton[2], # base_rev 5392 file_path, # path 5393 False, # added 5394 ) 5395 5396# enable True/False in older vsns of Python 5397try: 5398 _unused = True 5399except NameError: 5400 True = 1 5401 False = 0 5402 5403 5404 5405 5406Node-path: svnperl/python/svn/util.py 5407Node-kind: file 5408Node-action: add 5409Prop-content-length: 10 5410Text-content-length: 850 5411Text-content-md5: 381b2bd6ff73f43df51db60f0f11c9ff 5412Content-length: 860 5413 5414PROPS-END 5415# 5416# svn.util: public Python interface for miscellaneous bindings 5417# 5418# Subversion is a tool for revision control. 5419# See http://subversion.tigris.org for more information. 5420# 5421# ==================================================================== 5422# Copyright (c) 2000-2004 CollabNet. All rights reserved. 5423# 5424# This software is licensed as described in the file COPYING, which 5425# you should have received as part of this distribution. The terms 5426# are also available at http://subversion.tigris.org/license-1.html. 5427# If newer versions of this license are posted there, you may use a 5428# newer version instead, at your option. 5429# 5430###################################################################### 5431# 5432 5433# XXX This package might go a way eventually or get different contents 5434# For compatability reasons, we import everything from core 5435from core import * 5436 5437 5438Node-path: svnperl/python/svn/wc.py 5439Node-kind: file 5440Node-action: add 5441Prop-content-length: 10 5442Text-content-length: 616 5443Text-content-md5: 80f3d6791fa944237c050c5d8ee2d40c 5444Content-length: 626 5445 5446PROPS-END 5447# 5448# wc.py : various utilities for interacting with the _wc module 5449# 5450###################################################################### 5451# 5452# Copyright (c) 2000-2004 CollabNet. All rights reserved. 5453# 5454# This software is licensed as described in the file COPYING, which 5455# you should have received as part of this distribution. The terms 5456# are also available at http://subversion.tigris.org/license-1.html. 5457# If newer versions of this license are posted there, you may use a 5458# newer version instead, at your option. 5459# 5460###################################################################### 5461# 5462 5463from libsvn.wc import * 5464 5465 5466Node-path: svnperl/svn_client.i 5467Node-kind: file 5468Node-action: add 5469Prop-content-length: 10 5470Text-content-length: 11850 5471Text-content-md5: 01dcfc856b8488958c3608cd1914b469 5472Content-length: 11860 5473 5474PROPS-END 5475/* 5476 * svn_client.i : SWIG interface file for svn_client.h 5477 * 5478 * ==================================================================== 5479 * Copyright (c) 2000-2003 CollabNet. All rights reserved. 5480 * 5481 * This software is licensed as described in the file COPYING, which 5482 * you should have received as part of this distribution. The terms 5483 * are also available at http://subversion.tigris.org/license-1.html. 5484 * If newer versions of this license are posted there, you may use a 5485 * newer version instead, at your option. 5486 * 5487 * This software consists of voluntary contributions made by many 5488 * individuals. For exact contribution history, see the revision 5489 * history and logs, available at http://subversion.tigris.org/. 5490 * ==================================================================== 5491 */ 5492 5493%module client 5494%include typemaps.i 5495 5496%import apr.i 5497%import svn_types.i 5498%import svn_string.i 5499%import svn_delta.i 5500 5501/* ----------------------------------------------------------------------- 5502 don't wrap the following items 5503*/ 5504%ignore svn_client_proplist_item_t; 5505 5506/* ----------------------------------------------------------------------- 5507 these types (as 'type **') will always be an OUT param 5508*/ 5509%apply SWIGTYPE **OUTPARAM { 5510 svn_client_commit_info_t **, 5511 svn_auth_provider_object_t ** 5512}; 5513 5514/* ----------------------------------------------------------------------- 5515 all "targets" and "diff_options" arrays are constant inputs of 5516 svn_stringbuf_t * 5517 */ 5518%apply const apr_array_header_t *STRINGLIST { 5519 const apr_array_header_t *targets, 5520 const apr_array_header_t *diff_options 5521}; 5522 5523/* ----------------------------------------------------------------------- 5524 fix up the return hash for svn_client_propget() 5525*/ 5526%apply apr_hash_t **PROPHASH { apr_hash_t **props }; 5527 5528/* ----------------------------------------------------------------------- 5529 handle the return value for svn_client_proplist() 5530*/ 5531 5532%typemap(python,in,numinputs=0) apr_array_header_t ** (apr_array_header_t *temp) { 5533 $1 = &temp; 5534} 5535%typemap(python,argout,fragment="t_output_helper") apr_array_header_t ** { 5536 svn_client_proplist_item_t **ppitem; 5537 int i; 5538 int nelts = (*$1)->nelts; 5539 PyObject *list = PyList_New(nelts); 5540 if (list == NULL) 5541 return NULL; 5542 ppitem = (svn_client_proplist_item_t **)(*$1)->elts; 5543 for (i = 0; i < nelts; ++i, ++ppitem) { 5544 PyObject *item = PyTuple_New(2); 5545 PyObject *name = PyString_FromStringAndSize((*ppitem)->node_name->data, 5546 (*ppitem)->node_name->len); 5547 PyObject *hash = svn_swig_py_prophash_to_dict((*ppitem)->prop_hash); 5548 5549 if (item == NULL || name == NULL || hash == NULL) { 5550 Py_XDECREF(item); 5551 Py_XDECREF(name); 5552 Py_XDECREF(hash); 5553 Py_DECREF(list); 5554 return NULL; 5555 } 5556 PyTuple_SET_ITEM(item, 0, name); 5557 PyTuple_SET_ITEM(item, 1, hash); 5558 5559 PyList_SET_ITEM(list, i, item); 5560 } 5561 $result = t_output_helper($result, list); 5562} 5563 5564/* ----------------------------------------------------------------------- 5565 handle svn_wc_notify_func_t/baton pairs 5566*/ 5567 5568%typemap(python,in) (svn_wc_notify_func_t notify_func, void *notify_baton) { 5569 5570 $1 = svn_swig_py_notify_func; 5571 $2 = $input; /* our function is the baton. */ 5572} 5573%typemap(perl5,argout) apr_hash_t **statushash { 5574 /* ### FIXME-perl */ 5575} 5576 5577%typemap(java,in) (svn_wc_notify_func_t notify_func, void *notify_baton) { 5578 5579 $1 = svn_swig_java_notify_func; 5580 $2 = (void*)$input; /* our function is the baton. */ 5581} 5582 5583%typemap(jni) svn_wc_notify_func_t "jobject" 5584%typemap(jtype) svn_wc_notify_func_t "org.tigris.subversion.wc.Notifier" 5585%typemap(jstype) svn_wc_notify_func_t "org.tigris.subversion.wc.Notifier" 5586%typemap(javain) svn_wc_notify_func_t "$javainput" 5587%typemap(javaout) svn_wc_notify_func_t { 5588 return $jnicall; 5589 } 5590 5591%typemap(perl5,in) (svn_wc_notify_func_t notify_func, void *notify_baton) { 5592 /* ### FIXME-perl */ 5593} 5594 5595/* ----------------------------------------------------------------------- 5596 handle svn_wc_notify_func_t/baton pairs 5597*/ 5598 5599%typemap(python,in) (svn_wc_status_func_t status_func, void *status_baton) { 5600 $1 = svn_swig_py_status_func; 5601 $2 = $input; /* our function is the baton. */ 5602} 5603 5604/* ----------------------------------------------------------------------- 5605 handle svn_client_get_commit_log_t/baton pairs 5606*/ 5607 5608%typemap(python,in) (svn_client_get_commit_log_t log_msg_func, 5609 void *log_msg_baton) { 5610 5611 $1 = svn_swig_py_get_commit_log_func; 5612 $2 = $input; /* our function is the baton. */ 5613} 5614 5615%typemap(java,in) (svn_client_get_commit_log_t log_msg_func, 5616 void *log_msg_baton) { 5617 5618 $1 = svn_swig_java_get_commit_log_func; 5619 $2 = (void*)$input; /* our function is the baton. */ 5620} 5621 5622%typemap(jni) svn_client_get_commit_log_t "jobject" 5623%typemap(jtype) svn_client_get_commit_log_t "org.tigris.subversion.client.ClientPrompt" 5624%typemap(jstype) svn_client_get_commit_log_t "org.tigris.subversion.client.ClientPrompt" 5625%typemap(javain) svn_client_get_commit_log_t "$javainput" 5626%typemap(javaout) svn_client_get_commit_log_t { 5627 return $jnicall; 5628 } 5629 5630%typemap(perl5,in) (svn_client_get_commit_log_t log_msg_func, 5631 void *log_msg_baton) { 5632 /* ### FIXME-perl */ 5633} 5634 5635/* ----------------------------------------------------------------------- 5636 handle svn_client_prompt_t/baton pairs 5637*/ 5638 5639%typemap(java,memberin) (svn_client_prompt_t prompt_func, 5640 void *prompt_baton) { 5641 //$1 = svn_swig_java_client_prompt_func; 5642 //$2 = svn_swig_java_make_callback_baton(jenv, $input, _global_pool); 5643} 5644 5645%typemap(java,in) (svn_client_prompt_t prompt_func, 5646 void *prompt_baton) { 5647 $1 = svn_swig_java_client_prompt_func; 5648 $2 = svn_swig_java_make_callback_baton(jenv, $input, _global_pool); 5649} 5650 5651%typemap(java, jni) svn_client_prompt_t "jobject" 5652%typemap(java, jtype) svn_client_prompt_t "org.tigris.subversion.client.ClientPrompt" 5653%typemap(java, jstype) svn_client_prompt_t "org.tigris.subversion.client.ClientPrompt" 5654%typemap(java, javain) svn_client_prompt_t "$javainput" 5655 5656/* ----------------------------------------------------------------------- 5657 handle svn_log_message_receiver_t/baton pairs 5658*/ 5659 5660%typemap(java,in) (svn_log_message_receiver_t receiver, 5661 void *receiver_baton) { 5662 5663 $1 = svn_swig_java_log_message_receiver; 5664 $2 = (void*)$input; /* our function is the baton. */ 5665} 5666 5667%typemap(jni) svn_log_message_receiver_t "jobject" 5668%typemap(jtype) svn_log_message_receiver_t "org.tigris.subversion.client.LogMessageReceiver" 5669%typemap(jstype) svn_log_message_receiver_t "org.tigris.subversion.client.LogMessageReceiver" 5670%typemap(javain) svn_log_message_receiver_t "$javainput" 5671%typemap(javaout) svn_log_message_receiver_t { 5672 return $jnicall; 5673 } 5674 5675/* ----------------------------------------------------------------------- 5676 handle the "statushash" OUTPUT param for svn_client_status() 5677*/ 5678%typemap(python,in,numinputs=0) apr_hash_t **statushash = apr_hash_t **OUTPUT; 5679%typemap(python,argout,fragment="t_output_helper") apr_hash_t **statushash { 5680 $result = t_output_helper( 5681 $result, 5682 svn_swig_py_convert_hash(*$1, SWIGTYPE_p_svn_wc_status_t)); 5683} 5684 5685%typemap(perl5,argout) apr_hash_t **statushash { 5686 /* ### FIXME-perl */ 5687} 5688 5689/* ----------------------------------------------------------------------- 5690 handle the prompt_baton 5691*/ 5692 5693%typemap(jni) svn_log_message_receiver_t "jobject" 5694%typemap(jtype) svn_log_message_receiver_t "org.tigris.subversion.client.LogMessageReceiver" 5695%typemap(jstype) svn_log_message_receiver_t "org.tigris.subversion.client.LogMessageReceiver" 5696%typemap(javain) svn_log_message_receiver_t "$javainput" 5697%typemap(javaout) svn_log_message_receiver_t { 5698 return $jnicall; 5699 } 5700 5701/* ----------------------------------------------------------------------- 5702 We use 'svn_wc_status_t *' in some custom code, but it isn't in the 5703 API anywhere. Thus, SWIG doesn't generate a typemap entry for it. by 5704 adding a simple declaration here, SWIG will insert a name for it. 5705*/ 5706%types(svn_wc_status_t *); 5707 5708/* We also need SWIG to wrap svn_dirent_t for us. It doesn't appear in 5709 any API, but svn_client_ls returns a hash of pointers to dirents. */ 5710%types(svn_dirent_t *); 5711 5712/* ----------------------------------------------------------------------- 5713 thunk the various authentication prompt functions and store 5714 the inputed SV in _global_callback for use in the later argout 5715 typemap 5716*/ 5717%typemap(perl5, in) (svn_auth_simple_prompt_func_t prompt_func, 5718 void *prompt_baton) { 5719 $1 = svn_swig_pl_thunk_simple_prompt; 5720 _global_callback = $input; 5721 $2 = (void *) _global_callback; 5722} 5723 5724%typemap(perl5, in) (svn_auth_username_prompt_func_t prompt_func, 5725 void *prompt_baton) { 5726 $1 = svn_swig_pl_thunk_username_prompt; 5727 _global_callback = $input; 5728 $2 = (void *) _global_callback; 5729} 5730 5731%typemap(perl5, in) (svn_auth_ssl_server_trust_prompt_func_t prompt_func, 5732 void *prompt_baton) { 5733 $1 = svn_swig_pl_thunk_ssl_server_trust_prompt; 5734 _global_callback = $input; 5735 $2 = (void *) _global_callback; 5736} 5737 5738%typemap(perl5, in) (svn_auth_ssl_client_cert_prompt_func_t prompt_func, 5739 void *prompt_baton) { 5740 $1 = svn_swig_pl_thunk_ssl_client_cert_prompt; 5741 _global_callback = $input; 5742 $2 = (void *) _global_callback; 5743} 5744 5745%typemap(perl5, in) (svn_auth_ssl_client_cert_pw_prompt_func_t prompt_func, 5746 void *prompt_baton) { 5747 $1 = svn_swig_pl_thunk_ssl_client_cert_pw_prompt; 5748 _global_callback = $input; 5749 $2 = (void *) _global_callback; 5750} 5751 5752/* For all the prompt functions create a reference for the baton 5753 * (which in this case is an SV pointing to the prompt callback) 5754 * and make that a second return from the prompt function. The 5755 * auth_open_helper can then split these values up so they 5756 * can be stored and the callback can stay valid until the 5757 * auth_baton is freed. */ 5758%typemap(perl5, argout) void *prompt_baton (SV * _global_callback) { 5759 $result = sv_2mortal (newRV_inc (_global_callback)); 5760 argvi++; 5761} 5762 5763/* ----------------------------------------------------------------------- */ 5764 5765/* Convert perl hashes back into apr_hash_t * for setting the config 5766 * member of the svn_client_ctx_t. This is an ugly hack, it will 5767 * always allocate the new apr_hash_t out of the global current_pool 5768 * It would be better to make apr_hash_t's into magic variables in 5769 * perl that are tied to the apr_hash_t interface. This would 5770 * remove the need to convert to and from perl hashs all the time. 5771 */ 5772%typemap(perl5, in) apr_hash_t *config { 5773 $1 = svn_swig_pl_objs_to_hash_by_name ($input, "svn_config_t *", 5774 svn_swig_pl_make_pool ((SV *)NULL)); 5775} 5776 5777%typemap(perl5, out) apr_hash_t *config { 5778 $result = svn_swig_pl_convert_hash($1, SWIG_TypeQuery("svn_config_t *")); 5779 argvi++; 5780} 5781 5782/* ----------------------------------------------------------------------- */ 5783 5784%typemap(java, in) svn_stream_t *out %{ 5785 $1 = svn_swig_java_outputstream_to_stream(jenv, $input, _global_pool); 5786%} 5787%typemap(java, jni) svn_stream_t * "jobject"; 5788%typemap(java, jtype) svn_stream_t * "java.io.OutputStream"; 5789%typemap(java, jstype) svn_stream_t * "java.io.OutputStream"; 5790%typemap(java, javain) svn_stream_t * "$javainput"; 5791 5792/* ----------------------------------------------------------------------- */ 5793 5794/* Include the headers before we swig-include the svn_client.h header file. 5795 SWIG will split the nested svn_client_revision_t structure, and we need 5796 the types declared *before* the split structure is encountered. */ 5797 5798%{ 5799#include "svn_client.h" 5800#include "svn_time.h" 5801 5802#ifdef SWIGPYTHON 5803#include "swigutil_py.h" 5804#endif 5805 5806#ifdef SWIGJAVA 5807#include "swigutil_java.h" 5808#endif 5809 5810#ifdef SWIGPERL 5811#include "swigutil_pl.h" 5812#endif 5813%} 5814 5815%include svn_client.h 5816 5817 5818Node-path: svnperl/svn_delta.i 5819Node-kind: file 5820Node-action: add 5821Prop-content-length: 10 5822Text-content-length: 2568 5823Text-content-md5: d6364c510619d33662b5dd756c718711 5824Content-length: 2578 5825 5826PROPS-END 5827/* 5828 * svn_delta.i : SWIG interface file for svn_delta.h 5829 * 5830 * ==================================================================== 5831 * Copyright (c) 2000-2003 CollabNet. All rights reserved. 5832 * 5833 * This software is licensed as described in the file COPYING, which 5834 * you should have received as part of this distribution. The terms 5835 * are also available at http://subversion.tigris.org/license-1.html. 5836 * If newer versions of this license are posted there, you may use a 5837 * newer version instead, at your option. 5838 * 5839 * This software consists of voluntary contributions made by many 5840 * individuals. For exact contribution history, see the revision 5841 * history and logs, available at http://subversion.tigris.org/. 5842 * ==================================================================== 5843 */ 5844 5845%module delta 5846 5847%include "typemaps.i" 5848 5849%import apr.i 5850%import svn_types.i 5851%import svn_string.i 5852 5853/* ----------------------------------------------------------------------- 5854 For these types, "type **" is always an OUT param. 5855*/ 5856%apply SWIGTYPE **OUTPARAM { 5857 svn_txdelta_stream_t **, 5858 void **, 5859 svn_txdelta_window_t **, 5860 const svn_delta_editor_t **, 5861 svn_txdelta_window_handler_t * 5862}; 5863 5864/* ----------------------------------------------------------------------- 5865 mark window.new_data as readonly since we would need a pool to set it 5866 properly (e.g. to allocate an svn_string_t structure). 5867*/ 5868%immutable svn_txdelta_window_t::new_data; 5869 5870/* ----------------------------------------------------------------------- 5871 thunk editors for the various language bindings. 5872*/ 5873 5874#ifdef SWIGPYTHON 5875void svn_swig_py_make_editor(const svn_delta_editor_t **editor, 5876 void **edit_baton, 5877 PyObject *py_editor, 5878 apr_pool_t *pool); 5879#endif 5880 5881%typemap(perl5, in) (const svn_delta_editor_t *editor, void *edit_baton) { 5882 svn_delta_make_editor(&$1, &$2, $input, _global_pool); 5883} 5884 5885/* ----------------------------------------------------------------------- */ 5886 5887%include svn_delta.h 5888%{ 5889#include "svn_md5.h" 5890#include "svn_delta.h" 5891 5892#ifdef SWIGPYTHON 5893#include "swigutil_py.h" 5894#endif 5895 5896#ifdef SWIGJAVA 5897#include "swigutil_java.h" 5898#endif 5899 5900#ifdef SWIGPERL 5901#include "swigutil_pl.h" 5902#endif 5903%} 5904 5905/* ----------------------------------------------------------------------- 5906 editor callback invokers 5907*/ 5908 5909/* Cancel the typemap as they aren't returned valued in member functions 5910 if editor. */ 5911%typemap(perl5, in) (const svn_delta_editor_t *editor, void *edit_baton); 5912 5913#ifdef SWIGPERL 5914%include delta_editor.hi 5915#endif 5916 5917 5918Node-path: svnperl/svn_fs.i 5919Node-kind: file 5920Node-action: add 5921Prop-content-length: 10 5922Text-content-length: 5717 5923Text-content-md5: 483cb324468352333fd7fd1bb2febb66 5924Content-length: 5727 5925 5926PROPS-END 5927/* 5928 * svn_fs.i : SWIG interface file for svn_fs.h 5929 * 5930 * ==================================================================== 5931 * Copyright (c) 2000-2003 CollabNet. All rights reserved. 5932 * 5933 * This software is licensed as described in the file COPYING, which 5934 * you should have received as part of this distribution. The terms 5935 * are also available at http://subversion.tigris.org/license-1.html. 5936 * If newer versions of this license are posted there, you may use a 5937 * newer version instead, at your option. 5938 * 5939 * This software consists of voluntary contributions made by many 5940 * individuals. For exact contribution history, see the revision 5941 * history and logs, available at http://subversion.tigris.org/. 5942 * ==================================================================== 5943 */ 5944 5945%module fs 5946%include typemaps.i 5947 5948%import apr.i 5949%import svn_types.i 5950%import svn_string.i 5951%import svn_delta.i 5952 5953/* ----------------------------------------------------------------------- 5954 do not generate any constructors or destructors (of structures) -- all 5955 structures are going to come /out/ of the FS (so we don't need to 5956 construct the things) and will live in a pool (so we don't need to 5957 destroy the things). 5958*/ 5959%nodefault; 5960 5961/* ----------------------------------------------------------------------- 5962 these types (as 'type **') will always be an OUT param 5963*/ 5964%apply SWIGTYPE **OUTPARAM { 5965 svn_fs_root_t **, 5966 svn_fs_txn_t **, 5967 void **, 5968 svn_fs_history_t **, 5969 svn_fs_id_t ** 5970}; 5971 5972/* and this is always an OUT param */ 5973%apply const char **OUTPUT { const char ** }; 5974 5975/* ### need to deal with IN params which have "const" and OUT params which 5976 ### return non-const type. SWIG's type checking may see these as 5977 ### incompatible. */ 5978 5979/* ----------------------------------------------------------------------- 5980 These parameters may be NULL. 5981*/ 5982%apply const char *MAY_BE_NULL { 5983 const char *base_checksum, 5984 const char *result_checksum 5985}; 5986 5987/* ----------------------------------------------------------------------- 5988 for the FS, 'int *' will always be an OUTPUT parameter 5989*/ 5990%apply int *OUTPUT { int * }; 5991 5992/* ----------------------------------------------------------------------- 5993 define the data/len pair of svn_fs_parse_id to be a single argument 5994*/ 5995%apply (const char *PTR, apr_size_t LEN) { 5996 (const char *data, apr_size_t len) 5997} 5998 5999/* ----------------------------------------------------------------------- 6000 list_transaction's "apr_array_header_t **" is returning a list of strings. 6001*/ 6002 6003%typemap(in,numinputs=0) apr_array_header_t ** (apr_array_header_t *temp) { 6004 $1 = &temp; 6005} 6006%typemap(python, argout, fragment="t_output_helper") 6007apr_array_header_t **names_p { 6008 $result = t_output_helper($result, svn_swig_py_array_to_list(*$1)); 6009} 6010 6011%typemap(perl5, argout) apr_array_header_t **names_p { 6012 $result = svn_swig_pl_array_to_list(*$1); 6013 ++argvi; 6014} 6015/* ----------------------------------------------------------------------- 6016 revisions_changed's "apr_array_header_t **" is returning a list of 6017 revs. also, its input array is a list of strings. 6018*/ 6019 6020%typemap(python, argout, fragment="t_output_helper") 6021apr_array_header_t **revs { 6022 $result = t_output_helper($result, svn_swig_py_revarray_to_list(*$1)); 6023} 6024%typemap(perl5, argout) apr_array_header_t **revs { 6025 $result = svn_swig_pl_ints_to_list(*$1); 6026 ++argvi; 6027} 6028 6029/* ----------------------------------------------------------------------- 6030 all uses of "apr_hash_t **" are returning property hashes 6031*/ 6032 6033%apply apr_hash_t **PROPHASH { apr_hash_t ** }; 6034 6035/* ----------------------------------------------------------------------- 6036 except for svn_fs_dir_entries, which returns svn_fs_dirent_t structures 6037*/ 6038 6039%typemap(python,in,numinputs=0) apr_hash_t **entries_p = apr_hash_t **OUTPUT; 6040%typemap(python,argout,fragment="t_output_helper") apr_hash_t **entries_p { 6041 $result = t_output_helper( 6042 $result, 6043 svn_swig_py_convert_hash(*$1, SWIGTYPE_p_svn_fs_dirent_t)); 6044} 6045%typemap(perl5,in,numinputs=0) apr_hash_t **entries_p = apr_hash_t **OUTPUT; 6046%typemap(perl5,argout) apr_hash_t **entries_p { 6047 ST(argvi++) = svn_swig_pl_convert_hash(*$1, SWIGTYPE_p_svn_fs_dirent_t); 6048} 6049 6050/* ----------------------------------------------------------------------- 6051 and except for svn_fs_paths_changed, which returns svn_fs_path_change_t 6052 structures 6053*/ 6054 6055%typemap(python, in,numinputs=0) apr_hash_t **changed_paths_p = apr_hash_t **OUTPUT; 6056%typemap(python, argout, fragment="t_output_helper") apr_hash_t **changed_paths_p { 6057 $result = t_output_helper( 6058 $result, 6059 svn_swig_py_convert_hash(*$1, SWIGTYPE_p_svn_fs_path_change_t)); 6060} 6061 6062/* ----------------------------------------------------------------------- 6063 Fix the return value for svn_fs_commit_txn(). If the conflict result is 6064 NULL, then t_output_helper() is passed Py_None, but that goofs up 6065 because that is *also* the marker for "I haven't started assembling a 6066 multi-valued return yet" which means the second return value (new_rev) 6067 will not cause a 2-tuple to be manufactured. 6068 6069 The answer is to explicitly create a 2-tuple return value. 6070*/ 6071%typemap(python, argout) (const char **conflict_p, svn_revnum_t *new_rev) { 6072 /* this is always Py_None */ 6073 Py_DECREF($result); 6074 /* build the result tuple */ 6075 $result = Py_BuildValue("zi", *$1, (long)*$2); 6076} 6077 6078%typemap(perl5, argout) apr_hash_t **changed_paths_p { 6079 /* ### FIXME-perl */ 6080} 6081/* ----------------------------------------------------------------------- */ 6082 6083 6084 6085%include svn_fs.h 6086%{ 6087#include "svn_md5.h" 6088#include "svn_fs.h" 6089 6090#ifdef SWIGPYTHON 6091#include "swigutil_py.h" 6092#endif 6093 6094#ifdef SWIGJAVA 6095#include "swigutil_java.h" 6096#endif 6097 6098#ifdef SWIGPERL 6099#include "swigutil_pl.h" 6100#endif 6101%} 6102 6103 6104Node-path: svnperl/svn_ra.i 6105Node-kind: file 6106Node-action: add 6107Prop-content-length: 10 6108Text-content-length: 2602 6109Text-content-md5: 1eff5dcfd5431ffa33c6b4cd12bd9a79 6110Content-length: 2612 6111 6112PROPS-END 6113/* 6114 * svn_ra.i : SWIG interface file for svn_ra.h 6115 * 6116 * ==================================================================== 6117 * Copyright (c) 2000-2003 CollabNet. All rights reserved. 6118 * 6119 * This software is licensed as described in the file COPYING, which 6120 * you should have received as part of this distribution. The terms 6121 * are also available at http://subversion.tigris.org/license-1.html. 6122 * If newer versions of this license are posted there, you may use a 6123 * newer version instead, at your option. 6124 * 6125 * This software consists of voluntary contributions made by many 6126 * individuals. For exact contribution history, see the revision 6127 * history and logs, available at http://subversion.tigris.org/. 6128 * ==================================================================== 6129 */ 6130 6131%module ra 6132%include typemaps.i 6133 6134%import apr.i 6135%import svn_types.i 6136%import svn_string.i 6137%import svn_delta.i 6138 6139/* bad pool convention, also these should not be public interface at all 6140 as commented by sussman. */ 6141%ignore svn_ra_svn_init; 6142%ignore svn_ra_local_init; 6143%ignore svn_ra_dav_init; 6144 6145/* ----------------------------------------------------------------------- 6146 these types (as 'type **') will always be an OUT param 6147*/ 6148%apply SWIGTYPE **OUTPARAM { 6149 svn_ra_plugin_t **, 6150 session_baton **, 6151 const svn_ra_reporter_t **reporter, 6152 void **report_baton 6153}; 6154 6155%apply apr_hash_t **PROPHASH { apr_hash_t **props }; 6156 6157/* ----------------------------------------------------------------------- 6158 thunk ra_callback 6159*/ 6160%apply const char **OUTPUT { 6161 const char **url, 6162 const char **uuid 6163}; 6164 6165%apply const apr_array_header_t *STRINGLIST { 6166 const apr_array_header_t *paths 6167}; 6168 6169%typemap(perl5, in) (const svn_delta_editor_t *update_editor, 6170 void *update_baton) { 6171 svn_delta_make_editor(&$1, &$2, $input, _global_pool); 6172} 6173%typemap(perl5, in) (const svn_delta_editor_t *diff_editor, 6174 void *diff_baton) { 6175 svn_delta_make_editor(&$1, &$2, $input, _global_pool); 6176} 6177 6178%typemap(perl5, in) (const svn_ra_callbacks_t *callbacks, 6179 void *callback_baton) { 6180 svn_ra_make_callbacks(&$1, &$2, $input, _global_pool); 6181} 6182 6183%typemap(perl5, in) apr_hash_t *config { 6184 $1 = svn_swig_pl_objs_to_hash_by_name ($input, "svn_config_t *", 6185 _global_pool); 6186} 6187 6188/* ----------------------------------------------------------------------- */ 6189 6190%include svn_ra.h 6191%{ 6192#include "svn_ra.h" 6193 6194#ifdef SWIGPYTHON 6195#include "swigutil_py.h" 6196#endif 6197 6198#ifdef SWIGJAVA 6199#include "swigutil_java.h" 6200#endif 6201 6202#ifdef SWIGPERL 6203#include "swigutil_pl.h" 6204#endif 6205%} 6206 6207#ifdef SWIGPERL 6208%include ra_plugin.hi 6209%include ra_reporter.hi 6210#endif 6211 6212 6213Node-path: svnperl/svn_repos.i 6214Node-kind: file 6215Node-action: add 6216Prop-content-length: 10 6217Text-content-length: 3629 6218Text-content-md5: abc80867e227a5642d8288bdde1112c5 6219Content-length: 3639 6220 6221PROPS-END 6222/* 6223 * svn_repos.i : SWIG interface file for svn_repos.h 6224 * 6225 * ==================================================================== 6226 * Copyright (c) 2000-2003 CollabNet. All rights reserved. 6227 * 6228 * This software is licensed as described in the file COPYING, which 6229 * you should have received as part of this distribution. The terms 6230 * are also available at http://subversion.tigris.org/license-1.html. 6231 * If newer versions of this license are posted there, you may use a 6232 * newer version instead, at your option. 6233 * 6234 * This software consists of voluntary contributions made by many 6235 * individuals. For exact contribution history, see the revision 6236 * history and logs, available at http://subversion.tigris.org/. 6237 * ==================================================================== 6238 */ 6239 6240%module repos 6241%include typemaps.i 6242 6243%import apr.i 6244%import svn_types.i 6245%import svn_string.i 6246%import svn_delta.i 6247%import svn_fs.i 6248 6249/* ----------------------------------------------------------------------- 6250 these types (as 'type **') will always be an OUT param 6251*/ 6252%apply SWIGTYPE **OUTPARAM { 6253 svn_repos_t ** 6254}; 6255 6256/* ----------------------------------------------------------------------- 6257 Some of the various parameters need to be NULL sometimes 6258*/ 6259%apply const char *MAY_BE_NULL { 6260 const char *src_entry, 6261 const char *on_disk_template, 6262 const char *in_repos_template 6263}; 6264 6265/* ----------------------------------------------------------------------- 6266 handle the 'paths' parameter appropriately 6267*/ 6268%apply const apr_array_header_t *STRINGLIST { 6269 const apr_array_header_t *paths 6270}; 6271 6272/* ----------------------------------------------------------------------- 6273 XXX: for some reasons svn_delta_editor doesn't get typemapped even 6274 if svn_delta.i is imported. so we redeclare here. 6275*/ 6276 6277%typemap(perl5, in) (const svn_delta_editor_t *editor, void *edit_baton) { 6278 svn_delta_make_editor(&$1, &$2, $input, _global_pool); 6279} 6280 6281/* ----------------------------------------------------------------------- 6282 commit editor support 6283*/ 6284%apply SWIGTYPE **OUTPARAM { 6285 const svn_delta_editor_t **editor, 6286 void **edit_baton 6287}; 6288 6289/* ----------------------------------------------------------------------- 6290 handle svn_repos_history_func_t/baton pairs 6291*/ 6292%typemap(python,in) (svn_repos_history_func_t history_func, void *history_baton) { 6293 6294 $1 = svn_swig_py_repos_history_func; 6295 $2 = $input; /* our function is the baton. */ 6296} 6297 6298%typemap(perl5,in) (svn_repos_history_func_t history_func, void *history_baton) { 6299 6300 $1 = svn_swig_pl_thunk_history_func; 6301 $2 = $input; /* our function is the baton. */ 6302} 6303 6304 6305/* ----------------------------------------------------------------------- 6306 handle svn_repos_authz_read_func_t/baton pairs 6307*/ 6308 6309%typemap(perl5, in) (svn_repos_authz_func_t authz_read_func, void *authz_read_baton) { 6310 if (SvOK ($input)) { 6311 $1 = svn_swig_pl_thunk_authz_func; 6312 $2 = $input; /* our function is the baton */ 6313 } 6314 else { 6315 $1 = NULL; 6316 $2 = NULL; 6317 } 6318} 6319 6320/* ----------------------------------------------------------------------- 6321 handle config and fs_config in svn_repos_create 6322*/ 6323 6324%typemap(perl5, in) apr_hash_t *config { 6325 $1 = svn_swig_pl_objs_to_hash_by_name ($input, "svn_config_t *", 6326 _global_pool); 6327} 6328 6329%typemap(perl5, in) apr_hash_t *fs_config { 6330 $1 = svn_swig_pl_strings_to_hash ($input, _global_pool); 6331} 6332 6333 6334/* ----------------------------------------------------------------------- */ 6335 6336%include svn_repos.h 6337%{ 6338#include "svn_repos.h" 6339 6340#ifdef SWIGPYTHON 6341#include "swigutil_py.h" 6342#endif 6343 6344#ifdef SWIGJAVA 6345#include "swigutil_java.h" 6346#endif 6347 6348#ifdef SWIGPERL 6349#include "swigutil_pl.h" 6350#endif 6351%} 6352 6353 6354Node-path: svnperl/svn_string.i 6355Node-kind: file 6356Node-action: add 6357Prop-content-length: 10 6358Text-content-length: 6532 6359Text-content-md5: 82660c555cd5ccb442c420237530aca5 6360Content-length: 6542 6361 6362PROPS-END 6363/* 6364 * svn_string.i : SWIG interface file for svn_string.h 6365 * 6366 * ==================================================================== 6367 * Copyright (c) 2000-2003 CollabNet. All rights reserved. 6368 * 6369 * This software is licensed as described in the file COPYING, which 6370 * you should have received as part of this distribution. The terms 6371 * are also available at http://subversion.tigris.org/license-1.html. 6372 * If newer versions of this license are posted there, you may use a 6373 * newer version instead, at your option. 6374 * 6375 * This software consists of voluntary contributions made by many 6376 * individuals. For exact contribution history, see the revision 6377 * history and logs, available at http://subversion.tigris.org/. 6378 * ==================================================================== 6379 */ 6380 6381/* This interface file does not include a %module line because it should 6382 only be imported by other modules. */ 6383 6384%import apr.i 6385%import svn_types.i 6386 6387typedef struct svn_stringbuf_t svn_stringbuf_t; 6388typedef struct svn_string_t svn_string_t; 6389 6390/* ----------------------------------------------------------------------- 6391 generic OUT param typemap for svn_string(buf)_t. we can share these 6392 because we only refer to the ->data and ->len values. 6393*/ 6394%typemap(python,argout,fragment="t_output_helper") RET_STRING { 6395 PyObject *s; 6396 if (*$1 == NULL) { 6397 Py_INCREF(Py_None); 6398 s = Py_None; 6399 } 6400 else { 6401 s = PyString_FromStringAndSize((*$1)->data, (*$1)->len); 6402 if (s == NULL) 6403 return NULL; 6404 } 6405 $result = t_output_helper($result, s); 6406} 6407%typemap(java,out) RET_STRING { 6408 /* FIXME: This is just a stub -- implement JNI code for returning a string! */ 6409 $output = NULL; 6410} 6411 6412%typemap(jni) char * "jstring" 6413 6414%typemap(perl5,argout) RET_STRING { 6415 if (*$1) { 6416 $result = sv_newmortal(); 6417 sv_setpvn ($result, (*$1)->data, (*$1)->len); 6418 } 6419 else 6420 $result = &PL_sv_undef; 6421 argvi++; 6422} 6423/* ----------------------------------------------------------------------- 6424 TYPE: svn_stringbuf_t 6425*/ 6426 6427%typemap(python,in) svn_stringbuf_t * { 6428 if (!PyString_Check($input)) { 6429 PyErr_SetString(PyExc_TypeError, "not a string"); 6430 return NULL; 6431 } 6432 $1 = svn_stringbuf_ncreate(PyString_AS_STRING($input), 6433 PyString_GET_SIZE($input), 6434 /* ### gah... what pool to use? */ 6435 _global_pool); 6436} 6437 6438%typemap(perl5,in) svn_stringbuf_t * { 6439 /* ### FIXME-perl */ 6440} 6441%typemap(python,out) svn_stringbuf_t * { 6442 $result = PyString_FromStringAndSize($1->data, $1->len); 6443} 6444%typemap(perl5,out) svn_stringbuf_t * { 6445 /* ### FIXME-perl */ 6446} 6447 6448/* svn_stringbuf_t ** is always an output parameter */ 6449%typemap(python,in,numinputs=0) svn_stringbuf_t ** (svn_stringbuf_t *temp) { 6450 $1 = &temp; 6451} 6452%typemap(perl5,in,numinputs=0) svn_stringbuf_t ** (svn_stringbuf_t *temp) { 6453 $1 = &temp; 6454} 6455%apply RET_STRING { svn_stringbuf_t ** }; 6456 6457 6458/* ----------------------------------------------------------------------- 6459 TYPE: svn_string_t 6460*/ 6461 6462/* const svn_string_t * is always an input parameter */ 6463%typemap(python,in) const svn_string_t * (svn_string_t value) { 6464 if ($input == Py_None) 6465 $1 = NULL; 6466 else { 6467 if (!PyString_Check($input)) { 6468 PyErr_SetString(PyExc_TypeError, "not a string"); 6469 return NULL; 6470 } 6471 value.data = PyString_AS_STRING($input); 6472 value.len = PyString_GET_SIZE($input); 6473 $1 = &value; 6474 } 6475} 6476%typemap(perl5,in) const svn_string_t * (svn_string_t value) { 6477 if (SvOK($input)) { 6478 value.data = SvPV($input, value.len); 6479 $1 = &value; 6480 } 6481 else { 6482 $1 = NULL; 6483 } 6484} 6485 6486/* when storing an svn_string_t* into a structure, we must allocate the 6487 svn_string_t structure on the heap. */ 6488%typemap(python,memberin) const svn_string_t * { 6489 $1 = svn_string_dup($input, _global_pool); 6490} 6491%typemap(perl5,memberin) const svn_string_t * { 6492 $1 = svn_string_dup($input, _global_pool); 6493} 6494 6495%typemap(python,out) svn_string_t * { 6496 $result = PyString_FromStringAndSize($1->data, $1->len); 6497} 6498%typemap(perl5,out) svn_string_t * { 6499 $result = sv_2mortal(newSVpv($1->data, $1->len)); 6500 ++argvi; 6501} 6502 6503/* svn_string_t ** is always an output parameter */ 6504%typemap(in,numinputs=0) svn_string_t ** (svn_string_t *temp) { 6505 $1 = &temp; 6506} 6507%apply RET_STRING { svn_string_t ** }; 6508 6509 6510 6511/* ----------------------------------------------------------------------- 6512 define a way to return a 'const char *' 6513*/ 6514 6515/* ### note that SWIG drops the const in the arg decl, so we must cast */ 6516%typemap(in, numinputs=0) const char **OUTPUT (const char *temp = NULL) 6517 "$1 = (char **)&temp;" 6518 6519%typemap(python,argout,fragment="t_output_helper") const char **OUTPUT { 6520 PyObject *s; 6521 if (*$1 == NULL) { 6522 Py_INCREF(Py_None); 6523 s = Py_None; 6524 } 6525 else { 6526 s = PyString_FromString(*$1); 6527 if (s == NULL) 6528 return NULL; 6529 } 6530 $result = t_output_helper($result, s); 6531} 6532 6533%typemap(perl5,argout) const char **OUTPUT { 6534 if (*$1 == NULL) 6535 $result = &PL_sv_undef; 6536 else 6537 $result = sv_2mortal(newSVpv(*$1, 0)); 6538 ++argvi; 6539} 6540/* ----------------------------------------------------------------------- 6541 define a general INPUT param of an array of svn_stringbuf_t* items. 6542 */ 6543 6544%typemap(python,in) const apr_array_header_t *STRINGLIST { 6545 $1 = (apr_array_header_t *) svn_swig_py_strings_to_array($input, 6546 _global_pool); 6547 if ($1 == NULL) 6548 return NULL; 6549} 6550%typemap(perl5,in) const apr_array_header_t *STRINGLIST { 6551 $1 = (apr_array_header_t *) svn_swig_pl_strings_to_array($input, 6552 _global_pool); 6553} 6554 6555%typemap(jni) const apr_array_header_t *STRINGLIST "jobjectArray" 6556%typemap(jtype) const apr_array_header_t *STRINGLIST "java.lang.String[]" 6557%typemap(jstype) const apr_array_header_t *STRINGLIST "java.lang.String[]" 6558%typemap(javain) const apr_array_header_t *STRINGLIST "$javainput" 6559 6560%typemap(java,in) const apr_array_header_t *STRINGLIST (apr_array_header_t *temp) { 6561 temp = (apr_array_header_t *)svn_swig_java_strings_to_array(jenv, $input, _global_pool); 6562 $1 = temp; 6563} 6564 6565%typemap(java,freearg) const apr_array_header_t *STRINGLIST { 6566 /* FIXME: Perhaps free up "temp"? */ 6567} 6568 6569/* path lists */ 6570%apply const apr_array_header_t *STRINGLIST { 6571 const apr_array_header_t *paths 6572}; 6573 6574/* ----------------------------------------------------------------------- */ 6575 6576 6577Node-path: svnperl/svn_types.i 6578Node-kind: file 6579Node-action: add 6580Prop-content-length: 10 6581Text-content-length: 13306 6582Text-content-md5: 5e8a9b95aa95943e34874cae5e13d463 6583Content-length: 13316 6584 6585PROPS-END 6586/* 6587 * svn_types.i : SWIG interface file for svn_types.h 6588 * 6589 * ==================================================================== 6590 * Copyright (c) 2000-2003 CollabNet. All rights reserved. 6591 * 6592 * This software is licensed as described in the file COPYING, which 6593 * you should have received as part of this distribution. The terms 6594 * are also available at http://subversion.tigris.org/license-1.html. 6595 * If newer versions of this license are posted there, you may use a 6596 * newer version instead, at your option. 6597 * 6598 * This software consists of voluntary contributions made by many 6599 * individuals. For exact contribution history, see the revision 6600 * history and logs, available at http://subversion.tigris.org/. 6601 * ==================================================================== 6602 */ 6603 6604/* This interface file only defines types and their related information. 6605 There is no module associated with this interface file. */ 6606 6607%import apr.i 6608 6609/* ----------------------------------------------------------------------- 6610 Create a typemap to define "type **" as OUT parameters. 6611 6612 Note: SWIGTYPE is just a placeholder for "some arbitrary type". This 6613 typemap will be applied onto a "real" type. 6614*/ 6615 6616%typemap(python, in, numinputs=0) SWIGTYPE **OUTPARAM ($*1_type temp) { 6617 $1 = ($1_ltype)&temp; 6618} 6619%typemap(java, in) SWIGTYPE **OUTPARAM ($*1_type temp) { 6620 $1 = ($1_ltype)&temp; 6621} 6622%typemap(perl5, in, numinputs=0) SWIGTYPE **OUTPARAM ($*1_type temp) { 6623 $1 = ($1_ltype)&temp; 6624} 6625%typemap(python, argout, fragment="t_output_helper") SWIGTYPE **OUTPARAM { 6626 $result = t_output_helper($result, 6627 SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); 6628} 6629%typemap(perl5, argout) SWIGTYPE **OUTPARAM { 6630 ST(argvi) = sv_newmortal(); 6631 SWIG_MakePtr(ST(argvi++), (void *)*$1, $*1_descriptor,0); 6632} 6633 6634/* ----------------------------------------------------------------------- 6635 Create a typemap to handle enums. 6636*/ 6637 6638%typemap(python, in, numinputs=0) enum SWIGTYPE *OUTENUM ($*1_type temp) { 6639 $1 = ($1_ltype)&temp; 6640} 6641%typemap(perl5, in, numinputs=0) enum SWIGTYPE *OUTENUM (long temp) { 6642 $1 = ($1_ltype)&temp; 6643} 6644 6645%typemap(perl5, argout) enum SWIGTYPE *OUTENUM { 6646 if (argvi >= items) { 6647 EXTEND(sp,1); 6648 } 6649 $result = sv_newmortal(); 6650 sv_setiv($result,(IV) *($1)); 6651 argvi++; 6652} 6653 6654%typemap(java, in) enum SWIGTYPE *OUTENUM ($*1_type temp) { 6655 $1 = ($1_ltype)&temp; 6656} 6657%typemap(python, argout, fragment="t_output_helper") enum SWIGTYPE *OUTENUM { 6658 $result = t_output_helper($result, PyInt_FromLong(*$1)); 6659} 6660 6661/* ----------------------------------------------------------------------- 6662 Create a typemap for specifying string args that may be NULL. 6663*/ 6664%typemap(python, in, parse="z") const char *MAY_BE_NULL ""; 6665 6666%typemap(java, in) const char *MAY_BE_NULL { 6667 /* ### WHEN IS THIS USED? */ 6668 $1 = 0; 6669 if ($input) { 6670 $1 = ($1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0); 6671 if (!$1) return $null; 6672 } 6673} 6674 6675#ifdef SWIGPERL 6676%apply const char * { const char *MAY_BE_NULL }; 6677#endif 6678 6679%typemap(perl5,out) svn_error_t * { 6680 if ($1) { 6681 char buf[128], *p; 6682 SV *err = sv_newmortal(); 6683 p = svn_strerror($1->apr_err, buf, 128); 6684 sv_setpv (err, p); 6685 while ($1) { 6686 sv_catpvf (err, ": %s", $1->message); 6687 $1 = $1->child; 6688 } 6689 croak (SvPV_nolen(err)); 6690 } 6691} 6692 6693/* ----------------------------------------------------------------------- 6694 Define a more refined 'varin' typemap for 'const char *' members. This 6695 is used in place of the 'char *' handler defined automatically. 6696 6697 We need to do the free/malloc/strcpy special because of the const 6698*/ 6699%typemap(memberin) const char * { 6700 apr_size_t len = strlen($input) + 1; 6701 char *copied; 6702 if ($1) free((char *)$1); 6703 copied = malloc(len); 6704 memcpy(copied, $input, len); 6705 $1 = copied; 6706} 6707 6708/* ----------------------------------------------------------------------- 6709 Specify how svn_error_t returns are turned into exceptions. 6710*/ 6711 6712%typemap(python, out) svn_error_t * { 6713 if ($1 != NULL) { 6714 if ($1->apr_err != SVN_ERR_SWIG_PY_EXCEPTION_SET) 6715 svn_swig_py_svn_exception($1); 6716 else 6717 svn_error_clear($1); 6718 return NULL; 6719 } 6720 Py_INCREF(Py_None); 6721 $result = Py_None; 6722} 6723 6724%typemap(java, out) svn_error_t * %{ 6725 $result = ($1 != NULL) ? svn_swig_java_convert_error(jenv, $1) : NULL; 6726%} 6727%typemap(jni) svn_error_t * "jthrowable" 6728%typemap(jtype) svn_error_t * "org.tigris.subversion.SubversionException" 6729%typemap(jstype) svn_error_t * "org.tigris.subversion.SubversionException" 6730%typemap(javain) svn_error_t * "@javainput" 6731%typemap(javaout) svn_error_t * { 6732 return $jnicall; 6733} 6734 6735/* Make the proxy classes much more usable */ 6736%typemap(javaptrconstructormodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "public" 6737 6738/* ----------------------------------------------------------------------- 6739 'svn_revnum_t *' and 'svn_boolean_t *' will always be an OUTPUT parameter 6740*/ 6741%apply long *OUTPUT { svn_revnum_t * }; 6742%apply int *OUTPUT { svn_boolean_t * }; 6743 6744/* ----------------------------------------------------------------------- 6745 Define an OUTPUT typemap for 'svn_filesize_t *'. For now, we'll 6746 treat it as a 'long' even if that isn't entirely correct... 6747*/ 6748%typemap(python,in,numinputs=0) svn_filesize_t * (svn_filesize_t temp) 6749 "$1 = &temp;"; 6750 6751%typemap(python,argout,fragment="t_output_helper") svn_filesize_t * 6752 "$result = t_output_helper($result,PyInt_FromLong((long) (*$1)));"; 6753 6754%apply long *OUTPUT { svn_filesize_t * }; 6755 6756/* ----------------------------------------------------------------------- 6757 Define a general ptr/len typemap. This takes a single script argument 6758 and expands it into a ptr/len pair for the native call. 6759*/ 6760%typemap(python, in) (const char *PTR, apr_size_t LEN) { 6761 if (!PyString_Check($input)) { 6762 PyErr_SetString(PyExc_TypeError, "expecting a string"); 6763 return NULL; 6764 } 6765 $1 = PyString_AS_STRING($input); 6766 $2 = PyString_GET_SIZE($input); 6767} 6768 6769%typemap(java, in) (const char *PTR, apr_size_t LEN) (char c) { 6770 if ($input != NULL) { 6771 /* Do not use GetPrimitiveArrayCritical and ReleasePrimitiveArrayCritical 6772 * since the Subversion client might block the thread */ 6773 6774 $1 = JCALL2(GetByteArrayElements, jenv, $input, NULL); 6775 $2 = JCALL1(GetArrayLength, jenv, $input); 6776 } 6777 else { 6778 $1 = &c; 6779 $2 = 0; 6780 } 6781} 6782 6783%typemap(java, freearg) (const char *PTR, apr_size_t LEN) { 6784 if ($input != NULL) { 6785 JCALL3(ReleaseByteArrayElements, jenv, $input, $1, JNI_ABORT); 6786 } 6787 /* Since this buffer is used as input JNI_ABORT is safe as "mode" above*/ 6788} 6789 6790%typemap(jni) (const char *PTR, apr_size_t LEN) "jbyteArray" 6791%typemap(jtype) (const char *PTR, apr_size_t LEN) "byte[]" 6792%typemap(jstype) (const char *PTR, apr_size_t LEN) "byte[]" 6793%typemap(javain) (const char *PTR, apr_size_t LEN) "$javainput" 6794%typemap(javaout) (const char *PTR, apr_size_t LEN) { 6795 return $jnicall; 6796 } 6797 6798%typemap(perl5, in) (const char *PTR, apr_size_t LEN) { 6799 if (SvPOK($input)) { 6800 $1 = SvPV($input, $2); 6801 } else { 6802 /* set to 0 to avoid warning */ 6803 $1 = 0; 6804 $2 = 0; 6805 SWIG_croak("Expecting a string"); 6806 } 6807} 6808/* ----------------------------------------------------------------------- 6809 Define a generic arginit mapping for pools. 6810*/ 6811 6812%typemap(python, arginit) apr_pool_t *pool(apr_pool_t *_global_pool) { 6813 /* Assume that the pool here is the last argument in the list */ 6814 SWIG_ConvertPtr(PyTuple_GET_ITEM(args, PyTuple_GET_SIZE(args) - 1), 6815 (void **)&$1, $1_descriptor, SWIG_POINTER_EXCEPTION | 0); 6816 _global_pool = $1; 6817} 6818%typemap(perl5, in) apr_pool_t *pool ""; 6819%typemap(perl5, default) apr_pool_t *pool(apr_pool_t *_global_pool) { 6820 _global_pool = $1 = svn_swig_pl_make_pool (ST(items-1)); 6821} 6822 6823#ifdef SWIGPERL 6824%apply apr_pool_t *pool { 6825 apr_pool_t *dir_pool, 6826 apr_pool_t *file_pool, 6827 apr_pool_t *node_pool 6828}; 6829#endif 6830 6831%typemap(java, arginit) apr_pool_t *pool(apr_pool_t *_global_pool) { 6832 /* ### HACK: Get the input variable based on naming convention */ 6833 _global_pool = *(apr_pool_t **)&j$1; 6834 $1 = 0; 6835} 6836 6837/* ----------------------------------------------------------------------- 6838 result of check_path 6839*/ 6840%apply enum SWIGTYPE *OUTENUM { svn_node_kind_t * }; 6841 6842/* ----------------------------------------------------------------------- 6843 get_logs takes a callback function, so we have to thunk it 6844*/ 6845 6846%typemap(python, in) (svn_log_message_receiver_t receiver, 6847 void *receiver_baton) { 6848 $1 = svn_swig_py_thunk_log_receiver; 6849 $2 = (void *)$input; 6850} 6851%typemap(perl5, in) (svn_log_message_receiver_t receiver, 6852 void *receiver_baton) { 6853 $1 = svn_swig_pl_thunk_log_receiver; 6854 $2 = (void *)$input; 6855} 6856 6857/* stream_t * */ 6858%apply SWIGTYPE **OUTPARAM { svn_stream_t ** }; 6859 6860/* ----------------------------------------------------------------------- 6861 thunk commit_callback 6862*/ 6863%typemap(perl5, in) (svn_commit_callback_t callback, void *callback_baton) { 6864 $1 = svn_swig_pl_thunk_commit_callback; 6865 $2 = (void *)$input; 6866 SvREFCNT_inc($input); 6867}; 6868 6869/* ----------------------------------------------------------------------- 6870 svn_stream interpolability with io handle 6871*/ 6872 6873%typemap(perl5, in) svn_stream_t * { 6874 svn_swig_pl_make_stream (&$1, $input); 6875} 6876 6877%typemap(perl5, argout) svn_stream_t ** { 6878 $result = svn_swig_pl_from_stream (*$1); 6879 argvi++; 6880} 6881 6882/* ----------------------------------------------------------------------- 6883 Wrap the digest output for functions populating digests. 6884*/ 6885%typemap(perl5, in, numinputs=0) unsigned char digest[ANY] ($*1_type temp[33]) { 6886 $1 = ($1_ltype)temp; 6887} 6888%typemap(perl5, argout) unsigned char digest[ANY] { 6889 ST(argvi) = sv_newmortal(); 6890 sv_setpv((SV*)ST(argvi++), svn_md5_digest_to_cstring ($1,_global_pool)); 6891} 6892 6893#ifdef SWIGPERL 6894%apply unsigned char digest[ANY] { unsigned char *digest }; 6895#endif 6896 6897/* ----------------------------------------------------------------------- 6898 useful convertors for svn_opt_revision_t 6899*/ 6900%typemap(perl5, in) svn_opt_revision_t * (svn_opt_revision_t rev) { 6901 $1 = &rev; 6902 if ($input == NULL || $input == &PL_sv_undef || !SvOK($input)) { 6903 rev.kind = svn_opt_revision_unspecified; 6904 } 6905 else if (sv_isobject($input) && sv_derived_from($input, "_p_svn_opt_revision_t")) { 6906 SWIG_ConvertPtr($input, (void **)&$1, $1_descriptor, 0); 6907 } 6908 else if (SvIOK($input)) { 6909 rev.kind = svn_opt_revision_number; 6910 rev.value.number = SvIV($input); 6911 } 6912 else if (SvPOK($input)) { 6913 char *input = SvPV_nolen($input); 6914 if (strcasecmp(input, "BASE") == 0) 6915 rev.kind = svn_opt_revision_base; 6916 else if (strcasecmp(input, "HEAD") == 0) 6917 rev.kind = svn_opt_revision_head; 6918 else if (strcasecmp(input, "WORKING") == 0) 6919 rev.kind = svn_opt_revision_working; 6920 else if (strcasecmp(input, "COMMITTED") == 0) 6921 rev.kind = svn_opt_revision_committed; 6922 else if (strcasecmp(input, "PREV") == 0) 6923 rev.kind = svn_opt_revision_previous; 6924 else if (*input == '{') { 6925 time_t tm; 6926 char *end = strchr(input,'}'); 6927 if (!end) 6928 SWIG_croak("unknown opt_revision_t type"); 6929 *end = '\0'; 6930 tm = svn_parse_date (input + 1, NULL); 6931 if (tm == -1) 6932 SWIG_croak("unknown opt_revision_t type"); 6933 rev.kind = svn_opt_revision_date; 6934 apr_time_ansi_put(&(rev.value.date), tm); 6935 } else 6936 SWIG_croak("unknown opt_revison_t type"); 6937 } else 6938 SWIG_croak("unknown opt_revision_t type"); 6939} 6940 6941/* ----------------------------------------------------------------------- 6942 dirents hash 6943*/ 6944 6945%typemap(python,in,numinputs=0) apr_hash_t **dirents = apr_hash_t **OUTPUT; 6946%typemap(python,argout,fragment="t_output_helper") apr_hash_t **dirents { 6947 $result = t_output_helper 6948 ($result, 6949 svn_swig_py_convert_hash(*$1, SWIG_TypeQuery("svn_dirent_t *"))); 6950} 6951 6952%typemap(perl5,in,numinputs=0) apr_hash_t **dirents = apr_hash_t **OUTPUT; 6953%typemap(perl5,argout) apr_hash_t **dirents { 6954 ST(argvi++) = svn_swig_pl_convert_hash 6955 (*$1, SWIG_TypeQuery("svn_dirent_t *")); 6956} 6957 6958/* ----------------------------------------------------------------------- 6959 Special boolean mapping for java. 6960*/ 6961%typemap(java, jni) svn_boolean_t "jboolean"; 6962%typemap(java, jtype) svn_boolean_t "boolean"; 6963%typemap(java, jstype) svn_boolean_t "boolean"; 6964%typemap(java, in) svn_boolean_t %{ 6965 $1 = $input ? TRUE : FALSE; 6966%} 6967%typemap(java, out) svn_boolean_t %{ 6968 $result = $1 ? JNI_TRUE : JNI_FALSE; 6969%} 6970 6971/* ----------------------------------------------------------------------- 6972 Handle python thread locking. 6973 6974 Swig doesn't allow us to specify a language in the %exception command, 6975 so we have to use #ifdefs for the python-specific parts. 6976*/ 6977 6978%exception { 6979#ifdef SWIGPYTHON 6980 svn_swig_py_release_py_lock(); 6981#endif 6982 $action 6983#ifdef SWIGPYTHON 6984 svn_swig_py_acquire_py_lock(); 6985#endif 6986} 6987 6988/* ----------------------------------------------------------------------- */ 6989 6990%include svn_types.h 6991%{ 6992#include "svn_types.h" 6993#include "svn_time.h" 6994 6995#ifdef SWIGPYTHON 6996#include "swigutil_py.h" 6997#endif 6998 6999#ifdef SWIGJAVA 7000#include "swigutil_java.h" 7001#endif 7002 7003#ifdef SWIGPERL 7004#include "swigutil_pl.h" 7005#endif 7006%} 7007 7008 7009Node-path: svnperl/svn_wc.i 7010Node-kind: file 7011Node-action: add 7012Prop-content-length: 10 7013Text-content-length: 3500 7014Text-content-md5: b56f7f908ad6d04cfabd25660fb2ff7b 7015Content-length: 3510 7016 7017PROPS-END 7018/* 7019 * svn_wc.i : SWIG interface file for svn_wc.h 7020 * 7021 * ==================================================================== 7022 * Copyright (c) 2000-2003 CollabNet. All rights reserved. 7023 * 7024 * This software is licensed as described in the file COPYING, which 7025 * you should have received as part of this distribution. The terms 7026 * are also available at http://subversion.tigris.org/license-1.html. 7027 * If newer versions of this license are posted there, you may use a 7028 * newer version instead, at your option. 7029 * 7030 * This software consists of voluntary contributions made by many 7031 * individuals. For exact contribution history, see the revision 7032 * history and logs, available at http://subversion.tigris.org/. 7033 * ==================================================================== 7034 */ 7035 7036%module wc 7037%include typemaps.i 7038 7039%import apr.i 7040%import svn_types.i 7041%import svn_string.i 7042%import svn_delta.i 7043 7044/* ----------------------------------------------------------------------- 7045 ### these functions require a pool, which we don't have immediately 7046 ### handy. just eliminate these funcs for now. 7047*/ 7048%ignore svn_wc_set_auth_file; 7049 7050/* ### ignore this structure because the accessors will need a pool */ 7051%ignore svn_wc_keywords_t; 7052 7053/* ----------------------------------------------------------------------- 7054 these types (as 'type **') will always be an OUT param 7055*/ 7056%apply SWIGTYPE **OUTPARAM { 7057 svn_wc_entry_t **, 7058 svn_wc_adm_access_t **, 7059 svn_wc_status_t ** 7060}; 7061 7062/* we can't use the OUTPARAM cuz that is only for pointers. use the 7063 standard OUTPARAM definition for 'int' instead. */ 7064%apply int *OUTPUT { int * }; 7065 7066/* handle the property hash returned by svn_wc_prop_list */ 7067%apply apr_hash_t **PROPHASH { apr_hash_t **props }; 7068 7069/* ----------------------------------------------------------------------- 7070 handle svn_wc_notify_func_t/baton pairs 7071*/ 7072 7073%typemap(python,in) (svn_wc_notify_func_t notify_func, void *notify_baton) { 7074 7075 $1 = svn_swig_py_notify_func; 7076 $2 = $input; /* our function is the baton. */ 7077} 7078 7079%typemap(java,in) (svn_wc_notify_func_t notify_func, void *notify_baton) { 7080 7081 $1 = svn_swig_java_notify_func; 7082 $2 = (void*)$input; /* our function is the baton. */ 7083} 7084 7085%typemap(jni) svn_wc_notify_func_t "jobject" 7086%typemap(jtype) svn_wc_notify_func_t "org.tigris.subversion.wc.Notifier" 7087%typemap(jstype) svn_wc_notify_func_t "org.tigris.subversion.wc.Notifier" 7088%typemap(javain) svn_wc_notify_func_t "$javainput" 7089%typemap(javaout) svn_wc_notify_func_t { 7090 return $jnicall; 7091 } 7092 7093/* ----------------------------------------------------------------------- 7094 handle svn_cancel_func_t/baton pairs 7095*/ 7096 7097%typemap(python,in) (svn_cancel_func_t cancel_func, void *cancel_baton) { 7098 7099 $1 = svn_swig_py_cancel_func; 7100 $2 = $input; /* our function is the baton. */ 7101} 7102 7103%typemap(java,in) (svn_cancel_func_t cancel_func, void *cancel_baton) { 7104 7105 $1 = svn_swig_java_cancel_func; 7106 $2 = (void*)$input; /* our function is the baton. */ 7107} 7108 7109%typemap(jni) svn_cancel_func_t "jobject" 7110%typemap(jtype) svn_cancel_func_t "org.tigris.subversion.Canceller" 7111%typemap(jstype) svn_cancel_func_t "org.tigris.subversion.Canceller" 7112%typemap(javain) svn_cancel_func_t "$javainput" 7113%typemap(javaout) svn_cancel_func_t { 7114 return $jnicall; 7115 } 7116 7117/* ----------------------------------------------------------------------- */ 7118 7119%include svn_wc.h 7120%{ 7121#include "svn_wc.h" 7122 7123#ifdef SWIGPYTHON 7124#include "swigutil_py.h" 7125#endif 7126 7127#ifdef SWIGJAVA 7128#include "swigutil_java.h" 7129#endif 7130 7131#ifdef SWIGPERL 7132#include "swigutil_pl.h" 7133#endif 7134%} 7135 7136 7137Node-path: svnperl/swigutil_java.c 7138Node-kind: file 7139Node-action: add 7140Prop-content-length: 10 7141Text-content-length: 38607 7142Text-content-md5: 4efe389f4e95d2271a657c0d3d134443 7143Content-length: 38617 7144 7145PROPS-END 7146/* 7147 * swigutil_java.c: utility functions for the SWIG Java bindings 7148 * 7149 * ==================================================================== 7150 * Copyright (c) 2000-2004 CollabNet. All rights reserved. 7151 * 7152 * This software is licensed as described in the file COPYING, which 7153 * you should have received as part of this distribution. The terms 7154 * are also available at http://subversion.tigris.org/license-1.html. 7155 * If newer versions of this license are posted there, you may use a 7156 * newer version instead, at your option. 7157 * 7158 * This software consists of voluntary contributions made by many 7159 * individuals. For exact contribution history, see the revision 7160 * history and logs, available at http://subversion.tigris.org/. 7161 * ==================================================================== 7162 */ 7163 7164 7165#include <jni.h> 7166 7167#include <apr_pools.h> 7168#include <apr_hash.h> 7169 7170 7171#include "svn_client.h" 7172 7173#include "svn_string.h" 7174#include "svn_delta.h" 7175 7176#define SVN_SWIG_JAVA_DEFINE_CACHE 7177#include "swigutil_java.h" 7178 7179/* FIXME: Need java.swg for the JCALL macros. The following was taken 7180 from javahead.swg (which is included by java.swg). */ 7181#ifndef JCALL0 7182#ifdef __cplusplus 7183# define JCALL0(func, jenv) jenv->func() 7184# define JCALL1(func, jenv, ar1) jenv->func(ar1) 7185# define JCALL2(func, jenv, ar1, ar2) jenv->func(ar1, ar2) 7186# define JCALL3(func, jenv, ar1, ar2, ar3) jenv->func(ar1, ar2, ar3) 7187# define JCALL4(func, jenv, ar1, ar2, ar3, ar4) jenv->func(ar1, ar2, ar3, ar4) 7188# define JCALL7(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6, ar7) jenv->func(ar1, ar2, ar3, ar4, ar5, ar6, ar7) 7189#else 7190# define JCALL0(func, jenv) (*jenv)->func(jenv) 7191# define JCALL1(func, jenv, ar1) (*jenv)->func(jenv, ar1) 7192# define JCALL2(func, jenv, ar1, ar2) (*jenv)->func(jenv, ar1, ar2) 7193# define JCALL3(func, jenv, ar1, ar2, ar3) (*jenv)->func(jenv, ar1, ar2, ar3) 7194# define JCALL4(func, jenv, ar1, ar2, ar3, ar4) (*jenv)->func(jenv, ar1, ar2, ar3, ar4) 7195# define JCALL7(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6, ar7) (*jenv)->func(jenv, ar1, ar2, ar3, ar4, ar5, ar6, ar7) 7196#endif 7197#endif 7198 7199/* Convert an svn_error_t into a SubversionException */ 7200static jthrowable convert_error(JNIEnv *jenv, svn_error_t *error) 7201{ 7202 jthrowable cause; 7203 jthrowable exc; 7204 jstring msg; 7205 jstring file; 7206 7207 /* Is it wise to use recursion in an error handler? */ 7208 cause = (error->child) ? convert_error(jenv, error->child) : NULL; 7209 7210 /* ### need more error checking */ 7211 msg = JCALL1(NewStringUTF, jenv, error->message); 7212 file = error->file ? JCALL1(NewStringUTF, jenv, error->file) : NULL; 7213 7214 exc = JCALL7(NewObject, jenv, 7215 svn_swig_java_cls_subversionexception, 7216 svn_swig_java_mid_subversionexception_init, 7217 msg, cause, 7218 (jlong) error->apr_err, file, (jlong) error->line); 7219 return exc; 7220} 7221 7222/* Convert an svn_error_t into a SubversionException 7223 After conversion, the error will be cleared */ 7224jthrowable svn_swig_java_convert_error(JNIEnv *jenv, svn_error_t *error) 7225{ 7226 jthrowable exc; 7227 7228 exc = convert_error(jenv, error); 7229 svn_error_clear(error); 7230 return exc; 7231} 7232 7233/* this baton is used for the editor, directory, and file batons. */ 7234typedef struct { 7235 jobject editor; /* the editor handling the callbacks */ 7236 jobject baton; /* the dir/file baton (or NULL for edit baton) */ 7237 apr_pool_t *pool; /* pool to use for errors */ 7238 JNIEnv *jenv; /* Java native interface structure */ 7239} item_baton; 7240 7241typedef struct { 7242 jobject handler; /* the window handler (a callable) */ 7243 apr_pool_t *pool; /* a pool for constructing errors */ 7244 JNIEnv *jenv; /* Java native interface structure */ 7245} handler_baton; 7246 7247static jobject make_pointer(JNIEnv* env, void *ptr) 7248{ 7249 /* Return a Long object contining the C pointer to the object 7250 (SWIG/Java knows nothing of SWIG_NewPointerObj) */ 7251 jclass cls = JCALL1(FindClass, env, "java/lang/Long"); 7252 return JCALL3(NewObject, env, cls, 7253 JCALL3(GetMethodID, env, cls, "<init>", "(J)V"), (jlong) ptr); 7254} 7255 7256static jobject convert_hash(JNIEnv* jenv, apr_hash_t *hash, 7257 jobject (*converter_func)(JNIEnv* env, 7258 void *value, 7259 void *ctx), 7260 void *ctx) 7261{ 7262 apr_hash_index_t *hi; 7263 jclass cls = JCALL1(FindClass, jenv, "java/util/HashMap"); 7264 jobject dict = JCALL3(NewObject, jenv, cls, 7265 JCALL3(GetMethodID, jenv, cls, "<init>", "(I)V"), 7266 (jint) apr_hash_count(hash)); 7267 jmethodID put = JCALL3(GetMethodID, jenv, cls, "put", 7268 "(Ljava/lang/Object;Ljava/lang/Object;)" 7269 "Ljava/lang/Object;"); 7270 7271 if (dict == NULL) 7272 return NULL; 7273 7274 for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi)) 7275 { 7276 const void *key; 7277 void *val; 7278 jobject value; 7279 7280 apr_hash_this(hi, &key, NULL, &val); 7281 value = (*converter_func)(jenv, val, ctx); 7282 JCALL4(CallObjectMethod, jenv, dict, put, 7283 JCALL1(NewStringUTF, jenv, key), value); 7284 JCALL1(DeleteLocalRef, jenv, value); 7285 } 7286 7287 return dict; 7288} 7289 7290void svn_swig_java_add_to_list(JNIEnv* jenv, apr_array_header_t *array, 7291 jobject list) 7292{ 7293 /* TODO: This impl will be much like svn_swig_java_add_to_map */ 7294} 7295 7296void svn_swig_java_add_to_map(JNIEnv* jenv, apr_hash_t *hash, jobject map) 7297{ 7298 apr_hash_index_t *hi; 7299 jclass cls = JCALL1(FindClass, jenv, "java/util/Map"); 7300 jmethodID put = JCALL3(GetMethodID, jenv, cls, "put", 7301 "(Ljava/lang/Object;Ljava/lang/Object;)" 7302 "Ljava/lang/Object;"); 7303 7304 for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi)) 7305 { 7306 const void *key; 7307 void *val; 7308 jobject keyname, value, oldvalue; 7309 7310 apr_hash_this(hi, &key, NULL, &val); 7311 keyname = JCALL1(NewStringUTF, jenv, key); 7312 value = make_pointer(jenv, val); 7313 7314 oldvalue = JCALL4(CallObjectMethod, jenv, map, put, keyname, value); 7315 7316 JCALL1(DeleteLocalRef, jenv, value); 7317 JCALL1(DeleteLocalRef, jenv, oldvalue); 7318 JCALL1(DeleteLocalRef, jenv, keyname); 7319 7320 if (JCALL0(ExceptionOccurred, jenv)) 7321 return; 7322 } 7323} 7324 7325static jobject convert_to_swigtype(JNIEnv* jenv, void *value, void *ctx) 7326{ 7327 return make_pointer(jenv, value); 7328} 7329 7330static jobject convert_svn_string_t(JNIEnv* jenv, void *value, void *ctx) 7331{ 7332 const svn_string_t *s = value; 7333 7334 /* This will copy the data */ 7335 return JCALL1(NewStringUTF, jenv, s->data); 7336} 7337 7338jobject svn_swig_java_prophash_to_dict(JNIEnv *jenv, apr_hash_t *hash) 7339{ 7340 return convert_hash(jenv, hash, convert_svn_string_t, jenv); 7341} 7342 7343jobject svn_swig_java_convert_hash(JNIEnv *jenv, apr_hash_t *hash) 7344{ 7345 return convert_hash(jenv, hash, convert_to_swigtype, NULL); 7346} 7347 7348jobject svn_swig_java_c_strings_to_list(JNIEnv *jenv, char **strings) 7349{ 7350 jclass cls = JCALL1(FindClass, jenv, "java/util/ArrayList"); 7351 jobject list = JCALL2(NewObject, jenv, cls, 7352 JCALL3(GetMethodID, jenv, cls, "<init>", "()V")); 7353 jmethodID add = JCALL3(GetMethodID, jenv, cls, "add", "(Ljava/lang/Object;)Z"); 7354 char *s; 7355 jobject obj; 7356 while ((s = *strings++) != NULL) 7357 { 7358 obj = JCALL1(NewStringUTF, jenv, s); 7359 7360 if (obj == NULL) 7361 goto error; 7362 7363 JCALL3(CallBooleanMethod, jenv, list, add, obj); 7364 7365 JCALL1(DeleteLocalRef, jenv, obj); 7366 } 7367 7368 return list; 7369 7370 error: 7371 JCALL1(DeleteLocalRef, jenv, list); 7372 return NULL; 7373} 7374 7375jobject svn_swig_java_array_to_list(JNIEnv *jenv, 7376 const apr_array_header_t *strings) 7377{ 7378 jclass cls = JCALL1(FindClass, jenv, "java/util/ArrayList"); 7379 jobject list = JCALL3(NewObject, jenv, cls, 7380 JCALL3(GetMethodID, jenv, cls, "<init>", "(I)V"), 7381 strings->nelts); 7382 int i; 7383 jobject obj; 7384 7385 jmethodID add; 7386 if (strings->nelts > 0) 7387 add = JCALL3(GetMethodID, jenv, cls, "add", "(i, Ljava/lang/Object;)Z"); 7388 7389 for (i = 0; i < strings->nelts; ++i) 7390 { 7391 const char *s; 7392 7393 s = APR_ARRAY_IDX(strings, i, const char *); 7394 obj = JCALL1(NewStringUTF, jenv, s); 7395 if (obj == NULL) 7396 goto error; 7397 /* ### HELP: The format specifier might be 'I' instead of 'i' */ 7398 JCALL4(CallObjectMethod, jenv, list, add, i, obj); 7399 JCALL1(DeleteLocalRef, jenv, obj); 7400 } 7401 7402 return list; 7403 7404 error: 7405 JCALL1(DeleteLocalRef, jenv, list); 7406 return NULL; 7407} 7408 7409const apr_array_header_t *svn_swig_java_strings_to_array(JNIEnv *jenv, 7410 jobject source, 7411 apr_pool_t *pool) 7412{ 7413 int targlen; 7414 apr_array_header_t *temp; 7415 7416 jclass cls = JCALL1(FindClass, jenv, "java/util/List"); 7417 jmethodID size = JCALL3(GetMethodID, jenv, cls, "size", "()I"); 7418 jmethodID get = JCALL3(GetMethodID, jenv, cls, "get", 7419 "(I)Ljava/lang/Object;"); 7420 7421 jclass illegalArgCls = JCALL1(FindClass, jenv, 7422 "java/lang/IllegalArgumentException"); 7423 7424 if (!JCALL2(IsInstanceOf, jenv, source, cls)) 7425 { 7426 if (JCALL2(ThrowNew, jenv, illegalArgCls, "Not a List") != JNI_OK) 7427 return NULL; 7428 } 7429 7430 targlen = JCALL2(CallIntMethod, jenv, source, size); 7431 temp = apr_array_make(pool, targlen, sizeof(const char *)); 7432 while (targlen--) 7433 { 7434 jobject o = JCALL3(CallObjectMethod, jenv, source, get, targlen); 7435 const char * c_string; 7436 if (o == NULL) 7437 return NULL; 7438 else if (!JCALL2(IsInstanceOf, jenv, o, 7439 JCALL1(FindClass, jenv, "java/lang/String"))) 7440 { 7441 JCALL1(DeleteLocalRef, jenv, o); 7442 if (JCALL2(ThrowNew, jenv, illegalArgCls, "Not a String") != JNI_OK) 7443 { 7444 return NULL; 7445 } 7446 } 7447 c_string = (*jenv)->GetStringUTFChars(jenv, o, 0); 7448 APR_ARRAY_IDX(temp, targlen, const char *) = apr_pstrdup(pool, c_string); 7449 (*jenv)->ReleaseStringUTFChars(jenv, o, c_string); 7450 JCALL1(DeleteLocalRef, jenv, o); 7451 7452 } 7453 return temp; 7454} 7455 7456/* Convert a Java exception into a svn_error_t. 7457 This function may only be called if there is 7458 a pending exception. */ 7459static svn_error_t * convert_exception(JNIEnv *jenv, apr_pool_t *pool) 7460{ 7461 svn_error_t *result; 7462 apr_status_t status; 7463 char *msg; 7464 jthrowable exc; 7465 7466 /* Fetch the exception */ 7467 exc = JCALL0(ExceptionOccurred, jenv); 7468 7469#ifdef SVN_DEBUG 7470 /* Print the pending exception to stderr */ 7471 JCALL0(ExceptionDescribe, jenv); 7472#endif 7473 7474 /* Clear the exception */ 7475 JCALL0(ExceptionClear, jenv); 7476 7477 /* Interpret the exception: 7478 java.lang.OutOfMemoryError -> APR_ENOMEM 7479 other -> APR_EGENERAL */ 7480 /* ### Add other exceptions; use a table? */ 7481 if (JCALL2(IsInstanceOf, jenv, exc, svn_swig_java_cls_outofmemoryerror)) 7482 { 7483 status = APR_ENOMEM; 7484 msg = "JVM raised OutOfMemoryError"; 7485 } 7486 else 7487 { 7488 status = APR_EGENERAL; 7489 msg = "The Java callback raised an exception"; 7490 } 7491 result = svn_error_create(status, NULL, msg); 7492 7493 /* Free the local reference */ 7494 JCALL1(DeleteLocalRef, jenv, exc); 7495 return result; 7496} 7497 7498static item_baton * make_baton(JNIEnv *jenv, apr_pool_t *pool, 7499 jobject editor, jobject baton) 7500{ 7501 item_baton *newb = apr_palloc(pool, sizeof(*newb)); 7502 7503 /* one more reference to the editor. */ 7504 JCALL1(NewGlobalRef, jenv, editor); 7505 JCALL1(NewGlobalRef, jenv, baton); 7506 7507 /* note: we take the caller's reference to 'baton' */ 7508 7509 newb->editor = JCALL1(NewGlobalRef, jenv, editor); 7510 newb->baton = baton; 7511 newb->pool = pool; 7512 newb->jenv = jenv; 7513 7514 return newb; 7515} 7516 7517static svn_error_t * close_baton(void *baton, const char *method) 7518{ 7519 item_baton *ib = baton; 7520 jobject result; 7521 JNIEnv *jenv = ib->jenv; 7522 jclass cls = JCALL1(GetObjectClass, jenv, ib->editor); 7523 jmethodID methodID; 7524 7525 /* If there is no baton object, then it is an edit_baton, and we should 7526 not bother to pass an object. Note that we still shove a NULL onto 7527 the stack, but the format specified just won't reference it. */ 7528 7529 if (ib->baton) 7530 { 7531 methodID = JCALL3(GetMethodID, jenv, cls, method, 7532 "(Ljava/lang/Object;)Ljava/lang/Object;"); 7533 result = JCALL3(CallObjectMethod, jenv, ib->editor, methodID, ib->baton); 7534 } 7535 else 7536 { 7537 methodID = JCALL3(GetMethodID, jenv, cls, method, 7538 "()Ljava/lang/Object;"); 7539 result = JCALL2(CallObjectMethod, jenv, ib->editor, methodID); 7540 } 7541 7542 if (result == NULL) 7543 return convert_exception(ib->jenv, ib->pool); 7544 7545 /* there is no return value, so just toss this object */ 7546 JCALL1(DeleteGlobalRef, ib->jenv, result); 7547 7548 /* We're now done with the baton. Since there isn't really a free, all 7549 we need to do is note that its objects are no longer referenced by 7550 the baton. */ 7551 JCALL1(DeleteGlobalRef, ib->jenv, ib->editor); 7552 JCALL1(DeleteGlobalRef, ib->jenv, ib->baton); 7553 7554#ifdef SVN_DEBUG 7555 ib->editor = ib->baton = NULL; 7556#endif 7557 7558 return SVN_NO_ERROR; 7559} 7560 7561static svn_error_t * close_baton_checksum(void *baton, 7562 const char *text_checksum, 7563 const char *method) 7564{ 7565 item_baton *ib = baton; 7566 jobject result; 7567 JNIEnv *jenv = ib->jenv; 7568 jclass cls = JCALL1(GetObjectClass, jenv, ib->editor); 7569 jmethodID methodID; 7570 7571 methodID = JCALL3(GetMethodID, jenv, cls, method, 7572 "(Ljava/lang/Object;)Ljava/lang/Object;"); 7573 result = JCALL4(CallObjectMethod, jenv, ib->editor, methodID, ib->baton, 7574 text_checksum); 7575 7576 if (result == NULL) 7577 return convert_exception(ib->jenv, ib->pool); 7578 7579 /* there is no return value, so just toss this object */ 7580 JCALL1(DeleteGlobalRef, ib->jenv, result); 7581 7582 /* We're now done with the baton. Since there isn't really a free, all 7583 we need to do is note that its objects are no longer referenced by 7584 the baton. */ 7585 JCALL1(DeleteGlobalRef, ib->jenv, ib->editor); 7586 JCALL1(DeleteGlobalRef, ib->jenv, ib->baton); 7587 7588#ifdef SVN_DEBUG 7589 ib->editor = ib->baton = NULL; 7590#endif 7591 7592 return SVN_NO_ERROR; 7593} 7594 7595static svn_error_t * thunk_set_target_revision(void *edit_baton, 7596 svn_revnum_t target_revision, 7597 apr_pool_t *pool) 7598{ 7599 item_baton *ib = edit_baton; 7600 jobject result; 7601 jclass cls; /*= JCALL(FindClass, ib->jenv, "FIXME");*/ 7602 /* FIXME: Signature wants svn_revnum type instead of java.lang.Object */ 7603 jmethodID methodID = JCALL3(GetMethodID, ib->jenv, cls, 7604 "set_target_revision", "(Ljava/lang/Object;)"); 7605 7606 /* FIXME: Translate to JNI 7607 if ((result = PyObject_CallMethod(ib->editor, (char *)"set_target_revision", 7608 (char *)"l", target_revision)) == NULL) 7609 { 7610 return convert_exception(ib->jenv, pool); 7611 } 7612 */ 7613 7614 /* there is no return value, so just toss this object */ 7615 JCALL1(DeleteGlobalRef, ib->jenv, result); 7616 7617 return SVN_NO_ERROR; 7618} 7619 7620static svn_error_t * thunk_open_root(void *edit_baton, 7621 svn_revnum_t base_revision, 7622 apr_pool_t *dir_pool, 7623 void **root_baton) 7624{ 7625 item_baton *ib = edit_baton; 7626 jobject result; 7627 7628 /* FIXME: Translate to JNI 7629 if ((result = PyObject_CallMethod(ib->editor, (char *)"open_root", 7630 (char *)"lO&", base_revision, 7631 make_ob_pool, dir_pool)) == NULL) 7632 { 7633 return convert_exception(ib->jenv, dir_pool); 7634 } 7635 */ 7636 7637 /* make_baton takes our 'result' reference */ 7638 *root_baton = make_baton(ib->jenv, dir_pool, ib->editor, result); 7639 7640 return SVN_NO_ERROR; 7641} 7642 7643static svn_error_t * thunk_delete_entry(const char *path, 7644 svn_revnum_t revision, 7645 void *parent_baton, 7646 apr_pool_t *pool) 7647{ 7648 item_baton *ib = parent_baton; 7649 jobject result; 7650 7651 /* FIXME: Translate to JNI 7652 if ((result = PyObject_CallMethod(ib->editor, (char *)"delete_entry", 7653 (char *)"slOO&", path, revision, ib->baton, 7654 make_ob_pool, pool)) == NULL) 7655 { 7656 return convert_exception(ib->jenv, pool); 7657 } 7658 */ 7659 7660 /* there is no return value, so just toss this object */ 7661 JCALL1(DeleteGlobalRef, ib->jenv, result); 7662 7663 return SVN_NO_ERROR; 7664} 7665 7666static svn_error_t * thunk_add_directory(const char *path, 7667 void *parent_baton, 7668 const char *copyfrom_path, 7669 svn_revnum_t copyfrom_revision, 7670 apr_pool_t *dir_pool, 7671 void **child_baton) 7672{ 7673 item_baton *ib = parent_baton; 7674 jobject result; 7675 7676 /* FIXME: Translate to JNI 7677 if ((result = PyObject_CallMethod(ib->editor, (char *)"add_directory", 7678 (char *)"sOslO&", path, ib->baton, 7679 copyfrom_path, copyfrom_revision, 7680 make_ob_pool, dir_pool)) == NULL) 7681 { 7682 return convert_exception(ib->jenv, dir_pool); 7683 } 7684 */ 7685 7686 /* make_baton takes our 'result' reference */ 7687 *child_baton = make_baton(ib->jenv, dir_pool, ib->editor, result); 7688 7689 return SVN_NO_ERROR; 7690} 7691 7692static svn_error_t * thunk_open_directory(const char *path, 7693 void *parent_baton, 7694 svn_revnum_t base_revision, 7695 apr_pool_t *dir_pool, 7696 void **child_baton) 7697{ 7698 item_baton *ib = parent_baton; 7699 jobject result; 7700 7701 /* FIXME: Translate to JNI 7702 if ((result = PyObject_CallMethod(ib->editor, (char *)"open_directory", 7703 (char *)"sOlO&", path, ib->baton, 7704 base_revision, 7705 make_ob_pool, dir_pool)) == NULL) 7706 { 7707 return convert_exception(ib->jenv, dir_pool); 7708 } 7709 */ 7710 7711 /* make_baton takes our 'result' reference */ 7712 *child_baton = make_baton(ib->jenv, dir_pool, ib->editor, result); 7713 7714 return SVN_NO_ERROR; 7715} 7716 7717static svn_error_t * thunk_change_dir_prop(void *dir_baton, 7718 const char *name, 7719 const svn_string_t *value, 7720 apr_pool_t *pool) 7721{ 7722 item_baton *ib = dir_baton; 7723 jobject result; 7724 7725 /* FIXME: Translate to JNI 7726 if ((result = PyObject_CallMethod(ib->editor, (char *)"change_dir_prop", 7727 (char *)"Oss#O&", ib->baton, name, 7728 value->data, value->len, 7729 make_ob_pool, pool)) == NULL) 7730 { 7731 return convert_exception(ib->jenv, pool); 7732 } 7733 */ 7734 7735 /* there is no return value, so just toss this object */ 7736 JCALL1(DeleteGlobalRef, ib->jenv, result); 7737 7738 return SVN_NO_ERROR; 7739} 7740 7741static svn_error_t * thunk_close_directory(void *dir_baton, apr_pool_t *pool) 7742{ 7743 return close_baton(dir_baton, "close_directory"); 7744} 7745 7746static svn_error_t * thunk_add_file(const char *path, 7747 void *parent_baton, 7748 const char *copyfrom_path, 7749 svn_revnum_t copyfrom_revision, 7750 apr_pool_t *file_pool, 7751 void **file_baton) 7752{ 7753 item_baton *ib = parent_baton; 7754 jobject result; 7755 7756 /* FIXME: Translate to JNI 7757 if ((result = PyObject_CallMethod(ib->editor, (char *)"add_file", 7758 (char *)"sOslO&", path, ib->baton, 7759 copyfrom_path, copyfrom_revision, 7760 make_ob_pool, file_pool)) == NULL) 7761 { 7762 return convert_exception(ib->jenv, file_pool); 7763 } 7764 */ 7765 7766 /* make_baton takes our 'result' reference */ 7767 *file_baton = make_baton(ib->jenv, file_pool, ib->editor, result); 7768 7769 return SVN_NO_ERROR; 7770} 7771 7772static svn_error_t * thunk_open_file(const char *path, 7773 void *parent_baton, 7774 svn_revnum_t base_revision, 7775 apr_pool_t *file_pool, 7776 void **file_baton) 7777{ 7778 item_baton *ib = parent_baton; 7779 jobject result; 7780 7781 /* FIXME: Translate to JNI 7782 if ((result = PyObject_CallMethod(ib->editor, (char *)"open_file", 7783 (char *)"sOlO&", path, ib->baton, 7784 base_revision, 7785 make_ob_pool, file_pool)) == NULL) 7786 { 7787 return convert_exception(ib->jenv, file_pool); 7788 } 7789 */ 7790 7791 /* make_baton takes our 'result' reference */ 7792 *file_baton = make_baton(ib->jenv, file_pool, ib->editor, result); 7793 7794 return SVN_NO_ERROR; 7795} 7796 7797static svn_error_t * thunk_window_handler(svn_txdelta_window_t *window, 7798 void *baton) 7799{ 7800 handler_baton *hb = baton; 7801 jobject result; 7802 7803 if (window == NULL) 7804 { 7805 /* the last call; it closes the handler */ 7806 7807 /* invoke the handler with None for the window */ 7808 /* ### python doesn't have 'const' on the format */ 7809 /* FIXME: To JNI 7810 result = PyObject_CallFunction(hb->handler, (char *)"O", Py_None); 7811 */ 7812 7813 /* we no longer need to refer to the handler object */ 7814 JCALL1(DeleteGlobalRef, hb->jenv, hb->handler); 7815 } 7816 else 7817 { 7818 /* invoke the handler with the window */ 7819 /* FIXME: Translate to JNI 7820 result = PyObject_CallFunction(hb->handler, 7821 (char *)"O&", make_ob_window, window); 7822 */ 7823 } 7824 7825 if (result == NULL) 7826 return convert_exception(hb->jenv, hb->pool); 7827 7828 /* there is no return value, so just toss this object */ 7829 JCALL1(DeleteGlobalRef, hb->jenv, result); 7830 7831 return SVN_NO_ERROR; 7832} 7833 7834static svn_error_t * thunk_apply_textdelta( 7835 void *file_baton, 7836 const char *base_checksum, 7837 apr_pool_t *pool, 7838 svn_txdelta_window_handler_t *handler, 7839 void **h_baton) 7840{ 7841 item_baton *ib = file_baton; 7842 jobject result; 7843 7844 /* FIXME: Translate to JNI 7845 if ((result = PyObject_CallMethod(ib->editor, (char *)"apply_textdelta", 7846 (char *)"O", ib->baton)) == NULL) 7847 { 7848 return convert_exception(ib->jenv, pool); 7849 } 7850 */ 7851 7852 /* FIXME: To JNI 7853 if (result == Py_None) 7854 { 7855 JCALL1(DeleteGlobalRef, ib->jenv, result); 7856 *handler = NULL; 7857 *h_baton = NULL; 7858 } 7859 else 7860 */ 7861 { 7862 handler_baton *hb = apr_palloc(ib->pool, sizeof(*hb)); 7863 7864 /* return the thunk for invoking the handler. the baton takes our 7865 'result' reference. */ 7866 hb->handler = result; 7867 hb->pool = ib->pool; 7868 hb->jenv = ib->jenv; 7869 7870 *handler = thunk_window_handler; 7871 *h_baton = hb; 7872 } 7873 7874 return SVN_NO_ERROR; 7875} 7876 7877static svn_error_t * thunk_change_file_prop(void *file_baton, 7878 const char *name, 7879 const svn_string_t *value, 7880 apr_pool_t *pool) 7881{ 7882 item_baton *ib = file_baton; 7883 jobject result; 7884 7885 /* FIXME: Translate to JNI 7886 if ((result = PyObject_CallMethod(ib->editor, (char *)"change_file_prop", 7887 (char *)"Oss#O&", ib->baton, name, 7888 value->data, value->len, 7889 make_ob_pool, pool)) == NULL) 7890 { 7891 return convert_exception(ib->jenv, pool); 7892 } 7893 */ 7894 7895 /* there is no return value, so just toss this object */ 7896 JCALL1(DeleteGlobalRef, ib->jenv, result); 7897 7898 return SVN_NO_ERROR; 7899} 7900 7901static svn_error_t * thunk_close_file(void *file_baton, 7902 const char *text_checksum, 7903 apr_pool_t *pool) 7904{ 7905 return close_baton_checksum(file_baton, text_checksum, "close_file"); 7906} 7907 7908static svn_error_t * thunk_close_edit(void *edit_baton, apr_pool_t *pool) 7909{ 7910 return close_baton(edit_baton, "close_edit"); 7911} 7912 7913static svn_error_t * thunk_abort_edit(void *edit_baton, apr_pool_t *pool) 7914{ 7915 return close_baton(edit_baton, "abort_edit"); 7916} 7917 7918void svn_swig_java_make_editor(JNIEnv *jenv, 7919 const svn_delta_editor_t **editor, 7920 void **edit_baton, 7921 jobject java_editor, 7922 apr_pool_t *pool) 7923{ 7924 svn_delta_editor_t *thunk_editor = svn_delta_default_editor (pool); 7925 7926 thunk_editor->set_target_revision = thunk_set_target_revision; 7927 thunk_editor->open_root = thunk_open_root; 7928 thunk_editor->delete_entry = thunk_delete_entry; 7929 thunk_editor->add_directory = thunk_add_directory; 7930 thunk_editor->open_directory = thunk_open_directory; 7931 thunk_editor->change_dir_prop = thunk_change_dir_prop; 7932 thunk_editor->close_directory = thunk_close_directory; 7933 thunk_editor->add_file = thunk_add_file; 7934 thunk_editor->open_file = thunk_open_file; 7935 thunk_editor->apply_textdelta = thunk_apply_textdelta; 7936 thunk_editor->change_file_prop = thunk_change_file_prop; 7937 thunk_editor->close_file = thunk_close_file; 7938 thunk_editor->close_edit = thunk_close_edit; 7939 thunk_editor->abort_edit = thunk_abort_edit; 7940 7941 *editor = thunk_editor; 7942 *edit_baton = make_baton(jenv, pool, java_editor, NULL); 7943} 7944 7945/* This baton type is used for client prompt operations */ 7946typedef struct { 7947 jobject callback; /* Object to call back */ 7948 apr_pool_t *pool; /* pool to use for errors */ 7949 JNIEnv *jenv; /* Java native interface structure */ 7950} callback_baton_t; 7951 7952/* Pool cleanup handler. Removes global reference */ 7953static apr_status_t callback_baton_cleanup_handler(void *baton) 7954{ 7955 callback_baton_t *callback_baton = (callback_baton_t *) baton; 7956 JCALL1(DeleteGlobalRef, callback_baton->jenv, callback_baton->callback); 7957 return APR_SUCCESS; 7958} 7959 7960/* Create a callback baton */ 7961void *svn_swig_java_make_callback_baton(JNIEnv *jenv, 7962 jobject callback, 7963 apr_pool_t *pool) 7964{ 7965 jobject globalref; 7966 callback_baton_t *callback_baton; 7967 7968 globalref = JCALL1(NewGlobalRef, jenv, callback); 7969 if (globalref == NULL) 7970 { 7971 /* Exception occurred */ 7972 return 0; 7973 } 7974 7975 callback_baton = apr_palloc(pool, sizeof(*callback_baton)); 7976 7977 callback_baton->callback = globalref; 7978 callback_baton->pool = pool; 7979 callback_baton->jenv = jenv; 7980 7981 apr_pool_cleanup_register(pool, callback_baton, 7982 callback_baton_cleanup_handler, 7983 apr_pool_cleanup_null); 7984 7985 return callback_baton; 7986} 7987 7988/* a notify function that executes a Java method on an object which is 7989 passed in via the baton argument */ 7990void svn_swig_java_notify_func(void *baton, 7991 const char *path, 7992 svn_wc_notify_action_t action, 7993 svn_node_kind_t kind, 7994 const char *mime_type, 7995 svn_wc_notify_state_t content_state, 7996 svn_wc_notify_state_t prop_state, 7997 svn_revnum_t revision) 7998{ 7999 /* TODO: svn_swig_java_notify_func is not implemented yet */ 8000} 8001 8002/* a cancel function that executes a Java method on an object which is 8003 passed in via the cancel_baton argument */ 8004svn_error_t *svn_swig_java_cancel_func(void *cancel_baton) 8005{ 8006 /* TODO: svn_swig_java_cancel_func is not implemented yet */ 8007 return SVN_NO_ERROR; 8008} 8009 8010/* thunked commit log fetcher */ 8011svn_error_t *svn_swig_java_get_commit_log_func (const char **log_msg, 8012 const char **tmp_file, 8013 apr_array_header_t *commit_items, 8014 void *baton, 8015 apr_pool_t *pool) 8016{ 8017 return svn_error_create(APR_EGENERAL, NULL, "TODO: " 8018 "svn_swig_java_get_commit_log_func is not " 8019 "implemented yet"); 8020} 8021 8022/* log messages are returned in this */ 8023svn_error_t *svn_swig_java_log_message_receiver(void *baton, 8024 apr_hash_t *changed_paths, 8025 svn_revnum_t revision, 8026 const char *author, 8027 const char *date, /* use svn_time_from_string() if need apr_time_t */ 8028 const char *message, 8029 apr_pool_t *pool) 8030{ 8031 return svn_error_create(APR_EGENERAL, NULL, "TODO: svn_swig_java_get_commit_log_func is not implemented yet"); 8032} 8033 8034/* Prompt for username */ 8035svn_error_t *svn_swig_java_client_prompt_func(const char **info, 8036 const char *prompt, 8037 svn_boolean_t hide, 8038 void *baton, 8039 apr_pool_t *pool) 8040{ 8041 callback_baton_t *callback_baton; 8042 JNIEnv *jenv; 8043 jobject callback; 8044 jstring jprompt; 8045 jstring jresult; 8046 jboolean jhide; 8047 const char *c_str; 8048 svn_error_t *result; 8049 8050 callback_baton = (callback_baton_t *) baton; 8051 jenv = callback_baton->jenv; 8052 callback = callback_baton->callback; 8053 8054 /* Create a new local reference frame. Exit immediately 8055 if functions fails. */ 8056 if (JCALL1(PushLocalFrame, jenv, 2) < 0) 8057 { 8058 return convert_exception(jenv, callback_baton->pool); 8059 } 8060 8061 jprompt = JCALL1(NewStringUTF, jenv, prompt); 8062 if (!jprompt) 8063 { 8064 goto error; 8065 } 8066 jhide = hide ? JNI_TRUE : JNI_FALSE; 8067 jresult = JCALL4(CallObjectMethod, jenv, callback, 8068 svn_swig_java_mid_clientprompt_prompt, jprompt, jhide); 8069 if (!jresult) 8070 { 8071 goto error; 8072 } 8073 8074 c_str = JCALL2(GetStringUTFChars, jenv, jresult, NULL); 8075 if (!c_str) 8076 { 8077 goto error; 8078 } 8079 8080 *info = apr_pstrdup(pool, c_str); 8081 JCALL2(ReleaseStringUTFChars, jenv, jresult, c_str); 8082 JCALL1(PopLocalFrame, jenv, NULL); 8083 return SVN_NO_ERROR; 8084 8085error: 8086 result = convert_exception(jenv, callback_baton->pool); 8087 JCALL1(PopLocalFrame, jenv, NULL); 8088 return result; 8089} 8090 8091 8092/* This baton type is used for stream operations */ 8093typedef struct { 8094 jobject stream; /* Java stream object */ 8095 apr_pool_t *pool; /* pool to use for errors */ 8096 JNIEnv *jenv; /* Java native interface structure */ 8097} stream_baton_t; 8098 8099/* Create a stream baton. */ 8100static stream_baton_t *make_stream_baton(JNIEnv *jenv, 8101 jobject stream, 8102 apr_pool_t *pool) 8103{ 8104 jobject globalref; 8105 stream_baton_t *stream_baton; 8106 8107 /* The global reference is not necessary in all cases 8108 e.g. for a call to svn_client_cat() 8109 But we need it for svn_text_delta_t */ 8110 globalref = JCALL1(NewGlobalRef, jenv, stream); 8111 if (globalref == NULL) 8112 { 8113 /* Exception occurred */ 8114 return 0; 8115 } 8116 8117 stream_baton = apr_palloc(pool, sizeof(*stream_baton)); 8118 8119 stream_baton->stream = globalref; 8120 stream_baton->pool = pool; 8121 stream_baton->jenv = jenv; 8122 8123 return stream_baton; 8124} 8125 8126/* Pool cleanup handler. Removes global reference */ 8127static apr_status_t stream_baton_cleanup_handler(void *baton) 8128{ 8129 stream_baton_t *stream_baton = (stream_baton_t *) baton; 8130 JCALL1(DeleteGlobalRef, stream_baton->jenv, stream_baton->stream); 8131 return APR_SUCCESS; 8132} 8133 8134/* read/write/close functions for an OutputStream */ 8135 8136/* Read function for the OutputStream :-) 8137 Since this is a write only stream we simply generate 8138 an error. */ 8139static svn_error_t *read_outputstream(void *baton, 8140 char *buffer, 8141 apr_size_t *len) 8142{ 8143 svn_error_t *svn_error = svn_error_create(SVN_ERR_STREAM_UNEXPECTED_EOF, 8144 NULL, 8145 "Can't read from write only stream"); 8146 return svn_error; 8147} 8148 8149/* Writes to the OutputStream */ 8150static svn_error_t *write_outputstream(void *baton, 8151 const char *buffer, 8152 apr_size_t *len) 8153{ 8154 stream_baton_t *stream_baton; 8155 JNIEnv *jenv; 8156 jthrowable exc; 8157 jbyteArray bytearray; 8158 svn_error_t *result; 8159 8160 stream_baton = (stream_baton_t *) baton; 8161 jenv = stream_baton->jenv; 8162 bytearray = JCALL1(NewByteArray, jenv, (jsize) *len); 8163 if (bytearray == NULL) 8164 { 8165 goto outofmemory_error; 8166 } 8167 JCALL4(SetByteArrayRegion, jenv, bytearray, (jsize) 0, 8168 (jsize) *len, (jbyte *) buffer); 8169 exc = JCALL0(ExceptionOccurred, jenv); 8170 if (exc) 8171 { 8172 goto error; 8173 } 8174 8175 JCALL3(CallVoidMethod, jenv, stream_baton->stream, svn_swig_java_mid_outputstream_write, bytearray); 8176 exc = JCALL0(ExceptionOccurred, jenv); 8177 if (exc) 8178 { 8179 goto error; 8180 } 8181 8182 JCALL1(DeleteLocalRef, jenv, bytearray); 8183 return SVN_NO_ERROR; 8184 8185outofmemory_error: 8186 /* We now for sure that there is an exception pending */ 8187 exc = JCALL0(ExceptionOccurred, jenv); 8188 8189error: 8190 /* ### Better exception handling 8191 At this point, we now that there is exception exc pending. 8192 These are: 8193 - OutOfMemoryError (NewByteArray) 8194 - ArrayIndexOutOfBounds (SetByteArrayRegion) 8195 - IOException (CallVoidMethod[write]) 8196 At least, the OutOfMemory error should get a special treatment... */ 8197 /* DEBUG JCALL0(ExceptionDescribe, jenv); */ 8198 JCALL0(ExceptionClear, jenv); 8199 result = svn_error_create(SVN_ERR_STREAM_UNEXPECTED_EOF, NULL, 8200 "Write error on stream"); 8201 JCALL1(DeleteLocalRef, jenv, exc); 8202 return result; 8203} 8204 8205/* Closes the OutputStream 8206 Does nothing because we are not the owner of the stream. 8207 May flush the stream in future. */ 8208static svn_error_t *close_outputstream(void *baton) 8209{ 8210 return SVN_NO_ERROR; 8211} 8212 8213/* read/write/close functions for an InputStream */ 8214 8215/* Reads from the InputStream */ 8216static svn_error_t *read_inputstream(void *baton, 8217 char *buffer, 8218 apr_size_t *len) 8219{ 8220 stream_baton_t *stream_baton; 8221 JNIEnv *jenv; 8222 jthrowable exc; 8223 jbyteArray bytearray; 8224 jsize read_len; 8225 svn_error_t *result; 8226 8227 stream_baton = (stream_baton_t *) baton; 8228 jenv = stream_baton->jenv; 8229 bytearray = JCALL1(NewByteArray, jenv, (jsize) *len); 8230 if (bytearray == NULL) 8231 { 8232 goto outofmemory_error; 8233 } 8234 8235 read_len = JCALL3(CallIntMethod, jenv, stream_baton->stream, 8236 svn_swig_java_mid_inputstream_read, bytearray); 8237 exc = JCALL0(ExceptionOccurred, jenv); 8238 if (exc) 8239 { 8240 goto error; 8241 } 8242 8243 if (read_len > 0) 8244 { 8245 JCALL4(GetByteArrayRegion, jenv, bytearray, (jsize) 0, (jsize) read_len, 8246 (jbyte *) buffer); 8247 exc = JCALL0(ExceptionOccurred, jenv); 8248 if (exc) 8249 { 8250 goto error; 8251 } 8252 } 8253 else 8254 { 8255 read_len = 0; /* -1 is EOF, svn_stream_t wants 0 */ 8256 } 8257 8258 JCALL1(DeleteLocalRef, jenv, bytearray); 8259 *len = read_len; 8260 return SVN_NO_ERROR; 8261 8262outofmemory_error: 8263 /* We now for sure that there is an exception pending */ 8264 exc = JCALL0(ExceptionOccurred, jenv); 8265 8266error: 8267 /* ### Better exception handling 8268 At this point, we now that there is exception exc pending. 8269 These are: 8270 - OutOfMemoryError (NewByteArray) 8271 - ArrayIndexOutOfBounds (SetByteArrayRegion) 8272 - IOException (CallIntMethod[read]) 8273 At least, the OutOfMemory error should get a special treatment... */ 8274 /* DEBUG JCALL0(ExceptionDescribe, jenv); */ 8275 JCALL0(ExceptionClear, jenv); 8276 result = svn_error_create(SVN_ERR_STREAM_UNEXPECTED_EOF, NULL, 8277 "Write error on stream"); 8278 JCALL1(DeleteLocalRef, jenv, exc); 8279 return result; 8280} 8281 8282/* Write function for the InputStream :-) 8283 Since this is a read only stream we simply generate 8284 an error. */ 8285static svn_error_t *write_inputstream(void *baton, 8286 const char *buffer, 8287 apr_size_t *len) 8288{ 8289 svn_error_t *svn_error = svn_error_create(SVN_ERR_STREAM_UNEXPECTED_EOF, 8290 NULL, 8291 "Can't write on read only stream"); 8292 return svn_error; 8293} 8294 8295/* Closes the InputStream 8296 Does nothing because we are not the owner of the stream. */ 8297static svn_error_t *close_inputstream(void *baton) 8298{ 8299 return SVN_NO_ERROR; 8300} 8301 8302/* Create a svn_stream_t from a java.io.OutputStream object. 8303 Registers a pool cleanup handler for deallocating JVM 8304 resources. */ 8305svn_stream_t *svn_swig_java_outputstream_to_stream(JNIEnv *jenv, 8306 jobject outputstream, apr_pool_t *pool) 8307{ 8308 stream_baton_t *baton; 8309 svn_stream_t *stream; 8310 8311 baton = make_stream_baton(jenv, outputstream, pool); 8312 if (baton == NULL) 8313 { 8314 return NULL; 8315 } 8316 apr_pool_cleanup_register(pool, baton, stream_baton_cleanup_handler, 8317 apr_pool_cleanup_null); 8318 8319 stream = svn_stream_create(baton, pool); 8320 if (stream == NULL) 8321 { 8322 return NULL; 8323 } 8324 svn_stream_set_read(stream, read_outputstream); 8325 svn_stream_set_write(stream, write_outputstream); 8326 svn_stream_set_close(stream, close_outputstream); 8327 8328 return stream; 8329} 8330 8331/* Create a svn_stream_t from a java.io.InputStream object. 8332 Registers a pool cleanup handler for deallocating JVM 8333 resources. */ 8334svn_stream_t *svn_swig_java_inputstream_to_stream(JNIEnv *jenv, 8335 jobject inputstream, apr_pool_t *pool) 8336{ 8337 stream_baton_t *baton; 8338 svn_stream_t *stream; 8339 8340 baton = make_stream_baton(jenv, inputstream, pool); 8341 if (baton == NULL) 8342 { 8343 return NULL; 8344 } 8345 apr_pool_cleanup_register(pool, baton, stream_baton_cleanup_handler, 8346 apr_pool_cleanup_null); 8347 8348 stream = svn_stream_create(baton, pool); 8349 if (stream == NULL) 8350 { 8351 return NULL; 8352 } 8353 svn_stream_set_read(stream, read_inputstream); 8354 svn_stream_set_write(stream, write_inputstream); 8355 svn_stream_set_close(stream, close_inputstream); 8356 8357 return stream; 8358} 8359 8360 8361JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) 8362{ 8363 JNIEnv *jenv; 8364 if ((*jvm)->GetEnv(jvm, (void **) &jenv, JNI_VERSION_1_2)) 8365 { 8366 return JNI_ERR; 8367 } 8368#define SVN_SWIG_JAVA_INIT_CACHE 8369#include "swigutil_java_cache.h" 8370 8371 return JNI_VERSION_1_2; 8372} 8373 8374JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *reserved) 8375{ 8376 JNIEnv *jenv; 8377 if ((*jvm)->GetEnv(jvm, (void **) &jenv, JNI_VERSION_1_2)) 8378 { 8379 return; 8380 } 8381#define SVN_SWIG_JAVA_TERM_CACHE 8382#include "swigutil_java_cache.h" 8383} 8384 8385 8386Node-path: svnperl/swigutil_java.h 8387Node-kind: file 8388Node-action: add 8389Prop-content-length: 10 8390Text-content-length: 5813 8391Text-content-md5: e2a626417957c43e30d9b9332cedd4ff 8392Content-length: 5823 8393 8394PROPS-END 8395/* 8396 * swigutil_java.h : utility functions and stuff for the SWIG Java bindings 8397 * 8398 * ==================================================================== 8399 * Copyright (c) 2000-2004 CollabNet. All rights reserved. 8400 * 8401 * This software is licensed as described in the file COPYING, which 8402 * you should have received as part of this distribution. The terms 8403 * are also available at http://subversion.tigris.org/license-1.html. 8404 * If newer versions of this license are posted there, you may use a 8405 * newer version instead, at your option. 8406 * 8407 * This software consists of voluntary contributions made by many 8408 * individuals. For exact contribution history, see the revision 8409 * history and logs, available at http://subversion.tigris.org/. 8410 * ==================================================================== 8411 */ 8412 8413 8414#ifndef SVN_SWIG_SWIGUTIL_JAVA_H 8415#define SVN_SWIG_SWIGUTIL_JAVA_H 8416 8417#include <jni.h> 8418 8419#include <apr.h> 8420#include <apr_pools.h> 8421#include <apr_strings.h> 8422#include <apr_hash.h> 8423#include <apr_tables.h> 8424 8425#include "svn_types.h" 8426#include "svn_string.h" 8427#include "svn_delta.h" 8428#include "svn_wc.h" 8429 8430#include "swigutil_java_cache.h" 8431 8432#ifdef __cplusplus 8433extern "C" { 8434#endif /* __cplusplus */ 8435 8436 8437/* convert an svn_error_t into a SubversionException and clear error */ 8438jthrowable svn_swig_java_convert_error(JNIEnv *jenv, svn_error_t *error); 8439 8440/* helper function to convert an apr_hash_t* (char* -> svnstring_t*) to 8441 a Java Map */ 8442jobject svn_swig_java_prophash_to_dict(JNIEnv *jenv, apr_hash_t *hash); 8443 8444/* convert a hash of 'const char *' -> TYPE into a Java Map */ 8445jobject svn_swig_java_convert_hash(JNIEnv *jenv, apr_hash_t *hash); 8446 8447/* add all the elements from an array to an existing java.util.List */ 8448void svn_swig_java_add_to_list(JNIEnv* jenv, apr_array_header_t *array, 8449 jobject list); 8450 8451/* add all the elements from a hash to an existing java.util.Map */ 8452void svn_swig_java_add_to_map(JNIEnv* jenv, apr_hash_t *hash, jobject map); 8453 8454/* helper function to convert a 'char **' into a Java List of String 8455 objects */ 8456jobject svn_swig_java_c_strings_to_list(JNIEnv *jenv, char **strings); 8457 8458/* helper function to convert an array of 'const char *' to a Java List of 8459 String objects */ 8460jobject svn_swig_java_array_to_list(JNIEnv *jenv, 8461 const apr_array_header_t *strings); 8462 8463/* helper function to convert a Java List of String objects into an 8464 'apr_array_header_t *' of 'const char *' objects. Note that the 8465 objects must remain alive -- the values are not copied. This is 8466 appropriate for incoming arguments which are defined to last the 8467 duration of the function's execution. */ 8468const apr_array_header_t *svn_swig_java_strings_to_array(JNIEnv *jenv, 8469 jobject source, 8470 apr_pool_t *pool); 8471 8472/* make an editor that "thunks" from C callbacks up to Java */ 8473void svn_swig_java_make_editor(JNIEnv *jenv, 8474 const svn_delta_editor_t **editor, 8475 void **edit_baton, 8476 jobject java_editor, 8477 apr_pool_t *pool); 8478 8479/* a notify function that executes a Java method on an object which is 8480 passed in via the baton argument */ 8481void svn_swig_java_notify_func(void *baton, 8482 const char *path, 8483 svn_wc_notify_action_t action, 8484 svn_node_kind_t kind, 8485 const char *mime_type, 8486 svn_wc_notify_state_t content_state, 8487 svn_wc_notify_state_t prop_state, 8488 svn_revnum_t revision); 8489 8490/* a cancel function that executes a Java method on an object passed 8491 in via the cancel_baton argument. */ 8492svn_error_t *svn_swig_java_cancel_func(void *cancel_baton); 8493 8494/* thunked commit log fetcher */ 8495svn_error_t *svn_swig_java_get_commit_log_func(const char **log_msg, 8496 const char **tmp_file, 8497 apr_array_header_t *commit_items, 8498 void *baton, 8499 apr_pool_t *pool); 8500 8501/* log messages are returned in this */ 8502svn_error_t *svn_swig_java_log_message_receiver(void *baton, 8503 apr_hash_t *changed_paths, 8504 svn_revnum_t revision, 8505 const char *author, 8506 const char *date, /* use svn_time_from_string() if need apr_time_t */ 8507 const char *message, 8508 apr_pool_t *pool); 8509 8510/* Create a callback baton */ 8511void *svn_swig_java_make_callback_baton(JNIEnv *jenv, 8512 jobject callback, 8513 apr_pool_t *pool); 8514 8515/* Prompt for username */ 8516svn_error_t *svn_swig_java_client_prompt_func(const char **info, 8517 const char *prompt, 8518 svn_boolean_t hide, 8519 void *baton, 8520 apr_pool_t *pool); 8521 8522/* Create write-only svn_stream_t from java.io.OutputStream */ 8523svn_stream_t *svn_swig_java_outputstream_to_stream(JNIEnv *jenv, 8524 jobject outputstream, 8525 apr_pool_t *pool); 8526 8527/* Create read-only svn_stream_t from java.io.InputStream */ 8528svn_stream_t *svn_swig_java_inputstream_to_stream(JNIEnv *jenv, 8529 jobject inputstream, 8530 apr_pool_t *pool); 8531 8532#ifdef __cplusplus 8533} 8534#endif /* __cplusplus */ 8535 8536#endif /* SVN_SWIG_SWIGUTIL_JAVA_H */ 8537 8538 8539Node-path: svnperl/swigutil_java_cache.h 8540Node-kind: file 8541Node-action: add 8542Prop-content-length: 10 8543Text-content-length: 4700 8544Text-content-md5: 1bb11a0e7bcd9b3ef852ee5258890922 8545Content-length: 4710 8546 8547PROPS-END 8548/** 8549 * @copyright 8550 * ==================================================================== 8551 * Copyright (c) 2000-2004 CollabNet. All rights reserved. 8552 * 8553 * This software is licensed as described in the file COPYING, which 8554 * you should have received as part of this distribution. The terms 8555 * are also available at http://subversion.tigris.org/license-1.html. 8556 * If newer versions of this license are posted there, you may use a 8557 * newer version instead, at your option. 8558 * 8559 * This software consists of voluntary contributions made by many 8560 * individuals. For exact contribution history, see the revision 8561 * history and logs, available at http://subversion.tigris.org/. 8562 * ==================================================================== 8563 * @endcopyright 8564 * 8565 * @file swigutil_java_cache.h 8566 * @brief Caching of Java class references and method IDs. 8567 */ 8568 8569#if defined(SVN_SWIG_JAVA_DEFINE_CACHE) || defined(SVN_SWIG_JAVA_INIT_CACHE) || defined(SVN_SWIG_JAVA_TERM_CACHE) || !defined(SVN_SWIG_JAVACACHE_INCLUDED) 8570 8571#ifdef __cplusplus 8572extern "C" { 8573#endif /* __cplusplus */ 8574 8575 8576/* Define methodID/class references */ 8577#if defined(SVN_SWIG_JAVA_DEFINE_CACHE) 8578 8579#define SVN_SWIG_JAVA_CACHE_START 8580 8581#define SVN_SWIG_JAVA_CACHE_METHOD_DEF(jenv,name,clazz,method,signature) \ 8582 jmethodID name; 8583 8584#define SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,name,clazzname) \ 8585 jclass name; 8586 8587#define SVN_SWIG_JAVA_CACHE_END 8588 8589/* Initialize methodID/class references */ 8590#elif defined(SVN_SWIG_JAVA_INIT_CACHE) 8591 8592#define SVN_SWIG_JAVA_CACHE_START \ 8593 { jclass _clazz; 8594 8595#define SVN_SWIG_JAVA_CACHE_METHOD_DEF(jenv,name,clazz,method,signature) \ 8596 name = JCALL3(GetMethodID, jenv, clazz, method, signature); \ 8597 if (name == NULL) { return JNI_ERR; } 8598 8599#define SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,name,clazzname) \ 8600 _clazz = JCALL1(FindClass, jenv, clazzname); \ 8601 if (_clazz == NULL) { return JNI_ERR; } \ 8602 name = JCALL1(NewGlobalRef, jenv, _clazz); \ 8603 if (name == NULL) { return JNI_ERR; } 8604 8605#define SVN_SWIG_JAVA_CACHE_END \ 8606 } 8607 8608 8609/* Clear methodID/class references */ 8610#elif defined(SVN_SWIG_JAVA_TERM_CACHE) 8611 8612#define SVN_SWIG_JAVA_CACHE_START 8613 8614#define SVN_SWIG_JAVA_CACHE_METHOD_DEF(jenv,name,clazz,method,signature) 8615 8616#define SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,name,clazzname) \ 8617 JCALL1(DeleteGlobalRef, jenv, name); 8618 8619#define SVN_SWIG_JAVA_CACHE_END 8620 8621 8622/* Simple declaration */ 8623#elif !defined(SVN_SWIG_JAVACACHE_INCLUDED) 8624 8625#define SVN_SWIG_JAVACACHE_INCLUDED 8626 8627#define SVN_SWIG_JAVA_CACHE_START 8628 8629#define SVN_SWIG_JAVA_CACHE_METHOD_DEF(jenv,name,clazz,method,signature) \ 8630 extern jmethodID name; 8631 8632#define SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,name,clazzname) \ 8633 extern jclass name; 8634 8635#define SVN_SWIG_JAVA_CACHE_END 8636 8637#endif 8638 8639 8640SVN_SWIG_JAVA_CACHE_START 8641 8642SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,svn_swig_java_cls_long,"java/lang/Long") 8643SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,svn_swig_java_cls_string,"java/lang/String") 8644SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,svn_swig_java_cls_outofmemoryerror,"java/lang/OutOfMemoryError") 8645SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,svn_swig_java_cls_outputstream,"java/io/OutputStream") 8646SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,svn_swig_java_cls_inputstream,"java/io/InputStream") 8647SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,svn_swig_java_cls_list,"java/util/ArrayList") 8648SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,svn_swig_java_cls_list,"java/util/List") 8649SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,svn_swig_java_cls_list,"java/util/Map") 8650SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,svn_swig_java_cls_subversionexception,"org/tigris/subversion/SubversionException") 8651SVN_SWIG_JAVA_CACHE_CLASS_DEF(jenv,svn_swig_java_cls_clientprompt,"org/tigris/subversion/client/ClientPrompt") 8652 8653SVN_SWIG_JAVA_CACHE_METHOD_DEF(jenv,svn_swig_java_mid_long_longvalue,svn_swig_java_cls_long,"longValue","()J") 8654SVN_SWIG_JAVA_CACHE_METHOD_DEF(jenv,svn_swig_java_mid_outputstream_write,svn_swig_java_cls_outputstream,"write","([B)V") 8655SVN_SWIG_JAVA_CACHE_METHOD_DEF(jenv,svn_swig_java_mid_inputstream_read,svn_swig_java_cls_inputstream,"read","([B)I") 8656SVN_SWIG_JAVA_CACHE_METHOD_DEF(jenv,svn_swig_java_mid_subversionexception_init,svn_swig_java_cls_subversionexception,"<init>","(Ljava/lang/String;Ljava/lang/Throwable;JLjava/lang/String;J)V") 8657SVN_SWIG_JAVA_CACHE_METHOD_DEF(jenv,svn_swig_java_mid_clientprompt_prompt,svn_swig_java_cls_clientprompt,"prompt","(Ljava/lang/String;Z)Ljava/lang/String;") 8658 8659SVN_SWIG_JAVA_CACHE_END 8660 8661 8662#undef SVN_SWIG_JAVA_CACHE_START 8663#undef SVN_SWIG_JAVA_CACHE_CLASS_DEF 8664#undef SVN_SWIG_JAVA_CACHE_METHOD_DEF 8665#undef SVN_SWIG_JAVA_CACHE_END 8666 8667#undef SVN_SWIG_JAVA_DEFINE_CACHE 8668#undef SVN_SWIG_JAVA_INIT_CACHE 8669#undef SVN_SWIG_JAVA_TERM_CACHE 8670 8671#ifdef __cplusplus 8672} 8673#endif /* __cplusplus */ 8674 8675#endif 8676 8677 8678Node-path: svnperl/swigutil_pl.c 8679Node-kind: file 8680Node-action: add 8681Prop-content-length: 10 8682Text-content-length: 33243 8683Text-content-md5: 7f9788620af1b6fba78988b8963f2c79 8684Content-length: 33253 8685 8686PROPS-END 8687/* 8688 * swigutil_py.c: utility functions for the SWIG Perl bindings 8689 * 8690 * ==================================================================== 8691 * Copyright (c) 2000-2004 CollabNet. All rights reserved. 8692 * 8693 * This software is licensed as described in the file COPYING, which 8694 * you should have received as part of this distribution. The terms 8695 * are also available at http://subversion.tigris.org/license-1.html. 8696 * If newer versions of this license are posted there, you may use a 8697 * newer version instead, at your option. 8698 * 8699 * This software consists of voluntary contributions made by many 8700 * individuals. For exact contribution history, see the revision 8701 * history and logs, available at http://subversion.tigris.org/. 8702 * ==================================================================== 8703 */ 8704 8705#include <EXTERN.h> 8706#include <perl.h> 8707#include <XSUB.h> 8708 8709#include <stdarg.h> 8710 8711#include <apr.h> 8712#include <apr_general.h> 8713#include <apr_portable.h> 8714 8715#include "svn_pools.h" 8716#include "svn_opt.h" 8717 8718#include "swigutil_pl.h" 8719 8720/* element convertors for perl -> c */ 8721typedef void *(*pl_element_converter_t)(SV *value, void *ctx, apr_pool_t *pool); 8722 8723static void *convert_pl_string (SV *value, void *dummy, apr_pool_t *pool) 8724{ 8725 void **result = apr_palloc(pool, sizeof(void *)); 8726 *result = SvPV_nolen (value); 8727 return *result; 8728} 8729 8730static void *convert_pl_obj (SV *value, swig_type_info *tinfo, apr_pool_t *pool) 8731{ 8732 void **result = apr_palloc(pool, sizeof(void *)); 8733 if (SWIG_ConvertPtr(value, result, tinfo, 0) < 0) { 8734 croak("unable to convert from swig object"); 8735 } 8736 return *result; 8737} 8738 8739/* perl -> c hash convertors */ 8740static apr_hash_t *svn_swig_pl_to_hash(SV *source, 8741 pl_element_converter_t cv, 8742 void *ctx, apr_pool_t *pool) 8743{ 8744 apr_hash_t *hash; 8745 HV *h; 8746 char *key; 8747 I32 cnt, retlen; 8748 8749 if (!(source && SvROK(source) && SvTYPE(SvRV(source)) == SVt_PVHV)) { 8750 return NULL; 8751 } 8752 8753 hash = apr_hash_make (pool); 8754 h = (HV *)SvRV(source); 8755 cnt = hv_iterinit(h); 8756 while (cnt--) { 8757 SV* item = hv_iternextsv(h, &key, &retlen); 8758 void *val = cv (item, ctx, pool); 8759 apr_hash_set (hash, key, APR_HASH_KEY_STRING, val); 8760 } 8761 8762 return hash; 8763} 8764 8765apr_hash_t *svn_swig_pl_objs_to_hash(SV *source, swig_type_info *tinfo, 8766 apr_pool_t *pool) 8767{ 8768 8769 return svn_swig_pl_to_hash(source, (pl_element_converter_t)convert_pl_obj, 8770 tinfo, pool); 8771} 8772 8773apr_hash_t *svn_swig_pl_strings_to_hash(SV *source, apr_pool_t *pool) 8774{ 8775 8776 return svn_swig_pl_to_hash(source, convert_pl_string, NULL, pool); 8777} 8778 8779 8780apr_hash_t *svn_swig_pl_objs_to_hash_by_name(SV *source, 8781 const char *typename, 8782 apr_pool_t *pool) 8783{ 8784 swig_type_info *tinfo = SWIG_TypeQuery(typename); 8785 return svn_swig_pl_objs_to_hash (source, tinfo, pool); 8786} 8787 8788/* perl -> c array convertors */ 8789static const apr_array_header_t *svn_swig_pl_to_array (SV *source, 8790 pl_element_converter_t cv, 8791 void *ctx, apr_pool_t *pool) 8792{ 8793 int targlen; 8794 apr_array_header_t *temp; 8795 AV* array; 8796 8797 if (!(source && SvROK(source) && SvTYPE(SvRV(source)) == SVt_PVAV)) { 8798 /* raise exception here */ 8799 return NULL; 8800 } 8801 array = (AV *)SvRV (source); 8802 targlen = av_len (array) + 1; 8803 temp = apr_array_make (pool, targlen, sizeof(const char *)); 8804 temp->nelts = targlen; 8805 8806 while (targlen--) { 8807 /* more error handling here */ 8808 SV **item = av_fetch (array, targlen, 0); 8809 APR_ARRAY_IDX(temp, targlen, const char *) = cv (*item, ctx, pool); 8810 } 8811 8812 return temp; 8813} 8814 8815const apr_array_header_t *svn_swig_pl_strings_to_array(SV *source, 8816 apr_pool_t *pool) 8817{ 8818 return svn_swig_pl_to_array (source, convert_pl_string, NULL, pool); 8819} 8820 8821const apr_array_header_t *svn_swig_pl_objs_to_array(SV *source, 8822 swig_type_info *tinfo, 8823 apr_pool_t *pool) 8824{ 8825 return svn_swig_pl_to_array (source, 8826 (pl_element_converter_t)convert_pl_obj, 8827 tinfo, pool); 8828} 8829 8830/* element convertors for c -> perl */ 8831typedef SV *(*element_converter_t)(void *value, void *ctx); 8832 8833static SV *convert_string (const char *value, void *dummy) 8834{ 8835 SV *obj = sv_2mortal(newSVpv(value, 0)); 8836 return obj; 8837} 8838 8839static SV *convert_svn_string_t (svn_string_t *value, void *dummy) 8840{ 8841 SV *obj = sv_2mortal(newSVpv(value->data, value->len)); 8842 return obj; 8843} 8844 8845static SV *convert_to_swig_type (void *ptr, swig_type_info *tinfo) 8846{ 8847 SV *obj = sv_newmortal(); 8848 SWIG_MakePtr(obj, ptr, tinfo, 0); 8849 return obj; 8850} 8851 8852static SV *convert_int(int value, void *dummy) 8853{ 8854 return newSViv (value); 8855} 8856 8857/* c -> perl hash convertors */ 8858static SV *convert_hash (apr_hash_t *hash, element_converter_t converter_func, 8859 void *ctx) 8860{ 8861 apr_hash_index_t *hi; 8862 HV *hv; 8863 8864 hv = newHV(); 8865 for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi)) { 8866 const char *key; 8867 void *val; 8868 int klen; 8869 SV *obj; 8870 8871 apr_hash_this(hi, (void *)&key, NULL, &val); 8872 klen = strlen(key); 8873 8874 obj = converter_func (val, ctx); 8875 hv_store(hv, (const char *)key, klen, obj, 0); 8876 SvREFCNT_inc(obj); 8877 } 8878 8879 return newRV_inc((SV*)hv); 8880} 8881 8882SV *svn_swig_pl_prophash_to_hash (apr_hash_t *hash) 8883{ 8884 return convert_hash (hash, (element_converter_t)convert_svn_string_t, 8885 NULL); 8886} 8887 8888SV *svn_swig_pl_convert_hash (apr_hash_t *hash, swig_type_info *tinfo) 8889{ 8890 return convert_hash (hash, (element_converter_t)convert_to_swig_type, 8891 tinfo); 8892} 8893 8894/* c -> perl array convertors */ 8895static SV *convert_array(const apr_array_header_t *array, 8896 element_converter_t converter_func, void *ctx) 8897{ 8898 AV *list = newAV(); 8899 int i; 8900 8901 for (i = 0; i < array->nelts; ++i) { 8902 void *element = APR_ARRAY_IDX(array, i, void *); 8903 SV *item = converter_func (element, ctx); 8904 av_push (list, item); 8905 SvREFCNT_inc (item); 8906 } 8907 return newRV_inc((SV*)list); 8908} 8909 8910SV *svn_swig_pl_array_to_list(const apr_array_header_t *array) 8911{ 8912 return convert_array (array, (element_converter_t)convert_string, NULL); 8913} 8914 8915SV *svn_swig_pl_ints_to_list(const apr_array_header_t *array) 8916{ 8917 return convert_array (array, (element_converter_t)convert_int, NULL); 8918} 8919 8920typedef enum perl_func_invoker { 8921 CALL_METHOD, 8922 CALL_SV 8923} perl_func_invoker_t; 8924 8925/* put the va_arg in stack and invoke caller_func with func. 8926 fmt: 8927 * O: perl object 8928 * i: integer 8929 * s: string 8930 * S: swigtype 8931 8932 put returned value in result if result is not NULL 8933*/ 8934 8935static svn_error_t *perl_callback_thunk (perl_func_invoker_t caller_func, 8936 void *func, 8937 SV **result, 8938 const char *fmt, ...) 8939{ 8940 const char *fp = fmt; 8941 va_list ap; 8942 int count; 8943 8944 dSP ; 8945 ENTER ; 8946 SAVETMPS ; 8947 8948 PUSHMARK(SP) ; 8949 8950 va_start(ap, fmt); 8951 while (*fp) { 8952 char *c; 8953 void *o; 8954 SV *obj; 8955 swig_type_info *t; 8956 8957 switch (*fp++) { 8958 case 'O': 8959 XPUSHs (va_arg (ap, SV *)); 8960 break; 8961 case 'S': /* swig object */ 8962 o = va_arg (ap, void *); 8963 t = va_arg (ap, swig_type_info *); 8964 8965 obj = sv_newmortal (); 8966 SWIG_MakePtr (obj, o, t, 0); 8967 XPUSHs(obj); 8968 break; 8969 8970 case 's': /* string */ 8971 c = va_arg (ap, char *); 8972 XPUSHs(c ? sv_2mortal(newSVpv(c, 0)) : &PL_sv_undef); 8973 break; 8974 8975 case 'i': /* integer */ 8976 XPUSHs(sv_2mortal(newSViv(va_arg(ap, int)))); 8977 break; 8978 8979 } 8980 } 8981 8982 va_end (ap); 8983 8984 PUTBACK; 8985 switch (caller_func) { 8986 case CALL_SV: 8987 count = call_sv (func, G_SCALAR); 8988 break; 8989 case CALL_METHOD: 8990 count = call_method (func, G_SCALAR); 8991 break; 8992 default: 8993 croak ("unkonwn calling type"); 8994 break; 8995 } 8996 SPAGAIN ; 8997 8998 if (count != 1) 8999 croak("Big trouble\n") ; 9000 9001 if (result) { 9002 *result = POPs; 9003 SvREFCNT_inc(*result); 9004 } 9005 9006 FREETMPS ; 9007 LEAVE ; 9008 9009 return SVN_NO_ERROR; 9010} 9011 9012/*** Editor Wrapping ***/ 9013 9014/* this could be more perlish */ 9015typedef struct { 9016 SV *editor; /* the editor handling the callbacks */ 9017 SV *baton; /* the dir/file baton (or NULL for edit baton) */ 9018} item_baton; 9019 9020static item_baton * make_baton(apr_pool_t *pool, 9021 SV *editor, SV *baton) 9022{ 9023 item_baton *newb = apr_palloc(pool, sizeof(*newb)); 9024 9025 SvREFCNT_inc(editor); 9026 9027 newb->editor = editor; 9028 newb->baton = baton; 9029 9030 return newb; 9031} 9032 9033static svn_error_t * close_baton(void *baton, const char *method) 9034{ 9035 item_baton *ib = baton; 9036 dSP ; 9037 9038 ENTER ; 9039 SAVETMPS ; 9040 9041 PUSHMARK(SP) ; 9042 XPUSHs(ib->editor); 9043 9044 if (ib->baton) 9045 XPUSHs(ib->baton); 9046 9047 PUTBACK; 9048 9049 call_method(method, G_DISCARD); 9050 9051 /* check result? */ 9052 9053 SvREFCNT_dec(ib->editor); 9054 if (ib->baton) 9055 SvREFCNT_dec(ib->baton); 9056 9057#ifdef SVN_DEBUG 9058 ib->editor = ib->baton = NULL; 9059#endif 9060 9061 FREETMPS ; 9062 LEAVE ; 9063 9064 return SVN_NO_ERROR; 9065} 9066 9067static svn_error_t * thunk_set_target_revision(void *edit_baton, 9068 svn_revnum_t target_revision, 9069 apr_pool_t *pool) 9070{ 9071 item_baton *ib = edit_baton; 9072 9073 SVN_ERR (perl_callback_thunk (CALL_METHOD, 9074 (void *)"set_target_revision", NULL, 9075 "Oi", ib->editor, target_revision)); 9076 9077 return SVN_NO_ERROR; 9078} 9079 9080static svn_error_t * thunk_open_root(void *edit_baton, 9081 svn_revnum_t base_revision, 9082 apr_pool_t *dir_pool, 9083 void **root_baton) 9084{ 9085 item_baton *ib = edit_baton; 9086 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9087 SV *result; 9088 9089 SVN_ERR (perl_callback_thunk (CALL_METHOD, 9090 (void *)"open_root", &result, 9091 "OiS", ib->editor, base_revision, 9092 dir_pool, poolinfo)); 9093 9094 *root_baton = make_baton(dir_pool, ib->editor, result); 9095 return SVN_NO_ERROR; 9096} 9097 9098static svn_error_t * thunk_delete_entry(const char *path, 9099 svn_revnum_t revision, 9100 void *parent_baton, 9101 apr_pool_t *pool) 9102{ 9103 item_baton *ib = parent_baton; 9104 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9105 9106 SVN_ERR (perl_callback_thunk (CALL_METHOD, 9107 (void *)"delete_entry", NULL, 9108 "OsiOS", ib->editor, path, revision, 9109 ib->baton, pool, poolinfo)); 9110 return SVN_NO_ERROR; 9111} 9112 9113static svn_error_t * thunk_add_directory(const char *path, 9114 void *parent_baton, 9115 const char *copyfrom_path, 9116 svn_revnum_t copyfrom_revision, 9117 apr_pool_t *dir_pool, 9118 void **child_baton) 9119{ 9120 item_baton *ib = parent_baton; 9121 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9122 SV *result; 9123 9124 SVN_ERR (perl_callback_thunk (CALL_METHOD, 9125 (void *)"add_directory", &result, 9126 "OsOsiS", ib->editor, path, ib->baton, 9127 copyfrom_path, copyfrom_revision, 9128 dir_pool, poolinfo)); 9129 *child_baton = make_baton(dir_pool, ib->editor, result); 9130 return SVN_NO_ERROR; 9131} 9132 9133static svn_error_t * thunk_open_directory(const char *path, 9134 void *parent_baton, 9135 svn_revnum_t base_revision, 9136 apr_pool_t *dir_pool, 9137 void **child_baton) 9138{ 9139 item_baton *ib = parent_baton; 9140 SV *result; 9141 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9142 9143 SVN_ERR (perl_callback_thunk (CALL_METHOD, 9144 (void *)"open_directory", &result, 9145 "OsOiS", ib->editor, path, ib->baton, 9146 base_revision, dir_pool, poolinfo)); 9147 9148 *child_baton = make_baton(dir_pool, ib->editor, result); 9149 9150 return SVN_NO_ERROR; 9151} 9152 9153static svn_error_t * thunk_change_dir_prop(void *dir_baton, 9154 const char *name, 9155 const svn_string_t *value, 9156 apr_pool_t *pool) 9157{ 9158 item_baton *ib = dir_baton; 9159 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9160 9161 SVN_ERR (perl_callback_thunk (CALL_METHOD, 9162 (void *)"change_dir_prop", NULL, 9163 "OOssS", ib->editor, ib->baton, name, 9164 value ? value->data : NULL, 9165 pool, poolinfo)); 9166 9167 return SVN_NO_ERROR; 9168} 9169 9170static svn_error_t * thunk_close_directory(void *dir_baton, 9171 apr_pool_t *pool) 9172{ 9173 return close_baton(dir_baton, "close_directory"); 9174} 9175 9176static svn_error_t * thunk_absent_directory(const char *path, 9177 void *parent_baton, 9178 apr_pool_t *pool) 9179{ 9180 item_baton *ib = parent_baton; 9181 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9182 9183 SVN_ERR (perl_callback_thunk (CALL_METHOD, 9184 (void *)"absent_directory", NULL, 9185 "OsOS", ib->editor, path, ib->baton, 9186 pool, poolinfo)); 9187 9188 return SVN_NO_ERROR; 9189} 9190 9191static svn_error_t * thunk_add_file(const char *path, 9192 void *parent_baton, 9193 const char *copyfrom_path, 9194 svn_revnum_t copyfrom_revision, 9195 apr_pool_t *file_pool, 9196 void **file_baton) 9197{ 9198 item_baton *ib = parent_baton; 9199 SV *result; 9200 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9201 9202 SVN_ERR (perl_callback_thunk (CALL_METHOD, 9203 (void *)"add_file", &result, 9204 "OsOsiS", ib->editor, path, ib->baton, 9205 copyfrom_path, copyfrom_revision, 9206 file_pool, poolinfo)); 9207 9208 *file_baton = make_baton(file_pool, ib->editor, result); 9209 return SVN_NO_ERROR; 9210} 9211 9212static svn_error_t * thunk_open_file(const char *path, 9213 void *parent_baton, 9214 svn_revnum_t base_revision, 9215 apr_pool_t *file_pool, 9216 void **file_baton) 9217{ 9218 item_baton *ib = parent_baton; 9219 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9220 SV *result; 9221 9222 SVN_ERR (perl_callback_thunk (CALL_METHOD, 9223 (void *)"open_file", &result, 9224 "OsOiS", ib->editor, path, ib->baton, 9225 base_revision, file_pool, poolinfo)); 9226 9227 *file_baton = make_baton(file_pool, ib->editor, result); 9228 return SVN_NO_ERROR; 9229} 9230 9231static svn_error_t * thunk_window_handler(svn_txdelta_window_t *window, 9232 void *baton) 9233{ 9234 SV *handler = baton; 9235 9236 if (window == NULL) { 9237 SVN_ERR (perl_callback_thunk (CALL_SV, 9238 handler, NULL, "O", 9239 &PL_sv_undef)); 9240 } 9241 else { 9242 swig_type_info *tinfo = SWIG_TypeQuery("svn_txdelta_window_t *"); 9243 SVN_ERR (perl_callback_thunk (CALL_SV, 9244 handler, NULL, "S", window, tinfo)); 9245 } 9246 9247 return SVN_NO_ERROR; 9248} 9249 9250static svn_error_t * 9251thunk_apply_textdelta(void *file_baton, 9252 const char *base_checksum, 9253 apr_pool_t *pool, 9254 svn_txdelta_window_handler_t *handler, 9255 void **h_baton) 9256{ 9257 item_baton *ib = file_baton; 9258 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9259 SV *result; 9260 9261 SVN_ERR (perl_callback_thunk (CALL_METHOD, 9262 (void *)"apply_textdelta", &result, 9263 "OOsS", ib->editor, ib->baton, base_checksum, 9264 pool, poolinfo)); 9265 if (SvOK(result)) { 9266 if (SvROK(result) && SvTYPE(SvRV(result)) == SVt_PVAV) { 9267 swig_type_info *handler_info = SWIG_TypeQuery("svn_txdelta_window_handler_t"), *void_info = SWIG_TypeQuery("void *"); 9268 AV *array = (AV *)SvRV(result); 9269 9270 if (SWIG_ConvertPtr(*av_fetch (array, 0, 0), 9271 (void **)handler, handler_info,0) < 0) { 9272 croak("FOO!"); 9273 } 9274 if (SWIG_ConvertPtr(*av_fetch (array, 1, 0), 9275 h_baton, void_info,0) < 0) { 9276 croak("FOO!"); 9277 } 9278 } 9279 else { 9280 *handler = thunk_window_handler; 9281 *h_baton = result; 9282 } 9283 } 9284 else { 9285 *handler = svn_delta_noop_window_handler; 9286 *h_baton = NULL; 9287 } 9288 9289 return SVN_NO_ERROR; 9290} 9291 9292static svn_error_t * thunk_change_file_prop(void *file_baton, 9293 const char *name, 9294 const svn_string_t *value, 9295 apr_pool_t *pool) 9296{ 9297 item_baton *ib = file_baton; 9298 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9299 9300 SVN_ERR (perl_callback_thunk (CALL_METHOD, 9301 (void *)"change_file_prop", NULL, 9302 "OOssS", ib->editor, ib->baton, name, 9303 value ? value->data : NULL, 9304 pool, poolinfo)); 9305 9306 return SVN_NO_ERROR; 9307} 9308 9309static svn_error_t * thunk_close_file(void *file_baton, 9310 const char *text_checksum, 9311 apr_pool_t *pool) 9312{ 9313 item_baton *ib = file_baton; 9314 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9315 9316 SVN_ERR (perl_callback_thunk (CALL_METHOD, 9317 (void *)"close_file", NULL, "OOsS", 9318 ib->editor, ib->baton, text_checksum, 9319 pool, poolinfo)); 9320 9321 SvREFCNT_dec(ib->editor); 9322 SvREFCNT_dec(ib->baton); 9323 9324#ifdef SVN_DEBUG 9325 ib->editor = ib->baton = NULL; 9326#endif 9327 9328 return SVN_NO_ERROR; 9329} 9330 9331static svn_error_t * thunk_absent_file(const char *path, 9332 void *parent_baton, 9333 apr_pool_t *pool) 9334{ 9335 item_baton *ib = parent_baton; 9336 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9337 9338 SVN_ERR (perl_callback_thunk (CALL_METHOD, 9339 (void *)"absent_file", NULL, 9340 "OsOS", ib->editor, path, ib->baton, 9341 pool, poolinfo)); 9342 9343 return SVN_NO_ERROR; 9344} 9345 9346static svn_error_t * thunk_close_edit(void *edit_baton, 9347 apr_pool_t *pool) 9348{ 9349 return close_baton(edit_baton, "close_edit"); 9350} 9351 9352static svn_error_t * thunk_abort_edit(void *edit_baton, 9353 apr_pool_t *pool) 9354{ 9355 return close_baton(edit_baton, "abort_edit"); 9356} 9357 9358void svn_delta_make_editor(svn_delta_editor_t **editor, 9359 void **edit_baton, 9360 SV *perl_editor, 9361 apr_pool_t *pool) 9362{ 9363 svn_delta_editor_t *thunk_editor = svn_delta_default_editor (pool); 9364 9365 thunk_editor->set_target_revision = thunk_set_target_revision; 9366 thunk_editor->open_root = thunk_open_root; 9367 thunk_editor->delete_entry = thunk_delete_entry; 9368 thunk_editor->add_directory = thunk_add_directory; 9369 thunk_editor->open_directory = thunk_open_directory; 9370 thunk_editor->change_dir_prop = thunk_change_dir_prop; 9371 thunk_editor->close_directory = thunk_close_directory; 9372 thunk_editor->absent_directory = thunk_absent_directory; 9373 thunk_editor->add_file = thunk_add_file; 9374 thunk_editor->open_file = thunk_open_file; 9375 thunk_editor->apply_textdelta = thunk_apply_textdelta; 9376 thunk_editor->change_file_prop = thunk_change_file_prop; 9377 thunk_editor->close_file = thunk_close_file; 9378 thunk_editor->absent_file = thunk_absent_file; 9379 thunk_editor->close_edit = thunk_close_edit; 9380 thunk_editor->abort_edit = thunk_abort_edit; 9381 9382 *editor = thunk_editor; 9383 *edit_baton = make_baton(pool, perl_editor, NULL); 9384} 9385 9386svn_error_t *svn_swig_pl_thunk_log_receiver(void *baton, 9387 apr_hash_t *changed_paths, 9388 svn_revnum_t rev, 9389 const char *author, 9390 const char *date, 9391 const char *msg, 9392 apr_pool_t *pool) 9393{ 9394 SV *receiver = baton, *result; 9395 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9396 swig_type_info *tinfo = SWIG_TypeQuery("svn_log_changed_path_t *"); 9397 9398 if (!SvOK(receiver)) 9399 return SVN_NO_ERROR; 9400 9401 perl_callback_thunk (CALL_SV, 9402 receiver, &result, 9403 "OisssS", (changed_paths) ? 9404 svn_swig_pl_convert_hash(changed_paths, tinfo) 9405 : &PL_sv_undef, 9406 rev, author, date, msg, pool, poolinfo); 9407 9408 return SVN_NO_ERROR; 9409} 9410 9411svn_error_t *svn_swig_pl_thunk_history_func(void *baton, 9412 const char *path, 9413 svn_revnum_t revision, 9414 apr_pool_t *pool) 9415{ 9416 SV *func = baton; 9417 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9418 9419 if (!SvOK(func)) 9420 return SVN_NO_ERROR; 9421 9422 perl_callback_thunk (CALL_SV, 9423 func, NULL, 9424 "siS", path, revision, pool, poolinfo); 9425 9426 return SVN_NO_ERROR; 9427} 9428 9429svn_error_t *svn_swig_pl_thunk_authz_func (svn_boolean_t *allowed, 9430 svn_fs_root_t *root, 9431 const char *path, 9432 void *baton, 9433 apr_pool_t *pool) 9434{ 9435 SV *func = baton, *result; 9436 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9437 swig_type_info *rootinfo = SWIG_TypeQuery("svn_fs_root_t *"); 9438 9439 if (!SvOK(func)) 9440 return SVN_NO_ERROR; 9441 9442 perl_callback_thunk (CALL_SV, 9443 func, &result, 9444 "SsS", root, rootinfo, path, pool, poolinfo); 9445 9446 *allowed = SvIV (result); 9447 9448 return SVN_NO_ERROR; 9449} 9450 9451svn_error_t *svn_swig_pl_thunk_commit_callback(svn_revnum_t new_revision, 9452 const char *date, 9453 const char *author, 9454 void *baton) 9455{ 9456 if (!SvOK((SV *)baton)) 9457 return SVN_NO_ERROR; 9458 9459 perl_callback_thunk (CALL_SV, baton, NULL, 9460 "iss", new_revision, date, author); 9461 9462 return SVN_NO_ERROR; 9463} 9464 9465/* Wrap RA */ 9466 9467static svn_error_t * thunk_open_tmp_file(apr_file_t **fp, 9468 void *callback_baton, 9469 apr_pool_t *pool) 9470{ 9471 SV *result; 9472 swig_type_info *tinfo = SWIG_TypeQuery("apr_file_t *"); 9473 9474 perl_callback_thunk (CALL_METHOD, (void *)"open_tmp_file", 9475 &result, "O", callback_baton); 9476 9477 if (SWIG_ConvertPtr(result, (void *)fp, tinfo,0) < 0) { 9478 croak("ouch"); 9479 } 9480 9481 return SVN_NO_ERROR; 9482} 9483 9484svn_error_t *thunk_get_wc_prop (void *baton, 9485 const char *relpath, 9486 const char *name, 9487 const svn_string_t **value, 9488 apr_pool_t *pool) 9489{ 9490 SV *result; 9491 swig_type_info *tinfo = SWIG_TypeQuery("apr_pool_t *"); 9492 9493 perl_callback_thunk (CALL_METHOD, (void *)"get_wc_prop", 9494 &result, "OssS", baton, relpath, name, pool, tinfo); 9495 9496 /* this is svn_string_t * typemap in */ 9497 if (!SvOK (result) || result == &PL_sv_undef) { 9498 *value = NULL; 9499 } 9500 else if (SvPOK(result)) { 9501 *value = svn_string_create (SvPV_nolen (result), pool); 9502 } 9503 else { 9504 croak("not a string"); 9505 } 9506 9507 return SVN_NO_ERROR; 9508} 9509 9510 9511svn_error_t *svn_ra_make_callbacks(svn_ra_callbacks_t **cb, 9512 void **c_baton, 9513 SV *perl_callbacks, 9514 apr_pool_t *pool) 9515{ 9516 swig_type_info *tinfo = SWIG_TypeQuery("svn_auth_baton_t *"); 9517 SV *auth_baton; 9518 9519 *cb = apr_pcalloc (pool, sizeof(**cb)); 9520 9521 (*cb)->open_tmp_file = thunk_open_tmp_file; 9522 (*cb)->get_wc_prop = thunk_get_wc_prop; 9523 (*cb)->set_wc_prop = NULL; 9524 (*cb)->push_wc_prop = NULL; 9525 (*cb)->invalidate_wc_props = NULL; 9526 auth_baton = *hv_fetch((HV *)SvRV(perl_callbacks), "auth", 4, 0); 9527 9528 if (SWIG_ConvertPtr(auth_baton, (void **)&(*cb)->auth_baton, tinfo,0) < 0) { 9529 croak("ouch"); 9530 } 9531 *c_baton = perl_callbacks; 9532 SvREFCNT_inc(perl_callbacks); 9533 9534 return SVN_NO_ERROR; 9535} 9536 9537svn_error_t *svn_swig_pl_thunk_simple_prompt(svn_auth_cred_simple_t **cred, 9538 void *baton, 9539 const char *realm, 9540 const char *username, 9541 svn_boolean_t may_save, 9542 apr_pool_t *pool) 9543{ 9544 SV *result; 9545 swig_type_info *poolinfo = SWIG_TypeQuery ("apr_pool_t *"); 9546 swig_type_info *credinfo = SWIG_TypeQuery ("svn_auth_cred_simple_t *"); 9547 9548 /* Be nice and allocate the memory for the cred structure before passing it 9549 * off to the perl space */ 9550 *cred = apr_pcalloc (pool, sizeof (**cred)); 9551 if (!*cred) { 9552 croak ("Could not allocate memory for cred structure"); 9553 } 9554 perl_callback_thunk (CALL_SV, 9555 baton, &result, 9556 "SssiS", *cred, credinfo, 9557 realm, username, may_save, pool, poolinfo); 9558 9559 return SVN_NO_ERROR; 9560} 9561 9562svn_error_t *svn_swig_pl_thunk_username_prompt(svn_auth_cred_username_t **cred, 9563 void *baton, 9564 const char *realm, 9565 svn_boolean_t may_save, 9566 apr_pool_t *pool) 9567{ 9568 SV *result; 9569 swig_type_info *poolinfo = SWIG_TypeQuery ("apr_pool_t *"); 9570 swig_type_info *credinfo = SWIG_TypeQuery ("svn_auth_cred_username_t *"); 9571 9572 /* Be nice and allocate the memory for the cred structure before passing it 9573 * off to the perl space */ 9574 *cred = apr_pcalloc (pool, sizeof (**cred)); 9575 if (!*cred) { 9576 croak ("Could not allocate memory for cred structure"); 9577 } 9578 perl_callback_thunk (CALL_SV, 9579 baton, &result, 9580 "SsiS", *cred, credinfo, 9581 realm, may_save, pool, poolinfo); 9582 9583 return SVN_NO_ERROR; 9584} 9585 9586svn_error_t *svn_swig_pl_thunk_ssl_server_trust_prompt( 9587 svn_auth_cred_ssl_server_trust_t **cred, 9588 void *baton, 9589 const char *realm, 9590 apr_uint32_t failures, 9591 const svn_auth_ssl_server_cert_info_t *cert_info, 9592 svn_boolean_t may_save, 9593 apr_pool_t *pool) 9594{ 9595 SV *result; 9596 swig_type_info *poolinfo = SWIG_TypeQuery ("apr_pool_t *"); 9597 swig_type_info *credinfo = SWIG_TypeQuery ( 9598 "svn_auth_cred_ssl_server_trust_t *"); 9599 swig_type_info *cert_info_info = SWIG_TypeQuery ( 9600 "svn_auth_ssl_server_cert_info_t *"); 9601 9602 /* Be nice and allocate the memory for the cred structure before passing it 9603 * off to the perl space */ 9604 *cred = apr_pcalloc (pool, sizeof (**cred)); 9605 if (!*cred) { 9606 croak ("Could not allocate memory for cred structure"); 9607 } 9608 perl_callback_thunk (CALL_SV, 9609 baton, &result, 9610 "SsiSiS", *cred, credinfo, 9611 realm, failures, 9612 cert_info, cert_info_info, 9613 may_save, pool, poolinfo); 9614 9615 /* Allow the perl callback to indicate failure by setting all vars to 0 9616 * or by simply doing nothing. While still allowing them to indicate 9617 * failure by setting the cred strucutre's pointer to 0 via $$cred = 0 */ 9618 if (*cred) { 9619 if ((*cred)->may_save == 0 && (*cred)->accepted_failures == 0) { 9620 *cred = NULL; 9621 } 9622 } 9623 9624 return SVN_NO_ERROR; 9625} 9626 9627svn_error_t *svn_swig_pl_thunk_ssl_client_cert_prompt( 9628 svn_auth_cred_ssl_client_cert_t **cred, 9629 void *baton, 9630 const char * realm, 9631 svn_boolean_t may_save, 9632 apr_pool_t *pool) 9633{ 9634 SV *result; 9635 swig_type_info *poolinfo = SWIG_TypeQuery ("apr_pool_t *"); 9636 swig_type_info *credinfo = SWIG_TypeQuery ( 9637 "svn_auth_cred_ssl_client_cert_t *"); 9638 9639 /* Be nice and allocate the memory for the cred structure before passing it 9640 * off to the perl space */ 9641 *cred = apr_pcalloc (pool, sizeof (**cred)); 9642 if (!*cred) { 9643 croak ("Could not allocate memory for cred structure"); 9644 } 9645 perl_callback_thunk (CALL_SV, 9646 baton, &result, 9647 "SsiS", *cred, credinfo, 9648 realm, may_save, pool, poolinfo); 9649 9650 return SVN_NO_ERROR; 9651} 9652 9653svn_error_t *svn_swig_pl_thunk_ssl_client_cert_pw_prompt( 9654 svn_auth_cred_ssl_client_cert_pw_t **cred, 9655 void *baton, 9656 const char *realm, 9657 svn_boolean_t may_save, 9658 apr_pool_t *pool) 9659{ 9660 SV *result; 9661 swig_type_info *poolinfo = SWIG_TypeQuery ("apr_pool_t *"); 9662 swig_type_info *credinfo = SWIG_TypeQuery ( 9663 "svn_auth_cred_ssl_client_cert_pw_t *"); 9664 9665 /* Be nice and allocate the memory for the cred structure before passing it 9666 * off to the perl space */ 9667 *cred = apr_pcalloc (pool, sizeof (**cred)); 9668 if (!*cred) { 9669 croak ("Could not allocate memory for cred structure"); 9670 } 9671 perl_callback_thunk (CALL_SV, 9672 baton, &result, 9673 "SsiS", *cred, credinfo, 9674 realm, may_save, pool, poolinfo); 9675 9676 return SVN_NO_ERROR; 9677} 9678 9679/* default pool support */ 9680apr_pool_t *current_pool; 9681 9682apr_pool_t *svn_swig_pl_make_pool (SV *obj) 9683{ 9684 apr_pool_t *pool; 9685 9686 if (obj && sv_isobject (obj)) { 9687 swig_type_info *poolinfo = SWIG_TypeQuery("apr_pool_t *"); 9688 if (sv_derived_from (obj, "SVN::Pool")) { 9689 obj = SvRV(obj); 9690 } 9691 if (sv_derived_from(obj, "_p_apr_pool_t")) { 9692 SWIG_ConvertPtr(obj, (void **)&pool, poolinfo, 0); 9693 return pool; 9694 } 9695 } 9696 9697 if (!current_pool) 9698 perl_callback_thunk (CALL_METHOD, (void *)"new_default", 9699 &obj, "s", "SVN::Pool"); 9700 pool = current_pool; 9701 9702 return pool; 9703} 9704 9705/* stream interpolability with io::handle */ 9706 9707typedef struct { 9708 SV *obj; 9709 IO *io; 9710} io_baton_t; 9711 9712static svn_error_t *io_handle_read (void *baton, 9713 char *buffer, 9714 apr_size_t *len) 9715{ 9716 io_baton_t *io = baton; 9717 MAGIC *mg; 9718 9719 if ((mg = SvTIED_mg((SV*)io->io, PERL_MAGIC_tiedscalar))) { 9720 SV *ret; 9721 SV *buf = sv_newmortal(); 9722 perl_callback_thunk (CALL_METHOD, (void *)"READ", &ret, "OOi", 9723 SvTIED_obj((SV*)io->io, mg), 9724 buf, *len); 9725 *len = SvIV (ret); 9726 memmove (buffer, SvPV_nolen(buf), *len); 9727 } 9728 else 9729 *len = PerlIO_read (IoIFP (io->io), buffer, *len); 9730 return SVN_NO_ERROR; 9731} 9732 9733static svn_error_t *io_handle_write (void *baton, 9734 const char *data, 9735 apr_size_t *len) 9736{ 9737 io_baton_t *io = baton; 9738 MAGIC *mg; 9739 9740 if ((mg = SvTIED_mg((SV*)io->io, PERL_MAGIC_tiedscalar))) { 9741 SV *ret, *pv; 9742 pv = sv_2mortal (newSVpvn (data, *len)); 9743 perl_callback_thunk (CALL_METHOD, (void *)"WRITE", &ret, "OOi", 9744 SvTIED_obj((SV*)io->io, mg), pv, *len); 9745 *len = SvIV (ret); 9746 } 9747 else 9748 *len = PerlIO_write (IoIFP (io->io), data, *len); 9749 return SVN_NO_ERROR; 9750} 9751 9752static svn_error_t *io_handle_close (void *baton) 9753{ 9754 io_baton_t *io = baton; 9755 MAGIC *mg; 9756 9757 if ((mg = SvTIED_mg((SV*)io->io, PERL_MAGIC_tiedscalar))) { 9758 perl_callback_thunk (CALL_METHOD, (void *)"CLOSE", NULL, "O", 9759 SvTIED_obj((SV*)io->io, mg)); 9760 } 9761 else { 9762 PerlIO_close (IoIFP (io->io)); 9763 } 9764 9765 return SVN_NO_ERROR; 9766} 9767 9768static apr_status_t io_handle_cleanup (void *baton) 9769{ 9770 io_baton_t *io = baton; 9771 SvREFCNT_dec (io->obj); 9772 return APR_SUCCESS; 9773} 9774 9775svn_error_t *svn_swig_pl_make_stream (svn_stream_t **stream, SV *obj) 9776{ 9777 swig_type_info *tinfo = SWIG_TypeQuery("svn_stream_t *"); 9778 IO *io; 9779 int simple_type = 1; 9780 9781 if (!SvOK (obj)) { 9782 *stream = NULL; 9783 return SVN_NO_ERROR; 9784 } 9785 9786 if (obj && sv_isobject(obj)) { 9787 if (sv_derived_from (obj, "SVN::Stream")) 9788 perl_callback_thunk (CALL_METHOD, (void *)"svn_stream", 9789 &obj, "O", obj); 9790 else if (!sv_derived_from(obj, "_p_svn_stream_t")) 9791 simple_type = 0; 9792 9793 if (simple_type) { 9794 SWIG_ConvertPtr(obj, (void **)stream, tinfo, 0); 9795 return SVN_NO_ERROR; 9796 } 9797 } 9798 9799 if (obj && SvROK(obj) && SvTYPE(SvRV(obj)) == SVt_PVGV && 9800 (io = GvIO(SvRV(obj)))) { 9801 apr_pool_t *pool = current_pool; 9802 io_baton_t *iob = apr_palloc (pool, sizeof(io_baton_t)); 9803 SvREFCNT_inc (obj); 9804 iob->obj = obj; 9805 iob->io = io; 9806 *stream = svn_stream_create (iob, pool); 9807 svn_stream_set_read (*stream, io_handle_read); 9808 svn_stream_set_write (*stream, io_handle_write); 9809 svn_stream_set_close (*stream, io_handle_close); 9810 apr_pool_cleanup_register (pool, iob, io_handle_cleanup, 9811 io_handle_cleanup); 9812 9813 } 9814 else 9815 croak ("unknown type for svn_stream_t"); 9816 9817 return SVN_NO_ERROR; 9818} 9819 9820SV *svn_swig_pl_from_stream (svn_stream_t *stream) 9821{ 9822 swig_type_info *tinfo = SWIG_TypeQuery("svn_stream_t *"); 9823 SV *ret; 9824 9825 perl_callback_thunk (CALL_METHOD, (void *)"new", &ret, "sS", 9826 "SVN::Stream", stream, tinfo); 9827 9828 return sv_2mortal (ret); 9829} 9830 9831apr_file_t *svn_swig_pl_make_file (SV *file, apr_pool_t *pool) 9832{ 9833 apr_file_t *apr_file = NULL; 9834 9835 if (!SvOK(file) || file == &PL_sv_undef) 9836 return NULL; 9837 9838 if (SvPOKp(file)) { 9839 apr_file_open(&apr_file, SvPV_nolen(file), 9840 APR_CREATE | APR_READ | APR_WRITE, 9841 APR_OS_DEFAULT, 9842 pool); 9843 } else if (SvROK(file) && SvTYPE(SvRV(file)) == SVt_PVGV) { 9844 apr_status_t status; 9845 apr_os_file_t osfile = PerlIO_fileno(IoIFP(sv_2io(file))); 9846 status = apr_os_file_put (&apr_file, &osfile, O_CREAT | O_WRONLY, pool); 9847 if (status) 9848 return NULL; 9849 } 9850 return apr_file; 9851} 9852 9853 9854Node-path: svnperl/swigutil_pl.h 9855Node-kind: file 9856Node-action: add 9857Prop-content-length: 10 9858Text-content-length: 7631 9859Text-content-md5: 0c8d33bcb42fb6359587ee385a96e520 9860Content-length: 7641 9861 9862PROPS-END 9863/* 9864 * swigutil_pl.h : utility functions and stuff for the SWIG Perl bindings 9865 * 9866 * ==================================================================== 9867 * Copyright (c) 2000-2004 CollabNet. All rights reserved. 9868 * 9869 * This software is licensed as described in the file COPYING, which 9870 * you should have received as part of this distribution. The terms 9871 * are also available at http://subversion.tigris.org/license-1.html. 9872 * If newer versions of this license are posted there, you may use a 9873 * newer version instead, at your option. 9874 * 9875 * This software consists of voluntary contributions made by many 9876 * individuals. For exact contribution history, see the revision 9877 * history and logs, available at http://subversion.tigris.org/. 9878 * ==================================================================== 9879 */ 9880 9881 9882#ifndef SVN_SWIG_SWIGUTIL_PL_H 9883#define SVN_SWIG_SWIGUTIL_PL_H 9884 9885#include <EXTERN.h> 9886#include <perl.h> 9887#include <XSUB.h> 9888 9889#include <apr.h> 9890#include <apr_pools.h> 9891#include <apr_strings.h> 9892#include <apr_hash.h> 9893#include <apr_tables.h> 9894 9895#include "svn_types.h" 9896#include "svn_string.h" 9897#include "svn_delta.h" 9898#include "svn_client.h" 9899#include "svn_repos.h" 9900 9901#ifdef __cplusplus 9902extern "C" { 9903#endif /* __cplusplus */ 9904 9905 9906/* If this file is being included outside of a wrapper file, then need to 9907 create stubs for some of the SWIG types. */ 9908 9909/* if SWIGEXPORT is defined, then we're in a wrapper. otherwise, we need 9910 the prototypes and type definitions. */ 9911#ifndef SWIGEXPORT 9912#define SVN_NEED_SWIG_TYPES 9913#endif 9914 9915#ifdef SVN_NEED_SWIG_TYPES 9916 9917/* XXX: this has to be set by configure and also swig -swiglib needs 9918 to be added to include paths. 9919*/ 9920#if SWIG_VERSION >= 0x010320 9921#include "perl5/precommon.swg" 9922#endif 9923 9924typedef struct _unnamed swig_type_info; 9925 9926swig_type_info *SWIG_TypeQuery(const char *name); 9927int SWIG_ConvertPtr(SV *, void **, swig_type_info *, int flags); 9928void SWIG_MakePtr(SV *, void *, swig_type_info *, int flags); 9929 9930#endif /* SVN_NEED_SWIG_TYPES */ 9931 9932extern apr_pool_t *current_pool; 9933apr_pool_t *svn_swig_pl_make_pool (SV *obj); 9934 9935SV *svn_swig_pl_prophash_to_hash (apr_hash_t *hash); 9936SV *svn_swig_pl_convert_hash (apr_hash_t *hash, swig_type_info *tinfo); 9937 9938const apr_array_header_t *svn_swig_pl_strings_to_array(SV *source, 9939 apr_pool_t *pool); 9940 9941apr_hash_t *svn_swig_pl_strings_to_hash(SV *source, 9942 apr_pool_t *pool); 9943apr_hash_t *svn_swig_pl_objs_to_hash(SV *source, swig_type_info *tinfo, 9944 apr_pool_t *pool); 9945apr_hash_t *svn_swig_pl_objs_to_hash_by_name(SV *source, 9946 const char *typename, 9947 apr_pool_t *pool); 9948const apr_array_header_t *svn_swig_pl_objs_to_array(SV *source, 9949 swig_type_info *tinfo, 9950 apr_pool_t *pool); 9951 9952SV *svn_swig_pl_array_to_list(const apr_array_header_t *array); 9953SV *svn_swig_pl_ints_to_list(const apr_array_header_t *array); 9954 9955/* thunked log receiver function. */ 9956svn_error_t * svn_swig_pl_thunk_log_receiver(void *py_receiver, 9957 apr_hash_t *changed_paths, 9958 svn_revnum_t rev, 9959 const char *author, 9960 const char *date, 9961 const char *msg, 9962 apr_pool_t *pool); 9963/* thunked commit editor callback. */ 9964svn_error_t *svn_swig_pl_thunk_commit_callback(svn_revnum_t new_revision, 9965 const char *date, 9966 const char *author, 9967 void *baton); 9968 9969/* thunked repos_history callback. */ 9970svn_error_t *svn_swig_pl_thunk_history_func(void *baton, 9971 const char *path, 9972 svn_revnum_t revision, 9973 apr_pool_t *pool); 9974 9975/* thunked dir_delta authz read function. */ 9976svn_error_t *svn_swig_pl_thunk_authz_func (svn_boolean_t *allowed, 9977 svn_fs_root_t *root, 9978 const char *path, 9979 void *baton, 9980 apr_pool_t *pool); 9981 9982/* ra callbacks. */ 9983svn_error_t *svn_ra_make_callbacks(svn_ra_callbacks_t **cb, 9984 void **c_baton, 9985 SV *perl_callbacks, 9986 apr_pool_t *pool); 9987 9988/* thunked simple_prompt callback function */ 9989svn_error_t *svn_swig_pl_thunk_simple_prompt (svn_auth_cred_simple_t **cred, 9990 void *baton, 9991 const char *realm, 9992 const char *username, 9993 svn_boolean_t may_save, 9994 apr_pool_t *pool); 9995 9996/* thunked username_prompt callback function */ 9997svn_error_t *svn_swig_pl_thunk_username_prompt (svn_auth_cred_username_t **cred, 9998 void *baton, 9999 const char *realm, 10000 svn_boolean_t may_save, 10001 apr_pool_t *pool); 10002 10003/* thunked ssl_server_trust_prompt callback function */ 10004svn_error_t *svn_swig_pl_thunk_ssl_server_trust_prompt( 10005 svn_auth_cred_ssl_server_trust_t **cred, 10006 void *baton, 10007 const char *realm, 10008 apr_uint32_t failures, 10009 const svn_auth_ssl_server_cert_info_t *cert_info, 10010 svn_boolean_t may_save, 10011 apr_pool_t *pool); 10012 10013/* thunked ssl_client_cert callback function */ 10014svn_error_t *svn_swig_pl_thunk_ssl_client_cert_prompt ( 10015 svn_auth_cred_ssl_client_cert_t **cred, 10016 void *baton, 10017 const char *realm, 10018 svn_boolean_t may_save, 10019 apr_pool_t *pool); 10020 10021/* thunked ssl_client_cert_pw callback function */ 10022svn_error_t *svn_swig_pl_thunk_ssl_client_cert_pw_prompt ( 10023 svn_auth_cred_ssl_client_cert_pw_t **cred, 10024 void *baton, 10025 const char *realm, 10026 svn_boolean_t may_save, 10027 apr_pool_t *pool); 10028 10029/* thunked callback for svn_ra_get_wc_prop_func_t */ 10030svn_error_t *thunk_get_wc_prop (void *baton, 10031 const char *relpath, 10032 const char *name, 10033 const svn_string_t **value, 10034 apr_pool_t *pool); 10035 10036/* helper for making the editor */ 10037void svn_delta_make_editor(svn_delta_editor_t **editor, 10038 void **edit_baton, 10039 SV *perl_editor, 10040 apr_pool_t *pool); 10041 10042/* svn_stream_t helpers */ 10043svn_error_t *svn_swig_pl_make_stream (svn_stream_t **stream, SV *obj); 10044SV *svn_swig_pl_from_stream (svn_stream_t *stream); 10045 10046/* apr_file_t * */ 10047apr_file_t *svn_swig_pl_make_file (SV *file, apr_pool_t *pool); 10048 10049 10050#ifdef __cplusplus 10051} 10052#endif /* __cplusplus */ 10053 10054#endif /* SVN_SWIG_SWIGUTIL_PL_H */ 10055 10056 10057Node-path: svnperl/swigutil_py.c 10058Node-kind: file 10059Node-action: add 10060Prop-content-length: 10 10061Text-content-length: 34414 10062Text-content-md5: 4de4897430543d70e6dfc050bf151488 10063Content-length: 34424 10064 10065PROPS-END 10066/* 10067 * swigutil_py.c: utility functions for the SWIG Python bindings 10068 * 10069 * ==================================================================== 10070 * Copyright (c) 2000-2004 CollabNet. All rights reserved. 10071 * 10072 * This software is licensed as described in the file COPYING, which 10073 * you should have received as part of this distribution. The terms 10074 * are also available at http://subversion.tigris.org/license-1.html. 10075 * If newer versions of this license are posted there, you may use a 10076 * newer version instead, at your option. 10077 * 10078 * This software consists of voluntary contributions made by many 10079 * individuals. For exact contribution history, see the revision 10080 * history and logs, available at http://subversion.tigris.org/. 10081 * ==================================================================== 10082 */ 10083 10084 10085#include <Python.h> 10086 10087#include <sys/types.h> 10088#include <sys/stat.h> 10089#include <fcntl.h> 10090 10091#include <apr_pools.h> 10092#include <apr_hash.h> 10093#include <apr_portable.h> 10094#include <apr_thread_proc.h> 10095 10096#include "svn_string.h" 10097#include "svn_opt.h" 10098#include "svn_delta.h" 10099 10100#include "swigutil_py.h" 10101 10102 10103 10104/*** Manage the Global Interpreter Lock ***/ 10105 10106/* If both Python and APR have threads available, we can optimize ourselves 10107 * by releasing the global interpreter lock when we drop into our SVN calls. 10108 * 10109 * In svn_types.i, svn_swig_py_release_py_lock is called before every 10110 * function, then svn_swig_py_acquire_py_lock is called after every 10111 * function. So, if these functions become no-ops, then Python will 10112 * start to block... 10113 * 10114 * The Subversion libraries can be assumed to be thread-safe *only* when 10115 * APR_HAS_THREAD is 1. The APR pool allocations aren't thread-safe unless 10116 * APR_HAS_THREAD is 1. 10117 */ 10118 10119#if defined(WITH_THREAD) && APR_HAS_THREADS 10120#define ACQUIRE_PYTHON_LOCK 10121#endif 10122 10123#ifdef ACQUIRE_PYTHON_LOCK 10124static apr_threadkey_t *_saved_thread_key = NULL; 10125static apr_pool_t *_saved_thread_pool = NULL; 10126#endif 10127 10128void svn_swig_py_release_py_lock(void) 10129{ 10130#ifdef ACQUIRE_PYTHON_LOCK 10131 PyThreadState *thread_state; 10132 10133 if (_saved_thread_key == NULL) { 10134 10135 /* This is ugly. We call svn_swig_py_release_py_lock before executing any 10136 subversion function. Thus it gets called before any call to 10137 apr_initialize in our script. This means we have to call 10138 apr_initialize ourselves, or otherwise we won't be able to 10139 create our pool. */ 10140 apr_initialize(); 10141 10142 /* Obviously, creating a top-level pool for this is pretty stupid. */ 10143 apr_pool_create(&_saved_thread_pool, NULL); 10144 apr_threadkey_private_create(&_saved_thread_key, NULL, _saved_thread_pool); 10145 } 10146 10147 thread_state = PyEval_SaveThread(); 10148 apr_threadkey_private_set(thread_state, _saved_thread_key); 10149#endif 10150} 10151 10152void svn_swig_py_acquire_py_lock(void) 10153{ 10154#ifdef ACQUIRE_PYTHON_LOCK 10155 void *val; 10156 PyThreadState *thread_state; 10157 apr_threadkey_private_get(&val, _saved_thread_key); 10158 thread_state = val; 10159 PyEval_RestoreThread(thread_state); 10160#endif 10161} 10162 10163 10164 10165/*** Custom SubversionException stuffs. ***/ 10166 10167/* Global SubversionException class object. */ 10168static PyObject *SubversionException = NULL; 10169 10170 10171PyObject *svn_swig_py_exception_type(void) 10172{ 10173 Py_INCREF(SubversionException); 10174 return SubversionException; 10175} 10176 10177PyObject *svn_swig_py_register_exception(void) 10178{ 10179 /* If we haven't created our exception class, do so. */ 10180 if (SubversionException == NULL) 10181 { 10182 SubversionException = PyErr_NewException 10183 ((char *)"libsvn._core.SubversionException", NULL, NULL); 10184 } 10185 10186 /* Regardless, return the exception class. */ 10187 return svn_swig_py_exception_type(); 10188} 10189 10190void svn_swig_py_svn_exception(svn_error_t *err) 10191{ 10192 PyObject *exc_ob, *apr_err_ob; 10193 10194 if (err == NULL) 10195 return; 10196 10197 /* Make an integer for the error code. */ 10198 apr_err_ob = PyInt_FromLong(err->apr_err); 10199 if (apr_err_ob == NULL) 10200 return; 10201 10202 /* Instantiate a SubversionException object. */ 10203 exc_ob = PyObject_CallFunction(SubversionException, (char *)"sO", 10204 err->message, apr_err_ob); 10205 if (exc_ob == NULL) 10206 { 10207 Py_DECREF(apr_err_ob); 10208 return; 10209 } 10210 10211 /* Set the "apr_err" attribute of the exception to our error code. */ 10212 if (PyObject_SetAttrString(exc_ob, (char *)"apr_err", apr_err_ob) == -1) 10213 { 10214 Py_DECREF(apr_err_ob); 10215 Py_DECREF(exc_ob); 10216 return; 10217 } 10218 10219 /* Finished with the apr_err object. */ 10220 Py_DECREF(apr_err_ob); 10221 10222 /* Set the error state to our exception object. */ 10223 PyErr_SetObject(SubversionException, exc_ob); 10224 10225 /* Finished with the exc_ob object. */ 10226 Py_DECREF(exc_ob); 10227} 10228 10229 10230 10231/*** Helper/Conversion Routines ***/ 10232 10233static PyObject *make_pointer(const char *typename, void *ptr) 10234{ 10235 /* ### cache the swig_type_info at some point? */ 10236 return SWIG_NewPointerObj(ptr, SWIG_TypeQuery(typename), 0); 10237} 10238 10239/* for use by the "O&" format specifier */ 10240static PyObject *make_ob_pool(void *ptr) 10241{ 10242 return make_pointer("apr_pool_t *", ptr); 10243} 10244 10245/* for use by the "O&" format specifier */ 10246static PyObject *make_ob_window(void *ptr) 10247{ 10248 return make_pointer("svn_txdelta_window_t *", ptr); 10249} 10250 10251/* for use by the "O&" format specifier */ 10252static PyObject *make_ob_status(void *ptr) 10253{ 10254 return make_pointer("svn_wc_status_t *", ptr); 10255} 10256 10257static PyObject *convert_hash(apr_hash_t *hash, 10258 PyObject * (*converter_func)(void *value, 10259 void *ctx), 10260 void *ctx) 10261{ 10262 apr_hash_index_t *hi; 10263 PyObject *dict = PyDict_New(); 10264 10265 if (dict == NULL) 10266 return NULL; 10267 10268 for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi)) { 10269 const void *key; 10270 void *val; 10271 PyObject *value; 10272 10273 apr_hash_this(hi, &key, NULL, &val); 10274 value = (*converter_func)(val, ctx); 10275 if (value == NULL) { 10276 Py_DECREF(dict); 10277 return NULL; 10278 } 10279 /* ### gotta cast this thing cuz Python doesn't use "const" */ 10280 if (PyDict_SetItemString(dict, (char *)key, value) == -1) { 10281 Py_DECREF(value); 10282 Py_DECREF(dict); 10283 return NULL; 10284 } 10285 Py_DECREF(value); 10286 } 10287 10288 return dict; 10289} 10290 10291static PyObject *convert_to_swigtype(void *value, void *ctx) 10292{ 10293 /* ctx is a 'swig_type_info *' */ 10294 return SWIG_NewPointerObj(value, ctx, 0); 10295} 10296 10297static PyObject *convert_svn_string_t(void *value, void *ctx) 10298{ 10299 /* ctx is unused */ 10300 10301 const svn_string_t *s = value; 10302 10303 /* ### borrowing from value in the pool. or should we copy? note 10304 ### that copying is "safest" */ 10305 10306 /* ### gotta cast this thing cuz Python doesn't use "const" */ 10307 return PyBuffer_FromMemory((void *)s->data, s->len); 10308} 10309 10310static PyObject *convert_svn_client_commit_item_t(void *value, void *ctx) 10311{ 10312 PyObject *list; 10313 PyObject *path, *kind, *url, *rev, *cf_url, *state; 10314 svn_client_commit_item_t *item = value; 10315 10316 /* ctx is unused */ 10317 10318 list = PyList_New(6); 10319 10320 if (item->path) 10321 path = PyString_FromString(item->path); 10322 else 10323 { 10324 path = Py_None; 10325 Py_INCREF(Py_None); 10326 } 10327 10328 if (item->url) 10329 url = PyString_FromString(item->url); 10330 else 10331 { 10332 url = Py_None; 10333 Py_INCREF(Py_None); 10334 } 10335 10336 if (item->copyfrom_url) 10337 cf_url = PyString_FromString(item->copyfrom_url); 10338 else 10339 { 10340 cf_url = Py_None; 10341 Py_INCREF(Py_None); 10342 } 10343 10344 kind = PyInt_FromLong(item->kind); 10345 rev = PyInt_FromLong(item->revision); 10346 state = PyInt_FromLong(item->state_flags); 10347 10348 if (! (list && path && kind && url && rev && cf_url && state)) 10349 { 10350 Py_XDECREF(list); 10351 Py_XDECREF(path); 10352 Py_XDECREF(kind); 10353 Py_XDECREF(url); 10354 Py_XDECREF(rev); 10355 Py_XDECREF(cf_url); 10356 Py_XDECREF(state); 10357 return NULL; 10358 } 10359 10360 PyList_SET_ITEM(list, 0, path); 10361 PyList_SET_ITEM(list, 1, kind); 10362 PyList_SET_ITEM(list, 2, url); 10363 PyList_SET_ITEM(list, 3, rev); 10364 PyList_SET_ITEM(list, 4, cf_url); 10365 PyList_SET_ITEM(list, 5, state); 10366 return list; 10367} 10368 10369PyObject *svn_swig_py_prophash_to_dict(apr_hash_t *hash) 10370{ 10371 return convert_hash(hash, convert_svn_string_t, NULL); 10372} 10373 10374PyObject *svn_swig_py_convert_hash(apr_hash_t *hash, swig_type_info *type) 10375{ 10376 return convert_hash(hash, convert_to_swigtype, type); 10377} 10378 10379PyObject *svn_swig_py_c_strings_to_list(char **strings) 10380{ 10381 PyObject *list = PyList_New(0); 10382 char *s; 10383 10384 while ((s = *strings++) != NULL) { 10385 PyObject *ob = PyString_FromString(s); 10386 10387 if (ob == NULL) 10388 goto error; 10389 if (PyList_Append(list, ob) == -1) 10390 goto error; 10391 } 10392 10393 return list; 10394 10395 error: 10396 Py_DECREF(list); 10397 return NULL; 10398} 10399 10400const apr_array_header_t *svn_swig_py_strings_to_array(PyObject *source, 10401 apr_pool_t *pool) 10402{ 10403 int targlen; 10404 apr_array_header_t *temp; 10405 10406 if (!PySequence_Check(source)) { 10407 PyErr_SetString(PyExc_TypeError, "not a sequence"); 10408 return NULL; 10409 } 10410 targlen = PySequence_Length(source); 10411 temp = apr_array_make(pool, targlen, sizeof(const char *)); 10412 /* APR_ARRAY_IDX doesn't actually increment the array item count 10413 (like, say, apr_array_push would). */ 10414 temp->nelts = targlen; 10415 while (targlen--) { 10416 PyObject *o = PySequence_GetItem(source, targlen); 10417 if (o == NULL) 10418 return NULL; 10419 if (!PyString_Check(o)) { 10420 Py_DECREF(o); 10421 PyErr_SetString(PyExc_TypeError, "not a string"); 10422 return NULL; 10423 } 10424 APR_ARRAY_IDX(temp, targlen, const char *) = PyString_AS_STRING(o); 10425 Py_DECREF(o); 10426 } 10427 return temp; 10428} 10429 10430 10431/*** apr_array_header_t conversions. To create a new type of 10432 converter, simply copy-n-paste one of these function and tweak 10433 the creation of the PyObject *ob. ***/ 10434 10435PyObject *svn_swig_py_array_to_list(const apr_array_header_t *array) 10436{ 10437 PyObject *list = PyList_New(array->nelts); 10438 int i; 10439 10440 for (i = 0; i < array->nelts; ++i) { 10441 PyObject *ob = 10442 PyString_FromString(APR_ARRAY_IDX(array, i, const char *)); 10443 if (ob == NULL) 10444 goto error; 10445 PyList_SET_ITEM(list, i, ob); 10446 } 10447 return list; 10448 10449 error: 10450 Py_DECREF(list); 10451 return NULL; 10452} 10453 10454PyObject *svn_swig_py_revarray_to_list(const apr_array_header_t *array) 10455{ 10456 PyObject *list = PyList_New(array->nelts); 10457 int i; 10458 10459 for (i = 0; i < array->nelts; ++i) { 10460 PyObject *ob 10461 = PyInt_FromLong(APR_ARRAY_IDX(array, i, svn_revnum_t)); 10462 if (ob == NULL) 10463 goto error; 10464 PyList_SET_ITEM(list, i, ob); 10465 } 10466 return list; 10467 10468 error: 10469 Py_DECREF(list); 10470 return NULL; 10471} 10472 10473static PyObject * 10474commit_item_array_to_list(const apr_array_header_t *array) 10475{ 10476 PyObject *list = PyList_New(array->nelts); 10477 int i; 10478 10479 for (i = 0; i < array->nelts; ++i) { 10480 PyObject *ob = convert_svn_client_commit_item_t 10481 (APR_ARRAY_IDX(array, i, svn_client_commit_item_t *), NULL); 10482 if (ob == NULL) 10483 goto error; 10484 PyList_SET_ITEM(list, i, ob); 10485 } 10486 return list; 10487 10488 error: 10489 Py_DECREF(list); 10490 return NULL; 10491} 10492 10493 10494static svn_error_t * convert_python_error(void) 10495{ 10496 return svn_error_create(SVN_ERR_SWIG_PY_EXCEPTION_SET, NULL, 10497 "The Python callback raised an exception"); 10498} 10499 10500 10501/*** Editor Wrapping ***/ 10502 10503/* this baton is used for the editor, directory, and file batons. */ 10504typedef struct { 10505 PyObject *editor; /* the editor handling the callbacks */ 10506 PyObject *baton; /* the dir/file baton (or NULL for edit baton) */ 10507} item_baton; 10508 10509static item_baton * make_baton(apr_pool_t *pool, 10510 PyObject *editor, PyObject *baton) 10511{ 10512 item_baton *newb = apr_palloc(pool, sizeof(*newb)); 10513 10514 /* one more reference to the editor. */ 10515 Py_INCREF(editor); 10516 10517 /* note: we take the caller's reference to 'baton' */ 10518 10519 newb->editor = editor; 10520 newb->baton = baton; 10521 10522 return newb; 10523} 10524 10525static svn_error_t * close_baton(void *baton, const char *method) 10526{ 10527 item_baton *ib = baton; 10528 PyObject *result; 10529 svn_error_t *err; 10530 10531 svn_swig_py_acquire_py_lock(); 10532 10533 /* If there is no baton object, then it is an edit_baton, and we should 10534 not bother to pass an object. Note that we still shove a NULL onto 10535 the stack, but the format specified just won't reference it. */ 10536 /* ### python doesn't have 'const' on the method name and format */ 10537 if ((result = PyObject_CallMethod(ib->editor, (char *)method, 10538 ib->baton ? (char *)"(O)" : NULL, 10539 ib->baton)) == NULL) 10540 { 10541 err = convert_python_error(); 10542 goto finished; 10543 } 10544 10545 /* there is no return value, so just toss this object (probably Py_None) */ 10546 Py_DECREF(result); 10547 10548 /* We're now done with the baton. Since there isn't really a free, all 10549 we need to do is note that its objects are no longer referenced by 10550 the baton. */ 10551 Py_DECREF(ib->editor); 10552 Py_XDECREF(ib->baton); 10553 10554#ifdef SVN_DEBUG 10555 ib->editor = ib->baton = NULL; 10556#endif 10557 10558 err = SVN_NO_ERROR; 10559 10560 finished: 10561 svn_swig_py_release_py_lock(); 10562 return err; 10563} 10564 10565static svn_error_t * thunk_set_target_revision(void *edit_baton, 10566 svn_revnum_t target_revision, 10567 apr_pool_t *pool) 10568{ 10569 item_baton *ib = edit_baton; 10570 PyObject *result; 10571 svn_error_t *err; 10572 10573 svn_swig_py_acquire_py_lock(); 10574 10575 /* ### python doesn't have 'const' on the method name and format */ 10576 if ((result = PyObject_CallMethod(ib->editor, (char *)"set_target_revision", 10577 (char *)"l", target_revision)) == NULL) 10578 { 10579 err = convert_python_error(); 10580 goto finished; 10581 } 10582 10583 /* there is no return value, so just toss this object (probably Py_None) */ 10584 Py_DECREF(result); 10585 err = SVN_NO_ERROR; 10586 10587 finished: 10588 svn_swig_py_release_py_lock(); 10589 return err; 10590} 10591 10592static svn_error_t * thunk_open_root(void *edit_baton, 10593 svn_revnum_t base_revision, 10594 apr_pool_t *dir_pool, 10595 void **root_baton) 10596{ 10597 item_baton *ib = edit_baton; 10598 PyObject *result; 10599 svn_error_t *err; 10600 10601 svn_swig_py_acquire_py_lock(); 10602 10603 /* ### python doesn't have 'const' on the method name and format */ 10604 if ((result = PyObject_CallMethod(ib->editor, (char *)"open_root", 10605 (char *)"lO&", base_revision, 10606 make_ob_pool, dir_pool)) == NULL) 10607 { 10608 err = convert_python_error(); 10609 goto finished; 10610 } 10611 10612 /* make_baton takes our 'result' reference */ 10613 *root_baton = make_baton(dir_pool, ib->editor, result); 10614 err = SVN_NO_ERROR; 10615 10616 finished: 10617 svn_swig_py_release_py_lock(); 10618 return err; 10619} 10620 10621static svn_error_t * thunk_delete_entry(const char *path, 10622 svn_revnum_t revision, 10623 void *parent_baton, 10624 apr_pool_t *pool) 10625{ 10626 item_baton *ib = parent_baton; 10627 PyObject *result; 10628 svn_error_t *err; 10629 10630 svn_swig_py_acquire_py_lock(); 10631 10632 /* ### python doesn't have 'const' on the method name and format */ 10633 if ((result = PyObject_CallMethod(ib->editor, (char *)"delete_entry", 10634 (char *)"slOO&", path, revision, ib->baton, 10635 make_ob_pool, pool)) == NULL) 10636 { 10637 err = convert_python_error(); 10638 goto finished; 10639 } 10640 10641 /* there is no return value, so just toss this object (probably Py_None) */ 10642 Py_DECREF(result); 10643 err = SVN_NO_ERROR; 10644 10645 finished: 10646 svn_swig_py_release_py_lock(); 10647 return err; 10648} 10649 10650static svn_error_t * thunk_add_directory(const char *path, 10651 void *parent_baton, 10652 const char *copyfrom_path, 10653 svn_revnum_t copyfrom_revision, 10654 apr_pool_t *dir_pool, 10655 void **child_baton) 10656{ 10657 item_baton *ib = parent_baton; 10658 PyObject *result; 10659 svn_error_t *err; 10660 10661 svn_swig_py_acquire_py_lock(); 10662 10663 /* ### python doesn't have 'const' on the method name and format */ 10664 if ((result = PyObject_CallMethod(ib->editor, (char *)"add_directory", 10665 (char *)"sOslO&", path, ib->baton, 10666 copyfrom_path, copyfrom_revision, 10667 make_ob_pool, dir_pool)) == NULL) 10668 { 10669 err = convert_python_error(); 10670 goto finished; 10671 } 10672 10673 /* make_baton takes our 'result' reference */ 10674 *child_baton = make_baton(dir_pool, ib->editor, result); 10675 err = SVN_NO_ERROR; 10676 10677 finished: 10678 svn_swig_py_release_py_lock(); 10679 return err; 10680} 10681 10682static svn_error_t * thunk_open_directory(const char *path, 10683 void *parent_baton, 10684 svn_revnum_t base_revision, 10685 apr_pool_t *dir_pool, 10686 void **child_baton) 10687{ 10688 item_baton *ib = parent_baton; 10689 PyObject *result; 10690 svn_error_t *err; 10691 10692 svn_swig_py_acquire_py_lock(); 10693 10694 /* ### python doesn't have 'const' on the method name and format */ 10695 if ((result = PyObject_CallMethod(ib->editor, (char *)"open_directory", 10696 (char *)"sOlO&", path, ib->baton, 10697 base_revision, 10698 make_ob_pool, dir_pool)) == NULL) 10699 { 10700 err = convert_python_error(); 10701 goto finished; 10702 } 10703 10704 /* make_baton takes our 'result' reference */ 10705 *child_baton = make_baton(dir_pool, ib->editor, result); 10706 err = SVN_NO_ERROR; 10707 10708 finished: 10709 svn_swig_py_release_py_lock(); 10710 return err; 10711} 10712 10713static svn_error_t * thunk_change_dir_prop(void *dir_baton, 10714 const char *name, 10715 const svn_string_t *value, 10716 apr_pool_t *pool) 10717{ 10718 item_baton *ib = dir_baton; 10719 PyObject *result; 10720 svn_error_t *err; 10721 10722 svn_swig_py_acquire_py_lock(); 10723 10724 /* ### python doesn't have 'const' on the method name and format */ 10725 if ((result = PyObject_CallMethod(ib->editor, (char *)"change_dir_prop", 10726 (char *)"Oss#O&", ib->baton, name, 10727 value ? value->data : NULL, 10728 value ? value->len : 0, 10729 make_ob_pool, pool)) == NULL) 10730 { 10731 err = convert_python_error(); 10732 goto finished; 10733 } 10734 10735 /* there is no return value, so just toss this object (probably Py_None) */ 10736 Py_DECREF(result); 10737 err = SVN_NO_ERROR; 10738 10739 finished: 10740 svn_swig_py_release_py_lock(); 10741 return err; 10742} 10743 10744static svn_error_t * thunk_close_directory(void *dir_baton, 10745 apr_pool_t *pool) 10746{ 10747 return close_baton(dir_baton, "close_directory"); 10748} 10749 10750static svn_error_t * thunk_add_file(const char *path, 10751 void *parent_baton, 10752 const char *copyfrom_path, 10753 svn_revnum_t copyfrom_revision, 10754 apr_pool_t *file_pool, 10755 void **file_baton) 10756{ 10757 item_baton *ib = parent_baton; 10758 PyObject *result; 10759 svn_error_t *err; 10760 10761 svn_swig_py_acquire_py_lock(); 10762 10763 /* ### python doesn't have 'const' on the method name and format */ 10764 if ((result = PyObject_CallMethod(ib->editor, (char *)"add_file", 10765 (char *)"sOslO&", path, ib->baton, 10766 copyfrom_path, copyfrom_revision, 10767 make_ob_pool, file_pool)) == NULL) 10768 { 10769 err = convert_python_error(); 10770 goto finished; 10771 } 10772 10773 /* make_baton takes our 'result' reference */ 10774 *file_baton = make_baton(file_pool, ib->editor, result); 10775 10776 err = SVN_NO_ERROR; 10777 10778 finished: 10779 svn_swig_py_release_py_lock(); 10780 return err; 10781} 10782 10783static svn_error_t * thunk_open_file(const char *path, 10784 void *parent_baton, 10785 svn_revnum_t base_revision, 10786 apr_pool_t *file_pool, 10787 void **file_baton) 10788{ 10789 item_baton *ib = parent_baton; 10790 PyObject *result; 10791 svn_error_t *err; 10792 10793 svn_swig_py_acquire_py_lock(); 10794 10795 /* ### python doesn't have 'const' on the method name and format */ 10796 if ((result = PyObject_CallMethod(ib->editor, (char *)"open_file", 10797 (char *)"sOlO&", path, ib->baton, 10798 base_revision, 10799 make_ob_pool, file_pool)) == NULL) 10800 { 10801 err = convert_python_error(); 10802 goto finished; 10803 } 10804 10805 /* make_baton takes our 'result' reference */ 10806 *file_baton = make_baton(file_pool, ib->editor, result); 10807 err = SVN_NO_ERROR; 10808 10809 finished: 10810 svn_swig_py_release_py_lock(); 10811 return err; 10812} 10813 10814static svn_error_t * thunk_window_handler(svn_txdelta_window_t *window, 10815 void *baton) 10816{ 10817 PyObject *handler = baton; 10818 PyObject *result; 10819 svn_error_t *err; 10820 10821 svn_swig_py_acquire_py_lock(); 10822 10823 if (window == NULL) 10824 { 10825 /* the last call; it closes the handler */ 10826 10827 /* invoke the handler with None for the window */ 10828 /* ### python doesn't have 'const' on the format */ 10829 result = PyObject_CallFunction(handler, (char *)"O", Py_None); 10830 10831 /* we no longer need to refer to the handler object */ 10832 Py_DECREF(handler); 10833 } 10834 else 10835 { 10836 /* invoke the handler with the window */ 10837 /* ### python doesn't have 'const' on the format */ 10838 result = PyObject_CallFunction(handler, 10839 (char *)"O&", make_ob_window, window); 10840 } 10841 10842 if (result == NULL) 10843 { 10844 err = convert_python_error(); 10845 goto finished; 10846 } 10847 10848 /* there is no return value, so just toss this object (probably Py_None) */ 10849 Py_DECREF(result); 10850 err = SVN_NO_ERROR; 10851 10852 finished: 10853 svn_swig_py_release_py_lock(); 10854 return err; 10855} 10856 10857static svn_error_t * 10858thunk_apply_textdelta(void *file_baton, 10859 const char *base_checksum, 10860 apr_pool_t *pool, 10861 svn_txdelta_window_handler_t *handler, 10862 void **h_baton) 10863{ 10864 item_baton *ib = file_baton; 10865 PyObject *result; 10866 svn_error_t *err; 10867 10868 svn_swig_py_acquire_py_lock(); 10869 10870 /* ### python doesn't have 'const' on the method name and format */ 10871 if ((result = PyObject_CallMethod(ib->editor, (char *)"apply_textdelta", 10872 (char *)"(Os)", ib->baton, 10873 base_checksum)) == NULL) 10874 { 10875 err = convert_python_error(); 10876 goto finished; 10877 } 10878 10879 /* Interpret None to mean svn_delta_noop_window_handler. This is much 10880 easier/faster than making code always have to write a NOOP handler 10881 in Python. */ 10882 if (result == Py_None) 10883 { 10884 Py_DECREF(result); 10885 10886 *handler = svn_delta_noop_window_handler; 10887 *h_baton = NULL; 10888 } 10889 else 10890 { 10891 /* return the thunk for invoking the handler. the baton takes our 10892 'result' reference, which is the handler. */ 10893 *handler = thunk_window_handler; 10894 *h_baton = result; 10895 } 10896 10897 err = SVN_NO_ERROR; 10898 10899 finished: 10900 svn_swig_py_release_py_lock(); 10901 return err; 10902} 10903 10904static svn_error_t * thunk_change_file_prop(void *file_baton, 10905 const char *name, 10906 const svn_string_t *value, 10907 apr_pool_t *pool) 10908{ 10909 item_baton *ib = file_baton; 10910 PyObject *result; 10911 svn_error_t *err; 10912 10913 svn_swig_py_acquire_py_lock(); 10914 10915 /* ### python doesn't have 'const' on the method name and format */ 10916 if ((result = PyObject_CallMethod(ib->editor, (char *)"change_file_prop", 10917 (char *)"Oss#O&", ib->baton, name, 10918 value ? value->data : NULL, 10919 value ? value->len : 0, 10920 make_ob_pool, pool)) == NULL) 10921 { 10922 err = convert_python_error(); 10923 goto finished; 10924 } 10925 10926 /* there is no return value, so just toss this object (probably Py_None) */ 10927 Py_DECREF(result); 10928 err = SVN_NO_ERROR; 10929 10930 finished: 10931 svn_swig_py_release_py_lock(); 10932 return err; 10933} 10934 10935static svn_error_t * thunk_close_file(void *file_baton, 10936 const char *text_checksum, 10937 apr_pool_t *pool) 10938{ 10939 item_baton *ib = file_baton; 10940 PyObject *result; 10941 svn_error_t *err; 10942 10943 svn_swig_py_acquire_py_lock(); 10944 10945 /* ### python doesn't have 'const' on the method name and format */ 10946 if ((result = PyObject_CallMethod(ib->editor, (char *)"close_file", 10947 (char *)"(Os)", ib->baton, 10948 text_checksum)) == NULL) 10949 { 10950 err = convert_python_error(); 10951 goto finished; 10952 } 10953 10954 /* there is no return value, so just toss this object (probably Py_None) */ 10955 Py_DECREF(result); 10956 10957 /* We're now done with the baton. Since there isn't really a free, all 10958 we need to do is note that its objects are no longer referenced by 10959 the baton. */ 10960 Py_DECREF(ib->editor); 10961 Py_XDECREF(ib->baton); 10962 10963#ifdef SVN_DEBUG 10964 ib->editor = ib->baton = NULL; 10965#endif 10966 10967 err = SVN_NO_ERROR; 10968 10969 finished: 10970 svn_swig_py_release_py_lock(); 10971 return err; 10972} 10973 10974static svn_error_t * thunk_close_edit(void *edit_baton, 10975 apr_pool_t *pool) 10976{ 10977 return close_baton(edit_baton, "close_edit"); 10978} 10979 10980static svn_error_t * thunk_abort_edit(void *edit_baton, 10981 apr_pool_t *pool) 10982{ 10983 return close_baton(edit_baton, "abort_edit"); 10984} 10985 10986void svn_swig_py_make_editor(const svn_delta_editor_t **editor, 10987 void **edit_baton, 10988 PyObject *py_editor, 10989 apr_pool_t *pool) 10990{ 10991 svn_delta_editor_t *thunk_editor = svn_delta_default_editor (pool); 10992 10993 thunk_editor->set_target_revision = thunk_set_target_revision; 10994 thunk_editor->open_root = thunk_open_root; 10995 thunk_editor->delete_entry = thunk_delete_entry; 10996 thunk_editor->add_directory = thunk_add_directory; 10997 thunk_editor->open_directory = thunk_open_directory; 10998 thunk_editor->change_dir_prop = thunk_change_dir_prop; 10999 thunk_editor->close_directory = thunk_close_directory; 11000 thunk_editor->add_file = thunk_add_file; 11001 thunk_editor->open_file = thunk_open_file; 11002 thunk_editor->apply_textdelta = thunk_apply_textdelta; 11003 thunk_editor->change_file_prop = thunk_change_file_prop; 11004 thunk_editor->close_file = thunk_close_file; 11005 thunk_editor->close_edit = thunk_close_edit; 11006 thunk_editor->abort_edit = thunk_abort_edit; 11007 11008 *editor = thunk_editor; 11009 *edit_baton = make_baton(pool, py_editor, NULL); 11010} 11011 11012 11013 11014/*** Other Wrappers for SVN Functions ***/ 11015 11016 11017/* This is very hacky and gross. */ 11018apr_file_t *svn_swig_py_make_file (PyObject *py_file, 11019 apr_pool_t *pool) 11020{ 11021 apr_file_t *apr_file = NULL; 11022 11023 if (py_file == NULL || py_file == Py_None) 11024 return NULL; 11025 11026 if (PyString_Check(py_file)) 11027 { 11028 /* input is a path -- just open an apr_file_t */ 11029 apr_file_open(&apr_file, PyString_AS_STRING(py_file), 11030 APR_CREATE | APR_READ | APR_WRITE, 11031 APR_OS_DEFAULT, 11032 pool); 11033 } 11034 else if (PyFile_Check (py_file)) 11035 { 11036 apr_status_t status; 11037 FILE *file; 11038 apr_os_file_t osfile; 11039 11040 /* input is a file object -- convert to apr_file_t */ 11041 file = PyFile_AsFile(py_file); 11042#ifdef WIN32 11043 osfile = (apr_os_file_t)_get_osfhandle(_fileno(file)); 11044#else 11045 osfile = (apr_os_file_t)fileno(file); 11046#endif 11047 status = apr_os_file_put (&apr_file, &osfile, O_CREAT | O_WRONLY, pool); 11048 if (status) 11049 return NULL; 11050 } 11051 return apr_file; 11052} 11053 11054 11055/* Thunked version of svn_wc_notify_func_t callback type. */ 11056void svn_swig_py_notify_func(void *baton, 11057 const char *path, 11058 svn_wc_notify_action_t action, 11059 svn_node_kind_t kind, 11060 const char *mime_type, 11061 svn_wc_notify_state_t content_state, 11062 svn_wc_notify_state_t prop_state, 11063 svn_revnum_t revision) 11064{ 11065 PyObject *function = baton; 11066 PyObject *result; 11067 11068 if (function == NULL || function == Py_None) 11069 return; 11070 11071 svn_swig_py_acquire_py_lock(); 11072 if ((result = PyObject_CallFunction(function, 11073 (char *)"(siisiii)", 11074 path, action, kind, 11075 mime_type, 11076 content_state, prop_state, 11077 revision)) != NULL) 11078 { 11079 Py_XDECREF(result); 11080 } 11081 svn_swig_py_release_py_lock(); 11082} 11083 11084 11085/* Thunked version of svn_wc_status_func_t callback type. */ 11086void svn_swig_py_status_func(void *baton, 11087 const char *path, 11088 svn_wc_status_t *status) 11089{ 11090 PyObject *function = baton; 11091 PyObject *result; 11092 11093 if (function == NULL || function == Py_None) 11094 return; 11095 11096 svn_swig_py_acquire_py_lock(); 11097 /* ### shouldn't we set an exception if this fails? */ 11098 if ((result = PyObject_CallFunction(function, (char *)"sO&", path, 11099 make_ob_status, status)) != NULL) 11100 { 11101 Py_DECREF(result); 11102 } 11103 svn_swig_py_release_py_lock(); 11104} 11105 11106 11107/* Thunked version of svn_wc_cancel_func_t callback type. */ 11108svn_error_t *svn_swig_py_cancel_func(void *cancel_baton) 11109{ 11110 PyObject *function = cancel_baton; 11111 PyObject *result; 11112 svn_error_t *err = SVN_NO_ERROR; 11113 11114 if (function == NULL || function == Py_None) 11115 return SVN_NO_ERROR; 11116 11117 svn_swig_py_acquire_py_lock(); 11118 if ((result = PyObject_CallFunction(function, NULL)) != NULL) 11119 { 11120 err = convert_python_error(); 11121 goto finished; 11122 } 11123 11124 Py_DECREF(result); 11125 11126 finished: 11127 svn_swig_py_release_py_lock(); 11128 return err; 11129} 11130 11131 11132/* Thunked version of svn_client_get_commit_log_t callback type. */ 11133svn_error_t *svn_swig_py_get_commit_log_func(const char **log_msg, 11134 const char **tmp_file, 11135 apr_array_header_t *commit_items, 11136 void *baton, 11137 apr_pool_t *pool) 11138{ 11139 PyObject *function = baton; 11140 PyObject *result; 11141 PyObject *cmt_items; 11142 svn_error_t *err; 11143 11144 *log_msg = NULL; 11145 *tmp_file = NULL; 11146 11147 /* ### todo: for now, just ignore the whole tmp_file thing. */ 11148 11149 if ((function == NULL) || (function == Py_None)) 11150 return SVN_NO_ERROR; 11151 11152 svn_swig_py_acquire_py_lock(); 11153 11154 if (commit_items) 11155 { 11156 cmt_items = commit_item_array_to_list(commit_items); 11157 } 11158 else 11159 { 11160 cmt_items = Py_None; 11161 Py_INCREF(Py_None); 11162 } 11163 11164 /* ### python doesn't have 'const' on the method name and format */ 11165 if ((result = PyObject_CallFunction(function, 11166 (char *)"OO&", 11167 cmt_items, 11168 make_ob_pool, pool)) == NULL) 11169 { 11170 Py_DECREF(cmt_items); 11171 err = convert_python_error(); 11172 goto finished; 11173 } 11174 11175 Py_DECREF(cmt_items); 11176 11177 if (result == Py_None) 11178 { 11179 Py_DECREF(result); 11180 *log_msg = NULL; 11181 err = SVN_NO_ERROR; 11182 goto finished; 11183 } 11184 else if (PyString_Check(result)) 11185 { 11186 *log_msg = apr_pstrdup(pool, PyString_AS_STRING(result)); 11187 Py_DECREF(result); 11188 err = SVN_NO_ERROR; 11189 goto finished; 11190 } 11191 11192 Py_DECREF(result); 11193 PyErr_SetString(PyExc_TypeError, "not a string"); 11194 err = convert_python_error(); 11195 11196 finished: 11197 svn_swig_py_release_py_lock(); 11198 return err; 11199} 11200 11201 11202/* Thunked version of svn_repos_history_func_t callback type. */ 11203svn_error_t *svn_swig_py_repos_history_func(void *baton, 11204 const char *path, 11205 svn_revnum_t revision, 11206 apr_pool_t *pool) 11207{ 11208 PyObject *function = baton; 11209 PyObject *result; 11210 svn_error_t *err = SVN_NO_ERROR; 11211 11212 if (function == NULL || function == Py_None) 11213 return SVN_NO_ERROR; 11214 11215 svn_swig_py_acquire_py_lock(); 11216 if ((result = PyObject_CallFunction(function, 11217 (char *)"slO&", 11218 path, revision, 11219 make_ob_pool, pool)) != NULL) 11220 { 11221 if (result != Py_None) 11222 err = convert_python_error(); 11223 Py_DECREF(result); 11224 goto finished; 11225 } 11226 11227 finished: 11228 svn_swig_py_release_py_lock(); 11229 return err; 11230} 11231 11232 11233/* Thunked version of svn_log_message_receiver_t callback type. */ 11234svn_error_t * svn_swig_py_thunk_log_receiver(void *baton, 11235 apr_hash_t *changed_paths, 11236 svn_revnum_t rev, 11237 const char *author, 11238 const char *date, 11239 const char *msg, 11240 apr_pool_t *pool) 11241{ 11242 PyObject *receiver = baton; 11243 PyObject *result; 11244 swig_type_info *tinfo = SWIG_TypeQuery("svn_log_changed_path_t *"); 11245 PyObject *chpaths; 11246 svn_error_t *err; 11247 11248 if ((receiver == NULL) || (receiver == Py_None)) 11249 return SVN_NO_ERROR; 11250 11251 svn_swig_py_acquire_py_lock(); 11252 11253 if (changed_paths) 11254 { 11255 chpaths = svn_swig_py_convert_hash (changed_paths, tinfo); 11256 } 11257 else 11258 { 11259 chpaths = Py_None; 11260 Py_INCREF(Py_None); 11261 } 11262 11263 /* ### python doesn't have 'const' on the method name and format */ 11264 if ((result = PyObject_CallFunction(receiver, 11265 (char *)"OlsssO&", 11266 chpaths, rev, author, date, msg, 11267 make_ob_pool, pool)) == NULL) 11268 { 11269 Py_DECREF(chpaths); 11270 err = convert_python_error(); 11271 goto finished; 11272 } 11273 11274 /* there is no return value, so just toss this object (probably Py_None) */ 11275 Py_DECREF(result); 11276 Py_DECREF(chpaths); 11277 err = SVN_NO_ERROR; 11278 11279 finished: 11280 svn_swig_py_release_py_lock(); 11281 return err; 11282} 11283 11284 11285Node-path: svnperl/swigutil_py.h 11286Node-kind: file 11287Node-action: add 11288Prop-content-length: 10 11289Text-content-length: 6039 11290Text-content-md5: 0d5f2aa933a5359d7fb29eacbb735b4b 11291Content-length: 6049 11292 11293PROPS-END 11294/* 11295 * swigutil_py.h : utility functions and stuff for the SWIG Python bindings 11296 * 11297 * ==================================================================== 11298 * Copyright (c) 2000-2004 CollabNet. All rights reserved. 11299 * 11300 * This software is licensed as described in the file COPYING, which 11301 * you should have received as part of this distribution. The terms 11302 * are also available at http://subversion.tigris.org/license-1.html. 11303 * If newer versions of this license are posted there, you may use a 11304 * newer version instead, at your option. 11305 * 11306 * This software consists of voluntary contributions made by many 11307 * individuals. For exact contribution history, see the revision 11308 * history and logs, available at http://subversion.tigris.org/. 11309 * ==================================================================== 11310 */ 11311 11312 11313#ifndef SVN_SWIG_SWIGUTIL_PY_H 11314#define SVN_SWIG_SWIGUTIL_PY_H 11315 11316#include <Python.h> 11317 11318#include <apr.h> 11319#include <apr_pools.h> 11320#include <apr_strings.h> 11321#include <apr_hash.h> 11322#include <apr_tables.h> 11323 11324#include "svn_types.h" 11325#include "svn_string.h" 11326#include "svn_delta.h" 11327#include "svn_client.h" 11328#include "svn_repos.h" 11329 11330#ifdef __cplusplus 11331extern "C" { 11332#endif /* __cplusplus */ 11333 11334 11335/* If this file is being included outside of a wrapper file, then need to 11336 create stubs for some of the SWIG types. */ 11337 11338/* if SWIGEXPORT is defined, then we're in a wrapper. otherwise, we need 11339 the prototypes and type definitions. */ 11340#ifndef SWIGEXPORT 11341#define SVN_NEED_SWIG_TYPES 11342#endif 11343 11344#ifdef SVN_NEED_SWIG_TYPES 11345 11346typedef struct _unnamed swig_type_info; 11347PyObject *SWIG_NewPointerObj(void *, swig_type_info *, int own); 11348swig_type_info *SWIG_TypeQuery(const char *name); 11349 11350#endif /* SVN_NEED_SWIG_TYPES */ 11351 11352/* Functions to manage python's global interpreter lock */ 11353void svn_swig_py_release_py_lock(void); 11354void svn_swig_py_acquire_py_lock(void); 11355 11356 11357/*** Functions to expose a custom SubversionException ***/ 11358 11359/* register a new subversion exception class */ 11360PyObject *svn_swig_py_register_exception(void); 11361 11362/* get the object which represents the subversion exception class */ 11363PyObject *svn_swig_py_exception_type(void); 11364 11365/* raise a subversion exception, created from a normal subversion error */ 11366void svn_swig_py_svn_exception(svn_error_t *err); 11367 11368 11369 11370/* helper function to convert an apr_hash_t* (char* -> svnstring_t*) to 11371 a Python dict */ 11372PyObject *svn_swig_py_prophash_to_dict(apr_hash_t *hash); 11373 11374/* convert a hash of 'const char *' -> TYPE into a Python dict */ 11375PyObject *svn_swig_py_convert_hash(apr_hash_t *hash, swig_type_info *type); 11376 11377/* helper function to convert a 'char **' into a Python list of string 11378 objects */ 11379PyObject *svn_swig_py_c_strings_to_list(char **strings); 11380 11381/* helper function to convert an array of 'const char *' to a Python list 11382 of string objects */ 11383PyObject *svn_swig_py_array_to_list(const apr_array_header_t *strings); 11384 11385/* helper function to convert an array of 'svn_revnum_t' to a Python list 11386 of int objects */ 11387PyObject *svn_swig_py_revarray_to_list(const apr_array_header_t *revs); 11388 11389/* helper function to convert a Python sequence of strings into an 11390 'apr_array_header_t *' of 'const char *' objects. Note that the 11391 objects must remain alive -- the values are not copied. This is 11392 appropriate for incoming arguments which are defined to last the 11393 duration of the function's execution. */ 11394const apr_array_header_t *svn_swig_py_strings_to_array(PyObject *source, 11395 apr_pool_t *pool); 11396 11397/* make an editor that "thunks" from C callbacks up to Python */ 11398void svn_swig_py_make_editor(const svn_delta_editor_t **editor, 11399 void **edit_baton, 11400 PyObject *py_editor, 11401 apr_pool_t *pool); 11402 11403apr_file_t *svn_swig_py_make_file(PyObject *py_file, 11404 apr_pool_t *pool); 11405 11406/* a notify function that executes a Python function that is passed in 11407 via the baton argument */ 11408void svn_swig_py_notify_func(void *baton, 11409 const char *path, 11410 svn_wc_notify_action_t action, 11411 svn_node_kind_t kind, 11412 const char *mime_type, 11413 svn_wc_notify_state_t content_state, 11414 svn_wc_notify_state_t prop_state, 11415 svn_revnum_t revision); 11416 11417/* a status function that executes a Python function that is passed in 11418 via the baton argument */ 11419void svn_swig_py_status_func(void *baton, 11420 const char *path, 11421 svn_wc_status_t *status); 11422 11423/* a cancel function that executes a Python function passed in via the 11424 cancel_baton argument. */ 11425svn_error_t *svn_swig_py_cancel_func(void *cancel_baton); 11426 11427/* thunked commit log fetcher */ 11428svn_error_t *svn_swig_py_get_commit_log_func(const char **log_msg, 11429 const char **tmp_file, 11430 apr_array_header_t *commit_items, 11431 void *baton, 11432 apr_pool_t *pool); 11433 11434/* thunker history callback function */ 11435svn_error_t *svn_swig_py_repos_history_func(void *baton, 11436 const char *path, 11437 svn_revnum_t revision, 11438 apr_pool_t *pool); 11439 11440/* thunked log receiver function. */ 11441svn_error_t * svn_swig_py_thunk_log_receiver(void *py_receiver, 11442 apr_hash_t *changed_paths, 11443 svn_revnum_t rev, 11444 const char *author, 11445 const char *date, 11446 const char *msg, 11447 apr_pool_t *pool); 11448 11449#ifdef __cplusplus 11450} 11451#endif /* __cplusplus */ 11452 11453#endif /* SVN_SWIG_SWIGUTIL_PY_H */ 11454 11455 11456Revision-number: 24 11457Prop-content-length: 200 11458Content-length: 200 11459 11460K 7 11461svn:log 11462V 99 11463* Mimic r6941 in svn.collab. Made a branch and remove some files and directories just in that dir. 11464K 10 11465svn:author 11466V 6 11467plasma 11468K 8 11469svn:date 11470V 27 114712004-01-23T05:13:20.320762Z 11472PROPS-END 11473 11474Node-path: svnperl_branch 11475Node-kind: dir 11476Node-action: add 11477Node-copyfrom-rev: 23 11478Node-copyfrom-path: svnperl 11479 11480 11481Node-path: svnperl_branch/swigutil_java.c 11482Node-action: delete 11483 11484 11485Node-path: svnperl_branch/swigutil_java.h 11486Node-action: delete 11487 11488 11489Node-path: svnperl_branch/swigutil_py.c 11490Node-action: delete 11491 11492 11493Node-path: svnperl_branch/java 11494Node-action: delete 11495 11496 11497Node-path: svnperl_branch/python 11498Node-action: delete 11499 11500 11501Node-path: svnperl_branch/swigutil_java_cache.h 11502Node-action: delete 11503 11504 11505Node-path: svnperl_branch/swigutil_py.h 11506Node-action: delete 11507 11508 11509Revision-number: 25 11510Prop-content-length: 122 11511Content-length: 122 11512 11513K 7 11514svn:log 11515V 21 11516* Remove branch test. 11517K 10 11518svn:author 11519V 6 11520plasma 11521K 8 11522svn:date 11523V 27 115242004-01-23T08:38:14.380867Z 11525PROPS-END 11526 11527Node-path: svnperl_branch 11528Node-action: delete 11529 11530 11531Revision-number: 26 11532Prop-content-length: 199 11533Content-length: 199 11534 11535K 7 11536svn:log 11537V 98 11538* Mimic r6941 in svn.collab. Made a branch and remove some files and directories within that dir. 11539K 10 11540svn:author 11541V 6 11542plasma 11543K 8 11544svn:date 11545V 27 115462004-01-23T08:39:31.136538Z 11547PROPS-END 11548 11549Node-path: svnperl_branch 11550Node-kind: dir 11551Node-action: add 11552Node-copyfrom-rev: 24 11553Node-copyfrom-path: svnperl 11554 11555 11556Node-path: svnperl_branch/perl/t/1repos.t 11557Node-action: delete 11558 11559 11560Node-path: svnperl_branch/perl/t/2fs.t 11561Node-action: delete 11562 11563 11564Node-path: svnperl_branch/perl/t/0use.t 11565Node-action: delete 11566 11567 11568Node-path: svnperl_branch/perl/t/4pool.t 11569Node-action: delete 11570 11571 11572Node-path: svnperl_branch/perl/t/3client.t 11573Node-action: delete 11574 11575 11576Node-path: svnperl_branch/swigutil_java.c 11577Node-action: delete 11578 11579 11580Node-path: svnperl_branch/swigutil_java.h 11581Node-action: delete 11582 11583 11584Node-path: svnperl_branch/swigutil_py.c 11585Node-action: delete 11586 11587 11588Node-path: svnperl_branch/java 11589Node-action: delete 11590 11591 11592Node-path: svnperl_branch/python 11593Node-action: delete 11594 11595 11596Node-path: svnperl_branch/swigutil_java_cache.h 11597Node-action: delete 11598 11599 11600Node-path: svnperl_branch/swigutil_py.h 11601Node-action: delete 11602 11603 11604Revision-number: 27 11605Prop-content-length: 140 11606Content-length: 140 11607 11608K 7 11609svn:log 11610V 39 11611* Simulate a simple branch for svnperl. 11612K 10 11613svn:author 11614V 6 11615plasma 11616K 8 11617svn:date 11618V 27 116192004-01-23T13:50:48.043288Z 11620PROPS-END 11621 11622Node-path: svnperl_001 11623Node-kind: dir 11624Node-action: add 11625Node-copyfrom-rev: 26 11626Node-copyfrom-path: svnperl 11627 11628 11629Revision-number: 28 11630Prop-content-length: 130 11631Content-length: 130 11632 11633K 7 11634svn:log 11635V 29 11636* Simulate a branch from r23. 11637K 10 11638svn:author 11639V 6 11640plasma 11641K 8 11642svn:date 11643V 27 116442004-01-23T14:00:30.450298Z 11645PROPS-END 11646 11647Node-path: svnperl_002 11648Node-kind: dir 11649Node-action: add 11650Node-copyfrom-rev: 23 11651Node-copyfrom-path: svnperl 11652 11653 11654