printf-parse.c   printf-parse.c 
/* Formatted output to strings. /* Formatted output to strings.
Copyright (C) 1999-2000, 2002-2003, 2006-2010 Free Software Foundation, Inc. Copyright (C) 1999-2000, 2002-2003, 2006-2014 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, with this program; if not, see <http://www.gnu.org/licenses/>. */
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* This file can be parametrized with the following macros: /* This file can be parametrized with the following macros:
CHAR_T The element type of the format string. CHAR_T The element type of the format string.
CHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters CHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
in the format string are ASCII. in the format string are ASCII.
DIRECTIVE Structure denoting a format directive. DIRECTIVE Structure denoting a format directive.
Depends on CHAR_T. Depends on CHAR_T.
DIRECTIVES Structure denoting the set of format directives of a DIRECTIVES Structure denoting the set of format directives of a
format string. Depends on CHAR_T. format string. Depends on CHAR_T.
PRINTF_PARSE Function that parses a format string. PRINTF_PARSE Function that parses a format string.
skipping to change at line 66 skipping to change at line 65
# if HAVE_INTTYPES_H_WITH_UINTMAX # if HAVE_INTTYPES_H_WITH_UINTMAX
# include <inttypes.h> # include <inttypes.h>
# endif # endif
#else #else
# include <stdint.h> # include <stdint.h>
#endif #endif
/* malloc(), realloc(), free(). */ /* malloc(), realloc(), free(). */
#include <stdlib.h> #include <stdlib.h>
/* memcpy(). */
#include <string.h>
/* errno. */ /* errno. */
#include <errno.h> #include <errno.h>
/* Checked size_t computations. */ /* Checked size_t computations. */
#include "xsize.h" #include "xsize.h"
#if CHAR_T_ONLY_ASCII #if CHAR_T_ONLY_ASCII
/* c_isascii(). */ /* c_isascii(). */
# include "c-ctype.h" # include "c-ctype.h"
#endif #endif
#ifdef STATIC #ifdef STATIC
STATIC STATIC
#endif #endif
int int
PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
{ {
const CHAR_T *cp = format; /* pointer into format */ const CHAR_T *cp = format; /* pointer into format */
size_t arg_posn = 0; /* number of regular arguments consumed */ size_t arg_posn = 0; /* number of regular arguments consumed */
size_t d_allocated; /* allocated elements of d->dir */ size_t d_allocated; /* allocated elements of d->dir */
size_t a_allocated; /* allocated elements of a->arg */ size_t a_allocated; /* allocated elements of a->arg */
size_t max_width_length = 0; size_t max_width_length = 0;
size_t max_precision_length = 0; size_t max_precision_length = 0;
d->count = 0; d->count = 0;
d_allocated = 1; d_allocated = N_DIRECT_ALLOC_DIRECTIVES;
d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE)); d->dir = d->direct_alloc_dir;
if (d->dir == NULL)
/* Out of memory. */
goto out_of_memory_1;
a->count = 0; a->count = 0;
a_allocated = 0; a_allocated = N_DIRECT_ALLOC_ARGUMENTS;
a->arg = NULL; a->arg = a->direct_alloc_arg;
#define REGISTER_ARG(_index_,_type_) \ #define REGISTER_ARG(_index_,_type_) \
{ \ { \
size_t n = (_index_); \ size_t n = (_index_); \
if (n >= a_allocated) \ if (n >= a_allocated) \
{ \ { \
size_t memory_size; \ size_t memory_size; \
argument *memory; \ argument *memory; \
\ \
a_allocated = xtimes (a_allocated, 2); \ a_allocated = xtimes (a_allocated, 2); \
if (a_allocated <= n) \ if (a_allocated <= n) \
a_allocated = xsum (n, 1); \ a_allocated = xsum (n, 1); \
memory_size = xtimes (a_allocated, sizeof (argument)); \ memory_size = xtimes (a_allocated, sizeof (argument)); \
if (size_overflow_p (memory_size)) \ if (size_overflow_p (memory_size)) \
/* Overflow, would lead to out of memory. */ \ /* Overflow, would lead to out of memory. */ \
goto out_of_memory; \ goto out_of_memory; \
memory = (argument *) (a->arg \ memory = (argument *) (a->arg != a->direct_alloc_arg \
? realloc (a->arg, memory_size) \ ? realloc (a->arg, memory_size) \
: malloc (memory_size)); \ : malloc (memory_size)); \
if (memory == NULL) \ if (memory == NULL) \
/* Out of memory. */ \ /* Out of memory. */ \
goto out_of_memory; \ goto out_of_memory; \
if (a->arg == a->direct_alloc_arg) \
memcpy (memory, a->arg, a->count * sizeof (argument)); \
a->arg = memory; \ a->arg = memory; \
} \ } \
while (a->count <= n) \ while (a->count <= n) \
a->arg[a->count++].type = TYPE_NONE; \ a->arg[a->count++].type = TYPE_NONE; \
if (a->arg[n].type == TYPE_NONE) \ if (a->arg[n].type == TYPE_NONE) \
a->arg[n].type = (_type_); \ a->arg[n].type = (_type_); \
else if (a->arg[n].type != (_type_)) \ else if (a->arg[n].type != (_type_)) \
/* Ambiguous type for positional argument. */ \ /* Ambiguous type for positional argument. */ \
goto error; \ goto error; \
} }
skipping to change at line 209 skipping to change at line 210
else if (*cp == '#') else if (*cp == '#')
{ {
dp->flags |= FLAG_ALT; dp->flags |= FLAG_ALT;
cp++; cp++;
} }
else if (*cp == '0') else if (*cp == '0')
{ {
dp->flags |= FLAG_ZERO; dp->flags |= FLAG_ZERO;
cp++; cp++;
} }
#if __GLIBC__ >= 2 && !defined __UCLIBC__
else if (*cp == 'I')
{
dp->flags |= FLAG_LOCALIZED;
cp++;
}
#endif
else else
break; break;
} }
/* Parse the field width. */ /* Parse the field width. */
if (*cp == '*') if (*cp == '*')
{ {
dp->width_start = cp; dp->width_start = cp;
cp++; cp++;
dp->width_end = cp; dp->width_end = cp;
skipping to change at line 396 skipping to change at line 404
flags += 16; flags += 16;
} }
else if (sizeof (ptrdiff_t) > sizeof (int)) else if (sizeof (ptrdiff_t) > sizeof (int))
{ {
/* ptrdiff_t = long */ /* ptrdiff_t = long */
flags += 8; flags += 8;
} }
cp++; cp++;
} }
#if defined __APPLE__ && defined __MACH__ #if defined __APPLE__ && defined __MACH__
/* On MacOS X 10.3, PRIdMAX is defined as "qd". /* On Mac OS X 10.3, PRIdMAX is defined as "qd".
We cannot change it to "lld" because PRIdMAX must also We cannot change it to "lld" because PRIdMAX must also
be understood by the system's printf routines. */ be understood by the system's printf routines. */
else if (*cp == 'q') else if (*cp == 'q')
{ {
if (64 / 8 > sizeof (long)) if (64 / 8 > sizeof (long))
{ {
/* int64_t = long long */ /* int64_t = long long */
flags += 16; flags += 16;
} }
else else
{ {
/* int64_t = long */ /* int64_t = long */
flags += 8; flags += 8;
} }
cp++; cp++;
} }
#endif #endif
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
/* On native Win32, PRIdMAX is defined as "I64d". /* On native Windows, PRIdMAX is defined as "I64d".
We cannot change it to "lld" because PRIdMAX must also We cannot change it to "lld" because PRIdMAX must also
be understood by the system's printf routines. */ be understood by the system's printf routines. */
else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4') else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4')
{ {
if (64 / 8 > sizeof (long)) if (64 / 8 > sizeof (long))
{ {
/* __int64 = long long */ /* __int64 = long long */
flags += 16; flags += 16;
} }
else else
skipping to change at line 584 skipping to change at line 592
if (d->count >= d_allocated) if (d->count >= d_allocated)
{ {
size_t memory_size; size_t memory_size;
DIRECTIVE *memory; DIRECTIVE *memory;
d_allocated = xtimes (d_allocated, 2); d_allocated = xtimes (d_allocated, 2);
memory_size = xtimes (d_allocated, sizeof (DIRECTIVE)); memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
if (size_overflow_p (memory_size)) if (size_overflow_p (memory_size))
/* Overflow, would lead to out of memory. */ /* Overflow, would lead to out of memory. */
goto out_of_memory; goto out_of_memory;
memory = (DIRECTIVE *) realloc (d->dir, memory_size); memory = (DIRECTIVE *) (d->dir != d->direct_alloc_dir
? realloc (d->dir, memory_size)
: malloc (memory_size));
if (memory == NULL) if (memory == NULL)
/* Out of memory. */ /* Out of memory. */
goto out_of_memory; goto out_of_memory;
if (d->dir == d->direct_alloc_dir)
memcpy (memory, d->dir, d->count * sizeof (DIRECTIVE));
d->dir = memory; d->dir = memory;
} }
} }
#if CHAR_T_ONLY_ASCII #if CHAR_T_ONLY_ASCII
else if (!c_isascii (c)) else if (!c_isascii (c))
{ {
/* Non-ASCII character. Not supported. */ /* Non-ASCII character. Not supported. */
goto error; goto error;
} }
#endif #endif
} }
d->dir[d->count].dir_start = cp; d->dir[d->count].dir_start = cp;
d->max_width_length = max_width_length; d->max_width_length = max_width_length;
d->max_precision_length = max_precision_length; d->max_precision_length = max_precision_length;
return 0; return 0;
error: error:
if (a->arg) if (a->arg != a->direct_alloc_arg)
free (a->arg); free (a->arg);
if (d->dir) if (d->dir != d->direct_alloc_dir)
free (d->dir); free (d->dir);
errno = EINVAL; errno = EINVAL;
return -1; return -1;
out_of_memory: out_of_memory:
if (a->arg) if (a->arg != a->direct_alloc_arg)
free (a->arg); free (a->arg);
if (d->dir) if (d->dir != d->direct_alloc_dir)
free (d->dir); free (d->dir);
out_of_memory_1:
errno = ENOMEM; errno = ENOMEM;
return -1; return -1;
} }
#undef PRINTF_PARSE #undef PRINTF_PARSE
#undef DIRECTIVES #undef DIRECTIVES
#undef DIRECTIVE #undef DIRECTIVE
#undef CHAR_T_ONLY_ASCII #undef CHAR_T_ONLY_ASCII
#undef CHAR_T #undef CHAR_T
 End of changes. 19 change blocks. 
22 lines changed or deleted 33 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/