mirror of
https://github.com/autc04/Retro68.git
synced 2024-09-08 20:55:01 +00:00
286 lines
6.9 KiB
C
286 lines
6.9 KiB
C
|
/*
|
||
|
* Copyright (c) 2011 ARM Ltd
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions
|
||
|
* are met:
|
||
|
* 1. Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in the
|
||
|
* documentation and/or other materials provided with the distribution.
|
||
|
* 3. The name of the company may not be used to endorse or promote
|
||
|
* products derived from this software without specific prior written
|
||
|
* permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||
|
* IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*/
|
||
|
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdarg.h>
|
||
|
|
||
|
/* The macro LONG_TEST controls whether a short or a more comprehensive test
|
||
|
of strcmp should be performed. */
|
||
|
#ifdef LONG_TEST
|
||
|
#ifndef BUFF_SIZE
|
||
|
#define BUFF_SIZE 1024
|
||
|
#endif
|
||
|
|
||
|
#ifndef MAX_BLOCK_SIZE
|
||
|
#define MAX_BLOCK_SIZE 128
|
||
|
#endif
|
||
|
|
||
|
#ifndef MAX_OFFSET
|
||
|
#define MAX_OFFSET 3
|
||
|
#endif
|
||
|
|
||
|
#ifndef MAX_DIFF
|
||
|
#define MAX_DIFF 8
|
||
|
#endif
|
||
|
|
||
|
#ifndef MAX_LEN
|
||
|
#define MAX_LEN 8
|
||
|
#endif
|
||
|
|
||
|
#ifndef MAX_ZEROS
|
||
|
#define MAX_ZEROS 8
|
||
|
#endif
|
||
|
#else /* not defined LONG_TEST */
|
||
|
#ifndef BUFF_SIZE
|
||
|
#define BUFF_SIZE 1024
|
||
|
#endif
|
||
|
|
||
|
#ifndef MAX_BLOCK_SIZE
|
||
|
#define MAX_BLOCK_SIZE 64
|
||
|
#endif
|
||
|
|
||
|
#ifndef MAX_OFFSET
|
||
|
#define MAX_OFFSET 3
|
||
|
#endif
|
||
|
|
||
|
#ifndef MAX_DIFF
|
||
|
#define MAX_DIFF 4
|
||
|
#endif
|
||
|
|
||
|
#ifndef MAX_LEN
|
||
|
#define MAX_LEN 4
|
||
|
#endif
|
||
|
|
||
|
#ifndef MAX_ZEROS
|
||
|
#define MAX_ZEROS 4
|
||
|
#endif
|
||
|
#endif /* not defined LONG_TEST */
|
||
|
|
||
|
#if (MAX_OFFSET >= 26)
|
||
|
#error "MAX_OFFSET >= 26"
|
||
|
#endif
|
||
|
#if (MAX_OFFSET + MAX_BLOCK_SIZE + MAX_DIFF + MAX_LEN + MAX_ZEROS >= BUFF_SIZE)
|
||
|
#error "Buffer overrun: MAX_OFFSET + MAX_BLOCK_SIZE + MAX_DIFF + MAX_LEN + MAX_ZEROS >= BUFF_SIZE."
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#define TOO_MANY_ERRORS 11
|
||
|
int errors = 0;
|
||
|
|
||
|
const char *testname = "strcmp";
|
||
|
|
||
|
void
|
||
|
print_error (char const* msg, ...)
|
||
|
{
|
||
|
errors++;
|
||
|
if (errors == TOO_MANY_ERRORS)
|
||
|
{
|
||
|
fprintf (stderr, "Too many errors.\n");
|
||
|
}
|
||
|
else if (errors < TOO_MANY_ERRORS)
|
||
|
{
|
||
|
va_list ap;
|
||
|
va_start (ap, msg);
|
||
|
vfprintf (stderr, msg, ap);
|
||
|
va_end (ap);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* Further errors omitted. */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
printbuf (char *buf, char *name)
|
||
|
{
|
||
|
int i;
|
||
|
printf ("\n %s=", name);
|
||
|
for (i = 0; i < BUFF_SIZE; i++)
|
||
|
if (buf[i] != 0)
|
||
|
printf ("(%d,%c)", i, buf[i]);
|
||
|
else
|
||
|
printf ("(%d,%s)", i, "\\0");
|
||
|
printf ("\n");
|
||
|
}
|
||
|
|
||
|
int
|
||
|
main (void)
|
||
|
{
|
||
|
/* Allocate buffers to read and write from. */
|
||
|
char src[BUFF_SIZE], dest[BUFF_SIZE];
|
||
|
|
||
|
/* Fill the source buffer with non-null values, reproducable random data. */
|
||
|
srand (1539);
|
||
|
int i, j, zeros;
|
||
|
unsigned sa;
|
||
|
unsigned da;
|
||
|
unsigned n, m, len;
|
||
|
char *p;
|
||
|
int ret;
|
||
|
|
||
|
/* Make calls to strcmp with block sizes ranging between 1 and
|
||
|
MAX_BLOCK_SIZE bytes, aligned and misaligned source and destination. */
|
||
|
for (sa = 0; sa <= MAX_OFFSET; sa++)
|
||
|
for (da = 0; da <= MAX_OFFSET; da++)
|
||
|
for (n = 1; n <= MAX_BLOCK_SIZE; n++)
|
||
|
{
|
||
|
for (m = 1; m < n + MAX_DIFF; m++)
|
||
|
for (len = 0; len < MAX_LEN; len++)
|
||
|
for (zeros = 1; zeros < MAX_ZEROS; zeros++)
|
||
|
{
|
||
|
if (n - m > MAX_DIFF)
|
||
|
continue;
|
||
|
/* Make a copy of the source. */
|
||
|
for (i = 0; i < BUFF_SIZE; i++)
|
||
|
{
|
||
|
src[i] = 'A' + (i % 26);
|
||
|
dest[i] = src[i];
|
||
|
}
|
||
|
memcpy (dest + da, src + sa, n);
|
||
|
|
||
|
/* Make src 0-terminated. */
|
||
|
p = src + sa + n - 1;
|
||
|
for (i = 0; i < zeros; i++)
|
||
|
{
|
||
|
*p++ = '\0';
|
||
|
}
|
||
|
|
||
|
/* Modify dest. */
|
||
|
p = dest + da + m - 1;
|
||
|
for (j = 0; j < len; j++)
|
||
|
*p++ = 'x';
|
||
|
/* Make dest 0-terminated. */
|
||
|
*p = '\0';
|
||
|
|
||
|
ret = strcmp (src + sa, dest + da);
|
||
|
|
||
|
/* Check return value. */
|
||
|
if (n == m)
|
||
|
{
|
||
|
if (len == 0)
|
||
|
{
|
||
|
if (ret != 0)
|
||
|
{
|
||
|
print_error ("\nFailed: after %s of %u bytes "
|
||
|
"with src_align %u and dst_align %u, "
|
||
|
"dest after %d bytes is modified for %d bytes, "
|
||
|
"return value is %d, expected 0.\n",
|
||
|
testname, n, sa, da, m, len, ret);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (ret >= 0)
|
||
|
print_error ("\nFailed: after %s of %u bytes "
|
||
|
"with src_align %u and dst_align %u, "
|
||
|
"dest after %d bytes is modified for %d bytes, "
|
||
|
"return value is %d, expected negative.\n",
|
||
|
testname, n, sa, da, m, len, ret);
|
||
|
}
|
||
|
}
|
||
|
else if (m > n)
|
||
|
{
|
||
|
if (ret >= 0)
|
||
|
{
|
||
|
print_error ("\nFailed: after %s of %u bytes "
|
||
|
"with src_align %u and dst_align %u, "
|
||
|
"dest after %d bytes is modified for %d bytes, "
|
||
|
"return value is %d, expected negative.\n",
|
||
|
testname, n, sa, da, m, len, ret);
|
||
|
}
|
||
|
}
|
||
|
else /* m < n */
|
||
|
{
|
||
|
if (len == 0)
|
||
|
{
|
||
|
if (ret <= 0)
|
||
|
print_error ("\nFailed: after %s of %u bytes "
|
||
|
"with src_align %u and dst_align %u, "
|
||
|
"dest after %d bytes is modified for %d bytes, "
|
||
|
"return value is %d, expected positive.\n",
|
||
|
testname, n, sa, da, m, len, ret);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (ret >= 0)
|
||
|
print_error ("\nFailed: after %s of %u bytes "
|
||
|
"with src_align %u and dst_align %u, "
|
||
|
"dest after %d bytes is modified for %d bytes, "
|
||
|
"return value is %d, expected negative.\n",
|
||
|
testname, n, sa, da, m, len, ret);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Check some corner cases. */
|
||
|
src[1] = 'A';
|
||
|
dest[1] = 'A';
|
||
|
src[2] = 'B';
|
||
|
dest[2] = 'B';
|
||
|
src[3] = 'C';
|
||
|
dest[3] = 'C';
|
||
|
src[4] = '\0';
|
||
|
dest[4] = '\0';
|
||
|
|
||
|
src[0] = 0xc1;
|
||
|
dest[0] = 0x41;
|
||
|
ret = strcmp (src, dest);
|
||
|
if (ret <= 0)
|
||
|
print_error ("\nFailed: expected positive, return %d\n", ret);
|
||
|
|
||
|
src[0] = 0x01;
|
||
|
dest[0] = 0x82;
|
||
|
ret = strcmp (src, dest);
|
||
|
if (ret >= 0)
|
||
|
print_error ("\nFailed: expected negative, return %d\n", ret);
|
||
|
|
||
|
dest[0] = src[0] = 'D';
|
||
|
src[3] = 0xc1;
|
||
|
dest[3] = 0x41;
|
||
|
ret = strcmp (src, dest);
|
||
|
if (ret <= 0)
|
||
|
print_error ("\nFailed: expected positive, return %d\n", ret);
|
||
|
|
||
|
src[3] = 0x01;
|
||
|
dest[3] = 0x82;
|
||
|
ret = strcmp (src, dest);
|
||
|
if (ret >= 0)
|
||
|
print_error ("\nFailed: expected negative, return %d\n", ret);
|
||
|
|
||
|
printf ("\n");
|
||
|
if (errors != 0)
|
||
|
{
|
||
|
printf ("ERROR. FAILED.\n");
|
||
|
abort ();
|
||
|
}
|
||
|
exit (0);
|
||
|
}
|