avsscanf.c (25363B)
1 /* 2 * Copyright (c) 2005-2014 Rich Felker, et al. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 24 #include <errno.h> 25 #include <limits.h> 26 #include <math.h> 27 #include <stdarg.h> 28 #include <stddef.h> 29 #include <stdint.h> 30 #include <stdio.h> 31 #include <string.h> 32 #include <float.h> 33 34 #include "avstring.h" 35 #include "libm.h" 36 37 typedef struct FFFILE { 38 size_t buf_size; 39 unsigned char *buf; 40 unsigned char *rpos, *rend; 41 unsigned char *shend; 42 ptrdiff_t shlim, shcnt; 43 void *cookie; 44 size_t (*read)(struct FFFILE *, unsigned char *, size_t); 45 } FFFILE; 46 47 #define SIZE_hh -2 48 #define SIZE_h -1 49 #define SIZE_def 0 50 #define SIZE_l 1 51 #define SIZE_L 2 52 #define SIZE_ll 3 53 54 #define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->buf)) 55 56 static int fftoread(FFFILE *f) 57 { 58 f->rpos = f->rend = f->buf + f->buf_size; 59 return 0; 60 } 61 62 static size_t ffstring_read(FFFILE *f, unsigned char *buf, size_t len) 63 { 64 char *src = f->cookie; 65 size_t k = len+256; 66 char *end = memchr(src, 0, k); 67 68 if (end) k = end-src; 69 if (k < len) len = k; 70 memcpy(buf, src, len); 71 f->rpos = (void *)(src+len); 72 f->rend = (void *)(src+k); 73 f->cookie = src+k; 74 75 return len; 76 } 77 78 static int ffuflow(FFFILE *f) 79 { 80 unsigned char c; 81 if (!fftoread(f) && f->read(f, &c, 1)==1) return c; 82 return EOF; 83 } 84 85 static void ffshlim(FFFILE *f, ptrdiff_t lim) 86 { 87 f->shlim = lim; 88 f->shcnt = f->buf - f->rpos; 89 /* If lim is nonzero, rend must be a valid pointer. */ 90 if (lim && f->rend - f->rpos > lim) 91 f->shend = f->rpos + lim; 92 else 93 f->shend = f->rend; 94 } 95 96 static int ffshgetc(FFFILE *f) 97 { 98 int c; 99 ptrdiff_t cnt = shcnt(f); 100 if (f->shlim && cnt >= f->shlim || (c=ffuflow(f)) < 0) { 101 f->shcnt = f->buf - f->rpos + cnt; 102 f->shend = 0; 103 return EOF; 104 } 105 cnt++; 106 if (f->shlim && f->rend - f->rpos > f->shlim - cnt) 107 f->shend = f->rpos + (f->shlim - cnt); 108 else 109 f->shend = f->rend; 110 f->shcnt = f->buf - f->rpos + cnt; 111 if (f->rpos[-1] != c) f->rpos[-1] = c; 112 return c; 113 } 114 115 #define shlim(f, lim) ffshlim((f), (lim)) 116 #define shgetc(f) (((f)->rpos < (f)->shend) ? *(f)->rpos++ : ffshgetc(f)) 117 #define shunget(f) ((f)->shend ? (void)(f)->rpos-- : (void)0) 118 119 static const unsigned char table[] = { -1, 120 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 121 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 122 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 123 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1, 124 -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24, 125 25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1, 126 -1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24, 127 25,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1, 128 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 129 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 130 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 131 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 132 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 133 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 134 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 135 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 136 }; 137 138 static unsigned long long ffintscan(FFFILE *f, unsigned base, int pok, unsigned long long lim) 139 { 140 const unsigned char *val = table+1; 141 int c, neg=0; 142 unsigned x; 143 unsigned long long y; 144 if (base > 36 || base == 1) { 145 errno = EINVAL; 146 return 0; 147 } 148 while (av_isspace((c=shgetc(f)))); 149 if (c=='+' || c=='-') { 150 neg = -(c=='-'); 151 c = shgetc(f); 152 } 153 if ((base == 0 || base == 16) && c=='0') { 154 c = shgetc(f); 155 if ((c|32)=='x') { 156 c = shgetc(f); 157 if (val[c]>=16) { 158 shunget(f); 159 if (pok) shunget(f); 160 else shlim(f, 0); 161 return 0; 162 } 163 base = 16; 164 } else if (base == 0) { 165 base = 8; 166 } 167 } else { 168 if (base == 0) base = 10; 169 if (val[c] >= base) { 170 shunget(f); 171 shlim(f, 0); 172 errno = EINVAL; 173 return 0; 174 } 175 } 176 if (base == 10) { 177 for (x=0; c-'0'<10U && x<=UINT_MAX/10-1; c=shgetc(f)) 178 x = x*10 + (c-'0'); 179 for (y=x; c-'0'<10U && y<=ULLONG_MAX/10 && 10*y<=ULLONG_MAX-(c-'0'); c=shgetc(f)) 180 y = y*10 + (c-'0'); 181 if (c-'0'>=10U) goto done; 182 } else if (!(base & base-1)) { 183 int bs = "\0\1\2\4\7\3\6\5"[(0x17*base)>>5&7]; 184 for (x=0; val[c]<base && x<=UINT_MAX/32; c=shgetc(f)) 185 x = x<<bs | val[c]; 186 for (y=x; val[c]<base && y<=ULLONG_MAX>>bs; c=shgetc(f)) 187 y = y<<bs | val[c]; 188 } else { 189 for (x=0; val[c]<base && x<=UINT_MAX/36-1; c=shgetc(f)) 190 x = x*base + val[c]; 191 for (y=x; val[c]<base && y<=ULLONG_MAX/base && base*y<=ULLONG_MAX-val[c]; c=shgetc(f)) 192 y = y*base + val[c]; 193 } 194 if (val[c]<base) { 195 for (; val[c]<base; c=shgetc(f)); 196 errno = ERANGE; 197 y = lim; 198 if (lim&1) neg = 0; 199 } 200 done: 201 shunget(f); 202 if (y>=lim) { 203 if (!(lim&1) && !neg) { 204 errno = ERANGE; 205 return lim-1; 206 } else if (y>lim) { 207 errno = ERANGE; 208 return lim; 209 } 210 } 211 return (y^neg)-neg; 212 } 213 214 static long long scanexp(FFFILE *f, int pok) 215 { 216 int c; 217 int x; 218 long long y; 219 int neg = 0; 220 221 c = shgetc(f); 222 if (c=='+' || c=='-') { 223 neg = (c=='-'); 224 c = shgetc(f); 225 if (c-'0'>=10U && pok) shunget(f); 226 } 227 if (c-'0'>=10U) { 228 shunget(f); 229 return LLONG_MIN; 230 } 231 for (x=0; c-'0'<10U && x<INT_MAX/10; c = shgetc(f)) 232 x = 10*x + (c-'0'); 233 for (y=x; c-'0'<10U && y<LLONG_MAX/100; c = shgetc(f)) 234 y = 10*y + (c-'0'); 235 for (; c-'0'<10U; c = shgetc(f)); 236 shunget(f); 237 return neg ? -y : y; 238 } 239 240 #define LD_B1B_DIG 2 241 #define LD_B1B_MAX 9007199, 254740991 242 #define KMAX 128 243 #define MASK (KMAX-1) 244 245 static double decfloat(FFFILE *f, int c, int bits, int emin, int sign, int pok) 246 { 247 uint32_t x[KMAX]; 248 static const uint32_t th[] = { LD_B1B_MAX }; 249 int i, j, k, a, z; 250 long long lrp=0, dc=0; 251 long long e10=0; 252 int lnz = 0; 253 int gotdig = 0, gotrad = 0; 254 int rp; 255 int e2; 256 int emax = -emin-bits+3; 257 int denormal = 0; 258 double y; 259 double frac=0; 260 double bias=0; 261 static const int p10s[] = { 10, 100, 1000, 10000, 262 100000, 1000000, 10000000, 100000000 }; 263 264 j=0; 265 k=0; 266 267 /* Don't let leading zeros consume buffer space */ 268 for (; c=='0'; c = shgetc(f)) gotdig=1; 269 if (c=='.') { 270 gotrad = 1; 271 for (c = shgetc(f); c=='0'; c = shgetc(f)) gotdig=1, lrp--; 272 } 273 274 x[0] = 0; 275 for (; c-'0'<10U || c=='.'; c = shgetc(f)) { 276 if (c == '.') { 277 if (gotrad) break; 278 gotrad = 1; 279 lrp = dc; 280 } else if (k < KMAX-3) { 281 dc++; 282 if (c!='0') lnz = dc; 283 if (j) x[k] = x[k]*10 + c-'0'; 284 else x[k] = c-'0'; 285 if (++j==9) { 286 k++; 287 j=0; 288 } 289 gotdig=1; 290 } else { 291 dc++; 292 if (c!='0') { 293 lnz = (KMAX-4)*9; 294 x[KMAX-4] |= 1; 295 } 296 } 297 } 298 if (!gotrad) lrp=dc; 299 300 if (gotdig && (c|32)=='e') { 301 e10 = scanexp(f, pok); 302 if (e10 == LLONG_MIN) { 303 if (pok) { 304 shunget(f); 305 } else { 306 shlim(f, 0); 307 return 0; 308 } 309 e10 = 0; 310 } 311 lrp += e10; 312 } else if (c>=0) { 313 shunget(f); 314 } 315 if (!gotdig) { 316 errno = EINVAL; 317 shlim(f, 0); 318 return 0; 319 } 320 321 /* Handle zero specially to avoid nasty special cases later */ 322 if (!x[0]) return sign * 0.0; 323 324 /* Optimize small integers (w/no exponent) and over/under-flow */ 325 if (lrp==dc && dc<10 && (bits>30 || x[0]>>bits==0)) 326 return sign * (double)x[0]; 327 if (lrp > -emin/2) { 328 errno = ERANGE; 329 return sign * DBL_MAX * DBL_MAX; 330 } 331 if (lrp < emin-2*DBL_MANT_DIG) { 332 errno = ERANGE; 333 return sign * DBL_MIN * DBL_MIN; 334 } 335 336 /* Align incomplete final B1B digit */ 337 if (j) { 338 for (; j<9; j++) x[k]*=10; 339 k++; 340 j=0; 341 } 342 343 a = 0; 344 z = k; 345 e2 = 0; 346 rp = lrp; 347 348 /* Optimize small to mid-size integers (even in exp. notation) */ 349 if (lnz<9 && lnz<=rp && rp < 18) { 350 int bitlim; 351 if (rp == 9) return sign * (double)x[0]; 352 if (rp < 9) return sign * (double)x[0] / p10s[8-rp]; 353 bitlim = bits-3*(int)(rp-9); 354 if (bitlim>30 || x[0]>>bitlim==0) 355 return sign * (double)x[0] * p10s[rp-10]; 356 } 357 358 /* Drop trailing zeros */ 359 for (; !x[z-1]; z--); 360 361 /* Align radix point to B1B digit boundary */ 362 if (rp % 9) { 363 int rpm9 = rp>=0 ? rp%9 : rp%9+9; 364 int p10 = p10s[8-rpm9]; 365 uint32_t carry = 0; 366 for (k=a; k!=z; k++) { 367 uint32_t tmp = x[k] % p10; 368 x[k] = x[k]/p10 + carry; 369 carry = 1000000000/p10 * tmp; 370 if (k==a && !x[k]) { 371 a = (a+1 & MASK); 372 rp -= 9; 373 } 374 } 375 if (carry) x[z++] = carry; 376 rp += 9-rpm9; 377 } 378 379 /* Upscale until desired number of bits are left of radix point */ 380 while (rp < 9*LD_B1B_DIG || (rp == 9*LD_B1B_DIG && x[a]<th[0])) { 381 uint32_t carry = 0; 382 e2 -= 29; 383 for (k=(z-1 & MASK); ; k=(k-1 & MASK)) { 384 uint64_t tmp = ((uint64_t)x[k] << 29) + carry; 385 if (tmp > 1000000000) { 386 carry = tmp / 1000000000; 387 x[k] = tmp % 1000000000; 388 } else { 389 carry = 0; 390 x[k] = tmp; 391 } 392 if (k==(z-1 & MASK) && k!=a && !x[k]) z = k; 393 if (k==a) break; 394 } 395 if (carry) { 396 rp += 9; 397 a = (a-1 & MASK); 398 if (a == z) { 399 z = (z-1 & MASK); 400 x[z-1 & MASK] |= x[z]; 401 } 402 x[a] = carry; 403 } 404 } 405 406 /* Downscale until exactly number of bits are left of radix point */ 407 for (;;) { 408 uint32_t carry = 0; 409 int sh = 1; 410 for (i=0; i<LD_B1B_DIG; i++) { 411 k = (a+i & MASK); 412 if (k == z || x[k] < th[i]) { 413 i=LD_B1B_DIG; 414 break; 415 } 416 if (x[a+i & MASK] > th[i]) break; 417 } 418 if (i==LD_B1B_DIG && rp==9*LD_B1B_DIG) break; 419 /* FIXME: find a way to compute optimal sh */ 420 if (rp > 9+9*LD_B1B_DIG) sh = 9; 421 e2 += sh; 422 for (k=a; k!=z; k=(k+1 & MASK)) { 423 uint32_t tmp = x[k] & (1<<sh)-1; 424 x[k] = (x[k]>>sh) + carry; 425 carry = (1000000000>>sh) * tmp; 426 if (k==a && !x[k]) { 427 a = (a+1 & MASK); 428 i--; 429 rp -= 9; 430 } 431 } 432 if (carry) { 433 if ((z+1 & MASK) != a) { 434 x[z] = carry; 435 z = (z+1 & MASK); 436 } else x[z-1 & MASK] |= 1; 437 } 438 } 439 440 /* Assemble desired bits into floating point variable */ 441 for (y=i=0; i<LD_B1B_DIG; i++) { 442 if ((a+i & MASK)==z) x[(z=(z+1 & MASK))-1] = 0; 443 y = 1000000000.0L * y + x[a+i & MASK]; 444 } 445 446 y *= sign; 447 448 /* Limit precision for denormal results */ 449 if (bits > DBL_MANT_DIG+e2-emin) { 450 bits = DBL_MANT_DIG+e2-emin; 451 if (bits<0) bits=0; 452 denormal = 1; 453 } 454 455 /* Calculate bias term to force rounding, move out lower bits */ 456 if (bits < DBL_MANT_DIG) { 457 bias = copysign(scalbn(1, 2*DBL_MANT_DIG-bits-1), y); 458 frac = fmod(y, scalbn(1, DBL_MANT_DIG-bits)); 459 y -= frac; 460 y += bias; 461 } 462 463 /* Process tail of decimal input so it can affect rounding */ 464 if ((a+i & MASK) != z) { 465 uint32_t t = x[a+i & MASK]; 466 if (t < 500000000 && (t || (a+i+1 & MASK) != z)) 467 frac += 0.25*sign; 468 else if (t > 500000000) 469 frac += 0.75*sign; 470 else if (t == 500000000) { 471 if ((a+i+1 & MASK) == z) 472 frac += 0.5*sign; 473 else 474 frac += 0.75*sign; 475 } 476 if (DBL_MANT_DIG-bits >= 2 && !fmod(frac, 1)) 477 frac++; 478 } 479 480 y += frac; 481 y -= bias; 482 483 if ((e2+DBL_MANT_DIG & INT_MAX) > emax-5) { 484 if (fabs(y) >= pow(2, DBL_MANT_DIG)) { 485 if (denormal && bits==DBL_MANT_DIG+e2-emin) 486 denormal = 0; 487 y *= 0.5; 488 e2++; 489 } 490 if (e2+DBL_MANT_DIG>emax || (denormal && frac)) 491 errno = ERANGE; 492 } 493 494 return scalbn(y, e2); 495 } 496 497 static double hexfloat(FFFILE *f, int bits, int emin, int sign, int pok) 498 { 499 uint32_t x = 0; 500 double y = 0; 501 double scale = 1; 502 double bias = 0; 503 int gottail = 0, gotrad = 0, gotdig = 0; 504 long long rp = 0; 505 long long dc = 0; 506 long long e2 = 0; 507 int d; 508 int c; 509 510 c = shgetc(f); 511 512 /* Skip leading zeros */ 513 for (; c=='0'; c = shgetc(f)) 514 gotdig = 1; 515 516 if (c=='.') { 517 gotrad = 1; 518 c = shgetc(f); 519 /* Count zeros after the radix point before significand */ 520 for (rp=0; c=='0'; c = shgetc(f), rp--) gotdig = 1; 521 } 522 523 for (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; c = shgetc(f)) { 524 if (c=='.') { 525 if (gotrad) break; 526 rp = dc; 527 gotrad = 1; 528 } else { 529 gotdig = 1; 530 if (c > '9') d = (c|32)+10-'a'; 531 else d = c-'0'; 532 if (dc<8) { 533 x = x*16 + d; 534 } else if (dc < DBL_MANT_DIG/4+1) { 535 y += d*(scale/=16); 536 } else if (d && !gottail) { 537 y += 0.5*scale; 538 gottail = 1; 539 } 540 dc++; 541 } 542 } 543 if (!gotdig) { 544 shunget(f); 545 if (pok) { 546 shunget(f); 547 if (gotrad) shunget(f); 548 } else { 549 shlim(f, 0); 550 } 551 return sign * 0.0; 552 } 553 if (!gotrad) rp = dc; 554 while (dc<8) x *= 16, dc++; 555 if ((c|32)=='p') { 556 e2 = scanexp(f, pok); 557 if (e2 == LLONG_MIN) { 558 if (pok) { 559 shunget(f); 560 } else { 561 shlim(f, 0); 562 return 0; 563 } 564 e2 = 0; 565 } 566 } else { 567 shunget(f); 568 } 569 e2 += 4*rp - 32; 570 571 if (!x) return sign * 0.0; 572 if (e2 > -emin) { 573 errno = ERANGE; 574 return sign * DBL_MAX * DBL_MAX; 575 } 576 if (e2 < emin-2*DBL_MANT_DIG) { 577 errno = ERANGE; 578 return sign * DBL_MIN * DBL_MIN; 579 } 580 581 while (x < 0x80000000) { 582 if (y>=0.5) { 583 x += x + 1; 584 y += y - 1; 585 } else { 586 x += x; 587 y += y; 588 } 589 e2--; 590 } 591 592 if (bits > 32+e2-emin) { 593 bits = 32+e2-emin; 594 if (bits<0) bits=0; 595 } 596 597 if (bits < DBL_MANT_DIG) 598 bias = copysign(scalbn(1, 32+DBL_MANT_DIG-bits-1), sign); 599 600 if (bits<32 && y && !(x&1)) x++, y=0; 601 602 y = bias + sign*(double)x + sign*y; 603 y -= bias; 604 605 if (!y) errno = ERANGE; 606 607 return scalbn(y, e2); 608 } 609 610 static double fffloatscan(FFFILE *f, int prec, int pok) 611 { 612 int sign = 1; 613 size_t i; 614 int bits; 615 int emin; 616 int c; 617 618 switch (prec) { 619 case 0: 620 bits = FLT_MANT_DIG; 621 emin = FLT_MIN_EXP-bits; 622 break; 623 case 1: 624 bits = DBL_MANT_DIG; 625 emin = DBL_MIN_EXP-bits; 626 break; 627 case 2: 628 bits = DBL_MANT_DIG; 629 emin = DBL_MIN_EXP-bits; 630 break; 631 default: 632 return 0; 633 } 634 635 while (av_isspace((c = shgetc(f)))); 636 637 if (c=='+' || c=='-') { 638 sign -= 2*(c=='-'); 639 c = shgetc(f); 640 } 641 642 for (i=0; i<8 && (c|32)=="infinity"[i]; i++) 643 if (i<7) c = shgetc(f); 644 if (i==3 || i==8 || (i>3 && pok)) { 645 if (i!=8) { 646 shunget(f); 647 if (pok) for (; i>3; i--) shunget(f); 648 } 649 return sign * INFINITY; 650 } 651 if (!i) for (i=0; i<3 && (c|32)=="nan"[i]; i++) 652 if (i<2) c = shgetc(f); 653 if (i==3) { 654 if (shgetc(f) != '(') { 655 shunget(f); 656 return NAN; 657 } 658 for (i=1; ; i++) { 659 c = shgetc(f); 660 if (c-'0'<10U || c-'A'<26U || c-'a'<26U || c=='_') 661 continue; 662 if (c==')') return NAN; 663 shunget(f); 664 if (!pok) { 665 errno = EINVAL; 666 shlim(f, 0); 667 return 0; 668 } 669 while (i--) shunget(f); 670 return NAN; 671 } 672 } 673 674 if (i) { 675 shunget(f); 676 errno = EINVAL; 677 shlim(f, 0); 678 return 0; 679 } 680 681 if (c=='0') { 682 c = shgetc(f); 683 if ((c|32) == 'x') 684 return hexfloat(f, bits, emin, sign, pok); 685 shunget(f); 686 c = '0'; 687 } 688 689 return decfloat(f, c, bits, emin, sign, pok); 690 } 691 692 static void *arg_n(va_list ap, unsigned int n) 693 { 694 void *p; 695 unsigned int i; 696 va_list ap2; 697 va_copy(ap2, ap); 698 for (i=n; i>1; i--) va_arg(ap2, void *); 699 p = va_arg(ap2, void *); 700 va_end(ap2); 701 return p; 702 } 703 704 static void store_int(void *dest, int size, unsigned long long i) 705 { 706 if (!dest) return; 707 switch (size) { 708 case SIZE_hh: 709 *(char *)dest = i; 710 break; 711 case SIZE_h: 712 *(short *)dest = i; 713 break; 714 case SIZE_def: 715 *(int *)dest = i; 716 break; 717 case SIZE_l: 718 *(long *)dest = i; 719 break; 720 case SIZE_ll: 721 *(long long *)dest = i; 722 break; 723 } 724 } 725 726 static int ff_vfscanf(FFFILE *f, const char *fmt, va_list ap) 727 { 728 int width; 729 int size; 730 int base; 731 const unsigned char *p; 732 int c, t; 733 char *s; 734 void *dest=NULL; 735 int invert; 736 int matches=0; 737 unsigned long long x; 738 double y; 739 ptrdiff_t pos = 0; 740 unsigned char scanset[257]; 741 size_t i; 742 743 for (p=(const unsigned char *)fmt; *p; p++) { 744 745 if (av_isspace(*p)) { 746 while (av_isspace(p[1])) p++; 747 shlim(f, 0); 748 while (av_isspace(shgetc(f))); 749 shunget(f); 750 pos += shcnt(f); 751 continue; 752 } 753 if (*p != '%' || p[1] == '%') { 754 shlim(f, 0); 755 if (*p == '%') { 756 p++; 757 while (av_isspace((c=shgetc(f)))); 758 } else { 759 c = shgetc(f); 760 } 761 if (c!=*p) { 762 shunget(f); 763 if (c<0) goto input_fail; 764 goto match_fail; 765 } 766 pos += shcnt(f); 767 continue; 768 } 769 770 p++; 771 if (*p=='*') { 772 dest = 0; p++; 773 } else if (av_isdigit(*p) && p[1]=='$') { 774 dest = arg_n(ap, *p-'0'); p+=2; 775 } else { 776 dest = va_arg(ap, void *); 777 } 778 779 for (width=0; av_isdigit(*p); p++) { 780 width = 10*width + *p - '0'; 781 } 782 783 if (*p=='m') { 784 s = 0; 785 p++; 786 } 787 788 size = SIZE_def; 789 switch (*p++) { 790 case 'h': 791 if (*p == 'h') p++, size = SIZE_hh; 792 else size = SIZE_h; 793 break; 794 case 'l': 795 if (*p == 'l') p++, size = SIZE_ll; 796 else size = SIZE_l; 797 break; 798 case 'j': 799 size = SIZE_ll; 800 break; 801 case 'z': 802 case 't': 803 size = SIZE_l; 804 break; 805 case 'L': 806 size = SIZE_L; 807 break; 808 case 'd': case 'i': case 'o': case 'u': case 'x': 809 case 'a': case 'e': case 'f': case 'g': 810 case 'A': case 'E': case 'F': case 'G': case 'X': 811 case 's': case 'c': case '[': 812 case 'S': case 'C': 813 case 'p': case 'n': 814 p--; 815 break; 816 default: 817 goto fmt_fail; 818 } 819 820 t = *p; 821 822 /* C or S */ 823 if ((t&0x2f) == 3) { 824 t |= 32; 825 size = SIZE_l; 826 } 827 828 switch (t) { 829 case 'c': 830 if (width < 1) width = 1; 831 case '[': 832 break; 833 case 'n': 834 store_int(dest, size, pos); 835 /* do not increment match count, etc! */ 836 continue; 837 default: 838 shlim(f, 0); 839 while (av_isspace(shgetc(f))); 840 shunget(f); 841 pos += shcnt(f); 842 } 843 844 shlim(f, width); 845 if (shgetc(f) < 0) goto input_fail; 846 shunget(f); 847 848 switch (t) { 849 case 's': 850 case 'c': 851 case '[': 852 if (t == 'c' || t == 's') { 853 memset(scanset, -1, sizeof scanset); 854 scanset[0] = 0; 855 if (t == 's') { 856 scanset[1 + '\t'] = 0; 857 scanset[1 + '\n'] = 0; 858 scanset[1 + '\v'] = 0; 859 scanset[1 + '\f'] = 0; 860 scanset[1 + '\r'] = 0; 861 scanset[1 + ' ' ] = 0; 862 } 863 } else { 864 if (*++p == '^') p++, invert = 1; 865 else invert = 0; 866 memset(scanset, invert, sizeof scanset); 867 scanset[0] = 0; 868 if (*p == '-') p++, scanset[1+'-'] = 1-invert; 869 else if (*p == ']') p++, scanset[1+']'] = 1-invert; 870 for (; *p != ']'; p++) { 871 if (!*p) goto fmt_fail; 872 if (*p=='-' && p[1] && p[1] != ']') 873 for (c=p++[-1]; c<*p; c++) 874 scanset[1+c] = 1-invert; 875 scanset[1+*p] = 1-invert; 876 } 877 } 878 s = 0; 879 i = 0; 880 if ((s = dest)) { 881 while (scanset[(c=shgetc(f))+1]) 882 s[i++] = c; 883 } else { 884 while (scanset[(c=shgetc(f))+1]); 885 } 886 shunget(f); 887 if (!shcnt(f)) goto match_fail; 888 if (t == 'c' && shcnt(f) != width) goto match_fail; 889 if (t != 'c') { 890 if (s) s[i] = 0; 891 } 892 break; 893 case 'p': 894 case 'X': 895 case 'x': 896 base = 16; 897 goto int_common; 898 case 'o': 899 base = 8; 900 goto int_common; 901 case 'd': 902 case 'u': 903 base = 10; 904 goto int_common; 905 case 'i': 906 base = 0; 907 int_common: 908 x = ffintscan(f, base, 0, ULLONG_MAX); 909 if (!shcnt(f)) 910 goto match_fail; 911 if (t=='p' && dest) 912 *(void **)dest = (void *)(uintptr_t)x; 913 else 914 store_int(dest, size, x); 915 break; 916 case 'a': case 'A': 917 case 'e': case 'E': 918 case 'f': case 'F': 919 case 'g': case 'G': 920 y = fffloatscan(f, size, 0); 921 if (!shcnt(f)) 922 goto match_fail; 923 if (dest) { 924 switch (size) { 925 case SIZE_def: 926 *(float *)dest = y; 927 break; 928 case SIZE_l: 929 *(double *)dest = y; 930 break; 931 case SIZE_L: 932 *(double *)dest = y; 933 break; 934 } 935 } 936 break; 937 } 938 939 pos += shcnt(f); 940 if (dest) matches++; 941 } 942 if (0) { 943 fmt_fail: 944 input_fail: 945 if (!matches) matches--; 946 } 947 match_fail: 948 return matches; 949 } 950 951 static int ff_vsscanf(const char *s, const char *fmt, va_list ap) 952 { 953 FFFILE f = { 954 .buf = (void *)s, .cookie = (void *)s, 955 .read = ffstring_read, 956 }; 957 958 return ff_vfscanf(&f, fmt, ap); 959 } 960 961 int av_sscanf(const char *string, const char *format, ...) 962 { 963 int ret; 964 va_list ap; 965 va_start(ap, format); 966 ret = ff_vsscanf(string, format, ap); 967 va_end(ap); 968 return ret; 969 }