tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }