diff options
author | sdefresne@chromium.org <sdefresne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-08 11:43:14 +0000 |
---|---|---|
committer | sdefresne@chromium.org <sdefresne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-08 11:43:14 +0000 |
commit | e6d4e1483d679ec6bcb2a22752f72a77401e1406 (patch) | |
tree | 5076f909a23026f577f0479ec257c84bf125d865 | |
parent | 75438afb9c4941d8f8855edbc1da5432f9233d5b (diff) | |
download | chromium_src-e6d4e1483d679ec6bcb2a22752f72a77401e1406.zip chromium_src-e6d4e1483d679ec6bcb2a22752f72a77401e1406.tar.gz chromium_src-e6d4e1483d679ec6bcb2a22752f72a77401e1406.tar.bz2 |
Define print format macros for NSInteger & NSUInteger
The size of NSInteger and NSUInteger varies between 32-bit and 64-bit
architectures, however does not provides macro to safely format them
and instead recommend casting the value to the larger version that is
used on 64-bit architecture.
Using a cast could cause some formatting to be missed (if the type of
a variable changes), so instead we define our own macros to format those
types safely.
BUG=349458
Review URL: https://codereview.chromium.org/187793003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@255755 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/format_macros.h | 28 | ||||
-rw-r--r-- | base/mac/foundation_util_unittest.mm | 67 |
2 files changed, 95 insertions, 0 deletions
diff --git a/base/format_macros.h b/base/format_macros.h index 466d79b..4d90c59 100644 --- a/base/format_macros.h +++ b/base/format_macros.h @@ -46,6 +46,34 @@ #define PRIuS "zu" #endif +// The size of NSInteger and NSUInteger varies between 32-bit and 64-bit +// architectures and Apple does not provides standard format macros and +// recommends casting. This has many drawbacks, so instead define macros +// for formatting those types. +#if defined(OS_MACOSX) +#if defined(ARCH_CPU_64_BITS) +#if !defined(PRIdNS) +#define PRIdNS "ld" +#endif +#if !defined(PRIuNS) +#define PRIuNS "lu" +#endif +#if !defined(PRIxNS) +#define PRIxNS "lx" +#endif +#else // defined(ARCH_CPU_64_BITS) +#if !defined(PRIdNS) +#define PRIdNS "d" +#endif +#if !defined(PRIuNS) +#define PRIuNS "u" +#endif +#if !defined(PRIxNS) +#define PRIxNS "x" +#endif +#endif +#endif // defined(OS_MACOSX) + #else // OS_WIN #if !defined(PRId64) diff --git a/base/mac/foundation_util_unittest.mm b/base/mac/foundation_util_unittest.mm index 3b72b12..8bb7d0b 100644 --- a/base/mac/foundation_util_unittest.mm +++ b/base/mac/foundation_util_unittest.mm @@ -5,9 +5,12 @@ #include "base/mac/foundation_util.h" #include "base/basictypes.h" +#include "base/compiler_specific.h" #include "base/files/file_path.h" +#include "base/format_macros.h" #include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_nsautorelease_pool.h" +#include "base/strings/stringprintf.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" @@ -314,5 +317,69 @@ TEST(FoundationUtilTest, NSStringToFilePath) { EXPECT_EQ(FilePath("/a/b"), NSStringToFilePath(@"/a/b")); } +TEST(StringNumberConversionsTest, FormatNSInteger) { + // The PRI[dxu]NS macro assumes that NSInteger is a typedef to "int" on + // 32-bit architecture and a typedef to "long" on 64-bit architecture + // (respectively "unsigned int" and "unsigned long" for NSUInteger). Use + // pointer incompatibility to validate this at compilation. +#if defined(ARCH_CPU_64_BITS) + typedef long FormatNSIntegerAsType; + typedef unsigned long FormatNSUIntegerAsType; +#else + typedef int FormatNSIntegerAsType; + typedef unsigned int FormatNSUIntegerAsType; +#endif // defined(ARCH_CPU_64_BITS) + + NSInteger some_nsinteger; + FormatNSIntegerAsType* pointer_to_some_nsinteger ALLOW_UNUSED = + &some_nsinteger; + + NSUInteger some_nsuinteger; + FormatNSUIntegerAsType* pointer_to_some_nsuinteger ALLOW_UNUSED = + &some_nsuinteger; + + // Check that format specifier works correctly for NSInteger. + const struct { + NSInteger value; + const char* expected; + const char* expected_hex; + } nsinteger_cases[] = { + {12345678, "12345678", "bc614e"}, + {-12345678, "-12345678", "ff439eb2"}, +#if defined(ARCH_CPU_64_BITS) + {137451299150l, "137451299150", "2000bc614e"}, + {-137451299150l, "-137451299150", "ffffffdfff439eb2"}, +#endif + }; + + for (size_t i = 0; i < arraysize(nsinteger_cases); ++i) { + EXPECT_EQ(nsinteger_cases[i].expected, + StringPrintf("%" PRIdNS, nsinteger_cases[i].value)); + EXPECT_EQ(nsinteger_cases[i].expected_hex, + StringPrintf("%" PRIxNS, nsinteger_cases[i].value)); + } + + // Check that format specifier works correctly for NSUInteger. + const struct { + NSUInteger value; + const char* expected; + const char* expected_hex; + } nsuinteger_cases[] = { + {12345678u, "12345678", "bc614e"}, + {4282621618u, "4282621618", "ff439eb2"}, +#if defined(ARCH_CPU_64_BITS) + {137451299150ul, "137451299150", "2000bc614e"}, + {18446743936258252466ul, "18446743936258252466", "ffffffdfff439eb2"}, +#endif + }; + + for (size_t i = 0; i < arraysize(nsuinteger_cases); ++i) { + EXPECT_EQ(nsuinteger_cases[i].expected, + StringPrintf("%" PRIuNS, nsuinteger_cases[i].value)); + EXPECT_EQ(nsuinteger_cases[i].expected_hex, + StringPrintf("%" PRIxNS, nsuinteger_cases[i].value)); + } +} + } // namespace mac } // namespace base |