At least cope with "%llx" by reading the correct-sized va_arg from the
authorMichael Brown <mcb30@etherboot.org>
Sat, 13 May 2006 11:50:52 +0000 (11:50 +0000)
committerMichael Brown <mcb30@etherboot.org>
Sat, 13 May 2006 11:50:52 +0000 (11:50 +0000)
stack, even if we don't yet print it out.

At some point, vsprintf() needs to be fixed up so that it can correctly
cope with limited-sized buffers (i.e. vsnprintf), long longs, and
standard format specifiers (e.g. "%04x").  We should also remove the
special types (MAC addresses and IP addresses).  This would then enable
us to use gcc's ability to type-check printf format strings.

src/core/vsprintf.c

index 3c8e5b5..15f2113 100644 (file)
@@ -5,10 +5,11 @@
 #include "errno.h"
 #include "vsprintf.h"
 
-#define LONG_SHIFT  ((int)((sizeof(unsigned long)*CHAR_BIT) - 4))
-#define INT_SHIFT   ((int)((sizeof(unsigned int)*CHAR_BIT) - 4))
-#define SHRT_SHIFT  ((int)((sizeof(unsigned short)*CHAR_BIT) - 4))
-#define CHAR_SHIFT  ((int)((sizeof(unsigned char)*CHAR_BIT) - 4))
+#define LONGLONG_SHIFT ((int)((sizeof(unsigned long long)*CHAR_BIT) - 4))
+#define LONG_SHIFT     ((int)((sizeof(unsigned long)*CHAR_BIT) - 4))
+#define INT_SHIFT      ((int)((sizeof(unsigned int)*CHAR_BIT) - 4))
+#define SHRT_SHIFT     ((int)((sizeof(unsigned short)*CHAR_BIT) - 4))
+#define CHAR_SHIFT     ((int)((sizeof(unsigned char)*CHAR_BIT) - 4))
 
 /** @file */
 
@@ -62,7 +63,11 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                                shift = LONG_SHIFT;
                                fmt++;
                        }
-                       else if (*fmt == 'h') {
+                       if (*fmt == 'l') {
+                               shift = LONGLONG_SHIFT;
+                               fmt++;
+                       }
+                       if (*fmt == 'h') {
                                shift = SHRT_SHIFT;
                                fmt++;
                                if (*fmt == 'h') {
@@ -79,7 +84,9 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                                /* With x86 gcc, sizeof(long) == sizeof(int) */
                                unsigned long h;
                                int ncase;
-                               if (shift > INT_SHIFT) {
+                               if (shift > LONG_SHIFT) {
+                                       h = va_arg(args, unsigned long long);
+                               } else if (shift > INT_SHIFT) {
                                        h = va_arg(args, unsigned long);
                                } else {
                                        h = va_arg(args, unsigned int);
@@ -95,7 +102,9 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                        else if (*fmt == 'd') {
                                char *r, *t;
                                long i;
-                               if (shift > INT_SHIFT) {
+                               if (shift > LONG_SHIFT) {
+                                       i = va_arg(args, long long);
+                               } else if (shift > INT_SHIFT) {
                                        i = va_arg(args, long);
                                } else {
                                        i = va_arg(args, int);