00001 #include "config.h"
00002
00003 #ifdef HAVE_SYS_TYPES_H
00004 #include <sys/types.h>
00005 #endif
00006 #ifdef HAVE_SYS_STAT_H
00007 #include <sys/stat.h>
00008 #endif
00009
00010
00011
00012
00013
00014 #include <iostream>
00015 #include <fcntl.h>
00016
00017 #ifdef HAVE_UNISTD_H
00018 #include <unistd.h>
00019 #endif
00020
00021 #include <fstream>
00022 #include <vector>
00023 #include <algorithm>
00024 #include <cstdio>
00025 #include <cstdlib>
00026 #include <cerrno>
00027 #include <cstdlib>
00028 #include <cstdio>
00029
00030 #ifdef HAVE_STRINGS_H
00031 #include <strings.h>
00032 #endif
00033 #ifdef HAVE_STRING_H
00034 #include <string.h>
00035 #endif
00036
00037 #include "debug.h"
00038
00039 #ifdef DEBUG
00040
00041 #define DEBUG_FLUSH
00042
00043
00044
00045
00046 const debug_instance::size_type debug_instance::m_base = 10;
00047
00048
00049 const char * debug_instance::m_alphabet = "0123456789";
00050
00051 debug_instance::debug_instance(
00052 const char * name,
00053 const char * file,
00054 const int line
00055 )
00056 {
00057 if (debug_manager.is_paused())
00058 return;
00059 if (!ok())
00060 return;
00061 debug_manager.turn(name);
00062 if (!debug_manager.is_on()) {
00063 if (debug_manager.last_was_on())
00064 debug_manager.mf_write_function_header(name,file,line);
00065 return;
00066 }
00067
00068 debug_manager.mf_push(name, file, line);
00069 m_indent = 0;
00070 mf_set_newline(true);
00071 }
00072
00073 debug_instance::~debug_instance()
00074 {
00075 if (debug_manager.is_paused())
00076 return;
00077 if (!ok())
00078 return;
00079 if (!debug_manager.is_on()) {
00080 debug_manager.unturn();
00081 return;
00082 }
00083
00084 debug_manager.mf_pop();
00085 debug_manager.unturn();
00086 }
00087
00088 void debug_instance::indent(void)
00089 {
00090 if (debug_manager.is_paused())
00091 return;
00092 if (!ok())
00093 return;
00094 if (!debug_manager.is_on())
00095 return;
00096
00097 ++m_indent;
00098 }
00099
00100 void debug_instance::unindent(void)
00101 {
00102 if (debug_manager.is_paused())
00103 return;
00104 if (!ok())
00105 return;
00106 if (!debug_manager.is_on())
00107 return;
00108
00109 if (m_indent > 0)
00110 --m_indent;
00111 }
00112
00113 const bool debug_instance::ok(void) const
00114 {
00115 return(debug_manager.m_ok);
00116 }
00117
00118 void debug_instance::write(const bool a_arg)
00119 {
00120 if (!debug_manager.is_on())
00121 return;
00122 if (debug_manager.is_paused())
00123 return;
00124 if (!ok())
00125 return;
00126
00127 if (a_arg) {
00128 debug_manager.write("true");
00129 }
00130 else {
00131 debug_manager.write("false");
00132 }
00133 }
00134
00135 void debug_instance::write(const char a_arg)
00136 {
00137 if (!debug_manager.is_on())
00138 return;
00139 if (debug_manager.is_paused())
00140 return;
00141 if (!ok())
00142 return;
00143
00144 mf_check_newline();
00145 debug_manager.write(a_arg);
00146 if (a_arg == '\n')
00147 mf_set_newline(true);
00148 }
00149
00150 void debug_instance::write(const unsigned int a_arg)
00151 {
00152 if (!debug_manager.is_on())
00153 return;
00154 if (debug_manager.is_paused())
00155 return;
00156 if (!ok())
00157 return;
00158
00159 mfT_write_unsigned_integral(a_arg);
00160 }
00161
00162 void debug_instance::write(const int a_arg)
00163 {
00164 if (!debug_manager.is_on())
00165 return;
00166 if (debug_manager.is_paused())
00167 return;
00168 if (!ok())
00169 return;
00170
00171 mfT_write_integral(a_arg);
00172 }
00173
00174 void debug_instance::write(const unsigned short a_arg)
00175 {
00176 if (!debug_manager.is_on())
00177 return;
00178 if (debug_manager.is_paused())
00179 return;
00180 if (!ok())
00181 return;
00182
00183 mfT_write_unsigned_integral(a_arg);
00184 }
00185
00186 void debug_instance::write(const short a_arg)
00187 {
00188 if (!debug_manager.is_on())
00189 return;
00190 if (debug_manager.is_paused())
00191 return;
00192 if (!ok())
00193 return;
00194
00195 mfT_write_integral(a_arg);
00196 }
00197
00198 void debug_instance::write(const unsigned long a_arg)
00199 {
00200 if (!debug_manager.is_on())
00201 return;
00202 if (debug_manager.is_paused())
00203 return;
00204 if (!ok())
00205 return;
00206
00207 mfT_write_unsigned_integral(a_arg);
00208 }
00209
00210 void debug_instance::write(const long a_arg)
00211 {
00212 if (!debug_manager.is_on())
00213 return;
00214 if (debug_manager.is_paused())
00215 return;
00216 if (!ok())
00217 return;
00218
00219 mfT_write_integral(a_arg);
00220 }
00221
00222 void debug_instance::write(const unsigned long long a_arg)
00223 {
00224 if (!debug_manager.is_on())
00225 return;
00226 if (debug_manager.is_paused())
00227 return;
00228 if (!ok())
00229 return;
00230
00231 mfT_write_unsigned_integral(a_arg);
00232 }
00233
00234 void debug_instance::write(const long long a_arg)
00235 {
00236 if (!debug_manager.is_on())
00237 return;
00238 if (debug_manager.is_paused())
00239 return;
00240 if (!ok())
00241 return;
00242
00243 mfT_write_integral(a_arg);
00244 }
00245
00246 void debug_instance::write(const float a_arg)
00247 {
00248 if (!debug_manager.is_on())
00249 return;
00250 if (debug_manager.is_paused())
00251 return;
00252 if (!ok())
00253 return;
00254
00255 mfT_write_fractional(a_arg);
00256 }
00257
00258 void debug_instance::write(const double a_arg)
00259 {
00260 if (!debug_manager.is_on())
00261 return;
00262 if (debug_manager.is_paused())
00263 return;
00264 if (!ok())
00265 return;
00266
00267 mfT_write_fractional(a_arg);
00268 }
00269
00270 void debug_instance::write(const std::string& a_arg)
00271 {
00272 std::string::const_iterator si;
00273
00274 if (!debug_manager.is_on())
00275 return;
00276 if (debug_manager.is_paused())
00277 return;
00278 if (!ok())
00279 return;
00280
00281 for (si = a_arg.begin(); si != a_arg.end(); ++si) {
00282 write(*si);
00283 }
00284 }
00285
00286 void debug_instance::write(const char * a_arg)
00287 {
00288 char const * ch_ptr;
00289
00290 if (!debug_manager.is_on())
00291 return;
00292 if (debug_manager.is_paused())
00293 return;
00294 if (!ok())
00295 return;
00296
00297 for (ch_ptr = a_arg; *ch_ptr != '\0'; ++ch_ptr)
00298 write(*ch_ptr);
00299 }
00300
00301 void debug_instance::write(const void * a_arg)
00302 {
00303 if (!debug_manager.is_on())
00304 return;
00305 if (debug_manager.is_paused())
00306 return;
00307 if (!ok())
00308 return;
00309 if (!debug_manager.show_addresses())
00310 return;
00311
00312 mf_clear_buffer();
00313 snprintf(debug_manager.m_buffer,debug_manager.m_buffer_size,"0x%p",a_arg);
00314 write(debug_manager.m_buffer);
00315 }
00316
00317 void debug_instance::write(std::ostream& (*op)(std::ostream&))
00318 {
00319 if (!debug_manager.is_on())
00320 return;
00321 if (debug_manager.is_paused())
00322 return;
00323 if (!ok())
00324 return;
00325
00326 if (op == std::endl)
00327 write("\n");
00328 }
00329
00330 void debug_instance::write_oeol(void)
00331 {
00332 if (!debug_manager.is_on())
00333 return;
00334 if (debug_manager.is_paused())
00335 return;
00336 if (!m_newline)
00337 write("\n");
00338 }
00339
00340 void debug_instance::mf_clear_buffer(void)
00341 {
00342 debug_manager.mf_clear_buffer();
00343 }
00344
00345 void debug_instance::mf_check_newline(void)
00346 {
00347 if (!m_newline)
00348 return;
00349 mf_write_indent();
00350 m_newline = false;
00351 }
00352
00353 void debug_instance::mf_set_newline(bool a_bool)
00354 {
00355 m_newline = a_bool;
00356 }
00357
00358 void debug_instance::mf_write_indent(void)
00359 {
00360 unsigned int count;
00361
00362 for (count = 0; count < m_indent; ++count)
00363 debug_manager.write(" ");
00364 }
00365
00366 template<class T>
00367 void debug_instance::mfT_write_unsigned_integral(const T& a_t)
00368 {
00369 T num = 0;
00370 size_t len = 0;
00371 int digit = 0;
00372 char ch = 0;
00373
00374 num = a_t;
00375 if (num == 0) {
00376 write('0');
00377 }
00378
00379 while (num > 0) {
00380 ++len;
00381 num /= m_base;
00382 }
00383 num = a_t;
00384
00385 mf_clear_buffer();
00386 while (num > 0) {
00387 digit = num % m_base;
00388 ch = m_alphabet[digit];
00389 debug_manager.m_buffer[len-1] = ch;
00390 num /= m_base;
00391 --len;
00392 }
00393 write(debug_manager.m_buffer);
00394 }
00395
00396 template<class T>
00397 void debug_instance::mfT_write_integral(const T& a_t)
00398 {
00399 if (a_t < 0) {
00400 write('-');
00401 mfT_write_unsigned_integral(-a_t);
00402 }
00403 else {
00404 mfT_write_unsigned_integral(a_t);
00405 }
00406 }
00407
00408 template<class T>
00409 void debug_instance::mfT_write_fractional(const T& a_t)
00410 {
00411 T fraction = a_t;
00412 T left = a_t;
00413 bool negative = false;
00414 unsigned long long whole_part;
00415 unsigned long long fractional_part;
00416 unsigned long long new_fractional_part;
00417
00418 if (fraction < 0.0) {
00419 negative = true;
00420 fraction = -fraction;
00421 }
00422
00423 whole_part = static_cast<unsigned long long>(fraction);
00424 fractional_part = 0;
00425 left = fraction - whole_part;
00426 while (left != 0.0) {
00427 left *= 10;
00428 new_fractional_part = fractional_part * 10;
00429 if (fractional_part != new_fractional_part / 10)
00430 break;
00431 fractional_part = new_fractional_part;
00432 fractional_part += static_cast<unsigned long long>(left) % 10;
00433 left -= static_cast<unsigned long long>(left) % 10;
00434 }
00435
00436 if (negative)
00437 write('-');
00438 write(whole_part);
00439 if (fractional_part > 0) {
00440 write('.');
00441 write(fractional_part);
00442 }
00443 }
00444
00445
00446
00447 void __debug_write(debug_instance& di, const bool a_arg)
00448 {
00449 di.write(a_arg);
00450 }
00451
00452 void __debug_write(debug_instance& di, const char a_arg)
00453 {
00454 di.write(a_arg);
00455 }
00456
00457 void __debug_write(debug_instance& di, const unsigned int a_arg)
00458 {
00459 di.write(a_arg);
00460 }
00461
00462 void __debug_write(debug_instance& di, const int a_arg)
00463 {
00464 di.write(a_arg);
00465 }
00466
00467 void __debug_write(debug_instance& di, const unsigned short a_arg)
00468 {
00469 di.write(a_arg);
00470 }
00471
00472 void __debug_write(debug_instance& di, const short a_arg)
00473 {
00474 di.write(a_arg);
00475 }
00476
00477 void __debug_write(debug_instance& di, const unsigned long a_arg)
00478 {
00479 di.write(a_arg);
00480 }
00481
00482 void __debug_write(debug_instance& di, const long a_arg)
00483 {
00484 di.write(a_arg);
00485 }
00486
00487 void __debug_write(debug_instance& di, const unsigned long long a_arg)
00488 {
00489 di.write(a_arg);
00490 }
00491
00492 void __debug_write(debug_instance& di, const long long a_arg)
00493 {
00494 di.write(a_arg);
00495 }
00496
00497 void __debug_write(debug_instance& di, const float a_arg)
00498 {
00499 di.write(a_arg);
00500 }
00501
00502 void __debug_write(debug_instance& di, const double a_arg)
00503 {
00504 di.write(a_arg);
00505 }
00506
00507 void __debug_write(debug_instance& di, const std::string& a_arg)
00508 {
00509 di.write(a_arg);
00510 }
00511
00512 void __debug_write(debug_instance& di, const bool * a_arg)
00513 {
00514 di.write((void*)a_arg);
00515 }
00516
00517 void __debug_write(debug_instance& di, const char * a_arg)
00518 {
00519 di.write(a_arg);
00520 }
00521
00522 void __debug_write(debug_instance& di, const unsigned int * a_arg)
00523 {
00524 di.write((void*)a_arg);
00525 }
00526
00527 void __debug_write(debug_instance& di, const int * a_arg)
00528 {
00529 di.write((void*)a_arg);
00530 }
00531
00532 void __debug_write(debug_instance& di, const unsigned short * a_arg)
00533 {
00534 di.write((void*)a_arg);
00535 }
00536
00537 void __debug_write(debug_instance& di, const short * a_arg)
00538 {
00539 di.write((void*)a_arg);
00540 }
00541
00542 void __debug_write(debug_instance& di, const unsigned long * a_arg)
00543 {
00544 di.write((void*)a_arg);
00545 }
00546
00547 void __debug_write(debug_instance& di, const long * a_arg)
00548 {
00549 di.write((void*)a_arg);
00550 }
00551
00552 void __debug_write(debug_instance& di, const unsigned long long * a_arg)
00553 {
00554 di.write((void*)a_arg);
00555 }
00556
00557 void __debug_write(debug_instance& di, const long long * a_arg)
00558 {
00559 di.write((void*)a_arg);
00560 }
00561
00562 void __debug_write(debug_instance& di, const float * a_arg)
00563 {
00564 di.write((void*)a_arg);
00565 }
00566
00567 void __debug_write(debug_instance& di, const double * a_arg)
00568 {
00569 di.write((void*)a_arg);
00570 }
00571
00572
00573 void __debug_write(debug_instance& di, const void * a_arg)
00574 {
00575 di.write((void*)a_arg);
00576 }
00577
00578 void __debug_write(debug_instance& di, std::ostream& (*a_arg)(std::ostream&))
00579 {
00580 di.write(a_arg);
00581 }
00582
00583
00584
00585 debug_instance& operator<<(debug_instance& di, const bool a_arg)
00586 {
00587 __debug_write(di,a_arg);
00588 return(di);
00589 }
00590
00591 debug_instance& operator<<(debug_instance& di, const char a_arg)
00592 {
00593 __debug_write(di,a_arg);
00594 return(di);
00595 }
00596
00597 debug_instance& operator<<(debug_instance& di, const unsigned int a_arg)
00598 {
00599 __debug_write(di,a_arg);
00600 return(di);
00601 }
00602
00603 debug_instance& operator<<(debug_instance& di, const int a_arg)
00604 {
00605 __debug_write(di,a_arg);
00606 return(di);
00607 }
00608
00609 debug_instance& operator<<(debug_instance& di, const unsigned short a_arg)
00610 {
00611 __debug_write(di,a_arg);
00612 return(di);
00613 }
00614
00615 debug_instance& operator<<(debug_instance& di, const short a_arg)
00616 {
00617 __debug_write(di,a_arg);
00618 return(di);
00619 }
00620
00621 debug_instance& operator<<(debug_instance& di, const unsigned long a_arg)
00622 {
00623 __debug_write(di,a_arg);
00624 return(di);
00625 }
00626
00627 debug_instance& operator<<(debug_instance& di, const long a_arg)
00628 {
00629 __debug_write(di,a_arg);
00630 return(di);
00631 }
00632
00633 debug_instance& operator<<(debug_instance& di, const unsigned long long a_arg)
00634 {
00635 __debug_write(di,a_arg);
00636 return(di);
00637 }
00638
00639 debug_instance& operator<<(debug_instance& di, const long long a_arg)
00640 {
00641 __debug_write(di,a_arg);
00642 return(di);
00643 }
00644
00645 debug_instance& operator<<(debug_instance& di, const float a_arg)
00646 {
00647 __debug_write(di,a_arg);
00648 return(di);
00649 }
00650
00651 debug_instance& operator<<(debug_instance& di, const double a_arg)
00652 {
00653 __debug_write(di,a_arg);
00654 return(di);
00655 }
00656
00657 debug_instance& operator<<(debug_instance& di, const std::string& a_arg)
00658 {
00659 __debug_write(di,a_arg);
00660 return(di);
00661 }
00662
00663
00664 debug_instance& operator<<(debug_instance& di, const bool * a_arg)
00665 {
00666 __debug_write(di,a_arg);
00667 return(di);
00668 }
00669
00670 debug_instance& operator<<(debug_instance& di, const char * a_arg)
00671 {
00672 __debug_write(di,a_arg);
00673 return(di);
00674 }
00675
00676 debug_instance& operator<<(debug_instance& di, const unsigned int * a_arg)
00677 {
00678 __debug_write(di,a_arg);
00679 return(di);
00680 }
00681
00682 debug_instance& operator<<(debug_instance& di, const int * a_arg)
00683 {
00684 __debug_write(di,a_arg);
00685 return(di);
00686 }
00687
00688 debug_instance& operator<<(debug_instance& di, const unsigned short * a_arg)
00689 {
00690 __debug_write(di,a_arg);
00691 return(di);
00692 }
00693
00694 debug_instance& operator<<(debug_instance& di, const short * a_arg)
00695 {
00696 __debug_write(di,a_arg);
00697 return(di);
00698 }
00699
00700 debug_instance& operator<<(debug_instance& di, const unsigned long * a_arg)
00701 {
00702 __debug_write(di,a_arg);
00703 return(di);
00704 }
00705
00706 debug_instance& operator<<(debug_instance& di, const long * a_arg)
00707 {
00708 __debug_write(di,a_arg);
00709 return(di);
00710 }
00711
00712 debug_instance& operator<<(debug_instance& di, const unsigned long long * a_arg)
00713 {
00714 __debug_write(di,a_arg);
00715 return(di);
00716 }
00717
00718 debug_instance& operator<<(debug_instance& di, const long long * a_arg)
00719 {
00720 __debug_write(di,a_arg);
00721 return(di);
00722 }
00723
00724 debug_instance& operator<<(debug_instance& di, const float * a_arg)
00725 {
00726 __debug_write(di,a_arg);
00727 return(di);
00728 }
00729
00730 debug_instance& operator<<(debug_instance& di, const double * a_arg)
00731 {
00732 __debug_write(di,a_arg);
00733 return(di);
00734 }
00735
00736
00737 debug_instance& operator<<(debug_instance& di, const void * a_arg)
00738 {
00739 __debug_write(di,a_arg);
00740 return(di);
00741 }
00742
00743 debug_instance& operator<<(debug_instance& di, std::ostream& (*a_arg)(std::ostream&))
00744 {
00745 __debug_write(di,a_arg);
00746 return(di);
00747 }
00748
00749
00750
00751 const char * __debug_type(const bool a_arg)
00752 {
00753 return("bool");
00754 }
00755
00756 const char * __debug_type(const char a_arg)
00757 {
00758 return("char");
00759 }
00760
00761 const char * __debug_type(const unsigned int a_arg)
00762 {
00763 return("unsigned int");
00764 }
00765
00766 const char * __debug_type(const int a_arg)
00767 {
00768 return("int");
00769 }
00770
00771 const char * __debug_type(const unsigned short a_arg)
00772 {
00773 return("unsigned short");
00774 }
00775
00776 const char * __debug_type(const short a_arg)
00777 {
00778 return("short");
00779 }
00780
00781 const char * __debug_type(const unsigned long a_arg)
00782 {
00783 return("unsigned long");
00784 }
00785
00786 const char * __debug_type(const long a_arg)
00787 {
00788 return("long");
00789 }
00790
00791 const char * __debug_type(const unsigned long long a_arg)
00792 {
00793 return("unsigned long long");
00794 }
00795
00796 const char * __debug_type(const long long a_arg)
00797 {
00798 return("long long");
00799 }
00800
00801 const char * __debug_type(const float a_arg)
00802 {
00803 return("float");
00804 }
00805
00806 const char * __debug_type(const double a_arg)
00807 {
00808 return("double");
00809 }
00810
00811 const char * __debug_type(const std::string& a_arg)
00812 {
00813 return("std::string");
00814 }
00815
00816 const char * __debug_type(const bool * a_arg)
00817 {
00818 return("bool *");
00819 }
00820
00821 const char * __debug_type(const char * a_arg)
00822 {
00823 return("char *");
00824 }
00825
00826 const char * __debug_type(const unsigned int * a_arg)
00827 {
00828 return("unsigned int *");
00829 }
00830
00831 const char * __debug_type(const int * a_arg)
00832 {
00833 return("int *");
00834 }
00835
00836 const char * __debug_type(const unsigned short * a_arg)
00837 {
00838 return("unsigned short *");
00839 }
00840
00841 const char * __debug_type(const short * a_arg)
00842 {
00843 return("short *");
00844 }
00845
00846 const char * __debug_type(const unsigned long * a_arg)
00847 {
00848 return("unsigned long *");
00849 }
00850
00851 const char * __debug_type(const long * a_arg)
00852 {
00853 return("long *");
00854 }
00855
00856 const char * __debug_type(const unsigned long long * a_arg)
00857 {
00858 return("unsigned long long *");
00859 }
00860
00861 const char * __debug_type(const long long * a_arg)
00862 {
00863 return("long long *");
00864 }
00865
00866 const char * __debug_type(const float * a_arg)
00867 {
00868 return("float *");
00869 }
00870
00871 const char * __debug_type(const double * a_arg)
00872 {
00873 return("double *");
00874 }
00875
00876
00877 const char * __debug_type(const void * a_arg)
00878 {
00879 return("void *");
00880 }
00881
00882 const char * __debug_type(const std::string * a_arg)
00883 {
00884 return("std::string *");
00885 }
00886
00887
00888
00889 void ___debug_write_type_char(debug_instance& di, const char a_char)
00890 {
00891 switch (a_char) {
00892 case '\a': di << "\\a"; break;
00893 case '\b': di << "\\b"; break;
00894 case '\f': di << "\\f"; break;
00895 case '\n': di << "\\n"; break;
00896 case '\r': di << "\\r"; break;
00897 case '\t': di << "\\t"; break;
00898 case '"': di << "\\\""; break;
00899 default: di << a_char; break;
00900 }
00901 }
00902
00903 void __debug_write_type(debug_instance& di, const bool& a_arg)
00904 {
00905 di << "(";
00906 di << __debug_type(a_arg);
00907 if (debug_manager.show_addresses()) {
00908 di << " at ";
00909 di << (void*)&a_arg;
00910 }
00911 di << ") ";
00912 di << a_arg;
00913 di.write_oeol();
00914 }
00915
00916 void __debug_write_type(debug_instance& di, const char& a_arg)
00917 {
00918 di << "(";
00919 di << __debug_type(a_arg);
00920 if (debug_manager.show_addresses()) {
00921 di << " at ";
00922 di << (void*)&a_arg;
00923 }
00924 di << ") '";
00925 ___debug_write_type_char(di,a_arg);
00926 di << "'";
00927 di.write_oeol();
00928 }
00929
00930 void __debug_write_type(debug_instance& di, const unsigned int& a_arg)
00931 {
00932 di << "(";
00933 di << __debug_type(a_arg);
00934 if (debug_manager.show_addresses()) {
00935 di << " at ";
00936 di << (void*)&a_arg;
00937 }
00938 di << ") ";
00939 di << a_arg;
00940 di.write_oeol();
00941 }
00942
00943 void __debug_write_type(debug_instance& di, const int& a_arg)
00944 {
00945 di << "(";
00946 di << __debug_type(a_arg);
00947 if (debug_manager.show_addresses()) {
00948 di << " at ";
00949 di << (void*)&a_arg;
00950 }
00951 di << ") ";
00952 di << a_arg;
00953 di.write_oeol();
00954 }
00955
00956 void __debug_write_type(debug_instance& di, const unsigned short& a_arg)
00957 {
00958 di << "(";
00959 di << __debug_type(a_arg);
00960 if (debug_manager.show_addresses()) {
00961 di << " at ";
00962 di << (void*)&a_arg;
00963 }
00964 di << ") ";
00965 di << a_arg;
00966 di.write_oeol();
00967 }
00968
00969 void __debug_write_type(debug_instance& di, const short& a_arg)
00970 {
00971 di << "(";
00972 di << __debug_type(a_arg);
00973 if (debug_manager.show_addresses()) {
00974 di << " at ";
00975 di << (void*)&a_arg;
00976 }
00977 di << ") ";
00978 di << a_arg;
00979 di.write_oeol();
00980 }
00981
00982 void __debug_write_type(debug_instance& di, const unsigned long& a_arg)
00983 {
00984 di << "(";
00985 di << __debug_type(a_arg);
00986 if (debug_manager.show_addresses()) {
00987 di << " at ";
00988 di << (void*)&a_arg;
00989 }
00990 di << ") ";
00991 di << a_arg;
00992 di.write_oeol();
00993 }
00994
00995 void __debug_write_type(debug_instance& di, const long& a_arg)
00996 {
00997 di << "(";
00998 di << __debug_type(a_arg);
00999 if (debug_manager.show_addresses()) {
01000 di << " at ";
01001 di << (void*)&a_arg;
01002 }
01003 di << ") ";
01004 di << a_arg;
01005 di.write_oeol();
01006 }
01007
01008 void __debug_write_type(debug_instance& di, const unsigned long long& a_arg)
01009 {
01010 di << "(";
01011 di << __debug_type(a_arg);
01012 if (debug_manager.show_addresses()) {
01013 di << " at ";
01014 di << (void*)&a_arg;
01015 }
01016 di << ") ";
01017 di << a_arg;
01018 di.write_oeol();
01019 }
01020
01021 void __debug_write_type(debug_instance& di, const long long& a_arg)
01022 {
01023 di << "(";
01024 di << __debug_type(a_arg);
01025 if (debug_manager.show_addresses()) {
01026 di << " at ";
01027 di << (void*)&a_arg;
01028 }
01029 di << ") ";
01030 di << a_arg;
01031 di.write_oeol();
01032 }
01033
01034 void __debug_write_type(debug_instance& di, const float& a_arg)
01035 {
01036 di << "(";
01037 di << __debug_type(a_arg);
01038 if (debug_manager.show_addresses()) {
01039 di << " at ";
01040 di << (void*)&a_arg;
01041 }
01042 di << ") ";
01043 di << a_arg;
01044 di.write_oeol();
01045 }
01046
01047 void __debug_write_type(debug_instance& di, const double& a_arg)
01048 {
01049 di << "(";
01050 di << __debug_type(a_arg);
01051 if (debug_manager.show_addresses()) {
01052 di << " at ";
01053 di << (void*)&a_arg;
01054 }
01055 di << ") ";
01056 di << a_arg;
01057 di.write_oeol();
01058 }
01059
01060 void __debug_write_type(debug_instance& di, const std::string& a_arg)
01061 {
01062 std::string::const_iterator si;
01063
01064 di << "(";
01065 di << __debug_type(a_arg);
01066 if (debug_manager.show_addresses()) {
01067 di << " at ";
01068 di << (void*)&a_arg;
01069 }
01070 di << ") \"";
01071 for (si = a_arg.begin(); si != a_arg.end(); ++si)
01072 ___debug_write_type_char(di,*si);
01073 di << "\"";
01074 di.write_oeol();
01075 }
01076
01077
01078 void __debug_write_type(debug_instance& di, const bool * a_arg)
01079 {
01080 di << "(";
01081 di << __debug_type(a_arg);
01082 if (debug_manager.show_addresses()) {
01083 di << " at ";
01084 di << (void*)a_arg;
01085 }
01086 di << ") ";
01087 di << a_arg;
01088 di.write_oeol();
01089 }
01090
01091 void __debug_write_type(debug_instance& di, const char * a_arg)
01092 {
01093 const char * chptr;
01094
01095 di << "(";
01096 di << __debug_type(a_arg);
01097 if (debug_manager.show_addresses()) {
01098 di << " at ";
01099 di << (void*)a_arg;
01100 }
01101 di << ") ";
01102 if (a_arg != 0) {
01103 di << "\"";
01104 for (chptr = a_arg; *chptr != 0; ++chptr)
01105 ___debug_write_type_char(di,*chptr);
01106 di << "\"";
01107 }
01108 di.write_oeol();
01109 }
01110
01111 void __debug_write_type(debug_instance& di, const unsigned int * a_arg)
01112 {
01113 di << "(";
01114 di << __debug_type(a_arg);
01115 if (debug_manager.show_addresses()) {
01116 di << " at ";
01117 di << (void*)a_arg;
01118 }
01119 di << ") ";
01120 di << a_arg;
01121 di.write_oeol();
01122 }
01123
01124 void __debug_write_type(debug_instance& di, const int * a_arg)
01125 {
01126 di << "(";
01127 di << __debug_type(a_arg);
01128 if (debug_manager.show_addresses()) {
01129 di << " at ";
01130 di << (void*)a_arg;
01131 }
01132 di << ") ";
01133 di << a_arg;
01134 di.write_oeol();
01135 }
01136
01137 void __debug_write_type(debug_instance& di, const unsigned short * a_arg)
01138 {
01139 di << "(";
01140 di << __debug_type(a_arg);
01141 if (debug_manager.show_addresses()) {
01142 di << " at ";
01143 di << (void*)a_arg;
01144 }
01145 di << ") ";
01146 di << a_arg;
01147 di.write_oeol();
01148 }
01149
01150 void __debug_write_type(debug_instance& di, const short * a_arg)
01151 {
01152 di << "(";
01153 di << __debug_type(a_arg);
01154 if (debug_manager.show_addresses()) {
01155 di << " at ";
01156 di << (void*)a_arg;
01157 }
01158 di << ") ";
01159 di << a_arg;
01160 di.write_oeol();
01161 }
01162
01163 void __debug_write_type(debug_instance& di, const unsigned long * a_arg)
01164 {
01165 di << "(";
01166 di << __debug_type(a_arg);
01167 if (debug_manager.show_addresses()) {
01168 di << " at ";
01169 di << (void*)a_arg;
01170 }
01171 di << ") ";
01172 di << a_arg;
01173 di.write_oeol();
01174 }
01175
01176 void __debug_write_type(debug_instance& di, const long * a_arg)
01177 {
01178 di << "(";
01179 di << __debug_type(a_arg);
01180 if (debug_manager.show_addresses()) {
01181 di << " at ";
01182 di << (void*)a_arg;
01183 }
01184 di << ") ";
01185 di << a_arg;
01186 di.write_oeol();
01187 }
01188
01189 void __debug_write_type(debug_instance& di, const unsigned long long * a_arg)
01190 {
01191 di << "(";
01192 di << __debug_type(a_arg);
01193 if (debug_manager.show_addresses()) {
01194 di << " at ";
01195 di << (void*)a_arg;
01196 }
01197 di << ") ";
01198 di << a_arg;
01199 di.write_oeol();
01200 }
01201
01202 void __debug_write_type(debug_instance& di, const long long * a_arg)
01203 {
01204 di << "(";
01205 di << __debug_type(a_arg);
01206 if (debug_manager.show_addresses()) {
01207 di << " at ";
01208 di << (void*)a_arg;
01209 }
01210 di << ") ";
01211 di << a_arg;
01212 di.write_oeol();
01213 }
01214
01215 void __debug_write_type(debug_instance& di, const float * a_arg)
01216 {
01217 di << "(";
01218 di << __debug_type(a_arg);
01219 if (debug_manager.show_addresses()) {
01220 di << " at ";
01221 di << (void*)a_arg;
01222 }
01223 di << ") ";
01224 di << a_arg;
01225 di.write_oeol();
01226 }
01227
01228 void __debug_write_type(debug_instance& di, const double * a_arg)
01229 {
01230 di << "(";
01231 di << __debug_type(a_arg);
01232 if (debug_manager.show_addresses()) {
01233 di << " at ";
01234 di << (void*)a_arg;
01235 }
01236 di << ") ";
01237 di << a_arg;
01238 di.write_oeol();
01239 }
01240
01241
01242 void __debug_write_type(debug_instance& di, const void * a_arg)
01243 {
01244 di << "(";
01245 di << __debug_type(a_arg);
01246 if (debug_manager.show_addresses()) {
01247 di << " at ";
01248 di << (void*)a_arg;
01249 }
01250 di << ") ";
01251 di << a_arg;
01252 di.write_oeol();
01253 }
01254
01255 void __debug_write_type(debug_instance& di, const std::string * a_arg)
01256 {
01257 di << "(";
01258 di << __debug_type(a_arg);
01259 if (debug_manager.show_addresses()) {
01260 di << " at ";
01261 di << (void*)a_arg;
01262 }
01263 di << ") ";
01264 di << a_arg;
01265 di.write_oeol();
01266 }
01267
01268
01269
01270 void __debug_write_name_and_type(debug_instance& di, const bool& a_arg, const char * name)
01271 {
01272 di << name;
01273 di << " = ";
01274 __debug_write_type(di,a_arg);
01275 di.write_oeol();
01276 }
01277
01278 void __debug_write_name_and_type(debug_instance& di, const char& a_arg, const char * name)
01279 {
01280 di << name;
01281 di << " = ";
01282 __debug_write_type(di,a_arg);
01283 di.write_oeol();
01284 }
01285
01286 void __debug_write_name_and_type(debug_instance& di, const unsigned int& a_arg, const char * name)
01287 {
01288 di << name;
01289 di << " = ";
01290 __debug_write_type(di,a_arg);
01291 di.write_oeol();
01292 }
01293
01294 void __debug_write_name_and_type(debug_instance& di, const int& a_arg, const char * name)
01295 {
01296 di << name;
01297 di << " = ";
01298 __debug_write_type(di,a_arg);
01299 di.write_oeol();
01300 }
01301
01302 void __debug_write_name_and_type(debug_instance& di, const unsigned short& a_arg, const char * name)
01303 {
01304 di << name;
01305 di << " = ";
01306 __debug_write_type(di,a_arg);
01307 di.write_oeol();
01308 }
01309
01310 void __debug_write_name_and_type(debug_instance& di, const short& a_arg, const char * name)
01311 {
01312 di << name;
01313 di << " = ";
01314 __debug_write_type(di,a_arg);
01315 di.write_oeol();
01316 }
01317
01318 void __debug_write_name_and_type(debug_instance& di, const unsigned long& a_arg, const char * name)
01319 {
01320 di << name;
01321 di << " = ";
01322 __debug_write_type(di,a_arg);
01323 di.write_oeol();
01324 }
01325
01326 void __debug_write_name_and_type(debug_instance& di, const long& a_arg, const char * name)
01327 {
01328 di << name;
01329 di << " = ";
01330 __debug_write_type(di,a_arg);
01331 di.write_oeol();
01332 }
01333
01334 void __debug_write_name_and_type(debug_instance& di, const unsigned long long& a_arg, const char * name)
01335 {
01336 di << name;
01337 di << " = ";
01338 __debug_write_type(di,a_arg);
01339 di.write_oeol();
01340 }
01341
01342 void __debug_write_name_and_type(debug_instance& di, const long long& a_arg, const char * name)
01343 {
01344 di << name;
01345 di << " = ";
01346 __debug_write_type(di,a_arg);
01347 di.write_oeol();
01348 }
01349
01350 void __debug_write_name_and_type(debug_instance& di, const float& a_arg, const char * name)
01351 {
01352 di << name;
01353 di << " = ";
01354 __debug_write_type(di,a_arg);
01355 di.write_oeol();
01356 }
01357
01358 void __debug_write_name_and_type(debug_instance& di, const double& a_arg, const char * name)
01359 {
01360 di << name;
01361 di << " = ";
01362 __debug_write_type(di,a_arg);
01363 di.write_oeol();
01364 }
01365
01366 void __debug_write_name_and_type(debug_instance& di, const std::string& a_arg, const char * name)
01367 {
01368 di << name;
01369 di << " = ";
01370 __debug_write_type(di,a_arg);
01371 di.write_oeol();
01372 }
01373
01374
01375 void __debug_write_name_and_type(debug_instance& di, const bool * a_arg, const char * name)
01376 {
01377 di << name;
01378 di << " = ";
01379 __debug_write_type(di,a_arg);
01380 di.write_oeol();
01381 }
01382
01383 void __debug_write_name_and_type(debug_instance& di, const char * a_arg, const char * name)
01384 {
01385 di << name;
01386 di << " = ";
01387 __debug_write_type(di,a_arg);
01388 di.write_oeol();
01389 }
01390
01391 void __debug_write_name_and_type(debug_instance& di, const unsigned int * a_arg, const char * name)
01392 {
01393 di << name;
01394 di << " = ";
01395 __debug_write_type(di,a_arg);
01396 di.write_oeol();
01397 }
01398
01399 void __debug_write_name_and_type(debug_instance& di, const int * a_arg, const char * name)
01400 {
01401 di << name;
01402 di << " = ";
01403 __debug_write_type(di,a_arg);
01404 di.write_oeol();
01405 }
01406
01407 void __debug_write_name_and_type(debug_instance& di, const unsigned short * a_arg, const char * name)
01408 {
01409 di << name;
01410 di << " = ";
01411 __debug_write_type(di,a_arg);
01412 di.write_oeol();
01413 }
01414
01415 void __debug_write_name_and_type(debug_instance& di, const short * a_arg, const char * name)
01416 {
01417 di << name;
01418 di << " = ";
01419 __debug_write_type(di,a_arg);
01420 di.write_oeol();
01421 }
01422
01423 void __debug_write_name_and_type(debug_instance& di, const unsigned long * a_arg, const char * name)
01424 {
01425 di << name;
01426 di << " = ";
01427 __debug_write_type(di,a_arg);
01428 di.write_oeol();
01429 }
01430
01431 void __debug_write_name_and_type(debug_instance& di, const long * a_arg, const char * name)
01432 {
01433 di << name;
01434 di << " = ";
01435 __debug_write_type(di,a_arg);
01436 di.write_oeol();
01437 }
01438
01439 void __debug_write_name_and_type(debug_instance& di, const unsigned long long * a_arg, const char * name)
01440 {
01441 di << name;
01442 di << " = ";
01443 __debug_write_type(di,a_arg);
01444 di.write_oeol();
01445 }
01446
01447 void __debug_write_name_and_type(debug_instance& di, const long long * a_arg, const char * name)
01448 {
01449 di << name;
01450 di << " = ";
01451 __debug_write_type(di,a_arg);
01452 di.write_oeol();
01453 }
01454
01455 void __debug_write_name_and_type(debug_instance& di, const float * a_arg, const char * name)
01456 {
01457 di << name;
01458 di << " = ";
01459 __debug_write_type(di,a_arg);
01460 di.write_oeol();
01461 }
01462
01463 void __debug_write_name_and_type(debug_instance& di, const double * a_arg, const char * name)
01464 {
01465 di << name;
01466 di << " = ";
01467 __debug_write_type(di,a_arg);
01468 di.write_oeol();
01469 }
01470
01471
01472 void __debug_write_name_and_type(debug_instance& di, const void * a_arg, const char * name)
01473 {
01474 di << name;
01475 di << " = ";
01476 __debug_write_type(di,a_arg);
01477 di.write_oeol();
01478 }
01479
01480 void __debug_write_name_and_type(debug_instance& di, const std::string * a_arg, const char * name)
01481 {
01482 di << name;
01483 di << " = ";
01484 __debug_write_type(di,a_arg);
01485 di.write_oeol();
01486 }
01487
01488
01489
01490 debugger::debugger()
01491 {
01492 m_ok = false;
01493 m_buffer = 0;
01494 m_newline = true;
01495 m_context = context_begin;
01496 m_fd = -1;
01497 m_pause_level = 0;
01498 m_show_addresses = true;
01499
01500 set_depth();
01501 }
01502
01503 debugger::~debugger()
01504 {
01505 close();
01506 }
01507
01508 void debugger::init(const char * a_filename)
01509 {
01510 std::string tmpstr;
01511
01512 m_ok = true;
01513
01514 try {
01515 tmpstr = a_filename;
01516 }
01517 catch(...) {
01518 mf_print_error("Memory allocation error\n");
01519 m_ok = false;
01520 return;
01521 }
01522
01523 if ((tmpstr == "-") || (tmpstr == "std::cout"))
01524 m_fd = STDOUT_FILENO;
01525 else if (tmpstr == "std::cerr")
01526 m_fd = STDERR_FILENO;
01527 else {
01528 int old_errno = errno;
01529 unlink(a_filename);
01530 errno = old_errno;
01531 m_fd = open(a_filename, O_WRONLY|O_CREAT
01532 #ifdef O_LARGEFILE
01533 |O_LARGEFILE
01534 #endif
01535 ,
01536 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
01537 );
01538 }
01539
01540 if (m_fd == -1) {
01541 mf_print_error("Could not open debug output file\n");
01542 m_ok = false;
01543 return;
01544 }
01545
01546 m_out.attach(m_fd);
01547 if (errno != 0)
01548 errno = 0;
01549
01550 if (!m_out.is_open()) {
01551 mf_print_error("Could not attach output stream to file descriptor\n");
01552 m_ok = false;
01553 }
01554
01555 if (m_buffer != 0)
01556 delete[] m_buffer;
01557 m_buffer = new char[m_buffer_size];
01558 if (m_buffer == 0) {
01559 mf_print_error("Could not allocate buffer\n");
01560 m_out.close();
01561 m_ok = false;
01562 return;
01563 }
01564
01565 m_depth = 0;
01566 m_newline = true;
01567 m_context = context_begin;
01568 try {
01569 m_filename = a_filename;
01570 }
01571 catch(...) {
01572 mf_print_error("Could not allocate memory\n");
01573 m_ok = false;
01574 }
01575
01576 if (mf_errno() != 0) {
01577 mf_print_error("Errno is already non-zero!\n");
01578 }
01579
01580 m_out << "# vim:foldmethod=marker:foldmarker={,}" << std::endl;
01581 }
01582
01583 void debugger::init(int * argc, char * argv[])
01584 {
01585 int c, x;
01586 char * filename = 0;
01587 char * level = 0;
01588
01589 for (c = 1; c < *argc; ++c) {
01590 if (strncmp(argv[c],"--debug",7) == 0) {
01591 if (strcmp(argv[c],"--debug-level") == 0) {
01592 if (c > (*argc)-2) {
01593 mf_print_error("Integer expected after --debug-level\n");
01594 continue;
01595 }
01596 level = argv[c+1];
01597 for (x = c; x < (*argc)-2; ++x) {
01598 argv[x] = argv[x+2];
01599 }
01600 *argc -= 2;
01601 --c;
01602 }
01603 else if (strcmp(argv[c],"--debug-on-at") == 0) {
01604 if (c > (*argc)-2) {
01605 mf_print_error("String expected after --debug-on-at\n");
01606 continue;
01607 }
01608 filter new_filter;
01609
01610 new_filter.first = argv[c+1];
01611 new_filter.second = true;
01612 m_filter.push_back(new_filter);
01613 for (x = c; x < (*argc)-2; ++x) {
01614 argv[x] = argv[x+2];
01615 }
01616 *argc -= 2;
01617 --c;
01618 }
01619 else if (strcmp(argv[c],"--debug-off-at") == 0) {
01620 if (c > (*argc)-2) {
01621 mf_print_error("String expected after --debug-off-at\n");
01622 continue;
01623 }
01624 filter new_filter;
01625
01626 new_filter.first = argv[c+1];
01627 new_filter.second = false;
01628 m_filter.push_back(new_filter);
01629 for (x = c; x < (*argc)-2; ++x) {
01630 argv[x] = argv[x+2];
01631 }
01632 *argc -= 2;
01633 --c;
01634 }
01635 else if (strcmp(argv[c],"--debug-no-addresses") == 0) {
01636 m_show_addresses = false;
01637 for (x = c; x < (*argc)-1; ++x) {
01638 argv[x] = argv[x+1];
01639 }
01640 *argc -= 1;
01641 --c;
01642 }
01643 else {
01644 if ((strlen(argv[c]) != strlen("--debug"))
01645 || (strcmp(argv[c],"--debug") != 0))
01646 {
01647 const int buffer_size = 1024;
01648 char buffer[buffer_size] = { 0 };
01649
01650 sprintf(buffer, "Invalid debug argument: %s\n", argv[c]);
01651 mf_print_error(buffer);
01652 continue;
01653 }
01654 if (c > (*argc)-2) {
01655 mf_print_error("Filename expected after --debug\n");
01656 continue;
01657 }
01658 filename = argv[c+1];
01659 for (x = c; x < (*argc)-2; ++x) {
01660 argv[x] = argv[x+2];
01661 }
01662 *argc -= 2;
01663 --c;
01664 }
01665 }
01666 }
01667
01668 if (level != 0) {
01669 size_type n;
01670
01671 sscanf(level,"%u",&n);
01672 set_depth(n);
01673 }
01674
01675 if (filename != 0) {
01676 init(filename);
01677 }
01678 }
01679
01680 void debugger::close(void)
01681 {
01682 if (m_buffer != 0)
01683 delete[] m_buffer;
01684 if (m_out.is_open())
01685 m_out.close();
01686 m_depth = 0;
01687 m_ok = false;
01688 }
01689
01690 const bool debugger::ok(void) const
01691 {
01692 return(m_ok);
01693 }
01694
01695 void debugger::set_depth(void)
01696 {
01697 size_type last_depth = 0;
01698 m_max_depth = 1;
01699 while (m_max_depth != last_depth) {
01700 last_depth = m_max_depth;
01701 m_max_depth *= 2;
01702 m_max_depth += 1;
01703 }
01704 }
01705
01706 void debugger::set_depth(const debugger::size_type a_depth)
01707 {
01708 m_max_depth = a_depth;
01709 }
01710
01711 const std::string& debugger::filename(void) const
01712 {
01713 return(m_filename);
01714 }
01715
01716 void debugger::fork(void)
01717 {
01718 std::string filename;
01719
01720 if ((m_filename == "-")
01721 || (m_filename == "std::cout")
01722 || (m_filename == "std::cerr")
01723 || (m_filename.substr(0,4) == "/dev"))
01724 {
01725 mf_print_error("Child debugger has no output\n");
01726 close();
01727 return;
01728 }
01729
01730 mf_clear_buffer();
01731 snprintf(m_buffer,m_buffer_size,"%s.%d",m_filename.c_str(),getpid());
01732 try {
01733 filename = m_buffer;
01734 }
01735 catch(...) {
01736 mf_print_error("Could not allocate memory\n");
01737 m_ok = false;
01738 }
01739 close();
01740 init(filename.c_str());
01741 }
01742
01743 void debugger::write(const char a_char)
01744 {
01745 if (m_depth > m_max_depth)
01746 return;
01747 if (!is_on())
01748 return;
01749 if (is_paused())
01750 return;
01751 if (!m_ok)
01752 return;
01753 if (!mf_check_output_stream())
01754 return;
01755 mf_check_newline();
01756 m_out << a_char;
01757 #ifdef DEBUG_FLUSH
01758 m_out.flush();
01759 #endif
01760 if (a_char == '\n') {
01761 mf_set_newline(true);
01762 m_out.flush();
01763 }
01764 }
01765
01766 void debugger::write(const char * a_char_ptr)
01767 {
01768 char const * ch_ptr;
01769
01770 if (m_depth > m_max_depth)
01771 return;
01772 if (!is_on())
01773 return;
01774 if (is_paused())
01775 return;
01776 if (!m_ok)
01777 return;
01778 if (!mf_check_output_stream())
01779 return;
01780 if (a_char_ptr == 0) {
01781 write("(null)");
01782 return;
01783 }
01784 for (ch_ptr = a_char_ptr; *ch_ptr != '\0'; ++ch_ptr)
01785 write(*ch_ptr);
01786 }
01787
01788 void debugger::write(const std::string& a_string)
01789 {
01790 std::string::const_iterator si;
01791 char ch;
01792
01793 if (m_depth > m_max_depth)
01794 return;
01795 if (!is_on())
01796 return;
01797 if (is_paused())
01798 return;
01799 if (!m_ok)
01800 return;
01801 if (!mf_check_output_stream())
01802 return;
01803
01804 for (si = a_string.begin(); si != a_string.end(); ++si) {
01805 ch = *si;
01806 write(ch);
01807 }
01808 }
01809
01810 void debugger::set_context(const debugger::context a_context)
01811 {
01812 context old_context = m_context;
01813
01814 if (!m_ok)
01815 return;
01816 if (!is_on())
01817 return;
01818 m_context = a_context;
01819 switch(old_context) {
01820 case context_begin:
01821 switch(a_context) {
01822 case context_begin:
01823 break;
01824 case context_end:
01825 break;
01826 case context_input:
01827 write("Input:\n");
01828 break;
01829 case context_output:
01830 write("Output:\n");
01831 break;
01832 case context_variable:
01833 break;
01834 case context_message:
01835 break;
01836 case context_errno:
01837 break;
01838 }
01839 break;
01840 case context_end:
01841 switch(a_context) {
01842 case context_begin:
01843 mf_write_blank_line();
01844 break;
01845 case context_end:
01846 break;
01847 case context_input:
01848 mf_write_blank_line();
01849 write("Input:\n");
01850 break;
01851 case context_output:
01852 mf_write_blank_line();
01853 write("Output:\n");
01854 break;
01855 case context_variable:
01856 mf_write_blank_line();
01857 break;
01858 case context_message:
01859 mf_write_blank_line();
01860 break;
01861 case context_errno:
01862 break;
01863 }
01864 break;
01865 case context_input:
01866 switch(a_context) {
01867 case context_begin:
01868 mf_write_blank_line();
01869 break;
01870 case context_end:
01871 break;
01872 case context_input:
01873 break;
01874 case context_output:
01875 mf_write_blank_line();
01876 write("Output:\n");
01877 break;
01878 case context_variable:
01879 mf_write_blank_line();
01880 break;
01881 case context_message:
01882 mf_write_blank_line();
01883 break;
01884 case context_errno:
01885 mf_write_blank_line();
01886 break;
01887 }
01888 break;
01889 case context_output:
01890 switch(a_context) {
01891 case context_begin:
01892 mf_write_blank_line();
01893 break;
01894 case context_end:
01895 break;
01896 case context_input:
01897 mf_write_blank_line();
01898 write("Input:\n");
01899 break;
01900 case context_output:
01901 write("Output:\n");
01902 break;
01903 case context_variable:
01904 mf_write_blank_line();
01905 break;
01906 case context_message:
01907 mf_write_blank_line();
01908 break;
01909 case context_errno:
01910 mf_write_blank_line();
01911 break;
01912 }
01913 break;
01914 case context_variable:
01915 switch(a_context) {
01916 case context_begin:
01917 mf_write_blank_line();
01918 break;
01919 case context_end:
01920 break;
01921 case context_input:
01922 mf_write_blank_line();
01923 write("Input:\n");
01924 break;
01925 case context_output:
01926 mf_write_blank_line();
01927 write("Output:\n");
01928 break;
01929 case context_variable:
01930 break;
01931 case context_message:
01932 mf_write_blank_line();
01933 break;
01934 case context_errno:
01935 mf_write_blank_line();
01936 break;
01937 }
01938 break;
01939 case context_message:
01940 switch(a_context) {
01941 case context_begin:
01942 mf_write_blank_line();
01943 break;
01944 case context_end:
01945 break;
01946 case context_input:
01947 mf_write_blank_line();
01948 write("Input:\n");
01949 break;
01950 case context_output:
01951 mf_write_blank_line();
01952 write("Output:\n");
01953 break;
01954 case context_variable:
01955 mf_write_blank_line();
01956 break;
01957 case context_message:
01958 break;
01959 case context_errno:
01960 mf_write_blank_line();
01961 break;
01962 }
01963 break;
01964 case context_errno:
01965
01966 switch(a_context) {
01967 case context_begin:
01968 mf_write_blank_line();
01969 break;
01970 case context_end:
01971 break;
01972 case context_input:
01973 mf_write_blank_line();
01974 write("Input:\n");
01975 break;
01976 case context_output:
01977 mf_write_blank_line();
01978 write("Output:\n");
01979 break;
01980 case context_variable:
01981 mf_write_blank_line();
01982 break;
01983 case context_message:
01984 mf_write_blank_line();
01985 break;
01986 case context_errno:
01987 break;
01988 }
01989 break;
01990 }
01991 }
01992
01993 void debugger::pause(void)
01994 {
01995 m_pause_level++;
01996 }
01997
01998 void debugger::unpause(void)
01999 {
02000 m_pause_level--;
02001 }
02002
02003 const bool debugger::is_paused(void) const
02004 {
02005 return(m_pause_level > 0);
02006 }
02007
02008 void debugger::turn(const char * name)
02009 {
02010 std::string str;
02011 vector<filter>::const_iterator oi;
02012
02013 str = name;
02014 for (oi = m_filter.begin(); oi != m_filter.end(); oi++) {
02015 if (str.find(oi->first) != std::string::npos) {
02016 turn(oi->second);
02017 return;
02018 }
02019 else if (oi->first == "*") {
02020 turn(oi->second);
02021 return;
02022 }
02023 }
02024 if (m_on.size() == 0)
02025 if (m_filter.size() == 0)
02026 turn(true);
02027 else
02028 turn(false);
02029 else
02030 turn(m_on[0]);
02031 }
02032
02033 void debugger::turn(const bool a_value)
02034 {
02035 m_on.push_front(a_value);
02036 }
02037
02038 void debugger::unturn(void)
02039 {
02040 if (m_on.size() > 0)
02041 m_on.pop_front();
02042 }
02043
02044 const bool debugger::is_on(void) const
02045 {
02046 if (m_filter.size() == 0)
02047 return(true);
02048 if (m_on.size() == 0)
02049 return(false);
02050 if (m_on[0] == true)
02051 return(true);
02052 return(false);
02053 }
02054
02055 const bool debugger::last_was_on(void) const
02056 {
02057 if (m_filter.size() == 0)
02058 return(true);
02059 if (m_on.size() < 2)
02060 return(false);
02061 if (m_on[1] == true)
02062 return(true);
02063 return(false);
02064 }
02065
02066 const bool debugger::show_addresses(void) const
02067 {
02068 return(m_show_addresses);
02069 }
02070
02071 const int debugger::mf_errno(void) const
02072 {
02073 return(errno);
02074 }
02075
02076 const char * debugger::mf_errno_str(const int a_errno) const
02077 {
02078 return(strerror(a_errno));
02079 }
02080
02081 void debugger::mf_print_error(const char * a_message) const
02082 {
02083 char const * ch_ptr;
02084 static bool newline = true;
02085
02086 std::cerr << "*** ERROR: ";
02087 if (mf_errno() != 0) {
02088 std::cerr << "[" << mf_errno() << "]: " << mf_errno_str(mf_errno());
02089 }
02090 else {
02091 std::cerr << "An unknown error has occured";
02092 }
02093 std::cerr << std::endl;
02094 if (a_message != 0) {
02095 for (ch_ptr = a_message; *ch_ptr != '\0'; ++ch_ptr) {
02096 if (newline) {
02097 std::cerr << " ";
02098 newline = false;
02099 }
02100 std::cerr << (*ch_ptr);
02101 if (*ch_ptr == '\n')
02102 newline = true;
02103 }
02104 }
02105 }
02106
02107 bool debugger::mf_check_output_stream(void)
02108 {
02109 if (!m_ok)
02110 return(false);
02111 if (!m_out.is_open()) {
02112 mf_print_error("Debug output stream is not open\n");
02113 m_ok = false;
02114 return(false);
02115 }
02116 if (!m_out) {
02117 mf_print_error("Debug output stream error\n");
02118 m_ok = false;
02119 return(false);
02120 }
02121
02122 return(true);
02123 }
02124
02125 void debugger::mf_write(const char * a_message)
02126 {
02127 char const * ch_ptr;
02128
02129 if (m_depth > m_max_depth)
02130 return;
02131 if (!is_on())
02132 return;
02133 if (is_paused())
02134 return;
02135 if (!mf_check_output_stream())
02136 return;
02137
02138 for (ch_ptr = a_message; *ch_ptr != 0; ++ch_ptr) {
02139 m_out << *ch_ptr;
02140 #ifdef DEBUG_FLUSH
02141 m_out.flush();
02142 #endif
02143 if (!mf_check_output_stream())
02144 return;
02145 }
02146 }
02147
02148 void debugger::mf_write_prefix(void)
02149 {
02150 size_type count;
02151
02152 if (!is_on())
02153 return;
02154 if (is_paused())
02155 return;
02156 if (!m_ok)
02157 return;
02158 for (count = 0; count < m_depth; ++count)
02159 mf_write("| ");
02160 }
02161
02162 void debugger::mf_write_blank_line(void)
02163 {
02164 mf_write_prefix();
02165 mf_write("\n");
02166 }
02167
02168 const std::string debugger::mf_function_header(
02169 const char * a_name,
02170 const char * a_file,
02171 const int a_line
02172 )
02173 {
02174 std::string l_str;
02175
02176 mf_clear_buffer();
02177 snprintf(m_buffer, m_buffer_size, "%d", a_line);
02178
02179 l_str = a_file;
02180 l_str += "[";
02181 l_str += m_buffer;
02182 l_str += "]: ";
02183 l_str += a_name;
02184
02185 return(l_str);
02186 }
02187
02188 void debugger::mf_push(
02189 const char * a_name,
02190 const char * a_file,
02191 const int a_line
02192 )
02193 {
02194 if (!m_ok)
02195 return;
02196
02197 set_context(context_begin);
02198 mf_write_prefix();
02199 mf_write(mf_function_header(a_name, a_file, a_line).c_str());
02200 mf_write("\n");
02201 mf_write_prefix();
02202 mf_write("{\n");
02203
02204 m_depth++;
02205
02206 if (mf_errno() != 0) {
02207 set_context(context_errno);
02208 mf_write_prefix();
02209 mf_clear_buffer();
02210 snprintf(m_buffer, m_buffer_size,
02211 "errno: [%d] - %s\n", mf_errno(), mf_errno_str(mf_errno()));
02212 mf_write(m_buffer);
02213 }
02214
02215 mf_set_newline(true);
02216 }
02217
02218 void debugger::mf_pop(void)
02219 {
02220 if (!m_ok)
02221 return;
02222
02223 if (m_depth == 0) {
02224
02225
02226
02227
02228
02229 return;
02230 }
02231
02232 if (mf_errno() != 0) {
02233 set_context(context_errno);
02234 mf_write_prefix();
02235 mf_clear_buffer();
02236 snprintf(m_buffer, m_buffer_size,
02237 "errno: [%d] - %s\n", mf_errno(), mf_errno_str(mf_errno()));
02238 mf_write(m_buffer);
02239 }
02240
02241 set_context(context_end);
02242
02243 --m_depth;
02244
02245 mf_write_prefix();
02246 mf_write("}\n");
02247 }
02248
02249 void debugger::mf_write_function_header(
02250 const char * a_name,
02251 const char * a_file,
02252 const int a_line
02253 )
02254 {
02255 if (!m_ok)
02256 return;
02257
02258 turn(true);
02259 set_context(context_message);
02260 mf_write_prefix();
02261 mf_write(mf_function_header(a_name, a_file, a_line).c_str());
02262 mf_write(";\n");
02263 unturn();
02264 }
02265
02266 void debugger::mf_set_newline(const bool a_bool)
02267 {
02268 m_newline = a_bool;
02269 }
02270
02271 void debugger::mf_check_newline(void)
02272 {
02273 if (!m_newline)
02274 return;
02275 mf_write_prefix();
02276 m_newline = false;
02277 }
02278
02279 const size_t debugger::m_buffer_size = 256;
02280
02281 void debugger::mf_clear_buffer(void)
02282 {
02283 size_t n;
02284
02285 for (n = 0; n < m_buffer_size; ++n)
02286 m_buffer[n] = 0;
02287 }
02288
02289
02290
02291 debugger debug_manager;
02292
02293
02294
02295 #endif