Moved number() closer to vsnprintf() because it'll need the put_*() functions

once it's fixed.
Renamed some variables.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5407 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2003-11-18 04:02:59 +00:00
parent ac3863db5e
commit c29da59747
+124 -126
View File
@@ -79,81 +79,6 @@ do_div(uint64 *_number, uint32 base)
} }
static char *
number(char *str, long long num, unsigned base, int size, int precision, int type)
{
const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
char c, sign, tmp[66];
int i;
if (type & LARGE)
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (type & LEFT)
type &= ~ZEROPAD;
if (base < 2 || base > 36)
return 0;
c = (type & ZEROPAD) ? '0' : ' ';
sign = 0;
if (type & SIGN) {
if (num < 0) {
sign = '-';
num = -num;
size--;
} else if (type & PLUS) {
sign = '+';
size--;
} else if (type & SPACE) {
sign = ' ';
size--;
}
}
if (type & SPECIAL) {
if (base == 16)
size -= 2;
else if (base == 8)
size--;
}
i = 0;
if (num == 0)
tmp[i++] = '0';
else while (num != 0)
tmp[i++] = digits[do_div(&num, base)];
if (i > precision)
precision = i;
size -= precision;
if (!(type&(ZEROPAD + LEFT))) {
while (size-- > 0)
*str++ = ' ';
}
if (sign)
*str++ = sign;
if (type & SPECIAL) {
if (base == 8)
*str++ = '0';
else if (base == 16) {
*str++ = '0';
*str++ = digits[33];
}
}
if (!(type & LEFT))
while (size-- > 0)
*str++ = c;
while (i < precision--)
*str++ = '0';
while (i-- > 0)
*str++ = tmp[i];
while (size-- > 0)
*str++ = ' ';
return str;
}
static bool static bool
put_padding(char **_buffer, size_t *_bytesLeft, int32 count) put_padding(char **_buffer, size_t *_bytesLeft, int32 count)
{ {
@@ -236,14 +161,89 @@ put_character(char **_buffer, size_t *_bytesLeft, char c)
} }
static char *
number(char *str, long long num, unsigned base, int size, int precision, int type)
{
const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
char c, sign, tmp[66];
int i;
if (type & LARGE)
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (type & LEFT)
type &= ~ZEROPAD;
if (base < 2 || base > 36)
return 0;
c = (type & ZEROPAD) ? '0' : ' ';
sign = 0;
if (type & SIGN) {
if (num < 0) {
sign = '-';
num = -num;
size--;
} else if (type & PLUS) {
sign = '+';
size--;
} else if (type & SPACE) {
sign = ' ';
size--;
}
}
if (type & SPECIAL) {
if (base == 16)
size -= 2;
else if (base == 8)
size--;
}
i = 0;
if (num == 0)
tmp[i++] = '0';
else while (num != 0)
tmp[i++] = digits[do_div(&num, base)];
if (i > precision)
precision = i;
size -= precision;
if (!(type&(ZEROPAD + LEFT))) {
while (size-- > 0)
*str++ = ' ';
}
if (sign)
*str++ = sign;
if (type & SPECIAL) {
if (base == 8)
*str++ = '0';
else if (base == 16) {
*str++ = '0';
*str++ = digits[33];
}
}
if (!(type & LEFT))
while (size-- > 0)
*str++ = c;
while (i < precision--)
*str++ = '0';
while (i-- > 0)
*str++ = tmp[i];
while (size-- > 0)
*str++ = ' ';
return str;
}
int int
vsnprintf(char *buffer, size_t bytesLeft, const char *fmt, va_list args) vsnprintf(char *buffer, size_t bytesLeft, const char *format, va_list args)
{ {
uint64 num; uint64 num;
int base; int base;
char *str; char *string;
int flags; /* flags to number() */ int flags; /* flags to number() */
int field_width; /* width of output field */ int fieldWidth; /* width of output field */
int precision; int precision;
/* min. # of digits for integers; max number of chars for from string */ /* min. # of digits for integers; max number of chars for from string */
int qualifier; /* 'h', 'l', or 'L' for integer fields */ int qualifier; /* 'h', 'l', or 'L' for integer fields */
@@ -251,9 +251,9 @@ vsnprintf(char *buffer, size_t bytesLeft, const char *fmt, va_list args)
bytesLeft--; bytesLeft--;
// make space for the terminating '\0' byte // make space for the terminating '\0' byte
for (str = buffer; fmt[0] && bytesLeft > 0; fmt++) { for (string = buffer; format[0] && bytesLeft > 0; format++) {
if (fmt[0] != '%') { if (format[0] != '%') {
if (!put_character(&str, &bytesLeft, fmt[0])) if (!put_character(&string, &bytesLeft, format[0]))
break; break;
continue; continue;
@@ -264,8 +264,8 @@ vsnprintf(char *buffer, size_t bytesLeft, const char *fmt, va_list args)
flags = 0; flags = 0;
repeat: repeat:
++fmt; /* this also skips first '%' */ ++format; /* this also skips first '%' */
switch (fmt[0]) { switch (format[0]) {
case '-': flags |= LEFT; goto repeat; case '-': flags |= LEFT; goto repeat;
case '+': flags |= PLUS; goto repeat; case '+': flags |= PLUS; goto repeat;
case ' ': flags |= SPACE; goto repeat; case ' ': flags |= SPACE; goto repeat;
@@ -275,15 +275,15 @@ vsnprintf(char *buffer, size_t bytesLeft, const char *fmt, va_list args)
/* get field width */ /* get field width */
field_width = -1; fieldWidth = -1;
if (isdigit(*fmt)) if (isdigit(*format))
field_width = skip_atoi(&fmt); fieldWidth = skip_atoi(&format);
else if (fmt[0] == '*') { else if (format[0] == '*') {
++fmt; ++format;
/* it's the next argument */ /* it's the next argument */
field_width = va_arg(args, int); fieldWidth = va_arg(args, int);
if (field_width < 0) { if (fieldWidth < 0) {
field_width = -field_width; fieldWidth = -fieldWidth;
flags |= LEFT; flags |= LEFT;
} }
} }
@@ -291,12 +291,12 @@ vsnprintf(char *buffer, size_t bytesLeft, const char *fmt, va_list args)
/* get the precision */ /* get the precision */
precision = -1; precision = -1;
if (fmt[0] == '.') { if (format[0] == '.') {
++fmt; ++format;
if (isdigit(*fmt)) if (isdigit(*format))
precision = skip_atoi(&fmt); precision = skip_atoi(&format);
else if (fmt[0] == '*') { else if (format[0] == '*') {
++fmt; ++format;
/* it's the next argument */ /* it's the next argument */
precision = va_arg(args, int); precision = va_arg(args, int);
} }
@@ -307,22 +307,20 @@ vsnprintf(char *buffer, size_t bytesLeft, const char *fmt, va_list args)
/* get the conversion qualifier */ /* get the conversion qualifier */
qualifier = -1; qualifier = -1;
if (fmt[0] == 'h' || fmt[0] == 'l' || fmt[0] == 'L') { if (format[0] == 'h' || format[0] == 'l' || format[0] == 'L')
qualifier = fmt[0]; qualifier = *format++;
++fmt;
}
/* default base */ /* default base */
base = 10; base = 10;
switch (fmt[0]) { switch (format[0]) {
case 'c': case 'c':
if (!(flags & LEFT) && !put_padding(&str, &bytesLeft, field_width)) if (!(flags & LEFT) && !put_padding(&string, &bytesLeft, fieldWidth))
goto out; goto out;
put_character(&str, &bytesLeft, (char)va_arg(args, int)); put_character(&string, &bytesLeft, (char)va_arg(args, int));
if ((flags & LEFT) != 0 && !put_padding(&str, &bytesLeft, field_width)) if ((flags & LEFT) != 0 && !put_padding(&string, &bytesLeft, fieldWidth))
goto out; goto out;
continue; continue;
@@ -336,37 +334,37 @@ vsnprintf(char *buffer, size_t bytesLeft, const char *fmt, va_list args)
length = strnlen(argument, precision); length = strnlen(argument, precision);
if (!(flags & LEFT) && !put_padding(&str, &bytesLeft, field_width)) if (!(flags & LEFT) && !put_padding(&string, &bytesLeft, fieldWidth))
goto out; goto out;
if (!put_string(&str, &bytesLeft, argument, length)) if (!put_string(&string, &bytesLeft, argument, length))
goto out; goto out;
if ((flags & LEFT) != 0 && !put_padding(&str, &bytesLeft, field_width)) if ((flags & LEFT) != 0 && !put_padding(&string, &bytesLeft, fieldWidth))
goto out; goto out;
continue; continue;
} }
case 'p': case 'p':
if (field_width == -1) { if (fieldWidth == -1) {
field_width = 2*sizeof(void *); fieldWidth = 2*sizeof(void *);
flags |= ZEROPAD; flags |= ZEROPAD;
} }
// ToDo: fix me! // ToDo: fix me!
str[0] = '0'; string[0] = '0';
str[1] = 'x'; string[1] = 'x';
str = number(str + 2, (uint32)va_arg(args, void *), 16, string = number(string + 2, (uint32)va_arg(args, void *), 16,
field_width, precision, flags); fieldWidth, precision, flags);
continue; continue;
case 'n': case 'n':
if (qualifier == 'l') { if (qualifier == 'l') {
long *ip = va_arg(args, long *); long *ip = va_arg(args, long *);
*ip = (str - buffer); *ip = (string - buffer);
} else { } else {
int *ip = va_arg(args, int *); int *ip = va_arg(args, int *);
*ip = (str - buffer); *ip = (string - buffer);
} }
continue; continue;
@@ -388,13 +386,13 @@ vsnprintf(char *buffer, size_t bytesLeft, const char *fmt, va_list args)
break; break;
default: default:
if (fmt[0] != '%') if (format[0] != '%')
put_character(&str, &bytesLeft, '%'); put_character(&string, &bytesLeft, '%');
if (!fmt[0]) if (!format[0])
goto out; goto out;
put_character(&str, &bytesLeft, fmt[0]); put_character(&string, &bytesLeft, format[0]);
continue; continue;
} }
@@ -403,23 +401,23 @@ vsnprintf(char *buffer, size_t bytesLeft, const char *fmt, va_list args)
else if (qualifier == 'l') { else if (qualifier == 'l') {
num = va_arg(args, unsigned long); num = va_arg(args, unsigned long);
if (flags & SIGN) if (flags & SIGN)
num = (long) num; num = (long)num;
} else if (qualifier == 'h') { } else if (qualifier == 'h') {
num = (unsigned short) va_arg(args, int); num = (unsigned short)va_arg(args, int);
if (flags & SIGN) if (flags & SIGN)
num = (short) num; num = (short)num;
} else if (flags & SIGN) } else if (flags & SIGN)
num = va_arg(args, int); num = va_arg(args, int);
else else
num = va_arg(args, unsigned int); num = va_arg(args, unsigned int);
// ToDo: fix me! // ToDo: fix me!
str = number(str, num, base, field_width, precision, flags); string = number(string, num, base, fieldWidth, precision, flags);
} }
out: out:
*str = '\0'; *string = '\0';
return str - buffer; return string - buffer;
} }