stdint.h: streamline type definitions

Compilers (at least gcc and clang) already provide definitions to
create standard types and their range. For example, __INT16_TYPE__ is
normally defined as a short to be used with the int16_t typedef, and
__INT16_MAX__ is defined as 32767. So it makes sense to rely on them
rather than hardcoding our own, especially for the fast types where
the compiler itself knows what basic type is best.

Using compiler provided definitions makes even more sense when dealing
with 64-bit targets where some types such as intptr_t and size_t must
have a different size and range. Those definitions are then adjusted
by the compiler directly.

However there are two cases for which we should override those
definitions:

* The __INT32_TYPE__ definition on 32-bit targets vary between an int
  and a long int depending on the architecture and configuration.
  Notably, all compilers shipped with the Zephyr SDK, except for the
  i586-zephyr-elfiamcu variant, define __INT32_TYPE__ to a long int.
  Whereas, all Linux configurations for gcc, both 32-bit and 64-bit,
  always define __INT32_TYPE__ as an int. Having variability here is
  not welcome as pointers to a long int and to an int are not deemed
  compatible by the compiler, and printing an int32_t defined with a
  long using %d makes the compiler to complain, even if they're the
  same size on 32-bit targets. Given that an int is always 32 bits
  on all targets we might care about, and given that Zephyr hardcoded
  int32_t to an int before, then we just redefine __INT32_TYPE__ and
  derrivatives to an int to keep the peace in the code.

* The confusion also exists with __INTPTR_TYPE__. Looking again at the
  Zephyr SDK, it is defined as an int, even even when __INT32_TYPE__ is
  initially a long int. One notable exception is i586-zephyr-elf where
  __INTPTR_TYPE__ is a long int even when using -m32. On 64-bit targets
  this is always a long int. So let's redefine __INTPTR_TYPE__ to always
  be a long int on Zephyr which simplifies the code, works for both
  32-bit and 64-bit targets, and mimics what the Linux kernel does.
  Only a few print format strings needed adjustment.

In those two cases, there is a safeguard to ensure the type we're
enforcing has the right size and fail the build otherwise.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 347dab9..c67553b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -220,6 +220,9 @@
 # @Intent: Set compiler specific macro inclusion of AUTOCONF_H
 toolchain_cc_imacros(${AUTOCONF_H})
 
+# @Intent: Enforce standard integer type correspondance to match Zephyr usage.
+toolchain_cc_imacros(${ZEPHYR_BASE}/include/toolchain/zephyr_stdint.h)
+
 # @Intent: Set compiler specific flag for bare metal freestanding option
 toolchain_cc_freestanding()
 
diff --git a/arch/arm/core/cortex_m/mpu/arm_core_mpu.c b/arch/arm/core/cortex_m/mpu/arm_core_mpu.c
index dd9eafa..50eec30 100644
--- a/arch/arm/core/cortex_m/mpu/arm_core_mpu.c
+++ b/arch/arm/core/cortex_m/mpu/arm_core_mpu.c
@@ -175,7 +175,7 @@
 				 */
 				continue;
 			}
