diff options
author | René Scharfe <l.s.r@web.de> | 2016-09-25 09:15:42 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-09-25 16:44:12 -0700 |
commit | 60566cbb5890abc84fa18c56da70e35ace0b23bf (patch) | |
tree | e5d14dd403b88ba2f71baa8800ec878ba23817cb /git-compat-util.h | |
parent | a63d31b4d3640960d9a71606eee80c32459f906e (diff) | |
download | git-60566cbb5890abc84fa18c56da70e35ace0b23bf.tar.gz |
add COPY_ARRAY
Add COPY_ARRAY, a safe and convenient helper for copying arrays,
complementing ALLOC_ARRAY and REALLOC_ARRAY. Users just specify source,
destination and the number of elements; the size of an element is
inferred automatically.
It checks if the multiplication of size and element count overflows.
The inferred size is passed first to st_mult, which allows the division
there to be done at compilation time.
As a basic type safety check it makes sure the sizes of source and
destination elements are the same. That's evaluated at compilation time
as well.
COPY_ARRAY is safe to use with NULL as source pointer iff 0 elements are
to be copied. That convention is used in some cases for initializing
arrays. Raw memcpy(3) does not support it -- compilers are allowed to
assume that only valid pointers are passed to it and can optimize away
NULL checks after such a call.
Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'git-compat-util.h')
-rw-r--r-- | git-compat-util.h | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/git-compat-util.h b/git-compat-util.h index c99cddc54b..4662d0d3c4 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -785,6 +785,14 @@ extern FILE *fopen_for_writing(const char *path); #define ALLOC_ARRAY(x, alloc) (x) = xmalloc(st_mult(sizeof(*(x)), (alloc))) #define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), st_mult(sizeof(*(x)), (alloc))) +#define COPY_ARRAY(dst, src, n) copy_array((dst), (src), (n), sizeof(*(dst)) + \ + BUILD_ASSERT_OR_ZERO(sizeof(*(dst)) == sizeof(*(src)))) +static inline void copy_array(void *dst, const void *src, size_t n, size_t size) +{ + if (n) + memcpy(dst, src, st_mult(size, n)); +} + /* * These functions help you allocate structs with flex arrays, and copy * the data directly into the array. For example, if you had: |