00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "PrettyDebug.hh"
00027 #include "Message.hh"
00028 #include "NetworkMessage.hh"
00029
00030 #include <stdlib.h>
00031 #include <stdarg.h>
00032 #include <iostream>
00033 #include <cstring>
00034 #ifdef _WIN32
00035 #include <time.h>
00036 #include <sys/timeb.h>
00037 #else
00038 #include <sys/types.h>
00039 #include <sys/time.h>
00040 #include <unistd.h>
00041 #include <string>
00042 #include <libgen.h>
00043 #endif
00044
00045 using std::cout ;
00046 using std::cerr ;
00047 using std::endl ;
00048
00049 DebugOStream DebugOStream::nullOutputStream(cout);
00050 DebugOStream PrettyDebug::defaultOutputStream(cerr);
00051
00052
00053 DebugOStream* PrettyDebug::nullOutputStreamPtr = 0 ;
00054 DebugOStream& PrettyDebug::nullOutputStream = DebugOStream::nullOutputStream;
00055
00056 #ifdef _WIN32 //Mutex switch ON
00057 HANDLE PrettyDebug::g_hMutex= CreateMutex(NULL,FALSE,"HLA");
00058 #endif
00059
00060 std::string PrettyDebug::federateName_ = "" ;
00061
00062
00065 void
00066 PrettyDebug::Print(DebugOStream& theOutputStream,
00067 const char* theHeaderMessage, const char * Message)
00068 {
00069 char buffer[256] ;
00070
00071 #ifdef _WIN32
00072 if (WaitForSingleObject(g_hMutex,INFINITE) == WAIT_OBJECT_0)
00073 {
00074 struct _timeb timebuffer;_ftime(&timebuffer );
00075 sprintf(buffer,"HLALOG - %I64d.%03hd s - %s", timebuffer.time,timebuffer.millitm,federateName_.c_str());
00076
00077 if (Message != NULL)
00078 theOutputStream << buffer << " - " << theHeaderMessage << "> " << Message;
00079 else
00080 theOutputStream << buffer << " - " << theHeaderMessage << pdSEmptyMessage;
00081
00082 theOutputStream.flush();
00083 ReleaseMutex(g_hMutex);
00084 }
00085 #else
00086 struct timeval tv;
00087 gettimeofday( &tv, NULL );
00088 sprintf( buffer, "HLALOG - %ld.%06ld - %s",tv.tv_sec,tv.tv_usec,federateName_.c_str() ) ;
00089
00090 if (Message != NULL)
00091 theOutputStream << buffer << " - " << basename((char *)theHeaderMessage) << "> " << Message;
00092 else
00093 theOutputStream << buffer << " - " << basename((char *)theHeaderMessage) << pdSEmptyMessage;
00094 theOutputStream.flush();
00095 #endif
00096 }
00097
00098
00102 void
00103 PrettyDebug::ParseEnvString(const char *Name)
00104 {
00105 unsigned int i;
00106 char *Value = getenv(Name);
00107 char Key;
00108 char *Pos;
00109 char *DebugKeys = (char *) pdDebugKeysString ;
00110
00111 for (i = pdUnused; i < pdLast + 1; i++)
00112 Level_Map[i] = PrettyDebug::nullOutputStreamPtr;
00113
00114 if (Value != 0)
00115 {
00116 const char *pdInitMessage = " variable read, content = ";
00117 const char *pdTooLongInitMessage = "Env Var read(string too long).";
00118
00119 int length = strlen(LEnvVar) + strlen(pdInitMessage) + strlen(Value);
00120 if (length < pdMaxMessageSize)
00121 cout << LEnvVar << pdInitMessage << Value << endl;
00122 else
00123 cout << LEnvVar << pdTooLongInitMessage << endl;
00124
00125
00126
00127 for (i = 0; i < strlen(Value); i++)
00128 {
00129 Key = Value[i];
00130 Pos = strchr(DebugKeys, Key);
00131 if (Pos != 0)
00132 Level_Map[Pos - DebugKeys] = &(PrettyDebug::defaultOutputStream);
00133 }
00134 }
00135 return;
00136 }
00137
00138
00143 PrettyDebug::PrettyDebug(const char *Name, const char *Header)
00144 {
00145 if (NULL == Name)
00146 {
00147 PrettyDebug::Print(PrettyDebug::defaultOutputStream, "",
00148 "Error in pgCDebug constructor, no Name specified.\n");
00149 Name = "NoName";
00150 }
00151
00152 LEnvVar = strdup(Name);
00153 if (Header != 0)
00154 HeaderMessage = strdup(Header);
00155 else
00156 HeaderMessage = strdup("");
00157
00158
00159
00160 LMessage = 0;
00161
00162 if ((LEnvVar == 0) || (HeaderMessage == 0))
00163 {
00164 PrettyDebug::Print(PrettyDebug::defaultOutputStream, "",
00165 "Error in pgCDebug constructor memory allocation.\n");
00166 exit(EXIT_FAILURE);
00167 }
00168 ParseEnvString(Name);
00169 }
00170
00171
00173 PrettyDebug::~PrettyDebug()
00174 {
00175 free(LEnvVar);
00176 if (LMessage != 0) {
00177 free(LMessage);
00178 }
00179 if (HeaderMessage != 0) {
00180 free(HeaderMessage);
00181 }
00182 }
00183
00184
00186 bool
00187 PrettyDebug::Mode(pdDebugLevel Level)
00188 {
00189 return (Level_Map[Level] != PrettyDebug::nullOutputStreamPtr);
00190 }
00191
00192
00198 void
00199 PrettyDebug::enableDebugLevel(pdDebugLevel Level, DebugOStream& theOutputStream)
00200 {
00201 Level_Map[Level] = &(theOutputStream);
00202 return;
00203 }
00204
00205
00207 void
00208 PrettyDebug::disableDebugLevel(pdDebugLevel Level)
00209 {
00210 Level_Map[Level] = PrettyDebug::nullOutputStreamPtr;
00211 return;
00212 }
00213
00214
00215 #ifndef NDEBUG
00216
00224 void
00225 PrettyDebug::Out(pdDebugLevel Level, const char * Format, ...)
00226 {
00227 DebugOStream* theOutputStreamPtr = Level_Map[Level];
00228
00229
00230
00231
00232
00233 if (theOutputStreamPtr != PrettyDebug::nullOutputStreamPtr)
00234 {
00235 if (Format != 0)
00236 {
00237 if (LMessage == 0)
00238 {
00239
00240
00241
00242
00243
00244
00245 LMessage = (char *) malloc((pdMaxMessageSize+2) * sizeof(char));
00246
00247 if (LMessage == 0)
00248 {
00249 PrettyDebug::Print(PrettyDebug::defaultOutputStream,
00250 HeaderMessage,
00251 "Error in pgCDebug Out method while "
00252 "allocating initial memory for messages\n");
00253 exit(EXIT_FAILURE);
00254 }
00255
00256
00257
00258
00259 }
00260 va_list argptr;
00261 va_start(argptr, Format);
00262
00263
00264 vsprintf(LMessage, Format, argptr);
00265 va_end(argptr);
00266 }
00267 else
00268 strcpy(LMessage, "Pretty Debug received an empty Message.");
00269
00270 strcat(LMessage, "\n");
00271 PrettyDebug::Print(*theOutputStreamPtr, HeaderMessage, LMessage);
00272 }
00273 return;
00274 }
00275
00276 #endif // NDEBUG
00277
00278