LTP GCOV extension - code coverage report
Current view: directory - src - vstr_srch.c
Test: Vstr coverage
Date: 2005-01-10 Instrumented lines: 238
Code covered: 100.0 % Executed lines: 238

       1                 : #define VSTR_SRCH_C
       2                 : /*
       3                 :  *  Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004  James Antill
       4                 :  *
       5                 :  *  This library is free software; you can redistribute it and/or
       6                 :  *  modify it under the terms of the GNU Lesser General Public
       7                 :  *  License as published by the Free Software Foundation; either
       8                 :  *  version 2 of the License, or (at your option) any later version.
       9                 :  *
      10                 :  *  This library is distributed in the hope that it will be useful,
      11                 :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      12                 :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13                 :  *  Lesser General Public License for more details.
      14                 :  *
      15                 :  *  You should have received a copy of the GNU Lesser General Public
      16                 :  *  License along with this library; if not, write to the Free Software
      17                 :  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      18                 :  *
      19                 :  *  email: james@and.org
      20                 :  */
      21                 : /* functions for searching within a vstr */
      22                 : #include "main.h"
      23                 : 
      24                 : size_t vstr_srch_chr_fwd(const Vstr_base *base, size_t pos, size_t len,
      25                 :                          char srch)
      26          156290 : {
      27          156290 :   Vstr_iter iter[1];
      28          156290 :   char *found = NULL;
      29                 : 
      30          156290 :   if (!vstr_iter_fwd_beg(base, pos, len, iter))
      31             643 :     return (0);
      32                 : 
      33          182897 :   ASSERT(len == vstr_iter_len(iter));
      34                 : 
      35          190131 :   do
      36                 :   {
      37          190131 :     if (iter->node->type != VSTR_TYPE_NODE_NON)
      38                 :     {
      39          190127 :       found = vstr_wrap_memchr(iter->ptr, srch, iter->len);
      40          190127 :       if (found)
      41           35799 :         return (vstr_iter_pos(iter, pos, len) + (found - iter->ptr));
      42                 :     }
      43          154332 :   } while (vstr_iter_fwd_nxt(iter));
      44                 : 
      45          119848 :   return (0);
      46                 : }
      47                 : 
      48                 : static size_t vstr__srch_chr_rev_slow(const Vstr_base *base,
      49                 :                                       size_t pos, size_t len,
      50                 :                                       char srch)
      51             302 : {
      52             302 :   size_t ret = 0;
      53             302 :   size_t scan_pos = pos;
      54             302 :   size_t scan_len = len;
      55                 : 
      56             776 :   while (scan_len)
      57                 :   {
      58             697 :     size_t tmp = 0;
      59                 : 
      60             697 :     assert(scan_pos < (pos + len));
      61                 : 
      62             697 :     if (!(tmp = vstr_srch_chr_fwd(base, scan_pos, scan_len, srch)))
      63             223 :       break;
      64                 : 
      65             474 :     ret = tmp;
      66                 : 
      67             474 :     scan_pos = ret + 1;
      68             474 :     scan_len = len - VSTR_SC_POSDIFF(pos, ret);
      69                 :   }
      70                 : 
      71             302 :   return (ret);
      72                 : }
      73                 : 
      74                 : static size_t vstr__srch_chr_rev_fast(const Vstr_base *base,
      75                 :                                       size_t pos, size_t len,
      76                 :                                       char srch)
      77             104 : {
      78             104 :   unsigned int num = 0;
      79             104 :   unsigned int type = 0;
      80             104 :   char *scan_str = NULL;
      81             104 :   size_t scan_len = 0;
      82             104 :   char *found = NULL;
      83                 : 
      84             104 :   if (!vstr__base_scan_rev_beg(base, pos, &len, &num, &type,
      85                 :                                &scan_str, &scan_len))
      86              16 :     return (0);
      87                 : 
      88             260 :   do
      89                 :   {
      90             260 :     if (type != VSTR_TYPE_NODE_NON)
      91                 :     {
      92             256 :       found = vstr_wrap_memrchr(scan_str, srch, scan_len);
      93             256 :       if (found)
      94              80 :         return (pos + len + (found - scan_str));
      95                 :     }
      96             180 :   } while (vstr__base_scan_rev_nxt(base, &len, &num, &type,
      97                 :                                    &scan_str, &scan_len));
      98                 : 
      99               8 :   return (0);
     100                 : }
     101                 : 
     102                 : size_t vstr_srch_chr_rev(const Vstr_base *base, size_t pos, size_t len,
     103                 :                          char srch)
     104             406 : {
     105             406 :   if (base->iovec_upto_date)
     106             104 :     return (vstr__srch_chr_rev_fast(base, pos, len, srch));
     107                 : 
     108             302 :   return (vstr__srch_chr_rev_slow(base, pos, len, srch));
     109                 : }
     110                 : 
     111                 : size_t vstr_srch_chrs_fwd(const Vstr_base *base, size_t pos, size_t len,
     112                 :                           const char *srch, size_t chrs_len)
     113           49842 : {
     114           49842 :   size_t num = vstr_cspn_chrs_fwd(base, pos, len, srch, chrs_len);
     115                 : 
     116           49842 :   if (num == len)
     117            9880 :     return (0);
     118                 : 
     119           39962 :   return (pos + num);
     120                 : }
     121                 : 
     122                 : size_t vstr_srch_chrs_rev(const Vstr_base *base, size_t pos, size_t len,
     123                 :                           const char *srch, size_t chrs_len)
     124             125 : {
     125             125 :   size_t num = vstr_cspn_chrs_rev(base, pos, len, srch, chrs_len);
     126                 : 
     127             125 :   if (num == len)
     128              25 :     return (0);
     129                 : 
     130             100 :   return (pos + ((len - num) - 1));
     131                 : }
     132                 : 
     133                 : size_t vstr_csrch_chrs_fwd(const Vstr_base *base, size_t pos, size_t len,
     134                 :                            const char *srch, size_t chrs_len)
     135              45 : {
     136              45 :   size_t num = vstr_spn_chrs_fwd(base, pos, len, srch, chrs_len);
     137                 : 
     138              45 :   if (num == len)
     139               5 :     return (0);
     140                 : 
     141              40 :   return (pos + num);
     142                 : }
     143                 : 
     144                 : size_t vstr_csrch_chrs_rev(const Vstr_base *base, size_t pos, size_t len,
     145                 :                            const char *srch, size_t chrs_len)
     146              45 : {
     147              45 :   size_t num = vstr_spn_chrs_rev(base, pos, len, srch, chrs_len);
     148                 : 
     149              45 :   if (num == len)
     150               5 :     return (0);
     151                 : 
     152              40 :   return (pos + ((len - num) - 1));
     153                 : }
     154                 : 
     155                 : size_t vstr_srch_buf_fwd(const Vstr_base *base, size_t pos, size_t len,
     156                 :                          const void *const str, const size_t str_len)
     157          138719 : {
     158          138719 :   Vstr_iter iter[1];
     159                 : 
     160          138719 :   if (!len || (str_len > len))
     161            3433 :     return (0);
     162                 : 
     163          135286 :   if (!str_len)
     164            1232 :     return (pos);
     165                 : 
     166          134054 :   if (!str && !base->node_non_used)
     167               4 :     return (0);
     168                 : 
     169          134050 :   if (str && (str_len == 1))
     170           22693 :     return (vstr_srch_chr_fwd(base, pos, len, *(const char *)str));
     171                 : 
     172          111357 :   if (!vstr_iter_fwd_beg(base, pos, len, iter))
     173               8 :     return (0);
     174                 : 
     175         3554680 :   assert(len == vstr_iter_len(iter));
     176                 : 
     177         5334465 :   do
     178                 :   {
     179         5334465 :     if ((iter->node->type == VSTR_TYPE_NODE_NON) && !str)
     180                 :     {
     181             596 :       if (!vstr_cmp_buf(base, vstr_iter_pos(iter, pos, len), str_len,
     182                 :                         NULL, str_len))
     183             484 :         return (vstr_iter_pos(iter, pos, len));
     184         5333869 :       goto next_loop;
     185                 :     }
     186         5333869 :     if (!str)
     187             778 :       goto next_loop;
     188                 : 
     189         5333091 :     if (iter->node->type == VSTR_TYPE_NODE_NON)
     190              20 :       goto next_loop;
     191                 : 
     192                 :     /* find buf */
     193         5487996 :     while (vstr_iter_len(iter) >= str_len)
     194                 :     {
     195         5484367 :       size_t tmp = 0;
     196         5484367 :       size_t beg_pos = 0;
     197                 : 
     198         5484367 :       assert(iter->len);
     199                 : 
     200         5484367 :       if (*iter->ptr != *(const char *)str)
     201                 :       {
     202         5343268 :         char *som = NULL; /* start of a possible match */
     203                 : 
     204         5343268 :         if (!(som = vstr_wrap_memchr(iter->ptr, *(const char *)str,iter->len)))
     205         5236560 :           goto next_loop;
     206          106708 :         iter->len -= (som - iter->ptr);
     207          106708 :         iter->ptr = som;
     208          106708 :         continue;
     209                 :       }
     210                 : 
     211          141099 :       tmp = iter->len;
     212          141099 :       if (tmp > str_len)
     213          101940 :         tmp = str_len;
     214                 : 
     215          141099 :       beg_pos = vstr_iter_pos(iter, pos, len);
     216                 : 
     217          141099 :       if (!vstr_wrap_memcmp(iter->ptr, str, tmp) &&
     218                 :           ((tmp == str_len) ||
     219                 :            !vstr_cmp_buf(base, beg_pos + tmp, str_len - tmp,
     220                 :                          (const char *)str + tmp, str_len - tmp)))
     221           80798 :         return (beg_pos);
     222                 : 
     223           60301 :       ++iter->ptr;
     224           60301 :       --iter->len;
     225                 : 
     226           60301 :       if (!iter->len) break;
     227                 :     }
     228                 : 
     229                 :    next_loop:
     230         5253183 :     continue;
     231         5253183 :   } while (vstr_iter_fwd_nxt(iter) && (vstr_iter_len(iter) >= str_len));
     232                 : 
     233           30067 :   return (0);
     234                 : }
     235                 : 
     236                 : static size_t vstr__srch_buf_rev_slow(const Vstr_base *base,
     237                 :                                       size_t pos, size_t len,
     238                 :                                       const void *const str,
     239                 :                                       const size_t str_len)
     240             120 : {
     241             120 :   size_t ret = 0;
     242             120 :   size_t scan_pos = pos;
     243             120 :   size_t scan_len = len;
     244                 : 
     245             304 :   while (scan_len >= str_len)
     246                 :   {
     247             288 :     size_t tmp = 0;
     248                 : 
     249             288 :     assert(scan_pos < (pos + len));
     250                 : 
     251             288 :     if (!(tmp = vstr_srch_buf_fwd(base, scan_pos, scan_len, str, str_len)))
     252             104 :       break;
     253                 : 
     254             184 :     ret = tmp;
     255                 : 
     256             184 :     scan_pos = ret + 1;
     257             184 :     scan_len = len - VSTR_SC_POSDIFF(pos, ret);
     258                 :   }
     259                 : 
     260             120 :   return (ret);
     261                 : }
     262                 : 
     263                 : /* only to be used from srch_buf_rev_fast ... assumes a bunch of crap */
     264                 : static int vstr__cmp_eq_rev_buf(const Vstr_base *base, size_t len,
     265                 :                                 unsigned int num, unsigned int type,
     266                 :                                 const char *str, size_t str_len,
     267                 :                                 char *scan_str, size_t scan_len)
     268             140 : {
     269             140 :   assert((type != VSTR_TYPE_NODE_NON) && str && str_len &&
     270                 :          scan_str && scan_len);
     271                 :   
     272             140 :   if (str_len > (len + scan_len))
     273               8 :     return (FALSE);
     274                 :   
     275             216 :   while (str_len)
     276                 :   {
     277             168 :     size_t tmp = scan_len;
     278                 : 
     279             168 :     if (type == VSTR_TYPE_NODE_NON)
     280               4 :       return (FALSE);
     281                 :     
     282             164 :     if (tmp > str_len)
     283              76 :       tmp = str_len;
     284                 : 
     285             164 :     if (vstr_wrap_memcmp((str + str_len) - tmp,
     286                 :                          (scan_str + scan_len) - tmp, tmp))
     287              80 :       return (FALSE);
     288              84 :     ASSERT(tmp);
     289                 :     
     290              84 :     str_len  -= tmp;
     291              84 :     scan_len -= tmp;
     292              84 :     if (!scan_len)
     293              60 :       tmp = vstr__base_scan_rev_nxt(base, &len, &num, &type,
     294                 :                                     &scan_str, &scan_len);
     295              66 :     ASSERT(tmp || (!str_len && !scan_len));
     296                 :   }
     297                 :   
     298              48 :   return (TRUE);
     299                 : }
     300                 : 
     301                 : /* only to be used from srch_buf_rev_fast ... assumes a bunch of crap */
     302                 : static int vstr__cmp_eq_rev_non(const Vstr_base *base, size_t len,
     303                 :                                 unsigned int num, unsigned int type,
     304                 :                                 size_t str_len, size_t scan_len)
     305              32 : {
     306              32 :   char *scan_str = NULL;
     307              32 :   int tmp = FALSE;
     308                 :   
     309              32 :   assert(type == VSTR_TYPE_NODE_NON);
     310                 :   
     311              32 :   if (str_len > (len + scan_len))
     312               4 :     return (FALSE);
     313                 : 
     314              60 :   while (type == VSTR_TYPE_NODE_NON)
     315                 :   {
     316              48 :     if (str_len <= scan_len)
     317              16 :       return (TRUE);
     318                 : 
     319              32 :     str_len -= scan_len;
     320                 : 
     321              32 :     tmp = vstr__base_scan_rev_nxt(base, &len, &num, &type,
     322                 :                                   &scan_str, &scan_len);
     323              32 :     ASSERT(tmp);
     324                 :   }
     325                 : 
     326              12 :   return (FALSE);
     327                 : }
     328                 : 
     329                 : static size_t vstr__srch_buf_rev_fast(const Vstr_base *base,
     330                 :                                       size_t pos, size_t len,
     331                 :                                       const void *const str,
     332                 :                                       size_t str_len)
     333             136 : {
     334             136 :   unsigned int num = 0;
     335             136 :   unsigned int type = 0;
     336             136 :   char *scan_str = NULL;
     337             136 :   size_t scan_len = 0;
     338             136 :   size_t orig_len = len;
     339             136 :   const char *end_str = ((const char *)str) + (str_len - 1);
     340                 : 
     341             136 :   if (!vstr__base_scan_rev_beg(base, pos, &len, &num, &type,
     342                 :                                &scan_str, &scan_len))
     343               8 :     return (0);
     344                 : 
     345             566 :   assert(orig_len == (len + scan_len));
     346                 : 
     347             712 :   do
     348                 :   {
     349             712 :     size_t count = 0;
     350                 : 
     351             712 :     if ((type == VSTR_TYPE_NODE_NON) && !str)
     352                 :     {
     353              32 :       if (vstr__cmp_eq_rev_non(base, len, num, type, str_len, scan_len))
     354              16 :         return ((pos + len + scan_len) - str_len);
     355             680 :       continue;
     356                 :     }
     357                 : 
     358             680 :     if (!str)
     359             172 :       continue;
     360                 : 
     361             508 :     if (type == VSTR_TYPE_NODE_NON)
     362              32 :       continue;
     363                 : 
     364                 :     /* find buf */
     365            2264 :     while (count < scan_len)
     366                 :     {
     367            1836 :       size_t rest = 0;
     368            1836 :       size_t len_end = 0;
     369                 : 
     370            1836 :       ++count;
     371            1836 :       rest = scan_len - count;
     372            1836 :       if (scan_str[scan_len - count] != end_str[0])
     373                 :       {
     374            1804 :         char *som = NULL; /* start of a possible match */
     375                 : 
     376            1804 :         if (!rest || !(som = vstr_wrap_memrchr(scan_str, end_str[0], rest)))
     377            1280 :           continue;
     378             108 :         count += ((scan_str + rest) - som);
     379             108 :         rest = scan_len - count;
     380                 :       }
     381             140 :       assert(scan_str[scan_len - count] == end_str[0]);
     382                 : 
     383             140 :       len_end = VSTR_SC_POSDIFF(count, scan_len);
     384             140 :       if (vstr__cmp_eq_rev_buf(base, len, num, type,
     385                 :                                str,      str_len,
     386                 :                                scan_str, len_end))
     387              48 :         return ((pos + len + len_end) - str_len);
     388                 :     }
     389             648 :   } while (vstr__base_scan_rev_nxt(base, &len, &num, &type,
     390                 :                                    &scan_str, &scan_len));
     391                 : 
     392              64 :   return (0);
     393                 : }
     394                 : 
     395                 : size_t vstr_srch_buf_rev(const Vstr_base *base, size_t pos, size_t len,
     396                 :                          const void *const str, const size_t str_len)
     397            1624 : {
     398            1624 :   if (!len || (str_len > len))
     399              64 :     return (0);
     400                 : 
     401            1560 :   if (!str_len)
     402            1252 :     return (pos + len - 1);
     403                 : 
     404             308 :   if (str && (str_len == 1))
     405              52 :     return (vstr_srch_chr_rev(base, pos, len, *(const char *)str));
     406                 : 
     407             256 :   if (base->iovec_upto_date)
     408             136 :     return (vstr__srch_buf_rev_fast(base, pos, len, str, str_len));
     409                 : 
     410             120 :   return (vstr__srch_buf_rev_slow(base, pos, len, str, str_len));
     411                 : }
     412                 : 
     413                 : size_t vstr_srch_vstr_fwd(const Vstr_base *base, size_t pos, size_t len,
     414                 :                           const Vstr_base *ndl_base,
     415                 :                           size_t ndl_pos, size_t ndl_len)
     416             336 : { /* TODO: this could be faster, esp. with NON nodes */
     417             336 :   Vstr_iter iter[1];
     418             336 :   size_t scan_pos = pos;
     419             336 :   size_t scan_len = len;
     420                 : 
     421             336 :   if (ndl_len > len)
     422              40 :     return (0);
     423                 : 
     424             296 :   if (!vstr_iter_fwd_beg(ndl_base, ndl_pos, ndl_len, iter))
     425               8 :     return (0);
     426                 : 
     427             436 :   while ((scan_pos < vstr_sc_poslast(pos, len)) && (scan_len >= ndl_len))
     428                 :   {
     429             432 :     if (!vstr_cmp(base, scan_pos, ndl_len, ndl_base, ndl_pos, ndl_len))
     430             184 :       return (scan_pos);
     431                 : 
     432             248 :     --scan_len;
     433             248 :     ++scan_pos;
     434                 : 
     435             248 :     if (iter->node->type != VSTR_TYPE_NODE_NON)
     436                 :     {
     437             248 :       size_t tmp = 0;
     438                 : 
     439             248 :       if (!(tmp = vstr_srch_buf_fwd(base, scan_pos, scan_len,
     440                 :                                     iter->ptr, iter->len)))
     441             100 :         return (0);
     442                 : 
     443             148 :       ASSERT(tmp >= scan_pos);
     444             148 :       scan_len -= tmp - scan_pos;
     445             148 :       scan_pos = tmp;
     446                 :     }
     447                 :   }
     448                 : 
     449               4 :   return (0);
     450                 : }
     451                 : 
     452                 : static size_t vstr__srch_vstr_rev_slow(const Vstr_base *base,
     453                 :                                        size_t pos, size_t len,
     454                 :                                        const Vstr_base *ndl_base,
     455                 :                                        size_t ndl_pos, size_t ndl_len)
     456             140 : {
     457             140 :   size_t ret = 0;
     458             140 :   size_t scan_pos = pos;
     459             140 :   size_t scan_len = len;
     460                 : 
     461             240 :   while (scan_len >= ndl_len)
     462                 :   {
     463             180 :     size_t tmp = 0;
     464                 : 
     465             180 :     assert(scan_pos < (pos + len));
     466                 : 
     467             180 :     if (!(tmp = vstr_srch_vstr_fwd(base, scan_pos, scan_len,
     468                 :                                    ndl_base, ndl_pos, ndl_len)))
     469              80 :       break;
     470                 : 
     471             100 :     ret = tmp;
     472                 : 
     473             100 :     scan_pos = ret + 1;
     474             100 :     scan_len = len - VSTR_SC_POSDIFF(pos, ret);
     475                 :   }
     476                 : 
     477             140 :   return (ret);
     478                 : }
     479                 : 
     480                 : size_t vstr_srch_vstr_rev(const Vstr_base *base, size_t pos, size_t len,
     481                 :                           const Vstr_base *ndl_base,
     482                 :                           size_t ndl_pos, size_t ndl_len)
     483             140 : {
     484             140 :   return (vstr__srch_vstr_rev_slow(base, pos, len, ndl_base, ndl_pos, ndl_len));
     485                 : }
     486                 : 

Generated by: LTP GCOV extension version 1.1