]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/subversion/subversion/libsvn_delta/debug_editor.c
Update Subversion and dependencies to 1.14.0 LTS.
[FreeBSD/FreeBSD.git] / contrib / subversion / subversion / libsvn_delta / debug_editor.c
1 /*
2  * debug_editor.c :  An editor that writes the operations it does to stderr.
3  *
4  * ====================================================================
5  *    Licensed to the Apache Software Foundation (ASF) under one
6  *    or more contributor license agreements.  See the NOTICE file
7  *    distributed with this work for additional information
8  *    regarding copyright ownership.  The ASF licenses this file
9  *    to you under the Apache License, Version 2.0 (the
10  *    "License"); you may not use this file except in compliance
11  *    with the License.  You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  *    Unless required by applicable law or agreed to in writing,
16  *    software distributed under the License is distributed on an
17  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18  *    KIND, either express or implied.  See the License for the
19  *    specific language governing permissions and limitations
20  *    under the License.
21  * ====================================================================
22  */
23
24 #include "svn_io.h"
25
26 #include "private/svn_delta_private.h"
27
28 struct edit_baton
29 {
30   const svn_delta_editor_t *wrapped_editor;
31   void *wrapped_edit_baton;
32
33   int indent_level;
34
35   svn_stream_t *out;
36   const char *prefix;
37 };
38
39 struct dir_baton
40 {
41   void *edit_baton;
42   void *wrapped_dir_baton;
43 };
44
45 struct file_baton
46 {
47   void *edit_baton;
48   void *wrapped_file_baton;
49 };
50
51 static svn_error_t *
52 write_indent(struct edit_baton *eb, apr_pool_t *pool)
53 {
54   int i;
55
56   SVN_ERR(svn_stream_puts(eb->out, eb->prefix));
57   for (i = 0; i < eb->indent_level; ++i)
58     SVN_ERR(svn_stream_puts(eb->out, " "));
59
60   return SVN_NO_ERROR;
61 }
62
63 static svn_error_t *
64 set_target_revision(void *edit_baton,
65                     svn_revnum_t target_revision,
66                     apr_pool_t *pool)
67 {
68   struct edit_baton *eb = edit_baton;
69
70   SVN_ERR(write_indent(eb, pool));
71   SVN_ERR(svn_stream_printf(eb->out, pool, "set_target_revision : %ld\n",
72                             target_revision));
73
74   if (eb->wrapped_editor)
75     SVN_ERR(eb->wrapped_editor->set_target_revision(eb->wrapped_edit_baton,
76                                                     target_revision,
77                                                     pool));
78   return SVN_NO_ERROR;
79 }
80
81 static svn_error_t *
82 open_root(void *edit_baton,
83           svn_revnum_t base_revision,
84           apr_pool_t *pool,
85           void **root_baton)
86 {
87   struct edit_baton *eb = edit_baton;
88   struct dir_baton *dir_baton = apr_palloc(pool, sizeof(*dir_baton));
89
90   SVN_ERR(write_indent(eb, pool));
91   SVN_ERR(svn_stream_printf(eb->out, pool, "open_root : %ld\n",
92                             base_revision));
93   eb->indent_level++;
94
95   if (eb->wrapped_editor)
96     SVN_ERR(eb->wrapped_editor->open_root(eb->wrapped_edit_baton,
97                                           base_revision,
98                                           pool,
99                                           &dir_baton->wrapped_dir_baton));
100
101   dir_baton->edit_baton = edit_baton;
102
103   *root_baton = dir_baton;
104
105   return SVN_NO_ERROR;
106 }
107
108 static svn_error_t *
109 delete_entry(const char *path,
110              svn_revnum_t base_revision,
111              void *parent_baton,
112              apr_pool_t *pool)
113 {
114   struct dir_baton *pb = parent_baton;
115   struct edit_baton *eb = pb->edit_baton;
116
117   SVN_ERR(write_indent(eb, pool));
118   SVN_ERR(svn_stream_printf(eb->out, pool, "delete_entry : %s:%ld\n",
119                             path, base_revision));
120
121   if (eb->wrapped_editor)
122     SVN_ERR(eb->wrapped_editor->delete_entry(path,
123                                              base_revision,
124                                              pb->wrapped_dir_baton,
125                                              pool));
126   return SVN_NO_ERROR;
127 }
128
129 static svn_error_t *
130 add_directory(const char *path,
131               void *parent_baton,
132               const char *copyfrom_path,
133               svn_revnum_t copyfrom_revision,
134               apr_pool_t *pool,
135               void **child_baton)
136 {
137   struct dir_baton *pb = parent_baton;
138   struct edit_baton *eb = pb->edit_baton;
139   struct dir_baton *b = apr_palloc(pool, sizeof(*b));
140
141   SVN_ERR(write_indent(eb, pool));
142   SVN_ERR(svn_stream_printf(eb->out, pool,
143                             "add_directory : '%s' [from '%s':%ld]\n",
144                             path, copyfrom_path, copyfrom_revision));
145   eb->indent_level++;
146
147   if (eb->wrapped_editor)
148     SVN_ERR(eb->wrapped_editor->add_directory(path,
149                                               pb->wrapped_dir_baton,
150                                               copyfrom_path,
151                                               copyfrom_revision,
152                                               pool,
153                                               &b->wrapped_dir_baton));
154
155   b->edit_baton = eb;
156   *child_baton = b;
157
158   return SVN_NO_ERROR;
159 }
160
161 static svn_error_t *
162 open_directory(const char *path,
163                void *parent_baton,
164                svn_revnum_t base_revision,
165                apr_pool_t *pool,
166                void **child_baton)
167 {
168   struct dir_baton *pb = parent_baton;
169   struct edit_baton *eb = pb->edit_baton;
170   struct dir_baton *db = apr_palloc(pool, sizeof(*db));
171
172   SVN_ERR(write_indent(eb, pool));
173   SVN_ERR(svn_stream_printf(eb->out, pool, "open_directory : '%s':%ld\n",
174                             path, base_revision));
175   eb->indent_level++;
176
177   if (eb->wrapped_editor)
178     SVN_ERR(eb->wrapped_editor->open_directory(path,
179                                                pb->wrapped_dir_baton,
180                                                base_revision,
181                                                pool,
182                                                &db->wrapped_dir_baton));
183
184   db->edit_baton = eb;
185   *child_baton = db;
186
187   return SVN_NO_ERROR;
188 }
189
190 static svn_error_t *
191 add_file(const char *path,
192          void *parent_baton,
193          const char *copyfrom_path,
194          svn_revnum_t copyfrom_revision,
195          apr_pool_t *pool,
196          void **file_baton)
197 {
198   struct dir_baton *pb = parent_baton;
199   struct edit_baton *eb = pb->edit_baton;
200   struct file_baton *fb = apr_palloc(pool, sizeof(*fb));
201
202   SVN_ERR(write_indent(eb, pool));
203   SVN_ERR(svn_stream_printf(eb->out, pool,
204                             "add_file : '%s' [from '%s':%ld]\n",
205                             path, copyfrom_path, copyfrom_revision));
206
207   eb->indent_level++;
208
209   if (eb->wrapped_editor)
210     SVN_ERR(eb->wrapped_editor->add_file(path,
211                                          pb->wrapped_dir_baton,
212                                          copyfrom_path,
213                                          copyfrom_revision,
214                                          pool,
215                                          &fb->wrapped_file_baton));
216
217   fb->edit_baton = eb;
218   *file_baton = fb;
219
220   return SVN_NO_ERROR;
221 }
222
223 static svn_error_t *
224 open_file(const char *path,
225           void *parent_baton,
226           svn_revnum_t base_revision,
227           apr_pool_t *pool,
228           void **file_baton)
229 {
230   struct dir_baton *pb = parent_baton;
231   struct edit_baton *eb = pb->edit_baton;
232   struct file_baton *fb = apr_palloc(pool, sizeof(*fb));
233
234   SVN_ERR(write_indent(eb, pool));
235   SVN_ERR(svn_stream_printf(eb->out, pool, "open_file : '%s':%ld\n",
236                             path, base_revision));
237
238   eb->indent_level++;
239
240   if (eb->wrapped_editor)
241     SVN_ERR(eb->wrapped_editor->open_file(path,
242                                           pb->wrapped_dir_baton,
243                                           base_revision,
244                                           pool,
245                                           &fb->wrapped_file_baton));
246
247   fb->edit_baton = eb;
248   *file_baton = fb;
249
250   return SVN_NO_ERROR;
251 }
252
253 static svn_error_t *
254 apply_textdelta(void *file_baton,
255                 const char *base_checksum,
256                 apr_pool_t *pool,
257                 svn_txdelta_window_handler_t *handler,
258                 void **handler_baton)
259 {
260   struct file_baton *fb = file_baton;
261   struct edit_baton *eb = fb->edit_baton;
262
263   SVN_ERR(write_indent(eb, pool));
264   SVN_ERR(svn_stream_printf(eb->out, pool, "apply_textdelta : %s\n",
265                             base_checksum));
266
267   if (eb->wrapped_editor)
268     SVN_ERR(eb->wrapped_editor->apply_textdelta(fb->wrapped_file_baton,
269                                                 base_checksum,
270                                                 pool,
271                                                 handler,
272                                                 handler_baton));
273
274   return SVN_NO_ERROR;
275 }
276
277 static svn_error_t *
278 apply_textdelta_stream(const struct svn_delta_editor_t *editor,
279                        void *file_baton,
280                        const char *base_checksum,
281                        svn_txdelta_stream_open_func_t open_func,
282                        void *open_baton,
283                        apr_pool_t *scratch_pool)
284 {
285   struct file_baton *fb = file_baton;
286   struct edit_baton *eb = fb->edit_baton;
287
288   SVN_ERR(write_indent(eb, scratch_pool));
289   SVN_ERR(svn_stream_printf(eb->out, scratch_pool,
290                             "apply_textdelta_stream : %s\n",
291                             base_checksum));
292
293   if (eb->wrapped_editor)
294     SVN_ERR(eb->wrapped_editor->apply_textdelta_stream(eb->wrapped_editor,
295                                                        fb->wrapped_file_baton,
296                                                        base_checksum,
297                                                        open_func, open_baton,
298                                                        scratch_pool));
299
300   return SVN_NO_ERROR;
301 }
302
303 static svn_error_t *
304 close_file(void *file_baton,
305            const char *text_checksum,
306            apr_pool_t *pool)
307 {
308   struct file_baton *fb = file_baton;
309   struct edit_baton *eb = fb->edit_baton;
310
311   eb->indent_level--;
312
313   SVN_ERR(write_indent(eb, pool));
314   SVN_ERR(svn_stream_printf(eb->out, pool, "close_file : %s\n",
315                             text_checksum));
316
317   if (eb->wrapped_editor)
318     SVN_ERR(eb->wrapped_editor->close_file(fb->wrapped_file_baton,
319                                            text_checksum, pool));
320
321   return SVN_NO_ERROR;
322 }
323
324 static svn_error_t *
325 absent_file(const char *path,
326             void *file_baton,
327             apr_pool_t *pool)
328 {
329   struct file_baton *fb = file_baton;
330   struct edit_baton *eb = fb->edit_baton;
331
332   SVN_ERR(write_indent(eb, pool));
333   SVN_ERR(svn_stream_printf(eb->out, pool, "absent_file : %s\n", path));
334
335   if (eb->wrapped_editor)
336     SVN_ERR(eb->wrapped_editor->absent_file(path, fb->wrapped_file_baton,
337                                             pool));
338
339   return SVN_NO_ERROR;
340 }
341
342 static svn_error_t *
343 close_directory(void *dir_baton,
344                 apr_pool_t *pool)
345 {
346   struct dir_baton *db = dir_baton;
347   struct edit_baton *eb = db->edit_baton;
348
349   eb->indent_level--;
350   SVN_ERR(write_indent(eb, pool));
351   SVN_ERR(svn_stream_printf(eb->out, pool, "close_directory\n"));
352
353   if (eb->wrapped_editor)
354     SVN_ERR(eb->wrapped_editor->close_directory(db->wrapped_dir_baton,
355                                                 pool));
356
357   return SVN_NO_ERROR;
358 }
359
360 static svn_error_t *
361 absent_directory(const char *path,
362                  void *dir_baton,
363                  apr_pool_t *pool)
364 {
365   struct dir_baton *db = dir_baton;
366   struct edit_baton *eb = db->edit_baton;
367
368   SVN_ERR(write_indent(eb, pool));
369   SVN_ERR(svn_stream_printf(eb->out, pool, "absent_directory : %s\n",
370                             path));
371
372   if (eb->wrapped_editor)
373     SVN_ERR(eb->wrapped_editor->absent_directory(path, db->wrapped_dir_baton,
374                                                  pool));
375
376   return SVN_NO_ERROR;
377 }
378
379 static svn_error_t *
380 change_file_prop(void *file_baton,
381                  const char *name,
382                  const svn_string_t *value,
383                  apr_pool_t *pool)
384 {
385   struct file_baton *fb = file_baton;
386   struct edit_baton *eb = fb->edit_baton;
387
388   SVN_ERR(write_indent(eb, pool));
389   SVN_ERR(svn_stream_printf(eb->out, pool, "change_file_prop : %s -> %s\n",
390                             name, value ? value->data : "<deleted>"));
391
392   if (eb->wrapped_editor)
393     SVN_ERR(eb->wrapped_editor->change_file_prop(fb->wrapped_file_baton,
394                                                  name,
395                                                  value,
396                                                  pool));
397
398   return SVN_NO_ERROR;
399 }
400
401 static svn_error_t *
402 change_dir_prop(void *dir_baton,
403                 const char *name,
404                 const svn_string_t *value,
405                 apr_pool_t *pool)
406 {
407   struct dir_baton *db = dir_baton;
408   struct edit_baton *eb = db->edit_baton;
409
410   SVN_ERR(write_indent(eb, pool));
411   SVN_ERR(svn_stream_printf(eb->out, pool, "change_dir_prop : %s -> %s\n",
412                             name, value ? value->data : "<deleted>"));
413
414   if (eb->wrapped_editor)
415     SVN_ERR(eb->wrapped_editor->change_dir_prop(db->wrapped_dir_baton,
416                                                 name,
417                                                 value,
418                                                 pool));
419
420   return SVN_NO_ERROR;
421 }
422
423 static svn_error_t *
424 close_edit(void *edit_baton,
425            apr_pool_t *pool)
426 {
427   struct edit_baton *eb = edit_baton;
428
429   SVN_ERR(write_indent(eb, pool));
430   SVN_ERR(svn_stream_printf(eb->out, pool, "close_edit\n"));
431
432   if (eb->wrapped_editor)
433     SVN_ERR(eb->wrapped_editor->close_edit(eb->wrapped_edit_baton, pool));
434
435   return SVN_NO_ERROR;
436 }
437
438 static svn_error_t *
439 abort_edit(void *edit_baton,
440            apr_pool_t *pool)
441 {
442   struct edit_baton *eb = edit_baton;
443
444   SVN_ERR(write_indent(eb, pool));
445   SVN_ERR(svn_stream_printf(eb->out, pool, "abort_edit\n"));
446
447   if (eb->wrapped_editor)
448     SVN_ERR(eb->wrapped_editor->abort_edit(eb->wrapped_edit_baton, pool));
449
450   return SVN_NO_ERROR;
451 }
452
453 svn_error_t *
454 svn_delta__get_debug_editor(const svn_delta_editor_t **editor,
455                             void **edit_baton,
456                             const svn_delta_editor_t *wrapped_editor,
457                             void *wrapped_edit_baton,
458                             const char *prefix,
459                             apr_pool_t *pool)
460 {
461   svn_delta_editor_t *tree_editor = svn_delta_default_editor(pool);
462   struct edit_baton *eb = apr_palloc(pool, sizeof(*eb));
463   apr_file_t *errfp;
464   svn_stream_t *out;
465
466   apr_status_t apr_err = apr_file_open_stdout(&errfp, pool);
467   if (apr_err)
468     return svn_error_wrap_apr(apr_err, "Problem opening stderr");
469
470   out = svn_stream_from_aprfile2(errfp, TRUE, pool);
471
472   tree_editor->set_target_revision = set_target_revision;
473   tree_editor->open_root = open_root;
474   tree_editor->delete_entry = delete_entry;
475   tree_editor->add_directory = add_directory;
476   tree_editor->open_directory = open_directory;
477   tree_editor->change_dir_prop = change_dir_prop;
478   tree_editor->close_directory = close_directory;
479   tree_editor->absent_directory = absent_directory;
480   tree_editor->add_file = add_file;
481   tree_editor->open_file = open_file;
482   tree_editor->apply_textdelta = apply_textdelta;
483   tree_editor->apply_textdelta_stream = apply_textdelta_stream;
484   tree_editor->change_file_prop = change_file_prop;
485   tree_editor->close_file = close_file;
486   tree_editor->absent_file = absent_file;
487   tree_editor->close_edit = close_edit;
488   tree_editor->abort_edit = abort_edit;
489
490   eb->wrapped_editor = wrapped_editor;
491   eb->wrapped_edit_baton = wrapped_edit_baton;
492   eb->out = out;
493   eb->indent_level = 0;
494   /* This is DBG_FLAG from ../libsvn_subr/debug.c */
495   eb->prefix = apr_pstrcat(pool, "DBG: ", prefix, SVN_VA_NULL);
496
497   *editor = tree_editor;
498   *edit_baton = eb;
499
500   return SVN_NO_ERROR;
501 }