Start de-duplicating the regular and wide printf implementations.

This patch switches to C++ (in anticipation of needing it later), removes
a little duplication (via a macro for now), and ensures uniform support
for %C/%lc and %S/%ls between regular and wide (with new tests).

Since it's so hard to debug problems in printf (as the time I've wasted
already today will testify), that's all I want to do in this change. The
other 500 lines of diff can wait...

(Also merge "floatio.h" into "local.h" now all the users are in forked
code.)

Bug: http://b/67371539
Test: ran tests
Change-Id: I083353d89c32b9302d759ca6967cc6d8a62cd8a5
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 155c70b..0ff0785 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -261,10 +261,35 @@
 size_t parsefloat(FILE*, char*, char*);
 size_t wparsefloat(FILE*, wchar_t*, wchar_t*);
 
-__END_DECLS
-
 // Sanity check a FILE* for nullptr, so we can emit a message while crashing
 // instead of doing a blind null-dereference.
 #define CHECK_FP(fp) if (fp == nullptr) __fortify_fatal("%s: null FILE*", __FUNCTION__)
 
+/*
+ * Floating point scanf/printf (input/output) definitions.
+ */
+
+/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
+#define MAXEXP 308
+/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
+#define MAXFRACT 39
+
+/*
+ * MAXEXPDIG is the maximum number of decimal digits needed to store a
+ * floating point exponent in the largest supported format.  It should
+ * be ceil(log10(LDBL_MAX_10_EXP)) or, if hexadecimal floating point
+ * conversions are supported, ceil(log10(LDBL_MAX_EXP)).  But since it
+ * is presently never greater than 5 in practice, we fudge it.
+ */
+#define MAXEXPDIG 6
+#if LDBL_MAX_EXP > 999999
+#error "floating point buffers too small"
+#endif
+
+char* __hdtoa(double, const char*, int, int*, int*, char**);
+char* __hldtoa(long double, const char*, int, int*, int*, char**);
+char* __ldtoa(long double*, int, int, int*, int*, char**);
+
+__END_DECLS
+
 #endif