source: libcf/trunk/src/cf_debug.c@ 18

Last change on this file since 18 was 18, checked in by cheese, 11 years ago

#1 fix some bug

File size: 6.1 KB
Line 
1/**
2 * cf_debug.c
3 */
4#include "cf_debug.h"
5#include "cf_local.h"
6
7#include <stdlib.h>
8#include <ctype.h>
9#include <stdarg.h>
10#include <string.h>
11
12#ifdef _WIN32
13# include <io.h>
14#else
15# include <unistd.h>
16#endif
17
18#define IS_READABLE_CHAR(__c) (' ' <= __c && __c <= '~')
19
20#define CHECK_INVALID_CTX(__ctx) \
21 if (__ctx == NULL) \
22 return CF_ERROR_DEBUG_INVALID_CTX
23
24#define GET_CTX_OSTREAM(__ctx) \
25 ((((CF_DEBUG_CTX *)__ctx)->fp == NULL) \
26 ? stderr \
27 : ((CF_DEBUG_CTX *)__ctx)->fp)
28
29typedef struct __cf_debug_callstack__
30{
31 char file[NAME_LENGTH + 1];
32 char func[NAME_LENGTH + 1];
33 int line;
34
35 struct __cf_debug_callstack__ * caller;
36} S_CF_DEBUG_CALLSTACK, CF_DEBUG_CALLSTACK;
37
38/* implementation of CF_Debug_Ctx */
39typedef struct __cf_debug_ctx__
40{
41 char file[NAME_LENGTH + 1];
42 char func[NAME_LENGTH + 1];
43 int line;
44
45 FILE * fp;
46
47 CF_DEBUG_CALLSTACK callstack;
48} S_CF_DEBUG_CTX, CF_DEBUG_CTX;
49
50int
51CF_Debug_Local_Print (FILE * fp,
52 const char * file,
53 const char * func,
54 const int line,
55 const char * fmt,
56 va_list valist)
57{
58 fprintf (fp, "[DEBUG][%s:%d][%s] ", file, line, func);
59 vfprintf (fp, fmt, valist);
60
61 return CF_OK;
62}
63
64int
65CF_Debug_Local_PrintBin (FILE * fp,
66 const char * file,
67 const char * func,
68 const int line,
69 const unsigned char * bin,
70 const int len)
71{
72 int i, j;
73
74 for (i = 0 ; i < len ; i += 16)
75 {
76 fprintf (fp, "[DEBUG][%s:%d][%s] ", file, line, func);
77 fprintf (fp, "%06x : ", i);
78
79 for (j = 0 ; j < 16 ; j++)
80 {
81 if (i+j < len)
82 fprintf (fp, "%02x ", bin[i+j]);
83 else
84 fprintf (fp, " ");
85 }
86 fprintf (fp, " ");
87
88 for (j = 0 ; j < 16 ; j++)
89 {
90 if (i+j < len)
91 fprintf (fp, "%c", IS_READABLE_CHAR(bin[i+j]) ? bin[i+j] : '.');
92 }
93 fprintf (fp, "\n");
94 }
95
96 return CF_OK;
97}
98
99CF_Debug_Ctx
100CF_Debug_CreateCtx (void)
101{
102 CF_DEBUG_CTX * ctx = NULL;
103
104 ctx = (CF_DEBUG_CTX *) calloc (sizeof (CF_DEBUG_CTX), 1);
105
106 return (CF_Debug_Ctx) ctx;
107}
108
109int
110CF_Debug_DestroyCtx (CF_Debug_Ctx ctx)
111{
112 CF_DEBUG_CTX * context = (CF_DEBUG_CTX *) ctx;
113 CF_DEBUG_CALLSTACK * pop = NULL;
114 CF_DEBUG_CALLSTACK * next = NULL;
115
116 CHECK_INVALID_CTX (ctx);
117
118 if (context->fp != NULL)
119 fclose (context->fp);
120
121 for (pop = next = context->callstack.caller ; pop ; pop = next)
122 {
123 next = next->caller;
124 free (pop);
125 }
126
127 free (context);
128
129 return CF_OK;
130}
131
132int
133CF_Debug_SetOutputFD (CF_Debug_Ctx ctx,
134 int fd)
135{
136 int result = 0;
137 int dupfd = 0;
138
139 CF_DEBUG_CTX * context = (CF_DEBUG_CTX *) ctx;
140 FILE * fp = NULL;
141
142 CHECK_INVALID_CTX (ctx);
143
144 TRY
145 {
146 dupfd = dup (fd);
147 if (dupfd < 0)
148 {
149 result = -1;
150 TRY_BREAK;
151 }
152
153 fp = fdopen (dupfd, "a+");
154 if (fp == NULL)
155 {
156 close (dupfd);
157 result = -2;
158 TRY_BREAK;
159 }
160
161 context->fp = fp;
162 }
163 CATCH_IF (result < 0)
164 {
165 return CF_ERROR_DEBUG_SET_OUTPUT_FD;
166 }
167
168 return CF_OK;
169}
170
171int
172CF_Debug_Print (FILE * fp,
173 const char * file,
174 const char * func,
175 const int line,
176 const char * fmt, ...)
177{
178 va_list valist;
179
180 va_start (valist, fmt);
181 CF_Debug_Local_Print (fp, file, func, line, fmt, valist);
182 va_end (valist);
183
184 return CF_OK;
185}
186
187int
188CF_Debug_PrintBin (FILE * fp,
189 const char * file,
190 const char * func,
191 const int line,
192 const unsigned char * bin,
193 const int len,
194 const char * fmt, ...)
195{
196 va_list valist;
197
198 va_start (valist, fmt);
199 CF_Debug_Local_Print (fp, file, func, line, fmt, valist);
200 va_end (valist);
201
202 CF_Debug_Local_PrintBin (fp, file, func, line, bin, len);
203
204 return CF_OK;
205}
206
207int
208CF_Debug_UpdateCtx (CF_Debug_Ctx ctx,
209 const char * file,
210 const char * func,
211 const int line)
212{
213 CF_DEBUG_CTX * context = (CF_DEBUG_CTX *) ctx;
214
215 CHECK_INVALID_CTX (ctx);
216
217 strncpy (context->file, file, strlen (file));
218 strncpy (context->func, func, strlen (func));
219 context->line = line;
220
221 return CF_OK;
222}
223
224int
225CF_Debug_Trace (CF_Debug_Ctx ctx,
226 const char * fmt, ...)
227{
228 va_list valist;
229 CF_DEBUG_CTX * context = (CF_DEBUG_CTX *) ctx;
230
231 CHECK_INVALID_CTX (ctx);
232
233 va_start (valist, fmt);
234 CF_Debug_Local_Print (GET_CTX_OSTREAM (context),
235 context->file,
236 context->func,
237 context->line,
238 fmt, valist);
239 va_end (valist);
240
241 return CF_OK;
242}
243
244int
245CF_Debug_TraceBin (CF_Debug_Ctx ctx,
246 const unsigned char * bin,
247 const int len,
248 const char * fmt, ...)
249{
250 va_list valist;
251 CF_DEBUG_CTX * context = (CF_DEBUG_CTX *) ctx;
252
253 CHECK_INVALID_CTX (ctx);
254
255 va_start (valist, fmt);
256 CF_Debug_Local_Print (GET_CTX_OSTREAM (context),
257 context->file,
258 context->func,
259 context->line,
260 fmt, valist);
261 va_end (valist);
262
263 CF_Debug_Local_PrintBin (GET_CTX_OSTREAM (context),
264 context->file,
265 context->func,
266 context->line,
267 bin, len);
268
269 return CF_OK;
270}
271
272int
273CF_Debug_CallStackPush (CF_Debug_Ctx ctx,
274 const char * file,
275 const char * func,
276 const int line)
277{
278 CF_DEBUG_CTX * context = (CF_DEBUG_CTX *) ctx;
279 CF_DEBUG_CALLSTACK * push = NULL;
280
281 CHECK_INVALID_CTX (ctx);
282
283 push = (CF_DEBUG_CALLSTACK *) calloc (sizeof (CF_DEBUG_CALLSTACK), 1);
284 if (push == NULL)
285 return CF_ERROR_DEBUG_PUSH_CALLSTACK;
286
287 /* push to callstack */
288 sprintf (push->file, "%s", file);
289 sprintf (push->func, "%s", func);
290 push->line = line;
291 push->caller = context->callstack.caller;
292 context->callstack.caller = push;
293
294 CF_Debug_UpdateCtx (ctx, file, func, line);
295
296 return CF_OK;
297}
298
299int
300CF_Debug_CallStackPop (CF_Debug_Ctx ctx,
301 CF_Debug_CallStack * callstack)
302{
303 CF_DEBUG_CTX * context = (CF_DEBUG_CTX *) ctx;
304 CF_DEBUG_CALLSTACK * pop = NULL;
305
306 CHECK_INVALID_CTX (ctx);
307
308 pop = context->callstack.caller;
309 if (pop == NULL)
310 return CF_ERROR_DEBUG_POP_CALLSTACK;
311
312 if (callstack != NULL)
313 {
314 sprintf (callstack->file , "%s", pop->file);
315 sprintf (callstack->function, "%s", pop->func);
316 callstack->line = pop->line;
317 }
318
319 memset (context->file, 0x00, sizeof (context->file));
320 memset (context->func, 0x00, sizeof (context->func));
321 context->line = 0;
322
323 /* restore current context */
324 if (pop->caller != NULL)
325 {
326 CF_Debug_UpdateCtx (ctx,
327 pop->caller->file,
328 pop->caller->func,
329 pop->caller->line);
330 }
331
332 context->callstack.caller = pop->caller;
333 free (pop);
334
335 return CF_OK;
336}
Note: See TracBrowser for help on using the repository browser.