#include "chartype.h"
#include "check.h"
#include "inttypes.h"
+#include "strbuf.h"
#include "va_copy.h"
#include "xsprintf.h"
char F;
char SBuf[2];
const char* SPtr;
+ int UseStrBuf = 0;
/* Initialize the control structure */
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':
/* */
/* */
/* */
-/* (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