Commit 7c7ff7d1 by Russell Belfer

Migrate index, oid, and utils to new errors

This includes a few cleanups that came up while converting
these files.

This commit introduces a could new git error classes, including
the catchall class: GITERR_INVALID which I'm using as the class
for invalid and out of range values which are detected at too low
a level of library to use a higher level classification.  For
example, an overflow error in parsing an integer or a bad letter
in parsing an OID string would generate an error in this class.
parent fd771427
......@@ -123,12 +123,14 @@ typedef struct {
typedef enum {
GITERR_NOMEMORY,
GITERR_OS,
GITERR_INVALID,
GITERR_REFERENCE,
GITERR_ZLIB,
GITERR_REPOSITORY,
GITERR_CONFIG,
GITERR_REGEX,
GITERR_ODB
GITERR_ODB,
GITERR_INDEX
} git_error_class;
/**
......
......@@ -108,10 +108,10 @@ mode_t git_futils_canonical_mode(mode_t raw_mode)
return S_IFREG | GIT_CANONICAL_PERMS(raw_mode);
else if (S_ISLNK(raw_mode))
return S_IFLNK;
else if (S_ISDIR(raw_mode))
return S_IFDIR;
else if (S_ISGITLINK(raw_mode))
return S_IFGITLINK;
else if (S_ISDIR(raw_mode))
return S_IFDIR;
else
return 0;
}
......
......@@ -31,4 +31,6 @@ struct git_index {
git_vector unmerged;
};
extern void git_index__init_entry_from_stat(struct stat *st, git_index_entry *entry);
#endif
......@@ -395,7 +395,6 @@ static void workdir_iterator__free(git_iterator *self)
static int workdir_iterator__update_entry(workdir_iterator *wi)
{
int error;
git_path_with_stat *ps = git_vector_get(&wi->stack->entries, wi->stack->index);
git_buf_truncate(&wi->path, wi->root_len);
......@@ -412,24 +411,18 @@ static int workdir_iterator__update_entry(workdir_iterator *wi)
/* if there is an error processing the entry, treat as ignored */
wi->is_ignored = 1;
/* TODO: remove shared code for struct stat conversion with index.c */
wi->entry.ctime.seconds = (git_time_t)ps->st.st_ctime;
wi->entry.mtime.seconds = (git_time_t)ps->st.st_mtime;
wi->entry.dev = ps->st.st_rdev;
wi->entry.ino = ps->st.st_ino;
git_index__init_entry_from_stat(&ps->st, &wi->entry);
/* need different mode here to keep directories during iteration */
wi->entry.mode = git_futils_canonical_mode(ps->st.st_mode);
wi->entry.uid = ps->st.st_uid;
wi->entry.gid = ps->st.st_gid;
wi->entry.file_size = ps->st.st_size;
/* if this is a file type we don't handle, treat as ignored */
if (wi->entry.mode == 0)
return 0;
/* okay, we are far enough along to look up real ignore rule */
error = git_ignore__lookup(&wi->ignores, wi->entry.path, &wi->is_ignored);
if (error < 0)
return 0;
if (git_ignore__lookup(&wi->ignores, wi->entry.path, &wi->is_ignored) < 0)
return 0; /* if error, ignore it and ignore file */
/* detect submodules */
if (S_ISDIR(wi->entry.mode) &&
......
......@@ -13,13 +13,19 @@
static char to_hex[] = "0123456789abcdef";
static int oid_error_invalid(const char *msg)
{
giterr_set(GITERR_INVALID, "Unable to parse OID - %s", msg);
return -1;
}
int git_oid_fromstrn(git_oid *out, const char *str, size_t length)
{
size_t p;
int v;
if (length < 4)
return git__throw(GIT_ENOTOID, "Failed to generate sha1. Given string is too short");
return oid_error_invalid("input too short");
if (length > GIT_OID_HEXSZ)
length = GIT_OID_HEXSZ;
......@@ -29,7 +35,7 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length)
| git__fromhex(str[p + 1]);
if (v < 0)
return git__throw(GIT_ENOTOID, "Failed to generate sha1. Given string is not a valid sha1 hash");
return oid_error_invalid("contains invalid characters");
out->id[p / 2] = (unsigned char)v;
}
......@@ -37,7 +43,7 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length)
if (length % 2) {
v = (git__fromhex(str[p + 0]) << 4);
if (v < 0)
return git__throw(GIT_ENOTOID, "Failed to generate sha1. Given string is not a valid sha1 hash");
return oid_error_invalid("contains invalid characters");
out->id[p / 2] = (unsigned char)v;
p += 2;
......@@ -45,7 +51,7 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length)
memset(out->id + p / 2, 0, (GIT_OID_HEXSZ - p) / 2);
return GIT_SUCCESS;
return 0;
}
int git_oid_fromstr(git_oid *out, const char *str)
......@@ -109,7 +115,8 @@ char *git_oid_to_string(char *out, size_t n, const git_oid *oid)
return out;
}
int git_oid__parse(git_oid *oid, const char **buffer_out,
int git_oid__parse(
git_oid *oid, const char **buffer_out,
const char *buffer_end, const char *header)
{
const size_t sha_len = GIT_OID_HEXSZ;
......@@ -118,20 +125,20 @@ int git_oid__parse(git_oid *oid, const char **buffer_out,
const char *buffer = *buffer_out;
if (buffer + (header_len + sha_len + 1) > buffer_end)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse OID. Buffer too small");
return oid_error_invalid("input is too short");
if (memcmp(buffer, header, header_len) != 0)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse OID. Buffer and header do not match");
return oid_error_invalid("did not match expected header");
if (buffer[header_len + sha_len] != '\n')
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse OID. Buffer not terminated correctly");
return oid_error_invalid("not terminated correctly");
if (git_oid_fromstr(oid, buffer + header_len) < GIT_SUCCESS)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse OID. Failed to generate sha1");
if (git_oid_fromstr(oid, buffer + header_len) < 0)
return -1;
*buffer_out = buffer + (header_len + sha_len + 1);
return GIT_SUCCESS;
return 0;
}
void git_oid__writebuf(git_buf *buf, const char *header, const git_oid *oid)
......@@ -182,12 +189,11 @@ int git_oid_ncmp(const git_oid *oid_a, const git_oid *oid_b, unsigned int len)
int git_oid_streq(const git_oid *a, const char *str)
{
git_oid id;
int error;
if ((error = git_oid_fromstr(&id, str)) < GIT_SUCCESS)
return git__rethrow(error, "Failed to convert '%s' to oid.", str);
if (git_oid_fromstr(&id, str) < 0)
return -1;
return git_oid_cmp(a, &id) == 0 ? GIT_SUCCESS : GIT_ERROR;
return git_oid_cmp(a, &id) == 0 ? 0 : -1;
}
int git_oid_iszero(const git_oid *oid_a)
......@@ -216,15 +222,14 @@ struct git_oid_shorten {
static int resize_trie(git_oid_shorten *self, size_t new_size)
{
self->nodes = git__realloc(self->nodes, new_size * sizeof(trie_node));
if (self->nodes == NULL)
return GIT_ENOMEM;
GITERR_CHECK_ALLOC(self->nodes);
if (new_size > self->size) {
memset(&self->nodes[self->size], 0x0, (new_size - self->size) * sizeof(trie_node));
}
self->size = new_size;
return GIT_SUCCESS;
return 0;
}
static trie_node *push_leaf(git_oid_shorten *os, node_index idx, int push_at, const char *oid)
......@@ -233,7 +238,7 @@ static trie_node *push_leaf(git_oid_shorten *os, node_index idx, int push_at, co
node_index idx_leaf;
if (os->node_count >= os->size) {
if (resize_trie(os, os->size * 2) < GIT_SUCCESS)
if (resize_trie(os, os->size * 2) < 0)
return NULL;
}
......@@ -255,13 +260,11 @@ git_oid_shorten *git_oid_shorten_new(size_t min_length)
{
git_oid_shorten *os;
os = git__malloc(sizeof(git_oid_shorten));
os = git__calloc(1, sizeof(git_oid_shorten));
if (os == NULL)
return NULL;
memset(os, 0x0, sizeof(git_oid_shorten));
if (resize_trie(os, 16) < GIT_SUCCESS) {
if (resize_trie(os, 16) < 0) {
git__free(os);
return NULL;
}
......@@ -329,7 +332,7 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid)
node_index idx;
if (os->full)
return GIT_ENOMEM;
return -1;
if (text_oid == NULL)
return os->min_length;
......@@ -341,8 +344,10 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid)
int c = git__fromhex(text_oid[i]);
trie_node *node;
if (c == -1)
return git__throw(GIT_ENOTOID, "Failed to shorten OID. Invalid hex value");
if (c == -1) {
giterr_set(GITERR_INVALID, "Unable to shorten OID - invalid hex value");
return -1;
}
node = &os->nodes[idx];
......@@ -353,13 +358,12 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid)
node->tail = NULL;
node = push_leaf(os, idx, git__fromhex(tail[0]), &tail[1]);
if (node == NULL)
return GIT_ENOMEM;
GITERR_CHECK_ALLOC(node);
}
if (node->children[c] == 0) {
if (push_leaf(os, idx, c, &text_oid[i + 1]) == NULL)
return GIT_ENOMEM;
return -1;
break;
}
......
......@@ -112,31 +112,37 @@ int git__strtol64(int64_t *result, const char *nptr, const char **endptr, int ba
}
Return:
if (ndig == 0)
return git__throw(GIT_ENOTNUM, "Failed to convert string to long. Not a number");
if (ndig == 0) {
giterr_set(GITERR_INVALID, "Failed to convert string to long. Not a number");
return -1;
}
if (endptr)
*endptr = p;
if (ovfl)
return git__throw(GIT_EOVERFLOW, "Failed to convert string to long. Overflow error");
if (ovfl) {
giterr_set(GITERR_INVALID, "Failed to convert string to long. Overflow error");
return -1;
}
*result = neg ? -n : n;
return GIT_SUCCESS;
return 0;
}
int git__strtol32(int32_t *result, const char *nptr, const char **endptr, int base)
{
int error = GIT_SUCCESS;
int error;
int32_t tmp_int;
int64_t tmp_long;
if ((error = git__strtol64(&tmp_long, nptr, endptr, base)) < GIT_SUCCESS)
if ((error = git__strtol64(&tmp_long, nptr, endptr, base)) < 0)
return error;
tmp_int = tmp_long & 0xFFFFFFFF;
if (tmp_int != tmp_long)
return git__throw(GIT_EOVERFLOW, "Failed to convert. '%s' is too large", nptr);
if (tmp_int != tmp_long) {
giterr_set(GITERR_INVALID, "Failed to convert. '%s' is too large", nptr);
return -1;
}
*result = tmp_int;
......
......@@ -10,9 +10,9 @@ void test_core_oid__initialize(void)
void test_core_oid__streq(void)
{
cl_assert(git_oid_streq(&id, str_oid) == GIT_SUCCESS);
cl_assert(git_oid_streq(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") == GIT_ERROR);
cl_assert(git_oid_streq(&id, str_oid) == 0);
cl_assert(git_oid_streq(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") == -1);
cl_assert(git_oid_streq(&id, "deadbeef") == GIT_ENOTOID);
cl_assert(git_oid_streq(&id, "I'm not an oid.... :)") == GIT_ENOTOID);
cl_assert(git_oid_streq(&id, "deadbeef") == -1);
cl_assert(git_oid_streq(&id, "I'm not an oid.... :)") == -1);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment