hjl / source-git / glibc

Forked from source-git/glibc 3 years ago
Clone

Blame string/tester.c

Packit 6c4009
/* Tester for string functions.
Packit 6c4009
   Copyright (C) 1995-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#ifndef _GNU_SOURCE
Packit 6c4009
#define _GNU_SOURCE
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Make sure we don't test the optimized inline functions if we want to
Packit 6c4009
   test the real implementation.  */
Packit 6c4009
#if !defined DO_STRING_INLINES
Packit 6c4009
#undef __USE_STRING_INLINES
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include <errno.h>
Packit 6c4009
#include <stdio.h>
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
#include <strings.h>
Packit 6c4009
#include <fcntl.h>
Packit 6c4009
#include <libc-diag.h>
Packit 6c4009
Packit 6c4009
Packit 6c4009
#define	STREQ(a, b)	(strcmp((a), (b)) == 0)
Packit 6c4009
Packit 6c4009
const char *it = "<UNSET>";	/* Routine name for message routines. */
Packit 6c4009
size_t errors = 0;
Packit 6c4009
Packit 6c4009
/* Complain if condition is not true.  */
Packit 6c4009
static void
Packit 6c4009
check (int thing, int number)
Packit 6c4009
{
Packit 6c4009
  if (!thing)
Packit 6c4009
    {
Packit 6c4009
      printf ("%s flunked test %d\n", it, number);
Packit 6c4009
      ++errors;
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* Complain if first two args don't strcmp as equal.  */
Packit 6c4009
static void
Packit 6c4009
equal (const char *a, const char *b, int number)
Packit 6c4009
{
Packit 6c4009
  check (a != NULL && b != NULL && STREQ (a, b), number);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
char one[50];
Packit 6c4009
char two[50];
Packit 6c4009
char *cp;
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strcmp (void)
Packit 6c4009
{
Packit 6c4009
  it = "strcmp";
Packit 6c4009
  check (strcmp ("", "") == 0, 1);		/* Trivial case. */
Packit 6c4009
  check (strcmp ("a", "a") == 0, 2);		/* Identity. */
Packit 6c4009
  check (strcmp ("abc", "abc") == 0, 3);	/* Multicharacter. */
Packit 6c4009
  check (strcmp ("abc", "abcd") < 0, 4);	/* Length mismatches. */
Packit 6c4009
  check (strcmp ("abcd", "abc") > 0, 5);
Packit 6c4009
  check (strcmp ("abcd", "abce") < 0, 6);	/* Honest miscompares. */
Packit 6c4009
  check (strcmp ("abce", "abcd") > 0, 7);
Packit 6c4009
  check (strcmp ("a\203", "a") > 0, 8);		/* Tricky if char signed. */
Packit 6c4009
  check (strcmp ("a\203", "a\003") > 0, 9);
Packit 6c4009
Packit 6c4009
  {
Packit 6c4009
    char buf1[0x40], buf2[0x40];
Packit 6c4009
    int i, j;
Packit 6c4009
    for (i=0; i < 0x10; i++)
Packit 6c4009
      for (j = 0; j < 0x10; j++)
Packit 6c4009
	{
Packit 6c4009
	  int k;
Packit 6c4009
	  for (k = 0; k < 0x3f; k++)
Packit 6c4009
	    {
Packit 6c4009
	      buf1[k] = '0' ^ (k & 4);
Packit 6c4009
	      buf2[k] = '4' ^ (k & 4);
Packit 6c4009
	    }
Packit 6c4009
	  buf1[i] = buf1[0x3f] = 0;
Packit 6c4009
	  buf2[j] = buf2[0x3f] = 0;
Packit 6c4009
	  for (k = 0; k < 0xf; k++)
Packit 6c4009
	    {
Packit 6c4009
	      int cnum = 0x10+0x10*k+0x100*j+0x1000*i;
Packit 6c4009
	      check (strcmp (buf1+i,buf2+j) == 0, cnum);
Packit 6c4009
	      buf1[i+k] = 'A' + i + k;
Packit 6c4009
	      buf1[i+k+1] = 0;
Packit 6c4009
	      check (strcmp (buf1+i,buf2+j) > 0, cnum+1);
Packit 6c4009
	      check (strcmp (buf2+j,buf1+i) < 0, cnum+2);
Packit 6c4009
	      buf2[j+k] = 'B' + i + k;
Packit 6c4009
	      buf2[j+k+1] = 0;
Packit 6c4009
	      check (strcmp (buf1+i,buf2+j) < 0, cnum+3);
Packit 6c4009
	      check (strcmp (buf2+j,buf1+i) > 0, cnum+4);
Packit 6c4009
	      buf2[j+k] = 'A' + i + k;
Packit 6c4009
	      buf1[i] = 'A' + i + 0x80;
Packit 6c4009
	      check (strcmp (buf1+i,buf2+j) > 0, cnum+5);
Packit 6c4009
	      check (strcmp (buf2+j,buf1+i) < 0, cnum+6);
Packit 6c4009
	      buf1[i] = 'A' + i;
Packit 6c4009
	    }
Packit 6c4009
	}
Packit 6c4009
  }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#define SIMPLE_COPY(fn, n, str, ntest) \
Packit 6c4009
  do {									      \
Packit 6c4009
    int __n;								      \
Packit 6c4009
    char *cp;								      \
Packit 6c4009
    for (__n = 0; __n < (int) sizeof (one); ++__n)			      \
Packit 6c4009
      one[__n] = 'Z';							      \
Packit 6c4009
    fn (one, str);							      \
Packit 6c4009
    for (cp = one, __n = 0; __n < n; ++__n, ++cp)			      \
Packit 6c4009
      check (*cp == '0' + (n % 10), ntest);				      \
Packit 6c4009
    check (*cp == '\0', ntest);						      \
Packit 6c4009
  } while (0)
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strcpy (void)
Packit 6c4009
{
Packit 6c4009
  int i;
Packit 6c4009
  it = "strcpy";
Packit 6c4009
  check (strcpy (one, "abcd") == one, 1); /* Returned value. */
Packit 6c4009
  equal (one, "abcd", 2);		/* Basic test. */
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "x");
Packit 6c4009
  equal (one, "x", 3);			/* Writeover. */
Packit 6c4009
  equal (one+2, "cd", 4);		/* Wrote too much? */
Packit 6c4009
Packit 6c4009
  (void) strcpy (two, "hi there");
Packit 6c4009
  (void) strcpy (one, two);
Packit 6c4009
  equal (one, "hi there", 5);		/* Basic test encore. */
Packit 6c4009
  equal (two, "hi there", 6);		/* Stomped on source? */
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "");
Packit 6c4009
  equal (one, "", 7);			/* Boundary condition. */
Packit 6c4009
Packit 6c4009
  for (i = 0; i < 16; i++)
Packit 6c4009
    {
Packit 6c4009
      (void) strcpy (one + i, "hi there");	/* Unaligned destination. */
Packit 6c4009
      equal (one + i, "hi there", 8 + (i * 2));
Packit 6c4009
      (void) strcpy (two, one + i);		/* Unaligned source. */
Packit 6c4009
      equal (two, "hi there", 9 + (i * 2));
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  SIMPLE_COPY(strcpy, 0, "", 41);
Packit 6c4009
  SIMPLE_COPY(strcpy, 1, "1", 42);
Packit 6c4009
  SIMPLE_COPY(strcpy, 2, "22", 43);
Packit 6c4009
  SIMPLE_COPY(strcpy, 3, "333", 44);
Packit 6c4009
  SIMPLE_COPY(strcpy, 4, "4444", 45);
Packit 6c4009
  SIMPLE_COPY(strcpy, 5, "55555", 46);
Packit 6c4009
  SIMPLE_COPY(strcpy, 6, "666666", 47);
Packit 6c4009
  SIMPLE_COPY(strcpy, 7, "7777777", 48);
Packit 6c4009
  SIMPLE_COPY(strcpy, 8, "88888888", 49);
Packit 6c4009
  SIMPLE_COPY(strcpy, 9, "999999999", 50);
Packit 6c4009
  SIMPLE_COPY(strcpy, 10, "0000000000", 51);
Packit 6c4009
  SIMPLE_COPY(strcpy, 11, "11111111111", 52);
Packit 6c4009
  SIMPLE_COPY(strcpy, 12, "222222222222", 53);
Packit 6c4009
  SIMPLE_COPY(strcpy, 13, "3333333333333", 54);
Packit 6c4009
  SIMPLE_COPY(strcpy, 14, "44444444444444", 55);
Packit 6c4009
  SIMPLE_COPY(strcpy, 15, "555555555555555", 56);
Packit 6c4009
  SIMPLE_COPY(strcpy, 16, "6666666666666666", 57);
Packit 6c4009
Packit 6c4009
  /* Simple test using implicitly coerced `void *' arguments.  */
Packit 6c4009
  const void *src = "frobozz";
Packit 6c4009
  void *dst = one;
Packit 6c4009
  check (strcpy (dst, src) == dst, 1);
Packit 6c4009
  equal (dst, "frobozz", 2);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_stpcpy (void)
Packit 6c4009
{
Packit 6c4009
  it = "stpcpy";
Packit 6c4009
  check ((stpcpy (one, "a") - one) == 1, 1);
Packit 6c4009
  equal (one, "a", 2);
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "ab") - one) == 2, 3);
Packit 6c4009
  equal (one, "ab", 4);
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "abc") - one) == 3, 5);
Packit 6c4009
  equal (one, "abc", 6);
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "abcd") - one) == 4, 7);
Packit 6c4009
  equal (one, "abcd", 8);
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "abcde") - one) == 5, 9);
Packit 6c4009
  equal (one, "abcde", 10);
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "abcdef") - one) == 6, 11);
Packit 6c4009
  equal (one, "abcdef", 12);
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "abcdefg") - one) == 7, 13);
Packit 6c4009
  equal (one, "abcdefg", 14);
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "abcdefgh") - one) == 8, 15);
Packit 6c4009
  equal (one, "abcdefgh", 16);
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "abcdefghi") - one) == 9, 17);
Packit 6c4009
  equal (one, "abcdefghi", 18);
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "x") - one) == 1, 19);
Packit 6c4009
  equal (one, "x", 20);			/* Writeover. */
Packit 6c4009
  equal (one+2, "cdefghi", 21);		/* Wrote too much? */
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "xx") - one) == 2, 22);
Packit 6c4009
  equal (one, "xx", 23);		/* Writeover. */
Packit 6c4009
  equal (one+3, "defghi", 24);		/* Wrote too much? */
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "xxx") - one) == 3, 25);
Packit 6c4009
  equal (one, "xxx", 26);		/* Writeover. */
Packit 6c4009
  equal (one+4, "efghi", 27);		/* Wrote too much? */
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "xxxx") - one) == 4, 28);
Packit 6c4009
  equal (one, "xxxx", 29);		/* Writeover. */
Packit 6c4009
  equal (one+5, "fghi", 30);		/* Wrote too much? */
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "xxxxx") - one) == 5, 31);
Packit 6c4009
  equal (one, "xxxxx", 32);		/* Writeover. */
Packit 6c4009
  equal (one+6, "ghi", 33);		/* Wrote too much? */
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "xxxxxx") - one) == 6, 34);
Packit 6c4009
  equal (one, "xxxxxx", 35);		/* Writeover. */
Packit 6c4009
  equal (one+7, "hi", 36);		/* Wrote too much? */
Packit 6c4009
Packit 6c4009
  check ((stpcpy (one, "xxxxxxx") - one) == 7, 37);
Packit 6c4009
  equal (one, "xxxxxxx", 38);		/* Writeover. */
Packit 6c4009
  equal (one+8, "i", 39);		/* Wrote too much? */
Packit 6c4009
Packit 6c4009
  check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40);
Packit 6c4009
  equal (one, "abc", 41);
Packit 6c4009
  equal (one + 4, "xxx", 42);
