Enhancements to chprintf().
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12821 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
05c9b4ccb2
commit
e3e1081b51
|
@ -54,8 +54,9 @@ static char *long_to_string_with_divisor(char *p,
|
||||||
do {
|
do {
|
||||||
i = (int)(l % radix);
|
i = (int)(l % radix);
|
||||||
i += '0';
|
i += '0';
|
||||||
if (i > '9')
|
if (i > '9') {
|
||||||
i += 'A' - '0' - 10;
|
i += 'A' - '0' - 10;
|
||||||
|
}
|
||||||
*--q = i;
|
*--q = i;
|
||||||
l /= radix;
|
l /= radix;
|
||||||
} while ((ll /= radix) != 0);
|
} while ((ll /= radix) != 0);
|
||||||
|
@ -81,14 +82,16 @@ static const long pow10[FLOAT_PRECISION] = {
|
||||||
static char *ftoa(char *p, double num, unsigned long precision) {
|
static char *ftoa(char *p, double num, unsigned long precision) {
|
||||||
long l;
|
long l;
|
||||||
|
|
||||||
if ((precision == 0) || (precision > FLOAT_PRECISION))
|
if ((precision == 0) || (precision > FLOAT_PRECISION)) {
|
||||||
precision = FLOAT_PRECISION;
|
precision = FLOAT_PRECISION;
|
||||||
|
}
|
||||||
precision = pow10[precision - 1];
|
precision = pow10[precision - 1];
|
||||||
|
|
||||||
l = (long)num;
|
l = (long)num;
|
||||||
p = long_to_string_with_divisor(p, l, 10, 0);
|
p = long_to_string_with_divisor(p, l, 10, 0);
|
||||||
*p++ = '.';
|
*p++ = '.';
|
||||||
l = (long)((num - l) * precision);
|
l = (long)((num - l) * precision);
|
||||||
|
|
||||||
return long_to_string_with_divisor(p, l, 10, precision / 10);
|
return long_to_string_with_divisor(p, l, 10, precision / 10);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -123,7 +126,7 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
|
||||||
char *p, *s, c, filler;
|
char *p, *s, c, filler;
|
||||||
int i, precision, width;
|
int i, precision, width;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
bool is_long, left_align;
|
bool is_long, left_align, do_sign;
|
||||||
long l;
|
long l;
|
||||||
#if CHPRINTF_USE_FLOAT
|
#if CHPRINTF_USE_FLOAT
|
||||||
float f;
|
float f;
|
||||||
|
@ -134,58 +137,99 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
c = *fmt++;
|
c = *fmt++;
|
||||||
if (c == 0)
|
if (c == 0) {
|
||||||
return n;
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
if (c != '%') {
|
if (c != '%') {
|
||||||
streamPut(chp, (uint8_t)c);
|
streamPut(chp, (uint8_t)c);
|
||||||
n++;
|
n++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = tmpbuf;
|
p = tmpbuf;
|
||||||
s = tmpbuf;
|
s = tmpbuf;
|
||||||
left_align = FALSE;
|
|
||||||
|
/* Alignment mode.*/
|
||||||
|
left_align = false;
|
||||||
if (*fmt == '-') {
|
if (*fmt == '-') {
|
||||||
fmt++;
|
fmt++;
|
||||||
left_align = TRUE;
|
left_align = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sign mode.*/
|
||||||
|
do_sign = false;
|
||||||
|
if (*fmt == '+') {
|
||||||
|
fmt++;
|
||||||
|
do_sign = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Filler mode.*/
|
||||||
filler = ' ';
|
filler = ' ';
|
||||||
if (*fmt == '0') {
|
if (*fmt == '0') {
|
||||||
fmt++;
|
fmt++;
|
||||||
filler = '0';
|
filler = '0';
|
||||||
}
|
}
|
||||||
width = 0;
|
|
||||||
while (TRUE) {
|
/* Width modifier.*/
|
||||||
c = *fmt++;
|
if (c == '*') {
|
||||||
if (c >= '0' && c <= '9')
|
width = va_arg(ap, int);
|
||||||
c -= '0';
|
|
||||||
else if (c == '*')
|
|
||||||
c = va_arg(ap, int);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
width = width * 10 + c;
|
|
||||||
}
|
}
|
||||||
precision = 0;
|
else {
|
||||||
if (c == '.') {
|
width = 0;
|
||||||
while (TRUE) {
|
while (true) {
|
||||||
c = *fmt++;
|
c = *fmt++;
|
||||||
if (c >= '0' && c <= '9')
|
if (c == 0) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
c -= '0';
|
c -= '0';
|
||||||
else if (c == '*')
|
width = width * 10 + c;
|
||||||
c = va_arg(ap, int);
|
}
|
||||||
else
|
else {
|
||||||
break;
|
break;
|
||||||
precision *= 10;
|
}
|
||||||
precision += c;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Precision modifier.*/
|
||||||
|
precision = 0;
|
||||||
|
if (c == '.') {
|
||||||
|
c = *fmt++;
|
||||||
|
if (c == 0) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
if (c == '*') {
|
||||||
|
precision = va_arg(ap, int);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (true) {
|
||||||
|
c = *fmt++;
|
||||||
|
if (c == 0) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
|
c -= '0';
|
||||||
|
precision = precision * 10 + c;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Long modifier.*/
|
/* Long modifier.*/
|
||||||
if (c == 'l' || c == 'L') {
|
if (c == 'l' || c == 'L') {
|
||||||
is_long = TRUE;
|
is_long = true;
|
||||||
if (*fmt)
|
c = *fmt++;
|
||||||
c = *fmt++;
|
if (c == 0) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
is_long = (c >= 'A') && (c <= 'Z');
|
is_long = (c >= 'A') && (c <= 'Z');
|
||||||
|
}
|
||||||
|
|
||||||
/* Command decoding.*/
|
/* Command decoding.*/
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
@ -195,10 +239,12 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
filler = ' ';
|
filler = ' ';
|
||||||
if ((s = va_arg(ap, char *)) == 0)
|
if ((s = va_arg(ap, char *)) == 0) {
|
||||||
s = "(null)";
|
s = "(null)";
|
||||||
if (precision == 0)
|
}
|
||||||
|
if (precision == 0) {
|
||||||
precision = 32767;
|
precision = 32767;
|
||||||
|
}
|
||||||
for (p = s; *p && (--precision >= 0); p++)
|
for (p = s; *p && (--precision >= 0); p++)
|
||||||
;
|
;
|
||||||
break;
|
break;
|
||||||
|
@ -206,14 +252,20 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'I':
|
case 'I':
|
||||||
case 'i':
|
case 'i':
|
||||||
if (is_long)
|
if (is_long) {
|
||||||
l = va_arg(ap, long);
|
l = va_arg(ap, long);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
l = va_arg(ap, int);
|
l = va_arg(ap, int);
|
||||||
|
}
|
||||||
if (l < 0) {
|
if (l < 0) {
|
||||||
*p++ = '-';
|
*p++ = '-';
|
||||||
l = -l;
|
l = -l;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if (do_sign) {
|
||||||
|
*p++ = '+';
|
||||||
|
}
|
||||||
p = ch_ltoa(p, l, 10);
|
p = ch_ltoa(p, l, 10);
|
||||||
break;
|
break;
|
||||||
#if CHPRINTF_USE_FLOAT
|
#if CHPRINTF_USE_FLOAT
|
||||||
|
@ -223,6 +275,11 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
|
||||||
*p++ = '-';
|
*p++ = '-';
|
||||||
f = -f;
|
f = -f;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (do_sign) {
|
||||||
|
*p++ = '+';
|
||||||
|
}
|
||||||
|
}
|
||||||
p = ftoa(p, f, precision);
|
p = ftoa(p, f, precision);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -238,10 +295,12 @@ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) {
|
||||||
case 'o':
|
case 'o':
|
||||||
c = 8;
|
c = 8;
|
||||||
unsigned_common:
|
unsigned_common:
|
||||||
if (is_long)
|
if (is_long) {
|
||||||
l = va_arg(ap, unsigned long);
|
l = va_arg(ap, unsigned long);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
l = va_arg(ap, unsigned int);
|
l = va_arg(ap, unsigned int);
|
||||||
|
}
|
||||||
p = ch_ltoa(p, l, c);
|
p = ch_ltoa(p, l, c);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -249,10 +308,12 @@ unsigned_common:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i = (int)(p - s);
|
i = (int)(p - s);
|
||||||
if ((width -= i) < 0)
|
if ((width -= i) < 0) {
|
||||||
width = 0;
|
width = 0;
|
||||||
if (left_align == FALSE)
|
}
|
||||||
|
if (left_align == false) {
|
||||||
width = -width;
|
width = -width;
|
||||||
|
}
|
||||||
if (width < 0) {
|
if (width < 0) {
|
||||||
if (*s == '-' && filler == '0') {
|
if (*s == '-' && filler == '0') {
|
||||||
streamPut(chp, (uint8_t)*s++);
|
streamPut(chp, (uint8_t)*s++);
|
||||||
|
|
Loading…
Reference in New Issue