[PATCH] [sanitizer] Support padding with spaces in Printf.
Sergey Matveev
earthdok at google.com
Thu Jun 27 07:22:23 PDT 2013
Hi glider, samsonov,
http://llvm-reviews.chandlerc.com/D1057
Files:
lib/sanitizer_common/sanitizer_printf.cc
lib/sanitizer_common/tests/sanitizer_printf_test.cc
Index: lib/sanitizer_common/sanitizer_printf.cc
===================================================================
--- lib/sanitizer_common/sanitizer_printf.cc
+++ lib/sanitizer_common/sanitizer_printf.cc
@@ -38,16 +38,26 @@
}
// Appends number in a given base to buffer. If its length is less than
-// "minimal_num_length", it is padded with leading zeroes.
-static int AppendUnsigned(char **buff, const char *buff_end, u64 num,
- u8 base, u8 minimal_num_length) {
+// |minimal_num_length|, it is padded with leading zeroes or spaces, depending
+// on the value of |pad_with_zero|.
+static int AppendNumber(char **buff, const char *buff_end, u64 num, u8 base,
+ u8 minimal_num_length, bool pad_with_zero,
+ bool negative) {
uptr const kMaxLen = 30;
+ bool is_zero = (num == 0);
RAW_CHECK(base == 10 || base == 16);
+ RAW_CHECK(base == 10 || !negative);
+ RAW_CHECK(!is_zero || !negative);
RAW_CHECK(minimal_num_length < kMaxLen);
+ int result = 0;
+ if (negative && minimal_num_length)
+ --minimal_num_length;
+ if (negative && pad_with_zero)
+ result += AppendChar(buff, buff_end, '-');
uptr num_buffer[kMaxLen];
- uptr pos = 0;
+ int pos = 0;
do {
- RAW_CHECK_MSG(pos < kMaxLen, "appendNumber buffer overflow");
+ RAW_CHECK_MSG((uptr)pos < kMaxLen, "AppendNumber buffer overflow");
num_buffer[pos++] = num % base;
num /= base;
} while (num > 0);
@@ -57,26 +67,37 @@
sizeof(num_buffer[0]) * (minimal_num_length - pos));
pos = minimal_num_length;
}
- int result = 0;
- while (pos-- > 0) {
+ pos--;
+ while (pos > 0 && num_buffer[pos] == 0 && num_buffer[pos-1] == 0) {
+ result += AppendChar(buff, buff_end, pad_with_zero ? '0' : ' ');
+ pos--;
+ }
+ if (num_buffer[pos] == 0) {
+ result +=
+ AppendChar(buff, buff_end, (pad_with_zero || is_zero) ? '0' : ' ');
+ pos--;
+ }
+ if (negative && !pad_with_zero) result += AppendChar(buff, buff_end, '-');
+ while (pos >= 0) {
char digit = static_cast<char>(num_buffer[pos]);
result += AppendChar(buff, buff_end, (digit < 10) ? '0' + digit
: 'a' + digit - 10);
+ pos--;
}
return result;
}
+static int AppendUnsigned(char **buff, const char *buff_end, u64 num, u8 base,
+ u8 minimal_num_length, bool pad_with_zero) {
+ return AppendNumber(buff, buff_end, num, base, minimal_num_length,
+ pad_with_zero, false /* negative */);
+}
+
static int AppendSignedDecimal(char **buff, const char *buff_end, s64 num,
- u8 minimal_num_length) {
- int result = 0;
- if (num < 0) {
- result += AppendChar(buff, buff_end, '-');
- num = -num;
- if (minimal_num_length)
- --minimal_num_length;
- }
- result += AppendUnsigned(buff, buff_end, (u64)num, 10, minimal_num_length);
- return result;
+ u8 minimal_num_length, bool pad_with_zero) {
+ bool negative = (num < 0);
+ return AppendNumber(buff, buff_end, (u64)(negative ? -num : num), 10,
+ minimal_num_length, pad_with_zero, negative);
}
static int AppendString(char **buff, const char *buff_end, const char *s) {
@@ -93,14 +114,14 @@
int result = 0;
result += AppendString(buff, buff_end, "0x");
result += AppendUnsigned(buff, buff_end, ptr_value, 16,
- (SANITIZER_WORDSIZE == 64) ? 12 : 8);
+ (SANITIZER_WORDSIZE == 64) ? 12 : 8, true);
return result;
}
int VSNPrintf(char *buff, int buff_length,
const char *format, va_list args) {
static const char *kPrintfFormatsHelp =
- "Supported Printf formats: %(0[0-9]*)?(z|ll)?{d,u,x}; %p; %s; %c\n";
+ "Supported Printf formats: %([0-9]*)?(z|ll)?{d,u,x}; %p; %s; %c\n";
RAW_CHECK(format);
RAW_CHECK(buff_length > 0);
const char *buff_end = &buff[buff_length - 1];
@@ -112,11 +133,11 @@
continue;
}
cur++;
- bool have_width = (*cur == '0');
+ bool have_width = (*cur >= '0' && *cur <= '9');
+ bool pad_with_zero = (*cur == '0');
int width = 0;
if (have_width) {
while (*cur >= '0' && *cur <= '9') {
- have_width = true;
width = width * 10 + *cur++ - '0';
}
}
@@ -132,16 +153,17 @@
dval = have_ll ? va_arg(args, s64)
: have_z ? va_arg(args, sptr)
: va_arg(args, int);
- result += AppendSignedDecimal(&buff, buff_end, dval, width);
+ result += AppendSignedDecimal(&buff, buff_end, dval, width,
+ pad_with_zero);
break;
}
case 'u':
case 'x': {
uval = have_ll ? va_arg(args, u64)
: have_z ? va_arg(args, uptr)
: va_arg(args, unsigned);
result += AppendUnsigned(&buff, buff_end, uval,
- (*cur == 'u') ? 10 : 16, width);
+ (*cur == 'u') ? 10 : 16, width, pad_with_zero);
break;
}
case 'p': {
Index: lib/sanitizer_common/tests/sanitizer_printf_test.cc
===================================================================
--- lib/sanitizer_common/tests/sanitizer_printf_test.cc
+++ lib/sanitizer_common/tests/sanitizer_printf_test.cc
@@ -122,4 +122,13 @@
TestMinMax<unsigned long>("%zx-%zx", 0, ULONG_MAX); // NOLINT
}
+TEST(Printf, Padding) {
+ TestMinMax<int>("%3d - %3d", 1, 0);
+ TestMinMax<int>("%3d - %3d", -1, 100);
+ TestMinMax<int>("%3d - %3d", -1, -100);
+ TestMinMax<int>("%03d - %03d", 1, 0);
+ TestMinMax<int>("%03d - %03d", -1, 100);
+ TestMinMax<int>("%03d - %03d", -1, -100);
+}
+
} // namespace __sanitizer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1057.1.patch
Type: text/x-patch
Size: 5790 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130627/75d448bd/attachment.bin>
More information about the llvm-commits
mailing list