old.debug.cc

Go to the documentation of this file.
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  * For reasons unbeknownst to me, iostream must be included before fcntl.h, or
00012  * large-file support will break definitions for the C open() function.
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 /** What base to use in displaying numbers. */
00046 const debug_instance::size_type debug_instance::m_base = 10;
00047 
00048 /** The "alphabet" to use to display numbers */
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                         // This should never happen
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                 std::cerr 
02226                         << "*** ERROR: Attempt to pop from empty debugger stack"
02227                         << std::endl;
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

Generated on Mon Jul 12 12:02:45 2004 for rvm by doxygen 1.3.6