1 /*
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  */
21 
22 /* -*- c-file-style: "ruby" -*- */
23 /* Tell swigutil_rb.h that we're inside the implementation */
24 #define SVN_SWIG_SWIGUTIL_RB_C
25 
26 /* Windows hack: Allow overriding some <ruby.h> defaults */
27 #include "swigutil_rb__pre_ruby.h"
28 #include "swig_ruby_external_runtime.swg"
29 #include "swigutil_rb.h"
30 
31 #ifdef HAVE_RUBY_ST_H
32 #include <ruby/st.h>
33 #else
34 #include <st.h>
35 #endif
36 
37 #undef PACKAGE_BUGREPORT
38 #undef PACKAGE_NAME
39 #undef PACKAGE_STRING
40 #undef PACKAGE_TARNAME
41 #undef PACKAGE_VERSION
42 #undef _
43 
44 #include "svn_private_config.h"
45 
46 #ifndef RE_OPTION_IGNORECASE
47 #  ifdef ONIG_OPTION_IGNORECASE
48 #    define RE_OPTION_IGNORECASE ONIG_OPTION_IGNORECASE
49 #  endif
50 #endif
51 
52 #ifndef RSTRING_LEN
53 #  define RSTRING_LEN(str) (RSTRING(str)->len)
54 #endif
55 
56 #ifndef RSTRING_PTR
57 #  define RSTRING_PTR(str) (RSTRING(str)->ptr)
58 #endif
59 
60 #include <locale.h>
61 #include <math.h>
62 
63 #include "svn_hash.h"
64 #include "svn_nls.h"
65 #include "svn_pools.h"
66 #include "svn_props.h"
67 #include "svn_time.h"
68 #include "svn_utf.h"
69 
70 
71 #if APR_HAS_LARGE_FILES
72 #  define AOFF2NUM(num) LL2NUM(num)
73 #else
74 #  define AOFF2NUM(num) LONG2NUM(num)
75 #endif
76 
77 #if SIZEOF_LONG_LONG == 8
78 #  define AI642NUM(num) LL2NUM(num)
79 #else
80 #  define AI642NUM(num) LONG2NUM(num)
81 #endif
82 
83 #define EMPTY_CPP_ARGUMENT
84 
85 #define POOL_P(obj) (RTEST(rb_obj_is_kind_of(obj, rb_svn_core_pool())))
86 #define CONTEXT_P(obj) (RTEST(rb_obj_is_kind_of(obj, rb_svn_client_context())))
87 #define SVN_ERR_P(obj) (RTEST(rb_obj_is_kind_of(obj, rb_svn_error())))
88 
89 static VALUE mSvn = Qnil;
90 static VALUE mSvnClient = Qnil;
91 static VALUE mSvnUtil = Qnil;
92 static VALUE cSvnClientContext = Qnil;
93 static VALUE mSvnCore = Qnil;
94 static VALUE cSvnCorePool = Qnil;
95 static VALUE cSvnCoreStream = Qnil;
96 static VALUE cSvnDelta = Qnil;
97 static VALUE cSvnDeltaEditor = Qnil;
98 static VALUE cSvnDeltaTextDeltaWindowHandler = Qnil;
99 static VALUE cSvnError = Qnil;
100 static VALUE cSvnErrorSvnError = Qnil;
101 static VALUE cSvnFs = Qnil;
102 static VALUE cSvnFsFileSystem = Qnil;
103 static VALUE cSvnRa = Qnil;
104 static VALUE cSvnRaReporter3 = Qnil;
105 
106 static apr_pool_t *swig_rb_pool;
107 static apr_allocator_t *swig_rb_allocator;
108 
109 #define DECLARE_ID(key) static ID id_ ## key
110 #define DEFINE_ID(key) DEFINE_ID_WITH_NAME(key, #key)
111 #define DEFINE_ID_WITH_NAME(key, name) id_ ## key = rb_intern(name)
112 
113 DECLARE_ID(code);
114 DECLARE_ID(message);
115 DECLARE_ID(call);
116 DECLARE_ID(read);
117 DECLARE_ID(write);
118 DECLARE_ID(eqq);
119 DECLARE_ID(baton);
120 DECLARE_ID(new);
121 DECLARE_ID(new_corresponding_error);
122 DECLARE_ID(set_target_revision);
123 DECLARE_ID(open_root);
124 DECLARE_ID(delete_entry);
125 DECLARE_ID(add_directory);
126 DECLARE_ID(open_directory);
127 DECLARE_ID(change_dir_prop);
128 DECLARE_ID(close_directory);
129 DECLARE_ID(absent_directory);
130 DECLARE_ID(add_file);
131 DECLARE_ID(open_file);
132 DECLARE_ID(apply_textdelta);
133 DECLARE_ID(change_file_prop);
134 DECLARE_ID(absent_file);
135 DECLARE_ID(close_file);
136 DECLARE_ID(close_edit);
137 DECLARE_ID(abort_edit);
138 DECLARE_ID(__pool__);
139 DECLARE_ID(__pools__);
140 DECLARE_ID(name);
141 DECLARE_ID(value);
142 DECLARE_ID(swig_type_regex);
143 DECLARE_ID(open_tmp_file);
144 DECLARE_ID(get_wc_prop);
145 DECLARE_ID(set_wc_prop);
146 DECLARE_ID(push_wc_prop);
147 DECLARE_ID(invalidate_wc_props);
148 DECLARE_ID(progress_func);
149 DECLARE_ID(auth_baton);
150 DECLARE_ID(found_entry);
151 DECLARE_ID(file_changed);
152 DECLARE_ID(file_added);
153 DECLARE_ID(file_deleted);
154 DECLARE_ID(dir_added);
155 DECLARE_ID(dir_deleted);
156 DECLARE_ID(dir_props_changed);
157 DECLARE_ID(handler);
158 DECLARE_ID(handler_baton);
159 DECLARE_ID(__batons__);
160 DECLARE_ID(destroy);
161 DECLARE_ID(filename_to_temp_file);
162 DECLARE_ID(inspect);
163 DECLARE_ID(handle_error);
164 DECLARE_ID(set_path);
165 DECLARE_ID(delete_path);
166 DECLARE_ID(link_path);
167 DECLARE_ID(finish_report);
168 DECLARE_ID(abort_report);
169 DECLARE_ID(to_s);
170 DECLARE_ID(upcase);
171 
172 
173 typedef void *(*r2c_func)(VALUE value, void *ctx, apr_pool_t *pool);
174 typedef VALUE (*c2r_func)(void *value, void *ctx);
175 typedef struct hash_to_apr_hash_data_t
176 {
177   apr_hash_t *apr_hash;
178   r2c_func func;
179   void *ctx;
180   apr_pool_t *pool;
181 } hash_to_apr_hash_data_t;
182 
183 static void r2c_swig_type2(VALUE value, const char *type_name, void **result);
184 static const char *r2c_inspect(VALUE object);
185 
186 
187 
188 /* constant getter */
189 static VALUE
rb_svn(void)190 rb_svn(void)
191 {
192   if (NIL_P(mSvn)) {
193     mSvn = rb_const_get(rb_cObject, rb_intern("Svn"));
194   }
195   return mSvn;
196 }
197 
198 static VALUE
rb_svn_util(void)199 rb_svn_util(void)
200 {
201   if (NIL_P(mSvnUtil)) {
202     mSvnUtil = rb_const_get(rb_svn(), rb_intern("Util"));
203   }
204   return mSvnUtil;
205 }
206 
207 static VALUE
rb_svn_client(void)208 rb_svn_client(void)
209 {
210   if (NIL_P(mSvnClient)) {
211     mSvnClient = rb_const_get(rb_svn(), rb_intern("Client"));
212   }
213   return mSvnClient;
214 }
215 
216 static VALUE
rb_svn_client_context(void)217 rb_svn_client_context(void)
218 {
219   if (NIL_P(cSvnClientContext)) {
220     cSvnClientContext = rb_const_get(rb_svn_client(), rb_intern("Context"));
221   }
222   return cSvnClientContext;
223 }
224 
225 static VALUE
rb_svn_core(void)226 rb_svn_core(void)
227 {
228   if (NIL_P(mSvnCore)) {
229     mSvnCore = rb_const_get(rb_svn(), rb_intern("Core"));
230   }
231   return mSvnCore;
232 }
233 
234 static VALUE
rb_svn_core_pool(void)235 rb_svn_core_pool(void)
236 {
237   if (NIL_P(cSvnCorePool)) {
238     cSvnCorePool = rb_const_get(rb_svn_core(), rb_intern("Pool"));
239     rb_ivar_set(cSvnCorePool, id___pools__, rb_hash_new());
240   }
241   return cSvnCorePool;
242 }
243 
244 static VALUE
rb_svn_core_stream(void)245 rb_svn_core_stream(void)
246 {
247   if (NIL_P(cSvnCoreStream)) {
248     cSvnCoreStream = rb_const_get(rb_svn_core(), rb_intern("Stream"));
249   }
250   return cSvnCoreStream;
251 }
252 
253 static VALUE
rb_svn_delta(void)254 rb_svn_delta(void)
255 {
256   if (NIL_P(cSvnDelta)) {
257     cSvnDelta = rb_const_get(rb_svn(), rb_intern("Delta"));
258   }
259   return cSvnDelta;
260 }
261 
262 VALUE
svn_swig_rb_svn_delta_editor(void)263 svn_swig_rb_svn_delta_editor(void)
264 {
265   if (NIL_P(cSvnDeltaEditor)) {
266     cSvnDeltaEditor =
267       rb_const_get(rb_svn_delta(), rb_intern("Editor"));
268   }
269   return cSvnDeltaEditor;
270 }
271 
272 VALUE
svn_swig_rb_svn_delta_text_delta_window_handler(void)273 svn_swig_rb_svn_delta_text_delta_window_handler(void)
274 {
275   if (NIL_P(cSvnDeltaTextDeltaWindowHandler)) {
276     cSvnDeltaTextDeltaWindowHandler =
277       rb_const_get(rb_svn_delta(), rb_intern("TextDeltaWindowHandler"));
278   }
279   return cSvnDeltaTextDeltaWindowHandler;
280 }
281 
282 static VALUE
rb_svn_error(void)283 rb_svn_error(void)
284 {
285   if (NIL_P(cSvnError)) {
286     cSvnError = rb_const_get(rb_svn(), rb_intern("Error"));
287   }
288   return cSvnError;
289 }
290 
291 static VALUE
rb_svn_error_svn_error(void)292 rb_svn_error_svn_error(void)
293 {
294   if (NIL_P(cSvnErrorSvnError)) {
295     cSvnErrorSvnError = rb_const_get(rb_svn_error(), rb_intern("SvnError"));
296   }
297   return cSvnErrorSvnError;
298 }
299 
300 static VALUE
rb_svn_fs(void)301 rb_svn_fs(void)
302 {
303   if (NIL_P(cSvnFs)) {
304     cSvnFs = rb_const_get(rb_svn(), rb_intern("Fs"));
305   }
306   return cSvnFs;
307 }
308 
309 static VALUE
rb_svn_fs_file_system(void)310 rb_svn_fs_file_system(void)
311 {
312   if (NIL_P(cSvnFsFileSystem)) {
313     cSvnFsFileSystem = rb_const_get(rb_svn_fs(), rb_intern("FileSystem"));
314     rb_ivar_set(cSvnFsFileSystem, id___batons__, rb_hash_new());
315   }
316   return cSvnFsFileSystem;
317 }
318 
319 static VALUE
rb_svn_ra(void)320 rb_svn_ra(void)
321 {
322   if (NIL_P(cSvnRa)) {
323     cSvnRa = rb_const_get(rb_svn(), rb_intern("Ra"));
324   }
325   return cSvnRa;
326 }
327 
328 static VALUE
rb_svn_ra_reporter3(void)329 rb_svn_ra_reporter3(void)
330 {
331   if (NIL_P(cSvnRaReporter3)) {
332     cSvnRaReporter3 = rb_const_get(rb_svn_ra(), rb_intern("Reporter3"));
333   }
334   return cSvnRaReporter3;
335 }
336 
337 
338 /* constant resolver */
339 static VALUE
resolve_constant(VALUE parent,const char * prefix,VALUE name)340 resolve_constant(VALUE parent, const char *prefix, VALUE name)
341 {
342     VALUE const_name;
343 
344     const_name = rb_str_new2(prefix);
345     rb_str_concat(const_name,
346                   rb_funcall(rb_funcall(name, id_to_s, 0),
347                              id_upcase, 0));
348     return rb_const_get(parent, rb_intern(StringValuePtr(const_name)));
349 }
350 
351 
352 /* initialize */
353 static VALUE
svn_swig_rb_converter_to_locale_encoding(VALUE self,VALUE str)354 svn_swig_rb_converter_to_locale_encoding(VALUE self, VALUE str)
355 {
356   apr_pool_t *pool;
357   svn_error_t *err;
358   const char *dest;
359   VALUE result;
360 
361   pool = svn_pool_create(NULL);
362   err = svn_utf_cstring_from_utf8(&dest, StringValueCStr(str), pool);
363   if (err) {
364     svn_pool_destroy(pool);
365     svn_swig_rb_handle_svn_error(err);
366   }
367 
368   result = rb_str_new2(dest);
369   svn_pool_destroy(pool);
370   return result;
371 }
372 
373 static VALUE
svn_swig_rb_locale_set(int argc,VALUE * argv,VALUE self)374 svn_swig_rb_locale_set(int argc, VALUE *argv, VALUE self)
375 {
376   char *result;
377   int category;
378   const char *locale;
379   VALUE rb_category, rb_locale;
380 
381   rb_scan_args(argc, argv, "02", &rb_category, &rb_locale);
382 
383   if (NIL_P(rb_category))
384     category = LC_ALL;
385   else
386     category = NUM2INT(rb_category);
387 
388   if (NIL_P(rb_locale))
389     locale = "";
390   else
391     locale = StringValueCStr(rb_locale);
392 
393   result = setlocale(category, locale);
394 
395   return result ? rb_str_new2(result) : Qnil;
396 }
397 
398 static VALUE
svn_swig_rb_gettext_bindtextdomain(VALUE self,VALUE path)399 svn_swig_rb_gettext_bindtextdomain(VALUE self, VALUE path)
400 {
401 #ifdef ENABLE_NLS
402   bindtextdomain(PACKAGE_NAME, StringValueCStr(path));
403 #endif
404   return Qnil;
405 }
406 
407 static VALUE
svn_swig_rb_gettext__(VALUE self,VALUE message)408 svn_swig_rb_gettext__(VALUE self, VALUE message)
409 {
410 #ifdef ENABLE_NLS
411   return rb_str_new2(_(StringValueCStr(message)));
412 #else
413   return message;
414 #endif
415 }
416 
417 static void
svn_swig_rb_initialize_ids(void)418 svn_swig_rb_initialize_ids(void)
419 {
420   DEFINE_ID(code);
421   DEFINE_ID(message);
422   DEFINE_ID(call);
423   DEFINE_ID(read);
424   DEFINE_ID(write);
425   DEFINE_ID_WITH_NAME(eqq, "===");
426   DEFINE_ID(baton);
427   DEFINE_ID(new);
428   DEFINE_ID(new_corresponding_error);
429   DEFINE_ID(set_target_revision);
430   DEFINE_ID(open_root);
431   DEFINE_ID(delete_entry);
432   DEFINE_ID(add_directory);
433   DEFINE_ID(open_directory);
434   DEFINE_ID(change_dir_prop);
435   DEFINE_ID(close_directory);
436   DEFINE_ID(absent_directory);
437   DEFINE_ID(add_file);
438   DEFINE_ID(open_file);
439   DEFINE_ID(apply_textdelta);
440   DEFINE_ID(change_file_prop);
441   DEFINE_ID(absent_file);
442   DEFINE_ID(close_file);
443   DEFINE_ID(close_edit);
444   DEFINE_ID(abort_edit);
445   DEFINE_ID(__pool__);
446   DEFINE_ID(__pools__);
447   DEFINE_ID(name);
448   DEFINE_ID(value);
449   DEFINE_ID(swig_type_regex);
450   DEFINE_ID(open_tmp_file);
451   DEFINE_ID(get_wc_prop);
452   DEFINE_ID(set_wc_prop);
453   DEFINE_ID(push_wc_prop);
454   DEFINE_ID(invalidate_wc_props);
455   DEFINE_ID(progress_func);
456   DEFINE_ID(auth_baton);
457   DEFINE_ID(found_entry);
458   DEFINE_ID(file_changed);
459   DEFINE_ID(file_added);
460   DEFINE_ID(file_deleted);
461   DEFINE_ID(dir_added);
462   DEFINE_ID(dir_deleted);
463   DEFINE_ID(dir_props_changed);
464   DEFINE_ID(handler);
465   DEFINE_ID(handler_baton);
466   DEFINE_ID(__batons__);
467   DEFINE_ID(destroy);
468   DEFINE_ID(filename_to_temp_file);
469   DEFINE_ID(inspect);
470   DEFINE_ID(handle_error);
471   DEFINE_ID(set_path);
472   DEFINE_ID(delete_path);
473   DEFINE_ID(link_path);
474   DEFINE_ID(finish_report);
475   DEFINE_ID(abort_report);
476   DEFINE_ID(to_s);
477   DEFINE_ID(upcase);
478 }
479 
480 static void
check_apr_status(apr_status_t status,VALUE exception_class,const char * format)481 check_apr_status(apr_status_t status, VALUE exception_class, const char *format)
482 {
483     if (status != APR_SUCCESS) {
484         char buffer[1024];
485         apr_strerror(status, buffer, sizeof(buffer) - 1);
486         rb_raise(exception_class, format, buffer);
487     }
488 }
489 
490 static VALUE swig_type_re = Qnil;
491 
492 static VALUE
swig_type_regex(void)493 swig_type_regex(void)
494 {
495   if (NIL_P(swig_type_re)) {
496     char reg_str[] = "\\A(?:SWIG|Svn::Ext)::";
497     swig_type_re = rb_reg_new(reg_str, strlen(reg_str), 0);
498     rb_ivar_set(rb_svn(), id_swig_type_regex, swig_type_re);
499   }
500   return swig_type_re;
501 }
502 
503 static VALUE
find_swig_type_object(int num,VALUE * objects)504 find_swig_type_object(int num, VALUE *objects)
505 {
506   VALUE re;
507   int i;
508 
509   re = swig_type_regex();
510   for (i = 0; i < num; i++) {
511     if (RTEST(rb_reg_match(re,
512                            rb_funcall(rb_obj_class(objects[i]),
513                                       id_name,
514                                       0)))) {
515       return objects[i];
516     }
517   }
518 
519   return Qnil;
520 }
521 
522 static VALUE
svn_swig_rb_destroyer_destroy(VALUE self,VALUE target)523 svn_swig_rb_destroyer_destroy(VALUE self, VALUE target)
524 {
525     VALUE objects[1];
526 
527     objects[0] = target;
528     if (find_swig_type_object(1, objects) && DATA_PTR(target)) {
529         svn_swig_rb_destroy_internal_pool(target);
530         DATA_PTR(target) = NULL;
531     }
532 
533     return Qnil;
534 }
535 
536 void
svn_swig_rb_initialize(void)537 svn_swig_rb_initialize(void)
538 {
539   VALUE mSvnConverter, mSvnLocale, mSvnGetText, mSvnDestroyer;
540 
541   check_apr_status(apr_initialize(), rb_eLoadError, "cannot initialize APR: %s");
542 
543   if (atexit(apr_terminate)) {
544     rb_raise(rb_eLoadError, "atexit registration failed");
545   }
546 
547   check_apr_status(apr_allocator_create(&swig_rb_allocator),
548                    rb_eLoadError, "failed to create allocator: %s");
549   apr_allocator_max_free_set(swig_rb_allocator,
550                              SVN_ALLOCATOR_RECOMMENDED_MAX_FREE);
551 
552   swig_rb_pool = svn_pool_create_ex(NULL, swig_rb_allocator);
553   apr_pool_tag(swig_rb_pool, "svn-ruby-pool");
554 #if APR_HAS_THREADS
555   {
556     apr_thread_mutex_t *mutex;
557 
558     check_apr_status(apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_DEFAULT,
559                                              swig_rb_pool),
560                                              rb_eLoadError, "failed to create allocator: %s");
561     apr_allocator_mutex_set(swig_rb_allocator, mutex);
562   }
563 #endif
564   apr_allocator_owner_set(swig_rb_allocator, swig_rb_pool);
565 
566   svn_utf_initialize(swig_rb_pool);
567 
568   svn_swig_rb_initialize_ids();
569 
570   mSvnConverter = rb_define_module_under(rb_svn(), "Converter");
571   rb_define_module_function(mSvnConverter, "to_locale_encoding",
572                             svn_swig_rb_converter_to_locale_encoding, 1);
573 
574   mSvnLocale = rb_define_module_under(rb_svn(), "Locale");
575   rb_define_const(mSvnLocale, "ALL", INT2NUM(LC_ALL));
576   rb_define_const(mSvnLocale, "COLLATE", INT2NUM(LC_COLLATE));
577   rb_define_const(mSvnLocale, "CTYPE", INT2NUM(LC_CTYPE));
578 #ifdef LC_MESSAGES
579   rb_define_const(mSvnLocale, "MESSAGES", INT2NUM(LC_MESSAGES));
580 #endif
581   rb_define_const(mSvnLocale, "MONETARY", INT2NUM(LC_MONETARY));
582   rb_define_const(mSvnLocale, "NUMERIC", INT2NUM(LC_NUMERIC));
583   rb_define_const(mSvnLocale, "TIME", INT2NUM(LC_TIME));
584   rb_define_module_function(mSvnLocale, "set", svn_swig_rb_locale_set, -1);
585 
586   mSvnGetText = rb_define_module_under(rb_svn(), "GetText");
587   rb_define_module_function(mSvnGetText, "bindtextdomain",
588                             svn_swig_rb_gettext_bindtextdomain, 1);
589   rb_define_module_function(mSvnGetText, "_", svn_swig_rb_gettext__, 1);
590 
591   mSvnDestroyer = rb_define_module_under(rb_svn(), "Destroyer");
592   rb_define_module_function(mSvnDestroyer, "destroy",
593                             svn_swig_rb_destroyer_destroy, 1);
594 }
595 
596 apr_pool_t *
svn_swig_rb_pool(void)597 svn_swig_rb_pool(void)
598 {
599     return swig_rb_pool;
600 }
601 
602 apr_allocator_t *
svn_swig_rb_allocator(void)603 svn_swig_rb_allocator(void)
604 {
605     return swig_rb_allocator;
606 }
607 
608 
609 /* pool holder */
610 static VALUE
rb_svn_pool_holder(void)611 rb_svn_pool_holder(void)
612 {
613   return rb_ivar_get(rb_svn_core_pool(), id___pools__);
614 }
615 
616 static VALUE
rb_svn_fs_warning_callback_baton_holder(void)617 rb_svn_fs_warning_callback_baton_holder(void)
618 {
619   return rb_ivar_get(rb_svn_fs_file_system(), id___batons__);
620 }
621 
622 static VALUE
rb_holder_push(VALUE holder,VALUE obj)623 rb_holder_push(VALUE holder, VALUE obj)
624 {
625   VALUE key, objs;
626 
627   key = rb_obj_id(obj);
628   objs = rb_hash_aref(holder, key);
629 
630   if (NIL_P(objs)) {
631     objs = rb_ary_new();
632     rb_hash_aset(holder, key, objs);
633   }
634 
635   rb_ary_push(objs, obj);
636 
637   return Qnil;
638 }
639 
640 static VALUE
rb_holder_pop(VALUE holder,VALUE obj)641 rb_holder_pop(VALUE holder, VALUE obj)
642 {
643   VALUE key, objs;
644   VALUE result = Qnil;
645 
646   key = rb_obj_id(obj);
647   objs = rb_hash_aref(holder, key);
648 
649   if (!NIL_P(objs)) {
650     result = rb_ary_pop(objs);
651     if (RARRAY_LEN(objs) == 0) {
652       rb_hash_delete(holder, key);
653     }
654   }
655 
656   return result;
657 }
658 
659 
660 /* pool */
661 static VALUE
rb_get_pool(VALUE self)662 rb_get_pool(VALUE self)
663 {
664   return rb_ivar_get(self, id___pool__);
665 }
666 
667 static VALUE
rb_pools(VALUE self)668 rb_pools(VALUE self)
669 {
670   VALUE pools = rb_ivar_get(self, id___pools__);
671 
672   if (NIL_P(pools)) {
673     pools = rb_hash_new();
674     rb_ivar_set(self, id___pools__, pools);
675   }
676 
677   return pools;
678 }
679 
680 static VALUE
rb_set_pool(VALUE self,VALUE pool)681 rb_set_pool(VALUE self, VALUE pool)
682 {
683   if (NIL_P(pool)) {
684     VALUE old_pool = rb_ivar_get(self, id___pool__);
685     rb_hash_aset(rb_pools(self), rb_obj_id(old_pool), old_pool);
686     rb_ivar_set(self, id___pool__, Qnil);
687   } else {
688     if (NIL_P(rb_ivar_get(self, id___pool__))) {
689       rb_ivar_set(self, id___pool__, pool);
690     } else {
691       rb_hash_aset(rb_pools(self), rb_obj_id(pool), pool);
692     }
693   }
694 
695   return Qnil;
696 }
697 
698 static VALUE
rb_pool_new(VALUE parent)699 rb_pool_new(VALUE parent)
700 {
701   return rb_funcall(rb_svn_core_pool(), id_new, 1, parent);
702 }
703 
704 void
svn_swig_rb_get_pool(int argc,VALUE * argv,VALUE self,VALUE * rb_pool,apr_pool_t ** pool)705 svn_swig_rb_get_pool(int argc, VALUE *argv, VALUE self,
706                      VALUE *rb_pool, apr_pool_t **pool)
707 {
708   *rb_pool = Qnil;
709 
710   if (argc > 0) {
711     if (POOL_P(argv[argc - 1])) {
712       *rb_pool = rb_pool_new(argv[argc - 1]);
713       argc -= 1;
714     }
715   }
716 
717   if (NIL_P(*rb_pool) && !NIL_P(self)) {
718     *rb_pool = rb_get_pool(self);
719     if (POOL_P(*rb_pool)) {
720       *rb_pool = rb_pool_new(*rb_pool);
721     } else {
722       *rb_pool = Qnil;
723     }
724   }
725 
726   if (NIL_P(*rb_pool)) {
727     VALUE target;
728     target = find_swig_type_object(argc, argv);
729     *rb_pool = rb_pool_new(rb_get_pool(target));
730   }
731 
732   if (pool) {
733     apr_pool_wrapper_t *pool_wrapper;
734     apr_pool_wrapper_t **pool_wrapper_p;
735 
736     pool_wrapper_p = &pool_wrapper;
737     r2c_swig_type2(*rb_pool, "apr_pool_wrapper_t *", (void **)pool_wrapper_p);
738     *pool = pool_wrapper->pool;
739   }
740 }
741 
742 static svn_boolean_t
rb_set_pool_if_swig_type_object(VALUE target,VALUE pool)743 rb_set_pool_if_swig_type_object(VALUE target, VALUE pool)
744 {
745   VALUE targets[1];
746 
747   targets[0] = target;
748 
749   if (!NIL_P(find_swig_type_object(1, targets))) {
750     rb_set_pool(target, pool);
751     return TRUE;
752   } else {
753     return FALSE;
754   }
755 }
756 
757 struct rb_set_pool_for_hash_arg {
758   svn_boolean_t set;
759   VALUE pool;
760 };
761 
762 static int
rb_set_pool_for_hash_callback(VALUE key,VALUE value,struct rb_set_pool_for_hash_arg * arg)763 rb_set_pool_for_hash_callback(VALUE key, VALUE value,
764                               struct rb_set_pool_for_hash_arg *arg)
765 {
766   if (svn_swig_rb_set_pool(value, arg->pool))
767     arg->set = TRUE;
768   return ST_CONTINUE;
769 }
770 
771 svn_boolean_t
svn_swig_rb_set_pool(VALUE target,VALUE pool)772 svn_swig_rb_set_pool(VALUE target, VALUE pool)
773 {
774   if (NIL_P(target)) {
775     return FALSE;
776   }
777 
778   if (RTEST(rb_obj_is_kind_of(target, rb_cArray))) {
779     long i;
780     svn_boolean_t set = FALSE;
781 
782     for (i = 0; i < RARRAY_LEN(target); i++) {
783       if (svn_swig_rb_set_pool(RARRAY_PTR(target)[i], pool))
784         set = TRUE;
785     }
786     return set;
787   } else if (RTEST(rb_obj_is_kind_of(target, rb_cHash))) {
788     struct rb_set_pool_for_hash_arg arg;
789     arg.set = FALSE;
790     arg.pool = pool;
791     rb_hash_foreach(target, rb_set_pool_for_hash_callback, (VALUE)&arg);
792     return arg.set;
793   } else {
794     return rb_set_pool_if_swig_type_object(target, pool);
795   }
796 }
797 
798 void
svn_swig_rb_set_pool_for_no_swig_type(VALUE target,VALUE pool)799 svn_swig_rb_set_pool_for_no_swig_type(VALUE target, VALUE pool)
800 {
801   if (NIL_P(target)) {
802     return;
803   }
804 
805   if (!RTEST(rb_obj_is_kind_of(target, rb_cArray))) {
806     target = rb_ary_new3(1, target);
807   }
808 
809   rb_iterate(rb_each, target, rb_set_pool, pool);
810 }
811 
812 void
svn_swig_rb_push_pool(VALUE pool)813 svn_swig_rb_push_pool(VALUE pool)
814 {
815   if (!NIL_P(pool)) {
816     rb_holder_push(rb_svn_pool_holder(), pool);
817   }
818 }
819 
820 void
svn_swig_rb_pop_pool(VALUE pool)821 svn_swig_rb_pop_pool(VALUE pool)
822 {
823   if (!NIL_P(pool)) {
824     rb_holder_pop(rb_svn_pool_holder(), pool);
825   }
826 }
827 
828 void
svn_swig_rb_destroy_pool(VALUE pool)829 svn_swig_rb_destroy_pool(VALUE pool)
830 {
831   if (!NIL_P(pool)) {
832     rb_funcall(pool, id_destroy, 0);
833   }
834 }
835 
836 void
svn_swig_rb_destroy_internal_pool(VALUE object)837 svn_swig_rb_destroy_internal_pool(VALUE object)
838 {
839   svn_swig_rb_destroy_pool(rb_get_pool(object));
840 }
841 
842 
843 /* error */
844 void
svn_swig_rb_raise_svn_fs_already_close(void)845 svn_swig_rb_raise_svn_fs_already_close(void)
846 {
847   static VALUE rb_svn_error_fs_already_close = 0;
848 
849   if (!rb_svn_error_fs_already_close) {
850     rb_svn_error_fs_already_close =
851       rb_const_get(rb_svn_error(), rb_intern("FsAlreadyClose"));
852   }
853 
854   rb_raise(rb_svn_error_fs_already_close, "closed file system");
855 }
856 
857 void
svn_swig_rb_raise_svn_repos_already_close(void)858 svn_swig_rb_raise_svn_repos_already_close(void)
859 {
860   static VALUE rb_svn_error_repos_already_close = 0;
861 
862   if (!rb_svn_error_repos_already_close) {
863     rb_svn_error_repos_already_close =
864       rb_const_get(rb_svn_error(), rb_intern("ReposAlreadyClose"));
865   }
866 
867   rb_raise(rb_svn_error_repos_already_close, "closed repository");
868 }
869 
870 VALUE
svn_swig_rb_svn_error_new(VALUE code,VALUE message,VALUE file,VALUE line,VALUE child)871 svn_swig_rb_svn_error_new(VALUE code, VALUE message, VALUE file, VALUE line,
872                           VALUE child)
873 {
874   return rb_funcall(rb_svn_error_svn_error(),
875                     id_new_corresponding_error,
876                     5, code, message, file, line, child);
877 }
878 
879 VALUE
svn_swig_rb_svn_error_to_rb_error(svn_error_t * error)880 svn_swig_rb_svn_error_to_rb_error(svn_error_t *error)
881 {
882   VALUE error_code = INT2NUM(error->apr_err);
883   VALUE message;
884   VALUE file = Qnil;
885   VALUE line = Qnil;
886   VALUE child = Qnil;
887 
888   if (error->file)
889     file = rb_str_new2(error->file);
890   if (error->line)
891     line = LONG2NUM(error->line);
892 
893   message = rb_str_new2(error->message ? error->message : "");
894 
895   if (error->child)
896       child = svn_swig_rb_svn_error_to_rb_error(error->child);
897 
898   return svn_swig_rb_svn_error_new(error_code, message, file, line, child);
899 }
900 
901 void
svn_swig_rb_handle_svn_error(svn_error_t * error)902 svn_swig_rb_handle_svn_error(svn_error_t *error)
903 {
904   VALUE rb_error = svn_swig_rb_svn_error_to_rb_error(error);
905   svn_error_clear(error);
906   rb_exc_raise(rb_error);
907 }
908 
909 
910 static VALUE inited = Qnil;
911 /* C -> Ruby */
912 VALUE
svn_swig_rb_from_swig_type(void * value,void * ctx)913 svn_swig_rb_from_swig_type(void *value, void *ctx)
914 {
915   swig_type_info *info;
916 
917   if (NIL_P(inited)) {
918     SWIG_InitRuntime();
919     inited = Qtrue;
920   }
921 
922   info = SWIG_TypeQuery((char *)ctx);
923   if (info) {
924     return SWIG_NewPointerObj(value, info, 0);
925   } else {
926     rb_raise(rb_eArgError, "invalid SWIG type: %s", (char *)ctx);
927   }
928 }
929 #define c2r_swig_type svn_swig_rb_from_swig_type
930 
931 svn_depth_t
svn_swig_rb_to_depth(VALUE value)932 svn_swig_rb_to_depth(VALUE value)
933 {
934   if (NIL_P(value)) {
935     return svn_depth_infinity;
936   } else if (value == Qtrue) {
937     return SVN_DEPTH_INFINITY_OR_FILES(TRUE);
938   } else if (value == Qfalse) {
939     return SVN_DEPTH_INFINITY_OR_FILES(FALSE);
940   } else if (RTEST(rb_obj_is_kind_of(value, rb_cString)) ||
941              RTEST(rb_obj_is_kind_of(value, rb_cSymbol))) {
942     value = rb_funcall(value, id_to_s, 0);
943     return svn_depth_from_word(StringValueCStr(value));
944   } else if (RTEST(rb_obj_is_kind_of(value, rb_cInteger))) {
945     return NUM2INT(value);
946   } else {
947     rb_raise(rb_eArgError,
948              "'%s' must be DEPTH_STRING (e.g. \"infinity\" or :infinity) "
949              "or Svn::Core::DEPTH_*",
950              r2c_inspect(value));
951   }
952 }
953 
954 svn_mergeinfo_inheritance_t
svn_swig_rb_to_mergeinfo_inheritance(VALUE value)955 svn_swig_rb_to_mergeinfo_inheritance(VALUE value)
956 {
957   if (NIL_P(value)) {
958     return svn_mergeinfo_inherited;
959   } else if (RTEST(rb_obj_is_kind_of(value, rb_cString)) ||
960              RTEST(rb_obj_is_kind_of(value, rb_cSymbol))) {
961     value = rb_funcall(value, id_to_s, 0);
962     return svn_inheritance_from_word(StringValueCStr(value));
963   } else if (RTEST(rb_obj_is_kind_of(value, rb_cInteger))) {
964     return NUM2INT(value);
965   } else {
966     rb_raise(rb_eArgError,
967        "'%s' must be MERGEINFO_STRING (e.g. \"explicit\" or :explicit) "
968        "or Svn::Core::MERGEINFO_*",
969        r2c_inspect(value));
970   }
971 }
972 
973 static VALUE
c2r_string(void * value,void * ctx)974 c2r_string(void *value, void *ctx)
975 {
976   if (value) {
977     return rb_str_new2((const char *)value);
978   } else {
979     return Qnil;
980   }
981 }
982 
983 static VALUE
c2r_string2(const char * cstr)984 c2r_string2(const char *cstr)
985 {
986   return c2r_string((void *)cstr, NULL);
987 }
988 
989 #define c2r_bool2(bool) (bool ? Qtrue : Qfalse)
990 
991 VALUE
svn_swig_rb_svn_date_string_to_time(const char * date)992 svn_swig_rb_svn_date_string_to_time(const char *date)
993 {
994   if (date) {
995     apr_time_t tm;
996     svn_error_t *error;
997     apr_pool_t *pool;
998 
999     pool = svn_pool_create(NULL);
1000     error = svn_time_from_cstring(&tm, date, pool);
1001     svn_pool_destroy(pool);
1002     if (error)
1003       svn_swig_rb_handle_svn_error(error);
1004     return rb_time_new((time_t)apr_time_sec(tm), (time_t)apr_time_usec(tm));
1005   } else {
1006     return Qnil;
1007   }
1008 }
1009 #define c2r_svn_date_string2 svn_swig_rb_svn_date_string_to_time
1010 
1011 static VALUE
c2r_long(void * value,void * ctx)1012 c2r_long(void *value, void *ctx)
1013 {
1014   return INT2NUM(*(long *)value);
1015 }
1016 
1017 static VALUE
c2r_svn_string(void * value,void * ctx)1018 c2r_svn_string(void *value, void *ctx)
1019 {
1020   const svn_string_t *s = (svn_string_t *)value;
1021 
1022   return c2r_string2(s->data);
1023 }
1024 
1025 typedef struct prop_hash_each_arg_t {
1026   apr_array_header_t *array;
1027   apr_pool_t *pool;
1028 } prop_hash_each_arg_t;
1029 
1030 static int
svn_swig_rb_to_apr_array_row_prop_callback(VALUE key,VALUE value,prop_hash_each_arg_t * arg)1031 svn_swig_rb_to_apr_array_row_prop_callback(VALUE key, VALUE value,
1032                                            prop_hash_each_arg_t *arg)
1033 {
1034   svn_prop_t *prop;
1035 
1036   prop = apr_array_push(arg->array);
1037   prop->name = apr_pstrdup(arg->pool, StringValueCStr(key));
1038   prop->value = svn_string_ncreate(RSTRING_PTR(value), RSTRING_LEN(value),
1039                                    arg->pool);
1040   return ST_CONTINUE;
1041 }
1042 
1043 apr_array_header_t *
svn_swig_rb_to_apr_array_row_prop(VALUE array_or_hash,apr_pool_t * pool)1044 svn_swig_rb_to_apr_array_row_prop(VALUE array_or_hash, apr_pool_t *pool)
1045 {
1046   if (RTEST(rb_obj_is_kind_of(array_or_hash, rb_cArray))) {
1047     int i, len;
1048     apr_array_header_t *result;
1049 
1050     len = RARRAY_LEN(array_or_hash);
1051     result = apr_array_make(pool, len, sizeof(svn_prop_t));
1052     result->nelts = len;
1053     for (i = 0; i < len; i++) {
1054       VALUE name, value, item;
1055       svn_prop_t *prop;
1056 
1057       item = rb_ary_entry(array_or_hash, i);
1058       name = rb_funcall(item, id_name, 0);
1059       value = rb_funcall(item, id_value, 0);
1060       prop = &APR_ARRAY_IDX(result, i, svn_prop_t);
1061       prop->name = apr_pstrdup(pool, StringValueCStr(name));
1062       prop->value = svn_string_ncreate(RSTRING_PTR(value), RSTRING_LEN(value),
1063                                        pool);
1064     }
1065     return result;
1066   } else if (RTEST(rb_obj_is_kind_of(array_or_hash, rb_cHash))) {
1067     apr_array_header_t *result;
1068     prop_hash_each_arg_t arg;
1069 
1070     result = apr_array_make(pool, 0, sizeof(svn_prop_t));
1071     arg.array = result;
1072     arg.pool = pool;
1073     rb_hash_foreach(array_or_hash, svn_swig_rb_to_apr_array_row_prop_callback,
1074                     (VALUE)&arg);
1075     return result;
1076   } else {
1077     rb_raise(rb_eArgError,
1078              "'%s' must be [Svn::Core::Prop, ...] or {'name' => 'value', ...}",
1079              r2c_inspect(array_or_hash));
1080   }
1081 }
1082 
1083 static int
svn_swig_rb_to_apr_array_prop_callback(VALUE key,VALUE value,prop_hash_each_arg_t * arg)1084 svn_swig_rb_to_apr_array_prop_callback(VALUE key, VALUE value,
1085                                        prop_hash_each_arg_t *arg)
1086 {
1087   svn_prop_t *prop;
1088 
1089   prop = apr_palloc(arg->pool, sizeof(svn_prop_t));
1090   prop->name = apr_pstrdup(arg->pool, StringValueCStr(key));
1091   prop->value = svn_string_ncreate(RSTRING_PTR(value), RSTRING_LEN(value),
1092                                    arg->pool);
1093   APR_ARRAY_PUSH(arg->array, svn_prop_t *) = prop;
1094   return ST_CONTINUE;
1095 }
1096 
1097 apr_array_header_t *
svn_swig_rb_to_apr_array_prop(VALUE array_or_hash,apr_pool_t * pool)1098 svn_swig_rb_to_apr_array_prop(VALUE array_or_hash, apr_pool_t *pool)
1099 {
1100   if (RTEST(rb_obj_is_kind_of(array_or_hash, rb_cArray))) {
1101     int i, len;
1102     apr_array_header_t *result;
1103 
1104     len = RARRAY_LEN(array_or_hash);
1105     result = apr_array_make(pool, len, sizeof(svn_prop_t *));
1106     result->nelts = len;
1107     for (i = 0; i < len; i++) {
1108       VALUE name, value, item;
1109       svn_prop_t *prop;
1110 
1111       item = rb_ary_entry(array_or_hash, i);
1112       name = rb_funcall(item, id_name, 0);
1113       value = rb_funcall(item, id_value, 0);
1114       prop = apr_palloc(pool, sizeof(svn_prop_t));
1115       prop->name = apr_pstrdup(pool, StringValueCStr(name));
1116       prop->value = svn_string_ncreate(RSTRING_PTR(value), RSTRING_LEN(value),
1117                                        pool);
1118       APR_ARRAY_IDX(result, i, svn_prop_t *) = prop;
1119     }
1120     return result;
1121   } else if (RTEST(rb_obj_is_kind_of(array_or_hash, rb_cHash))) {
1122     apr_array_header_t *result;
1123     prop_hash_each_arg_t arg;
1124 
1125     result = apr_array_make(pool, 0, sizeof(svn_prop_t *));
1126     arg.array = result;
1127     arg.pool = pool;
1128     rb_hash_foreach(array_or_hash, svn_swig_rb_to_apr_array_prop_callback,
1129                     (VALUE)&arg);
1130     return result;
1131   } else {
1132     rb_raise(rb_eArgError,
1133              "'%s' must be [Svn::Core::Prop, ...] or {'name' => 'value', ...}",
1134              r2c_inspect(array_or_hash));
1135   }
1136 }
1137 
1138 
1139 /* C -> Ruby (dup) */
1140 #define DEFINE_DUP_BASE(type, dup_func, type_prefix)                         \
1141 static VALUE                                                                 \
1142 c2r_ ## type ## _dup(void *type, void *ctx)                                  \
1143 {                                                                            \
1144   apr_pool_t *pool;                                                          \
1145   VALUE rb_pool;                                                             \
1146   svn_ ## type ## _t *copied_item;                                           \
1147   VALUE rb_copied_item;                                                      \
1148                                                                              \
1149   if (!type)                                                                 \
1150     return Qnil;                                                             \
1151                                                                              \
1152   svn_swig_rb_get_pool(0, (VALUE *)0, 0, &rb_pool, &pool);                   \
1153   copied_item = svn_ ## dup_func((type_prefix svn_ ## type ## _t *)type,     \
1154                                   pool);                                     \
1155   rb_copied_item = c2r_swig_type((void *)copied_item,                        \
1156                                  (void *)"svn_" # type "_t *");              \
1157   rb_set_pool(rb_copied_item, rb_pool);                                      \
1158                                                                              \
1159   return rb_copied_item;                                                     \
1160 }
1161 
1162 #define DEFINE_DUP_BASE_WITH_CONVENIENCE(type, dup_func, type_prefix)   \
1163 DEFINE_DUP_BASE(type, dup_func, type_prefix)                            \
1164 static VALUE                                                            \
1165 c2r_ ## type ## __dup(type_prefix svn_ ## type ## _t *type)             \
1166 {                                                                       \
1167   void *void_type;                                                      \
1168   void_type = (void *)type;                                             \
1169   return c2r_ ## type ## _dup(void_type, NULL);                         \
1170 }
1171 
1172 #define DEFINE_DUP_WITH_FUNCTION_NAME(type, dup_func) \
1173   DEFINE_DUP_BASE_WITH_CONVENIENCE(type, dup_func, const)
1174 #define DEFINE_DUP(type) \
1175   DEFINE_DUP_WITH_FUNCTION_NAME(type, type ## _dup)
1176 
1177 #define DEFINE_DUP_NO_CONVENIENCE_WITH_FUNCTION_NAME(type, dup_func) \
1178   DEFINE_DUP_BASE(type, dup_func, const)
1179 #define DEFINE_DUP_NO_CONVENIENCE(type) \
1180   DEFINE_DUP_NO_CONVENIENCE_WITH_FUNCTION_NAME(type, type ## _dup)
1181 
1182 #define DEFINE_DUP_NO_CONST_WITH_FUNCTION_NAME(type, dup_func) \
1183   DEFINE_DUP_BASE_WITH_CONVENIENCE(type, dup_func,)
1184 #define DEFINE_DUP_NO_CONST(type) \
1185   DEFINE_DUP_NO_CONST_WITH_FUNCTION_NAME(type, type ## _dup)
1186 
1187 #define DEFINE_DUP_NO_CONST_NO_CONVENIENCE_WITH_FUNCTION_NAME(type, dup_func) \
1188   DEFINE_DUP_BASE(type, dup_func,)
1189 #define DEFINE_DUP_NO_CONST_NO_CONVENIENCE(type) \
1190   DEFINE_DUP_NO_CONST_NO_CONVENIENCE_WITH_FUNCTION_NAME(type, type ## _dup)
1191 
1192 
DEFINE_DUP_WITH_FUNCTION_NAME(wc_notify,wc_dup_notify)1193 DEFINE_DUP_WITH_FUNCTION_NAME(wc_notify, wc_dup_notify)
1194 DEFINE_DUP(txdelta_window)
1195 DEFINE_DUP(info)
1196 DEFINE_DUP(commit_info)
1197 DEFINE_DUP(lock)
1198 DEFINE_DUP(auth_ssl_server_cert_info)
1199 DEFINE_DUP(wc_entry)
1200 DEFINE_DUP(client_diff_summarize)
1201 DEFINE_DUP(dirent)
1202 DEFINE_DUP(log_entry)
1203 DEFINE_DUP_NO_CONVENIENCE(client_commit_item3)
1204 DEFINE_DUP_NO_CONVENIENCE(client_proplist_item)
1205 DEFINE_DUP_NO_CONVENIENCE(wc_external_item2)
1206 DEFINE_DUP_NO_CONVENIENCE(log_changed_path)
1207 DEFINE_DUP_NO_CONST_WITH_FUNCTION_NAME(wc_status2, wc_dup_status2)
1208 DEFINE_DUP_NO_CONST_NO_CONVENIENCE(merge_range)
1209 
1210 
1211 /* Ruby -> C */
1212 static const char *
1213 r2c_inspect(VALUE object)
1214 {
1215   VALUE inspected;
1216   inspected = rb_funcall(object, id_inspect, 0);
1217   return StringValueCStr(inspected);
1218 }
1219 
1220 static void *
r2c_string(VALUE value,void * ctx,apr_pool_t * pool)1221 r2c_string(VALUE value, void *ctx, apr_pool_t *pool)
1222 {
1223   return (void *)apr_pstrdup(pool, StringValuePtr(value));
1224 }
1225 
1226 static void *
r2c_svn_string(VALUE value,void * ctx,apr_pool_t * pool)1227 r2c_svn_string(VALUE value, void *ctx, apr_pool_t *pool)
1228 {
1229   return (void *)svn_string_create(StringValuePtr(value), pool);
1230 }
1231 
1232 void *
svn_swig_rb_to_swig_type(VALUE value,const void * ctx,apr_pool_t * pool)1233 svn_swig_rb_to_swig_type(VALUE value, const void *ctx, apr_pool_t *pool)
1234 {
1235   void **result = NULL;
1236   result = apr_palloc(pool, sizeof(void *));
1237   r2c_swig_type2(value, (const char *)ctx, result);
1238   return *result;
1239 }
1240 #define r2c_swig_type svn_swig_rb_to_swig_type
1241 
1242 static void
r2c_swig_type2(VALUE value,const char * type_name,void ** result)1243 r2c_swig_type2(VALUE value, const char *type_name, void **result)
1244 {
1245 #ifdef SWIG_IsOK
1246   int res;
1247   res = SWIG_ConvertPtr(value, result, SWIG_TypeQuery(type_name),
1248                         SWIG_POINTER_EXCEPTION);
1249   if (!SWIG_IsOK(res)) {
1250     VALUE message = rb_funcall(value, rb_intern("inspect"), 0);
1251     rb_str_cat2(message, "must be ");
1252     rb_str_cat2(message, type_name);
1253     SWIG_Error(SWIG_ArgError(res), StringValuePtr(message));
1254   }
1255 #endif
1256 }
1257 
1258 static void *
r2c_long(VALUE value,void * ctx,apr_pool_t * pool)1259 r2c_long(VALUE value, void *ctx, apr_pool_t *pool)
1260 {
1261   return (void *)NUM2LONG(value);
1262 }
1263 
1264 static void *
r2c_svn_err(VALUE rb_svn_err,void * ctx,apr_pool_t * pool)1265 r2c_svn_err(VALUE rb_svn_err, void *ctx, apr_pool_t *pool)
1266 {
1267   VALUE message;
1268   svn_error_t *err;
1269 
1270   message = rb_funcall(rb_svn_err, id_message, 0);
1271   err = svn_error_create(NUM2INT(rb_funcall(rb_svn_err, id_code, 0)),
1272                          NULL,
1273                          StringValuePtr(message));
1274   return (void *)err;
1275 }
1276 
1277 static void *
r2c_revnum(VALUE value,void * ctx,apr_pool_t * pool)1278 r2c_revnum(VALUE value, void *ctx, apr_pool_t *pool)
1279 {
1280   svn_revnum_t *revnum;
1281   revnum = apr_palloc(pool, sizeof(svn_revnum_t));
1282   *revnum = NUM2INT(value);
1283   return revnum;
1284 }
1285 
1286 static void *
r2c_merge_range(VALUE value,void * ctx,apr_pool_t * pool)1287 r2c_merge_range(VALUE value, void *ctx, apr_pool_t *pool)
1288 {
1289   return svn_swig_rb_array_to_apr_array_merge_range(value, pool);
1290 }
1291 
1292 
1293 /* apr_array_t -> Ruby Array */
1294 #define DEFINE_APR_ARRAY_TO_ARRAY(return_type, name, conv, amp, type, ctx)  \
1295 return_type                                                                 \
1296 name(const apr_array_header_t *apr_ary)                                     \
1297 {                                                                           \
1298   VALUE ary = rb_ary_new();                                                 \
1299   int i;                                                                    \
1300                                                                             \
1301   for (i = 0; i < apr_ary->nelts; i++) {                                    \
1302     rb_ary_push(ary, conv((void *)amp(APR_ARRAY_IDX(apr_ary, i, type)),     \
1303                           ctx));                                            \
1304   }                                                                         \
1305                                                                             \
1306   return ary;                                                               \
1307 }
1308 
DEFINE_APR_ARRAY_TO_ARRAY(VALUE,svn_swig_rb_apr_array_to_array_string,c2r_string,EMPTY_CPP_ARGUMENT,const char *,NULL)1309 DEFINE_APR_ARRAY_TO_ARRAY(VALUE, svn_swig_rb_apr_array_to_array_string,
1310                           c2r_string, EMPTY_CPP_ARGUMENT, const char *, NULL)
1311 DEFINE_APR_ARRAY_TO_ARRAY(VALUE, svn_swig_rb_apr_array_to_array_svn_string,
1312                           c2r_svn_string, &, svn_string_t, NULL)
1313 DEFINE_APR_ARRAY_TO_ARRAY(static VALUE, c2r_commit_item3_array,
1314                           c2r_client_commit_item3_dup, EMPTY_CPP_ARGUMENT,
1315                           svn_client_commit_item3_t *, NULL)
1316 DEFINE_APR_ARRAY_TO_ARRAY(VALUE, svn_swig_rb_apr_array_to_array_svn_rev,
1317                           c2r_long, &, svn_revnum_t, NULL)
1318 DEFINE_APR_ARRAY_TO_ARRAY(VALUE, svn_swig_rb_apr_array_to_array_proplist_item,
1319                           c2r_client_proplist_item_dup, EMPTY_CPP_ARGUMENT,
1320                           svn_client_proplist_item_t *, NULL)
1321 DEFINE_APR_ARRAY_TO_ARRAY(VALUE, svn_swig_rb_apr_array_to_array_external_item2,
1322                           c2r_wc_external_item2_dup, EMPTY_CPP_ARGUMENT,
1323                           svn_wc_external_item2_t *, NULL)
1324 DEFINE_APR_ARRAY_TO_ARRAY(VALUE, svn_swig_rb_apr_array_to_array_merge_range,
1325                           c2r_merge_range_dup, EMPTY_CPP_ARGUMENT,
1326                           svn_merge_range_t *, NULL)
1327 DEFINE_APR_ARRAY_TO_ARRAY(VALUE, svn_swig_rb_apr_array_to_array_auth_provider_object,
1328                           c2r_swig_type, EMPTY_CPP_ARGUMENT,
1329                           svn_auth_provider_object_t *, "svn_auth_provider_object_t*")
1330 
1331 static VALUE
1332 c2r_merge_range_array(void *value, void *ctx)
1333 {
1334   return svn_swig_rb_apr_array_to_array_merge_range(value);
1335 }
1336 
1337 VALUE
svn_swig_rb_prop_apr_array_to_hash_prop(const apr_array_header_t * apr_ary)1338 svn_swig_rb_prop_apr_array_to_hash_prop(const apr_array_header_t *apr_ary)
1339 {
1340   VALUE hash;
1341   int i;
1342 
1343   hash = rb_hash_new();
1344   for (i = 0; i < apr_ary->nelts; i++) {
1345     svn_prop_t prop;
1346     prop = APR_ARRAY_IDX(apr_ary, i, svn_prop_t);
1347     rb_hash_aset(hash,
1348                  prop.name ? rb_str_new2(prop.name) : Qnil,
1349                  prop.value && prop.value->data ?
1350                    rb_str_new2(prop.value->data) : Qnil);
1351   }
1352 
1353   return hash;
1354 }
1355 
1356 apr_array_header_t *
svn_swig_rb_array_to_apr_array_revision_range(VALUE array,apr_pool_t * pool)1357 svn_swig_rb_array_to_apr_array_revision_range(VALUE array, apr_pool_t *pool)
1358 {
1359   int i, len;
1360   apr_array_header_t *apr_ary;
1361 
1362   Check_Type(array, T_ARRAY);
1363   len = RARRAY_LEN(array);
1364   apr_ary = apr_array_make(pool, len, sizeof(svn_opt_revision_range_t *));
1365   apr_ary->nelts = len;
1366   for (i = 0; i < len; i++) {
1367     VALUE value;
1368     svn_opt_revision_range_t *range;
1369 
1370     value = rb_ary_entry(array, i);
1371     if (RTEST(rb_obj_is_kind_of(value, rb_cArray))) {
1372       if (RARRAY_LEN(value) != 2)
1373         rb_raise(rb_eArgError,
1374                  "revision range should be [start, end]: %s",
1375                  r2c_inspect(value));
1376       range = apr_palloc(pool, sizeof(*range));
1377       svn_swig_rb_set_revision(&range->start, rb_ary_entry(value, 0));
1378       svn_swig_rb_set_revision(&range->end, rb_ary_entry(value, 1));
1379     } else {
1380       range = r2c_swig_type(value, (void *)"svn_opt_revision_range_t *", pool);
1381     }
1382     APR_ARRAY_IDX(apr_ary, i, svn_opt_revision_range_t *) = range;
1383   }
1384   return apr_ary;
1385 }
1386 
1387 
1388 
1389 /* Ruby Array -> apr_array_t */
1390 #define DEFINE_ARRAY_TO_APR_ARRAY(type, name, converter, context) \
1391 apr_array_header_t *                                              \
1392 name(VALUE array, apr_pool_t *pool)                               \
1393 {                                                                 \
1394   int i, len;                                                     \
1395   apr_array_header_t *apr_ary;                                    \
1396                                                                   \
1397   Check_Type(array, T_ARRAY);                                     \
1398   len = RARRAY_LEN(array);                                       \
1399   apr_ary = apr_array_make(pool, len, sizeof(type));              \
1400   apr_ary->nelts = len;                                           \
1401   for (i = 0; i < len; i++) {                                     \
1402     VALUE value;                                                  \
1403     type val;                                                     \
1404     value = rb_ary_entry(array, i);                               \
1405     val = (type)converter(value, context, pool);                  \
1406     APR_ARRAY_IDX(apr_ary, i, type) = val;                        \
1407   }                                                               \
1408   return apr_ary;                                                 \
1409 }
1410 
DEFINE_ARRAY_TO_APR_ARRAY(const char *,svn_swig_rb_strings_to_apr_array,r2c_string,NULL)1411 DEFINE_ARRAY_TO_APR_ARRAY(const char *, svn_swig_rb_strings_to_apr_array,
1412                           r2c_string, NULL)
1413 DEFINE_ARRAY_TO_APR_ARRAY(svn_auth_provider_object_t *,
1414                           svn_swig_rb_array_to_auth_provider_object_apr_array,
1415                           r2c_swig_type, (void *)"svn_auth_provider_object_t *")
1416 DEFINE_ARRAY_TO_APR_ARRAY(svn_revnum_t,
1417                           svn_swig_rb_array_to_apr_array_revnum,
1418                           r2c_long, NULL)
1419 DEFINE_ARRAY_TO_APR_ARRAY(svn_merge_range_t *,
1420                           svn_swig_rb_array_to_apr_array_merge_range,
1421                           r2c_swig_type, (void *)"svn_merge_range_t *")
1422 DEFINE_ARRAY_TO_APR_ARRAY(svn_client_copy_source_t *,
1423                           svn_swig_rb_array_to_apr_array_copy_source,
1424                           r2c_swig_type, (void *)"svn_client_copy_source_t *")
1425 
1426 
1427 /* apr_hash_t -> Ruby Hash */
1428 static VALUE
1429 c2r_hash_with_key_convert(apr_hash_t *hash,
1430                           c2r_func key_conv,
1431                           void *key_ctx,
1432                           c2r_func value_conv,
1433                           void *value_ctx)
1434 {
1435   apr_hash_index_t *hi;
1436   VALUE r_hash;
1437 
1438   if (!hash)
1439     return Qnil;
1440 
1441   r_hash = rb_hash_new();
1442 
1443   for (hi = apr_hash_first(NULL, hash); hi; hi = apr_hash_next(hi)) {
1444     const void *key;
1445     void *val;
1446     VALUE v = Qnil;
1447 
1448     apr_hash_this(hi, &key, NULL, &val);
1449     if (val) {
1450       v = (*value_conv)(val, value_ctx);
1451     }
1452     rb_hash_aset(r_hash, (*key_conv)((void *)key, key_ctx), v);
1453   }
1454 
1455   return r_hash;
1456 }
1457 
1458 static VALUE
c2r_hash(apr_hash_t * hash,c2r_func value_conv,void * ctx)1459 c2r_hash(apr_hash_t *hash,
1460          c2r_func value_conv,
1461          void *ctx)
1462 {
1463   return c2r_hash_with_key_convert(hash, c2r_string, NULL, value_conv, ctx);
1464 }
1465 
1466 VALUE
svn_swig_rb_apr_hash_to_hash_string(apr_hash_t * hash)1467 svn_swig_rb_apr_hash_to_hash_string(apr_hash_t *hash)
1468 {
1469   return c2r_hash(hash, c2r_string, NULL);
1470 }
1471 
1472 VALUE
svn_swig_rb_apr_hash_to_hash_svn_string(apr_hash_t * hash)1473 svn_swig_rb_apr_hash_to_hash_svn_string(apr_hash_t *hash)
1474 {
1475   return c2r_hash(hash, c2r_svn_string, NULL);
1476 }
1477 
1478 VALUE
svn_swig_rb_apr_hash_to_hash_swig_type(apr_hash_t * hash,const char * type_name)1479 svn_swig_rb_apr_hash_to_hash_swig_type(apr_hash_t *hash, const char *type_name)
1480 {
1481   return c2r_hash(hash, c2r_swig_type, (void *)type_name);
1482 }
1483 
1484 VALUE
svn_swig_rb_apr_hash_to_hash_merge_range(apr_hash_t * hash)1485 svn_swig_rb_apr_hash_to_hash_merge_range(apr_hash_t *hash)
1486 {
1487   return c2r_hash(hash, c2r_merge_range_array, NULL);
1488 }
1489 
1490 static VALUE
c2r_merge_range_hash(void * value,void * ctx)1491 c2r_merge_range_hash(void *value, void *ctx)
1492 {
1493   apr_hash_t *hash = value;
1494 
1495   return svn_swig_rb_apr_hash_to_hash_merge_range(hash);
1496 }
1497 
1498 VALUE
svn_swig_rb_apr_hash_to_hash_merge_range_hash(apr_hash_t * hash)1499 svn_swig_rb_apr_hash_to_hash_merge_range_hash(apr_hash_t *hash)
1500 {
1501   return c2r_hash(hash, c2r_merge_range_hash, NULL);
1502 }
1503 
1504 VALUE
svn_swig_rb_prop_hash_to_hash(apr_hash_t * prop_hash)1505 svn_swig_rb_prop_hash_to_hash(apr_hash_t *prop_hash)
1506 {
1507   return svn_swig_rb_apr_hash_to_hash_svn_string(prop_hash);
1508 }
1509 
1510 static VALUE
c2r_revnum(void * value,void * ctx)1511 c2r_revnum(void *value, void *ctx)
1512 {
1513   svn_revnum_t *num = value;
1514   return INT2NUM(*num);
1515 }
1516 
1517 VALUE
svn_swig_rb_apr_revnum_key_hash_to_hash_string(apr_hash_t * hash)1518 svn_swig_rb_apr_revnum_key_hash_to_hash_string(apr_hash_t *hash)
1519 {
1520   return c2r_hash_with_key_convert(hash, c2r_revnum, NULL, c2r_string, NULL);
1521 }
1522 
1523 
1524 /* Ruby Hash -> apr_hash_t */
1525 static int
r2c_hash_i(VALUE key,VALUE value,hash_to_apr_hash_data_t * data)1526 r2c_hash_i(VALUE key, VALUE value, hash_to_apr_hash_data_t *data)
1527 {
1528   if (key != Qundef) {
1529     void *val = data->func(value, data->ctx, data->pool);
1530     svn_hash_sets(data->apr_hash, apr_pstrdup(data->pool, StringValuePtr(key)),
1531                   val);
1532   }
1533   return ST_CONTINUE;
1534 }
1535 
1536 static apr_hash_t *
r2c_hash(VALUE hash,r2c_func func,void * ctx,apr_pool_t * pool)1537 r2c_hash(VALUE hash, r2c_func func, void *ctx, apr_pool_t *pool)
1538 {
1539   if (NIL_P(hash)) {
1540     return NULL;
1541   } else {
1542     apr_hash_t *apr_hash;
1543     hash_to_apr_hash_data_t data;
1544 
1545     apr_hash = apr_hash_make(pool);
1546     data.apr_hash = apr_hash;
1547     data.ctx = ctx;
1548     data.func = func;
1549     data.pool = pool;
1550 
1551     rb_hash_foreach(hash, r2c_hash_i, (VALUE)&data);
1552 
1553     return apr_hash;
1554   }
1555 }
1556 
1557 
1558 apr_hash_t *
svn_swig_rb_hash_to_apr_hash_string(VALUE hash,apr_pool_t * pool)1559 svn_swig_rb_hash_to_apr_hash_string(VALUE hash, apr_pool_t *pool)
1560 {
1561   return r2c_hash(hash, r2c_string, NULL, pool);
1562 }
1563 
1564 apr_hash_t *
svn_swig_rb_hash_to_apr_hash_svn_string(VALUE hash,apr_pool_t * pool)1565 svn_swig_rb_hash_to_apr_hash_svn_string(VALUE hash, apr_pool_t *pool)
1566 {
1567   return r2c_hash(hash, r2c_svn_string, NULL, pool);
1568 }
1569 
1570 apr_hash_t *
svn_swig_rb_hash_to_apr_hash_swig_type(VALUE hash,const char * typename,apr_pool_t * pool)1571 svn_swig_rb_hash_to_apr_hash_swig_type(VALUE hash, const char *typename, apr_pool_t *pool)
1572 {
1573   return r2c_hash(hash, r2c_swig_type, (void *)typename, pool);
1574 }
1575 
1576 apr_hash_t *
svn_swig_rb_hash_to_apr_hash_revnum(VALUE hash,apr_pool_t * pool)1577 svn_swig_rb_hash_to_apr_hash_revnum(VALUE hash, apr_pool_t *pool)
1578 {
1579   return r2c_hash(hash, r2c_revnum, NULL, pool);
1580 }
1581 
1582 apr_hash_t *
svn_swig_rb_hash_to_apr_hash_merge_range(VALUE hash,apr_pool_t * pool)1583 svn_swig_rb_hash_to_apr_hash_merge_range(VALUE hash, apr_pool_t *pool)
1584 {
1585   return r2c_hash(hash, r2c_merge_range, NULL, pool);
1586 }
1587 
1588 
1589 /* callback */
1590 typedef struct callback_baton_t {
1591   VALUE pool;
1592   VALUE receiver;
1593   ID message;
1594   VALUE args;
1595 } callback_baton_t;
1596 
1597 typedef struct callback_rescue_baton_t {
1598   svn_error_t **err;
1599   VALUE pool;
1600 } callback_rescue_baton_t;
1601 
1602 typedef struct callback_handle_error_baton_t {
1603   callback_baton_t *callback_baton;
1604   callback_rescue_baton_t *rescue_baton;
1605 } callback_handle_error_baton_t;
1606 
1607 static VALUE
callback(VALUE baton,...)1608 callback(VALUE baton, ...)
1609 {
1610   callback_baton_t *cbb = (callback_baton_t *)baton;
1611   VALUE result;
1612 
1613   result = rb_apply(cbb->receiver, cbb->message, cbb->args);
1614   svn_swig_rb_push_pool(cbb->pool);
1615 
1616   return result;
1617 }
1618 
1619 static VALUE
callback_rescue(VALUE baton,...)1620 callback_rescue(VALUE baton, ...)
1621 {
1622   callback_rescue_baton_t *rescue_baton = (callback_rescue_baton_t*)baton;
1623 
1624   *(rescue_baton->err) = r2c_svn_err(
1625 #ifdef HAVE_RB_ERRINFO
1626                                      rb_errinfo(),
1627 #else
1628                                      ruby_errinfo,
1629 #endif
1630                                      NULL, NULL);
1631   svn_swig_rb_push_pool(rescue_baton->pool);
1632 
1633   return Qnil;
1634 }
1635 
1636 static VALUE
callback_ensure(VALUE pool,...)1637 callback_ensure(VALUE pool, ...)
1638 {
1639   svn_swig_rb_pop_pool(pool);
1640 
1641   return Qnil;
1642 }
1643 
1644 static VALUE
invoke_callback(VALUE baton,VALUE pool)1645 invoke_callback(VALUE baton, VALUE pool)
1646 {
1647   callback_baton_t *cbb = (callback_baton_t *)baton;
1648   VALUE subpool;
1649   VALUE argv[1];
1650 
1651   argv[0] = pool;
1652   svn_swig_rb_get_pool(1, argv, Qnil, &subpool, NULL);
1653   cbb->pool = subpool;
1654   return rb_ensure(callback, baton, callback_ensure, subpool);
1655 }
1656 
1657 static VALUE
callback_handle_error(VALUE baton,...)1658 callback_handle_error(VALUE baton, ...)
1659 {
1660   callback_handle_error_baton_t *handle_error_baton;
1661   handle_error_baton = (callback_handle_error_baton_t *)baton;
1662 
1663   return rb_rescue2(callback,
1664                     (VALUE)(handle_error_baton->callback_baton),
1665                     callback_rescue,
1666                     (VALUE)(handle_error_baton->rescue_baton),
1667                     rb_svn_error(),
1668                     (VALUE)0);
1669 }
1670 
1671 static VALUE
invoke_callback_handle_error(VALUE baton,VALUE pool,svn_error_t ** err)1672 invoke_callback_handle_error(VALUE baton, VALUE pool, svn_error_t **err)
1673 {
1674   callback_baton_t *cbb = (callback_baton_t *)baton;
1675   callback_handle_error_baton_t handle_error_baton;
1676   callback_rescue_baton_t rescue_baton;
1677 
1678   rescue_baton.err = err;
1679   rescue_baton.pool = pool;
1680   cbb->pool = pool;
1681   handle_error_baton.callback_baton = cbb;
1682   handle_error_baton.rescue_baton = &rescue_baton;
1683 
1684   return rb_ensure(callback_handle_error, (VALUE)&handle_error_baton,
1685                    callback_ensure, pool);
1686 }
1687 
1688 
1689 /* svn_delta_editor_t */
1690 typedef struct item_baton {
1691   VALUE editor;
1692   VALUE baton;
1693 } item_baton;
1694 
1695 static void
add_baton(VALUE editor,VALUE baton)1696 add_baton(VALUE editor, VALUE baton)
1697 {
1698   if (NIL_P((rb_ivar_get(editor, id_baton)))) {
1699     rb_ivar_set(editor, id_baton, rb_ary_new());
1700   }
1701 
1702   rb_ary_push(rb_ivar_get(editor, id_baton), baton);
1703 }
1704 
1705 static item_baton *
make_baton(apr_pool_t * pool,VALUE editor,VALUE baton)1706 make_baton(apr_pool_t *pool, VALUE editor, VALUE baton)
1707 {
1708   item_baton *newb = apr_palloc(pool, sizeof(*newb));
1709 
1710   newb->editor = editor;
1711   newb->baton = baton;
1712   add_baton(editor, baton);
1713 
1714   return newb;
1715 }
1716 
1717 static VALUE
add_baton_if_delta_editor(VALUE target,VALUE baton)1718 add_baton_if_delta_editor(VALUE target, VALUE baton)
1719 {
1720   if (RTEST(rb_obj_is_kind_of(target, svn_swig_rb_svn_delta_editor()))) {
1721     add_baton(target, baton);
1722   }
1723 
1724   return Qnil;
1725 }
1726 
1727 void
svn_swig_rb_set_baton(VALUE target,VALUE baton)1728 svn_swig_rb_set_baton(VALUE target, VALUE baton)
1729 {
1730   if (NIL_P(baton)) {
1731     return;
1732   }
1733 
1734   if (!RTEST(rb_obj_is_kind_of(target, rb_cArray))) {
1735     target = rb_ary_new3(1, target);
1736   }
1737 
1738   rb_iterate(rb_each, target, add_baton_if_delta_editor, baton);
1739 }
1740 
1741 
1742 static svn_error_t *
delta_editor_set_target_revision(void * edit_baton,svn_revnum_t target_revision,apr_pool_t * pool)1743 delta_editor_set_target_revision(void *edit_baton,
1744                                  svn_revnum_t target_revision,
1745                                  apr_pool_t *pool)
1746 {
1747   item_baton *ib = edit_baton;
1748   svn_error_t *err = SVN_NO_ERROR;
1749   callback_baton_t cbb;
1750 
1751   cbb.receiver = ib->editor;
1752   cbb.message = id_set_target_revision;
1753   cbb.args = rb_ary_new3(1, INT2NUM(target_revision));
1754   invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
1755   return err;
1756 }
1757 
1758 static svn_error_t *
delta_editor_open_root(void * edit_baton,svn_revnum_t base_revision,apr_pool_t * dir_pool,void ** root_baton)1759 delta_editor_open_root(void *edit_baton,
1760                        svn_revnum_t base_revision,
1761                        apr_pool_t *dir_pool,
1762                        void **root_baton)
1763 {
1764   item_baton *ib = edit_baton;
1765   svn_error_t *err = SVN_NO_ERROR;
1766   callback_baton_t cbb;
1767   VALUE result;
1768 
1769   cbb.receiver = ib->editor;
1770   cbb.message = id_open_root;
1771   cbb.args = rb_ary_new3(1, INT2NUM(base_revision));
1772   result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
1773   *root_baton = make_baton(dir_pool, ib->editor, result);
1774   return err;
1775 }
1776 
1777 static svn_error_t *
delta_editor_delete_entry(const char * path,svn_revnum_t revision,void * parent_baton,apr_pool_t * pool)1778 delta_editor_delete_entry(const char *path,
1779                           svn_revnum_t revision,
1780                           void *parent_baton,
1781                           apr_pool_t *pool)
1782 {
1783   item_baton *ib = parent_baton;
1784   svn_error_t *err = SVN_NO_ERROR;
1785   callback_baton_t cbb;
1786 
1787   cbb.receiver = ib->editor;
1788   cbb.message = id_delete_entry;
1789   cbb.args = rb_ary_new3(3, c2r_string2(path), INT2NUM(revision), ib->baton);
1790   invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
1791   return err;
1792 }
1793 
1794 static svn_error_t *
delta_editor_add_directory(const char * path,void * parent_baton,const char * copyfrom_path,svn_revnum_t copyfrom_revision,apr_pool_t * dir_pool,void ** child_baton)1795 delta_editor_add_directory(const char *path,
1796                            void *parent_baton,
1797                            const char *copyfrom_path,
1798                            svn_revnum_t copyfrom_revision,
1799                            apr_pool_t *dir_pool,
1800                            void **child_baton)
1801 {
1802   item_baton *ib = parent_baton;
1803   svn_error_t *err = SVN_NO_ERROR;
1804   callback_baton_t cbb;
1805   VALUE result;
1806 
1807   cbb.receiver = ib->editor;
1808   cbb.message = id_add_directory;
1809   cbb.args = rb_ary_new3(4,
1810                          c2r_string2(path),
1811                          ib->baton,
1812                          c2r_string2(copyfrom_path),
1813                          INT2NUM(copyfrom_revision));
1814   result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
1815   *child_baton = make_baton(dir_pool, ib->editor, result);
1816   return err;
1817 }
1818 
1819 static svn_error_t *
delta_editor_open_directory(const char * path,void * parent_baton,svn_revnum_t base_revision,apr_pool_t * dir_pool,void ** child_baton)1820 delta_editor_open_directory(const char *path,
1821                             void *parent_baton,
1822                             svn_revnum_t base_revision,
1823                             apr_pool_t *dir_pool,
1824                             void **child_baton)
1825 {
1826   item_baton *ib = parent_baton;
1827   svn_error_t *err = SVN_NO_ERROR;
1828   callback_baton_t cbb;
1829   VALUE result;
1830 
1831   cbb.receiver = ib->editor;
1832   cbb.message = id_open_directory;
1833   cbb.args = rb_ary_new3(3,
1834                          c2r_string2(path),
1835                          ib->baton,
1836                          INT2NUM(base_revision));
1837   result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
1838   *child_baton = make_baton(dir_pool, ib->editor, result);
1839   return err;
1840 }
1841 
1842 static svn_error_t *
delta_editor_change_dir_prop(void * dir_baton,const char * name,const svn_string_t * value,apr_pool_t * pool)1843 delta_editor_change_dir_prop(void *dir_baton,
1844                              const char *name,
1845                              const svn_string_t *value,
1846                              apr_pool_t *pool)
1847 {
1848   item_baton *ib = dir_baton;
1849   svn_error_t *err = SVN_NO_ERROR;
1850   callback_baton_t cbb;
1851 
1852   cbb.receiver = ib->editor;
1853   cbb.message = id_change_dir_prop;
1854   cbb.args = rb_ary_new3(3,
1855                          ib->baton,
1856                          c2r_string2(name),
1857                          value ? rb_str_new(value->data, value->len) : Qnil);
1858   invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
1859   return err;
1860 }
1861 
1862 static svn_error_t *
delta_editor_close_baton(void * baton,ID method_id)1863 delta_editor_close_baton(void *baton, ID method_id)
1864 {
1865   item_baton *ib = baton;
1866   svn_error_t *err = SVN_NO_ERROR;
1867   callback_baton_t cbb;
1868 
1869   cbb.receiver = ib->editor;
1870   cbb.message = method_id;
1871   cbb.args = rb_ary_new3(1, ib->baton);
1872   invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
1873   return err;
1874 }
1875 
1876 static svn_error_t *
delta_editor_close_directory(void * dir_baton,apr_pool_t * pool)1877 delta_editor_close_directory(void *dir_baton, apr_pool_t *pool)
1878 {
1879   return delta_editor_close_baton(dir_baton, id_close_directory);
1880 }
1881 
1882 static svn_error_t *
delta_editor_absent_directory(const char * path,void * parent_baton,apr_pool_t * pool)1883 delta_editor_absent_directory(const char *path,
1884                               void *parent_baton,
1885                               apr_pool_t *pool)
1886 {
1887   item_baton *ib = parent_baton;
1888   svn_error_t *err = SVN_NO_ERROR;
1889   callback_baton_t cbb;
1890 
1891   cbb.receiver = ib->editor;
1892   cbb.message = id_absent_directory;
1893   cbb.args = rb_ary_new3(2, c2r_string2(path), ib->baton);
1894   invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
1895   return err;
1896 }
1897 
1898 static svn_error_t *
delta_editor_add_file(const char * path,void * parent_baton,const char * copyfrom_path,svn_revnum_t copyfrom_revision,apr_pool_t * file_pool,void ** file_baton)1899 delta_editor_add_file(const char *path,
1900                       void *parent_baton,
1901                       const char *copyfrom_path,
1902                       svn_revnum_t copyfrom_revision,
1903                       apr_pool_t *file_pool,
1904                       void **file_baton)
1905 {
1906   item_baton *ib = parent_baton;
1907   svn_error_t *err = SVN_NO_ERROR;
1908   callback_baton_t cbb;
1909   VALUE result;
1910 
1911   cbb.receiver = ib->editor;
1912   cbb.message = id_add_file;
1913   cbb.args = rb_ary_new3(4,
1914                          c2r_string2(path),
1915                          ib->baton,
1916                          c2r_string2(copyfrom_path),
1917                          INT2NUM(copyfrom_revision));
1918   result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
1919   *file_baton = make_baton(file_pool, ib->editor, result);
1920   return err;
1921 }
1922 
1923 static svn_error_t *
delta_editor_open_file(const char * path,void * parent_baton,svn_revnum_t base_revision,apr_pool_t * file_pool,void ** file_baton)1924 delta_editor_open_file(const char *path,
1925                        void *parent_baton,
1926                        svn_revnum_t base_revision,
1927                        apr_pool_t *file_pool,
1928                        void **file_baton)
1929 {
1930   item_baton *ib = parent_baton;
1931   svn_error_t *err = SVN_NO_ERROR;
1932   callback_baton_t cbb;
1933   VALUE result;
1934 
1935   cbb.receiver = ib->editor;
1936   cbb.message = id_open_file;
1937   cbb.args = rb_ary_new3(3,
1938                          c2r_string2(path),
1939                          ib->baton,
1940                          INT2NUM(base_revision));
1941   result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
1942   *file_baton = make_baton(file_pool, ib->editor, result);
1943   return err;
1944 }
1945 
1946 static svn_error_t *
delta_editor_window_handler(svn_txdelta_window_t * window,void * baton)1947 delta_editor_window_handler(svn_txdelta_window_t *window, void *baton)
1948 {
1949   VALUE handler = (VALUE)baton;
1950   callback_baton_t cbb;
1951   VALUE result;
1952   svn_error_t *err = SVN_NO_ERROR;
1953 
1954   cbb.receiver = handler;
1955   cbb.message = id_call;
1956   cbb.args = rb_ary_new3(1, c2r_txdelta_window__dup(window));
1957   result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
1958   return err;
1959 }
1960 
1961 static svn_error_t *
delta_editor_apply_textdelta(void * file_baton,const char * base_checksum,apr_pool_t * pool,svn_txdelta_window_handler_t * handler,void ** h_baton)1962 delta_editor_apply_textdelta(void *file_baton,
1963                              const char *base_checksum,
1964                              apr_pool_t *pool,
1965                              svn_txdelta_window_handler_t *handler,
1966                              void **h_baton)
1967 {
1968   item_baton *ib = file_baton;
1969   svn_error_t *err = SVN_NO_ERROR;
1970   callback_baton_t cbb;
1971   VALUE result;
1972 
1973   cbb.receiver = ib->editor;
1974   cbb.message = id_apply_textdelta;
1975   cbb.args = rb_ary_new3(2, ib->baton, c2r_string2(base_checksum));
1976   result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
1977   if (NIL_P(result)) {
1978     *handler = svn_delta_noop_window_handler;
1979     *h_baton = NULL;
1980   } else {
1981     *handler = delta_editor_window_handler;
1982     *h_baton = (void *)result;
1983   }
1984 
1985   return err;
1986 }
1987 
1988 static svn_error_t *
delta_editor_change_file_prop(void * file_baton,const char * name,const svn_string_t * value,apr_pool_t * pool)1989 delta_editor_change_file_prop(void *file_baton,
1990                               const char *name,
1991                               const svn_string_t *value,
1992                               apr_pool_t *pool)
1993 {
1994   item_baton *ib = file_baton;
1995   svn_error_t *err = SVN_NO_ERROR;
1996   callback_baton_t cbb;
1997 
1998   cbb.receiver = ib->editor;
1999   cbb.message = id_change_file_prop;
2000   cbb.args = rb_ary_new3(3,
2001                          ib->baton,
2002                          c2r_string2(name),
2003                          value ? rb_str_new(value->data, value->len) : Qnil);
2004   invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
2005 
2006   return err;
2007 }
2008 
2009 static svn_error_t *
delta_editor_close_file(void * file_baton,const char * text_checksum,apr_pool_t * pool)2010 delta_editor_close_file(void *file_baton,
2011                         const char *text_checksum,
2012                         apr_pool_t *pool)
2013 {
2014   item_baton *ib = file_baton;
2015   svn_error_t *err = SVN_NO_ERROR;
2016   callback_baton_t cbb;
2017 
2018   cbb.receiver = ib->editor;
2019   cbb.message = id_close_file;
2020   cbb.args = rb_ary_new3(2, ib->baton, c2r_string2(text_checksum));
2021   invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
2022 
2023   return err;
2024 }
2025 
2026 static svn_error_t *
delta_editor_absent_file(const char * path,void * parent_baton,apr_pool_t * pool)2027 delta_editor_absent_file(const char *path,
2028                          void *parent_baton,
2029                          apr_pool_t *pool)
2030 {
2031   item_baton *ib = parent_baton;
2032   svn_error_t *err = SVN_NO_ERROR;
2033   callback_baton_t cbb;
2034 
2035   cbb.receiver = ib->editor;
2036   cbb.message = id_absent_file;
2037   cbb.args = rb_ary_new3(2, c2r_string2(path), ib->baton);
2038   invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
2039 
2040   return err;
2041 }
2042 
2043 static svn_error_t *
delta_editor_close_edit(void * edit_baton,apr_pool_t * pool)2044 delta_editor_close_edit(void *edit_baton, apr_pool_t *pool)
2045 {
2046   item_baton *ib = edit_baton;
2047   svn_error_t *err = delta_editor_close_baton(edit_baton, id_close_edit);
2048   rb_ary_clear(rb_ivar_get(ib->editor, id_baton));
2049   return err;
2050 }
2051 
2052 static svn_error_t *
delta_editor_abort_edit(void * edit_baton,apr_pool_t * pool)2053 delta_editor_abort_edit(void *edit_baton, apr_pool_t *pool)
2054 {
2055   item_baton *ib = edit_baton;
2056   svn_error_t *err = delta_editor_close_baton(edit_baton, id_abort_edit);
2057   rb_ary_clear(rb_ivar_get(ib->editor, id_baton));
2058   return err;
2059 }
2060 
2061 void
svn_swig_rb_make_delta_editor(svn_delta_editor_t ** editor,void ** edit_baton,VALUE rb_editor,apr_pool_t * pool)2062 svn_swig_rb_make_delta_editor(svn_delta_editor_t **editor,
2063                               void **edit_baton,
2064                               VALUE rb_editor,
2065                               apr_pool_t *pool)
2066 {
2067   svn_delta_editor_t *thunk_editor = svn_delta_default_editor(pool);
2068 
2069   thunk_editor->set_target_revision = delta_editor_set_target_revision;
2070   thunk_editor->open_root = delta_editor_open_root;
2071   thunk_editor->delete_entry = delta_editor_delete_entry;
2072   thunk_editor->add_directory = delta_editor_add_directory;
2073   thunk_editor->open_directory = delta_editor_open_directory;
2074   thunk_editor->change_dir_prop = delta_editor_change_dir_prop;
2075   thunk_editor->close_directory = delta_editor_close_directory;
2076   thunk_editor->absent_directory = delta_editor_absent_directory;
2077   thunk_editor->add_file = delta_editor_add_file;
2078   thunk_editor->open_file = delta_editor_open_file;
2079   thunk_editor->apply_textdelta = delta_editor_apply_textdelta;
2080   thunk_editor->change_file_prop = delta_editor_change_file_prop;
2081   thunk_editor->close_file = delta_editor_close_file;
2082   thunk_editor->absent_file = delta_editor_absent_file;
2083   thunk_editor->close_edit = delta_editor_close_edit;
2084   thunk_editor->abort_edit = delta_editor_abort_edit;
2085 
2086   *editor = thunk_editor;
2087   rb_ivar_set(rb_editor, id_baton, rb_ary_new());
2088   *edit_baton = make_baton(pool, rb_editor, Qnil);
2089 }
2090 
2091 
2092 VALUE
svn_swig_rb_make_baton(VALUE proc,VALUE pool)2093 svn_swig_rb_make_baton(VALUE proc, VALUE pool)
2094 {
2095   if (NIL_P(proc)) {
2096     return Qnil;
2097   } else {
2098     return rb_ary_new3(2, proc, pool);
2099   }
2100 }
2101 
2102 void
svn_swig_rb_from_baton(VALUE baton,VALUE * proc,VALUE * pool)2103 svn_swig_rb_from_baton(VALUE baton, VALUE *proc, VALUE *pool)
2104 {
2105   if (NIL_P(baton)) {
2106     *proc = Qnil;
2107     *pool = Qnil;
2108   } else {
2109     *proc = rb_ary_entry(baton, 0);
2110     *pool = rb_ary_entry(baton, 1);
2111   }
2112 }
2113 
2114 svn_error_t *
svn_swig_rb_log_receiver(void * baton,apr_hash_t * changed_paths,svn_revnum_t revision,const char * author,const char * date,const char * message,apr_pool_t * pool)2115 svn_swig_rb_log_receiver(void *baton,
2116                          apr_hash_t *changed_paths,
2117                          svn_revnum_t revision,
2118                          const char *author,
2119                          const char *date,
2120                          const char *message,
2121                          apr_pool_t *pool)
2122 {
2123   svn_error_t *err = SVN_NO_ERROR;
2124   VALUE proc, rb_pool;
2125 
2126   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2127 
2128   if (!NIL_P(proc)) {
2129     callback_baton_t cbb;
2130     VALUE rb_changed_paths = Qnil;
2131 
2132     if (changed_paths) {
2133       rb_changed_paths = c2r_hash(changed_paths,
2134                                   c2r_log_changed_path_dup,
2135                                   NULL);
2136     }
2137 
2138     cbb.receiver = proc;
2139     cbb.message = id_call;
2140     cbb.args = rb_ary_new3(5,
2141                            rb_changed_paths,
2142                            c2r_long(&revision, NULL),
2143                            c2r_string2(author),
2144                            c2r_svn_date_string2(date),
2145                            c2r_string2(message));
2146     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2147   }
2148   return err;
2149 }
2150 
2151 svn_error_t *
svn_swig_rb_log_entry_receiver(void * baton,svn_log_entry_t * entry,apr_pool_t * pool)2152 svn_swig_rb_log_entry_receiver(void *baton,
2153                                svn_log_entry_t *entry,
2154                                apr_pool_t *pool)
2155 {
2156     svn_error_t *err = SVN_NO_ERROR;
2157     VALUE proc, rb_pool;
2158 
2159     svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2160 
2161     if (!NIL_P(proc)) {
2162         callback_baton_t cbb;
2163 
2164         cbb.receiver = proc;
2165         cbb.message = id_call;
2166         cbb.args = rb_ary_new3(1, c2r_log_entry__dup(entry));
2167         invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2168     }
2169     return err;
2170 }
2171 
2172 
2173 svn_error_t *
svn_swig_rb_repos_authz_func(svn_boolean_t * allowed,svn_fs_root_t * root,const char * path,void * baton,apr_pool_t * pool)2174 svn_swig_rb_repos_authz_func(svn_boolean_t *allowed,
2175                              svn_fs_root_t *root,
2176                              const char *path,
2177                              void *baton,
2178                              apr_pool_t *pool)
2179 {
2180   svn_error_t *err = SVN_NO_ERROR;
2181   VALUE proc, rb_pool;
2182 
2183   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2184 
2185   *allowed = TRUE;
2186 
2187   if (!NIL_P(proc)) {
2188     callback_baton_t cbb;
2189     VALUE result;
2190 
2191     cbb.receiver = proc;
2192     cbb.message = id_call;
2193     cbb.args = rb_ary_new3(2,
2194                            c2r_swig_type((void *)root,
2195                                          (void *)"svn_fs_root_t *"),
2196                            c2r_string2(path));
2197     result = invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2198 
2199     *allowed = RTEST(result);
2200   }
2201   return err;
2202 }
2203 
2204 svn_error_t *
svn_swig_rb_repos_authz_callback(svn_repos_authz_access_t required,svn_boolean_t * allowed,svn_fs_root_t * root,const char * path,void * baton,apr_pool_t * pool)2205 svn_swig_rb_repos_authz_callback(svn_repos_authz_access_t required,
2206                                  svn_boolean_t *allowed,
2207                                  svn_fs_root_t *root,
2208                                  const char *path,
2209                                  void *baton,
2210                                  apr_pool_t *pool)
2211 {
2212   svn_error_t *err = SVN_NO_ERROR;
2213   VALUE proc, rb_pool;
2214 
2215   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2216 
2217   *allowed = TRUE;
2218 
2219   if (!NIL_P(proc)) {
2220     callback_baton_t cbb;
2221     VALUE result;
2222 
2223     cbb.receiver = proc;
2224     cbb.message = id_call;
2225     cbb.args = rb_ary_new3(3,
2226                            INT2NUM(required),
2227                            c2r_swig_type((void *)root,
2228                                          (void *)"svn_fs_root_t *"),
2229                            c2r_string2(path));
2230     result = invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2231 
2232     *allowed = RTEST(result);
2233   }
2234   return err;
2235 }
2236 
2237 svn_error_t *
svn_swig_rb_get_commit_log_func(const char ** log_msg,const char ** tmp_file,const apr_array_header_t * commit_items,void * baton,apr_pool_t * pool)2238 svn_swig_rb_get_commit_log_func(const char **log_msg,
2239                                 const char **tmp_file,
2240                                 const apr_array_header_t *commit_items,
2241                                 void *baton,
2242                                 apr_pool_t *pool)
2243 {
2244   svn_error_t *err = SVN_NO_ERROR;
2245   VALUE proc, rb_pool;
2246 
2247   *log_msg = NULL;
2248   *tmp_file = NULL;
2249 
2250   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2251 
2252   if (!NIL_P(proc)) {
2253     callback_baton_t cbb;
2254     VALUE result;
2255     VALUE is_message;
2256     VALUE value;
2257     char *ret;
2258 
2259     cbb.receiver = proc;
2260     cbb.message = id_call;
2261     cbb.args = rb_ary_new3(1, c2r_commit_item3_array(commit_items));
2262     result = invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2263 
2264     if (!err) {
2265       char error_message[] =
2266         "log_msg_func should return an array not '%s': "
2267         "[TRUE_IF_IT_IS_MESSAGE, MESSAGE_OR_FILE_AS_STRING]";
2268 
2269       if (!RTEST(rb_obj_is_kind_of(result, rb_cArray)))
2270         rb_raise(rb_eTypeError, error_message, r2c_inspect(result));
2271       is_message = rb_ary_entry(result, 0);
2272       value = rb_ary_entry(result, 1);
2273 
2274       if (!RTEST(rb_obj_is_kind_of(value, rb_cString)))
2275         rb_raise(rb_eTypeError, error_message, r2c_inspect(result));
2276       ret = (char *)r2c_string(value, NULL, pool);
2277       if (RTEST(is_message)) {
2278         *log_msg = ret;
2279       } else {
2280         *tmp_file = ret;
2281       }
2282     }
2283   }
2284   return err;
2285 }
2286 
2287 
2288 void
svn_swig_rb_notify_func2(void * baton,const svn_wc_notify_t * notify,apr_pool_t * pool)2289 svn_swig_rb_notify_func2(void *baton,
2290                          const svn_wc_notify_t *notify,
2291                          apr_pool_t *pool)
2292 {
2293   VALUE proc, rb_pool;
2294   callback_baton_t cbb;
2295 
2296   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2297 
2298   if (!NIL_P(proc)) {
2299     cbb.receiver = proc;
2300     cbb.message = id_call;
2301     cbb.args = rb_ary_new3(1, c2r_wc_notify__dup(notify));
2302   }
2303 
2304   if (!NIL_P(proc))
2305     invoke_callback((VALUE)(&cbb), rb_pool);
2306 }
2307 
2308 svn_error_t *
svn_swig_rb_conflict_resolver_func(svn_wc_conflict_result_t ** result,const svn_wc_conflict_description_t * description,void * baton,apr_pool_t * pool)2309 svn_swig_rb_conflict_resolver_func
2310     (svn_wc_conflict_result_t **result,
2311      const svn_wc_conflict_description_t *description,
2312      void *baton,
2313      apr_pool_t *pool)
2314 {
2315   svn_error_t *err = SVN_NO_ERROR;
2316   VALUE proc, rb_pool;
2317 
2318   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2319 
2320   if (NIL_P(proc)) {
2321     *result = svn_wc_create_conflict_result(svn_wc_conflict_choose_postpone,
2322                                             description->merged_file,
2323                                             pool);
2324   } else {
2325     callback_baton_t cbb;
2326     VALUE fret;
2327 
2328     cbb.receiver = proc;
2329     cbb.message = id_call;
2330     cbb.args = rb_ary_new3(
2331                    1,
2332                    c2r_swig_type((void *)description,
2333                                  (void *)"svn_wc_conflict_description_t *") );
2334     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2335     fret = invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2336     *result = svn_wc_create_conflict_result(NUM2INT(fret),
2337                                             description->merged_file,
2338                                             pool);
2339   }
2340 
2341   return err;
2342 }
2343 
2344 svn_error_t *
svn_swig_rb_commit_callback(svn_revnum_t new_revision,const char * date,const char * author,void * baton)2345 svn_swig_rb_commit_callback(svn_revnum_t new_revision,
2346                             const char *date,
2347                             const char *author,
2348                             void *baton)
2349 {
2350   svn_error_t *err = SVN_NO_ERROR;
2351   VALUE proc, rb_pool;
2352 
2353   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2354 
2355   if (!NIL_P(proc)) {
2356     callback_baton_t cbb;
2357 
2358     cbb.receiver = proc;
2359     cbb.message = id_call;
2360     cbb.args = rb_ary_new3(3,
2361                            INT2NUM(new_revision),
2362                            c2r_svn_date_string2(date),
2363                            c2r_string2(author));
2364     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2365   }
2366 
2367   return err;
2368 }
2369 
2370 svn_error_t *
svn_swig_rb_commit_callback2(const svn_commit_info_t * commit_info,void * baton,apr_pool_t * pool)2371 svn_swig_rb_commit_callback2(const svn_commit_info_t *commit_info,
2372                              void *baton, apr_pool_t *pool)
2373 {
2374   svn_error_t *err = SVN_NO_ERROR;
2375   VALUE proc, rb_pool;
2376 
2377   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2378 
2379   if (!NIL_P(proc)) {
2380     callback_baton_t cbb;
2381 
2382     cbb.receiver = proc;
2383     cbb.message = id_call;
2384     cbb.args = rb_ary_new3(1, c2r_commit_info__dup(commit_info));
2385     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2386   }
2387 
2388   return err;
2389 }
2390 
2391 svn_error_t *
svn_swig_rb_cancel_func(void * cancel_baton)2392 svn_swig_rb_cancel_func(void *cancel_baton)
2393 {
2394   svn_error_t *err = SVN_NO_ERROR;
2395   VALUE proc, rb_pool;
2396 
2397   svn_swig_rb_from_baton((VALUE)cancel_baton, &proc, &rb_pool);
2398 
2399   if (!NIL_P(proc)) {
2400     callback_baton_t cbb;
2401 
2402     cbb.receiver = proc;
2403     cbb.message = id_call;
2404     cbb.args = rb_ary_new3(0);
2405     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2406   }
2407 
2408   return err;
2409 }
2410 
2411 svn_error_t *
svn_swig_rb_info_receiver(void * baton,const char * path,const svn_info_t * info,apr_pool_t * pool)2412 svn_swig_rb_info_receiver(void *baton,
2413                           const char *path,
2414                           const svn_info_t *info,
2415                           apr_pool_t *pool)
2416 {
2417   svn_error_t *err = SVN_NO_ERROR;
2418   VALUE proc, rb_pool;
2419 
2420   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2421 
2422   if (!NIL_P(proc)) {
2423     callback_baton_t cbb;
2424 
2425     cbb.receiver = proc;
2426     cbb.message = id_call;
2427     cbb.args = rb_ary_new3(2, c2r_string2(path), c2r_info__dup(info));
2428     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2429   }
2430 
2431   return err;
2432 }
2433 
2434 svn_boolean_t
svn_swig_rb_config_enumerator(const char * name,const char * value,void * baton,apr_pool_t * pool)2435 svn_swig_rb_config_enumerator(const char *name,
2436                               const char *value,
2437                               void *baton,
2438                               apr_pool_t *pool)
2439 {
2440   svn_boolean_t result = FALSE;
2441   VALUE proc, rb_pool;
2442 
2443   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2444 
2445   if (!NIL_P(proc)) {
2446     callback_baton_t cbb;
2447 
2448     cbb.receiver = proc;
2449     cbb.message = id_call;
2450     cbb.args = rb_ary_new3(2, c2r_string2(name), c2r_string2(value));
2451     result = RTEST(invoke_callback((VALUE)(&cbb), rb_pool));
2452   }
2453 
2454   return result;
2455 }
2456 
2457 svn_boolean_t
svn_swig_rb_config_section_enumerator(const char * name,void * baton,apr_pool_t * pool)2458 svn_swig_rb_config_section_enumerator(const char *name,
2459                                       void *baton,
2460                                       apr_pool_t *pool)
2461 {
2462   svn_boolean_t result = FALSE;
2463   VALUE proc, rb_pool;
2464 
2465   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2466 
2467   if (!NIL_P(proc)) {
2468     callback_baton_t cbb;
2469 
2470     cbb.receiver = proc;
2471     cbb.message = id_call;
2472     cbb.args = rb_ary_new3(1, c2r_string2(name));
2473     result = RTEST(invoke_callback((VALUE)(&cbb), rb_pool));
2474   }
2475 
2476   return result;
2477 }
2478 
2479 svn_error_t *
svn_swig_rb_delta_path_driver_cb_func(void ** dir_baton,void * parent_baton,void * callback_baton,const char * path,apr_pool_t * pool)2480 svn_swig_rb_delta_path_driver_cb_func(void **dir_baton,
2481                                       void *parent_baton,
2482                                       void *callback_baton,
2483                                       const char *path,
2484                                       apr_pool_t *pool)
2485 {
2486   svn_error_t *err = SVN_NO_ERROR;
2487   VALUE proc, rb_pool;
2488 
2489   svn_swig_rb_from_baton((VALUE)callback_baton, &proc, &rb_pool);
2490 
2491   if (!NIL_P(proc)) {
2492     callback_baton_t cbb;
2493     VALUE result;
2494     item_baton *ib = (item_baton *)parent_baton;
2495 
2496     cbb.receiver = proc;
2497     cbb.message = id_call;
2498     cbb.args = rb_ary_new3(2, ib->baton, c2r_string2(path));
2499     result = invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2500     *dir_baton = make_baton(pool, ib->editor, result);
2501   }
2502 
2503   return err;
2504 }
2505 
2506 svn_error_t *
svn_swig_rb_txdelta_window_handler(svn_txdelta_window_t * window,void * baton)2507 svn_swig_rb_txdelta_window_handler(svn_txdelta_window_t *window,
2508                                    void *baton)
2509 {
2510   svn_error_t *err = SVN_NO_ERROR;
2511   VALUE proc, rb_pool;
2512 
2513   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2514 
2515   if (!NIL_P(proc)) {
2516     callback_baton_t cbb;
2517 
2518     cbb.receiver = proc;
2519     cbb.message = id_call;
2520     cbb.args = rb_ary_new3(1, c2r_txdelta_window__dup(window));
2521     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2522   }
2523 
2524   return err;
2525 }
2526 
2527 void
svn_swig_rb_fs_warning_callback(void * baton,svn_error_t * err)2528 svn_swig_rb_fs_warning_callback(void *baton, svn_error_t *err)
2529 {
2530   VALUE proc, rb_pool;
2531 
2532   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2533 
2534   if (!NIL_P(proc)) {
2535     callback_baton_t cbb;
2536 
2537     cbb.receiver = proc;
2538     cbb.message = id_call;
2539     cbb.args = rb_ary_new3(1, svn_swig_rb_svn_error_to_rb_error(err));
2540     invoke_callback((VALUE)(&cbb), rb_pool);
2541   }
2542 }
2543 
2544 static apr_status_t
cleanup_fs_warning_callback_baton(void * baton)2545 cleanup_fs_warning_callback_baton(void *baton)
2546 {
2547   rb_holder_pop(rb_svn_fs_warning_callback_baton_holder(), (VALUE)baton);
2548   return APR_SUCCESS;
2549 }
2550 
2551 void
svn_swig_rb_fs_warning_callback_baton_register(VALUE baton,apr_pool_t * pool)2552 svn_swig_rb_fs_warning_callback_baton_register(VALUE baton, apr_pool_t *pool)
2553 {
2554   rb_holder_push(rb_svn_fs_warning_callback_baton_holder(), (VALUE)baton);
2555   apr_pool_cleanup_register(pool, (void *)baton,
2556                             cleanup_fs_warning_callback_baton,
2557                             apr_pool_cleanup_null);
2558 }
2559 
2560 svn_error_t *
svn_swig_rb_fs_get_locks_callback(void * baton,svn_lock_t * lock,apr_pool_t * pool)2561 svn_swig_rb_fs_get_locks_callback(void *baton,
2562                                   svn_lock_t *lock,
2563                                   apr_pool_t *pool)
2564 {
2565   svn_error_t *err = SVN_NO_ERROR;
2566   VALUE proc, rb_pool;
2567 
2568   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2569 
2570   if (!NIL_P(proc)) {
2571     callback_baton_t cbb;
2572 
2573     cbb.receiver = proc;
2574     cbb.message = id_call;
2575     cbb.args = rb_ary_new3(1, c2r_lock__dup(lock));
2576     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2577   }
2578 
2579   return err;
2580 }
2581 
2582 
2583 /* svn_ra_callbacks_t */
2584 static svn_error_t *
ra_callbacks_open_tmp_file(apr_file_t ** fp,void * callback_baton,apr_pool_t * pool)2585 ra_callbacks_open_tmp_file(apr_file_t **fp,
2586                            void *callback_baton,
2587                            apr_pool_t *pool)
2588 {
2589   VALUE callbacks = (VALUE)callback_baton;
2590   svn_error_t *err = SVN_NO_ERROR;
2591 
2592   if (!NIL_P(callbacks)) {
2593     callback_baton_t cbb;
2594     VALUE result;
2595 
2596     cbb.receiver = callbacks;
2597     cbb.message = id_open_tmp_file;
2598     cbb.args = rb_ary_new3(0);
2599 
2600     result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
2601     *fp = svn_swig_rb_make_file(result, pool);
2602   }
2603 
2604   return err;
2605 }
2606 
2607 static svn_error_t *
ra_callbacks_get_wc_prop(void * baton,const char * relpath,const char * name,const svn_string_t ** value,apr_pool_t * pool)2608 ra_callbacks_get_wc_prop(void *baton,
2609                          const char *relpath,
2610                          const char *name,
2611                          const svn_string_t **value,
2612                          apr_pool_t *pool)
2613 {
2614   VALUE callbacks = (VALUE)baton;
2615   svn_error_t *err = SVN_NO_ERROR;
2616 
2617   if (!NIL_P(callbacks)) {
2618     callback_baton_t cbb;
2619     VALUE result;
2620 
2621     cbb.receiver = callbacks;
2622     cbb.message = id_get_wc_prop;
2623     cbb.args = rb_ary_new3(2, c2r_string2(relpath), c2r_string2(name));
2624     result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
2625     if (NIL_P(result)) {
2626       *value = NULL;
2627     } else {
2628       *value = r2c_svn_string(result, NULL, pool);
2629     }
2630   }
2631 
2632   return err;
2633 }
2634 
2635 static svn_error_t *
ra_callbacks_set_wc_prop(void * baton,const char * path,const char * name,const svn_string_t * value,apr_pool_t * pool)2636 ra_callbacks_set_wc_prop(void *baton,
2637                          const char *path,
2638                          const char *name,
2639                          const svn_string_t *value,
2640                          apr_pool_t *pool)
2641 {
2642   VALUE callbacks = (VALUE)baton;
2643   svn_error_t *err = SVN_NO_ERROR;
2644 
2645   if (!NIL_P(callbacks)) {
2646     callback_baton_t cbb;
2647 
2648     cbb.receiver = callbacks;
2649     cbb.message = id_set_wc_prop;
2650     cbb.args = rb_ary_new3(3,
2651                            c2r_string2(path),
2652                            c2r_string2(name),
2653                            c2r_svn_string((void *)value, NULL));
2654     invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
2655   }
2656 
2657   return err;
2658 }
2659 
2660 static svn_error_t *
ra_callbacks_push_wc_prop(void * baton,const char * path,const char * name,const svn_string_t * value,apr_pool_t * pool)2661 ra_callbacks_push_wc_prop(void *baton,
2662                           const char *path,
2663                           const char *name,
2664                           const svn_string_t *value,
2665                           apr_pool_t *pool)
2666 {
2667   VALUE callbacks = (VALUE)baton;
2668   svn_error_t *err = SVN_NO_ERROR;
2669 
2670   if (!NIL_P(callbacks)) {
2671     callback_baton_t cbb;
2672 
2673     cbb.receiver = callbacks;
2674     cbb.message = id_push_wc_prop;
2675     cbb.args = rb_ary_new3(3,
2676                            c2r_string2(path),
2677                            c2r_string2(name),
2678                            c2r_svn_string((void *)value, NULL));
2679     invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
2680   }
2681 
2682   return err;
2683 }
2684 
2685 static svn_error_t *
ra_callbacks_invalidate_wc_props(void * baton,const char * path,const char * name,apr_pool_t * pool)2686 ra_callbacks_invalidate_wc_props(void *baton,
2687                                  const char *path,
2688                                  const char *name,
2689                                  apr_pool_t *pool)
2690 {
2691   VALUE callbacks = (VALUE)baton;
2692   svn_error_t *err = SVN_NO_ERROR;
2693 
2694   if (!NIL_P(callbacks)) {
2695     callback_baton_t cbb;
2696 
2697     cbb.receiver = callbacks;
2698     cbb.message = id_invalidate_wc_props;
2699     cbb.args = rb_ary_new3(2, c2r_string2(path), c2r_string2(name));
2700     invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
2701   }
2702 
2703   return err;
2704 }
2705 
2706 
2707 static void
ra_callbacks_progress_func(apr_off_t progress,apr_off_t total,void * baton,apr_pool_t * pool)2708 ra_callbacks_progress_func(apr_off_t progress,
2709                            apr_off_t total,
2710                            void *baton,
2711                            apr_pool_t *pool)
2712 {
2713   VALUE callbacks = (VALUE)baton;
2714   if (!NIL_P(callbacks)) {
2715     callback_baton_t cbb;
2716 
2717     cbb.receiver = callbacks;
2718     cbb.message = id_progress_func;
2719     cbb.args = rb_ary_new3(2, AOFF2NUM(progress), AOFF2NUM(total));
2720     invoke_callback((VALUE)(&cbb), Qnil);
2721   }
2722 }
2723 
2724 void
svn_swig_rb_setup_ra_callbacks(svn_ra_callbacks2_t ** callbacks,void ** baton,VALUE rb_callbacks,apr_pool_t * pool)2725 svn_swig_rb_setup_ra_callbacks(svn_ra_callbacks2_t **callbacks,
2726                                void **baton,
2727                                VALUE rb_callbacks,
2728                                apr_pool_t *pool)
2729 {
2730   void *auth_baton = NULL;
2731 
2732   if (!NIL_P(rb_callbacks)) {
2733     VALUE rb_auth_baton = Qnil;
2734     rb_auth_baton = rb_funcall(rb_callbacks, id_auth_baton, 0);
2735     auth_baton = r2c_swig_type(rb_auth_baton,
2736                                (void *)"svn_auth_baton_t *",
2737                                pool);
2738   }
2739 
2740   *callbacks = apr_pcalloc(pool, sizeof(**callbacks));
2741   *baton = (void *)rb_callbacks;
2742 
2743   (*callbacks)->open_tmp_file = ra_callbacks_open_tmp_file;
2744   (*callbacks)->auth_baton = auth_baton;
2745   (*callbacks)->get_wc_prop = ra_callbacks_get_wc_prop;
2746   (*callbacks)->set_wc_prop = ra_callbacks_set_wc_prop;
2747   (*callbacks)->push_wc_prop = ra_callbacks_push_wc_prop;
2748   (*callbacks)->invalidate_wc_props = ra_callbacks_invalidate_wc_props;
2749   (*callbacks)->progress_func = ra_callbacks_progress_func;
2750   (*callbacks)->progress_baton = (void *)rb_callbacks;
2751 }
2752 
2753 
2754 svn_error_t *
svn_swig_rb_ra_lock_callback(void * baton,const char * path,svn_boolean_t do_lock,const svn_lock_t * lock,svn_error_t * ra_err,apr_pool_t * pool)2755 svn_swig_rb_ra_lock_callback(void *baton,
2756                              const char *path,
2757                              svn_boolean_t do_lock,
2758                              const svn_lock_t *lock,
2759                              svn_error_t *ra_err,
2760                              apr_pool_t *pool)
2761 {
2762   svn_error_t *err = SVN_NO_ERROR;
2763   VALUE proc, rb_pool;
2764 
2765   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2766 
2767   if (!NIL_P(proc)) {
2768     callback_baton_t cbb;
2769 
2770     cbb.receiver = proc;
2771     cbb.message = id_call;
2772     cbb.args = rb_ary_new3(4,
2773                            c2r_string2(path),
2774                            do_lock ? Qtrue : Qfalse,
2775                            c2r_lock__dup(lock),
2776                            ra_err ?
2777                              svn_swig_rb_svn_error_to_rb_error(ra_err) :
2778                              Qnil);
2779     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2780   }
2781 
2782   return err;
2783 }
2784 
2785 svn_error_t *
svn_swig_rb_just_call(void * baton)2786 svn_swig_rb_just_call(void *baton)
2787 {
2788   svn_error_t *err = SVN_NO_ERROR;
2789   VALUE proc, rb_pool;
2790 
2791   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2792 
2793   if (!NIL_P(proc)) {
2794     callback_baton_t cbb;
2795 
2796     cbb.receiver = proc;
2797     cbb.message = id_call;
2798     cbb.args = rb_ary_new3(0);
2799     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2800   }
2801 
2802   return err;
2803 }
2804 
2805 svn_error_t *
svn_swig_rb_ra_file_rev_handler(void * baton,const char * path,svn_revnum_t rev,apr_hash_t * rev_props,svn_txdelta_window_handler_t * delta_handler,void ** delta_baton,apr_array_header_t * prop_diffs,apr_pool_t * pool)2806 svn_swig_rb_ra_file_rev_handler(void *baton,
2807                                 const char *path,
2808                                 svn_revnum_t rev,
2809                                 apr_hash_t *rev_props,
2810                                 svn_txdelta_window_handler_t *delta_handler,
2811                                 void **delta_baton,
2812                                 apr_array_header_t *prop_diffs,
2813                                 apr_pool_t *pool)
2814 {
2815   svn_error_t *err = SVN_NO_ERROR;
2816   VALUE proc, rb_pool;
2817 
2818   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2819 
2820   if (!NIL_P(proc)) {
2821     callback_baton_t cbb;
2822 
2823     cbb.receiver = proc;
2824     cbb.message = id_call;
2825     cbb.args = rb_ary_new3(4,
2826                            c2r_string2(path),
2827                            c2r_long(&rev, NULL),
2828                            svn_swig_rb_apr_hash_to_hash_svn_string(rev_props),
2829                            svn_swig_rb_prop_apr_array_to_hash_prop(prop_diffs));
2830     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2831   }
2832 
2833   return err;
2834 }
2835 
2836 svn_error_t *
svn_swig_rb_repos_history_func(void * baton,const char * path,svn_revnum_t revision,apr_pool_t * pool)2837 svn_swig_rb_repos_history_func(void *baton,
2838                                const char *path,
2839                                svn_revnum_t revision,
2840                                apr_pool_t *pool)
2841 {
2842   svn_error_t *err = SVN_NO_ERROR;
2843   VALUE proc, rb_pool;
2844 
2845   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2846 
2847   if (!NIL_P(proc)) {
2848     callback_baton_t cbb;
2849     VALUE result = Qnil;
2850 
2851     cbb.receiver = proc;
2852     cbb.message = id_call;
2853     cbb.args = rb_ary_new3(2,
2854                            c2r_string2(path),
2855                            c2r_long(&revision, NULL));
2856     result = invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2857 
2858     if (!err && SVN_ERR_P(result)) {
2859       err = r2c_svn_err(result, NULL, NULL);
2860     }
2861   }
2862 
2863   return err;
2864 }
2865 
2866 svn_error_t *
svn_swig_rb_repos_file_rev_handler(void * baton,const char * path,svn_revnum_t rev,apr_hash_t * rev_props,svn_txdelta_window_handler_t * delta_handler,void ** delta_baton,apr_array_header_t * prop_diffs,apr_pool_t * pool)2867 svn_swig_rb_repos_file_rev_handler(void *baton,
2868                                    const char *path,
2869                                    svn_revnum_t rev,
2870                                    apr_hash_t *rev_props,
2871                                    svn_txdelta_window_handler_t *delta_handler,
2872                                    void **delta_baton,
2873                                    apr_array_header_t *prop_diffs,
2874                                    apr_pool_t *pool)
2875 {
2876   svn_error_t *err = SVN_NO_ERROR;
2877   VALUE proc, rb_pool;
2878 
2879   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2880 
2881   if (!NIL_P(proc)) {
2882     callback_baton_t cbb;
2883 
2884     cbb.receiver = proc;
2885     cbb.message = id_call;
2886     cbb.args = rb_ary_new3(4,
2887                            c2r_string2(path),
2888                            c2r_long(&rev, NULL),
2889                            svn_swig_rb_apr_hash_to_hash_svn_string(rev_props),
2890                            svn_swig_rb_prop_apr_array_to_hash_prop(prop_diffs));
2891     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2892   }
2893 
2894   return err;
2895 }
2896 
2897 svn_error_t *
svn_swig_rb_wc_relocation_validator3(void * baton,const char * uuid,const char * url,const char * root_url,apr_pool_t * pool)2898 svn_swig_rb_wc_relocation_validator3(void *baton,
2899                                      const char *uuid,
2900                                      const char *url,
2901                                      const char *root_url,
2902                                      apr_pool_t *pool)
2903 {
2904   svn_error_t *err = SVN_NO_ERROR;
2905   VALUE proc, rb_pool;
2906 
2907   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2908 
2909   if (!NIL_P(proc)) {
2910     callback_baton_t cbb;
2911 
2912     cbb.receiver = proc;
2913     cbb.message = id_call;
2914     cbb.args = rb_ary_new3(3,
2915                            c2r_string2(uuid),
2916                            c2r_string2(url),
2917                            c2r_string2(root_url));
2918     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2919   }
2920 
2921   return err;
2922 }
2923 
2924 
2925 
2926 /* auth provider callbacks */
2927 svn_error_t *
svn_swig_rb_auth_simple_prompt_func(svn_auth_cred_simple_t ** cred,void * baton,const char * realm,const char * username,svn_boolean_t may_save,apr_pool_t * pool)2928 svn_swig_rb_auth_simple_prompt_func(svn_auth_cred_simple_t **cred,
2929                                     void *baton,
2930                                     const char *realm,
2931                                     const char *username,
2932                                     svn_boolean_t may_save,
2933                                     apr_pool_t *pool)
2934 {
2935   svn_auth_cred_simple_t *new_cred = NULL;
2936   svn_error_t *err = SVN_NO_ERROR;
2937   VALUE proc, rb_pool;
2938 
2939   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2940 
2941   if (!NIL_P(proc)) {
2942     callback_baton_t cbb;
2943     VALUE result;
2944 
2945     cbb.receiver = proc;
2946     cbb.message = id_call;
2947     cbb.args = rb_ary_new3(3,
2948                            c2r_string2(realm),
2949                            c2r_string2(username),
2950                            RTEST(may_save) ? Qtrue : Qfalse);
2951     result = invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2952 
2953     if (!NIL_P(result)) {
2954       void *result_cred = NULL;
2955       svn_auth_cred_simple_t *tmp_cred = NULL;
2956 
2957       r2c_swig_type2(result, "svn_auth_cred_simple_t *", &result_cred);
2958       tmp_cred = (svn_auth_cred_simple_t *)result_cred;
2959       new_cred = apr_pcalloc(pool, sizeof(*new_cred));
2960       new_cred->username = tmp_cred->username ?
2961         apr_pstrdup(pool, tmp_cred->username) : NULL;
2962       new_cred->password = tmp_cred->password ?
2963         apr_pstrdup(pool, tmp_cred->password) : NULL;
2964       new_cred->may_save = tmp_cred->may_save;
2965     }
2966   }
2967 
2968   *cred = new_cred;
2969   return err;
2970 }
2971 
2972 svn_error_t *
svn_swig_rb_auth_gnome_keyring_unlock_prompt_func(char ** keyring_passwd,const char * keyring_name,void * baton,apr_pool_t * pool)2973 svn_swig_rb_auth_gnome_keyring_unlock_prompt_func(char **keyring_passwd,
2974                                                   const char *keyring_name,
2975                                                   void *baton,
2976                                                   apr_pool_t *pool)
2977 {
2978   svn_error_t *err = SVN_NO_ERROR;
2979   VALUE proc, rb_pool;
2980   *keyring_passwd = NULL;
2981 
2982   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
2983 
2984   if (!NIL_P(proc)) {
2985     char error_message[] =
2986       "svn_auth_gnome_keyring_unlock_prompt_func_t should"
2987       "return a string, not '%s'.";
2988 
2989     callback_baton_t cbb;
2990     VALUE result;
2991 
2992     cbb.receiver = proc;
2993     cbb.message = id_call;
2994     cbb.args = rb_ary_new3(1, c2r_string2(keyring_name));
2995     result = invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
2996 
2997     if (!NIL_P(result)) {
2998       if (!RTEST(rb_obj_is_kind_of(result, rb_cString)))
2999         rb_raise(rb_eTypeError, error_message, r2c_inspect(result));
3000       *keyring_passwd = (char *)r2c_string(result, NULL, pool);
3001     }
3002   }
3003 
3004   return err;
3005 }
3006 
3007 svn_error_t *
svn_swig_rb_auth_username_prompt_func(svn_auth_cred_username_t ** cred,void * baton,const char * realm,svn_boolean_t may_save,apr_pool_t * pool)3008 svn_swig_rb_auth_username_prompt_func(svn_auth_cred_username_t **cred,
3009                                       void *baton,
3010                                       const char *realm,
3011                                       svn_boolean_t may_save,
3012                                       apr_pool_t *pool)
3013 {
3014   svn_auth_cred_username_t *new_cred = NULL;
3015   svn_error_t *err = SVN_NO_ERROR;
3016   VALUE proc, rb_pool;
3017 
3018   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
3019 
3020   if (!NIL_P(proc)) {
3021     callback_baton_t cbb;
3022     VALUE result;
3023 
3024     cbb.receiver = proc;
3025     cbb.message = id_call;
3026     cbb.args = rb_ary_new3(2,
3027                            c2r_string2(realm),
3028                            RTEST(may_save) ? Qtrue : Qfalse);
3029     result = invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3030 
3031     if (!NIL_P(result)) {
3032       void *result_cred = NULL;
3033       svn_auth_cred_username_t *tmp_cred = NULL;
3034 
3035       r2c_swig_type2(result, "svn_auth_cred_username_t *", &result_cred);
3036       tmp_cred = (svn_auth_cred_username_t *)result_cred;
3037       new_cred = apr_pcalloc(pool, sizeof(*new_cred));
3038       new_cred->username = tmp_cred->username ?
3039         apr_pstrdup(pool, tmp_cred->username) : NULL;
3040       new_cred->may_save = tmp_cred->may_save;
3041     }
3042   }
3043 
3044   *cred = new_cred;
3045   return err;
3046 }
3047 
3048 svn_error_t *
svn_swig_rb_auth_ssl_server_trust_prompt_func(svn_auth_cred_ssl_server_trust_t ** cred,void * baton,const char * realm,apr_uint32_t failures,const svn_auth_ssl_server_cert_info_t * cert_info,svn_boolean_t may_save,apr_pool_t * pool)3049 svn_swig_rb_auth_ssl_server_trust_prompt_func(
3050   svn_auth_cred_ssl_server_trust_t **cred,
3051   void *baton,
3052   const char *realm,
3053   apr_uint32_t failures,
3054   const svn_auth_ssl_server_cert_info_t *cert_info,
3055   svn_boolean_t may_save,
3056   apr_pool_t *pool)
3057 {
3058   svn_auth_cred_ssl_server_trust_t *new_cred = NULL;
3059   svn_error_t *err = SVN_NO_ERROR;
3060   VALUE proc, rb_pool;
3061 
3062   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
3063 
3064   if (!NIL_P(proc)) {
3065     callback_baton_t cbb;
3066     VALUE result;
3067 
3068     cbb.receiver = proc;
3069     cbb.message = id_call;
3070     cbb.args = rb_ary_new3(4,
3071                            c2r_string2(realm),
3072                            UINT2NUM(failures),
3073                            c2r_auth_ssl_server_cert_info__dup(cert_info),
3074                            RTEST(may_save) ? Qtrue : Qfalse);
3075     result = invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3076 
3077     if (!NIL_P(result)) {
3078       void *result_cred;
3079       svn_auth_cred_ssl_server_trust_t *tmp_cred = NULL;
3080 
3081       r2c_swig_type2(result, "svn_auth_cred_ssl_server_trust_t *",
3082                      &result_cred);
3083       tmp_cred = (svn_auth_cred_ssl_server_trust_t *)result_cred;
3084       new_cred = apr_pcalloc(pool, sizeof(*new_cred));
3085       *new_cred = *tmp_cred;
3086     }
3087   }
3088 
3089   *cred = new_cred;
3090   return err;
3091 }
3092 
3093 svn_error_t *
svn_swig_rb_auth_ssl_client_cert_prompt_func(svn_auth_cred_ssl_client_cert_t ** cred,void * baton,const char * realm,svn_boolean_t may_save,apr_pool_t * pool)3094 svn_swig_rb_auth_ssl_client_cert_prompt_func(
3095   svn_auth_cred_ssl_client_cert_t **cred,
3096   void *baton,
3097   const char *realm,
3098   svn_boolean_t may_save,
3099   apr_pool_t *pool)
3100 {
3101   svn_auth_cred_ssl_client_cert_t *new_cred = NULL;
3102   svn_error_t *err = SVN_NO_ERROR;
3103   VALUE proc, rb_pool;
3104 
3105   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
3106 
3107   if (!NIL_P(proc)) {
3108     callback_baton_t cbb;
3109     VALUE result;
3110 
3111     cbb.receiver = proc;
3112     cbb.message = id_call;
3113     cbb.args = rb_ary_new3(2,
3114                            c2r_string2(realm),
3115                            RTEST(may_save) ? Qtrue : Qfalse);
3116     result = invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3117 
3118     if (!NIL_P(result)) {
3119       void *result_cred = NULL;
3120       svn_auth_cred_ssl_client_cert_t *tmp_cred = NULL;
3121 
3122       r2c_swig_type2(result, "svn_auth_cred_ssl_client_cert_t *",
3123                      &result_cred);
3124       tmp_cred = (svn_auth_cred_ssl_client_cert_t *)result_cred;
3125       new_cred = apr_pcalloc(pool, sizeof(*new_cred));
3126       new_cred->cert_file = tmp_cred->cert_file ?
3127         apr_pstrdup(pool, tmp_cred->cert_file) : NULL;
3128       new_cred->may_save = tmp_cred->may_save;
3129     }
3130   }
3131 
3132   *cred = new_cred;
3133   return err;
3134 }
3135 
3136 svn_error_t *
svn_swig_rb_auth_ssl_client_cert_pw_prompt_func(svn_auth_cred_ssl_client_cert_pw_t ** cred,void * baton,const char * realm,svn_boolean_t may_save,apr_pool_t * pool)3137 svn_swig_rb_auth_ssl_client_cert_pw_prompt_func(
3138   svn_auth_cred_ssl_client_cert_pw_t **cred,
3139   void *baton,
3140   const char *realm,
3141   svn_boolean_t may_save,
3142   apr_pool_t *pool)
3143 {
3144   svn_auth_cred_ssl_client_cert_pw_t *new_cred = NULL;
3145   svn_error_t *err = SVN_NO_ERROR;
3146   VALUE proc, rb_pool;
3147 
3148   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
3149 
3150   if (!NIL_P(proc)) {
3151     callback_baton_t cbb;
3152     VALUE result;
3153 
3154     cbb.receiver = proc;
3155     cbb.message = id_call;
3156     cbb.args = rb_ary_new3(2,
3157                            c2r_string2(realm),
3158                            RTEST(may_save) ? Qtrue : Qfalse);
3159     result = invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3160 
3161     if (!NIL_P(result)) {
3162       void *result_cred = NULL;
3163       svn_auth_cred_ssl_client_cert_pw_t *tmp_cred = NULL;
3164 
3165       r2c_swig_type2(result, "svn_auth_cred_ssl_client_cert_pw_t *",
3166                      &result_cred);
3167       tmp_cred = (svn_auth_cred_ssl_client_cert_pw_t *)result_cred;
3168       new_cred = apr_pcalloc(pool, sizeof(*new_cred));
3169       new_cred->password = tmp_cred->password ?
3170         apr_pstrdup(pool, tmp_cred->password) : NULL;
3171       new_cred->may_save = tmp_cred->may_save;
3172     }
3173   }
3174 
3175   *cred = new_cred;
3176   return err;
3177 }
3178 
3179 
3180 apr_file_t *
svn_swig_rb_make_file(VALUE file,apr_pool_t * pool)3181 svn_swig_rb_make_file(VALUE file, apr_pool_t *pool)
3182 {
3183   apr_file_t *apr_file = NULL;
3184 
3185   apr_file_open(&apr_file, StringValuePtr(file),
3186                 APR_CREATE | APR_READ | APR_WRITE,
3187                 APR_OS_DEFAULT,
3188                 pool);
3189 
3190   return apr_file;
3191 }
3192 
3193 
3194 static svn_error_t *
read_handler_rbio(void * baton,char * buffer,apr_size_t * len)3195 read_handler_rbio(void *baton, char *buffer, apr_size_t *len)
3196 {
3197   VALUE result;
3198   VALUE io = (VALUE)baton;
3199   svn_error_t *err = SVN_NO_ERROR;
3200 
3201   result = rb_funcall(io, id_read, 1, INT2NUM(*len));
3202   if (NIL_P(result)) {
3203     *len = 0;
3204   } else {
3205     memcpy(buffer, StringValuePtr(result), RSTRING_LEN(result));
3206     *len = RSTRING_LEN(result);
3207   }
3208 
3209   return err;
3210 }
3211 
3212 static svn_error_t *
write_handler_rbio(void * baton,const char * data,apr_size_t * len)3213 write_handler_rbio(void *baton, const char *data, apr_size_t *len)
3214 {
3215   VALUE io = (VALUE)baton;
3216   svn_error_t *err = SVN_NO_ERROR;
3217 
3218   rb_funcall(io, id_write, 1, rb_str_new(data, *len));
3219 
3220   return err;
3221 }
3222 
3223 svn_stream_t *
svn_swig_rb_make_stream(VALUE io)3224 svn_swig_rb_make_stream(VALUE io)
3225 {
3226   svn_stream_t *stream;
3227 
3228   if (RTEST(rb_funcall(rb_svn_core_stream(), id_eqq, 1, io))) {
3229     svn_stream_t **stream_p;
3230     stream_p = &stream;
3231     r2c_swig_type2(io, "svn_stream_t *", (void **)stream_p);
3232   } else {
3233     VALUE rb_pool = rb_pool_new(Qnil);
3234     apr_pool_wrapper_t *pool_wrapper;
3235     apr_pool_wrapper_t **pool_wrapper_p;
3236 
3237     rb_set_pool(io, rb_pool);
3238     pool_wrapper_p = &pool_wrapper;
3239     r2c_swig_type2(rb_pool, "apr_pool_wrapper_t *", (void **)pool_wrapper_p);
3240     stream = svn_stream_create((void *)io, pool_wrapper->pool);
3241     svn_stream_set_read2(stream, NULL /* only full read support */,
3242                          read_handler_rbio);
3243     svn_stream_set_write(stream, write_handler_rbio);
3244   }
3245 
3246   return stream;
3247 }
3248 
3249 VALUE
svn_swig_rb_filename_to_temp_file(const char * file_name)3250 svn_swig_rb_filename_to_temp_file(const char *file_name)
3251 {
3252   return rb_funcall(rb_svn_util(), id_filename_to_temp_file,
3253                     1, rb_str_new2(file_name));
3254 }
3255 
3256 void
svn_swig_rb_set_revision(svn_opt_revision_t * rev,VALUE value)3257 svn_swig_rb_set_revision(svn_opt_revision_t *rev, VALUE value)
3258 {
3259   switch (TYPE(value)) {
3260   case T_NIL:
3261     rev->kind = svn_opt_revision_unspecified;
3262     break;
3263   case T_FIXNUM:
3264     rev->kind = svn_opt_revision_number;
3265     rev->value.number = NUM2LONG(value);
3266     break;
3267   case T_STRING:
3268     if (RTEST(rb_reg_match(rb_reg_new("^BASE$",
3269                                       strlen("^BASE$"),
3270                                       RE_OPTION_IGNORECASE),
3271                            value)))
3272       rev->kind = svn_opt_revision_base;
3273     else if (RTEST(rb_reg_match(rb_reg_new("^HEAD$",
3274                                            strlen("^HEAD$"),
3275                                            RE_OPTION_IGNORECASE),
3276                                 value)))
3277       rev->kind = svn_opt_revision_head;
3278     else if (RTEST(rb_reg_match(rb_reg_new("^WORKING$",
3279                                            strlen("^WORKING$"),
3280                                            RE_OPTION_IGNORECASE),
3281                                 value)))
3282       rev->kind = svn_opt_revision_working;
3283     else if (RTEST(rb_reg_match(rb_reg_new("^COMMITTED$",
3284                                            strlen("^COMMITTED$"),
3285                                            RE_OPTION_IGNORECASE),
3286                                 value)))
3287       rev->kind = svn_opt_revision_committed;
3288     else if (RTEST(rb_reg_match(rb_reg_new("^PREV$",
3289                                            strlen("^PREV$"),
3290                                            RE_OPTION_IGNORECASE),
3291                                 value)))
3292       rev->kind = svn_opt_revision_previous;
3293     else
3294       rb_raise(rb_eArgError,
3295                "invalid value: %s",
3296                StringValuePtr(value));
3297     break;
3298   default:
3299     if (rb_obj_is_kind_of(value,
3300                           rb_const_get(rb_cObject, rb_intern("Time")))) {
3301       double sec;
3302       double whole_sec;
3303       double frac_sec;
3304 
3305       sec = NUM2DBL(rb_funcall(value, rb_intern("to_f"), 0));
3306       frac_sec = modf(sec, &whole_sec);
3307 
3308       rev->kind = svn_opt_revision_date;
3309       rev->value.date = apr_time_make(whole_sec, frac_sec*APR_USEC_PER_SEC);
3310     } else {
3311       rb_raise(rb_eArgError,
3312                "invalid type: %s",
3313                rb_class2name(CLASS_OF(value)));
3314     }
3315     break;
3316   }
3317 }
3318 
3319 void
svn_swig_rb_adjust_arg_for_client_ctx_and_pool(int * argc,VALUE ** argv)3320 svn_swig_rb_adjust_arg_for_client_ctx_and_pool(int *argc, VALUE **argv)
3321 {
3322   if (*argc > 1) {
3323     VALUE last_arg = (*argv)[*argc - 1];
3324     if (NIL_P(last_arg) || POOL_P(last_arg)) {
3325       *argv += *argc - 2;
3326       *argc = 2;
3327     } else {
3328       if (CONTEXT_P(last_arg)) {
3329         *argv += *argc - 1;
3330         *argc = 1;
3331       } else {
3332         *argv += *argc - 2;
3333         *argc = 2;
3334       }
3335     }
3336   }
3337 }
3338 
3339 void
svn_swig_rb_wc_status_func(void * baton,const char * path,svn_wc_status2_t * status)3340 svn_swig_rb_wc_status_func(void *baton,
3341                            const char *path,
3342                            svn_wc_status2_t *status)
3343 {
3344   VALUE proc, rb_pool;
3345 
3346   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
3347 
3348   if (!NIL_P(proc)) {
3349     callback_baton_t cbb;
3350 
3351     cbb.receiver = proc;
3352     cbb.message = id_call;
3353     cbb.args = rb_ary_new3(2, c2r_string2(path), c2r_wc_status2__dup(status));
3354     invoke_callback((VALUE)(&cbb), rb_pool);
3355   }
3356 }
3357 
3358 svn_error_t *
svn_swig_rb_client_blame_receiver_func(void * baton,apr_int64_t line_no,svn_revnum_t revision,const char * author,const char * date,const char * line,apr_pool_t * pool)3359 svn_swig_rb_client_blame_receiver_func(void *baton,
3360                                        apr_int64_t line_no,
3361                                        svn_revnum_t revision,
3362                                        const char *author,
3363                                        const char *date,
3364                                        const char *line,
3365                                        apr_pool_t *pool)
3366 {
3367   svn_error_t *err = SVN_NO_ERROR;
3368   VALUE proc, rb_pool;
3369 
3370   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
3371 
3372   if (!NIL_P(proc)) {
3373     callback_baton_t cbb;
3374 
3375     cbb.receiver = proc;
3376     cbb.message = id_call;
3377     cbb.args = rb_ary_new3(5,
3378                            AI642NUM(line_no),
3379                            INT2NUM(revision),
3380                            c2r_string2(author),
3381                            c2r_svn_date_string2(date),
3382                            c2r_string2(line));
3383     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3384   }
3385 
3386   return err;
3387 }
3388 
3389 
3390 
3391 /* svn_wc_entry_callbacks2_t */
3392 static svn_error_t *
wc_entry_callbacks2_found_entry(const char * path,const svn_wc_entry_t * entry,void * walk_baton,apr_pool_t * pool)3393 wc_entry_callbacks2_found_entry(const char *path,
3394                                 const svn_wc_entry_t *entry,
3395                                 void *walk_baton,
3396                                 apr_pool_t *pool)
3397 {
3398   svn_error_t *err = SVN_NO_ERROR;
3399   VALUE callbacks, rb_pool;
3400 
3401   svn_swig_rb_from_baton((VALUE)walk_baton, &callbacks, &rb_pool);
3402 
3403   if (!NIL_P(callbacks)) {
3404     callback_baton_t cbb;
3405 
3406     cbb.receiver = callbacks;
3407     cbb.message = id_found_entry;
3408     cbb.args = rb_ary_new3(2,
3409                            c2r_string2(path),
3410                            c2r_wc_entry__dup(entry));
3411     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3412   }
3413 
3414   return err;
3415 }
3416 
3417 static svn_error_t *
wc_entry_callbacks2_handle_error(const char * path,svn_error_t * err,void * walk_baton,apr_pool_t * pool)3418 wc_entry_callbacks2_handle_error(const char *path,
3419                                  svn_error_t *err,
3420                                  void *walk_baton,
3421                                  apr_pool_t *pool)
3422 {
3423   VALUE callbacks, rb_pool;
3424 
3425   svn_swig_rb_from_baton((VALUE)walk_baton, &callbacks, &rb_pool);
3426 
3427   if (!NIL_P(callbacks)) {
3428     callback_baton_t cbb;
3429     ID message;
3430 
3431     message = id_handle_error;
3432     if (rb_obj_respond_to(callbacks, message, FALSE)) {
3433       VALUE rb_err;
3434 
3435       cbb.receiver = callbacks;
3436       cbb.message = id_handle_error;
3437       rb_err = err ? svn_swig_rb_svn_error_to_rb_error(err) : Qnil;
3438       if (err)
3439         svn_error_clear(err);
3440       err = NULL;
3441       cbb.args = rb_ary_new3(2, c2r_string2(path), rb_err);
3442       invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3443     }
3444   }
3445 
3446   return err;
3447 }
3448 
3449 svn_wc_entry_callbacks2_t *
svn_swig_rb_wc_entry_callbacks2(void)3450 svn_swig_rb_wc_entry_callbacks2(void)
3451 {
3452   static svn_wc_entry_callbacks2_t wc_entry_callbacks = {
3453     wc_entry_callbacks2_found_entry,
3454     wc_entry_callbacks2_handle_error,
3455   };
3456 
3457   return &wc_entry_callbacks;
3458 }
3459 
3460 
3461 
3462 /* svn_wc_diff_callbacks2_t */
3463 static svn_error_t *
wc_diff_callbacks_file_changed(svn_wc_adm_access_t * adm_access,svn_wc_notify_state_t * contentstate,svn_wc_notify_state_t * propstate,const char * path,const char * tmpfile1,const char * tmpfile2,svn_revnum_t rev1,svn_revnum_t rev2,const char * mimetype1,const char * mimetype2,const apr_array_header_t * propchanges,apr_hash_t * originalprops,void * diff_baton)3464 wc_diff_callbacks_file_changed(svn_wc_adm_access_t *adm_access,
3465                                svn_wc_notify_state_t *contentstate,
3466                                svn_wc_notify_state_t *propstate,
3467                                const char *path,
3468                                const char *tmpfile1,
3469                                const char *tmpfile2,
3470                                svn_revnum_t rev1,
3471                                svn_revnum_t rev2,
3472                                const char *mimetype1,
3473                                const char *mimetype2,
3474                                const apr_array_header_t *propchanges,
3475                                apr_hash_t *originalprops,
3476                                void *diff_baton)
3477 {
3478   VALUE callbacks, rb_pool;
3479   svn_error_t *err = SVN_NO_ERROR;
3480 
3481   svn_swig_rb_from_baton((VALUE)diff_baton, &callbacks, &rb_pool);
3482   if (!NIL_P(callbacks)) {
3483     callback_baton_t cbb;
3484     VALUE result = Qnil;
3485 
3486     cbb.receiver = callbacks;
3487     cbb.message = id_file_changed;
3488     cbb.args = rb_ary_new3(10,
3489                            c2r_swig_type((void *)adm_access,
3490                                          (void *)"svn_wc_adm_access_t *"),
3491                            c2r_string2(path),
3492                            c2r_string2(tmpfile1),
3493                            c2r_string2(tmpfile2),
3494                            INT2NUM(rev1),
3495                            INT2NUM(rev2),
3496                            c2r_string2(mimetype1),
3497                            c2r_string2(mimetype2),
3498                            svn_swig_rb_prop_apr_array_to_hash_prop(propchanges),
3499                            svn_swig_rb_prop_hash_to_hash(originalprops));
3500     result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
3501 
3502     if (contentstate)
3503       *contentstate = NUM2INT(rb_ary_entry(result, 0));
3504     if (propstate)
3505       *propstate = NUM2INT(rb_ary_entry(result, 1));
3506   }
3507 
3508   return err;
3509 }
3510 
3511 static svn_error_t *
wc_diff_callbacks_file_added(svn_wc_adm_access_t * adm_access,svn_wc_notify_state_t * contentstate,svn_wc_notify_state_t * propstate,const char * path,const char * tmpfile1,const char * tmpfile2,svn_revnum_t rev1,svn_revnum_t rev2,const char * mimetype1,const char * mimetype2,const apr_array_header_t * propchanges,apr_hash_t * originalprops,void * diff_baton)3512 wc_diff_callbacks_file_added(svn_wc_adm_access_t *adm_access,
3513                              svn_wc_notify_state_t *contentstate,
3514                              svn_wc_notify_state_t *propstate,
3515                              const char *path,
3516                              const char *tmpfile1,
3517                              const char *tmpfile2,
3518                              svn_revnum_t rev1,
3519                              svn_revnum_t rev2,
3520                              const char *mimetype1,
3521                              const char *mimetype2,
3522                              const apr_array_header_t *propchanges,
3523                              apr_hash_t *originalprops,
3524                              void *diff_baton)
3525 {
3526   VALUE callbacks, rb_pool;
3527   svn_error_t *err = SVN_NO_ERROR;
3528 
3529   svn_swig_rb_from_baton((VALUE)diff_baton, &callbacks, &rb_pool);
3530   if (!NIL_P(callbacks)) {
3531     callback_baton_t cbb;
3532     VALUE result = Qnil;
3533 
3534     cbb.receiver = callbacks;
3535     cbb.message = id_file_added;
3536     cbb.args = rb_ary_new3(10,
3537                            c2r_swig_type((void *)adm_access,
3538                                          (void *)"svn_wc_adm_access_t *"),
3539                            c2r_string2(path),
3540                            c2r_string2(tmpfile1),
3541                            c2r_string2(tmpfile2),
3542                            INT2NUM(rev1),
3543                            INT2NUM(rev2),
3544                            c2r_string2(mimetype1),
3545                            c2r_string2(mimetype2),
3546                            svn_swig_rb_prop_apr_array_to_hash_prop(propchanges),
3547                            svn_swig_rb_prop_hash_to_hash(originalprops));
3548     result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
3549 
3550     if (contentstate)
3551       *contentstate = NUM2INT(rb_ary_entry(result, 0));
3552     if (propstate)
3553       *propstate = NUM2INT(rb_ary_entry(result, 1));
3554   }
3555 
3556   return err;
3557 }
3558 
3559 static svn_error_t *
wc_diff_callbacks_file_deleted(svn_wc_adm_access_t * adm_access,svn_wc_notify_state_t * state,const char * path,const char * tmpfile1,const char * tmpfile2,const char * mimetype1,const char * mimetype2,apr_hash_t * originalprops,void * diff_baton)3560 wc_diff_callbacks_file_deleted(svn_wc_adm_access_t *adm_access,
3561                                svn_wc_notify_state_t *state,
3562                                const char *path,
3563                                const char *tmpfile1,
3564                                const char *tmpfile2,
3565                                const char *mimetype1,
3566                                const char *mimetype2,
3567                                apr_hash_t *originalprops,
3568                                void *diff_baton)
3569 {
3570   VALUE callbacks, rb_pool;
3571   svn_error_t *err = SVN_NO_ERROR;
3572 
3573   svn_swig_rb_from_baton((VALUE)diff_baton, &callbacks, &rb_pool);
3574   if (!NIL_P(callbacks)) {
3575     callback_baton_t cbb;
3576     VALUE result = Qnil;
3577 
3578     cbb.receiver = callbacks;
3579     cbb.message = id_file_deleted;
3580     cbb.args = rb_ary_new3(7,
3581                            c2r_swig_type((void *)adm_access,
3582                                          (void *)"svn_wc_adm_access_t *"),
3583                            c2r_string2(path),
3584                            c2r_string2(tmpfile1),
3585                            c2r_string2(tmpfile2),
3586                            c2r_string2(mimetype1),
3587                            c2r_string2(mimetype2),
3588                            svn_swig_rb_prop_hash_to_hash(originalprops));
3589     result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
3590     if (state)
3591       *state = NUM2INT(result);
3592   }
3593 
3594   return err;
3595 }
3596 
3597 static svn_error_t *
wc_diff_callbacks_dir_added(svn_wc_adm_access_t * adm_access,svn_wc_notify_state_t * state,const char * path,svn_revnum_t rev,void * diff_baton)3598 wc_diff_callbacks_dir_added(svn_wc_adm_access_t *adm_access,
3599                             svn_wc_notify_state_t *state,
3600                             const char *path,
3601                             svn_revnum_t rev,
3602                             void *diff_baton)
3603 {
3604   VALUE callbacks, rb_pool;
3605   svn_error_t *err = SVN_NO_ERROR;
3606 
3607   svn_swig_rb_from_baton((VALUE)diff_baton, &callbacks, &rb_pool);
3608   if (!NIL_P(callbacks)) {
3609     callback_baton_t cbb;
3610     VALUE result = Qnil;
3611 
3612     cbb.receiver = callbacks;
3613     cbb.message = id_dir_added;
3614     cbb.args = rb_ary_new3(3,
3615                            c2r_swig_type((void *)adm_access,
3616                                          (void *)"svn_wc_adm_access_t *"),
3617                            c2r_string2(path),
3618                            INT2NUM(rev));
3619     result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
3620     if (state)
3621       *state = NUM2INT(result);
3622   }
3623 
3624   return err;
3625 }
3626 
3627 static svn_error_t *
wc_diff_callbacks_dir_deleted(svn_wc_adm_access_t * adm_access,svn_wc_notify_state_t * state,const char * path,void * diff_baton)3628 wc_diff_callbacks_dir_deleted(svn_wc_adm_access_t *adm_access,
3629                               svn_wc_notify_state_t *state,
3630                               const char *path,
3631                               void *diff_baton)
3632 {
3633   VALUE callbacks, rb_pool;
3634   svn_error_t *err = SVN_NO_ERROR;
3635 
3636   svn_swig_rb_from_baton((VALUE)diff_baton, &callbacks, &rb_pool);
3637   if (!NIL_P(callbacks)) {
3638     callback_baton_t cbb;
3639     VALUE result = Qnil;
3640 
3641     cbb.receiver = callbacks;
3642     cbb.message = id_dir_deleted;
3643     cbb.args = rb_ary_new3(2,
3644                            c2r_swig_type((void *)adm_access,
3645                                          (void *)"svn_wc_adm_access_t *"),
3646                            c2r_string2(path));
3647     result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
3648     if (state)
3649       *state = NUM2INT(result);
3650   }
3651 
3652   return err;
3653 }
3654 
3655 static svn_error_t *
wc_diff_callbacks_dir_props_changed(svn_wc_adm_access_t * adm_access,svn_wc_notify_state_t * state,const char * path,const apr_array_header_t * propchanges,apr_hash_t * originalprops,void * diff_baton)3656 wc_diff_callbacks_dir_props_changed(svn_wc_adm_access_t *adm_access,
3657                                     svn_wc_notify_state_t *state,
3658                                     const char *path,
3659                                     const apr_array_header_t *propchanges,
3660                                     apr_hash_t *originalprops,
3661                                     void *diff_baton)
3662 {
3663   VALUE callbacks, rb_pool;
3664   svn_error_t *err = SVN_NO_ERROR;
3665 
3666   svn_swig_rb_from_baton((VALUE)diff_baton, &callbacks, &rb_pool);
3667   if (!NIL_P(callbacks)) {
3668     callback_baton_t cbb;
3669     VALUE result = Qnil;
3670 
3671     cbb.receiver = callbacks;
3672     cbb.message = id_dir_props_changed;
3673     cbb.args = rb_ary_new3(4,
3674                            c2r_swig_type((void *)adm_access,
3675                                          (void *)"svn_wc_adm_access_t *"),
3676                            c2r_string2(path),
3677                            svn_swig_rb_prop_apr_array_to_hash_prop(propchanges),
3678                            svn_swig_rb_prop_hash_to_hash(originalprops));
3679     result = invoke_callback_handle_error((VALUE)(&cbb), Qnil, &err);
3680 
3681     if (state)
3682       *state = NUM2INT(result);
3683   }
3684 
3685   return err;
3686 }
3687 
3688 svn_wc_diff_callbacks2_t *
svn_swig_rb_wc_diff_callbacks2(void)3689 svn_swig_rb_wc_diff_callbacks2(void)
3690 {
3691   static svn_wc_diff_callbacks2_t wc_diff_callbacks2 = {
3692     wc_diff_callbacks_file_changed,
3693     wc_diff_callbacks_file_added,
3694     wc_diff_callbacks_file_deleted,
3695     wc_diff_callbacks_dir_added,
3696     wc_diff_callbacks_dir_deleted,
3697     wc_diff_callbacks_dir_props_changed
3698   };
3699 
3700   return &wc_diff_callbacks2;
3701 }
3702 
3703 
3704 VALUE
svn_swig_rb_make_txdelta_window_handler_wrapper(VALUE * rb_handler_pool,apr_pool_t ** handler_pool,svn_txdelta_window_handler_t ** handler,void *** handler_baton)3705 svn_swig_rb_make_txdelta_window_handler_wrapper(VALUE *rb_handler_pool,
3706                                                 apr_pool_t **handler_pool,
3707                                                 svn_txdelta_window_handler_t **handler,
3708                                                 void ***handler_baton)
3709 {
3710   VALUE obj;
3711 
3712   obj = rb_class_new_instance(0, NULL, rb_cObject);
3713   svn_swig_rb_get_pool(0, NULL, obj, rb_handler_pool, handler_pool);
3714   svn_swig_rb_set_pool_for_no_swig_type(obj, *rb_handler_pool);
3715   *handler = apr_palloc(*handler_pool, sizeof(svn_txdelta_window_handler_t));
3716   *handler_baton = apr_palloc(*handler_pool, sizeof(void *));
3717 
3718   return obj;
3719 }
3720 
3721 VALUE
svn_swig_rb_setup_txdelta_window_handler_wrapper(VALUE obj,svn_txdelta_window_handler_t handler,void * handler_baton)3722 svn_swig_rb_setup_txdelta_window_handler_wrapper(VALUE obj,
3723                                                  svn_txdelta_window_handler_t handler,
3724                                                  void *handler_baton)
3725 {
3726   rb_ivar_set(obj, id_handler,
3727               c2r_swig_type((void *)handler,
3728                             (void *)"svn_txdelta_window_handler_t"));
3729   rb_ivar_set(obj, id_handler_baton,
3730               c2r_swig_type(handler_baton, (void *)"void *"));
3731   return obj;
3732 }
3733 
3734 svn_error_t *
svn_swig_rb_invoke_txdelta_window_handler_wrapper(VALUE obj,svn_txdelta_window_t * window,apr_pool_t * pool)3735 svn_swig_rb_invoke_txdelta_window_handler_wrapper(VALUE obj,
3736                                                   svn_txdelta_window_t *window,
3737                                                   apr_pool_t *pool)
3738 {
3739   svn_txdelta_window_handler_t handler;
3740   svn_txdelta_window_handler_t *handler_p;
3741   void *handler_baton;
3742 
3743   handler_p = &handler;
3744   r2c_swig_type2(rb_ivar_get(obj, id_handler),
3745                  "svn_txdelta_window_handler_t", (void **)handler_p);
3746   r2c_swig_type2(rb_ivar_get(obj, id_handler_baton),
3747                  "void *", &handler_baton);
3748 
3749   return handler(window, handler_baton);
3750 }
3751 
3752 
3753 VALUE
svn_swig_rb_txdelta_window_t_ops_get(svn_txdelta_window_t * window)3754 svn_swig_rb_txdelta_window_t_ops_get(svn_txdelta_window_t *window)
3755 {
3756   VALUE ops;
3757   const svn_txdelta_op_t *op;
3758   int i;
3759 
3760   ops = rb_ary_new2(window->num_ops);
3761 
3762   for (i = 0; i < window->num_ops; i++) {
3763     op = window->ops + i;
3764     rb_ary_push(ops, c2r_swig_type((void *)op, (void *)"svn_txdelta_op_t *"));
3765   }
3766 
3767   return ops;
3768 }
3769 
3770 
3771 svn_error_t *
svn_swig_rb_client_diff_summarize_func(const svn_client_diff_summarize_t * diff,void * baton,apr_pool_t * pool)3772 svn_swig_rb_client_diff_summarize_func(const svn_client_diff_summarize_t *diff,
3773                                        void *baton,
3774                                        apr_pool_t *pool)
3775 {
3776   svn_error_t *err = SVN_NO_ERROR;
3777   VALUE proc, rb_pool;
3778 
3779   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
3780 
3781   if (!NIL_P(proc)) {
3782     callback_baton_t cbb;
3783 
3784     cbb.receiver = proc;
3785     cbb.message = id_call;
3786     cbb.args = rb_ary_new3(1, c2r_client_diff_summarize__dup(diff));
3787     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3788   }
3789 
3790   return err;
3791 }
3792 
3793 svn_error_t *
svn_swig_rb_client_list_func(void * baton,const char * path,const svn_dirent_t * dirent,const svn_lock_t * lock,const char * abs_path,apr_pool_t * pool)3794 svn_swig_rb_client_list_func(void *baton,
3795                              const char *path,
3796                              const svn_dirent_t *dirent,
3797                              const svn_lock_t *lock,
3798                              const char *abs_path,
3799                              apr_pool_t *pool)
3800 {
3801   svn_error_t *err = SVN_NO_ERROR;
3802   VALUE proc, rb_pool;
3803 
3804   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
3805 
3806   if (!NIL_P(proc)) {
3807     callback_baton_t cbb;
3808 
3809     cbb.receiver = proc;
3810     cbb.message = id_call;
3811     cbb.args = rb_ary_new3(4,
3812                            c2r_string2(path),
3813                            c2r_dirent__dup(dirent),
3814                            c2r_lock__dup(lock),
3815                            c2r_string2(abs_path));
3816     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3817   }
3818 
3819   return err;
3820 }
3821 
3822 svn_error_t *
svn_swig_rb_proplist_receiver(void * baton,const char * path,apr_hash_t * prop_hash,apr_pool_t * pool)3823 svn_swig_rb_proplist_receiver(void *baton,
3824                               const char *path,
3825                               apr_hash_t *prop_hash,
3826                               apr_pool_t *pool)
3827 {
3828   svn_error_t *err = SVN_NO_ERROR;
3829   VALUE proc, rb_pool;
3830 
3831   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
3832   if (!NIL_P(proc)) {
3833     callback_baton_t cbb;
3834 
3835     cbb.receiver = proc;
3836     cbb.message = id_call;
3837     cbb.args = rb_ary_new3(2,
3838                            c2r_string2(path),
3839                            svn_swig_rb_prop_hash_to_hash(prop_hash));
3840     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3841   }
3842 
3843   return err;
3844 }
3845 
3846 svn_error_t *
svn_swig_rb_changelist_receiver(void * baton,const char * path,const char * changelist,apr_pool_t * pool)3847 svn_swig_rb_changelist_receiver(void *baton,
3848                                 const char *path,
3849                                 const char *changelist,
3850                                 apr_pool_t *pool)
3851 {
3852   svn_error_t *err = SVN_NO_ERROR;
3853   VALUE proc, rb_pool;
3854 
3855   svn_swig_rb_from_baton((VALUE)baton, &proc, &rb_pool);
3856   if (!NIL_P(proc)) {
3857     callback_baton_t cbb;
3858 
3859     cbb.receiver = proc;
3860     cbb.message = id_call;
3861     cbb.args = rb_ary_new3(2,
3862                            c2r_string2(path),
3863                            c2r_string2(changelist));
3864     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3865   }
3866 
3867   return err;
3868 }
3869 
3870 
3871 /* svn_ra_reporter3_t */
3872 static void
c2r_ra_reporter3(VALUE rb_reporter,svn_ra_reporter3_t ** reporter,void ** baton,apr_pool_t * pool)3873 c2r_ra_reporter3(VALUE rb_reporter, svn_ra_reporter3_t **reporter, void **baton,
3874                  apr_pool_t *pool)
3875 {
3876     VALUE rb_baton;
3877 
3878     r2c_swig_type2(rb_reporter, "svn_ra_reporter3_t *", (void **)reporter);
3879 
3880     rb_baton = rb_funcall(rb_reporter, id_baton, 0);
3881     r2c_swig_type2(rb_baton, "void *", baton);
3882 }
3883 
3884 static svn_error_t *
svn_swig_rb_ra_reporter_set_path(void * report_baton,const char * path,svn_revnum_t revision,svn_depth_t depth,svn_boolean_t start_empty,const char * lock_token,apr_pool_t * pool)3885 svn_swig_rb_ra_reporter_set_path(void *report_baton, const char *path,
3886                                  svn_revnum_t revision, svn_depth_t depth,
3887                                  svn_boolean_t start_empty,
3888                                  const char *lock_token, apr_pool_t *pool)
3889 {
3890   svn_error_t *err = SVN_NO_ERROR;
3891   VALUE reporter, rb_pool;
3892 
3893   svn_swig_rb_from_baton((VALUE)report_baton, &reporter, &rb_pool);
3894   if (rb_obj_is_kind_of(reporter, rb_svn_ra_reporter3())) {
3895     svn_ra_reporter3_t *svn_reporter;
3896     void *baton;
3897 
3898     c2r_ra_reporter3(reporter, &svn_reporter, &baton, pool);
3899     err = svn_reporter->set_path(baton, path, revision, depth,
3900                                  start_empty, lock_token, pool);
3901   } else if (!NIL_P(reporter)) {
3902     callback_baton_t cbb;
3903 
3904     cbb.receiver = reporter;
3905     cbb.message = id_set_path;
3906     cbb.args = rb_ary_new3(4,
3907                            c2r_string2(path),
3908                            INT2NUM(revision),
3909                            INT2NUM(depth),
3910                            c2r_bool2(start_empty));
3911     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3912   }
3913 
3914   return err;
3915 }
3916 
3917 static svn_error_t *
svn_swig_rb_ra_reporter_delete_path(void * report_baton,const char * path,apr_pool_t * pool)3918 svn_swig_rb_ra_reporter_delete_path(void *report_baton, const char *path,
3919                                     apr_pool_t *pool)
3920 {
3921   svn_error_t *err = SVN_NO_ERROR;
3922   VALUE reporter, rb_pool;
3923 
3924   svn_swig_rb_from_baton((VALUE)report_baton, &reporter, &rb_pool);
3925   if (rb_obj_is_kind_of(reporter, rb_svn_ra_reporter3())) {
3926     svn_ra_reporter3_t *svn_reporter;
3927     void *baton;
3928 
3929     c2r_ra_reporter3(reporter, &svn_reporter, &baton, pool);
3930     err = svn_reporter->delete_path(baton, path, pool);
3931   } else if (!NIL_P(reporter)) {
3932     callback_baton_t cbb;
3933 
3934     cbb.receiver = reporter;
3935     cbb.message = id_delete_path;
3936     cbb.args = rb_ary_new3(1,
3937                            c2r_string2(path));
3938     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3939   }
3940 
3941   return err;
3942 }
3943 
3944 static svn_error_t *
svn_swig_rb_ra_reporter_link_path(void * report_baton,const char * path,const char * url,svn_revnum_t revision,svn_depth_t depth,svn_boolean_t start_empty,const char * lock_token,apr_pool_t * pool)3945 svn_swig_rb_ra_reporter_link_path(void *report_baton, const char *path,
3946                                   const char *url, svn_revnum_t revision,
3947                                   svn_depth_t depth, svn_boolean_t start_empty,
3948                                   const char *lock_token, apr_pool_t *pool)
3949 {
3950   svn_error_t *err = SVN_NO_ERROR;
3951   VALUE reporter, rb_pool;
3952 
3953   svn_swig_rb_from_baton((VALUE)report_baton, &reporter, &rb_pool);
3954   if (rb_obj_is_kind_of(reporter, rb_svn_ra_reporter3())) {
3955     svn_ra_reporter3_t *svn_reporter;
3956     void *baton;
3957 
3958     c2r_ra_reporter3(reporter, &svn_reporter, &baton, pool);
3959     err = svn_reporter->link_path(baton, path, url, revision, depth,
3960                                   start_empty, lock_token, pool);
3961   } else if (!NIL_P(reporter)) {
3962     callback_baton_t cbb;
3963 
3964     cbb.receiver = reporter;
3965     cbb.message = id_link_path;
3966     cbb.args = rb_ary_new3(5,
3967                            c2r_string2(path),
3968                            c2r_string2(url),
3969                            INT2NUM(revision),
3970                            INT2NUM(depth),
3971                            c2r_bool2(start_empty));
3972     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3973   }
3974 
3975   return err;
3976 }
3977 
3978 static svn_error_t *
svn_swig_rb_ra_reporter_finish_report(void * report_baton,apr_pool_t * pool)3979 svn_swig_rb_ra_reporter_finish_report(void *report_baton, apr_pool_t *pool)
3980 {
3981   svn_error_t *err = SVN_NO_ERROR;
3982   VALUE reporter, rb_pool;
3983 
3984   svn_swig_rb_from_baton((VALUE)report_baton, &reporter, &rb_pool);
3985   if (rb_obj_is_kind_of(reporter, rb_svn_ra_reporter3())) {
3986     svn_ra_reporter3_t *svn_reporter;
3987     void *baton;
3988 
3989     c2r_ra_reporter3(reporter, &svn_reporter, &baton, pool);
3990     err = svn_reporter->finish_report(baton, pool);
3991   } else if (!NIL_P(reporter)) {
3992     callback_baton_t cbb;
3993 
3994     cbb.receiver = reporter;
3995     cbb.message = id_finish_report;
3996     cbb.args = rb_ary_new();
3997     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
3998   }
3999 
4000   return err;
4001 }
4002 
4003 static svn_error_t *
svn_swig_rb_ra_reporter_abort_report(void * report_baton,apr_pool_t * pool)4004 svn_swig_rb_ra_reporter_abort_report(void *report_baton, apr_pool_t *pool)
4005 {
4006   svn_error_t *err = SVN_NO_ERROR;
4007   VALUE reporter, rb_pool;
4008 
4009   svn_swig_rb_from_baton((VALUE)report_baton, &reporter, &rb_pool);
4010   if (rb_obj_is_kind_of(reporter, rb_svn_ra_reporter3())) {
4011     svn_ra_reporter3_t *svn_reporter;
4012     void *baton;
4013 
4014     c2r_ra_reporter3(reporter, &svn_reporter, &baton, pool);
4015     err = svn_reporter->abort_report(baton, pool);
4016   } else if (!NIL_P(reporter)) {
4017     callback_baton_t cbb;
4018 
4019     cbb.receiver = reporter;
4020     cbb.message = id_abort_report;
4021     cbb.args = rb_ary_new();
4022     invoke_callback_handle_error((VALUE)(&cbb), rb_pool, &err);
4023   }
4024 
4025   return err;
4026 }
4027 
4028 static svn_ra_reporter3_t rb_ra_reporter3 = {
4029   svn_swig_rb_ra_reporter_set_path,
4030   svn_swig_rb_ra_reporter_delete_path,
4031   svn_swig_rb_ra_reporter_link_path,
4032   svn_swig_rb_ra_reporter_finish_report,
4033   svn_swig_rb_ra_reporter_abort_report
4034 };
4035 
svn_swig_rb_get_ra_reporter3()4036 svn_ra_reporter3_t *svn_swig_rb_get_ra_reporter3()
4037 {
4038   return &rb_ra_reporter3;
4039 }
4040