1 /* 2 * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 /** 17 * 18 * @file picodbg.h 19 * 20 * Provides functions and macros to debug the Pico system and to trace 21 * the execution of its code. 22 * 23 * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland 24 * All rights reserved. 25 * 26 * History: 27 * - 2009-04-20 -- initial version 28 */ 29 30 /** 31 * @addtogroup picodbg 32 * ---------------------------------------------------\n 33 * <b> Pico Debug Support </b>\n 34 * ---------------------------------------------------\n 35 * GENERAL REMARKS 36 * --------------- 37 * This module provides a set of macros to help debug the Pico system. 38 * The usage of macros allows for completely removing debug code from 39 * the binaries delivered to customers. To enable diagnostic output 40 * the preprocessor symbol PICO_DEBUG has to be defined. 41 * 42 * By using global variables (to store the current log level etc.) 43 * this module violates a basic Pico design principle! 44 * 45 * Justification:\n 46 * - going without global data would reduce the functionality 47 * of this module considerably (e.g., log level could not be 48 * changed at runtime etc.) 49 * - at the moment, the only known system interdicting global 50 * variables is Symbian; but even there global variables are 51 * possible by using thread-local storage 52 * - allocating global data on the heap would require to pass 53 * a handle to this memory block to all routines of this 54 * module which in turn implies that _every_ function in the 55 * Pico system would require a pointer to some global data; 56 * obviously, this would be very awkward 57 * 58 * Furthermore, this module uses the non-standardized but handy 59 * __FUNCTION__ macro. It expands to the name of the enclosing 60 * function. For compilers not supporting this macro simply 61 * define __FUNCTION__ as an empty string. 62 * 63 * 64 * INITIALIZATION/TERMINATION\n 65 * --------------------------\n 66 * Before using any debug macros, this module has to be initialized 67 * by calling PICODBG_INITIALIZE(). If the routines are not needed 68 * anymore, PICODBG_TERMINATE() has to be called to terminate the 69 * module (e.g., to close the log file). 70 * 71 * 72 * TRACING\n 73 * -------\n 74 * Each tracing message is associated with a log level which describes 75 * its severity. The following levels are supported: 76 * - Trace - Very detailed log messages, potentially of a high 77 * frequency and volume 78 * - Debug - Less detailed and/or less frequent debugging messages 79 * - Info - Informational messages 80 * - Warn - Warnings which don't appear to the Pico user 81 * - Error - Error messages 82 * 83 * Tracing messages can use the well-known printf format specification. 84 * But because variadic macros (macros with a variable no. arguments) 85 * are not commonly supported by compilers a little trick is used 86 * which requires the format string and its arguments to be enclosed 87 * in double parenthesis: 88 * 89 * - PICODBG_INFO(("hello, world!")); 90 * - PICODBG_TRACE(("argc=%d", argc)); 91 * ... 92 * 93 * Each tracing message is expected to be a single line of text. Some 94 * contextual information (e.g., log level, time and date, source file 95 * and line number) and a newline are automatically added. The output 96 * format can be customized by a call to PICODBG_SET_OUTPUT_FORMAT(). 97 * 98 * Sample output: 99 * - *** info|2008-04-03|14:51:36|dbgdemo.c(15)|hello world 100 * - *** trace|2008-04-03|14:51:36|dbgdemo.c(16)|argc=2 101 * - ... 102 * 103 * To compose a tracing message line consisting of, e.g. the elements 104 * of an array, on the Info level two additional macros shown in the 105 * following example are provided: 106 * 107 * PICODBG_INFO_CTX();\n 108 * for (i = 0; i < len; i++)\n 109 * ...some calc with arr and i\n 110 * PICODBG_INFO_MSG((" %d", arr[i]));\n 111 * }\n 112 * PICODBG_INFO_MSG(("\n"));\n 113 * 114 * Colored output of tracing messages helps to capture severe problems 115 * quickly. This feature is supported on the Windows platform and on 116 * platforms supporting ANSI escape codes. PICODBG_ENABLE_COLORS() lets 117 * you turn on and off colored output. 118 * 119 * 120 * FILTERING\n 121 * ---------\n 122 * By calling PICODBG_SET_LOG_LEVEL() the log level may be changed at 123 * any time to increase/decrease the amount of debugging output. 124 * 125 * By calling PICODBG_SET_LOG_FILTERFN() the log filter may be changed 126 * at any time to change the source file name being used as filter for 127 * log messages (ie. only tracing info of the specified file will be 128 * logged). To disable the file name based filter set the filter file 129 * name to an empty string. 130 * 131 * Future version of this module might provide further filtering 132 * possibilities (e.g., filtering based on function names * etc.). 133 * 134 * 135 * LOGGING\n 136 * -------\n 137 * By default, tracing messages are output to the console (stderr). 138 * This allows for separating diagnostic output from other console 139 * output to stdout. In addition, tracing messages may be saved to 140 * a file by calling PICODBG_SET_LOG_FILE(). 141 * Currently, file output is the only additional output target; but 142 * on embedded systems, more output targets may be required (e.g., 143 * sending output to a serial port or over the network). 144 * 145 * 146 * ASSERTIONS\n 147 * ----------\n 148 * To support the 'design/programming by contract' paradigm, this 149 * module also provides assertions. PICODBG_ASSERT(expr) evualuates 150 * an expression and, when the result is false, prints a diagnostic 151 * message and aborts the program. 152 * 153 * 154 * FUTURE EXTENSIONS\n 155 * -----------------\n 156 * - advanced tracing functions to dump complex data 157 * - debug memory allocation that can be used to assist in 158 * finding memory problems 159 */ 160 161 162 #if !defined(__PICODBG_H__) 163 #define __PICODBG_H__ 164 165 #ifdef __cplusplus 166 extern "C" { 167 #endif 168 #if 0 169 } 170 #endif 171 172 173 /* Not all compilers support the __FUNCTION__ macro */ 174 #if !defined(__FUNCTION__) && !defined(__GNUC__) 175 #define __FUNCTION__ "" 176 #endif 177 178 179 /* Log levels sorted by severity */ 180 #define PICODBG_LOG_LEVEL_ERROR 1 181 #define PICODBG_LOG_LEVEL_WARN 2 182 #define PICODBG_LOG_LEVEL_INFO 3 183 #define PICODBG_LOG_LEVEL_DEBUG 4 184 #define PICODBG_LOG_LEVEL_TRACE 5 185 186 /* Output format flags */ 187 #define PICODBG_SHOW_LEVEL 0x0001 188 #define PICODBG_SHOW_DATE 0x0002 189 #define PICODBG_SHOW_TIME 0x0004 190 #define PICODBG_SHOW_SRCNAME 0x0008 191 #define PICODBG_SHOW_SRCLINE 0x0010 192 #define PICODBG_SHOW_SRCALL (PICODBG_SHOW_SRCNAME | PICODBG_SHOW_SRCLINE) 193 #define PICODBG_SHOW_FUNCTION 0x0020 194 #define PICODBG_SHOW_POS (PICODBG_SHOW_SRCALL | PICODBG_SHOW_FUNCTION) 195 196 /* definition of PICO_DEBUG enables debugging code */ 197 #if defined(PICO_DEBUG) 198 199 #define PICODBG_INITIALIZE(level) \ 200 picodbg_initialize(level) 201 202 #define PICODBG_TERMINATE() \ 203 picodbg_terminate() 204 205 #define PICODBG_SET_LOG_LEVEL(level) \ 206 picodbg_setLogLevel(level) 207 208 #define PICODBG_SET_LOG_FILTERFN(name) \ 209 picodbg_setLogFilterFN(name) 210 211 #define PICODBG_SET_LOG_FILE(name) \ 212 picodbg_setLogFile(name) 213 214 #define PICODBG_ENABLE_COLORS(flag) \ 215 picodbg_enableColors(flag) 216 217 #define PICODBG_SET_OUTPUT_FORMAT(format) \ 218 picodbg_setOutputFormat(format) 219 220 221 #define PICODBG_ASSERT(expr) \ 222 for (;!(expr);picodbg_assert(__FILE__, __LINE__, __FUNCTION__, #expr)) 223 224 #define PICODBG_ASSERT_RANGE(val, min, max) \ 225 PICODBG_ASSERT(((val) >= (min)) && ((val) <= (max))) 226 227 228 #define PICODBG_LOG(level, msg) \ 229 picodbg_log(level, 1, __FILE__, __LINE__, __FUNCTION__, picodbg_varargs msg) 230 231 #define PICODBG_ERROR(msg) \ 232 PICODBG_LOG(PICODBG_LOG_LEVEL_ERROR, msg) 233 234 #define PICODBG_WARN(msg) \ 235 PICODBG_LOG(PICODBG_LOG_LEVEL_WARN, msg) 236 237 #define PICODBG_INFO(msg) \ 238 PICODBG_LOG(PICODBG_LOG_LEVEL_INFO, msg) 239 240 #define PICODBG_DEBUG(msg) \ 241 PICODBG_LOG(PICODBG_LOG_LEVEL_DEBUG, msg) 242 243 #define PICODBG_TRACE(msg) \ 244 PICODBG_LOG(PICODBG_LOG_LEVEL_TRACE, msg) 245 246 247 #define PICODBG_INFO_CTX() \ 248 picodbg_log(PICODBG_LOG_LEVEL_INFO, 0, __FILE__, __LINE__, __FUNCTION__, "") 249 250 #define PICODBG_INFO_MSG(msg) \ 251 picodbg_log_msg(PICODBG_LOG_LEVEL_INFO, __FILE__, picodbg_varargs msg) 252 253 #define PICODBG_INFO_MSG_F(filterfn, msg) \ 254 picodbg_log_msg(PICODBG_LOG_LEVEL_INFO, (const char *)filterfn, picodbg_varargs msg) 255 256 257 258 /* helper routines; should NOT be used directly! */ 259 260 void picodbg_initialize(int level); 261 void picodbg_terminate(); 262 263 void picodbg_setLogLevel(int level); 264 void picodbg_setLogFilterFN(const char *name); 265 void picodbg_setLogFile(const char *name); 266 void picodbg_enableColors(int flag); 267 void picodbg_setOutputFormat(unsigned int format); 268 269 const char *picodbg_varargs(const char *format, ...); 270 271 void picodbg_log(int level, int donewline, const char *file, int line, 272 const char *func, const char *msg); 273 void picodbg_assert(const char *file, int line, const char *func, 274 const char *expr); 275 276 void picodbg_log_msg(int level, const char *file, const char *msg); 277 278 279 #else /* release version; omit debugging code */ 280 281 #define PICODBG_INITIALIZE(level) 282 #define PICODBG_TERMINATE() 283 #define PICODBG_SET_LOG_LEVEL(level) 284 #define PICODBG_SET_LOG_FILTERFN(name) 285 #define PICODBG_SET_LOG_FILE(name) 286 #define PICODBG_ENABLE_COLORS(flag) 287 #define PICODBG_SET_OUTPUT_FORMAT(format) 288 289 #define PICODBG_ASSERT(expr) 290 #define PICODBG_ASSERT_RANGE(val, min, max) 291 292 #define PICODBG_LOG(level, msg) 293 #define PICODBG_ERROR(msg) 294 #define PICODBG_WARN(msg) 295 #define PICODBG_INFO(msg) 296 #define PICODBG_DEBUG(msg) 297 #define PICODBG_TRACE(msg) 298 299 #define PICODBG_INFO_CTX() 300 #define PICODBG_INFO_MSG(msg) 301 #define PICODBG_INFO_MSG_F(filterfn, msg) 302 303 304 #endif /* defined(PICO_DEBUG) */ 305 306 #ifdef __cplusplus 307 } 308 #endif 309 310 311 #endif /* !defined(__PICODBG_H__) */ 312