1*181254a7Smrg /* GCC Quad-Precision Math Library
2*181254a7Smrg Copyright (C) 2011 Free Software Foundation, Inc.
3*181254a7Smrg Written by Jakub Jelinek <jakub@redhat.com>
4*181254a7Smrg
5*181254a7Smrg This file is part of the libquadmath library.
6*181254a7Smrg Libquadmath is free software; you can redistribute it and/or
7*181254a7Smrg modify it under the terms of the GNU Library General Public
8*181254a7Smrg License as published by the Free Software Foundation; either
9*181254a7Smrg version 2 of the License, or (at your option) any later version.
10*181254a7Smrg
11*181254a7Smrg Libquadmath is distributed in the hope that it will be useful,
12*181254a7Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
13*181254a7Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14*181254a7Smrg Library General Public License for more details.
15*181254a7Smrg
16*181254a7Smrg You should have received a copy of the GNU Library General Public
17*181254a7Smrg License along with libquadmath; see the file COPYING.LIB. If
18*181254a7Smrg not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19*181254a7Smrg Boston, MA 02110-1301, USA. */
20*181254a7Smrg
21*181254a7Smrg #include <stdlib.h>
22*181254a7Smrg #include <stdio.h>
23*181254a7Smrg #ifdef HAVE_LIMITS_H
24*181254a7Smrg #include <limits.h>
25*181254a7Smrg #endif
26*181254a7Smrg #ifdef HAVE_LANGINFO_H
27*181254a7Smrg #include <langinfo.h>
28*181254a7Smrg #endif
29*181254a7Smrg #ifdef HAVE_CTYPE_H
30*181254a7Smrg #include <ctype.h>
31*181254a7Smrg #endif
32*181254a7Smrg #ifdef HAVE_WCHAR_H
33*181254a7Smrg #include <wchar.h>
34*181254a7Smrg #endif
35*181254a7Smrg #ifdef HAVE_WCTYPE_H
36*181254a7Smrg #include <wctype.h>
37*181254a7Smrg #endif
38*181254a7Smrg #ifdef HAVE_PRINTF_HOOKS
39*181254a7Smrg #include <printf.h>
40*181254a7Smrg #endif
41*181254a7Smrg #ifdef HAVE_LOCALE_H
42*181254a7Smrg #include <locale.h>
43*181254a7Smrg #endif
44*181254a7Smrg #include "quadmath-imp.h"
45*181254a7Smrg #include "gmp-impl.h"
46*181254a7Smrg
47*181254a7Smrg #ifdef HAVE_WCHAR_H
48*181254a7Smrg #define L_(x) L##x
49*181254a7Smrg #else
50*181254a7Smrg #define L_(x) x
51*181254a7Smrg #undef wchar_t
52*181254a7Smrg #undef wint_t
53*181254a7Smrg #undef putwc
54*181254a7Smrg #undef WEOF
55*181254a7Smrg #define wchar_t char
56*181254a7Smrg #define wint_t int
57*181254a7Smrg #define putwc(c,f) putc(c,f)
58*181254a7Smrg #define WEOF EOF
59*181254a7Smrg #endif
60*181254a7Smrg
61*181254a7Smrg #ifndef HAVE_CTYPE_H
62*181254a7Smrg /* Won't work for EBCDIC. */
63*181254a7Smrg #undef isupper
64*181254a7Smrg #undef isdigit
65*181254a7Smrg #undef isxdigit
66*181254a7Smrg #undef tolower
67*181254a7Smrg #define isupper(x) \
68*181254a7Smrg ({__typeof(x) __is_x = (x); __is_x >= 'A' && __is_x <= 'Z'; })
69*181254a7Smrg #define isdigit(x) \
70*181254a7Smrg ({__typeof(x) __is_x = (x); __is_x >= '0' && __is_x <= '9'; })
71*181254a7Smrg #define isxdigit(x) \
72*181254a7Smrg ({__typeof(x) __is_x = (x); \
73*181254a7Smrg (__is_x >= '0' && __is_x <= '9') \
74*181254a7Smrg || ((x) >= 'A' && (x) <= 'F') \
75*181254a7Smrg || ((x) >= 'a' && (x) <= 'f'); })
76*181254a7Smrg #define tolower(x) \
77*181254a7Smrg ({__typeof(x) __is_x = (x); \
78*181254a7Smrg (__is_x >= 'A' && __is_x <= 'Z') ? __is_x - 'A' + 'a' : __is_x; })
79*181254a7Smrg #endif
80*181254a7Smrg
81*181254a7Smrg #ifndef CHAR_MAX
82*181254a7Smrg #ifdef __CHAR_UNSIGNED__
83*181254a7Smrg #define CHAR_MAX (2 * __SCHAR_MAX__ + 1)
84*181254a7Smrg #else
85*181254a7Smrg #define CHAR_MAX __SCHAR_MAX__
86*181254a7Smrg #endif
87*181254a7Smrg #endif
88*181254a7Smrg
89*181254a7Smrg #ifndef HAVE_PRINTF_HOOKS
90*181254a7Smrg #define printf_info __quadmath_printf_info
91*181254a7Smrg struct printf_info
92*181254a7Smrg {
93*181254a7Smrg int prec; /* Precision. */
94*181254a7Smrg int width; /* Width. */
95*181254a7Smrg wchar_t spec; /* Format letter. */
96*181254a7Smrg unsigned int is_long_double:1;/* L flag. */
97*181254a7Smrg unsigned int is_short:1; /* h flag. */
98*181254a7Smrg unsigned int is_long:1; /* l flag. */
99*181254a7Smrg unsigned int alt:1; /* # flag. */
100*181254a7Smrg unsigned int space:1; /* Space flag. */
101*181254a7Smrg unsigned int left:1; /* - flag. */
102*181254a7Smrg unsigned int showsign:1; /* + flag. */
103*181254a7Smrg unsigned int group:1; /* ' flag. */
104*181254a7Smrg unsigned int extra:1; /* For special use. */
105*181254a7Smrg unsigned int is_char:1; /* hh flag. */
106*181254a7Smrg unsigned int wide:1; /* Nonzero for wide character streams. */
107*181254a7Smrg unsigned int i18n:1; /* I flag. */
108*181254a7Smrg unsigned short int user; /* Bits for user-installed modifiers. */
109*181254a7Smrg wchar_t pad; /* Padding character. */
110*181254a7Smrg };
111*181254a7Smrg #endif
112*181254a7Smrg
113*181254a7Smrg struct __quadmath_printf_file
114*181254a7Smrg {
115*181254a7Smrg FILE *fp;
116*181254a7Smrg char *str;
117*181254a7Smrg size_t size;
118*181254a7Smrg size_t len;
119*181254a7Smrg int file_p;
120*181254a7Smrg };
121*181254a7Smrg
122*181254a7Smrg int
123*181254a7Smrg __quadmath_printf_fp (struct __quadmath_printf_file *fp,
124*181254a7Smrg const struct printf_info *info,
125*181254a7Smrg const void *const *args) attribute_hidden;
126*181254a7Smrg int
127*181254a7Smrg __quadmath_printf_fphex (struct __quadmath_printf_file *fp,
128*181254a7Smrg const struct printf_info *info,
129*181254a7Smrg const void *const *args) attribute_hidden;
130*181254a7Smrg
131*181254a7Smrg size_t __quadmath_do_pad (struct __quadmath_printf_file *fp, int wide,
132*181254a7Smrg int c, size_t n) attribute_hidden;
133*181254a7Smrg
134*181254a7Smrg static inline __attribute__((__unused__)) size_t
__quadmath_do_put(struct __quadmath_printf_file * fp,int wide,const char * s,size_t n)135*181254a7Smrg __quadmath_do_put (struct __quadmath_printf_file *fp, int wide,
136*181254a7Smrg const char *s, size_t n)
137*181254a7Smrg {
138*181254a7Smrg size_t len;
139*181254a7Smrg if (fp->file_p)
140*181254a7Smrg {
141*181254a7Smrg if (wide)
142*181254a7Smrg {
143*181254a7Smrg size_t cnt;
144*181254a7Smrg const wchar_t *ls = (const wchar_t *) s;
145*181254a7Smrg for (cnt = 0; cnt < n; cnt++)
146*181254a7Smrg if (putwc (ls[cnt], fp->fp) == WEOF)
147*181254a7Smrg break;
148*181254a7Smrg return cnt;
149*181254a7Smrg }
150*181254a7Smrg return fwrite (s, 1, n, fp->fp);
151*181254a7Smrg }
152*181254a7Smrg len = MIN (fp->size, n);
153*181254a7Smrg memcpy (fp->str, s, len);
154*181254a7Smrg fp->str += len;
155*181254a7Smrg fp->size -= len;
156*181254a7Smrg fp->len += n;
157*181254a7Smrg return n;
158*181254a7Smrg }
159*181254a7Smrg
160*181254a7Smrg static inline __attribute__((__unused__)) int
__quadmath_do_putc(struct __quadmath_printf_file * fp,int wide,wchar_t c)161*181254a7Smrg __quadmath_do_putc (struct __quadmath_printf_file *fp, int wide,
162*181254a7Smrg wchar_t c)
163*181254a7Smrg {
164*181254a7Smrg if (fp->file_p)
165*181254a7Smrg return wide ? (int) putwc (c, fp->fp) : putc (c, fp->fp);
166*181254a7Smrg if (fp->size)
167*181254a7Smrg {
168*181254a7Smrg *(fp->str++) = c;
169*181254a7Smrg fp->size--;
170*181254a7Smrg }
171*181254a7Smrg fp->len++;
172*181254a7Smrg return (unsigned char) c;
173*181254a7Smrg }
174*181254a7Smrg
175*181254a7Smrg #define PUT(f, s, n) __quadmath_do_put (f, wide, s, n)
176*181254a7Smrg #define PAD(f, c, n) __quadmath_do_pad (f, wide, c, n)
177*181254a7Smrg #define PUTC(c, f) __quadmath_do_putc (f, wide, c)
178*181254a7Smrg
179*181254a7Smrg #define nl_langinfo_wc(x) \
180*181254a7Smrg ({ union { const char *mb; wchar_t wc; } u; u.mb = nl_langinfo (x); u.wc; })
181*181254a7Smrg
182*181254a7Smrg #undef _itoa
183*181254a7Smrg #define _itoa __quadmath_itoa
184*181254a7Smrg
185*181254a7Smrg #undef NAN
186*181254a7Smrg #define NAN __builtin_nanf ("")
187