Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

more/diag/debug.h

Go to the documentation of this file.
00001 
00002 //  Copyright (C) 1999--2001  Petter Urkedal (petter.urkedal@matfys.lth.se)
00003 
00004 //  This file is free software; you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation; either version 2 of the License, or
00007 //  (at your option) any later version.
00008 
00009 //  This file is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program; if not, write to the Free Software
00016 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 //  As a special exception, you may use this file as part of a free
00019 //  software library without restriction.  Specifically, if other files
00020 //  instantiate templates or use macros or inline functions from this
00021 //  file, or you compile this file and link it with other files to
00022 //  produce an executable, this file does not by itself cause the
00023 //  resulting executable to be covered by the GNU General Public
00024 //  License.  This exception does not however invalidate any other
00025 //  reasons why the executable file might be covered by the GNU General
00026 //  Public License.
00027 
00028 //  $Id: debug.h,v 1.1 2002/05/30 18:01:37 petter_urkedal Exp $
00029 
00030 
00031 
00032 #ifndef MORE_DIAG_DEBUG_H
00033 #define MORE_DIAG_DEBUG_H
00034 
00035 #include <iostream>
00036 #include <iomanip>
00037 #include <string>
00038 #include <memory>
00039 #include <more/io/fwd.h>
00040 
00041 
00042 #define MORE_SHOW(x) \
00043     ((void)(std::clog << __FILE__ << ":" << __LINE__ << ": info: " \
00044                       << #x << " = " << x << std::endl))
00045 #define MORE_ECHO(x) \
00046     ((void)(std::clog << __FILE__ << ":" << __LINE__ << ": info: " \
00047                       << #x << std::endl, (x)))
00048 #define MORE_SHOW_SOMETIMES(x) \
00049     ((more::diag::show_sometimes_helper())? MORE_SHOW(x) : (void)0)
00050 #define MORE_HERE \
00051     (std::cerr << __FILE__ << ":" << __LINE__ << ": info: Here!" << std::endl)
00052 
00053 /** \def MORE_CHECK
00054  **
00055  ** Check that a logical expression is true. This is similar to assert,
00056  ** but instead of aborting, it keeps a count of the number of
00057  ** failures.  See check_exit_status. */
00058 #define MORE_CHECK(x) \
00059     ((x)? (void)0 : ::more::diag::bits::check_failed(__FILE__, __LINE__, #x))
00060 
00061 /** \def MORE_CHECK_EQ
00062  **
00063  ** Check that <tt>x == y</tt>.  If the check fails, the LHS and RHS
00064  ** are printed to <tt>std::cerr</tt>. */
00065 #define MORE_CHECK_EQ(x, y) \
00066     (((x) == (y))? (void)0 : \
00067      (::more::diag::bits::check_failed(__FILE__, __LINE__, #x " == " #y), \
00068       std::cerr << "    LHS = " << (x) << "\n    RHS = " << (y) << std::endl, \
00069       (void)0))
00070 
00071 #define MORE_CHECK_FAILED(msg) \
00072     more::diag::bits::check_failed(__FILE__, __LINE__, (msg))
00073 
00074 #ifdef MORE_CHECK_ALLOCATIONS
00075 #  define MORE_NEW(T, args...) \
00076     (::new(::more::diag::checkmem::alloc(sizeof(T), __FILE__, __LINE__)) \
00077         T(args))
00078 #  define MORE_DELETE(T, ptr) \
00079     do { \
00080         if (T* p = (ptr)) { \
00081             p->~T(); \
00082             ::more::diag::checkmem::free(p, __FILE__, __LINE__); \
00083         } \
00084     } while (0)
00085 #else
00086 #  define MORE_NEW(T, args...) new T(args)
00087 #  define MORE_DELETE(T, ptr) delete (ptr)
00088 #endif
00089 
00090 
00091 
00092 namespace more {
00093 namespace diag {
00094   ///\if bits
00095   namespace bits {
00096     void check_failed(char const*, int, char const*);
00097   }
00098   ///\endif
00099 
00100   /** If MORE_CHECK has failed at least once, reports the number of
00101       fails, and returns nonzero, otherwise return err. */
00102   int check_exit_status(int err = 0);
00103 
00104   /** report a fatal error and abort. */
00105   void fatal(char const*);
00106 
00107   std::ostream& cdbg(int);
00108   void set_debug_level(int);
00109   void parse_debug_level_from_cmdline(int& argc, char**& argv);
00110   void debug_init(io::cmdline&);
00111   bool show_sometimes_helper();
00112 
00113   /** Used to force earlier activation of the allocation checker.  If
00114       static destructors deallocate memory with MORE_FREE, you may get
00115       bogus reports of unallocated memory.  To fix this try to make a
00116       static instance of this class in the source file to be checked.
00117       There is no standard way to ensure that the checker is
00118       initialized before all other static initializers, so you may
00119       have to expreimet with placing it before or after in the same
00120       source file, or even name the variable starting with "AA" or
00121       "zz".  Wrap the declaration in #ifdef MORE_CHECK_ALLOCATIONS for
00122       zero overhead when not debugging. */
00123   struct checkmem {
00124       struct header {
00125           unsigned long magic0;
00126           unsigned long magic1;
00127           header* next;
00128           header* prev;
00129           unsigned long serial;
00130           const char* file;
00131           int line;
00132       };
00133 
00134       checkmem() { init(); }
00135 
00136       static void* alloc(std::size_t, char const* = 0, int = 0);
00137       static void free(void*, char const* = 0, int = 0);
00138       static void init();
00139       static void finalize();
00140 
00141     private:
00142       static bool is_init;
00143       static long alloc_count;
00144       static unsigned long serial;
00145       static header link;
00146       static unsigned long magic0;
00147       static unsigned long magic1;
00148   };
00149   struct checkmem_tag {};
00150 
00151 
00152   /** A slightly simplified auto_ptr which uses MORE_DELETE. */
00153   template <typename T>
00154     struct auto_ptr {
00155         auto_ptr(T* p = 0) : m_p(p) {}
00156         auto_ptr(auto_ptr& ap) : m_p(ap.release()) {}
00157         auto_ptr& operator=(auto_ptr& ap) { reset(ap.release()); return *this; }
00158         ~auto_ptr() { MORE_DELETE(T, m_p); }
00159         T* operator->() { return m_p; }
00160         T& operator*() { return *m_p; }
00161         T* get() { return m_p; }
00162         T* release() { T* p = m_p; m_p = 0; return p; }
00163         void reset(T* p = 0) { MORE_DELETE(T, m_p); m_p = p; }
00164       private:
00165         T* m_p;
00166     };
00167 }}
00168 
00169 
00170 #endif

Generated on Sat Sep 7 19:11:10 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.