FxLibcTest/src/string/core.c

169 lines
3.9 KiB
C

#include <ft/test.h>
#include <ft/all-tests.h>
#include <gint/std/string.h>
#include "memarray.h"
//---
// Utilities
//---
/* Fill buffer with non-zero and position-sensitive data */
static void fill(uint8_t *buf, int size, int start)
{
for(int i = 0; i < size; i++) buf[i] = start+i;
}
/* Clear buffer */
static void clear(uint8_t *buf, int size)
{
for(int i = 0; i < size; i++) buf[i] = 0;
}
/* Check buffer equality (returns zero on equal) */
static int cmp(uint8_t *left, uint8_t *right, int size)
{
for(int i = 0; i < size; i++) if(left[i] != right[i]) return 1;
return 0;
}
//---
// Naive functions (baseline)
//---
static void *naive_memcpy(void *_dst, void const *_src, size_t len)
{
uint8_t *dst = _dst;
uint8_t const *src = _src;
while(len--) *dst++ = *src++;
return _dst;
}
static void *naive_memset(void *_dst, int byte, size_t len)
{
uint8_t *dst = _dst;
while(len--) *dst++ = byte;
return _dst;
}
static void *naive_memmove(void *dst, void const *src, size_t len)
{
uint8_t tmp[len];
naive_memcpy(tmp, src, len);
naive_memcpy(dst, tmp, len);
return dst;
}
static int naive_memcmp(void const *_s1, void const *_s2, size_t len)
{
uint8_t const *s1 = _s1, *s2 = _s2;
for(size_t i = 0; i < len; i++)
{
if(s1[i] != s2[i]) return s1[i] - s2[i];
}
return 0;
}
//---
// memset
//---
static int _string_memset_func(memarray_args_t const *args)
{
fill(args->full_buf1, args->full_size, 0);
fill(args->full_buf2, args->full_size, 0);
memset(args->buf1, 0, args->size);
naive_memset(args->buf2, 0, args->size);
return cmp(args->full_buf1, args->full_buf2, args->full_size);
}
uint8_t _string_memset_rc[MEMARRAY_RC_SINGLE];
static void _string_memset(ft_test *t)
{
memarray_single(_string_memset_rc, _string_memset_func);
memarray_assert(_string_memset_rc, t);
}
static jwidget *_string_memset_widget(GUNUSED ft_test *t)
{
return memarray_widget(_string_memset_rc);
}
ft_test ft_string_memset = {
.name = "Configurations of memset",
.function = _string_memset,
.widget = _string_memset_widget,
};
//---
// memcpy
//---
static int _string_memcpy_func(memarray_args_t const *args)
{
fill(args->full_left1, args->full_size, 0);
fill(args->full_left2, args->full_size, 0);
clear(args->full_right1, args->full_size);
clear(args->full_right2, args->full_size);
memcpy(args->right1, args->left1, args->size);
naive_memcpy(args->right2, args->left2, args->size);
return cmp(args->full_right1, args->full_right2, args->full_size);
}
uint8_t _string_memcpy_rc[MEMARRAY_RC_DOUBLE];
static void _string_memcpy(ft_test *t)
{
memarray_double(_string_memcpy_rc, false, _string_memcpy_func);
memarray_assert(_string_memcpy_rc, t);
}
static jwidget *_string_memcpy_widget(GUNUSED ft_test *t)
{
return memarray_widget(_string_memcpy_rc);
}
ft_test ft_string_memcpy = {
.name = "Configurations of memcpy",
.function = _string_memcpy,
.widget = _string_memcpy_widget,
};
//---
// memmove
//---
static int _string_memmove_func(memarray_args_t const *args)
{
fill(args->full_left1, args->full_size, 0);
fill(args->full_left2, args->full_size, 0);
fill(args->full_right1, args->full_size, 0);
fill(args->full_right2, args->full_size, 0);
memmove(args->right1, args->left1, args->size);
naive_memmove(args->right2, args->left2, args->size);
return cmp(args->full_right1, args->full_right2, args->full_size);
}
uint8_t _string_memmove_rc[MEMARRAY_RC_DOUBLE_OVERLAP];
static void _string_memmove(ft_test *t)
{
memarray_double(_string_memmove_rc, true, _string_memmove_func);
memarray_assert(_string_memmove_rc, t);
}
static jwidget *_string_memmove_widget(GUNUSED ft_test *t)
{
return memarray_widget(_string_memmove_rc);
}
ft_test ft_string_memmove = {
.name = "Configurations of memmove",
.function = _string_memmove,
.widget = _string_memmove_widget,
};