diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:22 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:22 +0000 |
commit | 3a1720af1d7f43edc5b214cde0be11bfb94d077e (patch) | |
tree | 029e0ff2d5e3c0eaf2405fd8e669555fdf5e1297 /lib/scudo/standalone/string_utils.cc | |
parent | 8f3cadc28cb2bb9e8f9d69eeaaea1f57f2f7b2ab (diff) |
Notes
Diffstat (limited to 'lib/scudo/standalone/string_utils.cc')
-rw-r--r-- | lib/scudo/standalone/string_utils.cc | 236 |
1 files changed, 0 insertions, 236 deletions
diff --git a/lib/scudo/standalone/string_utils.cc b/lib/scudo/standalone/string_utils.cc deleted file mode 100644 index f0068afc1e8b2..0000000000000 --- a/lib/scudo/standalone/string_utils.cc +++ /dev/null @@ -1,236 +0,0 @@ -//===-- string_utils.cc -----------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "string_utils.h" -#include "common.h" - -#include <ctype.h> -#include <stdarg.h> -#include <string.h> - -namespace scudo { - -static int appendChar(char **Buffer, const char *BufferEnd, char C) { - if (*Buffer < BufferEnd) { - **Buffer = C; - (*Buffer)++; - } - return 1; -} - -// Appends number in a given Base to buffer. If its length is less than -// |MinNumberLength|, it is padded with leading zeroes or spaces, depending -// on the value of |PadWithZero|. -static int appendNumber(char **Buffer, const char *BufferEnd, u64 AbsoluteValue, - u8 Base, u8 MinNumberLength, bool PadWithZero, - bool Negative, bool Upper) { - constexpr uptr MaxLen = 30; - RAW_CHECK(Base == 10 || Base == 16); - RAW_CHECK(Base == 10 || !Negative); - RAW_CHECK(AbsoluteValue || !Negative); - RAW_CHECK(MinNumberLength < MaxLen); - int Res = 0; - if (Negative && MinNumberLength) - --MinNumberLength; - if (Negative && PadWithZero) - Res += appendChar(Buffer, BufferEnd, '-'); - uptr NumBuffer[MaxLen]; - int Pos = 0; - do { - RAW_CHECK_MSG(static_cast<uptr>(Pos) < MaxLen, - "appendNumber buffer overflow"); - NumBuffer[Pos++] = AbsoluteValue % Base; - AbsoluteValue /= Base; - } while (AbsoluteValue > 0); - if (Pos < MinNumberLength) { - memset(&NumBuffer[Pos], 0, - sizeof(NumBuffer[0]) * static_cast<uptr>(MinNumberLength - Pos)); - Pos = MinNumberLength; - } - RAW_CHECK(Pos > 0); - Pos--; - for (; Pos >= 0 && NumBuffer[Pos] == 0; Pos--) { - char c = (PadWithZero || Pos == 0) ? '0' : ' '; - Res += appendChar(Buffer, BufferEnd, c); - } - if (Negative && !PadWithZero) - Res += appendChar(Buffer, BufferEnd, '-'); - for (; Pos >= 0; Pos--) { - char Digit = static_cast<char>(NumBuffer[Pos]); - Digit = static_cast<char>((Digit < 10) ? '0' + Digit - : (Upper ? 'A' : 'a') + Digit - 10); - Res += appendChar(Buffer, BufferEnd, Digit); - } - return Res; -} - -static int appendUnsigned(char **Buffer, const char *BufferEnd, u64 Num, - u8 Base, u8 MinNumberLength, bool PadWithZero, - bool Upper) { - return appendNumber(Buffer, BufferEnd, Num, Base, MinNumberLength, - PadWithZero, /*Negative=*/false, Upper); -} - -static int appendSignedDecimal(char **Buffer, const char *BufferEnd, s64 Num, - u8 MinNumberLength, bool PadWithZero) { - const bool Negative = (Num < 0); - return appendNumber(Buffer, BufferEnd, - static_cast<u64>(Negative ? -Num : Num), 10, - MinNumberLength, PadWithZero, Negative, - /*Upper=*/false); -} - -// Use the fact that explicitly requesting 0 Width (%0s) results in UB and -// interpret Width == 0 as "no Width requested": -// Width == 0 - no Width requested -// Width < 0 - left-justify S within and pad it to -Width chars, if necessary -// Width > 0 - right-justify S, not implemented yet -static int appendString(char **Buffer, const char *BufferEnd, int Width, - int MaxChars, const char *S) { - if (!S) - S = "<null>"; - int Res = 0; - for (; *S; S++) { - if (MaxChars >= 0 && Res >= MaxChars) - break; - Res += appendChar(Buffer, BufferEnd, *S); - } - // Only the left justified strings are supported. - while (Width < -Res) - Res += appendChar(Buffer, BufferEnd, ' '); - return Res; -} - -static int appendPointer(char **Buffer, const char *BufferEnd, u64 ptr_value) { - int Res = 0; - Res += appendString(Buffer, BufferEnd, 0, -1, "0x"); - Res += appendUnsigned(Buffer, BufferEnd, ptr_value, 16, - SCUDO_POINTER_FORMAT_LENGTH, /*PadWithZero=*/true, - /*Upper=*/false); - return Res; -} - -int formatString(char *Buffer, uptr BufferLength, const char *Format, - va_list Args) { - UNUSED static const char *PrintfFormatsHelp = - "Supported formatString formats: %([0-9]*)?(z|ll)?{d,u,x,X}; %p; " - "%[-]([0-9]*)?(\\.\\*)?s; %c\n"; - RAW_CHECK(Format); - RAW_CHECK(BufferLength > 0); - const char *BufferEnd = &Buffer[BufferLength - 1]; - const char *Cur = Format; - int Res = 0; - for (; *Cur; Cur++) { - if (*Cur != '%') { - Res += appendChar(&Buffer, BufferEnd, *Cur); - continue; - } - Cur++; - const bool LeftJustified = *Cur == '-'; - if (LeftJustified) - Cur++; - bool HaveWidth = (*Cur >= '0' && *Cur <= '9'); - const bool PadWithZero = (*Cur == '0'); - u8 Width = 0; - if (HaveWidth) { - while (*Cur >= '0' && *Cur <= '9') - Width = static_cast<u8>(Width * 10 + *Cur++ - '0'); - } - const bool HavePrecision = (Cur[0] == '.' && Cur[1] == '*'); - int Precision = -1; - if (HavePrecision) { - Cur += 2; - Precision = va_arg(Args, int); - } - const bool HaveZ = (*Cur == 'z'); - Cur += HaveZ; - const bool HaveLL = !HaveZ && (Cur[0] == 'l' && Cur[1] == 'l'); - Cur += HaveLL * 2; - s64 DVal; - u64 UVal; - const bool HaveLength = HaveZ || HaveLL; - const bool HaveFlags = HaveWidth || HaveLength; - // At the moment only %s supports precision and left-justification. - CHECK(!((Precision >= 0 || LeftJustified) && *Cur != 's')); - switch (*Cur) { - case 'd': { - DVal = HaveLL ? va_arg(Args, s64) - : HaveZ ? va_arg(Args, sptr) : va_arg(Args, int); - Res += appendSignedDecimal(&Buffer, BufferEnd, DVal, Width, PadWithZero); - break; - } - case 'u': - case 'x': - case 'X': { - UVal = HaveLL ? va_arg(Args, u64) - : HaveZ ? va_arg(Args, uptr) : va_arg(Args, unsigned); - const bool Upper = (*Cur == 'X'); - Res += appendUnsigned(&Buffer, BufferEnd, UVal, (*Cur == 'u') ? 10 : 16, - Width, PadWithZero, Upper); - break; - } - case 'p': { - RAW_CHECK_MSG(!HaveFlags, PrintfFormatsHelp); - Res += appendPointer(&Buffer, BufferEnd, va_arg(Args, uptr)); - break; - } - case 's': { - RAW_CHECK_MSG(!HaveLength, PrintfFormatsHelp); - // Only left-justified Width is supported. - CHECK(!HaveWidth || LeftJustified); - Res += appendString(&Buffer, BufferEnd, LeftJustified ? -Width : Width, - Precision, va_arg(Args, char *)); - break; - } - case 'c': { - RAW_CHECK_MSG(!HaveFlags, PrintfFormatsHelp); - Res += - appendChar(&Buffer, BufferEnd, static_cast<char>(va_arg(Args, int))); - break; - } - case '%': { - RAW_CHECK_MSG(!HaveFlags, PrintfFormatsHelp); - Res += appendChar(&Buffer, BufferEnd, '%'); - break; - } - default: { - RAW_CHECK_MSG(false, PrintfFormatsHelp); - } - } - } - RAW_CHECK(Buffer <= BufferEnd); - appendChar(&Buffer, BufferEnd + 1, '\0'); - return Res; -} - -void ScopedString::append(const char *Format, va_list Args) { - CHECK_LT(Length, String.size()); - formatString(String.data() + Length, String.size() - Length, Format, Args); - Length += strlen(String.data() + Length); - CHECK_LT(Length, String.size()); -} - -FORMAT(2, 3) -void ScopedString::append(const char *Format, ...) { - va_list Args; - va_start(Args, Format); - append(Format, Args); - va_end(Args); -} - -FORMAT(1, 2) -void Printf(const char *Format, ...) { - va_list Args; - va_start(Args, Format); - ScopedString Msg(512); - Msg.append(Format, Args); - outputRaw(Msg.data()); - va_end(Args); -} - -} // namespace scudo |