Packit 6c4009
Packit 6c4009
  SIMPLE_COPY(stpcpy, 0, "", 43);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 1, "1", 44);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 2, "22", 45);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 3, "333", 46);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 4, "4444", 47);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 5, "55555", 48);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 6, "666666", 49);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 7, "7777777", 50);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 8, "88888888", 51);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 9, "999999999", 52);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 10, "0000000000", 53);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 11, "11111111111", 54);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 12, "222222222222", 55);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 13, "3333333333333", 56);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 14, "44444444444444", 57);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 15, "555555555555555", 58);
Packit 6c4009
  SIMPLE_COPY(stpcpy, 16, "6666666666666666", 59);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_stpncpy (void)
Packit 6c4009
{
Packit 6c4009
  it = "stpncpy";
Packit 6c4009
  memset (one, 'x', sizeof (one));
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (8, 0)
Packit 6c4009
  /* GCC 8 warns about stpncpy truncating output; this is deliberately
Packit 6c4009
     tested here.  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
Packit 6c4009
#endif
Packit 6c4009
  check (stpncpy (one, "abc", 2) == one + 2, 1);
Packit 6c4009
  check (stpncpy (one, "abc", 3) == one + 3, 2);
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
  check (stpncpy (one, "abc", 4) == one + 3, 3);
Packit 6c4009
  check (one[3] == '\0' && one[4] == 'x', 4);
Packit 6c4009
  check (stpncpy (one, "abcd", 5) == one + 4, 5);
Packit 6c4009
  check (one[4] == '\0' && one[5] == 'x', 6);
Packit 6c4009
  check (stpncpy (one, "abcd", 6) == one + 4, 7);
Packit 6c4009
  check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strcat (void)
Packit 6c4009
{
Packit 6c4009
  it = "strcat";
Packit 6c4009
  (void) strcpy (one, "ijk");
Packit 6c4009
  check (strcat (one, "lmn") == one, 1); /* Returned value. */
Packit 6c4009
  equal (one, "ijklmn", 2);		/* Basic test. */
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "x");
Packit 6c4009
  (void) strcat (one, "yz");
Packit 6c4009
  equal (one, "xyz", 3);			/* Writeover. */
Packit 6c4009
  equal (one+4, "mn", 4);			/* Wrote too much? */
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "gh");
Packit 6c4009
  (void) strcpy (two, "ef");
Packit 6c4009
  (void) strcat (one, two);
Packit 6c4009
  equal (one, "ghef", 5);			/* Basic test encore. */
Packit 6c4009
  equal (two, "ef", 6);			/* Stomped on source? */
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "");
Packit 6c4009
  (void) strcat (one, "");
Packit 6c4009
  equal (one, "", 7);			/* Boundary conditions. */
Packit 6c4009
  (void) strcpy (one, "ab");
Packit 6c4009
  (void) strcat (one, "");
Packit 6c4009
  equal (one, "ab", 8);
Packit 6c4009
  (void) strcpy (one, "");
Packit 6c4009
  (void) strcat (one, "cd");
Packit 6c4009
  equal (one, "cd", 9);
Packit 6c4009
Packit 6c4009
  int ntest = 10;
Packit 6c4009
  char buf1[80] __attribute__ ((aligned (16)));
Packit 6c4009
  char buf2[32] __attribute__ ((aligned (16)));
Packit 6c4009
  for (size_t n1 = 0; n1 < 16; ++n1)
Packit 6c4009
    for (size_t n2 = 0; n2 < 16; ++n2)
Packit 6c4009
      for (size_t n3 = 0; n3 < 32; ++n3)
Packit 6c4009
	{
Packit 6c4009
	  size_t olderrors = errors;
Packit 6c4009
Packit 6c4009
	  memset (buf1, 'b', sizeof (buf1));
Packit 6c4009
Packit 6c4009
	  memset (buf1 + n2, 'a', n3);
Packit 6c4009
	  buf1[n2 + n3] = '\0';
Packit 6c4009
	  strcpy (buf2 + n1, "123");
Packit 6c4009
Packit 6c4009
	  check (strcat (buf1 + n2, buf2 + n1) == buf1 + n2, ntest);
Packit 6c4009
	  if (errors == olderrors)
Packit 6c4009
	    for (size_t i = 0; i < sizeof (buf1); ++i)
Packit 6c4009
	      {
Packit 6c4009
		if (i < n2)
Packit 6c4009
		  check (buf1[i] == 'b', ntest);
Packit 6c4009
		else if (i < n2 + n3)
Packit 6c4009
		  check (buf1[i] == 'a', ntest);
Packit 6c4009
		else if (i < n2 + n3 + 3)
Packit 6c4009
		  check (buf1[i] == "123"[i - (n2 + n3)], ntest);
Packit 6c4009
		else if (i == n2 + n3 + 3)
Packit 6c4009
		  check (buf1[i] == '\0', ntest);
Packit 6c4009
		else
Packit 6c4009
		  check (buf1[i] == 'b', ntest);
Packit 6c4009
Packit 6c4009
		if (errors != olderrors)
Packit 6c4009
		  {
Packit 6c4009
		    printf ("n1=%zu, n2=%zu, n3=%zu, buf1=%02hhx",
Packit 6c4009
			    n1, n2, n3, buf1[0]);
Packit 6c4009
		    for (size_t j = 1; j < sizeof (buf1); ++j)
Packit 6c4009
		      printf (",%02hhx", buf1[j]);
Packit 6c4009
		    putchar_unlocked ('\n');
Packit 6c4009
		    break;
Packit 6c4009
		  }
Packit 6c4009
	      }
Packit 6c4009
	}
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strncat (void)
Packit 6c4009
{
Packit 6c4009
  /* First test it as strcat, with big counts, then test the count
Packit 6c4009
     mechanism.  */
Packit 6c4009
  it = "strncat";
Packit 6c4009
  (void) strcpy (one, "ijk");
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (7, 0)
Packit 6c4009
  /* GCC 7 warns about the size passed to strncat being larger than
Packit 6c4009
     the size of the buffer; this is deliberately tested here..  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
Packit 6c4009
#endif
Packit 6c4009
  check (strncat (one, "lmn", 99) == one, 1);	/* Returned value. */
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
  equal (one, "ijklmn", 2);		/* Basic test. */
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "x");
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (7, 0)
Packit 6c4009
  /* GCC 7 warns about the size passed to strncat being larger than
Packit 6c4009
     the size of the buffer; this is deliberately tested here..  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
Packit 6c4009
#endif
Packit 6c4009
  (void) strncat (one, "yz", 99);
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
  equal (one, "xyz", 3);		/* Writeover. */
Packit 6c4009
  equal (one+4, "mn", 4);		/* Wrote too much? */
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "gh");
Packit 6c4009
  (void) strcpy (two, "ef");
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (7, 0)
Packit 6c4009
  /* GCC 7 warns about the size passed to strncat being larger than
Packit 6c4009
     the size of the buffer; this is deliberately tested here; GCC 8
Packit 6c4009
     gives a -Warray-bounds warning about this.  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
Packit 6c4009
#endif
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (8, "-Warray-bounds");
Packit 6c4009
  (void) strncat (one, two, 99);
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
  equal (one, "ghef", 5);			/* Basic test encore. */
Packit 6c4009
  equal (two, "ef", 6);			/* Stomped on source? */
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "");
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (7, 0)
Packit 6c4009
  /* GCC 7 warns about the size passed to strncat being larger than
Packit 6c4009
     the size of the buffer; this is deliberately tested here..  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
Packit 6c4009
#endif
Packit 6c4009
  (void) strncat (one, "", 99);
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
  equal (one, "", 7);			/* Boundary conditions. */
Packit 6c4009
  (void) strcpy (one, "ab");
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (7, 0)
Packit 6c4009
  /* GCC 7 warns about the size passed to strncat being larger than
Packit 6c4009
     the size of the buffer; this is deliberately tested here..  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
Packit 6c4009
#endif
Packit 6c4009
  (void) strncat (one, "", 99);
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
  equal (one, "ab", 8);
Packit 6c4009
  (void) strcpy (one, "");
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (7, 0)
Packit 6c4009
  /* GCC 7 warns about the size passed to strncat being larger than
Packit 6c4009
     the size of the buffer; this is deliberately tested here..  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
Packit 6c4009
#endif
Packit 6c4009
  (void) strncat (one, "cd", 99);
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
  equal (one, "cd", 9);
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "ab");
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (8, 0)
Packit 6c4009
  /* GCC 8 warns about strncat truncating output; this is deliberately
Packit 6c4009
     tested here.  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
Packit 6c4009
#endif
Packit 6c4009
  (void) strncat (one, "cdef", 2);
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
  equal (one, "abcd", 10);			/* Count-limited. */
Packit 6c4009
Packit 6c4009
  (void) strncat (one, "gh", 0);
Packit 6c4009
  equal (one, "abcd", 11);			/* Zero count. */
Packit 6c4009
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (7, 0)
Packit 6c4009
  /* GCC 8 warns about strncat bound equal to source length; this is
Packit 6c4009
     deliberately tested here.  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-overflow=");
Packit 6c4009
#endif
Packit 6c4009
  (void) strncat (one, "gh", 2);
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
  equal (one, "abcdgh", 12);		/* Count and length equal. */
Packit 6c4009
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (7, 0)
Packit 6c4009
  /* GCC 7 warns about the size passed to strncat being larger than
Packit 6c4009
     the size of the buffer; this is deliberately tested here..  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
Packit 6c4009
#endif
Packit 6c4009
  (void) strncat (one, "ij", (size_t)-1);	/* set sign bit in count */
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
  equal (one, "abcdghij", 13);
Packit 6c4009
Packit 6c4009
  int ntest = 14;
Packit 6c4009
  char buf1[80] __attribute__ ((aligned (16)));
Packit 6c4009
  char buf2[32] __attribute__ ((aligned (16)));
Packit 6c4009
  for (size_t n1 = 0; n1 < 16; ++n1)
Packit 6c4009
    for (size_t n2 = 0; n2 < 16; ++n2)
Packit 6c4009
      for (size_t n3 = 0; n3 < 32; ++n3)
Packit 6c4009
	for (size_t n4 = 0; n4 < 16; ++n4)
Packit 6c4009
	  {
Packit 6c4009
	    size_t olderrors = errors;
Packit 6c4009
Packit 6c4009
	    memset (buf1, 'b', sizeof (buf1));
Packit 6c4009
Packit 6c4009
	    memset (buf1 + n2, 'a', n3);
Packit 6c4009
	    buf1[n2 + n3] = '\0';
Packit 6c4009
	    strcpy (buf2 + n1, "123");
Packit 6c4009
Packit 6c4009
	    DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (7, 0)
Packit 6c4009
	    /* GCC 7 warns about the size passed to strncat being
Packit 6c4009
	       larger than the size of the buffer; this is
Packit 6c4009
	       deliberately tested here; GCC 8 gives a -Warray-bounds
Packit 6c4009
	       warning about this.  */
Packit 6c4009
	    DIAG_IGNORE_NEEDS_COMMENT (7, "-Wstringop-overflow=");
Packit 6c4009
	    /* GCC 9 as of 2018-06-14 warns that the size passed is
Packit 6c4009
	       large enough that, if it were the actual object size,
Packit 6c4009
	       the objects would have to overlap.  */
Packit 6c4009
	    DIAG_IGNORE_NEEDS_COMMENT (9, "-Wrestrict");
Packit 6c4009
#endif
Packit 6c4009
	    DIAG_IGNORE_NEEDS_COMMENT (8, "-Warray-bounds");
Packit 6c4009
	    check (strncat (buf1 + n2, buf2 + n1, ~((size_t) 0) - n4)
Packit 6c4009
		   == buf1 + n2, ntest);
Packit 6c4009
	    DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
	    if (errors == olderrors)
Packit 6c4009
	      for (size_t i = 0; i < sizeof (buf1); ++i)
Packit 6c4009
		{
Packit 6c4009
		  if (i < n2)
Packit 6c4009
		    check (buf1[i] == 'b', ntest);
Packit 6c4009
		  else if (i < n2 + n3)
Packit 6c4009
		    check (buf1[i] == 'a', ntest);
Packit 6c4009
		  else if (i < n2 + n3 + 3)
Packit 6c4009
		    check (buf1[i] == "123"[i - (n2 + n3)], ntest);
Packit 6c4009
		  else if (i == n2 + n3 + 3)
Packit 6c4009
		    check (buf1[i] == '\0', ntest);
Packit 6c4009
		  else
Packit 6c4009
		    check (buf1[i] == 'b', ntest);
Packit 6c4009
Packit 6c4009
		  if (errors != olderrors)
Packit 6c4009
		    {
Packit 6c4009
		      printf ("n1=%zu, n2=%zu, n3=%zu, n4=%zu, buf1=%02hhx",
Packit 6c4009
			      n1, n2, n3, n4, buf1[0]);
Packit 6c4009
		      for (size_t j = 1; j < sizeof (buf1); ++j)
Packit 6c4009
			printf (",%02hhx", buf1[j]);
Packit 6c4009
		      putchar_unlocked ('\n');
Packit 6c4009
		      break;
Packit 6c4009
		    }
Packit 6c4009
		}
Packit 6c4009
	  }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strncmp (void)
Packit 6c4009
{
Packit 6c4009
  /* First test as strcmp with big counts, then test count code.  */
Packit 6c4009
  it = "strncmp";
Packit 6c4009
  check (strncmp ("", "", 99) == 0, 1);	/* Trivial case. */
Packit 6c4009
  check (strncmp ("a", "a", 99) == 0, 2);	/* Identity. */
Packit 6c4009
  check (strncmp ("abc", "abc", 99) == 0, 3);	/* Multicharacter. */
Packit 6c4009
  check (strncmp ("abc", "abcd", 99) < 0, 4);	/* Length unequal. */
Packit 6c4009
  check (strncmp ("abcd", "abc", 99) > 0, 5);
Packit 6c4009
  check (strncmp ("abcd", "abce", 99) < 0, 6);	/* Honestly unequal. */
Packit 6c4009
  check (strncmp ("abce", "abcd", 99) > 0, 7);
Packit 6c4009
  check (strncmp ("a\203", "a", 2) > 0, 8);	/* Tricky if '\203' < 0 */
Packit 6c4009
  check (strncmp ("a\203", "a\003", 2) > 0, 9);
Packit 6c4009
  check (strncmp ("abce", "abcd", 3) == 0, 10);	/* Count limited. */
Packit 6c4009
  check (strncmp ("abce", "abc", 3) == 0, 11);	/* Count == length. */
Packit 6c4009
  check (strncmp ("abcd", "abce", 4) < 0, 12);	/* Nudging limit. */
Packit 6c4009
  check (strncmp ("abc", "def", 0) == 0, 13);	/* Zero count. */
Packit 6c4009
  check (strncmp ("abc", "", (size_t)-1) > 0, 14);	/* set sign bit in count */
Packit 6c4009
  check (strncmp ("abc", "abc", (size_t)-2) == 0, 15);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strncpy (void)
Packit 6c4009
{
Packit 6c4009
  /* Testing is a bit different because of odd semantics.  */
Packit 6c4009
  it = "strncpy";
Packit 6c4009
  check (strncpy (one, "abc", 4) == one, 1);	/* Returned value. */
Packit 6c4009
  equal (one, "abc", 2);			/* Did the copy go right? */
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "abcdefgh");
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (8, 0)
Packit 6c4009
  /* GCC 8 warns about strncpy truncating output; this is deliberately
Packit 6c4009
     tested here.  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
Packit 6c4009
#endif
Packit 6c4009
  (void) strncpy (one, "xyz", 2);
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
  equal (one, "xycdefgh", 3);			/* Copy cut by count. */
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "abcdefgh");
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (8, 0)
Packit 6c4009
  /* GCC 8 warns about strncpy truncating output; this is deliberately
Packit 6c4009
     tested here.  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
Packit 6c4009
#endif
Packit 6c4009
  (void) strncpy (one, "xyz", 3);		/* Copy cut just before NUL. */
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
  equal (one, "xyzdefgh", 4);
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "abcdefgh");
Packit 6c4009
  (void) strncpy (one, "xyz", 4);		/* Copy just includes NUL. */
Packit 6c4009
  equal (one, "xyz", 5);
Packit 6c4009
  equal (one+4, "efgh", 6);			/* Wrote too much? */
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "abcdefgh");
Packit 6c4009
  (void) strncpy (one, "xyz", 5);		/* Copy includes padding. */
Packit 6c4009
  equal (one, "xyz", 7);
Packit 6c4009
  equal (one+4, "", 8);
Packit 6c4009
  equal (one+5, "fgh", 9);
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "abc");
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (8, 0)
Packit 6c4009
  /* GCC 8 warns about strncpy truncating output; this is deliberately
Packit 6c4009
     tested here.  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (8, "-Wstringop-truncation");
Packit 6c4009
#endif
Packit 6c4009
  (void) strncpy (one, "xyz", 0);		/* Zero-length copy. */
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
  equal (one, "abc", 10);
Packit 6c4009
Packit 6c4009
  (void) strncpy (one, "", 2);		/* Zero-length source. */
Packit 6c4009
  equal (one, "", 11);
Packit 6c4009
  equal (one+1, "", 12);
Packit 6c4009
  equal (one+2, "c", 13);
Packit 6c4009
Packit 6c4009
  (void) strcpy (one, "hi there");
Packit 6c4009
  (void) strncpy (two, one, 9);
Packit 6c4009
  equal (two, "hi there", 14);		/* Just paranoia. */
