diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/blob.c | 1 | ||||
-rw-r--r-- | src/branch.c | 2 | ||||
-rw-r--r-- | src/commit.c | 87 | ||||
-rw-r--r-- | src/config.c | 1 | ||||
-rw-r--r-- | src/config_file.c | 1 | ||||
-rw-r--r-- | src/index.c | 2 | ||||
-rw-r--r-- | src/iterator.c | 521 | ||||
-rw-r--r-- | src/iterator.h | 11 | ||||
-rw-r--r-- | src/odb.c | 22 | ||||
-rw-r--r-- | src/odb_loose.c | 2 | ||||
-rw-r--r-- | src/odb_pack.c | 3 | ||||
-rw-r--r-- | src/refdb.c | 44 | ||||
-rw-r--r-- | src/refdb.h | 2 | ||||
-rw-r--r-- | src/refdb_fs.c | 42 | ||||
-rw-r--r-- | src/refs.c | 72 | ||||
-rw-r--r-- | src/repository.c | 7 | ||||
-rw-r--r-- | src/revparse.c | 2 | ||||
-rw-r--r-- | src/submodule.c | 1 | ||||
-rw-r--r-- | src/tag.c | 1 | ||||
-rw-r--r-- | src/transports/smart_protocol.c | 1 | ||||
-rw-r--r-- | src/unix/posix.h | 2 | ||||
-rw-r--r-- | src/util.h | 2 |
22 files changed, 491 insertions, 338 deletions
diff --git a/src/blob.c b/src/blob.c index c0514fc13..11e1f4d77 100644 --- a/src/blob.c +++ b/src/blob.c @@ -8,6 +8,7 @@ #include "git2/common.h" #include "git2/object.h" #include "git2/repository.h" +#include "git2/odb_backend.h" #include "common.h" #include "blob.h" diff --git a/src/branch.c b/src/branch.c index e7088790e..956286b74 100644 --- a/src/branch.c +++ b/src/branch.c @@ -377,7 +377,7 @@ int git_branch_remote_name(char *buffer, size_t buffer_len, git_repository *repo if (buffer) git_buf_copy_cstr(buffer, buffer_len, &buf); - ret = git_buf_len(&buf) + 1; + ret = (int)git_buf_len(&buf) + 1; git_buf_free(&buf); return ret; diff --git a/src/commit.c b/src/commit.c index c7b83ed43..dd416920d 100644 --- a/src/commit.c +++ b/src/commit.c @@ -9,6 +9,7 @@ #include "git2/object.h" #include "git2/repository.h" #include "git2/signature.h" +#include "git2/sys/commit.h" #include "common.h" #include "odb.h" @@ -44,16 +45,16 @@ void git_commit__free(git_commit *commit) } int git_commit_create_v( - git_oid *oid, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_tree *tree, - int parent_count, - ...) + git_oid *oid, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + int parent_count, + ...) { va_list ap; int i, res; @@ -76,30 +77,29 @@ int git_commit_create_v( return res; } -int git_commit_create( - git_oid *oid, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_tree *tree, - int parent_count, - const git_commit *parents[]) +int git_commit_create_from_oids( + git_oid *oid, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_oid *tree, + int parent_count, + const git_oid *parents[]) { git_buf commit = GIT_BUF_INIT; int i; git_odb *odb; + assert(oid && repo && tree && parent_count >= 0); assert(git_object_owner((const git_object *)tree) == repo); - git_oid__writebuf(&commit, "tree ", git_object_id((const git_object *)tree)); + git_oid__writebuf(&commit, "tree ", tree); - for (i = 0; i < parent_count; ++i) { - assert(git_object_owner((const git_object *)parents[i]) == repo); - git_oid__writebuf(&commit, "parent ", git_object_id((const git_object *)parents[i])); - } + for (i = 0; i < parent_count; ++i) + git_oid__writebuf(&commit, "parent ", parents[i]); git_signature__writebuf(&commit, "author ", author); git_signature__writebuf(&commit, "committer ", committer); @@ -131,6 +131,41 @@ on_error: return -1; } +int git_commit_create( + git_oid *oid, + git_repository *repo, + const char *update_ref, + const git_signature *author, + const git_signature *committer, + const char *message_encoding, + const char *message, + const git_tree *tree, + int parent_count, + const git_commit *parents[]) +{ + int retval, i; + const git_oid **parent_oids; + + assert(parent_count >= 0); + + parent_oids = git__malloc(parent_count * sizeof(git_oid *)); + GITERR_CHECK_ALLOC(parent_oids); + + for (i = 0; i < parent_count; ++i) { + assert(git_object_owner((const git_object *)parents[i]) == repo); + parent_oids[i] = git_object_id((const git_object *)parents[i]); + } + + retval = git_commit_create_from_oids( + oid, repo, update_ref, author, committer, + message_encoding, message, + git_object_id((const git_object *)tree), parent_count, parent_oids); + + git__free((void *)parent_oids); + + return retval; +} + int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len) { const char *buffer = data; diff --git a/src/config.c b/src/config.c index 5379b0ec5..1283522ca 100644 --- a/src/config.c +++ b/src/config.c @@ -9,6 +9,7 @@ #include "fileops.h" #include "config.h" #include "git2/config.h" +#include "git2/sys/config.h" #include "vector.h" #include "buf_text.h" #include "config_file.h" diff --git a/src/config_file.c b/src/config_file.c index 8b51ab21b..a4ff8bb94 100644 --- a/src/config_file.c +++ b/src/config_file.c @@ -12,6 +12,7 @@ #include "buffer.h" #include "buf_text.h" #include "git2/config.h" +#include "git2/sys/config.h" #include "git2/types.h" #include "strmap.h" diff --git a/src/index.c b/src/index.c index 6290ec4e8..2afd28158 100644 --- a/src/index.c +++ b/src/index.c @@ -1345,7 +1345,7 @@ static size_t read_extension(git_index *index, const char *buffer, size_t buffer static int parse_index(git_index *index, const char *buffer, size_t buffer_size) { unsigned int i; - struct index_header header; + struct index_header header = { 0 }; git_oid checksum_calculated, checksum_expected; #define seek_forward(_increase) { \ diff --git a/src/iterator.c b/src/iterator.c index 5b5ed9525..ff08c1ce0 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -26,8 +26,6 @@ (GIT_ITERATOR_IGNORE_CASE | GIT_ITERATOR_DONT_IGNORE_CASE) #define ITERATOR_BASE_INIT(P,NAME_LC,NAME_UC,REPO) do { \ - (P) = git__calloc(1, sizeof(NAME_LC ## _iterator)); \ - GITERR_CHECK_ALLOC(P); \ (P)->base.type = GIT_ITERATOR_TYPE_ ## NAME_UC; \ (P)->base.cb = &(P)->cb; \ ITERATOR_SET_CB(P,NAME_LC); \ @@ -148,7 +146,8 @@ int git_iterator_for_nothing( const char *start, const char *end) { - empty_iterator *i; + empty_iterator *i = git__calloc(1, sizeof(empty_iterator)); + GITERR_CHECK_ALLOC(i); #define empty_iterator__current empty_iterator__noop #define empty_iterator__advance empty_iterator__noop @@ -581,6 +580,9 @@ int git_iterator_for_tree( if ((error = git_object_dup((git_object **)&tree, (git_object *)tree)) < 0) return error; + ti = git__calloc(1, sizeof(tree_iterator)); + GITERR_CHECK_ALLOC(ti); + ITERATOR_BASE_INIT(ti, tree, TREE, git_tree_owner(tree)); if ((error = iterator__update_ignore_case((git_iterator *)ti, flags)) < 0) @@ -810,7 +812,8 @@ int git_iterator_for_index( const char *start, const char *end) { - index_iterator *ii; + index_iterator *ii = git__calloc(1, sizeof(index_iterator)); + GITERR_CHECK_ALLOC(ii); ITERATOR_BASE_INIT(ii, index, INDEX, git_index_owner(index)); @@ -833,237 +836,221 @@ int git_iterator_for_index( } -#define WORKDIR_MAX_DEPTH 100 - -typedef struct workdir_iterator_frame workdir_iterator_frame; -struct workdir_iterator_frame { - workdir_iterator_frame *next; +typedef struct fs_iterator_frame fs_iterator_frame; +struct fs_iterator_frame { + fs_iterator_frame *next; git_vector entries; size_t index; }; -typedef struct { +typedef struct fs_iterator fs_iterator; +struct fs_iterator { git_iterator base; git_iterator_callbacks cb; - workdir_iterator_frame *stack; - git_ignores ignores; + fs_iterator_frame *stack; git_index_entry entry; git_buf path; size_t root_len; - int is_ignored; int depth; -} workdir_iterator; -GIT_INLINE(bool) path_is_dotgit(const git_path_with_stat *ps) -{ - if (!ps) - return false; - else { - const char *path = ps->path; - size_t len = ps->path_len; - - if (len < 4) - return false; - if (path[len - 1] == '/') - len--; - if (tolower(path[len - 1]) != 't' || - tolower(path[len - 2]) != 'i' || - tolower(path[len - 3]) != 'g' || - tolower(path[len - 4]) != '.') - return false; - return (len == 4 || path[len - 5] == '/'); - } -} + int (*enter_dir_cb)(fs_iterator *self); + int (*leave_dir_cb)(fs_iterator *self); + int (*update_entry_cb)(fs_iterator *self); +}; -static workdir_iterator_frame *workdir_iterator__alloc_frame( - workdir_iterator *wi) +#define FS_MAX_DEPTH 100 + +static fs_iterator_frame *fs_iterator__alloc_frame(fs_iterator *fi) { - workdir_iterator_frame *wf = git__calloc(1, sizeof(workdir_iterator_frame)); + fs_iterator_frame *ff = git__calloc(1, sizeof(fs_iterator_frame)); git_vector_cmp entry_compare = CASESELECT( - iterator__ignore_case(wi), + iterator__ignore_case(fi), git_path_with_stat_cmp_icase, git_path_with_stat_cmp); - if (wf == NULL) - return NULL; - - if (git_vector_init(&wf->entries, 0, entry_compare) != 0) { - git__free(wf); - return NULL; + if (ff && git_vector_init(&ff->entries, 0, entry_compare) < 0) { + git__free(ff); + ff = NULL; } - return wf; + return ff; } -static void workdir_iterator__free_frame(workdir_iterator_frame *wf) +static void fs_iterator__free_frame(fs_iterator_frame *ff) { - unsigned int i; + size_t i; git_path_with_stat *path; - git_vector_foreach(&wf->entries, i, path) + git_vector_foreach(&ff->entries, i, path) git__free(path); - git_vector_free(&wf->entries); - git__free(wf); + git_vector_free(&ff->entries); + git__free(ff); +} + +static void fs_iterator__pop_frame( + fs_iterator *fi, fs_iterator_frame *ff, bool pop_last) +{ + if (fi && fi->stack == ff) { + if (!ff->next && !pop_last) { + memset(&fi->entry, 0, sizeof(fi->entry)); + return; + } + + if (fi->leave_dir_cb) + (void)fi->leave_dir_cb(fi); + + fi->stack = ff->next; + fi->depth--; + } + + fs_iterator__free_frame(ff); } -static int workdir_iterator__update_entry(workdir_iterator *wi); +static int fs_iterator__update_entry(fs_iterator *fi); -static int workdir_iterator__entry_cmp(const void *i, const void *item) +static int fs_iterator__entry_cmp(const void *i, const void *item) { - const workdir_iterator *wi = (const workdir_iterator *)i; + const fs_iterator *fi = (const fs_iterator *)i; const git_path_with_stat *ps = item; - return wi->base.prefixcomp(wi->base.start, ps->path); + return fi->base.prefixcomp(fi->base.start, ps->path); } -static void workdir_iterator__seek_frame_start( - workdir_iterator *wi, workdir_iterator_frame *wf) +static void fs_iterator__seek_frame_start( + fs_iterator *fi, fs_iterator_frame *ff) { - if (!wf) + if (!ff) return; - if (wi->base.start) + if (fi->base.start) git_vector_bsearch2( - &wf->index, &wf->entries, workdir_iterator__entry_cmp, wi); + &ff->index, &ff->entries, fs_iterator__entry_cmp, fi); else - wf->index = 0; - - if (path_is_dotgit(git_vector_get(&wf->entries, wf->index))) - wf->index++; + ff->index = 0; } -static int workdir_iterator__expand_dir(workdir_iterator *wi) +static int fs_iterator__expand_dir(fs_iterator *fi) { int error; - workdir_iterator_frame *wf; + fs_iterator_frame *ff; + + if (fi->depth > FS_MAX_DEPTH) { + giterr_set(GITERR_REPOSITORY, + "Directory nesting is too deep (%d)", fi->depth); + return -1; + } - wf = workdir_iterator__alloc_frame(wi); - GITERR_CHECK_ALLOC(wf); + ff = fs_iterator__alloc_frame(fi); + GITERR_CHECK_ALLOC(ff); error = git_path_dirload_with_stat( - wi->path.ptr, wi->root_len, iterator__ignore_case(wi), - wi->base.start, wi->base.end, &wf->entries); + fi->path.ptr, fi->root_len, iterator__ignore_case(fi), + fi->base.start, fi->base.end, &ff->entries); - if (error < 0 || wf->entries.length == 0) { - workdir_iterator__free_frame(wf); + if (error < 0 || ff->entries.length == 0) { + fs_iterator__free_frame(ff); return GIT_ENOTFOUND; } - if (++(wi->depth) > WORKDIR_MAX_DEPTH) { - giterr_set(GITERR_REPOSITORY, - "Working directory is too deep (%d)", wi->depth); - workdir_iterator__free_frame(wf); - return -1; - } - - workdir_iterator__seek_frame_start(wi, wf); + fs_iterator__seek_frame_start(fi, ff); - /* only push new ignores if this is not top level directory */ - if (wi->stack != NULL) { - ssize_t slash_pos = git_buf_rfind_next(&wi->path, '/'); - (void)git_ignore__push_dir(&wi->ignores, &wi->path.ptr[slash_pos + 1]); - } + ff->next = fi->stack; + fi->stack = ff; + fi->depth++; - wf->next = wi->stack; - wi->stack = wf; + if (fi->enter_dir_cb && (error = fi->enter_dir_cb(fi)) < 0) + return error; - return workdir_iterator__update_entry(wi); + return fs_iterator__update_entry(fi); } -static int workdir_iterator__current( +static int fs_iterator__current( const git_index_entry **entry, git_iterator *self) { - workdir_iterator *wi = (workdir_iterator *)self; + fs_iterator *fi = (fs_iterator *)self; if (entry) - *entry = (wi->entry.path == NULL) ? NULL : &wi->entry; + *entry = (fi->entry.path == NULL) ? NULL : &fi->entry; return 0; } -static int workdir_iterator__at_end(git_iterator *self) +static int fs_iterator__at_end(git_iterator *self) { - return (((workdir_iterator *)self)->entry.path == NULL); + return (((fs_iterator *)self)->entry.path == NULL); } -static int workdir_iterator__advance_into( +static int fs_iterator__advance_into( const git_index_entry **entry, git_iterator *iter) { int error = 0; - workdir_iterator *wi = (workdir_iterator *)iter; + fs_iterator *fi = (fs_iterator *)iter; iterator__clear_entry(entry); - /* workdir iterator will allow you to explicitly advance into a - * commit/submodule (as well as a tree) to avoid some cases where an - * entry is mislabeled as a submodule in the working directory + /* Allow you to explicitly advance into a commit/submodule (as well as a + * tree) to avoid cases where an entry is mislabeled as a submodule in + * the working directory. The fs iterator will never have COMMMIT + * entries on it's own, but a wrapper might add them. */ - if (wi->entry.path != NULL && - (wi->entry.mode == GIT_FILEMODE_TREE || - wi->entry.mode == GIT_FILEMODE_COMMIT)) + if (fi->entry.path != NULL && + (fi->entry.mode == GIT_FILEMODE_TREE || + fi->entry.mode == GIT_FILEMODE_COMMIT)) /* returns GIT_ENOTFOUND if the directory is empty */ - error = workdir_iterator__expand_dir(wi); + error = fs_iterator__expand_dir(fi); if (!error && entry) - error = workdir_iterator__current(entry, iter); + error = fs_iterator__current(entry, iter); return error; } -static int workdir_iterator__advance( +static int fs_iterator__advance_over( const git_index_entry **entry, git_iterator *self) { int error = 0; - workdir_iterator *wi = (workdir_iterator *)self; - workdir_iterator_frame *wf; + fs_iterator *fi = (fs_iterator *)self; + fs_iterator_frame *ff; git_path_with_stat *next; - /* given include_trees & autoexpand, we might have to go into a tree */ - if (iterator__do_autoexpand(wi) && - wi->entry.path != NULL && - wi->entry.mode == GIT_FILEMODE_TREE) - { - error = workdir_iterator__advance_into(entry, self); - - /* continue silently past empty directories if autoexpanding */ - if (error != GIT_ENOTFOUND) - return error; - giterr_clear(); - error = 0; - } - if (entry != NULL) *entry = NULL; - while (wi->entry.path != NULL) { - wf = wi->stack; - next = git_vector_get(&wf->entries, ++wf->index); + while (fi->entry.path != NULL) { + ff = fi->stack; + next = git_vector_get(&ff->entries, ++ff->index); - if (next != NULL) { - /* match git's behavior of ignoring anything named ".git" */ - if (path_is_dotgit(next)) - continue; - /* else found a good entry */ + if (next != NULL) break; - } - - /* pop stack if anything is left to pop */ - if (!wf->next) { - memset(&wi->entry, 0, sizeof(wi->entry)); - return 0; - } - wi->stack = wf->next; - wi->depth--; - workdir_iterator__free_frame(wf); - git_ignore__pop_dir(&wi->ignores); + fs_iterator__pop_frame(fi, ff, false); } - error = workdir_iterator__update_entry(wi); + error = fs_iterator__update_entry(fi); if (!error && entry != NULL) - error = workdir_iterator__current(entry, self); + error = fs_iterator__current(entry, self); return error; } -static int workdir_iterator__seek(git_iterator *self, const char *prefix) +static int fs_iterator__advance( + const git_index_entry **entry, git_iterator *self) +{ + fs_iterator *fi = (fs_iterator *)self; + + /* given include_trees & autoexpand, we might have to go into a tree */ + if (iterator__do_autoexpand(fi) && + fi->entry.path != NULL && + fi->entry.mode == GIT_FILEMODE_TREE) + { + int error = fs_iterator__advance_into(entry, self); + if (error != GIT_ENOTFOUND) + return error; + /* continue silently past empty directories if autoexpanding */ + giterr_clear(); + } + + return fs_iterator__advance_over(entry, self); +} + +static int fs_iterator__seek(git_iterator *self, const char *prefix) { GIT_UNUSED(self); GIT_UNUSED(prefix); @@ -1073,107 +1060,192 @@ static int workdir_iterator__seek(git_iterator *self, const char *prefix) return 0; } -static int workdir_iterator__reset( +static int fs_iterator__reset( git_iterator *self, const char *start, const char *end) { - workdir_iterator *wi = (workdir_iterator *)self; + fs_iterator *fi = (fs_iterator *)self; - while (wi->stack != NULL && wi->stack->next != NULL) { - workdir_iterator_frame *wf = wi->stack; - wi->stack = wf->next; - workdir_iterator__free_frame(wf); - git_ignore__pop_dir(&wi->ignores); - } - wi->depth = 0; + while (fi->stack != NULL && fi->stack->next != NULL) + fs_iterator__pop_frame(fi, fi->stack, false); + fi->depth = 0; if (iterator__reset_range(self, start, end) < 0) return -1; - workdir_iterator__seek_frame_start(wi, wi->stack); + fs_iterator__seek_frame_start(fi, fi->stack); - return workdir_iterator__update_entry(wi); + return fs_iterator__update_entry(fi); } -static void workdir_iterator__free(git_iterator *self) +static void fs_iterator__free(git_iterator *self) { - workdir_iterator *wi = (workdir_iterator *)self; + fs_iterator *fi = (fs_iterator *)self; - while (wi->stack != NULL) { - workdir_iterator_frame *wf = wi->stack; - wi->stack = wf->next; - workdir_iterator__free_frame(wf); - } + while (fi->stack != NULL) + fs_iterator__pop_frame(fi, fi->stack, true); - git_ignore__free(&wi->ignores); - git_buf_free(&wi->path); + git_buf_free(&fi->path); } -static int workdir_iterator__update_entry(workdir_iterator *wi) +static int fs_iterator__update_entry(fs_iterator *fi) { - int error = 0; git_path_with_stat *ps = - git_vector_get(&wi->stack->entries, wi->stack->index); + git_vector_get(&fi->stack->entries, fi->stack->index); - git_buf_truncate(&wi->path, wi->root_len); - memset(&wi->entry, 0, sizeof(wi->entry)); + git_buf_truncate(&fi->path, fi->root_len); + memset(&fi->entry, 0, sizeof(fi->entry)); if (!ps) return 0; + if (git_buf_put(&fi->path, ps->path, ps->path_len) < 0) + return -1; + if (iterator__past_end(fi, fi->path.ptr + fi->root_len)) + return 0; - /* skip over .git entries */ - if (path_is_dotgit(ps)) - return workdir_iterator__advance(NULL, (git_iterator *)wi); + fi->entry.path = ps->path; + git_index_entry__init_from_stat(&fi->entry, &ps->st); + + /* need different mode here to keep directories during iteration */ + fi->entry.mode = git_futils_canonical_mode(ps->st.st_mode); + + /* allow wrapper to check/update the entry (can force skip) */ + if (fi->update_entry_cb && + fi->update_entry_cb(fi) == GIT_ENOTFOUND) + return fs_iterator__advance_over(NULL, (git_iterator *)fi); + + /* if this is a tree and trees aren't included, then skip */ + if (fi->entry.mode == GIT_FILEMODE_TREE && !iterator__include_trees(fi)) + return git_iterator_advance(NULL, (git_iterator *)fi); + + return 0; +} + +static int fs_iterator__initialize( + git_iterator **out, fs_iterator *fi, const char *root) +{ + int error; - if (git_buf_put(&wi->path, ps->path, ps->path_len) < 0) + if (git_buf_sets(&fi->path, root) < 0 || git_path_to_dir(&fi->path) < 0) { + git__free(fi); return -1; + } + fi->root_len = fi->path.size; - if (iterator__past_end(wi, wi->path.ptr + wi->root_len)) - return 0; + if ((error = fs_iterator__expand_dir(fi)) == GIT_ENOTFOUND) { + giterr_clear(); + error = 0; + } + if (error) { + git_iterator_free((git_iterator *)fi); + fi = NULL; + } - wi->entry.path = ps->path; + *out = (git_iterator *)fi; + return error; +} - wi->is_ignored = -1; +int git_iterator_for_filesystem( + git_iterator **out, + const char *root, + git_iterator_flag_t flags, + const char *start, + const char *end) +{ + fs_iterator *fi = git__calloc(1, sizeof(fs_iterator)); + GITERR_CHECK_ALLOC(fi); - git_index_entry__init_from_stat(&wi->entry, &ps->st); + ITERATOR_BASE_INIT(fi, fs, FS, NULL); - /* need different mode here to keep directories during iteration */ - wi->entry.mode = git_futils_canonical_mode(ps->st.st_mode); + if ((flags & GIT_ITERATOR_IGNORE_CASE) != 0) + fi->base.flags |= GIT_ITERATOR_IGNORE_CASE; - /* if this is a file type we don't handle, treat as ignored */ - if (wi->entry.mode == 0) { - wi->is_ignored = 1; - return 0; + return fs_iterator__initialize(out, fi, root); +} + + +typedef struct { + fs_iterator fi; + git_ignores ignores; + int is_ignored; +} workdir_iterator; + +GIT_INLINE(bool) workdir_path_is_dotgit(const git_buf *path) +{ + size_t len; + + if (!path || (len = path->size) < 4) + return false; + + if (path->ptr[len - 1] == '/') + len--; + + if (tolower(path->ptr[len - 1]) != 't' || + tolower(path->ptr[len - 2]) != 'i' || + tolower(path->ptr[len - 3]) != 'g' || + tolower(path->ptr[len - 4]) != '.') + return false; + + return (len == 4 || path->ptr[len - 5] == '/'); +} + +static int workdir_iterator__enter_dir(fs_iterator *fi) +{ + /* only push new ignores if this is not top level directory */ + if (fi->stack->next != NULL) { + workdir_iterator *wi = (workdir_iterator *)fi; + ssize_t slash_pos = git_buf_rfind_next(&fi->path, '/'); + + (void)git_ignore__push_dir(&wi->ignores, &fi->path.ptr[slash_pos + 1]); } - /* if this isn't a tree, then we're done */ - if (wi->entry.mode != GIT_FILEMODE_TREE) - return 0; + return 0; +} - /* detect submodules */ - error = git_submodule_lookup(NULL, wi->base.repo, wi->entry.path); - if (error == GIT_ENOTFOUND) - giterr_clear(); +static int workdir_iterator__leave_dir(fs_iterator *fi) +{ + workdir_iterator *wi = (workdir_iterator *)fi; + git_ignore__pop_dir(&wi->ignores); + return 0; +} - if (error == GIT_EEXISTS) /* if contains .git, treat as untracked submod */ - error = 0; +static int workdir_iterator__update_entry(fs_iterator *fi) +{ + int error = 0; + workdir_iterator *wi = (workdir_iterator *)fi; + + /* skip over .git entries */ + if (workdir_path_is_dotgit(&fi->path)) + return GIT_ENOTFOUND; + + /* reset is_ignored since we haven't checked yet */ + wi->is_ignored = -1; - /* if submodule, mark as GITLINK and remove trailing slash */ - if (!error) { - size_t len = strlen(wi->entry.path); - assert(wi->entry.path[len - 1] == '/'); - wi->entry.path[len - 1] = '\0'; - wi->entry.mode = S_IFGITLINK; + /* check if apparent tree entries are actually submodules */ + if (fi->entry.mode != GIT_FILEMODE_TREE) return 0; + + error = git_submodule_lookup(NULL, fi->base.repo, fi->entry.path); + if (error < 0) + giterr_clear(); + + /* mark submodule (or any dir with .git) as GITLINK and remove slash */ + if (!error || error == GIT_EEXISTS) { + fi->entry.mode = S_IFGITLINK; + fi->entry.path[strlen(fi->entry.path) - 1] = '\0'; } - if (iterator__include_trees(wi)) - return 0; + return 0; +} - return workdir_iterator__advance(NULL, (git_iterator *)wi); +static void workdir_iterator__free(git_iterator *self) +{ + workdir_iterator *wi = (workdir_iterator *)self; + fs_iterator__free(self); + git_ignore__free(&wi->ignores); } int git_iterator_for_workdir( - git_iterator **iter, + git_iterator **out, git_repository *repo, git_iterator_flag_t flags, const char *start, @@ -1182,38 +1254,28 @@ int git_iterator_for_workdir( int error; workdir_iterator *wi; - assert(iter && repo); + if (git_repository__ensure_not_bare(repo, "scan working directory") < 0) + return GIT_EBAREREPO; - if ((error = git_repository__ensure_not_bare( - repo, "scan working directory")) < 0) - return error; + /* initialize as an fs iterator then do overrides */ + wi = git__calloc(1, sizeof(workdir_iterator)); + GITERR_CHECK_ALLOC(wi); + ITERATOR_BASE_INIT((&wi->fi), fs, FS, repo); - ITERATOR_BASE_INIT(wi, workdir, WORKDIR, repo); - - if ((error = iterator__update_ignore_case((git_iterator *)wi, flags)) < 0) - goto fail; + wi->fi.base.type = GIT_ITERATOR_TYPE_WORKDIR; + wi->fi.cb.free = workdir_iterator__free; + wi->fi.enter_dir_cb = workdir_iterator__enter_dir; + wi->fi.leave_dir_cb = workdir_iterator__leave_dir; + wi->fi.update_entry_cb = workdir_iterator__update_entry; - if (git_buf_sets(&wi->path, git_repository_workdir(repo)) < 0 || - git_path_to_dir(&wi->path) < 0 || - git_ignore__for_path(repo, "", &wi->ignores) < 0) + if ((error = iterator__update_ignore_case((git_iterator *)wi, flags)) < 0 || + (error = git_ignore__for_path(repo, "", &wi->ignores)) < 0) { - git__free(wi); - return -1; - } - wi->root_len = wi->path.size; - - if ((error = workdir_iterator__expand_dir(wi)) < 0) { - if (error != GIT_ENOTFOUND) - goto fail; - giterr_clear(); + git_iterator_free((git_iterator *)wi); + return error; } - *iter = (git_iterator *)wi; - return 0; - -fail: - git_iterator_free((git_iterator *)wi); - return error; + return fs_iterator__initialize(out, &wi->fi, git_repository_workdir(repo)); } @@ -1315,7 +1377,8 @@ bool git_iterator_current_is_ignored(git_iterator *iter) if (wi->is_ignored != -1) return (bool)(wi->is_ignored != 0); - if (git_ignore__lookup(&wi->ignores, wi->entry.path, &wi->is_ignored) < 0) + if (git_ignore__lookup( + &wi->ignores, wi->fi.entry.path, &wi->is_ignored) < 0) wi->is_ignored = true; return (bool)wi->is_ignored; @@ -1340,10 +1403,10 @@ int git_iterator_current_workdir_path(git_buf **path, git_iterator *iter) { workdir_iterator *wi = (workdir_iterator *)iter; - if (iter->type != GIT_ITERATOR_TYPE_WORKDIR || !wi->entry.path) + if (iter->type != GIT_ITERATOR_TYPE_WORKDIR || !wi->fi.entry.path) *path = NULL; else - *path = &wi->path; + *path = &wi->fi.path; return 0; } diff --git a/src/iterator.h b/src/iterator.h index 4a4e6a9d8..7998f7c6b 100644 --- a/src/iterator.h +++ b/src/iterator.h @@ -19,6 +19,7 @@ typedef enum { GIT_ITERATOR_TYPE_TREE = 1, GIT_ITERATOR_TYPE_INDEX = 2, GIT_ITERATOR_TYPE_WORKDIR = 3, + GIT_ITERATOR_TYPE_FS = 4, } git_iterator_type_t; typedef enum { @@ -88,6 +89,16 @@ extern int git_iterator_for_workdir( const char *start, const char *end); +/* for filesystem iterators, you have to explicitly pass in the ignore_case + * behavior that you desire + */ +extern int git_iterator_for_filesystem( + git_iterator **out, + const char *root, + git_iterator_flag_t flags, + const char *start, + const char *end); + extern void git_iterator_free(git_iterator *iter); /* Return a git_index_entry structure for the current value the iterator @@ -8,6 +8,7 @@ #include "common.h" #include <zlib.h> #include "git2/object.h" +#include "git2/sys/odb_backend.h" #include "fileops.h" #include "hash.h" #include "odb.h" @@ -407,6 +408,27 @@ int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority) return add_backend_internal(odb, backend, priority, true, 0); } +size_t git_odb_num_backends(git_odb *odb) +{ + assert(odb); + return odb->backends.length; +} + +int git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos) +{ + backend_internal *internal; + + assert(odb && odb); + internal = git_vector_get(&odb->backends, pos); + + if (internal && internal->backend) { + *out = internal->backend; + return 0; + } + + return GIT_ENOTFOUND; +} + static int add_default_backends( git_odb *db, const char *objects_dir, bool as_alternates, int alternate_depth) diff --git a/src/odb_loose.c b/src/odb_loose.c index 68083f7fd..e78172cf6 100644 --- a/src/odb_loose.c +++ b/src/odb_loose.c @@ -8,7 +8,7 @@ #include "common.h" #include <zlib.h> #include "git2/object.h" -#include "git2/oid.h" +#include "git2/sys/odb_backend.h" #include "fileops.h" #include "hash.h" #include "odb.h" diff --git a/src/odb_pack.c b/src/odb_pack.c index 7240a4ac7..773e14974 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -8,7 +8,8 @@ #include "common.h" #include <zlib.h> #include "git2/repository.h" -#include "git2/oid.h" +#include "git2/indexer.h" +#include "git2/sys/odb_backend.h" #include "fileops.h" #include "hash.h" #include "odb.h" diff --git a/src/refdb.c b/src/refdb.c index d9b73c6e7..33a1934d1 100644 --- a/src/refdb.c +++ b/src/refdb.c @@ -7,15 +7,16 @@ #include "common.h" #include "posix.h" + #include "git2/object.h" #include "git2/refs.h" #include "git2/refdb.h" +#include "git2/sys/refdb_backend.h" + #include "hash.h" #include "refdb.h" #include "refs.h" -#include "git2/refdb_backend.h" - int git_refdb_new(git_refdb **out, git_repository *repo) { git_refdb *db; @@ -45,7 +46,7 @@ int git_refdb_open(git_refdb **out, git_repository *repo) return -1; /* Add the default (filesystem) backend */ - if (git_refdb_backend_fs(&dir, repo, db) < 0) { + if (git_refdb_backend_fs(&dir, repo) < 0) { git_refdb_free(db); return -1; } @@ -57,15 +58,19 @@ int git_refdb_open(git_refdb **out, git_repository *repo) return 0; } -int git_refdb_set_backend(git_refdb *db, git_refdb_backend *backend) +static void refdb_free_backend(git_refdb *db) { if (db->backend) { - if(db->backend->free) + if (db->backend->free) db->backend->free(db->backend); else git__free(db->backend); } +} +int git_refdb_set_backend(git_refdb *db, git_refdb_backend *backend) +{ + refdb_free_backend(db); db->backend = backend; return 0; @@ -74,23 +79,16 @@ int git_refdb_set_backend(git_refdb *db, git_refdb_backend *backend) int git_refdb_compress(git_refdb *db) { assert(db); - - if (db->backend->compress) { + + if (db->backend->compress) return db->backend->compress(db->backend); - } - + return 0; } static void refdb_free(git_refdb *db) { - if (db->backend) { - if(db->backend->free) - db->backend->free(db->backend); - else - git__free(db->backend); - } - + refdb_free_backend(db); git__free(db); } @@ -111,9 +109,19 @@ int git_refdb_exists(int *exists, git_refdb *refdb, const char *ref_name) int git_refdb_lookup(git_reference **out, git_refdb *db, const char *ref_name) { - assert(db && db->backend && ref_name); + git_reference *ref; + int error; + + assert(db && db->backend && out && ref_name); - return db->backend->lookup(out, db->backend, ref_name); + if (!(error = db->backend->lookup(&ref, db->backend, ref_name))) { + ref->db = db; + *out = ref; + } else { + *out = NULL; + } + + return error; } int git_refdb_foreach( diff --git a/src/refdb.h b/src/refdb.h index 0969711b9..047113ac8 100644 --- a/src/refdb.h +++ b/src/refdb.h @@ -41,6 +41,6 @@ int git_refdb_foreach_glob( int git_refdb_write(git_refdb *refdb, const git_reference *ref); -int git_refdb_delete(struct git_refdb *refdb, const git_reference *ref); +int git_refdb_delete(git_refdb *refdb, const git_reference *ref); #endif diff --git a/src/refdb_fs.c b/src/refdb_fs.c index 784749fd3..443871005 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -18,7 +18,8 @@ #include <git2/tag.h> #include <git2/object.h> #include <git2/refdb.h> -#include <git2/refdb_backend.h> +#include <git2/sys/refdb_backend.h> +#include <git2/sys/refs.h> GIT__USE_STRMAP; @@ -42,7 +43,6 @@ typedef struct refdb_fs_backend { git_repository *repo; const char *path; - git_refdb *refdb; git_refcache refcache; } refdb_fs_backend; @@ -62,7 +62,7 @@ static int reference_read( /* Determine the full path of the file */ if (git_buf_joinpath(&path, repo_path, ref_name) < 0) return -1; - + result = git_futils_readbuffer_updated(file_content, path.ptr, mtime, NULL, updated); git_buf_free(&path); @@ -175,7 +175,7 @@ static int packed_load(refdb_fs_backend *backend) ref_cache->packfile = git_strmap_alloc(); GITERR_CHECK_ALLOC(ref_cache->packfile); } - + result = reference_read(&packfile, &ref_cache->packfile_time, backend->path, GIT_PACKEDREFS_FILE, &updated); @@ -193,7 +193,7 @@ static int packed_load(refdb_fs_backend *backend) if (result < 0) return -1; - + if (!updated) return 0; @@ -430,12 +430,12 @@ static int loose_lookup( goto done; } - *out = git_reference__alloc_symbolic(backend->refdb, ref_name, target); + *out = git_reference__alloc_symbolic(ref_name, target); } else { if ((error = loose_parse_oid(&oid, &ref_file)) < 0) goto done; - - *out = git_reference__alloc(backend->refdb, ref_name, &oid, NULL); + + *out = git_reference__alloc(ref_name, &oid, NULL); } if (*out == NULL) @@ -456,19 +456,19 @@ static int packed_map_entry( if (packed_load(backend) < 0) return -1; - + /* Look up on the packfile */ packfile_refs = backend->refcache.packfile; *pos = git_strmap_lookup_index(packfile_refs, ref_name); - + if (!git_strmap_valid_index(packfile_refs, *pos)) { giterr_set(GITERR_REFERENCE, "Reference '%s' not found", ref_name); return GIT_ENOTFOUND; } *entry = git_strmap_value_at(packfile_refs, *pos); - + return 0; } @@ -480,14 +480,14 @@ static int packed_lookup( struct packref *entry; khiter_t pos; int error = 0; - + if ((error = packed_map_entry(&entry, &pos, backend, ref_name)) < 0) return error; - if ((*out = git_reference__alloc(backend->refdb, ref_name, + if ((*out = git_reference__alloc(ref_name, &entry->oid, &entry->peel)) == NULL) return -1; - + return 0; } @@ -583,7 +583,7 @@ static int refdb_fs_backend__foreach( git_buf refs_path = GIT_BUF_INIT; const char *ref_name; void *ref = NULL; - + GIT_UNUSED(ref); assert(_backend); @@ -591,7 +591,7 @@ static int refdb_fs_backend__foreach( if (packed_load(backend) < 0) return -1; - + /* list all the packed references first */ if (list_type & GIT_REF_OID) { git_strmap_foreach(backend->refcache.packfile, ref_name, ref, { @@ -925,7 +925,7 @@ static int refdb_fs_backend__delete( repo = backend->repo; /* If a loose reference exists, remove it from the filesystem */ - + if (git_buf_joinpath(&loose_path, repo->path_repository, ref->name) < 0) return -1; @@ -933,7 +933,7 @@ static int refdb_fs_backend__delete( error = p_unlink(loose_path.ptr); loose_deleted = 1; } - + git_buf_free(&loose_path); if (error != 0) @@ -947,7 +947,7 @@ static int refdb_fs_backend__delete( error = packed_write(backend); } - + if (pack_error == GIT_ENOTFOUND) error = loose_deleted ? 0 : GIT_ENOTFOUND; else @@ -999,8 +999,7 @@ static void refdb_fs_backend__free(git_refdb_backend *_backend) int git_refdb_backend_fs( git_refdb_backend **backend_out, - git_repository *repository, - git_refdb *refdb) + git_repository *repository) { refdb_fs_backend *backend; @@ -1009,7 +1008,6 @@ int git_refdb_backend_fs( backend->repo = repository; backend->path = repository->path_repository; - backend->refdb = refdb; backend->parent.exists = &refdb_fs_backend__exists; backend->parent.lookup = &refdb_fs_backend__lookup; diff --git a/src/refs.c b/src/refs.c index 29d1c4fa9..9c6684a5a 100644 --- a/src/refs.c +++ b/src/refs.c @@ -19,7 +19,7 @@ #include <git2/branch.h> #include <git2/refs.h> #include <git2/refdb.h> -#include <git2/refdb_backend.h> +#include <git2/sys/refs.h> GIT__USE_STRMAP; @@ -31,7 +31,7 @@ enum { GIT_PACKREF_WAS_LOOSE = 2 }; -static git_reference *alloc_ref(git_refdb *refdb, const char *name) +static git_reference *alloc_ref(const char *name) { git_reference *ref; size_t namelen = strlen(name); @@ -39,22 +39,19 @@ static git_reference *alloc_ref(git_refdb *refdb, const char *name) if ((ref = git__calloc(1, sizeof(git_reference) + namelen + 1)) == NULL) return NULL; - ref->db = refdb; memcpy(ref->name, name, namelen + 1); return ref; } git_reference *git_reference__alloc_symbolic( - git_refdb *refdb, - const char *name, - const char *target) + const char *name, const char *target) { git_reference *ref; - assert(refdb && name && target); + assert(name && target); - ref = alloc_ref(refdb, name); + ref = alloc_ref(name); if (!ref) return NULL; @@ -69,16 +66,15 @@ git_reference *git_reference__alloc_symbolic( } git_reference *git_reference__alloc( - git_refdb *refdb, const char *name, const git_oid *oid, const git_oid *peel) { git_reference *ref; - assert(refdb && name && oid); + assert(name && oid); - ref = alloc_ref(refdb, name); + ref = alloc_ref(name); if (!ref) return NULL; @@ -258,10 +254,10 @@ int git_reference_lookup_resolved( max_nesting = MAX_NESTING_LEVEL; else if (max_nesting < 0) max_nesting = DEFAULT_NESTING_LEVEL; - + strncpy(scan_name, name, GIT_REFNAME_MAX); scan_type = GIT_REF_SYMBOLIC; - + if ((error = git_repository_refdb__weakptr(&refdb, repo)) < 0) return -1; @@ -279,7 +275,7 @@ int git_reference_lookup_resolved( if ((error = git_refdb_lookup(&ref, refdb, scan_name)) < 0) return error; - + scan_type = ref->type; } @@ -357,7 +353,7 @@ static int reference__create( git_refdb *refdb; git_reference *ref = NULL; int error = 0; - + if (ref_out) *ref_out = NULL; @@ -368,18 +364,19 @@ static int reference__create( if (oid != NULL) { assert(symbolic == NULL); - ref = git_reference__alloc(refdb, name, oid, NULL); + ref = git_reference__alloc(name, oid, NULL); } else { - ref = git_reference__alloc_symbolic(refdb, name, symbolic); + ref = git_reference__alloc_symbolic(name, symbolic); } - + GITERR_CHECK_ALLOC(ref); + ref->db = refdb; if ((error = git_refdb_write(refdb, ref)) < 0) { git_reference_free(ref); return error; } - + if (ref_out == NULL) git_reference_free(ref); else @@ -399,17 +396,17 @@ int git_reference_create( int error = 0; assert(repo && name && oid); - + /* Sanity check the reference being created - target must exist. */ if ((error = git_repository_odb__weakptr(&odb, repo)) < 0) return error; - + if (!git_odb_exists(odb, oid)) { giterr_set(GITERR_REFERENCE, "Target OID for the reference doesn't exist on the repository"); return -1; } - + return reference__create(ref_out, repo, name, oid, NULL, force); } @@ -424,7 +421,7 @@ int git_reference_symbolic_create( int error = 0; assert(repo && name && target); - + if ((error = git_reference__normalize_name_lax( normalized, sizeof(normalized), target)) < 0) return error; @@ -438,7 +435,7 @@ int git_reference_set_target( const git_oid *id) { assert(out && ref && id); - + if (ref->type != GIT_REF_OID) { giterr_set(GITERR_REFERENCE, "Cannot set OID on symbolic reference"); return -1; @@ -453,13 +450,13 @@ int git_reference_symbolic_set_target( const char *target) { assert(out && ref && target); - + if (ref->type != GIT_REF_SYMBOLIC) { giterr_set(GITERR_REFERENCE, "Cannot set symbolic target on a direct reference"); return -1; } - + return git_reference_symbolic_create(out, ref->db->repo, ref->name, target, 1); } @@ -475,7 +472,7 @@ int git_reference_rename( git_reference *result = NULL; int error = 0; int reference_has_log; - + *out = NULL; normalization_flags = ref->type == GIT_REF_SYMBOLIC ? @@ -490,10 +487,9 @@ int git_reference_rename( * Create the new reference. */ if (ref->type == GIT_REF_OID) { - result = git_reference__alloc(ref->db, new_name, - &ref->target.oid, &ref->peel); + result = git_reference__alloc(new_name, &ref->target.oid, &ref->peel); } else if (ref->type == GIT_REF_SYMBOLIC) { - result = git_reference__alloc_symbolic(ref->db, new_name, ref->target.symbolic); + result = git_reference__alloc_symbolic(new_name, ref->target.symbolic); } else { assert(0); } @@ -501,6 +497,8 @@ int git_reference_rename( if (result == NULL) return -1; + result->db = ref->db; + /* Check if we have to update HEAD. */ if ((error = git_branch_is_head(ref)) < 0) goto on_error; @@ -510,11 +508,11 @@ int git_reference_rename( /* Now delete the old ref and save the new one. */ if ((error = git_refdb_delete(ref->db, ref)) < 0) goto on_error; - + /* Save the new reference. */ if ((error = git_refdb_write(ref->db, result)) < 0) goto rollback; - + /* Update HEAD it was poiting to the reference being renamed. */ if (should_head_be_updated && (error = git_repository_set_head(ref->db->repo, new_name)) < 0) { giterr_set(GITERR_REFERENCE, "Failed to update HEAD after renaming reference"); @@ -548,7 +546,7 @@ int git_reference_resolve(git_reference **ref_out, const git_reference *ref) switch (git_reference_type(ref)) { case GIT_REF_OID: return git_reference_lookup(ref_out, ref->db->repo, ref->name); - + case GIT_REF_SYMBOLIC: return git_reference_lookup_resolved(ref_out, ref->db->repo, ref->target.symbolic, -1); @@ -847,7 +845,7 @@ static int reference__update_terminal( if (nesting > MAX_NESTING_LEVEL) return GIT_ENOTFOUND; - + error = git_reference_lookup(&ref, repo, ref_name); /* If we haven't found the reference at all, create a new reference. */ @@ -855,10 +853,10 @@ static int reference__update_terminal( giterr_clear(); return git_reference_create(NULL, repo, ref_name, oid, 0); } - + if (error < 0) return error; - + /* If the ref is a symbolic reference, follow its target. */ if (git_reference_type(ref) == GIT_REF_SYMBOLIC) { error = reference__update_terminal(repo, git_reference_symbolic_target(ref), oid, @@ -868,7 +866,7 @@ static int reference__update_terminal( git_reference_free(ref); error = git_reference_create(NULL, repo, ref_name, oid, 1); } - + return error; } diff --git a/src/repository.c b/src/repository.c index 64ab2f4db..a16f69da4 100644 --- a/src/repository.c +++ b/src/repository.c @@ -9,6 +9,7 @@ #include "git2/object.h" #include "git2/refdb.h" +#include "git2/sys/repository.h" #include "common.h" #include "repository.h" @@ -129,6 +130,12 @@ static git_repository *repository_alloc(void) return repo; } +int git_repository_new(git_repository **out) +{ + *out = repository_alloc(); + return 0; +} + static int load_config_data(git_repository *repo) { int is_bare; diff --git a/src/revparse.c b/src/revparse.c index 74635ed04..8a22a04f3 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -16,7 +16,7 @@ static int disambiguate_refname(git_reference **out, git_repository *repo, const char *refname) { - int error, i; + int error = 0, i; bool fallbackmode = true; git_reference *ref; git_buf refnamebuf = GIT_BUF_INIT, name = GIT_BUF_INIT; diff --git a/src/submodule.c b/src/submodule.c index 2fdaf2f77..0a22e3b13 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -7,6 +7,7 @@ #include "common.h" #include "git2/config.h" +#include "git2/sys/config.h" #include "git2/types.h" #include "git2/repository.h" #include "git2/index.h" @@ -13,6 +13,7 @@ #include "git2/object.h" #include "git2/repository.h" #include "git2/signature.h" +#include "git2/odb_backend.h" void git_tag__free(git_tag *tag) { diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 8acedeb49..90851980c 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -5,6 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ #include "git2.h" +#include "git2/odb_backend.h" #include "smart.h" #include "refs.h" diff --git a/src/unix/posix.h b/src/unix/posix.h index f4886c5d1..9c9f837b9 100644 --- a/src/unix/posix.h +++ b/src/unix/posix.h @@ -21,6 +21,8 @@ /* The OpenBSD realpath function behaves differently */ #if !defined(__OpenBSD__) # define p_realpath(p, po) realpath(p, po) +#else +char *p_realpath(const char *, char *); #endif #define p_vsnprintf(b, c, f, a) vsnprintf(b, c, f, a) diff --git a/src/util.h b/src/util.h index c0f271997..af3ef0b46 100644 --- a/src/util.h +++ b/src/util.h @@ -7,6 +7,8 @@ #ifndef INCLUDE_util_h__ #define INCLUDE_util_h__ +#include "common.h" + #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) #define bitsizeof(x) (CHAR_BIT * sizeof(x)) #define MSB(x, bits) ((x) & (~0ULL << (bitsizeof(x) - (bits)))) |