Browse Source
This commit provides basic utility classes for the reftable library. Signed-off-by: Han-Wen Nienhuys <hanwen@google.com> Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
Han-Wen Nienhuys
3 years ago
committed by
Junio C Hamano
16 changed files with 570 additions and 7 deletions
@ -0,0 +1,128 @@
@@ -0,0 +1,128 @@
|
||||
/* |
||||
Copyright 2020 Google LLC |
||||
|
||||
Use of this source code is governed by a BSD-style |
||||
license that can be found in the LICENSE file or at |
||||
https://developers.google.com/open-source/licenses/bsd |
||||
*/ |
||||
|
||||
#include "basics.h" |
||||
|
||||
void put_be24(uint8_t *out, uint32_t i) |
||||
{ |
||||
out[0] = (uint8_t)((i >> 16) & 0xff); |
||||
out[1] = (uint8_t)((i >> 8) & 0xff); |
||||
out[2] = (uint8_t)(i & 0xff); |
||||
} |
||||
|
||||
uint32_t get_be24(uint8_t *in) |
||||
{ |
||||
return (uint32_t)(in[0]) << 16 | (uint32_t)(in[1]) << 8 | |
||||
(uint32_t)(in[2]); |
||||
} |
||||
|
||||
void put_be16(uint8_t *out, uint16_t i) |
||||
{ |
||||
out[0] = (uint8_t)((i >> 8) & 0xff); |
||||
out[1] = (uint8_t)(i & 0xff); |
||||
} |
||||
|
||||
int binsearch(size_t sz, int (*f)(size_t k, void *args), void *args) |
||||
{ |
||||
size_t lo = 0; |
||||
size_t hi = sz; |
||||
|
||||
/* Invariants: |
||||
* |
||||
* (hi == sz) || f(hi) == true |
||||
* (lo == 0 && f(0) == true) || fi(lo) == false |
||||
*/ |
||||
while (hi - lo > 1) { |
||||
size_t mid = lo + (hi - lo) / 2; |
||||
|
||||
if (f(mid, args)) |
||||
hi = mid; |
||||
else |
||||
lo = mid; |
||||
} |
||||
|
||||
if (lo) |
||||
return hi; |
||||
|
||||
return f(0, args) ? 0 : 1; |
||||
} |
||||
|
||||
void free_names(char **a) |
||||
{ |
||||
char **p; |
||||
if (!a) { |
||||
return; |
||||
} |
||||
for (p = a; *p; p++) { |
||||
reftable_free(*p); |
||||
} |
||||
reftable_free(a); |
||||
} |
||||
|
||||
int names_length(char **names) |
||||
{ |
||||
char **p = names; |
||||
for (; *p; p++) { |
||||
/* empty */ |
||||
} |
||||
return p - names; |
||||
} |
||||
|
||||
void parse_names(char *buf, int size, char ***namesp) |
||||
{ |
||||
char **names = NULL; |
||||
size_t names_cap = 0; |
||||
size_t names_len = 0; |
||||
|
||||
char *p = buf; |
||||
char *end = buf + size; |
||||
while (p < end) { |
||||
char *next = strchr(p, '\n'); |
||||
if (next && next < end) { |
||||
*next = 0; |
||||
} else { |
||||
next = end; |
||||
} |
||||
if (p < next) { |
||||
if (names_len == names_cap) { |
||||
names_cap = 2 * names_cap + 1; |
||||
names = reftable_realloc( |
||||
names, names_cap * sizeof(*names)); |
||||
} |
||||
names[names_len++] = xstrdup(p); |
||||
} |
||||
p = next + 1; |
||||
} |
||||
|
||||
names = reftable_realloc(names, (names_len + 1) * sizeof(*names)); |
||||
names[names_len] = NULL; |
||||
*namesp = names; |
||||
} |
||||
|
||||
int names_equal(char **a, char **b) |
||||
{ |
||||
int i = 0; |
||||
for (; a[i] && b[i]; i++) { |
||||
if (strcmp(a[i], b[i])) { |
||||
return 0; |
||||
} |
||||
} |
||||
|
||||
return a[i] == b[i]; |
||||
} |
||||
|
||||
int common_prefix_size(struct strbuf *a, struct strbuf *b) |
||||
{ |
||||
int p = 0; |
||||
for (; p < a->len && p < b->len; p++) { |
||||
if (a->buf[p] != b->buf[p]) |
||||
break; |
||||
} |
||||
|
||||
return p; |
||||
} |
@ -0,0 +1,60 @@
@@ -0,0 +1,60 @@
|
||||
/* |
||||
Copyright 2020 Google LLC |
||||
|
||||
Use of this source code is governed by a BSD-style |
||||
license that can be found in the LICENSE file or at |
||||
https://developers.google.com/open-source/licenses/bsd |
||||
*/ |
||||
|
||||
#ifndef BASICS_H |
||||
#define BASICS_H |
||||
|
||||
/* |
||||
* miscellaneous utilities that are not provided by Git. |
||||
*/ |
||||
|
||||
#include "system.h" |
||||
|
||||
/* Bigendian en/decoding of integers */ |
||||
|
||||
void put_be24(uint8_t *out, uint32_t i); |
||||
uint32_t get_be24(uint8_t *in); |
||||
void put_be16(uint8_t *out, uint16_t i); |
||||
|
||||
/* |
||||
* find smallest index i in [0, sz) at which f(i) is true, assuming |
||||
* that f is ascending. Return sz if f(i) is false for all indices. |
||||
* |
||||
* Contrary to bsearch(3), this returns something useful if the argument is not |
||||
* found. |
||||
*/ |
||||
int binsearch(size_t sz, int (*f)(size_t k, void *args), void *args); |
||||
|
||||
/* |
||||
* Frees a NULL terminated array of malloced strings. The array itself is also |
||||
* freed. |
||||
*/ |
||||
void free_names(char **a); |
||||
|
||||
/* parse a newline separated list of names. `size` is the length of the buffer, |
||||
* without terminating '\0'. Empty names are discarded. */ |
||||
void parse_names(char *buf, int size, char ***namesp); |
||||
|
||||
/* compares two NULL-terminated arrays of strings. */ |
||||
int names_equal(char **a, char **b); |
||||
|
||||
/* returns the array size of a NULL-terminated array of strings. */ |
||||
int names_length(char **names); |
||||
|
||||
/* Allocation routines; they invoke the functions set through |
||||
* reftable_set_alloc() */ |
||||
void *reftable_malloc(size_t sz); |
||||
void *reftable_realloc(void *p, size_t sz); |
||||
void reftable_free(void *p); |
||||
void *reftable_calloc(size_t sz); |
||||
|
||||
/* Find the longest shared prefix size of `a` and `b` */ |
||||
struct strbuf; |
||||
int common_prefix_size(struct strbuf *a, struct strbuf *b); |
||||
|
||||
#endif |
@ -0,0 +1,98 @@
@@ -0,0 +1,98 @@
|
||||
/* |
||||
Copyright 2020 Google LLC |
||||
|
||||
Use of this source code is governed by a BSD-style |
||||
license that can be found in the LICENSE file or at |
||||
https://developers.google.com/open-source/licenses/bsd |
||||
*/ |
||||
|
||||
#include "system.h" |
||||
|
||||
#include "basics.h" |
||||
#include "test_framework.h" |
||||
#include "reftable-tests.h" |
||||
|
||||
struct binsearch_args { |
||||
int key; |
||||
int *arr; |
||||
}; |
||||
|
||||
static int binsearch_func(size_t i, void *void_args) |
||||
{ |
||||
struct binsearch_args *args = void_args; |
||||
|
||||
return args->key < args->arr[i]; |
||||
} |
||||
|
||||
static void test_binsearch(void) |
||||
{ |
||||
int arr[] = { 2, 4, 6, 8, 10 }; |
||||
size_t sz = ARRAY_SIZE(arr); |
||||
struct binsearch_args args = { |
||||
.arr = arr, |
||||
}; |
||||
|
||||
int i = 0; |
||||
for (i = 1; i < 11; i++) { |
||||
int res; |
||||
args.key = i; |
||||
res = binsearch(sz, &binsearch_func, &args); |
||||
|
||||
if (res < sz) { |
||||
EXPECT(args.key < arr[res]); |
||||
if (res > 0) { |
||||
EXPECT(args.key >= arr[res - 1]); |
||||
} |
||||
} else { |
||||
EXPECT(args.key == 10 || args.key == 11); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void test_names_length(void) |
||||
{ |
||||
char *a[] = { "a", "b", NULL }; |
||||
EXPECT(names_length(a) == 2); |
||||
} |
||||
|
||||
static void test_parse_names_normal(void) |
||||
{ |
||||
char in[] = "a\nb\n"; |
||||
char **out = NULL; |
||||
parse_names(in, strlen(in), &out); |
||||
EXPECT(!strcmp(out[0], "a")); |
||||
EXPECT(!strcmp(out[1], "b")); |
||||
EXPECT(!out[2]); |
||||
free_names(out); |
||||
} |
||||
|
||||
static void test_parse_names_drop_empty(void) |
||||
{ |
||||
char in[] = "a\n\n"; |
||||
char **out = NULL; |
||||
parse_names(in, strlen(in), &out); |
||||
EXPECT(!strcmp(out[0], "a")); |
||||
EXPECT(!out[1]); |
||||
free_names(out); |
||||
} |
||||
|
||||
static void test_common_prefix(void) |
||||
{ |
||||
struct strbuf s1 = STRBUF_INIT; |
||||
struct strbuf s2 = STRBUF_INIT; |
||||
strbuf_addstr(&s1, "abcdef"); |
||||
strbuf_addstr(&s2, "abc"); |
||||
EXPECT(common_prefix_size(&s1, &s2) == 3); |
||||
strbuf_release(&s1); |
||||
strbuf_release(&s2); |
||||
} |
||||
|
||||
int basics_test_main(int argc, const char *argv[]) |
||||
{ |
||||
RUN_TEST(test_common_prefix); |
||||
RUN_TEST(test_parse_names_normal); |
||||
RUN_TEST(test_parse_names_drop_empty); |
||||
RUN_TEST(test_binsearch); |
||||
RUN_TEST(test_names_length); |
||||
return 0; |
||||
} |
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
/* |
||||
Copyright 2020 Google LLC |
||||
|
||||
Use of this source code is governed by a BSD-style |
||||
license that can be found in the LICENSE file or at |
||||
https://developers.google.com/open-source/licenses/bsd |
||||
*/ |
||||
|
||||
#include "reftable-malloc.h" |
||||
|
||||
#include "basics.h" |
||||
#include "system.h" |
||||
|
||||
static void *(*reftable_malloc_ptr)(size_t sz); |
||||
static void *(*reftable_realloc_ptr)(void *, size_t); |
||||
static void (*reftable_free_ptr)(void *); |
||||
|
||||
void *reftable_malloc(size_t sz) |
||||
{ |
||||
if (reftable_malloc_ptr) |
||||
return (*reftable_malloc_ptr)(sz); |
||||
return malloc(sz); |
||||
} |
||||
|
||||
void *reftable_realloc(void *p, size_t sz) |
||||
{ |
||||
if (reftable_realloc_ptr) |
||||
return (*reftable_realloc_ptr)(p, sz); |
||||
return realloc(p, sz); |
||||
} |
||||
|
||||
void reftable_free(void *p) |
||||
{ |
||||
if (reftable_free_ptr) |
||||
reftable_free_ptr(p); |
||||
else |
||||
free(p); |
||||
} |
||||
|
||||
void *reftable_calloc(size_t sz) |
||||
{ |
||||
void *p = reftable_malloc(sz); |
||||
memset(p, 0, sz); |
||||
return p; |
||||
} |
||||
|
||||
void reftable_set_alloc(void *(*malloc)(size_t), |
||||
void *(*realloc)(void *, size_t), void (*free)(void *)) |
||||
{ |
||||
reftable_malloc_ptr = malloc; |
||||
reftable_realloc_ptr = realloc; |
||||
reftable_free_ptr = free; |
||||
} |
||||
|
||||
int hash_size(uint32_t id) |
||||
{ |
||||
switch (id) { |
||||
case 0: |
||||
case GIT_SHA1_FORMAT_ID: |
||||
return GIT_SHA1_RAWSZ; |
||||
case GIT_SHA256_FORMAT_ID: |
||||
return GIT_SHA256_RAWSZ; |
||||
} |
||||
abort(); |
||||
} |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
/* |
||||
Copyright 2020 Google LLC |
||||
|
||||
Use of this source code is governed by a BSD-style |
||||
license that can be found in the LICENSE file or at |
||||
https://developers.google.com/open-source/licenses/bsd |
||||
*/ |
||||
|
||||
#ifndef REFTABLE_H |
||||
#define REFTABLE_H |
||||
|
||||
#include <stddef.h> |
||||
|
||||
/* Overrides the functions to use for memory management. */ |
||||
void reftable_set_alloc(void *(*malloc)(size_t), |
||||
void *(*realloc)(void *, size_t), void (*free)(void *)); |
||||
|
||||
#endif |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
/* |
||||
Copyright 2020 Google LLC |
||||
|
||||
Use of this source code is governed by a BSD-style |
||||
license that can be found in the LICENSE file or at |
||||
https://developers.google.com/open-source/licenses/bsd |
||||
*/ |
||||
|
||||
#ifndef REFTABLE_TESTS_H |
||||
#define REFTABLE_TESTS_H |
||||
|
||||
int basics_test_main(int argc, const char **argv); |
||||
int block_test_main(int argc, const char **argv); |
||||
int merged_test_main(int argc, const char **argv); |
||||
int record_test_main(int argc, const char **argv); |
||||
int refname_test_main(int argc, const char **argv); |
||||
int reftable_test_main(int argc, const char **argv); |
||||
int stack_test_main(int argc, const char **argv); |
||||
int tree_test_main(int argc, const char **argv); |
||||
int reftable_dump_main(int argc, char *const *argv); |
||||
|
||||
#endif |
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
/* |
||||
Copyright 2020 Google LLC |
||||
|
||||
Use of this source code is governed by a BSD-style |
||||
license that can be found in the LICENSE file or at |
||||
https://developers.google.com/open-source/licenses/bsd |
||||
*/ |
||||
|
||||
#ifndef SYSTEM_H |
||||
#define SYSTEM_H |
||||
|
||||
/* This header glues the reftable library to the rest of Git */ |
||||
|
||||
#include "git-compat-util.h" |
||||
#include "strbuf.h" |
||||
#include "hash.h" /* hash ID, sizes.*/ |
||||
#include "dir.h" /* remove_dir_recursively, for tests.*/ |
||||
|
||||
#include <zlib.h> |
||||
|
||||
#ifdef NO_UNCOMPRESS2 |
||||
/* |
||||
* This is uncompress2, which is only available in zlib >= 1.2.9 |
||||
* (released as of early 2017) |
||||
*/ |
||||
int uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, |
||||
uLong *sourceLen); |
||||
#endif |
||||
|
||||
int hash_size(uint32_t id); |
||||
|
||||
#endif |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
/* |
||||
Copyright 2020 Google LLC |
||||
|
||||
Use of this source code is governed by a BSD-style |
||||
license that can be found in the LICENSE file or at |
||||
https://developers.google.com/open-source/licenses/bsd |
||||
*/ |
||||
|
||||
#include "system.h" |
||||
#include "test_framework.h" |
||||
|
||||
#include "basics.h" |
||||
|
||||
void set_test_hash(uint8_t *p, int i) |
||||
{ |
||||
memset(p, (uint8_t)i, hash_size(GIT_SHA1_FORMAT_ID)); |
||||
} |
||||
|
||||
ssize_t strbuf_add_void(void *b, const void *data, size_t sz) |
||||
{ |
||||
strbuf_add(b, data, sz); |
||||
return sz; |
||||
} |
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
/* |
||||
Copyright 2020 Google LLC |
||||
|
||||
Use of this source code is governed by a BSD-style |
||||
license that can be found in the LICENSE file or at |
||||
https://developers.google.com/open-source/licenses/bsd |
||||
*/ |
||||
|
||||
#ifndef TEST_FRAMEWORK_H |
||||
#define TEST_FRAMEWORK_H |
||||
|
||||
#include "system.h" |
||||
#include "reftable-error.h" |
||||
|
||||
#define EXPECT_ERR(c) \ |
||||
if (c != 0) { \ |
||||
fflush(stderr); \ |
||||
fflush(stdout); \ |
||||
fprintf(stderr, "%s: %d: error == %d (%s), want 0\n", \ |
||||
__FILE__, __LINE__, c, reftable_error_str(c)); \ |
||||
abort(); \ |
||||
} |
||||
|
||||
#define EXPECT_STREQ(a, b) \ |
||||
if (strcmp(a, b)) { \ |
||||
fflush(stderr); \ |
||||
fflush(stdout); \ |
||||
fprintf(stderr, "%s:%d: %s (%s) != %s (%s)\n", __FILE__, \ |
||||
__LINE__, #a, a, #b, b); \ |
||||
abort(); \ |
||||
} |
||||
|
||||
#define EXPECT(c) \ |
||||
if (!(c)) { \ |
||||
fflush(stderr); \ |
||||
fflush(stdout); \ |
||||
fprintf(stderr, "%s: %d: failed assertion %s\n", __FILE__, \ |
||||
__LINE__, #c); \ |
||||
abort(); \ |
||||
} |
||||
|
||||
#define RUN_TEST(f) \ |
||||
fprintf(stderr, "running %s\n", #f); \ |
||||
fflush(stderr); \ |
||||
f(); |
||||
|
||||
void set_test_hash(uint8_t *p, int i); |
||||
|
||||
/* Like strbuf_add, but suitable for passing to reftable_new_writer |
||||
*/ |
||||
ssize_t strbuf_add_void(void *b, const void *data, size_t sz); |
||||
|
||||
#endif |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
#include "reftable/reftable-tests.h" |
||||
#include "test-tool.h" |
||||
|
||||
int cmd__reftable(int argc, const char **argv) |
||||
{ |
||||
basics_test_main(argc, argv); |
||||
|
||||
return 0; |
||||
} |
Loading…
Reference in new issue