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

       1                 : #define VSTR_SPLIT_C
       2                 : /*
       3                 :  *  Copyright (C) 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 to split a Vstr into sections (ala. perl split()) */
      22                 : #include "main.h"
      23                 : 
      24                 : 
      25                 : #define VSTR__SPLIT_LIM(x) (!limit || (limit > (x)))
      26                 : 
      27                 : /* do the null fields go to the end ? */
      28                 : static int vstr__split_buf_null_end(const Vstr_base *base,
      29                 :                                     size_t pos, size_t len,
      30                 :                                     const void *buf, size_t buf_len,
      31                 :                                     unsigned int *ret_num)
      32             435 : {
      33             435 :   assert(vstr_cmp_buf_eq(base, pos, buf_len, buf, buf_len));
      34             435 :   assert(len >= buf_len);
      35                 : 
      36             435 :   *ret_num = 1;
      37                 : 
      38             435 :   if (len == buf_len)
      39               5 :     return (TRUE);
      40                 : 
      41             430 :   pos += buf_len;
      42             430 :   len -= buf_len;
      43                 : 
      44             611 :   while (len >= buf_len)
      45                 :   {
      46             577 :     if (!vstr_cmp_buf_eq(base, pos, buf_len, buf, buf_len))
      47             396 :       return (FALSE);
      48                 : 
      49             181 :     ++*ret_num;
      50             181 :     pos += buf_len;
      51             181 :     len -= buf_len;
      52                 :   }
      53                 : 
      54              34 :   return (!len);
      55                 : }
      56                 : 
      57                 : static unsigned int vstr__split_hdl_err(Vstr_sects *sects,
      58                 :                                         unsigned int flags, unsigned int added,
      59                 :                                         int *bad_ret)
      60             190 : {
      61             190 :   ASSERT(bad_ret);
      62             190 :   ASSERT(!*bad_ret);
      63                 :   
      64             190 :   if (sects->malloc_bad)
      65                 :   {
      66              10 :     ASSERT(sects->num >= added);
      67              10 :     sects->num -= added;
      68              10 :     *bad_ret = TRUE;
      69              10 :     return (0);
      70                 :   }
      71                 :   
      72             180 :   ASSERT(!sects->can_add_sz);
      73             180 :   ASSERT(sects->num == sects->sz);
      74                 :   
      75             180 :   if (flags & VSTR_FLAG_SPLIT_NO_RET)
      76              10 :     *bad_ret = TRUE;
      77                 :   
      78             180 :   return (1);
      79                 : }
      80                 :     
      81                 : #define VSTR__SPLIT_HDL_ERR(bad_ret) do {                               \
      82                 :       unsigned int err_ret = vstr__split_hdl_err(sects, flags, added,   \
      83                 :                                                  bad_ret);              \
      84                 :                                                                         \
      85                 :       if (*bad_ret)                                                     \
      86                 :         return (err_ret);                                               \
      87                 :     } while (FALSE)
      88                 : 
      89                 : static unsigned int vstr__split_hdl_null_beg(size_t *pos, size_t *len,
      90                 :                                              size_t buf_len,
      91                 :                                              Vstr_sects *sects,
      92                 :                                              unsigned int flags,
      93                 :                                              unsigned int count,
      94                 :                                              unsigned int limit,
      95                 :                                              unsigned int added,
      96                 :                                              int *bad_ret)
      97             227 : {
      98             227 :   const int is_remain = !!(flags & VSTR_FLAG_SPLIT_REMAIN);
      99                 : 
     100             227 :   ASSERT(count);
     101                 : 
     102             227 :   if (limit && (count >= (limit - added)))
     103               5 :     count = (limit - is_remain) - added;
     104                 : 
     105             609 :   while (count)
     106                 :   {
     107             384 :     if (flags & VSTR_FLAG_SPLIT_BEG_NULL)
     108                 :     {
     109             144 :       if (!vstr_sects_add(sects, *pos, 0))
     110              42 :         VSTR__SPLIT_HDL_ERR(bad_ret);
     111                 : 
     112             142 :       ++added;
     113                 :     }
     114                 : 
     115             382 :     *pos += buf_len;
     116             382 :     *len -= buf_len;
     117             382 :     --count;
     118                 :   }
     119                 : 
     120             225 :   return (added);
     121                 : }
     122                 : 
     123                 : static unsigned int vstr__split_hdl_null_mid(size_t *pos, size_t *len,
     124                 :                                              size_t buf_len,
     125                 :                                              Vstr_sects *sects,
     126                 :                                              unsigned int flags,
     127                 :                                              unsigned int count,
     128                 :                                              unsigned int limit,
     129                 :                                              unsigned int added,
     130                 :                                              int *bad_ret)
     131            2157 : {
     132            2157 :   const int is_remain = !!(flags & VSTR_FLAG_SPLIT_REMAIN);
     133                 : 
     134            2157 :   ASSERT(count);
     135                 : 
     136            2157 :   if (limit && (count >= (limit - added)))
     137              26 :     count = (limit - is_remain) - added;
     138                 : 
     139            5744 :   while (count)
     140                 :   {
     141            3589 :     if (flags & VSTR_FLAG_SPLIT_MID_NULL)
     142                 :     {
     143             202 :       if (!vstr_sects_add(sects, *pos, 0))
     144              27 :         VSTR__SPLIT_HDL_ERR(bad_ret);
     145                 : 
     146             200 :       ++added;
     147                 :     }
     148                 : 
     149            3587 :     *pos += buf_len;
     150            3587 :     *len -= buf_len;
     151            3587 :     --count;
     152                 :   }
     153                 : 
     154            2155 :   return (added);
     155                 : }
     156                 : 
     157                 : static unsigned int vstr__split_hdl_null_end(size_t pos, size_t len,
     158                 :                                              size_t buf_len,
     159                 :                                              Vstr_sects *sects,
     160                 :                                              unsigned int flags,
     161                 :                                              unsigned int count,
     162                 :                                              unsigned int limit,
     163                 :                                              unsigned int added)
     164              49 : {
     165              49 :   const int is_remain = !!(flags & VSTR_FLAG_SPLIT_REMAIN);
     166              49 :   int bad_ret = FALSE;
     167                 :   
     168              49 :   assert(len);
     169                 : 
     170              49 :   if (!(flags & VSTR_FLAG_SPLIT_END_NULL))
     171              11 :     goto no_end_null;
     172                 : 
     173              38 :   if (limit && (count >= (limit - added)))
     174               6 :     count = (limit - is_remain) - added;
     175                 : 
     176             125 :   while (count)
     177                 :   {
     178              90 :     if (!vstr_sects_add(sects, pos, 0))
     179              28 :       VSTR__SPLIT_HDL_ERR(&bad_ret);
     180                 : 
     181              87 :     ++added;
     182                 : 
     183              87 :     pos += buf_len;
     184              87 :     len -= buf_len;
     185              87 :     --count;
     186                 :   }
     187                 : 
     188                 :  no_end_null:
     189              46 :   if (((len &&  (flags & VSTR_FLAG_SPLIT_REMAIN)) ||
     190                 :        (!len && (flags & VSTR_FLAG_SPLIT_POST_NULL))))
     191                 :   {
     192              31 :     if (!vstr_sects_add(sects, pos, len))
     193               6 :       VSTR__SPLIT_HDL_ERR(&bad_ret);
     194              30 :     ++added;
     195                 :   }
     196                 : 
     197              45 :   return (added);
     198                 : }
     199                 : 
     200                 : static unsigned int vstr__split_hdl_end(size_t pos, size_t len,
     201                 :                                         size_t split_pos,
     202                 :                                         Vstr_sects *sects,
     203                 :                                         unsigned int limit, unsigned int flags,
     204                 :                                         unsigned int added)
     205            9696 : {
     206            9696 :   int bad_ret = FALSE;
     207                 :   
     208            9696 :   if (len)
     209                 :   {
     210            9612 :     if (flags & VSTR_FLAG_SPLIT_REMAIN)
     211                 :     {
     212              46 :       ASSERT(!limit || (added <= (limit - 1)));
     213                 : 
     214              46 :       if (!vstr_sects_add(sects, pos, len))
     215               1 :         VSTR__SPLIT_HDL_ERR(&bad_ret);
     216                 : 
     217              45 :       ++added;
     218                 :     }
     219            9566 :     else if (!split_pos)
     220                 :     {
     221            9551 :       if (!vstr_sects_add(sects, pos, len))
     222              25 :         VSTR__SPLIT_HDL_ERR(&bad_ret);
     223                 : 
     224            9551 :       ++added;
     225                 :     }
     226                 :   }
     227              84 :   else if ((flags & VSTR_FLAG_SPLIT_POST_NULL) && (!limit || (added < limit)))
     228                 :   {
     229              16 :     if (!vstr_sects_add(sects, pos, 0))
     230               6 :       VSTR__SPLIT_HDL_ERR(&bad_ret);
     231                 :     
     232              15 :     ++added;
     233                 :   }
     234                 : 
     235            9694 :   return (added);
     236                 : }
     237                 : 
     238                 : static unsigned int vstr__split_hdl_def(size_t *pos, size_t *len,
     239                 :                                         size_t split_pos, size_t buf_len, 
     240                 :                                         Vstr_sects *sects,
     241                 :                                         unsigned int flags,
     242                 :                                         unsigned int added,
     243                 :                                         int *bad_ret)
     244           14284 : {
     245           14284 :   size_t split_len = (split_pos - *pos);
     246                 :   
     247           14284 :   ASSERT(split_pos > *pos);
     248                 :   
     249           14284 :   if (!vstr_sects_add(sects, *pos, split_len))
     250              55 :     VSTR__SPLIT_HDL_ERR(bad_ret);
     251                 :   
     252           14274 :   ++added;
     253                 :   
     254           14274 :   split_len += buf_len;
     255                 :   
     256           14274 :   *pos += split_len;
     257           14274 :   *len -= split_len;
     258                 :   
     259           14274 :   return (added);
     260                 : }
     261                 : 
     262                 : unsigned int vstr_split_buf(const Vstr_base *base, size_t pos, size_t len,
     263                 :                             const void *buf, size_t buf_len,
     264                 :                             Vstr_sects *sects,
     265                 :                             unsigned int limit, unsigned int flags)
     266             465 : {
     267             465 :   size_t orig_pos = pos;
     268             465 :   size_t split_pos = 0;
     269             465 :   unsigned int added = 0;
     270             465 :   const int is_remain = !!(flags & VSTR_FLAG_SPLIT_REMAIN);
     271             465 :   int bad_ret = FALSE;
     272                 :   
     273           11403 :   while (len && (!limit || (added < (limit - is_remain))) &&
     274                 :          (split_pos = vstr_srch_buf_fwd(base, pos, len, buf, buf_len)))
     275                 :   {
     276           10979 :     if (split_pos == orig_pos)
     277                 :     {
     278             167 :       unsigned int count = 0;
     279                 : 
     280             167 :       assert(orig_pos == pos);
     281                 : 
     282             167 :       if (vstr__split_buf_null_end(base, pos, len, buf, buf_len, &count))
     283                 :       {
     284              16 :         if (!(flags & VSTR_FLAG_SPLIT_BEG_NULL))
     285               5 :           return (0);
     286                 : 
     287              11 :         return (vstr__split_hdl_null_end(pos, len, buf_len, sects, flags,
     288                 :                                          count, limit, added));
     289                 :       }
     290             151 :       added = vstr__split_hdl_null_beg(&pos, &len, buf_len, sects, flags,
     291                 :                                        count, limit, added, &bad_ret);
     292             151 :       if (bad_ret)
     293               1 :         return (added);
     294                 :     }
     295           10812 :     else if (split_pos == pos)
     296                 :     {
     297             268 :       unsigned int count = 0;
     298                 : 
     299             268 :       if (vstr__split_buf_null_end(base, pos, len, buf, buf_len, &count))
     300              18 :         return (vstr__split_hdl_null_end(pos, len, buf_len, sects, flags,
     301                 :                                          count, limit, added));
     302             250 :       added = vstr__split_hdl_null_mid(&pos, &len, buf_len, sects, flags,
     303                 :                                        count, limit, added, &bad_ret);
     304             250 :       if (bad_ret)
     305               1 :         return (added);
     306                 :     }
     307                 :     else
     308                 :     {
     309           10544 :       added = vstr__split_hdl_def(&pos, &len, split_pos, buf_len, sects,
     310                 :                                   flags, added, &bad_ret);
     311           10544 :       if (bad_ret)
     312               5 :         return (added);
     313                 :     }
     314                 :   }
     315                 : 
     316             424 :   return (vstr__split_hdl_end(pos, len, split_pos, sects, limit, flags, added));
     317                 : }
     318                 : 
     319                 : unsigned int vstr_split_chrs(const Vstr_base *base, size_t pos, size_t len,
     320                 :                              const char *chrs, size_t chrs_len,
     321                 :                              Vstr_sects *sects,
     322                 :                              unsigned int limit, unsigned int flags)
     323            9304 : {
     324            9304 :   size_t orig_pos = pos;
     325            9304 :   size_t split_pos = 0;
     326            9304 :   unsigned int added = 0;
     327            9304 :   const int is_remain = !!(flags & VSTR_FLAG_SPLIT_REMAIN);
     328            9304 :   int bad_ret = FALSE;
     329                 : 
     330           15020 :   while (len && (!limit || (added < (limit - is_remain))) &&
     331                 :          (split_pos = vstr_srch_chrs_fwd(base, pos, len, chrs, chrs_len)))
     332                 :   {
     333            5748 :     if (split_pos == orig_pos)
     334                 :     {
     335              91 :       unsigned int count = 0;
     336                 : 
     337              91 :       assert(orig_pos == pos);
     338                 : 
     339              91 :       if ((count = vstr_spn_chrs_fwd(base, pos, len, chrs, chrs_len)) == len)
     340                 :       {
     341              15 :         if (!(flags & VSTR_FLAG_SPLIT_BEG_NULL))
     342               5 :           return (0);
     343                 : 
     344              10 :         return (vstr__split_hdl_null_end(pos, len, 1, sects, flags,
     345                 :                                          count, limit, added));
     346                 :       }
     347              76 :       added = vstr__split_hdl_null_beg(&pos, &len, 1, sects, flags,
     348                 :                                        count, limit, added, &bad_ret);
     349              76 :       if (bad_ret)
     350               1 :         return (added);
     351                 :     }
     352            5657 :     else if (split_pos == pos)
     353                 :     {
     354            1917 :       unsigned int count = 0;
     355                 : 
     356            1917 :       if ((count = vstr_spn_chrs_fwd(base, pos, len, chrs, chrs_len)) == len)
     357              10 :         return (vstr__split_hdl_null_end(pos, len, 1, sects, flags,
     358                 :                                          count, limit, added));
     359                 : 
     360            1907 :       added = vstr__split_hdl_null_mid(&pos, &len, 1, sects, flags,
     361                 :                                        count, limit, added, &bad_ret);
     362            1907 :       if (bad_ret)
     363               1 :         return (added);
     364                 :     }
     365                 :     else
     366                 :     {
     367            3740 :       added = vstr__split_hdl_def(&pos, &len, split_pos, 1, sects,
     368                 :                                   flags, added, &bad_ret);
     369            3740 :       if (bad_ret)
     370               5 :         return (added);
     371                 :     }
     372                 :   }
     373                 : 
     374            9272 :   return (vstr__split_hdl_end(pos, len, split_pos, sects, limit, flags, added));
     375                 : }
     376                 : #undef VSTR__SPLIT_HDL_ERR

Generated by: LTP GCOV extension version 1.1