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 { ...@@ -123,12 +123,14 @@ typedef struct {
typedef enum { typedef enum {
GITERR_NOMEMORY, GITERR_NOMEMORY,
GITERR_OS, GITERR_OS,
GITERR_INVALID,
GITERR_REFERENCE, GITERR_REFERENCE,
GITERR_ZLIB, GITERR_ZLIB,
GITERR_REPOSITORY, GITERR_REPOSITORY,
GITERR_CONFIG, GITERR_CONFIG,
GITERR_REGEX, GITERR_REGEX,
GITERR_ODB GITERR_ODB,
GITERR_INDEX
} git_error_class; } git_error_class;
/** /**
......
...@@ -108,10 +108,10 @@ mode_t git_futils_canonical_mode(mode_t raw_mode) ...@@ -108,10 +108,10 @@ mode_t git_futils_canonical_mode(mode_t raw_mode)
return S_IFREG | GIT_CANONICAL_PERMS(raw_mode); return S_IFREG | GIT_CANONICAL_PERMS(raw_mode);
else if (S_ISLNK(raw_mode)) else if (S_ISLNK(raw_mode))
return S_IFLNK; return S_IFLNK;
else if (S_ISDIR(raw_mode))
return S_IFDIR;
else if (S_ISGITLINK(raw_mode)) else if (S_ISGITLINK(raw_mode))
return S_IFGITLINK; return S_IFGITLINK;
else if (S_ISDIR(raw_mode))
return S_IFDIR;
else else
return 0; return 0;
} }
......
...@@ -31,4 +31,6 @@ struct git_index { ...@@ -31,4 +31,6 @@ struct git_index {
git_vector unmerged; git_vector unmerged;
}; };
extern void git_index__init_entry_from_stat(struct stat *st, git_index_entry *entry);
#endif #endif
...@@ -395,7 +395,6 @@ static void workdir_iterator__free(git_iterator *self) ...@@ -395,7 +395,6 @@ static void workdir_iterator__free(git_iterator *self)
static int workdir_iterator__update_entry(workdir_iterator *wi) 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_path_with_stat *ps = git_vector_get(&wi->stack->entries, wi->stack->index);
git_buf_truncate(&wi->path, wi->root_len); git_buf_truncate(&wi->path, wi->root_len);
...@@ -412,24 +411,18 @@ static int workdir_iterator__update_entry(workdir_iterator *wi) ...@@ -412,24 +411,18 @@ static int workdir_iterator__update_entry(workdir_iterator *wi)
/* if there is an error processing the entry, treat as ignored */ /* if there is an error processing the entry, treat as ignored */
wi->is_ignored = 1; wi->is_ignored = 1;
/* TODO: remove shared code for struct stat conversion with index.c */ git_index__init_entry_from_stat(&ps->st, &wi->entry);
wi->entry.ctime.seconds = (git_time_t)ps->st.st_ctime;
wi->entry.mtime.seconds = (git_time_t)ps->st.st_mtime; /* need different mode here to keep directories during iteration */
wi->entry.dev = ps->st.st_rdev;
wi->entry.ino = ps->st.st_ino;
wi->entry.mode = git_futils_canonical_mode(ps->st.st_mode); 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 this is a file type we don't handle, treat as ignored */
if (wi->entry.mode == 0) if (wi->entry.mode == 0)
return 0; return 0;
/* okay, we are far enough along to look up real ignore rule */ /* 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 (git_ignore__lookup(&wi->ignores, wi->entry.path, &wi->is_ignored) < 0)
if (error < 0) return 0; /* if error, ignore it and ignore file */
return 0;
/* detect submodules */ /* detect submodules */
if (S_ISDIR(wi->entry.mode) && if (S_ISDIR(wi->entry.mode) &&
......
...@@ -13,13 +13,19 @@ ...@@ -13,13 +13,19 @@
static char to_hex[] = "0123456789abcdef"; 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) int git_oid_fromstrn(git_oid *out, const char *str, size_t length)
{ {
size_t p; size_t p;
int v; int v;
if (length < 4) 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) if (length > GIT_OID_HEXSZ)
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) ...@@ -29,7 +35,7 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length)
| git__fromhex(str[p + 1]); | git__fromhex(str[p + 1]);
if (v < 0) 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; out->id[p / 2] = (unsigned char)v;
} }
...@@ -37,7 +43,7 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length) ...@@ -37,7 +43,7 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length)
if (length % 2) { if (length % 2) {
v = (git__fromhex(str[p + 0]) << 4); v = (git__fromhex(str[p + 0]) << 4);
if (v < 0) 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; out->id[p / 2] = (unsigned char)v;
p += 2; p += 2;
...@@ -45,7 +51,7 @@ int git_oid_fromstrn(git_oid *out, const char *str, size_t length) ...@@ -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); 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) int git_oid_fromstr(git_oid *out, const char *str)
...@@ -109,8 +115,9 @@ char *git_oid_to_string(char *out, size_t n, const git_oid *oid) ...@@ -109,8 +115,9 @@ char *git_oid_to_string(char *out, size_t n, const git_oid *oid)
return out; return out;
} }
int git_oid__parse(git_oid *oid, const char **buffer_out, int git_oid__parse(
const char *buffer_end, const char *header) git_oid *oid, const char **buffer_out,
const char *buffer_end, const char *header)
{ {
const size_t sha_len = GIT_OID_HEXSZ; const size_t sha_len = GIT_OID_HEXSZ;
const size_t header_len = strlen(header); const size_t header_len = strlen(header);
...@@ -118,20 +125,20 @@ int git_oid__parse(git_oid *oid, const char **buffer_out, ...@@ -118,20 +125,20 @@ int git_oid__parse(git_oid *oid, const char **buffer_out,
const char *buffer = *buffer_out; const char *buffer = *buffer_out;
if (buffer + (header_len + sha_len + 1) > buffer_end) 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) 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') 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) if (git_oid_fromstr(oid, buffer + header_len) < 0)
return git__throw(GIT_EOBJCORRUPTED, "Failed to parse OID. Failed to generate sha1"); return -1;
*buffer_out = buffer + (header_len + sha_len + 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) 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) ...@@ -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) int git_oid_streq(const git_oid *a, const char *str)
{ {
git_oid id; git_oid id;
int error;
if ((error = git_oid_fromstr(&id, str)) < GIT_SUCCESS) if (git_oid_fromstr(&id, str) < 0)
return git__rethrow(error, "Failed to convert '%s' to oid.", str); 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) int git_oid_iszero(const git_oid *oid_a)
...@@ -216,15 +222,14 @@ struct git_oid_shorten { ...@@ -216,15 +222,14 @@ struct git_oid_shorten {
static int resize_trie(git_oid_shorten *self, size_t new_size) static int resize_trie(git_oid_shorten *self, size_t new_size)
{ {
self->nodes = git__realloc(self->nodes, new_size * sizeof(trie_node)); self->nodes = git__realloc(self->nodes, new_size * sizeof(trie_node));
if (self->nodes == NULL) GITERR_CHECK_ALLOC(self->nodes);
return GIT_ENOMEM;
if (new_size > self->size) { if (new_size > self->size) {
memset(&self->nodes[self->size], 0x0, (new_size - self->size) * sizeof(trie_node)); memset(&self->nodes[self->size], 0x0, (new_size - self->size) * sizeof(trie_node));
} }
self->size = new_size; 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) 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 ...@@ -233,7 +238,7 @@ static trie_node *push_leaf(git_oid_shorten *os, node_index idx, int push_at, co
node_index idx_leaf; node_index idx_leaf;
if (os->node_count >= os->size) { 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; return NULL;
} }
...@@ -255,13 +260,11 @@ git_oid_shorten *git_oid_shorten_new(size_t min_length) ...@@ -255,13 +260,11 @@ git_oid_shorten *git_oid_shorten_new(size_t min_length)
{ {
git_oid_shorten *os; git_oid_shorten *os;
os = git__malloc(sizeof(git_oid_shorten)); os = git__calloc(1, sizeof(git_oid_shorten));
if (os == NULL) if (os == NULL)
return NULL; return NULL;
memset(os, 0x0, sizeof(git_oid_shorten)); if (resize_trie(os, 16) < 0) {
if (resize_trie(os, 16) < GIT_SUCCESS) {
git__free(os); git__free(os);
return NULL; return NULL;
} }
...@@ -329,7 +332,7 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid) ...@@ -329,7 +332,7 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid)
node_index idx; node_index idx;
if (os->full) if (os->full)
return GIT_ENOMEM; return -1;
if (text_oid == NULL) if (text_oid == NULL)
return os->min_length; return os->min_length;
...@@ -341,8 +344,10 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid) ...@@ -341,8 +344,10 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid)
int c = git__fromhex(text_oid[i]); int c = git__fromhex(text_oid[i]);
trie_node *node; trie_node *node;
if (c == -1) if (c == -1) {
return git__throw(GIT_ENOTOID, "Failed to shorten OID. Invalid hex value"); giterr_set(GITERR_INVALID, "Unable to shorten OID - invalid hex value");
return -1;
}
node = &os->nodes[idx]; node = &os->nodes[idx];
...@@ -353,13 +358,12 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid) ...@@ -353,13 +358,12 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid)
node->tail = NULL; node->tail = NULL;
node = push_leaf(os, idx, git__fromhex(tail[0]), &tail[1]); node = push_leaf(os, idx, git__fromhex(tail[0]), &tail[1]);
if (node == NULL) GITERR_CHECK_ALLOC(node);
return GIT_ENOMEM;
} }
if (node->children[c] == 0) { if (node->children[c] == 0) {
if (push_leaf(os, idx, c, &text_oid[i + 1]) == NULL) if (push_leaf(os, idx, c, &text_oid[i + 1]) == NULL)
return GIT_ENOMEM; return -1;
break; break;
} }
......
...@@ -112,34 +112,40 @@ int git__strtol64(int64_t *result, const char *nptr, const char **endptr, int ba ...@@ -112,34 +112,40 @@ int git__strtol64(int64_t *result, const char *nptr, const char **endptr, int ba
} }
Return: Return:
if (ndig == 0) if (ndig == 0) {
return git__throw(GIT_ENOTNUM, "Failed to convert string to long. Not a number"); giterr_set(GITERR_INVALID, "Failed to convert string to long. Not a number");
return -1;
}
if (endptr) if (endptr)
*endptr = p; *endptr = p;
if (ovfl) if (ovfl) {
return git__throw(GIT_EOVERFLOW, "Failed to convert string to long. Overflow error"); giterr_set(GITERR_INVALID, "Failed to convert string to long. Overflow error");
return -1;
}
*result = neg ? -n : n; *result = neg ? -n : n;
return GIT_SUCCESS; return 0;
} }
int git__strtol32(int32_t *result, const char *nptr, const char **endptr, int base) int git__strtol32(int32_t *result, const char *nptr, const char **endptr, int base)
{ {
int error = GIT_SUCCESS; int error;
int32_t tmp_int; int32_t tmp_int;
int64_t tmp_long; 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; return error;
tmp_int = tmp_long & 0xFFFFFFFF; tmp_int = tmp_long & 0xFFFFFFFF;
if (tmp_int != tmp_long) if (tmp_int != tmp_long) {
return git__throw(GIT_EOVERFLOW, "Failed to convert. '%s' is too large", nptr); giterr_set(GITERR_INVALID, "Failed to convert. '%s' is too large", nptr);
return -1;
}
*result = tmp_int; *result = tmp_int;
return error; return error;
} }
......
...@@ -10,9 +10,9 @@ void test_core_oid__initialize(void) ...@@ -10,9 +10,9 @@ void test_core_oid__initialize(void)
void test_core_oid__streq(void) void test_core_oid__streq(void)
{ {
cl_assert(git_oid_streq(&id, str_oid) == GIT_SUCCESS); cl_assert(git_oid_streq(&id, str_oid) == 0);
cl_assert(git_oid_streq(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") == GIT_ERROR); cl_assert(git_oid_streq(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") == -1);
cl_assert(git_oid_streq(&id, "deadbeef") == GIT_ENOTOID); cl_assert(git_oid_streq(&id, "deadbeef") == -1);
cl_assert(git_oid_streq(&id, "I'm not an oid.... :)") == GIT_ENOTOID); 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