[freenos] r333 committed - Implemented support for length modifiers in format strings with vnspri...

  • From: codesite-noreply@xxxxxxxxxx
  • To: freenos@xxxxxxxxxxxxx
  • Date: Thu, 03 Sep 2009 22:47:48 +0000

Revision: 333
Author: nieklinnenbank
Date: Thu Sep  3 15:47:20 2009
Log: 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. */

Other related posts:

  • » [freenos] r333 committed - Implemented support for length modifiers in format strings with vnspri... - codesite-noreply