]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/subversion/subversion/svnbench/null-list-cmd.c
MFV r353630: 10809 Performance optimization of AVL tree comparator functions
[FreeBSD/FreeBSD.git] / contrib / subversion / subversion / svnbench / null-list-cmd.c
1 /*
2  * list-cmd.c -- list a URL
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_cmdline.h"
25 #include "svn_client.h"
26 #include "svn_error.h"
27 #include "svn_pools.h"
28 #include "svn_time.h"
29 #include "svn_xml.h"
30 #include "svn_dirent_uri.h"
31 #include "svn_path.h"
32 #include "svn_utf.h"
33 #include "svn_opt.h"
34
35 #include "cl.h"
36
37 #include "svn_private_config.h"
38 #include "private/svn_string_private.h"
39
40 \f
41
42 /* Baton used when printing directory entries. */
43 struct print_baton {
44   svn_boolean_t verbose;
45   apr_int64_t directories;
46   apr_int64_t files;
47   apr_int64_t locks;
48   svn_client_ctx_t *ctx;
49 };
50
51 /* Field flags required for this function */
52 static const apr_uint32_t print_dirent_fields = SVN_DIRENT_KIND;
53 static const apr_uint32_t print_dirent_fields_verbose = (
54     SVN_DIRENT_KIND  | SVN_DIRENT_SIZE | SVN_DIRENT_TIME |
55     SVN_DIRENT_CREATED_REV | SVN_DIRENT_LAST_AUTHOR);
56
57 /* This implements the svn_client_list_func2_t API, printing a single
58    directory entry in text format. */
59 static svn_error_t *
60 print_dirent(void *baton,
61              const char *path,
62              const svn_dirent_t *dirent,
63              const svn_lock_t *lock,
64              const char *abs_path,
65              const char *external_parent_url,
66              const char *external_target,
67              apr_pool_t *pool)
68 {
69   struct print_baton *pb = baton;
70
71   if (pb->ctx->cancel_func)
72     SVN_ERR(pb->ctx->cancel_func(pb->ctx->cancel_baton));
73
74   if (dirent->kind == svn_node_dir)
75     pb->directories++;
76   if (dirent->kind == svn_node_file)
77     pb->files++;
78   if (lock)
79     pb->locks++;
80
81   return SVN_NO_ERROR;
82 }
83
84
85 /* This implements the `svn_opt_subcommand_t' interface. */
86 svn_error_t *
87 svn_cl__null_list(apr_getopt_t *os,
88                   void *baton,
89                   apr_pool_t *pool)
90 {
91   svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
92   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
93   apr_array_header_t *targets;
94   int i;
95   apr_pool_t *subpool = svn_pool_create(pool);
96   apr_uint32_t dirent_fields;
97   struct print_baton pb = { FALSE };
98   svn_boolean_t seen_nonexistent_target = FALSE;
99   svn_error_t *err;
100
101   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
102                                                       opt_state->targets,
103                                                       ctx, FALSE, pool));
104
105   /* Add "." if user passed 0 arguments */
106   svn_opt_push_implicit_dot_target(targets, pool);
107
108   if (opt_state->verbose)
109     dirent_fields = print_dirent_fields_verbose;
110   else
111     dirent_fields = print_dirent_fields;
112
113   pb.ctx = ctx;
114   pb.verbose = opt_state->verbose;
115
116   if (opt_state->depth == svn_depth_unknown)
117     opt_state->depth = svn_depth_immediates;
118
119   /* For each target, try to list it. */
120   for (i = 0; i < targets->nelts; i++)
121     {
122       const char *target = APR_ARRAY_IDX(targets, i, const char *);
123       const char *truepath;
124       svn_opt_revision_t peg_revision;
125       apr_array_header_t *patterns = NULL;
126       int k;
127
128       svn_pool_clear(subpool);
129
130       SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
131
132       /* Get peg revisions. */
133       SVN_ERR(svn_opt_parse_path(&peg_revision, &truepath, target,
134                                  subpool));
135
136       if (opt_state->search_patterns)
137         {
138           patterns = apr_array_make(subpool, 4, sizeof(const char *));
139           for (k = 0; k < opt_state->search_patterns->nelts; ++k)
140             {
141               apr_array_header_t *pattern_group
142                 = APR_ARRAY_IDX(opt_state->search_patterns, k,
143                                 apr_array_header_t *);
144
145               /* Should never fail but ... */
146               if (pattern_group->nelts != 1)
147                 return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
148                                   _("'search-and' option is not supported"));
149
150               APR_ARRAY_PUSH(patterns, const char *)
151                 = APR_ARRAY_IDX(pattern_group, 0, const char *);
152             }
153         }
154
155       err = svn_client_list4(truepath, &peg_revision,
156                              &(opt_state->start_revision), patterns,
157                              opt_state->depth,
158                              dirent_fields,
159                              opt_state->verbose,
160                              FALSE, /* include externals */
161                              print_dirent,
162                              &pb, ctx, subpool);
163
164       if (err)
165         {
166           /* If one of the targets is a non-existent URL or wc-entry,
167              don't bail out.  Just warn and move on to the next target. */
168           if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND ||
169               err->apr_err == SVN_ERR_FS_NOT_FOUND)
170               svn_handle_warning2(stderr, err, "svnbench: ");
171           else
172               return svn_error_trace(err);
173
174           svn_error_clear(err);
175           err = NULL;
176           seen_nonexistent_target = TRUE;
177         }
178       else if (!opt_state->quiet)
179         SVN_ERR(svn_cmdline_printf(pool,
180                                    _("%15s directories\n"
181                                      "%15s files\n"
182                                      "%15s locks\n"),
183                                    svn__ui64toa_sep(pb.directories, ',', pool),
184                                    svn__ui64toa_sep(pb.files, ',', pool),
185                                    svn__ui64toa_sep(pb.locks, ',', pool)));
186     }
187
188   svn_pool_destroy(subpool);
189
190   if (seen_nonexistent_target)
191     return svn_error_create(
192       SVN_ERR_ILLEGAL_TARGET, NULL,
193       _("Could not list all targets because some targets don't exist"));
194   else
195     return SVN_NO_ERROR;
196 }