Fix format macros for fast16 and fast32 int types.

Also change original format test to cover all cases.

Test: bionic unit tests
Change-Id: I2995145562c02918e0b596c008e63459912447ab
diff --git a/libc/include/inttypes.h b/libc/include/inttypes.h
index 2c268e6..f74afa3 100644
--- a/libc/include/inttypes.h
+++ b/libc/include/inttypes.h
@@ -29,6 +29,7 @@
 #define __PRI_64_prefix "ll"
 #define __PRI_PTR_prefix
 #endif
+#define __PRI_FAST_prefix __PRI_PTR_prefix
 
 /*
  * 7.8.1 Macros for format specifiers
@@ -58,8 +59,8 @@
 #define	PRIdLEAST64		__PRI_64_prefix"d"		/* int_least64_t */
 
 #define	PRIdFAST8		"d"		/* int_fast8_t */
-#define	PRIdFAST16		"d"		/* int_fast16_t */
-#define	PRIdFAST32		"d"		/* int_fast32_t */
+#define	PRIdFAST16		__PRI_FAST_prefix"d"	/* int_fast16_t */
+#define	PRIdFAST32		__PRI_FAST_prefix"d"	/* int_fast32_t */
 #define	PRIdFAST64		__PRI_64_prefix"d"		/* int_fast64_t */
 
 #define	PRIdMAX			"jd"		/* intmax_t */
@@ -76,8 +77,8 @@
 #define	PRIiLEAST64		__PRI_64_prefix"i"		/* int_least64_t */
 
 #define	PRIiFAST8		"i"		/* int_fast8_t */
-#define	PRIiFAST16		"i"		/* int_fast16_t */
-#define	PRIiFAST32		"i"		/* int_fast32_t */
+#define	PRIiFAST16		__PRI_FAST_prefix"i"	/* int_fast16_t */
+#define	PRIiFAST32		__PRI_FAST_prefix"i"	/* int_fast32_t */
 #define	PRIiFAST64		__PRI_64_prefix"i"		/* int_fast64_t */
 
 #define	PRIiMAX			"ji"		/* intmax_t */
@@ -95,8 +96,8 @@
 #define	PRIoLEAST64		__PRI_64_prefix"o"		/* int_least64_t */
 
 #define	PRIoFAST8		"o"		/* int_fast8_t */
-#define	PRIoFAST16		"o"		/* int_fast16_t */
-#define	PRIoFAST32		"o"		/* int_fast32_t */
+#define	PRIoFAST16		__PRI_FAST_prefix"o"	/* int_fast16_t */
+#define	PRIoFAST32		__PRI_FAST_prefix"o"	/* int_fast32_t */
 #define	PRIoFAST64		__PRI_64_prefix"o"		/* int_fast64_t */
 
 #define	PRIoMAX			"jo"		/* intmax_t */
@@ -113,8 +114,8 @@
 #define	PRIuLEAST64		__PRI_64_prefix"u"		/* uint_least64_t */
 
 #define	PRIuFAST8		"u"		/* uint_fast8_t */
-#define	PRIuFAST16		"u"		/* uint_fast16_t */
-#define	PRIuFAST32		"u"		/* uint_fast32_t */
+#define	PRIuFAST16		__PRI_FAST_prefix"u"	/* uint_fast16_t */
+#define	PRIuFAST32		__PRI_FAST_prefix"u"	/* uint_fast32_t */
 #define	PRIuFAST64		__PRI_64_prefix"u"		/* uint_fast64_t */
 
 #define	PRIuMAX			"ju"		/* uintmax_t */
@@ -131,8 +132,8 @@
 #define	PRIxLEAST64		__PRI_64_prefix"x"		/* uint_least64_t */
 
 #define	PRIxFAST8		"x"		/* uint_fast8_t */
-#define	PRIxFAST16		"x"		/* uint_fast16_t */
-#define	PRIxFAST32		"x"		/* uint_fast32_t */
+#define	PRIxFAST16		__PRI_FAST_prefix"x"	/* uint_fast16_t */
+#define	PRIxFAST32		__PRI_FAST_prefix"x"	/* uint_fast32_t */
 #define	PRIxFAST64		__PRI_64_prefix"x"		/* uint_fast64_t */
 
 #define	PRIxMAX			"jx"		/* uintmax_t */
@@ -149,8 +150,8 @@
 #define	PRIXLEAST64		__PRI_64_prefix"X"		/* uint_least64_t */
 
 #define	PRIXFAST8		"X"		/* uint_fast8_t */
-#define	PRIXFAST16		"X"		/* uint_fast16_t */
-#define	PRIXFAST32		"X"		/* uint_fast32_t */
+#define	PRIXFAST16		__PRI_FAST_prefix"X"	/* uint_fast16_t */
+#define	PRIXFAST32		__PRI_FAST_prefix"X"	/* uint_fast32_t */
 #define	PRIXFAST64		__PRI_64_prefix"X"		/* uint_fast64_t */
 
 #define	PRIXMAX			"jX"		/* uintmax_t */
