LCOV - code coverage report
Current view: top level - lib - printf-parse.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 0 235 0.0 %
Date: 2017-08-04 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /* Formatted output to strings.
       2             :    Copyright (C) 1999-2000, 2002-2003, 2006-2016 Free Software Foundation, Inc.
       3             : 
       4             :    This program is free software; you can redistribute it and/or modify
       5             :    it under the terms of the GNU General Public License as published by
       6             :    the Free Software Foundation; either version 3, or (at your option)
       7             :    any later version.
       8             : 
       9             :    This program is distributed in the hope that it will be useful,
      10             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :    GNU General Public License for more details.
      13             : 
      14             :    You should have received a copy of the GNU General Public License along
      15             :    with this program; if not, see <http://www.gnu.org/licenses/>.  */
      16             : 
      17             : /* This file can be parametrized with the following macros:
      18             :      CHAR_T             The element type of the format string.
      19             :      CHAR_T_ONLY_ASCII  Set to 1 to enable verification that all characters
      20             :                         in the format string are ASCII.
      21             :      DIRECTIVE          Structure denoting a format directive.
      22             :                         Depends on CHAR_T.
      23             :      DIRECTIVES         Structure denoting the set of format directives of a
      24             :                         format string.  Depends on CHAR_T.
      25             :      PRINTF_PARSE       Function that parses a format string.
      26             :                         Depends on CHAR_T.
      27             :      STATIC             Set to 'static' to declare the function static.
      28             :      ENABLE_UNISTDIO    Set to 1 to enable the unistdio extensions.  */
      29             : 
      30             : #ifndef PRINTF_PARSE
      31             : # include <config.h>
      32             : #endif
      33             : 
      34             : /* Specification.  */
      35             : #ifndef PRINTF_PARSE
      36             : # include "printf-parse.h"
      37             : #endif
      38             : 
      39             : /* Default parameters.  */
      40             : #ifndef PRINTF_PARSE
      41             : # define PRINTF_PARSE printf_parse
      42             : # define CHAR_T char
      43             : # define DIRECTIVE char_directive
      44             : # define DIRECTIVES char_directives
      45             : #endif
      46             : 
      47             : /* Get size_t, NULL.  */
      48             : #include <stddef.h>
      49             : 
      50             : /* Get intmax_t.  */
      51             : #if defined IN_LIBINTL || defined IN_LIBASPRINTF
      52             : # if HAVE_STDINT_H_WITH_UINTMAX
      53             : #  include <stdint.h>
      54             : # endif
      55             : # if HAVE_INTTYPES_H_WITH_UINTMAX
      56             : #  include <inttypes.h>
      57             : # endif
      58             : #else
      59             : # include <stdint.h>
      60             : #endif
      61             : 
      62             : /* malloc(), realloc(), free().  */
      63             : #include <stdlib.h>
      64             : 
      65             : /* memcpy().  */
      66             : #include <string.h>
      67             : 
      68             : /* errno.  */
      69             : #include <errno.h>
      70             : 
      71             : /* Checked size_t computations.  */
      72             : #include "xsize.h"
      73             : 
      74             : #if CHAR_T_ONLY_ASCII
      75             : /* c_isascii().  */
      76             : # include "c-ctype.h"
      77             : #endif
      78             : 
      79             : #ifdef STATIC
      80             : STATIC
      81             : #endif
      82             : int
      83           0 : PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
      84             : {
      85           0 :   const CHAR_T *cp = format;    /* pointer into format */
      86           0 :   size_t arg_posn = 0;          /* number of regular arguments consumed */
      87             :   size_t d_allocated;           /* allocated elements of d->dir */
      88             :   size_t a_allocated;           /* allocated elements of a->arg */
      89           0 :   size_t max_width_length = 0;
      90           0 :   size_t max_precision_length = 0;
      91             : 
      92           0 :   d->count = 0;
      93           0 :   d_allocated = N_DIRECT_ALLOC_DIRECTIVES;
      94           0 :   d->dir = d->direct_alloc_dir;
      95             : 
      96           0 :   a->count = 0;
      97           0 :   a_allocated = N_DIRECT_ALLOC_ARGUMENTS;
      98           0 :   a->arg = a->direct_alloc_arg;
      99             : 
     100             : #define REGISTER_ARG(_index_,_type_) \
     101             :   {                                                                     \
     102             :     size_t n = (_index_);                                               \
     103             :     if (n >= a_allocated)                                               \
     104             :       {                                                                 \
     105             :         size_t memory_size;                                             \
     106             :         argument *memory;                                               \
     107             :                                                                         \
     108             :         a_allocated = xtimes (a_allocated, 2);                          \
     109             :         if (a_allocated <= n)                                           \
     110             :           a_allocated = xsum (n, 1);                                    \
     111             :         memory_size = xtimes (a_allocated, sizeof (argument));          \
     112             :         if (size_overflow_p (memory_size))                              \
     113             :           /* Overflow, would lead to out of memory.  */                 \
     114             :           goto out_of_memory;                                           \
     115             :         memory = (argument *) (a->arg != a->direct_alloc_arg            \
     116             :                                ? realloc (a->arg, memory_size)          \
     117             :                                : malloc (memory_size));                 \
     118             :         if (memory == NULL)                                             \
     119             :           /* Out of memory.  */                                         \
     120             :           goto out_of_memory;                                           \
     121             :         if (a->arg == a->direct_alloc_arg)                              \
     122             :           memcpy (memory, a->arg, a->count * sizeof (argument));        \
     123             :         a->arg = memory;                                                \
     124             :       }                                                                 \
     125             :     while (a->count <= n)                                               \
     126             :       a->arg[a->count++].type = TYPE_NONE;                              \
     127             :     if (a->arg[n].type == TYPE_NONE)                                    \
     128             :       a->arg[n].type = (_type_);                                        \
     129             :     else if (a->arg[n].type != (_type_))                                \
     130             :       /* Ambiguous type for positional argument.  */                    \
     131             :       goto error;                                                       \
     132             :   }
     133             : 
     134           0 :   while (*cp != '\0')
     135             :     {
     136           0 :       CHAR_T c = *cp++;
     137           0 :       if (c == '%')
     138             :         {
     139           0 :           size_t arg_index = ARG_NONE;
     140           0 :           DIRECTIVE *dp = &d->dir[d->count]; /* pointer to next directive */
     141             : 
     142             :           /* Initialize the next directive.  */
     143           0 :           dp->dir_start = cp - 1;
     144           0 :           dp->flags = 0;
     145           0 :           dp->width_start = NULL;
     146           0 :           dp->width_end = NULL;
     147           0 :           dp->width_arg_index = ARG_NONE;
     148           0 :           dp->precision_start = NULL;
     149           0 :           dp->precision_end = NULL;
     150           0 :           dp->precision_arg_index = ARG_NONE;
     151           0 :           dp->arg_index = ARG_NONE;
     152             : 
     153             :           /* Test for positional argument.  */
     154           0 :           if (*cp >= '0' && *cp <= '9')
     155             :             {
     156             :               const CHAR_T *np;
     157             : 
     158           0 :               for (np = cp; *np >= '0' && *np <= '9'; np++)
     159             :                 ;
     160           0 :               if (*np == '$')
     161             :                 {
     162           0 :                   size_t n = 0;
     163             : 
     164           0 :                   for (np = cp; *np >= '0' && *np <= '9'; np++)
     165           0 :                     n = xsum (xtimes (n, 10), *np - '0');
     166           0 :                   if (n == 0)
     167             :                     /* Positional argument 0.  */
     168           0 :                     goto error;
     169           0 :                   if (size_overflow_p (n))
     170             :                     /* n too large, would lead to out of memory later.  */
     171           0 :                     goto error;
     172           0 :                   arg_index = n - 1;
     173           0 :                   cp = np + 1;
     174             :                 }
     175             :             }
     176             : 
     177             :           /* Read the flags.  */
     178             :           for (;;)
     179             :             {
     180           0 :               if (*cp == '\'')
     181             :                 {
     182           0 :                   dp->flags |= FLAG_GROUP;
     183           0 :                   cp++;
     184             :                 }
     185           0 :               else if (*cp == '-')
     186             :                 {
     187           0 :                   dp->flags |= FLAG_LEFT;
     188           0 :                   cp++;
     189             :                 }
     190           0 :               else if (*cp == '+')
     191             :                 {
     192           0 :                   dp->flags |= FLAG_SHOWSIGN;
     193           0 :                   cp++;
     194             :                 }
     195           0 :               else if (*cp == ' ')
     196             :                 {
     197           0 :                   dp->flags |= FLAG_SPACE;
     198           0 :                   cp++;
     199             :                 }
     200           0 :               else if (*cp == '#')
     201             :                 {
     202           0 :                   dp->flags |= FLAG_ALT;
     203           0 :                   cp++;
     204             :                 }
     205           0 :               else if (*cp == '0')
     206             :                 {
     207           0 :                   dp->flags |= FLAG_ZERO;
     208           0 :                   cp++;
     209             :                 }
     210             : #if __GLIBC__ >= 2 && !defined __UCLIBC__
     211           0 :               else if (*cp == 'I')
     212             :                 {
     213           0 :                   dp->flags |= FLAG_LOCALIZED;
     214           0 :                   cp++;
     215             :                 }
     216             : #endif
     217             :               else
     218           0 :                 break;
     219           0 :             }
     220             : 
     221             :           /* Parse the field width.  */
     222           0 :           if (*cp == '*')
     223             :             {
     224           0 :               dp->width_start = cp;
     225           0 :               cp++;
     226           0 :               dp->width_end = cp;
     227           0 :               if (max_width_length < 1)
     228           0 :                 max_width_length = 1;
     229             : 
     230             :               /* Test for positional argument.  */
     231           0 :               if (*cp >= '0' && *cp <= '9')
     232             :                 {
     233             :                   const CHAR_T *np;
     234             : 
     235           0 :                   for (np = cp; *np >= '0' && *np <= '9'; np++)
     236             :                     ;
     237           0 :                   if (*np == '$')
     238             :                     {
     239           0 :                       size_t n = 0;
     240             : 
     241           0 :                       for (np = cp; *np >= '0' && *np <= '9'; np++)
     242           0 :                         n = xsum (xtimes (n, 10), *np - '0');
     243           0 :                       if (n == 0)
     244             :                         /* Positional argument 0.  */
     245           0 :                         goto error;
     246           0 :                       if (size_overflow_p (n))
     247             :                         /* n too large, would lead to out of memory later.  */
     248           0 :                         goto error;
     249           0 :                       dp->width_arg_index = n - 1;
     250           0 :                       cp = np + 1;
     251             :                     }
     252             :                 }
     253           0 :               if (dp->width_arg_index == ARG_NONE)
     254             :                 {
     255           0 :                   dp->width_arg_index = arg_posn++;
     256           0 :                   if (dp->width_arg_index == ARG_NONE)
     257             :                     /* arg_posn wrapped around.  */
     258           0 :                     goto error;
     259             :                 }
     260           0 :               REGISTER_ARG (dp->width_arg_index, TYPE_INT);
     261             :             }
     262           0 :           else if (*cp >= '0' && *cp <= '9')
     263             :             {
     264             :               size_t width_length;
     265             : 
     266           0 :               dp->width_start = cp;
     267           0 :               for (; *cp >= '0' && *cp <= '9'; cp++)
     268             :                 ;
     269           0 :               dp->width_end = cp;
     270           0 :               width_length = dp->width_end - dp->width_start;
     271           0 :               if (max_width_length < width_length)
     272           0 :                 max_width_length = width_length;
     273             :             }
     274             : 
     275             :           /* Parse the precision.  */
     276           0 :           if (*cp == '.')
     277             :             {
     278           0 :               cp++;
     279           0 :               if (*cp == '*')
     280             :                 {
     281           0 :                   dp->precision_start = cp - 1;
     282           0 :                   cp++;
     283           0 :                   dp->precision_end = cp;
     284           0 :                   if (max_precision_length < 2)
     285           0 :                     max_precision_length = 2;
     286             : 
     287             :                   /* Test for positional argument.  */
     288           0 :                   if (*cp >= '0' && *cp <= '9')
     289             :                     {
     290             :                       const CHAR_T *np;
     291             : 
     292           0 :                       for (np = cp; *np >= '0' && *np <= '9'; np++)
     293             :                         ;
     294           0 :                       if (*np == '$')
     295             :                         {
     296           0 :                           size_t n = 0;
     297             : 
     298           0 :                           for (np = cp; *np >= '0' && *np <= '9'; np++)
     299           0 :                             n = xsum (xtimes (n, 10), *np - '0');
     300           0 :                           if (n == 0)
     301             :                             /* Positional argument 0.  */
     302           0 :                             goto error;
     303           0 :                           if (size_overflow_p (n))
     304             :                             /* n too large, would lead to out of memory
     305             :                                later.  */
     306           0 :                             goto error;
     307           0 :                           dp->precision_arg_index = n - 1;
     308           0 :                           cp = np + 1;
     309             :                         }
     310             :                     }
     311           0 :                   if (dp->precision_arg_index == ARG_NONE)
     312             :                     {
     313           0 :                       dp->precision_arg_index = arg_posn++;
     314           0 :                       if (dp->precision_arg_index == ARG_NONE)
     315             :                         /* arg_posn wrapped around.  */
     316           0 :                         goto error;
     317             :                     }
     318           0 :                   REGISTER_ARG (dp->precision_arg_index, TYPE_INT);
     319             :                 }
     320             :               else
     321             :                 {
     322             :                   size_t precision_length;
     323             : 
     324           0 :                   dp->precision_start = cp - 1;
     325           0 :                   for (; *cp >= '0' && *cp <= '9'; cp++)
     326             :                     ;
     327           0 :                   dp->precision_end = cp;
     328           0 :                   precision_length = dp->precision_end - dp->precision_start;
     329           0 :                   if (max_precision_length < precision_length)
     330           0 :                     max_precision_length = precision_length;
     331             :                 }
     332             :             }
     333             : 
     334             :           {
     335             :             arg_type type;
     336             : 
     337             :             /* Parse argument type/size specifiers.  */
     338             :             {
     339           0 :               int flags = 0;
     340             : 
     341             :               for (;;)
     342             :                 {
     343           0 :                   if (*cp == 'h')
     344             :                     {
     345           0 :                       flags |= (1 << (flags & 1));
     346           0 :                       cp++;
     347             :                     }
     348           0 :                   else if (*cp == 'L')
     349             :                     {
     350           0 :                       flags |= 4;
     351           0 :                       cp++;
     352             :                     }
     353           0 :                   else if (*cp == 'l')
     354             :                     {
     355           0 :                       flags += 8;
     356           0 :                       cp++;
     357             :                     }
     358           0 :                   else if (*cp == 'j')
     359             :                     {
     360             :                       if (sizeof (intmax_t) > sizeof (long))
     361             :                         {
     362             :                           /* intmax_t = long long */
     363             :                           flags += 16;
     364             :                         }
     365             :                       else if (sizeof (intmax_t) > sizeof (int))
     366             :                         {
     367             :                           /* intmax_t = long */
     368           0 :                           flags += 8;
     369             :                         }
     370           0 :                       cp++;
     371             :                     }
     372           0 :                   else if (*cp == 'z' || *cp == 'Z')
     373             :                     {
     374             :                       /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
     375             :                          because the warning facility in gcc-2.95.2 understands
     376             :                          only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784).  */
     377             :                       if (sizeof (size_t) > sizeof (long))
     378             :                         {
     379             :                           /* size_t = long long */
     380             :                           flags += 16;
     381             :                         }
     382             :                       else if (sizeof (size_t) > sizeof (int))
     383             :                         {
     384             :                           /* size_t = long */
     385           0 :                           flags += 8;
     386             :                         }
     387           0 :                       cp++;
     388             :                     }
     389           0 :                   else if (*cp == 't')
     390             :                     {
     391             :                       if (sizeof (ptrdiff_t) > sizeof (long))
     392             :                         {
     393             :                           /* ptrdiff_t = long long */
     394             :                           flags += 16;
     395             :                         }
     396             :                       else if (sizeof (ptrdiff_t) > sizeof (int))
     397             :                         {
     398             :                           /* ptrdiff_t = long */
     399           0 :                           flags += 8;
     400             :                         }
     401           0 :                       cp++;
     402             :                     }
     403             : #if defined __APPLE__ && defined __MACH__
     404             :                   /* On Mac OS X 10.3, PRIdMAX is defined as "qd".
     405             :                      We cannot change it to "lld" because PRIdMAX must also
     406             :                      be understood by the system's printf routines.  */
     407             :                   else if (*cp == 'q')
     408             :                     {
     409             :                       if (64 / 8 > sizeof (long))
     410             :                         {
     411             :                           /* int64_t = long long */
     412             :                           flags += 16;
     413             :                         }
     414             :                       else
     415             :                         {
     416             :                           /* int64_t = long */
     417             :                           flags += 8;
     418             :                         }
     419             :                       cp++;
     420             :                     }
     421             : #endif
     422             : #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
     423             :                   /* On native Windows, PRIdMAX is defined as "I64d".
     424             :                      We cannot change it to "lld" because PRIdMAX must also
     425             :                      be understood by the system's printf routines.  */
     426             :                   else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4')
     427             :                     {
     428             :                       if (64 / 8 > sizeof (long))
     429             :                         {
     430             :                           /* __int64 = long long */
     431             :                           flags += 16;
     432             :                         }
     433             :                       else
     434             :                         {
     435             :                           /* __int64 = long */
     436             :                           flags += 8;
     437             :                         }
     438             :                       cp += 3;
     439             :                     }
     440             : #endif
     441             :                   else
     442           0 :                     break;
     443           0 :                 }
     444             : 
     445             :               /* Read the conversion character.  */
     446           0 :               c = *cp++;
     447           0 :               switch (c)
     448             :                 {
     449             :                 case 'd': case 'i':
     450             : #if HAVE_LONG_LONG_INT
     451             :                   /* If 'long long' exists and is larger than 'long':  */
     452           0 :                   if (flags >= 16 || (flags & 4))
     453           0 :                     type = TYPE_LONGLONGINT;
     454             :                   else
     455             : #endif
     456             :                   /* If 'long long' exists and is the same as 'long', we parse
     457             :                      "lld" into TYPE_LONGINT.  */
     458           0 :                   if (flags >= 8)
     459           0 :                     type = TYPE_LONGINT;
     460           0 :                   else if (flags & 2)
     461           0 :                     type = TYPE_SCHAR;
     462           0 :                   else if (flags & 1)
     463           0 :                     type = TYPE_SHORT;
     464             :                   else
     465           0 :                     type = TYPE_INT;
     466           0 :                   break;
     467             :                 case 'o': case 'u': case 'x': case 'X':
     468             : #if HAVE_LONG_LONG_INT
     469             :                   /* If 'long long' exists and is larger than 'long':  */
     470           0 :                   if (flags >= 16 || (flags & 4))
     471           0 :                     type = TYPE_ULONGLONGINT;
     472             :                   else
     473             : #endif
     474             :                   /* If 'unsigned long long' exists and is the same as
     475             :                      'unsigned long', we parse "llu" into TYPE_ULONGINT.  */
     476           0 :                   if (flags >= 8)
     477           0 :                     type = TYPE_ULONGINT;
     478           0 :                   else if (flags & 2)
     479           0 :                     type = TYPE_UCHAR;
     480           0 :                   else if (flags & 1)
     481           0 :                     type = TYPE_USHORT;
     482             :                   else
     483           0 :                     type = TYPE_UINT;
     484           0 :                   break;
     485             :                 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
     486             :                 case 'a': case 'A':
     487           0 :                   if (flags >= 16 || (flags & 4))
     488           0 :                     type = TYPE_LONGDOUBLE;
     489             :                   else
     490           0 :                     type = TYPE_DOUBLE;
     491           0 :                   break;
     492             :                 case 'c':
     493           0 :                   if (flags >= 8)
     494             : #if HAVE_WINT_T
     495           0 :                     type = TYPE_WIDE_CHAR;
     496             : #else
     497             :                     goto error;
     498             : #endif
     499             :                   else
     500           0 :                     type = TYPE_CHAR;
     501           0 :                   break;
     502             : #if HAVE_WINT_T
     503             :                 case 'C':
     504           0 :                   type = TYPE_WIDE_CHAR;
     505           0 :                   c = 'c';
     506           0 :                   break;
     507             : #endif
     508             :                 case 's':
     509           0 :                   if (flags >= 8)
     510             : #if HAVE_WCHAR_T
     511           0 :                     type = TYPE_WIDE_STRING;
     512             : #else
     513             :                     goto error;
     514             : #endif
     515             :                   else
     516           0 :                     type = TYPE_STRING;
     517           0 :                   break;
     518             : #if HAVE_WCHAR_T
     519             :                 case 'S':
     520           0 :                   type = TYPE_WIDE_STRING;
     521           0 :                   c = 's';
     522           0 :                   break;
     523             : #endif
     524             :                 case 'p':
     525           0 :                   type = TYPE_POINTER;
     526           0 :                   break;
     527             :                 case 'n':
     528             : #if HAVE_LONG_LONG_INT
     529             :                   /* If 'long long' exists and is larger than 'long':  */
     530           0 :                   if (flags >= 16 || (flags & 4))
     531           0 :                     type = TYPE_COUNT_LONGLONGINT_POINTER;
     532             :                   else
     533             : #endif
     534             :                   /* If 'long long' exists and is the same as 'long', we parse
     535             :                      "lln" into TYPE_COUNT_LONGINT_POINTER.  */
     536           0 :                   if (flags >= 8)
     537           0 :                     type = TYPE_COUNT_LONGINT_POINTER;
     538           0 :                   else if (flags & 2)
     539           0 :                     type = TYPE_COUNT_SCHAR_POINTER;
     540           0 :                   else if (flags & 1)
     541           0 :                     type = TYPE_COUNT_SHORT_POINTER;
     542             :                   else
     543           0 :                     type = TYPE_COUNT_INT_POINTER;
     544           0 :                   break;
     545             : #if ENABLE_UNISTDIO
     546             :                 /* The unistdio extensions.  */
     547             :                 case 'U':
     548             :                   if (flags >= 16)
     549             :                     type = TYPE_U32_STRING;
     550             :                   else if (flags >= 8)
     551             :                     type = TYPE_U16_STRING;
     552             :                   else
     553             :                     type = TYPE_U8_STRING;
     554             :                   break;
     555             : #endif
     556             :                 case '%':
     557           0 :                   type = TYPE_NONE;
     558           0 :                   break;
     559             :                 default:
     560             :                   /* Unknown conversion character.  */
     561           0 :                   goto error;
     562             :                 }
     563             :             }
     564             : 
     565           0 :             if (type != TYPE_NONE)
     566             :               {
     567           0 :                 dp->arg_index = arg_index;
     568           0 :                 if (dp->arg_index == ARG_NONE)
     569             :                   {
     570           0 :                     dp->arg_index = arg_posn++;
     571           0 :                     if (dp->arg_index == ARG_NONE)
     572             :                       /* arg_posn wrapped around.  */
     573           0 :                       goto error;
     574             :                   }
     575           0 :                 REGISTER_ARG (dp->arg_index, type);
     576             :               }
     577           0 :             dp->conversion = c;
     578           0 :             dp->dir_end = cp;
     579             :           }
     580             : 
     581           0 :           d->count++;
     582           0 :           if (d->count >= d_allocated)
     583             :             {
     584             :               size_t memory_size;
     585             :               DIRECTIVE *memory;
     586             : 
     587           0 :               d_allocated = xtimes (d_allocated, 2);
     588           0 :               memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
     589           0 :               if (size_overflow_p (memory_size))
     590             :                 /* Overflow, would lead to out of memory.  */
     591           0 :                 goto out_of_memory;
     592           0 :               memory = (DIRECTIVE *) (d->dir != d->direct_alloc_dir
     593           0 :                                       ? realloc (d->dir, memory_size)
     594             :                                       : malloc (memory_size));
     595           0 :               if (memory == NULL)
     596             :                 /* Out of memory.  */
     597           0 :                 goto out_of_memory;
     598           0 :               if (d->dir == d->direct_alloc_dir)
     599           0 :                 memcpy (memory, d->dir, d->count * sizeof (DIRECTIVE));
     600           0 :               d->dir = memory;
     601             :             }
     602             :         }
     603             : #if CHAR_T_ONLY_ASCII
     604             :       else if (!c_isascii (c))
     605             :         {
     606             :           /* Non-ASCII character.  Not supported.  */
     607             :           goto error;
     608             :         }
     609             : #endif
     610             :     }
     611           0 :   d->dir[d->count].dir_start = cp;
     612             : 
     613           0 :   d->max_width_length = max_width_length;
     614           0 :   d->max_precision_length = max_precision_length;
     615           0 :   return 0;
     616             : 
     617             : error:
     618           0 :   if (a->arg != a->direct_alloc_arg)
     619           0 :     free (a->arg);
     620           0 :   if (d->dir != d->direct_alloc_dir)
     621           0 :     free (d->dir);
     622           0 :   errno = EINVAL;
     623           0 :   return -1;
     624             : 
     625             : out_of_memory:
     626           0 :   if (a->arg != a->direct_alloc_arg)
     627           0 :     free (a->arg);
     628           0 :   if (d->dir != d->direct_alloc_dir)
     629           0 :     free (d->dir);
     630           0 :   errno = ENOMEM;
     631           0 :   return -1;
     632             : }
     633             : 
     634             : #undef PRINTF_PARSE
     635             : #undef DIRECTIVES
     636             : #undef DIRECTIVE
     637             : #undef CHAR_T_ONLY_ASCII
     638             : #undef CHAR_T

Generated by: LCOV version 1.10