From 6a7e844500a05cc72b09198153f788bb4c273694 Mon Sep 17 00:00:00 2001 From: cuz Date: Mon, 31 Mar 2008 20:51:31 +0000 Subject: [PATCH] The conversion specifier to output a StrBuf had to be changed, because gcc 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 | 39 ++++++++++++++++++++++++++++++++++----- src/common/xsprintf.h | 16 ++++++++++++++-- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/common/xsprintf.c b/src/common/xsprintf.c index 194d8f99e..0a0727e09 100644 --- a/src/common/xsprintf.c +++ b/src/common/xsprintf.c @@ -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': diff --git a/src/common/xsprintf.h b/src/common/xsprintf.h index 202a8b7b2..cc32d4620 100644 --- a/src/common/xsprintf.h +++ b/src/common/xsprintf.h @@ -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 */ /* */ @@ -33,6 +33,18 @@ +/* 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 -- 2.39.2