Tools/NetTest - Add TCP retransmit test
[tpg/acess2.git] / Tools / nativelib / logging.c
1 /*
2  * Acess2 libnative (Kernel Simulation Library)
3  * - By John Hodge (thePowersGang)
4  *
5  * logging.c
6  * - Logging functions
7  */
8 #include <stdio.h>
9 #include <stdarg.h>
10 #include <stdlib.h>
11 #include <stdint.h>
12 #include <acess_logging.h>
13 #include <ctype.h>
14 #include <inttypes.h>
15 #include <shortlock.h>
16
17 extern int      Threads_GetTID();
18
19 #define LOGHDR(col,type)        fprintf(stderr, "\e["col"m[%-8.8s]"type"%2i ", Ident, Threads_GetTID())
20 #define LOGTAIL()       fprintf(stderr, "\e[0m\n")
21
22 #define LOG_LOCK_ACQUIRE()      do{ \
23         if(!gbThreadInLog)      SHORTLOCK(&glDebugLock); \
24         gbThreadInLog ++; \
25 }while(0)
26 #define LOG_LOCK_RELEASE()      do {\
27         gbThreadInLog --; \
28         if(!gbThreadInLog)      SHORTREL(&glDebugLock); \
29 } while(0)
30
31 #define PUTERR(col,type)        {\
32         LOG_LOCK_ACQUIRE(); \
33         LOGHDR(col,type);\
34         va_list args; va_start(args, Message);\
35         vfprintf(stderr, Message, args);\
36         va_end(args);\
37         LOGTAIL();\
38         LOG_LOCK_RELEASE(); \
39 }
40
41 // === GLOBALS ===
42 int __thread    gbThreadInLog;
43 tShortSpinlock  glDebugLock;
44
45 // === CODE ===
46 void Log_KernelPanic(const char *Ident, const char *Message, ...) {
47         PUTERR("35", "k")
48         exit(-1);
49 }
50 void Log_Panic(const char *Ident, const char *Message, ...)
51         PUTERR("34", "p")
52 void Log_Error(const char *Ident, const char *Message, ...)
53         PUTERR("31", "e")
54 void Log_Warning(const char *Ident, const char *Message, ...)
55         PUTERR("33", "w")
56 void Log_Notice(const char *Ident, const char *Message, ...)
57         PUTERR("32", "n")
58 void Log_Log(const char *Ident, const char *Message, ...)
59         PUTERR("37", "l")
60 void Log_Debug(const char *Ident, const char *Message, ...)
61         PUTERR("37", "d")
62
63 void Panic(const char *Message, ...) {
64         const char *Ident = "";
65         PUTERR("35", "k")
66         exit(-1);
67 }
68 void Warning(const char *Message, ...) {
69         const char *Ident = "";
70         PUTERR("33", "W")
71 }
72 void Log(const char *Message, ...) {
73         const char *Ident = "";
74         PUTERR("37", "L")
75 }
76 void Debug(const char *Message, ...) {
77         const char *Ident = "";
78         PUTERR("38", "D")
79 }
80
81 char _prn(char byte)
82 {
83         return (' ' <= byte && byte <= 'z') ? byte : '.';
84 }
85 void Debug_HexDump(const char *Prefix, const void *Data, size_t Length)
86 {
87         const uint8_t *data = Data;
88         size_t  ofs;
89         LOG_LOCK_ACQUIRE();
90         fprintf(stderr, "[HexDump ]d %s: %i bytes\n", Prefix, (int)Length);
91         for( ofs = 0; ofs + 16 <= Length; ofs += 16 )
92         {
93                 const uint8_t   *d = data + ofs;
94                 fprintf(stderr, "[HexDump ]d %s:", Prefix);
95                 fprintf(stderr, "  %02x %02x %02x %02x %02x %02x %02x %02x",
96                         d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7]);
97                 fprintf(stderr, "  %02x %02x %02x %02x %02x %02x %02x %02x",
98                         d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
99                 fprintf(stderr, " |%c%c%c%c""%c%c%c%c %c%c%c%c""%c%c%c%c",
100                         _prn(d[ 0]), _prn(d[ 1]), _prn(d[ 2]), _prn(d[ 3]),
101                         _prn(d[ 4]), _prn(d[ 5]), _prn(d[ 6]), _prn(d[ 7]),
102                         _prn(d[ 8]), _prn(d[ 9]), _prn(d[10]), _prn(d[11]),
103                         _prn(d[12]), _prn(d[13]), _prn(d[14]), _prn(d[15])
104                         );
105                 fprintf(stderr, "\n");
106         }
107         
108         if( ofs < Length )
109         {
110                 const uint8_t   *d = data + ofs;
111                 fprintf(stderr, "[HexDump ]d %s: ", Prefix);
112                 for( int i = 0; i < Length - ofs; i ++ )
113                 {
114                         if( i == 8 )    fprintf(stderr, " ");
115                         fprintf(stderr, " %02x", d[i]);
116                 }
117                 for( int i = Length - ofs; i < 16; i ++ )
118                 {
119                         if( i == 8 )    fprintf(stderr, " ");
120                         fprintf(stderr, "   ");
121                 }
122                 fprintf(stderr, " |");
123                 for( int i = 0; i < Length - ofs; i ++ )
124                 {
125                         if( i == 8 )    fprintf(stderr, " ");
126                         fprintf(stderr, "%c", _prn(d[i]));
127                 }
128                 
129                 fprintf(stderr, "\n");
130         }
131         LOG_LOCK_RELEASE();
132 }
133
134  int    giDebug_TraceLevel = 0;
135
136 void Debug_TraceEnter(const char *Function, const char *Format, ...)
137 {
138         LOG_LOCK_ACQUIRE();
139         //const char *Ident = "Trace";
140         //LOGHDR("37","T");
141         for( int i = 0; i < giDebug_TraceLevel; i ++ )
142                 fprintf(stderr, " ");
143         fprintf(stderr, "%s: (", Function);
144
145         va_list args;
146         va_start(args, Format);
147         
148         int hasBeenPrev = 0;
149         while(*Format)
150         {
151                 while( *Format && isblank(*Format) )
152                         Format ++;
153                 if( !*Format )  break;
154                 
155                 char type = *Format++;
156                 const char *start = Format;
157                 while( *Format && !isblank(*Format) )
158                         Format ++;
159                 
160                 if(hasBeenPrev)
161                         fprintf(stderr, ",");
162                 hasBeenPrev = 1;
163                 
164                 fprintf(stderr, "%.*s=", (int)(Format-start), start);
165                 switch(type)
166                 {
167                 case 'p':
168                         fprintf(stderr, "%p", va_arg(args,const void *));
169                         break;
170                 case 's':
171                         fprintf(stderr, "\"%s\"", va_arg(args,const char *));
172                         break;
173                 case 'i':
174                         fprintf(stderr, "%i", va_arg(args,int));
175                         break;
176                 case 'x':
177                         fprintf(stderr, "0x%x", va_arg(args,unsigned int));
178                         break;
179                 case 'X':
180                         fprintf(stderr, "0x%"PRIx64, va_arg(args,uint64_t));
181                         break;
182                 default:
183                         va_arg(args,uintptr_t);
184                         fprintf(stderr, "?");
185                         break;
186                 }
187         }
188
189         va_end(args);
190
191         fprintf(stderr, ")");
192         LOGTAIL();
193         giDebug_TraceLevel ++;
194         LOG_LOCK_RELEASE();
195 }
196
197 void Debug_TraceLog(const char *Function, const char *Format, ...)
198 {
199         LOG_LOCK_ACQUIRE();
200         //const char *Ident = "Trace";
201         //LOGHDR("37","T");
202         
203         for( int i = 0; i < giDebug_TraceLevel; i ++ )
204                 fprintf(stderr, " ");
205         fprintf(stderr, "%s: ", Function);
206         
207         va_list args;
208         va_start(args, Format);
209
210         vfprintf(stderr, Format, args);
211         
212         va_end(args);
213         LOGTAIL();
214         LOG_LOCK_RELEASE();
215 }
216
217 void Debug_TraceLeave(const char *Function, char Type, ...)
218 {
219         if( giDebug_TraceLevel == 0 ) {
220                 Log_Error("Debug", "Function %s called LEAVE without ENTER", Function);
221         }
222         
223         LOG_LOCK_ACQUIRE();
224         //const char *Ident = "Trace";
225         //LOGHDR("37","T");
226         
227         va_list args;
228         va_start(args, Type);
229
230         if( giDebug_TraceLevel > 0 )
231         {       
232                 giDebug_TraceLevel --;
233                 for( int i = 0; i < giDebug_TraceLevel; i ++ )
234                         fprintf(stderr, " ");
235         }
236         fprintf(stderr, "%s: RETURN", Function);
237         switch(Type)
238         {
239         case '-':
240                 break;
241         case 'i':
242                 fprintf(stderr, " %i", va_arg(args, int));
243                 break;
244         case 'x':
245                 fprintf(stderr, " 0x%x", va_arg(args, unsigned int));
246                 break;
247         case 'X':
248                 fprintf(stderr, " 0x%"PRIx64, va_arg(args,uint64_t));
249                 break;
250         case 's':
251                 fprintf(stderr, " \"%s\"", va_arg(args, const char *));
252                 break;
253         case 'p':
254                 fprintf(stderr, " %p", va_arg(args, const void *));
255                 break;
256         case 'n':
257                 fprintf(stderr, " NULL");
258                 break;
259         default:
260                 fprintf(stderr, " ?");
261                 break;
262         }
263         
264         va_end(args);
265         LOGTAIL();
266         LOG_LOCK_RELEASE();
267 }
268

UCC git Repository :: git.ucc.asn.au