From 08e688d151bbe676353a47b1e8ccfc5ea868db01 Mon Sep 17 00:00:00 2001
From: Ian Moffett <ian@osmora.org>
Date: Sun, 19 May 2024 20:47:13 -0400
Subject: libc: vsnprintf: Add '%d' support

Signed-off-by: Ian Moffett <ian@osmora.org>
---
 lib/libc/src/stdio/vsnprintf.c | 48 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

(limited to 'lib/libc/src/stdio')

diff --git a/lib/libc/src/stdio/vsnprintf.c b/lib/libc/src/stdio/vsnprintf.c
index 6cc0a04..112ed1f 100644
--- a/lib/libc/src/stdio/vsnprintf.c
+++ b/lib/libc/src/stdio/vsnprintf.c
@@ -28,6 +28,7 @@
  */
 
 #include <sys/types.h>
+#include <stdint.h>
 #include <stdio.h>
 
 static inline void
@@ -48,6 +49,48 @@ printstr(char *buf, size_t size, size_t *off, const char *s)
     buf[*off] = 0;
 }
 
+static void
+dec_to_str(int value, char *buf, size_t size, size_t *off)
+{
+        size_t i = 0;
+        uint8_t is_negative = 0;
+        uint8_t tmp;
+        char intbuf[4096];
+
+        if (value == 0) {
+            intbuf[i++] = '0';
+            intbuf[i++] = '\0';
+            printstr(buf, size, off, intbuf);
+            return;
+        }
+
+        if (value < 0) {
+            /* Easier to handle positive numbers */
+            value *= -1;
+            is_negative = 1;
+        }
+
+        while (value > 0) {
+            intbuf[i++] = '0' + (value % 10);
+            value /= 10;
+        }
+
+        if (is_negative) {
+            intbuf[i++] = '-';
+        }
+
+        intbuf[i--] = '\0';
+
+        /* Result is in reverse */
+        for (int j = 0; j < i; ++j, --i) {
+            tmp = intbuf[j];
+            intbuf[j] = intbuf[i];
+            intbuf[i] = tmp;
+        }
+
+        printstr(buf, size, off, intbuf);
+}
+
 int
 vsnprintf(char *s, size_t size, const char *fmt, va_list ap)
 {
@@ -55,6 +98,7 @@ vsnprintf(char *s, size_t size, const char *fmt, va_list ap)
     ssize_t num = 0;
     char c, c1;
     const char *tmp_str;
+    int tmp_num;
 
     while (off < (size - 1)) {
         while (*fmt && *fmt != '%') {
@@ -75,6 +119,10 @@ vsnprintf(char *s, size_t size, const char *fmt, va_list ap)
             tmp_str = va_arg(ap, const char *);
             printstr(s, size, &off, tmp_str);
             break;
+        case 'd':
+            tmp_num = va_arg(ap, int);
+            dec_to_str(tmp_num, s, size, &off);
+            break;
         }
     }
 
-- 
cgit v1.2.3