/** * Copyright Mikael Högdahl - triyana@users.sourceforge.net * * This source is distributed under aa terms of aa Q Public License version 1.0, * created by Trolltech (www.trolltech.com). */ #include "MHDebug.h" #include "MHDate.h" #include "MHVector.h" #include "MHString.h" #include "MHUtil.h" int MHDebug::aaLevel = 0; bool MHDebug::aaTrace = false; bool MHDebug::aaLogStuff = false; bool MHDebug::aaFlush = false; FILE* MHDebug::aaFile = 0; MHVector* MHDebug::aaLog = 0; MHVector* MHDebug::aaWatches = 0; char MHDebug::aaBuffer [BUFFER_SIZE]; char MHDebug::aaBuffer2 [BUFFER_SIZE]; /** * Start tracing * @param const char* - Name of method * @param bool - true to time method, default false */ MHDebug::MHDebug (const char* pName, bool bTime) { int f; aaLevel++; aName = new MHString (pName); aTime = bTime; aWatch = false; aTab[0] = '\0'; aDate = new MHDate (); ASS (aaLog) ASS (aaWatches) for (f = 0; f < aaWatches->Size(); f++) { MHString* s = (MHString*)(*aaWatches)[f]; if (*s == *aName) aWatch = true; } for (f = 1; f < aaLevel && f < 20; f++) strcat (aTab, "\t"); if (aWatch == true && aaTrace == true) { sprintf (aaBuffer, "%s=> %s", aTab, pName); MHDebug::Print (aaBuffer); } aSecs = MHUtil::Time(); } /** * Stop tracing */ MHDebug::~MHDebug () { if (aWatch == true && aaTrace == true) { double diff = MHUtil::Time() - aSecs; if (diff > 1) sprintf (aaBuffer, "(%.2f sec)", diff); else if (diff > 0.01) sprintf (aaBuffer, "(%.4f sec)", diff); else sprintf (aaBuffer, "(%.6f sec)", diff); sprintf (aaBuffer2, "%s<= %s %s", aTab, aName->Get(), (aTime) ? aaBuffer : ""); MHDebug::Print (aaBuffer2); } aaLevel--; delete aName; delete aDate; } /** * Log debug message * @param char* - First string * @param ... - Additional data */ void MHDebug::Log (const char *Message, ...) { ASS (aaLog) ASS (aaWatches) if (aWatch == true && aaLogStuff == true) { va_list args; va_start (args, Message); vsnprintf (aaBuffer, BUFFER_SIZE, Message, args); va_end (args); sprintf (aaBuffer2, "\t%s%s", aTab, aaBuffer); MHDebug::Print (aaBuffer2); } } /** * Set options * @param const char* - options string */ void MHDebug::Options (const char* pString) { ASS (aaLog) ASS (aaWatches) MHVector ve, ve2; MHString s(pString); MHString* p; MHString* o; MHString* a; s.Split (',', &ve); for (int f = 0; f < ve.Size(); f++) { p = (MHString*) ve[f]; p->Split ('=', &ve2); if (ve2.Size() == 2) { o = (MHString*) ve2[0]; a = (MHString*) ve2[1]; if (*o == "T" && *a == "1") aaTrace = true; else if (*o == "L" && *a == "1") aaLogStuff = true; else if (*o == "F" && *a == "1") aaFlush = true; else if (*o == "O" && a->Size() > 0) aaFile = fopen (a->Get(), "wb"); } ve2.Erase(); } ve.Erase(); } /** * Print string to: * Screen or * File or * Vector (print result with PrintLog methods) * @param const char* - String to print */ void MHDebug::Print (const char* buffer) { ASS (aaLog) ASS (aaWatches) if (aaFile) { fwrite (buffer, sizeof(char), strlen (buffer), aaFile); fwrite ("\n", sizeof(char), 1, aaFile); } else if (aaFlush == false) aaLog->Push (new MHString(buffer)); else printf ("%s\n", buffer); } /** * Print debug results to screen */ void MHDebug::PrintLog () { MHString* p; for (int f = 0; f < aaLog->Size(); f++) { p = (MHString*) (*aaLog)[f]; printf ("%s\n", p->Get()); } } /** * Start debug session */ void MHDebug::Start () { aaWatches = new MHVector (); aaLog = new MHVector (); } /** * Start debug session */ void MHDebug::Stop () { ASS (aaLog) ASS (aaWatches) aaWatches->Erase (); aaLog->Erase(); delete aaWatches; delete aaLog; if (aaFile) fclose (aaFile); aaFile = 0; aaWatches = 0; aaLog = 0; } /** * Set what methods to watch * @param const char* - Methods name, seperated with a , use "" to watch all */ void MHDebug::Watch (const char* pString) { ASS (aaLog) ASS (aaWatches) MHVector ve; MHString s(pString); aaWatches->Erase(); s.Split (',', &ve); for (int f = 0; f < ve.Size(); f++) aaWatches->Push (new MHString(*(MHString*)ve[f])); ve.Erase(); }