(root)/
glibc-2.38/
stdio-common/
printf-parse.h
       1  /* Internal header for parsing printf format strings.
       2     Copyright (C) 1995-2023 Free Software Foundation, Inc.
       3     This file is part of th GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <printf.h>
      20  #include <stdint.h>
      21  #include <stddef.h>
      22  #include <string.h>
      23  #include <wchar.h>
      24  
      25  
      26  struct printf_spec
      27    {
      28      /* Information parsed from the format spec.  */
      29      struct printf_info info;
      30  
      31      /* Pointers into the format string for the end of this format
      32         spec and the next (or to the end of the string if no more).  */
      33      const UCHAR_T *end_of_fmt, *next_fmt;
      34  
      35      /* Position of arguments for precision and width, or -1 if `info' has
      36         the constant value.  */
      37      int prec_arg, width_arg;
      38  
      39      int data_arg;		/* Position of data argument.  */
      40      int data_arg_type;		/* Type of first argument.  */
      41      /* Number of arguments consumed by this format specifier.  */
      42      size_t ndata_args;
      43      /* Size of the parameter for PA_USER type.  */
      44      int size;
      45    };
      46  
      47  #ifndef DONT_NEED_READ_INT
      48  /* Read a simple integer from a string and update the string pointer.
      49     It is assumed that the first character is a digit.  */
      50  static int
      51  read_int (const UCHAR_T * *pstr)
      52  {
      53    int retval = **pstr - L_('0');
      54  
      55    while (ISDIGIT (*++(*pstr)))
      56      if (retval >= 0)
      57        {
      58  	if (INT_MAX / 10 < retval)
      59  	  retval = -1;
      60  	else
      61  	  {
      62  	    int digit = **pstr - L_('0');
      63  
      64  	    retval *= 10;
      65  	    if (INT_MAX - digit < retval)
      66  	      retval = -1;
      67  	    else
      68  	      retval += digit;
      69  	  }
      70        }
      71  
      72    return retval;
      73  }
      74  #endif
      75  
      76  
      77  /* Find the next spec in FORMAT, or the end of the string.  Returns
      78     a pointer into FORMAT, to a '%' or a '\0'.  */
      79  __extern_always_inline const unsigned char *
      80  __find_specmb (const unsigned char *format)
      81  {
      82    return (const unsigned char *) __strchrnul ((const char *) format, '%');
      83  }
      84  
      85  __extern_always_inline const unsigned int *
      86  __find_specwc (const unsigned int *format)
      87  {
      88    return (const unsigned int *) __wcschrnul ((const wchar_t *) format, L'%');
      89  }
      90  
      91  
      92  /* FORMAT must point to a '%' at the beginning of a spec.  Fills in *SPEC
      93     with the parsed details.  POSN is the number of arguments already
      94     consumed.  At most MAXTYPES - POSN types are filled in TYPES.  Return
      95     the number of args consumed by this spec; *MAX_REF_ARG is updated so it
      96     remains the highest argument index used.  *FAILED is set to indicate
      97     whether parsing failed and printf should return with an error status.  */
      98  extern size_t __parse_one_specmb (const unsigned char *format, size_t posn,
      99  				  struct printf_spec *spec,
     100  				  size_t *max_ref_arg,
     101  				  bool *failed) attribute_hidden;
     102  
     103  extern size_t __parse_one_specwc (const unsigned int *format, size_t posn,
     104  				  struct printf_spec *spec,
     105  				  size_t *max_ref_arg,
     106  				  bool *failed) attribute_hidden;
     107  
     108  
     109  
     110  /* This variable is defined in reg-modifier.c.  */
     111  struct printf_modifier_record;
     112  extern struct printf_modifier_record **__printf_modifier_table
     113       attribute_hidden;
     114  
     115  /* Handle registered modifiers.  */
     116  extern int __handle_registered_modifier_mb (const unsigned char **format,
     117  					    struct printf_info *info)
     118       attribute_hidden;
     119  extern int __handle_registered_modifier_wc (const unsigned int **format,
     120  					    struct printf_info *info)
     121       attribute_hidden;