1/*
2 * debug_reporter.c :  An reporter 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
25/*** ***/
26#include "debug_reporter.h"
27
28struct report_baton
29{
30  const svn_ra_reporter3_t *wrapped_reporter;
31  void *wrapped_report_baton;
32
33  svn_stream_t *out;
34};
35
36#define BOOLEAN_TO_WORD(condition)  ((condition) ? "True" : "False")
37
38
39/*** Wrappers. ***/
40
41static svn_error_t *
42set_path(void *report_baton,
43         const char *path,
44         svn_revnum_t revision,
45         svn_depth_t depth,
46         svn_boolean_t start_empty,
47         const char *lock_token,
48         apr_pool_t *pool)
49{
50  struct report_baton *rb = report_baton;
51  SVN_ERR(svn_stream_printf(rb->out, pool, "set_path(%s, %ld, %s, %s, %s)\n",
52                            path, revision, svn_depth_to_word(depth),
53                            BOOLEAN_TO_WORD(start_empty), lock_token));
54  SVN_ERR(rb->wrapped_reporter->set_path(rb->wrapped_report_baton, path,
55                                         revision, depth,
56                                         start_empty, lock_token, pool));
57  return SVN_NO_ERROR;
58}
59
60static svn_error_t *
61delete_path(void *report_baton,
62            const char *path,
63            apr_pool_t *pool)
64{
65  struct report_baton *rb = report_baton;
66  SVN_ERR(svn_stream_printf(rb->out, pool, "delete_path(%s)\n", path));
67  SVN_ERR(rb->wrapped_reporter->delete_path(rb->wrapped_report_baton,
68                                            path, pool));
69  return SVN_NO_ERROR;
70}
71
72static svn_error_t *
73link_path(void *report_baton,
74          const char *path,
75          const char *url,
76          svn_revnum_t revision,
77          svn_depth_t depth,
78          svn_boolean_t start_empty,
79          const char *lock_token,
80          apr_pool_t *pool)
81{
82  struct report_baton *rb = report_baton;
83  SVN_ERR(svn_stream_printf(rb->out, pool,
84                            "link_path(%s, %s, %ld, %s, %s, %s)\n",
85                            path, url, revision, svn_depth_to_word(depth),
86                            BOOLEAN_TO_WORD(start_empty), lock_token));
87  SVN_ERR(rb->wrapped_reporter->link_path(rb->wrapped_report_baton, path, url,
88                                          revision, depth, start_empty,
89                                          lock_token, pool));
90  return SVN_NO_ERROR;
91}
92
93static svn_error_t *
94finish_report(void *report_baton,
95              apr_pool_t *pool)
96{
97  struct report_baton *rb = report_baton;
98  SVN_ERR(svn_stream_puts(rb->out, "finish_report()\n"));
99  SVN_ERR(rb->wrapped_reporter->finish_report(rb->wrapped_report_baton, pool));
100  return SVN_NO_ERROR;
101}
102
103static svn_error_t *
104abort_report(void *report_baton,
105             apr_pool_t *pool)
106{
107  struct report_baton *rb = report_baton;
108  SVN_ERR(svn_stream_puts(rb->out, "abort_report()\n"));
109  SVN_ERR(rb->wrapped_reporter->abort_report(rb->wrapped_report_baton, pool));
110  return SVN_NO_ERROR;
111}
112
113
114/*** Public interfaces. ***/
115svn_error_t *
116svn_ra__get_debug_reporter(const svn_ra_reporter3_t **reporter,
117                           void **report_baton,
118                           const svn_ra_reporter3_t *wrapped_reporter,
119                           void *wrapped_report_baton,
120                           apr_pool_t *pool)
121{
122  svn_ra_reporter3_t *tree_reporter;
123  struct report_baton *rb;
124  apr_file_t *errfp;
125  svn_stream_t *out;
126
127  apr_status_t apr_err = apr_file_open_stderr(&errfp, pool);
128  if (apr_err)
129    return svn_error_wrap_apr(apr_err, "Problem opening stderr");
130
131  out = svn_stream_from_aprfile2(errfp, TRUE, pool);
132
133  /* ### svn_delta_default_editor() */
134  tree_reporter = apr_palloc(pool, sizeof(*tree_reporter));
135  rb = apr_palloc(pool, sizeof(*rb));
136
137  tree_reporter->set_path = set_path;
138  tree_reporter->delete_path = delete_path;
139  tree_reporter->link_path = link_path;
140  tree_reporter->finish_report = finish_report;
141  tree_reporter->abort_report = abort_report;
142
143  rb->wrapped_reporter = wrapped_reporter;
144  rb->wrapped_report_baton = wrapped_report_baton;
145  rb->out = out;
146
147  *reporter = tree_reporter;
148  *report_baton = rb;
149
150  return SVN_NO_ERROR;
151}
152