void Error::TraceWrite(const TCHAR * bufp, va_list args) { // wxWidgets doesn't expect newlines in the string, but Camelot source provides them. So we print each bit // separately #if 1 // replace \n by a space - the real solution is to remove the \n from all the trace statements (yawn) TCHAR buf[MAXERRORFORMATLENGTH]; camStrncpy(buf, bufp, MAXERRORFORMATLENGTH); buf[MAXERRORFORMATLENGTH-1]=0; TCHAR * b=buf; do { if (*b == '\n') *b=' '; } while(*b++); wxVLogDebug(buf, args); #else // this way is bad as it doesn't work with args either side of the newline TCHAR * newline; do { newline = camStrchr(bufp, _T('\n')); if (newline) *newline++=0; // We really should pass only the args before the newline here, but... wxVLogDebug(bufp, args); bufp=newline; } while (bufp && *bufp); #endif }
/************************************************************************************** > INT32 StringBase::BuildList(const TCHAR* format) Author: Justin_Flude (Xara Group Ltd) <*****@*****.**> Created: 22nd April 1993 Inputs: A pointer to the format string to be analysed. Returns: The number of format specifiers in the string, which should be the same as the number of arguments to be formatted. Purpose: This private helper function scans the layout string, breaking it up into literal text and parameters, which are placed on an private list in the order they are encountered, together with their type and which argument passed to Format that they refer to. The formatting must be done in two passes as the order of the parameters is not known until the whole format string has been scanned. Scope: Private ***************************************************************************************/ INT32 StringBase::BuildList(const TCHAR* format) { /* if (IsUserName("JustinF")) TRACE( _T("\tBuildList called with format string %s\n"), format); */ ENSURE(format, "Null parameter passed to StringBase::BuildList"); const TCHAR* start = format; INT32 nArgs = 0; while (*start) { const TCHAR* next = start; // Look for a format specifier in the layout string if (*next == TEXT('#')) if (IsNumeric(*(++next))) { INT32 ArgPos = *next - TEXT('0'); // MS approved method - yuck!!! ENSURE(ArgPos >= 1 && ArgPos <= 9, "Illegal format string passed to MakeMsg!"); if (*(++next) == TEXT('%')) { // Seem to have found the beginning of a specifier, // so try parsing it, to extract the type information if (*(++next) == TEXT('-')) next++; if (*next == TEXT('#')) next++; if (*next == TEXT('0')) next++; while (IsNumeric(*next)) next++; if (*next == TEXT('.')) while (IsNumeric(*++next)); // Ok, we have skipped the width, precision etc. and // "next" should now be pointing at the type character(s) ArgType kind; if (*next == TEXT('l')) // an INT32 something or another? switch (*++next) { case TEXT('d'): case TEXT('i'): kind = SIGNED_INT32_ARG; break; case TEXT('u'): case TEXT('x'): case TEXT('X'): kind = UNSIGNED_INT32_ARG; break; default: // false alarm, can't be a specifier next = start + 1; goto not_format; } else switch (*next) // single type character { case TEXT('c'): kind = CHAR_ARG; break; case TEXT('d'): case TEXT('i'): kind = SIGNED_INT_ARG; break; case TEXT('p'): // a pointer kind = UINT_PTR_ARG; break; case TEXT('u'): case TEXT('x'): case TEXT('X'): kind = UNSIGNED_INT_ARG; break; case TEXT('s'): kind = CHAR_POINTER_ARG; break; case TEXT('S'): kind = STRING_POINTER_ARG; break; default: next = start + 1; goto not_format; // boo hiss hooray! } // Successfully parsed the format specifier, so add // it to the Item list. Skip the leading #n of the specifier, // so (next) now points to the character following the '%X' // format specifier. next++; // Extract the specifier. TCHAR temp[64]; INT32 len = next - start - 2; camStrncpy(temp, start + 2, len); temp[len] = 0; new Item(temp, ArgPos, kind); start = next; nArgs++; /* if (IsUserName("JustinF")) { TRACE( _T("\tItem: (%d) at #%d %s\n"), kind, ArgPos, temp); TRACE( _T("\t\tRemaining: %s\n"), start); } */ continue; } else // Put back the previous character next--; } not_format: // Scan a literal up to the next '#' or null, whichever is sooner while (*next && *next != TEXT('#')) next++; TCHAR temp[256]; INT32 len = next - start; camStrncpy(temp, start, len); temp[len] = 0; new Item(temp, 0, LITERAL); start = next; /* if (IsUserName("JustinF")) { TRACE( _T("\tLiteral: %s\n"), temp); } */ } return nArgs; }