OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ******************************************************************************* |
| 3 * |
| 4 * Copyright (C) 2003-2009, International Business Machines |
| 5 * Corporation and others. All Rights Reserved. |
| 6 * |
| 7 ******************************************************************************* |
| 8 * file name: utracimp.h |
| 9 * encoding: US-ASCII |
| 10 * tab size: 8 (not used) |
| 11 * indentation:4 |
| 12 * |
| 13 * created on: 2003aug06 |
| 14 * created by: Markus W. Scherer |
| 15 * |
| 16 * Internal header for ICU tracing/logging. |
| 17 * |
| 18 * |
| 19 * Various notes: |
| 20 * - using a trace level variable to only call trace functions |
| 21 * when the level is sufficient |
| 22 * - using the same variable for tracing on/off to never make a function |
| 23 * call when off |
| 24 * - the function number is put into a local variable by the entry macro |
| 25 * and used implicitly to avoid copy&paste/typing mistakes by the developer |
| 26 * - the application must call utrace_setFunctions() and pass in |
| 27 * implementations for the trace functions |
| 28 * - ICU trace macros call ICU functions that route through the function |
| 29 * pointers if they have been set; |
| 30 * this avoids an indirection at the call site |
| 31 * (which would cost more code for another check and for the indirection) |
| 32 * |
| 33 * ### TODO Issues: |
| 34 * - Verify that va_list is portable among compilers for the same platform. |
| 35 * va_list should be portable because printf() would fail otherwise! |
| 36 * - Should enum values like UTraceLevel be passed into int32_t-type arguments, |
| 37 * or should enum types be used? |
| 38 */ |
| 39 |
| 40 #ifndef __UTRACIMP_H__ |
| 41 #define __UTRACIMP_H__ |
| 42 |
| 43 #include "unicode/utrace.h" |
| 44 #include <stdarg.h> |
| 45 |
| 46 U_CDECL_BEGIN |
| 47 |
| 48 /** |
| 49 * \var utrace_level |
| 50 * Trace level variable. Negative for "off". |
| 51 * Use only via UTRACE_ macros. |
| 52 * @internal |
| 53 */ |
| 54 #ifdef UTRACE_IMPL |
| 55 U_EXPORT int32_t |
| 56 #else |
| 57 U_CFUNC U_COMMON_API int32_t |
| 58 #endif |
| 59 utrace_level; |
| 60 |
| 61 |
| 62 /** |
| 63 * Traced Function Exit return types. |
| 64 * Flags indicating the number and types of varargs included in a call |
| 65 * to a UTraceExit function. |
| 66 * Bits 0-3: The function return type. First variable param. |
| 67 * Bit 4: Flag for presence of U_ErrorCode status param. |
| 68 * @internal |
| 69 */ |
| 70 typedef enum UTraceExitVal { |
| 71 /** The traced function returns no value @internal */ |
| 72 UTRACE_EXITV_NONE = 0, |
| 73 /** The traced function returns an int32_t, or compatible, type. @internal
*/ |
| 74 UTRACE_EXITV_I32 = 1, |
| 75 /** The traced function returns a pointer @internal */ |
| 76 UTRACE_EXITV_PTR = 2, |
| 77 /** The traced function returns a UBool @internal */ |
| 78 UTRACE_EXITV_BOOL = 3, |
| 79 /** Mask to extract the return type values from a UTraceExitVal @internal *
/ |
| 80 UTRACE_EXITV_MASK = 0xf, |
| 81 /** Bit indicating that the traced function includes a UErrorCode parameter
@internal */ |
| 82 UTRACE_EXITV_STATUS = 0x10 |
| 83 } UTraceExitVal; |
| 84 |
| 85 /** |
| 86 * Trace function for the entry point of a function. |
| 87 * Do not use directly, use UTRACE_ENTRY instead. |
| 88 * @param fnNumber The UTraceFunctionNumber for the current function. |
| 89 * @internal |
| 90 */ |
| 91 U_CAPI void U_EXPORT2 |
| 92 utrace_entry(int32_t fnNumber); |
| 93 |
| 94 /** |
| 95 * Trace function for each exit point of a function. |
| 96 * Do not use directly, use UTRACE_EXIT* instead. |
| 97 * @param fnNumber The UTraceFunctionNumber for the current function. |
| 98 * @param returnType The type of the value returned by the function. |
| 99 * @param errorCode The UErrorCode value at function exit. See UTRACE_EXIT. |
| 100 * @internal |
| 101 */ |
| 102 U_CAPI void U_EXPORT2 |
| 103 utrace_exit(int32_t fnNumber, int32_t returnType, ...); |
| 104 |
| 105 |
| 106 /** |
| 107 * Trace function used inside functions that have a UTRACE_ENTRY() statement. |
| 108 * Do not use directly, use UTRACE_DATAX() macros instead. |
| 109 * |
| 110 * @param utraceFnNumber The number of the current function, from the local |
| 111 * variable of the same name. |
| 112 * @param level The trace level for this message. |
| 113 * @param fmt The trace format string. |
| 114 * |
| 115 * @internal |
| 116 */ |
| 117 U_CAPI void U_EXPORT2 |
| 118 utrace_data(int32_t utraceFnNumber, int32_t level, const char *fmt, ...); |
| 119 |
| 120 U_CDECL_END |
| 121 |
| 122 #if U_ENABLE_TRACING |
| 123 |
| 124 /** |
| 125 * Boolean expression to see if ICU tracing is turned on |
| 126 * to at least the specified level. |
| 127 * @internal |
| 128 */ |
| 129 #define UTRACE_LEVEL(level) (utrace_getLevel()>=(level)) |
| 130 |
| 131 /** |
| 132 * Flag bit in utraceFnNumber, the local variable added to each function |
| 133 * with tracing code to contains the function number. |
| 134 * |
| 135 * Set the flag if the function's entry is traced, which will cause the |
| 136 * function's exit to also be traced. utraceFnNumber is uncoditionally |
| 137 * set at entry, whether or not the entry is traced, so that it will |
| 138 * always be available for error trace output. |
| 139 * @internal |
| 140 */ |
| 141 #define UTRACE_TRACED_ENTRY 0x80000000 |
| 142 |
| 143 /** |
| 144 * Trace statement for the entry point of a function. |
| 145 * Stores the function number in a local variable. |
| 146 * In C code, must be placed immediately after the last variable declaration. |
| 147 * Must be matched with UTRACE_EXIT() at all function exit points. |
| 148 * |
| 149 * Tracing should start with UTRACE_ENTRY after checking for |
| 150 * U_FAILURE at function entry, so that if a function returns immediately |
| 151 * because of a pre-existing error condition, it does not show up in the trace, |
| 152 * consistent with ICU's error handling model. |
| 153 * |
| 154 * @param fnNumber The UTraceFunctionNumber for the current function. |
| 155 * @internal |
| 156 */ |
| 157 #define UTRACE_ENTRY(fnNumber) \ |
| 158 int32_t utraceFnNumber=(fnNumber); \ |
| 159 if(utrace_getLevel()>=UTRACE_INFO) { \ |
| 160 utrace_entry(fnNumber); \ |
| 161 utraceFnNumber |= UTRACE_TRACED_ENTRY; \ |
| 162 } |
| 163 |
| 164 |
| 165 /** |
| 166 * Trace statement for the entry point of open and close functions. |
| 167 * Produces trace output at a less verbose setting than plain UTRACE_ENTRY |
| 168 * Stores the function number in a local variable. |
| 169 * In C code, must be placed immediately after the last variable declaration. |
| 170 * Must be matched with UTRACE_EXIT() at all function exit points. |
| 171 * |
| 172 * @param fnNumber The UTraceFunctionNumber for the current function. |
| 173 * @internal |
| 174 */ |
| 175 #define UTRACE_ENTRY_OC(fnNumber) \ |
| 176 int32_t utraceFnNumber=(fnNumber); \ |
| 177 if(utrace_getLevel()>=UTRACE_OPEN_CLOSE) { \ |
| 178 utrace_entry(fnNumber); \ |
| 179 utraceFnNumber |= UTRACE_TRACED_ENTRY; \ |
| 180 } |
| 181 |
| 182 /** |
| 183 * Trace statement for each exit point of a function that has a UTRACE_ENTRY() |
| 184 * statement. |
| 185 * |
| 186 * @param errorCode The function's ICU UErrorCode value at function exit, |
| 187 * or U_ZERO_ERROR if the function does not use a UErrorCode. |
| 188 * 0==U_ZERO_ERROR indicates success, |
| 189 * positive values an error (see u_errorName()), |
| 190 * negative values an informational status. |
| 191 * |
| 192 * @internal |
| 193 */ |
| 194 #define UTRACE_EXIT() \ |
| 195 {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \ |
| 196 utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, UTRACE_EXITV_NONE); \ |
| 197 }} |
| 198 |
| 199 /** |
| 200 * Trace statement for each exit point of a function that has a UTRACE_ENTRY() |
| 201 * statement, and that returns a value. |
| 202 * |
| 203 * @param val The function's return value, int32_t or comatible type. |
| 204 * |
| 205 * @internal |
| 206 */ |
| 207 #define UTRACE_EXIT_VALUE(val) \ |
| 208 {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \ |
| 209 utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, UTRACE_EXITV_I32, val
); \ |
| 210 }} |
| 211 |
| 212 #define UTRACE_EXIT_STATUS(status) \ |
| 213 {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \ |
| 214 utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, UTRACE_EXITV_STATUS,
status); \ |
| 215 }} |
| 216 |
| 217 #define UTRACE_EXIT_VALUE_STATUS(val, status) \ |
| 218 {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \ |
| 219 utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (UTRACE_EXITV_I32 | U
TRACE_EXITV_STATUS), val, status); \ |
| 220 }} |
| 221 |
| 222 #define UTRACE_EXIT_PTR_STATUS(ptr, status) \ |
| 223 {if(utraceFnNumber & UTRACE_TRACED_ENTRY) { \ |
| 224 utrace_exit(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (UTRACE_EXITV_PTR | U
TRACE_EXITV_STATUS), ptr, status); \ |
| 225 }} |
| 226 |
| 227 /** |
| 228 * Trace statement used inside functions that have a UTRACE_ENTRY() statement. |
| 229 * Takes no data arguments. |
| 230 * The number of arguments for this macro must match the number of inserts |
| 231 * in the format string. Vector inserts count as two arguments. |
| 232 * Calls utrace_data() if the level is high enough. |
| 233 * @internal |
| 234 */ |
| 235 #define UTRACE_DATA0(level, fmt) \ |
| 236 if(UTRACE_LEVEL(level)) { \ |
| 237 utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt)); \ |
| 238 } |
| 239 |
| 240 /** |
| 241 * Trace statement used inside functions that have a UTRACE_ENTRY() statement. |
| 242 * Takes one data argument. |
| 243 * The number of arguments for this macro must match the number of inserts |
| 244 * in the format string. Vector inserts count as two arguments. |
| 245 * Calls utrace_data() if the level is high enough. |
| 246 * @internal |
| 247 */ |
| 248 #define UTRACE_DATA1(level, fmt, a) \ |
| 249 if(UTRACE_LEVEL(level)) { \ |
| 250 utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY , (level), (fmt), (a))
; \ |
| 251 } |
| 252 |
| 253 /** |
| 254 * Trace statement used inside functions that have a UTRACE_ENTRY() statement. |
| 255 * Takes two data arguments. |
| 256 * The number of arguments for this macro must match the number of inserts |
| 257 * in the format string. Vector inserts count as two arguments. |
| 258 * Calls utrace_data() if the level is high enough. |
| 259 * @internal |
| 260 */ |
| 261 #define UTRACE_DATA2(level, fmt, a, b) \ |
| 262 if(UTRACE_LEVEL(level)) { \ |
| 263 utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY , (level), (fmt), (a),
(b)); \ |
| 264 } |
| 265 |
| 266 /** |
| 267 * Trace statement used inside functions that have a UTRACE_ENTRY() statement. |
| 268 * Takes three data arguments. |
| 269 * The number of arguments for this macro must match the number of inserts |
| 270 * in the format string. Vector inserts count as two arguments. |
| 271 * Calls utrace_data() if the level is high enough. |
| 272 * @internal |
| 273 */ |
| 274 #define UTRACE_DATA3(level, fmt, a, b, c) \ |
| 275 if(UTRACE_LEVEL(level)) { \ |
| 276 utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a),
(b), (c)); \ |
| 277 } |
| 278 |
| 279 /** |
| 280 * Trace statement used inside functions that have a UTRACE_ENTRY() statement. |
| 281 * Takes four data arguments. |
| 282 * The number of arguments for this macro must match the number of inserts |
| 283 * in the format string. Vector inserts count as two arguments. |
| 284 * Calls utrace_data() if the level is high enough. |
| 285 * @internal |
| 286 */ |
| 287 #define UTRACE_DATA4(level, fmt, a, b, c, d) \ |
| 288 if(UTRACE_LEVEL(level)) { \ |
| 289 utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a),
(b), (c), (d)); \ |
| 290 } |
| 291 |
| 292 /** |
| 293 * Trace statement used inside functions that have a UTRACE_ENTRY() statement. |
| 294 * Takes five data arguments. |
| 295 * The number of arguments for this macro must match the number of inserts |
| 296 * in the format string. Vector inserts count as two arguments. |
| 297 * Calls utrace_data() if the level is high enough. |
| 298 * @internal |
| 299 */ |
| 300 #define UTRACE_DATA5(level, fmt, a, b, c, d, e) \ |
| 301 if(UTRACE_LEVEL(level)) { \ |
| 302 utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a),
(b), (c), (d), (e)); \ |
| 303 } |
| 304 |
| 305 /** |
| 306 * Trace statement used inside functions that have a UTRACE_ENTRY() statement. |
| 307 * Takes six data arguments. |
| 308 * The number of arguments for this macro must match the number of inserts |
| 309 * in the format string. Vector inserts count as two arguments. |
| 310 * Calls utrace_data() if the level is high enough. |
| 311 * @internal |
| 312 */ |
| 313 #define UTRACE_DATA6(level, fmt, a, b, c, d, e, f) \ |
| 314 if(UTRACE_LEVEL(level)) { \ |
| 315 utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a),
(b), (c), (d), (e), (f)); \ |
| 316 } |
| 317 |
| 318 /** |
| 319 * Trace statement used inside functions that have a UTRACE_ENTRY() statement. |
| 320 * Takes seven data arguments. |
| 321 * The number of arguments for this macro must match the number of inserts |
| 322 * in the format string. Vector inserts count as two arguments. |
| 323 * Calls utrace_data() if the level is high enough. |
| 324 * @internal |
| 325 */ |
| 326 #define UTRACE_DATA7(level, fmt, a, b, c, d, e, f, g) \ |
| 327 if(UTRACE_LEVEL(level)) { \ |
| 328 utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a),
(b), (c), (d), (e), (f), (g)); \ |
| 329 } |
| 330 |
| 331 /** |
| 332 * Trace statement used inside functions that have a UTRACE_ENTRY() statement. |
| 333 * Takes eight data arguments. |
| 334 * The number of arguments for this macro must match the number of inserts |
| 335 * in the format string. Vector inserts count as two arguments. |
| 336 * Calls utrace_data() if the level is high enough. |
| 337 * @internal |
| 338 */ |
| 339 #define UTRACE_DATA8(level, fmt, a, b, c, d, e, f, g, h) \ |
| 340 if(UTRACE_LEVEL(level)) { \ |
| 341 utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a),
(b), (c), (d), (e), (f), (g), (h)); \ |
| 342 } |
| 343 |
| 344 /** |
| 345 * Trace statement used inside functions that have a UTRACE_ENTRY() statement. |
| 346 * Takes nine data arguments. |
| 347 * The number of arguments for this macro must match the number of inserts |
| 348 * in the format string. Vector inserts count as two arguments. |
| 349 * Calls utrace_data() if the level is high enough. |
| 350 * @internal |
| 351 */ |
| 352 #define UTRACE_DATA9(level, fmt, a, b, c, d, e, f, g, h, i) \ |
| 353 if(UTRACE_LEVEL(level)) { \ |
| 354 utrace_data(utraceFnNumber & ~UTRACE_TRACED_ENTRY, (level), (fmt), (a),
(b), (c), (d), (e), (f), (g), (h), (i)); \ |
| 355 } |
| 356 |
| 357 #else |
| 358 |
| 359 /* |
| 360 * When tracing is disabled, the following macros become empty |
| 361 */ |
| 362 |
| 363 #define UTRACE_LEVEL(level) 0 |
| 364 #define UTRACE_ENTRY(fnNumber) |
| 365 #define UTRACE_ENTRY_OC(fnNumber) |
| 366 #define UTRACE_EXIT() |
| 367 #define UTRACE_EXIT_VALUE(val) |
| 368 #define UTRACE_EXIT_STATUS(status) |
| 369 #define UTRACE_EXIT_VALUE_STATUS(val, status) |
| 370 #define UTRACE_EXIT_PTR_STATUS(ptr, status) |
| 371 #define UTRACE_DATA0(level, fmt) |
| 372 #define UTRACE_DATA1(level, fmt, a) |
| 373 #define UTRACE_DATA2(level, fmt, a, b) |
| 374 #define UTRACE_DATA3(level, fmt, a, b, c) |
| 375 #define UTRACE_DATA4(level, fmt, a, b, c, d) |
| 376 #define UTRACE_DATA5(level, fmt, a, b, c, d, e) |
| 377 #define UTRACE_DATA6(level, fmt, a, b, c, d, e, f) |
| 378 #define UTRACE_DATA7(level, fmt, a, b, c, d, e, f, g) |
| 379 #define UTRACE_DATA8(level, fmt, a, b, c, d, e, f, g, h) |
| 380 #define UTRACE_DATA9(level, fmt, a, b, c, d, e, f, g, h, i) |
| 381 |
| 382 #endif |
| 383 |
| 384 #endif |
OLD | NEW |