Back to index

glibc  2.9
printf-parse.h
Go to the documentation of this file.
00001 /* Internal header for parsing printf format strings.
00002    Copyright (C) 1995-1999, 2000, 2002, 2003, 2007
00003    Free Software Foundation, Inc.
00004    This file is part of th GNU C Library.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <printf.h>
00022 #include <stdint.h>
00023 #include <stddef.h>
00024 #include <string.h>
00025 #include <wchar.h>
00026 
00027 
00028 struct printf_spec
00029   {
00030     /* Information parsed from the format spec.  */
00031     struct printf_info info;
00032 
00033     /* Pointers into the format string for the end of this format
00034        spec and the next (or to the end of the string if no more).  */
00035     const UCHAR_T *end_of_fmt, *next_fmt;
00036 
00037     /* Position of arguments for precision and width, or -1 if `info' has
00038        the constant value.  */
00039     int prec_arg, width_arg;
00040 
00041     int data_arg;           /* Position of data argument.  */
00042     int data_arg_type;             /* Type of first argument.  */
00043     /* Number of arguments consumed by this format specifier.  */
00044     size_t ndata_args;
00045   };
00046 
00047 
00048 /* The various kinds off arguments that can be passed to printf.  */
00049 union printf_arg
00050   {
00051     wchar_t pa_wchar;
00052     int pa_int;
00053     long int pa_long_int;
00054     long long int pa_long_long_int;
00055     unsigned int pa_u_int;
00056     unsigned long int pa_u_long_int;
00057     unsigned long long int pa_u_long_long_int;
00058     double pa_double;
00059     long double pa_long_double;
00060     const char *pa_string;
00061     const wchar_t *pa_wstring;
00062     void *pa_pointer;
00063   };
00064 
00065 
00066 #ifndef DONT_NEED_READ_INT
00067 /* Read a simple integer from a string and update the string pointer.
00068    It is assumed that the first character is a digit.  */
00069 static unsigned int
00070 read_int (const UCHAR_T * *pstr)
00071 {
00072   unsigned int retval = **pstr - L_('0');
00073 
00074   while (ISDIGIT (*++(*pstr)))
00075     {
00076       retval *= 10;
00077       retval += **pstr - L_('0');
00078     }
00079 
00080   return retval;
00081 }
00082 #endif
00083 
00084 
00085 /* These are defined in reg-printf.c.  */
00086 extern printf_arginfo_function **__printf_arginfo_table attribute_hidden;
00087 extern printf_function **__printf_function_table attribute_hidden;
00088 
00089 
00090 /* Find the next spec in FORMAT, or the end of the string.  Returns
00091    a pointer into FORMAT, to a '%' or a '\0'.  */
00092 __extern_always_inline const unsigned char *
00093 __find_specmb (const unsigned char *format)
00094 {
00095   return (const unsigned char *) __strchrnul ((const char *) format, '%');
00096 }
00097 
00098 __extern_always_inline const unsigned int *
00099 __find_specwc (const unsigned int *format)
00100 {
00101   return (const unsigned int *) __wcschrnul ((const wchar_t *) format, L'%');
00102 }
00103 
00104 
00105 /* FORMAT must point to a '%' at the beginning of a spec.  Fills in *SPEC
00106    with the parsed details.  POSN is the number of arguments already
00107    consumed.  At most MAXTYPES - POSN types are filled in TYPES.  Return
00108    the number of args consumed by this spec; *MAX_REF_ARG is updated so it
00109    remains the highest argument index used.  */
00110 extern size_t __parse_one_specmb (const unsigned char *format, size_t posn,
00111                               struct printf_spec *spec,
00112                               size_t *max_ref_arg) attribute_hidden;
00113 
00114 extern size_t __parse_one_specwc (const unsigned int *format, size_t posn,
00115                               struct printf_spec *spec,
00116                               size_t *max_ref_arg) attribute_hidden;