2
2
* sorts.c: all sorts of sorts
4
4
* ====================================================================
5
* Copyright (c) 2000-2004 CollabNet. All rights reserved.
5
* Copyright (c) 2000-2006 CollabNet. All rights reserved.
7
7
* This software is licensed as described in the file COPYING, which
8
8
* you should have received as part of this distribution. The terms
70
70
assert(astr[a->klen] == '\0');
71
71
assert(bstr[b->klen] == '\0');
72
return svn_path_compare_paths (astr, bstr);
72
return svn_path_compare_paths(astr, bstr);
77
svn_sort_compare_items_lexically (const svn_sort__item_t *a,
78
const svn_sort__item_t *b)
77
svn_sort_compare_items_lexically(const svn_sort__item_t *a,
78
const svn_sort__item_t *b)
83
83
/* Compare bytes of a's key and b's key up to the common length. */
84
84
len = (a->klen < b->klen) ? a->klen : b->klen;
85
val = memcmp (a->key, b->key, len);
85
val = memcmp(a->key, b->key, len);
108
svn_sort_compare_paths (const void *a, const void *b)
108
svn_sort_compare_paths(const void *a, const void *b)
110
110
const char *item1 = *((const char * const *) a);
111
111
const char *item2 = *((const char * const *) b);
113
return svn_path_compare_paths (item1, item2);
113
return svn_path_compare_paths(item1, item2);
118
118
apr_array_header_t *
119
svn_sort__hash (apr_hash_t *ht,
120
int (*comparison_func) (const svn_sort__item_t *,
121
const svn_sort__item_t *),
119
svn_sort__hash(apr_hash_t *ht,
120
int (*comparison_func)(const svn_sort__item_t *,
121
const svn_sort__item_t *),
124
124
apr_hash_index_t *hi;
125
125
apr_array_header_t *ary;
127
/* allocate an array with only one element to begin with. */
128
ary = apr_array_make (pool, 1, sizeof(svn_sort__item_t));
127
/* allocate an array with enough elements to hold all the keys. */
128
ary = apr_array_make(pool, apr_hash_count(ht), sizeof(svn_sort__item_t));
130
130
/* loop over hash table and push all keys into the array */
131
for (hi = apr_hash_first (pool, ht); hi; hi = apr_hash_next (hi))
131
for (hi = apr_hash_first(pool, ht); hi; hi = apr_hash_next(hi))
133
svn_sort__item_t *item = apr_array_push (ary);
133
svn_sort__item_t *item = apr_array_push(ary);
135
apr_hash_this (hi, &item->key, &item->klen, &item->value);
135
apr_hash_this(hi, &item->key, &item->klen, &item->value);
138
138
/* now quicksort the array. */
139
qsort (ary->elts, ary->nelts, ary->elt_size,
140
(int (*)(const void *, const void *))comparison_func);
139
qsort(ary->elts, ary->nelts, ary->elt_size,
140
(int (*)(const void *, const void *))comparison_func);
147
147
/** Sorting properties **/
150
svn_prop_is_svn_prop (const char *prop_name)
150
svn_prop_is_svn_prop(const char *prop_name)
152
return strncmp (prop_name, SVN_PROP_PREFIX, (sizeof (SVN_PROP_PREFIX) - 1))
152
return strncmp(prop_name, SVN_PROP_PREFIX, (sizeof(SVN_PROP_PREFIX) - 1))
159
svn_property_kind (int *prefix_len,
160
const char *prop_name)
159
svn_property_kind(int *prefix_len,
160
const char *prop_name)
162
apr_size_t wc_prefix_len = sizeof (SVN_PROP_WC_PREFIX) - 1;
163
apr_size_t entry_prefix_len = sizeof (SVN_PROP_ENTRY_PREFIX) - 1;
162
apr_size_t wc_prefix_len = sizeof(SVN_PROP_WC_PREFIX) - 1;
163
apr_size_t entry_prefix_len = sizeof(SVN_PROP_ENTRY_PREFIX) - 1;
165
if (strncmp (prop_name, SVN_PROP_WC_PREFIX, wc_prefix_len) == 0)
165
if (strncmp(prop_name, SVN_PROP_WC_PREFIX, wc_prefix_len) == 0)
168
168
*prefix_len = wc_prefix_len;
169
169
return svn_prop_wc_kind;
172
if (strncmp (prop_name, SVN_PROP_ENTRY_PREFIX, entry_prefix_len) == 0)
172
if (strncmp(prop_name, SVN_PROP_ENTRY_PREFIX, entry_prefix_len) == 0)
175
175
*prefix_len = entry_prefix_len;
187
svn_categorize_props (const apr_array_header_t *proplist,
188
apr_array_header_t **entry_props,
189
apr_array_header_t **wc_props,
190
apr_array_header_t **regular_props,
187
svn_categorize_props(const apr_array_header_t *proplist,
188
apr_array_header_t **entry_props,
189
apr_array_header_t **wc_props,
190
apr_array_header_t **regular_props,
195
*entry_props = apr_array_make (pool, 1, sizeof (svn_prop_t));
195
*entry_props = apr_array_make(pool, 1, sizeof(svn_prop_t));
197
*wc_props = apr_array_make (pool, 1, sizeof (svn_prop_t));
197
*wc_props = apr_array_make(pool, 1, sizeof(svn_prop_t));
198
198
if (regular_props)
199
*regular_props = apr_array_make (pool, 1, sizeof (svn_prop_t));
199
*regular_props = apr_array_make(pool, 1, sizeof(svn_prop_t));
201
201
for (i = 0; i < proplist->nelts; i++)
203
203
svn_prop_t *prop, *newprop;
204
204
enum svn_prop_kind kind;
206
prop = &APR_ARRAY_IDX (proplist, i, svn_prop_t);
207
kind = svn_property_kind (NULL, prop->name);
206
prop = &APR_ARRAY_IDX(proplist, i, svn_prop_t);
207
kind = svn_property_kind(NULL, prop->name);
210
210
if (kind == svn_prop_regular_kind)
212
212
if (regular_props)
213
newprop = apr_array_push (*regular_props);
213
newprop = apr_array_push(*regular_props);
215
215
else if (kind == svn_prop_wc_kind)
218
newprop = apr_array_push (*wc_props);
218
newprop = apr_array_push(*wc_props);
220
220
else if (kind == svn_prop_entry_kind)
223
newprop = apr_array_push (*entry_props);
223
newprop = apr_array_push(*entry_props);
226
226
/* Technically this can't happen, but might as well have the
227
227
code ready in case that ever changes. */
228
return svn_error_createf (SVN_ERR_BAD_PROP_KIND, NULL,
229
"Bad property kind for property '%s'",
228
return svn_error_createf(SVN_ERR_BAD_PROP_KIND, NULL,
229
"Bad property kind for property '%s'",
244
svn_prop_diffs (apr_array_header_t **propdiffs,
245
apr_hash_t *target_props,
246
apr_hash_t *source_props,
244
svn_prop_diffs(apr_array_header_t **propdiffs,
245
apr_hash_t *target_props,
246
apr_hash_t *source_props,
249
249
apr_hash_index_t *hi;
250
apr_array_header_t *ary = apr_array_make (pool, 1, sizeof (svn_prop_t));
250
apr_array_header_t *ary = apr_array_make(pool, 1, sizeof(svn_prop_t));
252
252
/* Note: we will be storing the pointers to the keys (from the hashes)
253
253
into the propdiffs array. It is acceptable for us to
263
263
const svn_string_t *propval1, *propval2;
265
265
/* Get next property */
266
apr_hash_this (hi, &key, &klen, &val);
266
apr_hash_this(hi, &key, &klen, &val);
269
269
/* Does property name exist in TARGET_PROPS? */
270
propval2 = apr_hash_get (target_props, key, klen);
270
propval2 = apr_hash_get(target_props, key, klen);
272
272
if (propval2 == NULL)
274
274
/* Add a delete event to the array */
275
svn_prop_t *p = apr_array_push (ary);
275
svn_prop_t *p = apr_array_push(ary);
279
else if (! svn_string_compare (propval1, propval2))
279
else if (! svn_string_compare(propval1, propval2))
281
281
/* Add a set (modification) event to the array */
282
svn_prop_t *p = apr_array_push (ary);
282
svn_prop_t *p = apr_array_push(ary);
284
p->value = svn_string_dup (propval2, pool);
284
p->value = svn_string_dup(propval2, pool);
288
288
/* Loop over TARGET_PROPS and examine each key. This allows us to
289
289
detect `set-creation' events */
290
for (hi = apr_hash_first (pool, target_props); hi; hi = apr_hash_next (hi))
290
for (hi = apr_hash_first(pool, target_props); hi; hi = apr_hash_next(hi))
293
293
apr_ssize_t klen;
295
295
const svn_string_t *propval;
297
297
/* Get next property */
298
apr_hash_this (hi, &key, &klen, &val);
298
apr_hash_this(hi, &key, &klen, &val);
301
301
/* Does property name exist in SOURCE_PROPS? */
302
if (NULL == apr_hash_get (source_props, key, klen))
302
if (NULL == apr_hash_get(source_props, key, klen))
304
304
/* Add a set (creation) event to the array */
305
svn_prop_t *p = apr_array_push (ary);
305
svn_prop_t *p = apr_array_push(ary);
307
p->value = svn_string_dup (propval, pool);
307
p->value = svn_string_dup(propval, pool);
319
svn_prop_needs_translation (const char *propname)
319
svn_prop_needs_translation(const char *propname)
321
321
/* ### Someday, we may want to be picky and choosy about which
322
322
properties require UTF8 and EOL conversion. For now, all "svn:"
323
323
props need it. */
325
return svn_prop_is_svn_prop (propname);
325
return svn_prop_is_svn_prop(propname);