@@ -168,8 +169,8 @@
 #define	SCNdLEAST64		__PRI_64_prefix"d"		/* int_least64_t */
 
 #define	SCNdFAST8		"hhd"		/* int_fast8_t */
-#define	SCNdFAST16		"hd"		/* int_fast16_t */
-#define	SCNdFAST32		"d"		/* int_fast32_t */
+#define	SCNdFAST16		__PRI_FAST_prefix"d"	/* int_fast16_t */
+#define	SCNdFAST32		__PRI_FAST_prefix"d"	/* int_fast32_t */
 #define	SCNdFAST64		__PRI_64_prefix"d"		/* int_fast64_t */
 
 #define	SCNdMAX			"jd"		/* intmax_t */
@@ -186,8 +187,8 @@
 #define	SCNiLEAST64		__PRI_64_prefix"i"		/* int_least64_t */
 
 #define	SCNiFAST8		"hhi"		/* int_fast8_t */
-#define	SCNiFAST16		"hi"		/* int_fast16_t */
-#define	SCNiFAST32		"i"		/* int_fast32_t */
+#define	SCNiFAST16		__PRI_FAST_prefix"i"	/* int_fast16_t */
+#define	SCNiFAST32		__PRI_FAST_prefix"i"	/* int_fast32_t */
 #define	SCNiFAST64		__PRI_64_prefix"i"		/* int_fast64_t */
 
 #define	SCNiMAX			"ji"		/* intmax_t */
@@ -205,8 +206,8 @@
 #define	SCNoLEAST64		__PRI_64_prefix"o"		/* uint_least64_t */
 
 #define	SCNoFAST8		"hho"		/* uint_fast8_t */
-#define	SCNoFAST16		"ho"		/* uint_fast16_t */
-#define	SCNoFAST32		"o"		/* uint_fast32_t */
+#define	SCNoFAST16		__PRI_FAST_prefix"o"	/* uint_fast16_t */
+#define	SCNoFAST32		__PRI_FAST_prefix"o"	/* uint_fast32_t */
 #define	SCNoFAST64		__PRI_64_prefix"o"		/* uint_fast64_t */
 
 #define	SCNoMAX			"jo"		/* uintmax_t */
@@ -223,8 +224,8 @@
 #define	SCNuLEAST64		__PRI_64_prefix"u"		/* uint_least64_t */
 
 #define	SCNuFAST8		"hhu"		/* uint_fast8_t */
-#define	SCNuFAST16		"hu"		/* uint_fast16_t */
-#define	SCNuFAST32		"u"		/* uint_fast32_t */
+#define	SCNuFAST16		__PRI_FAST_prefix"u"	/* uint_fast16_t */
+#define	SCNuFAST32		__PRI_FAST_prefix"u"		/* uint_fast32_t */
 #define	SCNuFAST64		__PRI_64_prefix"u"		/* uint_fast64_t */
 
 #define	SCNuMAX			"ju"		/* uintmax_t */
@@ -241,8 +242,8 @@
 #define	SCNxLEAST64		__PRI_64_prefix"x"		/* uint_least64_t */
 
 #define	SCNxFAST8		"hhx"		/* uint_fast8_t */
-#define	SCNxFAST16		"hx"		/* uint_fast16_t */
-#define	SCNxFAST32		"x"		/* uint_fast32_t */
+#define	SCNxFAST16		__PRI_FAST_prefix"x"	/* uint_fast16_t */
+#define	SCNxFAST32		__PRI_FAST_prefix"x"	/* uint_fast32_t */
 #define	SCNxFAST64		__PRI_64_prefix"x"		/* uint_fast64_t */
 
 #define	SCNxMAX			"jx"		/* uintmax_t */
diff --git a/tests/inttypes_test.cpp b/tests/inttypes_test.cpp
index dbbb6d4..80580a4 100644
--- a/tests/inttypes_test.cpp
+++ b/tests/inttypes_test.cpp
@@ -20,24 +20,81 @@
 #include <gtest/gtest.h>
 #include <stdio.h>
 
