w_debug.cpp

00001 /*<std-header orig-src='shore'>
00002 
00003  $Id: w_debug.cpp,v 1.3 2010/06/18 21:22:48 nhall Exp $
00004 
00005 SHORE -- Scalable Heterogeneous Object REpository
00006 
00007 Copyright (c) 1994-99 Computer Sciences Department, University of
00008                       Wisconsin -- Madison
00009 All Rights Reserved.
00010 
00011 Permission to use, copy, modify and distribute this software and its
00012 documentation is hereby granted, provided that both the copyright
00013 notice and this permission notice appear in all copies of the
00014 software, derivative works or modified versions, and any portions
00015 thereof, and that both notices appear in supporting documentation.
00016 
00017 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
00018 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
00019 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
00020 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00021 
00022 This software was developed with support by the Advanced Research
00023 Project Agency, ARPA order number 018 (formerly 8230), monitored by
00024 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
00025 Further funding for this work was provided by DARPA through
00026 Rome Research Laboratory Contract No. F30602-97-2-0247.
00027 
00028 */
00029 
00030 #include "w_defines.h"
00031 
00032 /*  -- do not edit anything above this line --   </std-header>*/
00033 
00034 #ifdef __GNUG__
00035 #pragma implementation
00036 #endif 
00037 #include <w_debug.h>
00038 
00039 
00040 #ifdef __ERRLOG_C__
00041 
00042 // gcc implementation in errlog.cpp since it is in #included there
00043 
00044 /* compile this stuff even if -UDEBUG because
00045  * other layers might be using -DDEBUG
00046  * and we want to be able to link, in any case
00047  */
00048 
00049 #include <w_stream.h>
00050 #include <iostream>
00051 #include <cstring>
00052 #include <cstdlib>
00053 #include "w_debug.h"
00054 
00055 #ifdef W_TRACE
00056 w_debug _w_debug("debug", getenv("DEBUG_FILE"));
00057 #endif
00058 
00059 
00060 #ifdef USE_REGEX
00061 bool        _w_debug::re_ready = false;
00062 regex_t     _w_debug::re_posix_re;
00063 char*       _w_debug::re_error_str = "Bad regular expression";
00064 #endif /* USE_REGEX */
00065 
00066 // I'm ambivalent about making this thread-safe.
00067 // To do so would require moving this and all related tests into
00068 // sthread/.
00069 // The disadvantage is that it would that much more change the
00070 // timing of things.
00071 // The errlog and such is most useful for debugging single-threaded
00072 // tests anyway, and still somewhat useful for mt stuff despite this
00073 // being not-safe; it would clearly change the timing for mt situations
00074 // we're trying to debug; I think it's probably more useful to
00075 // decipher mixed-up debugging output for those cases.
00076 //
00077 
00078 w_debug::w_debug(const char *n, const char *f) : 
00079     ErrLog(n, log_to_unix_file, f?f:"-")
00080 {
00081 #ifdef USE_REGEX
00082     //re_ready = false;
00083     //re_error_str = "Bad regular expression";
00084     re_syntax_options = RE_NO_BK_VBAR;
00085 #endif /* USE_REGEX */
00086 
00087     mask = 0;
00088     const char *temp_flags = getenv("DEBUG_FLAGS");
00089     // malloc the flags so it can be freed
00090     if(!temp_flags) {
00091         temp_flags = "";
00092         mask = _none;
00093     }
00094 
00095     // make a copy of the flags so we can delete it later
00096     _flags = new char[strlen(temp_flags)+1];
00097     strcpy(_flags, temp_flags);
00098     assert(_flags != NULL);
00099 
00100     if(!strcmp(_flags,"all")) {
00101     mask |= _all;
00102 #ifdef USE_REGEX
00103     } else if(!none()) {
00104     char *s;
00105     if((s=re_comp_debug(_flags)) != 0) {
00106         if(strstr(s, "No previous regular expression")) {
00107         // this is ok
00108         } else {
00109         cerr << "Error in regex, flags not set: " <<  s << endl;
00110         }
00111         mask = _none;
00112     }
00113 #endif /* USE_REGEX */
00114     }
00115 
00116     assert( !( none() && all() ) );
00117 }
00118 
00119 w_debug::~w_debug()
00120 {
00121     if(_flags) delete [] _flags;
00122     _flags = NULL;
00123 
00124 }
00125 
00126 void
00127 w_debug::setflags(const char *newflags)
00128 {
00129     if(!newflags) return;
00130 #ifdef USE_REGEX
00131     {
00132         char *s;
00133         if((s=re_comp_debug(newflags)) != 0) {
00134             cerr << "Error in regex, flags not set: " <<  s << endl;
00135             mask = _none;
00136             return;
00137         }
00138     }
00139 #endif /* USE_REGEX */
00140 
00141     mask = 0;
00142     if(_flags) delete []  _flags;
00143     _flags = new char[strlen(newflags)+1];
00144     strcpy(_flags, newflags);
00145     if(strlen(_flags)==0) {
00146         mask |= _none;
00147     } else if(!strcmp(_flags,"all")) {
00148         mask |= _all;
00149     }
00150     assert( !( none() && all() ) );
00151 }
00152 
00153 #ifdef USE_REGEX
00154 int 
00155 w_debug::re_exec_debug(const char* string)
00156 {
00157     if (!re_ready)  {
00158         cerr << __LINE__ 
00159         << " " << __FILE__ 
00160         << ": No compiled string." <<endl;
00161         return 0;
00162     }
00163     int match = (re_exec_posix(string)==1);
00164     return  match;
00165 }
00166 
00167 char* 
00168 w_debug::re_comp_debug(const char* pattern)
00169 {
00170     if (re_ready)
00171         regfree(&re_posix_re);
00172     char *res;
00173 
00174     res = re_comp_posix(pattern);
00175     if(res) {
00176         cerr << __LINE__ 
00177         << " " << __FILE__ 
00178         << " Error in re_comp_debug: " << res << endl;
00179     }
00180     re_ready = true;
00181     return NULL;
00182 }
00183 #endif /* USE_REGEX */
00184 
00185 
00186 int
00187 w_debug::flag_on(
00188     const char *fn,
00189     const char *file
00190 )
00191 {
00192     int res = 0;
00193     assert( !( none() && all() ) );
00194     if(_flags==NULL) {
00195     res = 0; //  another constructor called this
00196             // before this's constructor got called. 
00197     } else if(none())     {
00198     res = 0;
00199     } else if(all())     {
00200     res = 1;
00201 #ifdef USE_REGEX
00202     } else  if(file && re_exec_debug(file)) {
00203     res = 1;
00204     } else if(fn && re_exec_debug(fn)) {
00205     res = 1;
00206 #endif /* USE_REGEX */
00207     } else
00208     // if the regular expression didn't match,
00209     // try searching the strings
00210     if(file && strstr(_flags,file)) {
00211     res = 1;
00212     } else if(fn && strstr(_flags,fn)) {
00213     res = 1;
00214     }
00215     return res;
00216 }
00217 
00218 /* This function prints a hex dump of (len) bytes at address (p) */
00219 void
00220 w_debug::memdump(void *p, int len)
00221 {
00222     register int i;
00223     char *c = (char *)p;
00224     
00225     clog << "x";
00226     for(i=0; i< len; i++) {
00227         W_FORM2(clog,("%2.2x", (*(c+i))&0xff));
00228         if(i%32 == 31) {
00229             clog << endl << "x";
00230         } else if(i%4 == 3) {
00231             clog <<  " x";
00232         }
00233     }
00234     clog << "--done" << endl;
00235 }
00236 #endif /* __ERRLOG_C__ */
00237 

Generated on Wed Jul 7 17:22:32 2010 for Shore Storage Manager by  doxygen 1.4.7