back to topotato report
topotato coverage report
Current view: top level - lib/printf - printf-pos.c (source / functions) Hit Total Coverage
Test: test_bgp_distance_change.py::BGPDistanceChange Lines: 0 294 0.0 %
Date: 2023-02-24 18:37:13 Functions: 0 8 0.0 %

          Line data    Source code
       1             : /*-
       2             :  * SPDX-License-Identifier: BSD-3-Clause
       3             :  *
       4             :  * Copyright (c) 1990, 1993
       5             :  *      The Regents of the University of California.  All rights reserved.
       6             :  *
       7             :  * This code is derived from software contributed to Berkeley by
       8             :  * Chris Torek.
       9             :  *
      10             :  * Redistribution and use in source and binary forms, with or without
      11             :  * modification, are permitted provided that the following conditions
      12             :  * are met:
      13             :  * 1. Redistributions of source code must retain the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer.
      15             :  * 2. Redistributions in binary form must reproduce the above copyright
      16             :  *    notice, this list of conditions and the following disclaimer in the
      17             :  *    documentation and/or other materials provided with the distribution.
      18             :  * 3. Neither the name of the University nor the names of its contributors
      19             :  *    may be used to endorse or promote products derived from this software
      20             :  *    without specific prior written permission.
      21             :  *
      22             :  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      23             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      24             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      25             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      26             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      27             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      28             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      29             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      30             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      31             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      32             :  * SUCH DAMAGE.
      33             :  */
      34             : 
      35             : #ifdef HAVE_CONFIG_H
      36             : #include "config.h"
      37             : #endif
      38             : 
      39             : #ifdef HAVE_SYS_CDEFS_H
      40             : #include <sys/cdefs.h>
      41             : #endif
      42             : 
      43             : /*
      44             :  * This is the code responsible for handling positional arguments
      45             :  * (%m$ and %m$.n$) for vfprintf() and vfwprintf().
      46             :  */
      47             : 
      48             : #include <sys/types.h>
      49             : 
      50             : #include <limits.h>
      51             : #include <stdarg.h>
      52             : #include <stddef.h>
      53             : #include <stdint.h>
      54             : #include <stdio.h>
      55             : #include <stdlib.h>
      56             : #include <string.h>
      57             : #include <strings.h>
      58             : #include <wchar.h>
      59             : 
      60             : #include "printflocal.h"
      61             : 
      62             : #ifdef  NL_ARGMAX
      63             : #define MAX_POSARG      NL_ARGMAX
      64             : #else
      65             : #define MAX_POSARG      65536
      66             : #endif
      67             : 
      68             : /*
      69             :  * Type ids for argument type table.
      70             :  */
      71             : enum typeid {
      72             :         T_UNUSED, TP_SHORT, T_INT, T_U_INT, TP_INT,
      73             :         T_LONG, T_U_LONG, TP_LONG, T_LLONG, T_U_LLONG, TP_LLONG,
      74             :         T_PTRDIFFT, TP_PTRDIFFT, T_SSIZET, T_SIZET, TP_SSIZET,
      75             :         T_INT64T, T_UINT64T, T_INTMAXT, T_UINTMAXT, TP_INTMAXT, TP_VOID,
      76             :         TP_CHAR, TP_SCHAR, T_DOUBLE, T_LONG_DOUBLE, T_WINT, TP_WCHAR
      77             : };
      78             : 
      79             : /* An expandable array of types. */
      80             : struct typetable {
      81             :         enum typeid *table; /* table of types */
      82             :         enum typeid stattable[STATIC_ARG_TBL_SIZE];
      83             :         u_int tablesize;        /* current size of type table */
      84             :         u_int tablemax;         /* largest used index in table */
      85             :         u_int nextarg;          /* 1-based argument index */
      86             : };
      87             : 
      88             : static int      __grow_type_table(struct typetable *);
      89             : static void     build_arg_table (struct typetable *, va_list, union arg **);
      90             : 
      91             : /*
      92             :  * Initialize a struct typetable.
      93             :  */
      94             : static inline void
      95           0 : inittypes(struct typetable *types)
      96             : {
      97           0 :         u_int n;
      98             : 
      99           0 :         types->table = types->stattable;
     100           0 :         types->tablesize = STATIC_ARG_TBL_SIZE;
     101           0 :         types->tablemax = 0;
     102           0 :         types->nextarg = 1;
     103           0 :         for (n = 0; n < STATIC_ARG_TBL_SIZE; n++)
     104           0 :                 types->table[n] = T_UNUSED;
     105             : }
     106             : 
     107             : /*
     108             :  * struct typetable destructor.
     109             :  */
     110             : static inline void
     111           0 : freetypes(struct typetable *types)
     112             : {
     113             : 
     114           0 :         if (types->table != types->stattable)
     115           0 :                 free (types->table);
     116             : }
     117             : 
     118             : /*
     119             :  * Ensure that there is space to add a new argument type to the type table.
     120             :  * Expand the table if necessary. Returns 0 on success.
     121             :  */
     122             : static inline int
     123           0 : _ensurespace(struct typetable *types)
     124             : {
     125             : 
     126           0 :         if (types->nextarg >= types->tablesize) {
     127           0 :                 if (__grow_type_table(types))
     128             :                         return -1;
     129             :         }
     130           0 :         if (types->nextarg > types->tablemax)
     131           0 :                 types->tablemax = types->nextarg;
     132             :         return 0;
     133             : }
     134             : 
     135             : /*
     136             :  * Add an argument type to the table, expanding if necessary.
     137             :  * Returns 0 on success.
     138             :  */
     139             : static inline int
     140           0 : addtype(struct typetable *types, enum typeid type)
     141             : {
     142             : 
     143           0 :         if (_ensurespace(types))
     144             :                 return -1;
     145           0 :         types->table[types->nextarg++] = type;
     146           0 :         return 0;
     147             : }
     148             : 
     149             : static inline int
     150           0 : addsarg(struct typetable *types, int flags)
     151             : {
     152             : 
     153           0 :         if (_ensurespace(types))
     154             :                 return -1;
     155           0 :         if (flags & LONGDBL)
     156           0 :                 types->table[types->nextarg++] = T_INT64T;
     157           0 :         else if (flags & INTMAXT)
     158           0 :                 types->table[types->nextarg++] = T_INTMAXT;
     159           0 :         else if (flags & SIZET)
     160           0 :                 types->table[types->nextarg++] = T_SSIZET;
     161           0 :         else if (flags & PTRDIFFT)
     162           0 :                 types->table[types->nextarg++] = T_PTRDIFFT;
     163           0 :         else if (flags & LLONGINT)
     164           0 :                 types->table[types->nextarg++] = T_LLONG;
     165           0 :         else if (flags & LONGINT)
     166           0 :                 types->table[types->nextarg++] = T_LONG;
     167             :         else
     168           0 :                 types->table[types->nextarg++] = T_INT;
     169             :         return 0;
     170             : }
     171             : 
     172             : static inline int
     173           0 : adduarg(struct typetable *types, int flags)
     174             : {
     175             : 
     176           0 :         if (_ensurespace(types))
     177             :                 return -1;
     178           0 :         if (flags & LONGDBL)
     179           0 :                 types->table[types->nextarg++] = T_UINT64T;
     180           0 :         else if (flags & INTMAXT)
     181           0 :                 types->table[types->nextarg++] = T_UINTMAXT;
     182           0 :         else if (flags & SIZET)
     183           0 :                 types->table[types->nextarg++] = T_SIZET;
     184           0 :         else if (flags & PTRDIFFT)
     185           0 :                 types->table[types->nextarg++] = T_SIZET;
     186           0 :         else if (flags & LLONGINT)
     187           0 :                 types->table[types->nextarg++] = T_U_LLONG;
     188           0 :         else if (flags & LONGINT)
     189           0 :                 types->table[types->nextarg++] = T_U_LONG;
     190             :         else
     191           0 :                 types->table[types->nextarg++] = T_U_INT;
     192             :         return 0;
     193             : }
     194             : 
     195             : /*
     196             :  * Add * arguments to the type array.
     197             :  */
     198             : static inline int
     199           0 : addaster(struct typetable *types, char **fmtp)
     200             : {
     201           0 :         char *cp;
     202           0 :         u_int n2;
     203             : 
     204           0 :         n2 = 0;
     205           0 :         cp = *fmtp;
     206           0 :         while (is_digit(*cp)) {
     207           0 :                 n2 = 10 * n2 + to_digit(*cp);
     208           0 :                 cp++;
     209             :         }
     210           0 :         if (*cp == '$') {
     211           0 :                 u_int hold = types->nextarg;
     212           0 :                 types->nextarg = n2;
     213           0 :                 if (addtype(types, T_INT))
     214             :                         return -1;
     215           0 :                 types->nextarg = hold;
     216           0 :                 *fmtp = ++cp;
     217             :         } else {
     218           0 :                 if (addtype(types, T_INT))
     219             :                         return -1;
     220             :         }
     221             :         return 0;
     222             : }
     223             : 
     224             : #ifdef WCHAR_SUPPORT
     225             : static inline int
     226             : addwaster(struct typetable *types, wchar_t **fmtp)
     227             : {
     228             :         wchar_t *cp;
     229             :         u_int n2;
     230             : 
     231             :         n2 = 0;
     232             :         cp = *fmtp;
     233             :         while (is_digit(*cp)) {
     234             :                 n2 = 10 * n2 + to_digit(*cp);
     235             :                 cp++;
     236             :         }
     237             :         if (*cp == '$') {
     238             :                 u_int hold = types->nextarg;
     239             :                 types->nextarg = n2;
     240             :                 if (addtype(types, T_INT))
     241             :                         return -1;
     242             :                 types->nextarg = hold;
     243             :                 *fmtp = ++cp;
     244             :         } else {
     245             :                 if (addtype(types, T_INT))
     246             :                         return -1;
     247             :         }
     248             :         return 0;
     249             : }
     250             : #endif /* WCHAR_SUPPORT */
     251             : 
     252             : /*
     253             :  * Find all arguments when a positional parameter is encountered.  Returns a
     254             :  * table, indexed by argument number, of pointers to each arguments.  The
     255             :  * initial argument table should be an array of STATIC_ARG_TBL_SIZE entries.
     256             :  * It will be replaces with a malloc-ed one if it overflows.
     257             :  * Returns 0 on success. On failure, returns nonzero and sets errno.
     258             :  */
     259             : int
     260           0 : _frr_find_arguments (const char *fmt0, va_list ap, union arg **argtable)
     261             : {
     262           0 :         char *fmt;              /* format string */
     263           0 :         int ch;                 /* character from fmt */
     264           0 :         u_int n;                /* handy integer (short term usage) */
     265           0 :         int error;
     266           0 :         int flags;              /* flags as above */
     267           0 :         struct typetable types; /* table of types */
     268             : 
     269           0 :         fmt = (char *)fmt0;
     270           0 :         inittypes(&types);
     271             :         error = 0;
     272             : 
     273             :         /*
     274             :          * Scan the format for conversions (`%' character).
     275             :          */
     276             :         for (;;) {
     277           0 :                 while ((ch = *fmt) != '\0' && ch != '%')
     278           0 :                         fmt++;
     279           0 :                 if (ch == '\0')
     280           0 :                         goto done;
     281           0 :                 fmt++;          /* skip over '%' */
     282             : 
     283           0 :                 flags = 0;
     284             : 
     285           0 : rflag:          ch = *fmt++;
     286           0 : reswitch:       switch (ch) {
     287           0 :                 case ' ':
     288             :                 case '#':
     289           0 :                         goto rflag;
     290           0 :                 case '*':
     291           0 :                         if ((error = addaster(&types, &fmt)))
     292           0 :                                 goto error;
     293           0 :                         goto rflag;
     294           0 :                 case '-':
     295             :                 case '+':
     296             :                 case '\'':
     297           0 :                         goto rflag;
     298           0 :                 case '.':
     299           0 :                         if ((ch = *fmt++) == '*') {
     300           0 :                                 if ((error = addaster(&types, &fmt)))
     301           0 :                                         goto error;
     302           0 :                                 goto rflag;
     303             :                         }
     304           0 :                         while (is_digit(ch)) {
     305           0 :                                 ch = *fmt++;
     306             :                         }
     307           0 :                         goto reswitch;
     308           0 :                 case '0':
     309           0 :                         goto rflag;
     310             :                 case '1': case '2': case '3': case '4':
     311             :                 case '5': case '6': case '7': case '8': case '9':
     312             :                         n = 0;
     313           0 :                         do {
     314           0 :                                 n = 10 * n + to_digit(ch);
     315             :                                 /* Detect overflow */
     316           0 :                                 if (n > MAX_POSARG) {
     317           0 :                                         error = -1;
     318           0 :                                         goto error;
     319             :                                 }
     320           0 :                                 ch = *fmt++;
     321           0 :                         } while (is_digit(ch));
     322           0 :                         if (ch == '$') {
     323           0 :                                 types.nextarg = n;
     324           0 :                                 goto rflag;
     325             :                         }
     326           0 :                         goto reswitch;
     327           0 :                 case 'L':
     328           0 :                         flags |= LONGDBL;
     329           0 :                         goto rflag;
     330           0 :                 case 'h':
     331           0 :                         if (flags & SHORTINT) {
     332           0 :                                 flags &= ~SHORTINT;
     333           0 :                                 flags |= CHARINT;
     334             :                         } else
     335           0 :                                 flags |= SHORTINT;
     336           0 :                         goto rflag;
     337           0 :                 case 'j':
     338           0 :                         flags |= INTMAXT;
     339           0 :                         goto rflag;
     340           0 :                 case 'l':
     341           0 :                         if (flags & LONGINT) {
     342           0 :                                 flags &= ~LONGINT;
     343           0 :                                 flags |= LLONGINT;
     344             :                         } else
     345           0 :                                 flags |= LONGINT;
     346           0 :                         goto rflag;
     347           0 :                 case 'q':
     348           0 :                         flags |= LLONGINT;      /* not necessarily */
     349           0 :                         goto rflag;
     350           0 :                 case 't':
     351           0 :                         flags |= PTRDIFFT;
     352           0 :                         goto rflag;
     353           0 :                 case 'z':
     354           0 :                         flags |= SIZET;
     355           0 :                         goto rflag;
     356           0 :                 case 'C':
     357           0 :                         flags |= LONGINT;
     358             :                         /*FALLTHROUGH*/
     359           0 :                 case 'c':
     360           0 :                         error = addtype(&types,
     361           0 :                                         (flags & LONGINT) ? T_WINT : T_INT);
     362           0 :                         if (error)
     363           0 :                                 goto error;
     364             :                         break;
     365           0 :                 case 'D':
     366           0 :                         flags |= LONGINT;
     367             :                         /*FALLTHROUGH*/
     368           0 :                 case 'd':
     369             :                 case 'i':
     370           0 :                         if ((error = addsarg(&types, flags)))
     371           0 :                                 goto error;
     372             :                         break;
     373             : #ifndef NO_FLOATING_POINT
     374           0 :                 case 'a':
     375             :                 case 'A':
     376             :                 case 'e':
     377             :                 case 'E':
     378             :                 case 'f':
     379             :                 case 'g':
     380             :                 case 'G':
     381           0 :                         error = addtype(&types,
     382           0 :                             (flags & LONGDBL) ? T_LONG_DOUBLE : T_DOUBLE);
     383           0 :                         if (error)
     384           0 :                                 goto error;
     385             :                         break;
     386             : #endif /* !NO_FLOATING_POINT */
     387             : #ifdef DANGEROUS_PERCENT_N
     388             :                 case 'n':
     389             :                         if (flags & INTMAXT)
     390             :                                 error = addtype(&types, TP_INTMAXT);
     391             :                         else if (flags & PTRDIFFT)
     392             :                                 error = addtype(&types, TP_PTRDIFFT);
     393             :                         else if (flags & SIZET)
     394             :                                 error = addtype(&types, TP_SSIZET);
     395             :                         else if (flags & LLONGINT)
     396             :                                 error = addtype(&types, TP_LLONG);
     397             :                         else if (flags & LONGINT)
     398             :                                 error = addtype(&types, TP_LONG);
     399             :                         else if (flags & SHORTINT)
     400             :                                 error = addtype(&types, TP_SHORT);
     401             :                         else if (flags & CHARINT)
     402             :                                 error = addtype(&types, TP_SCHAR);
     403             :                         else
     404             :                                 error = addtype(&types, TP_INT);
     405             :                         if (error)
     406             :                                 goto error;
     407             :                         continue;       /* no output */
     408             : #endif
     409           0 :                 case 'O':
     410           0 :                         flags |= LONGINT;
     411             :                         /*FALLTHROUGH*/
     412           0 :                 case 'o':
     413           0 :                         if ((error = adduarg(&types, flags)))
     414           0 :                                 goto error;
     415             :                         break;
     416           0 :                 case 'p':
     417           0 :                         if ((error = addtype(&types, TP_VOID)))
     418           0 :                                 goto error;
     419             :                         break;
     420           0 :                 case 'S':
     421           0 :                         flags |= LONGINT;
     422             :                         /*FALLTHROUGH*/
     423           0 :                 case 's':
     424           0 :                         error = addtype(&types,
     425           0 :                                         (flags & LONGINT) ? TP_WCHAR : TP_CHAR);
     426           0 :                         if (error)
     427           0 :                                 goto error;
     428             :                         break;
     429           0 :                 case 'U':
     430           0 :                         flags |= LONGINT;
     431             :                         /*FALLTHROUGH*/
     432           0 :                 case 'u':
     433             :                 case 'X':
     434             :                 case 'x':
     435           0 :                         if ((error = adduarg(&types, flags)))
     436           0 :                                 goto error;
     437             :                         break;
     438           0 :                 default:        /* "%?" prints ?, unless ? is NUL */
     439           0 :                         if (ch == '\0')
     440           0 :                                 goto done;
     441             :                         break;
     442             :                 }
     443             :         }
     444           0 : done:
     445           0 :         build_arg_table(&types, ap, argtable);
     446           0 : error:
     447           0 :         freetypes(&types);
     448           0 :         return (error || *argtable == NULL);
     449             : }
     450             : 
     451             : #ifdef WCHAR_SUPPORT
     452             : /* wchar version of __find_arguments. */
     453             : int
     454             : _frr_find_warguments (const wchar_t *fmt0, va_list ap, union arg **argtable)
     455             : {
     456             :         wchar_t *fmt;           /* format string */
     457             :         wchar_t ch;             /* character from fmt */
     458             :         u_int n;                /* handy integer (short term usage) */
     459             :         int error;
     460             :         int flags;              /* flags as above */
     461             :         struct typetable types; /* table of types */
     462             : 
     463             :         fmt = (wchar_t *)fmt0;
     464             :         inittypes(&types);
     465             :         error = 0;
     466             : 
     467             :         /*
     468             :          * Scan the format for conversions (`%' character).
     469             :          */
     470             :         for (;;) {
     471             :                 while ((ch = *fmt) != '\0' && ch != '%')
     472             :                         fmt++;
     473             :                 if (ch == '\0')
     474             :                         goto done;
     475             :                 fmt++;          /* skip over '%' */
     476             : 
     477             :                 flags = 0;
     478             : 
     479             : rflag:          ch = *fmt++;
     480             : reswitch:       switch (ch) {
     481             :                 case ' ':
     482             :                 case '#':
     483             :                         goto rflag;
     484             :                 case '*':
     485             :                         if ((error = addwaster(&types, &fmt)))
     486             :                                 goto error;
     487             :                         goto rflag;
     488             :                 case '-':
     489             :                 case '+':
     490             :                 case '\'':
     491             :                         goto rflag;
     492             :                 case '.':
     493             :                         if ((ch = *fmt++) == '*') {
     494             :                                 if ((error = addwaster(&types, &fmt)))
     495             :                                         goto error;
     496             :                                 goto rflag;
     497             :                         }
     498             :                         while (is_digit(ch)) {
     499             :                                 ch = *fmt++;
     500             :                         }
     501             :                         goto reswitch;
     502             :                 case '0':
     503             :                         goto rflag;
     504             :                 case '1': case '2': case '3': case '4':
     505             :                 case '5': case '6': case '7': case '8': case '9':
     506             :                         n = 0;
     507             :                         do {
     508             :                                 n = 10 * n + to_digit(ch);
     509             :                                 /* Detect overflow */
     510             :                                 if (n > MAX_POSARG) {
     511             :                                         error = -1;
     512             :                                         goto error;
     513             :                                 }
     514             :                                 ch = *fmt++;
     515             :                         } while (is_digit(ch));
     516             :                         if (ch == '$') {
     517             :                                 types.nextarg = n;
     518             :                                 goto rflag;
     519             :                         }
     520             :                         goto reswitch;
     521             :                 case 'L':
     522             :                         flags |= LONGDBL;
     523             :                         goto rflag;
     524             :                 case 'h':
     525             :                         if (flags & SHORTINT) {
     526             :                                 flags &= ~SHORTINT;
     527             :                                 flags |= CHARINT;
     528             :                         } else
     529             :                                 flags |= SHORTINT;
     530             :                         goto rflag;
     531             :                 case 'j':
     532             :                         flags |= INTMAXT;
     533             :                         goto rflag;
     534             :                 case 'l':
     535             :                         if (flags & LONGINT) {
     536             :                                 flags &= ~LONGINT;
     537             :                                 flags |= LLONGINT;
     538             :                         } else
     539             :                                 flags |= LONGINT;
     540             :                         goto rflag;
     541             :                 case 'q':
     542             :                         flags |= LLONGINT;      /* not necessarily */
     543             :                         goto rflag;
     544             :                 case 't':
     545             :                         flags |= PTRDIFFT;
     546             :                         goto rflag;
     547             :                 case 'z':
     548             :                         flags |= SIZET;
     549             :                         goto rflag;
     550             :                 case 'C':
     551             :                         flags |= LONGINT;
     552             :                         /*FALLTHROUGH*/
     553             :                 case 'c':
     554             :                         error = addtype(&types,
     555             :                                         (flags & LONGINT) ? T_WINT : T_INT);
     556             :                         if (error)
     557             :                                 goto error;
     558             :                         break;
     559             :                 case 'D':
     560             :                         flags |= LONGINT;
     561             :                         /*FALLTHROUGH*/
     562             :                 case 'd':
     563             :                 case 'i':
     564             :                         if ((error = addsarg(&types, flags)))
     565             :                                 goto error;
     566             :                         break;
     567             : #ifndef NO_FLOATING_POINT
     568             :                 case 'a':
     569             :                 case 'A':
     570             :                 case 'e':
     571             :                 case 'E':
     572             :                 case 'f':
     573             :                 case 'g':
     574             :                 case 'G':
     575             :                         error = addtype(&types,
     576             :                             (flags & LONGDBL) ? T_LONG_DOUBLE : T_DOUBLE);
     577             :                         if (error)
     578             :                                 goto error;
     579             :                         break;
     580             : #endif /* !NO_FLOATING_POINT */
     581             : #ifdef DANGEROUS_PERCENT_N
     582             :                 case 'n':
     583             :                         if (flags & INTMAXT)
     584             :                                 error = addtype(&types, TP_INTMAXT);
     585             :                         else if (flags & PTRDIFFT)
     586             :                                 error = addtype(&types, TP_PTRDIFFT);
     587             :                         else if (flags & SIZET)
     588             :                                 error = addtype(&types, TP_SSIZET);
     589             :                         else if (flags & LLONGINT)
     590             :                                 error = addtype(&types, TP_LLONG);
     591             :                         else if (flags & LONGINT)
     592             :                                 error = addtype(&types, TP_LONG);
     593             :                         else if (flags & SHORTINT)
     594             :                                 error = addtype(&types, TP_SHORT);
     595             :                         else if (flags & CHARINT)
     596             :                                 error = addtype(&types, TP_SCHAR);
     597             :                         else
     598             :                                 error = addtype(&types, TP_INT);
     599             :                         if (error)
     600             :                                 goto error;
     601             :                         continue;       /* no output */
     602             : #endif
     603             :                 case 'O':
     604             :                         flags |= LONGINT;
     605             :                         /*FALLTHROUGH*/
     606             :                 case 'o':
     607             :                         if ((error = adduarg(&types, flags)))
     608             :                                 goto error;
     609             :                         break;
     610             :                 case 'p':
     611             :                         if ((error = addtype(&types, TP_VOID)))
     612             :                                 goto error;
     613             :                         break;
     614             :                 case 'S':
     615             :                         flags |= LONGINT;
     616             :                         /*FALLTHROUGH*/
     617             :                 case 's':
     618             :                         error = addtype(&types,
     619             :                             (flags & LONGINT) ? TP_WCHAR : TP_CHAR);
     620             :                         if (error)
     621             :                                 goto error;
     622             :                         break;
     623             :                 case 'U':
     624             :                         flags |= LONGINT;
     625             :                         /*FALLTHROUGH*/
     626             :                 case 'u':
     627             :                 case 'X':
     628             :                 case 'x':
     629             :                         if ((error = adduarg(&types, flags)))
     630             :                                 goto error;
     631             :                         break;
     632             :                 default:        /* "%?" prints ?, unless ? is NUL */
     633             :                         if (ch == '\0')
     634             :                                 goto done;
     635             :                         break;
     636             :                 }
     637             :         }
     638             : done:
     639             :         build_arg_table(&types, ap, argtable);
     640             : error:
     641             :         freetypes(&types);
     642             :         return (error || *argtable == NULL);
     643             : }
     644             : #endif /* WCHAR_SUPPORT */
     645             : 
     646             : /*
     647             :  * Increase the size of the type table. Returns 0 on success.
     648             :  */
     649             : static int
     650           0 : __grow_type_table(struct typetable *types)
     651             : {
     652           0 :         enum typeid *const oldtable = types->table;
     653           0 :         const int oldsize = types->tablesize;
     654           0 :         enum typeid *newtable;
     655           0 :         u_int n, newsize;
     656             : 
     657             :         /* Detect overflow */
     658           0 :         if (types->nextarg > MAX_POSARG)
     659             :                 return -1;
     660             : 
     661           0 :         newsize = oldsize * 2;
     662           0 :         if (newsize < types->nextarg + 1)
     663             :                 newsize = types->nextarg + 1;
     664           0 :         if (oldsize == STATIC_ARG_TBL_SIZE) {
     665           0 :                 if ((newtable = malloc(newsize * sizeof(enum typeid))) == NULL)
     666             :                         return -1;
     667           0 :                 bcopy(oldtable, newtable, oldsize * sizeof(enum typeid));
     668             :         } else {
     669           0 :                 newtable = realloc(oldtable, newsize * sizeof(enum typeid));
     670           0 :                 if (newtable == NULL)
     671             :                         return -1;
     672             :         }
     673           0 :         for (n = oldsize; n < newsize; n++)
     674           0 :                 newtable[n] = T_UNUSED;
     675             : 
     676           0 :         types->table = newtable;
     677           0 :         types->tablesize = newsize;
     678             : 
     679           0 :         return 0;
     680             : }
     681             : 
     682             : /*
     683             :  * Build the argument table from the completed type table.
     684             :  * On malloc failure, *argtable is set to NULL.
     685             :  */
     686             : static void
     687           0 : build_arg_table(struct typetable *types, va_list ap, union arg **argtable)
     688             : {
     689           0 :         u_int n;
     690             : 
     691           0 :         if (types->tablemax >= STATIC_ARG_TBL_SIZE) {
     692           0 :                 *argtable = (union arg *)
     693           0 :                     malloc (sizeof(union arg) * (types->tablemax + 1));
     694           0 :                 if (*argtable == NULL)
     695             :                         return;
     696             :         }
     697             : 
     698           0 :         (*argtable) [0].intarg = 0;
     699           0 :         for (n = 1; n <= types->tablemax; n++) {
     700           0 :                 switch (types->table[n]) {
     701           0 :                     case T_UNUSED: /* whoops! */
     702           0 :                         (*argtable) [n].intarg = va_arg (ap, int);
     703           0 :                         break;
     704           0 :                     case TP_SCHAR:
     705           0 :                         (*argtable) [n].pschararg = va_arg (ap, signed char *);
     706           0 :                         break;
     707           0 :                     case TP_SHORT:
     708           0 :                         (*argtable) [n].pshortarg = va_arg (ap, short *);
     709           0 :                         break;
     710           0 :                     case T_INT:
     711           0 :                         (*argtable) [n].intarg = va_arg (ap, int);
     712           0 :                         break;
     713           0 :                     case T_U_INT:
     714           0 :                         (*argtable) [n].uintarg = va_arg (ap, unsigned int);
     715           0 :                         break;
     716           0 :                     case TP_INT:
     717           0 :                         (*argtable) [n].pintarg = va_arg (ap, int *);
     718           0 :                         break;
     719           0 :                     case T_LONG:
     720           0 :                         (*argtable) [n].longarg = va_arg (ap, long);
     721           0 :                         break;
     722           0 :                     case T_U_LONG:
     723           0 :                         (*argtable) [n].ulongarg = va_arg (ap, unsigned long);
     724           0 :                         break;
     725           0 :                     case TP_LONG:
     726           0 :                         (*argtable) [n].plongarg = va_arg (ap, long *);
     727           0 :                         break;
     728           0 :                     case T_LLONG:
     729           0 :                         (*argtable) [n].longlongarg = va_arg (ap, long long);
     730           0 :                         break;
     731           0 :                     case T_U_LLONG:
     732           0 :                         (*argtable) [n].ulonglongarg = va_arg (ap, unsigned long long);
     733           0 :                         break;
     734           0 :                     case TP_LLONG:
     735           0 :                         (*argtable) [n].plonglongarg = va_arg (ap, long long *);
     736           0 :                         break;
     737           0 :                     case T_PTRDIFFT:
     738           0 :                         (*argtable) [n].ptrdiffarg = va_arg (ap, ptrdiff_t);
     739           0 :                         break;
     740           0 :                     case TP_PTRDIFFT:
     741           0 :                         (*argtable) [n].pptrdiffarg = va_arg (ap, ptrdiff_t *);
     742           0 :                         break;
     743           0 :                     case T_SIZET:
     744           0 :                         (*argtable) [n].sizearg = va_arg (ap, size_t);
     745           0 :                         break;
     746           0 :                     case T_SSIZET:
     747           0 :                         (*argtable) [n].sizearg = va_arg (ap, ssize_t);
     748           0 :                         break;
     749           0 :                     case TP_SSIZET:
     750           0 :                         (*argtable) [n].pssizearg = va_arg (ap, ssize_t *);
     751           0 :                         break;
     752           0 :                     case T_INTMAXT:
     753           0 :                         (*argtable) [n].intmaxarg = va_arg (ap, intmax_t);
     754           0 :                         break;
     755           0 :                     case T_UINTMAXT:
     756           0 :                         (*argtable) [n].uintmaxarg = va_arg (ap, uintmax_t);
     757           0 :                         break;
     758           0 :                     case TP_INTMAXT:
     759           0 :                         (*argtable) [n].pintmaxarg = va_arg (ap, intmax_t *);
     760           0 :                         break;
     761           0 :                     case T_INT64T:
     762           0 :                         (*argtable) [n].intmaxarg = va_arg (ap, int64_t);
     763           0 :                         break;
     764           0 :                     case T_UINT64T:
     765           0 :                         (*argtable) [n].uintmaxarg = va_arg (ap, uint64_t);
     766           0 :                         break;
     767           0 :                     case T_DOUBLE:
     768             : #ifndef NO_FLOATING_POINT
     769           0 :                         (*argtable) [n].doublearg = va_arg (ap, double);
     770             : #endif
     771           0 :                         break;
     772           0 :                     case T_LONG_DOUBLE:
     773             : #ifndef NO_FLOATING_POINT
     774           0 :                         (*argtable) [n].longdoublearg = va_arg (ap, long double);
     775             : #endif
     776           0 :                         break;
     777           0 :                     case TP_CHAR:
     778           0 :                         (*argtable) [n].pchararg = va_arg (ap, char *);
     779           0 :                         break;
     780           0 :                     case TP_VOID:
     781           0 :                         (*argtable) [n].pvoidarg = va_arg (ap, void *);
     782           0 :                         break;
     783           0 :                     case T_WINT:
     784           0 :                         (*argtable) [n].wintarg = va_arg (ap, wint_t);
     785           0 :                         break;
     786           0 :                     case TP_WCHAR:
     787           0 :                         (*argtable) [n].pwchararg = va_arg (ap, wchar_t *);
     788           0 :                         break;
     789             :                 }
     790             :         }
     791             : }

Generated by: LCOV version v1.16-topotato