mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-10-28 23:34:53 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			106 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Copyright (C) 1991-2014 Free Software Foundation, Inc.
 | |
|    This file is part of the GNU C Library.
 | |
| 
 | |
|    The GNU C Library is free software; you can redistribute it and/or
 | |
|    modify it under the terms of the GNU Lesser General Public
 | |
|    License as published by the Free Software Foundation; either
 | |
|    version 2.1 of the License, or (at your option) any later version.
 | |
| 
 | |
|    The GNU C Library is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|    Lesser General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU Lesser General Public
 | |
|    License along with the GNU C Library; if not, see
 | |
|    <http://www.gnu.org/licenses/>.  */
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <printf.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <wchar.h>
 | |
| #include <sys/param.h>
 | |
| 
 | |
| #include "../locale/localeinfo.h"
 | |
| 
 | |
| #ifndef COMPILE_WPRINTF
 | |
| # define CHAR_T		char
 | |
| # define UCHAR_T	unsigned char
 | |
| # define INT_T		int
 | |
| # define L_(Str)	Str
 | |
| # define ISDIGIT(Ch)	isdigit (Ch)
 | |
| # define ISASCII(Ch)	isascii (Ch)
 | |
| # define MBRLEN(Cp, L, St) __mbrlen (Cp, L, St)
 | |
| 
 | |
| # define PUT(F, S, N)	_IO_sputn (F, S, N)
 | |
| # define PAD(Padchar)							      \
 | |
|   if (width > 0)							      \
 | |
|     done += _IO_padn (s, Padchar, width)
 | |
| #else
 | |
| # define vfprintf	vfwprintf
 | |
| # define CHAR_T		wchar_t
 | |
| # define UCHAR_T	uwchar_t
 | |
| # define INT_T		wint_t
 | |
| # define L_(Str)	L##Str
 | |
| # define ISDIGIT(Ch)	iswdigit (Ch)
 | |
| 
 | |
| # define PUT(F, S, N)	_IO_sputn (F, S, N)
 | |
| # define PAD(Padchar)							      \
 | |
|   if (width > 0)							      \
 | |
|     done += _IO_wpadn (s, Padchar, width)
 | |
| #endif
 | |
| 
 | |
| #define DONT_NEED_READ_INT
 | |
| #include "printf-parse.h"
 | |
| 
 | |
| 
 | |
| size_t
 | |
| parse_printf_format (fmt, n, argtypes)
 | |
|       const char *fmt;
 | |
|       size_t n;
 | |
|       int *argtypes;
 | |
| {
 | |
|   size_t nargs;			/* Number of arguments.  */
 | |
|   size_t max_ref_arg;		/* Highest index used in a positional arg.  */
 | |
|   struct printf_spec spec;
 | |
|   const unsigned char *f = (const unsigned char *) fmt;
 | |
| 
 | |
|   nargs = 0;
 | |
|   max_ref_arg = 0;
 | |
| 
 | |
|   /* Search for format specifications.  */
 | |
|   for (f = __find_specmb (f); *f != '\0'; f = spec.next_fmt)
 | |
|     {
 | |
|       /* Parse this spec.  */
 | |
|       nargs += __parse_one_specmb (f, nargs, &spec, &max_ref_arg);
 | |
| 
 | |
|       /* If the width is determined by an argument this is an int.  */
 | |
|       if (spec.width_arg != -1 && (size_t) spec.width_arg < n)
 | |
| 	argtypes[spec.width_arg] = PA_INT;
 | |
| 
 | |
|       /* If the precision is determined by an argument this is an int.  */
 | |
|       if (spec.prec_arg != -1 && (size_t) spec.prec_arg < n)
 | |
| 	argtypes[spec.prec_arg] = PA_INT;
 | |
| 
 | |
|       if ((size_t) spec.data_arg < n)
 | |
| 	switch (spec.ndata_args)
 | |
| 	  {
 | |
| 	  case 0:		/* No arguments.  */
 | |
| 	    break;
 | |
| 	  case 1:		/* One argument; we already have the type.  */
 | |
| 	    argtypes[spec.data_arg] = spec.data_arg_type;
 | |
| 	    break;
 | |
| 	  default:
 | |
| 	    /* We have more than one argument for this format spec.  We must
 | |
|                call the arginfo function again to determine all the types.  */
 | |
| 	    (void) (*__printf_arginfo_table[spec.info.spec])
 | |
| 	      (&spec.info, n - spec.data_arg, &argtypes[spec.data_arg],
 | |
| 	       &spec.size);
 | |
| 	    break;
 | |
| 	  }
 | |
|     }
 | |
| 
 | |
|   return MAX (nargs, max_ref_arg);
 | |
| }
 |