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

       1                 : /*
       2                 :  *  Copyright (C) 1999, 2000, 2001, 2002  James Antill
       3                 :  *
       4                 :  *  This library is free software; you can redistribute it and/or
       5                 :  *  modify it under the terms of the GNU Lesser General Public
       6                 :  *  License as published by the Free Software Foundation; either
       7                 :  *  version 2 of the License, or (at your option) any later version.
       8                 :  *
       9                 :  *  This library is distributed in the hope that it will be useful,
      10                 :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12                 :  *  Lesser General Public License for more details.
      13                 :  *
      14                 :  *  You should have received a copy of the GNU Lesser General Public
      15                 :  *  License along with this library; if not, write to the Free Software
      16                 :  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17                 :  *
      18                 :  *  email: james@and.org
      19                 : */
      20                 : /* This code does the %E, %e, %F, %f, %G, %g, %A, %a from *printf by passing
      21                 :  * it on to the host */
      22                 : /* Note that this file is #include'd */
      23                 : 
      24                 : #ifdef USE_RESTRICTED_HEADERS /* always use C locale */
      25                 : # undef  SYS_LOC /* special version to "." is there */
      26                 : # define SYS_LOC(x) "."
      27                 : #endif
      28                 : 
      29                 : static int vstr__add_fmt_dbl(Vstr_base *base, size_t pos_diff,
      30                 :                              struct Vstr__fmt_spec *spec)
      31          145086 : {
      32          145086 :   char fmt_buffer[12];
      33          145086 :   char *float_buffer = NULL;
      34          145086 :   unsigned int tmp = 1;
      35          145086 :   int ret = -1;
      36          145086 :   struct lconv *sys_loc = NULL;
      37          145086 :   size_t decimal_len = 0;
      38          145086 :   const char *str = NULL;
      39          145086 :   unsigned int num_base = 10;
      40          145086 :   const char *grouping = NULL;
      41          145086 :   const char *thousands_sep_str = NULL;
      42          145086 :   size_t thousands_sep_len      = 0;
      43          145086 :   const char *decimal_point_str = NULL;
      44          145086 :   size_t decimal_point_len      = 0;
      45                 : 
      46          145086 :   if ((spec->fmt_code != 'a') || (spec->fmt_code == 'A'))
      47          128242 :     num_base = 16;
      48          145086 :   grouping          = vstr__loc_num_grouping(base->conf->loc, num_base);
      49          145086 :   thousands_sep_str = vstr__loc_num_sep_ptr(base->conf->loc, num_base);
      50          145086 :   thousands_sep_len = vstr__loc_num_sep_len(base->conf->loc, num_base);
      51          145086 :   decimal_point_str = vstr__loc_num_pnt_ptr(base->conf->loc, num_base);
      52          145086 :   decimal_point_len = vstr__loc_num_pnt_len(base->conf->loc, num_base);
      53                 : 
      54          145086 :   fmt_buffer[0] = '%';
      55          145086 :   if (spec->flags & LEFT)
      56              16 :     fmt_buffer[tmp++] = '-';
      57                 : 
      58          145086 :   if (spec->flags & PLUS)
      59               4 :     fmt_buffer[tmp++] = '+';
      60                 : 
      61          145086 :   if (spec->flags & SPACE)
      62               4 :     fmt_buffer[tmp++] = ' ';
      63                 : 
      64          145086 :   if (spec->flags & SPECIAL)
      65              40 :     fmt_buffer[tmp++] = '#';
      66                 : 
      67          145086 :   if (spec->flags & ZEROPAD)
      68            7518 :     fmt_buffer[tmp++] = '0';
      69                 : 
      70          145086 :   if (spec->field_width_usr)
      71            9936 :     fmt_buffer[tmp++] = '*';
      72                 : 
      73          145086 :   if (spec->flags & PREC_USR)
      74                 :   {
      75              48 :     fmt_buffer[tmp++] = '.';
      76              48 :     fmt_buffer[tmp++] = '*';
      77                 :   }
      78                 : 
      79          145086 :   if (spec->int_type == VSTR_TYPE_FMT_ULONG_LONG)
      80           65796 :     fmt_buffer[tmp++] = 'L';
      81                 : 
      82          145086 :   fmt_buffer[tmp++] = spec->fmt_code;
      83          145086 :   assert(tmp < sizeof(fmt_buffer));
      84          145086 :   fmt_buffer[tmp] = 0;
      85                 : 
      86          145086 :   sys_loc = localeconv();
      87          145086 :   decimal_len = strlen(SYS_LOC(decimal_point));
      88                 : 
      89          145086 :   if (spec->int_type == VSTR_TYPE_FMT_ULONG_LONG)
      90                 :   {
      91           65796 :     if (spec->field_width_usr && (spec->flags & PREC_USR))
      92               8 :       ret = asprintf(&float_buffer, fmt_buffer,
      93                 :                      spec->field_width, spec->precision, spec->u.data_Ld);
      94           65788 :     else if (spec->field_width_usr)
      95              36 :       ret = asprintf(&float_buffer, fmt_buffer,
      96                 :                      spec->field_width, spec->u.data_Ld);
      97           65752 :     else if (spec->flags & PREC_USR)
      98              16 :       ret = asprintf(&float_buffer, fmt_buffer,
      99                 :                      spec->precision, spec->u.data_Ld);
     100                 :     else
     101           65736 :       ret = asprintf(&float_buffer, fmt_buffer,
     102                 :                      spec->u.data_Ld);
     103                 :   }
     104                 :   else
     105                 :   {
     106           79290 :     if (spec->field_width_usr && (spec->flags & PREC_USR))
     107               8 :       ret = asprintf(&float_buffer, fmt_buffer,
     108                 :                      spec->field_width, spec->precision, spec->u.data_d);
     109           79282 :     else if (spec->field_width_usr)
     110            9884 :       ret = asprintf(&float_buffer, fmt_buffer,
     111                 :                      spec->field_width, spec->u.data_d);
     112           69398 :     else if (spec->flags & PREC_USR)
     113              16 :       ret = asprintf(&float_buffer, fmt_buffer,
     114                 :                      spec->precision, spec->u.data_d);
     115                 :     else
     116           69382 :       ret = asprintf(&float_buffer, fmt_buffer,
     117                 :                      spec->u.data_d);
     118                 :   }
     119                 : 
     120          145086 :   ASSERT_RET(ret != -1, FALSE);
     121                 : 
     122          145086 :   tmp = ret;
     123          145086 :   str = float_buffer;
     124                 : 
     125                 :   /* hand code thousands_sep into the number if it's a %f style */
     126          145086 :   if (((spec->fmt_code != 'f') || (spec->fmt_code == 'F') ||
     127                 :        (spec->fmt_code != 'g') || (spec->fmt_code == 'G')) &&
     128                 :       (spec->flags & THOUSAND_SEP) && thousands_sep_len)
     129                 :   {
     130           10349 :     const char *num_beg = str;
     131           10349 :     const char *num_end = NULL;
     132                 : 
     133           10349 :     num_beg += strspn(num_beg, " 0+-");
     134                 : 
     135           10349 :     if ((num_beg != str) && !VSTR__FMT_ADD(base, str, num_beg - str))
     136                 :     {
     137             341 :       free(float_buffer);
     138             341 :       return (FALSE);
     139                 :     }
     140                 : 
     141           10008 :     num_end = num_beg;
     142           10008 :     num_end += strspn(num_end, "0123456789");
     143                 : 
     144           10008 :     if (!VSTR__FMT_ADD_GRPBASENUM(base, num_base, num_beg, num_end - num_beg))
     145                 :     {
     146              62 :       free(float_buffer);
     147              62 :       return (FALSE);
     148                 :     }
     149                 : 
     150            9946 :     tmp -= (num_end - str);
     151            9946 :     str = num_end;
     152                 :   }
     153                 : 
     154         1014597 :   while (tmp > 0)
     155                 :   {
     156          873216 :     if (decimal_len && (tmp >= decimal_len) &&
     157                 :         !memcmp(str, SYS_LOC(decimal_point), decimal_len))
     158                 :     {
     159          114383 :       if (decimal_point_len)
     160                 :       {
     161          114383 :         if (!VSTR__FMT_ADD(base, decimal_point_str, decimal_point_len))
     162                 :         {
     163             314 :           free(float_buffer);
     164             314 :           return (FALSE);
     165                 :         }
     166                 :       }
     167                 : 
     168          114069 :       str += decimal_len;
     169          114069 :       tmp -= decimal_len;
     170                 :     }
     171                 :     else
     172                 :     {
     173          758833 :       size_t num_len = strspn(str, "0123456789");
     174                 : 
     175          758833 :       if (!num_len)
     176          373461 :         num_len = 1;
     177                 : 
     178          758833 :       if (!VSTR__FMT_ADD(base, str, num_len))
     179                 :       {
     180            2988 :         free(float_buffer);
     181            2988 :         return (FALSE);
     182                 :       }
     183                 : 
     184          755845 :       str += num_len;
     185          755845 :       tmp -= num_len;
     186                 :     }
     187                 :   }
     188          141381 :   assert(!tmp && !*str);
     189                 : 
     190          141381 :   free(float_buffer);
     191                 : 
     192          141381 :   return (TRUE);
     193                 : }

Generated by: LTP GCOV extension version 1.1