xfail scan-tree-dump-not throw in g++.dg/pr99966.C on hppa*64*-*-*
[official-gcc.git] / gcc / m2 / mc-boot-ch / Gdtoa.cc
blob94f4488c13f45505e78ff4ce35d51de91cfe828b
1 /* Gdtoa.cc provides access to double string conversion.
3 Copyright (C) 2016-2024 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius@glam.ac.uk>.
6 This file is part of GNU Modula-2.
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.
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.
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/>. */
22 #define GM2
24 #include "config.h"
25 #include "system.h"
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
32 #define MAX_FP_DIGITS 500
34 typedef enum Mode { maxsignicant, decimaldigits } Mode;
36 /* maxsignicant: return a string containing max(1,ndigits)
37 significant digits. The return string contains the string
38 produced by ecvt. decimaldigits: return a string produced by
39 fcvt. The string will contain ndigits past the decimal point
40 (ndigits may be negative). */
42 double
43 dtoa_strtod (const char *s, int *error)
45 char *endp;
46 double d;
48 errno = 0;
49 d = strtod (s, &endp);
50 if (endp != NULL && (*endp == '\0'))
51 *error = (errno != 0);
52 else
53 *error = TRUE;
54 return d;
57 /* dtoa_calcmaxsig - calculates the position of the decimal point it
58 also removes the decimal point and exponent from string, p. */
60 int
61 dtoa_calcmaxsig (char *p, int ndigits)
63 char *e;
64 char *o;
65 int x;
67 e = index (p, 'E');
68 if (e == NULL)
69 x = 0;
70 else
72 *e = (char)0;
73 x = atoi (e + 1);
76 o = index (p, '.');
77 if (o == NULL)
78 return strlen (p) + x;
79 else
81 memmove (o, o + 1, ndigits - (o - p));
82 return o - p + x;
86 /* dtoa_calcdecimal - calculates the position of the decimal point it
87 also removes the decimal point and exponent from string, p. It
88 truncates the digits in p accordingly to ndigits. Ie ndigits is
89 the number of digits after the '.' */
91 int
92 dtoa_calcdecimal (char *p, int str_size, int ndigits)
94 char *e;
95 char *o;
96 int x;
97 int l;
99 e = index (p, 'E');
100 if (e == NULL)
101 x = 0;
102 else
104 *e = (char)0;
105 x = atoi (e + 1);
108 l = strlen (p);
109 o = index (p, '.');
110 if (o == NULL)
111 x += strlen (p);
112 else
114 int m = strlen (o);
115 memmove (o, o + 1, l - (o - p));
116 if (m > 0)
117 o[m - 1] = '0';
118 x += o - p;
120 if ((x + ndigits >= 0) && (x + ndigits < str_size))
121 p[x + ndigits] = (char)0;
122 return x;
127 dtoa_calcsign (char *p, int str_size)
129 if (p[0] == '-')
131 memmove (p, p + 1, str_size - 1);
132 return TRUE;
134 else
135 return FALSE;
139 char *
140 dtoa_dtoa (double d, int mode, int ndigits, int *decpt, int *sign)
142 char format[50];
143 char *p;
144 int r;
145 switch (mode)
148 case maxsignicant:
149 ndigits += 20; /* enough for exponent. */
150 p = (char *) malloc (ndigits);
151 snprintf (format, 50, "%s%d%s", "%.", ndigits - 20, "E");
152 snprintf (p, ndigits, format, d);
153 *sign = dtoa_calcsign (p, ndigits);
154 *decpt = dtoa_calcmaxsig (p, ndigits);
155 return p;
156 case decimaldigits:
157 p = (char *) malloc (MAX_FP_DIGITS + 20);
158 snprintf (format, 50, "%s%d%s", "%.", MAX_FP_DIGITS, "E");
159 snprintf (p, MAX_FP_DIGITS + 20, format, d);
160 *sign = dtoa_calcsign (p, MAX_FP_DIGITS + 20);
161 *decpt = dtoa_calcdecimal (p, MAX_FP_DIGITS + 20, ndigits);
162 return p;
163 default:
164 abort ();
168 #if defined(GM2)
169 /* GNU Modula-2 hooks */
171 void
172 _M2_dtoa_init (void)
176 void
177 _M2_dtoa_fini (void)
180 #endif
182 #ifdef __cplusplus
184 #endif