Merge from Etherboot 5.4
[people/lynusvaz/gpxe.git] / src / core / vsprintf.c
index 414b450..83a494a 100644 (file)
@@ -2,6 +2,7 @@
 #include "if_ether.h" /* for ETH_ALEN */
 #include "limits.h" /* for CHAR_BIT */
 #include "console.h"
+#include "errno.h"
 #include "vsprintf.h"
 
 #define LONG_SHIFT  ((int)((sizeof(unsigned long)*CHAR_BIT) - 4))
 #define SHRT_SHIFT  ((int)((sizeof(unsigned short)*CHAR_BIT) - 4))
 #define CHAR_SHIFT  ((int)((sizeof(unsigned char)*CHAR_BIT) - 4))
 
-/**************************************************************************
-PRINTF and friends
+/** @file */
 
-       Formats:
-               %[#]x   - 4 bytes int (8 hex digits, lower case)
-               %[#]X   - 4 bytes int (8 hex digits, upper case)
-               %[#]lx  - 8 bytes long (16 hex digits, lower case)
-               %[#]lX  - 8 bytes long (16 hex digits, upper case)
-               %[#]hx  - 2 bytes int (4 hex digits, lower case)
-               %[#]hX  - 2 bytes int (4 hex digits, upper case)
-               %[#]hhx - 1 byte int (2 hex digits, lower case)
-               %[#]hhX - 1 byte int (2 hex digits, upper case)
-                       - optional # prefixes 0x or 0X
-               %d      - decimal int
-               %c      - char
-               %s      - string
-               %@      - Internet address in ddd.ddd.ddd.ddd notation
-               %!      - Ethernet address in xx:xx:xx:xx:xx:xx notation
-       Note: width specification ignored
-**************************************************************************/
+/**
+ * Write a formatted string to a buffer.
+ *
+ * @v buf              Buffer into which to write the string, or NULL
+ * @v fmt              Format string
+ * @v args             Arguments corresponding to the format string
+ * @ret len            Length of string written to buffer (if buf != NULL)
+ * @ret        0               (if buf == NULL)
+ * @err None           -
+ *
+ * If #buf==NULL, then the string will be written to the console
+ * directly using putchar().
+ *
+ */
 static int vsprintf(char *buf, const char *fmt, va_list args)
 {
-       char *p, *s;
+       const char *p;
+       char *s;
        s = buf;
        for ( ; *fmt != '\0'; ++fmt) {
                if (*fmt != '%') {
@@ -47,10 +45,12 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                while (*fmt >= '0' && *fmt <= '9')
                        fmt++;
                if (*fmt == 's') {
-                       for(p = va_arg(args, char *); *p != '\0'; p++) 
+                       for(p = va_arg(args, char *); *p != '\0'; p++)
                                buf ? *s++ = *p : putchar(*p);
-               }
-               else {  /* Length of item is bounded */
+               } else if (*fmt == 'm') {
+                       for(p = strerror(errno); *p != '\0'; p++)
+                               buf ? *s++ = *p : putchar(*p);
+               } else {        /* Length of item is bounded */
                        char tmp[40], *q = tmp;
                        int alt = 0;
                        int shift = INT_SHIFT;
@@ -70,7 +70,7 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                                        fmt++;
                                }
                        }
-                       
+
                        /*
                         * Before each format q points to tmp buffer
                         * After each format q points past end of item
@@ -93,7 +93,7 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                                        *q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
                        }
                        else if (*fmt == 'd') {
-                               char *r;
+                               char *r, *t;
                                long i;
                                if (shift > INT_SHIFT) {
                                        i = va_arg(args, long);
@@ -104,17 +104,17 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                                        *q++ = '-';
                                        i = -i;
                                }
-                               p = q;          /* save beginning of digits */
+                               t = q;          /* save beginning of digits */
                                do {
                                        *q++ = '0' + (i % 10);
                                        i /= 10;
                                } while (i);
                                /* reverse digits, stop in middle */
                                r = q;          /* don't alter q */
-                               while (--r > p) {
+                               while (--r > t) {
                                        i = *r;
-                                       *r = *p;
-                                       *p++ = i;
+                                       *r = *t;
+                                       *t++ = i;
                                }
                        }
                        else if (*fmt == '@') {
@@ -129,7 +129,7 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                                --q;
                        }
                        else if (*fmt == '!') {
-                               char *r;
+                               const char *r;
                                p = va_arg(args, char *);
                                for (r = p + ETH_ALEN; p < r; ++p)
                                        q += sprintf(q, "%hhX:", *p);
@@ -149,6 +149,20 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
        return (s - buf);
 }
 
+/**
+ * Write a formatted string to a buffer.
+ *
+ * @v buf              Buffer into which to write the string, or NULL
+ * @v fmt              Format string
+ * @v ...              Arguments corresponding to the format string
+ * @ret len            Length of string written to buffer (if buf != NULL)
+ * @ret        0               (if buf == NULL)
+ * @err None           -
+ *
+ * If #buf==NULL, then the string will be written to the console
+ * directly using putchar().
+ *
+ */
 int sprintf(char *buf, const char *fmt, ...)
 {
        va_list args;
@@ -159,11 +173,21 @@ int sprintf(char *buf, const char *fmt, ...)
        return i;
 }
 
-void printf(const char *fmt, ...)
+/**
+ * Write a formatted string to the console.
+ *
+ * @v fmt              Format string
+ * @v ...              Arguments corresponding to the format string
+ * @ret        None            -
+ * @err None           -
+ *
+ */
+int printf(const char *fmt, ...)
 {
        va_list args;
        int i;
        va_start(args, fmt);
        i=vsprintf(0, fmt, args);
        va_end(args);
+       return i;
 }