1f9f848faSopenharmony_ci/****************************************************************
2f9f848faSopenharmony_ci
3f9f848faSopenharmony_ciThe author of this software is David M. Gay.
4f9f848faSopenharmony_ci
5f9f848faSopenharmony_ciCopyright (C) 2000 by Lucent Technologies
6f9f848faSopenharmony_ciAll Rights Reserved
7f9f848faSopenharmony_ci
8f9f848faSopenharmony_ciPermission to use, copy, modify, and distribute this software and
9f9f848faSopenharmony_ciits documentation for any purpose and without fee is hereby
10f9f848faSopenharmony_cigranted, provided that the above copyright notice appear in all
11f9f848faSopenharmony_cicopies and that both that the copyright notice and this
12f9f848faSopenharmony_cipermission notice and warranty disclaimer appear in supporting
13f9f848faSopenharmony_cidocumentation, and that the name of Lucent or any of its entities
14f9f848faSopenharmony_cinot be used in advertising or publicity pertaining to
15f9f848faSopenharmony_cidistribution of the software without specific, written prior
16f9f848faSopenharmony_cipermission.
17f9f848faSopenharmony_ci
18f9f848faSopenharmony_ciLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19f9f848faSopenharmony_ciINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20f9f848faSopenharmony_ciIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21f9f848faSopenharmony_ciSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22f9f848faSopenharmony_ciWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23f9f848faSopenharmony_ciIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24f9f848faSopenharmony_ciARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25f9f848faSopenharmony_ciTHIS SOFTWARE.
26f9f848faSopenharmony_ci
27f9f848faSopenharmony_ci****************************************************************/
28f9f848faSopenharmony_ci
29f9f848faSopenharmony_ci/* Please send bug reports to David M. Gay (dmg at acm dot org,
30f9f848faSopenharmony_ci * with " at " changed at "@" and " dot " changed to ".").	*/
31f9f848faSopenharmony_ci
32f9f848faSopenharmony_ci#include "gdtoaimp.h"
33f9f848faSopenharmony_ci
34f9f848faSopenharmony_ci static void
35f9f848faSopenharmony_ci#ifdef KR_headers
36f9f848faSopenharmony_ciL_shift(x, x1, i) ULong *x; ULong *x1; int i;
37f9f848faSopenharmony_ci#else
38f9f848faSopenharmony_ciL_shift(ULong *x, ULong *x1, int i)
39f9f848faSopenharmony_ci#endif
40f9f848faSopenharmony_ci{
41f9f848faSopenharmony_ci	int j;
42f9f848faSopenharmony_ci
43f9f848faSopenharmony_ci	i = 8 - i;
44f9f848faSopenharmony_ci	i <<= 2;
45f9f848faSopenharmony_ci	j = ULbits - i;
46f9f848faSopenharmony_ci	do {
47f9f848faSopenharmony_ci		*x |= x[1] << j;
48f9f848faSopenharmony_ci		x[1] >>= i;
49f9f848faSopenharmony_ci		} while(++x < x1);
50f9f848faSopenharmony_ci	}
51f9f848faSopenharmony_ci
52f9f848faSopenharmony_ci int
53f9f848faSopenharmony_ci#ifdef KR_headers
54f9f848faSopenharmony_cihexnan(sp, fpi, x0)
55f9f848faSopenharmony_ci	CONST char **sp; FPI *fpi; ULong *x0;
56f9f848faSopenharmony_ci#else
57f9f848faSopenharmony_cihexnan( CONST char **sp, FPI *fpi, ULong *x0)
58f9f848faSopenharmony_ci#endif
59f9f848faSopenharmony_ci{
60f9f848faSopenharmony_ci	ULong c, h, *x, *x1, *xe;
61f9f848faSopenharmony_ci	CONST char *s;
62f9f848faSopenharmony_ci	int havedig, hd0, i, nbits;
63f9f848faSopenharmony_ci
64f9f848faSopenharmony_ci	if (!hexdig['0'])
65f9f848faSopenharmony_ci		hexdig_init_D2A();
66f9f848faSopenharmony_ci	nbits = fpi->nbits;
67f9f848faSopenharmony_ci	x = x0 + (nbits >> kshift);
68f9f848faSopenharmony_ci	if (nbits & kmask)
69f9f848faSopenharmony_ci		x++;
70f9f848faSopenharmony_ci	*--x = 0;
71f9f848faSopenharmony_ci	x1 = xe = x;
72f9f848faSopenharmony_ci	havedig = hd0 = i = 0;
73f9f848faSopenharmony_ci	s = *sp;
74f9f848faSopenharmony_ci	/* allow optional initial 0x or 0X */
75f9f848faSopenharmony_ci	while((c = *(CONST unsigned char*)(s+1)) && c <= ' ')
76f9f848faSopenharmony_ci		++s;
77f9f848faSopenharmony_ci	if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')
78f9f848faSopenharmony_ci	 && *(CONST unsigned char*)(s+3) > ' ')
79f9f848faSopenharmony_ci		s += 2;
80f9f848faSopenharmony_ci	while((c = *(CONST unsigned char*)++s)) {
81f9f848faSopenharmony_ci		if (!(h = hexdig[c])) {
82f9f848faSopenharmony_ci			if (c <= ' ') {
83f9f848faSopenharmony_ci				if (hd0 < havedig) {
84f9f848faSopenharmony_ci					if (x < x1 && i < 8)
85f9f848faSopenharmony_ci						L_shift(x, x1, i);
86f9f848faSopenharmony_ci					if (x <= x0) {
87f9f848faSopenharmony_ci						i = 8;
88f9f848faSopenharmony_ci						continue;
89f9f848faSopenharmony_ci						}
90f9f848faSopenharmony_ci					hd0 = havedig;
91f9f848faSopenharmony_ci					*--x = 0;
92f9f848faSopenharmony_ci					x1 = x;
93f9f848faSopenharmony_ci					i = 0;
94f9f848faSopenharmony_ci					}
95f9f848faSopenharmony_ci				while(*(CONST unsigned char*)(s+1) <= ' ')
96f9f848faSopenharmony_ci					++s;
97f9f848faSopenharmony_ci				if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')
98f9f848faSopenharmony_ci				 && *(CONST unsigned char*)(s+3) > ' ')
99f9f848faSopenharmony_ci					s += 2;
100f9f848faSopenharmony_ci				continue;
101f9f848faSopenharmony_ci				}
102f9f848faSopenharmony_ci			if (/*(*/ c == ')' && havedig) {
103f9f848faSopenharmony_ci				*sp = s + 1;
104f9f848faSopenharmony_ci				break;
105f9f848faSopenharmony_ci				}
106f9f848faSopenharmony_ci#ifndef GDTOA_NON_PEDANTIC_NANCHECK
107f9f848faSopenharmony_ci			do {
108f9f848faSopenharmony_ci				if (/*(*/ c == ')') {
109f9f848faSopenharmony_ci					*sp = s + 1;
110f9f848faSopenharmony_ci					break;
111f9f848faSopenharmony_ci					}
112f9f848faSopenharmony_ci				} while((c = *++s));
113f9f848faSopenharmony_ci#endif
114f9f848faSopenharmony_ci			return STRTOG_NaN;
115f9f848faSopenharmony_ci			}
116f9f848faSopenharmony_ci		havedig++;
117f9f848faSopenharmony_ci		if (++i > 8) {
118f9f848faSopenharmony_ci			if (x <= x0)
119f9f848faSopenharmony_ci				continue;
120f9f848faSopenharmony_ci			i = 1;
121f9f848faSopenharmony_ci			*--x = 0;
122f9f848faSopenharmony_ci			}
123f9f848faSopenharmony_ci		*x = (*x << 4) | (h & 0xf);
124f9f848faSopenharmony_ci		}
125f9f848faSopenharmony_ci	if (!havedig)
126f9f848faSopenharmony_ci		return STRTOG_NaN;
127f9f848faSopenharmony_ci	if (x < x1 && i < 8)
128f9f848faSopenharmony_ci		L_shift(x, x1, i);
129f9f848faSopenharmony_ci	if (x > x0) {
130f9f848faSopenharmony_ci		x1 = x0;
131f9f848faSopenharmony_ci		do *x1++ = *x++;
132f9f848faSopenharmony_ci			while(x <= xe);
133f9f848faSopenharmony_ci		do *x1++ = 0;
134f9f848faSopenharmony_ci			while(x1 <= xe);
135f9f848faSopenharmony_ci		}
136f9f848faSopenharmony_ci	else {
137f9f848faSopenharmony_ci		/* truncate high-order word if necessary */
138f9f848faSopenharmony_ci		if ( (i = nbits & (ULbits-1)) !=0)
139f9f848faSopenharmony_ci			*xe &= ((ULong)0xffffffff) >> (ULbits - i);
140f9f848faSopenharmony_ci		}
141f9f848faSopenharmony_ci	for(x1 = xe;; --x1) {
142f9f848faSopenharmony_ci		if (*x1 != 0)
143f9f848faSopenharmony_ci			break;
144f9f848faSopenharmony_ci		if (x1 == x0) {
145f9f848faSopenharmony_ci			*x1 = 1;
146f9f848faSopenharmony_ci			break;
147f9f848faSopenharmony_ci			}
148f9f848faSopenharmony_ci		}
149f9f848faSopenharmony_ci	return STRTOG_NaNbits;
150f9f848faSopenharmony_ci	}
151