Fix printf bugs.
authorcoderain <coderain@sdf.org>
Tue, 4 Sep 2018 04:49:39 +0000 (06:49 +0200)
committercoderain <coderain@sdf.org>
Tue, 4 Sep 2018 04:49:39 +0000 (06:49 +0200)
crt/src/printf.c

index 4a320aaba39cb74e2ead83587fb86a872c89f8b4..57a83d8ddf069e3544f8753774ed833d4f43be96 100644 (file)
@@ -46,14 +46,16 @@ static int __crt_strputc(__crt_stream_or_string_t *str, char c)
     {
         return fputc_unlocked(c, str->stream) != EOF;
     }
-    else if (str->size > 1)
+    else
     {
-        *str->string++ = c;
-        str->size--;
+        if (str->size > 1)
+        {
+            *str->string++ = c;
+            str->size--;
+        }
+
         return 1;
     }
-
-    return 0;
 }
 
 static int __crt_strputs(__crt_stream_or_string_t *str, const char *s)
@@ -62,16 +64,28 @@ static int __crt_strputs(__crt_stream_or_string_t *str, const char *s)
     {
         return fputs_unlocked(s, str->stream) != EOF ? strlen(s) : 0;
     }
-    else if (str->size > 1)
+    else
     {
         int length = strlen(s);
-        strncpy(str->string, s, str->size - 1);
-        if (length > (str->size - 1)) length = str->size - 1;
-        str->string += length;
-        str->size -= length;
-    }
 
-    return 0;
+        if (str->size > 1)
+        {
+            strncpy(str->string, s, str->size - 1);
+
+            if (length < str->size)
+            {
+                str->string += length;
+                str->size -= length;
+            }
+            else
+            {
+                str->string += str->size - 1;
+                str->size = 0;
+            }
+        }
+
+        return length;
+    }
 }
 
 static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *format, va_list ap)
@@ -213,7 +227,7 @@ static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *fo
                 {
                     while (length < width)
                     {
-                        __crt_strputc(str, padding);
+                        ret += __crt_strputc(str, padding);
                         length++;
                     }
                 }
@@ -222,13 +236,13 @@ static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *fo
                 {
                     while (*data && precision > 0)
                     {
-                        __crt_strputc(str, *data++);
+                        ret += __crt_strputc(str, *data++);
                         precision--;
                     }
                 }
                 else
                 {
-                    __crt_strputs(str, data ? data : "(null)");
+                    ret += __crt_strputs(str, data ? data : "(null)");
                 }
                 break;
 
@@ -242,12 +256,12 @@ static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *fo
                 {
                     if (*data == '-')
                     {
-                        __crt_strputc(str, '-');
+                        ret += __crt_strputc(str, '-');
                         data++;
                     }
                     else
                     {
-                        __crt_strputc(str, (flags & __CRT_PRINTF_FLAG_PLUS) ? '+' : ' ');
+                        ret += __crt_strputc(str, (flags & __CRT_PRINTF_FLAG_PLUS) ? '+' : ' ');
                         length++;
                     }
                 }
@@ -256,13 +270,13 @@ static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *fo
                 {
                     while (length < width - precision)
                     {
-                        __crt_strputc(str, padding);
+                        ret += __crt_strputc(str, padding);
                         length++;
                     }
 
                     while (length < width)
                     {
-                        __crt_strputc(str, '0');
+                        ret += __crt_strputc(str, '0');
                         length++;
                     }
                 }
@@ -270,18 +284,18 @@ static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *fo
                 {
                     while (length < precision)
                     {
-                        __crt_strputc(str, '0');
+                        ret += __crt_strputc(str, '0');
                         length++;
                     }
                 }
 
-                __crt_strputs(str, data);
+                ret += __crt_strputs(str, data);
                 break;
             }
 
             while (length < width)
             {
-                __crt_strputc(str, padding);
+                ret += __crt_strputc(str, padding);
                 length++;
             }
         }