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

       1                 : /* Copyright (c) 2007 James Antill -- See LICENSE file for terms. */
       2                 : 
       3                 : #ifndef USTR_IO_H
       4                 : #error " You should have already included ustr-io.h, or just include ustr.h."
       5                 : #endif
       6                 : 
       7                 : USTR_CONF_i_PROTO
       8                 : int ustrp__io_get(struct Ustr_pool *p, struct Ustr **ps1, FILE *fp,
       9                 :                   size_t minlen, size_t *got)
      10             108 : {
      11             108 :   size_t olen = ustr_len(*ps1);
      12             108 :   size_t ret  = 0;
      13                 :   
      14              54 :   USTR_ASSERT(ps1 && ustrp__assert_valid(!!p, *ps1) && fp);
      15                 : 
      16             108 :   if (!minlen)
      17                 :   {
      18               4 :     if (got)
      19               4 :       *got = 0;
      20               4 :     return (USTR_TRUE);
      21                 :   }
      22                 :   
      23             104 :   if (!ustrp__add_undef(p, ps1, minlen))
      24               4 :     return (USTR_FALSE);
      25                 : 
      26             100 :   ret = fread(ustr_wstr(*ps1) + olen, 1, minlen, fp);
      27             100 :   if (ret < minlen)
      28              44 :     ustrp__del(p, ps1, minlen - ret);
      29                 : 
      30             100 :   if (got)
      31              92 :     *got = ret;
      32                 :   
      33             100 :   return (ret > 0);
      34                 : }
      35                 : USTR_CONF_I_PROTO
      36                 : int ustr_io_get(struct Ustr **ps1, FILE *fp, size_t minlen, size_t *got)
      37              24 : { return (ustrp__io_get(0, ps1, fp, minlen, got)); }
      38                 : USTR_CONF_I_PROTO
      39                 : int ustrp_io_get(struct Ustr_pool *p, struct Ustrp **ps1, FILE *fp,
      40                 :                  size_t minlen, size_t *got)
      41               4 : {
      42               4 :   struct Ustr *tmp = &(*ps1)->s;
      43               4 :   int ret = ustrp__io_get(p, &tmp, fp, minlen, got);
      44               4 :   *ps1 = USTRP(tmp);
      45               4 :   return (ret);
      46                 : }
      47                 : 
      48                 : USTR_CONF_i_PROTO
      49                 : int ustrp__io_getfile(struct Ustr_pool *p, struct Ustr **ps1, FILE *fp)
      50              36 : {
      51              36 :   const size_t blksz = (1024 * 8) - (1 + 8 + 8 + 8 + sizeof(USTR_END_ALOCDx));
      52              36 :   size_t num = blksz;
      53              36 :   size_t got = 0;
      54                 : 
      55                 :   do
      56                 :   { /* round up... not perfect as we'll be able to round up post add_undef */
      57              80 :     size_t sz   = ustr_size(*ps1);
      58              80 :     size_t clen = ustr_len(*ps1);
      59                 : 
      60              80 :     num = blksz;
      61              80 :     if (num < (sz - clen))
      62              12 :       num = sz - clen;
      63              80 :   } while (ustrp__io_get(p, ps1, fp, num, &got) && (got == num));
      64                 : 
      65              36 :   return (feof(fp));
      66                 : }
      67                 : USTR_CONF_I_PROTO
      68                 : int ustr_io_getfile(struct Ustr **ps1, FILE *fp)
      69              16 : { return (ustrp__io_getfile(0, ps1, fp)); }
      70                 : USTR_CONF_I_PROTO
      71                 : int ustrp_io_getfile(struct Ustr_pool *p, struct Ustrp **ps1, FILE *fp)
      72               8 : {
      73               8 :   struct Ustr *tmp = &(*ps1)->s;
      74               8 :   int ret = ustrp__io_getfile(p, &tmp, fp);
      75               8 :   *ps1 = USTRP(tmp);
      76               8 :   return (ret);
      77                 : }
      78                 : 
      79                 : USTR_CONF_i_PROTO
      80                 : int ustrp__io_getfilename(struct Ustr_pool *p, struct Ustr **ps1,
      81                 :                           const char *name)
      82              16 : {
      83              16 :   FILE *fp = fopen(name, "rb");
      84              16 :   int ret = USTR_FALSE;
      85              16 :   int save_errno = 0;
      86                 :   
      87              16 :   if (!fp)
      88               4 :     return (USTR_FALSE);
      89                 :   
      90              12 :   ret = ustrp__io_getfile(p, ps1, fp);
      91                 :   
      92              12 :   save_errno = errno;
      93              12 :   fclose(fp);
      94              12 :   errno = save_errno;
      95                 :   
      96              12 :   return (ret);
      97                 : }
      98                 : USTR_CONF_I_PROTO
      99                 : int ustr_io_getfilename(struct Ustr **ps1, const char *name)
     100               8 : { return (ustrp__io_getfilename(0, ps1, name)); }
     101                 : USTR_CONF_I_PROTO
     102                 : int ustrp_io_getfilename(struct Ustr_pool *p, struct Ustrp **ps1,
     103                 :                          const char *name)
     104               8 : {
     105               8 :   struct Ustr *tmp = &(*ps1)->s;
     106               8 :   int ret = ustrp__io_getfilename(p, &tmp, name);
     107               8 :   *ps1 = USTRP(tmp);
     108               8 :   return (ret);
     109                 : }
     110                 : 
     111                 : /* We bow to retarded GLibc getc_unlocked */
     112                 : #ifdef getc_unlocked
     113                 : # define USTR__IO_GETC(x) getc_unlocked(x)
     114                 : #else
     115                 : # define USTR__IO_GETC(x) getc(x)
     116                 : #endif
     117                 : 
     118                 : USTR_CONF_i_PROTO int ustrp__io_getdelim(struct Ustr_pool *p, struct Ustr **ps1,
     119                 :                                          FILE *fp, char delim)
     120             272 : {
     121             272 :   int val = EOF;
     122             272 :   size_t olen = 0;
     123             272 :   size_t clen = 0;
     124             272 :   size_t linesz = 80; /* Unix "tradition" is 80x24, assuming delim == '\n' */
     125                 :   
     126             136 :   USTR_ASSERT(ps1 && ustrp__assert_valid(!!p, *ps1) && fp);
     127                 : 
     128             340 :   olen = clen = ustr_len(*ps1);
     129             560 :   while (ustrp__add_undef(p, ps1, linesz))
     130                 :   {
     131             288 :     char *wstr = ustr_wstr(*ps1) + clen;
     132             288 :     size_t num = linesz;
     133                 :     
     134            3472 :     while (num && ((val = USTR__IO_GETC(fp)) != EOF))
     135                 :     {
     136            3164 :       --num;
     137            3164 :       if ((*wstr++ = val) == delim)
     138             268 :         break;
     139                 :     }
     140                 :     
     141             288 :     if (num)
     142                 :     {
     143             272 :       if (!ferror(fp)) /* only way we can easily test,
     144                 :                           as it might be hanging from previously */
     145             272 :         errno = 0;
     146                 : 
     147             272 :       ustrp__del(p, ps1, num);
     148             272 :       break;
     149                 :     }
     150                 :     
     151              16 :     clen += linesz;
     152                 :   }
     153                 : 
     154             273 :   return ((val == delim) || ((val == EOF) && (ustr_len(*ps1) != olen)));
     155                 : }
     156                 : #undef USTR__IO_GETC
     157                 : USTR_CONF_I_PROTO
     158                 : int ustr_io_getdelim(struct Ustr **ps1, FILE *fp, char delim)
     159             156 : { return (ustrp__io_getdelim(0, ps1, fp, delim)); }
     160                 : USTR_CONF_I_PROTO int ustrp_io_getdelim(struct Ustr_pool *p, struct Ustrp **ps1,
     161                 :                                         FILE *fp, char delim)
     162               4 : {
     163               4 :   struct Ustr *tmp = &(*ps1)->s;
     164               4 :   int ret = ustrp__io_getdelim(p, &tmp, fp, delim);
     165               4 :   *ps1 = USTRP(tmp);
     166               4 :   return (ret);
     167                 : }
     168                 : 
     169                 : USTR_CONF_I_PROTO
     170                 : int ustr_io_getline(struct Ustr **ps1, FILE *fp)
     171              96 : { return (ustrp__io_getdelim(0, ps1, fp, '\n')); }
     172                 : USTR_CONF_I_PROTO
     173                 : int ustrp_io_getline(struct Ustr_pool *p, struct Ustrp **ps1, FILE *fp)
     174              16 : {
     175              16 :   struct Ustr *tmp = &(*ps1)->s;
     176              16 :   int ret = ustrp__io_getdelim(p, &tmp, fp, '\n');
     177              16 :   *ps1 = USTRP(tmp);
     178              16 :   return (ret);
     179                 : }
     180                 : 
     181                 : USTR_CONF_i_PROTO
     182                 : int ustrp__io_put(struct Ustr_pool *p, struct Ustr **ps1,FILE *fp,size_t beglen)
     183              52 : {
     184              52 :   size_t ret = 0;
     185              52 :   size_t clen = ustr_len(*ps1);
     186                 :   
     187              26 :   USTR_ASSERT(ps1 && ustrp__assert_valid(!!p, *ps1) && fp);
     188                 : 
     189              52 :   USTR_ASSERT_RET(beglen <= clen, USTR_FALSE);
     190                 :   
     191              52 :   if (!beglen)
     192               8 :     return (USTR_TRUE);
     193                 : 
     194                 :   /* Because most errors only happen when a fflush() of the stdio stream,
     195                 :    * you have to assume that any data written is indeterminate anyway.
     196                 :    * So only go to the effort of making it determinate if beglen != clen.
     197                 :    * If you need efficient IO, that you can deal with errors for, use Vstr
     198                 :    * and POSIX IO. */
     199              44 :   if ((beglen != clen) && !ustrp__sc_ensure_owner(p, ps1))
     200               4 :     return (USTR_FALSE);
     201                 :   
     202              50 :   if ((ret = fwrite(ustr_cstr(*ps1), 1, beglen, fp)))
     203                 :   {
     204              36 :     int save_errno = errno;
     205                 :     
     206              36 :     if (beglen != clen) /* Note not ret != clen, see above. */
     207               8 :       ustrp__del_subustr(p, ps1, 1, ret); /* if it fails, see above */
     208                 :     else
     209                 :       /* In certain cases this means we'll lose the config. for *ps1. But it's
     210                 :        * worth it so we don't have to ensure_owner() all the time. If you care
     211                 :        * pass owned Ustr's. */
     212              28 :       ustrp__sc_del(p, ps1);
     213              36 :     errno = save_errno;
     214                 :   }
     215                 :   
     216              40 :   return (ret == beglen);
     217                 : }
     218                 : USTR_CONF_I_PROTO
     219                 : int ustr_io_put(struct Ustr **ps1, FILE *fp, size_t beglen)
     220              16 : { return (ustrp__io_put(0, ps1, fp, beglen)); }
     221                 : USTR_CONF_I_PROTO
     222                 : int ustrp_io_put(struct Ustr_pool *p, struct Ustrp **ps1,FILE *fp,size_t beglen)
     223               4 : {
     224               4 :   struct Ustr *tmp = &(*ps1)->s;
     225               4 :   int ret = ustrp__io_put(p, &tmp, fp, beglen);
     226               4 :   *ps1 = USTRP(tmp);
     227               4 :   return (ret);
     228                 : }
     229                 : 
     230                 : /* We bow to retarded GLibc putc_unlocked */
     231                 : #ifdef putc_unlocked
     232                 : # define USTR__IO_PUTC(x, y) putc_unlocked(x, y)
     233                 : #else
     234                 : # define USTR__IO_PUTC(x, y) putc(x, y)
     235                 : #endif
     236                 : USTR_CONF_i_PROTO int ustrp__io_putline(struct Ustr_pool *p, struct Ustr **ps1,
     237                 :                                         FILE *fp, size_t beglen)
     238              12 : {
     239              12 :   if (!ustrp__io_put(p, ps1, fp, beglen))
     240               4 :     return (USTR_FALSE);
     241                 : 
     242               8 :   return (USTR__IO_PUTC('\n', fp) != EOF);
     243                 : }
     244                 : #undef USTR__IO_PUTC
     245                 : USTR_CONF_I_PROTO
     246                 : int ustr_io_putline(struct Ustr **ps1, FILE *fp, size_t beglen)
     247               8 : { return (ustrp__io_putline(0, ps1, fp, beglen)); }
     248                 : USTR_CONF_I_PROTO int ustrp_io_putline(struct Ustr_pool *p, struct Ustrp **ps1,
     249                 :                                        FILE *fp, size_t beglen)
     250               4 : {
     251               4 :   struct Ustr *tmp = &(*ps1)->s;
     252               4 :   int ret = ustrp__io_putline(p, &tmp, fp, beglen);
     253               4 :   *ps1 = USTRP(tmp);
     254               4 :   return (ret);
     255                 : }
     256                 : 
     257                 : USTR_CONF_i_PROTO
     258                 : int ustrp__io_putfilename(struct Ustr_pool *p, struct Ustr **ps1,
     259                 :                           const char *name, const char *mode)
     260              28 : {
     261              28 :   FILE *fp = fopen(name, mode);
     262              28 :   int ret = USTR_FALSE;
     263                 :   
     264              28 :   if (!fp)
     265               8 :     return (USTR_FALSE);
     266                 :   
     267              25 :   if ((ret = ustrp__io_put(p, ps1, fp, ustr_len(*ps1))))
     268              16 :     ret = !fclose(fp); /* if everything OK, defer to the fclose() return */
     269                 :   else
     270                 :   {
     271               4 :     int save_errno = errno; /* otherwise ignore it */
     272               4 :     fclose(fp);
     273               4 :     errno = save_errno;
     274                 :   }
     275                 :   
     276              20 :   return (ret);
     277                 : }
     278                 : USTR_CONF_I_PROTO
     279                 : int ustr_io_putfilename(struct Ustr **ps1, const char *name, const char *mode)
     280              20 : { return (ustrp__io_putfilename(0, ps1, name, mode)); }
     281                 : USTR_CONF_I_PROTO
     282                 : int ustrp_io_putfilename(struct Ustr_pool *p, struct Ustrp **ps1,
     283                 :                          const char *name, const char *mode)
     284               8 : {
     285               8 :   struct Ustr *tmp = &(*ps1)->s;
     286               8 :   int ret = ustrp__io_putfilename(p, &tmp, name, mode);
     287               8 :   *ps1 = USTRP(tmp);
     288               8 :   return (ret);
     289                 : }

Generated by: LTP GCOV extension version 1.4