]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/m2/gm2-libs-ch/ldtoa.cc
modula-2: Module registration constructors need to be visible [PR108259].
[thirdparty/gcc.git] / gcc / m2 / gm2-libs-ch / ldtoa.cc
CommitLineData
1eee94d3
GM
1/* ldtoa.c provide long double floating point string conversion routines.
2
3Copyright (C) 2009-2022 Free Software Foundation, Inc.
4Contributed by Gaius Mulley <gaius@glam.ac.uk>.
5
6This file is part of GNU Modula-2.
7
8GNU Modula-2 is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GNU Modula-2 is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16General Public License for more details.
17
18Under Section 7 of GPL version 3, you are granted additional
19permissions described in the GCC Runtime Library Exception, version
203.1, as published by the Free Software Foundation.
21
22You should have received a copy of the GNU General Public License and
23a copy of the GCC Runtime Library Exception along with this program;
24see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25<http://www.gnu.org/licenses/>. */
26
27#include "config.h"
28#include "system.h"
29#include "ansidecl.h"
30
31#include "gm2-libs-host.h"
32#include "m2rts.h"
33
34# ifdef __cplusplus
35extern "C" {
36# endif
37
38#define MAX_FP_DIGITS 500
39
40typedef enum Mode { maxsignicant, decimaldigits } Mode;
41
42extern int dtoa_calcmaxsig (char *p, int ndigits);
43extern int dtoa_calcdecimal (char *p, int str_size, int ndigits);
44extern int dtoa_calcsign (char *p, int str_size);
45
46/* maxsignicant: return a string containing max(1,ndigits)
47 significant digits. The return string contains the string
48 produced by snprintf. decimaldigits: return a string produced by
49 fcvt. The string will contain ndigits past the decimal point
50 (ndigits may be negative). */
51
52long double
53ldtoa_strtold (const char *s, int *error)
54{
55 char *endp;
56 long double d;
57
58 errno = 0;
59#if defined(HAVE_STRTOLD)
60 d = strtold (s, &endp);
61#else
62 /* fall back to using strtod. */
63 d = (long double)strtod (s, &endp);
64#endif
65 if (endp != NULL && (*endp == '\0'))
66 *error = (errno != 0);
67 else
68 *error = TRUE;
69 return d;
70}
71
72char *
73ldtoa_ldtoa (long double d, int mode, int ndigits, int *decpt, int *sign)
74{
75 char format[50];
76 char *p;
77 int r;
78 switch (mode)
79 {
80
81 case maxsignicant:
82 ndigits += 20; /* enough for exponent. */
83 p = (char *) malloc (ndigits);
84 snprintf (format, 50, "%s%d%s", "%.", ndigits - 20, "LE");
85 snprintf (p, ndigits, format, d);
86 *sign = dtoa_calcsign (p, ndigits);
87 *decpt = dtoa_calcmaxsig (p, ndigits);
88 return p;
89 case decimaldigits:
90 p = (char *) malloc (MAX_FP_DIGITS + 20);
91 snprintf (format, 50, "%s%d%s", "%.", MAX_FP_DIGITS, "LE");
92 snprintf (p, MAX_FP_DIGITS + 20, format, d);
93 *sign = dtoa_calcsign (p, MAX_FP_DIGITS + 20);
94 *decpt = dtoa_calcdecimal (p, MAX_FP_DIGITS + 20, ndigits);
95 return p;
96 default:
97 abort ();
98 }
99}
100
101/* GNU Modula-2 hooks */
102
103void
104_M2_ldtoa_init (int, char **, char **)
105{
106}
107
108void
109_M2_ldtoa_finish (int, char **, char **)
110{
111}
112
113void
114_M2_ldtoa_dep (void)
115{
116}
117
118# ifdef __cplusplus
119}
120
121struct _M2_ldtoa_ctor { _M2_ldtoa_ctor (); } _M2_ldtoa_ctor;
122
123_M2_ldtoa_ctor::_M2_ldtoa_ctor (void)
124{
125 M2RTS_RegisterModule ("ldtoa", _M2_ldtoa_init, _M2_ldtoa_finish,
126 _M2_ldtoa_dep);
127}
128
129#else
130void
131_M2_ldtoa_ctor (void)
132{
133}
134
135# endif