00001 #ifndef __debug_h__
00002 #define __debug_h__
00003
00004 #include <iostream>
00005 #include <fstream>
00006 #include <string>
00007 #include <map>
00008 #include <vector>
00009 #include <deque>
00010 #include <list>
00011
00012 #include <cstdio>
00013
00014 #ifdef DEBUG
00015 #define debug_init(f) debug_manager.init(f)
00016 #define debug_args(c,v) debug_manager.init(&c,v)
00017 #define debug_close debug_manager.close();
00018
00019 #ifdef __GNUC__
00020 #define debug debug_instance __di(__PRETTY_FUNCTION__,__FILE__,__LINE__)
00021 #else
00022 #define debug debug_instance __di("",__FILE__,__LINE__)
00023 #endif
00024
00025 #define dout(stream_arguments) if (__di.ok()) __di stream_arguments
00026
00027 #define debug_write(s) \
00028 debug_manager.set_context(debugger::context_message); \
00029 __di.write(s); \
00030 ;
00031
00032 #define debug_var(var) \
00033 debug_manager.set_context(debugger::context_variable); \
00034 __debug_write_name_and_type(__di,var,#var); \
00035 ;
00036
00037 #define debug_input_var(var) \
00038 debug_manager.set_context(debugger::context_input); \
00039 __di.indent(); \
00040 __debug_write_name_and_type(__di,var,#var); \
00041 __di.unindent(); \
00042 ;
00043
00044 #define debug_input_args(argc,argv) \
00045 debug_manager.set_context(debugger::context_input); \
00046 __di.indent(); \
00047 __debug_write_name_and_type(__di,argc,#argc); \
00048 __debug_write_name_and_type(__di,argv,#argv); \
00049 { \
00050 __di.indent(); \
00051 int __arg_count; \
00052 char __arg_buffer[1024] = { 0 }; \
00053 \
00054 for (__arg_count = 0; __arg_count < argc; ++__arg_count) { \
00055 snprintf(__arg_buffer, 1024, "%s[%d] = %s\n", \
00056 #argv, __arg_count, argv[__arg_count]); \
00057 __di.write(__arg_buffer); \
00058 } \
00059 __di.unindent(); \
00060 } \
00061 __di.unindent(); \
00062 ;
00063
00064 #define debug_output_var(var) \
00065 debug_manager.set_context(debugger::context_output); \
00066 __di.indent(); \
00067 __debug_write_name_and_type(__di,var,#var); \
00068 __di.unindent(); \
00069 ;
00070
00071 #define debug_value(value) \
00072 debug_manager.set_context(debugger::context_variable); \
00073 __debug_write_type(__di,value); \
00074 ;
00075
00076 #define debug_input_value(value) \
00077 debug_manager.set_context(debugger::context_input); \
00078 __di.indent(); \
00079 __debug_write_type(__di,value); \
00080 __di.unindent(); \
00081 ;
00082
00083 #define debug_output_value(value) \
00084 debug_manager.set_context(debugger::context_output); \
00085 __di.indent(); \
00086 __debug_write_type(__di,value); \
00087 __di.unindent(); \
00088 ;
00089
00090 #define debug_fork debug_manager.fork()
00091
00092 #define di_var(var) __debug_write_name_and_type(di,var,#var)
00093
00094 #define di_struct(var,elem) __debug_write_name_and_type(di,var.elem,#elem)
00095
00096 #define di_class(class,var) __debug_write_name_and_type(di,(class)var,#var)
00097
00098 #define di_switch_enums(x) \
00099 switch(a_arg) { \
00100 x \
00101 default: \
00102 di << "*** UNKNOWN "; \
00103 di << __debug_type(a_arg); \
00104 di << " TYPE ***"; \
00105 break; \
00106 }
00107
00108 #define di_enum(var) \
00109 case var: \
00110 di << #var; \
00111 break;
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 #define debug_generate_enum_headers(TYPE) \
00129 const char * __debug_type(const TYPE& a_arg); \
00130 \
00131 const char * __debug_type(const TYPE * a_arg); \
00132 \
00133 debug_instance& operator<<(debug_instance& di, const TYPE& a_arg); \
00134 \
00135 debug_instance& operator<<(debug_instance& di, const TYPE * a_arg); \
00136 \
00137 void __debug_write_type(debug_instance& di, const TYPE& a_arg); \
00138 \
00139 void __debug_write_type(debug_instance& di, const TYPE * a_arg); \
00140 \
00141 void __debug_write_name_and_type(debug_instance& di, const TYPE& a_arg, const char * name); \
00142 \
00143 void __debug_write_name_and_type(debug_instance& di, const TYPE * a_arg, const char * name);
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 #define debug_generate_enum_code(TYPE) \
00187 const char * __debug_type(const TYPE& a_arg) \
00188 { \
00189 return(#TYPE); \
00190 } \
00191 \
00192 const char * __debug_type(const TYPE * a_arg) \
00193 { \
00194 static char buffer[1024] = { 0 }; \
00195 \
00196 snprintf(buffer,1024,"%s *",#TYPE); \
00197 return(buffer); \
00198 } \
00199 \
00200 debug_instance& operator<<(debug_instance& di, const TYPE& a_arg) \
00201 { \
00202 __debug_write(di,a_arg); \
00203 return(di); \
00204 } \
00205 \
00206 debug_instance& operator<<(debug_instance& di, const TYPE * a_arg) \
00207 { \
00208 di << (void*)a_arg; \
00209 return(di); \
00210 } \
00211 \
00212 void __debug_write_type(debug_instance& di, const TYPE& a_arg) \
00213 { \
00214 di << "("; \
00215 di << __debug_type(a_arg); \
00216 if (debug_manager.show_addresses()) { \
00217 di << " at "; \
00218 di << (void*)&a_arg; \
00219 } \
00220 di << ") "; \
00221 di << a_arg; \
00222 di.write_oeol(); \
00223 } \
00224 \
00225 void __debug_write_type(debug_instance& di, const TYPE * a_arg) \
00226 { \
00227 di << "("; \
00228 di << __debug_type(a_arg); \
00229 if (debug_manager.show_addresses()) { \
00230 di << " at "; \
00231 di << (void*)&a_arg; \
00232 } \
00233 di << ") "; \
00234 di << a_arg; \
00235 di.write_oeol(); \
00236 } \
00237 \
00238 void __debug_write_name_and_type(debug_instance& di, const TYPE& a_arg, const char * name) \
00239 { \
00240 di << name; \
00241 di << " = "; \
00242 __debug_write_type(di,a_arg); \
00243 di.write_oeol(); \
00244 } \
00245 \
00246 void __debug_write_name_and_type(debug_instance& di, const TYPE * a_arg, const char * name) \
00247 { \
00248 di << name; \
00249 di << " = "; \
00250 __debug_write_type(di,a_arg); \
00251 di.write_oeol(); \
00252 }
00253
00254
00255
00256
00257
00258
00259 #define debug_generate_struct_headers(TYPE) \
00260 const char * __debug_type(const TYPE& a_arg); \
00261 \
00262 const char * __debug_type(const TYPE * a_arg); \
00263 \
00264 debug_instance& operator<<(debug_instance& di, const TYPE& a_arg); \
00265 \
00266 debug_instance& operator<<(debug_instance& di, const TYPE * a_arg); \
00267 \
00268 void __debug_write_type(debug_instance& di, const TYPE& a_arg); \
00269 \
00270 void __debug_write_type(debug_instance& di, const TYPE * a_arg); \
00271 \
00272 void __debug_write_name_and_type(debug_instance& di, const TYPE& a_arg, const char * name); \
00273 \
00274 void __debug_write_name_and_type(debug_instance& di, const TYPE * a_arg, const char * name);
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 #define debug_generate_struct_code(TYPE) \
00293 const char * __debug_type(const TYPE& a_arg) \
00294 { \
00295 return(#TYPE); \
00296 } \
00297 \
00298 const char * __debug_type(const TYPE * a_arg) \
00299 { \
00300 static char buffer[1024] = { 0 }; \
00301 \
00302 snprintf(buffer,1024,"%s *",#TYPE); \
00303 return(buffer); \
00304 } \
00305 \
00306 debug_instance& operator<<(debug_instance& di, const TYPE& a_arg) \
00307 { \
00308 __debug_write(di,a_arg); \
00309 return(di); \
00310 } \
00311 \
00312 debug_instance& operator<<(debug_instance& di, const TYPE * a_arg) \
00313 { \
00314 di << (void*)a_arg; \
00315 return(di); \
00316 } \
00317 \
00318 void __debug_write_type(debug_instance& di, const TYPE& a_arg) \
00319 { \
00320 di << "("; \
00321 di << __debug_type(a_arg); \
00322 if (debug_manager.show_addresses()) { \
00323 di << " at "; \
00324 di << (void*)&a_arg; \
00325 } \
00326 di << ")"; \
00327 di << std::endl; \
00328 di.indent(); \
00329 di << a_arg; \
00330 di.unindent(); \
00331 di.write_oeol(); \
00332 } \
00333 \
00334 void __debug_write_type(debug_instance& di, const TYPE * a_arg) \
00335 { \
00336 di << "("; \
00337 di << __debug_type(a_arg); \
00338 if (debug_manager.show_addresses()) { \
00339 di << " at "; \
00340 di << (void*)&a_arg; \
00341 } \
00342 di << ") "; \
00343 di << a_arg; \
00344 di.write_oeol(); \
00345 } \
00346 \
00347 void __debug_write_name_and_type(debug_instance& di, const TYPE& a_arg, const char * name) \
00348 { \
00349 di << name; \
00350 di << " = "; \
00351 __debug_write_type(di,a_arg); \
00352 di.write_oeol(); \
00353 } \
00354 \
00355 void __debug_write_name_and_type(debug_instance& di, const TYPE * a_arg, const char * name) \
00356 { \
00357 di << name; \
00358 di << " = "; \
00359 __debug_write_type(di,a_arg); \
00360 di.write_oeol(); \
00361 }
00362
00363
00364
00365
00366
00367
00368 #define debug_generate_type_headers(TYPE) \
00369 const char * __debug_type(const TYPE& a_arg); \
00370 \
00371 const char * __debug_type(const TYPE * a_arg); \
00372 \
00373 debug_instance& operator<<(debug_instance& di, const TYPE& a_arg); \
00374 \
00375 debug_instance& operator<<(debug_instance& di, const TYPE * a_arg); \
00376 \
00377 void __debug_write_type(debug_instance& di, const TYPE& a_arg); \
00378 \
00379 void __debug_write_type(debug_instance& di, const TYPE * a_arg); \
00380 \
00381 void __debug_write_name_and_type(debug_instance& di, const TYPE& a_arg, const char * name); \
00382 \
00383 void __debug_write_name_and_type(debug_instance& di, const TYPE * a_arg, const char * name);
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 #define debug_generate_type_code(TYPE) \
00394 const char * __debug_type(const TYPE& a_arg) \
00395 { \
00396 return(#TYPE); \
00397 } \
00398 \
00399 const char * __debug_type(const TYPE * a_arg) \
00400 { \
00401 static char buffer[1024] = { 0 }; \
00402 \
00403 snprintf(buffer,1024,"%s *",#TYPE); \
00404 return(buffer); \
00405 } \
00406 \
00407 debug_instance& operator<<(debug_instance& di, const TYPE& a_arg) \
00408 { \
00409 __debug_write(di,a_arg); \
00410 return(di); \
00411 } \
00412 \
00413 debug_instance& operator<<(debug_instance& di, const TYPE * a_arg) \
00414 { \
00415 di << (void*)a_arg; \
00416 return(di); \
00417 } \
00418 \
00419 void __debug_write_type(debug_instance& di, const TYPE& a_arg) \
00420 { \
00421 di << "("; \
00422 di << __debug_type(a_arg); \
00423 if (debug_manager.show_addresses()) { \
00424 di << " at "; \
00425 di << (void*)&a_arg; \
00426 } \
00427 di << ") "; \
00428 di << a_arg; \
00429 di.write_oeol(); \
00430 } \
00431 \
00432 void __debug_write_type(debug_instance& di, const TYPE * a_arg) \
00433 { \
00434 di << "("; \
00435 di << __debug_type(a_arg); \
00436 if (debug_manager.show_addresses()) { \
00437 di << " at "; \
00438 di << (void*)&a_arg; \
00439 } \
00440 di << ") "; \
00441 di << a_arg; \
00442 di.write_oeol(); \
00443 } \
00444 \
00445 void __debug_write_name_and_type(debug_instance& di, const TYPE& a_arg, const char * name) \
00446 { \
00447 di << name; \
00448 di << " = "; \
00449 __debug_write_type(di,a_arg); \
00450 di.write_oeol(); \
00451 } \
00452 \
00453 void __debug_write_name_and_type(debug_instance& di, const TYPE * a_arg, const char * name) \
00454 { \
00455 di << name; \
00456 di << " = "; \
00457 __debug_write_type(di,a_arg); \
00458 di.write_oeol(); \
00459 }
00460
00461
00462
00463
00464
00465
00466 #define debug_generate_class_headers(TYPE) \
00467 const char * __debug_type(const TYPE& a_arg); \
00468 \
00469 const char * __debug_type(const TYPE * a_arg); \
00470 \
00471 debug_instance& operator<<(debug_instance& di, const TYPE& a_arg); \
00472 \
00473 debug_instance& operator<<(debug_instance& di, const TYPE * a_arg); \
00474 \
00475 void __debug_write_type(debug_instance& di, const TYPE& a_arg); \
00476 \
00477 void __debug_write_type(debug_instance& di, const TYPE * a_arg); \
00478 \
00479 void __debug_write_name_and_type(debug_instance& di, const TYPE& a_arg, const char * name); \
00480 \
00481 void __debug_write_name_and_type(debug_instance& di, const TYPE * a_arg, const char * name);
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 #define debug_generate_class_code(TYPE) \
00498 const char * __debug_type(const TYPE& a_arg) \
00499 { \
00500 return(#TYPE); \
00501 } \
00502 \
00503 const char * __debug_type(const TYPE * a_arg) \
00504 { \
00505 static char buffer[1024] = { 0 }; \
00506 \
00507 snprintf(buffer,1024,"%s *",#TYPE); \
00508 return(buffer); \
00509 } \
00510 \
00511 debug_instance& operator<<(debug_instance& di, const TYPE& a_arg) \
00512 { \
00513 a_arg.__debug_write(di); \
00514 return(di); \
00515 } \
00516 \
00517 debug_instance& operator<<(debug_instance& di, const TYPE * a_arg) \
00518 { \
00519 di << (void*)a_arg; \
00520 return(di); \
00521 } \
00522 \
00523 void __debug_write_type(debug_instance& di, const TYPE& a_arg) \
00524 { \
00525 di << "("; \
00526 di << __debug_type(a_arg); \
00527 if (debug_manager.show_addresses()) { \
00528 di << " at "; \
00529 di << (void*)&a_arg; \
00530 } \
00531 di << ")"; \
00532 di << std::endl; \
00533 di.indent(); \
00534 di << a_arg; \
00535 di.unindent(); \
00536 di.write_oeol(); \
00537 } \
00538 \
00539 void __debug_write_type(debug_instance& di, const TYPE * a_arg) \
00540 { \
00541 di << "("; \
00542 di << __debug_type(a_arg); \
00543 if (debug_manager.show_addresses()) { \
00544 di << " at "; \
00545 di << (void*)&a_arg; \
00546 } \
00547 di << ") "; \
00548 di << a_arg; \
00549 di.write_oeol(); \
00550 } \
00551 \
00552 void __debug_write_name_and_type(debug_instance& di, const TYPE& a_arg, const char * name) \
00553 { \
00554 di << name; \
00555 di << " = "; \
00556 __debug_write_type(di,a_arg); \
00557 di.write_oeol(); \
00558 } \
00559 \
00560 void __debug_write_name_and_type(debug_instance& di, const TYPE * a_arg, const char * name) \
00561 { \
00562 di << name; \
00563 di << " = "; \
00564 __debug_write_type(di,a_arg); \
00565 di.write_oeol(); \
00566 }
00567
00568
00569
00570
00571
00572
00573 #define debug_generate_Tclass_headers(T,N) \
00574 template<T> \
00575 const char * __debug_type(const N& a_arg); \
00576 \
00577 template<T> \
00578 const char * __debug_type(const N * a_arg); \
00579 \
00580 template<T> \
00581 debug_instance& operator<<(debug_instance& di, const N& a_arg); \
00582 \
00583 template<T> \
00584 debug_instance& operator<<(debug_instance& di, const N * a_arg); \
00585 \
00586 template<T> \
00587 void __debug_write_type(debug_instance& di, const N& a_arg); \
00588 \
00589 template<T> \
00590 void __debug_write_type(debug_instance& di, const N * a_arg); \
00591 \
00592 template<T> \
00593 void __debug_write_name_and_type(debug_instance& di, const N& a_arg, const char * name); \
00594 \
00595 template<T> \
00596 void __debug_write_name_and_type(debug_instance& di, const N * a_arg, const char * name);
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 #define debug_generate_Tclass_code(T,N) \
00613 template<T> \
00614 const char * __debug_type(const N& a_arg) \
00615 { \
00616 return(#N); \
00617 } \
00618 \
00619 template<T> \
00620 const char * __debug_type(const N * a_arg) \
00621 { \
00622 static char buffer[1024] = { 0 }; \
00623 \
00624 snprintf(buffer,1024,"%s *",#N); \
00625 return(buffer); \
00626 } \
00627 \
00628 template<T> \
00629 debug_instance& operator<<(debug_instance& di, const N& a_arg) \
00630 { \
00631 a_arg.__debug_write(di); \
00632 return(di); \
00633 } \
00634 \
00635 template<T> \
00636 debug_instance& operator<<(debug_instance& di, const N * a_arg) \
00637 { \
00638 di << (void*)a_arg; \
00639 return(di); \
00640 } \
00641 \
00642 template<T> \
00643 void __debug_write_type(debug_instance& di, const N& a_arg) \
00644 { \
00645 di << "("; \
00646 di << __debug_type(a_arg); \
00647 if (debug_manager.show_addresses()) { \
00648 di << " at "; \
00649 di << (void*)&a_arg; \
00650 } \
00651 di << ")"; \
00652 di << std::endl; \
00653 di.indent(); \
00654 di << a_arg; \
00655 di.unindent(); \
00656 di.write_oeol(); \
00657 } \
00658 \
00659 template<T> \
00660 void __debug_write_type(debug_instance& di, const N * a_arg) \
00661 { \
00662 di << "("; \
00663 di << __debug_type(a_arg); \
00664 if (debug_manager.show_addresses()) { \
00665 di << " at "; \
00666 di << (void*)&a_arg; \
00667 } \
00668 di << ") "; \
00669 di << a_arg; \
00670 di.write_oeol(); \
00671 } \
00672 \
00673 template<T> \
00674 void __debug_write_name_and_type(debug_instance& di, const N& a_arg, const char * name) \
00675 { \
00676 di << name; \
00677 di << " = "; \
00678 __debug_write_type(di,a_arg); \
00679 di.write_oeol(); \
00680 } \
00681 \
00682 template<T> \
00683 void __debug_write_name_and_type(debug_instance& di, const N * a_arg, const char * name) \
00684 { \
00685 di << name; \
00686 di << " = "; \
00687 __debug_write_type(di,a_arg); \
00688 di.write_oeol(); \
00689 }
00690
00691 #else
00692 #define debug_init(f)
00693 #define debug_args(c,v)
00694 #define debug_close
00695
00696 #define debug
00697
00698 #define dout(stream_arguments)
00699 #define di_var(var)
00700 #define di_struct(var,elem)
00701 #define di_class(class,var)
00702 #define debug_write(s)
00703 #define debug_var(var)
00704 #define debug_input_var(var)
00705 #define debug_input_args(argc,argv)
00706 #define debug_output_var(var)
00707 #define debug_value(value)
00708 #define debug_input_value(value)
00709 #define debug_output_value(value)
00710 #define debug_fork
00711
00712 #define debug_generate_enum_headers(TYPE)
00713 #define debug_generate_enum_code(TYPE)
00714 #define debug_generate_struct_headers(TYPE)
00715 #define debug_generate_struct_code(TYPE)
00716 #define debug_generate_class_headers(TYPE)
00717 #define debug_generate_class_code(TYPE)
00718 #endif
00719
00720 #ifdef DEBUG
00721
00722
00723
00724 class debugger;
00725
00726 extern debugger debug_manager;
00727
00728 class debug_instance
00729 {
00730 public:
00731 typedef size_t size_type;
00732 typedef enum context_types {
00733 context_begin,
00734 context_end,
00735 context_input,
00736 context_output,
00737 context_variable,
00738 context_message
00739 } context;
00740
00741 debug_instance(const char * name, const char * file, const int line);
00742 ~debug_instance();
00743
00744 void indent(void);
00745 void unindent(void);
00746
00747 const bool ok(void) const;
00748
00749 void write(const bool a_arg);
00750 void write(const char a_arg);
00751 void write(const unsigned int a_arg);
00752 void write(const int a_arg);
00753 void write(const unsigned short a_arg);
00754 void write(const short a_arg);
00755 void write(const unsigned long a_arg);
00756 void write(const long a_arg);
00757 void write(const unsigned long long a_arg);
00758 void write(const long long a_arg);
00759 void write(const float a_arg);
00760 void write(const double a_arg);
00761 void write(const std::string& a_arg);
00762
00763 void write(const char * a_arg);
00764 void write(std::ostream& (*op)(std::ostream&));
00765
00766 void write(const void * a_arg);
00767
00768 void write_oeol(void);
00769
00770 private:
00771 unsigned int m_indent;
00772 bool m_newline;
00773 context m_context;
00774 static const size_type m_base;
00775 static const char * m_alphabet;
00776
00777 void mf_clear_buffer(void);
00778 void mf_check_newline(void);
00779 void mf_set_newline(bool a_bool);
00780 void mf_write_indent(void);
00781
00782
00783 template<class T>
00784 void debug_instance::mfT_write_unsigned_integral(const T& a_t);
00785 template<class T>
00786 void debug_instance::mfT_write_integral(const T& a_t);
00787 template<class T>
00788 void debug_instance::mfT_write_fractional(const T& a_t);
00789 };
00790
00791
00792
00793 void __debug_write(debug_instance& di, const bool a_arg);
00794 void __debug_write(debug_instance& di, const char a_arg);
00795 void __debug_write(debug_instance& di, const unsigned int a_arg);
00796 void __debug_write(debug_instance& di, const int a_arg);
00797 void __debug_write(debug_instance& di, const unsigned short a_arg);
00798 void __debug_write(debug_instance& di, const short a_arg);
00799 void __debug_write(debug_instance& di, const unsigned long a_arg);
00800 void __debug_write(debug_instance& di, const long a_arg);
00801 void __debug_write(debug_instance& di, const unsigned long long a_arg);
00802 void __debug_write(debug_instance& di, const long long a_arg);
00803 void __debug_write(debug_instance& di, const float a_arg);
00804 void __debug_write(debug_instance& di, const double a_arg);
00805 void __debug_write(debug_instance& di, const std::string& a_arg);
00806
00807 void __debug_write(debug_instance& di, const bool * a_arg);
00808 void __debug_write(debug_instance& di, const char * a_arg);
00809 void __debug_write(debug_instance& di, const unsigned int * a_arg);
00810 void __debug_write(debug_instance& di, const int * a_arg);
00811 void __debug_write(debug_instance& di, const unsigned short * a_arg);
00812 void __debug_write(debug_instance& di, const short * a_arg);
00813 void __debug_write(debug_instance& di, const unsigned long * a_arg);
00814 void __debug_write(debug_instance& di, const long * a_arg);
00815 void __debug_write(debug_instance& di, const unsigned long long * a_arg);
00816 void __debug_write(debug_instance& di, const long long * a_arg);
00817 void __debug_write(debug_instance& di, const float * a_arg);
00818 void __debug_write(debug_instance& di, const double * a_arg);
00819
00820 void __debug_write(debug_instance& di, const void * a_arg);
00821 void __debug_write(debug_instance& di, std::ostream& (*a_arg)(std::ostream&));
00822
00823
00824
00825 debug_instance& operator<<(debug_instance& di, const bool a_arg);
00826 debug_instance& operator<<(debug_instance& di, const char a_arg);
00827 debug_instance& operator<<(debug_instance& di, const unsigned int a_arg);
00828 debug_instance& operator<<(debug_instance& di, const int a_arg);
00829 debug_instance& operator<<(debug_instance& di, const unsigned short a_arg);
00830 debug_instance& operator<<(debug_instance& di, const short a_arg);
00831 debug_instance& operator<<(debug_instance& di, const unsigned long a_arg);
00832 debug_instance& operator<<(debug_instance& di, const long a_arg);
00833 debug_instance& operator<<(debug_instance& di, const unsigned long long a_arg);
00834 debug_instance& operator<<(debug_instance& di, const long long a_arg);
00835 debug_instance& operator<<(debug_instance& di, const float a_arg);
00836 debug_instance& operator<<(debug_instance& di, const double a_arg);
00837 debug_instance& operator<<(debug_instance& di, const std::string& a_arg);
00838
00839 debug_instance& operator<<(debug_instance& di, const bool * a_arg);
00840 debug_instance& operator<<(debug_instance& di, const char * a_arg);
00841 debug_instance& operator<<(debug_instance& di, const unsigned int * a_arg);
00842 debug_instance& operator<<(debug_instance& di, const int * a_arg);
00843 debug_instance& operator<<(debug_instance& di, const unsigned short * a_arg);
00844 debug_instance& operator<<(debug_instance& di, const short * a_arg);
00845 debug_instance& operator<<(debug_instance& di, const unsigned long * a_arg);
00846 debug_instance& operator<<(debug_instance& di, const long * a_arg);
00847 debug_instance& operator<<(debug_instance& di, const unsigned long long * a_arg);
00848 debug_instance& operator<<(debug_instance& di, const long long * a_arg);
00849 debug_instance& operator<<(debug_instance& di, const float * a_arg);
00850 debug_instance& operator<<(debug_instance& di, const double * a_arg);
00851
00852 debug_instance& operator<<(debug_instance& di, const void * a_arg);
00853 debug_instance& operator<<(debug_instance& di, std::ostream& (*a_arg)(std::ostream&));
00854
00855
00856
00857 const char * __debug_type(const bool a_arg);
00858 const char * __debug_type(const char a_arg);
00859 const char * __debug_type(const unsigned int a_arg);
00860 const char * __debug_type(const int a_arg);
00861 const char * __debug_type(const unsigned short a_arg);
00862 const char * __debug_type(const short a_arg);
00863 const char * __debug_type(const unsigned long a_arg);
00864 const char * __debug_type(const long a_arg);
00865 const char * __debug_type(const unsigned long long a_arg);
00866 const char * __debug_type(const long long a_arg);
00867 const char * __debug_type(const float a_arg);
00868 const char * __debug_type(const double a_arg);
00869 const char * __debug_type(const std::string& a_arg);
00870
00871 const char * __debug_type(const bool * a_arg);
00872 const char * __debug_type(const char * a_arg);
00873 const char * __debug_type(const unsigned int * a_arg);
00874 const char * __debug_type(const int * a_arg);
00875 const char * __debug_type(const unsigned short * a_arg);
00876 const char * __debug_type(const short * a_arg);
00877 const char * __debug_type(const unsigned long * a_arg);
00878 const char * __debug_type(const long * a_arg);
00879 const char * __debug_type(const unsigned long long * a_arg);
00880 const char * __debug_type(const long long * a_arg);
00881 const char * __debug_type(const float * a_arg);
00882 const char * __debug_type(const double * a_arg);
00883 const char * __debug_type(const std::string * a_arg);
00884
00885 const char * __debug_type(const void * a_arg);
00886
00887 template<class T1, class T2>
00888 const char * __debug_type(const std::pair<T1,T2>& a_arg)
00889 {
00890 debug_manager.pause();
00891
00892 static char buffer[1024] = { 0 };
00893 {
00894 T1 a1;
00895 T2 a2;
00896
00897 snprintf(buffer,1024,"std::pair<%s,%s>",__debug_type(a1),__debug_type(a2));
00898 }
00899
00900 debug_manager.unpause();
00901 return(buffer);
00902 }
00903
00904 template<class T1, class T2>
00905 const char * __debug_type(const std::map<T1,T2>& a_arg)
00906 {
00907 debug_manager.pause();
00908
00909 static char buffer[1024] = { 0 };
00910 {
00911 T1 a1;
00912 T2 a2;
00913
00914 snprintf(buffer,1024,"std::map<%s,%s>",__debug_type(a1),__debug_type(a2));
00915 }
00916
00917 debug_manager.unpause();
00918 return(buffer);
00919 }
00920
00921 template<class T>
00922 const char * __debug_type(const std::vector<T>& a_arg)
00923 {
00924 debug_manager.pause();
00925
00926 static char buffer[1024] = { 0 };
00927 {
00928 T a;
00929
00930 snprintf(buffer,1024,"std::vector<%s>",__debug_type(a));
00931 }
00932
00933 debug_manager.unpause();
00934 return(buffer);
00935 }
00936
00937 template<class T>
00938 const char * __debug_type(const std::list<T>& a_arg)
00939 {
00940 debug_manager.pause();
00941
00942 static char buffer[1024] = { 0 };
00943 {
00944 T a;
00945
00946 snprintf(buffer,1024,"std::list<%s>",__debug_type(a));
00947 }
00948
00949 debug_manager.unpause();
00950 return(buffer);
00951 }
00952
00953
00954
00955 void __debug_write_type(debug_instance& di, const bool& a_arg);
00956 void __debug_write_type(debug_instance& di, const char& a_arg);
00957 void __debug_write_type(debug_instance& di, const unsigned int& a_arg);
00958 void __debug_write_type(debug_instance& di, const int& a_arg);
00959 void __debug_write_type(debug_instance& di, const unsigned short& a_arg);
00960 void __debug_write_type(debug_instance& di, const short& a_arg);
00961 void __debug_write_type(debug_instance& di, const unsigned long& a_arg);
00962 void __debug_write_type(debug_instance& di, const long& a_arg);
00963 void __debug_write_type(debug_instance& di, const unsigned long long& a_arg);
00964 void __debug_write_type(debug_instance& di, const long long& a_arg);
00965 void __debug_write_type(debug_instance& di, const float& a_arg);
00966 void __debug_write_type(debug_instance& di, const double& a_arg);
00967 void __debug_write_type(debug_instance& di, const std::string& a_arg);
00968
00969 void __debug_write_type(debug_instance& di, const bool * a_arg);
00970 void __debug_write_type(debug_instance& di, const char * a_arg);
00971 void __debug_write_type(debug_instance& di, const unsigned int * a_arg);
00972 void __debug_write_type(debug_instance& di, const int * a_arg);
00973 void __debug_write_type(debug_instance& di, const unsigned short * a_arg);
00974 void __debug_write_type(debug_instance& di, const short * a_arg);
00975 void __debug_write_type(debug_instance& di, const unsigned long * a_arg);
00976 void __debug_write_type(debug_instance& di, const long * a_arg);
00977 void __debug_write_type(debug_instance& di, const unsigned long long * a_arg);
00978 void __debug_write_type(debug_instance& di, const long long * a_arg);
00979 void __debug_write_type(debug_instance& di, const float * a_arg);
00980 void __debug_write_type(debug_instance& di, const double * a_arg);
00981 void __debug_write_type(debug_instance& di, const std::string * a_arg);
00982
00983 void __debug_write_type(debug_instance& di, const void * a_arg);
00984
00985 template<class T1, class T2>
00986 void __debug_write_type(
00987 debug_instance& di,
00988 const std::map<T1,T2>& a_map
00989 )
00990 {
00991 std::map<T1,T2>::const_iterator mi;
00992
00993 di << "(";
00994 di << __debug_type(a_map);
00995 if (debug_manager.show_addresses()) {
00996 di << " at ";
00997 di << (void*)&a_map;
00998 }
00999 di << ") (size: ";
01000 di << a_map.size();
01001 di << ")";
01002 di << std::endl;
01003
01004 di.indent();
01005 for (mi = a_map.begin(); mi != a_map.end(); ++mi) {
01006 di << "[";
01007 di << mi->first;
01008 di << "] = ";
01009 __debug_write_type(di,mi->second);
01010 di.write_oeol();
01011 }
01012 di.unindent();
01013 }
01014
01015 template<class T>
01016 void __debug_write_type(
01017 debug_instance& di,
01018 const std::vector<T>& a_vector
01019 )
01020 {
01021 std::vector<T>::size_type count;
01022
01023 di << "(";
01024 di << __debug_type(a_vector);
01025 if (debug_manager.show_addresses()) {
01026 di << " at ";
01027 di << (void*)&a_vector;
01028 }
01029 di << ") (size: ";
01030 di << a_vector.size();
01031 di << ")";
01032 di << std::endl;
01033
01034 di.indent();
01035 for (count = 0; count != a_vector.size(); ++count) {
01036 di << "[";
01037 di << count;
01038 di << "] = ";
01039 __debug_write_type(di,a_vector[count]);
01040 di.write_oeol();
01041 }
01042 di.unindent();
01043 }
01044
01045 template<class T>
01046 void __debug_write_type(
01047 debug_instance& di,
01048 const std::list<T>& a_list
01049 )
01050 {
01051 std::list<T>::const_iterator li;
01052 std::list<T>::size_type count;
01053
01054 di << "(";
01055 di << __debug_type(a_list);
01056 if (debug_manager.show_addresses()) {
01057 di << " at ";
01058 di << (void*)&a_list;
01059 }
01060 di << ") (size: ";
01061 di << a_list.size();
01062 di << ")";
01063 di << std::endl;
01064
01065 di.indent();
01066 for (li = a_list.begin(), count=0; li != a_list.end(); ++li, ++count) {
01067 di << "{";
01068 di << count;
01069 di << "} = ";
01070 __debug_write_type(di,*li);
01071 di.write_oeol();
01072 }
01073 di.unindent();
01074 }
01075
01076 template<class T1, class T2>
01077 void __debug_write_type(
01078 debug_instance& di,
01079 const std::pair<T1,T2>& a_pair
01080 )
01081 {
01082 di << "(";
01083 di << __debug_type(a_pair);
01084 if (debug_manager.show_addresses()) {
01085 di << " at ";
01086 di << (void*)&a_pair;
01087 }
01088 di << ")";
01089 di << std::endl;
01090 di.indent();
01091 __debug_write_name_and_type(di,a_pair.first,"first");
01092 __debug_write_name_and_type(di,a_pair.second,"second");
01093 di.unindent();
01094 di.write_oeol();
01095 }
01096
01097
01098
01099 void __debug_write_name_and_type(debug_instance& di, const bool& a_arg, const char * name);
01100 void __debug_write_name_and_type(debug_instance& di, const char& a_arg, const char * name);
01101 void __debug_write_name_and_type(debug_instance& di, const unsigned int& a_arg, const char * name);
01102 void __debug_write_name_and_type(debug_instance& di, const int& a_arg, const char * name);
01103 void __debug_write_name_and_type(debug_instance& di, const unsigned short& a_arg, const char * name);
01104 void __debug_write_name_and_type(debug_instance& di, const short& a_arg, const char * name);
01105 void __debug_write_name_and_type(debug_instance& di, const unsigned long& a_arg, const char * name);
01106 void __debug_write_name_and_type(debug_instance& di, const long& a_arg, const char * name);
01107 void __debug_write_name_and_type(debug_instance& di, const unsigned long long& a_arg, const char * name);
01108 void __debug_write_name_and_type(debug_instance& di, const long long& a_arg, const char * name);
01109 void __debug_write_name_and_type(debug_instance& di, const float& a_arg, const char * name);
01110 void __debug_write_name_and_type(debug_instance& di, const double& a_arg, const char * name);
01111 void __debug_write_name_and_type(debug_instance& di, const std::string& a_arg, const char * name);
01112
01113 void __debug_write_name_and_type(debug_instance& di, const bool * a_arg, const char * name);
01114 void __debug_write_name_and_type(debug_instance& di, const char * a_arg, const char * name);
01115 void __debug_write_name_and_type(debug_instance& di, const unsigned int * a_arg, const char * name);
01116 void __debug_write_name_and_type(debug_instance& di, const int * a_arg, const char * name);
01117 void __debug_write_name_and_type(debug_instance& di, const unsigned short * a_arg, const char * name);
01118 void __debug_write_name_and_type(debug_instance& di, const short * a_arg, const char * name);
01119 void __debug_write_name_and_type(debug_instance& di, const unsigned long * a_arg, const char * name);
01120 void __debug_write_name_and_type(debug_instance& di, const long * a_arg, const char * name);
01121 void __debug_write_name_and_type(debug_instance& di, const unsigned long long * a_arg, const char * name);
01122 void __debug_write_name_and_type(debug_instance& di, const long long * a_arg, const char * name);
01123 void __debug_write_name_and_type(debug_instance& di, const float * a_arg, const char * name);
01124 void __debug_write_name_and_type(debug_instance& di, const double * a_arg, const char * name);
01125 void __debug_write_name_and_type(debug_instance& di, const std::string * a_arg, const char * name);
01126
01127 void __debug_write_name_and_type(debug_instance& di, const void * a_arg, const char * name);
01128
01129 template<class T1, class T2>
01130 void __debug_write_name_and_type(
01131 debug_instance& di,
01132 const std::pair<T1,T2>& a_pair,
01133 const char *name
01134 )
01135 {
01136 di << name;
01137 di << " = ";
01138 di << __debug_write_type(di,a_pair);
01139 di.write_oeol();
01140 }
01141
01142 template<class T1, class T2>
01143 void __debug_write_name_and_type(
01144 debug_instance& di,
01145 const std::map<T1,T2>& a_map,
01146 const char* name
01147 )
01148 {
01149 di << name;
01150 di << " = ";
01151 __debug_write_type(di,a_map);
01152 di.write_oeol();
01153 }
01154
01155 template<class T>
01156 void __debug_write_name_and_type(
01157 debug_instance& di,
01158 const std::vector<T>& a_vector,
01159 const char* name
01160 )
01161 {
01162 di << name;
01163 di << " = ";
01164 __debug_write_type(di,a_vector);
01165 di.write_oeol();
01166 }
01167
01168 template<class T>
01169 void __debug_write_name_and_type(
01170 debug_instance& di,
01171 const std::list<T>& a_list,
01172 const char* name
01173 )
01174 {
01175 di << name;
01176 di << " = ";
01177 __debug_write_type(di,a_list);
01178 di.write_oeol();
01179 }
01180
01181
01182
01183 class debugger {
01184 public:
01185 typedef size_t size_type;
01186 typedef enum context_types {
01187 context_begin,
01188 context_end,
01189 context_input,
01190 context_output,
01191 context_variable,
01192 context_message,
01193 context_errno
01194 } context;
01195 typedef pair<std::string,bool> filter;
01196
01197 debugger();
01198 ~debugger();
01199 void init(const char * a_filename);
01200 void init(int * argc, char * argv[]);
01201 void close(void);
01202 const bool ok(void) const;
01203
01204 void set_depth(void);
01205 void set_depth(const size_type a_depth);
01206
01207 std::ostream& out(void);
01208 const std::string& filename(void) const;
01209 void fork(void);
01210
01211 void write(const char a_char);
01212 void write(const char * a_char_ptr);
01213 void write(const std::string& a_string);
01214 void set_context(const context m_context);
01215
01216 void pause(void);
01217 void unpause(void);
01218 const bool is_paused(void) const;
01219 const bool show_addresses(void) const;
01220
01221 void turn(const char * name);
01222 void turn(const bool a_value);
01223 void unturn(void);
01224 const bool is_on(void) const;
01225 const bool last_was_on(void) const;
01226
01227 private:
01228 size_type m_depth;
01229 size_type m_max_depth;
01230 int m_fd;
01231 std::ofstream m_out;
01232 bool m_ok;
01233 bool m_newline;
01234 context m_context;
01235 static const size_t m_buffer_size;
01236 char * m_buffer;
01237 std::string m_filename;
01238 unsigned long long m_pause_level;
01239 bool m_show_addresses;
01240 vector<filter> m_filter;
01241 deque<bool> m_on;
01242
01243 void mf_clear_buffer(void);
01244 const int mf_errno(void) const;
01245 const char * mf_errno_str(const int a_errno) const;
01246 void mf_print_error(const char * a_message) const;
01247 const std::string mf_function_header(
01248 const char * a_name,
01249 const char * a_file,
01250 const int a_line);
01251 void mf_push(
01252 const char * a_name,
01253 const char * a_file,
01254 const int a_line
01255 );
01256 void mf_write_function_header(
01257 const char * a_name,
01258 const char * a_file,
01259 const int a_line);
01260 void mf_pop(void);
01261 bool mf_check_output_stream(void);
01262 void mf_write(const char * a_message);
01263 void mf_write_prefix(void);
01264 void mf_write_blank_line(void);
01265 void mf_set_newline(const bool a_bool);
01266 void mf_check_newline(void);
01267
01268 friend class debug_instance;
01269 };
01270
01271
01272
01273 #endif
01274
01275 #endif