Revision: 333 Author: nieklinnenbank Date: Thu Sep 3 15:47:20 2009Log: Implemented support for length modifiers in format strings with vnsprintf().
It allows user applications to specify the length a field must have. When the format argument uses less space, it is padded with white spaces. If the format argument uses more bytes than specified by the length modifier, the output is truncated to the length set by the length modifier. Fixes issue 30 http://code.google.com/p/freenos/source/detail?r=333 Modified: /trunk/lib/libc/stdio/vsnprintf.c ======================================= --- /trunk/lib/libc/stdio/vsnprintf.c Thu Apr 9 14:46:04 2009 +++ /trunk/lib/libc/stdio/vsnprintf.c Thu Sep 3 15:47:20 2009 @@ -22,7 +22,7 @@int vsnprintf(char *buffer, unsigned int size, const char *fmt, va_list args)
{ char buf[20], *ptr; - int ch; + int ch, length = -1, i; unsigned int written = 0; /* Loop formatted message. */ @@ -35,46 +35,72 @@ } else { + switch_again: + switch (*fmt) { - case 'd': - case 'u': - itoa(buf, 10, va_arg(args, int)); - ptr = buf; - goto string; - - case 'l': - itoa(buf, 10, va_arg(args, long)); - ptr = buf; - goto string; - - case 'x': - itoa(buf, 16, va_arg(args, int)); - ptr = buf; - goto string; - - case 'c': - buf[0] = va_arg(args, int); - buf[1] = ZERO; - ptr = buf; - goto string; - - case 's': - ptr = va_arg(args, char *); - - string: - while(*ptr && written++ < size) - { - *buffer++ = *ptr++; - } - break; - - default: - *buffer++ = ch; - written++; - break; + /* Length modifier. */ + case '0' ... '9': + + for (i = 0; i < 19 && *fmt >= '0' && *fmt <= '9'; i++) + { + buf[i] = *fmt++; + buf[i+1] = ZERO; + } + length = atoi(buf); + goto switch_again; + + /* Integer. */ + case 'd': + case 'u': + itoa(buf, 10, va_arg(args, int)); + ptr = buf; + goto string; + + /* Long integer. */ + case 'l': + itoa(buf, 10, va_arg(args, long)); + ptr = buf; + goto string; + + /* Hexadecimal. */ + case 'x': + itoa(buf, 16, va_arg(args, int)); + ptr = buf; + goto string; + + /* Character. */ + case 'c': + buf[0] = va_arg(args, int); + buf[1] = ZERO; + ptr = buf; + goto string; + + /* String. */ + case 's': + ptr = va_arg(args, char *); + + string: + while( ((length == -1 && *ptr) || + (length > 0 && length--)) && written++ < size) + { + if (*ptr) + { + *buffer++ = *ptr++; + } + else + *buffer++ = ' '; + } + break; + + /* Unsupported. */ + default: + *buffer++ = ch; + written++; + break; } fmt++; + length = -1; } } /* Null terminate. */