23 #include "config_auto.h" 34 #include <sys/types.h> 72 return CHAR_BIT *
sizeof(long);
78 while (isascii(p = fgetc(s)) && isspace(p));
84 SetBit(
unsigned long *bitmap,
unsigned int bit) {
89 TestBit(
unsigned long *bitmap,
unsigned int bit) {
90 return static_cast<int>(bitmap[bit/
LongBit()] >> (bit%
LongBit())) & 1;
93 static inline int DigitValue(
int ch,
int base) {
94 if (ch >=
'0' && ch <=
'9') {
95 if (base >= 10 || ch <=
'7')
97 }
else if (ch >=
'A' && ch <=
'Z' && base == 16) {
99 }
else if (ch >=
'a' && ch <=
'z' && base == 16) {
106 static uintmax_t streamtoumax(FILE* s,
int base) {
111 for (c = fgetc(s); isascii(c) && isspace(c); c = fgetc(s));
114 if (c ==
'-' || c ==
'+') {
123 if (c ==
'x' || c ==
'X') {
130 }
else if (base == 16) {
133 if (c ==
'x' || c ==
'X') c = fgetc(s);
138 for (; (c != EOF) && (d = DigitValue(c, base)) >= 0; c = fgetc(s))
142 return minus ? -v : v;
145 static double streamtofloat(FILE* s) {
152 for (c = fgetc(s); isascii(c) && isspace(c); c = fgetc(s));
155 if (c ==
'-' || c ==
'+') {
161 for (; c != EOF && (d = DigitValue(c, 10)) >= 0; c = fgetc(s))
164 for (c = fgetc(s); c != EOF && (d = DigitValue(c, 10)) >= 0; c = fgetc(s)) {
169 double f =
static_cast<double>(v)
170 + static_cast<double>(w) /
static_cast<double>(k);
171 if (c ==
'e' || c ==
'E') {
174 if (c ==
'-' || c ==
'+') {
175 expsign = (c ==
'-') ? -1 : 1;
179 for (; (c != EOF) && (d = DigitValue(c, 10)) >= 0; c = fgetc(s)) {
180 exponent = exponent * 10 + d;
183 f *= pow(10.0, static_cast<double>(exponent));
187 return minus ? -f : f;
190 static int tvfscanf(FILE* stream,
const char *format, va_list ap);
192 int tfscanf(FILE* stream,
const char *format, ...) {
196 va_start(ap, format);
197 rv = tvfscanf(stream, format, ap);
205 int fscanf(FILE* stream,
const char *format, ...) {
209 va_start(ap, format);
210 rv = tvfscanf(stream, format, ap);
216 int vfscanf(FILE* stream,
const char *format, ...) {
220 va_start(ap, format);
221 rv = tvfscanf(stream, format, ap);
228 static int tvfscanf(FILE* stream,
const char *format, va_list ap) {
229 const char *p = format;
234 unsigned int width = UINT_MAX;
246 char *sarg =
nullptr;
249 unsigned long matchmap[((1 << CHAR_BIT)+(CHAR_BIT *
sizeof(
long) - 1)) /
250 (CHAR_BIT *
sizeof(long))];
252 unsigned char range_start = 0;
253 off_t start_off = ftell(stream);
258 while ((ch = *p++) && !bail) {
263 flags = 0; rank =
RANK_INT; width = UINT_MAX;
264 }
else if (isascii(ch) && isspace(ch)) {
267 if (fgetc(stream) != ch)
275 }
else if (
'0' <= ch && ch <=
'9') {
280 state = ST_MODIFIERS;
286 if (ch >=
'0' && ch <=
'9') {
287 width = width*10+(ch-
'0');
289 state = ST_MODIFIERS;
354 val = ftell(stream) - start_off;
358 q = SkipSpace(stream);
363 val = streamtoumax(stream, base);
371 *va_arg(ap,
unsigned char *)
372 =
static_cast<unsigned char>(val);
375 *va_arg(ap,
unsigned short *)
376 =
static_cast<unsigned short>(val);
379 *va_arg(ap,
unsigned int *)
380 =
static_cast<unsigned int>(val);
383 *va_arg(ap,
unsigned long *)
384 =
static_cast<unsigned long>(val);
387 *va_arg(ap,
unsigned long long *)
388 =
static_cast<unsigned long long>(val);
392 =
reinterpret_cast<void *
>(
static_cast<uintptr_t
>(val));
403 q = SkipSpace(stream);
410 double fval = streamtofloat(stream);
413 *va_arg(ap,
float *) =
static_cast<float>(fval);
415 *va_arg(ap,
double *) =
static_cast<double>(fval);
422 width = (flags &
FL_WIDTH) ? width : 1;
423 sarg = va_arg(ap,
char *);
425 if ((q = fgetc(stream)) <= 0) {
439 sarg = va_arg(ap,
char *);
444 if ((isascii(q) && isspace(q)) || (q <= 0)) {
463 sarg = va_arg(ap,
char *);
464 state = ST_MATCH_INIT;
466 memset(matchmap, 0,
sizeof matchmap);
470 if (fgetc(stream) !=
'%')
482 if (ch ==
'^' && !(flags &
FL_INV)) {
485 SetBit(matchmap, static_cast<unsigned char>(ch));
493 }
else if (ch ==
'-') {
494 range_start =
static_cast<unsigned char>(ch);
495 state = ST_MATCH_RANGE;
497 SetBit(matchmap, static_cast<unsigned char>(ch));
503 SetBit(matchmap, static_cast<unsigned char>(
'-'));
507 for (i = range_start ; i < (static_cast<unsigned char>(ch)) ; i++)
517 unsigned char qc =
static_cast<unsigned char>(q);
518 if (q <= 0 || !(TestBit(matchmap, qc)^matchinv)) {
542 int creat(
const char *pathname, mode_t mode) {
543 return open(pathname, O_CREAT | O_TRUNC | O_WRONLY, mode);
int tfscanf(FILE *stream, const char *format,...)