GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libc/gdtoa/gethex.c Lines: 0 169 0.0 %
Date: 2017-11-07 Branches: 0 159 0.0 %

Line Branch Exec Source
1
/****************************************************************
2
3
The author of this software is David M. Gay.
4
5
Copyright (C) 1998 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
29
/* Please send bug reports to David M. Gay (dmg at acm dot org,
30
 * with " at " changed at "@" and " dot " changed to ".").	*/
31
32
#include "gdtoaimp.h"
33
34
#ifdef USE_LOCALE
35
#include "locale.h"
36
#endif
37
38
 int
39
#ifdef KR_headers
40
gethex(sp, fpi, exp, bp, sign)
41
	CONST char **sp; FPI *fpi; Long *exp; Bigint **bp; int sign;
42
#else
43
gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
44
#endif
45
{
46
	Bigint *b;
47
	CONST unsigned char *decpt, *s0, *s, *s1;
48
	int big, esign, havedig, irv, j, k, n, n0, nbits, up, zret;
49
	ULong L, lostbits, *x;
50
	Long e, e1;
51
#ifdef USE_LOCALE
52
	int i;
53
#ifdef NO_LOCALE_CACHE
54
	const unsigned char *decimalpoint = (unsigned char*)localeconv()->decimal_point;
55
#else
56
	const unsigned char *decimalpoint;
57
	static unsigned char *decimalpoint_cache;
58
	if (!(s0 = decimalpoint_cache)) {
59
		s0 = (unsigned char*)localeconv()->decimal_point;
60
		decimalpoint_cache = strdup(s0);
61
	}
62
	decimalpoint = s0;
63
#endif
64
#endif
65
66
	if (!hexdig['0'])
67
		__hexdig_init_D2A();
68
	*bp = 0;
69
	havedig = 0;
70
	s0 = *(CONST unsigned char **)sp + 2;
71
	while(s0[havedig] == '0')
72
		havedig++;
73
	s0 += havedig;
74
	s = s0;
75
	decpt = 0;
76
	zret = 0;
77
	e = 0;
78
	if (hexdig[*s])
79
		havedig++;
80
	else {
81
		zret = 1;
82
#ifdef USE_LOCALE
83
		for(i = 0; decimalpoint[i]; ++i) {
84
			if (s[i] != decimalpoint[i])
85
				goto pcheck;
86
			}
87
		decpt = s += i;
88
#else
89
		if (*s != '.')
90
			goto pcheck;
91
		decpt = ++s;
92
#endif
93
		if (!hexdig[*s])
94
			goto pcheck;
95
		while(*s == '0')
96
			s++;
97
		if (hexdig[*s])
98
			zret = 0;
99
		havedig = 1;
100
		s0 = s;
101
		}
102
	while(hexdig[*s])
103
		s++;
104
#ifdef USE_LOCALE
105
	if (*s == *decimalpoint && !decpt) {
106
		for(i = 1; decimalpoint[i]; ++i) {
107
			if (s[i] != decimalpoint[i])
108
				goto pcheck;
109
			}
110
		decpt = s += i;
111
#else
112
	if (*s == '.' && !decpt) {
113
		decpt = ++s;
114
#endif
115
		while(hexdig[*s])
116
			s++;
117
		}/*}*/
118
	if (decpt)
119
		e = -(((Long)(s-decpt)) << 2);
120
 pcheck:
121
	s1 = s;
122
	big = esign = 0;
123
	switch(*s) {
124
	  case 'p':
125
	  case 'P':
126
		switch(*++s) {
127
		  case '-':
128
			esign = 1;
129
			/* no break */
130
		  case '+':
131
			s++;
132
		  }
133
		if ((n = hexdig[*s]) == 0 || n > 0x19) {
134
			s = s1;
135
			break;
136
			}
137
		e1 = n - 0x10;
138
		while((n = hexdig[*++s]) !=0 && n <= 0x19) {
139
			if (e1 & 0xf8000000)
140
				big = 1;
141
			e1 = 10*e1 + n - 0x10;
142
			}
143
		if (esign)
144
			e1 = -e1;
145
		e += e1;
146
	  }
147
	*sp = (char*)s;
148
	if (!havedig)
149
		*sp = (char*)s0 - 1;
150
	if (zret)
151
		return STRTOG_Zero;
152
	if (big) {
153
		if (esign) {
154
			switch(fpi->rounding) {
155
			  case FPI_Round_up:
156
				if (sign)
157
					break;
158
				goto ret_tiny;
159
			  case FPI_Round_down:
160
				if (!sign)
161
					break;
162
				goto ret_tiny;
163
			  }
164
			goto retz;
165
 ret_tiny:
166
			b = Balloc(0);
167
			if (b == NULL)
168
				return (STRTOG_NoMemory);
169
			b->wds = 1;
170
			b->x[0] = 1;
171
			goto dret;
172
			}
173
		switch(fpi->rounding) {
174
		  case FPI_Round_near:
175
			goto ovfl1;
176
		  case FPI_Round_up:
177
			if (!sign)
178
				goto ovfl1;
179
			goto ret_big;
180
		  case FPI_Round_down:
181
			if (sign)
182
				goto ovfl1;
183
			goto ret_big;
184
		  }
185
 ret_big:
186
		nbits = fpi->nbits;
187
		n0 = n = nbits >> kshift;
188
		if (nbits & kmask)
189
			++n;
190
		for(j = n, k = 0; j >>= 1; ++k);
191
		*bp = b = Balloc(k);
192
		if (*bp == NULL)
193
			return (STRTOG_NoMemory);
194
		b->wds = n;
195
		for(j = 0; j < n0; ++j)
196
			b->x[j] = ALL_ON;
197
		if (n > n0)
198
			b->x[j] = ULbits >> (ULbits - (nbits & kmask));
199
		*exp = fpi->emin;
200
		return STRTOG_Normal | STRTOG_Inexlo;
201
		}
202
	n = s1 - s0 - 1;
203
	for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1)
204
		k++;
205
	b = Balloc(k);
206
	if (b == NULL)
207
		return (STRTOG_NoMemory);
208
	x = b->x;
209
	n = 0;
210
	L = 0;
211
#ifdef USE_LOCALE
212
	for(i = 0; decimalpoint[i+1]; ++i);
213
#endif
214
	while(s1 > s0) {
215
#ifdef USE_LOCALE
216
		if (*--s1 == decimalpoint[i]) {
217
			s1 -= i;
218
			continue;
219
			}
220
#else
221
		if (*--s1 == '.')
222
			continue;
223
#endif
224
		if (n == ULbits) {
225
			*x++ = L;
226
			L = 0;
227
			n = 0;
228
			}
229
		L |= (hexdig[*s1] & 0x0f) << n;
230
		n += 4;
231
		}
232
	*x++ = L;
233
	b->wds = n = x - b->x;
234
	n = ULbits*n - hi0bits(L);
235
	nbits = fpi->nbits;
236
	lostbits = 0;
237
	x = b->x;
238
	if (n > nbits) {
239
		n -= nbits;
240
		if (any_on(b,n)) {
241
			lostbits = 1;
242
			k = n - 1;
243
			if (x[k>>kshift] & 1 << (k & kmask)) {
244
				lostbits = 2;
245
				if (k > 0 && any_on(b,k))
246
					lostbits = 3;
247
				}
248
			}
249
		rshift(b, n);
250
		e += n;
251
		}
252
	else if (n < nbits) {
253
		n = nbits - n;
254
		b = lshift(b, n);
255
		if (b == NULL)
256
			return (STRTOG_NoMemory);
257
		e -= n;
258
		x = b->x;
259
		}
260
	if (e > fpi->emax) {
261
 ovfl:
262
		Bfree(b);
263
 ovfl1:
264
#ifndef NO_ERRNO
265
		errno = ERANGE;
266
#endif
267
		return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
268
		}
269
	irv = STRTOG_Normal;
270
	if (e < fpi->emin) {
271
		irv = STRTOG_Denormal;
272
		n = fpi->emin - e;
273
		if (n >= nbits) {
274
			switch (fpi->rounding) {
275
			  case FPI_Round_near:
276
				if (n == nbits && (n < 2 || any_on(b,n-1)))
277
					goto one_bit;
278
				break;
279
			  case FPI_Round_up:
280
				if (!sign)
281
					goto one_bit;
282
				break;
283
			  case FPI_Round_down:
284
				if (sign) {
285
 one_bit:
286
					x[0] = b->wds = 1;
287
 dret:
288
					*bp = b;
289
					*exp = fpi->emin;
290
#ifndef NO_ERRNO
291
					errno = ERANGE;
292
#endif
293
					return STRTOG_Denormal | STRTOG_Inexhi
294
						| STRTOG_Underflow;
295
					}
296
			  }
297
			Bfree(b);
298
 retz:
299
#ifndef NO_ERRNO
300
			errno = ERANGE;
301
#endif
302
			return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow;
303
			}
304
		k = n - 1;
305
		if (lostbits)
306
			lostbits = 1;
307
		else if (k > 0)
308
			lostbits = any_on(b,k);
309
		if (x[k>>kshift] & 1 << (k & kmask))
310
			lostbits |= 2;
311
		nbits -= n;
312
		rshift(b,n);
313
		e = fpi->emin;
314
		}
315
	if (lostbits) {
316
		up = 0;
317
		switch(fpi->rounding) {
318
		  case FPI_Round_zero:
319
			break;
320
		  case FPI_Round_near:
321
			if (lostbits & 2
322
			 && (lostbits | x[0]) & 1)
323
				up = 1;
324
			break;
325
		  case FPI_Round_up:
326
			up = 1 - sign;
327
			break;
328
		  case FPI_Round_down:
329
			up = sign;
330
		  }
331
		if (up) {
332
			k = b->wds;
333
			b = increment(b);
334
			if (b == NULL)
335
				return (STRTOG_NoMemory);
336
			x = b->x;
337
			if (irv == STRTOG_Denormal) {
338
				if (nbits == fpi->nbits - 1
339
				 && x[nbits >> kshift] & 1 << (nbits & kmask))
340
					irv =  STRTOG_Normal;
341
				}
342
			else if (b->wds > k
343
			 || ((n = nbits & kmask) !=0
344
			      && hi0bits(x[k-1]) < 32-n)) {
345
				rshift(b,1);
346
				if (++e > fpi->emax)
347
					goto ovfl;
348
				}
349
			irv |= STRTOG_Inexhi;
350
			}
351
		else
352
			irv |= STRTOG_Inexlo;
353
		}
354
	*bp = b;
355
	*exp = e;
356
	return irv;
357
	}