OpenCoverage

ftoastr.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/coreutils/src/gnulib/lib/ftoastr.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* floating point to accurate string-
2-
3 Copyright (C) 2010-2018 Free Software Foundation, Inc.-
4-
5 This program is free software: you can redistribute it and/or modify-
6 it under the terms of the GNU General Public License as published by-
7 the Free Software Foundation; either version 3 of the License, or-
8 (at your option) any later version.-
9-
10 This program 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-
13 GNU General Public License for more details.-
14-
15 You should have received a copy of the GNU General Public License-
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */-
17-
18/* Written by Paul Eggert. */-
19-
20/* This code can misbehave on some buggy or older platforms, when-
21 operating on arguments on floating types other than 'double', or-
22 when given unusual combinations of options. Gnulib's-
23 snprintf-posix module works around many of these problems.-
24-
25 This code relies on sprintf, strtod, etc. operating accurately;-
26 otherwise, the resulting strings could be inaccurate or too long. */-
27-
28#include <config.h>-
29-
30#include "ftoastr.h"-
31-
32#include <float.h>-
33#include <stdio.h>-
34#include <stdlib.h>-
35-
36#if LENGTH == 3-
37# define FLOAT long double-
38# define FLOAT_DIG LDBL_DIG-
39# define FLOAT_MIN LDBL_MIN-
40# define FLOAT_PREC_BOUND _GL_LDBL_PREC_BOUND-
41# define FTOASTR ldtoastr-
42# define PROMOTED_FLOAT long double-
43# if HAVE_C99_STRTOLD-
44# define STRTOF strtold-
45# endif-
46#elif LENGTH == 2-
47# define FLOAT double-
48# define FLOAT_DIG DBL_DIG-
49# define FLOAT_MIN DBL_MIN-
50# define FLOAT_PREC_BOUND _GL_DBL_PREC_BOUND-
51# define FTOASTR dtoastr-
52# define PROMOTED_FLOAT double-
53#else-
54# define LENGTH 1-
55# define FLOAT float-
56# define FLOAT_DIG FLT_DIG-
57# define FLOAT_MIN FLT_MIN-
58# define FLOAT_PREC_BOUND _GL_FLT_PREC_BOUND-
59# define FTOASTR ftoastr-
60# define PROMOTED_FLOAT double-
61# if HAVE_STRTOF-
62# define STRTOF strtof-
63# endif-
64#endif-
65-
66/* On pre-C99 hosts, approximate strtof and strtold with strtod. This-
67 may generate one or two extra digits, but that's better than not-
68 working at all. */-
69#ifndef STRTOF-
70# define STRTOF strtod-
71#endif-
72-
73/* On hosts where it's not known that snprintf works, use sprintf to-
74 implement the subset needed here. Typically BUFSIZE is big enough-
75 and there's little or no performance hit. */-
76#if ! GNULIB_SNPRINTF-
77# undef snprintf-
78# define snprintf ftoastr_snprintf-
79static int-
80ftoastr_snprintf (char *buf, size_t bufsize, char const *format,-
81 int width, int prec, FLOAT x)-
82{-
83 PROMOTED_FLOAT promoted_x = x;-
84 char width_0_buffer[LENGTH == 1 ? FLT_BUFSIZE_BOUND-
85 : LENGTH == 2 ? DBL_BUFSIZE_BOUND-
86 : LDBL_BUFSIZE_BOUND];-
87 int n = width;-
88 if (bufsize < sizeof width_0_buffer)-
89 {-
90 n = sprintf (width_0_buffer, format, 0, prec, promoted_x);-
91 if (n < 0)-
92 return n;-
93 if (n < width)-
94 n = width;-
95 }-
96 if (n < bufsize)-
97 n = sprintf (buf, format, width, prec, promoted_x);-
98 return n;-
99}-
100#endif-
101-
102int-
103FTOASTR (char *buf, size_t bufsize, int flags, int width, FLOAT x)-
104{-
105 /* The following method is simple but slow.-
106 For ideas about speeding things up, please see:-
107-
108 Andrysco M, Jhala R, Lerner S. Printing floating-point numbers:-
109 a faster, always correct method. ACM SIGPLAN notices - POPL '16.-
110 2016;51(1):555-67 <http://dx.doi.org/10.1145/2914770.2837654>; draft at-
111 <https://cseweb.ucsd.edu/~lerner/papers/fp-printing-popl16.pdf>. */-
112-
113 PROMOTED_FLOAT promoted_x = x;-
114 char format[sizeof "%-+ 0*.*Lg"];-
115 FLOAT abs_x = x < 0 ? -x : x;
x < 0Description
TRUEevaluated 6 times by 1 test
Evaluated by:
  • od
FALSEevaluated 1076 times by 2 tests
Evaluated by:
  • getlimits
  • od
6-1076
116 int prec;-
117-
118 char *p = format;-
119 *p++ = '%';-
120-
121 /* Support flags that generate output parsable by strtof. */-
122 *p = '-'; p += (flags & FTOASTR_LEFT_JUSTIFY ) != 0;-
123 *p = '+'; p += (flags & FTOASTR_ALWAYS_SIGNED ) != 0;-
124 *p = ' '; p += (flags & FTOASTR_SPACE_POSITIVE) != 0;-
125 *p = '0'; p += (flags & FTOASTR_ZERO_PAD ) != 0;-
126-
127 *p++ = '*';-
128 *p++ = '.';-
129 *p++ = '*';-
130 *p = 'L'; p += 2 < LENGTH;-
131 *p++ = flags & FTOASTR_UPPER_E ? 'G' : 'g';
flags & FTOASTR_UPPER_EDescription
TRUEnever evaluated
FALSEevaluated 1082 times by 2 tests
Evaluated by:
  • getlimits
  • od
0-1082
132 *p = '\0';-
133-
134 for (prec = abs_x < FLOAT_MIN ? 1 : FLOAT_DIG; ; prec++)-
135 {-
136 int n = snprintf (buf, bufsize, format, width, prec, promoted_x);-
137 if (n < 0
n < 0Description
TRUEnever evaluated
FALSEevaluated 2790 times by 2 tests
Evaluated by:
  • getlimits
  • od
0-2790
138 || FLOAT_PREC_BOUND <= prec
(((((53) * 1) ...) + 1) <= precDescription
TRUEevaluated 357 times by 2 tests
Evaluated by:
  • getlimits
  • od
FALSEevaluated 2433 times by 2 tests
Evaluated by:
  • getlimits
  • od
357-2433
139 || (n < bufsize && STRTOF (buf, NULL) == x))
n < bufsizeDescription
TRUEevaluated 2433 times by 2 tests
Evaluated by:
  • getlimits
  • od
FALSEnever evaluated
strtod (buf, (...id *)0) ) == xDescription
TRUEevaluated 725 times by 2 tests
Evaluated by:
  • getlimits
  • od
FALSEevaluated 1708 times by 2 tests
Evaluated by:
  • getlimits
  • od
0-2433
140 return n;
executed 1082 times by 2 tests: return n;
Executed by:
  • getlimits
  • od
1082
141 }
executed 1708 times by 2 tests: end of block
Executed by:
  • getlimits
  • od
1708
142}
never executed: end of block
0
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2