gwenhywfar  5.10.1
debug.c
Go to the documentation of this file.
1 /***************************************************************************
2  $RCSfile$
3  -------------------
4  cvs : $Id$
5  begin : Sun Dec 04 2004
6  copyright : (C) 2004 by Martin Preuss
7  email : martin@libchipcard.de
8 
9  ***************************************************************************
10  * *
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU Lesser General Public *
13  * License as published by the Free Software Foundation; either *
14  * version 2.1 of the License, or (at your option) any later version. *
15  * *
16  * This library is distributed in the hope that it will be useful, *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
19  * Lesser General Public License for more details. *
20  * *
21  * You should have received a copy of the GNU Lesser General Public *
22  * License along with this library; if not, write to the Free Software *
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
24  * MA 02111-1307 USA *
25  * *
26  ***************************************************************************/
27 
28 
29 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif
32 
33 #include "debug_p.h"
34 
35 #include <stdarg.h>
36 #include <assert.h>
37 #include <stdio.h>
38 #ifdef HAVE_STRINGS_H
39 # include <strings.h>
40 #endif
41 #include <gwenhywfar/misc.h>
42 
43 
44 
46 
47 
48 
49 uint32_t GWEN_Debug_PrintDec(char *buffer,
50  uint32_t size,
51  uint32_t num,
52  int leadingZero,
53  uint32_t length)
54 {
55  uint32_t i;
56  uint32_t j;
57  uint32_t k;
58  char numbuf[16];
59  int numOr;
60 
61  /* first convert number */
62  numOr=0;
63  i=0;
64  j=1000000000;
65 
66  while (j) {
67  k=num/j;
68  numOr|=k;
69  if (numOr || leadingZero || j==1) {
70  numbuf[i]=k+'0';
71  i++;
72  }
73  num-=(k*j);
74  j/=10;
75  } /* while j */
76 
77  j=0;
78  if (length) {
79  if (i>length)
80  i=length;
81 
82  /* fill left up to length-(sizeof number) */
83  k=length-i;
84  while (k) {
85  if (j<size) {
86  if (leadingZero)
87  buffer[j]='0';
88  else
89  buffer[j]=' ';
90  }
91  j++;
92  k--;
93  } /* while k */
94  } /* if length */
95 
96  /* copy number */
97  for (k=0; k<i; k++) {
98  if (j<size)
99  buffer[j]=numbuf[k];
100  j++;
101  } /* while i */
102 
103  /* append trailing 0 */
104  if (j<size)
105  buffer[j]=0;
106  j++;
107  /* return length (or possible length) */
108  return j;
109 }
110 
111 
112 
113 uint32_t GWEN_Debug_PrintHex(char *buffer,
114  uint32_t size,
115  uint32_t num,
116  int leadingZero,
117  int up,
118  uint32_t length)
119 {
120  uint32_t i;
121  uint32_t j;
122  uint32_t k;
123  char numbuf[16];
124  int numOr;
125 
126  /* first convert number */
127  numOr=0;
128  i=0;
129  j=8;
130 
131  while (j) {
132  k=(num>>((j-1)*4))&0xf;
133  numOr|=k;
134  if (numOr || leadingZero || j==1) {
135  if (k>9) {
136  if (up)
137  numbuf[i]=k+'0'+7;
138  else
139  numbuf[i]=k+'0'+7+32;
140  }
141  else
142  numbuf[i]=k+'0';
143  i++;
144  }
145  j--;
146  } /* while j */
147 
148  j=0;
149  if (length) {
150  if (i>length)
151  i=length;
152 
153  /* fill left up to length-(sizeof number) */
154  k=length-i;
155  while (k) {
156  if (j<size) {
157  if (leadingZero)
158  buffer[j]='0';
159  else
160  buffer[j]=' ';
161  }
162  j++;
163  k--;
164  } /* while k */
165  } /* if length */
166 
167  /* copy number */
168  for (k=0; k<i; k++) {
169  if (j<size)
170  buffer[j]=numbuf[k];
171  j++;
172  } /* while i */
173 
174  /* append trailing 0 */
175  if (j<size)
176  buffer[j]=0;
177  j++;
178  /* return length (or possible length) */
179  return j;
180 }
181 
182 
183 
184 
185 
186 uint32_t GWEN_Debug_Snprintf(char *buffer,
187  uint32_t size,
188  const char *fmt, ...)
189 {
190  va_list arguments;
191  uint32_t i;
192 
193  i=0;
194  va_start(arguments, fmt);
195  while (*fmt) {
196  if (*fmt=='%') {
197  fmt++;
198  if (*fmt=='%') {
199  /* write character '%' */
200  if (i<size)
201  buffer[i]='%';
202  i++;
203  }
204  else {
205  uint32_t length;
206  int leadingZero;
207 
208  leadingZero=0;
209  length=0;
210 
211  /* read length */
212  if ((*fmt)>='0' && (*fmt)<='9') {
213  /* read number */
214  if (*fmt=='0') {
215  leadingZero=1;
216  }
217  while ((*fmt)>='0' && (*fmt)<='9') {
218  length*=10;
219  length+=*fmt-'0';
220  fmt++;
221  } /* while */
222  }
223 
224  /* read type */
225  switch (*fmt) {
226  /* decimal integer */
227  case 'c':
228  case 'd': {
229  int p;
230 
231  p=va_arg(arguments, int);
232  if (p<0) {
233  if (i<size)
234  buffer[i]='-';
235  i++;
236  p=-p;
237  }
238  i+=GWEN_Debug_PrintDec(buffer+i,
239  size-i,
240  p,
241  leadingZero,
242  length)-1;
243  break;
244  }
245 
246  /* hexadecimal integer */
247  case 'x': {
248  unsigned int p;
249 
250  p=va_arg(arguments, unsigned int);
251  i+=GWEN_Debug_PrintHex(buffer+i,
252  size-i,
253  p,
254  leadingZero,
255  0,
256  length)-1;
257  break;
258  }
259 
260  /* hexadecimal integer */
261  case 'X': {
262  unsigned int p;
263 
264  p=va_arg(arguments, unsigned int);
265  i+=GWEN_Debug_PrintHex(buffer+i,
266  size-i,
267  p,
268  leadingZero,
269  1,
270  length)-1;
271  break;
272  }
273 
274  case 's': {
275  const char *p;
276 
277  p=va_arg(arguments, const char *);
278  if (!p)
279  p="(null)";
280  while (*p) {
281  if (i<size)
282  buffer[i]=*p;
283  i++;
284  p++;
285  } /* while */
286  break;
287  }
288 
289  default:
290  break;
291  } /* switch */
292  }
293  }
294  else {
295  if (i<size)
296  buffer[i]=*fmt;
297  i++;
298  }
299  fmt++;
300  } /* while */
301 
302  /* add trailing 0 */
303  if (i<size)
304  buffer[i]=0;
305  i++;
306  va_end(arguments);
307  return i;
308 }
309 
310 
311 
312 
313 #ifdef NO_VARIADIC_MACROS
314 void DBG_ERROR(const char *dbg_logger, const char *format, ...)
315 {
316  va_list args;
317  char dbg_buffer[256];
318  va_start(args, format);
319  vsnprintf(dbg_buffer, sizeof(dbg_buffer)-1, format, args);
320  dbg_buffer[sizeof(dbg_buffer)-1] = 0;
321  GWEN_Logger_Log(dbg_logger, GWEN_LoggerLevelError, dbg_buffer);
322  va_end(args);
323 }
324 
325 void DBG_WARN(const char *dbg_logger, const char *format, ...)
326 {
327  va_list args;
328  char dbg_buffer[256];
329  va_start(args, format);
330  vsnprintf(dbg_buffer, sizeof(dbg_buffer)-1, format, args);
331  dbg_buffer[sizeof(dbg_buffer)-1] = 0;
332  GWEN_Logger_Log(dbg_logger, GWEN_LoggerLevelWarning, dbg_buffer);
333  va_end(args);
334 }
335 
336 void DBG_NOTICE(const char *dbg_logger, const char *format, ...)
337 {
338  if (GWEN_Logger_GetLevel(dbg_logger)>=GWEN_LoggerLevelNotice) {
339  va_list args;
340  char dbg_buffer[256];
341  va_start(args, format);
342  vsnprintf(dbg_buffer, sizeof(dbg_buffer)-1, format, args);
343  dbg_buffer[sizeof(dbg_buffer)-1] = 0;
344  GWEN_Logger_Log(dbg_logger, GWEN_LoggerLevelNotice, dbg_buffer);
345  va_end(args);
346  }
347 }
348 
349 void DBG_INFO(const char *dbg_logger, const char *format, ...)
350 {
351  if (GWEN_Logger_GetLevel(dbg_logger)>=GWEN_LoggerLevelInfo) {
352  va_list args;
353  char dbg_buffer[256];
354  va_start(args, format);
355  vsnprintf(dbg_buffer, sizeof(dbg_buffer)-1, format, args);
356  dbg_buffer[sizeof(dbg_buffer)-1] = 0;
357  GWEN_Logger_Log(dbg_logger, GWEN_LoggerLevelInfo, dbg_buffer);
358  va_end(args);
359  }
360 }
361 
362 void DBG_DEBUG(const char *dbg_logger, const char *format, ...)
363 {
364 # ifndef DISABLE_DEBUGLOG
365  if (GWEN_Logger_GetLevel(dbg_logger)>=GWEN_LoggerLevelDebug) {
366  va_list args;
367  char dbg_buffer[256];
368  va_start(args, format);
369  vsnprintf(dbg_buffer, sizeof(dbg_buffer)-1, format, args);
370  dbg_buffer[sizeof(dbg_buffer)-1] = 0;
371  GWEN_Logger_Log(dbg_logger, GWEN_LoggerLevelDebug, dbg_buffer);
372  va_end(args);
373  }
374 # endif /* DISABLE_DEBUGLOG */
375 }
376 
377 void DBG_VERBOUS(const char *dbg_logger, const char *format, ...)
378 {
379 # ifndef DISABLE_DEBUGLOG
380  if (GWEN_Logger_GetLevel(dbg_logger)>=GWEN_LoggerLevelVerbous) {
381  va_list args;
382  char dbg_buffer[256];
383  va_start(args, format);
384  vsnprintf(dbg_buffer, sizeof(dbg_buffer)-1, format, args);
385  dbg_buffer[sizeof(dbg_buffer)-1] = 0;
386  GWEN_Logger_Log(dbg_logger, GWEN_LoggerLevelVerbous, dbg_buffer);
387  va_end(args);
388  }
389 # endif /* DISABLE_DEBUGLOG */
390 }
391 
392 #endif /* NO_VARIADIC_MACROS */
393 
394 
395 
396 
397 
398 
399 
400 GWEN_MEMORY_DEBUG_ENTRY *GWEN_MemoryDebugEntry_new(GWEN_MEMORY_DEBUG_ENTRY_TYPE t,
401  const char *wFile,
402  int wLine)
403 {
404  GWEN_MEMORY_DEBUG_ENTRY *e;
405 
406  assert(wFile);
407  assert(wLine);
408  GWEN_NEW_OBJECT(GWEN_MEMORY_DEBUG_ENTRY, e);
409  e->file=strdup(wFile);
410  e->line=wLine;
411  e->type=t;
412  return e;
413 }
414 
415 
416 
417 void GWEN_MemoryDebugEntry_free(GWEN_MEMORY_DEBUG_ENTRY *e)
418 {
419  if (e) {
420  free(e->file);
421  GWEN_FREE_OBJECT(e);
422  }
423 }
424 
425 
426 
427 
429 {
431 
432  assert(name);
434  o->name=strdup(name);
435  return o;
436 }
437 
438 
439 
441 {
442  if (o) {
443  GWEN_MEMORY_DEBUG_ENTRY *e;
444 
445  e=o->entries;
446  while (e) {
447  GWEN_MEMORY_DEBUG_ENTRY *next;
448 
449  next=e->next;
451  e=next;
452  }
453  free(o->name);
454  GWEN_FREE_OBJECT(o);
455  }
456 }
457 
458 
459 
461 {
463 
465  while (o) {
466  assert(o->name);
467  if (strcasecmp(o->name, name)==0)
468  break;
469  if (o->next==o) {
470  DBG_ERROR(GWEN_LOGDOMAIN, "What ?? Pointing to myself ??");
471  abort();
472  }
473  o=o->next;
474  }
475 
476  return o;
477 }
478 
479 
480 
481 void GWEN_MemoryDebug_Increment(const char *name,
482  const char *wFile,
483  int wLine,
484  int attach)
485 {
487  GWEN_MEMORY_DEBUG_ENTRY *e;
488 
489  assert(name);
490  assert(wFile);
491  assert(wLine);
493  if (!o) {
496  e=GWEN_MemoryDebugEntry_new(attach?GWEN_MemoryDebugEntryTypeAttach:
497  GWEN_MemoryDebugEntryTypeCreate,
498  wFile, wLine);
499  GWEN_LIST_ADD(GWEN_MEMORY_DEBUG_ENTRY, e, &(o->entries));
500  o->count++;
501  }
502  else {
503  e=GWEN_MemoryDebugEntry_new(attach?GWEN_MemoryDebugEntryTypeAttach:
504  GWEN_MemoryDebugEntryTypeCreate,
505  wFile, wLine);
506  GWEN_LIST_ADD(GWEN_MEMORY_DEBUG_ENTRY, e, &(o->entries));
507  o->count++;
508  }
509 }
510 
511 
512 
513 void GWEN_MemoryDebug_Decrement(const char *name,
514  const char *wFile,
515  int wLine)
516 {
518  GWEN_MEMORY_DEBUG_ENTRY *e;
519 
520  assert(name);
521  assert(wFile);
522  assert(wLine);
524  if (!o) {
526  "Object to be freed not found (%s at %s:%d)",
527  name, wFile, wLine);
530  e=GWEN_MemoryDebugEntry_new(GWEN_MemoryDebugEntryTypeFree,
531  wFile, wLine);
532  GWEN_LIST_ADD(GWEN_MEMORY_DEBUG_ENTRY, e, &(o->entries));
533  o->count--;
534  }
535  else {
536  e=GWEN_MemoryDebugEntry_new(GWEN_MemoryDebugEntryTypeFree,
537  wFile, wLine);
538  GWEN_LIST_ADD(GWEN_MEMORY_DEBUG_ENTRY, e, &(o->entries));
539  o->count--;
540  }
541 }
542 
543 
544 
546  uint32_t mode)
547 {
548 
549  DBG_ERROR(0, "Object \"%s\" (count=%ld)",
550  o->name, o->count);
551  if (o->count!=0 || mode==GWEN_MEMORY_DEBUG_MODE_DETAILED) {
552  GWEN_MEMORY_DEBUG_ENTRY *e;
553 
554  if (mode!=GWEN_MEMORY_DEBUG_MODE_SHORT) {
555  e=o->entries;
556  while (e) {
557  const char *s;
558 
559  fprintf(stderr, " ");
560  switch (e->type) {
561  case GWEN_MemoryDebugEntryTypeCreate:
562  s="created";
563  break;
564  case GWEN_MemoryDebugEntryTypeAttach:
565  s="attached";
566  break;
567  case GWEN_MemoryDebugEntryTypeFree:
568  s="freed";
569  break;
570  case GWEN_MemoryDebugEntryTypeUnknown:
571  default:
572  s="<unknown action>";
573  break;
574  }
575  DBG_ERROR(0, " %s at %s:%d", s, e->file, e->line);
576  e=e->next;
577  } /* while e */
578  }
579  }
580 }
581 
582 
583 
584 void GWEN_MemoryDebug_DumpObject(const char *name,
585  uint32_t mode)
586 {
588 
589  assert(name);
591  if (!o) {
592  DBG_ERROR(GWEN_LOGDOMAIN, "Object \"%s\" not found", name);
593  }
594  else
596 }
597 
598 
599 
600 long int GWEN_MemoryDebug_GetObjectCount(const char *name)
601 {
603 
604  assert(name);
606  if (!o) {
607  DBG_ERROR(GWEN_LOGDOMAIN, "Object \"%s\" not found", name);
608  return 0;
609  }
610  else
611  return o->count;
612 }
613 
614 
615 
616 void GWEN_MemoryDebug_Dump(uint32_t mode)
617 {
619 
620  DBG_ERROR(0, "Gwenhywfar Memory Debugger Statistics:");
621  DBG_ERROR(0, "====================================== begin\n");
623  while (o) {
625  o=o->next;
626  }
627  DBG_ERROR(0, "====================================== end\n");
628 }
629 
630 
631 
633 {
635 
637  while (o) {
639 
640  next=o->next;
642  o=next;
643  }
645 }
646 
647 
648 
649 
#define GWEN_MEMORY_DEBUG_MODE_DETAILED
Definition: debug.h:52
GWENHYWFAR_API const char * fmt
Definition: buffer.h:283
GWEN_MEMORY_DEBUG_OBJECT * GWEN_MemoryDebugObject_new(const char *name)
Definition: debug.c:428
#define DBG_NOTICE(dbg_logger, format, args...)
Definition: debug.h:152
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
uint32_t GWEN_Debug_Snprintf(char *buffer, uint32_t size, const char *fmt,...)
Definition: debug.c:186
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:224
static GWEN_MEMORY_DEBUG_OBJECT * gwen_debug__memobjects
Definition: debug.c:45
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:125
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void GWEN_MemoryDebugEntry_free(GWEN_MEMORY_DEBUG_ENTRY *e)
Definition: debug.c:417
void GWEN_MemoryDebug_CleanUp(void)
Definition: debug.c:632
struct GWEN_MEMORY_DEBUG_OBJECT GWEN_MEMORY_DEBUG_OBJECT
Definition: debug.h:55
void GWEN_MemoryDebug__DumpObject(GWEN_MEMORY_DEBUG_OBJECT *o, uint32_t mode)
Definition: debug.c:545
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
void GWEN_Logger_Log(const char *logDomain, GWEN_LOGGER_LEVEL priority, const char *s)
Definition: logger.c:553
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:214
#define GWEN_MEMORY_DEBUG_MODE_SHORT
Definition: debug.h:53
void GWEN_MemoryDebug_Dump(uint32_t mode)
Definition: debug.c:616
uint32_t GWEN_Debug_PrintDec(char *buffer, uint32_t size, uint32_t num, int leadingZero, uint32_t length)
Definition: debug.c:49
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
uint32_t GWEN_Debug_PrintHex(char *buffer, uint32_t size, uint32_t num, int leadingZero, int up, uint32_t length)
Definition: debug.c:113
int GWEN_Logger_GetLevel(const char *logDomain)
Definition: logger.c:638
#define GWEN_LIST_ADD(typ, sr, head)
Definition: misc.h:82
GWEN_MEMORY_DEBUG_ENTRY * GWEN_MemoryDebugEntry_new(GWEN_MEMORY_DEBUG_ENTRY_TYPE t, const char *wFile, int wLine)
Definition: debug.c:400
void GWEN_MemoryDebug_Increment(const char *name, const char *wFile, int wLine, int attach)
Definition: debug.c:481
long int GWEN_MemoryDebug_GetObjectCount(const char *name)
Definition: debug.c:600
void GWEN_MemoryDebug_DumpObject(const char *name, uint32_t mode)
Definition: debug.c:584
void GWEN_MemoryDebugObject_free(GWEN_MEMORY_DEBUG_OBJECT *o)
Definition: debug.c:440
GWEN_MEMORY_DEBUG_OBJECT * GWEN_MemoryDebug__FindObject(const char *name)
Definition: debug.c:460
void GWEN_MemoryDebug_Decrement(const char *name, const char *wFile, int wLine)
Definition: debug.c:513