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.c103
1 files changed, 103 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..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}