mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 23:10:40 +00:00
ICU-2403 Tracing, more cleanup.
X-SVN-Rev: 13183
This commit is contained in:
parent
e93e5a99cd
commit
e6cb032d93
5 changed files with 170 additions and 88 deletions
|
@ -68,7 +68,11 @@ typedef enum UTraceLevel UTraceLevel;
|
|||
* Use only via UTRACE_ macros.
|
||||
* @internal
|
||||
*/
|
||||
U_COMMON_API int32_t
|
||||
#ifdef UTRACE_IMPL
|
||||
U_EXPORT int32_t
|
||||
#else
|
||||
U_IMPORT int32_t
|
||||
#endif
|
||||
utrace_level;
|
||||
|
||||
/**
|
||||
|
@ -139,9 +143,9 @@ typedef enum UTraceExitVal UTraceExitVal;
|
|||
* @draft ICU 2.8
|
||||
*/
|
||||
#define UTRACE_EXIT() \
|
||||
if(UTRACE_IS_ON) { \
|
||||
{if(UTRACE_IS_ON) { \
|
||||
utrace_exit(utraceFnNumber, UTRACE_EXITV_NONE); \
|
||||
}
|
||||
}}
|
||||
|
||||
/**
|
||||
* Trace statement for each exit point of a function that has a UTRACE_ENTRY()
|
||||
|
@ -152,14 +156,19 @@ typedef enum UTraceExitVal UTraceExitVal;
|
|||
* @draft ICU 2.8
|
||||
*/
|
||||
#define UTRACE_EXIT_D(val) \
|
||||
if(UTRACE_IS_ON) { \
|
||||
{if(UTRACE_IS_ON) { \
|
||||
utrace_exit(utraceFnNumber, UTRACE_EXITV_I32, val); \
|
||||
}
|
||||
}}
|
||||
|
||||
#define UTRACE_EXIT_S(status) \
|
||||
if(UTRACE_IS_ON) { \
|
||||
{if(UTRACE_IS_ON) { \
|
||||
utrace_exit(utraceFnNumber, UTRACE_EXITV_STATUS, status); \
|
||||
}
|
||||
}}
|
||||
|
||||
#define UTRACE_EXIT_DS(val, status) \
|
||||
{if(UTRACE_IS_ON) { \
|
||||
utrace_exit(utraceFnNumber, (UTRACE_EXITV_I32 | UTRACE_EXITV_STATUS), val, status); \
|
||||
}}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -180,7 +189,7 @@ utrace_entry(int32_t fnNumber);
|
|||
* @internal
|
||||
*/
|
||||
U_CAPI void U_EXPORT2
|
||||
utrace_exit(int32_t fnNumber, UTraceExitVal returnType, ...);
|
||||
utrace_exit(int32_t fnNumber, int32_t returnType, ...);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -430,6 +439,10 @@ utrace_format(char *outBuf, int32_t capacity,
|
|||
int32_t indent, const char *fmt, va_list args);
|
||||
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
utrace_formatExit(char *outBuf, int32_t capacity, int32_t indent,
|
||||
int32_t fnNumber, int32_t argtype, va_list args);
|
||||
|
||||
/* Trace function numbers --------------------------------------------------- */
|
||||
|
||||
/**
|
||||
|
@ -461,8 +474,10 @@ enum UTraceFunctionNumber {
|
|||
UTRACE_UCOL_CLOSE,
|
||||
UTRACE_UCOL_STRCOLL,
|
||||
UTRACE_UCOL_GET_SORTKEY,
|
||||
UTRACE_COLLATION_LIMIT,
|
||||
UTRACE_COLLATION_GETLOCALE
|
||||
UTRACE_UCOL_GETLOCALE,
|
||||
UTRACE_UCOL_NEXTSORTKEYPART,
|
||||
UTRACE_UCOL_STRCOLLITER,
|
||||
UTRACE_COLLATION_LIMIT
|
||||
};
|
||||
typedef enum UTraceFunctionNumber UTraceFunctionNumber;
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* indentation:4
|
||||
*/
|
||||
|
||||
#define UTRACE_IMPL
|
||||
#include "unicode/utrace.h"
|
||||
#include "cstring.h"
|
||||
#include "uassert.h"
|
||||
|
@ -19,6 +20,9 @@ static UTraceExit *pTraceExitFunc = NULL;
|
|||
static UTraceData *pTraceDataFunc = NULL;
|
||||
static void *gTraceContext = NULL;
|
||||
|
||||
U_EXPORT int32_t
|
||||
utrace_level;
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
utrace_entry(int32_t fnNumber) {
|
||||
if (pTraceEntryFunc != NULL) {
|
||||
|
@ -29,7 +33,7 @@ utrace_entry(int32_t fnNumber) {
|
|||
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
utrace_exit(int32_t fnNumber, UTraceExitVal returnType, ...) {
|
||||
utrace_exit(int32_t fnNumber, int32_t returnType, ...) {
|
||||
if (pTraceExitFunc != NULL) {
|
||||
va_list args;
|
||||
va_start(args, returnType);
|
||||
|
@ -55,7 +59,12 @@ static void outputChar(char c, char *outBuf, int32_t *outIx, int32_t capacity, i
|
|||
int32_t i;
|
||||
if (*outIx < capacity) {
|
||||
outBuf[*outIx] = c;
|
||||
(*outIx)++;
|
||||
if (c != 0) {
|
||||
/* Nulls only appear as end-of-string terminators. Move them to the output
|
||||
* buffer, but do not update the length of the buffer, so that any
|
||||
* following output will overwrite the null. */
|
||||
(*outIx)++;
|
||||
};
|
||||
}
|
||||
if (c == '\n') {
|
||||
for(i=0; i<indent; i++) {
|
||||
|
@ -211,7 +220,7 @@ utrace_format(char *outBuf, int32_t capacity, int32_t indent, const char *fmt, v
|
|||
int32_t charsToOutput;
|
||||
int32_t i;
|
||||
|
||||
vectorType = fmt[fmtIx];
|
||||
vectorType = fmt[fmtIx]; /* b, h, d, l, p, etc. */
|
||||
if (vectorType != 0) {
|
||||
fmtIx++;
|
||||
}
|
||||
|
@ -221,45 +230,52 @@ utrace_format(char *outBuf, int32_t capacity, int32_t indent, const char *fmt, v
|
|||
i64Ptr = (int64_t *)i8Ptr;
|
||||
ptrPtr = (void **)i8Ptr;
|
||||
vectorLen =(int32_t)va_arg(args, int32_t);
|
||||
for (i=0; i<vectorLen; i++) {
|
||||
switch (vectorType) {
|
||||
case 'b':
|
||||
charsToOutput = 2;
|
||||
longArg = *i8Ptr++;
|
||||
break;
|
||||
case 'h':
|
||||
charsToOutput = 4;
|
||||
longArg = *i16Ptr++;
|
||||
break;
|
||||
case 'd':
|
||||
charsToOutput = 8;
|
||||
longArg = *i32Ptr++;
|
||||
break;
|
||||
case 'l':
|
||||
charsToOutput = 16;
|
||||
longArg = *i64Ptr++;
|
||||
break;
|
||||
case 'p':
|
||||
charsToOutput = 0;
|
||||
outputPtrBytes(*ptrPtr, outBuf, &outIx, capacity);
|
||||
ptrPtr++;
|
||||
break;
|
||||
case 'c':
|
||||
charsToOutput = 0;
|
||||
outputChar(*i8Ptr, outBuf, &outIx, capacity, indent);
|
||||
i8Ptr++;
|
||||
break;
|
||||
case 's':
|
||||
charsToOutput = 0;
|
||||
outputString(i8Ptr, outBuf, &outIx, capacity, indent);
|
||||
outputChar('\n', outBuf, &outIx, capacity, indent);
|
||||
|
||||
}
|
||||
if (charsToOutput > 0) {
|
||||
outputHexBytes(longArg, charsToOutput, outBuf, &outIx, capacity);
|
||||
outputChar(' ', outBuf, &outIx, capacity, indent);
|
||||
if (ptrPtr == NULL) {
|
||||
outputString("NULL", outBuf, &outIx, capacity, indent);
|
||||
} else {
|
||||
for (i=0; i<vectorLen; i++) {
|
||||
switch (vectorType) {
|
||||
case 'b':
|
||||
charsToOutput = 2;
|
||||
longArg = *i8Ptr++;
|
||||
break;
|
||||
case 'h':
|
||||
charsToOutput = 4;
|
||||
longArg = *i16Ptr++;
|
||||
break;
|
||||
case 'd':
|
||||
charsToOutput = 8;
|
||||
longArg = *i32Ptr++;
|
||||
break;
|
||||
case 'l':
|
||||
charsToOutput = 16;
|
||||
longArg = *i64Ptr++;
|
||||
break;
|
||||
case 'p':
|
||||
charsToOutput = 0;
|
||||
outputPtrBytes(*ptrPtr, outBuf, &outIx, capacity);
|
||||
ptrPtr++;
|
||||
break;
|
||||
case 'c':
|
||||
charsToOutput = 0;
|
||||
outputChar(*i8Ptr, outBuf, &outIx, capacity, indent);
|
||||
i8Ptr++;
|
||||
break;
|
||||
case 's':
|
||||
charsToOutput = 0;
|
||||
outputString(i8Ptr, outBuf, &outIx, capacity, indent);
|
||||
outputChar('\n', outBuf, &outIx, capacity, indent);
|
||||
|
||||
}
|
||||
if (charsToOutput > 0) {
|
||||
outputHexBytes(longArg, charsToOutput, outBuf, &outIx, capacity);
|
||||
outputChar(' ', outBuf, &outIx, capacity, indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
outputChar('[', outBuf, &outIx, capacity, indent);
|
||||
outputHexBytes(vectorLen, 8, outBuf, &outIx, capacity);
|
||||
outputChar(']', outBuf, &outIx, capacity, indent);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -272,10 +288,48 @@ utrace_format(char *outBuf, int32_t capacity, int32_t indent, const char *fmt, v
|
|||
outputChar(fmtC, outBuf, &outIx, capacity, indent);
|
||||
}
|
||||
}
|
||||
outputChar(0, outBuf, &outIx, capacity, indent);
|
||||
return outIx;
|
||||
}
|
||||
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
utrace_formatExit(char *outBuf, int32_t capacity, int32_t indent,
|
||||
int32_t fnNumber, int32_t argType, va_list args) {
|
||||
int32_t outIx = 0;
|
||||
int32_t intVal;
|
||||
UBool boolVal;
|
||||
void *ptrVal;
|
||||
UErrorCode status;
|
||||
|
||||
outputString(utrace_functionName(fnNumber), outBuf, &outIx, capacity, indent);
|
||||
outputString(" returns", outBuf, &outIx, capacity, indent);
|
||||
switch (argType & UTRACE_EXITV_MASK) {
|
||||
case UTRACE_EXITV_I32:
|
||||
outputChar(' ', outBuf, &outIx, capacity, indent);
|
||||
intVal = (int32_t)va_arg(args, int32_t);
|
||||
outputHexBytes(intVal, 8, outBuf, &outIx, capacity);
|
||||
break;
|
||||
case UTRACE_EXITV_PTR:
|
||||
outputChar(' ', outBuf, &outIx, capacity, indent);
|
||||
ptrVal = (void *)va_arg(args, void *);
|
||||
outputPtrBytes(ptrVal, outBuf, &outIx, capacity);
|
||||
break;
|
||||
case UTRACE_EXITV_BOOL:
|
||||
outputChar(' ', outBuf, &outIx, capacity, indent);
|
||||
boolVal = (UBool)va_arg(args, int32_t); /* gcc wants int, not UBool */
|
||||
outputString(boolVal? "TRUE": "FALSE", outBuf, &outIx, capacity, indent);
|
||||
}
|
||||
|
||||
outputString(".", outBuf, &outIx, capacity, indent);
|
||||
if (argType & UTRACE_EXITV_STATUS) {
|
||||
outputString(" Status = ", outBuf, &outIx, capacity, indent);
|
||||
status = (UErrorCode)va_arg(args, UErrorCode);
|
||||
outputString(u_errorName(status), outBuf, &outIx, capacity, indent);
|
||||
}
|
||||
outputChar(0, outBuf, &outIx, capacity, indent);
|
||||
}
|
||||
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
utrace_setFunctions(const void *context,
|
||||
|
@ -318,6 +372,8 @@ trCollNames[] = {
|
|||
"ucol_strcoll",
|
||||
"ucol_getSortKey",
|
||||
"ucol_getLocale",
|
||||
"ucol_nextSortKeyPart",
|
||||
"ucol_strcollIter",
|
||||
0};
|
||||
|
||||
|
||||
|
|
|
@ -4290,10 +4290,10 @@ ucol_getSortKey(const UCollator *coll,
|
|||
UTRACE_ENTRY(UTRACE_UCOL_GET_SORTKEY);
|
||||
if (UTRACE_LEVEL(UTRACE_VERBOSE)) {
|
||||
int32_t actualSrcLen = sourceLength;
|
||||
if (actualSrcLen==0 && source!=NULL) {
|
||||
if (actualSrcLen==-1 && source!=NULL) {
|
||||
actualSrcLen = u_strlen(source);
|
||||
}
|
||||
UTRACE_DATA2(UTRACE_VERBOSE, "source string %vh", source, actualSrcLen);
|
||||
UTRACE_DATA3(UTRACE_VERBOSE, "coll=%p, source string = %vh ", coll, source, actualSrcLen);
|
||||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
@ -5758,6 +5758,7 @@ ucol_nextSortKeyPart(const UCollator *coll,
|
|||
if(status==NULL || U_FAILURE(*status)) {
|
||||
return 0;
|
||||
}
|
||||
UTRACE_ENTRY(UTRACE_UCOL_NEXTSORTKEYPART);
|
||||
if( coll==NULL || iter==NULL ||
|
||||
state==NULL ||
|
||||
count<0 || (count>0 && dest==NULL)
|
||||
|
@ -5765,9 +5766,12 @@ ucol_nextSortKeyPart(const UCollator *coll,
|
|||
*status=U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
|
||||
UTRACE_DATA6(UTRACE_VERBOSE, "coll=%p, iter=%p, state=%d %d, dest=%p, count=%d",
|
||||
coll, iter, state[0], state[1], dest, count);
|
||||
|
||||
if(count==0) {
|
||||
/* nothing to do */
|
||||
UTRACE_EXIT_D(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5844,6 +5848,7 @@ ucol_nextSortKeyPart(const UCollator *coll,
|
|||
s.iterator = unorm_setIter(normIter, iter, UNORM_FCD, status);
|
||||
s.flags &= ~UCOL_ITER_NORM;
|
||||
if(U_FAILURE(*status)) {
|
||||
UTRACE_EXIT_S(*status);
|
||||
return 0;
|
||||
}
|
||||
} else if(level == UCOL_PSK_IDENTICAL) {
|
||||
|
@ -5853,6 +5858,7 @@ ucol_nextSortKeyPart(const UCollator *coll,
|
|||
s.iterator = unorm_setIter(normIter, iter, UNORM_NFD, status);
|
||||
s.flags &= ~UCOL_ITER_NORM;
|
||||
if(U_FAILURE(*status)) {
|
||||
UTRACE_EXIT_S(*status);
|
||||
return 0;
|
||||
}
|
||||
doingIdenticalFromStart = TRUE;
|
||||
|
@ -5877,6 +5883,7 @@ ucol_nextSortKeyPart(const UCollator *coll,
|
|||
/* reset to previous state */
|
||||
s.iterator->setState(s.iterator, iterState, status);
|
||||
if(U_FAILURE(*status)) {
|
||||
UTRACE_EXIT_S(*status);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -5921,6 +5928,7 @@ ucol_nextSortKeyPart(const UCollator *coll,
|
|||
if(CE==UCOL_NO_MORE_CES) {
|
||||
/* should not happen */
|
||||
*status=U_INTERNAL_PROGRAM_ERROR;
|
||||
UTRACE_EXIT_S(*status);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -6401,6 +6409,7 @@ ucol_nextSortKeyPart(const UCollator *coll,
|
|||
// At this point we have a NFD iterator that is positioned
|
||||
// in the right place
|
||||
if(U_FAILURE(*status)) {
|
||||
UTRACE_EXIT_S(*status);
|
||||
return 0;
|
||||
}
|
||||
first = uiter_previous32(s.iterator);
|
||||
|
@ -6470,6 +6479,7 @@ ucol_nextSortKeyPart(const UCollator *coll,
|
|||
break;
|
||||
default:
|
||||
*status = U_INTERNAL_PROGRAM_ERROR;
|
||||
UTRACE_EXIT_S(*status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -6543,6 +6553,9 @@ saveState:
|
|||
}
|
||||
|
||||
// Return number of meaningful sortkey bytes.
|
||||
UTRACE_DATA4(UTRACE_VERBOSE, "dest = %vb, state=%d %d",
|
||||
dest,i, state[0], state[1]);
|
||||
UTRACE_EXIT_D(i);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -8486,11 +8499,20 @@ ucol_strcollIter( const UCollator *coll,
|
|||
UCharIterator *sIter,
|
||||
UCharIterator *tIter,
|
||||
UErrorCode *status) {
|
||||
if(!status || U_FAILURE(*status) || sIter == tIter) {
|
||||
if(!status || U_FAILURE(*status)) {
|
||||
return UCOL_EQUAL;
|
||||
}
|
||||
|
||||
UTRACE_ENTRY(UTRACE_UCOL_STRCOLLITER);
|
||||
UTRACE_DATA3(UTRACE_VERBOSE, "coll=%p, sIter=%p, tIter=%p", coll, sIter, tIter);
|
||||
|
||||
if (sIter == tIter) {
|
||||
UTRACE_EXIT_DS(UCOL_EQUAL, *status)
|
||||
return UCOL_EQUAL;
|
||||
}
|
||||
if(sIter == NULL || tIter == NULL || coll == NULL) {
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
UTRACE_EXIT_DS(UCOL_EQUAL, *status)
|
||||
return UCOL_EQUAL;
|
||||
}
|
||||
|
||||
|
@ -8570,6 +8592,7 @@ end_compare:
|
|||
unorm_closeIter(tNormIter);
|
||||
}
|
||||
|
||||
UTRACE_EXIT_DS(result, *status)
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -8585,9 +8608,22 @@ ucol_strcoll( const UCollator *coll,
|
|||
const UChar *target,
|
||||
int32_t targetLength) {
|
||||
U_ALIGN_CODE(16);
|
||||
|
||||
UTRACE_ENTRY(UTRACE_UCOL_STRCOLL);
|
||||
UTRACE_DATA5(UTRACE_VERBOSE, "coll=%p, source=%p, sourceLength=%d, target=%p, targetLength=%d",
|
||||
coll, source, sourceLength, target, targetLength);
|
||||
if (UTRACE_LEVEL(UTRACE_VERBOSE)) {
|
||||
UTRACE_DATA3(UTRACE_VERBOSE, "coll=%p, source=%p, target=%p", coll, source, target);
|
||||
int32_t actualLen = sourceLength;
|
||||
if (actualLen==-1 && source!=NULL) {
|
||||
actualLen = u_strlen(source);
|
||||
}
|
||||
UTRACE_DATA2(UTRACE_VERBOSE, "source string = %vh ", source, actualLen);
|
||||
actualLen = targetLength;
|
||||
if (actualLen==-1 && target!=NULL) {
|
||||
actualLen = u_strlen(target);
|
||||
}
|
||||
UTRACE_DATA2(UTRACE_VERBOSE, "target string = %vh ", target, actualLen);
|
||||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
if(source == NULL || target == NULL) {
|
||||
// do not crash, but return. Should have
|
||||
|
@ -8754,7 +8790,7 @@ ucol_getLocale(const UCollator *coll, ULocDataLocaleType type, UErrorCode *statu
|
|||
if(status == NULL || U_FAILURE(*status)) {
|
||||
return NULL;
|
||||
}
|
||||
UTRACE_ENTRY(UTRACE_COLLATION_GETLOCALE);
|
||||
UTRACE_ENTRY(UTRACE_UCOL_GETLOCALE);
|
||||
UTRACE_DATA1(UTRACE_INFO, "coll=%p", coll);
|
||||
|
||||
switch(type) {
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "unicode/ustring.h"
|
||||
#include "unicode/ures.h"
|
||||
#include "unicode/ucoleitr.h"
|
||||
#include "unicode/utrace.h"
|
||||
#include "cintltst.h"
|
||||
#include "capitst.h"
|
||||
#include "ccolltst.h"
|
||||
|
@ -533,9 +532,6 @@ void TestRuleBasedColl()
|
|||
log_err("Rule \"z < a\" fails");
|
||||
}
|
||||
ucol_close(col1);
|
||||
|
||||
/* Turn off tracing for tests that follow */
|
||||
utrace_setFunctions(NULL, NULL, NULL, NULL, UTRACE_VERBOSE, &status);
|
||||
}
|
||||
|
||||
void TestCompare()
|
||||
|
|
|
@ -65,45 +65,24 @@ void ctest_setICU_DATA(void);
|
|||
*/
|
||||
static int traceFnNestingDepth = 0;
|
||||
void U_CALLCONV TraceEntry(const void *context, int32_t fnNumber) {
|
||||
fprintf(stderr, "%s() Enter \n", utrace_functionName(fnNumber));
|
||||
fprintf(stdout, "%s() Enter \n", utrace_functionName(fnNumber));
|
||||
traceFnNestingDepth++;
|
||||
}
|
||||
|
||||
void U_CALLCONV TraceExit(const void *context, int32_t fnNumber, UTraceExitVal type, va_list args) {
|
||||
int32_t intVal;
|
||||
UBool boolVal;
|
||||
void *ptrVal;
|
||||
|
||||
fprintf(stderr, "%s() returns", utrace_functionName(fnNumber));
|
||||
switch (type & UTRACE_EXITV_MASK) {
|
||||
case UTRACE_EXITV_NONE:
|
||||
fprintf(stderr, ".");
|
||||
break;
|
||||
case UTRACE_EXITV_I32:
|
||||
intVal = (int32_t)va_arg(args, int32_t);
|
||||
fprintf(stderr, " %d", intVal);
|
||||
break;
|
||||
case UTRACE_EXITV_PTR:
|
||||
ptrVal = (void *)va_arg(args, void *);
|
||||
fprintf(stderr, " %x", ptrVal);
|
||||
break;
|
||||
case UTRACE_EXITV_BOOL:
|
||||
boolVal = (UBool)va_arg(args, int32_t); /* gcc wants int, not UBool */
|
||||
fprintf(stderr, boolVal? " TRUE": " FALSE");
|
||||
char buf[2000];
|
||||
if (traceFnNestingDepth>0) {
|
||||
traceFnNestingDepth--;
|
||||
}
|
||||
if (type & UTRACE_EXITV_STATUS) {
|
||||
UErrorCode status = (UErrorCode)va_arg(args, UErrorCode);
|
||||
fprintf(stderr, " Status = %s.", u_errorName(status));
|
||||
}
|
||||
traceFnNestingDepth--;
|
||||
fprintf(stderr, "\n");
|
||||
utrace_formatExit(buf, sizeof(buf), traceFnNestingDepth*3, fnNumber, type, args);
|
||||
fprintf(stdout, "%s\n", buf);
|
||||
}
|
||||
|
||||
void U_CALLCONV TraceData(const void *context, int32_t fnNumber,
|
||||
int32_t level, const char *fmt, va_list args) {
|
||||
char buf[2000];
|
||||
utrace_format(buf, sizeof(buf), traceFnNestingDepth*3, fmt, args);
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
fprintf(stdout, "%s\n", buf);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue