Back to index

glibc  2.9
test-strcpy.c
Go to the documentation of this file.
00001 /* Test and measure strcpy functions.
00002    Copyright (C) 1999, 2002, 2003, 2005 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Written by Jakub Jelinek <jakub@redhat.com>, 1999.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #ifndef STRCPY_RESULT
00022 # define STRCPY_RESULT(dst, len) dst
00023 # define TEST_MAIN
00024 # include "test-string.h"
00025 
00026 char *simple_strcpy (char *, const char *);
00027 
00028 IMPL (simple_strcpy, 0)
00029 IMPL (strcpy, 1)
00030 
00031 char *
00032 simple_strcpy (char *dst, const char *src)
00033 {
00034   char *ret = dst;
00035   while ((*dst++ = *src++) != '\0');
00036   return ret;
00037 }
00038 #endif
00039 
00040 typedef char *(*proto_t) (char *, const char *);
00041 
00042 static void
00043 do_one_test (impl_t *impl, char *dst, const char *src,
00044             size_t len __attribute__((unused)))
00045 {
00046   if (CALL (impl, dst, src) != STRCPY_RESULT (dst, len))
00047     {
00048       error (0, 0, "Wrong result in function %s %p %p", impl->name,
00049             CALL (impl, dst, src), STRCPY_RESULT (dst, len));
00050       ret = 1;
00051       return;
00052     }
00053 
00054   if (strcmp (dst, src) != 0)
00055     {
00056       error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"",
00057             impl->name, dst, src);
00058       ret = 1;
00059       return;
00060     }
00061 
00062   if (HP_TIMING_AVAIL)
00063     {
00064       hp_timing_t start __attribute ((unused));
00065       hp_timing_t stop __attribute ((unused));;
00066       hp_timing_t best_time = ~ (hp_timing_t) 0;
00067       size_t i;
00068 
00069       for (i = 0; i < 32; ++i)
00070        {
00071          HP_TIMING_NOW (start);
00072          CALL (impl, dst, src);
00073          HP_TIMING_NOW (stop);
00074          HP_TIMING_BEST (best_time, start, stop);
00075        }
00076 
00077       printf ("\t%zd", (size_t) best_time);
00078     }
00079 }
00080 
00081 static void
00082 do_test (size_t align1, size_t align2, size_t len, int max_char)
00083 {
00084   size_t i;
00085   char *s1, *s2;
00086 
00087   align1 &= 7;
00088   if (align1 + len >= page_size)
00089     return;
00090 
00091   align2 &= 7;
00092   if (align2 + len >= page_size)
00093     return;
00094 
00095   s1 = (char *) (buf1 + align1);
00096   s2 = (char *) (buf2 + align2);
00097 
00098   for (i = 0; i < len; i++)
00099     s1[i] = 32 + 23 * i % (max_char - 32);
00100   s1[len] = 0;
00101 
00102   if (HP_TIMING_AVAIL)
00103     printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2);
00104 
00105   FOR_EACH_IMPL (impl, 0)
00106     do_one_test (impl, s2, s1, len);
00107 
00108   if (HP_TIMING_AVAIL)
00109     putchar ('\n');
00110 }
00111 
00112 static void
00113 do_random_tests (void)
00114 {
00115   size_t i, j, n, align1, align2, len;
00116   unsigned char *p1 = buf1 + page_size - 512;
00117   unsigned char *p2 = buf2 + page_size - 512;
00118   unsigned char *res;
00119 
00120   for (n = 0; n < ITERATIONS; n++)
00121     {
00122       align1 = random () & 31;
00123       if (random () & 1)
00124        align2 = random () & 31;
00125       else
00126        align2 = align1 + (random () & 24);
00127       len = random () & 511;
00128       j = align1;
00129       if (align2 > j)
00130        j = align2;
00131       if (len + j >= 511)
00132        len = 510 - j - (random () & 7);
00133       j = len + align1 + 64;
00134       if (j > 512)
00135        j = 512;
00136       for (i = 0; i < j; i++)
00137        {
00138          if (i == len + align1)
00139            p1[i] = 0;
00140          else
00141            {
00142              p1[i] = random () & 255;
00143              if (i >= align1 && i < len + align1 && !p1[i])
00144               p1[i] = (random () & 127) + 3;
00145            }
00146        }
00147 
00148       FOR_EACH_IMPL (impl, 1)
00149        {
00150          memset (p2 - 64, '\1', 512 + 64);
00151          res = (unsigned char *) CALL (impl, (char *) (p2 + align2),
00152                                    (char *) (p1 + align1));
00153          if (res != STRCPY_RESULT (p2 + align2, len))
00154            {
00155              error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
00156                    n, impl->name, align1, align2, len, res,
00157                    STRCPY_RESULT (p2 + align2, len));
00158              ret = 1;
00159            }
00160          for (j = 0; j < align2 + 64; ++j)
00161            {
00162              if (p2[j - 64] != '\1')
00163               {
00164                 error (0, 0, "Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
00165                       n, impl->name, align1, align2, len);
00166                 ret = 1;
00167                 break;
00168               }
00169            }
00170          for (j = align2 + len + 1; j < 512; ++j)
00171            {
00172              if (p2[j] != '\1')
00173               {
00174                 error (0, 0, "Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
00175                       n, impl->name, align1, align2, len);
00176                 ret = 1;
00177                 break;
00178               }
00179            }
00180          if (memcmp (p1 + align1, p2 + align2, len + 1))
00181            {
00182              error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)",
00183                    n, impl->name, align1, align2, len);
00184              ret = 1;
00185            }
00186        }
00187     }
00188 }
00189 
00190 int
00191 test_main (void)
00192 {
00193   size_t i;
00194 
00195   test_init ();
00196 
00197   printf ("%23s", "");
00198   FOR_EACH_IMPL (impl, 0)
00199     printf ("\t%s", impl->name);
00200   putchar ('\n');
00201 
00202   for (i = 0; i < 16; ++i)
00203     {
00204       do_test (0, 0, i, 127);
00205       do_test (0, 0, i, 255);
00206       do_test (0, i, i, 127);
00207       do_test (i, 0, i, 255);
00208     }
00209 
00210   for (i = 1; i < 8; ++i)
00211     {
00212       do_test (0, 0, 8 << i, 127);
00213       do_test (8 - i, 2 * i, 8 << i, 127);
00214     }
00215 
00216   for (i = 1; i < 8; ++i)
00217     {
00218       do_test (i, 2 * i, 8 << i, 127);
00219       do_test (2 * i, i, 8 << i, 255);
00220       do_test (i, i, 8 << i, 127);
00221       do_test (i, i, 8 << i, 255);
00222     }
00223 
00224   do_random_tests ();
00225   return ret;
00226 }
00227 
00228 #include "../test-skeleton.c"