00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <stdarg.h>
00023 #include <string.h>
00024 #include <time.h>
00025
00026 #if defined(_WIN32)
00027 # include "pthread_w32.h"
00028 # define vsnprintf _vsnprintf
00029 #else
00030 # include <pthread.h>
00031 # include <sys/time.h>
00032 #endif
00033
00034 #include "trace.h"
00035
00036
00041 static void traceData(traceContextData * pContext,
00042 char symbol,
00043 char * fmt,
00044 va_list args);
00045
00049 static pthread_once_t trace_init = PTHREAD_ONCE_INIT;
00050
00055 #define TRACE_INITIALISE (void) pthread_once(&trace_init, traceInitialise);
00056
00060 static FILE * g_file = NULL;
00061
00062
00063
00064
00065
00066 unsigned char g_bSev0Enabled = 0;
00067 unsigned char g_bSev1Enabled = 0;
00068 unsigned char g_bSev2Enabled = 1;
00069 unsigned char g_bSev3Enabled = 1;
00070 unsigned char g_bSev4Enabled = 1;
00071 unsigned char g_bSev5Enabled = 1;
00072
00073
00074
00075
00076
00077 static pthread_key_t g_keyStackDepth;
00078
00079
00080
00081
00082
00083
00084
00085
00086 void traceInitialise(void)
00087 {
00088
00089 (void) pthread_key_create(&g_keyStackDepth, NULL);
00090
00091
00092 g_file = stdout;
00093
00094 }
00095
00096 #define TRACE_BUFLEN 1024
00097
00098 #define FIFTY_SPACES " "
00099
00100 void traceData(traceContextData * pContext, char symbol, char * fmt, va_list args)
00101 {
00102 char message[TRACE_BUFLEN];
00103 int * pStackDepth = NULL;
00104 int nStackDepth = 0;
00105 int nIndent = 0;
00106 size_t nOffset = 0;
00107 size_t nBytesAvail = TRACE_BUFLEN;
00108
00109
00110 memset(message, (int) ' ', TRACE_BUFLEN);
00111
00112
00113 pStackDepth = (int *) pthread_getspecific(g_keyStackDepth);
00114 if (pStackDepth == NULL) {
00115 pStackDepth = (int *) malloc(sizeof(int));
00116 *pStackDepth = 0;
00117 pthread_setspecific(g_keyStackDepth, (void *) pStackDepth);
00118 }
00119
00120
00121 {
00122 struct timeval now;
00123 struct tm * nowTM;
00124
00125
00126 gettimeofday(&now, NULL);
00127
00128 nowTM = localtime(&(now.tv_sec));
00129
00130
00131 nOffset += strftime(message + nOffset, nBytesAvail, "%d/%m/%y %H:%M:%S ", nowTM);
00132 }
00133
00134
00135 {
00136 pthread_t this_thread;
00137
00138 this_thread = pthread_self();
00139
00140 sprintf(message + nOffset, "%8lX ", this_thread);
00141
00142
00143 nOffset += 9;
00144 nBytesAvail -= 9;
00145 }
00146
00147
00148 {
00149 sprintf(message + nOffset, "%c ", symbol);
00150 nOffset += 2;
00151 nBytesAvail -= 2;
00152 }
00153
00154
00155 {
00156
00157 message[nOffset] = ' ';
00158
00159
00160 nStackDepth = *pStackDepth;
00161
00162
00163 if (symbol == '<') { nStackDepth--; }
00164
00165
00166 nIndent = g_bSev1Enabled ? nStackDepth * 2 : 0;
00167
00168
00169 nOffset += nIndent;
00170 nBytesAvail -= nIndent;
00171
00172
00173 vsnprintf(message + nOffset, nBytesAvail, fmt, args);
00174
00175
00176 if (symbol == '>') { nStackDepth++; }
00177
00178
00179 *pStackDepth = nStackDepth;
00180 }
00181
00182
00183 fprintf(g_file, "%s\n", message);
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193 void traceEntry(traceContextData * pContext)
00194 {
00195 TRACE_INITIALISE;
00196
00197 if (g_bSev1Enabled) {
00198 traceData(pContext, '>', &(pContext->pszFunction[2]), NULL);
00199 }
00200 }
00201
00202
00203 void traceExit(traceContextData * pContext)
00204 {
00205 TRACE_INITIALISE;
00206
00207 if (g_bSev1Enabled) {
00208 traceData(pContext, '<', &(pContext->pszFunction[2]), NULL);
00209 }
00210 }
00211
00212 void traceDebug(traceContextData * pContext, char * fmt, ...)
00213 {
00214 va_list args;
00215
00216 TRACE_INITIALISE;
00217
00218 if (g_bSev1Enabled) {
00219 va_start(args, fmt);
00220 traceData(pContext, 'D', fmt, args);
00221 va_end(args);
00222 }
00223 }
00224
00225 void traceInfo(traceContextData * pContext, char * fmt, ...)
00226 {
00227 va_list args;
00228
00229 TRACE_INITIALISE;
00230
00231 if (g_bSev3Enabled) {
00232 va_start(args, fmt);
00233 traceData(pContext, 'I', fmt, args);
00234 va_end(args);
00235 }
00236 }
00237
00238 void traceWarning(traceContextData * pContext, char * fmt, ...)
00239 {
00240 va_list args;
00241
00242 TRACE_INITIALISE;
00243
00244 if (g_bSev4Enabled) {
00245 va_start(args, fmt);
00246 traceData(pContext, 'W', fmt, args);
00247 va_end(args);
00248 }
00249 }
00250
00251 void traceError(traceContextData * pContext, char * fmt, ...)
00252 {
00253 va_list args;
00254
00255 TRACE_INITIALISE;
00256
00257 if (g_bSev5Enabled) {
00258 va_start(args, fmt);
00259 traceData(pContext, 'E', fmt, args);
00260 va_end(args);
00261 }
00262 }
00263