mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-09 19:58:09 +00:00
Merge remote branch 'ramsay/dev'
* ramsay/dev: Add a pack index 'virtual function' to fetch an index entry Add a pack index 'virtual function' to search by file offset Change the interface of the pack index search function Add an 64-bit offset table index bounds check for v2 pack index Add a minimum size check when opening an v2 pack index file win32: Add separate MinGW and MSVC compatability header files Makefile: Add support for custom build options in config.mak file Fix some coding style issues
This commit is contained in:
commit
fb799dfe77
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
/apidocs
|
||||
/trash-*.exe
|
||||
/libgit2.pc
|
||||
/config.mak
|
||||
*.o
|
||||
*.a
|
||||
*.exe
|
||||
|
2
Makefile
2
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)
|
||||
|
@ -9,7 +9,7 @@ struct git_commit {
|
||||
git_oid id;
|
||||
time_t commit_time;
|
||||
unsigned parsed:1,
|
||||
flags:26;
|
||||
flags:26;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
43
src/common.h
43
src/common.h
@ -32,43 +32,13 @@
|
||||
# include <io.h>
|
||||
# include <direct.h>
|
||||
# include <windows.h>
|
||||
# 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 <unistd.h>
|
||||
@ -84,13 +54,4 @@ typedef __int64 off64_t;
|
||||
|
||||
#define GIT_PATH_MAX 4096
|
||||
|
||||
#ifndef GIT_HAVE_INTTYPES_H
|
||||
/* add some missing <stdint.h> 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__ */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
14
src/mingw-compat.h
Normal file
14
src/mingw-compat.h
Normal file
@ -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__ */
|
41
src/msvc-compat.h
Normal file
41
src/msvc-compat.h
Normal file
@ -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 <stdint.h> 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__ */
|
393
src/odb.c
393
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;
|
||||
}
|
||||
|
||||
|
@ -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__ */
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -3,19 +3,19 @@
|
||||
#include <git/odb.h>
|
||||
|
||||
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)
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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, ...)
|
||||
|
@ -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__); \
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user