-			LOG_DBG("set region 0x%x 0x%x",
+			LOG_DBG("set region 0x%lx 0x%x",
 				partition.start, partition.size);
 			__ASSERT(region_num < _MAX_DYNAMIC_MPU_REGIONS_NUM,
 				"Out-of-bounds error for dynamic region map.");
diff --git a/include/toolchain/zephyr_stdint.h b/include/toolchain/zephyr_stdint.h
new file mode 100644
index 0000000..afa1999
--- /dev/null
+++ b/include/toolchain/zephyr_stdint.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019 BayLibre SAS
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef ZEPHYR_INCLUDE_TOOLCHAIN_STDINT_H_
+#define ZEPHYR_INCLUDE_TOOLCHAIN_STDINT_H_
+
+/*
+ * Some gcc versions and/or configurations as found in the Zephyr SDK
+ * (questionably) define __INT32_TYPE__ and derrivatives as a long int
+ * which makes the printf format checker to complain about long vs int
+ * mismatch when %u is given a u32_t argument, and u32_t pointers not
+ * being compatible with int pointers. Let's redefine them to follow
+ * common expectations and usage.
+ */
+
+#if __SIZEOF_INT__ != 4
+#error "unexpected int width"
+#endif
+
+#undef __INT32_TYPE__
+#undef __UINT32_TYPE__
+#undef __INT_LEAST32_TYPE__
+#undef __UINT_LEAST32_TYPE__
+#define __INT32_TYPE__ int
+#define __UINT32_TYPE__ unsigned int
+#define __INT_LEAST32_TYPE__ __INT32_TYPE__
+#define __UINT_LEAST32_TYPE__ __UINT32_TYPE__
+
+/*
+ * The confusion also exists with __INTPTR_TYPE__ which is either an int
+ * (even when __INT32_TYPE__ is a long int) or a long int. Let's redefine
+ * it to a long int to get some uniformity. Doing so also makes it compatible
+ * with LP64 (64-bit) targets where a long is always 64-bit wide.
+ */
+
+#if __SIZEOF_POINTER__ != __SIZEOF_LONG__
+#error "unexpected size difference between pointers and long ints"
+#endif
+
+#undef __INTPTR_TYPE__
+#undef __UINTPTR_TYPE__
+#define __INTPTR_TYPE__ long int
+#define __UINTPTR_TYPE__ long unsigned int
+
+#endif /* ZEPHYR_INCLUDE_TOOLCHAIN_STDINT_H_ */
diff --git a/kernel/mem_domain.c b/kernel/mem_domain.c
index 461a039..b9343aa 100644
--- a/kernel/mem_domain.c
+++ b/kernel/mem_domain.c
@@ -31,7 +31,7 @@
 
 	if (exec && write) {
 		__ASSERT(false,
-			"partition is writable and executable <start %x>",
+			"partition is writable and executable <start %lx>",
 			 part->start);
 		return false;
 	}
@@ -59,7 +59,7 @@
 		if ((cur_write && exec) || (cur_exec && write)) {
 			__ASSERT(false, "overlapping partitions are "
 				 "writable and executable "
-				 "<%x...%x>, <%x...%x>",
+				 "<%lx...%x>, <%lx...%x>",
 				 part->start, last,
 				 parts[i].start, cur_last);
 			return false;
diff --git a/lib/libc/minimal/include/inttypes.h b/lib/libc/minimal/include/inttypes.h
index 66ba8dd..82c4bf3 100644
--- a/lib/libc/minimal/include/inttypes.h
+++ b/lib/libc/minimal/include/inttypes.h
@@ -14,36 +14,36 @@
 #define	PRId16			"d"		/* int16_t */
 #define	PRId32			"d"		/* int32_t */
 #define	PRId64			"lld"		/* int64_t */
-#define	PRIdPTR			"d"		/* intptr_t */
+#define	PRIdPTR			"ld"		/* intptr_t */
 
 #define	PRIi8			"i"		/* int8_t */
 #define	PRIi16			"i"		/* int16_t */
 #define	PRIi32			"i"		/* int32_t */
 #define	PRIi64			"lli"		/* int64_t */
-#define	PRIiPTR			"i"		/* intptr_t */
+#define	PRIiPTR			"li"		/* intptr_t */
 
 #define	PRIo8			"o"		/* int8_t */
 #define	PRIo16			"o"		/* int16_t */
 #define	PRIo32			"o"		/* int32_t */
 #define	PRIo64			"llo"		/* int64_t */
-#define	PRIoPTR			"o"		/* intptr_t */
+#define	PRIoPTR			"lo"		/* intptr_t */
 
 #define	PRIu8			"u"		/* uint8_t */
 #define	PRIu16			"u"		/* uint16_t */
 #define	PRIu32			"u"		/* uint32_t */
 #define	PRIu64			"llu"		/* uint64_t */
-#define	PRIuPTR			"u"		/* uintptr_t */
+#define	PRIuPTR			"lu"		/* uintptr_t */
 
 #define	PRIx8			"x"		/* uint8_t */
 #define	PRIx16			"x"		/* uint16_t */
 #define	PRIx32			"x"		/* uint32_t */
 #define	PRIx64			"llx"		/* uint64_t */
-#define	PRIxPTR			"x"		/* uintptr_t */
+#define	PRIxPTR			"lx"		/* uintptr_t */
 
 #define	PRIX8			"X"		/* uint8_t */
 #define	PRIX16			"X"		/* uint16_t */
 #define	PRIX32			"X"		/* uint32_t */
 #define	PRIX64			"llX"		/* uint64_t */
-#define	PRIXPTR			"X"		/* uintptr_t */
+#define	PRIXPTR			"lX"		/* uintptr_t */
 
 #endif
diff --git a/lib/libc/minimal/include/stdint.h b/lib/libc/minimal/include/stdint.h
index 68a523b..ff8dd79 100644
--- a/lib/libc/minimal/include/stdint.h
+++ b/lib/libc/minimal/include/stdint.h
@@ -13,64 +13,62 @@
 extern "C" {
 #endif
 
-#define INT8_MAX    0x7F
-#define INT16_MAX   0x7FFF
-#define INT32_MAX   0x7FFFFFFF
-#define INT64_MAX   0x7FFFFFFFFFFFFFFFLL
+#define INT8_MAX    __INT8_MAX__
+#define INT16_MAX   __INT16_MAX__
+#define INT32_MAX   __INT32_MAX__
+#define INT64_MAX   __INT64_MAX__
 
 #define INT8_MIN    (-INT8_MAX - 1)
 #define INT16_MIN   (-INT16_MAX - 1)
 #define INT32_MIN   (-INT32_MAX - 1)
 #define INT64_MIN   (-INT64_MAX - 1LL)
 
-#define UINT8_MAX   0xFF
-#define UINT16_MAX  0xFFFF
-#define UINT32_MAX  0xFFFFFFFFU
-#define UINT64_MAX  0xFFFFFFFFFFFFFFFFULL
+#define UINT8_MAX   __UINT8_MAX__
+#define UINT16_MAX  __UINT16_MAX__
+#define UINT32_MAX  __UINT32_MAX__
+#define UINT64_MAX  __UINT64_MAX__
 
-#define INTPTR_MIN  INT32_MIN
-#define INTPTR_MAX  INT32_MAX
-#define UINTPTR_MAX UINT32_MAX
+#define INTPTR_MAX  __INTPTR_MAX__
+#define INTPTR_MIN  (-INTPTR_MAX - 1)
+#define UINTPTR_MAX __UINTPTR_MAX__
 
-#define PTRDIFF_MIN INT32_MIN
-#define PTRDIFF_MAX INT32_MAX
+#define PTRDIFF_MAX __PTRDIFF_MAX__
+#define PTRDIFF_MIN (-PTRDIFF_MAX - 1)
 
-#define SIZE_MAX    UINT32_MAX
+#define SIZE_MAX    __SIZE_MAX__
 
-typedef signed char         int8_t;
-typedef signed short        int16_t;
-typedef signed int          int32_t;
-typedef signed long long    int64_t;
+typedef __INT8_TYPE__		int8_t;
+typedef __INT16_TYPE__		int16_t;
+typedef __INT32_TYPE__		int32_t;
+typedef __INT64_TYPE__		int64_t;
 
-/* Assume int to be the fastest type for all types except 64bit ones */
+typedef __INT_FAST8_TYPE__	int_fast8_t;
+typedef __INT_FAST16_TYPE__	int_fast16_t;
+typedef __INT_FAST32_TYPE__	int_fast32_t;
+typedef __INT_FAST64_TYPE__	int_fast64_t;
 
-typedef signed int          int_fast8_t;
-typedef signed int          int_fast16_t;
-typedef signed int          int_fast32_t;
-typedef signed long long    int_fast64_t;
+typedef __INT_LEAST8_TYPE__	int_least8_t;
+typedef __INT_LEAST16_TYPE__	int_least16_t;
+typedef __INT_LEAST32_TYPE__	int_least32_t;
+typedef __INT_LEAST64_TYPE__	int_least64_t;
 
-typedef signed char         int_least8_t;
-typedef signed short        int_least16_t;
-typedef signed int          int_least32_t;
-typedef signed long long    int_least64_t;
+typedef __UINT8_TYPE__		uint8_t;
+typedef __UINT16_TYPE__		uint16_t;
+typedef __UINT32_TYPE__		uint32_t;
+typedef __UINT64_TYPE__		uint64_t;
 
-typedef unsigned char       uint8_t;
-typedef unsigned short      uint16_t;
-typedef unsigned int        uint32_t;
-typedef unsigned long long  uint64_t;
+typedef __UINT_FAST8_TYPE__	uint_fast8_t;
+typedef __UINT_FAST16_TYPE__	uint_fast16_t;
+typedef __UINT_FAST32_TYPE__	uint_fast32_t;
+typedef __UINT_FAST64_TYPE__	uint_fast64_t;
 
-typedef unsigned int        uint_fast8_t;
-typedef unsigned int        uint_fast16_t;
-typedef unsigned int        uint_fast32_t;
-typedef unsigned long long  uint_fast64_t;
+typedef __UINT_LEAST8_TYPE__	uint_least8_t;
+typedef __UINT_LEAST16_TYPE__	uint_least16_t;
+typedef __UINT_LEAST32_TYPE__	uint_least32_t;
+typedef __UINT_LEAST64_TYPE__	uint_least64_t;
 
-typedef unsigned char       uint_least8_t;
-typedef unsigned short      uint_least16_t;
-typedef unsigned int        uint_least32_t;
-typedef unsigned long long  uint_least64_t;
-
-typedef int                 intptr_t;
-typedef unsigned int        uintptr_t;
+typedef __INTPTR_TYPE__		intptr_t;
+typedef __UINTPTR_TYPE__	uintptr_t;
 
 #ifdef __cplusplus
 }