From 39571b37a38d289f0895ca060eb1d6f579300af6 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Mon, 26 Jan 2015 18:21:33 +0000 Subject: [PATCH] Teach raw_ostream to support hex formatting without a prefix '0x'. Previously using format_hex() would always print a 0x prior to the hex characters. This allows this to be optional, so that one can choose to print (e.g.) 255 as either 0xFF or just FF. Differential Revision: http://reviews.llvm.org/D7151 llvm-svn: 227108 --- llvm/include/llvm/Support/Format.h | 35 +++++++++++++++++++++-------- llvm/lib/Support/raw_ostream.cpp | 7 ++++-- llvm/unittests/Support/raw_ostream_test.cpp | 2 ++ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/llvm/include/llvm/Support/Format.h b/llvm/include/llvm/Support/Format.h index 5d599e9..86904ad 100644 --- a/llvm/include/llvm/Support/Format.h +++ b/llvm/include/llvm/Support/Format.h @@ -259,21 +259,38 @@ class FormattedNumber { unsigned Width; bool Hex; bool Upper; + bool HexPrefix; friend class raw_ostream; public: - FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U) - : HexValue(HV), DecValue(DV), Width(W), Hex(H), Upper(U) { } + FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U, + bool Prefix) + : HexValue(HV), DecValue(DV), Width(W), Hex(H), Upper(U), + HexPrefix(Prefix) {} }; /// format_hex - Output \p N as a fixed width hexadecimal. If number will not /// fit in width, full number is still printed. Examples: -/// OS << format_hex(255, 4) => 0xff -/// OS << format_hex(255, 4, true) => 0xFF -/// OS << format_hex(255, 6) => 0x00ff -/// OS << format_hex(255, 2) => 0xff -inline FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false) { +/// OS << format_hex(255, 4) => 0xff +/// OS << format_hex(255, 4, true) => 0xFF +/// OS << format_hex(255, 6) => 0x00ff +/// OS << format_hex(255, 2) => 0xff +inline FormattedNumber format_hex(uint64_t N, unsigned Width, + bool Upper = false) { assert(Width <= 18 && "hex width must be <= 18"); - return FormattedNumber(N, 0, Width, true, Upper); + return FormattedNumber(N, 0, Width, true, Upper, true); +} + +/// format_hex_no_prefix - Output \p N as a fixed width hexadecimal. Does not +/// prepend '0x' to the outputted string. If number will not fit in width, +/// full number is still printed. Examples: +/// OS << format_hex_no_prefix(255, 4) => ff +/// OS << format_hex_no_prefix(255, 4, true) => FF +/// OS << format_hex_no_prefix(255, 6) => 00ff +/// OS << format_hex_no_prefix(255, 2) => ff +inline FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, + bool Upper = false) { + assert(Width <= 18 && "hex width must be <= 18"); + return FormattedNumber(N, 0, Width, true, Upper, false); } /// format_decimal - Output \p N as a right justified, fixed-width decimal. If @@ -283,7 +300,7 @@ inline FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false) /// OS << format_decimal(-1, 3) => " -1" /// OS << format_decimal(12345, 3) => "12345" inline FormattedNumber format_decimal(int64_t N, unsigned Width) { - return FormattedNumber(0, N, Width, false, false); + return FormattedNumber(0, N, Width, false, false, false); } diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp index 1bcc31b..aa618b9 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -410,9 +410,12 @@ raw_ostream &raw_ostream::operator<<(const FormattedString &FS) { raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) { if (FN.Hex) { unsigned Nibbles = (64 - countLeadingZeros(FN.HexValue)+3)/4; - unsigned Width = (FN.Width > Nibbles+2) ? FN.Width : Nibbles+2; - + unsigned PrefixChars = FN.HexPrefix ? 2 : 0; + unsigned Width = std::max(FN.Width, Nibbles + PrefixChars); + char NumberBuffer[20] = "0x0000000000000000"; + if (!FN.HexPrefix) + NumberBuffer[1] = '0'; char *EndPtr = NumberBuffer+Width; char *CurPtr = EndPtr; const char A = FN.Upper ? 'A' : 'a'; diff --git a/llvm/unittests/Support/raw_ostream_test.cpp b/llvm/unittests/Support/raw_ostream_test.cpp index 39cfaf0..ff98602 100644 --- a/llvm/unittests/Support/raw_ostream_test.cpp +++ b/llvm/unittests/Support/raw_ostream_test.cpp @@ -162,6 +162,8 @@ TEST(raw_ostreamTest, FormatHex) { EXPECT_EQ("0x1", printToString(format_hex(1, 3), 3)); EXPECT_EQ("0x12", printToString(format_hex(0x12, 3), 4)); EXPECT_EQ("0x123", printToString(format_hex(0x123, 3), 5)); + EXPECT_EQ("FF", printToString(format_hex_no_prefix(0xFF, 2, true), 4)); + EXPECT_EQ("ABCD", printToString(format_hex_no_prefix(0xABCD, 2, true), 4)); EXPECT_EQ("0xffffffffffffffff", printToString(format_hex(UINT64_MAX, 18), 18)); EXPECT_EQ("0x8000000000000000", -- 2.7.4