16 #include "config_auto.h"
62 return CHAR_BIT *
sizeof(long);
68 while (isascii(p = fgetc(s)) && isspace(p));
74 SetBit(
unsigned long *bitmap,
unsigned int bit) {
79 TestBit(
unsigned long *bitmap,
unsigned int bit) {
80 return static_cast<int>(bitmap[bit/
LongBit()] >> (bit%
LongBit())) & 1;
83 static inline int DigitValue(
int ch,
int base) {
84 if (ch >=
'0' && ch <=
'9') {
85 if (base >= 10 || ch <=
'7')
87 }
else if (ch >=
'A' && ch <=
'Z' && base == 16) {
89 }
else if (ch >=
'a' && ch <=
'z' && base == 16) {
96 static uintmax_t streamtoumax(FILE* s,
int base) {
101 for (c = fgetc(s); isascii(c) && isspace(c); c = fgetc(s));
104 if (c ==
'-' || c ==
'+') {
113 if (c ==
'x' || c ==
'X') {
120 }
else if (base == 16) {
123 if (c ==
'x' || c ==
'X') c = fgetc(s);
128 for (; (c != EOF) && (d = DigitValue(c, base)) >= 0; c = fgetc(s))
132 return minus ? -v : v;
135 static double streamtofloat(FILE* s) {
142 for (c = fgetc(s); isascii(c) && isspace(c); c = fgetc(s));
145 if (c ==
'-' || c ==
'+') {
151 for (; c != EOF && (d = DigitValue(c, 10)) >= 0; c = fgetc(s))
154 for (c = fgetc(s); c != EOF && (d = DigitValue(c, 10)) >= 0; c = fgetc(s)) {
159 double f = v + static_cast<double>(w) / k;
160 if (c ==
'e' || c ==
'E') {
163 if (c ==
'-' || c ==
'+') {
164 expsign = (c ==
'-') ? -1 : 1;
168 for (; (c != EOF) && (d = DigitValue(c, 10)) >= 0; c = fgetc(s)) {
169 exponent = exponent * 10 + d;
172 f *= pow(10.0, static_cast<double>(exponent));
176 return minus ? -f : f;
179 static int tvfscanf(FILE* stream,
const char *format, va_list ap);
181 int tfscanf(FILE* stream,
const char *format, ...) {
185 va_start(ap, format);
186 rv = tvfscanf(stream, format, ap);
192 static int tvfscanf(FILE* stream,
const char *format, va_list ap) {
193 const char *p = format;
198 unsigned int width = UINT_MAX;
210 char *sarg =
nullptr;
213 unsigned long matchmap[((1 << CHAR_BIT)+(CHAR_BIT *
sizeof(
long) - 1)) /
214 (CHAR_BIT *
sizeof(long))];
216 unsigned char range_start = 0;
217 auto start_off = std::ftell(stream);
222 while ((ch = *p++) && !bail) {
227 flags = 0; rank =
RANK_INT; width = UINT_MAX;
228 }
else if (isascii(ch) && isspace(ch)) {
231 if (fgetc(stream) != ch)
239 }
else if (
'0' <= ch && ch <=
'9') {
244 state = ST_MODIFIERS;
250 if (ch >=
'0' && ch <=
'9') {
251 width = width*10+(ch-
'0');
253 state = ST_MODIFIERS;
318 val = std::ftell(stream) - start_off;
322 q = SkipSpace(stream);
327 val = streamtoumax(stream, base);
335 *va_arg(ap,
unsigned char *)
336 = static_cast<unsigned char>(val);
339 *va_arg(ap,
unsigned short *)
340 = static_cast<unsigned short>(val);
343 *va_arg(ap,
unsigned int *)
344 = static_cast<unsigned int>(val);
347 *va_arg(ap,
unsigned long *)
348 = static_cast<unsigned long>(val);
351 *va_arg(ap,
unsigned long long *)
352 = static_cast<unsigned long long>(val);
356 = reinterpret_cast<void *>(static_cast<uintptr_t>(val));
367 q = SkipSpace(stream);
374 double fval = streamtofloat(stream);
377 *va_arg(ap,
float *) = static_cast<float>(fval);
379 *va_arg(ap,
double *) = static_cast<double>(fval);
386 width = (flags &
FL_WIDTH) ? width : 1;
387 sarg = va_arg(ap,
char *);
389 if ((q = fgetc(stream)) <= 0) {
403 sarg = va_arg(ap,
char *);
408 if ((isascii(q) && isspace(q)) || (q <= 0)) {
427 sarg = va_arg(ap,
char *);
428 state = ST_MATCH_INIT;
430 memset(matchmap, 0,
sizeof matchmap);
434 if (fgetc(stream) !=
'%')
446 if (ch ==
'^' && !(flags &
FL_INV)) {
449 SetBit(matchmap, static_cast<unsigned char>(ch));
457 }
else if (ch ==
'-') {
458 range_start = static_cast<unsigned char>(ch);
459 state = ST_MATCH_RANGE;
461 SetBit(matchmap, static_cast<unsigned char>(ch));
467 SetBit(matchmap, static_cast<unsigned char>(
'-'));
471 for (i = range_start ; i < (static_cast<unsigned char>(ch)) ; i++)
481 auto qc = static_cast<unsigned char>(q);
482 if (q <= 0 || !(TestBit(matchmap, qc)^matchinv)) {