Coverage Report

Created: 2025-07-11 06:31

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