1251881Speter/* 2251881Speter * debug_editor.c : An editor that writes the operations it does to stderr. 3251881Speter * 4251881Speter * ==================================================================== 5251881Speter * Licensed to the Apache Software Foundation (ASF) under one 6251881Speter * or more contributor license agreements. See the NOTICE file 7251881Speter * distributed with this work for additional information 8251881Speter * regarding copyright ownership. The ASF licenses this file 9251881Speter * to you under the Apache License, Version 2.0 (the 10251881Speter * "License"); you may not use this file except in compliance 11251881Speter * with the License. You may obtain a copy of the License at 12251881Speter * 13251881Speter * http://www.apache.org/licenses/LICENSE-2.0 14251881Speter * 15251881Speter * Unless required by applicable law or agreed to in writing, 16251881Speter * software distributed under the License is distributed on an 17251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18251881Speter * KIND, either express or implied. See the License for the 19251881Speter * specific language governing permissions and limitations 20251881Speter * under the License. 21251881Speter * ==================================================================== 22251881Speter */ 23251881Speter 24251881Speter#include "svn_io.h" 25251881Speter 26251881Speter#include "debug_editor.h" 27251881Speter 28251881Speterstruct edit_baton 29251881Speter{ 30251881Speter const svn_delta_editor_t *wrapped_editor; 31251881Speter void *wrapped_edit_baton; 32251881Speter 33251881Speter int indent_level; 34251881Speter 35251881Speter svn_stream_t *out; 36251881Speter}; 37251881Speter 38251881Speterstruct dir_baton 39251881Speter{ 40251881Speter void *edit_baton; 41251881Speter void *wrapped_dir_baton; 42251881Speter}; 43251881Speter 44251881Speterstruct file_baton 45251881Speter{ 46251881Speter void *edit_baton; 47251881Speter void *wrapped_file_baton; 48251881Speter}; 49251881Speter 50251881Speterstatic svn_error_t * 51251881Speterwrite_indent(struct edit_baton *eb, apr_pool_t *pool) 52251881Speter{ 53251881Speter int i; 54251881Speter 55251881Speter /* This is DBG_FLAG from ../libsvn_subr/debug.c */ 56251881Speter SVN_ERR(svn_stream_puts(eb->out, "DBG:")); 57251881Speter for (i = 0; i < eb->indent_level; ++i) 58251881Speter SVN_ERR(svn_stream_puts(eb->out, " ")); 59251881Speter 60251881Speter return SVN_NO_ERROR; 61251881Speter} 62251881Speter 63251881Speterstatic svn_error_t * 64251881Speterset_target_revision(void *edit_baton, 65251881Speter svn_revnum_t target_revision, 66251881Speter apr_pool_t *pool) 67251881Speter{ 68251881Speter struct edit_baton *eb = edit_baton; 69251881Speter 70251881Speter SVN_ERR(write_indent(eb, pool)); 71251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, "set_target_revision : %ld\n", 72251881Speter target_revision)); 73251881Speter 74251881Speter return eb->wrapped_editor->set_target_revision(eb->wrapped_edit_baton, 75251881Speter target_revision, 76251881Speter pool); 77251881Speter} 78251881Speter 79251881Speterstatic svn_error_t * 80251881Speteropen_root(void *edit_baton, 81251881Speter svn_revnum_t base_revision, 82251881Speter apr_pool_t *pool, 83251881Speter void **root_baton) 84251881Speter{ 85251881Speter struct edit_baton *eb = edit_baton; 86251881Speter struct dir_baton *dir_baton = apr_palloc(pool, sizeof(*dir_baton)); 87251881Speter 88251881Speter SVN_ERR(write_indent(eb, pool)); 89251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, "open_root : %ld\n", 90251881Speter base_revision)); 91251881Speter eb->indent_level++; 92251881Speter 93251881Speter SVN_ERR(eb->wrapped_editor->open_root(eb->wrapped_edit_baton, 94251881Speter base_revision, 95251881Speter pool, 96251881Speter &dir_baton->wrapped_dir_baton)); 97251881Speter 98251881Speter dir_baton->edit_baton = edit_baton; 99251881Speter 100251881Speter *root_baton = dir_baton; 101251881Speter 102251881Speter return SVN_NO_ERROR; 103251881Speter} 104251881Speter 105251881Speterstatic svn_error_t * 106251881Speterdelete_entry(const char *path, 107251881Speter svn_revnum_t base_revision, 108251881Speter void *parent_baton, 109251881Speter apr_pool_t *pool) 110251881Speter{ 111251881Speter struct dir_baton *pb = parent_baton; 112251881Speter struct edit_baton *eb = pb->edit_baton; 113251881Speter 114251881Speter SVN_ERR(write_indent(eb, pool)); 115251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, "delete_entry : %s:%ld\n", 116251881Speter path, base_revision)); 117251881Speter 118251881Speter return eb->wrapped_editor->delete_entry(path, 119251881Speter base_revision, 120251881Speter pb->wrapped_dir_baton, 121251881Speter pool); 122251881Speter} 123251881Speter 124251881Speterstatic svn_error_t * 125251881Speteradd_directory(const char *path, 126251881Speter void *parent_baton, 127251881Speter const char *copyfrom_path, 128251881Speter svn_revnum_t copyfrom_revision, 129251881Speter apr_pool_t *pool, 130251881Speter void **child_baton) 131251881Speter{ 132251881Speter struct dir_baton *pb = parent_baton; 133251881Speter struct edit_baton *eb = pb->edit_baton; 134251881Speter struct dir_baton *b = apr_palloc(pool, sizeof(*b)); 135251881Speter 136251881Speter SVN_ERR(write_indent(eb, pool)); 137251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, 138251881Speter "add_directory : '%s' [from '%s':%ld]\n", 139251881Speter path, copyfrom_path, copyfrom_revision)); 140251881Speter eb->indent_level++; 141251881Speter 142251881Speter SVN_ERR(eb->wrapped_editor->add_directory(path, 143251881Speter pb->wrapped_dir_baton, 144251881Speter copyfrom_path, 145251881Speter copyfrom_revision, 146251881Speter pool, 147251881Speter &b->wrapped_dir_baton)); 148251881Speter 149251881Speter b->edit_baton = eb; 150251881Speter *child_baton = b; 151251881Speter 152251881Speter return SVN_NO_ERROR; 153251881Speter} 154251881Speter 155251881Speterstatic svn_error_t * 156251881Speteropen_directory(const char *path, 157251881Speter void *parent_baton, 158251881Speter svn_revnum_t base_revision, 159251881Speter apr_pool_t *pool, 160251881Speter void **child_baton) 161251881Speter{ 162251881Speter struct dir_baton *pb = parent_baton; 163251881Speter struct edit_baton *eb = pb->edit_baton; 164251881Speter struct dir_baton *db = apr_palloc(pool, sizeof(*db)); 165251881Speter 166251881Speter SVN_ERR(write_indent(eb, pool)); 167251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, "open_directory : '%s':%ld\n", 168251881Speter path, base_revision)); 169251881Speter eb->indent_level++; 170251881Speter 171251881Speter SVN_ERR(eb->wrapped_editor->open_directory(path, 172251881Speter pb->wrapped_dir_baton, 173251881Speter base_revision, 174251881Speter pool, 175251881Speter &db->wrapped_dir_baton)); 176251881Speter 177251881Speter db->edit_baton = eb; 178251881Speter *child_baton = db; 179251881Speter 180251881Speter return SVN_NO_ERROR; 181251881Speter} 182251881Speter 183251881Speterstatic svn_error_t * 184251881Speteradd_file(const char *path, 185251881Speter void *parent_baton, 186251881Speter const char *copyfrom_path, 187251881Speter svn_revnum_t copyfrom_revision, 188251881Speter apr_pool_t *pool, 189251881Speter void **file_baton) 190251881Speter{ 191251881Speter struct dir_baton *pb = parent_baton; 192251881Speter struct edit_baton *eb = pb->edit_baton; 193251881Speter struct file_baton *fb = apr_palloc(pool, sizeof(*fb)); 194251881Speter 195251881Speter SVN_ERR(write_indent(eb, pool)); 196251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, 197251881Speter "add_file : '%s' [from '%s':%ld]\n", 198251881Speter path, copyfrom_path, copyfrom_revision)); 199251881Speter 200251881Speter eb->indent_level++; 201251881Speter 202251881Speter SVN_ERR(eb->wrapped_editor->add_file(path, 203251881Speter pb->wrapped_dir_baton, 204251881Speter copyfrom_path, 205251881Speter copyfrom_revision, 206251881Speter pool, 207251881Speter &fb->wrapped_file_baton)); 208251881Speter 209251881Speter fb->edit_baton = eb; 210251881Speter *file_baton = fb; 211251881Speter 212251881Speter return SVN_NO_ERROR; 213251881Speter} 214251881Speter 215251881Speterstatic svn_error_t * 216251881Speteropen_file(const char *path, 217251881Speter void *parent_baton, 218251881Speter svn_revnum_t base_revision, 219251881Speter apr_pool_t *pool, 220251881Speter void **file_baton) 221251881Speter{ 222251881Speter struct dir_baton *pb = parent_baton; 223251881Speter struct edit_baton *eb = pb->edit_baton; 224251881Speter struct file_baton *fb = apr_palloc(pool, sizeof(*fb)); 225251881Speter 226251881Speter SVN_ERR(write_indent(eb, pool)); 227251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, "open_file : '%s':%ld\n", 228251881Speter path, base_revision)); 229251881Speter 230251881Speter eb->indent_level++; 231251881Speter 232251881Speter SVN_ERR(eb->wrapped_editor->open_file(path, 233251881Speter pb->wrapped_dir_baton, 234251881Speter base_revision, 235251881Speter pool, 236251881Speter &fb->wrapped_file_baton)); 237251881Speter 238251881Speter fb->edit_baton = eb; 239251881Speter *file_baton = fb; 240251881Speter 241251881Speter return SVN_NO_ERROR; 242251881Speter} 243251881Speter 244251881Speterstatic svn_error_t * 245251881Speterapply_textdelta(void *file_baton, 246251881Speter const char *base_checksum, 247251881Speter apr_pool_t *pool, 248251881Speter svn_txdelta_window_handler_t *handler, 249251881Speter void **handler_baton) 250251881Speter{ 251251881Speter struct file_baton *fb = file_baton; 252251881Speter struct edit_baton *eb = fb->edit_baton; 253251881Speter 254251881Speter SVN_ERR(write_indent(eb, pool)); 255251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, "apply_textdelta : %s\n", 256251881Speter base_checksum)); 257251881Speter 258251881Speter SVN_ERR(eb->wrapped_editor->apply_textdelta(fb->wrapped_file_baton, 259251881Speter base_checksum, 260251881Speter pool, 261251881Speter handler, 262251881Speter handler_baton)); 263251881Speter 264251881Speter return SVN_NO_ERROR; 265251881Speter} 266251881Speter 267251881Speterstatic svn_error_t * 268251881Speterclose_file(void *file_baton, 269251881Speter const char *text_checksum, 270251881Speter apr_pool_t *pool) 271251881Speter{ 272251881Speter struct file_baton *fb = file_baton; 273251881Speter struct edit_baton *eb = fb->edit_baton; 274251881Speter 275251881Speter eb->indent_level--; 276251881Speter 277251881Speter SVN_ERR(write_indent(eb, pool)); 278251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, "close_file : %s\n", 279251881Speter text_checksum)); 280251881Speter 281251881Speter SVN_ERR(eb->wrapped_editor->close_file(fb->wrapped_file_baton, 282251881Speter text_checksum, pool)); 283251881Speter 284251881Speter return SVN_NO_ERROR; 285251881Speter} 286251881Speter 287251881Speterstatic svn_error_t * 288251881Speterabsent_file(const char *path, 289251881Speter void *file_baton, 290251881Speter apr_pool_t *pool) 291251881Speter{ 292251881Speter struct file_baton *fb = file_baton; 293251881Speter struct edit_baton *eb = fb->edit_baton; 294251881Speter 295251881Speter SVN_ERR(write_indent(eb, pool)); 296251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, "absent_file : %s\n", path)); 297251881Speter 298251881Speter SVN_ERR(eb->wrapped_editor->absent_file(path, fb->wrapped_file_baton, 299251881Speter pool)); 300251881Speter 301251881Speter return SVN_NO_ERROR; 302251881Speter} 303251881Speter 304251881Speterstatic svn_error_t * 305251881Speterclose_directory(void *dir_baton, 306251881Speter apr_pool_t *pool) 307251881Speter{ 308251881Speter struct dir_baton *db = dir_baton; 309251881Speter struct edit_baton *eb = db->edit_baton; 310251881Speter 311251881Speter eb->indent_level--; 312251881Speter SVN_ERR(write_indent(eb, pool)); 313251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, "close_directory\n")); 314251881Speter 315251881Speter SVN_ERR(eb->wrapped_editor->close_directory(db->wrapped_dir_baton, 316251881Speter pool)); 317251881Speter 318251881Speter return SVN_NO_ERROR; 319251881Speter} 320251881Speter 321251881Speterstatic svn_error_t * 322251881Speterabsent_directory(const char *path, 323251881Speter void *dir_baton, 324251881Speter apr_pool_t *pool) 325251881Speter{ 326251881Speter struct dir_baton *db = dir_baton; 327251881Speter struct edit_baton *eb = db->edit_baton; 328251881Speter 329251881Speter SVN_ERR(write_indent(eb, pool)); 330251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, "absent_directory : %s\n", 331251881Speter path)); 332251881Speter 333251881Speter SVN_ERR(eb->wrapped_editor->absent_directory(path, db->wrapped_dir_baton, 334251881Speter pool)); 335251881Speter 336251881Speter return SVN_NO_ERROR; 337251881Speter} 338251881Speter 339251881Speterstatic svn_error_t * 340251881Speterchange_file_prop(void *file_baton, 341251881Speter const char *name, 342251881Speter const svn_string_t *value, 343251881Speter apr_pool_t *pool) 344251881Speter{ 345251881Speter struct file_baton *fb = file_baton; 346251881Speter struct edit_baton *eb = fb->edit_baton; 347251881Speter 348251881Speter SVN_ERR(write_indent(eb, pool)); 349251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, "change_file_prop : %s\n", 350251881Speter name)); 351251881Speter 352251881Speter SVN_ERR(eb->wrapped_editor->change_file_prop(fb->wrapped_file_baton, 353251881Speter name, 354251881Speter value, 355251881Speter pool)); 356251881Speter 357251881Speter return SVN_NO_ERROR; 358251881Speter} 359251881Speter 360251881Speterstatic svn_error_t * 361251881Speterchange_dir_prop(void *dir_baton, 362251881Speter const char *name, 363251881Speter const svn_string_t *value, 364251881Speter apr_pool_t *pool) 365251881Speter{ 366251881Speter struct dir_baton *db = dir_baton; 367251881Speter struct edit_baton *eb = db->edit_baton; 368251881Speter 369251881Speter SVN_ERR(write_indent(eb, pool)); 370251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, "change_dir_prop : %s\n", name)); 371251881Speter 372251881Speter SVN_ERR(eb->wrapped_editor->change_dir_prop(db->wrapped_dir_baton, 373251881Speter name, 374251881Speter value, 375251881Speter pool)); 376251881Speter 377251881Speter return SVN_NO_ERROR; 378251881Speter} 379251881Speter 380251881Speterstatic svn_error_t * 381251881Speterclose_edit(void *edit_baton, 382251881Speter apr_pool_t *pool) 383251881Speter{ 384251881Speter struct edit_baton *eb = edit_baton; 385251881Speter 386251881Speter SVN_ERR(write_indent(eb, pool)); 387251881Speter SVN_ERR(svn_stream_printf(eb->out, pool, "close_edit\n")); 388251881Speter 389251881Speter SVN_ERR(eb->wrapped_editor->close_edit(eb->wrapped_edit_baton, pool)); 390251881Speter 391251881Speter return SVN_NO_ERROR; 392251881Speter} 393251881Speter 394251881Spetersvn_error_t * 395251881Spetersvn_delta__get_debug_editor(const svn_delta_editor_t **editor, 396251881Speter void **edit_baton, 397251881Speter const svn_delta_editor_t *wrapped_editor, 398251881Speter void *wrapped_edit_baton, 399251881Speter apr_pool_t *pool) 400251881Speter{ 401251881Speter svn_delta_editor_t *tree_editor = svn_delta_default_editor(pool); 402251881Speter struct edit_baton *eb = apr_palloc(pool, sizeof(*eb)); 403251881Speter apr_file_t *errfp; 404251881Speter svn_stream_t *out; 405251881Speter 406251881Speter apr_status_t apr_err = apr_file_open_stderr(&errfp, pool); 407251881Speter if (apr_err) 408251881Speter return svn_error_wrap_apr(apr_err, "Problem opening stderr"); 409251881Speter 410251881Speter out = svn_stream_from_aprfile2(errfp, TRUE, pool); 411251881Speter 412251881Speter tree_editor->set_target_revision = set_target_revision; 413251881Speter tree_editor->open_root = open_root; 414251881Speter tree_editor->delete_entry = delete_entry; 415251881Speter tree_editor->add_directory = add_directory; 416251881Speter tree_editor->open_directory = open_directory; 417251881Speter tree_editor->change_dir_prop = change_dir_prop; 418251881Speter tree_editor->close_directory = close_directory; 419251881Speter tree_editor->absent_directory = absent_directory; 420251881Speter tree_editor->add_file = add_file; 421251881Speter tree_editor->open_file = open_file; 422251881Speter tree_editor->apply_textdelta = apply_textdelta; 423251881Speter tree_editor->change_file_prop = change_file_prop; 424251881Speter tree_editor->close_file = close_file; 425251881Speter tree_editor->absent_file = absent_file; 426251881Speter tree_editor->close_edit = close_edit; 427251881Speter 428251881Speter eb->wrapped_editor = wrapped_editor; 429251881Speter eb->wrapped_edit_baton = wrapped_edit_baton; 430251881Speter eb->out = out; 431251881Speter eb->indent_level = 0; 432251881Speter 433251881Speter *editor = tree_editor; 434251881Speter *edit_baton = eb; 435251881Speter 436251881Speter return SVN_NO_ERROR; 437251881Speter} 438