LTP GCOV extension - code coverage report
Current view: directory - work/ustr - ustr-parse-code.h
Test: Ustr coverage
Date: 2008-02-26 Instrumented lines: 157
Code covered: 100.0 % Executed lines: 157

       1                 : /* Copyright (c) 2007 James Antill -- See LICENSE file for terms. */
       2                 : 
       3                 : #ifndef USTR_PARSE_H
       4                 : #error " You should have already included ustr-parse.h, or just include ustr.h."
       5                 : #endif
       6                 : 
       7                 : #if ! USTR_CONF_HAVE_STDINT_H
       8                 : # define USTR__UMAX unsigned long
       9                 : #else
      10                 : # define USTR__UMAX uintmax_t
      11                 : #endif
      12                 : 
      13                 : /* basically uses: [ ]*[-+](0b|0B|0o|0O|0x|0X|0)[0-9a-z_]+ */
      14                 : USTR_CONF_e_PROTO
      15                 : int ustr__parse_num_beg(const char **ptr, size_t *len,
      16                 :                         unsigned int flags, int *tst_neg, int *tst_0,
      17                 :                         unsigned int *ern)
      18                 :     USTR__COMPILE_ATTR_WARN_UNUSED_RET() USTR__COMPILE_ATTR_NONNULL_A();
      19                 : USTR_CONF_i_PROTO
      20                 : int ustr__parse_num_beg(const char **ptr, size_t *len,
      21                 :                         unsigned int flags, int *tst_neg, int *tst_0,
      22                 :                         unsigned int *ern)
      23             264 : {
      24             264 :   unsigned int base = flags & USTR__MASK_PARSE_NUM_BASE;
      25             264 :   int auto_base = USTR_FALSE;
      26                 : 
      27             264 :   if (!base)
      28             196 :     auto_base = USTR_TRUE;
      29              68 :   else if (base > 36)
      30               4 :     base = 36;
      31              64 :   else if (base == 1)
      32               8 :     ++base;
      33                 : 
      34             264 :   if (flags & USTR_FLAG_PARSE_NUM_SPACE)
      35                 :   {
      36             190 :     while (*len && (**ptr == ' '))
      37                 :     {
      38              88 :       ++*ptr;
      39              88 :       --*len;
      40                 :     }    
      41                 : 
      42              68 :     if (!*len)
      43                 :     {
      44               4 :       *ern = USTR_TYPE_PARSE_NUM_ERR_ONLY_S;
      45               4 :       return (0);
      46                 :     }
      47                 :   }
      48                 : 
      49             260 :   if (!(flags & USTR_FLAG_PARSE_NUM_NO_BEG_PM))
      50                 :   {
      51             252 :     switch (**ptr)
      52                 :     {
      53                 :       case '-':
      54              52 :         *tst_neg = USTR_TRUE;
      55                 :       case '+':
      56              84 :         ++*ptr;
      57              84 :         --*len;
      58                 :     }
      59             252 :     if (!*len)
      60                 :     {
      61               8 :       *ern = USTR_TYPE_PARSE_NUM_ERR_ONLY_SPM;
      62               8 :       return (0);
      63                 :     }
      64                 :   }
      65                 : 
      66             252 :   if (**ptr != '0')
      67                 :   {
      68              96 :     if (base)
      69              48 :       return (base);
      70              48 :     return (10);
      71                 :   }
      72                 :   
      73             156 :   ++*ptr;
      74             156 :   --*len;
      75                 :   
      76             156 :   if (!*len)
      77                 :   {
      78              24 :     *tst_0 = USTR_TRUE;    
      79              24 :     return (10);
      80                 :   }
      81             164 :   else if ((auto_base || (base ==  2)) && ((**ptr == 'b') || (**ptr == 'B')))
      82              32 :     base =  2;
      83             128 :   else if ((auto_base || (base ==  8)) && ((**ptr == 'o') || (**ptr == 'O')))
      84              28 :     base =  8;
      85             120 :   else if ((auto_base || (base == 16)) && ((**ptr == 'x') || (**ptr == 'X')))
      86              48 :     base = 16;
      87              24 :   else if ((flags & USTR_FLAG_PARSE_NUM_NO_BEG_ZERO) &&
      88                 :            (!auto_base || (**ptr == '0')))
      89                 :   {
      90               4 :     *ern = USTR_TYPE_PARSE_NUM_ERR_BEG_ZERO;
      91               4 :     return (0);
      92                 :   }
      93                 :   else
      94                 :   {
      95              20 :     *tst_0 = USTR_TRUE;
      96              20 :     if (base)
      97               4 :       return (base);
      98              16 :     return (8);
      99                 :   }
     100                 :   
     101             108 :   ++*ptr;
     102             108 :   --*len;
     103                 :   
     104             108 :   if (!*len)
     105                 :   {
     106              12 :     *ern = USTR_TYPE_PARSE_NUM_ERR_ONLY_SPMX;
     107              12 :     return (0);
     108                 :   }
     109                 : 
     110              96 :   if ((flags & USTR_FLAG_PARSE_NUM_NO_BEG_ZERO) && (**ptr == '0') && (*len > 1))
     111                 :   {
     112               4 :     *ern = USTR_TYPE_PARSE_NUM_ERR_BEG_ZERO;
     113               4 :     return (0);
     114                 :   }
     115                 : 
     116              92 :   return (base);
     117                 : }
     118                 : #if USTR_CONF_HAVE_STDINT_H
     119                 : USTR_CONF_I_PROTO
     120                 : #else
     121                 : USTR_CONF_e_PROTO
     122                 : USTR__UMAX ustr_parse_uintmaxx(const struct Ustr *, size_t, unsigned int,
     123                 :                                USTR__UMAX, USTR__UMAX, char,
     124                 :                                size_t *, unsigned int *)
     125                 :     USTR__COMPILE_ATTR_WARN_UNUSED_RET() USTR__COMPILE_ATTR_NONNULL_L((1));
     126                 : USTR_CONF_i_PROTO
     127                 : #endif
     128                 : USTR__UMAX ustr_parse_uintmaxx(const struct Ustr *s1, size_t off,
     129                 :                                unsigned int flags,
     130                 :                                USTR__UMAX num_min, USTR__UMAX num_max,
     131                 :                                const char *sep,
     132                 :                                size_t *ret_len, unsigned int *ern)
     133             264 : {
     134                 :   static const char local_let_low[]  = "abcdefghijklmnopqrstuvwxyz";
     135                 :   static const char local_let_high[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     136                 :   unsigned int dummy_ern;
     137             264 :   unsigned int num_base = 0;
     138             264 :   int tst_neg   = USTR_FALSE;
     139             264 :   int tst_0     = USTR_FALSE;
     140             264 :   int done_once = USTR_FALSE;
     141             264 :   char num_end = '9';
     142             264 :   const char *ptr = ustr_cstr(s1);
     143             264 :   size_t      len = ustr_len(s1);
     144                 :   size_t orig_len;
     145             264 :   USTR__UMAX ret = 0;
     146             264 :   size_t slen = strlen(sep);
     147                 :   
     148             132 :   USTR_ASSERT(ustr_assert_valid(s1));
     149             132 :   USTR_ASSERT(!(flags & USTR_FLAG_PARSE_NUM_NO_NEGATIVE) || !num_min);
     150                 :   
     151             264 :   if (!ern) ern = &dummy_ern;
     152             264 :   *ern = USTR_TYPE_PARSE_NUM_ERR_NONE;
     153                 : 
     154             264 :   USTR_ASSERT_RET(off <= len, 0);
     155             264 :   ptr += off;
     156             264 :   len -= off;
     157                 :   
     158             264 :   orig_len = len;
     159                 :   
     160             264 :   if (!(num_base = ustr__parse_num_beg(&ptr,&len, flags, &tst_neg,&tst_0, ern)))
     161              32 :     return (0);
     162                 : 
     163             232 :   if (tst_neg && (flags & USTR_FLAG_PARSE_NUM_NO_NEGATIVE))
     164                 :   {
     165               4 :     *ern = USTR_TYPE_PARSE_NUM_ERR_NEGATIVE;
     166               4 :     return (0);
     167                 :   }
     168                 :   
     169             228 :   if (num_base < 10)
     170              72 :     num_end = '0' + num_base - 1;
     171                 : 
     172             228 :   if (tst_neg)
     173              44 :     num_max = num_min;
     174                 :   
     175             228 :   done_once = tst_0;
     176            1412 :   while (len)
     177                 :   {
     178            1004 :     const char *end = 0;
     179            1004 :     unsigned int add_num = 0;
     180            1004 :     USTR__UMAX old_ret = ret;
     181                 :       
     182            1004 :     if (done_once && (flags & USTR_FLAG_PARSE_NUM_SEP) &&
     183                 :         (*ptr == *sep) && (len >= slen) && !memcmp(ptr, sep, slen))
     184                 :     {
     185              84 :       ptr += slen;
     186              84 :       len -= slen;
     187              84 :       continue;
     188                 :     }
     189                 :     else
     190                 :     {
     191            1524 :       if ((*ptr >= '0') && (*ptr <= num_end))
     192             604 :         add_num = (*ptr - '0');
     193             316 :       else if (num_base <= 10)
     194              24 :         break;
     195             292 :       else if ((end = memchr(local_let_low,  *ptr, num_base - 10)))
     196             104 :         add_num = 10 + (end - local_let_low);
     197             188 :       else if ((end = memchr(local_let_high, *ptr, num_base - 10)))
     198             176 :         add_num = 10 + (end - local_let_high);
     199                 :       else
     200              12 :         break;
     201                 :     }
     202                 :     
     203             884 :     ret = (ret * num_base) + add_num;
     204             884 :     if ((flags & USTR_FLAG_PARSE_NUM_OVERFLOW) &&
     205                 :         (((ret - add_num) / num_base) != old_ret))
     206                 :     {
     207              12 :       *ern = USTR_TYPE_PARSE_NUM_ERR_OVERFLOW;
     208              12 :       ret = 0;
     209              12 :       break;
     210                 :     }
     211                 : 
     212             872 :     ++ptr;
     213             872 :     --len;
     214             872 :     done_once = USTR_TRUE;
     215                 :   }
     216                 : 
     217             228 :   if (!done_once)
     218                 :   {
     219              24 :     *ern = USTR_TYPE_PARSE_NUM_ERR_OOB;
     220              24 :     return (0);
     221                 :   }
     222                 :   
     223             204 :   if (!*ern && (flags & USTR_FLAG_PARSE_NUM_EXACT) && len)
     224               4 :     *ern = USTR_TYPE_PARSE_NUM_ERR_OOB;
     225                 : 
     226             204 :   if (ret > num_max)
     227                 :   {
     228              28 :     ret = num_max;
     229              28 :     if (flags & USTR_FLAG_PARSE_NUM_OVERFLOW)
     230                 :     {
     231              16 :       if (!*ern)
     232              16 :         *ern = USTR_TYPE_PARSE_NUM_ERR_OVERFLOW;
     233              16 :       ret = 0;
     234                 :     }
     235                 :   }
     236                 : 
     237             204 :   if (ret_len)
     238              28 :     *ret_len = orig_len - len;
     239                 :   
     240             204 :   if (tst_neg)
     241              40 :     return (-ret);
     242                 :   
     243             164 :   return (ret);
     244                 : }
     245                 : 
     246                 : #if USTR_CONF_HAVE_STDINT_H
     247                 : USTR_CONF_I_PROTO
     248                 : uintmax_t ustr_parse_uintmax(const struct Ustr *s1, size_t off,
     249                 :                              unsigned int flags, size_t *len, unsigned int *ern)
     250              40 : {
     251              20 :   ustr_assert(!(flags & USTR_FLAG_PARSE_NUM_NO_NEGATIVE));
     252              40 :   flags |= USTR_FLAG_PARSE_NUM_NO_NEGATIVE;
     253              40 :   return (ustr_parse_uintmaxx(s1, off, flags, 0, UINTMAX_MAX, "_", len, ern));
     254                 : }
     255                 : USTR_CONF_I_PROTO
     256                 : intmax_t ustr_parse_intmax(const struct Ustr *s1, size_t off,
     257                 :                            unsigned int flags, size_t *len, unsigned int *ern)
     258              16 : {
     259              16 :   uintmax_t num_min = INTMAX_MIN;
     260               8 :   ustr_assert(!(flags & USTR_FLAG_PARSE_NUM_NO_NEGATIVE));
     261              16 :   return (ustr_parse_uintmaxx(s1,off, flags, -num_min,INTMAX_MAX, "_",len,ern));
     262                 : }
     263                 : #endif
     264                 : 
     265                 : USTR_CONF_I_PROTO
     266                 : unsigned long ustr_parse_ulongx(const struct Ustr *s1, size_t off,
     267                 :                                 unsigned int flags,
     268                 :                                 unsigned long num_min, unsigned long num_max,
     269                 :                                 const char *sep, size_t *len, unsigned int *ern)
     270              40 : { return (ustr_parse_uintmaxx(s1,off, flags, num_min,num_max, sep, len, ern)); }
     271                 : 
     272                 : USTR_CONF_I_PROTO
     273                 : unsigned long ustr_parse_ulong(const struct Ustr *s1, size_t off,
     274                 :                                unsigned int flags,
     275                 :                                size_t *len, unsigned int *ern)
     276              12 : {
     277               6 :   ustr_assert(!(flags & USTR_FLAG_PARSE_NUM_NO_NEGATIVE));
     278              12 :   flags |= USTR_FLAG_PARSE_NUM_NO_NEGATIVE;
     279              12 :   return (ustr_parse_uintmaxx(s1, off, flags, 0, ULONG_MAX, "_", len, ern));
     280                 : }
     281                 : USTR_CONF_I_PROTO
     282                 : long ustr_parse_long(const struct Ustr *s1, size_t off, unsigned int flags,
     283                 :                      size_t *len, unsigned int *ern)
     284               8 : {
     285               8 :   unsigned long num_min = LONG_MIN;
     286               4 :   ustr_assert(!(flags & USTR_FLAG_PARSE_NUM_NO_NEGATIVE));
     287               8 :   return (ustr_parse_uintmaxx(s1,off, flags, -num_min, LONG_MAX, "_", len,ern));
     288                 : }
     289                 : 
     290                 : USTR_CONF_I_PROTO
     291                 : unsigned int ustr_parse_uint(const struct Ustr *s1, size_t off,
     292                 :                              unsigned int flags, size_t *len, unsigned int *ern)
     293              44 : {
     294              22 :   ustr_assert(!(flags & USTR_FLAG_PARSE_NUM_NO_NEGATIVE));
     295              44 :   flags |= USTR_FLAG_PARSE_NUM_NO_NEGATIVE;
     296              44 :   return (ustr_parse_uintmaxx(s1, off, flags, 0, UINT_MAX, "_", len, ern));
     297                 : }
     298                 : USTR_CONF_I_PROTO
     299                 : int ustr_parse_int(const struct Ustr *s1, size_t off, unsigned int flags,
     300                 :                    size_t *len, unsigned int *ern)
     301              40 : {
     302              40 :   unsigned int num_min = INT_MIN;
     303              20 :   ustr_assert(!(flags & USTR_FLAG_PARSE_NUM_NO_NEGATIVE));
     304              40 :   return (ustr_parse_uintmaxx(s1,off, flags, -num_min, INT_MAX, "_", len, ern));
     305                 : }
     306                 : 
     307                 : USTR_CONF_I_PROTO
     308                 : unsigned short ustr_parse_ushort(const struct Ustr *s1, size_t off,
     309                 :                                  unsigned int flags,
     310                 :                                  size_t *len, unsigned int *ern)
     311              12 : {
     312               6 :   ustr_assert(!(flags & USTR_FLAG_PARSE_NUM_NO_NEGATIVE));
     313              12 :   flags |= USTR_FLAG_PARSE_NUM_NO_NEGATIVE;
     314              12 :   return (ustr_parse_uintmaxx(s1, off, flags, 0, USHRT_MAX, "_", len, ern));
     315                 : }
     316                 : USTR_CONF_I_PROTO
     317                 : short ustr_parse_short(const struct Ustr *s1, size_t off, unsigned int flags,
     318                 :                        size_t *len, unsigned int *ern)
     319              20 : {
     320              20 :   unsigned short num_min = SHRT_MIN;
     321              10 :   ustr_assert(!(flags & USTR_FLAG_PARSE_NUM_NO_NEGATIVE));
     322              20 :   return (ustr_parse_uintmaxx(s1,off, flags, -num_min, SHRT_MAX, "_", len,ern));
     323                 : }
     324                 : 
     325                 : /* void *ustr_parse_num(const struct Ustr *s1, unsigned int flags,
     326                 :                         unsigned int *ern,
     327                 :                         void *(*func)(unsigned int, int,unsigned int *, void *),
     328                 :                         void *data)
     329                 : 
     330                 :   if (is_neg) add_num = -add_num;
     331                 :   
     332                 :   if (!(ret = func(num_base, add_num, err, ret)) && !*err)
     333                 :     return (NULL);
     334                 : */
     335                 : 

Generated by: LTP GCOV extension version 1.4