Fix compiler warning due to missing function prototype.
[svn.git] / subversion / libsvn_client / changelist.c
blob5c19d098d254e99e52c4c4cb6358a7b3239eed04
1 /*
2 * changelist.c: implementation of the 'changelist' command
4 * ====================================================================
5 * Copyright (c) 2006-2007 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 /* ==================================================================== */
23 /*** Includes. ***/
25 #include "svn_client.h"
26 #include "svn_wc.h"
27 #include "svn_pools.h"
28 #include "svn_path.h"
29 #include "svn_hash.h"
31 #include "client.h"
32 #include "private/svn_wc_private.h"
35 /* Entry-walker callback for svn_client_add_to_changelist() and
36 svn_client_remove_from_changelist() below. */
37 struct set_cl_fe_baton
39 svn_wc_adm_access_t *adm_access;
40 const char *changelist; /* NULL if removing changelists */
41 apr_hash_t *changelist_hash;
42 svn_client_ctx_t *ctx;
43 apr_pool_t *pool;
47 static svn_error_t *
48 set_entry_changelist(const char *path,
49 const svn_wc_entry_t *entry,
50 void *baton,
51 apr_pool_t *pool)
53 struct set_cl_fe_baton *b = (struct set_cl_fe_baton *)baton;
54 svn_wc_adm_access_t *adm_access;
56 /* We only care about files right now. */
57 if (entry->kind != svn_node_file)
59 if ((strcmp(SVN_WC_ENTRY_THIS_DIR, entry->name) == 0)
60 && (b->ctx->notify_func2))
61 b->ctx->notify_func2(b->ctx->notify_baton2,
62 svn_wc_create_notify(path,
63 svn_wc_notify_skip,
64 pool),
65 pool);
66 return SVN_NO_ERROR;
69 /* See if this entry passes our changelist filtering. */
70 if (! SVN_WC__CL_MATCH(b->changelist_hash, entry))
71 return SVN_NO_ERROR;
73 /* Get the ADM_ACCESS for our file's parent directory,
74 specifically. */
75 SVN_ERR(svn_wc_adm_retrieve(&adm_access, b->adm_access,
76 svn_path_dirname(path, pool), pool));
77 return svn_wc_set_changelist(path, b->changelist, adm_access,
78 b->ctx->cancel_func, b->ctx->cancel_baton,
79 b->ctx->notify_func2, b->ctx->notify_baton2,
80 pool);
84 static const svn_wc_entry_callbacks2_t set_cl_entry_callbacks =
85 { set_entry_changelist, svn_client__default_walker_error_handler };
88 svn_error_t *
89 svn_client_add_to_changelist(const apr_array_header_t *paths,
90 const char *changelist,
91 svn_depth_t depth,
92 const apr_array_header_t *changelists,
93 svn_client_ctx_t *ctx,
94 apr_pool_t *pool)
96 /* ### Someday this routine might use a different underlying API to
97 ### to make the associations in a centralized database. */
99 apr_pool_t *subpool = svn_pool_create(pool);
100 apr_hash_t *changelist_hash = NULL;
101 int i;
103 if (changelists && changelists->nelts)
104 SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists, pool));
106 for (i = 0; i < paths->nelts; i++)
108 struct set_cl_fe_baton seb;
109 svn_wc_adm_access_t *adm_access;
110 const char *path = APR_ARRAY_IDX(paths, i, const char *);
112 svn_pool_clear(subpool);
113 SVN_ERR(svn_wc_adm_probe_open3(&adm_access, NULL, path,
114 TRUE, /* write lock */ -1, /* infinity */
115 ctx->cancel_func, ctx->cancel_baton,
116 subpool));
118 seb.adm_access = adm_access;
119 seb.changelist = changelist;
120 seb.changelist_hash = changelist_hash;
121 seb.ctx = ctx;
122 seb.pool = subpool;
123 SVN_ERR(svn_wc_walk_entries3(path, adm_access,
124 &set_cl_entry_callbacks, &seb,
125 depth, FALSE, /* no hidden entries */
126 ctx->cancel_func, ctx->cancel_baton,
127 subpool));
129 SVN_ERR(svn_wc_adm_close(adm_access));
132 svn_pool_destroy(subpool);
133 return SVN_NO_ERROR;
137 svn_error_t *
138 svn_client_remove_from_changelists(const apr_array_header_t *paths,
139 svn_depth_t depth,
140 const apr_array_header_t *changelists,
141 svn_client_ctx_t *ctx,
142 apr_pool_t *pool)
144 /* ### Someday this routine might use a different underlying API to
145 ### to make the associations in a centralized database. */
147 apr_pool_t *subpool = svn_pool_create(pool);
148 apr_hash_t *changelist_hash = NULL;
149 int i;
151 if (changelists && changelists->nelts)
152 SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash, changelists, pool));
154 for (i = 0; i < paths->nelts; i++)
156 struct set_cl_fe_baton seb;
157 svn_wc_adm_access_t *adm_access;
158 const char *path = APR_ARRAY_IDX(paths, i, const char *);
160 svn_pool_clear(subpool);
161 SVN_ERR(svn_wc_adm_probe_open3(&adm_access, NULL, path,
162 TRUE, /* write lock */ -1, /* infinity */
163 ctx->cancel_func, ctx->cancel_baton,
164 subpool));
166 seb.adm_access = adm_access;
167 seb.changelist = NULL;
168 seb.changelist_hash = changelist_hash;
169 seb.ctx = ctx;
170 seb.pool = subpool;
171 SVN_ERR(svn_wc_walk_entries3(path, adm_access,
172 &set_cl_entry_callbacks, &seb,
173 depth, FALSE, /* no hidden entries */
174 ctx->cancel_func, ctx->cancel_baton,
175 subpool));
177 SVN_ERR(svn_wc_adm_close(adm_access));
180 svn_pool_destroy(subpool);
181 return SVN_NO_ERROR;
186 /* Entry-walker callback for svn_client_get_changelist() below. */
187 struct get_cl_fe_baton
189 svn_changelist_receiver_t callback_func;
190 void *callback_baton;
191 apr_hash_t *changelists;
192 apr_pool_t *pool;
196 static svn_error_t *
197 get_entry_changelist(const char *path,
198 const svn_wc_entry_t *entry,
199 void *baton,
200 apr_pool_t *pool)
202 struct get_cl_fe_baton *b = (struct get_cl_fe_baton *)baton;
204 /* If the entry has a changelist, and is a file or is the "this-dir"
205 entry for directory, and the changelist matches one that we're
206 looking for (or we aren't looking for any in particular)... */
207 if (SVN_WC__CL_MATCH(b->changelists, entry)
208 && ((entry->kind == svn_node_file)
209 || ((entry->kind == svn_node_dir)
210 && (strcmp(entry->name, SVN_WC_ENTRY_THIS_DIR) == 0))))
212 /* ...then call the callback function. */
213 SVN_ERR(b->callback_func(b->callback_baton, path,
214 entry->changelist, pool));
217 return SVN_NO_ERROR;
221 static const svn_wc_entry_callbacks2_t get_cl_entry_callbacks =
222 { get_entry_changelist, svn_client__default_walker_error_handler };
225 svn_error_t *
226 svn_client_get_changelists(const char *path,
227 const apr_array_header_t *changelists,
228 svn_depth_t depth,
229 svn_changelist_receiver_t callback_func,
230 void *callback_baton,
231 svn_client_ctx_t *ctx,
232 apr_pool_t *pool)
234 struct get_cl_fe_baton geb;
235 svn_wc_adm_access_t *adm_access;
237 geb.callback_func = callback_func;
238 geb.callback_baton = callback_baton;
239 geb.pool = pool;
240 if (changelists)
241 SVN_ERR(svn_hash_from_cstring_keys(&(geb.changelists), changelists, pool));
242 else
243 geb.changelists = NULL;
244 SVN_ERR(svn_wc_adm_probe_open3(&adm_access, NULL, path,
245 FALSE, /* no write lock */
246 -1, /* levels to lock == infinity */
247 ctx->cancel_func, ctx->cancel_baton, pool));
248 SVN_ERR(svn_wc_walk_entries3(path, adm_access, &get_cl_entry_callbacks, &geb,
249 depth, FALSE, /* don't show hidden entries */
250 ctx->cancel_func, ctx->cancel_baton, pool));
251 SVN_ERR(svn_wc_adm_close(adm_access));
253 return SVN_NO_ERROR;