Created
January 14, 2019 19:44
-
-
Save sunfishcode/f8d2ef8fc5f56e67f0dae1601b7b6d58 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- vfprintf.c.orig 2019-01-08 16:56:58.147457674 -0800 | |
+++ vfprintf.c 2019-01-11 13:49:08.320056831 -0800 | |
@@ -11,6 +11,54 @@ | |
#include <math.h> | |
#include <float.h> | |
+#if defined(WASM_NO_FLOATING_POINT_SUPPORT) | |
+ | |
+__attribute__((__cold__, __noreturn__)) | |
+static void floating_point_not_supported(void) { | |
+ fputs("Support for floating-point formatting is currently disabled.\n" | |
+ "To enable it, link with -lprintf-f64.a .\n", stderr); | |
+ abort(); | |
+} | |
+ | |
+#elif defined(WASM_NO_LONG_DOUBLE_SUPPORT) | |
+ | |
+typedef double long_double; | |
+#undef LDBL_TRUE_MIN | |
+#define LDBL_TRUE_MIN DBL_DENORM_MIN | |
+#undef LDBL_MIN | |
+#define LDBL_MIN DBL_MIN | |
+#undef LDBL_MAX | |
+#define LDBL_MAX DBL_MAX | |
+#undef LDBL_EPSILON | |
+#define LDBL_EPSILON DBL_EPSILON | |
+#undef LDBL_MANT_DIG | |
+#define LDBL_MANT_DIG DBL_MANT_DIG | |
+#undef LDBL_MIN_EXP | |
+#define LDBL_MIN_EXP DBL_MIN_EXP | |
+#undef LDBL_MAX_EXP | |
+#define LDBL_MAX_EXP DBL_MAX_EXP | |
+#undef LDBL_DIG | |
+#define LDBL_DIG DBL_DIG | |
+#undef LDBL_MIN_10_EXP | |
+#define LDBL_MIN_10_EXP DBL_MIN_10_EXP | |
+#undef LDBL_MAX_10_EXP | |
+#define LDBL_MAX_10_EXP DBL_MAX_10_EXP | |
+#undef frexpl | |
+#define frexpl(x, exp) frexp(x, exp) | |
+__attribute__((__cold__, __noreturn__)) | |
+static void long_double_not_supported(void) { | |
+ fputs("Support for formatting long double values is currently disabled.\n" | |
+ "To enable it, link with -lprintf-f128.a .\n", stderr); | |
+ abort(); | |
+} | |
+ | |
+#else | |
+ | |
+// Full long double support. | |
+typedef long double long_double; | |
+ | |
+#endif | |
+ | |
/* Some useful macros */ | |
#define MAX(a,b) ((a)>(b) ? (a) : (b)) | |
@@ -102,7 +150,9 @@ | |
union arg | |
{ | |
uintmax_t i; | |
- long double f; | |
+#ifndef WASM_NO_FLOATING_POINT_SUPPORT | |
+ long_double f; | |
+#endif | |
void *p; | |
}; | |
@@ -125,8 +175,17 @@ | |
break; case UMAX: arg->i = va_arg(*ap, uintmax_t); | |
break; case PDIFF: arg->i = va_arg(*ap, ptrdiff_t); | |
break; case UIPTR: arg->i = (uintptr_t)va_arg(*ap, void *); | |
+#if defined(WASM_NO_FLOATING_POINT_SUPPORT) | |
+ break; case DBL: | |
+ break; case LDBL: floating_point_not_supported(); | |
+#else | |
break; case DBL: arg->f = va_arg(*ap, double); | |
- break; case LDBL: arg->f = va_arg(*ap, long double); | |
+#if defined(WASM_NO_LONG_DOUBLE_SUPPORT) | |
+ break; case LDBL: long_double_not_supported(); | |
+#else | |
+ break; case LDBL: arg->f = va_arg(*ap, long_double); | |
+#endif | |
+#endif | |
} | |
} | |
@@ -170,14 +229,15 @@ | |
return s; | |
} | |
+#ifndef WASM_NO_FLOATING_POINT_SUPPORT | |
/* Do not override this check. The floating point printing code below | |
* depends on the float.h constants being right. If they are wrong, it | |
* may overflow the stack. */ | |
#if LDBL_MANT_DIG == 53 | |
-typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)]; | |
+typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long_double)]; | |
#endif | |
-static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t) | |
+static int fmt_fp(FILE *f, long_double y, int w, int p, int fl, int t) | |
{ | |
uint32_t big[(LDBL_MANT_DIG+28)/29 + 1 // mantissa expansion | |
+ (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion | |
@@ -211,7 +271,7 @@ | |
if (y) e2--; | |
if ((t|32)=='a') { | |
- long double round = 8.0; | |
+ long_double round = 8.0; | |
int re; | |
if (t&32) prefix += 9; | |
@@ -318,8 +378,8 @@ | |
x = *d % i; | |
/* Are there any significant digits past j? */ | |
if (x || d+1!=z) { | |
- long double round = 2/LDBL_EPSILON; | |
- long double small; | |
+ long_double round = 2/LDBL_EPSILON; | |
+ long_double small; | |
if ((*d/i & 1) || (i==1000000000 && d>a && (d[-1]&1))) | |
round += 2; | |
if (x<i/2) small=0x0.8p0; | |
@@ -417,6 +477,7 @@ | |
return MAX(w, pl+l); | |
} | |
+#endif | |
static int getint(char **s) { | |
int i; | |
@@ -614,12 +675,14 @@ | |
pad(f, ' ', w, p, fl^LEFT_ADJ); | |
l = w>p ? w : p; | |
continue; | |
+#if !defined(WASM_NO_FLOATING_POINT_SUPPORT) | |
case 'e': case 'f': case 'g': case 'a': | |
case 'E': case 'F': case 'G': case 'A': | |
if (xp && p<0) goto overflow; | |
l = fmt_fp(f, arg.f, w, p, fl, t); | |
if (l<0) goto overflow; | |
continue; | |
+#endif | |
} | |
if (p < z-a) p = z-a; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment