Added binary and unicode file i/o support to msvcrt.
[reactos.git] / reactos / lib / crtdll / stdlib / fcvtbuf.c
1 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
2 #include <msvcrt/stdlib.h>
3 #include <msvcrt/stdio.h>
4 #include <msvcrt/string.h>
5 #include <msvcrt/float.h>
6 #include <msvcrt/alloc.h>
7 // #include <msvcrt/locale.h>
8
9 void __ecvround (char *, char *, const char *, int *);
10 char *ecvtbuf (double, int, int *, int *, char *);
11
12 char *
13 fcvtbuf (double value, int ndigits, int *decpt, int *sign, char *buf)
14 {
15 static char INFINITY[] = "Infinity";
16 char decimal = '.' /* localeconv()->decimal_point[0] */;
17 int digits = ndigits >= 0 ? ndigits : 0;
18 char *cvtbuf = (char *)alloca (2*DBL_MAX_10_EXP + 16);
19 char *s = cvtbuf;
20 char *dot;
21
22 sprintf (cvtbuf, "%-+#.*f", DBL_MAX_10_EXP + digits + 1, value);
23
24 /* The sign. */
25 if (*s++ == '-')
26 *sign = 1;
27 else
28 *sign = 0;
29
30 /* Where's the decimal point? */
31 dot = strchr (s, decimal);
32 *decpt = dot ? dot - s : strlen (s);
33
34 /* SunOS docs says if NDIGITS is 8 or more, produce "Infinity"
35 instead of "Inf". */
36 if (strncmp (s, "Inf", 3) == 0)
37 {
38 memcpy (buf, INFINITY, ndigits >= 8 ? 9 : 3);
39 if (ndigits < 8)
40 buf[3] = '\0';
41 return buf;
42 }
43 else if (ndigits < 0)
44 return ecvtbuf (value, *decpt + ndigits, decpt, sign, buf);
45 else if (*s == '0' && value != 0.0)
46 return ecvtbuf (value, ndigits, decpt, sign, buf);
47 else
48 {
49 memcpy (buf, s, *decpt);
50 if (s[*decpt] == decimal)
51 {
52 memcpy (buf + *decpt, s + *decpt + 1, ndigits);
53 buf[*decpt + ndigits] = '\0';
54 }
55 else
56 buf[*decpt] = '\0';
57 __ecvround (buf, buf + *decpt + ndigits - 1,
58 s + *decpt + ndigits + 1, decpt);
59 return buf;
60 }
61 }