Blame stdio-common/printf-parse.h

Packit 6c4009
/* Internal header for parsing printf format strings.
Packit 6c4009
   Copyright (C) 1995-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of th GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <printf.h>
Packit 6c4009
#include <stdint.h>
Packit 6c4009
#include <stddef.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
#include <wchar.h>
Packit 6c4009
Packit 6c4009
Packit 6c4009
struct printf_spec
Packit 6c4009
  {
Packit 6c4009
    /* Information parsed from the format spec.  */
Packit 6c4009
    struct printf_info info;
Packit 6c4009
Packit 6c4009
    /* Pointers into the format string for the end of this format
Packit 6c4009
       spec and the next (or to the end of the string if no more).  */
Packit 6c4009
    const UCHAR_T *end_of_fmt, *next_fmt;
Packit 6c4009
Packit 6c4009
    /* Position of arguments for precision and width, or -1 if `info' has
Packit 6c4009
       the constant value.  */
Packit 6c4009
    int prec_arg, width_arg;
Packit 6c4009
Packit 6c4009
    int data_arg;		/* Position of data argument.  */
Packit 6c4009
    int data_arg_type;		/* Type of first argument.  */
Packit 6c4009
    /* Number of arguments consumed by this format specifier.  */
Packit 6c4009
    size_t ndata_args;
Packit 6c4009
    /* Size of the parameter for PA_USER type.  */
Packit 6c4009
    int size;
Packit 6c4009
  };
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* The various kinds off arguments that can be passed to printf.  */
Packit 6c4009
union printf_arg
Packit 6c4009
  {
Packit 6c4009
    wchar_t pa_wchar;
Packit 6c4009
    int pa_int;
Packit 6c4009
    long int pa_long_int;
Packit 6c4009
    long long int pa_long_long_int;
Packit 6c4009
    unsigned int pa_u_int;
Packit 6c4009
    unsigned long int pa_u_long_int;
Packit 6c4009
    unsigned long long int pa_u_long_long_int;
Packit 6c4009
    double pa_double;
Packit 6c4009
    long double pa_long_double;
Packit 6c4009
    const char *pa_string;
Packit 6c4009
    const wchar_t *pa_wstring;
Packit 6c4009
    void *pa_pointer;
Packit 6c4009
    void *pa_user;
Packit 6c4009
  };
Packit 6c4009
Packit 6c4009
Packit 6c4009
#ifndef DONT_NEED_READ_INT
Packit 6c4009
/* Read a simple integer from a string and update the string pointer.
Packit 6c4009
   It is assumed that the first character is a digit.  */
Packit 6c4009
static int
Packit 6c4009
read_int (const UCHAR_T * *pstr)
Packit 6c4009
{
Packit 6c4009
  int retval = **pstr - L_('0');
Packit 6c4009
Packit 6c4009
  while (ISDIGIT (*++(*pstr)))
Packit 6c4009
    if (retval >= 0)
Packit 6c4009
      {
Packit 6c4009
	if (INT_MAX / 10 < retval)
Packit 6c4009
	  retval = -1;
Packit 6c4009
	else
Packit 6c4009
	  {
Packit 6c4009
	    int digit = **pstr - L_('0');
Packit 6c4009
Packit 6c4009
	    retval *= 10;
Packit 6c4009
	    if (INT_MAX - digit < retval)
Packit 6c4009
	      retval = -1;
Packit 6c4009
	    else
Packit 6c4009
	      retval += digit;
Packit 6c4009
	  }
Packit 6c4009
      }
Packit 6c4009
Packit 6c4009
  return retval;
Packit 6c4009
}
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* These are defined in reg-printf.c.  */
Packit 6c4009
extern printf_arginfo_size_function **__printf_arginfo_table attribute_hidden;
Packit 6c4009
extern printf_function **__printf_function_table attribute_hidden;
Packit 6c4009
extern printf_va_arg_function **__printf_va_arg_table attribute_hidden;
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Find the next spec in FORMAT, or the end of the string.  Returns
Packit 6c4009
   a pointer into FORMAT, to a '%' or a '\0'.  */
Packit 6c4009
__extern_always_inline const unsigned char *
Packit 6c4009
__find_specmb (const unsigned char *format)
Packit 6c4009
{
Packit 6c4009
  return (const unsigned char *) __strchrnul ((const char *) format, '%');
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
__extern_always_inline const unsigned int *
Packit 6c4009
__find_specwc (const unsigned int *format)
Packit 6c4009
{
Packit 6c4009
  return (const unsigned int *) __wcschrnul ((const wchar_t *) format, L'%');
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* FORMAT must point to a '%' at the beginning of a spec.  Fills in *SPEC
Packit 6c4009
   with the parsed details.  POSN is the number of arguments already
Packit 6c4009
   consumed.  At most MAXTYPES - POSN types are filled in TYPES.  Return
Packit 6c4009
   the number of args consumed by this spec; *MAX_REF_ARG is updated so it
Packit 6c4009
   remains the highest argument index used.  */
Packit 6c4009
extern size_t __parse_one_specmb (const unsigned char *format, size_t posn,
Packit 6c4009
				  struct printf_spec *spec,
Packit 6c4009
				  size_t *max_ref_arg) attribute_hidden;
Packit 6c4009
Packit 6c4009
extern size_t __parse_one_specwc (const unsigned int *format, size_t posn,
Packit 6c4009
				  struct printf_spec *spec,
Packit 6c4009
				  size_t *max_ref_arg) attribute_hidden;
Packit 6c4009
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* This variable is defined in reg-modifier.c.  */
Packit 6c4009
struct printf_modifier_record;
Packit 6c4009
extern struct printf_modifier_record **__printf_modifier_table
Packit 6c4009
     attribute_hidden;
Packit 6c4009
Packit 6c4009
/* Handle registered modifiers.  */
Packit 6c4009
extern int __handle_registered_modifier_mb (const unsigned char **format,
Packit 6c4009
					    struct printf_info *info)
Packit 6c4009
     attribute_hidden;
Packit 6c4009
extern int __handle_registered_modifier_wc (const unsigned int **format,
Packit 6c4009
					    struct printf_info *info)
Packit 6c4009
     attribute_hidden;