xref: /netbsd-src/external/gpl3/gcc.old/dist/libquadmath/printf/quadmath-printf.c (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
1*627f7eb2Smrg /* GCC Quad-Precision Math Library
2*627f7eb2Smrg    Copyright (C) 2011 Free Software Foundation, Inc.
3*627f7eb2Smrg    Written by Jakub Jelinek  <jakub@redhat.com>
4*627f7eb2Smrg 
5*627f7eb2Smrg This file is part of the libquadmath library.
6*627f7eb2Smrg Libquadmath is free software; you can redistribute it and/or
7*627f7eb2Smrg modify it under the terms of the GNU Library General Public
8*627f7eb2Smrg License as published by the Free Software Foundation; either
9*627f7eb2Smrg version 2 of the License, or (at your option) any later version.
10*627f7eb2Smrg 
11*627f7eb2Smrg Libquadmath is distributed in the hope that it will be useful,
12*627f7eb2Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
13*627f7eb2Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*627f7eb2Smrg Library General Public License for more details.
15*627f7eb2Smrg 
16*627f7eb2Smrg You should have received a copy of the GNU Library General Public
17*627f7eb2Smrg License along with libquadmath; see the file COPYING.LIB.  If
18*627f7eb2Smrg not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19*627f7eb2Smrg Boston, MA 02110-1301, USA.  */
20*627f7eb2Smrg 
21*627f7eb2Smrg #include <config.h>
22*627f7eb2Smrg #include <stdarg.h>
23*627f7eb2Smrg #include <string.h>
24*627f7eb2Smrg #include <stdio.h>
25*627f7eb2Smrg #include "quadmath-printf.h"
26*627f7eb2Smrg 
27*627f7eb2Smrg /* Read a simple integer from a string and update the string pointer.
28*627f7eb2Smrg    It is assumed that the first character is a digit.  */
29*627f7eb2Smrg static unsigned int
read_int(const char ** pstr)30*627f7eb2Smrg read_int (const char **pstr)
31*627f7eb2Smrg {
32*627f7eb2Smrg   unsigned int retval = (unsigned char) **pstr - '0';
33*627f7eb2Smrg 
34*627f7eb2Smrg   while (isdigit ((unsigned char) *++(*pstr)))
35*627f7eb2Smrg     {
36*627f7eb2Smrg       retval *= 10;
37*627f7eb2Smrg       retval += (unsigned char) **pstr - '0';
38*627f7eb2Smrg     }
39*627f7eb2Smrg 
40*627f7eb2Smrg   return retval;
41*627f7eb2Smrg }
42*627f7eb2Smrg 
43*627f7eb2Smrg #define PADSIZE 16
44*627f7eb2Smrg static char const blanks[PADSIZE] =
45*627f7eb2Smrg {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
46*627f7eb2Smrg static char const zeroes[PADSIZE] =
47*627f7eb2Smrg {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
48*627f7eb2Smrg static wchar_t const wblanks[PADSIZE] =
49*627f7eb2Smrg {
50*627f7eb2Smrg   L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '),
51*627f7eb2Smrg   L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' ')
52*627f7eb2Smrg };
53*627f7eb2Smrg static wchar_t const wzeroes[PADSIZE] =
54*627f7eb2Smrg {
55*627f7eb2Smrg   L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'),
56*627f7eb2Smrg   L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0')
57*627f7eb2Smrg };
58*627f7eb2Smrg 
59*627f7eb2Smrg attribute_hidden size_t
__quadmath_do_pad(struct __quadmath_printf_file * fp,int wide,int c,size_t n)60*627f7eb2Smrg __quadmath_do_pad (struct __quadmath_printf_file *fp, int wide, int c,
61*627f7eb2Smrg 		   size_t n)
62*627f7eb2Smrg {
63*627f7eb2Smrg   ssize_t i;
64*627f7eb2Smrg   char padbuf[PADSIZE];
65*627f7eb2Smrg   wchar_t wpadbuf[PADSIZE];
66*627f7eb2Smrg   const char *padstr;
67*627f7eb2Smrg   size_t w, written = 0;
68*627f7eb2Smrg   if (wide)
69*627f7eb2Smrg     {
70*627f7eb2Smrg       if (c == ' ')
71*627f7eb2Smrg 	padstr = (const char *) wblanks;
72*627f7eb2Smrg       else if (c == '0')
73*627f7eb2Smrg 	padstr = (const char *) wzeroes;
74*627f7eb2Smrg       else
75*627f7eb2Smrg 	{
76*627f7eb2Smrg 	  padstr = (const char *) wpadbuf;
77*627f7eb2Smrg 	  for (i = 0; i < PADSIZE; i++)
78*627f7eb2Smrg 	    wpadbuf[i] = c;
79*627f7eb2Smrg 	}
80*627f7eb2Smrg     }
81*627f7eb2Smrg   else
82*627f7eb2Smrg     {
83*627f7eb2Smrg       if (c == ' ')
84*627f7eb2Smrg 	padstr = blanks;
85*627f7eb2Smrg       else if (c == '0')
86*627f7eb2Smrg 	padstr = zeroes;
87*627f7eb2Smrg       else
88*627f7eb2Smrg 	{
89*627f7eb2Smrg 	  padstr = (const char *) padbuf;
90*627f7eb2Smrg 	  for (i = 0; i < PADSIZE; i++)
91*627f7eb2Smrg 	    padbuf[i] = c;
92*627f7eb2Smrg 	}
93*627f7eb2Smrg     }
94*627f7eb2Smrg   for (i = n; i >= PADSIZE; i -= PADSIZE)
95*627f7eb2Smrg     {
96*627f7eb2Smrg       w = PUT (fp, (char *) padstr, PADSIZE);
97*627f7eb2Smrg       written += w;
98*627f7eb2Smrg       if (w != PADSIZE)
99*627f7eb2Smrg 	return written;
100*627f7eb2Smrg     }
101*627f7eb2Smrg   if (i > 0)
102*627f7eb2Smrg     {
103*627f7eb2Smrg       w = PUT (fp, (char *) padstr, i);
104*627f7eb2Smrg       written += w;
105*627f7eb2Smrg     }
106*627f7eb2Smrg   return written;
107*627f7eb2Smrg }
108*627f7eb2Smrg 
109*627f7eb2Smrg /* This is a stripped down version of snprintf, which just handles
110*627f7eb2Smrg    a single %eEfFgGaA format entry with Q modifier.  % has to be
111*627f7eb2Smrg    the first character of the format string, no $ can be used.  */
112*627f7eb2Smrg int
quadmath_snprintf(char * str,size_t size,const char * format,...)113*627f7eb2Smrg quadmath_snprintf (char *str, size_t size, const char *format, ...)
114*627f7eb2Smrg {
115*627f7eb2Smrg   struct printf_info info;
116*627f7eb2Smrg   va_list ap;
117*627f7eb2Smrg   __float128 fpnum, *fpnum_addr = &fpnum, **fpnum_addr2 = &fpnum_addr;
118*627f7eb2Smrg   struct __quadmath_printf_file qfp;
119*627f7eb2Smrg 
120*627f7eb2Smrg   if (*format++ != '%')
121*627f7eb2Smrg     return -1;
122*627f7eb2Smrg 
123*627f7eb2Smrg   /* Clear information structure.  */
124*627f7eb2Smrg   memset (&info, '\0', sizeof info);
125*627f7eb2Smrg   /* info.alt = 0;
126*627f7eb2Smrg   info.space = 0;
127*627f7eb2Smrg   info.left = 0;
128*627f7eb2Smrg   info.showsign = 0;
129*627f7eb2Smrg   info.group = 0;
130*627f7eb2Smrg   info.i18n = 0;
131*627f7eb2Smrg   info.extra = 0; */
132*627f7eb2Smrg   info.pad = ' ';
133*627f7eb2Smrg   /* info.wide = 0; */
134*627f7eb2Smrg 
135*627f7eb2Smrg   /* Check for spec modifiers.  */
136*627f7eb2Smrg   do
137*627f7eb2Smrg     {
138*627f7eb2Smrg       switch (*format)
139*627f7eb2Smrg 	{
140*627f7eb2Smrg 	case ' ':
141*627f7eb2Smrg 	  /* Output a space in place of a sign, when there is no sign.  */
142*627f7eb2Smrg 	  info.space = 1;
143*627f7eb2Smrg 	  continue;
144*627f7eb2Smrg 	case '+':
145*627f7eb2Smrg 	  /* Always output + or - for numbers.  */
146*627f7eb2Smrg 	  info.showsign = 1;
147*627f7eb2Smrg 	  continue;
148*627f7eb2Smrg 	case '-':
149*627f7eb2Smrg 	  /* Left-justify things.  */
150*627f7eb2Smrg 	  info.left = 1;
151*627f7eb2Smrg 	  continue;
152*627f7eb2Smrg 	case '#':
153*627f7eb2Smrg 	  /* Use the "alternate form":
154*627f7eb2Smrg 	     Hex has 0x or 0X, FP always has a decimal point.  */
155*627f7eb2Smrg 	  info.alt = 1;
156*627f7eb2Smrg 	  continue;
157*627f7eb2Smrg 	case '0':
158*627f7eb2Smrg 	  /* Pad with 0s.  */
159*627f7eb2Smrg 	  info.pad = '0';
160*627f7eb2Smrg 	  continue;
161*627f7eb2Smrg 	case '\'':
162*627f7eb2Smrg 	  /* Show grouping in numbers if the locale information
163*627f7eb2Smrg 	     indicates any.  */
164*627f7eb2Smrg 	  info.group = 1;
165*627f7eb2Smrg 	  continue;
166*627f7eb2Smrg 	case 'I':
167*627f7eb2Smrg 	  /* Use the internationalized form of the output.  Currently
168*627f7eb2Smrg 	     means to use the `outdigits' of the current locale.  */
169*627f7eb2Smrg 	  info.i18n = 1;
170*627f7eb2Smrg 	  continue;
171*627f7eb2Smrg 	default:
172*627f7eb2Smrg 	  break;
173*627f7eb2Smrg 	}
174*627f7eb2Smrg       break;
175*627f7eb2Smrg     }
176*627f7eb2Smrg   while (*++format);
177*627f7eb2Smrg 
178*627f7eb2Smrg   if (info.left)
179*627f7eb2Smrg     info.pad = ' ';
180*627f7eb2Smrg 
181*627f7eb2Smrg   va_start (ap, format);
182*627f7eb2Smrg 
183*627f7eb2Smrg   /* Get the field width.  */
184*627f7eb2Smrg   /* info.width = 0; */
185*627f7eb2Smrg   if (*format == '*')
186*627f7eb2Smrg     {
187*627f7eb2Smrg       /* The field width is given in an argument.
188*627f7eb2Smrg 	 A negative field width indicates left justification.  */
189*627f7eb2Smrg       ++format;
190*627f7eb2Smrg       info.width = va_arg (ap, int);
191*627f7eb2Smrg     }
192*627f7eb2Smrg   else if (isdigit (*format))
193*627f7eb2Smrg     /* Constant width specification.  */
194*627f7eb2Smrg     info.width = read_int (&format);
195*627f7eb2Smrg 
196*627f7eb2Smrg   /* Get the precision.  */
197*627f7eb2Smrg   /* -1 means none given; 0 means explicit 0.  */
198*627f7eb2Smrg   info.prec = -1;
199*627f7eb2Smrg   if (*format == '.')
200*627f7eb2Smrg     {
201*627f7eb2Smrg       ++format;
202*627f7eb2Smrg       if (*format == '*')
203*627f7eb2Smrg 	{
204*627f7eb2Smrg 	  /* The precision is given in an argument.  */
205*627f7eb2Smrg 	  ++format;
206*627f7eb2Smrg 
207*627f7eb2Smrg 	  info.prec = va_arg (ap, int);
208*627f7eb2Smrg 	}
209*627f7eb2Smrg       else if (isdigit (*format))
210*627f7eb2Smrg 	info.prec = read_int (&format);
211*627f7eb2Smrg       else
212*627f7eb2Smrg 	/* "%.?" is treated like "%.0?".  */
213*627f7eb2Smrg 	info.prec = 0;
214*627f7eb2Smrg     }
215*627f7eb2Smrg 
216*627f7eb2Smrg   /* Check for type modifiers.  */
217*627f7eb2Smrg   /* info.is_long_double = 0;
218*627f7eb2Smrg   info.is_short = 0;
219*627f7eb2Smrg   info.is_long = 0;
220*627f7eb2Smrg   info.is_char = 0;
221*627f7eb2Smrg   info.user = 0; */
222*627f7eb2Smrg 
223*627f7eb2Smrg   /* We require Q modifier.  */
224*627f7eb2Smrg   if (*format++ != 'Q')
225*627f7eb2Smrg     {
226*627f7eb2Smrg       va_end (ap);
227*627f7eb2Smrg       return -1;
228*627f7eb2Smrg     }
229*627f7eb2Smrg 
230*627f7eb2Smrg   /* Get the format specification.  */
231*627f7eb2Smrg   info.spec = (wchar_t) *format++;
232*627f7eb2Smrg   if (info.spec == L_('\0') || *format != '\0')
233*627f7eb2Smrg     {
234*627f7eb2Smrg       va_end (ap);
235*627f7eb2Smrg       return -1;
236*627f7eb2Smrg     }
237*627f7eb2Smrg 
238*627f7eb2Smrg   switch (info.spec)
239*627f7eb2Smrg     {
240*627f7eb2Smrg     case L_('e'):
241*627f7eb2Smrg     case L_('E'):
242*627f7eb2Smrg     case L_('f'):
243*627f7eb2Smrg     case L_('F'):
244*627f7eb2Smrg     case L_('g'):
245*627f7eb2Smrg     case L_('G'):
246*627f7eb2Smrg     case L_('a'):
247*627f7eb2Smrg     case L_('A'):
248*627f7eb2Smrg       break;
249*627f7eb2Smrg     default:
250*627f7eb2Smrg       va_end (ap);
251*627f7eb2Smrg       return -1;
252*627f7eb2Smrg     }
253*627f7eb2Smrg 
254*627f7eb2Smrg   fpnum = va_arg (ap, __float128);
255*627f7eb2Smrg   va_end (ap);
256*627f7eb2Smrg 
257*627f7eb2Smrg   qfp.fp = NULL;
258*627f7eb2Smrg   qfp.str = str;
259*627f7eb2Smrg   qfp.size = size ? size - 1 : 0;
260*627f7eb2Smrg   qfp.len = 0;
261*627f7eb2Smrg   qfp.file_p = 0;
262*627f7eb2Smrg 
263*627f7eb2Smrg   if (info.spec == L_('a') || info.spec == L_('A'))
264*627f7eb2Smrg     __quadmath_printf_fphex (&qfp, &info, (const void *const *)&fpnum_addr2);
265*627f7eb2Smrg   else
266*627f7eb2Smrg     __quadmath_printf_fp (&qfp, &info, (const void *const *)&fpnum_addr2);
267*627f7eb2Smrg 
268*627f7eb2Smrg   if (size)
269*627f7eb2Smrg     *qfp.str = '\0';
270*627f7eb2Smrg 
271*627f7eb2Smrg   return qfp.len;
272*627f7eb2Smrg }
273*627f7eb2Smrg 
274*627f7eb2Smrg #ifdef HAVE_PRINTF_HOOKS
275*627f7eb2Smrg static int pa_flt128;
276*627f7eb2Smrg int mod_Q attribute_hidden;
277*627f7eb2Smrg 
278*627f7eb2Smrg static void
flt128_va(void * mem,va_list * ap)279*627f7eb2Smrg flt128_va (void *mem, va_list *ap)
280*627f7eb2Smrg {
281*627f7eb2Smrg   __float128 d = va_arg (*ap, __float128);
282*627f7eb2Smrg   memcpy (mem, &d, sizeof (d));
283*627f7eb2Smrg }
284*627f7eb2Smrg 
285*627f7eb2Smrg static int
flt128_ais(const struct printf_info * info,size_t n,int * argtype,int * size)286*627f7eb2Smrg flt128_ais (const struct printf_info *info, size_t n __attribute__ ((unused)),
287*627f7eb2Smrg 	    int *argtype, int *size)
288*627f7eb2Smrg {
289*627f7eb2Smrg   if (info->user & mod_Q)
290*627f7eb2Smrg     {
291*627f7eb2Smrg       argtype[0] = pa_flt128;
292*627f7eb2Smrg       size[0] = sizeof (__float128);
293*627f7eb2Smrg       return 1;
294*627f7eb2Smrg     }
295*627f7eb2Smrg #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 13)
296*627f7eb2Smrg   /* Workaround bug in glibc printf hook handling.  */
297*627f7eb2Smrg   size[0] = -1;
298*627f7eb2Smrg   switch (info->spec)
299*627f7eb2Smrg     {
300*627f7eb2Smrg     case L_('i'):
301*627f7eb2Smrg     case L_('d'):
302*627f7eb2Smrg     case L_('u'):
303*627f7eb2Smrg     case L_('o'):
304*627f7eb2Smrg     case L_('X'):
305*627f7eb2Smrg     case L_('x'):
306*627f7eb2Smrg #if __LONG_MAX__ != __LONG_LONG_MAX__
307*627f7eb2Smrg       if (info->is_long_double)
308*627f7eb2Smrg 	argtype[0] = PA_INT|PA_FLAG_LONG_LONG;
309*627f7eb2Smrg       else
310*627f7eb2Smrg #endif
311*627f7eb2Smrg       if (info->is_long)
312*627f7eb2Smrg 	argtype[0] = PA_INT|PA_FLAG_LONG;
313*627f7eb2Smrg       else if (info->is_short)
314*627f7eb2Smrg 	argtype[0] = PA_INT|PA_FLAG_SHORT;
315*627f7eb2Smrg       else if (info->is_char)
316*627f7eb2Smrg 	argtype[0] = PA_CHAR;
317*627f7eb2Smrg       else
318*627f7eb2Smrg 	argtype[0] = PA_INT;
319*627f7eb2Smrg       return 1;
320*627f7eb2Smrg     case L_('e'):
321*627f7eb2Smrg     case L_('E'):
322*627f7eb2Smrg     case L_('f'):
323*627f7eb2Smrg     case L_('F'):
324*627f7eb2Smrg     case L_('g'):
325*627f7eb2Smrg     case L_('G'):
326*627f7eb2Smrg     case L_('a'):
327*627f7eb2Smrg     case L_('A'):
328*627f7eb2Smrg       if (info->is_long_double)
329*627f7eb2Smrg 	argtype[0] = PA_DOUBLE|PA_FLAG_LONG_DOUBLE;
330*627f7eb2Smrg       else
331*627f7eb2Smrg 	argtype[0] = PA_DOUBLE;
332*627f7eb2Smrg       return 1;
333*627f7eb2Smrg     case L_('c'):
334*627f7eb2Smrg       argtype[0] = PA_CHAR;
335*627f7eb2Smrg       return 1;
336*627f7eb2Smrg     case L_('C'):
337*627f7eb2Smrg       argtype[0] = PA_WCHAR;
338*627f7eb2Smrg       return 1;
339*627f7eb2Smrg     case L_('s'):
340*627f7eb2Smrg       argtype[0] = PA_STRING;
341*627f7eb2Smrg       return 1;
342*627f7eb2Smrg     case L_('S'):
343*627f7eb2Smrg       argtype[0] = PA_WSTRING;
344*627f7eb2Smrg       return 1;
345*627f7eb2Smrg     case L_('p'):
346*627f7eb2Smrg       argtype[0] = PA_POINTER;
347*627f7eb2Smrg       return 1;
348*627f7eb2Smrg     case L_('n'):
349*627f7eb2Smrg       argtype[0] = PA_INT|PA_FLAG_PTR;
350*627f7eb2Smrg       return 1;
351*627f7eb2Smrg 
352*627f7eb2Smrg     case L_('m'):
353*627f7eb2Smrg     default:
354*627f7eb2Smrg       /* An unknown spec will consume no args.  */
355*627f7eb2Smrg       return 0;
356*627f7eb2Smrg     }
357*627f7eb2Smrg #endif
358*627f7eb2Smrg   return -1;
359*627f7eb2Smrg }
360*627f7eb2Smrg 
361*627f7eb2Smrg static int
flt128_printf_fp(FILE * fp,const struct printf_info * info,const void * const * args)362*627f7eb2Smrg flt128_printf_fp (FILE *fp, const struct printf_info *info,
363*627f7eb2Smrg 		  const void *const *args)
364*627f7eb2Smrg {
365*627f7eb2Smrg   struct __quadmath_printf_file qpf
366*627f7eb2Smrg     = { .fp = fp, .str = NULL, .size = 0, .len = 0, .file_p = 1 };
367*627f7eb2Smrg 
368*627f7eb2Smrg   if ((info->user & mod_Q) == 0)
369*627f7eb2Smrg     return -2;
370*627f7eb2Smrg 
371*627f7eb2Smrg   return __quadmath_printf_fp (&qpf, info, args);
372*627f7eb2Smrg }
373*627f7eb2Smrg 
374*627f7eb2Smrg static int
flt128_printf_fphex(FILE * fp,const struct printf_info * info,const void * const * args)375*627f7eb2Smrg flt128_printf_fphex (FILE *fp, const struct printf_info *info,
376*627f7eb2Smrg 		     const void *const *args)
377*627f7eb2Smrg {
378*627f7eb2Smrg   struct __quadmath_printf_file qpf
379*627f7eb2Smrg     = { .fp = fp, .str = NULL, .size = 0, .len = 0, .file_p = 1 };
380*627f7eb2Smrg 
381*627f7eb2Smrg   if ((info->user & mod_Q) == 0)
382*627f7eb2Smrg     return -2;
383*627f7eb2Smrg 
384*627f7eb2Smrg   return __quadmath_printf_fphex (&qpf, info, args);
385*627f7eb2Smrg }
386*627f7eb2Smrg 
387*627f7eb2Smrg __attribute__((constructor)) static void
register_printf_flt128(void)388*627f7eb2Smrg register_printf_flt128 (void)
389*627f7eb2Smrg {
390*627f7eb2Smrg   pa_flt128 = register_printf_type (flt128_va);
391*627f7eb2Smrg   if (pa_flt128 == -1)
392*627f7eb2Smrg     return;
393*627f7eb2Smrg   mod_Q = register_printf_modifier (L_("Q"));
394*627f7eb2Smrg   if (mod_Q == -1)
395*627f7eb2Smrg     return;
396*627f7eb2Smrg   register_printf_specifier ('f', flt128_printf_fp, flt128_ais);
397*627f7eb2Smrg   register_printf_specifier ('F', flt128_printf_fp, flt128_ais);
398*627f7eb2Smrg   register_printf_specifier ('e', flt128_printf_fp, flt128_ais);
399*627f7eb2Smrg   register_printf_specifier ('E', flt128_printf_fp, flt128_ais);
400*627f7eb2Smrg   register_printf_specifier ('g', flt128_printf_fp, flt128_ais);
401*627f7eb2Smrg   register_printf_specifier ('G', flt128_printf_fp, flt128_ais);
402*627f7eb2Smrg   register_printf_specifier ('a', flt128_printf_fphex, flt128_ais);
403*627f7eb2Smrg   register_printf_specifier ('A', flt128_printf_fphex, flt128_ais);
404*627f7eb2Smrg }
405*627f7eb2Smrg 
406*627f7eb2Smrg __attribute__((destructor)) static void
unregister_printf_flt128(void)407*627f7eb2Smrg unregister_printf_flt128 (void)
408*627f7eb2Smrg {
409*627f7eb2Smrg   /* No way to unregister printf type and modifier currently,
410*627f7eb2Smrg      and only one printf specifier can be registered right now.  */
411*627f7eb2Smrg   if (pa_flt128 == -1 || mod_Q == -1)
412*627f7eb2Smrg     return;
413*627f7eb2Smrg   register_printf_specifier ('f', NULL, NULL);
414*627f7eb2Smrg   register_printf_specifier ('F', NULL, NULL);
415*627f7eb2Smrg   register_printf_specifier ('e', NULL, NULL);
416*627f7eb2Smrg   register_printf_specifier ('E', NULL, NULL);
417*627f7eb2Smrg   register_printf_specifier ('g', NULL, NULL);
418*627f7eb2Smrg   register_printf_specifier ('G', NULL, NULL);
419*627f7eb2Smrg   register_printf_specifier ('a', NULL, NULL);
420*627f7eb2Smrg   register_printf_specifier ('A', NULL, NULL);
421*627f7eb2Smrg }
422*627f7eb2Smrg #endif
423