1/*
2 * deprecated.c:  holding file for all deprecated APIs.
3 *                "we can't lose 'em, but we can shun 'em!"
4 *
5 * ====================================================================
6 *    Licensed to the Apache Software Foundation (ASF) under one
7 *    or more contributor license agreements.  See the NOTICE file
8 *    distributed with this work for additional information
9 *    regarding copyright ownership.  The ASF licenses this file
10 *    to you under the Apache License, Version 2.0 (the
11 *    "License"); you may not use this file except in compliance
12 *    with the License.  You may obtain a copy of the License at
13 *
14 *      http://www.apache.org/licenses/LICENSE-2.0
15 *
16 *    Unless required by applicable law or agreed to in writing,
17 *    software distributed under the License is distributed on an
18 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19 *    KIND, either express or implied.  See the License for the
20 *    specific language governing permissions and limitations
21 *    under the License.
22 * ====================================================================
23 */
24
25/* ==================================================================== */
26
27
28
29#include <assert.h>
30
31/* We define this here to remove any further warnings about the usage of
32   deprecated functions in this file. */
33#define SVN_DEPRECATED
34
35#include "svn_hash.h"
36#include "svn_subst.h"
37#include "svn_path.h"
38#include "svn_opt.h"
39#include "svn_cmdline.h"
40#include "svn_version.h"
41#include "svn_pools.h"
42#include "svn_dso.h"
43#include "svn_mergeinfo.h"
44#include "svn_utf.h"
45#include "svn_xml.h"
46
47#include "opt.h"
48#include "private/svn_opt_private.h"
49#include "private/svn_mergeinfo_private.h"
50#include "private/svn_subr_private.h"
51
52#include "svn_private_config.h"
53
54
55
56
57/*** Code. ***/
58
59/*** From subst.c ***/
60/* Convert an old-style svn_subst_keywords_t struct * into a new-style
61 * keywords hash.  Keyword values are shallow copies, so the produced
62 * hash must not be assumed to have lifetime longer than the struct it
63 * is based on.  A NULL input causes a NULL output. */
64static apr_hash_t *
65kwstruct_to_kwhash(const svn_subst_keywords_t *kwstruct,
66                   apr_pool_t *pool)
67{
68  apr_hash_t *kwhash;
69
70  if (kwstruct == NULL)
71    return NULL;
72
73  kwhash = apr_hash_make(pool);
74
75  if (kwstruct->revision)
76    {
77      svn_hash_sets(kwhash, SVN_KEYWORD_REVISION_LONG, kwstruct->revision);
78      svn_hash_sets(kwhash, SVN_KEYWORD_REVISION_MEDIUM, kwstruct->revision);
79      svn_hash_sets(kwhash, SVN_KEYWORD_REVISION_SHORT, kwstruct->revision);
80    }
81  if (kwstruct->date)
82    {
83      svn_hash_sets(kwhash, SVN_KEYWORD_DATE_LONG, kwstruct->date);
84      svn_hash_sets(kwhash, SVN_KEYWORD_DATE_SHORT, kwstruct->date);
85    }
86  if (kwstruct->author)
87    {
88      svn_hash_sets(kwhash, SVN_KEYWORD_AUTHOR_LONG, kwstruct->author);
89      svn_hash_sets(kwhash, SVN_KEYWORD_AUTHOR_SHORT, kwstruct->author);
90    }
91  if (kwstruct->url)
92    {
93      svn_hash_sets(kwhash, SVN_KEYWORD_URL_LONG, kwstruct->url);
94      svn_hash_sets(kwhash, SVN_KEYWORD_URL_SHORT, kwstruct->url);
95    }
96  if (kwstruct->id)
97    {
98      svn_hash_sets(kwhash, SVN_KEYWORD_ID, kwstruct->id);
99    }
100
101  return kwhash;
102}
103
104
105svn_error_t *
106svn_subst_translate_stream3(svn_stream_t *src_stream,
107                            svn_stream_t *dst_stream,
108                            const char *eol_str,
109                            svn_boolean_t repair,
110                            apr_hash_t *keywords,
111                            svn_boolean_t expand,
112                            apr_pool_t *pool)
113{
114  /* The docstring requires that *some* translation be requested. */
115  SVN_ERR_ASSERT(eol_str || keywords);
116
117  /* We don't want the copy3 to close the provided streams. */
118  src_stream = svn_stream_disown(src_stream, pool);
119  dst_stream = svn_stream_disown(dst_stream, pool);
120
121  /* Wrap the destination stream with our translation stream. It is more
122     efficient than wrapping the source stream. */
123  dst_stream = svn_subst_stream_translated(dst_stream, eol_str, repair,
124                                           keywords, expand, pool);
125
126  return svn_error_trace(svn_stream_copy3(src_stream, dst_stream,
127                                          NULL, NULL, pool));
128}
129
130svn_error_t *
131svn_subst_translate_stream2(svn_stream_t *s, /* src stream */
132                            svn_stream_t *d, /* dst stream */
133                            const char *eol_str,
134                            svn_boolean_t repair,
135                            const svn_subst_keywords_t *keywords,
136                            svn_boolean_t expand,
137                            apr_pool_t *pool)
138{
139  apr_hash_t *kh = kwstruct_to_kwhash(keywords, pool);
140
141  return svn_error_trace(svn_subst_translate_stream3(s, d, eol_str, repair,
142                                                     kh, expand, pool));
143}
144
145svn_error_t *
146svn_subst_translate_stream(svn_stream_t *s, /* src stream */
147                           svn_stream_t *d, /* dst stream */
148                           const char *eol_str,
149                           svn_boolean_t repair,
150                           const svn_subst_keywords_t *keywords,
151                           svn_boolean_t expand)
152{
153  apr_pool_t *pool = svn_pool_create(NULL);
154  svn_error_t *err = svn_subst_translate_stream2(s, d, eol_str, repair,
155                                                 keywords, expand, pool);
156  svn_pool_destroy(pool);
157  return svn_error_trace(err);
158}
159
160svn_error_t *
161svn_subst_translate_cstring(const char *src,
162                            const char **dst,
163                            const char *eol_str,
164                            svn_boolean_t repair,
165                            const svn_subst_keywords_t *keywords,
166                            svn_boolean_t expand,
167                            apr_pool_t *pool)
168{
169  apr_hash_t *kh = kwstruct_to_kwhash(keywords, pool);
170
171  return svn_error_trace(svn_subst_translate_cstring2(src, dst, eol_str,
172                                                      repair, kh, expand,
173                                                      pool));
174}
175
176svn_error_t *
177svn_subst_copy_and_translate(const char *src,
178                             const char *dst,
179                             const char *eol_str,
180                             svn_boolean_t repair,
181                             const svn_subst_keywords_t *keywords,
182                             svn_boolean_t expand,
183                             apr_pool_t *pool)
184{
185  return svn_error_trace(svn_subst_copy_and_translate2(src, dst, eol_str,
186                                                       repair, keywords,
187                                                       expand, FALSE, pool));
188}
189
190svn_error_t *
191svn_subst_copy_and_translate2(const char *src,
192                              const char *dst,
193                              const char *eol_str,
194                              svn_boolean_t repair,
195                              const svn_subst_keywords_t *keywords,
196                              svn_boolean_t expand,
197                              svn_boolean_t special,
198                              apr_pool_t *pool)
199{
200  apr_hash_t *kh = kwstruct_to_kwhash(keywords, pool);
201
202  return svn_error_trace(svn_subst_copy_and_translate3(src, dst, eol_str,
203                                                       repair, kh, expand,
204                                                       special, pool));
205}
206
207svn_error_t *
208svn_subst_copy_and_translate3(const char *src,
209                              const char *dst,
210                              const char *eol_str,
211                              svn_boolean_t repair,
212                              apr_hash_t *keywords,
213                              svn_boolean_t expand,
214                              svn_boolean_t special,
215                              apr_pool_t *pool)
216{
217  return svn_error_trace(svn_subst_copy_and_translate4(src, dst, eol_str,
218                                                       repair, keywords,
219                                                       expand, special,
220                                                       NULL, NULL,
221                                                       pool));
222}
223
224
225svn_error_t *
226svn_subst_stream_translated_to_normal_form(svn_stream_t **stream,
227                                           svn_stream_t *source,
228                                           svn_subst_eol_style_t eol_style,
229                                           const char *eol_str,
230                                           svn_boolean_t always_repair_eols,
231                                           apr_hash_t *keywords,
232                                           apr_pool_t *pool)
233{
234  if (eol_style == svn_subst_eol_style_native)
235    eol_str = SVN_SUBST_NATIVE_EOL_STR;
236  else if (! (eol_style == svn_subst_eol_style_fixed
237              || eol_style == svn_subst_eol_style_none))
238    return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL, NULL, NULL);
239
240 *stream = svn_subst_stream_translated(source, eol_str,
241                                       eol_style == svn_subst_eol_style_fixed
242                                       || always_repair_eols,
243                                       keywords, FALSE, pool);
244
245 return SVN_NO_ERROR;
246}
247
248svn_error_t *
249svn_subst_translate_string(svn_string_t **new_value,
250                           const svn_string_t *value,
251                           const char *encoding,
252                           apr_pool_t *pool)
253{
254  return svn_subst_translate_string2(new_value, NULL, NULL, value,
255                                     encoding, FALSE, pool, pool);
256}
257
258svn_error_t *
259svn_subst_stream_detranslated(svn_stream_t **stream_p,
260                              const char *src,
261                              svn_subst_eol_style_t eol_style,
262                              const char *eol_str,
263                              svn_boolean_t always_repair_eols,
264                              apr_hash_t *keywords,
265                              svn_boolean_t special,
266                              apr_pool_t *pool)
267{
268  svn_stream_t *src_stream;
269
270  if (special)
271    return svn_subst_read_specialfile(stream_p, src, pool, pool);
272
273  /* This will be closed by svn_subst_stream_translated_to_normal_form
274     when the returned stream is closed. */
275  SVN_ERR(svn_stream_open_readonly(&src_stream, src, pool, pool));
276
277  return svn_error_trace(svn_subst_stream_translated_to_normal_form(
278                           stream_p, src_stream,
279                           eol_style, eol_str,
280                           always_repair_eols,
281                           keywords, pool));
282}
283
284svn_error_t *
285svn_subst_translate_to_normal_form(const char *src,
286                                   const char *dst,
287                                   svn_subst_eol_style_t eol_style,
288                                   const char *eol_str,
289                                   svn_boolean_t always_repair_eols,
290                                   apr_hash_t *keywords,
291                                   svn_boolean_t special,
292                                   apr_pool_t *pool)
293{
294
295  if (eol_style == svn_subst_eol_style_native)
296    eol_str = SVN_SUBST_NATIVE_EOL_STR;
297  else if (! (eol_style == svn_subst_eol_style_fixed
298              || eol_style == svn_subst_eol_style_none))
299    return svn_error_create(SVN_ERR_IO_UNKNOWN_EOL, NULL, NULL);
300
301  return svn_error_trace(svn_subst_copy_and_translate3(
302                           src, dst, eol_str,
303                           eol_style == svn_subst_eol_style_fixed
304                             || always_repair_eols,
305                           keywords,
306                           FALSE /* contract keywords */,
307                           special,
308                           pool));
309}
310
311
312/*** From opt.c ***/
313/* Same as print_command_info2(), but with deprecated struct revision. */
314static svn_error_t *
315print_command_info(const svn_opt_subcommand_desc_t *cmd,
316                   const apr_getopt_option_t *options_table,
317                   svn_boolean_t help,
318                   apr_pool_t *pool,
319                   FILE *stream)
320{
321  svn_boolean_t first_time;
322  apr_size_t i;
323
324  /* Print the canonical command name. */
325  SVN_ERR(svn_cmdline_fputs(cmd->name, stream, pool));
326
327  /* Print the list of aliases. */
328  first_time = TRUE;
329  for (i = 0; i < SVN_OPT_MAX_ALIASES; i++)
330    {
331      if (cmd->aliases[i] == NULL)
332        break;
333
334      if (first_time) {
335        SVN_ERR(svn_cmdline_fputs(" (", stream, pool));
336        first_time = FALSE;
337      }
338      else
339        SVN_ERR(svn_cmdline_fputs(", ", stream, pool));
340
341      SVN_ERR(svn_cmdline_fputs(cmd->aliases[i], stream, pool));
342    }
343
344  if (! first_time)
345    SVN_ERR(svn_cmdline_fputs(")", stream, pool));
346
347  if (help)
348    {
349      const apr_getopt_option_t *option;
350      svn_boolean_t have_options = FALSE;
351
352      SVN_ERR(svn_cmdline_fprintf(stream, pool, ": %s", _(cmd->help)));
353
354      /* Loop over all valid option codes attached to the subcommand */
355      for (i = 0; i < SVN_OPT_MAX_OPTIONS; i++)
356        {
357          if (cmd->valid_options[i])
358            {
359              if (!have_options)
360                {
361                  SVN_ERR(svn_cmdline_fputs(_("\nValid options:\n"),
362                                            stream, pool));
363                  have_options = TRUE;
364                }
365
366              /* convert each option code into an option */
367              option =
368                svn_opt_get_option_from_code2(cmd->valid_options[i],
369                                              options_table, NULL, pool);
370
371              /* print the option's docstring */
372              if (option && option->description)
373                {
374                  const char *optstr;
375                  svn_opt_format_option(&optstr, option, TRUE, pool);
376                  SVN_ERR(svn_cmdline_fprintf(stream, pool, "  %s\n",
377                                              optstr));
378                }
379            }
380        }
381
382      if (have_options)
383        SVN_ERR(svn_cmdline_fprintf(stream, pool, "\n"));
384    }
385
386  return SVN_NO_ERROR;
387}
388
389const svn_opt_subcommand_desc_t *
390svn_opt_get_canonical_subcommand(const svn_opt_subcommand_desc_t *table,
391                                 const char *cmd_name)
392{
393  int i = 0;
394
395  if (cmd_name == NULL)
396    return NULL;
397
398  while (table[i].name) {
399    int j;
400    if (strcmp(cmd_name, table[i].name) == 0)
401      return table + i;
402    for (j = 0; (j < SVN_OPT_MAX_ALIASES) && table[i].aliases[j]; j++)
403      if (strcmp(cmd_name, table[i].aliases[j]) == 0)
404        return table + i;
405
406    i++;
407  }
408
409  /* If we get here, there was no matching subcommand name or alias. */
410  return NULL;
411}
412
413void
414svn_opt_subcommand_help2(const char *subcommand,
415                         const svn_opt_subcommand_desc2_t *table,
416                         const apr_getopt_option_t *options_table,
417                         apr_pool_t *pool)
418{
419  svn_opt_subcommand_help3(subcommand, table, options_table,
420                           NULL, pool);
421}
422
423void
424svn_opt_subcommand_help(const char *subcommand,
425                        const svn_opt_subcommand_desc_t *table,
426                        const apr_getopt_option_t *options_table,
427                        apr_pool_t *pool)
428{
429  const svn_opt_subcommand_desc_t *cmd =
430    svn_opt_get_canonical_subcommand(table, subcommand);
431  svn_error_t *err;
432
433  if (cmd)
434    err = print_command_info(cmd, options_table, TRUE, pool, stdout);
435  else
436    err = svn_cmdline_fprintf(stderr, pool,
437                              _("\"%s\": unknown command.\n\n"), subcommand);
438
439  if (err) {
440    svn_handle_error2(err, stderr, FALSE, "svn: ");
441    svn_error_clear(err);
442  }
443}
444
445svn_error_t *
446svn_opt_args_to_target_array3(apr_array_header_t **targets_p,
447                              apr_getopt_t *os,
448                              const apr_array_header_t *known_targets,
449                              apr_pool_t *pool)
450{
451  return svn_error_trace(svn_opt__args_to_target_array(targets_p, os,
452                                                       known_targets, pool));
453}
454
455svn_error_t *
456svn_opt_args_to_target_array2(apr_array_header_t **targets_p,
457                              apr_getopt_t *os,
458                              const apr_array_header_t *known_targets,
459                              apr_pool_t *pool)
460{
461  svn_error_t *err = svn_opt_args_to_target_array3(targets_p, os,
462                                                   known_targets, pool);
463
464  if (err && err->apr_err == SVN_ERR_RESERVED_FILENAME_SPECIFIED)
465    {
466      svn_error_clear(err);
467      return SVN_NO_ERROR;
468    }
469
470  return err;
471}
472
473svn_error_t *
474svn_opt_args_to_target_array(apr_array_header_t **targets_p,
475                             apr_getopt_t *os,
476                             const apr_array_header_t *known_targets,
477                             svn_opt_revision_t *start_revision,
478                             svn_opt_revision_t *end_revision,
479                             svn_boolean_t extract_revisions,
480                             apr_pool_t *pool)
481{
482  apr_array_header_t *output_targets;
483
484  SVN_ERR(svn_opt_args_to_target_array2(&output_targets, os,
485                                        known_targets, pool));
486
487  if (extract_revisions)
488    {
489      svn_opt_revision_t temprev;
490      const char *path;
491
492      if (output_targets->nelts > 0)
493        {
494          path = APR_ARRAY_IDX(output_targets, 0, const char *);
495          SVN_ERR(svn_opt_parse_path(&temprev, &path, path, pool));
496          if (temprev.kind != svn_opt_revision_unspecified)
497            {
498              APR_ARRAY_IDX(output_targets, 0, const char *) = path;
499              start_revision->kind = temprev.kind;
500              start_revision->value = temprev.value;
501            }
502        }
503      if (output_targets->nelts > 1)
504        {
505          path = APR_ARRAY_IDX(output_targets, 1, const char *);
506          SVN_ERR(svn_opt_parse_path(&temprev, &path, path, pool));
507          if (temprev.kind != svn_opt_revision_unspecified)
508            {
509              APR_ARRAY_IDX(output_targets, 1, const char *) = path;
510              end_revision->kind = temprev.kind;
511              end_revision->value = temprev.value;
512            }
513        }
514    }
515
516  *targets_p = output_targets;
517  return SVN_NO_ERROR;
518}
519
520svn_error_t *
521svn_opt_print_help3(apr_getopt_t *os,
522                    const char *pgm_name,
523                    svn_boolean_t print_version,
524                    svn_boolean_t quiet,
525                    const char *version_footer,
526                    const char *header,
527                    const svn_opt_subcommand_desc2_t *cmd_table,
528                    const apr_getopt_option_t *option_table,
529                    const int *global_options,
530                    const char *footer,
531                    apr_pool_t *pool)
532{
533  return svn_error_trace(svn_opt_print_help4(os,
534                                             pgm_name,
535                                             print_version,
536                                             quiet,
537                                             FALSE,
538                                             version_footer,
539                                             header,
540                                             cmd_table,
541                                             option_table,
542                                             global_options,
543                                             footer,
544                                             pool));
545}
546
547svn_error_t *
548svn_opt_print_help2(apr_getopt_t *os,
549                    const char *pgm_name,
550                    svn_boolean_t print_version,
551                    svn_boolean_t quiet,
552                    const char *version_footer,
553                    const char *header,
554                    const svn_opt_subcommand_desc2_t *cmd_table,
555                    const apr_getopt_option_t *option_table,
556                    const char *footer,
557                    apr_pool_t *pool)
558{
559  return svn_error_trace(svn_opt_print_help4(os,
560                                             pgm_name,
561                                             print_version,
562                                             quiet,
563                                             FALSE,
564                                             version_footer,
565                                             header,
566                                             cmd_table,
567                                             option_table,
568                                             NULL,
569                                             footer,
570                                             pool));
571}
572
573svn_error_t *
574svn_opt_print_help(apr_getopt_t *os,
575                   const char *pgm_name,
576                   svn_boolean_t print_version,
577                   svn_boolean_t quiet,
578                   const char *version_footer,
579                   const char *header,
580                   const svn_opt_subcommand_desc_t *cmd_table,
581                   const apr_getopt_option_t *option_table,
582                   const char *footer,
583                   apr_pool_t *pool)
584{
585  apr_array_header_t *targets = NULL;
586
587  if (os)
588    SVN_ERR(svn_opt_parse_all_args(&targets, os, pool));
589
590  if (os && targets->nelts)  /* help on subcommand(s) requested */
591    {
592      int i;
593
594      for (i = 0; i < targets->nelts; i++)
595        {
596          svn_opt_subcommand_help(APR_ARRAY_IDX(targets, i, const char *),
597                                  cmd_table, option_table, pool);
598        }
599    }
600  else if (print_version)   /* just --version */
601    {
602      SVN_ERR(svn_opt__print_version_info(pgm_name, version_footer,
603                                          svn_version_extended(FALSE, pool),
604                                          quiet, FALSE, pool));
605    }
606  else if (os && !targets->nelts)            /* `-h', `--help', or `help' */
607    svn_opt_print_generic_help(header,
608                               cmd_table,
609                               option_table,
610                               footer,
611                               pool,
612                               stdout);
613  else                                       /* unknown option or cmd */
614    SVN_ERR(svn_cmdline_fprintf(stderr, pool,
615                                _("Type '%s help' for usage.\n"), pgm_name));
616
617  return SVN_NO_ERROR;
618}
619
620void
621svn_opt_print_generic_help(const char *header,
622                           const svn_opt_subcommand_desc_t *cmd_table,
623                           const apr_getopt_option_t *opt_table,
624                           const char *footer,
625                           apr_pool_t *pool, FILE *stream)
626{
627  int i = 0;
628  svn_error_t *err;
629
630  if (header)
631    if ((err = svn_cmdline_fputs(header, stream, pool)))
632      goto print_error;
633
634  while (cmd_table[i].name)
635    {
636      if ((err = svn_cmdline_fputs("   ", stream, pool))
637          || (err = print_command_info(cmd_table + i, opt_table, FALSE,
638                                       pool, stream))
639          || (err = svn_cmdline_fputs("\n", stream, pool)))
640        goto print_error;
641      i++;
642    }
643
644  if ((err = svn_cmdline_fputs("\n", stream, pool)))
645    goto print_error;
646
647  if (footer)
648    if ((err = svn_cmdline_fputs(footer, stream, pool)))
649      goto print_error;
650
651  return;
652
653 print_error:
654  svn_handle_error2(err, stderr, FALSE, "svn: ");
655  svn_error_clear(err);
656}
657
658/*** From io.c ***/
659svn_error_t *
660svn_io_open_unique_file2(apr_file_t **file,
661                         const char **temp_path,
662                         const char *path,
663                         const char *suffix,
664                         svn_io_file_del_t delete_when,
665                         apr_pool_t *pool)
666{
667  const char *dirpath;
668  const char *filename;
669
670  svn_path_split(path, &dirpath, &filename, pool);
671  return svn_error_trace(svn_io_open_uniquely_named(file, temp_path,
672                                                    dirpath, filename, suffix,
673                                                    delete_when,
674                                                    pool, pool));
675}
676
677svn_error_t *
678svn_io_open_unique_file(apr_file_t **file,
679                        const char **temp_path,
680                        const char *path,
681                        const char *suffix,
682                        svn_boolean_t delete_on_close,
683                        apr_pool_t *pool)
684{
685  return svn_error_trace(svn_io_open_unique_file2(file, temp_path,
686                                                  path, suffix,
687                                                  delete_on_close
688                                                    ? svn_io_file_del_on_close
689                                                    : svn_io_file_del_none,
690                                                  pool));
691}
692
693svn_error_t *
694svn_io_run_diff(const char *dir,
695                const char *const *user_args,
696                int num_user_args,
697                const char *label1,
698                const char *label2,
699                const char *from,
700                const char *to,
701                int *pexitcode,
702                apr_file_t *outfile,
703                apr_file_t *errfile,
704                const char *diff_cmd,
705                apr_pool_t *pool)
706{
707  SVN_ERR(svn_path_cstring_to_utf8(&diff_cmd, diff_cmd, pool));
708
709  return svn_error_trace(svn_io_run_diff2(dir, user_args, num_user_args,
710                                          label1, label2,
711                                          from, to, pexitcode,
712                                          outfile, errfile, diff_cmd,
713                                          pool));
714}
715
716svn_error_t *
717svn_io_run_diff3_2(int *exitcode,
718                   const char *dir,
719                   const char *mine,
720                   const char *older,
721                   const char *yours,
722                   const char *mine_label,
723                   const char *older_label,
724                   const char *yours_label,
725                   apr_file_t *merged,
726                   const char *diff3_cmd,
727                   const apr_array_header_t *user_args,
728                   apr_pool_t *pool)
729{
730  SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, pool));
731
732  return svn_error_trace(svn_io_run_diff3_3(exitcode, dir,
733                                            mine, older, yours,
734                                            mine_label, older_label,
735                                            yours_label, merged,
736                                            diff3_cmd, user_args, pool));
737}
738
739svn_error_t *
740svn_io_run_diff3(const char *dir,
741                 const char *mine,
742                 const char *older,
743                 const char *yours,
744                 const char *mine_label,
745                 const char *older_label,
746                 const char *yours_label,
747                 apr_file_t *merged,
748                 int *exitcode,
749                 const char *diff3_cmd,
750                 apr_pool_t *pool)
751{
752  return svn_error_trace(svn_io_run_diff3_2(exitcode, dir, mine, older, yours,
753                                            mine_label, older_label,
754                                            yours_label,
755                                            merged, diff3_cmd, NULL, pool));
756}
757
758svn_error_t *
759svn_io_remove_file(const char *path,
760                   apr_pool_t *scratch_pool)
761{
762  return svn_error_trace(svn_io_remove_file2(path, FALSE, scratch_pool));
763}
764
765svn_error_t *svn_io_file_lock(const char *lock_file,
766                              svn_boolean_t exclusive,
767                              apr_pool_t *pool)
768{
769  return svn_io_file_lock2(lock_file, exclusive, FALSE, pool);
770}
771
772svn_error_t *
773svn_io_get_dirents2(apr_hash_t **dirents,
774                    const char *path,
775                    apr_pool_t *pool)
776{
777  /* Note that the first part of svn_io_dirent2_t is identical
778     to svn_io_dirent_t to allow this construct */
779  return svn_error_trace(
780            svn_io_get_dirents3(dirents, path, FALSE, pool, pool));
781}
782
783svn_error_t *
784svn_io_get_dirents(apr_hash_t **dirents,
785                   const char *path,
786                   apr_pool_t *pool)
787{
788  /* Note that in C, padding is not allowed at the beginning of structs,
789     so this is actually portable, since the kind field of svn_io_dirent_t
790     is first in that struct. */
791  return svn_io_get_dirents2(dirents, path, pool);
792}
793
794svn_error_t *
795svn_io_start_cmd2(apr_proc_t *cmd_proc,
796                  const char *path,
797                  const char *cmd,
798                  const char *const *args,
799                  svn_boolean_t inherit,
800                  svn_boolean_t infile_pipe,
801                  apr_file_t *infile,
802                  svn_boolean_t outfile_pipe,
803                  apr_file_t *outfile,
804                  svn_boolean_t errfile_pipe,
805                  apr_file_t *errfile,
806                  apr_pool_t *pool)
807{
808  return svn_io_start_cmd3(cmd_proc, path, cmd, args, NULL, inherit,
809                           infile_pipe, infile, outfile_pipe, outfile,
810                           errfile_pipe, errfile, pool);
811}
812
813svn_error_t *
814svn_io_start_cmd(apr_proc_t *cmd_proc,
815                 const char *path,
816                 const char *cmd,
817                 const char *const *args,
818                 svn_boolean_t inherit,
819                 apr_file_t *infile,
820                 apr_file_t *outfile,
821                 apr_file_t *errfile,
822                 apr_pool_t *pool)
823{
824  return svn_io_start_cmd2(cmd_proc, path, cmd, args, inherit, FALSE,
825                           infile, FALSE, outfile, FALSE, errfile, pool);
826}
827
828svn_error_t *
829svn_io_file_read_full(apr_file_t *file, void *buf,
830                      apr_size_t nbytes, apr_size_t *bytes_read,
831                      apr_pool_t *pool)
832{
833  return svn_io_file_read_full2(file, buf, nbytes, bytes_read, NULL, pool);
834}
835
836struct walk_func_filter_baton_t
837{
838  svn_io_walk_func_t walk_func;
839  void *walk_baton;
840};
841
842/* Implements svn_io_walk_func_t, but only allows APR_DIR and APR_REG
843   finfo types through to the wrapped function/baton.  */
844static svn_error_t *
845walk_func_filter_func(void *baton,
846                      const char *path,
847                      const apr_finfo_t *finfo,
848                      apr_pool_t *pool)
849{
850  struct walk_func_filter_baton_t *b = baton;
851
852  if (finfo->filetype == APR_DIR || finfo->filetype == APR_REG)
853    SVN_ERR(b->walk_func(b->walk_baton, path, finfo, pool));
854
855  return SVN_NO_ERROR;
856}
857
858svn_error_t *
859svn_io_dir_walk(const char *dirname,
860                apr_int32_t wanted,
861                svn_io_walk_func_t walk_func,
862                void *walk_baton,
863                apr_pool_t *pool)
864{
865  struct walk_func_filter_baton_t baton;
866  baton.walk_func = walk_func;
867  baton.walk_baton = walk_baton;
868  return svn_error_trace(svn_io_dir_walk2(dirname, wanted,
869                                          walk_func_filter_func,
870                                          &baton, pool));
871}
872
873svn_error_t *
874svn_io_stat_dirent(const svn_io_dirent2_t **dirent_p,
875                   const char *path,
876                   svn_boolean_t ignore_enoent,
877                   apr_pool_t *result_pool,
878                   apr_pool_t *scratch_pool)
879{
880  return svn_error_trace(
881            svn_io_stat_dirent2(dirent_p,
882                                path,
883                                FALSE,
884                                ignore_enoent,
885                                result_pool,
886                                scratch_pool));
887}
888
889/*** From constructors.c ***/
890svn_log_changed_path_t *
891svn_log_changed_path_dup(const svn_log_changed_path_t *changed_path,
892                         apr_pool_t *pool)
893{
894  svn_log_changed_path_t *new_changed_path
895    = apr_palloc(pool, sizeof(*new_changed_path));
896
897  *new_changed_path = *changed_path;
898
899  if (new_changed_path->copyfrom_path)
900    new_changed_path->copyfrom_path =
901      apr_pstrdup(pool, new_changed_path->copyfrom_path);
902
903  return new_changed_path;
904}
905
906/*** From cmdline.c ***/
907svn_error_t *
908svn_cmdline_prompt_user(const char **result,
909                        const char *prompt_str,
910                        apr_pool_t *pool)
911{
912  return svn_error_trace(svn_cmdline_prompt_user2(result, prompt_str, NULL,
913                                                  pool));
914}
915
916svn_error_t *
917svn_cmdline_setup_auth_baton(svn_auth_baton_t **ab,
918                             svn_boolean_t non_interactive,
919                             const char *auth_username,
920                             const char *auth_password,
921                             const char *config_dir,
922                             svn_boolean_t no_auth_cache,
923                             svn_config_t *cfg,
924                             svn_cancel_func_t cancel_func,
925                             void *cancel_baton,
926                             apr_pool_t *pool)
927{
928  return svn_error_trace(svn_cmdline_create_auth_baton(
929                           ab, non_interactive,
930                           auth_username, auth_password,
931                           config_dir, no_auth_cache, FALSE,
932                           cfg, cancel_func, cancel_baton, pool));
933}
934
935/*** From dso.c ***/
936void
937svn_dso_initialize(void)
938{
939  svn_error_t *err = svn_dso_initialize2();
940  if (err)
941    {
942      svn_error_clear(err);
943      abort();
944    }
945}
946
947/*** From simple_providers.c ***/
948void
949svn_auth_get_simple_provider(svn_auth_provider_object_t **provider,
950                             apr_pool_t *pool)
951{
952  svn_auth_get_simple_provider2(provider, NULL, NULL, pool);
953}
954
955/*** From ssl_client_cert_pw_providers.c ***/
956void
957svn_auth_get_ssl_client_cert_pw_file_provider
958  (svn_auth_provider_object_t **provider,
959   apr_pool_t *pool)
960{
961  svn_auth_get_ssl_client_cert_pw_file_provider2(provider, NULL, NULL, pool);
962}
963
964/*** From path.c ***/
965
966#define SVN_EMPTY_PATH ""
967
968const char *
969svn_path_url_add_component(const char *url,
970                           const char *component,
971                           apr_pool_t *pool)
972{
973  /* URL can have trailing '/' */
974  url = svn_path_canonicalize(url, pool);
975
976  return svn_path_url_add_component2(url, component, pool);
977}
978
979void
980svn_path_split(const char *path,
981               const char **dirpath,
982               const char **base_name,
983               apr_pool_t *pool)
984{
985  assert(dirpath != base_name);
986
987  if (dirpath)
988    *dirpath = svn_path_dirname(path, pool);
989
990  if (base_name)
991    *base_name = svn_path_basename(path, pool);
992}
993
994
995svn_error_t *
996svn_path_split_if_file(const char *path,
997                       const char **pdirectory,
998                       const char **pfile,
999                       apr_pool_t *pool)
1000{
1001  apr_finfo_t finfo;
1002  svn_error_t *err;
1003
1004  SVN_ERR_ASSERT(svn_path_is_canonical(path, pool));
1005
1006  err = svn_io_stat(&finfo, path, APR_FINFO_TYPE, pool);
1007  if (err && ! APR_STATUS_IS_ENOENT(err->apr_err))
1008    return err;
1009
1010  if (err || finfo.filetype == APR_REG)
1011    {
1012      svn_error_clear(err);
1013      svn_path_split(path, pdirectory, pfile, pool);
1014    }
1015  else if (finfo.filetype == APR_DIR)
1016    {
1017      *pdirectory = path;
1018      *pfile = SVN_EMPTY_PATH;
1019    }
1020  else
1021    {
1022      return svn_error_createf(SVN_ERR_BAD_FILENAME, NULL,
1023                               _("'%s' is neither a file nor a directory name"),
1024                               svn_path_local_style(path, pool));
1025    }
1026
1027  return SVN_NO_ERROR;
1028}
1029
1030/*** From stream.c ***/
1031svn_error_t *svn_stream_copy2(svn_stream_t *from, svn_stream_t *to,
1032                              svn_cancel_func_t cancel_func,
1033                              void *cancel_baton,
1034                              apr_pool_t *scratch_pool)
1035{
1036  return svn_error_trace(svn_stream_copy3(
1037                           svn_stream_disown(from, scratch_pool),
1038                           svn_stream_disown(to, scratch_pool),
1039                           cancel_func, cancel_baton, scratch_pool));
1040}
1041
1042svn_error_t *svn_stream_copy(svn_stream_t *from, svn_stream_t *to,
1043                             apr_pool_t *scratch_pool)
1044{
1045  return svn_error_trace(svn_stream_copy3(
1046                           svn_stream_disown(from, scratch_pool),
1047                           svn_stream_disown(to, scratch_pool),
1048                           NULL, NULL, scratch_pool));
1049}
1050
1051svn_stream_t *
1052svn_stream_from_aprfile(apr_file_t *file, apr_pool_t *pool)
1053{
1054  return svn_stream_from_aprfile2(file, TRUE, pool);
1055}
1056
1057svn_error_t *
1058svn_stream_contents_same(svn_boolean_t *same,
1059                         svn_stream_t *stream1,
1060                         svn_stream_t *stream2,
1061                         apr_pool_t *pool)
1062{
1063  return svn_error_trace(svn_stream_contents_same2(
1064                           same,
1065                           svn_stream_disown(stream1, pool),
1066                           svn_stream_disown(stream2, pool),
1067                           pool));
1068}
1069
1070/*** From path.c ***/
1071
1072const char *
1073svn_path_internal_style(const char *path, apr_pool_t *pool)
1074{
1075  if (svn_path_is_url(path))
1076    return svn_uri_canonicalize(path, pool);
1077  else
1078    return svn_dirent_internal_style(path, pool);
1079}
1080
1081
1082const char *
1083svn_path_local_style(const char *path, apr_pool_t *pool)
1084{
1085  if (svn_path_is_url(path))
1086    return apr_pstrdup(pool, path);
1087  else
1088    return svn_dirent_local_style(path, pool);
1089}
1090
1091const char *
1092svn_path_canonicalize(const char *path, apr_pool_t *pool)
1093{
1094  if (svn_path_is_url(path))
1095    return svn_uri_canonicalize(path, pool);
1096  else
1097    return svn_dirent_canonicalize(path, pool);
1098}
1099
1100
1101/*** From mergeinfo.c ***/
1102
1103svn_error_t *
1104svn_mergeinfo_inheritable(svn_mergeinfo_t *output,
1105                          svn_mergeinfo_t mergeinfo,
1106                          const char *path,
1107                          svn_revnum_t start,
1108                          svn_revnum_t end,
1109                          apr_pool_t *pool)
1110{
1111  return svn_error_trace(svn_mergeinfo_inheritable2(output, mergeinfo, path,
1112                                                    start, end,
1113                                                    TRUE, pool, pool));
1114}
1115
1116svn_error_t *
1117svn_rangelist_inheritable(svn_rangelist_t **inheritable_rangelist,
1118                          const svn_rangelist_t *rangelist,
1119                          svn_revnum_t start,
1120                          svn_revnum_t end,
1121                          apr_pool_t *pool)
1122{
1123  return svn_error_trace(svn_rangelist_inheritable2(inheritable_rangelist,
1124                                                    rangelist,
1125                                                    start, end, TRUE,
1126                                                    pool, pool));
1127}
1128
1129svn_error_t *
1130svn_rangelist_merge(svn_rangelist_t **rangelist,
1131                    const svn_rangelist_t *changes,
1132                    apr_pool_t *pool)
1133{
1134  SVN_ERR(svn_rangelist_merge2(*rangelist, changes,
1135                               pool, pool));
1136
1137  return svn_error_trace(
1138            svn_rangelist__combine_adjacent_ranges(*rangelist, pool));
1139}
1140
1141svn_error_t *
1142svn_mergeinfo_diff(svn_mergeinfo_t *deleted, svn_mergeinfo_t *added,
1143                   svn_mergeinfo_t from, svn_mergeinfo_t to,
1144                   svn_boolean_t consider_inheritance,
1145                   apr_pool_t *pool)
1146{
1147  return svn_error_trace(svn_mergeinfo_diff2(deleted, added, from, to,
1148                                             consider_inheritance, pool,
1149                                             pool));
1150}
1151
1152svn_error_t *
1153svn_mergeinfo_merge(svn_mergeinfo_t mergeinfo,
1154                    svn_mergeinfo_t changes,
1155                    apr_pool_t *pool)
1156{
1157  return svn_error_trace(svn_mergeinfo_merge2(mergeinfo, changes, pool,
1158                         pool));
1159}
1160
1161svn_error_t *
1162svn_mergeinfo_remove(svn_mergeinfo_t *mergeinfo, svn_mergeinfo_t eraser,
1163                     svn_mergeinfo_t whiteboard, apr_pool_t *pool)
1164{
1165  return svn_mergeinfo_remove2(mergeinfo, eraser, whiteboard, TRUE, pool,
1166                               pool);
1167}
1168
1169svn_error_t *
1170svn_mergeinfo_intersect(svn_mergeinfo_t *mergeinfo,
1171                        svn_mergeinfo_t mergeinfo1,
1172                        svn_mergeinfo_t mergeinfo2,
1173                        apr_pool_t *pool)
1174{
1175  return svn_mergeinfo_intersect2(mergeinfo, mergeinfo1, mergeinfo2,
1176                                  TRUE, pool, pool);
1177}
1178
1179/*** From config.c ***/
1180svn_error_t *
1181svn_config_create(svn_config_t **cfgp,
1182                  svn_boolean_t section_names_case_sensitive,
1183                  apr_pool_t *result_pool)
1184{
1185  return svn_error_trace(svn_config_create2(cfgp,
1186                                            section_names_case_sensitive,
1187                                            FALSE,
1188                                            result_pool));
1189}
1190
1191svn_error_t *
1192svn_config_read2(svn_config_t **cfgp, const char *file,
1193                 svn_boolean_t must_exist,
1194                 svn_boolean_t section_names_case_sensitive,
1195                 apr_pool_t *result_pool)
1196{
1197  return svn_error_trace(svn_config_read3(cfgp, file,
1198                                          must_exist,
1199                                          section_names_case_sensitive,
1200                                          FALSE,
1201                                          result_pool));
1202}
1203
1204svn_error_t *
1205svn_config_read(svn_config_t **cfgp, const char *file,
1206                svn_boolean_t must_exist,
1207                apr_pool_t *result_pool)
1208{
1209  return svn_error_trace(svn_config_read3(cfgp, file,
1210                                          must_exist,
1211                                          FALSE, FALSE,
1212                                          result_pool));
1213}
1214
1215#ifdef SVN_DISABLE_FULL_VERSION_MATCH
1216/* This double underscore name is used by the 1.6 command line client.
1217   Keeping this name is sufficient for the 1.6 client to use the 1.7
1218   libraries at runtime. */
1219svn_error_t *
1220svn_opt__eat_peg_revisions(apr_array_header_t **true_targets_p,
1221                           apr_array_header_t *targets,
1222                           apr_pool_t *pool);
1223svn_error_t *
1224svn_opt__eat_peg_revisions(apr_array_header_t **true_targets_p,
1225                           apr_array_header_t *targets,
1226                           apr_pool_t *pool)
1227{
1228  unsigned int i;
1229  apr_array_header_t *true_targets;
1230
1231  true_targets = apr_array_make(pool, 5, sizeof(const char *));
1232
1233  for (i = 0; i < targets->nelts; i++)
1234    {
1235      const char *target = APR_ARRAY_IDX(targets, i, const char *);
1236      const char *true_target;
1237
1238      SVN_ERR(svn_opt__split_arg_at_peg_revision(&true_target, NULL,
1239                                                 target, pool));
1240      APR_ARRAY_PUSH(true_targets, const char *) = true_target;
1241    }
1242
1243  SVN_ERR_ASSERT(true_targets_p);
1244  *true_targets_p = true_targets;
1245
1246  return SVN_NO_ERROR;
1247}
1248#endif
1249
1250void
1251svn_xml_make_header(svn_stringbuf_t **str, apr_pool_t *pool)
1252{
1253  svn_xml_make_header2(str, NULL, pool);
1254}
1255
1256void
1257svn_utf_initialize(apr_pool_t *pool)
1258{
1259  svn_utf_initialize2(FALSE, pool);
1260}
1261
1262svn_error_t *
1263svn_subst_build_keywords(svn_subst_keywords_t *kw,
1264                         const char *keywords_val,
1265                         const char *rev,
1266                         const char *url,
1267                         apr_time_t date,
1268                         const char *author,
1269                         apr_pool_t *pool)
1270{
1271  apr_hash_t *kwhash;
1272  const svn_string_t *val;
1273
1274  SVN_ERR(svn_subst_build_keywords2(&kwhash, keywords_val, rev,
1275                                    url, date, author, pool));
1276
1277  /* The behaviour of pre-1.3 svn_subst_build_keywords, which we are
1278   * replicating here, is to write to a slot in the svn_subst_keywords_t
1279   * only if the relevant keyword was present in keywords_val, otherwise
1280   * leaving that slot untouched. */
1281
1282  val = svn_hash_gets(kwhash, SVN_KEYWORD_REVISION_LONG);
1283  if (val)
1284    kw->revision = val;
1285
1286  val = svn_hash_gets(kwhash, SVN_KEYWORD_DATE_LONG);
1287  if (val)
1288    kw->date = val;
1289
1290  val = svn_hash_gets(kwhash, SVN_KEYWORD_AUTHOR_LONG);
1291  if (val)
1292    kw->author = val;
1293
1294  val = svn_hash_gets(kwhash, SVN_KEYWORD_URL_LONG);
1295  if (val)
1296    kw->url = val;
1297
1298  val = svn_hash_gets(kwhash, SVN_KEYWORD_ID);
1299  if (val)
1300    kw->id = val;
1301
1302  return SVN_NO_ERROR;
1303}
1304
1305/*** From version.c ***/
1306svn_error_t *
1307svn_ver_check_list(const svn_version_t *my_version,
1308                   const svn_version_checklist_t *checklist)
1309{
1310  return svn_ver_check_list2(my_version, checklist, svn_ver_compatible);
1311}
1312