(root)/
glibc-2.38/
stdio-common/
printf-prs.c
       1  /* Copyright (C) 1991-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library 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 GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <stdio.h>
      19  #include <printf.h>
      20  #include <stdlib.h>
      21  #include <string.h>
      22  #include <wchar.h>
      23  #include <sys/param.h>
      24  #include <printf.h>
      25  
      26  #include "../locale/localeinfo.h"
      27  
      28  #ifndef COMPILE_WPRINTF
      29  # define CHAR_T		char
      30  # define UCHAR_T	unsigned char
      31  # define INT_T		int
      32  # define L_(Str)	Str
      33  # define ISDIGIT(Ch)	isdigit (Ch)
      34  # define ISASCII(Ch)	isascii (Ch)
      35  # define MBRLEN(Cp, L, St) __mbrlen (Cp, L, St)
      36  
      37  # define PUT(F, S, N)	_IO_sputn (F, S, N)
      38  # define PAD(Padchar)							      \
      39    if (width > 0)							      \
      40      done += _IO_padn (s, Padchar, width)
      41  #else
      42  # define vfprintf	vfwprintf
      43  # define CHAR_T		wchar_t
      44  # define UCHAR_T	uwchar_t
      45  # define INT_T		wint_t
      46  # define L_(Str)	L##Str
      47  # define ISDIGIT(Ch)	iswdigit (Ch)
      48  
      49  # define PUT(F, S, N)	_IO_sputn (F, S, N)
      50  # define PAD(Padchar)							      \
      51    if (width > 0)							      \
      52      done += _IO_wpadn (s, Padchar, width)
      53  #endif
      54  
      55  #define DONT_NEED_READ_INT
      56  #include "printf-parse.h"
      57  
      58  
      59  size_t
      60  parse_printf_format (const char *fmt, size_t n, int *argtypes)
      61  {
      62    size_t nargs;			/* Number of arguments.  */
      63    size_t max_ref_arg;		/* Highest index used in a positional arg.  */
      64    struct printf_spec spec;
      65    const unsigned char *f = (const unsigned char *) fmt;
      66    bool failed;
      67  
      68    nargs = 0;
      69    max_ref_arg = 0;
      70  
      71    /* Search for format specifications.  */
      72    for (f = __find_specmb (f); *f != '\0'; f = spec.next_fmt)
      73      {
      74        /* Parse this spec.  */
      75        nargs += __parse_one_specmb (f, nargs, &spec, &max_ref_arg, &failed);
      76  
      77        /* If the width is determined by an argument, it is an int.  */
      78        if (spec.width_arg != -1 && (size_t) spec.width_arg < n)
      79  	argtypes[spec.width_arg] = PA_INT;
      80  
      81        /* If the precision is determined by an argument, it is an int.  */
      82        if (spec.prec_arg != -1 && (size_t) spec.prec_arg < n)
      83  	argtypes[spec.prec_arg] = PA_INT;
      84  
      85        if ((size_t) spec.data_arg < n)
      86  	switch (spec.ndata_args)
      87  	  {
      88  	  case 0:		/* No arguments.  */
      89  	    break;
      90  	  case 1:		/* One argument; we already have the type.  */
      91  	    argtypes[spec.data_arg] = spec.data_arg_type;
      92  	    break;
      93  	  default:
      94  	    /* We have more than one argument for this format spec.  We must
      95                 call the arginfo function again to determine all the types.  */
      96  	    (void) (*__printf_arginfo_table[spec.info.spec])
      97  	      (&spec.info, n - spec.data_arg, &argtypes[spec.data_arg],
      98  	       &spec.size);
      99  	    break;
     100  	  }
     101      }
     102  
     103    return MAX (nargs, max_ref_arg);
     104  }