Back to index

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