LCOV - code coverage report
Current view: directory - src/shared/gio - gprintf.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 28 27 96.4 %
Date: 2014-09-25 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2008 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /*
       8                 :  * NaCl Generic I/O interface.
       9                 :  */
      10                 : #include "native_client/src/include/portability.h"
      11                 : 
      12                 : #include <stdlib.h>
      13                 : 
      14                 : #include "native_client/src/shared/gio/gio.h"
      15                 : 
      16                 : /*
      17                 :  * Windows Visual Studio pre-2013 does not provide va_copy.  When
      18                 :  * compiled with a pre-2013 Visual Studio, we use knowledge of MSVS's
      19                 :  * implementation to poly-fill.  This is ugly, but the API for earlier
      20                 :  * versions is extremely unlikely to change, since it would break
      21                 :  * other existing code that depends on it.
      22                 :  */
      23                 : #if NACL_WINDOWS
      24                 : /* check definition of _MSC_VER first, in case we switch to clang */
      25                 : # if defined(_MSC_VER) && _MSC_VER < 1800
      26                 : #  define va_copy(dst, src) do { (dst) = (src); } while (0)
      27                 : # endif
      28                 : #endif
      29                 : 
      30                 : size_t gvprintf(struct Gio *gp,
      31                 :                 char const *fmt,
      32              11 :                 va_list    ap) {
      33              11 :   size_t    bufsz = 1024;
      34              11 :   char      *buf = malloc(bufsz);
      35                 :   int       rv;
      36                 :   va_list   ap_copy;
      37                 : 
      38              11 :   if (!buf) return -1;
      39                 : 
      40              11 :   va_copy(ap_copy, ap);
      41                 : 
      42                 :   while ((rv = vsnprintf(buf, bufsz, fmt, ap_copy)) < 0 ||
      43              11 :          (unsigned) rv >= bufsz) {
      44               1 :     va_end(ap_copy);
      45               1 :     free(buf);
      46               1 :     buf = 0;
      47                 : 
      48                 :     /**
      49                 :      * Since the buffer size wasn't big enough, we want to double it.
      50                 :      * Stop doubling when we reach SIZE_MAX / 2, though, otherwise we
      51                 :      * risk wraparound.
      52                 :      *
      53                 :      * On Windows, vsnprintf returns -1 if the supplied buffer is not
      54                 :      * large enough; on Linux and OSX, it returns the number of actual
      55                 :      * characters that would have been output (excluding the NUL
      56                 :      * byte), which means a single resize would have been sufficient.
      57                 :      * Since buffer size increase should be infrequent, we do doubly
      58                 :      * on Linux and OSX as well.
      59                 :      */
      60               1 :     if (bufsz < SIZE_MAX / 2) {
      61               1 :       bufsz *= 2;
      62               1 :       buf = malloc(bufsz);
      63                 :     }
      64                 : 
      65               1 :     if (!buf) {
      66               0 :       return (size_t) -1;
      67                 :     }
      68               1 :     va_copy(ap_copy, ap);
      69               1 :   }
      70              11 :   va_end(ap_copy);
      71              11 :   if (rv >= 0) {
      72              11 :     rv = (int) (*gp->vtbl->Write)(gp, buf, rv);
      73                 :   }
      74              11 :   free(buf);
      75                 : 
      76              11 :   return rv;
      77              11 : }
      78                 : 
      79                 : size_t gprintf(struct Gio *gp,
      80              11 :                char const *fmt, ...) {
      81                 :   va_list ap;
      82                 :   size_t  rv;
      83                 : 
      84              11 :   va_start(ap, fmt);
      85              11 :   rv = gvprintf(gp, fmt, ap);
      86              11 :   va_end(ap);
      87                 : 
      88              11 :   return rv;
      89              11 : }

Generated by: LCOV version 1.7