static struct rerere_dir *find_rerere_dir(const char *hex) { unsigned char sha1[20]; struct rerere_dir *rr_dir; int pos; if (get_sha1_hex(hex, sha1)) return NULL; /* BUG */ pos = sha1_pos(sha1, rerere_dir, rerere_dir_nr, rerere_dir_sha1); if (pos < 0) { rr_dir = xmalloc(sizeof(*rr_dir)); hashcpy(rr_dir->sha1, sha1); rr_dir->status = NULL; rr_dir->status_nr = 0; rr_dir->status_alloc = 0; pos = -1 - pos; /* Make sure the array is big enough ... */ ALLOC_GROW(rerere_dir, rerere_dir_nr + 1, rerere_dir_alloc); /* ... and add it in. */ rerere_dir_nr++; MOVE_ARRAY(rerere_dir + pos + 1, rerere_dir + pos, rerere_dir_nr - pos - 1); rerere_dir[pos] = rr_dir; scan_rerere_dir(rr_dir); } return rerere_dir[pos]; }
static struct cache_tree_sub *find_subtree(struct cache_tree *it, const char *path, int pathlen, int create) { struct cache_tree_sub *down; int pos = subtree_pos(it, path, pathlen); if (0 <= pos) return it->down[pos]; if (!create) return NULL; pos = -pos-1; ALLOC_GROW(it->down, it->subtree_nr + 1, it->subtree_alloc); it->subtree_nr++; FLEX_ALLOC_MEM(down, name, path, pathlen); down->cache_tree = NULL; down->namelen = pathlen; if (pos < it->subtree_nr) MOVE_ARRAY(it->down + pos + 1, it->down + pos, it->subtree_nr - pos - 1); it->down[pos] = down; return down; }
int remove_entry_from_dir(struct ref_dir *dir, const char *refname) { int refname_len = strlen(refname); int entry_index; struct ref_entry *entry; int is_dir = refname[refname_len - 1] == '/'; if (is_dir) { /* * refname represents a reference directory. Remove * the trailing slash; otherwise we will get the * directory *representing* refname rather than the * one *containing* it. */ char *dirname = xmemdupz(refname, refname_len - 1); dir = find_containing_dir(dir, dirname, 0); free(dirname); } else { dir = find_containing_dir(dir, refname, 0); } if (!dir) return -1; entry_index = search_ref_dir(dir, refname, refname_len); if (entry_index == -1) return -1; entry = dir->entries[entry_index]; MOVE_ARRAY(&dir->entries[entry_index], &dir->entries[entry_index + 1], dir->nr - entry_index - 1); dir->nr--; if (dir->sorted > entry_index) dir->sorted--; free_ref_entry(entry); return dir->nr; }
static struct notes_merge_pair *find_notes_merge_pair_pos( struct notes_merge_pair *list, int len, struct object_id *obj, int insert_new, int *occupied) { /* * Both diff_tree_remote() and diff_tree_local() tend to process * merge_pairs in ascending order. Therefore, cache last returned * index, and search sequentially from there until the appropriate * position is found. * * Since inserts only happen from diff_tree_remote() (which mainly * _appends_), we don't care that inserting into the middle of the * list is expensive (using memmove()). */ static int last_index; int i = last_index < len ? last_index : len - 1; int prev_cmp = 0, cmp = -1; while (i >= 0 && i < len) { cmp = oidcmp(obj, &list[i].obj); if (!cmp) /* obj belongs @ i */ break; else if (cmp < 0 && prev_cmp <= 0) /* obj belongs < i */ i--; else if (cmp < 0) /* obj belongs between i-1 and i */ break; else if (cmp > 0 && prev_cmp >= 0) /* obj belongs > i */ i++; else /* if (cmp > 0) */ { /* obj belongs between i and i+1 */ i++; break; } prev_cmp = cmp; } if (i < 0) i = 0; /* obj belongs at, or immediately preceding, index i (0 <= i <= len) */ if (!cmp) *occupied = 1; else { *occupied = 0; if (insert_new && i < len) { MOVE_ARRAY(list + i + 1, list + i, len - i); memset(list + i, 0, sizeof(struct notes_merge_pair)); } } last_index = i; return list + i; }
static int do_invalidate_path(struct cache_tree *it, const char *path) { /* a/b/c * ==> invalidate self * ==> find "a", have it invalidate "b/c" * a * ==> invalidate self * ==> if "a" exists as a subtree, remove it. */ const char *slash; int namelen; struct cache_tree_sub *down; #if DEBUG fprintf(stderr, "cache-tree invalidate <%s>\n", path); #endif if (!it) return 0; slash = strchrnul(path, '/'); namelen = slash - path; it->entry_count = -1; if (!*slash) { int pos; pos = subtree_pos(it, path, namelen); if (0 <= pos) { cache_tree_free(&it->down[pos]->cache_tree); free(it->down[pos]); /* 0 1 2 3 4 5 * ^ ^subtree_nr = 6 * pos * move 4 and 5 up one place (2 entries) * 2 = 6 - 3 - 1 = subtree_nr - pos - 1 */ MOVE_ARRAY(it->down + pos, it->down + pos + 1, it->subtree_nr - pos - 1); it->subtree_nr--; } return 1; } down = find_subtree(it, path, namelen, 0); if (down) do_invalidate_path(down->cache_tree, slash + 1); return 1; }
int parse_options_end(struct parse_opt_ctx_t *ctx) { MOVE_ARRAY(ctx->out + ctx->cpidx, ctx->argv, ctx->argc); ctx->out[ctx->cpidx + ctx->argc] = NULL; return ctx->cpidx + ctx->argc; }