-TEST(inttypes, misc) {
-  char buf[512];
+#define PRINTF_TYPED(FMT_SUFFIX, TYPE_SUFFIX) \
+  do { \
+    char buf[512]; \
+    memset(buf, 0, sizeof(buf)); \
+    snprintf(buf, sizeof(buf), "%" PRId##FMT_SUFFIX, int##TYPE_SUFFIX(123)); \
+    EXPECT_STREQ("123", buf); \
+    memset(buf, 0, sizeof(buf)); \
+    snprintf(buf, sizeof(buf), "%" PRIi##FMT_SUFFIX, int##TYPE_SUFFIX(123)); \
+    EXPECT_STREQ("123", buf); \
+    memset(buf, 0, sizeof(buf)); \
+    snprintf(buf, sizeof(buf), "%" PRIo##FMT_SUFFIX, int##TYPE_SUFFIX(123)); \
+    EXPECT_STREQ("173", buf); \
+    memset(buf, 0, sizeof(buf)); \
+    snprintf(buf, sizeof(buf), "%" PRIu##FMT_SUFFIX, uint##TYPE_SUFFIX(123)); \
+    EXPECT_STREQ("123", buf); \
+    memset(buf, 0, sizeof(buf)); \
+    snprintf(buf, sizeof(buf), "%" PRIx##FMT_SUFFIX, uint##TYPE_SUFFIX(123)); \
+    EXPECT_STREQ("7b", buf); \
+    memset(buf, 0, sizeof(buf)); \
+    snprintf(buf, sizeof(buf), "%" PRIX##FMT_SUFFIX, uint##TYPE_SUFFIX(123)); \
+    EXPECT_STREQ("7B", buf); \
+  } while (false) \
 
-  intptr_t i = 0;
-  uintptr_t u = 0;
+#define PRINTF_SIZED(WIDTH) \
+  PRINTF_TYPED(WIDTH, WIDTH##_t); \
+  PRINTF_TYPED(FAST##WIDTH, _fast##WIDTH##_t); \
+  PRINTF_TYPED(LEAST##WIDTH, _least##WIDTH##_t) \
 
-  snprintf(buf, sizeof(buf), "%08" PRIdPTR, i);
-  snprintf(buf, sizeof(buf), "%08" PRIiPTR, i);
-  snprintf(buf, sizeof(buf), "%08" PRIoPTR, i);
-  snprintf(buf, sizeof(buf), "%08" PRIuPTR, u);
-  snprintf(buf, sizeof(buf), "%08" PRIxPTR, u);
-  snprintf(buf, sizeof(buf), "%08" PRIXPTR, u);
 
-  sscanf(buf, "%08" SCNdPTR, &i);
-  sscanf(buf, "%08" SCNiPTR, &i);
-  sscanf(buf, "%08" SCNoPTR, &u);
-  sscanf(buf, "%08" SCNuPTR, &u);
-  sscanf(buf, "%08" SCNxPTR, &u);
+#define SCANF_TYPED(FMT_SUFFIX, TYPE_SUFFIX) \
+  do { \
+    int##TYPE_SUFFIX dst_int##TYPE_SUFFIX = 0; \
+    uint##TYPE_SUFFIX dst_uint##TYPE_SUFFIX = 0u; \
+    \
+    sscanf("123", "%" SCNd##FMT_SUFFIX, &dst_int##TYPE_SUFFIX); \
+    EXPECT_EQ(123, dst_int##TYPE_SUFFIX); \
+    dst_int##TYPE_SUFFIX = 0; \
+    sscanf("123", "%" SCNi##FMT_SUFFIX, &dst_int##TYPE_SUFFIX); \
+    EXPECT_EQ(123, dst_int##TYPE_SUFFIX); \
+    dst_int##TYPE_SUFFIX = 0; \
+    sscanf("173", "%" SCNo##FMT_SUFFIX, &dst_int##TYPE_SUFFIX); \
+    EXPECT_EQ(123, dst_int##TYPE_SUFFIX); \
+    dst_int##TYPE_SUFFIX = 0; \
+    sscanf("123", "%" SCNu##FMT_SUFFIX, &dst_uint##TYPE_SUFFIX); \
+    EXPECT_EQ(123u, dst_uint##TYPE_SUFFIX); \
+    dst_uint##TYPE_SUFFIX = 0; \
+    sscanf("7B", "%" SCNx##FMT_SUFFIX, &dst_uint##TYPE_SUFFIX); \
+    EXPECT_EQ(123u, dst_uint##TYPE_SUFFIX); \
+    dst_uint##TYPE_SUFFIX = 0; \
+  } while (false) \
+
+#define SCANF_SIZED(SIZE) \
+  SCANF_TYPED(SIZE, SIZE##_t); \
+  SCANF_TYPED(FAST##SIZE, _fast##SIZE##_t); \
+  SCANF_TYPED(LEAST##SIZE, _least##SIZE##_t) \
+
+
+TEST(inttypes, printf_macros) {
+  PRINTF_SIZED(8);
+  PRINTF_SIZED(16);
+  PRINTF_SIZED(32);
+  PRINTF_SIZED(64);
+
+  PRINTF_TYPED(MAX, max_t);
+  PRINTF_TYPED(PTR, ptr_t);
+}
+
+TEST(inttypes, scanf_macros) {
+  SCANF_SIZED(8);
+  SCANF_SIZED(16);
+  SCANF_SIZED(32);
+  SCANF_SIZED(64);
+
+  SCANF_TYPED(MAX, max_t);
+  SCANF_TYPED(PTR, ptr_t);
 }
 
 TEST(inttypes, wcstoimax) {