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&gt>
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&gt>
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