// Copyright (C) 1996 Keith Whitwell. // This file may only be copied under the terms of the GNU Library General // Public License - see the file COPYING in the lib3d distribution. #include #include #include #include #include #include #include #include int Debuggable::initLevel = 0; int Debuggable::nrTok = 0; int Debuggable::activeTok = 0; char **Debuggable::tok = 0; char Debuggable::configPath[256]; char Debuggable::errBuf[bufferSize]; char Debuggable::debugOnBuf[bufferSize]; char Debuggable::debugOffBuf[10]; ostrstream Debuggable::errStr(errBuf, sizeof(errBuf)); ostrstream Debuggable::debugOn(debugOnBuf, sizeof(debugOnBuf)); ostrstream Debuggable::debugOff(debugOffBuf, sizeof(debugOffBuf)); bool Debuggable::noDebug = (getenv("NODEBUG") != 0); Debuggable::Debuggable() : good(true), init(-1), _debug(&debugOff) { } void Debuggable::initDebug() { _debug = &debugOff; if (!*getName()) return; if (noDebug) return; if (initLevel == 0) { setDebugConfigPath("."); } const char *name = getName(); for (int i = 0; i < activeTok && _debug == &debugOff ; i++) { if (strstr(name, tok[i]) != 0) { _debug = &debugOn; } } init = initLevel; } void Debuggable::setDebugConfigPath( const char *path ) { ostrstream p( configPath, sizeof(configPath) ); p << path << "/debug.conf" << ends; if (!p.good()) { err() << "Config path too long" << endlog; } reconfigure(); // Increments initLevel. } void Debuggable::reconfigure() { char s[256]; int lines = 0; ifstream in( configPath ); static int notified = false; if (!in) { if (!notified) { ::debug() << "No debug.conf file present - debugging disabled" << endlog; notified = true; } return; } while (in.getline(s, sizeof(s))) { lines++; } while( nrTok ) { free( tok[--nrTok] ); } delete [] tok; tok = new char *[lines]; // in.seekg(0); ifstream in2( configPath ); for(activeTok = 0; in2.getline(s, sizeof(s)) && activeTok < lines ;) { tok[activeTok] = new char[strlen(s)+1]; strcpy(tok[activeTok++], s); } initLevel++; } ostream & endlog( ostream &out ) { out << endl; if (*Debuggable::errBuf) { Debuggable::errStr << ends; cout << Debuggable::errBuf << flush; Debuggable::errBuf[0] = 0; Debuggable::errStr.seekp(0); } if (*Debuggable::debugOnBuf) { Debuggable::debugOn << ends; cout << Debuggable::debugOnBuf << flush; Debuggable::debugOnBuf[0] = 0; Debuggable::debugOn.seekp(0); } return out; } ostream & Debuggable::print( ostream &out ) const { return out << getName() << "(" << (const void *)this << ")" << " status: " << (good ? "good" : "bad"); } #ifdef MAIN class Test : public Debuggable { public: Test() {} ~Test() {} void test() { debug() << "hello, world" << endlog; } protected: const char *getName() const { return "Test"; } }; main() { Test test; test.test(); } #endif