Packit 6c4009
  equal (one, "hi there", 15);		/* Stomped on source? */
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strlen (void)
Packit 6c4009
{
Packit 6c4009
  it = "strlen";
Packit 6c4009
  check (strlen ("") == 0, 1);		/* Empty. */
Packit 6c4009
  check (strlen ("a") == 1, 2);		/* Single char. */
Packit 6c4009
  check (strlen ("abcd") == 4, 3);	/* Multiple chars. */
Packit 6c4009
  {
Packit 6c4009
    char buf[4096];
Packit 6c4009
    int i;
Packit 6c4009
    char *p;
Packit 6c4009
    for (i=0; i < 0x100; i++)
Packit 6c4009
      {
Packit 6c4009
	p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
Packit 6c4009
	strcpy (p, "OK");
Packit 6c4009
	strcpy (p+3, "BAD/WRONG");
Packit 6c4009
	check (strlen (p) == 2, 4+i);
Packit 6c4009
      }
Packit 6c4009
   }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strnlen (void)
Packit 6c4009
{
Packit 6c4009
  it = "strnlen";
Packit 6c4009
  check (strnlen ("", 10) == 0, 1);		/* Empty. */
Packit 6c4009
  check (strnlen ("a", 10) == 1, 2);		/* Single char. */
Packit 6c4009
  check (strnlen ("abcd", 10) == 4, 3);		/* Multiple chars. */
Packit 6c4009
  check (strnlen ("foo", (size_t) -1) == 3, 4);	/* limits of n. */
Packit 6c4009
  check (strnlen ("abcd", 0) == 0, 5);		/* Restricted. */
Packit 6c4009
  check (strnlen ("abcd", 1) == 1, 6);		/* Restricted. */
Packit 6c4009
  check (strnlen ("abcd", 2) == 2, 7);		/* Restricted. */
Packit 6c4009
  check (strnlen ("abcd", 3) == 3, 8);		/* Restricted. */
Packit 6c4009
  check (strnlen ("abcd", 4) == 4, 9);		/* Restricted. */
Packit 6c4009
Packit 6c4009
  char buf[4096];
Packit 6c4009
  for (int i = 0; i < 0x100; ++i)
Packit 6c4009
    {
Packit 6c4009
      char *p = (char *) ((unsigned long int)(buf + 0xff) & ~0xff) + i;
Packit 6c4009
      strcpy (p, "OK");
Packit 6c4009
      strcpy (p + 3, "BAD/WRONG");
Packit 6c4009
      check (strnlen (p, 100) == 2, 10 + i);
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strchr (void)
Packit 6c4009
{
Packit 6c4009
  it = "strchr";
Packit 6c4009
  check (strchr ("abcd", 'z') == NULL, 1);	/* Not found. */
Packit 6c4009
  (void) strcpy (one, "abcd");
Packit 6c4009
  check (strchr (one, 'c') == one+2, 2);	/* Basic test. */
Packit 6c4009
  check (strchr (one, 'd') == one+3, 3);	/* End of string. */
Packit 6c4009
  check (strchr (one, 'a') == one, 4);		/* Beginning. */
Packit 6c4009
  check (strchr (one, '\0') == one+4, 5);	/* Finding NUL. */
Packit 6c4009
  (void) strcpy (one, "ababa");
Packit 6c4009
  check (strchr (one, 'b') == one+1, 6);	/* Finding first. */
Packit 6c4009
  (void) strcpy (one, "");
Packit 6c4009
  check (strchr (one, 'b') == NULL, 7);		/* Empty string. */
Packit 6c4009
  check (strchr (one, '\0') == one, 8);		/* NUL in empty string. */
Packit 6c4009
  {
Packit 6c4009
    char buf[4096];
Packit 6c4009
    int i;
Packit 6c4009
    char *p;
Packit 6c4009
    for (i=0; i < 0x100; i++)
Packit 6c4009
      {
Packit 6c4009
	p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
Packit 6c4009
	strcpy (p, "OK");
Packit 6c4009
	strcpy (p+3, "BAD/WRONG");
Packit 6c4009
	check (strchr (p, '/') == NULL, 9+i);
Packit 6c4009
      }
Packit 6c4009
   }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strchrnul (void)
Packit 6c4009
{
Packit 6c4009
  const char *os;
Packit 6c4009
  it = "strchrnul";
Packit 6c4009
  cp = strchrnul ((os = "abcd"), 'z');
Packit 6c4009
  check (*cp == '\0', 1);			/* Not found. */
Packit 6c4009
  check (cp == os + 4, 2);
Packit 6c4009
  (void) strcpy (one, "abcd");
Packit 6c4009
  check (strchrnul (one, 'c') == one+2, 3);	/* Basic test. */
Packit 6c4009
  check (strchrnul (one, 'd') == one+3, 4);	/* End of string. */
Packit 6c4009
  check (strchrnul (one, 'a') == one, 5);	/* Beginning. */
Packit 6c4009
  check (strchrnul (one, '\0') == one+4, 6);	/* Finding NUL. */
Packit 6c4009
  (void) strcpy (one, "ababa");
Packit 6c4009
  check (strchrnul (one, 'b') == one+1, 7);	/* Finding first. */
Packit 6c4009
  (void) strcpy (one, "");
Packit 6c4009
  check (strchrnul (one, 'b') == one, 8);	/* Empty string. */
Packit 6c4009
  check (strchrnul (one, '\0') == one, 9);	/* NUL in empty string. */
Packit 6c4009
  {
Packit 6c4009
    char buf[4096];
Packit 6c4009
    int i;
Packit 6c4009
    char *p;
Packit 6c4009
    for (i=0; i < 0x100; i++)
Packit 6c4009
      {
Packit 6c4009
	p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
Packit 6c4009
	strcpy (p, "OK");
Packit 6c4009
	strcpy (p+3, "BAD/WRONG");
Packit 6c4009
	cp = strchrnul (p, '/');
Packit 6c4009
	check (*cp == '\0', 9+2*i);
Packit 6c4009
	check (cp == p+2, 10+2*i);
Packit 6c4009
      }
Packit 6c4009
   }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_rawmemchr (void)
Packit 6c4009
{
Packit 6c4009
  it = "rawmemchr";
Packit 6c4009
  (void) strcpy (one, "abcd");
Packit 6c4009
  check (rawmemchr (one, 'c') == one+2, 1);	/* Basic test. */
Packit 6c4009
  check (rawmemchr (one, 'd') == one+3, 2);	/* End of string. */
Packit 6c4009
  check (rawmemchr (one, 'a') == one, 3);		/* Beginning. */
Packit 6c4009
  check (rawmemchr (one, '\0') == one+4, 4);	/* Finding NUL. */
Packit 6c4009
  (void) strcpy (one, "ababa");
Packit 6c4009
  check (rawmemchr (one, 'b') == one+1, 5);	/* Finding first. */
Packit 6c4009
  (void) strcpy (one, "");
Packit 6c4009
  check (rawmemchr (one, '\0') == one, 6);	/* NUL in empty string. */
Packit 6c4009
  {
Packit 6c4009
    char buf[4096];
Packit 6c4009
    int i;
Packit 6c4009
    char *p;
Packit 6c4009
    for (i=0; i < 0x100; i++)
Packit 6c4009
      {
Packit 6c4009
	p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
Packit 6c4009
	strcpy (p, "OK");
Packit 6c4009
	strcpy (p+3, "BAD/WRONG");
Packit 6c4009
	check (rawmemchr (p, 'R') == p+8, 6+i);
Packit 6c4009
      }
Packit 6c4009
   }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_index (void)
Packit 6c4009
{
Packit 6c4009
  it = "index";
Packit 6c4009
  check (index ("abcd", 'z') == NULL, 1);	/* Not found. */
Packit 6c4009
  (void) strcpy (one, "abcd");
Packit 6c4009
  check (index (one, 'c') == one+2, 2);	/* Basic test. */
Packit 6c4009
  check (index (one, 'd') == one+3, 3);	/* End of string. */
Packit 6c4009
  check (index (one, 'a') == one, 4);	/* Beginning. */
Packit 6c4009
  check (index (one, '\0') == one+4, 5);	/* Finding NUL. */
Packit 6c4009
  (void) strcpy (one, "ababa");
Packit 6c4009
  check (index (one, 'b') == one+1, 6);	/* Finding first. */
Packit 6c4009
  (void) strcpy (one, "");
Packit 6c4009
  check (index (one, 'b') == NULL, 7);	/* Empty string. */
Packit 6c4009
  check (index (one, '\0') == one, 8);	/* NUL in empty string. */
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strrchr (void)
Packit 6c4009
{
Packit 6c4009
  it = "strrchr";
Packit 6c4009
  check (strrchr ("abcd", 'z') == NULL, 1);	/* Not found. */
Packit 6c4009
  (void) strcpy (one, "abcd");
Packit 6c4009
  check (strrchr (one, 'c') == one+2, 2);	/* Basic test. */
Packit 6c4009
  check (strrchr (one, 'd') == one+3, 3);	/* End of string. */
Packit 6c4009
  check (strrchr (one, 'a') == one, 4);		/* Beginning. */
Packit 6c4009
  check (strrchr (one, '\0') == one+4, 5);	/* Finding NUL. */
Packit 6c4009
  (void) strcpy (one, "ababa");
Packit 6c4009
  check (strrchr (one, 'b') == one+3, 6);	/* Finding last. */
Packit 6c4009
  (void) strcpy (one, "");
Packit 6c4009
  check (strrchr (one, 'b') == NULL, 7);	/* Empty string. */
Packit 6c4009
  check (strrchr (one, '\0') == one, 8);	/* NUL in empty string. */
Packit 6c4009
  {
Packit 6c4009
    char buf[4096];
Packit 6c4009
    int i;
Packit 6c4009
    char *p;
Packit 6c4009
    for (i=0; i < 0x100; i++)
Packit 6c4009
      {
Packit 6c4009
	p = (char *) ((unsigned long int) (buf + 0xff) & ~0xff) + i;
Packit 6c4009
	strcpy (p, "OK");
Packit 6c4009
	strcpy (p+3, "BAD/WRONG");
Packit 6c4009
	check (strrchr (p, '/') == NULL, 9+i);
Packit 6c4009
      }
Packit 6c4009
   }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_memrchr (void)
Packit 6c4009
{
Packit 6c4009
  size_t l;
Packit 6c4009
  it = "memrchr";
Packit 6c4009
  check (memrchr ("abcd", 'z', 5) == NULL, 1);	/* Not found. */
Packit 6c4009
  (void) strcpy (one, "abcd");
Packit 6c4009
  l = strlen (one) + 1;
Packit 6c4009
  check (memrchr (one, 'c', l) == one+2, 2);	/* Basic test. */
Packit 6c4009
  check (memrchr (one, 'd', l) == one+3, 3);	/* End of string. */
Packit 6c4009
  check (memrchr (one, 'a', l) == one, 4);		/* Beginning. */
Packit 6c4009
  check (memrchr (one, '\0', l) == one+4, 5);	/* Finding NUL. */
Packit 6c4009
  (void) strcpy (one, "ababa");
Packit 6c4009
  l = strlen (one) + 1;
Packit 6c4009
  check (memrchr (one, 'b', l) == one+3, 6);	/* Finding last. */
Packit 6c4009
  (void) strcpy (one, "");
Packit 6c4009
  l = strlen (one) + 1;
Packit 6c4009
  check (memrchr (one, 'b', l) == NULL, 7);	/* Empty string. */
Packit 6c4009
  check (memrchr (one, '\0', l) == one, 8);	/* NUL in empty string. */
Packit 6c4009
Packit 6c4009
  /* now test all possible alignment and length combinations to catch
Packit 6c4009
     bugs due to unrolled loops (assuming unrolling is limited to no
Packit 6c4009
     more than 128 byte chunks: */
Packit 6c4009
  {
Packit 6c4009
    char buf[128 + sizeof(long)];
Packit 6c4009
    long align, len, i, pos, n = 9;
Packit 6c4009
Packit 6c4009
    for (align = 0; align < (long) sizeof(long); ++align) {
Packit 6c4009
      for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
Packit 6c4009
	for (i = 0; i < len; ++i)
Packit 6c4009
	  buf[align + i] = 'x';		/* don't depend on memset... */
Packit 6c4009
Packit 6c4009
	for (pos = len - 1; pos >= 0; --pos) {
Packit 6c4009
#if 0
Packit 6c4009
	  printf("align %d, len %d, pos %d\n", align, len, pos);
Packit 6c4009
#endif
Packit 6c4009
	  check(memrchr(buf + align, 'x', len) == buf + align + pos, n++);
Packit 6c4009
	  check(memrchr(buf + align + pos + 1, 'x', len - (pos + 1)) == NULL,
Packit 6c4009
		n++);
Packit 6c4009
	  buf[align + pos] = '-';
Packit 6c4009
	}
Packit 6c4009
      }
Packit 6c4009
    }
Packit 6c4009
  }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_rindex (void)
Packit 6c4009
{
Packit 6c4009
  it = "rindex";
Packit 6c4009
  check (rindex ("abcd", 'z') == NULL, 1);	/* Not found. */
Packit 6c4009
  (void) strcpy (one, "abcd");
Packit 6c4009
  check (rindex (one, 'c') == one+2, 2);	/* Basic test. */
Packit 6c4009
  check (rindex (one, 'd') == one+3, 3);	/* End of string. */
Packit 6c4009
  check (rindex (one, 'a') == one, 4);	/* Beginning. */
Packit 6c4009
  check (rindex (one, '\0') == one+4, 5);	/* Finding NUL. */
Packit 6c4009
  (void) strcpy (one, "ababa");
Packit 6c4009
  check (rindex (one, 'b') == one+3, 6);	/* Finding last. */
Packit 6c4009
  (void) strcpy (one, "");
Packit 6c4009
  check (rindex (one, 'b') == NULL, 7);	/* Empty string. */
Packit 6c4009
  check (rindex (one, '\0') == one, 8);	/* NUL in empty string. */
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strpbrk (void)
Packit 6c4009
{
Packit 6c4009
  it = "strpbrk";
Packit 6c4009
  check(strpbrk("abcd", "z") == NULL, 1);	/* Not found. */
Packit 6c4009
  (void) strcpy(one, "abcd");
Packit 6c4009
  check(strpbrk(one, "c") == one+2, 2);	/* Basic test. */
Packit 6c4009
  check(strpbrk(one, "d") == one+3, 3);	/* End of string. */
Packit 6c4009
  check(strpbrk(one, "a") == one, 4);	/* Beginning. */
Packit 6c4009
  check(strpbrk(one, "") == NULL, 5);	/* Empty search list. */
Packit 6c4009
  check(strpbrk(one, "cb") == one+1, 6);	/* Multiple search. */
Packit 6c4009
  (void) strcpy(one, "abcabdea");
Packit 6c4009
  check(strpbrk(one, "b") == one+1, 7);	/* Finding first. */
Packit 6c4009
  check(strpbrk(one, "cb") == one+1, 8);	/* With multiple search. */
Packit 6c4009
  check(strpbrk(one, "db") == one+1, 9);	/* Another variant. */
Packit 6c4009
  (void) strcpy(one, "");
Packit 6c4009
  check(strpbrk(one, "bc") == NULL, 10);	/* Empty string. */
Packit 6c4009
  (void) strcpy(one, "");
Packit 6c4009
  check(strpbrk(one, "bcd") == NULL, 11);	/* Empty string. */
Packit 6c4009
  (void) strcpy(one, "");
Packit 6c4009
  check(strpbrk(one, "bcde") == NULL, 12);	/* Empty string. */
Packit 6c4009
  check(strpbrk(one, "") == NULL, 13);	/* Both strings empty. */
Packit 6c4009
  (void) strcpy(one, "abcabdea");
Packit 6c4009
  check(strpbrk(one, "befg") == one+1, 14);	/* Finding first. */
Packit 6c4009
  check(strpbrk(one, "cbr") == one+1, 15);	/* With multiple search. */
Packit 6c4009
  check(strpbrk(one, "db") == one+1, 16);	/* Another variant. */
Packit 6c4009
  check(strpbrk(one, "efgh") == one+6, 17);	/* And yet another. */
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strstr (void)
Packit 6c4009
{
Packit 6c4009
  it = "strstr";
Packit 6c4009
  check(strstr("abcd", "z") == NULL, 1);	/* Not found. */
Packit 6c4009
  check(strstr("abcd", "abx") == NULL, 2);	/* Dead end. */
Packit 6c4009
  (void) strcpy(one, "abcd");
Packit 6c4009
  check(strstr(one, "c") == one+2, 3);	/* Basic test. */
Packit 6c4009
  check(strstr(one, "bc") == one+1, 4);	/* Multichar. */
Packit 6c4009
  check(strstr(one, "d") == one+3, 5);	/* End of string. */
Packit 6c4009
  check(strstr(one, "cd") == one+2, 6);	/* Tail of string. */
Packit 6c4009
  check(strstr(one, "abc") == one, 7);	/* Beginning. */
Packit 6c4009
  check(strstr(one, "abcd") == one, 8);	/* Exact match. */
Packit 6c4009
  check(strstr(one, "abcde") == NULL, 9);	/* Too long. */
Packit 6c4009
  check(strstr(one, "de") == NULL, 10);	/* Past end. */
Packit 6c4009
  check(strstr(one, "") == one, 11);	/* Finding empty. */
Packit 6c4009
  (void) strcpy(one, "ababa");
Packit 6c4009
  check(strstr(one, "ba") == one+1, 12);	/* Finding first. */
Packit 6c4009
  (void) strcpy(one, "");
Packit 6c4009
  check(strstr(one, "b") == NULL, 13);	/* Empty string. */
Packit 6c4009
  check(strstr(one, "") == one, 14);	/* Empty in empty string. */
Packit 6c4009
  (void) strcpy(one, "bcbca");
Packit 6c4009
  check(strstr(one, "bca") == one+2, 15);	/* False start. */
Packit 6c4009
  (void) strcpy(one, "bbbcabbca");
Packit 6c4009
  check(strstr(one, "bbca") == one+1, 16);	/* With overlap. */
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strspn (void)
Packit 6c4009
{
Packit 6c4009
  it = "strspn";
Packit 6c4009
  check(strspn("abcba", "abc") == 5, 1);	/* Whole string. */
Packit 6c4009
  check(strspn("abcba", "ab") == 2, 2);	/* Partial. */
Packit 6c4009
  check(strspn("abc", "qx") == 0, 3);	/* None. */
Packit 6c4009
  check(strspn("", "ab") == 0, 4);	/* Null string. */
Packit 6c4009
  check(strspn("abc", "") == 0, 5);	/* Null search list. */
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strcspn (void)
Packit 6c4009
{
Packit 6c4009
  it = "strcspn";
Packit 6c4009
  check(strcspn("abcba", "qx") == 5, 1);	/* Whole string. */
Packit 6c4009
  check(strcspn("abcba", "cx") == 2, 2);	/* Partial. */
Packit 6c4009
  check(strcspn("abc", "abc") == 0, 3);	/* None. */
Packit 6c4009
  check(strcspn("", "ab") == 0, 4);	/* Null string. */
Packit 6c4009
  check(strcspn("abc", "") == 3, 5);	/* Null search list. */
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strtok (void)
Packit 6c4009
{
Packit 6c4009
  it = "strtok";
Packit 6c4009
  (void) strcpy(one, "first, second, third");
Packit 6c4009
  equal(strtok(one, ", "), "first", 1);	/* Basic test. */
Packit 6c4009
  equal(one, "first", 2);
Packit 6c4009
  equal(strtok((char *)NULL, ", "), "second", 3);
Packit 6c4009
  equal(strtok((char *)NULL, ", "), "third", 4);
Packit 6c4009
  check(strtok((char *)NULL, ", ") == NULL, 5);
Packit 6c4009
  (void) strcpy(one, ", first, ");
Packit 6c4009
  equal(strtok(one, ", "), "first", 6);	/* Extra delims, 1 tok. */
Packit 6c4009
  check(strtok((char *)NULL, ", ") == NULL, 7);
Packit 6c4009
  (void) strcpy(one, "1a, 1b; 2a, 2b");
Packit 6c4009
  equal(strtok(one, ", "), "1a", 8);	/* Changing delim lists. */
Packit 6c4009
  equal(strtok((char *)NULL, "; "), "1b", 9);
Packit 6c4009
  equal(strtok((char *)NULL, ", "), "2a", 10);
Packit 6c4009
  (void) strcpy(two, "x-y");
Packit 6c4009
  equal(strtok(two, "-"), "x", 11);	/* New string before done. */
Packit 6c4009
  equal(strtok((char *)NULL, "-"), "y", 12);
Packit 6c4009
  check(strtok((char *)NULL, "-") == NULL, 13);
Packit 6c4009
  (void) strcpy(one, "a,b, c,, ,d");
Packit 6c4009
  equal(strtok(one, ", "), "a", 14);	/* Different separators. */
Packit 6c4009
  equal(strtok((char *)NULL, ", "), "b", 15);
Packit 6c4009
  equal(strtok((char *)NULL, " ,"), "c", 16);	/* Permute list too. */
Packit 6c4009
  equal(strtok((char *)NULL, " ,"), "d", 17);
Packit 6c4009
  check(strtok((char *)NULL, ", ") == NULL, 18);
Packit 6c4009
  check(strtok((char *)NULL, ", ") == NULL, 19);	/* Persistence. */
Packit 6c4009
  (void) strcpy(one, ", ");
Packit 6c4009
  check(strtok(one, ", ") == NULL, 20);	/* No tokens. */
Packit 6c4009
  (void) strcpy(one, "");
Packit 6c4009
  check(strtok(one, ", ") == NULL, 21);	/* Empty string. */
Packit 6c4009
  (void) strcpy(one, "abc");
Packit 6c4009
  equal(strtok(one, ", "), "abc", 22);	/* No delimiters. */
Packit 6c4009
  check(strtok((char *)NULL, ", ") == NULL, 23);
Packit 6c4009
  (void) strcpy(one, "abc");
Packit 6c4009
  equal(strtok(one, ""), "abc", 24);	/* Empty delimiter list. */
Packit 6c4009
  check(strtok((char *)NULL, "") == NULL, 25);
Packit 6c4009
  (void) strcpy(one, "abcdefgh");
Packit 6c4009
  (void) strcpy(one, "a,b,c");
Packit 6c4009
  equal(strtok(one, ","), "a", 26);	/* Basics again... */
Packit 6c4009
  equal(strtok((char *)NULL, ","), "b", 27);
Packit 6c4009
  equal(strtok((char *)NULL, ","), "c", 28);
Packit 6c4009
  check(strtok((char *)NULL, ",") == NULL, 29);
Packit 6c4009
  equal(one+6, "gh", 30);			/* Stomped past end? */
Packit 6c4009
  equal(one, "a", 31);			/* Stomped old tokens? */
Packit 6c4009
  equal(one+2, "b", 32);
Packit 6c4009
  equal(one+4, "c", 33);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strtok_r (void)
Packit 6c4009
{
Packit 6c4009
  it = "strtok_r";
Packit 6c4009
  (void) strcpy(one, "first, second, third");
Packit 6c4009
  cp = NULL;	/* Always initialize cp to make sure it doesn't point to some old data.  */
Packit 6c4009
  equal(strtok_r(one, ", ", &cp), "first", 1);	/* Basic test. */
Packit 6c4009
  equal(one, "first", 2);
Packit 6c4009
  equal(strtok_r((char *)NULL, ", ", &cp), "second", 3);
Packit 6c4009
  equal(strtok_r((char *)NULL, ", ", &cp), "third", 4);
Packit 6c4009
  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 5);
Packit 6c4009
  (void) strcpy(one, ", first, ");
Packit 6c4009
  cp = NULL;
Packit 6c4009
  equal(strtok_r(one, ", ", &cp), "first", 6);	/* Extra delims, 1 tok. */
Packit 6c4009
  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 7);
Packit 6c4009
  (void) strcpy(one, "1a, 1b; 2a, 2b");
Packit 6c4009
  cp = NULL;
Packit 6c4009
  equal(strtok_r(one, ", ", &cp), "1a", 8);	/* Changing delim lists. */
Packit 6c4009
  equal(strtok_r((char *)NULL, "; ", &cp), "1b", 9);
Packit 6c4009
  equal(strtok_r((char *)NULL, ", ", &cp), "2a", 10);
Packit 6c4009
  (void) strcpy(two, "x-y");
Packit 6c4009
  cp = NULL;
Packit 6c4009
  equal(strtok_r(two, "-", &cp), "x", 11);	/* New string before done. */
Packit 6c4009
  equal(strtok_r((char *)NULL, "-", &cp), "y", 12);
Packit 6c4009
  check(strtok_r((char *)NULL, "-", &cp) == NULL, 13);
Packit 6c4009
  (void) strcpy(one, "a,b, c,, ,d");
Packit 6c4009
  cp = NULL;
Packit 6c4009
  equal(strtok_r(one, ", ", &cp), "a", 14);	/* Different separators. */
Packit 6c4009
  equal(strtok_r((char *)NULL, ", ", &cp), "b", 15);
Packit 6c4009
  equal(strtok_r((char *)NULL, " ,", &cp), "c", 16);	/* Permute list too. */
Packit 6c4009
  equal(strtok_r((char *)NULL, " ,", &cp), "d", 17);
Packit 6c4009
  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 18);
Packit 6c4009
  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 19);	/* Persistence. */
Packit 6c4009
  (void) strcpy(one, ", ");
Packit 6c4009
  cp = NULL;
Packit 6c4009
  check(strtok_r(one, ", ", &cp) == NULL, 20);	/* No tokens. */
Packit 6c4009
  (void) strcpy(one, "");
Packit 6c4009
  cp = NULL;
Packit 6c4009
  check(strtok_r(one, ", ", &cp) == NULL, 21);	/* Empty string. */
Packit 6c4009
  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 22);	/* Persistence. */
Packit 6c4009
  (void) strcpy(one, "abc");
Packit 6c4009
  cp = NULL;
Packit 6c4009
  equal(strtok_r(one, ", ", &cp), "abc", 23);	/* No delimiters. */
Packit 6c4009
  check(strtok_r((char *)NULL, ", ", &cp) == NULL, 24);
Packit 6c4009
  (void) strcpy(one, "abc");
Packit 6c4009
  cp = NULL;
Packit 6c4009
  equal(strtok_r(one, "", &cp), "abc", 25);	/* Empty delimiter list. */
Packit 6c4009
  check(strtok_r((char *)NULL, "", &cp) == NULL, 26);
Packit 6c4009
  (void) strcpy(one, "abcdefgh");
Packit 6c4009
  (void) strcpy(one, "a,b,c");
Packit 6c4009
  cp = NULL;
Packit 6c4009
  equal(strtok_r(one, ",", &cp), "a", 27);	/* Basics again... */
Packit 6c4009
  equal(strtok_r((char *)NULL, ",", &cp), "b", 28);
Packit 6c4009
  equal(strtok_r((char *)NULL, ",", &cp), "c", 29);
Packit 6c4009
  check(strtok_r((char *)NULL, ",", &cp) == NULL, 30);
Packit 6c4009
  equal(one+6, "gh", 31);			/* Stomped past end? */
Packit 6c4009
  equal(one, "a", 32);				/* Stomped old tokens? */
Packit 6c4009
  equal(one+2, "b", 33);
Packit 6c4009
  equal(one+4, "c", 34);
Packit 6c4009
  strcpy (one, ":::");
Packit 6c4009
  cp = NULL;
Packit 6c4009
  check (strtok_r (one, ":", &cp) == NULL, 35);	/* Must store pointer in cp. */
Packit 6c4009
  check (strtok_r (NULL, ":", &cp) == NULL, 36);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strsep (void)
Packit 6c4009
{
Packit 6c4009
  char *ptr;
Packit 6c4009
  it = "strsep";
Packit 6c4009
  cp = strcpy(one, "first, second, third");
Packit 6c4009
  equal(strsep(&cp, ", "), "first", 1);	/* Basic test. */
Packit 6c4009
  equal(one, "first", 2);
Packit 6c4009
  equal(strsep(&cp, ", "), "", 3);
Packit 6c4009
  equal(strsep(&cp, ", "), "second", 4);
Packit 6c4009
  equal(strsep(&cp, ", "), "", 5);
Packit 6c4009
  equal(strsep(&cp, ", "), "third", 6);
Packit 6c4009
  check(strsep(&cp, ", ") == NULL, 7);
Packit 6c4009
  cp = strcpy(one, ", first, ");
Packit 6c4009
  equal(strsep(&cp, ", "), "", 8);
Packit 6c4009
  equal(strsep(&cp, ", "), "", 9);
Packit 6c4009
  equal(strsep(&cp, ", "), "first", 10);	/* Extra delims, 1 tok. */
Packit 6c4009
  equal(strsep(&cp, ", "), "", 11);
Packit 6c4009
  equal(strsep(&cp, ", "), "", 12);
Packit 6c4009
  check(strsep(&cp, ", ") == NULL, 13);
Packit 6c4009
  cp = strcpy(one, "1a, 1b; 2a, 2b");
Packit 6c4009
  equal(strsep(&cp, ", "), "1a", 14);	/* Changing delim lists. */
Packit 6c4009
  equal(strsep(&cp, ", "), "", 15);
Packit 6c4009
  equal(strsep(&cp, "; "), "1b", 16);
Packit 6c4009
  equal(strsep(&cp, ", "), "", 17);
Packit 6c4009
  equal(strsep(&cp, ", "), "2a", 18);
Packit 6c4009
  cp = strcpy(two, "x-y");
Packit 6c4009
  equal(strsep(&cp, "-"), "x", 19);	/* New string before done. */
Packit 6c4009
  equal(strsep(&cp, "-"), "y", 20);
Packit 6c4009
  check(strsep(&cp, "-") == NULL, 21);
Packit 6c4009
  cp = strcpy(one, "a,b, c,, ,d ");
Packit 6c4009
  equal(strsep(&cp, ", "), "a", 22);	/* Different separators. */
Packit 6c4009
  equal(strsep(&cp, ", "), "b", 23);
Packit 6c4009
  equal(strsep(&cp, " ,"), "", 24);
Packit 6c4009
  equal(strsep(&cp, " ,"), "c", 25);	/* Permute list too. */
Packit 6c4009
  equal(strsep(&cp, " ,"), "", 26);
Packit 6c4009
  equal(strsep(&cp, " ,"), "", 27);
Packit 6c4009
  equal(strsep(&cp, " ,"), "", 28);
Packit 6c4009
  equal(strsep(&cp, " ,"), "d", 29);
Packit 6c4009
  equal(strsep(&cp, " ,"), "", 30);
Packit 6c4009
  check(strsep(&cp, ", ") == NULL, 31);
Packit 6c4009
  check(strsep(&cp, ", ") == NULL, 32);	/* Persistence. */
Packit 6c4009
  cp = strcpy(one, ", ");
Packit 6c4009
  equal(strsep(&cp, ", "), "", 33);
Packit 6c4009
  equal(strsep(&cp, ", "), "", 34);
Packit 6c4009
  equal(strsep(&cp, ", "), "", 35);
Packit 6c4009
  check(strsep(&cp, ", ") == NULL, 36);	/* No tokens. */
Packit 6c4009
  cp = strcpy(one, "");
Packit 6c4009
  equal(strsep(&cp, ", "), "", 37);
Packit 6c4009
  check(strsep(&cp, ", ") == NULL, 38);	/* Empty string. */
Packit 6c4009
  cp = strcpy(one, "abc");
Packit 6c4009
  equal(strsep(&cp, ", "), "abc", 39);	/* No delimiters. */
Packit 6c4009
  check(strsep(&cp, ", ") == NULL, 40);
Packit 6c4009
  cp = strcpy(one, "abc");
Packit 6c4009
  equal(strsep(&cp, ""), "abc", 41);	/* Empty delimiter list. */
Packit 6c4009
  check(strsep(&cp, "") == NULL, 42);
Packit 6c4009
  (void) strcpy(one, "abcdefgh");
Packit 6c4009
  cp = strcpy(one, "a,b,c");
Packit 6c4009
  equal(strsep(&cp, ","), "a", 43);	/* Basics again... */
Packit 6c4009
  equal(strsep(&cp, ","), "b", 44);
Packit 6c4009
  equal(strsep(&cp, ","), "c", 45);
Packit 6c4009
  check(strsep(&cp, ",") == NULL, 46);
Packit 6c4009
  equal(one+6, "gh", 47);		/* Stomped past end? */
Packit 6c4009
  equal(one, "a", 48);			/* Stomped old tokens? */
Packit 6c4009
  equal(one+2, "b", 49);
Packit 6c4009
  equal(one+4, "c", 50);
Packit 6c4009
Packit 6c4009
  {
Packit 6c4009
    char text[] = "This,is,a,test";
Packit 6c4009
    char *list = strdupa (text);
Packit 6c4009
    equal (strsep (&list, ","), "This", 51);
Packit 6c4009
    equal (strsep (&list, ","), "is", 52);
Packit 6c4009
    equal (strsep (&list, ","), "a", 53);
Packit 6c4009
    equal (strsep (&list, ","), "test", 54);
Packit 6c4009
    check (strsep (&list, ",") == NULL, 55);
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  cp = strcpy(one, "a,b, c,, ,d,");
Packit 6c4009
  equal(strsep(&cp, ","), "a", 56);	/* Different separators. */
Packit 6c4009
  equal(strsep(&cp, ","), "b", 57);
Packit 6c4009
  equal(strsep(&cp, ","), " c", 58);	/* Permute list too. */
Packit 6c4009
  equal(strsep(&cp, ","), "", 59);
Packit 6c4009
  equal(strsep(&cp, ","), " ", 60);
Packit 6c4009
  equal(strsep(&cp, ","), "d", 61);
Packit 6c4009
  equal(strsep(&cp, ","), "", 62);
Packit 6c4009
  check(strsep(&cp, ",") == NULL, 63);
Packit 6c4009
  check(strsep(&cp, ",") == NULL, 64);	/* Persistence. */
Packit 6c4009
Packit 6c4009
  cp = strcpy(one, "a,b, c,, ,d,");
Packit 6c4009
  equal(strsep(&cp, "xy,"), "a", 65);	/* Different separators. */
Packit 6c4009
  equal(strsep(&cp, "x,y"), "b", 66);
Packit 6c4009
  equal(strsep(&cp, ",xy"), " c", 67);	/* Permute list too. */
Packit 6c4009
  equal(strsep(&cp, "xy,"), "", 68);
Packit 6c4009
  equal(strsep(&cp, "x,y"), " ", 69);
Packit 6c4009
  equal(strsep(&cp, ",xy"), "d", 70);
Packit 6c4009
  equal(strsep(&cp, "xy,"), "", 71);
Packit 6c4009
  check(strsep(&cp, "x,y") == NULL, 72);
Packit 6c4009
  check(strsep(&cp, ",xy") == NULL, 73);	/* Persistence. */
Packit 6c4009
Packit 6c4009
  cp = strcpy(one, "ABC");
Packit 6c4009
  one[4] = ':';
Packit 6c4009
  equal(strsep(&cp, "C"), "AB", 74);	/* Access beyond NUL.  */
Packit 6c4009
  ptr = strsep(&cp, ":");
Packit 6c4009
  equal(ptr, "", 75);
Packit 6c4009
  check(ptr == one + 3, 76);
Packit 6c4009
  check(cp == NULL, 77);
Packit 6c4009
Packit 6c4009
  cp = strcpy(one, "ABC");
Packit 6c4009
  one[4] = ':';
Packit 6c4009
  equal(strsep(&cp, "CD"), "AB", 78);	/* Access beyond NUL.  */
Packit 6c4009
  ptr = strsep(&cp, ":.");
Packit 6c4009
  equal(ptr, "", 79);
Packit 6c4009
  check(ptr == one + 3, 80);
Packit 6c4009
Packit 6c4009
  cp = strcpy(one, "ABC");		/* No token in string.  */
Packit 6c4009
  equal(strsep(&cp, ","), "ABC", 81);
Packit 6c4009
  check(cp == NULL, 82);
Packit 6c4009
Packit 6c4009
  *one = '\0';				/* Empty string. */
Packit 6c4009
  cp = one;
Packit 6c4009
  ptr = strsep(&cp, ",");
Packit 6c4009
  equal(ptr, "", 83);
Packit 6c4009
  check(ptr == one, 84);
Packit 6c4009
  check(cp == NULL, 85);
Packit 6c4009
Packit 6c4009
  *one = '\0';				/* Empty string and no token. */
Packit 6c4009
  cp = one;
Packit 6c4009
  ptr = strsep(&cp, "");
Packit 6c4009
  equal(ptr, "", 86);
Packit 6c4009
  check(ptr == one , 87);
Packit 6c4009
  check(cp == NULL, 88);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_memcmp (void)
Packit 6c4009
{
Packit 6c4009
  int cnt = 1;
Packit 6c4009
  char one[21];
Packit 6c4009
  char two[21];
Packit 6c4009
Packit 6c4009
  it = "memcmp";
Packit 6c4009
  check(memcmp("a", "a", 1) == 0, cnt++);	/* Identity. */
Packit 6c4009
  check(memcmp("abc", "abc", 3) == 0, cnt++);	/* Multicharacter. */
Packit 6c4009
  check(memcmp("abcd", "abcf", 4) < 0, cnt++);	/* Honestly unequal. */
Packit 6c4009
  check(memcmp("abcf", "abcd", 4) > 0, cnt++);
Packit 6c4009
  check(memcmp("alph", "cold", 4) < 0, cnt++);
Packit 6c4009
  check(memcmp("a\203", "a\003", 2) > 0, cnt++);
Packit 6c4009
  check(memcmp("a\003", "a\203", 2) < 0, cnt++);
Packit 6c4009
  check(memcmp("a\003bc", "a\203bc", 2) < 0, cnt++);
Packit 6c4009
  check(memcmp("abc\203", "abc\003", 4) > 0, cnt++);
Packit 6c4009
  check(memcmp("abc\003", "abc\203", 4) < 0, cnt++);
Packit 6c4009
  check(memcmp("abcf", "abcd", 3) == 0, cnt++);	/* Count limited. */
Packit 6c4009
  check(memcmp("abc", "def", 0) == 0, cnt++);	/* Zero count. */
Packit 6c4009
  /* Comparisons with shifting 4-byte boundaries. */
Packit 6c4009
  for (int i = 0; i < 4; ++i)
Packit 6c4009
    {
Packit 6c4009
      char *a = one + i;
Packit 6c4009
      char *b = two + i;
Packit 6c4009
      memcpy(a, "--------11112222", 16);
Packit 6c4009
      memcpy(b, "--------33334444", 16);
Packit 6c4009
      check(memcmp(b, a, 16) > 0, cnt++);
Packit 6c4009
      check(memcmp(a, b, 16) < 0, cnt++);
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_memchr (void)
Packit 6c4009
{
Packit 6c4009
  it = "memchr";
Packit 6c4009
  check(memchr("abcd", 'z', 4) == NULL, 1);	/* Not found. */
Packit 6c4009
  (void) strcpy(one, "abcd");
Packit 6c4009
  check(memchr(one, 'c', 4) == one+2, 2);	/* Basic test. */
Packit 6c4009
  check(memchr(one, ~0xff|'c', 4) == one+2, 2);	/* ignore highorder bits. */
Packit 6c4009
  check(memchr(one, 'd', 4) == one+3, 3);	/* End of string. */
Packit 6c4009
  check(memchr(one, 'a', 4) == one, 4);	/* Beginning. */
Packit 6c4009
  check(memchr(one, '\0', 5) == one+4, 5);	/* Finding NUL. */
Packit 6c4009
  (void) strcpy(one, "ababa");
Packit 6c4009
  check(memchr(one, 'b', 5) == one+1, 6);	/* Finding first. */
Packit 6c4009
  check(memchr(one, 'b', 0) == NULL, 7);	/* Zero count. */
Packit 6c4009
  check(memchr(one, 'a', 1) == one, 8);	/* Singleton case. */
Packit 6c4009
  (void) strcpy(one, "a\203b");
Packit 6c4009
  check(memchr(one, 0203, 3) == one+1, 9);	/* Unsignedness. */
Packit 6c4009
Packit 6c4009
  /* now test all possible alignment and length combinations to catch
Packit 6c4009
     bugs due to unrolled loops (assuming unrolling is limited to no
Packit 6c4009
     more than 128 byte chunks: */
Packit 6c4009
  {
Packit 6c4009
    char buf[128 + sizeof(long)];
Packit 6c4009
    long align, len, i, pos;
Packit 6c4009
Packit 6c4009
    for (align = 0; align < (long) sizeof(long); ++align) {
Packit 6c4009
      for (len = 0; len < (long) (sizeof(buf) - align); ++len) {
Packit 6c4009
	for (i = 0; i < len; ++i) {
Packit 6c4009
	  buf[align + i] = 'x';		/* don't depend on memset... */
Packit 6c4009
	}
Packit 6c4009
	for (pos = 0; pos < len; ++pos) {
Packit 6c4009
#if 0
Packit 6c4009
	  printf("align %d, len %d, pos %d\n", align, len, pos);
Packit 6c4009
#endif
Packit 6c4009
	  check(memchr(buf + align, 'x', len) == buf + align + pos, 10);
Packit 6c4009
	  check(memchr(buf + align, 'x', pos) == NULL, 11);
Packit 6c4009
	  buf[align + pos] = '-';
Packit 6c4009
	}
Packit 6c4009
      }
Packit 6c4009
    }
Packit 6c4009
  }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_memcpy (void)
Packit 6c4009
{
Packit 6c4009
  int i;
Packit 6c4009
  it = "memcpy";
Packit 6c4009
  check(memcpy(one, "abc", 4) == one, 1);	/* Returned value. */
Packit 6c4009
  equal(one, "abc", 2);			/* Did the copy go right? */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abcdefgh");
Packit 6c4009
  (void) memcpy(one+1, "xyz", 2);
Packit 6c4009
  equal(one, "axydefgh", 3);		/* Basic test. */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abc");
Packit 6c4009
  (void) memcpy(one, "xyz", 0);
Packit 6c4009
  equal(one, "abc", 4);			/* Zero-length copy. */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "hi there");
Packit 6c4009
  (void) strcpy(two, "foo");
Packit 6c4009
  (void) memcpy(two, one, 9);
Packit 6c4009
  equal(two, "hi there", 5);		/* Just paranoia. */
Packit 6c4009
  equal(one, "hi there", 6);		/* Stomped on source? */
Packit 6c4009
Packit 6c4009
  for (i = 0; i < 16; i++)
Packit 6c4009
    {
Packit 6c4009
      const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
Packit 6c4009
      strcpy (one, x);
Packit 6c4009
      check (memcpy (one + i, "hi there", 9) == one + i,
Packit 6c4009
	     7 + (i * 6));		/* Unaligned destination. */
Packit 6c4009
      check (memcmp (one, x, i) == 0, 8 + (i * 6));  /* Wrote under? */
Packit 6c4009
      equal (one + i, "hi there", 9 + (i * 6));
Packit 6c4009
      check (one[i + 9] == 'x', 10 + (i * 6));       /* Wrote over? */
Packit 6c4009
      check (memcpy (two, one + i, 9) == two,
Packit 6c4009
	     11 + (i * 6));		/* Unaligned source. */
Packit 6c4009
      equal (two, "hi there", 12 + (i * 6));
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_mempcpy (void)
Packit 6c4009
{
Packit 6c4009
  int i;
Packit 6c4009
  it = "mempcpy";
Packit 6c4009
  check(mempcpy(one, "abc", 4) == one + 4, 1);	/* Returned value. */
Packit 6c4009
  equal(one, "abc", 2);			/* Did the copy go right? */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abcdefgh");
Packit 6c4009
  (void) mempcpy(one+1, "xyz", 2);
Packit 6c4009
  equal(one, "axydefgh", 3);		/* Basic test. */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abc");
Packit 6c4009
  (void) mempcpy(one, "xyz", 0);
Packit 6c4009
  equal(one, "abc", 4);			/* Zero-length copy. */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "hi there");
Packit 6c4009
  (void) strcpy(two, "foo");
Packit 6c4009
  (void) mempcpy(two, one, 9);
Packit 6c4009
  equal(two, "hi there", 5);		/* Just paranoia. */
Packit 6c4009
  equal(one, "hi there", 6);		/* Stomped on source? */
Packit 6c4009
Packit 6c4009
  for (i = 0; i < 16; i++)
Packit 6c4009
    {
Packit 6c4009
      const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
Packit 6c4009
      strcpy (one, x);
Packit 6c4009
      check (mempcpy (one + i, "hi there", 9) == one + i + 9,
Packit 6c4009
	     7 + (i * 6));		/* Unaligned destination. */
Packit 6c4009
      check (memcmp (one, x, i) == 0, 8 + (i * 6));  /* Wrote under? */
Packit 6c4009
      equal (one + i, "hi there", 9 + (i * 6));
Packit 6c4009
      check (one[i + 9] == 'x', 10 + (i * 6));       /* Wrote over? */
Packit 6c4009
      check (mempcpy (two, one + i, 9) == two + 9,
Packit 6c4009
	     11 + (i * 6));		/* Unaligned source. */
Packit 6c4009
      equal (two, "hi there", 12 + (i * 6));
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_memmove (void)
Packit 6c4009
{
Packit 6c4009
  it = "memmove";
Packit 6c4009
  check(memmove(one, "abc", 4) == one, 1);	/* Returned value. */
Packit 6c4009
  equal(one, "abc", 2);			/* Did the copy go right? */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abcdefgh");
Packit 6c4009
  (void) memmove(one+1, "xyz", 2);
Packit 6c4009
  equal(one, "axydefgh", 3);		/* Basic test. */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abc");
Packit 6c4009
  (void) memmove(one, "xyz", 0);
Packit 6c4009
  equal(one, "abc", 4);			/* Zero-length copy. */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "hi there");
Packit 6c4009
  (void) strcpy(two, "foo");
Packit 6c4009
  (void) memmove(two, one, 9);
Packit 6c4009
  equal(two, "hi there", 5);		/* Just paranoia. */
Packit 6c4009
  equal(one, "hi there", 6);		/* Stomped on source? */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abcdefgh");
Packit 6c4009
  (void) memmove(one+1, one, 9);
Packit 6c4009
  equal(one, "aabcdefgh", 7);		/* Overlap, right-to-left. */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abcdefgh");
Packit 6c4009
  (void) memmove(one+1, one+2, 7);
Packit 6c4009
  equal(one, "acdefgh", 8);		/* Overlap, left-to-right. */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abcdefgh");
Packit 6c4009
  (void) memmove(one, one, 9);
Packit 6c4009
  equal(one, "abcdefgh", 9);		/* 100% overlap. */
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_memccpy (void)
Packit 6c4009
{
Packit 6c4009
  /* First test like memcpy, then the search part The SVID, the only
Packit 6c4009
     place where memccpy is mentioned, says overlap might fail, so we
Packit 6c4009
     don't try it.  Besides, it's hard to see the rationale for a
Packit 6c4009
     non-left-to-right memccpy.  */
Packit 6c4009
  it = "memccpy";
Packit 6c4009
  check(memccpy(one, "abc", 'q', 4) == NULL, 1);	/* Returned value. */
Packit 6c4009
  equal(one, "abc", 2);			/* Did the copy go right? */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abcdefgh");
Packit 6c4009
  (void) memccpy(one+1, "xyz", 'q', 2);
Packit 6c4009
  equal(one, "axydefgh", 3);		/* Basic test. */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abc");
Packit 6c4009
  (void) memccpy(one, "xyz", 'q', 0);
Packit 6c4009
  equal(one, "abc", 4);			/* Zero-length copy. */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "hi there");
Packit 6c4009
  (void) strcpy(two, "foo");
Packit 6c4009
  (void) memccpy(two, one, 'q', 9);
Packit 6c4009
  equal(two, "hi there", 5);		/* Just paranoia. */
Packit 6c4009
  equal(one, "hi there", 6);		/* Stomped on source? */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abcdefgh");
Packit 6c4009
  (void) strcpy(two, "horsefeathers");
Packit 6c4009
  check(memccpy(two, one, 'f', 9) == two+6, 7);	/* Returned value. */
Packit 6c4009
  equal(one, "abcdefgh", 8);		/* Source intact? */
Packit 6c4009
  equal(two, "abcdefeathers", 9);		/* Copy correct? */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abcd");
Packit 6c4009
  (void) strcpy(two, "bumblebee");
Packit 6c4009
  check(memccpy(two, one, 'a', 4) == two+1, 10);	/* First char. */
Packit 6c4009
  equal(two, "aumblebee", 11);
Packit 6c4009
  check(memccpy(two, one, 'd', 4) == two+4, 12);	/* Last char. */
Packit 6c4009
  equal(two, "abcdlebee", 13);
Packit 6c4009
  (void) strcpy(one, "xyz");
Packit 6c4009
  check(memccpy(two, one, 'x', 1) == two+1, 14);	/* Singleton. */
Packit 6c4009
  equal(two, "xbcdlebee", 15);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_memset (void)
Packit 6c4009
{
Packit 6c4009
  int i;
Packit 6c4009
Packit 6c4009
  it = "memset";
Packit 6c4009
  (void) strcpy(one, "abcdefgh");
Packit 6c4009
  check(memset(one+1, 'x', 3) == one+1, 1);	/* Return value. */
Packit 6c4009
  equal(one, "axxxefgh", 2);		/* Basic test. */
Packit 6c4009
Packit 6c4009
  DIAG_PUSH_NEEDS_COMMENT;
Packit 6c4009
#if __GNUC_PREREQ (5, 0)
Packit 6c4009
  /* GCC 5.0 warns about a zero-length memset because the arguments to memset
Packit 6c4009
     may be in the wrong order.  But we really want to test this.  */
Packit 6c4009
  DIAG_IGNORE_NEEDS_COMMENT (5.0, "-Wmemset-transposed-args")
Packit 6c4009
#endif
Packit 6c4009
  (void) memset(one+2, 'y', 0);
Packit 6c4009
  equal(one, "axxxefgh", 3);		/* Zero-length set. */
Packit 6c4009
  DIAG_POP_NEEDS_COMMENT;
Packit 6c4009
Packit 6c4009
  (void) memset(one+5, 0, 1);
Packit 6c4009
  equal(one, "axxxe", 4);			/* Zero fill. */
Packit 6c4009
  equal(one+6, "gh", 5);			/* And the leftover. */
Packit 6c4009
Packit 6c4009
  (void) memset(one+2, 010045, 1);
Packit 6c4009
  equal(one, "ax\045xe", 6);		/* Unsigned char convert. */
Packit 6c4009
Packit 6c4009
  /* Non-8bit fill character.  */
Packit 6c4009
  memset (one, 0x101, sizeof (one));
Packit 6c4009
  for (i = 0; i < (int) sizeof (one); ++i)
Packit 6c4009
    check (one[i] == '\01', 7);
Packit 6c4009
Packit 6c4009
  /* Test for more complex versions of memset, for all alignments and
Packit 6c4009
     lengths up to 256. This test takes a little while, perhaps it should
Packit 6c4009
     be made weaker?  */
Packit 6c4009
  {
Packit 6c4009
    char data[512];
Packit 6c4009
    int j;
Packit 6c4009
    int k;
Packit 6c4009
    int c;
Packit 6c4009
Packit 6c4009
    for (i = 0; i < 512; i++)
Packit 6c4009
      data[i] = 'x';
Packit 6c4009
    for (c = 0; c <= 'y'; c += 'y')  /* check for memset(,0,) and
Packit 6c4009
					memset(,'y',) */
Packit 6c4009
      for (j = 0; j < 256; j++)
Packit 6c4009
	for (i = 0; i < 256; i++)
Packit 6c4009
	  {
Packit 6c4009
	    memset (data + i, c, j);
Packit 6c4009
	    for (k = 0; k < i; k++)
Packit 6c4009
	      if (data[k] != 'x')
Packit 6c4009
		goto fail;
Packit 6c4009
	    for (k = i; k < i+j; k++)
Packit 6c4009
	      {
Packit 6c4009
		if (data[k] != c)
Packit 6c4009
		  goto fail;
Packit 6c4009
		data[k] = 'x';
Packit 6c4009
	      }
Packit 6c4009
	    for (k = i+j; k < 512; k++)
Packit 6c4009
	      if (data[k] != 'x')
Packit 6c4009
		goto fail;
Packit 6c4009
	    continue;
Packit 6c4009
Packit 6c4009
	  fail:
Packit 6c4009
	    check (0, 8 + i + j * 256 + (c != 0) * 256 * 256);
Packit 6c4009
	  }
Packit 6c4009
  }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_bcopy (void)
Packit 6c4009
{
Packit 6c4009
  /* Much like memcpy.  Berklix manual is silent about overlap, so
Packit 6c4009
     don't test it.  */
Packit 6c4009
  it = "bcopy";
Packit 6c4009
  (void) bcopy("abc", one, 4);
Packit 6c4009
  equal(one, "abc", 1);			/* Simple copy. */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abcdefgh");
Packit 6c4009
  (void) bcopy("xyz", one+1, 2);
Packit 6c4009
  equal(one, "axydefgh", 2);		/* Basic test. */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abc");
Packit 6c4009
  (void) bcopy("xyz", one, 0);
Packit 6c4009
  equal(one, "abc", 3);			/* Zero-length copy. */
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "hi there");
Packit 6c4009
  (void) strcpy(two, "foo");
Packit 6c4009
  (void) bcopy(one, two, 9);
Packit 6c4009
  equal(two, "hi there", 4);		/* Just paranoia. */
Packit 6c4009
  equal(one, "hi there", 5);		/* Stomped on source? */
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_bzero (void)
Packit 6c4009
{
Packit 6c4009
  it = "bzero";
Packit 6c4009
  (void) strcpy(one, "abcdef");
Packit 6c4009
  bzero(one+2, 2);
Packit 6c4009
  equal(one, "ab", 1);			/* Basic test. */
Packit 6c4009
  equal(one+3, "", 2);
Packit 6c4009
  equal(one+4, "ef", 3);
Packit 6c4009
Packit 6c4009
  (void) strcpy(one, "abcdef");
Packit 6c4009
  bzero(one+2, 0);
Packit 6c4009
  equal(one, "abcdef", 4);		/* Zero-length copy. */
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strndup (void)
Packit 6c4009
{
Packit 6c4009
  char *p, *q;
Packit 6c4009
  it = "strndup";
Packit 6c4009
  p = strndup("abcdef", 12);
Packit 6c4009
  check(p != NULL, 1);
Packit 6c4009
  if (p != NULL)
Packit 6c4009
    {
Packit 6c4009
      equal(p, "abcdef", 2);
Packit 6c4009
      q = strndup(p + 1, 2);
Packit 6c4009
      check(q != NULL, 3);
Packit 6c4009
      if (q != NULL)
Packit 6c4009
	equal(q, "bc", 4);
Packit 6c4009
      free (q);
Packit 6c4009
    }
Packit 6c4009
  free (p);
Packit 6c4009
  p = strndup("abc def", 3);
Packit 6c4009
  check(p != NULL, 5);
Packit 6c4009
  if (p != NULL)
Packit 6c4009
    equal(p, "abc", 6);
Packit 6c4009
  free (p);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_bcmp (void)
Packit 6c4009
{
Packit 6c4009
  it = "bcmp";
Packit 6c4009
  check(bcmp("a", "a", 1) == 0, 1);	/* Identity. */
Packit 6c4009
  check(bcmp("abc", "abc", 3) == 0, 2);	/* Multicharacter. */
Packit 6c4009
  check(bcmp("abcd", "abce", 4) != 0, 3);	/* Honestly unequal. */
Packit 6c4009
  check(bcmp("abce", "abcd", 4) != 0, 4);
Packit 6c4009
  check(bcmp("alph", "beta", 4) != 0, 5);
Packit 6c4009
  check(bcmp("abce", "abcd", 3) == 0, 6);	/* Count limited. */
Packit 6c4009
  check(bcmp("abc", "def", 0) == 0, 8);	/* Zero count. */
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strerror (void)
Packit 6c4009
{
Packit 6c4009
  it = "strerror";
Packit 6c4009
  check(strerror(EDOM) != 0, 1);
Packit 6c4009
  check(strerror(ERANGE) != 0, 2);
Packit 6c4009
  check(strerror(ENOENT) != 0, 3);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strcasecmp (void)
Packit 6c4009
{
Packit 6c4009
  it = "strcasecmp";
Packit 6c4009
  /* Note that the locale is "C".  */
Packit 6c4009
  check(strcasecmp("a", "a") == 0, 1);
Packit 6c4009
  check(strcasecmp("a", "A") == 0, 2);
Packit 6c4009
  check(strcasecmp("A", "a") == 0, 3);
Packit 6c4009
  check(strcasecmp("a", "b") < 0, 4);
Packit 6c4009
  check(strcasecmp("c", "b") > 0, 5);
Packit 6c4009
  check(strcasecmp("abc", "AbC") == 0, 6);
Packit 6c4009
  check(strcasecmp("0123456789", "0123456789") == 0, 7);
Packit 6c4009
  check(strcasecmp("", "0123456789") < 0, 8);
Packit 6c4009
  check(strcasecmp("AbC", "") > 0, 9);
Packit 6c4009
  check(strcasecmp("AbC", "A") > 0, 10);
Packit 6c4009
  check(strcasecmp("AbC", "Ab") > 0, 11);
Packit 6c4009
  check(strcasecmp("AbC", "ab") > 0, 12);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
test_strncasecmp (void)
Packit 6c4009
{
Packit 6c4009
  it = "strncasecmp";
Packit 6c4009
  /* Note that the locale is "C".  */
Packit 6c4009
  check(strncasecmp("a", "a", 5) == 0, 1);
Packit 6c4009
  check(strncasecmp("a", "A", 5) == 0, 2);
Packit 6c4009
  check(strncasecmp("A", "a", 5) == 0, 3);
Packit 6c4009
  check(strncasecmp("a", "b", 5) < 0, 4);
Packit 6c4009
  check(strncasecmp("c", "b", 5) > 0, 5);
Packit 6c4009
  check(strncasecmp("abc", "AbC", 5) == 0, 6);
Packit 6c4009
  check(strncasecmp("0123456789", "0123456789", 10) == 0, 7);
Packit 6c4009
  check(strncasecmp("", "0123456789", 10) < 0, 8);
Packit 6c4009
  check(strncasecmp("AbC", "", 5) > 0, 9);
Packit 6c4009
  check(strncasecmp("AbC", "A", 5) > 0, 10);
Packit 6c4009
  check(strncasecmp("AbC", "Ab", 5) > 0, 11);
Packit 6c4009
  check(strncasecmp("AbC", "ab", 5) > 0, 12);
Packit 6c4009
  check(strncasecmp("0123456789", "AbC", 0) == 0, 13);
Packit 6c4009
  check(strncasecmp("AbC", "abc", 1) == 0, 14);
Packit 6c4009
  check(strncasecmp("AbC", "abc", 2) == 0, 15);
Packit 6c4009
  check(strncasecmp("AbC", "abc", 3) == 0, 16);
Packit 6c4009
  check(strncasecmp("AbC", "abcd", 3) == 0, 17);
Packit 6c4009
  check(strncasecmp("AbC", "abcd", 4) < 0, 18);
Packit 6c4009
  check(strncasecmp("ADC", "abcd", 1) == 0, 19);
Packit 6c4009
  check(strncasecmp("ADC", "abcd", 2) > 0, 20);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
main (void)
Packit 6c4009
{
Packit 6c4009
  int status;
Packit 6c4009
Packit 6c4009
  /* Test strcmp first because we use it to test other things.  */
Packit 6c4009
  test_strcmp ();
Packit 6c4009
Packit 6c4009
  /* Test strcpy next because we need it to set up other tests.  */
Packit 6c4009
  test_strcpy ();
Packit 6c4009
Packit 6c4009
  /* A closely related function is stpcpy.  */
Packit 6c4009
  test_stpcpy ();
Packit 6c4009
Packit 6c4009
  /* stpncpy.  */
Packit 6c4009
  test_stpncpy ();
Packit 6c4009
Packit 6c4009
  /* strcat.  */
Packit 6c4009
  test_strcat ();
Packit 6c4009
Packit 6c4009
  /* strncat.  */
Packit 6c4009
  test_strncat ();
Packit 6c4009
Packit 6c4009
  /* strncmp.  */
Packit 6c4009
  test_strncmp ();
Packit 6c4009
Packit 6c4009
  /* strncpy.  */
Packit 6c4009
  test_strncpy ();
Packit 6c4009
Packit 6c4009
  /* strlen.  */
Packit 6c4009
  test_strlen ();
Packit 6c4009
Packit 6c4009
  /* strnlen.  */
Packit 6c4009
  test_strnlen ();
Packit 6c4009
Packit 6c4009
  /* strchr.  */
Packit 6c4009
  test_strchr ();
Packit 6c4009
Packit 6c4009
  /* strchrnul.  */
Packit 6c4009
  test_strchrnul ();
Packit 6c4009
Packit 6c4009
  /* rawmemchr.  */
Packit 6c4009
  test_rawmemchr ();
Packit 6c4009
Packit 6c4009
  /* index - just like strchr.  */
Packit 6c4009
  test_index ();
Packit 6c4009
Packit 6c4009
  /* strrchr.  */
Packit 6c4009
  test_strrchr ();
Packit 6c4009
Packit 6c4009
  /* memrchr.  */
Packit 6c4009
  test_memrchr ();
Packit 6c4009
Packit 6c4009
  /* rindex - just like strrchr.  */
Packit 6c4009
  test_rindex ();
Packit 6c4009
Packit 6c4009
  /* strpbrk - somewhat like strchr.  */
Packit 6c4009
  test_strpbrk ();
Packit 6c4009
Packit 6c4009
  /* strstr - somewhat like strchr.  */
Packit 6c4009
  test_strstr ();
Packit 6c4009
Packit 6c4009
  /* strspn.  */
Packit 6c4009
  test_strspn ();
Packit 6c4009
Packit 6c4009
  /* strcspn.  */
Packit 6c4009
  test_strcspn ();
Packit 6c4009
Packit 6c4009
  /* strtok - the hard one.  */
Packit 6c4009
  test_strtok ();
Packit 6c4009
Packit 6c4009
  /* strtok_r.  */
Packit 6c4009
  test_strtok_r ();
Packit 6c4009
Packit 6c4009
  /* strsep.  */
Packit 6c4009
  test_strsep ();
Packit 6c4009
Packit 6c4009
  /* memcmp.  */
Packit 6c4009
  test_memcmp ();
Packit 6c4009
Packit 6c4009
  /* memchr.  */
Packit 6c4009
  test_memchr ();
Packit 6c4009
Packit 6c4009
  /* memcpy - need not work for overlap.  */
Packit 6c4009
  test_memcpy ();
Packit 6c4009
Packit 6c4009
  /* memmove - must work on overlap.  */
Packit 6c4009
  test_memmove ();
Packit 6c4009
Packit 6c4009
  /* mempcpy */
Packit 6c4009
  test_mempcpy ();
Packit 6c4009
Packit 6c4009
  /* memccpy.  */
Packit 6c4009
  test_memccpy ();
Packit 6c4009
Packit 6c4009
  /* memset.  */
Packit 6c4009
  test_memset ();
Packit 6c4009
Packit 6c4009
  /* bcopy.  */
Packit 6c4009
  test_bcopy ();
Packit 6c4009
Packit 6c4009
  /* bzero.  */
Packit 6c4009
  test_bzero ();
Packit 6c4009
Packit 6c4009
  /* bcmp - somewhat like memcmp.  */
Packit 6c4009
  test_bcmp ();
Packit 6c4009
Packit 6c4009
  /* strndup.  */
Packit 6c4009
  test_strndup ();
Packit 6c4009
Packit 6c4009
  /* strerror - VERY system-dependent.  */
Packit 6c4009
  test_strerror ();
Packit 6c4009
Packit 6c4009
  /* strcasecmp.  Without locale dependencies.  */
Packit 6c4009
  test_strcasecmp ();
Packit 6c4009
Packit 6c4009
  /* strncasecmp.  Without locale dependencies.  */
Packit 6c4009
  test_strncasecmp ();
Packit 6c4009
Packit 6c4009
  if (errors == 0)
Packit 6c4009
    {
Packit 6c4009
      status = EXIT_SUCCESS;
Packit 6c4009
      puts("No errors.");
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      status = EXIT_FAILURE;
Packit 6c4009
      printf("%Zd errors.\n", errors);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  return status;
Packit 6c4009
}