// Purpose: macros for implementing type-safe vararg passing of strings
// Author: Vaclav Slavik
// Created: 2007-02-19
-// RCS-ID: $Id$
// Copyright: (c) 2007 REA Elektronik GmbH
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
: m_wchar(str), m_str(NULL), m_cstr(NULL) {}
// Possible argument types. These are or-combinable for wxASSERT_ARG_TYPE
- // convenience.
+ // convenience. Some of the values are or-combined with another value, this
+ // expresses "supertypes" for use with wxASSERT_ARG_TYPE masks. For example,
+ // a char* string is also a pointer and an integer is also a char.
enum ArgumentType
{
Arg_Char = 0x0001, // character as char %c
Arg_Pointer = 0x0002, // %p
- Arg_String = 0x0004, // any form of string
+ Arg_String = 0x0004 | Arg_Pointer, // any form of string (%s and %p too)
- Arg_Int = 0x0008,
+ Arg_Int = 0x0008 | Arg_Char, // (ints can be used with %c)
#if SIZEOF_INT == SIZEOF_LONG
Arg_LongInt = Arg_Int,
#else
Arg_Double = 0x0040,
Arg_LongDouble = 0x0080,
-#ifdef wxSIZE_T_IS_UINT
+#if defined(wxSIZE_T_IS_UINT)
Arg_Size_t = Arg_Int,
-#endif
-#ifdef wxSIZE_T_IS_ULONG
+#elif defined(wxSIZE_T_IS_ULONG)
Arg_Size_t = Arg_LongInt,
+#elif defined(SIZEOF_LONG_LONG) && SIZEOF_SIZE_T == SIZEOF_LONG_LONG
+ Arg_Size_t = Arg_LongLongInt,
+#else
+ Arg_Size_t = 0x0100,
#endif
- Arg_IntPtr = 0x0100, // %n -- store # of chars written
- Arg_ShortIntPtr = 0x0200,
- Arg_LongIntPtr = 0x0400,
+ Arg_IntPtr = 0x0200, // %n -- store # of chars written
+ Arg_ShortIntPtr = 0x0400,
+ Arg_LongIntPtr = 0x0800,
Arg_Unknown = 0x8000 // unrecognized specifier (likely error)
};
{ return const_cast<wxFormatString*>(this)->AsChar(); }
private:
// InputAsChar() returns the value passed to ctor, only converted
- // to char, while AsChar() takes the the string returned by InputAsChar()
+ // to char, while AsChar() takes the string returned by InputAsChar()
// and does format string conversion on it as well (and similarly for
// ..AsWChar() below)
const char* InputAsChar();
// the correct type (one of wxFormatString::Arg_XXX or-combination in
// 'expected_mask').
#define wxASSERT_ARG_TYPE(fmt, index, expected_mask) \
- do \
- { \
+ wxSTATEMENT_MACRO_BEGIN \
if ( !fmt ) \
break; \
const int argtype = fmt->GetArgumentType(index); \
wxASSERT_MSG( (argtype & (expected_mask)) == argtype, \
"format specifier doesn't match argument type" ); \
- } while ( wxFalse )
+ wxSTATEMENT_MACRO_END
#else
- #define wxASSERT_ARG_TYPE(fmt, index, expected_mask)
+ // Just define it to suppress "unused parameter" warnings for the
+ // parameters which we don't use otherwise
+ #define wxASSERT_ARG_TYPE(fmt, index, expected_mask) \
+ wxUnusedVar(fmt); \
+ wxUnusedVar(index)
#endif // wxDEBUG_LEVEL/!wxDEBUG_LEVEL
wxFORMAT_STRING_SPECIFIER(double, wxFormatString::Arg_Double)
wxFORMAT_STRING_SPECIFIER(long double, wxFormatString::Arg_LongDouble)
+#if wxWCHAR_T_IS_REAL_TYPE
wxFORMAT_STRING_SPECIFIER(wchar_t, wxFormatString::Arg_Char | wxFormatString::Arg_Int)
+#endif
-wxFORMAT_STRING_SPECIFIER(char*, wxFormatString::Arg_String | wxFormatString::Arg_Pointer)
-wxFORMAT_STRING_SPECIFIER(unsigned char*, wxFormatString::Arg_String | wxFormatString::Arg_Pointer)
-wxFORMAT_STRING_SPECIFIER(signed char*, wxFormatString::Arg_String | wxFormatString::Arg_Pointer)
-wxFORMAT_STRING_SPECIFIER(const char*, wxFormatString::Arg_String | wxFormatString::Arg_Pointer)
-wxFORMAT_STRING_SPECIFIER(const unsigned char*, wxFormatString::Arg_String | wxFormatString::Arg_Pointer)
-wxFORMAT_STRING_SPECIFIER(const signed char*, wxFormatString::Arg_String | wxFormatString::Arg_Pointer)
-wxFORMAT_STRING_SPECIFIER(wchar_t*, wxFormatString::Arg_String | wxFormatString::Arg_Pointer)
-wxFORMAT_STRING_SPECIFIER(const wchar_t*, wxFormatString::Arg_String | wxFormatString::Arg_Pointer)
+#if !wxUSE_UNICODE
+wxFORMAT_STRING_SPECIFIER(char, wxFormatString::Arg_Char | wxFormatString::Arg_Int)
+wxFORMAT_STRING_SPECIFIER(signed char, wxFormatString::Arg_Char | wxFormatString::Arg_Int)
+wxFORMAT_STRING_SPECIFIER(unsigned char, wxFormatString::Arg_Char | wxFormatString::Arg_Int)
+#endif
+
+wxFORMAT_STRING_SPECIFIER(char*, wxFormatString::Arg_String)
+wxFORMAT_STRING_SPECIFIER(unsigned char*, wxFormatString::Arg_String)
+wxFORMAT_STRING_SPECIFIER(signed char*, wxFormatString::Arg_String)
+wxFORMAT_STRING_SPECIFIER(const char*, wxFormatString::Arg_String)
+wxFORMAT_STRING_SPECIFIER(const unsigned char*, wxFormatString::Arg_String)
+wxFORMAT_STRING_SPECIFIER(const signed char*, wxFormatString::Arg_String)
+wxFORMAT_STRING_SPECIFIER(wchar_t*, wxFormatString::Arg_String)
+wxFORMAT_STRING_SPECIFIER(const wchar_t*, wxFormatString::Arg_String)
wxFORMAT_STRING_SPECIFIER(int*, wxFormatString::Arg_IntPtr | wxFormatString::Arg_Pointer)
wxFORMAT_STRING_SPECIFIER(short int*, wxFormatString::Arg_ShortIntPtr | wxFormatString::Arg_Pointer)
unsigned index)
: m_value(buf)
{
- wxASSERT_ARG_TYPE( fmt, index,
- wxFormatString::Arg_String | wxFormatString::Arg_Pointer );
+ wxASSERT_ARG_TYPE( fmt, index, wxFormatString::Arg_String );
}
const CharType *get() const { return m_value; }
unsigned index)
: m_value(value)
{
- wxASSERT_ARG_TYPE( fmt, index,
- wxFormatString::Arg_String | wxFormatString::Arg_Pointer );
+ wxASSERT_ARG_TYPE( fmt, index, wxFormatString::Arg_String );
}
const wxStringCharType *get() const;
const wxFormatString *fmt,
unsigned index)
{
- wxASSERT_ARG_TYPE( fmt, index,
- wxFormatString::Arg_String | wxFormatString::Arg_Pointer );
+ wxASSERT_ARG_TYPE( fmt, index, wxFormatString::Arg_String );
if ( wxLocaleIsUtf8 )
{
#undef WX_ARG_NORMALIZER_FORWARD
#undef _WX_ARG_NORMALIZER_FORWARD_IMPL
-#undef wxASSERT_ARG_TYPE
+// NB: Don't #undef wxASSERT_ARG_TYPE here as it's also used in wx/longlong.h.
// ----------------------------------------------------------------------------
// WX_VA_ARG_STRING