This source file includes following definitions.
- ftoastr_snprintf
- FTOASTR
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 #ifdef C_LOCALE
37 # include "c-snprintf.h"
38 # include "c-strtod.h"
39 # define PREFIX(name) c_ ## name
40 #else
41 # define PREFIX(name) name
42 #endif
43
44 #if LENGTH == 3
45 # define FLOAT long double
46 # define FLOAT_DIG LDBL_DIG
47 # define FLOAT_MIN LDBL_MIN
48 # define FLOAT_PREC_BOUND _GL_LDBL_PREC_BOUND
49 # define FTOASTR PREFIX (ldtoastr)
50 # define PROMOTED_FLOAT long double
51 # define STRTOF PREFIX (strtold)
52 #elif LENGTH == 2
53 # define FLOAT double
54 # define FLOAT_DIG DBL_DIG
55 # define FLOAT_MIN DBL_MIN
56 # define FLOAT_PREC_BOUND _GL_DBL_PREC_BOUND
57 # define FTOASTR PREFIX (dtoastr)
58 # define PROMOTED_FLOAT double
59 #else
60 # define LENGTH 1
61 # define FLOAT float
62 # define FLOAT_DIG FLT_DIG
63 # define FLOAT_MIN FLT_MIN
64 # define FLOAT_PREC_BOUND _GL_FLT_PREC_BOUND
65 # define FTOASTR PREFIX (ftoastr)
66 # define PROMOTED_FLOAT double
67 # if HAVE_STRTOF
68 # define STRTOF strtof
69 # endif
70 #endif
71
72
73
74
75 #ifndef STRTOF
76 # define STRTOF PREFIX (strtod)
77 #endif
78
79
80
81
82 #ifdef C_LOCALE
83 # undef snprintf
84 # define snprintf c_snprintf
85 #elif ! GNULIB_SNPRINTF
86 # undef snprintf
87 # define snprintf ftoastr_snprintf
88 static int
89 ftoastr_snprintf (char *buf, size_t bufsize, char const *format,
90 int width, int prec, FLOAT x)
91 {
92 PROMOTED_FLOAT promoted_x = x;
93 char width_0_buffer[LENGTH == 1 ? FLT_BUFSIZE_BOUND
94 : LENGTH == 2 ? DBL_BUFSIZE_BOUND
95 : LDBL_BUFSIZE_BOUND];
96 int n = width;
97 if (bufsize < sizeof width_0_buffer)
98 {
99 n = sprintf (width_0_buffer, format, 0, prec, promoted_x);
100 if (n < 0)
101 return n;
102 if (n < width)
103 n = width;
104 }
105 if (n < bufsize)
106 n = sprintf (buf, format, width, prec, promoted_x);
107 return n;
108 }
109 #endif
110
111 int
112 FTOASTR (char *buf, size_t bufsize, int flags, int width, FLOAT x)
113 {
114
115
116
117
118
119
120
121
122 PROMOTED_FLOAT promoted_x = x;
123 char format[sizeof "%-+ 0*.*Lg"];
124 FLOAT abs_x = x < 0 ? -x : x;
125 int prec;
126
127 char *p = format;
128 *p++ = '%';
129
130
131 *p = '-'; p += (flags & FTOASTR_LEFT_JUSTIFY ) != 0;
132 *p = '+'; p += (flags & FTOASTR_ALWAYS_SIGNED ) != 0;
133 *p = ' '; p += (flags & FTOASTR_SPACE_POSITIVE) != 0;
134 *p = '0'; p += (flags & FTOASTR_ZERO_PAD ) != 0;
135
136 *p++ = '*';
137 *p++ = '.';
138 *p++ = '*';
139 *p = 'L'; p += 2 < LENGTH;
140 *p++ = flags & FTOASTR_UPPER_E ? 'G' : 'g';
141 *p = '\0';
142
143 for (prec = abs_x < FLOAT_MIN ? 1 : FLOAT_DIG; ; prec++)
144 {
145 int n = snprintf (buf, bufsize, format, width, prec, promoted_x);
146 if (n < 0
147 || FLOAT_PREC_BOUND <= prec
148 || (n < bufsize && STRTOF (buf, NULL) == x))
149 return n;
150 }
151 }