4coder/non-source/test_data/lots_of_files/xwstoxfl.c

127 lines
3.7 KiB
C
Raw Permalink Normal View History

2018-03-16 18:19:11 +00:00
/* _WStoxflt function */
#include <ctype.h>
#include <locale.h>
#include <wchar.h>
#include <wctype.h>
#include "xmath.h"
_C_STD_BEGIN
#if !defined(MRTDLL)
_C_LIB_DECL
#endif /* defined(MRTDLL) */
#define BASE 16 /* hexadecimal */
#define NDIG 7 /* hexadecimal digits per long element */
#define MAXSIG (5 * NDIG) /* maximum significant digits to keep */
_CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _WStoxflt(const wchar_t *s0, const wchar_t *s,
wchar_t **endptr, long lo[], int maxsig)
{ /* convert wide string to array of long plus exponent */
char buf[MAXSIG + 1]; /* worst case, with room for rounding digit */
int nsig; /* number of significant digits seen */
int seen; /* any valid field characters seen */
int word = 0; /* current long word to fill */
const wchar_t *pd;
static const wchar_t digits[] =
{ /* hex digits in both cases */
L'0', L'1', L'2', L'3',
L'4', L'5', L'6', L'7',
L'8', L'9', L'a', L'b',
L'c', L'd', L'e', L'f',
L'A', L'B', L'C', L'D',
L'E', L'F', L'\0'};
static const wchar_t vals[] =
{ /* values of hex digits */
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
10, 11, 12, 13, 14, 15};
maxsig *= NDIG; /* convert word count to digit count */
if (MAXSIG < maxsig)
maxsig = MAXSIG; /* protect against bad call */
lo[0] = 0; /* power of ten exponent */
lo[1] = 0; /* first NDIG-digit word of fraction */
for (seen = 0; *s == L'0'; ++s, seen = 1)
; /* strip leading zeros */
for (nsig = 0;
(pd = (wchar_t *)wmemchr(&digits[0], *s, 22)) != 0; ++s, seen = 1)
if (nsig <= maxsig)
buf[nsig++] = vals[pd - digits]; /* accumulate a digit */
else
++lo[0]; /* too many digits, just scale exponent */
if (*s == localeconv()->decimal_point[0])
++s;
if (nsig == 0)
for (; *s == '0'; ++s, seen = 1)
--lo[0]; /* strip zeros after point */
for (; (pd = (wchar_t *)wmemchr(&digits[0], *s, 22)) != 0; ++s, seen = 1)
if (nsig <= maxsig)
{ /* accumulate a fraction digit */
buf[nsig++] = vals[pd - digits];
--lo[0];
}
if (maxsig < nsig)
{ /* discard excess digit after rounding up */
unsigned int ms = maxsig; /* to quiet warnings */
if (BASE / 2 <= buf[ms])
++buf[ms - 1]; /* okay if digit becomes BASE */
nsig = maxsig;
++lo[0];
}
for (; 0 < nsig && buf[nsig - 1] == '\0'; --nsig)
++lo[0]; /* discard trailing zeros */
if (nsig == 0)
buf[nsig++] = '\0'; /* ensure at least one digit */
lo[0] <<= 2; /* change hex exponent to binary exponent */
if (seen)
{ /* convert digit sequence to words */
int bufidx = 0; /* next digit in buffer */
int wordidx = NDIG - nsig % NDIG; /* next digit in word (% NDIG) */
word = wordidx % NDIG == 0 ? 0 : 1;
for (; bufidx < nsig; ++wordidx, ++bufidx)
if (wordidx % NDIG == 0)
lo[++word] = buf[bufidx];
else
lo[word] = lo[word] * BASE + buf[bufidx];
if (*s == L'p' || *s == L'P')
{ /* parse exponent */
const wchar_t *ssav = s;
const wchar_t esign = *++s == L'+' || *s == L'-'
? *s++ : L'+';
int eseen = 0;
long lexp = 0;
for (; iswdigit(*s); ++s, eseen = 1)
if (lexp < 100000000) /* else overflow */
lexp = lexp * 10 + *s - L'0';
if (esign == '-')
lexp = -lexp;
lo[0] += lexp;
if (!eseen)
s = ssav; /* roll back if incomplete exponent */
}
}
if (!seen)
word = 0; /* return zero if bad parse */
if (endptr)
*endptr = (wchar_t *)(seen ? s : s0); /* roll back if bad parse */
return (word);
}
#if !defined(MRTDLL)
_END_C_LIB_DECL
#endif /* !defined(MRTDLL) */
_C_STD_END
/*
* Copyright (c) 1992-2012 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
V6.00:0009 */