Commit 2fe54afa by Russell Belfer

Put hooks in place for precompose in dirload fn

This doesn't actual do string precompose but it puts the hooks in
place into the iterators and the git_path_dirload function so that
the actual precompose work is ready to go.
parent 6b7991e2
...@@ -67,6 +67,7 @@ static struct map_data _cvar_maps[] = { ...@@ -67,6 +67,7 @@ static struct map_data _cvar_maps[] = {
{"core.ignorestat", NULL, 0, GIT_IGNORESTAT_DEFAULT }, {"core.ignorestat", NULL, 0, GIT_IGNORESTAT_DEFAULT },
{"core.trustctime", NULL, 0, GIT_TRUSTCTIME_DEFAULT }, {"core.trustctime", NULL, 0, GIT_TRUSTCTIME_DEFAULT },
{"core.abbrev", _cvar_map_int, 1, GIT_ABBREV_DEFAULT }, {"core.abbrev", _cvar_map_int, 1, GIT_ABBREV_DEFAULT },
{"core.precomposeunicode", NULL, 0, GIT_PRECOMPOSE_DEFAULT },
}; };
int git_repository__cvar(int *out, git_repository *repo, git_cvar_cached cvar) int git_repository__cvar(int *out, git_repository *repo, git_cvar_cached cvar)
......
...@@ -986,7 +986,10 @@ static int fs_iterator__expand_dir(fs_iterator *fi) ...@@ -986,7 +986,10 @@ static int fs_iterator__expand_dir(fs_iterator *fi)
GITERR_CHECK_ALLOC(ff); GITERR_CHECK_ALLOC(ff);
error = git_path_dirload_with_stat( error = git_path_dirload_with_stat(
fi->path.ptr, fi->root_len, iterator__ignore_case(fi), fi->path.ptr, fi->root_len,
(iterator__ignore_case(fi) ? GIT_PATH_DIRLOAD_IGNORE_CASE : 0) |
(iterator__flag(fi, PRECOMPOSE_UNICODE) ?
GIT_PATH_DIRLOAD_PRECOMPOSE_UNICODE : 0),
fi->base.start, fi->base.end, &ff->entries); fi->base.start, fi->base.end, &ff->entries);
if (error < 0) { if (error < 0) {
...@@ -1356,6 +1359,15 @@ int git_iterator_for_workdir_ext( ...@@ -1356,6 +1359,15 @@ int git_iterator_for_workdir_ext(
return error; return error;
} }
/* try to look up precompose and set flag if appropriate */
{
int precompose = 0;
if (git_repository__cvar(&precompose, repo, GIT_CVAR_PRECOMPOSE) < 0)
giterr_clear();
else if (precompose)
wi->fi.base.flags |= GIT_ITERATOR_PRECOMPOSE_UNICODE;
}
return fs_iterator__initialize(out, &wi->fi, repo_workdir); return fs_iterator__initialize(out, &wi->fi, repo_workdir);
} }
......
...@@ -24,13 +24,15 @@ typedef enum { ...@@ -24,13 +24,15 @@ typedef enum {
typedef enum { typedef enum {
/** ignore case for entry sort order */ /** ignore case for entry sort order */
GIT_ITERATOR_IGNORE_CASE = (1 << 0), GIT_ITERATOR_IGNORE_CASE = (1u << 0),
/** force case sensitivity for entry sort order */ /** force case sensitivity for entry sort order */
GIT_ITERATOR_DONT_IGNORE_CASE = (1 << 1), GIT_ITERATOR_DONT_IGNORE_CASE = (1u << 1),
/** return tree items in addition to blob items */ /** return tree items in addition to blob items */
GIT_ITERATOR_INCLUDE_TREES = (1 << 2), GIT_ITERATOR_INCLUDE_TREES = (1u << 2),
/** don't flatten trees, requiring advance_into (implies INCLUDE_TREES) */ /** don't flatten trees, requiring advance_into (implies INCLUDE_TREES) */
GIT_ITERATOR_DONT_AUTOEXPAND = (1 << 3), GIT_ITERATOR_DONT_AUTOEXPAND = (1u << 3),
/** convert precomposed unicode to decomposed unicode */
GIT_ITERATOR_PRECOMPOSE_UNICODE = (1u << 4),
} git_iterator_flag_t; } git_iterator_flag_t;
typedef struct { typedef struct {
......
...@@ -781,6 +781,7 @@ int git_path_dirload( ...@@ -781,6 +781,7 @@ int git_path_dirload(
const char *path, const char *path,
size_t prefix_len, size_t prefix_len,
size_t alloc_extra, size_t alloc_extra,
unsigned int flags,
git_vector *contents) git_vector *contents)
{ {
int error, need_slash; int error, need_slash;
...@@ -816,6 +817,12 @@ int git_path_dirload( ...@@ -816,6 +817,12 @@ int git_path_dirload(
entry_len = strlen(de->d_name); entry_len = strlen(de->d_name);
/* if we read decomposed unicode and precompose flag is set,
* then precompose it now so app code sees it as precomposed
*/
if ((flags & GIT_PATH_DIRLOAD_PRECOMPOSE_UNICODE) != 0) {
}
entry_path = git__malloc( entry_path = git__malloc(
path_len + need_slash + entry_len + 1 + alloc_extra); path_len + need_slash + entry_len + 1 + alloc_extra);
GITERR_CHECK_ALLOC(entry_path); GITERR_CHECK_ALLOC(entry_path);
...@@ -858,7 +865,7 @@ int git_path_with_stat_cmp_icase(const void *a, const void *b) ...@@ -858,7 +865,7 @@ int git_path_with_stat_cmp_icase(const void *a, const void *b)
int git_path_dirload_with_stat( int git_path_dirload_with_stat(
const char *path, const char *path,
size_t prefix_len, size_t prefix_len,
bool ignore_case, unsigned int flags,
const char *start_stat, const char *start_stat,
const char *end_stat, const char *end_stat,
git_vector *contents) git_vector *contents)
...@@ -875,13 +882,14 @@ int git_path_dirload_with_stat( ...@@ -875,13 +882,14 @@ int git_path_dirload_with_stat(
return -1; return -1;
error = git_path_dirload( error = git_path_dirload(
path, prefix_len, sizeof(git_path_with_stat) + 1, contents); path, prefix_len, sizeof(git_path_with_stat) + 1, flags, contents);
if (error < 0) { if (error < 0) {
git_buf_free(&full); git_buf_free(&full);
return error; return error;
} }
strncomp = ignore_case ? git__strncasecmp : git__strncmp; strncomp = (flags & GIT_PATH_DIRLOAD_IGNORE_CASE) != 0 ?
git__strncasecmp : git__strncmp;
/* stat struct at start of git_path_with_stat, so shift path text */ /* stat struct at start of git_path_with_stat, so shift path text */
git_vector_foreach(contents, i, ps) { git_vector_foreach(contents, i, ps) {
......
...@@ -290,6 +290,11 @@ extern int git_path_walk_up( ...@@ -290,6 +290,11 @@ extern int git_path_walk_up(
int (*fn)(void *state, git_buf *), int (*fn)(void *state, git_buf *),
void *state); void *state);
enum {
GIT_PATH_DIRLOAD_IGNORE_CASE = (1u << 0),
GIT_PATH_DIRLOAD_PRECOMPOSE_UNICODE = (1u << 1),
};
/** /**
* Load all directory entries (except '.' and '..') into a vector. * Load all directory entries (except '.' and '..') into a vector.
* *
...@@ -310,6 +315,7 @@ extern int git_path_dirload( ...@@ -310,6 +315,7 @@ extern int git_path_dirload(
const char *path, const char *path,
size_t prefix_len, size_t prefix_len,
size_t alloc_extra, size_t alloc_extra,
unsigned int flags,
git_vector *contents); git_vector *contents);
...@@ -336,7 +342,7 @@ extern int git_path_with_stat_cmp_icase(const void *a, const void *b); ...@@ -336,7 +342,7 @@ extern int git_path_with_stat_cmp_icase(const void *a, const void *b);
* *
* @param path The directory to read from * @param path The directory to read from
* @param prefix_len The trailing part of path to prefix to entry paths * @param prefix_len The trailing part of path to prefix to entry paths
* @param ignore_case How to sort and compare paths with start/end limits * @param flags GIT_PATH_DIRLOAD flags from above
* @param start_stat As optimization, only stat values after this prefix * @param start_stat As optimization, only stat values after this prefix
* @param end_stat As optimization, only stat values before this prefix * @param end_stat As optimization, only stat values before this prefix
* @param contents Vector to fill with git_path_with_stat structures * @param contents Vector to fill with git_path_with_stat structures
...@@ -344,7 +350,7 @@ extern int git_path_with_stat_cmp_icase(const void *a, const void *b); ...@@ -344,7 +350,7 @@ extern int git_path_with_stat_cmp_icase(const void *a, const void *b);
extern int git_path_dirload_with_stat( extern int git_path_dirload_with_stat(
const char *path, const char *path,
size_t prefix_len, size_t prefix_len,
bool ignore_case, unsigned int flags,
const char *start_stat, const char *start_stat,
const char *end_stat, const char *end_stat,
git_vector *contents); git_vector *contents);
......
...@@ -458,17 +458,23 @@ static void refdb_fs_backend__iterator_free(git_reference_iterator *_iter) ...@@ -458,17 +458,23 @@ static void refdb_fs_backend__iterator_free(git_reference_iterator *_iter)
static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter) static int iter_load_loose_paths(refdb_fs_backend *backend, refdb_fs_iter *iter)
{ {
int error = 0; int error = 0, t;
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
git_iterator_flag_t flags = 0;
git_iterator *fsit = NULL; git_iterator *fsit = NULL;
const git_index_entry *entry = NULL; const git_index_entry *entry = NULL;
if (!backend->path) /* do nothing if no path for loose refs */ if (!backend->path) /* do nothing if no path for loose refs */
return 0; return 0;
if (!git_repository__cvar(&t, backend->repo, GIT_CVAR_IGNORECASE) && t)
flags |= GIT_ITERATOR_IGNORE_CASE;
if (!git_repository__cvar(&t, backend->repo, GIT_CVAR_PRECOMPOSE) && t)
flags |= GIT_ITERATOR_PRECOMPOSE_UNICODE;
if ((error = git_buf_printf(&path, "%s/refs", backend->path)) < 0 || if ((error = git_buf_printf(&path, "%s/refs", backend->path)) < 0 ||
(error = git_iterator_for_filesystem( (error = git_iterator_for_filesystem(
&fsit, git_buf_cstr(&path), 0, NULL, NULL)) < 0) { &fsit, git_buf_cstr(&path), flags, NULL, NULL)) < 0) {
git_buf_free(&path); git_buf_free(&path);
return error; return error;
} }
......
...@@ -37,6 +37,7 @@ typedef enum { ...@@ -37,6 +37,7 @@ typedef enum {
GIT_CVAR_IGNORESTAT, /* core.ignorestat */ GIT_CVAR_IGNORESTAT, /* core.ignorestat */
GIT_CVAR_TRUSTCTIME, /* core.trustctime */ GIT_CVAR_TRUSTCTIME, /* core.trustctime */
GIT_CVAR_ABBREV, /* core.abbrev */ GIT_CVAR_ABBREV, /* core.abbrev */
GIT_CVAR_PRECOMPOSE, /* core.precomposeunicode */
GIT_CVAR_CACHE_MAX GIT_CVAR_CACHE_MAX
} git_cvar_cached; } git_cvar_cached;
...@@ -86,6 +87,8 @@ typedef enum { ...@@ -86,6 +87,8 @@ typedef enum {
GIT_TRUSTCTIME_DEFAULT = GIT_CVAR_TRUE, GIT_TRUSTCTIME_DEFAULT = GIT_CVAR_TRUE,
/* core.abbrev */ /* core.abbrev */
GIT_ABBREV_DEFAULT = 7, GIT_ABBREV_DEFAULT = 7,
/* core.precomposeunicode */
GIT_PRECOMPOSE_DEFAULT = GIT_CVAR_FALSE,
} git_cvar_value; } git_cvar_value;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment