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