diff --git a/include/git2/oid.h b/include/git2/oid.h index c35acdcdc..8d93e79cf 100644 --- a/include/git2/oid.h +++ b/include/git2/oid.h @@ -201,6 +201,16 @@ GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, size_t len); */ GIT_EXTERN(int) git_oid_streq(const git_oid *id, const char *str); +/** + * Compare an oid to an hex formatted object id. + * + * @param id oid structure. + * @param str input hex string of an object id. + * @return -1 if str is not valid, <0 if id sorts before str, + * 0 if id matches str, >0 if id sorts after str. + */ +GIT_EXTERN(int) git_oid_strcmp(const git_oid *id, const char *str); + /** * Check is an oid is all zeros. * diff --git a/src/oid.c b/src/oid.c index 4b6699009..c7ce6ee50 100644 --- a/src/oid.c +++ b/src/oid.c @@ -194,14 +194,31 @@ int git_oid_ncmp(const git_oid *oid_a, const git_oid *oid_b, size_t len) return 0; } -int git_oid_streq(const git_oid *a, const char *str) +int git_oid_strcmp(const git_oid *oid_a, const char *str) { - git_oid id; + const unsigned char *a = oid_a->id; + unsigned char strval; + int hexval; - if (git_oid_fromstr(&id, str) < 0) - return -1; + for (a = oid_a->id; *str && (a - oid_a->id) < GIT_OID_RAWSZ; ++a) { + if ((hexval = git__fromhex(*str++)) < 0) + return -1; + strval = hexval << 4; + if (*str) { + if ((hexval = git__fromhex(*str++)) < 0) + return -1; + strval |= hexval; + } + if (*a != strval) + return (*a - strval); + } - return git_oid_cmp(a, &id) == 0 ? 0 : -1; + return 0; +} + +int git_oid_streq(const git_oid *oid_a, const char *str) +{ + return git_oid_strcmp(oid_a, str) == 0 ? 0 : -1; } int git_oid_iszero(const git_oid *oid_a) diff --git a/tests-clar/core/oid.c b/tests-clar/core/oid.c index d863a3e85..7ee6fb67d 100644 --- a/tests-clar/core/oid.c +++ b/tests-clar/core/oid.c @@ -16,17 +16,39 @@ void test_core_oid__initialize(void) void test_core_oid__streq(void) { - cl_assert(git_oid_streq(&id, str_oid) == 0); - cl_assert(git_oid_streq(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") == -1); + cl_assert_equal_i(0, git_oid_streq(&id, str_oid)); + cl_assert_equal_i(-1, git_oid_streq(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); - cl_assert(git_oid_streq(&id, "deadbeef") == -1); - cl_assert(git_oid_streq(&id, "I'm not an oid.... :)") == -1); - - cl_assert(git_oid_streq(&idp, "ae90f12eea699729ed0000000000000000000000") == 0); - cl_assert(git_oid_streq(&idp, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") == -1); + cl_assert_equal_i(-1, git_oid_streq(&id, "deadbeef")); + cl_assert_equal_i(-1, git_oid_streq(&id, "I'm not an oid.... :)")); - cl_assert(git_oid_streq(&idp, "deadbeef") == -1); - cl_assert(git_oid_streq(&idp, "I'm not an oid.... :)") == -1); + cl_assert_equal_i(0, git_oid_streq(&idp, "ae90f12eea699729ed0000000000000000000000")); + cl_assert_equal_i(0, git_oid_streq(&idp, "ae90f12eea699729ed")); + cl_assert_equal_i(-1, git_oid_streq(&idp, "ae90f12eea699729ed1")); + cl_assert_equal_i(-1, git_oid_streq(&idp, "ae90f12eea699729ec")); + cl_assert_equal_i(-1, git_oid_streq(&idp, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")); + + cl_assert_equal_i(-1, git_oid_streq(&idp, "deadbeef")); + cl_assert_equal_i(-1, git_oid_streq(&idp, "I'm not an oid.... :)")); +} + +void test_core_oid__strcmp(void) +{ + cl_assert_equal_i(0, git_oid_strcmp(&id, str_oid)); + cl_assert(git_oid_strcmp(&id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0); + + cl_assert(git_oid_strcmp(&id, "deadbeef") < 0); + cl_assert_equal_i(-1, git_oid_strcmp(&id, "I'm not an oid.... :)")); + + cl_assert_equal_i(0, git_oid_strcmp(&idp, "ae90f12eea699729ed0000000000000000000000")); + cl_assert_equal_i(0, git_oid_strcmp(&idp, "ae90f12eea699729ed")); + cl_assert(git_oid_strcmp(&idp, "ae90f12eea699729ed1") < 0); + cl_assert(git_oid_strcmp(&idp, "ae90f12eea699729ec") > 0); + cl_assert(git_oid_strcmp(&idp, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef") < 0); + + cl_assert(git_oid_strcmp(&idp, "deadbeef") < 0); + cl_assert_equal_i(-1, git_oid_strcmp(&idp, "I'm not an oid.... :)")); +} void test_core_oid__ncmp(void) {