зеркало из https://github.com/microsoft/STL.git
89 строки
2.4 KiB
C++
89 строки
2.4 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
// _Stopfx function
|
|
|
|
#include <ctype.h>
|
|
|
|
#include "xmath.hpp"
|
|
|
|
_EXTERN_C_UNLESS_PURE
|
|
|
|
int _Stopfx(const char** ps, char** endptr) { // parse prefix of floating-point field
|
|
const char* s = *ps;
|
|
int code = 0;
|
|
|
|
while (isspace(static_cast<unsigned char>(*s))) {
|
|
++s;
|
|
}
|
|
|
|
if (*s == '-') {
|
|
code = FL_NEG;
|
|
++s;
|
|
} else if (*s == '+') {
|
|
++s;
|
|
}
|
|
|
|
if (*s == 'n' || *s == 'N') { // parse "nan" or fail
|
|
if ((*++s != 'a' && *s != 'A') || (*++s != 'n' && *s != 'N')) { // parse failed, roll back pointer
|
|
s = *ps;
|
|
code = FL_ERR;
|
|
} else { // parse optional (n-char-sequence)
|
|
const char* q = ++s;
|
|
|
|
code = FL_NAN;
|
|
if (*q == '(') { // got '(', skip through ')'
|
|
do {
|
|
++q;
|
|
} while (isalnum(static_cast<unsigned char>(*q)) || *q == '_');
|
|
|
|
if (*q == ')') {
|
|
s = ++q;
|
|
}
|
|
}
|
|
}
|
|
if (endptr != nullptr) {
|
|
*endptr = const_cast<char*>(s);
|
|
}
|
|
} else if (*s == 'i' || *s == 'I') { // parse "inf" or fail
|
|
if ((*++s != 'n' && *s != 'N') || (*++s != 'f' && *s != 'F')) { // parse failed, roll back pointer
|
|
s = *ps;
|
|
code = FL_ERR;
|
|
} else { // parse optional rest of "infinity"
|
|
const char* q = ++s;
|
|
code |= FL_INF;
|
|
|
|
if ((*q == 'i' || *q == 'I') //
|
|
&& (*++q == 'n' || *q == 'N') //
|
|
&& (*++q == 'i' || *q == 'I') //
|
|
&& (*++q == 't' || *q == 'T') //
|
|
&& (*++q == 'y' || *q == 'Y')) {
|
|
s = ++q;
|
|
}
|
|
}
|
|
|
|
if (endptr != nullptr) {
|
|
*endptr = const_cast<char*>(s);
|
|
}
|
|
} else if (*s == '0' && (s[1] == 'x' || s[1] == 'X')) { // test for valid hex field following 0x or 0X
|
|
const char* s1 = s + 2;
|
|
if (*s1 == '.') {
|
|
++s1;
|
|
}
|
|
|
|
if (isxdigit(static_cast<unsigned char>(*s1))) {
|
|
s += 2;
|
|
code |= FL_HEX;
|
|
} else {
|
|
code |= FL_DEC;
|
|
}
|
|
} else {
|
|
code |= FL_DEC;
|
|
}
|
|
|
|
*ps = s;
|
|
return code;
|
|
}
|
|
|
|
_END_EXTERN_C_UNLESS_PURE
|