COSA
An Object-Oriented Platform for Arduino Programming
Debug.hh
Go to the documentation of this file.
1 
21 #ifndef COSA_DEBUG_HH
22 #define COSA_DEBUG_HH
23 
24 #include "Cosa/Types.h"
25 #include "Cosa/IOStream.hh"
26 
27 extern class Debug debug;
28 
48 class Debug : public IOStream {
49 public:
53  Debug() :
54  IOStream(),
55  m_var(NULL),
56  EXITCHARACTER(0x1d)
57  {}
58 
69  bool begin(IOStream::Device* dev,
70  const char* file,
71  int line,
72  const char* func);
73 
83  void assert(const char* file,
84  int line,
85  const char* func,
86  str_P cond);
87 
97  void break_at(const char* file,
98  int line,
99  const char* func,
100  str_P cond);
101 
108  bool check_stack(int room = 128);
109 
119  void observe_at(const char* file,
120  int line,
121  const char* func,
122  str_P expr)
123  {
124  UNUSED(file);
125  printf(PSTR("Debug::observe_at:%s:%d:%S="), func, line, expr);
126  }
127 
132  bool end();
133 
139  class Variable {
140  public:
145  Variable(const char* func, str_P name, void* ref, size_t size) :
146  m_next(debug.m_var),
147  m_func(func),
148  m_name(name),
149  m_ref(ref),
150  m_size(size)
151  {
152  debug.m_var = this;
153  }
154 
160  {
161  debug.m_var = m_next;
162  }
163 
167  void print();
168 
169  protected:
170  friend class Debug;
171  class Variable* m_next;
172  const char* m_func;
174  void* m_ref;
175  size_t m_size;
176  };
177 
178 protected:
186  void run(const char* file = NULL,
187  int line = 0,
188  const char* func = NULL,
189  str_P expr = NULL);
190 
191 #if !defined(COSA_DEBUG_NO_BACKTRACE)
192 
196  void do_backtrace(const char* func);
197 #endif
198 
199 #if !defined(COSA_DEBUG_NO_HELP)
200 
203  void do_help();
204 #endif
205 
206 #if !defined(COSA_DEBUG_NO_LOOKUP_VARIABLES)
207 
212  bool do_lookup_variables(const char* name);
213 #endif
214 
215 #if !defined(COSA_DEBUG_NO_MEMORY_USAGE)
216 
220  void do_memory_usage(int marker);
221 #endif
222 
223 #if !defined(COSA_DEBUG_NO_PRINT_DATA)
224 
227  void do_print_data();
228 #endif
229 
230 #if !defined(COSA_DEBUG_NO_PRINT_HEAP)
231 
234  void do_print_heap();
235 #endif
236 
237 #if !defined(COSA_DEBUG_NO_PRINT_STACK)
238 
241  void do_print_stack(int marker);
242 #endif
243 
244 #if !defined(COSA_DEBUG_NO_PRINT_VARIABLES)
245 
256  void do_print_variables();
257 #endif
258 
259 #if !defined(COSA_DEBUG_NO_QUIT)
260 
263  void do_quit();
264 #endif
265 
266  friend class Variable;
269  int DATAEND;
270  int DATASIZE;
271 };
272 
273 #if !defined(NDEBUG)
274 
280 #define DEBUG_STREAM(dev) \
281  do { \
282  debug.begin(&dev, __FILE__,__LINE__, __PRETTY_FUNCTION__); \
283  } while (0)
284 
285 #if defined(ASSERT)
286 #undef ASSERT
287 #endif
288 
294 #define ASSERT(cond) \
295  do { \
296  if (UNLIKELY(!(cond))) \
297  debug.assert(__FILE__,__LINE__, __PRETTY_FUNCTION__, \
298  __PSTR(# cond)); \
299  } while (0)
300 
306 #define BREAKPOINT() \
307  do { \
308  debug.break_at(__FILE__,__LINE__, __PRETTY_FUNCTION__, NULL); \
309  } while (0)
310 
317 #define BREAK_IF(cond) \
318  do { \
319  if (UNLIKELY(cond)) \
320  debug.break_at(__FILE__,__LINE__, __PRETTY_FUNCTION__, \
321  __PSTR(# cond)); \
322  } while (0)
323 
328 #define CHECK_STACK(room) \
329  do { \
330  if (UNLIKELY(!(debug.check_stack(room)))) \
331  debug.assert(__FILE__,__LINE__, __PRETTY_FUNCTION__, \
332  __PSTR("check_stack()")); \
333  } while (0)
334 
341 #define OBSERVE_IF(cond,expr) \
342  do { \
343  if (UNLIKELY(cond)) { \
344  debug.observe_at(__FILE__,__LINE__, __PRETTY_FUNCTION__, \
345  __PSTR(# expr)); \
346  debug.print(expr); \
347  debug.println(); \
348  } \
349  } while (0)
350 
355 #define OBSERVE(expr) OBSERVE_IF(expr,true)
356 
363 #define REGISTER(var) \
364  Debug::Variable debug__ ## var(__PRETTY_FUNCTION__, \
365  __PSTR(#var), \
366  (void*) &var, \
367  sizeof(var));
368 
369 #else
370 
371 #if !defined(ASSERT)
372 #define ASSERT(cond) do { if (!(cond)) exit(0); } while (0)
373 #endif
374 #define BREAKPOINT()
375 #define BREAK_IF(cond)
376 #define CHECK_STACK(room)
377 #define DEBUG_STREAM(dev)
378 #define OBSERVE_IF(cond,expr)
379 #define OBSERVE(expr)
380 #define REGISTER(var)
381 
382 #endif
383 #endif
void do_quit()
void do_print_heap()
Definition: Debug.cpp:274
#define NULL
Definition: Types.h:101
void run(const char *file=NULL, int line=0, const char *func=NULL, str_P expr=NULL)
Definition: Debug.cpp:85
void do_print_stack(int marker)
Definition: Debug.cpp:286
void print()
Definition: Debug.cpp:303
#define PSTR(s)
Definition: Types.h:202
bool check_stack(int room=128)
Definition: Debug.cpp:68
Debug()
Definition: Debug.hh:53
void observe_at(const char *file, int line, const char *func, str_P expr)
Definition: Debug.hh:119
void do_print_variables()
Definition: Debug.cpp:296
const char * m_func
Registered in function.
Definition: Debug.hh:172
char EXITCHARACTER
Character to emit on exit.
Definition: Debug.hh:268
void do_backtrace(const char *func)
Definition: Debug.cpp:187
void assert(const char *file, int line, const char *func, str_P cond)
Definition: Debug.cpp:45
bool end()
Definition: Debug.cpp:77
void printf(str_P format,...)
Definition: IOStream.hh:487
bool begin(IOStream::Device *dev, const char *file, int line, const char *func)
Definition: Debug.cpp:28
Variable * m_var
Last registered variable.
Definition: Debug.hh:267
void do_print_data()
Definition: Debug.cpp:266
const class prog_str * str_P
Definition: Types.h:187
void do_help()
Definition: Debug.cpp:200
void do_memory_usage(int marker)
Definition: Debug.cpp:253
int DATAEND
End of data segment.
Definition: Debug.hh:269
class Debug debug
Definition: Debug.cpp:23
void break_at(const char *file, int line, const char *func, str_P cond)
Definition: Debug.cpp:58
Variable(const char *func, str_P name, void *ref, size_t size)
Definition: Debug.hh:145
int DATASIZE
Size of data segment.
Definition: Debug.hh:270
#define UNUSED(x)
Definition: ATmega328P.hh:31
void * m_ref
Variable value reference.
Definition: Debug.hh:174
bool do_lookup_variables(const char *name)
Definition: Debug.cpp:238
Definition: Debug.hh:48
size_t m_size
Variable value size.
Definition: Debug.hh:175
class Variable * m_next
Next variable.
Definition: Debug.hh:171
str_P m_name
Function name.
Definition: Debug.hh:173