Back to index

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