16# include "config_auto.h"
44 RANK_PTR = std::numeric_limits<int>::max()
62 return CHAR_BIT *
sizeof(long);
65static inline int SkipSpace(FILE *s) {
67 while (isascii(
p = fgetc(s)) && isspace(
p)) {
74static inline void SetBit(
unsigned long *bitmap,
unsigned int bit) {
78static inline int TestBit(
unsigned long *bitmap,
unsigned int bit) {
79 return static_cast<int>(bitmap[bit /
LongBit()] >> (bit %
LongBit())) & 1;
82static inline int DigitValue(
int ch,
int base) {
83 if (
ch >=
'0' &&
ch <=
'9') {
84 if (base >= 10 ||
ch <=
'7') {
87 }
else if (
ch >=
'A' &&
ch <=
'Z' && base == 16) {
89 }
else if (
ch >=
'a' &&
ch <=
'z' && base == 16) {
96static uintmax_t streamtoumax(FILE *s,
int base) {
101 for (c = fgetc(s); isascii(c) && isspace(c); c = fgetc(s)) {
106 if (c ==
'-' || c ==
'+') {
115 if (c ==
'x' || c ==
'X') {
122 }
else if (base == 16) {
125 if (c ==
'x' || c ==
'X') {
132 for (; (c != EOF) && (d = DigitValue(c, base)) >= 0; c = fgetc(s)) {
137 return minus ? -v : v;
140static double streamtofloat(FILE *s) {
147 for (c = fgetc(s); isascii(c) && isspace(c); c = fgetc(s)) {
152 if (c ==
'-' || c ==
'+') {
158 for (; c != EOF && (d = DigitValue(c, 10)) >= 0; c = fgetc(s)) {
162 for (c = fgetc(s); c != EOF && (d = DigitValue(c, 10)) >= 0; c = fgetc(s)) {
167 double f = v +
static_cast<double>(w) / k;
168 if (c ==
'e' || c ==
'E') {
171 if (c ==
'-' || c ==
'+') {
172 expsign = (c ==
'-') ? -1 : 1;
176 for (; (c != EOF) && (d = DigitValue(c, 10)) >= 0; c = fgetc(s)) {
177 exponent = exponent * 10 + d;
180 f *= pow(10.0,
static_cast<double>(exponent));
184 return minus ? -f : f;
187static int tvfscanf(FILE *stream,
const char *format, va_list ap);
189int tfscanf(FILE *stream,
const char *format, ...) {
193 va_start(ap, format);
194 rv = tvfscanf(stream, format, ap);
200static int tvfscanf(FILE *stream,
const char *format, va_list ap) {
201 const char *
p = format;
206 unsigned int width = UINT_MAX;
218 char *sarg =
nullptr;
222 matchmap[((1 << CHAR_BIT) + (CHAR_BIT *
sizeof(
long) - 1)) / (CHAR_BIT *
sizeof(long))];
224 unsigned char range_start = 0;
225 auto start_off = std::ftell(stream);
230 while ((
ch = *
p++) && !bail) {
238 }
else if (isascii(
ch) && isspace(
ch)) {
241 if (fgetc(stream) !=
ch) {
250 }
else if (
'0' <=
ch &&
ch <=
'9') {
255 state = ST_MODIFIERS;
261 if (
ch >=
'0' &&
ch <=
'9') {
262 width = width * 10 + (
ch -
'0');
264 state = ST_MODIFIERS;
330 val = std::ftell(stream) - start_off;
334 q = SkipSpace(stream);
339 val = streamtoumax(stream, base);
347 *va_arg(ap,
unsigned char *) =
static_cast<unsigned char>(val);
350 *va_arg(ap,
unsigned short *) =
static_cast<unsigned short>(val);
353 *va_arg(ap,
unsigned int *) =
static_cast<unsigned int>(val);
356 *va_arg(ap,
unsigned long *) =
static_cast<unsigned long>(val);
359 *va_arg(ap,
unsigned long long *) =
static_cast<unsigned long long>(val);
362 *va_arg(ap,
void **) =
reinterpret_cast<void *
>(
static_cast<uintptr_t
>(val));
373 q = SkipSpace(stream);
380 double fval = streamtofloat(stream);
383 *va_arg(ap,
float *) =
static_cast<float>(fval);
385 *va_arg(ap,
double *) =
static_cast<double>(fval);
393 width = (flags &
FL_WIDTH) ? width : 1;
394 sarg = va_arg(ap,
char *);
396 if ((q = fgetc(stream)) <= 0) {
410 sarg = va_arg(ap,
char *);
415 if ((isascii(q) && isspace(q)) || (q <= 0)) {
433 sarg = va_arg(ap,
char *);
434 state = ST_MATCH_INIT;
436 memset(matchmap, 0,
sizeof matchmap);
440 if (fgetc(stream) !=
'%') {
453 if (
ch ==
'^' && !(flags &
FL_INV)) {
456 SetBit(matchmap,
static_cast<unsigned char>(
ch));
464 }
else if (
ch ==
'-') {
465 range_start =
static_cast<unsigned char>(
ch);
466 state = ST_MATCH_RANGE;
468 SetBit(matchmap,
static_cast<unsigned char>(
ch));
474 SetBit(matchmap,
static_cast<unsigned char>(
'-'));
478 for (
i = range_start; i < (static_cast<unsigned char>(
ch));
i++) {
489 auto qc =
static_cast<unsigned char>(q);
490 if (q <= 0 || !(TestBit(matchmap, qc) ^ matchinv)) {
509 if (bail ==
BAIL_EOF && !converted) {
int tfscanf(FILE *stream, const char *format,...)