Changeset 80f345c in mainline for uspace/lib/c/generic/stdio/scanf.c


Ignore:
Timestamp:
2018-06-14T12:40:20Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
be2a20ac
Parents:
f4aa1c8
git-author:
Jiri Svoboda <jiri@…> (2018-06-13 21:39:34)
git-committer:
Jiri Svoboda <jiri@…> (2018-06-14 12:40:20)
Message:

Need to carefully pass va_list around by reference to be portable.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/stdio/scanf.c

    rf4aa1c8 r80f345c  
    126126        size_t size;
    127127} strbuf_t;
     128
     129/** Wrapper needed to pass va_list around by reference in a portable fashion */
     130typedef struct {
     131        va_list ap;
     132} va_encaps_t;
    128133
    129134static int digit_value(char digit)
     
    343348 * @return EOK on success, ENOMEM if out of memory
    344349 */
    345 static int strbuf_init(strbuf_t *strbuf, cvtspec_t *spec, va_list ap)
     350static int strbuf_init(strbuf_t *strbuf, cvtspec_t *spec, va_encaps_t *va)
    346351{
    347352        if (spec->noassign) {
     
    365370                 * location
    366371                 */
    367                 strbuf->pptr = va_arg(ap, char **);
     372                strbuf->pptr = va_arg(va->ap, char **);
    368373                *strbuf->pptr = strbuf->buf;
    369374        } else {
     
    371376                strbuf->memalloc = false;
    372377                strbuf->size = 0;
    373                 strbuf->buf = va_arg(ap, char *);
     378                strbuf->buf = va_arg(va->ap, char *);
    374379                strbuf->pptr = NULL;
    375380        }
     
    985990
    986991/** Perform a single conversion. */
    987 static int vfscanf_cvt(FILE *f, const char **fmt, va_list ap, int *numchar,
    988     unsigned *ncvt)
     992static int vfscanf_cvt(FILE *f, const char **fmt, va_encaps_t *va,
     993    int *numchar, unsigned *ncvt)
    989994{
    990995        int rc;
     
    10891094        case cs_char:
    10901095                /* Characters */
    1091                 rc = strbuf_init(&strbuf, &cvtspec, ap);
     1096                rc = strbuf_init(&strbuf, &cvtspec, va);
    10921097                if (rc != EOK)
    10931098                        return rc;
     
    11081113        case cs_str:
    11091114                /* Non-whitespace string */
    1110                 rc = strbuf_init(&strbuf, &cvtspec, ap);
     1115                rc = strbuf_init(&strbuf, &cvtspec, va);
    11111116                if (rc != EOK)
    11121117                        return rc;
     
    11271132        case cs_set:
    11281133                /* String of characters from scanset */
    1129                 rc = strbuf_init(&strbuf, &cvtspec, ap);
     1134                rc = strbuf_init(&strbuf, &cvtspec, va);
    11301135                if (rc != EOK)
    11311136                        return rc;
     
    11631168                switch (cvtspec.lenmod) {
    11641169                case lm_none:
    1165                         iptr = va_arg(ap, int *);
     1170                        iptr = va_arg(va->ap, int *);
    11661171                        *iptr = ival;
    11671172                        break;
    11681173                case lm_hh:
    1169                         scptr = va_arg(ap, signed char *);
     1174                        scptr = va_arg(va->ap, signed char *);
    11701175                        *scptr = ival;
    11711176                        break;
    11721177                case lm_h:
    1173                         sptr = va_arg(ap, short *);
     1178                        sptr = va_arg(va->ap, short *);
    11741179                        *sptr = ival;
    11751180                        break;
    11761181                case lm_l:
    1177                         lptr = va_arg(ap, long *);
     1182                        lptr = va_arg(va->ap, long *);
    11781183                        *lptr = ival;
    11791184                        break;
    11801185                case lm_ll:
    1181                         llptr = va_arg(ap, long long *);
     1186                        llptr = va_arg(va->ap, long long *);
    11821187                        *llptr = ival;
    11831188                        break;
    11841189                case lm_j:
    1185                         imptr = va_arg(ap, intmax_t *);
     1190                        imptr = va_arg(va->ap, intmax_t *);
    11861191                        *imptr = ival;
    11871192                        break;
    11881193                case lm_z:
    1189                         ssptr = va_arg(ap, ssize_t *);
     1194                        ssptr = va_arg(va->ap, ssize_t *);
    11901195                        *ssptr = ival;
    11911196                        break;
    11921197                case lm_t:
    1193                         pdptr = va_arg(ap, ptrdiff_t *);
     1198                        pdptr = va_arg(va->ap, ptrdiff_t *);
    11941199                        *pdptr = ival;
    11951200                        break;
     
    12051210                switch (cvtspec.lenmod) {
    12061211                case lm_none:
    1207                         uptr = va_arg(ap, unsigned *);
     1212                        uptr = va_arg(va->ap, unsigned *);
    12081213                        *uptr = uval;
    12091214                        break;
    12101215                case lm_hh:
    1211                         ucptr = va_arg(ap, unsigned char *);
     1216                        ucptr = va_arg(va->ap, unsigned char *);
    12121217                        *ucptr = uval;
    12131218                        break;
    12141219                case lm_h:
    1215                         usptr = va_arg(ap, unsigned short *);
     1220                        usptr = va_arg(va->ap, unsigned short *);
    12161221                        *usptr = uval;
    12171222                        break;
    12181223                case lm_l:
    1219                         ulptr = va_arg(ap, unsigned long *);
     1224                        ulptr = va_arg(va->ap, unsigned long *);
    12201225                        *ulptr = uval;
    12211226                        break;
    12221227                case lm_ll:
    1223                         ullptr = va_arg(ap, unsigned long long *);
     1228                        ullptr = va_arg(va->ap, unsigned long long *);
    12241229                        *ullptr = uval;
    12251230                        break;
    12261231                case lm_j:
    1227                         umptr = va_arg(ap, uintmax_t *);
     1232                        umptr = va_arg(va->ap, uintmax_t *);
    12281233                        *umptr = uval;
    12291234                        break;
    12301235                case lm_z:
    1231                         szptr = va_arg(ap, size_t *);
     1236                        szptr = va_arg(va->ap, size_t *);
    12321237                        *szptr = uval;
    12331238                        break;
    12341239                case lm_t:
    1235                         updptr = va_arg(ap, ptrdiff_t *);
     1240                        updptr = va_arg(va->ap, ptrdiff_t *);
    12361241                        *updptr = uval;
    12371242                        break;
     
    12451250                switch (cvtspec.lenmod) {
    12461251                case lm_none:
    1247                         fptr = va_arg(ap, float *);
     1252                        fptr = va_arg(va->ap, float *);
    12481253                        *fptr = fval;
    12491254                        break;
    12501255                case lm_l:
    1251                         dptr = va_arg(ap, double *);
     1256                        dptr = va_arg(va->ap, double *);
    12521257                        *dptr = fval;
    12531258                        break;
    12541259                case lm_L:
    1255                         ldptr = va_arg(ap, long double *);
     1260                        ldptr = va_arg(va->ap, long double *);
    12561261                        *ldptr = fval;
    12571262                        break;
     
    12631268                break;
    12641269        case cs_ptr:
    1265                 pptr = va_arg(ap, void *);
     1270                pptr = va_arg(va->ap, void *);
    12661271                *pptr = (void *)(uintptr_t)uval;
    12671272                ++(*ncvt);
     
    12781283        case cs_numchar:
    12791284                /* Store number of characters read so far. */
    1280                 iptr = va_arg(ap, int *);
     1285                iptr = va_arg(va->ap, int *);
    12811286                *iptr = *numchar;
    12821287                /* No incrementing of ncvt */
     
    12981303        int numchar;
    12991304        bool input_error = false;
     1305        va_encaps_t va;
    13001306        int rc;
     1307
     1308        va_copy(va.ap, ap);
    13011309
    13021310        ncvt = 0;
     
    13151323                } else if (*cp == '%') {
    13161324                        /* Conversion specification */
    1317                         rc = vfscanf_cvt(f, &cp, ap, &numchar, &ncvt);
     1325                        rc = vfscanf_cvt(f, &cp, &va, &numchar,
     1326                            &ncvt);
    13181327                        if (rc == EIO) {
    13191328                                /* Input error */
Note: See TracChangeset for help on using the changeset viewer.