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

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

#1 change local functions in source code to static functions and some comments

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