Jump to: navigation, search

This code was used for the review of memchr :

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>

void fail(const char *format, ...)
{
    va_list arguments;
    va_start(arguments, format);
    fprintf(stderr, "Error: ");
    vfprintf(stderr, format, arguments);
    fputc('\n', stderr);
    perror("perror output");
    exit(EXIT_FAILURE);
}

void *clc_memchr(const void *s, int c, size_t n)
{
    unsigned char *p = (unsigned char*)s;
    while( n-- )
        if( *p != (unsigned char)c )
            p++;
        else
            return p;
    return 0;
}

int urandom_fd;

void generate_random_bytes(void *buffer, size_t size)
{
    read(urandom_fd, buffer, size);
}

int main()
{
    srand(time(NULL));

    urandom_fd = open("/dev/urandom", O_RDONLY);

    unsigned char *buffer = malloc(64);
    if (!buffer)
	fail("malloc failed");

    memset(buffer, 10, 64);
    if (clc_memchr(buffer, 5, 0) != NULL)
	fail("memchr bad 1");

    if (clc_memchr(buffer, 10, 0) != NULL)
	fail("memchr bad 2");

    free(buffer);

    size_t buffer_size_limit = 10000;
    buffer = malloc(buffer_size_limit);

    if (!buffer)
	fail("malloc failed");

    for (size_t i = 1; i < buffer_size_limit; ++i)
    {
	generate_random_bytes(buffer, i);
	unsigned char searched_character;
	generate_random_bytes(&searched_character, sizeof(searched_character));

	if (clc_memchr(buffer, searched_character, i) != memchr(buffer, searched_character, i))
	    fail("clc_memchr did not have the same behaviour as the standard memchr");
    }

    buffer_size_limit = 25000;
    buffer = realloc(buffer, buffer_size_limit);

    if (!buffer)
	fail("realloc failed");

    for (size_t i = 1; i < buffer_size_limit; ++i)
    {
	unsigned char value = i % UCHAR_MAX;
	unsigned char searched_value = (i % UCHAR_MAX) + 1;
	memset(buffer, value, i);

	if (clc_memchr(buffer, searched_value, i) != NULL)
	    fail("clc_memchr found a value where there was none");

	if (i >= 2)
	{
	    buffer[0] = searched_value;
	    if (clc_memchr(buffer, searched_value, i) != &buffer[0])
		fail("clc_memchr failed to find the first element in the buffer");

	    buffer[0] = value;
	    buffer[i - 1] = searched_value;

	    if (clc_memchr(buffer, searched_value, i) != &buffer[i - 1])
		fail("clc_memchr failed to find the last element in the buffer");
	}
    }

    free(buffer);

    return 0;
}
Personal tools