Back to index

glibc  2.9
test-strchr.c
Go to the documentation of this file.
00001 /* Test and measure strchr functions.
00002    Copyright (C) 1999, 2002, 2003 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 #define TEST_MAIN
00022 #include "test-string.h"
00023 
00024 typedef char *(*proto_t) (const char *, int);
00025 char *simple_strchr (const char *, int);
00026 char *stupid_strchr (const char *, int);
00027 
00028 IMPL (stupid_strchr, 0)
00029 IMPL (simple_strchr, 0)
00030 IMPL (strchr, 1)
00031 
00032 char *
00033 simple_strchr (const char *s, int c)
00034 {
00035   for (; *s != (char) c; ++s)
00036     if (*s == '\0')
00037       return NULL;
00038   return (char *) s;
00039 }
00040 
00041 char *
00042 stupid_strchr (const char *s, int c)
00043 {
00044   size_t n = strlen (s) + 1;
00045 
00046   while (n--)
00047     if (*s++ == (char) c)
00048       return (char *) s - 1;
00049   return NULL;
00050 }
00051 
00052 static void
00053 do_one_test (impl_t *impl, const char *s, int c, char *exp_res)
00054 {
00055   char *res = CALL (impl, s, c);
00056   if (res != exp_res)
00057     {
00058       error (0, 0, "Wrong result in function %s %p %p", impl->name,
00059             res, exp_res);
00060       ret = 1;
00061       return;
00062     }
00063 
00064   if (HP_TIMING_AVAIL)
00065     {
00066       hp_timing_t start __attribute ((unused));
00067       hp_timing_t stop __attribute ((unused));
00068       hp_timing_t best_time = ~ (hp_timing_t) 0;
00069       size_t i;
00070 
00071       for (i = 0; i < 32; ++i)
00072        {
00073          HP_TIMING_NOW (start);
00074          CALL (impl, s, c);
00075          HP_TIMING_NOW (stop);
00076          HP_TIMING_BEST (best_time, start, stop);
00077        }
00078 
00079       printf ("\t%zd", (size_t) best_time);
00080     }
00081 }
00082 
00083 static void
00084 do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char)
00085 {
00086   size_t i;
00087   char *result;
00088 
00089   align &= 7;
00090   if (align + len >= page_size)
00091     return;
00092 
00093   for (i = 0; i < len; ++i)
00094     {
00095       buf1[align + i] = 32 + 23 * i % (max_char - 32);
00096       if (buf1[align + i] == seek_char)
00097         buf1[align + i] = seek_char + 1;
00098     }
00099   buf1[align + len] = 0;
00100 
00101   if (pos < len)
00102     {
00103       buf1[align + pos] = seek_char;
00104       result = (char *) (buf1 + align + pos);
00105     }
00106   else if (seek_char == 0)
00107     result = (char *) (buf1 + align + len);
00108   else
00109     result = NULL;
00110 
00111   if (HP_TIMING_AVAIL)
00112     printf ("Length %4zd, alignment %2zd:", pos, align);
00113 
00114   FOR_EACH_IMPL (impl, 0)
00115     do_one_test (impl, (char *) (buf1 + align), seek_char, result);
00116 
00117   if (HP_TIMING_AVAIL)
00118     putchar ('\n');
00119 }
00120 
00121 static void
00122 do_random_tests (void)
00123 {
00124   size_t i, j, n, align, pos, len;
00125   int seek_char;
00126   char *result;
00127   unsigned char *p = buf1 + page_size - 512;
00128 
00129   for (n = 0; n < ITERATIONS; n++)
00130     {
00131       align = random () & 15;
00132       pos = random () & 511;
00133       seek_char = random () & 255;
00134       if (pos + align >= 511)
00135        pos = 510 - align - (random () & 7);
00136       len = random () & 511;
00137       if ((pos == len && seek_char)
00138          || (pos > len && (random () & 1)))
00139        len = pos + 1 + (random () & 7);
00140       if (len + align >= 512)
00141         len = 511 - align - (random () & 7);
00142       if (pos == len && seek_char)
00143        len = pos + 1;
00144       j = (pos > len ? pos : len) + align + 64;
00145       if (j > 512)
00146         j = 512;
00147 
00148       for (i = 0; i < j; i++)
00149        {
00150          if (i == pos + align)
00151            p[i] = seek_char;
00152          else if (i == len + align)
00153            p[i] = 0;
00154          else
00155            {
00156              p[i] = random () & 255;
00157              if (i < pos + align && p[i] == seek_char)
00158               p[i] = seek_char + 13;
00159              if (i < len + align && !p[i])
00160               {
00161                 p[i] = seek_char - 13;
00162                 if (!p[i])
00163                   p[i] = 140;
00164               }
00165            }
00166        }
00167 
00168       if (pos <= len)
00169        result = (char *) (p + pos + align);
00170       else if (seek_char == 0)
00171        result = (char *) (p + len + align);
00172       else
00173        result = NULL;
00174 
00175       FOR_EACH_IMPL (impl, 1)
00176        if (CALL (impl, (char *) (p + align), seek_char) != result)
00177          {
00178            error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p",
00179                  n, impl->name, align, seek_char, len, pos,
00180                  CALL (impl, (char *) (p + align), seek_char), result, p);
00181            ret = 1;
00182          }
00183     }
00184 }
00185 
00186 int
00187 test_main (void)
00188 {
00189   size_t i;
00190 
00191   test_init ();
00192 
00193   printf ("%20s", "");
00194   FOR_EACH_IMPL (impl, 0)
00195     printf ("\t%s", impl->name);
00196   putchar ('\n');
00197 
00198   for (i = 1; i < 8; ++i)
00199     {
00200       do_test (0, 16 << i, 2048, 23, 127);
00201       do_test (i, 16 << i, 2048, 23, 127);
00202     }
00203 
00204   for (i = 1; i < 8; ++i)
00205     {
00206       do_test (i, 64, 256, 23, 127);
00207       do_test (i, 64, 256, 23, 255);
00208     }
00209 
00210   for (i = 0; i < 32; ++i)
00211     {
00212       do_test (0, i, i + 1, 23, 127);
00213       do_test (0, i, i + 1, 23, 255);
00214     }
00215 
00216   for (i = 1; i < 8; ++i)
00217     {
00218       do_test (0, 16 << i, 2048, 0, 127);
00219       do_test (i, 16 << i, 2048, 0, 127);
00220     }
00221 
00222   for (i = 1; i < 8; ++i)
00223     {
00224       do_test (i, 64, 256, 0, 127);
00225       do_test (i, 64, 256, 0, 255);
00226     }
00227 
00228   for (i = 0; i < 32; ++i)
00229     {
00230       do_test (0, i, i + 1, 0, 127);
00231       do_test (0, i, i + 1, 0, 255);
00232     }
00233 
00234   do_random_tests ();
00235   return ret;
00236 }
00237 
00238 #include "../test-skeleton.c"