]> git.sur5r.net Git - u-boot/blobdiff - lib/vsprintf.c
Merge branch 'master' of git://git.denx.de/u-boot-fsl-qoriq
[u-boot] / lib / vsprintf.c
index 92a9232c2a1421fd3033f9248d23749cce9d07b0..7ec758e40fc5ba3530376f74c893e520b23c7118 100644 (file)
 #endif
 
 #include <div64.h>
-# define NUM_TYPE long long
 #define noinline __attribute__((noinline))
 
 /* some reluctance to put this into a new limits.h, so it is here */
 #define INT_MAX                ((int)(~0U>>1))
 
-const char hex_asc[] = "0123456789abcdef";
-#define hex_asc_lo(x)   hex_asc[((x) & 0x0f)]
-#define hex_asc_hi(x)   hex_asc[((x) & 0xf0) >> 4]
-
-static inline char *pack_hex_byte(char *buf, u8 byte)
-{
-       *buf++ = hex_asc_hi(byte);
-       *buf++ = hex_asc_lo(byte);
-       return buf;
-}
-
 unsigned long simple_strtoul(const char *cp, char **endp,
                                unsigned int base)
 {
@@ -104,7 +92,7 @@ long simple_strtol(const char *cp, char **endp, unsigned int base)
        return simple_strtoul(cp, endp, base);
 }
 
-int ustrtoul(const char *cp, char **endp, unsigned int base)
+unsigned long ustrtoul(const char *cp, char **endp, unsigned int base)
 {
        unsigned long result = simple_strtoul(cp, endp, base);
        switch (**endp) {
@@ -127,6 +115,29 @@ int ustrtoul(const char *cp, char **endp, unsigned int base)
        return result;
 }
 
+unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base)
+{
+       unsigned long long result = simple_strtoull(cp, endp, base);
+       switch (**endp) {
+       case 'G':
+               result *= 1024;
+               /* fall through */
+       case 'M':
+               result *= 1024;
+               /* fall through */
+       case 'K':
+       case 'k':
+               result *= 1024;
+               if ((*endp)[1] == 'i') {
+                       if ((*endp)[2] == 'B')
+                               (*endp) += 3;
+                       else
+                               (*endp) += 2;
+               }
+       }
+       return result;
+}
+
 unsigned long long simple_strtoull(const char *cp, char **endp,
                                        unsigned int base)
 {
@@ -259,7 +270,7 @@ static char *put_dec_full(char *buf, unsigned q)
        return buf;
 }
 /* No inlining helps gcc to use registers better */
-static noinline char *put_dec(char *buf, unsigned NUM_TYPE num)
+static noinline char *put_dec(char *buf, u64 num)
 {
        while (1) {
                unsigned rem;
@@ -292,7 +303,7 @@ static noinline char *put_dec(char *buf, unsigned NUM_TYPE num)
 #define ADDCH(str, ch) (*(str)++ = (ch))
 #endif
 
-static char *number(char *buf, char *end, unsigned NUM_TYPE num,
+static char *number(char *buf, char *end, u64 num,
                int base, int size, int precision, int type)
 {
        /* we are called with base 8, 10 or 16, only, thus don't need "G..."  */
@@ -311,9 +322,9 @@ static char *number(char *buf, char *end, unsigned NUM_TYPE num,
                type &= ~ZEROPAD;
        sign = 0;
        if (type & SIGN) {
-               if ((signed NUM_TYPE) num < 0) {
+               if ((s64) num < 0) {
                        sign = '-';
-                       num = -(signed NUM_TYPE) num;
+                       num = -(s64) num;
                        size--;
                } else if (type & PLUS) {
                        sign = '+';
@@ -396,7 +407,7 @@ static char *string(char *buf, char *end, char *s, int field_width,
 {
        int len, i;
 
-       if (s == 0)
+       if (s == NULL)
                s = "<NULL>";
 
        len = strnlen(s, precision);
@@ -412,6 +423,17 @@ static char *string(char *buf, char *end, char *s, int field_width,
 }
 
 #ifdef CONFIG_CMD_NET
+static const char hex_asc[] = "0123456789abcdef";
+#define hex_asc_lo(x)  hex_asc[((x) & 0x0f)]
+#define hex_asc_hi(x)  hex_asc[((x) & 0xf0) >> 4]
+
+static inline char *pack_hex_byte(char *buf, u8 byte)
+{
+       *buf++ = hex_asc_hi(byte);
+       *buf++ = hex_asc_lo(byte);
+       return buf;
+}
+
 static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width,
                                int precision, int flags)
 {
@@ -496,9 +518,15 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width,
 static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
                int field_width, int precision, int flags)
 {
+       /*
+        * Being a boot loader, we explicitly allow pointers to
+        * (physical) address null.
+        */
+#if 0
        if (!ptr)
                return string(buf, end, "(null)", field_width, precision,
                              flags);
+#endif
 
 #ifdef CONFIG_CMD_NET
        switch (*fmt) {
@@ -534,7 +562,7 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
 static int vsnprintf_internal(char *buf, size_t size, const char *fmt,
                              va_list args)
 {
-       unsigned NUM_TYPE num;
+       u64 num;
        int base;
        char *str;
 
@@ -722,6 +750,7 @@ repeat:
                ADDCH(str, '\0');
                if (str > end)
                        end[-1] = '\0';
+               --str;
        }
 #else
        *str = '\0';
@@ -842,3 +871,19 @@ char *simple_itoa(ulong i)
        } while (i > 0);
        return p + 1;
 }
+
+/* We don't seem to have %'d in U-Boot */
+void print_grouped_ull(unsigned long long int_val, int digits)
+{
+       char str[21], *s;
+       int grab = 3;
+
+       digits = (digits + 2) / 3;
+       sprintf(str, "%*llu", digits * 3, int_val);
+       for (s = str; *s; s += grab) {
+               if (s != str)
+                       putc(s[-1] != ' ' ? ',' : ' ');
+               printf("%.*s", grab, s);
+               grab = 3;
+       }
+}