Back to index

glibc  2.9
printf-prs.c
Go to the documentation of this file.
00001 /* Copyright (C) 1991, 1992, 1995, 1996, 1999, 2000, 2002, 2003, 2004, 2005,
00002    2007 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <stdio.h>
00021 #include <printf.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <wchar.h>
00025 #include <sys/param.h>
00026 
00027 #include "../locale/localeinfo.h"
00028 
00029 #ifndef COMPILE_WPRINTF
00030 # define CHAR_T             char
00031 # define UCHAR_T     unsigned char
00032 # define INT_T              int
00033 # define L_(Str)     Str
00034 # define ISDIGIT(Ch) isdigit (Ch)
00035 # define ISASCII(Ch) isascii (Ch)
00036 # define MBRLEN(Cp, L, St) __mbrlen (Cp, L, St)
00037 
00038 # define PUT(F, S, N)       _IO_sputn (F, S, N)
00039 # define PAD(Padchar)                                                       \
00040   if (width > 0)                                                     \
00041     done += INTUSE(_IO_padn) (s, Padchar, width)
00042 #else
00043 # define vfprintf    vfwprintf
00044 # define CHAR_T             wchar_t
00045 # define UCHAR_T     uwchar_t
00046 # define INT_T              wint_t
00047 # define L_(Str)     L##Str
00048 # define ISDIGIT(Ch) iswdigit (Ch)
00049 
00050 # define PUT(F, S, N)       _IO_sputn (F, S, N)
00051 # define PAD(Padchar)                                                       \
00052   if (width > 0)                                                     \
00053     done += _IO_wpadn (s, Padchar, width)
00054 #endif
00055 
00056 #define DONT_NEED_READ_INT
00057 #include "printf-parse.h"
00058 
00059 
00060 size_t
00061 parse_printf_format (fmt, n, argtypes)
00062       const char *fmt;
00063       size_t n;
00064       int *argtypes;
00065 {
00066   size_t nargs;                    /* Number of arguments.  */
00067   size_t max_ref_arg;              /* Highest index used in a positional arg.  */
00068   struct printf_spec spec;
00069   const unsigned char *f = (const unsigned char *) fmt;
00070 
00071   nargs = 0;
00072   max_ref_arg = 0;
00073 
00074   /* Search for format specifications.  */
00075   for (f = __find_specmb (f); *f != '\0'; f = spec.next_fmt)
00076     {
00077       /* Parse this spec.  */
00078       nargs += __parse_one_specmb (f, nargs, &spec, &max_ref_arg);
00079 
00080       /* If the width is determined by an argument this is an int.  */
00081       if (spec.width_arg != -1 && (size_t) spec.width_arg < n)
00082        argtypes[spec.width_arg] = PA_INT;
00083 
00084       /* If the precision is determined by an argument this is an int.  */
00085       if (spec.prec_arg != -1 && (size_t) spec.prec_arg < n)
00086        argtypes[spec.prec_arg] = PA_INT;
00087 
00088       if ((size_t) spec.data_arg < n)
00089        switch (spec.ndata_args)
00090          {
00091          case 0:            /* No arguments.  */
00092            break;
00093          case 1:            /* One argument; we already have the type.  */
00094            argtypes[spec.data_arg] = spec.data_arg_type;
00095            break;
00096          default:
00097            /* We have more than one argument for this format spec.  We must
00098                call the arginfo function again to determine all the types.  */
00099            (void) (*__printf_arginfo_table[spec.info.spec])
00100              (&spec.info, n - spec.data_arg, &argtypes[spec.data_arg]);
00101            break;
00102          }
00103     }
00104 
00105   return MAX (nargs, max_ref_arg);
00106 }