Fix format_number.

I broke this the other day when silencing x86 gcc warnings.

Bug: 7904160
Change-Id: I8e60cc1f8cbaff95248c8738d84e515413d839e4
This commit is contained in:
Elliott Hughes 2012-12-20 18:59:05 -08:00
parent 4b58214205
commit eababde214

View File

@ -30,14 +30,16 @@
// compile under GCC 4.7 // compile under GCC 4.7
#undef _FORTIFY_SOURCE #undef _FORTIFY_SOURCE
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdint.h>
#include <stddef.h>
#include "linker_format.h" #include "linker_format.h"
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include "linker_debug.h" #include "linker_debug.h"
/* define UNIT_TESTS to build this file as a single executable that runs /* define UNIT_TESTS to build this file as a single executable that runs
@ -357,49 +359,49 @@ parse_decimal(const char *format, int *ppos)
return result; return result;
} }
/* write an octal/decimal/number into a bounded buffer. // Writes number 'value' in base 'base' into buffer 'buf' of size 'buf_size' bytes.
* assumes that bufsize > 0, and 'digits' is a string of // Assumes that buf_size > 0.
* digits of at least 'base' values. static void format_number(char* buf, size_t buf_size, uint64_t value, int base, bool caps) {
*/ char* p = buf;
static void char* end = buf + buf_size - 1;
format_number(char *buffer, size_t bufsize, uint64_t value, int base, const char *digits)
{
char *pos = buffer;
char *end = buffer + bufsize - 1;
/* generate digit string in reverse order */ // Generate digit string in reverse order.
while (value) { while (value) {
unsigned d = value % base; unsigned d = value % base;
value /= base; value /= base;
if (pos != end) { if (p != end) {
*pos++ = digits[d]; char ch;
} if (d < 10) {
ch = '0' + d;
} else {
ch = (caps ? 'A' : 'a') + (d - 10);
}
*p++ = ch;
} }
}
/* special case for 0 */ // Special case for 0.
if (pos == buffer) { if (p == buf) {
if (pos != end) { if (p != end) {
*pos++ = '0'; *p++ = '0';
}
} }
pos[0] = '\0'; }
*p = '\0';
/* now reverse digit string in-place */ // Reverse digit string in-place.
end = pos - 1; size_t length = p - buf;
pos = buffer; for (size_t i = 0, j = length - 1; i < j; ++i, --j) {
while (pos != end) { char ch = buf[i];
int ch = pos[0]; buf[i] = buf[j];
pos[0] = end[0]; buf[j] = ch;
end[0] = (char) ch; }
pos++;
end--;
}
} }
/* Write an integer (octal or decimal) into a buffer, assumes buffsize > 2 */ /* Write an integer (octal or decimal) into a buffer, assumes buffsize > 2 */
static void static void
format_integer(char *buffer, size_t buffsize, uint64_t value, int base, int isSigned) format_integer(char *buffer, size_t buffsize, uint64_t value, int base, int isSigned)
{ {
// TODO: this is incorrect for MIN_INT.
if (isSigned && (int64_t)value < 0) { if (isSigned && (int64_t)value < 0) {
buffer[0] = '-'; buffer[0] = '-';
buffer += 1; buffer += 1;
@ -407,17 +409,12 @@ format_integer(char *buffer, size_t buffsize, uint64_t value, int base, int isSi
value = (uint64_t)(-(int64_t)value); value = (uint64_t)(-(int64_t)value);
} }
format_number(buffer, buffsize, value, base, "0123456789"); format_number(buffer, buffsize, value, base, false);
} }
/* Write an hexadecimal into a buffer, isCap is true for capital alphas. // Assumes buf_size > 2.
* Assumes bufsize > 2 */ static void format_hex(char* buf, size_t buf_size, uint64_t value, bool caps) {
static void format_number(buf, buf_size, value, 16, caps);
format_hex(char *buffer, size_t buffsize, uint64_t value, int isCap)
{
const char *digits = isCap ? "0123456789ABCDEF" : "0123456789abcdef";
format_number(buffer, buffsize, value, 16, digits);
} }
@ -543,7 +540,7 @@ out_vformat(Out *o, const char *format, va_list args)
uint64_t value = (uintptr_t) va_arg(args, void*); uint64_t value = (uintptr_t) va_arg(args, void*);
buffer[0] = '0'; buffer[0] = '0';
buffer[1] = 'x'; buffer[1] = 'x';
format_hex(buffer + 2, sizeof buffer-2, value, 0); format_hex(buffer + 2, sizeof buffer-2, value, false);
str = buffer; str = buffer;
} else { } else {
/* integers - first read value from stack */ /* integers - first read value from stack */