| lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 1 | /* Copyright (C) 1991-1993,1995-1999,2000,2001 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, write to the Free | 
|  | 16 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | 
|  | 17 | 02111-1307 USA.  */ | 
|  | 18 |  | 
|  | 19 | /* March 11, 2001         Manuel Novoa III | 
|  | 20 | * | 
|  | 21 | * Modified as appropriate for my new stdio lib. | 
|  | 22 | */ | 
|  | 23 |  | 
|  | 24 | #ifndef	_PRINTF_H | 
|  | 25 |  | 
|  | 26 | #define	_PRINTF_H	1 | 
|  | 27 | #include <features.h> | 
|  | 28 |  | 
|  | 29 | __BEGIN_DECLS | 
|  | 30 |  | 
|  | 31 | #define	__need_FILE | 
|  | 32 | #include <stdio.h> | 
|  | 33 | #define	__need_size_t | 
|  | 34 | #define __need_wchar_t | 
|  | 35 | #include <stddef.h> | 
|  | 36 |  | 
|  | 37 | /* WARNING -- This is definitely nonportable... but it seems to work | 
|  | 38 | * with gcc, which is currently the only "supported" compiler. | 
|  | 39 | * The library code uses bitmasks for space-efficiency (you can't | 
|  | 40 | * set/test multiple bitfields in one operation).  Unfortunatly, we | 
|  | 41 | * need to support bitfields since that's what glibc made visible to users. | 
|  | 42 | * So, we take | 
|  | 43 | * advantage of how gcc lays out bitfields to create an appropriate | 
|  | 44 | * mapping.  Inside uclibc (i.e. if _LIBC is defined) we access the | 
|  | 45 | * bitfields using bitmasks in a single flag variable. | 
|  | 46 | * | 
|  | 47 | * WARNING -- This may very well fail if built with -fpack-struct!!! | 
|  | 48 | * | 
|  | 49 | * TODO -- Add a validation test. | 
|  | 50 | * TODO -- Add an option to build in a shim translation function if | 
|  | 51 | *         the bitfield<->bitmask mapping fails. | 
|  | 52 | */ | 
|  | 53 | #include <endian.h> | 
|  | 54 |  | 
|  | 55 | struct printf_info { | 
|  | 56 | int prec;                     /* Precision.  */ | 
|  | 57 | int width;                    /* Width.  */ | 
|  | 58 | #ifdef __UCLIBC_HAS_WCHAR__ | 
|  | 59 | wchar_t spec;                 /* Format letter.  */ | 
|  | 60 | #else | 
|  | 61 | int spec; | 
|  | 62 | #endif | 
|  | 63 |  | 
|  | 64 | #ifndef _LIBC | 
|  | 65 |  | 
|  | 66 | #if __BYTE_ORDER == __LITTLE_ENDIAN | 
|  | 67 | unsigned int space:1;         /* Space flag.  */ | 
|  | 68 | unsigned int showsign:1;      /* + flag.  */ | 
|  | 69 | unsigned int extra:1;         /* For special use.  */ | 
|  | 70 | unsigned int left:1;          /* - flag.  */ | 
|  | 71 | unsigned int alt:1;           /* # flag.  */ | 
|  | 72 | unsigned int group:1;         /* ' flag.  */ | 
|  | 73 | unsigned int i18n:1;          /* I flag.  */ | 
|  | 74 | unsigned int wide:1;          /* Nonzero for wide character streams.  */ | 
|  | 75 | unsigned int is_char:1;       /* hh flag.  */ | 
|  | 76 | unsigned int is_short:1;      /* h flag.  */ | 
|  | 77 | unsigned int is_long:1;       /* l flag.  */ | 
|  | 78 | unsigned int is_long_double:1;/* L flag.  */ | 
|  | 79 | unsigned int __padding:20;    /* non-gnu: match _flags width of 32 bits */ | 
|  | 80 | #elif __BYTE_ORDER == __BIG_ENDIAN | 
|  | 81 | unsigned int __padding:20;    /* non-gnu: match _flags width of 32 bits */ | 
|  | 82 | unsigned int is_long_double:1;/* L flag.  */ | 
|  | 83 | unsigned int is_long:1;       /* l flag.  */ | 
|  | 84 | unsigned int is_short:1;      /* h flag.  */ | 
|  | 85 | unsigned int is_char:1;       /* hh flag.  */ | 
|  | 86 | unsigned int wide:1;          /* Nonzero for wide character streams.  */ | 
|  | 87 | unsigned int i18n:1;          /* I flag.  */ | 
|  | 88 | unsigned int group:1;         /* ' flag.  */ | 
|  | 89 | unsigned int alt:1;           /* # flag.  */ | 
|  | 90 | unsigned int left:1;          /* - flag.  */ | 
|  | 91 | unsigned int extra:1;         /* For special use.  */ | 
|  | 92 | unsigned int showsign:1;      /* + flag.  */ | 
|  | 93 | unsigned int space:1;         /* Space flag.  */ | 
|  | 94 | #else | 
|  | 95 | #error unsupported byte order! | 
|  | 96 | #endif | 
|  | 97 |  | 
|  | 98 | #else  /* _LIBC */ | 
|  | 99 |  | 
|  | 100 | uint32_t _flags;	/* non-gnu */ | 
|  | 101 | #define __PRINT_INFO_FLAG_space                 (1<<0) | 
|  | 102 | #define __PRINT_INFO_FLAG_showsign              (1<<1) | 
|  | 103 | #define __PRINT_INFO_FLAG_extra                 (1<<2) | 
|  | 104 | #define __PRINT_INFO_FLAG_left                  (1<<3) | 
|  | 105 | #define __PRINT_INFO_FLAG_alt                   (1<<4) | 
|  | 106 | #define __PRINT_INFO_FLAG_group                 (1<<5) | 
|  | 107 | #define __PRINT_INFO_FLAG_i18n                  (1<<6) | 
|  | 108 | #define __PRINT_INFO_FLAG_wide                  (1<<7) | 
|  | 109 |  | 
|  | 110 | #define __PRINT_INFO_FLAG_is_char               (1<<8) | 
|  | 111 | #define __PRINT_INFO_FLAG_is_short              (1<<9) | 
|  | 112 | #define __PRINT_INFO_FLAG_is_long               (1<<10) | 
|  | 113 | #define __PRINT_INFO_FLAG_is_long_double        (1<<11) | 
|  | 114 |  | 
|  | 115 | #define PRINT_INFO_FLAG_VAL(INFO_PTR,BITFIELD) \ | 
|  | 116 | ((INFO_PTR)->_flags & __PRINT_INFO_FLAG_##BITFIELD) | 
|  | 117 | #define PRINT_INFO_SET_FLAG(INFO_PTR,BITFIELD) \ | 
|  | 118 | ((INFO_PTR)->_flags |= __PRINT_INFO_FLAG_##BITFIELD) | 
|  | 119 | #define PRINT_INFO_CLR_FLAG(INFO_PTR,BITFIELD) \ | 
|  | 120 | ((INFO_PTR)->_flags &= ~__PRINT_INFO_FLAG_##BITFIELD) | 
|  | 121 | #define PRINT_INFO_SET_extra(INFO_PTR,VAL) \ | 
|  | 122 | ((INFO_PTR)->_flags |= (((INFO_PTR)->_flags & ~1) | ((VAL) & 1))) | 
|  | 123 |  | 
|  | 124 | #endif /* _LIBC */ | 
|  | 125 |  | 
|  | 126 | #ifdef __UCLIBC_HAS_WCHAR__ | 
|  | 127 | wchar_t pad;                  /* Padding character.  */ | 
|  | 128 | #else | 
|  | 129 | int pad; | 
|  | 130 | #endif | 
|  | 131 | }; | 
|  | 132 |  | 
|  | 133 |  | 
|  | 134 | /* Type of a printf specifier-handler function. | 
|  | 135 | STREAM is the FILE on which to write output. | 
|  | 136 | INFO gives information about the format specification. | 
|  | 137 | ARGS is a vector of pointers to the argument data; | 
|  | 138 | the number of pointers will be the number returned | 
|  | 139 | by the associated arginfo function for the same INFO. | 
|  | 140 |  | 
|  | 141 | The function should return the number of characters written, | 
|  | 142 | or -1 for errors.  */ | 
|  | 143 |  | 
|  | 144 | #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ | 
|  | 145 | typedef int (*printf_function) (FILE *__stream, | 
|  | 146 | __const struct printf_info *__info, | 
|  | 147 | __const void *__const *__args); | 
|  | 148 |  | 
|  | 149 | /* Type of a printf specifier-arginfo function. | 
|  | 150 | INFO gives information about the format specification. | 
|  | 151 | N, ARGTYPES, and return value are as for parse_printf_format.  */ | 
|  | 152 |  | 
|  | 153 | typedef int printf_arginfo_function (__const struct printf_info *__info, | 
|  | 154 | size_t __n, int *__argtypes); | 
|  | 155 |  | 
|  | 156 |  | 
|  | 157 | /* Register FUNC to be called to format SPEC specifiers; ARGINFO must be | 
|  | 158 | specified to determine how many arguments a SPEC conversion requires and | 
|  | 159 | what their types are.  */ | 
|  | 160 |  | 
|  | 161 | extern int register_printf_function (int __spec, printf_function __func, | 
|  | 162 | printf_arginfo_function __arginfo); | 
|  | 163 | #endif | 
|  | 164 |  | 
|  | 165 |  | 
|  | 166 | /* Parse FMT, and fill in N elements of ARGTYPES with the | 
|  | 167 | types needed for the conversions FMT specifies.  Returns | 
|  | 168 | the number of arguments required by FMT. | 
|  | 169 |  | 
|  | 170 | The ARGINFO function registered with a user-defined format is passed a | 
|  | 171 | `struct printf_info' describing the format spec being parsed.  A width | 
|  | 172 | or precision of INT_MIN means a `*' was used to indicate that the | 
|  | 173 | width/precision will come from an arg.  The function should fill in the | 
|  | 174 | array it is passed with the types of the arguments it wants, and return | 
|  | 175 | the number of arguments it wants.  */ | 
|  | 176 |  | 
|  | 177 | extern size_t parse_printf_format (__const char *__restrict __fmt, size_t __n, | 
|  | 178 | int *__restrict __argtypes) __THROW; | 
|  | 179 |  | 
|  | 180 |  | 
|  | 181 | /* Codes returned by `parse_printf_format' for basic types. | 
|  | 182 |  | 
|  | 183 | These values cover all the standard format specifications. | 
|  | 184 | Users can add new values after PA_LAST for their own types.  */ | 
|  | 185 |  | 
|  | 186 | /* WARNING -- The above is not entirely true, even for glibc. | 
|  | 187 | * As far as the library code is concerned, such args are treated | 
|  | 188 | * as 'your type' pointers if qualified by PA_FLAG_PTR.  If they | 
|  | 189 | * aren't qualified as pointers, I _think_ glibc just ignores them | 
|  | 190 | * and carries on.  I think it should be treated as an error. */ | 
|  | 191 |  | 
|  | 192 | enum {                          /* C type: */ | 
|  | 193 | PA_INT,                       /* int */ | 
|  | 194 | PA_CHAR,                      /* int, cast to char */ | 
|  | 195 | PA_WCHAR,                     /* wide char */ | 
|  | 196 | PA_STRING,                    /* const char *, a '\0'-terminated string */ | 
|  | 197 | PA_WSTRING,                   /* const wchar_t *, wide character string */ | 
|  | 198 | PA_POINTER,                   /* void * */ | 
|  | 199 | PA_FLOAT,                     /* float */ | 
|  | 200 | PA_DOUBLE,                    /* double */ | 
|  | 201 | __PA_NOARG,                   /* non-glibc -- signals non-arg width or prec */ | 
|  | 202 | PA_LAST | 
|  | 203 | }; | 
|  | 204 |  | 
|  | 205 | /* Flag bits that can be set in a type returned by `parse_printf_format'.  */ | 
|  | 206 | /* WARNING -- These differ in value from what glibc uses. */ | 
|  | 207 | #define PA_FLAG_MASK		(0xff00) | 
|  | 208 | #define __PA_FLAG_CHAR		(0x0100) /* non-gnu -- to deal with hh */ | 
|  | 209 | #define PA_FLAG_SHORT		(0x0200) | 
|  | 210 | #define PA_FLAG_LONG		(0x0400) | 
|  | 211 | #define PA_FLAG_LONG_LONG	(0x0800) | 
|  | 212 | #define PA_FLAG_LONG_DOUBLE	PA_FLAG_LONG_LONG | 
|  | 213 | #define PA_FLAG_PTR		(0x1000) /* TODO -- make dynamic??? */ | 
|  | 214 |  | 
|  | 215 | #define __PA_INTMASK		(0x0f00) /* non-gnu -- all int flags */ | 
|  | 216 |  | 
|  | 217 | #if 0 | 
|  | 218 | /* Function which can be registered as `printf'-handlers.  */ | 
|  | 219 |  | 
|  | 220 | /* Print floating point value using using abbreviations for the orders | 
|  | 221 | of magnitude used for numbers ('k' for kilo, 'm' for mega etc).  If | 
|  | 222 | the format specifier is a uppercase character powers of 1000 are | 
|  | 223 | used.  Otherwise powers of 1024.  */ | 
|  | 224 | extern int printf_size (FILE *__restrict __fp, | 
|  | 225 | __const struct printf_info *__info, | 
|  | 226 | __const void *__const *__restrict __args) __THROW; | 
|  | 227 |  | 
|  | 228 | /* This is the appropriate argument information function for `printf_size'.  */ | 
|  | 229 | extern int printf_size_info (__const struct printf_info *__restrict | 
|  | 230 | __info, size_t __n, int *__restrict __argtypes) | 
|  | 231 | __THROW; | 
|  | 232 |  | 
|  | 233 | #endif | 
|  | 234 |  | 
|  | 235 | __END_DECLS | 
|  | 236 |  | 
|  | 237 | #endif /* printf.h  */ |