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