summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormillert <>2002-12-02 15:38:54 +0000
committermillert <>2002-12-02 15:38:54 +0000
commit4affa22d97e7ea069b70bc4be601b8da989a17b8 (patch)
tree54be0bf72d5e48013fdce0d5f358e6bd68947bbb
parent67603614edacd4bbbfcbe86a0c4e6f2b0c731c09 (diff)
downloadopenbsd-4affa22d97e7ea069b70bc4be601b8da989a17b8.tar.gz
openbsd-4affa22d97e7ea069b70bc4be601b8da989a17b8.tar.bz2
openbsd-4affa22d97e7ea069b70bc4be601b8da989a17b8.zip
Add ecvt(), fcvt() and gcvt() for standard compliance and legacy code.
-rw-r--r--src/lib/libc/stdlib/Makefile.inc16
-rw-r--r--src/lib/libc/stdlib/ecvt.3172
-rw-r--r--src/lib/libc/stdlib/ecvt.c110
-rw-r--r--src/lib/libc/stdlib/gcvt.c103
-rw-r--r--src/lib/libc/stdlib/strtod.c4
5 files changed, 396 insertions, 9 deletions
diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc
index 68a8aa6437..6b23e5cb2d 100644
--- a/src/lib/libc/stdlib/Makefile.inc
+++ b/src/lib/libc/stdlib/Makefile.inc
@@ -4,10 +4,10 @@
4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib 4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib
5 5
6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \ 6SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \
7 calloc.c cfree.c exit.c getenv.c getopt.c getsubopt.c heapsort.c \ 7 calloc.c cfree.c exit.c ecvt.c gcvt.c getenv.c getopt.c getsubopt.c \
8 l64a.c malloc.c merge.c multibyte.c putenv.c qsort.c radixsort.c \ 8 heapsort.c l64a.c malloc.c merge.c multibyte.c putenv.c qsort.c \
9 rand.c random.c realpath.c setenv.c strtod.c strtol.c strtoll.c \ 9 radixsort.c rand.c random.c realpath.c setenv.c strtod.c strtol.c \
10 strtoul.c strtoull.c system.c tfind.c tsearch.c \ 10 strtoll.c strtoul.c strtoull.c system.c tfind.c tsearch.c \
11 _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \ 11 _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \
12 mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c 12 mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c
13 13
@@ -33,10 +33,12 @@ SRCS+= abs.c div.c labs.c ldiv.c
33.endif 33.endif
34 34
35MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 atoll.3 \ 35MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 atoll.3 \
36 bsearch.3 div.3 exit.3 getenv.3 getopt.3 getsubopt.3 labs.3 ldiv.3 \ 36 bsearch.3 div.3 ecvt.3 exit.3 getenv.3 getopt.3 getsubopt.3 labs.3 \
37 malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 \ 37 ldiv.3 malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 \
38 random.3 realpath.3 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3 38 rand.3 random.3 realpath.3 strtod.3 strtol.3 strtoul.3 system.3 \
39 tsearch.3
39 40
41MLINKS+=ecvt.3 fcvt.3 ecvt.3 gcvt.3
40MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3 42MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3
41MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3 43MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3
42MLINKS+=malloc.3 cfree.3 malloc.3 malloc.conf.5 44MLINKS+=malloc.3 cfree.3 malloc.3 malloc.conf.5
diff --git a/src/lib/libc/stdlib/ecvt.3 b/src/lib/libc/stdlib/ecvt.3
new file mode 100644
index 0000000000..1ff9a4f61b
--- /dev/null
+++ b/src/lib/libc/stdlib/ecvt.3
@@ -0,0 +1,172 @@
1.\" $OpenBSD
2.\"
3.\" Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. The name of the author may not be used to endorse or promote products
15.\" derived from this software without specific prior written permission.
16.\"
17.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27.\"
28.Dd December 1, 2002
29.Dt ECVT 3
30.Os
31.Sh NAME
32.Nm ecvt ,
33.Nm fcvt ,
34.Nm gcvt
35.Nd convert double to
36.Tn ASCII
37string
38.Sh SYNOPSIS
39.Fd #include <stdlib.h>
40.Ft char *
41.Fn ecvt "double value" "int ndigit" "int *decpt" "int *sign"
42.Ft char *
43.Fn fcvt "double value" "int ndigit" "int *decpt" "int *sign"
44.Ft char *
45.Fn gcvt "double value" "int ndigit" "char *buf"
46.Sh DESCRIPTION
47.Bf -symbolic
48These functions are provided for compatibility with legacy code.
49New code should use the
50.Xr snprintf 3
51function for improved safety and portability.
52.Ef
53.Pp
54The
55.Fn ecvt ,
56.Fn fcvt
57and
58.Fn gcvt
59functions convert the double precision floating-point number
60.Fa value
61to a NUL-terminated
62.Tn ASCII
63string.
64.Pp
65The
66.Fn ecvt
67function converts
68.Fa value
69to a NUL-terminated string of exactly
70.Fa ndigit
71digits and returns a pointer to that string.
72The result is padded with zeroes from left to right as needed.
73There are no leading zeroes unless
74.Fa value
75itself is 0.
76The least significant digit is rounded in an implementation-dependent manner.
77The position of the decimal point relative to the beginning of the string
78is stored in
79.Fa decpt .
80A negative value indicates that the decimal point is located
81to the left of the returned digits (this occurs when there is no
82whole number component to
83.Fa value ) .
84If
85.Fa value
86is zero, it is unspecified whether the integer pointed to by
87.Fa decpt
88will be 0 or 1.
89The decimal point itself is not included in the returned string.
90If the sign of the result is negative, the integer pointed to by
91.Fa sign
92is non-zero; otherwise, it is 0.
93.Pp
94If the converted value is out of range or is not representable,
95the contents of the returned string are unspecified.
96.Pp
97The
98.Fn fcvt
99function is identical to
100.Fn ecvt
101with the exception that
102.Fa ndigit
103specifies the number of digits after the decimal point (zero-padded as
104needed).
105.Pp
106The
107.Fn gcvt
108function converts
109.Fa value
110to a NUL-terminated string similar to the %g
111.Xr printf 3
112format specifier and stores the result in
113.Fa buf .
114It produces
115.Fa ndigit
116significant digits similar to the %f
117.Xr printf 3
118format specifier where possible.
119If
120.Fa ndigit
121does allow sufficient precision, the result is stored in
122exponential notation similar to the %e
123.Xr printf 3
124format specifier.
125If
126.Fa value
127is less than zero,
128.Fa buf
129will be prefixed with a minus sign.
130A decimal point is included in the returned string if
131.Fa value
132is not a whole number.
133Unlike the
134.Fn ecvt
135and
136.Fn fcvt
137functions,
138.Fa buf
139is not zero-padded.
140.Sh RETURN VALUES
141The
142.Fn ecvt ,
143.Fn fcvt
144and
145.Fn gcvt
146functions return a NUL-terminated string representation of
147.Fa value .
148.Sh WARNINGS
149The
150.Fn ecvt
151and
152.Fn fcvt
153functions return a pointer to internal storage space that will be
154overwritten by subsequent calls to either function.
155.Pp
156The maximum possible precision of the return value is limited by the
157precision of a double and may not be the same on all architectures.
158.Pp
159The
160.Xr snprintf 3
161function is preferred over these functions for new code.
162.Sh SEE ALSO
163.Xr printf 3 ,
164.Xr strtod 3
165.Sh STANDARDS
166The
167.Fn ecvt ,
168.Fn fcvt
169and
170.Fn gcvt
171functions conform to
172.St -susv3 .
diff --git a/src/lib/libc/stdlib/ecvt.c b/src/lib/libc/stdlib/ecvt.c
new file mode 100644
index 0000000000..7460407c84
--- /dev/null
+++ b/src/lib/libc/stdlib/ecvt.c
@@ -0,0 +1,110 @@
1/* $OpenBSD: ecvt.c,v 1.1 2002/12/02 15:38:54 millert Exp $ */
2
3/*
4 * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char rcsid[] = "$OpenBSD: ecvt.c,v 1.1 2002/12/02 15:38:54 millert Exp $";
32#endif /* LIBC_SCCS and not lint */
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37
38extern char *__dtoa(double, int, int, int *, int *, char **);
39static char *__cvt(double, int, int *, int *, int, int);
40
41static char *
42__cvt(double value, int ndigit, int *decpt, int *sign, int fmode, int pad)
43{
44 static char *s;
45 char *p, *rve;
46 size_t siz;
47
48 if (ndigit == 0) {
49 *sign = value < 0.0;
50 *decpt = 0;
51 return ("");
52 }
53
54 if (s) {
55 free(s);
56 s = NULL;
57 }
58
59 if (ndigit < 0)
60 siz = -ndigit + 1;
61 else
62 siz = ndigit + 1;
63
64
65 /* __dtoa() doesn't allocate space for 0 so we do it by hand */
66 if (value == 0.0) {
67 *decpt = 1 - fmode; /* 1 for 'e', 0 for 'f' */
68 *sign = 0;
69 if ((rve = s = (char *)malloc(siz)) == NULL)
70 return(NULL);
71 *rve++ = '0';
72 *rve = '\0';
73 } else {
74 p = __dtoa(value, fmode + 2, ndigit, decpt, sign, &rve);
75 if (*decpt == 9999) {
76 /* Nan or Infinity */
77 *decpt = 0;
78 return(p);
79 }
80 /* make a local copy and adjust rve to be in terms of s */
81 if (pad && fmode)
82 siz += *decpt;
83 if ((s = (char *)malloc(siz)) == NULL)
84 return(NULL);
85 (void) strlcpy(s, p, siz);
86 rve = s + (rve - p);
87 }
88
89 /* Add trailing zeros (unless we got NaN or Inf) */
90 if (pad && *decpt != 9999) {
91 siz -= rve - s;
92 while (--siz)
93 *rve++ = '0';
94 *rve = '\0';
95 }
96
97 return(s);
98}
99
100char *
101ecvt(double value, int ndigit, int *decpt, int *sign)
102{
103 return(__cvt(value, ndigit, decpt, sign, 0, 1));
104}
105
106char *
107fcvt(double value, int ndigit, int *decpt, int *sign)
108{
109 return(__cvt(value, ndigit, decpt, sign, 1, 1));
110}
diff --git a/src/lib/libc/stdlib/gcvt.c b/src/lib/libc/stdlib/gcvt.c
new file mode 100644
index 0000000000..c1a96b17a5
--- /dev/null
+++ b/src/lib/libc/stdlib/gcvt.c
@@ -0,0 +1,103 @@
1/* $OpenBSD: gcvt.c,v 1.1 2002/12/02 15:38:54 millert Exp $ */
2
3/*
4 * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char rcsid[] = "$OpenBSD: gcvt.c,v 1.1 2002/12/02 15:38:54 millert Exp $";
32#endif /* LIBC_SCCS and not lint */
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37
38extern char *__dtoa(double, int, int, int *, int *, char **);
39
40char *
41gcvt(double value, int ndigit, char *buf)
42{
43 char *digits, *dst, *src;
44 int i, decpt, sign;
45
46 if (ndigit == 0) {
47 buf[0] = '\0';
48 return (buf);
49 }
50
51 digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL);
52 if (decpt == 9999)
53 return (strcpy(buf, digits));
54
55 dst = buf;
56 if (sign)
57 *dst++ = '-';
58
59 if (decpt < 0 || decpt > ndigit) {
60 /* exponential format */
61 if (--decpt < 0) {
62 sign = 1;
63 decpt = -decpt;
64 } else
65 sign = 0;
66 for (src = digits; *src != '\0'; )
67 *dst++ = *src++;
68 *dst++ = 'e';
69 if (sign)
70 *dst++ = '-';
71 else
72 *dst++ = '+';
73 if (decpt < 10) {
74 *dst++ = '0';
75 *dst++ = '0' + decpt;
76 *dst = '\0';
77 } else {
78 /* XXX - optimize */
79 for (sign = decpt, i = 0; (sign /= 10) != 0; i++)
80 sign /= 10;
81 while (decpt != 0) {
82 dst[i--] = '0' + decpt % 10;
83 decpt /= 10;
84 }
85 }
86 } else {
87 /* standard format */
88 for (i = 0, src = digits; i < decpt; i++) {
89 if (*src != '\0')
90 *dst++ = *src++;
91 else
92 *dst++ = '0';
93 }
94 if (*src != '\0') {
95 *dst++ = '.'; /* XXX - locale-specific (LC_NUMERIC) */
96 for (i = decpt; digits[i] != '\0'; i++) {
97 *dst++ = digits[i];
98 }
99 }
100 *dst = '\0';
101 }
102 return (buf);
103}
diff --git a/src/lib/libc/stdlib/strtod.c b/src/lib/libc/stdlib/strtod.c
index ce7ce9fe56..17d26a1dc3 100644
--- a/src/lib/libc/stdlib/strtod.c
+++ b/src/lib/libc/stdlib/strtod.c
@@ -90,7 +90,7 @@
90 */ 90 */
91 91
92#if defined(LIBC_SCCS) && !defined(lint) 92#if defined(LIBC_SCCS) && !defined(lint)
93static char *rcsid = "$OpenBSD: strtod.c,v 1.15 2002/02/19 19:39:37 millert Exp $"; 93static char *rcsid = "$OpenBSD: strtod.c,v 1.16 2002/12/02 15:38:54 millert Exp $";
94#endif /* LIBC_SCCS and not lint */ 94#endif /* LIBC_SCCS and not lint */
95 95
96#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ 96#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
@@ -1992,7 +1992,7 @@ __dtoa
1992 *decpt = 9999; 1992 *decpt = 9999;
1993 s = 1993 s =
1994#ifdef IEEE_Arith 1994#ifdef IEEE_Arith
1995 !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" : 1995 !word1(d) && !(word0(d) & 0xfffff) ? ndigits < 8 ? "Inf" : "Infinity" :
1996#endif 1996#endif
1997 "NaN"; 1997 "NaN";
1998 if (rve) 1998 if (rve)