#include <sys/cdefs.h>
#include <dlfcn.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <atf-c.h>
static char *(*strrchr_fn)(const char *, int);
ATF_TC_WITHOUT_HEAD(nul);
ATF_TC_BODY(nul, tc)
{
size_t i, j, k;
char buf[1+15+64];
buf[0] = '\0';
memset(buf + 1, '-', sizeof(buf) - 1);
for (i = 0; i < 16; i++)
for (j = 0; j < 64; j++)
for (k = j; k < 64; k++) {
buf[i + j + 1] = '\0';
buf[i + k + 1] = '\0';
ATF_CHECK_EQ(strrchr_fn(buf + i + 1, '\0'), buf + i + j + 1);
buf[i + j + 1] = '-';
buf[i + k + 1] = '-';
}
}
ATF_TC_WITHOUT_HEAD(not_found);
ATF_TC_BODY(not_found, tc)
{
size_t i, j;
char buf[1+15+64+2];
buf[0] = 'X';
memset(buf + 1, '-', sizeof(buf) - 1);
for (i = 0; i < 16; i++)
for (j = 0; j < 64; j++) {
buf[i + j + 1] = '\0';
buf[i + j + 2] = 'X';
ATF_CHECK_EQ(strrchr_fn(buf + i + 1, 'X'), NULL);
buf[i + j + 1] = '-';
buf[i + j + 2] = '-';
}
}
static void
do_found_test(char buf[], size_t first, size_t second)
{
buf[first] = 'X';
buf[second] = 'X';
ATF_CHECK_EQ(strrchr_fn(buf, 'X'), buf + second);
buf[first] = '-';
buf[second] = '-';
}
ATF_TC_WITHOUT_HEAD(found);
ATF_TC_BODY(found, tc)
{
size_t i, j, k, l;
char buf[1+15+64+2];
buf[0] = 'X';
memset(buf + 1, '-', sizeof(buf) - 1);
for (i = 0; i < 16; i++)
for (j = 0; j < 64; j++)
for (k = 0; k < j; k++)
for (l = 0; l <= k; l++) {
buf[i + j + 1] = '\0';
buf[i + j + 2] = 'X';
do_found_test(buf + i + 1, l, k);
buf[i + j + 1] = '-';
buf[i + j + 2] = '-';
}
}
static void
do_values_test(char buf[], size_t len, size_t i, int c)
{
buf[-1] = c;
buf[len] = '\0';
buf[len + 1] = 'c';
memset(buf, c == UCHAR_MAX ? c - 1 : c + 1, len);
if (i < len) {
buf[i] = c;
ATF_CHECK_EQ(strrchr_fn(buf, c), buf + i);
} else
ATF_CHECK_EQ(strrchr_fn(buf, c), c == 0 ? buf + len : NULL);
}
ATF_TC_WITHOUT_HEAD(values);
ATF_TC_BODY(values, tc)
{
size_t i, j, k;
int c;
char buf[1+15+64+2];
for (i = 0; i < 16; i++)
for (j = 0; j < 64; j++)
for (k = 0; k <= j; k++)
for (c = 0; c <= UCHAR_MAX; c++)
do_values_test(buf + i + 1, j, k, c);
}
ATF_TP_ADD_TCS(tp)
{
void *dl_handle;
dl_handle = dlopen(NULL, RTLD_LAZY);
strrchr_fn = dlsym(dl_handle, "test_strrchr");
if (strrchr_fn == NULL)
strrchr_fn = strrchr;
ATF_TP_ADD_TC(tp, nul);
ATF_TP_ADD_TC(tp, not_found);
ATF_TP_ADD_TC(tp, found);
ATF_TP_ADD_TC(tp, values);
return (atf_no_error());
}