Since we're using floating point values at several places in the kernel, I added

a very simplistic floating point output routine to snprintf() and friends, for
your convenience.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19583 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2006-12-21 12:05:16 +00:00
parent d6edf65b05
commit dedf1bccfe
1 changed files with 86 additions and 9 deletions

View File

@ -16,6 +16,17 @@
#include <stdio.h>
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
#define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
#define FLOATING_SUPPORT
static int
skip_atoi(const char **s)
{
@ -28,15 +39,6 @@ skip_atoi(const char **s)
}
#define ZEROPAD 1 /* pad with zero */
#define SIGN 2 /* unsigned/signed long */
#define PLUS 4 /* show plus */
#define SPACE 8 /* space if plus */
#define LEFT 16 /* left justified */
#define SPECIAL 32 /* 0x */
#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
static uint64
do_div(uint64 *_number, uint32 base)
{
@ -204,6 +206,68 @@ number(char **_string, int32 *_bytesLeft, int64 num, uint32 base, int size,
}
#ifdef FLOATING_SUPPORT
/*!
This is a very basic floating point to string conversion routine.
It prints up to 3 fraction digits, and doesn't support any precision arguments.
It's just here for your convenience so that you can use it for debug output.
*/
static bool
floating(char **_string, int32 *_bytesLeft, double value, int fieldWidth, int flags)
{
char buffer[66];
bool sign = value < 0.0;
uint64 fraction;
uint64 integer;
int32 length = 0;
if (sign)
value = -value;
fraction = (uint64)(value * 1000) % 1000;
integer = (uint64)value;
// put fraction part, if any
if (fraction != 0) {
bool first = true;
while (fraction != 0) {
int digit = do_div(&fraction, 10);
if (!first || digit > 0) {
buffer[length++] = '0' + digit;
first = false;
}
}
buffer[length++] = '.';
}
// put integer part
if (integer == 0)
buffer[length++] = '0';
else while (integer != 0) {
buffer[length++] = '0' + do_div(&integer, 10);
}
// write back to string
if (!(flags & LEFT) && !put_padding(_string, _bytesLeft, fieldWidth))
return false;
while (length-- > 0) {
if (!put_character(_string, _bytesLeft, buffer[length]))
return false;
}
if ((flags & LEFT) != 0 && !put_padding(_string, _bytesLeft, fieldWidth))
return false;
return true;
}
#endif // FLOATING_SUPPORT
int
vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args)
{
@ -327,6 +391,19 @@ vsnprintf(char *buffer, size_t bufferSize, const char *format, va_list args)
continue;
}
#ifdef FLOATING_SUPPORT
case 'f':
case 'F':
case 'g':
case 'G':
{
double value = va_arg(args, double);
if (!floating(&string, &bytesLeft, value, flags, fieldWidth))
goto out;
continue;
}
#endif // FLOATING_SUPPORT
case 'p':
if (fieldWidth == -1) {
fieldWidth = 2*sizeof(void *);