2 * svn_tests_editor.c: a `dummy' editor implementation for testing
4 * ====================================================================
5 * Copyright (c) 2000-2004 CollabNet. All rights reserved.
7 * This software is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at http://subversion.tigris.org/license-1.html.
10 * If newer versions of this license are posted there, you may use a
11 * newer version instead, at your option.
13 * This software consists of voluntary contributions made by many
14 * individuals. For exact contribution history, see the revision
15 * history and logs, available at http://subversion.tigris.org/.
16 * ====================================================================
19 /* ==================================================================== */
26 #include <apr_pools.h>
27 #include <apr_file_io.h>
29 #include "svn_types.h"
31 #include "svn_error.h"
33 #include "svn_delta.h"
38 const char *root_path
;
39 const char *editor_name
;
40 svn_stream_t
*out_stream
;
43 svn_boolean_t verbose
;
49 struct edit_baton
*edit_baton
;
50 struct node_baton
*parent_baton
;
56 /* Print newline character to EB->outstream. */
58 newline(struct edit_baton
*eb
)
61 return svn_stream_write(eb
->out_stream
, "\n", &len
);
65 /* Print EB->indentation * LEVEL spaces, followed by STR,
68 print(struct edit_baton
*eb
, int level
, svn_stringbuf_t
*str
)
74 for (i
= 0; i
< (eb
->indentation
* level
); i
++)
75 SVN_ERR(svn_stream_write(eb
->out_stream
, " ", &len
));
78 SVN_ERR(svn_stream_write(eb
->out_stream
, str
->data
, &len
));
84 /* A dummy routine designed to consume windows of vcdiff data, (of
85 type svn_text_delta_window_handler_t). This will be called by the
86 vcdiff parser everytime it has a window ready to go. */
88 my_vcdiff_windoweater(svn_txdelta_window_t
*window
, void *baton
)
91 struct node_baton
*nb
= baton
;
92 struct edit_baton
*eb
= nb
->edit_baton
;
93 apr_pool_t
*pool
= eb
->pool
;
96 /* We're done if non-verbose */
101 str
= svn_stringbuf_createf(pool
,
102 "[%s] window_handler (%d ops)\n",
106 str
= svn_stringbuf_createf(pool
,
107 "[%s] window_handler (EOT)\n",
110 SVN_ERR(print(eb
, nb
->indent_level
+ 2, str
));
114 /* Delve into the vcdiff window and print the data. */
115 for (i
= 1; i
<= window
->num_ops
; i
++)
117 switch (window
->ops
[i
].action_code
)
119 case svn_txdelta_new
:
120 str
= svn_stringbuf_createf
122 "(%d) new text: length %" APR_SIZE_T_FMT
"\n",
123 i
, (window
->ops
[i
].length
));
126 case svn_txdelta_source
:
127 str
= svn_stringbuf_createf
129 "(%d) source text: offset %" APR_SIZE_T_FMT
130 ", length %" APR_SIZE_T_FMT
"\n",
131 i
, window
->ops
[i
].offset
, window
->ops
[i
].length
);
134 case svn_txdelta_target
:
135 str
= svn_stringbuf_createf
137 "(%d) target text: offset %" APR_SIZE_T_FMT
138 ", length %" APR_SIZE_T_FMT
"\n",
139 i
, window
->ops
[i
].offset
, window
->ops
[i
].length
);
143 str
= svn_stringbuf_createf(pool
,
144 "(%d) unknown window type\n", i
);
147 SVN_ERR(print(eb
, nb
->indent_level
+ 2, str
));
151 SVN_ERR(newline(eb
));
159 test_delete_entry(const char *path
,
160 svn_revnum_t revision
,
164 struct node_baton
*nb
= parent_baton
;
165 struct edit_baton
*eb
= nb
->edit_baton
;
166 const char *full_path
;
167 svn_stringbuf_t
*str
;
169 full_path
= svn_path_join(eb
->root_path
, path
, pool
);
170 str
= svn_stringbuf_createf(pool
,
171 "[%s] delete_entry (%s)\n",
172 eb
->editor_name
, full_path
);
173 SVN_ERR(print(eb
, nb
->indent_level
+ 1, str
));
176 SVN_ERR(newline(eb
));
183 test_set_target_revision(void *edit_baton
,
184 svn_revnum_t target_revision
,
187 struct edit_baton
*eb
= edit_baton
;
188 svn_stringbuf_t
*str
;
190 str
= svn_stringbuf_createf(pool
,
191 "[%s] set_target_revision (%ld)\n",
194 SVN_ERR(print(eb
, 0, str
));
197 SVN_ERR(newline(eb
));
204 test_open_root(void *edit_baton
,
205 svn_revnum_t base_revision
,
209 struct edit_baton
*eb
= edit_baton
;
210 struct node_baton
*nb
= apr_pcalloc(pool
, sizeof(*nb
));
211 svn_stringbuf_t
*str
;
213 nb
->path
= apr_pstrdup(pool
, eb
->root_path
);
215 nb
->indent_level
= 0;
218 str
= svn_stringbuf_createf(pool
,
219 "[%s] open_root (%s)\n",
222 SVN_ERR(print(eb
, nb
->indent_level
, str
));
224 /* We're done if non-verbose */
228 str
= svn_stringbuf_createf(pool
,
229 "base_revision: %ld\n",
231 SVN_ERR(print(eb
, nb
->indent_level
, str
));
232 SVN_ERR(newline(eb
));
239 add_or_open(const char *path
,
241 const char *base_path
,
242 svn_revnum_t base_revision
,
245 svn_boolean_t is_dir
,
246 const char *pivot_string
)
248 struct node_baton
*pb
= parent_baton
;
249 struct edit_baton
*eb
= pb
->edit_baton
;
250 struct node_baton
*nb
= apr_pcalloc(pool
, sizeof(*nb
));
251 svn_stringbuf_t
*str
;
253 /* Set child_baton to a new dir baton. */
254 nb
->path
= svn_path_join(eb
->root_path
, path
, pool
);
255 nb
->edit_baton
= pb
->edit_baton
;
256 nb
->parent_baton
= pb
;
257 nb
->indent_level
= (pb
->indent_level
+ 1);
260 str
= svn_stringbuf_createf(pool
, "[%s] %s_%s (%s)\n",
261 eb
->editor_name
, pivot_string
,
262 is_dir
? "directory" : "file", nb
->path
);
263 SVN_ERR(print(eb
, nb
->indent_level
, str
));
265 /* We're done if non-verbose */
269 str
= svn_stringbuf_createf(pool
, "parent: %s\n", pb
->path
);
270 SVN_ERR(print(eb
, nb
->indent_level
, str
));
272 if (strcmp(pivot_string
, "add") == 0)
274 str
= svn_stringbuf_createf(pool
, "copyfrom_path: %s\n",
275 base_path
? base_path
: "");
276 SVN_ERR(print(eb
, nb
->indent_level
, str
));
278 str
= svn_stringbuf_createf(pool
, "copyfrom_revision: %ld\n",
280 SVN_ERR(print(eb
, nb
->indent_level
, str
));
284 str
= svn_stringbuf_createf(pool
, "base_revision: %ld\n",
286 SVN_ERR(print(eb
, nb
->indent_level
, str
));
289 SVN_ERR(newline(eb
));
296 close_file_or_dir(void *baton
,
297 svn_boolean_t is_dir
,
300 struct node_baton
*nb
= baton
;
301 struct edit_baton
*eb
= nb
->edit_baton
;
302 svn_stringbuf_t
*str
;
304 str
= svn_stringbuf_createf(pool
,
305 "[%s] close_%s (%s)\n",
307 is_dir
? "directory" : "file",
309 SVN_ERR(print(eb
, nb
->indent_level
, str
));
311 SVN_ERR(newline(eb
));
318 test_add_directory(const char *path
,
320 const char *copyfrom_path
,
321 svn_revnum_t copyfrom_revision
,
325 return add_or_open(path
, parent_baton
, copyfrom_path
, copyfrom_revision
,
326 pool
, child_baton
, TRUE
, "add");
331 test_open_directory(const char *path
,
333 svn_revnum_t base_revision
,
337 return add_or_open(path
, parent_baton
, NULL
, base_revision
,
338 pool
, child_baton
, TRUE
, "open");
343 test_add_file(const char *path
,
345 const char *copyfrom_path
,
346 svn_revnum_t copyfrom_revision
,
350 return add_or_open(path
, parent_baton
, copyfrom_path
, copyfrom_revision
,
351 pool
, file_baton
, FALSE
, "add");
356 test_open_file(const char *path
,
358 svn_revnum_t base_revision
,
362 return add_or_open(path
, parent_baton
, NULL
, base_revision
,
363 pool
, file_baton
, FALSE
, "open");
368 test_close_directory(void *dir_baton
,
371 return close_file_or_dir(dir_baton
, TRUE
, pool
);
376 absent_file_or_dir(const char *path
,
378 svn_boolean_t is_dir
,
381 struct node_baton
*nb
= baton
;
382 struct edit_baton
*eb
= nb
->edit_baton
;
383 svn_stringbuf_t
*str
;
385 str
= svn_stringbuf_createf(pool
,
386 "[%s] absent_%s (%s)\n",
388 is_dir
? "directory" : "file",
390 SVN_ERR(print(eb
, nb
->indent_level
, str
));
392 SVN_ERR(newline(eb
));
399 test_absent_directory(const char *path
,
403 return absent_file_or_dir(path
, baton
, TRUE
, pool
);
408 test_close_file(void *file_baton
,
409 const char *text_checksum
,
412 return close_file_or_dir(file_baton
, FALSE
, pool
);
417 test_absent_file(const char *path
,
421 return absent_file_or_dir(path
, baton
, FALSE
, pool
);
426 test_close_edit(void *edit_baton
,
429 struct edit_baton
*eb
= edit_baton
;
430 svn_stringbuf_t
*str
;
432 str
= svn_stringbuf_createf(pool
, "[%s] close_edit\n", eb
->editor_name
);
433 SVN_ERR(print(eb
, 0, str
));
436 SVN_ERR(newline(eb
));
442 test_abort_edit(void *edit_baton
,
445 struct edit_baton
*eb
= edit_baton
;
446 svn_stringbuf_t
*str
;
448 str
= svn_stringbuf_createf(pool
, "[%s] ***ABORT_EDIT***\n",
450 SVN_ERR(print(eb
, 0, str
));
453 SVN_ERR(newline(eb
));
459 test_apply_textdelta(void *file_baton
,
460 const char *base_checksum
,
462 svn_txdelta_window_handler_t
*handler
,
463 void **handler_baton
)
465 struct node_baton
*nb
= file_baton
;
466 struct edit_baton
*eb
= nb
->edit_baton
;
467 svn_stringbuf_t
*str
;
469 /* Set the value of HANDLER and HANDLER_BATON here */
470 *handler
= my_vcdiff_windoweater
;
473 str
= svn_stringbuf_createf(pool
, "[%s] apply_textdelta (%s)\n",
474 eb
->editor_name
, nb
->path
);
475 SVN_ERR(print(eb
, nb
->indent_level
+ 1, str
));
478 SVN_ERR(newline(eb
));
485 change_prop(void *baton
,
487 const svn_string_t
*value
,
489 svn_boolean_t is_dir
)
491 struct node_baton
*nb
= baton
;
492 struct edit_baton
*eb
= nb
->edit_baton
;
493 svn_stringbuf_t
*str
;
495 str
= svn_stringbuf_createf(pool
, "[%s] change_%s_prop (%s)\n",
497 is_dir
? "directory" : "file", nb
->path
);
498 SVN_ERR(print(eb
, nb
->indent_level
+ 1, str
));
500 /* We're done if non-verbose */
504 str
= svn_stringbuf_createf(pool
, "name: %s\n", name
);
505 SVN_ERR(print(eb
, nb
->indent_level
+ 1, str
));
507 str
= svn_stringbuf_createf(pool
, "value: %s\n",
508 value
? value
->data
: "(null)");
509 SVN_ERR(print(eb
, nb
->indent_level
+ 1, str
));
511 SVN_ERR(newline(eb
));
518 test_change_file_prop(void *file_baton
,
520 const svn_string_t
*value
,
523 return change_prop(file_baton
, name
, value
, pool
, FALSE
);
528 test_change_dir_prop(void *parent_baton
,
530 const svn_string_t
*value
,
533 return change_prop(parent_baton
, name
, value
, pool
, TRUE
);
537 /*---------------------------------------------------------------*/
539 /** Public interface: svn_test_get_editor() **/
543 svn_test_get_editor(const svn_delta_editor_t
**editor
,
545 const char *editor_name
,
546 svn_stream_t
*out_stream
,
548 svn_boolean_t verbose
,
552 svn_delta_editor_t
*my_editor
;
553 struct edit_baton
*my_edit_baton
;
555 /* Set up the editor. */
556 my_editor
= svn_delta_default_editor(pool
);
557 my_editor
->set_target_revision
= test_set_target_revision
;
558 my_editor
->open_root
= test_open_root
;
559 my_editor
->delete_entry
= test_delete_entry
;
560 my_editor
->add_directory
= test_add_directory
;
561 my_editor
->open_directory
= test_open_directory
;
562 my_editor
->close_directory
= test_close_directory
;
563 my_editor
->absent_directory
= test_absent_directory
;
564 my_editor
->add_file
= test_add_file
;
565 my_editor
->open_file
= test_open_file
;
566 my_editor
->close_file
= test_close_file
;
567 my_editor
->absent_file
= test_absent_file
;
568 my_editor
->apply_textdelta
= test_apply_textdelta
;
569 my_editor
->change_file_prop
= test_change_file_prop
;
570 my_editor
->change_dir_prop
= test_change_dir_prop
;
571 my_editor
->close_edit
= test_close_edit
;
572 my_editor
->abort_edit
= test_abort_edit
;
574 /* Set up the edit baton. */
575 my_edit_baton
= apr_pcalloc(pool
, sizeof(*my_edit_baton
));
576 my_edit_baton
->root_path
= apr_pstrdup(pool
, path
);
577 my_edit_baton
->editor_name
= apr_pstrdup(pool
, editor_name
);
578 my_edit_baton
->pool
= pool
;
579 my_edit_baton
->indentation
= indentation
;
580 my_edit_baton
->verbose
= verbose
;
581 my_edit_baton
->out_stream
= out_stream
;
584 *edit_baton
= my_edit_baton
;