summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/ecvt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/stdlib/ecvt.c')
-rw-r--r--src/lib/libc/stdlib/ecvt.c110
1 files changed, 110 insertions, 0 deletions
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}