]> git.sur5r.net Git - cc65/commitdiff
The conversion specifier to output a StrBuf had to be changed, because gcc
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 31 Mar 2008 20:51:31 +0000 (20:51 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 31 Mar 2008 20:51:31 +0000 (20:51 +0000)
emits a warning for each such unknown conversion specifier.

git-svn-id: svn://svn.cc65.org/cc65/trunk@3824 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/common/xsprintf.c
src/common/xsprintf.h

index 194d8f99eae61e34e17c85dc67d3efda4b3b5c14..0a0727e09e32880399f12b36556f9cce053769d9 100644 (file)
@@ -42,6 +42,7 @@
 #include "chartype.h"
 #include "check.h"
 #include "inttypes.h"
+#include "strbuf.h"
 #include "va_copy.h"
 #include "xsprintf.h"
 
@@ -374,6 +375,7 @@ int xvsnprintf (char* Buf, size_t Size, const char* Format, va_list ap)
     char F;
     char SBuf[2];
     const char* SPtr;
+    int UseStrBuf = 0;
 
 
     /* Initialize the control structure */
@@ -571,11 +573,38 @@ int xvsnprintf (char* Buf, size_t Size, const char* Format, va_list ap)
                 break;
 
             case 'p':
-                /* Use hex format for pointers */
-                P.Flags |= (fUnsigned | fPrec);
-                P.Prec = ((sizeof (void*) * CHAR_BIT) + 3) / 4;
-                P.Base = 16;
-                FormatInt (&P, (uintptr_t) va_arg (P.ap, void*));
+                /* See comment at top of header file */
+                if (UseStrBuf) {
+                    /* Argument is StrBuf */
+                    const StrBuf* S = va_arg (P.ap, const StrBuf*);
+                    CHECK (S != 0);
+                    /* Handle the length by using a precision */
+                    if ((P.Flags & fPrec) != 0) {
+                        /* Precision already specified, use length of string 
+                         * if less.
+                         */
+                        if ((unsigned) P.Prec > SB_GetLen (S)) {
+                            P.Prec = SB_GetLen (S);
+                        }
+                    } else {
+                        /* No precision, add it */
+                        P.Flags |= fPrec;
+                        P.Prec  = SB_GetLen (S);
+                    }
+                    FormatStr (&P, SB_GetConstBuf (S));
+                    UseStrBuf = 0;              /* Reset flag */
+                } else {
+                    /* Use hex format for pointers */
+                    P.Flags |= (fUnsigned | fPrec);
+                    P.Prec = ((sizeof (void*) * CHAR_BIT) + 3) / 4;
+                    P.Base = 16;
+                    FormatInt (&P, (uintptr_t) va_arg (P.ap, void*));
+                }
+                break;
+
+            case 'm':
+                /* See comment at top of header file */
+                UseStrBuf = 1;
                 break;
 
             case 'n':
index 202a8b7b2db7ffa02fdeeb1eb78b2d360b0df966..cc32d462053b8514300e187b428c6a58b875c0ce 100644 (file)
@@ -6,8 +6,8 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2004 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/* (C) 2000-2008 Ullrich von Bassewitz                                       */
+/*               Roemerstrasse 52                                            */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 
 
 
+/* We need a way to output a StrBuf, but on the other side, we don't want to 
+ * switch off gcc's printf format string checking. So we cheat as follows: 
+ * %m (which is a gcc extension and doesn't take an argument) switches %p 
+ * between outputting a pointer and a string buf. This works just one time,
+ * so each StrBuf needs in fact a %m%p spec. There's no way to apply a width
+ * and precision to such a StrBuf, but *not* using %p would bring up a warning
+ * about a wrong argument type each time. Maybe gcc will one day allow custom
+ * format specifiers and we can change this ...
+ */
+
+
+
 #ifndef XSPRINTF_H
 #define XSPRINTF_H