summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/gcvt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/stdlib/gcvt.c')
-rw-r--r--src/lib/libc/stdlib/gcvt.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/lib/libc/stdlib/gcvt.c b/src/lib/libc/stdlib/gcvt.c
new file mode 100644
index 0000000000..240c4db5b0
--- /dev/null
+++ b/src/lib/libc/stdlib/gcvt.c
@@ -0,0 +1,106 @@
1/* $OpenBSD: gcvt.c,v 1.3 2003/05/09 20:01:43 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.3 2003/05/09 20:01:43 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 /* Infinity or NaN, assume buffer is at least ndigit long. */
54 strlcpy(buf, digits, ndigit + 1);
55 return (buf);
56 }
57
58 dst = buf;
59 if (sign)
60 *dst++ = '-';
61
62 if (decpt < 0 || decpt > ndigit) {
63 /* exponential format */
64 if (--decpt < 0) {
65 sign = 1;
66 decpt = -decpt;
67 } else
68 sign = 0;
69 for (src = digits; *src != '\0'; )
70 *dst++ = *src++;
71 *dst++ = 'e';
72 if (sign)
73 *dst++ = '-';
74 else
75 *dst++ = '+';
76 if (decpt < 10) {
77 *dst++ = '0';
78 *dst++ = '0' + decpt;
79 *dst = '\0';
80 } else {
81 /* XXX - optimize */
82 for (sign = decpt, i = 0; (sign /= 10) != 0; i++)
83 sign /= 10;
84 while (decpt != 0) {
85 dst[i--] = '0' + decpt % 10;
86 decpt /= 10;
87 }
88 }
89 } else {
90 /* standard format */
91 for (i = 0, src = digits; i < decpt; i++) {
92 if (*src != '\0')
93 *dst++ = *src++;
94 else
95 *dst++ = '0';
96 }
97 if (*src != '\0') {
98 *dst++ = '.'; /* XXX - locale-specific (LC_NUMERIC) */
99 for (i = decpt; digits[i] != '\0'; i++) {
100 *dst++ = digits[i];
101 }
102 }
103 *dst = '\0';
104 }
105 return (buf);
106}