]>
Commit | Line | Data |
---|---|---|
9385eb3d A |
1 | /**************************************************************** |
2 | ||
3 | The author of this software is David M. Gay. | |
4 | ||
5 | Copyright (C) 2000 by Lucent Technologies | |
6 | All Rights Reserved | |
7 | ||
8 | Permission to use, copy, modify, and distribute this software and | |
9 | its documentation for any purpose and without fee is hereby | |
10 | granted, provided that the above copyright notice appear in all | |
11 | copies and that both that the copyright notice and this | |
12 | permission notice and warranty disclaimer appear in supporting | |
13 | documentation, and that the name of Lucent or any of its entities | |
14 | not be used in advertising or publicity pertaining to | |
15 | distribution of the software without specific, written prior | |
16 | permission. | |
17 | ||
18 | LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
19 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. | |
20 | IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY | |
21 | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
22 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |
23 | IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
24 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |
25 | THIS SOFTWARE. | |
26 | ||
27 | ****************************************************************/ | |
28 | ||
3d9156a7 A |
29 | /* Please send bug reports to David M. Gay (dmg at acm dot org, |
30 | * with " at " changed at "@" and " dot " changed to "."). */ | |
9385eb3d A |
31 | |
32 | #include "gdtoaimp.h" | |
ad3c9f2a | 33 | #include <fpmath.h> |
9385eb3d | 34 | |
ad3c9f2a | 35 | #ifndef __APPLE__ |
9385eb3d A |
36 | static void |
37 | #ifdef KR_headers | |
38 | L_shift(x, x1, i) ULong *x; ULong *x1; int i; | |
39 | #else | |
40 | L_shift(ULong *x, ULong *x1, int i) | |
41 | #endif | |
42 | { | |
43 | int j; | |
44 | ||
45 | i = 8 - i; | |
46 | i <<= 2; | |
47 | j = ULbits - i; | |
48 | do { | |
49 | *x |= x[1] << j; | |
50 | x[1] >>= i; | |
51 | } while(++x < x1); | |
52 | } | |
ad3c9f2a | 53 | #endif /* !__APPLE__ */ |
9385eb3d A |
54 | |
55 | int | |
56 | #ifdef KR_headers | |
57 | hexnan(sp, fpi, x0) | |
6465356a | 58 | CONST char **sp; CONST FPI *fpi; ULong *x0; |
9385eb3d | 59 | #else |
6465356a | 60 | hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0) |
9385eb3d A |
61 | #endif |
62 | { | |
ad3c9f2a A |
63 | #ifdef __APPLE__ |
64 | int nbits, len; | |
65 | char *cp; | |
66 | #else /* !__APPLE__ */ | |
9385eb3d | 67 | ULong c, h, *x, *x1, *xe; |
ad3c9f2a | 68 | #endif /* __APPLE__ */ |
9385eb3d | 69 | CONST char *s; |
ad3c9f2a | 70 | #ifndef __APPLE__ |
9385eb3d | 71 | int havedig, hd0, i, nbits; |
ad3c9f2a | 72 | #endif /* !__APPLE__ */ |
9385eb3d | 73 | |
ad3c9f2a A |
74 | #ifdef __APPLE__ |
75 | if (sp == NULL || *sp == NULL || **sp != '(') | |
76 | return STRTOG_NaN; | |
77 | #else /* !__APPLE__ */ | |
9385eb3d A |
78 | if (!hexdig['0']) |
79 | hexdig_init_D2A(); | |
80 | nbits = fpi->nbits; | |
81 | x = x0 + (nbits >> kshift); | |
82 | if (nbits & kmask) | |
83 | x++; | |
84 | *--x = 0; | |
85 | x1 = xe = x; | |
86 | havedig = hd0 = i = 0; | |
ad3c9f2a | 87 | #endif /* __APPLE__ */ |
9385eb3d | 88 | s = *sp; |
ad3c9f2a A |
89 | #ifdef __APPLE__ |
90 | if ((cp = strchr(s + 1, ')')) == NULL) { | |
91 | return STRTOG_NaN; | |
92 | } | |
93 | else { | |
94 | len = cp - (s + 1); | |
95 | cp = alloca(len + 1); | |
96 | if (!cp) | |
97 | #else /* !__APPLE__ */ | |
34e8f829 A |
98 | /* allow optional initial 0x or 0X */ |
99 | while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') | |
100 | ++s; | |
101 | if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') | |
102 | && *(CONST unsigned char*)(s+3) > ' ') | |
103 | s += 2; | |
1f2f436a | 104 | while((c = *(CONST unsigned char*)++s)) { |
9385eb3d A |
105 | if (!(h = hexdig[c])) { |
106 | if (c <= ' ') { | |
107 | if (hd0 < havedig) { | |
108 | if (x < x1 && i < 8) | |
109 | L_shift(x, x1, i); | |
110 | if (x <= x0) { | |
111 | i = 8; | |
112 | continue; | |
113 | } | |
114 | hd0 = havedig; | |
115 | *--x = 0; | |
116 | x1 = x; | |
117 | i = 0; | |
118 | } | |
34e8f829 A |
119 | while(*(CONST unsigned char*)(s+1) <= ' ') |
120 | ++s; | |
121 | if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') | |
122 | && *(CONST unsigned char*)(s+3) > ' ') | |
123 | s += 2; | |
9385eb3d A |
124 | continue; |
125 | } | |
126 | if (/*(*/ c == ')' && havedig) { | |
127 | *sp = s + 1; | |
128 | break; | |
129 | } | |
34e8f829 A |
130 | #ifndef GDTOA_NON_PEDANTIC_NANCHECK |
131 | do { | |
132 | if (/*(*/ c == ')') { | |
133 | *sp = s + 1; | |
134 | break; | |
135 | } | |
1f2f436a | 136 | } while((c = *++s)); |
34e8f829 | 137 | #endif |
ad3c9f2a | 138 | #endif /* __APPLE__ */ |
9385eb3d | 139 | return STRTOG_NaN; |
ad3c9f2a A |
140 | #ifdef __APPLE__ |
141 | strlcpy(cp, s + 1, len + 1); | |
142 | *sp += len + 2; | |
143 | #else /* !__APPLE__ */ | |
9385eb3d A |
144 | } |
145 | havedig++; | |
146 | if (++i > 8) { | |
147 | if (x <= x0) | |
148 | continue; | |
149 | i = 1; | |
150 | *--x = 0; | |
151 | } | |
1f2f436a | 152 | *x = (*x << 4) | (h & 0xf); |
ad3c9f2a | 153 | #endif /* __APPLE__ */ |
9385eb3d | 154 | } |
ad3c9f2a A |
155 | #ifdef __APPLE__ |
156 | nbits = fpi->nbits; | |
157 | /* a hack */ | |
158 | if (nbits == 52) { /* double */ | |
159 | union IEEEd2bits u; | |
160 | u.d = nan(cp); | |
161 | x0[1] = u.bits.manh; | |
162 | x0[0] = u.bits.manl; | |
163 | #else /* !__APPLE__ */ | |
9385eb3d A |
164 | if (!havedig) |
165 | return STRTOG_NaN; | |
166 | if (x < x1 && i < 8) | |
167 | L_shift(x, x1, i); | |
168 | if (x > x0) { | |
169 | x1 = x0; | |
170 | do *x1++ = *x++; | |
171 | while(x <= xe); | |
172 | do *x1++ = 0; | |
173 | while(x1 <= xe); | |
ad3c9f2a | 174 | #endif /* __APPLE__ */ |
9385eb3d | 175 | } |
ad3c9f2a A |
176 | #ifdef __APPLE__ |
177 | else if (nbits < 52) { /* float */ | |
178 | union IEEEf2bits u; | |
179 | u.f = nanf(cp); | |
180 | x0[0] = u.bits.man; | |
181 | #else /* !__APPLE__ */ | |
9385eb3d A |
182 | else { |
183 | /* truncate high-order word if necessary */ | |
184 | if ( (i = nbits & (ULbits-1)) !=0) | |
185 | *xe &= ((ULong)0xffffffff) >> (ULbits - i); | |
ad3c9f2a | 186 | #endif /* __APPLE__ */ |
9385eb3d | 187 | } |
ad3c9f2a A |
188 | #ifdef __APPLE__ |
189 | else { /* long double */ | |
190 | union IEEEl2bits u; | |
191 | u.e = nanl(cp); | |
b061a43b | 192 | #if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__) |
ad3c9f2a A |
193 | x0[1] = (ULong)u.bits.manh; |
194 | x0[0] = (ULong)u.bits.manl; | |
195 | #else | |
196 | #error unsupported architecture | |
197 | #endif | |
198 | #else /* !__APPLE__ */ | |
9385eb3d A |
199 | for(x1 = xe;; --x1) { |
200 | if (*x1 != 0) | |
201 | break; | |
202 | if (x1 == x0) { | |
203 | *x1 = 1; | |
204 | break; | |
205 | } | |
ad3c9f2a | 206 | #endif /* __APPLE__ */ |
9385eb3d A |
207 | } |
208 | return STRTOG_NaNbits; | |
209 | } |