]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/m2/mc-boot-ch/Gldtoa.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / mc-boot-ch / Gldtoa.cc
1 /* Gldtoa.cc provides access to long double string conversion.
2
3 Copyright (C) 2016-2024 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius@glam.ac.uk>.
5
6 This file is part of GNU Modula-2.
7
8 GNU Modula-2 is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GNU Modula-2 is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU Modula-2; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22 #include "config.h"
23 #include "system.h"
24
25 #include "gm2-libs-host.h"
26
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30
31 #define MAX_FP_DIGITS 500
32
33 typedef enum Mode { maxsignicant, decimaldigits } Mode;
34
35 extern int dtoa_calcmaxsig (char *p, int ndigits);
36 extern int dtoa_calcdecimal (char *p, int str_size, int ndigits);
37 extern int dtoa_calcsign (char *p, int str_size);
38
39 /* maxsignicant: return a string containing max(1,ndigits)
40 significant digits. The return string contains the string
41 produced by snprintf. decimaldigits: return a string produced by
42 fcvt. The string will contain ndigits past the decimal point
43 (ndigits may be negative). */
44
45 long double
46 ldtoa_strtold (const char *s, int *error)
47 {
48 char *endp;
49 long double d;
50
51 errno = 0;
52 #if defined(HAVE_STRTOLD)
53 d = strtold (s, &endp);
54 #else
55 /* fall back to using strtod. */
56 d = (long double)strtod (s, &endp);
57 #endif
58 if (endp != NULL && (*endp == '\0'))
59 *error = (errno != 0);
60 else
61 *error = TRUE;
62 return d;
63 }
64
65 char *
66 ldtoa_ldtoa (long double d, int mode, int ndigits, int *decpt, int *sign)
67 {
68 char format[50];
69 char *p;
70 int r;
71 switch (mode)
72 {
73
74 case maxsignicant:
75 ndigits += 20; /* enough for exponent. */
76 p = (char *)malloc (ndigits);
77 snprintf (format, 50, "%s%d%s", "%.", ndigits - 20, "LE");
78 snprintf (p, ndigits, format, d);
79 *sign = dtoa_calcsign (p, ndigits);
80 *decpt = dtoa_calcmaxsig (p, ndigits);
81 return p;
82 case decimaldigits:
83 p = (char *)malloc (MAX_FP_DIGITS + 20);
84 snprintf (format, 50, "%s%d%s", "%.", MAX_FP_DIGITS, "LE");
85 snprintf (p, MAX_FP_DIGITS + 20, format, d);
86 *sign = dtoa_calcsign (p, MAX_FP_DIGITS + 20);
87 *decpt = dtoa_calcdecimal (p, MAX_FP_DIGITS + 20, ndigits);
88 return p;
89 default:
90 abort ();
91 }
92 }
93
94 /* GNU Modula-2 hooks */
95
96 void
97 _M2_ldtoa_init (void)
98 {
99 }
100
101 void
102 _M2_ldtoa_fini (void)
103 {
104 }
105 # ifdef __cplusplus
106 }
107 # endif