summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdlib
diff options
context:
space:
mode:
authormillert <millert@openbsd.org>2002-12-02 15:38:54 +0000
committermillert <millert@openbsd.org>2002-12-02 15:38:54 +0000
commit80944f1949cd485fef6c77d9be08a8bb48d4a55e (patch)
treec1ec6c7043085515a170c88335b10c3e0b0535b2 /lib/libc/stdlib
parentspelling; from Jolan <jolan at cryptonomicon.org> (diff)
downloadwireguard-openbsd-80944f1949cd485fef6c77d9be08a8bb48d4a55e.tar.xz
wireguard-openbsd-80944f1949cd485fef6c77d9be08a8bb48d4a55e.zip
Add ecvt(), fcvt() and gcvt() for standard compliance and legacy code.
Diffstat (limited to 'lib/libc/stdlib')
-rw-r--r--lib/libc/stdlib/Makefile.inc16
-rw-r--r--lib/libc/stdlib/ecvt.3172
-rw-r--r--lib/libc/stdlib/ecvt.c110
-rw-r--r--lib/libc/stdlib/gcvt.c103
-rw-r--r--lib/libc/stdlib/strtod.c4
5 files changed, 396 insertions, 9 deletions
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index 68a8aa6437c..6b23e5cb2d0 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -4,10 +4,10 @@
.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib
SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \
- calloc.c cfree.c exit.c getenv.c getopt.c getsubopt.c heapsort.c \
- l64a.c malloc.c merge.c multibyte.c putenv.c qsort.c radixsort.c \
- rand.c random.c realpath.c setenv.c strtod.c strtol.c strtoll.c \
- strtoul.c strtoull.c system.c tfind.c tsearch.c \
+ calloc.c cfree.c exit.c ecvt.c gcvt.c getenv.c getopt.c getsubopt.c \
+ heapsort.c l64a.c malloc.c merge.c multibyte.c putenv.c qsort.c \
+ radixsort.c rand.c random.c realpath.c setenv.c strtod.c strtol.c \
+ strtoll.c strtoul.c strtoull.c system.c tfind.c tsearch.c \
_rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \
mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c
@@ -33,10 +33,12 @@ SRCS+= abs.c div.c labs.c ldiv.c
.endif
MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 atoll.3 \
- bsearch.3 div.3 exit.3 getenv.3 getopt.3 getsubopt.3 labs.3 ldiv.3 \
- malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 rand.3 \
- random.3 realpath.3 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3
+ bsearch.3 div.3 ecvt.3 exit.3 getenv.3 getopt.3 getsubopt.3 labs.3 \
+ ldiv.3 malloc.3 memory.3 qabs.3 qdiv.3 qsort.3 radixsort.3 rand48.3 \
+ rand.3 random.3 realpath.3 strtod.3 strtol.3 strtoul.3 system.3 \
+ tsearch.3
+MLINKS+=ecvt.3 fcvt.3 ecvt.3 gcvt.3
MLINKS+=getenv.3 setenv.3 getenv.3 unsetenv.3 getenv.3 putenv.3
MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3
MLINKS+=malloc.3 cfree.3 malloc.3 malloc.conf.5
diff --git a/lib/libc/stdlib/ecvt.3 b/lib/libc/stdlib/ecvt.3
new file mode 100644
index 00000000000..1ff9a4f61b4
--- /dev/null
+++ b/lib/libc/stdlib/ecvt.3
@@ -0,0 +1,172 @@
+.\" $OpenBSD
+.\"
+.\" Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd December 1, 2002
+.Dt ECVT 3
+.Os
+.Sh NAME
+.Nm ecvt ,
+.Nm fcvt ,
+.Nm gcvt
+.Nd convert double to
+.Tn ASCII
+string
+.Sh SYNOPSIS
+.Fd #include <stdlib.h>
+.Ft char *
+.Fn ecvt "double value" "int ndigit" "int *decpt" "int *sign"
+.Ft char *
+.Fn fcvt "double value" "int ndigit" "int *decpt" "int *sign"
+.Ft char *
+.Fn gcvt "double value" "int ndigit" "char *buf"
+.Sh DESCRIPTION
+.Bf -symbolic
+These functions are provided for compatibility with legacy code.
+New code should use the
+.Xr snprintf 3
+function for improved safety and portability.
+.Ef
+.Pp
+The
+.Fn ecvt ,
+.Fn fcvt
+and
+.Fn gcvt
+functions convert the double precision floating-point number
+.Fa value
+to a NUL-terminated
+.Tn ASCII
+string.
+.Pp
+The
+.Fn ecvt
+function converts
+.Fa value
+to a NUL-terminated string of exactly
+.Fa ndigit
+digits and returns a pointer to that string.
+The result is padded with zeroes from left to right as needed.
+There are no leading zeroes unless
+.Fa value
+itself is 0.
+The least significant digit is rounded in an implementation-dependent manner.
+The position of the decimal point relative to the beginning of the string
+is stored in
+.Fa decpt .
+A negative value indicates that the decimal point is located
+to the left of the returned digits (this occurs when there is no
+whole number component to
+.Fa value ) .
+If
+.Fa value
+is zero, it is unspecified whether the integer pointed to by
+.Fa decpt
+will be 0 or 1.
+The decimal point itself is not included in the returned string.
+If the sign of the result is negative, the integer pointed to by
+.Fa sign
+is non-zero; otherwise, it is 0.
+.Pp
+If the converted value is out of range or is not representable,
+the contents of the returned string are unspecified.
+.Pp
+The
+.Fn fcvt
+function is identical to
+.Fn ecvt
+with the exception that
+.Fa ndigit
+specifies the number of digits after the decimal point (zero-padded as
+needed).
+.Pp
+The
+.Fn gcvt
+function converts
+.Fa value
+to a NUL-terminated string similar to the %g
+.Xr printf 3
+format specifier and stores the result in
+.Fa buf .
+It produces
+.Fa ndigit
+significant digits similar to the %f
+.Xr printf 3
+format specifier where possible.
+If
+.Fa ndigit
+does allow sufficient precision, the result is stored in
+exponential notation similar to the %e
+.Xr printf 3
+format specifier.
+If
+.Fa value
+is less than zero,
+.Fa buf
+will be prefixed with a minus sign.
+A decimal point is included in the returned string if
+.Fa value
+is not a whole number.
+Unlike the
+.Fn ecvt
+and
+.Fn fcvt
+functions,
+.Fa buf
+is not zero-padded.
+.Sh RETURN VALUES
+The
+.Fn ecvt ,
+.Fn fcvt
+and
+.Fn gcvt
+functions return a NUL-terminated string representation of
+.Fa value .
+.Sh WARNINGS
+The
+.Fn ecvt
+and
+.Fn fcvt
+functions return a pointer to internal storage space that will be
+overwritten by subsequent calls to either function.
+.Pp
+The maximum possible precision of the return value is limited by the
+precision of a double and may not be the same on all architectures.
+.Pp
+The
+.Xr snprintf 3
+function is preferred over these functions for new code.
+.Sh SEE ALSO
+.Xr printf 3 ,
+.Xr strtod 3
+.Sh STANDARDS
+The
+.Fn ecvt ,
+.Fn fcvt
+and
+.Fn gcvt
+functions conform to
+.St -susv3 .
diff --git a/lib/libc/stdlib/ecvt.c b/lib/libc/stdlib/ecvt.c
new file mode 100644
index 00000000000..7460407c84a
--- /dev/null
+++ b/lib/libc/stdlib/ecvt.c
@@ -0,0 +1,110 @@
+/* $OpenBSD: ecvt.c,v 1.1 2002/12/02 15:38:54 millert Exp $ */
+
+/*
+ * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD: ecvt.c,v 1.1 2002/12/02 15:38:54 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern char *__dtoa(double, int, int, int *, int *, char **);
+static char *__cvt(double, int, int *, int *, int, int);
+
+static char *
+__cvt(double value, int ndigit, int *decpt, int *sign, int fmode, int pad)
+{
+ static char *s;
+ char *p, *rve;
+ size_t siz;
+
+ if (ndigit == 0) {
+ *sign = value < 0.0;
+ *decpt = 0;
+ return ("");
+ }
+
+ if (s) {
+ free(s);
+ s = NULL;
+ }
+
+ if (ndigit < 0)
+ siz = -ndigit + 1;
+ else
+ siz = ndigit + 1;
+
+
+ /* __dtoa() doesn't allocate space for 0 so we do it by hand */
+ if (value == 0.0) {
+ *decpt = 1 - fmode; /* 1 for 'e', 0 for 'f' */
+ *sign = 0;
+ if ((rve = s = (char *)malloc(siz)) == NULL)
+ return(NULL);
+ *rve++ = '0';
+ *rve = '\0';
+ } else {
+ p = __dtoa(value, fmode + 2, ndigit, decpt, sign, &rve);
+ if (*decpt == 9999) {
+ /* Nan or Infinity */
+ *decpt = 0;
+ return(p);
+ }
+ /* make a local copy and adjust rve to be in terms of s */
+ if (pad && fmode)
+ siz += *decpt;
+ if ((s = (char *)malloc(siz)) == NULL)
+ return(NULL);
+ (void) strlcpy(s, p, siz);
+ rve = s + (rve - p);
+ }
+
+ /* Add trailing zeros (unless we got NaN or Inf) */
+ if (pad && *decpt != 9999) {
+ siz -= rve - s;
+ while (--siz)
+ *rve++ = '0';
+ *rve = '\0';
+ }
+
+ return(s);
+}
+
+char *
+ecvt(double value, int ndigit, int *decpt, int *sign)
+{
+ return(__cvt(value, ndigit, decpt, sign, 0, 1));
+}
+
+char *
+fcvt(double value, int ndigit, int *decpt, int *sign)
+{
+ return(__cvt(value, ndigit, decpt, sign, 1, 1));
+}
diff --git a/lib/libc/stdlib/gcvt.c b/lib/libc/stdlib/gcvt.c
new file mode 100644
index 00000000000..c1a96b17a59
--- /dev/null
+++ b/lib/libc/stdlib/gcvt.c
@@ -0,0 +1,103 @@
+/* $OpenBSD: gcvt.c,v 1.1 2002/12/02 15:38:54 millert Exp $ */
+
+/*
+ * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD: gcvt.c,v 1.1 2002/12/02 15:38:54 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern char *__dtoa(double, int, int, int *, int *, char **);
+
+char *
+gcvt(double value, int ndigit, char *buf)
+{
+ char *digits, *dst, *src;
+ int i, decpt, sign;
+
+ if (ndigit == 0) {
+ buf[0] = '\0';
+ return (buf);
+ }
+
+ digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL);
+ if (decpt == 9999)
+ return (strcpy(buf, digits));
+
+ dst = buf;
+ if (sign)
+ *dst++ = '-';
+
+ if (decpt < 0 || decpt > ndigit) {
+ /* exponential format */
+ if (--decpt < 0) {
+ sign = 1;
+ decpt = -decpt;
+ } else
+ sign = 0;
+ for (src = digits; *src != '\0'; )
+ *dst++ = *src++;
+ *dst++ = 'e';
+ if (sign)
+ *dst++ = '-';
+ else
+ *dst++ = '+';
+ if (decpt < 10) {
+ *dst++ = '0';
+ *dst++ = '0' + decpt;
+ *dst = '\0';
+ } else {
+ /* XXX - optimize */
+ for (sign = decpt, i = 0; (sign /= 10) != 0; i++)
+ sign /= 10;
+ while (decpt != 0) {
+ dst[i--] = '0' + decpt % 10;
+ decpt /= 10;
+ }
+ }
+ } else {
+ /* standard format */
+ for (i = 0, src = digits; i < decpt; i++) {
+ if (*src != '\0')
+ *dst++ = *src++;
+ else
+ *dst++ = '0';
+ }
+ if (*src != '\0') {
+ *dst++ = '.'; /* XXX - locale-specific (LC_NUMERIC) */
+ for (i = decpt; digits[i] != '\0'; i++) {
+ *dst++ = digits[i];
+ }
+ }
+ *dst = '\0';
+ }
+ return (buf);
+}
diff --git a/lib/libc/stdlib/strtod.c b/lib/libc/stdlib/strtod.c
index ce7ce9fe562..17d26a1dc33 100644
--- a/lib/libc/stdlib/strtod.c
+++ b/lib/libc/stdlib/strtod.c
@@ -90,7 +90,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: strtod.c,v 1.15 2002/02/19 19:39:37 millert Exp $";
+static char *rcsid = "$OpenBSD: strtod.c,v 1.16 2002/12/02 15:38:54 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
@@ -1992,7 +1992,7 @@ __dtoa
*decpt = 9999;
s =
#ifdef IEEE_Arith
- !word1(d) && !(word0(d) & 0xfffff) ? "Infinity" :
+ !word1(d) && !(word0(d) & 0xfffff) ? ndigits < 8 ? "Inf" : "Infinity" :
#endif
"NaN";
if (rve)