diff --git a/.gitignore b/.gitignore index 5c7507cc2..0c3aa3474 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /apidocs /trash-*.exe /libgit2.pc +/config.mak *.o *.a *.exe diff --git a/Makefile b/Makefile index ff5f93335..00c5bdc46 100644 --- a/Makefile +++ b/Makefile @@ -52,6 +52,8 @@ ifneq (,$(findstring MINGW,$(uname_S))) SPARSE_FLAGS=-Wno-one-bit-signed-bitfield endif +-include config.mak + SRC_C = $(wildcard src/*.c) OS_SRC = $(wildcard src/$(OS)/*.c) SRC_C += $(OS_SRC) diff --git a/src/commit.h b/src/commit.h index 0b19f4634..05504cd34 100644 --- a/src/commit.h +++ b/src/commit.h @@ -9,7 +9,7 @@ struct git_commit { git_oid id; time_t commit_time; unsigned parsed:1, - flags:26; + flags:26; }; #endif diff --git a/src/common.h b/src/common.h index ae3a1615a..ff87c872c 100644 --- a/src/common.h +++ b/src/common.h @@ -32,43 +32,13 @@ # include # include # include +# include "msvc-compat.h" +# include "mingw-compat.h" # define snprintf _snprintf -# if defined(__DMC__) -# if defined(_M_AMD64) -# define SSIZE_T long long -# else -# define SSIZE_T int -# endif -# endif - typedef SSIZE_T ssize_t; -# if defined(_MSC_VER) -/* access() mode parameter #defines */ -# define F_OK 0 /* existence check */ -# define W_OK 2 /* write mode check */ -# define R_OK 4 /* read mode check */ -# endif - -#if defined(__MINGW32__) - -# define off_t off64_t -# define lseek _lseeki64 -# define stat _stati64 -# define fstat _fstati64 - -#elif defined(_MSC_VER) - -typedef __int64 off64_t; -# define off_t off64_t -# define lseek _lseeki64 -# define stat _stat64 -# define fstat _fstat64 - -#endif - #else # include @@ -84,13 +54,4 @@ typedef __int64 off64_t; #define GIT_PATH_MAX 4096 -#ifndef GIT_HAVE_INTTYPES_H -/* add some missing typedef's */ -typedef long int32_t; -typedef unsigned long uint32_t; - -typedef long long int64_t; -typedef unsigned long long uint64_t; -#endif - #endif /* INCLUDE_common_h__ */ diff --git a/src/fileops.h b/src/fileops.h index 53495ca95..dc5b2ce5d 100644 --- a/src/fileops.h +++ b/src/fileops.h @@ -34,7 +34,7 @@ extern int git__fsync(int fd); # ifndef GIT__WIN32_NO_HIDE_FILEOPS # define unlink(p) git__unlink(p) # define mkstemp(t) git__mkstemp(t) -# define mkdir(p,m) git__mkdir(p,m) +# define mkdir(p,m) git__mkdir(p, m) # define fsync(fd) git__fsync(fd) # endif #endif /* GIT_WIN32 */ diff --git a/src/git/commit.h b/src/git/commit.h index 979709bdb..010f258ae 100644 --- a/src/git/commit.h +++ b/src/git/commit.h @@ -25,14 +25,14 @@ typedef struct git_commit git_commit; * pool's git_odb, or if the commit is present but is * too malformed to be parsed successfully. */ -GIT_EXTERN(git_commit*) git_commit_parse(git_revpool *pool, const git_oid *id); +GIT_EXTERN(git_commit *) git_commit_parse(git_revpool *pool, const git_oid *id); /** * Get the id of a commit. * @param commit a previously parsed commit. * @return object identity for the commit. */ -GIT_EXTERN(const git_oid*) git_commit_id(git_commit *commit); +GIT_EXTERN(const git_oid *) git_commit_id(git_commit *commit); /** @} */ GIT_END_DECL diff --git a/src/git/common.h b/src/git/common.h index 375649f87..19c6a202c 100644 --- a/src/git/common.h +++ b/src/git/common.h @@ -16,8 +16,8 @@ /** Declare a public function exported for application use. */ #ifdef __GNUC__ # define GIT_EXTERN(type) extern \ - __attribute__((visibility("default"))) \ - type + __attribute__((visibility("default"))) \ + type #else # define GIT_EXTERN(type) extern type #endif @@ -25,9 +25,9 @@ /** Declare a public TLS symbol exported for application use. */ #ifdef __GNUC__ # define GIT_EXTERN_TLS(type) extern \ - __attribute__((visibility("default"))) \ - GIT_TLS \ - type + __attribute__((visibility("default"))) \ + GIT_TLS \ + type #else # define GIT_EXTERN_TLS(type) extern GIT_TLS type #endif diff --git a/src/git/oid.h b/src/git/oid.h index f3d6802e9..fe3c74b75 100644 --- a/src/git/oid.h +++ b/src/git/oid.h @@ -20,8 +20,7 @@ GIT_BEGIN_DECL #define GIT_OID_HEXSZ (GIT_OID_RAWSZ * 2) /** Unique identity of any object (commit, tree, blob, tag). */ -typedef struct -{ +typedef struct { /** raw binary formatted id */ unsigned char id[GIT_OID_RAWSZ]; } git_oid; diff --git a/src/git/revwalk.h b/src/git/revwalk.h index efaa4277c..5fac2a68a 100644 --- a/src/git/revwalk.h +++ b/src/git/revwalk.h @@ -25,7 +25,7 @@ GIT_BEGIN_DECL * @param db the database objects are read from. * @return the new traversal handle; NULL if memory is exhausted. */ -GIT_EXTERN(git_revpool*) gitrp_alloc(git_odb *db); +GIT_EXTERN(git_revpool *) gitrp_alloc(git_odb *db); /** * Reset the traversal machinary for reuse. @@ -52,7 +52,7 @@ GIT_EXTERN(void) gitrp_hide(git_revpool *pool, git_commit *commit); * @param pool the pool to pop the commit from. * @return next commit; NULL if there is no more output. */ -GIT_EXTERN(git_commit*) gitrp_next(git_revpool *pool); +GIT_EXTERN(git_commit *) gitrp_next(git_revpool *pool); /** * Free a revwalk previously allocated. diff --git a/src/mingw-compat.h b/src/mingw-compat.h new file mode 100644 index 000000000..e3805dff2 --- /dev/null +++ b/src/mingw-compat.h @@ -0,0 +1,14 @@ +#ifndef INCLUDE_mingw_compat__ +#define INCLUDE_mingw_compat__ + +#if defined(__MINGW32__) + +/* use a 64-bit file offset type */ +# define off_t off64_t +# define lseek _lseeki64 +# define stat _stati64 +# define fstat _fstati64 + +#endif + +#endif /* INCLUDE_mingw_compat__ */ diff --git a/src/msvc-compat.h b/src/msvc-compat.h new file mode 100644 index 000000000..62ab0af99 --- /dev/null +++ b/src/msvc-compat.h @@ -0,0 +1,41 @@ +#ifndef INCLUDE_msvc_compat__ +#define INCLUDE_msvc_compat__ + +#if defined(_MSC_VER) + +/* access() mode parameter #defines */ +# define F_OK 0 /* existence check */ +# define W_OK 2 /* write mode check */ +# define R_OK 4 /* read mode check */ + +/* use a 64-bit file offset type */ +typedef __int64 off64_t; +# define off_t off64_t +# define lseek _lseeki64 +# define stat _stat64 +# define fstat _fstat64 + +/* stat: file mode type testing macros */ +# define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) +# define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +# define S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFIFO) + +/* add some missing typedef's */ +typedef signed char int8_t; +typedef unsigned char uint8_t; + +typedef short int16_t; +typedef unsigned short uint16_t; + +typedef long int32_t; +typedef unsigned long uint32_t; + +typedef long long int64_t; +typedef unsigned long long uint64_t; + +typedef long long intmax_t; +typedef unsigned long long uintmax_t; + +#endif + +#endif /* INCLUDE_msvc_compat__ */ diff --git a/src/odb.c b/src/odb.c index 982cc52d0..85a843cc1 100644 --- a/src/odb.c +++ b/src/odb.c @@ -31,15 +31,31 @@ #include "odb.h" #define GIT_PACK_NAME_MAX (5 + 40 + 1) + +typedef struct { + uint32_t n; + unsigned char *oid; + off_t offset; + off_t size; +} index_entry; + struct git_pack { git_odb *db; git_lck lock; /** Functions to access idx_map. */ int (*idx_search)( - off_t *, + uint32_t *, struct git_pack *, const git_oid *); + int (*idx_search_offset)( + uint32_t *, + struct git_pack *, + off_t); + int (*idx_get)( + index_entry *, + struct git_pack *, + uint32_t n); /** The .idx file, mapped into memory. */ git_file idx_fd; @@ -49,10 +65,18 @@ struct git_pack { uint32_t *im_crc; uint32_t *im_offset32; uint32_t *im_offset64; + uint32_t *im_off_idx; + uint32_t *im_off_next; /** Number of objects in this pack. */ uint32_t obj_cnt; + /** The size of the .pack file. */ + off_t pack_size; + + /** The mtime of the .pack file. */ + time_t pack_mtime; + /** Number of git_packlist we appear in. */ unsigned int refcnt; @@ -100,7 +124,7 @@ typedef struct { /* object header data */ static struct { const char *str; /* type name string */ int loose; /* valid loose object type flag */ -} obj_type_table [] = { +} obj_type_table[] = { { "", 0 }, /* 0 = GIT_OBJ__EXT1 */ { "commit", 1 }, /* 1 = GIT_OBJ_COMMIT */ { "tree", 1 }, /* 2 = GIT_OBJ_TREE */ @@ -113,7 +137,7 @@ static struct { GIT_INLINE(uint32_t) decode32(void *b) { - return ntohl(*((uint32_t*)b)); + return ntohl(*((uint32_t *)b)); } GIT_INLINE(uint64_t) decode64(void *b) @@ -226,7 +250,7 @@ static int is_zlib_compressed_data(unsigned char *data) unsigned int w; w = ((unsigned int)(data[0]) << 8) + data[1]; - return data[0] == 0x78 && !(w %31); + return data[0] == 0x78 && !(w % 31); } static size_t get_binary_object_header(obj_hdr *hdr, gitfo_buf *obj) @@ -663,20 +687,65 @@ static int pack_openidx_map(git_pack *p) return GIT_SUCCESS; } -static int idxv1_search(off_t *out, git_pack *p, const git_oid *id) +typedef struct { + off_t offset; + uint32_t n; +} offset_idx_info; + +static int cmp_offset_idx_info(const void *lhs, const void *rhs) +{ + const offset_idx_info *a = lhs; + const offset_idx_info *b = rhs; + return (a->offset < b->offset) ? -1 : (a->offset > b->offset) ? 1 : 0; +} + +static int make_offset_index(git_pack *p, offset_idx_info *data) +{ + off_t min_off = 3 * 4, max_off = p->pack_size - GIT_OID_RAWSZ; + uint32_t *idx, *next; + uint32_t j; + + qsort(data, p->obj_cnt, sizeof(*data), cmp_offset_idx_info); + + if (data[0].offset < min_off || data[p->obj_cnt].offset > max_off) + return GIT_ERROR; + + if ((idx = git__malloc(sizeof(*idx) * (p->obj_cnt+1))) == NULL) + return GIT_ERROR; + if ((next = git__malloc(sizeof(*next) * p->obj_cnt)) == NULL) { + free(idx); + return GIT_ERROR; + } + + for (j = 0; j < p->obj_cnt+1; j++) + idx[j] = data[j].n; + + for (j = 0; j < p->obj_cnt; j++) { + assert(idx[j] < p->obj_cnt); + assert(idx[j+1] < p->obj_cnt+1); + + next[idx[j]] = idx[j+1]; + } + + p->im_off_idx = idx; + p->im_off_next = next; + return GIT_SUCCESS; +} + +static int idxv1_search(uint32_t *out, git_pack *p, const git_oid *id) { unsigned char *data = p->im_oid; - size_t lo = id->id[0] ? p->im_fanout[id->id[0] - 1] : 0; - size_t hi = p->im_fanout[id->id[0]]; + uint32_t lo = id->id[0] ? p->im_fanout[id->id[0] - 1] : 0; + uint32_t hi = p->im_fanout[id->id[0]]; do { - size_t mid = (lo + hi) >> 1; - size_t pos = 24 * mid; + uint32_t mid = (lo + hi) >> 1; + uint32_t pos = 24 * mid; int cmp = memcmp(id->id, data + pos + 4, 20); if (cmp < 0) hi = mid; else if (!cmp) { - *out = decode32(data + pos); + *out = mid; return GIT_SUCCESS; } else lo = mid + 1; @@ -684,12 +753,58 @@ static int idxv1_search(off_t *out, git_pack *p, const git_oid *id) return GIT_ENOTFOUND; } +static int idxv1_search_offset(uint32_t *out, git_pack *p, off_t offset) +{ + if (offset > 0 && offset < (p->pack_size - GIT_OID_RAWSZ)) { + uint32_t lo = 0, hi = p->obj_cnt+1; + unsigned char *data = p->im_oid; + uint32_t *idx = p->im_off_idx; + do { + uint32_t mid = (lo + hi) >> 1; + uint32_t n = idx[mid]; + uint32_t pos = n * (GIT_OID_RAWSZ + 4); + off_t here = decode32(data + pos); + if (offset < here) + hi = mid; + else if (offset == here) { + *out = n; + return GIT_SUCCESS; + } else + lo = mid + 1; + } while (lo < hi); + } + return GIT_ENOTFOUND; +} + +static int idxv1_get(index_entry *e, git_pack *p, uint32_t n) +{ + unsigned char *data = p->im_oid; + uint32_t *next = p->im_off_next; + + if (n < p->obj_cnt) { + uint32_t pos = n * (GIT_OID_RAWSZ + 4); + off_t next_off = p->pack_size - GIT_OID_RAWSZ; + e->n = n; + e->oid = data + pos + 4; + e->offset = decode32(data + pos); + if (next[n] < p->obj_cnt) { + pos = next[n] * (GIT_OID_RAWSZ + 4); + next_off = decode32(data + pos); + } + e->size = next_off - e->offset; + return GIT_SUCCESS; + } + return GIT_ENOTFOUND; +} + static int pack_openidx_v1(git_pack *p) { uint32_t *src_fanout = p->idx_map.data; uint32_t *im_fanout; + offset_idx_info *info; size_t expsz; - int j; + uint32_t j; + if ((im_fanout = git__malloc(sizeof(*im_fanout) * 256)) == NULL) return GIT_ERROR; @@ -711,29 +826,48 @@ static int pack_openidx_v1(git_pack *p) } p->idx_search = idxv1_search; + p->idx_search_offset = idxv1_search_offset; + p->idx_get = idxv1_get; p->im_fanout = im_fanout; - p->im_oid = (unsigned char*)(src_fanout + 256); + p->im_oid = (unsigned char *)(src_fanout + 256); + + if ((info = git__malloc(sizeof(*info) * (p->obj_cnt+1))) == NULL) { + free(im_fanout); + return GIT_ERROR; + } + + for (j = 0; j < p->obj_cnt; j++) { + uint32_t pos = j * (GIT_OID_RAWSZ + 4); + info[j].offset = decode32(p->im_oid + pos); + info[j].n = j; + } + info[p->obj_cnt].offset = p->pack_size - GIT_OID_RAWSZ; + info[p->obj_cnt].n = p->obj_cnt; + + if (make_offset_index(p, info)) { + free(im_fanout); + free(info); + return GIT_ERROR; + } + free(info); + return GIT_SUCCESS; } -static int idxv2_search(off_t *out, git_pack *p, const git_oid *id) +static int idxv2_search(uint32_t *out, git_pack *p, const git_oid *id) { unsigned char *data = p->im_oid; - size_t lo = id->id[0] ? p->im_fanout[id->id[0] - 1] : 0; - size_t hi = p->im_fanout[id->id[0]]; + uint32_t lo = id->id[0] ? p->im_fanout[id->id[0] - 1] : 0; + uint32_t hi = p->im_fanout[id->id[0]]; do { - size_t mid = (lo + hi) >> 1; - size_t pos = 20 * mid; + uint32_t mid = (lo + hi) >> 1; + uint32_t pos = 20 * mid; int cmp = memcmp(id->id, data + pos, 20); if (cmp < 0) hi = mid; else if (!cmp) { - uint32_t o32 = decode32(p->im_offset32 + mid); - if (o32 & 0x80000000) - *out = decode64(p->im_offset64 + 2*(o32 & ~0x80000000)); - else - *out = o32; + *out = mid; return GIT_SUCCESS; } else lo = mid + 1; @@ -741,12 +875,71 @@ static int idxv2_search(off_t *out, git_pack *p, const git_oid *id) return GIT_ENOTFOUND; } +static int idxv2_search_offset(uint32_t *out, git_pack *p, off_t offset) +{ + if (offset > 0 && offset < (p->pack_size - GIT_OID_RAWSZ)) { + uint32_t lo = 0, hi = p->obj_cnt+1; + uint32_t *idx = p->im_off_idx; + do { + uint32_t mid = (lo + hi) >> 1; + uint32_t n = idx[mid]; + uint32_t o32 = decode32(p->im_offset32 + n); + off_t here = o32; + + if (o32 & 0x80000000) { + uint32_t o64_idx = (o32 & ~0x80000000); + here = decode64(p->im_offset64 + 2*o64_idx); + } + + if (offset < here) + hi = mid; + else if (offset == here) { + *out = n; + return GIT_SUCCESS; + } else + lo = mid + 1; + } while (lo < hi); + } + return GIT_ENOTFOUND; +} + +static int idxv2_get(index_entry *e, git_pack *p, uint32_t n) +{ + unsigned char *data = p->im_oid; + uint32_t *next = p->im_off_next; + + if (n < p->obj_cnt) { + uint32_t o32 = decode32(p->im_offset32 + n); + off_t next_off = p->pack_size - GIT_OID_RAWSZ; + e->n = n; + e->oid = data + n * GIT_OID_RAWSZ; + e->offset = o32; + if (o32 & 0x80000000) { + uint32_t o64_idx = (o32 & ~0x80000000); + e->offset = decode64(p->im_offset64 + 2*o64_idx); + } + if (next[n] < p->obj_cnt) { + o32 = decode32(p->im_offset32 + next[n]); + next_off = o32; + if (o32 & 0x80000000) { + uint32_t o64_idx = (o32 & ~0x80000000); + next_off = decode64(p->im_offset64 + 2*o64_idx); + } + } + e->size = next_off - e->offset; + return GIT_SUCCESS; + } + return GIT_ENOTFOUND; +} + static int pack_openidx_v2(git_pack *p) { unsigned char *data = p->idx_map.data; - uint32_t *src_fanout = (uint32_t*)(data + 8); + uint32_t *src_fanout = (uint32_t *)(data + 8); uint32_t *im_fanout; - int j; + offset_idx_info *info; + size_t sz, o64_sz, o64_len; + uint32_t j; if ((im_fanout = git__malloc(sizeof(*im_fanout) * 256)) == NULL) return GIT_ERROR; @@ -761,52 +954,128 @@ static int pack_openidx_v2(git_pack *p) } p->obj_cnt = im_fanout[255]; + /* minimum size of .idx file (with empty 64-bit offsets table): */ + sz = 4 + 4 + 256 * 4 + p->obj_cnt * (20 + 4 + 4) + 2 * 20; + if (p->idx_map.len < sz) { + free(im_fanout); + return GIT_ERROR; + } + p->idx_search = idxv2_search; + p->idx_search_offset = idxv2_search_offset; + p->idx_get = idxv2_get; p->im_fanout = im_fanout; - p->im_oid = (unsigned char*)(src_fanout + 256); - p->im_crc = (uint32_t*)(p->im_oid + 20 * p->obj_cnt); + p->im_oid = (unsigned char *)(src_fanout + 256); + p->im_crc = (uint32_t *)(p->im_oid + 20 * p->obj_cnt); p->im_offset32 = p->im_crc + p->obj_cnt; p->im_offset64 = p->im_offset32 + p->obj_cnt; + + if ((info = git__malloc(sizeof(*info) * (p->obj_cnt+1))) == NULL) { + free(im_fanout); + return GIT_ERROR; + } + + /* check 64-bit offset table index values are within bounds */ + o64_sz = p->idx_map.len - sz; + o64_len = o64_sz / 8; + for (j = 0; j < p->obj_cnt; j++) { + uint32_t o32 = decode32(p->im_offset32 + j); + off_t offset = o32; + if (o32 & 0x80000000) { + uint32_t o64_idx = (o32 & ~0x80000000); + if (o64_idx >= o64_len) { + free(im_fanout); + free(info); + return GIT_ERROR; + } + offset = decode64(p->im_offset64 + 2*o64_idx); + } + info[j].offset = offset; + info[j].n = j; + } + info[p->obj_cnt].offset = p->pack_size - GIT_OID_RAWSZ; + info[p->obj_cnt].n = p->obj_cnt; + + if (make_offset_index(p, info)) { + free(im_fanout); + free(info); + return GIT_ERROR; + } + free(info); + + return GIT_SUCCESS; +} + +static int pack_stat(git_pack *p) +{ + char pb[GIT_PATH_MAX]; + struct stat sb; + + if (git__fmt(pb, sizeof(pb), "%s/pack/%s.pack", + p->db->objects_dir, + p->pack_name) < 0) + return GIT_ERROR; + + if (stat(pb, &sb) || !S_ISREG(sb.st_mode)) + return GIT_ERROR; + + if (sb.st_size < (3 * 4 + GIT_OID_RAWSZ)) + return GIT_ERROR; + + p->pack_size = sb.st_size; + p->pack_mtime = sb.st_mtime; + return GIT_SUCCESS; } static int pack_openidx(git_pack *p) { gitlck_lock(&p->lock); - if (p->invalid) - goto unlock_fail; + + if (p->invalid) { + gitlck_unlock(&p->lock); + return GIT_ERROR; + } + if (++p->idxcnt == 1 && !p->idx_search) { + int status, version; uint32_t *data; - if (pack_openidx_map(p)) - goto invalid_fail; + if (pack_stat(p) || pack_openidx_map(p)) { + p->invalid = 1; + p->idxcnt--; + gitlck_unlock(&p->lock); + return GIT_ERROR; + } data = p->idx_map.data; + status = GIT_SUCCESS; + version = 1; - if (decode32(&data[0]) == PACK_TOC) { - switch (decode32(&data[1])) { - case 2: - if (pack_openidx_v2(p)) - goto unmap_fail; - break; - default: - goto unmap_fail; - } - } else if (pack_openidx_v1(p)) - goto unmap_fail; + if (decode32(&data[0]) == PACK_TOC) + version = decode32(&data[1]); + + switch (version) { + case 1: + status = pack_openidx_v1(p); + break; + case 2: + status = pack_openidx_v2(p); + break; + default: + status = GIT_ERROR; + } + + if (status != GIT_SUCCESS) { + gitfo_free_map(&p->idx_map); + p->invalid = 1; + p->idxcnt--; + gitlck_unlock(&p->lock); + return status; + } } + gitlck_unlock(&p->lock); return GIT_SUCCESS; - -unmap_fail: - gitfo_free_map(&p->idx_map); - -invalid_fail: - p->invalid = 1; - p->idxcnt--; - -unlock_fail: - gitlck_unlock(&p->lock); - return GIT_ERROR; } static void pack_decidx(git_pack *p) @@ -900,7 +1169,7 @@ static int scan_one_pack(void *state, char *name) return 0; } -static git_packlist* scan_packs(git_odb *db) +static git_packlist *scan_packs(git_odb *db) { char pb[GIT_PATH_MAX]; struct scanned_pack *state = NULL, *c; @@ -954,7 +1223,7 @@ static git_packlist *packlist_get(git_odb *db) return pl; } -static int search_packs(git_pack **p, off_t *offset, git_odb *db, const git_oid *id) +static int search_packs(git_pack **p, uint32_t *n, git_odb *db, const git_oid *id) { git_packlist *pl = packlist_get(db); size_t j; @@ -965,7 +1234,7 @@ static int search_packs(git_pack **p, off_t *offset, git_odb *db, const git_oid for (j = 0; j < pl->n_packs; j++) { git_pack *pack = pl->packs[j]; - off_t pos; + uint32_t pos; int res; if (pack_openidx(pack)) @@ -974,17 +1243,17 @@ static int search_packs(git_pack **p, off_t *offset, git_odb *db, const git_oid pack_decidx(pack); if (!res) { - packlist_dec(db,pl); + packlist_dec(db, pl); if (p) *p = pack; - if (offset) - *offset = pos; + if (n) + *n = pos; return GIT_SUCCESS; } } - packlist_dec(db,pl); + packlist_dec(db, pl); return GIT_ENOTFOUND; } @@ -1109,18 +1378,18 @@ int git_odb__read_loose(git_obj *out, git_odb *db, const git_oid *id) static int read_packed(git_obj *out, git_pack *p, const git_oid *id) { - off_t pos; + uint32_t n; int res; assert(out && p && id); if (pack_openidx(p)) return GIT_ERROR; - res = p->idx_search(&pos, p, id); + res = p->idx_search(&n, p, id); pack_decidx(p); if (!res) { - /* TODO unpack object at pos */ + /* TODO unpack object */ res = GIT_ERROR; } diff --git a/src/util.h b/src/util.h index 3f541ffa6..4195117c1 100644 --- a/src/util.h +++ b/src/util.h @@ -58,6 +58,6 @@ GIT_INLINE(int) git__is_sizet(off_t p) alloc = alloc_nr(alloc); \ x = xrealloc((x), alloc * sizeof(*(x))); \ } \ - } while(0) + } while (0) #endif /* INCLUDE_util_h__ */ diff --git a/tests/Makefile b/tests/Makefile index 487addc85..beaa5abd5 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -41,6 +41,8 @@ ifneq (,$(findstring MINGW,$(uname_S))) EXTRA_LIBS += -lwsock32 -lpthread endif +-include ../config.mak + GIT_LIB = ../libgit2.a HDRS = $(wildcard ../src/*.h) diff --git a/tests/t0020-dirent.c b/tests/t0020-dirent.c index 399b7d5ee..2e6776cae 100644 --- a/tests/t0020-dirent.c +++ b/tests/t0020-dirent.c @@ -123,9 +123,9 @@ BEGIN_TEST(dot) must_pass(setup(&dot)); must_pass(gitfo_dirent(path_buffer, - sizeof(path_buffer), - one_entry, - &dot)); + sizeof(path_buffer), + one_entry, + &dot)); must_pass(check_counts(&dot)); @@ -148,9 +148,9 @@ BEGIN_TEST(sub) must_pass(setup(&sub)); must_pass(gitfo_dirent(path_buffer, - sizeof(path_buffer), - one_entry, - &sub)); + sizeof(path_buffer), + one_entry, + &sub)); must_pass(check_counts(&sub)); @@ -167,9 +167,9 @@ BEGIN_TEST(sub_slash) must_pass(setup(&sub_slash)); must_pass(gitfo_dirent(path_buffer, - sizeof(path_buffer), - one_entry, - &sub_slash)); + sizeof(path_buffer), + one_entry, + &sub_slash)); must_pass(check_counts(&sub_slash)); @@ -196,17 +196,17 @@ BEGIN_TEST(empty) must_pass(setup(&empty)); must_pass(gitfo_dirent(path_buffer, - sizeof(path_buffer), - one_entry, - &empty)); + sizeof(path_buffer), + one_entry, + &empty)); must_pass(check_counts(&empty)); /* make sure callback not called */ must_pass(gitfo_dirent(path_buffer, - sizeof(path_buffer), - dont_call_me, - &empty)); + sizeof(path_buffer), + dont_call_me, + &empty)); must_pass(knockdown(&empty)); END_TEST @@ -229,9 +229,9 @@ BEGIN_TEST(odd) must_pass(setup(&odd)); must_pass(gitfo_dirent(path_buffer, - sizeof(path_buffer), - one_entry, - &odd)); + sizeof(path_buffer), + one_entry, + &odd)); must_pass(check_counts(&odd)); diff --git a/tests/t0101-oid.c b/tests/t0101-oid.c index 16ba02bda..c867e4ff4 100644 --- a/tests/t0101-oid.c +++ b/tests/t0101-oid.c @@ -50,7 +50,7 @@ BEGIN_TEST(invalid_string_all_chars) test_die("line %d: must accept '%s'", __LINE__, in); if (memcmp(out.id, exp, sizeof(out.id))) test_die("line %d: bad parse of '%s', %x != %x", - __LINE__, in, exp[19], out.id[19]); + __LINE__, in, exp[19], out.id[19]); } else if (!git_oid_mkstr(&out, in)) test_die("line %d: must not accept '%s'", __LINE__, in); } diff --git a/tests/t0102-objtype.c b/tests/t0102-objtype.c index 425b3cd58..b42f3f731 100644 --- a/tests/t0102-objtype.c +++ b/tests/t0102-objtype.c @@ -3,19 +3,19 @@ #include BEGIN_TEST(type_to_string) - must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_BAD),"")); - must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ__EXT1),"")); - must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_COMMIT),"commit")); - must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_TREE),"tree")); - must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_BLOB),"blob")); - must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_TAG),"tag")); - must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ__EXT2),"")); - must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_OFS_DELTA),"OFS_DELTA")); - must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_REF_DELTA),"REF_DELTA")); + must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_BAD), "")); + must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ__EXT1), "")); + must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_COMMIT), "commit")); + must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_TREE), "tree")); + must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_BLOB), "blob")); + must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_TAG), "tag")); + must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ__EXT2), "")); + must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_OFS_DELTA), "OFS_DELTA")); + must_be_true(!strcmp(git_obj_type_to_string(GIT_OBJ_REF_DELTA), "REF_DELTA")); - must_be_true(!strcmp(git_obj_type_to_string(-2),"")); - must_be_true(!strcmp(git_obj_type_to_string(8),"")); - must_be_true(!strcmp(git_obj_type_to_string(1234),"")); + must_be_true(!strcmp(git_obj_type_to_string(-2), "")); + must_be_true(!strcmp(git_obj_type_to_string(8), "")); + must_be_true(!strcmp(git_obj_type_to_string(1234), "")); END_TEST BEGIN_TEST(string_to_type) diff --git a/tests/t0201-existsloose.c b/tests/t0201-existsloose.c index 76f293894..0c7fda8e4 100644 --- a/tests/t0201-existsloose.c +++ b/tests/t0201-existsloose.c @@ -37,8 +37,8 @@ BEGIN_TEST(exists_loose_one) must_be_true(git_odb_exists(db, &id)); /* Test for a non-existant object */ - must_pass(git_oid_mkstr(&id2,"8b137891791fe96927ad78e64b0aad7bded08baa")); - must_be_true(0 == git_odb_exists(db, &id2)); + must_pass(git_oid_mkstr(&id2, "8b137891791fe96927ad78e64b0aad7bded08baa")); + must_be_true(0 == git_odb_exists(db, &id2)); git_odb_close(db); must_pass(remove_object_files(odb_dir, &one)); diff --git a/tests/t0301-write.c b/tests/t0301-write.c index f161ce12c..b4440c0be 100644 --- a/tests/t0301-write.c +++ b/tests/t0301-write.c @@ -351,55 +351,54 @@ static git_obj some_obj = { static int make_odb_dir(void) { - if (gitfo_mkdir(odb_dir, 0755) < 0) { - if (errno == EEXIST) { - fprintf(stderr, "odb directory \"%s\" already exists!\n", odb_dir); - return -1; - } - fprintf(stderr, "can't make odb directory \"%s\"\n", odb_dir); - return -1; - } - - return 0; + if (gitfo_mkdir(odb_dir, 0755) < 0) { + int err = errno; + fprintf(stderr, "can't make directory \"%s\"", odb_dir); + if (err == EEXIST) + fprintf(stderr, " (already exists)"); + fprintf(stderr, "\n"); + return -1; + } + return 0; } static int remove_object_files(object_data *d) { - if (gitfo_unlink(d->file) < 0) { - fprintf(stderr, "can't delete object file \"%s\"\n", d->file); - return -1; - } - if ((gitfo_rmdir(d->dir) < 0) && (errno != ENOTEMPTY)) { - fprintf(stderr, "can't remove object directory \"%s\"\n", d->dir); - return -1; - } + if (gitfo_unlink(d->file) < 0) { + fprintf(stderr, "can't delete object file \"%s\"\n", d->file); + return -1; + } + if ((gitfo_rmdir(d->dir) < 0) && (errno != ENOTEMPTY)) { + fprintf(stderr, "can't remove directory \"%s\"\n", d->dir); + return -1; + } - if (gitfo_rmdir(odb_dir) < 0) { - fprintf(stderr, "can't remove odb directory \"%s\"\n", odb_dir); - return -1; - } + if (gitfo_rmdir(odb_dir) < 0) { + fprintf(stderr, "can't remove directory \"%s\"\n", odb_dir); + return -1; + } - return 0; + return 0; } static int check_object_files(object_data *d) { - if (gitfo_exists(d->dir) < 0) - return -1; - if (gitfo_exists(d->file) < 0) - return -1; - return 0; + if (gitfo_exists(d->dir) < 0) + return -1; + if (gitfo_exists(d->file) < 0) + return -1; + return 0; } static int cmp_objects(git_obj *o1, git_obj *o2) { - if (o1->type != o2->type) - return -1; - if (o1->len != o2->len) - return -1; - if ((o1->len > 0) && (memcmp(o1->data, o2->data, o1->len) != 0)) - return -1; - return 0; + if (o1->type != o2->type) + return -1; + if (o1->len != o2->len) + return -1; + if ((o1->len > 0) && (memcmp(o1->data, o2->data, o1->len) != 0)) + return -1; + return 0; } BEGIN_TEST(write_commit) diff --git a/tests/test_helpers.c b/tests/test_helpers.c index 6829e2c49..46a29b40d 100644 --- a/tests/test_helpers.c +++ b/tests/test_helpers.c @@ -29,66 +29,66 @@ int write_object_data(char *file, void *data, size_t len) { - git_file fd; - int ret; + git_file fd; + int ret; - if ((fd = gitfo_creat(file, S_IREAD | S_IWRITE)) < 0) - return -1; - ret = gitfo_write(fd, data, len); - gitfo_close(fd); + if ((fd = gitfo_creat(file, S_IREAD | S_IWRITE)) < 0) + return -1; + ret = gitfo_write(fd, data, len); + gitfo_close(fd); - return ret; + return ret; } int write_object_files(const char *odb_dir, object_data *d) { - if (gitfo_mkdir(odb_dir, 0755) < 0) { - if (errno == EEXIST) { - fprintf(stderr, "odb directory \"%s\" already exists!\n", odb_dir); - return -1; - } - fprintf(stderr, "can't make odb directory \"%s\"\n", odb_dir); - return -1; - } + if (gitfo_mkdir(odb_dir, 0755) < 0) { + int err = errno; + fprintf(stderr, "can't make directory \"%s\"", odb_dir); + if (err == EEXIST) + fprintf(stderr, " (already exists)"); + fprintf(stderr, "\n"); + return -1; + } - if ((gitfo_mkdir(d->dir, 0755) < 0) && (errno != EEXIST)) { - fprintf(stderr, "can't make object directory \"%s\"\n", d->dir); - return -1; - } - if (write_object_data(d->file, d->bytes, d->blen) < 0) { - fprintf(stderr, "can't write object file \"%s\"\n", d->file); - return -1; - } + if ((gitfo_mkdir(d->dir, 0755) < 0) && (errno != EEXIST)) { + fprintf(stderr, "can't make object directory \"%s\"\n", d->dir); + return -1; + } + if (write_object_data(d->file, d->bytes, d->blen) < 0) { + fprintf(stderr, "can't write object file \"%s\"\n", d->file); + return -1; + } - return 0; + return 0; } int remove_object_files(const char *odb_dir, object_data *d) { - if (gitfo_unlink(d->file) < 0) { - fprintf(stderr, "can't delete object file \"%s\"\n", d->file); - return -1; - } - if ((gitfo_rmdir(d->dir) < 0) && (errno != ENOTEMPTY)) { - fprintf(stderr, "can't remove object directory \"%s\"\n", d->dir); - return -1; - } + if (gitfo_unlink(d->file) < 0) { + fprintf(stderr, "can't delete object file \"%s\"\n", d->file); + return -1; + } + if ((gitfo_rmdir(d->dir) < 0) && (errno != ENOTEMPTY)) { + fprintf(stderr, "can't remove object directory \"%s\"\n", d->dir); + return -1; + } - if (gitfo_rmdir(odb_dir) < 0) { - fprintf(stderr, "can't remove odb directory \"%s\"\n", odb_dir); - return -1; - } + if (gitfo_rmdir(odb_dir) < 0) { + fprintf(stderr, "can't remove directory \"%s\"\n", odb_dir); + return -1; + } - return 0; + return 0; } int cmp_objects(git_obj *o, object_data *d) { - if (o->type != git_obj_string_to_type(d->type)) - return -1; - if (o->len != d->dlen) - return -1; - if ((o->len > 0) && (memcmp(o->data, d->data, o->len) != 0)) - return -1; - return 0; + if (o->type != git_obj_string_to_type(d->type)) + return -1; + if (o->len != d->dlen) + return -1; + if ((o->len > 0) && (memcmp(o->data, d->data, o->len) != 0)) + return -1; + return 0; } diff --git a/tests/test_lib.c b/tests/test_lib.c index 9475785cf..1ce3f92bf 100644 --- a/tests/test_lib.c +++ b/tests/test_lib.c @@ -26,8 +26,7 @@ #define GIT__NO_HIDE_MALLOC #include "test_lib.h" -struct test_info -{ +struct test_info { struct test_info *next; const char *test_name; const char *file_name; @@ -40,9 +39,9 @@ static struct test_info *current_test; static void show_test_result(const char *status) { fprintf(stderr, "* %-6s %5d: %s\n", - status, - current_test->line_no, - current_test->test_name); + status, + current_test->line_no, + current_test->test_name); } void test_die(const char *fmt, ...) diff --git a/tests/test_lib.h b/tests/test_lib.h index f863bba4d..78f992332 100644 --- a/tests/test_lib.h +++ b/tests/test_lib.h @@ -45,7 +45,7 @@ * @param name C symbol to assign to this test's function. */ #define BEGIN_TEST(name) \ - void testfunc__##name (void) \ + void testfunc__##name(void) \ { \ test_begin(#name, __FILE__, __LINE__); \ {