source: branches/stable/BUGEX/bugex.h

Last change on this file was 17651, checked in by westram, 5 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1//  ==================================================================== //
2//                                                                       //
3//    File      : bugex.h                                                //
4//    Purpose   : Debugging code                                         //
5//                                                                       //
6//                                                                       //
7//  Coded by Ralf Westram (coder@reallysoft.de) in April 2003            //
8//  Copyright Department of Microbiology (Technical University Munich)   //
9//                                                                       //
10//  Visit our web site at: http://www.arb-home.de/                       //
11//                                                                       //
12//                                                                       //
13//  ==================================================================== //
14
15// Description :
16//
17// when using the macros XXX_DUMP_VAL and XXX_DUMP_STR the program prints
18// out information about the specified variables.
19//
20// This information is prefixed by 'FILE:LINENO: '
21//
22// The intention is to use the program as compile-command in emacs and follow
23// the program flow with next-error / previous-error
24//
25// Note : When finished with debugging you should remove the #include "bugex.h"
26// because it adds unneeded code to EVERY object file!
27
28// --------------------------------------------------------------------------------
29// This section is used by Ralf
30// If you want to use the DUMP-Macros copy this section and personalize it!
31
32#if defined(DEVEL_RALF)
33
34#define BUGEX_DUMPS
35#define BUGEX_MAX_STRING_PRINT 40
36
37#define RALF_DUMP_EXPR(type,var) ALL_DUMP_EXPR(type,var)
38#define RALF_DUMP_VAL(var)       ALL_DUMP_VAL(var)
39#define RALF_DUMP_STR(var)       ALL_DUMP_STR(var)
40#define RALF_DUMP_PTR(var)       ALL_DUMP_PTR(var)
41#define RALF_DUMP_MARK()         ALL_DUMP_MARK()
42
43#else
44
45#define RALF_DUMP_VAL(var)
46#define RALF_DUMP_STR(var)
47#define RALF_DUMP_MARK()
48
49#endif
50
51// --------------------------------------------------------------------------------
52// Definition of needed macros/functions :
53
54#if defined(BUGEX_DUMPS)
55
56#ifndef _GLIBCXX_CCTYPE
57#include <cctype>
58#endif
59
60// Do NOT use the following macros!!!
61
62#define ALL_DUMP_EXPR(type,expr)                                        \
63    do {                                                                \
64        type tmp_var = (expr);                                          \
65        bugex_dump_value(&tmp_var, "[" #expr "]", sizeof(tmp_var), __FILE__, __LINE__); \
66    } while (0)
67
68#define ALL_DUMP_VAL(var) bugex_dump_value(&var, #var, sizeof(var), __FILE__, __LINE__)
69#define ALL_DUMP_STR(var) bugex_dump_string(&var, #var, __FILE__, __LINE__)
70#define ALL_DUMP_PTR(var) bugex_dump_pointer(&var, #var, __FILE__, __LINE__)
71#define ALL_DUMP_MARK()   bugex_dump_mark(__FILE__, __LINE__)
72
73static void bugex_dump_mark(const char *file, size_t lineno) {
74    fprintf(stderr, "%s:%zu: ------------------------------ MARK\n", file, lineno);
75    fflush(stderr);
76}
77
78static void bugex_printString(const char *str, size_t len) {
79    while (len--) {
80        unsigned char c = (unsigned char)*str++;
81        if (isprint(c)) {
82            fputc(c, stderr);
83        }
84        else {
85            switch (c) {
86                case '\n': fputs("\\n", stderr); break;
87                case '\t': fputs("\\t", stderr); break;
88                default: fprintf(stderr, "\\%i", (int)c); break;
89            }
90        }
91    }
92}
93
94static void bugex_dump_pointer(void *somePtr, const char *someName, const char *file, size_t lineno) {
95    fprintf(stderr, "%s:%zu: %s: %p -> %p\n", file, lineno, someName, somePtr, *(void**)somePtr);
96    fflush(stderr);
97}
98
99static void bugex_dump_string(void *strPtr, const char *strName, const char *file, size_t lineno) {
100    const char *s = *((const char **)strPtr);
101
102    fprintf(stderr, "%s:%zu: ", file, lineno);
103
104    if (s == 0) {               // NULp pointer
105        fprintf(stderr, "%s is NULp (&=%p)\n", strName, strPtr);
106    }
107    else {
108        size_t len = strlen(s);
109
110        fprintf(stderr, "%s = \"", strName);
111        if (len <= BUGEX_MAX_STRING_PRINT) { // short strings
112            bugex_printString(s, len);
113        }
114        else {
115            bugex_printString(s, BUGEX_MAX_STRING_PRINT/2);
116            fprintf(stderr, "\" .. \"");
117            bugex_printString(s+len-BUGEX_MAX_STRING_PRINT/2, BUGEX_MAX_STRING_PRINT/2);
118        }
119        fprintf(stderr, "\" (len=%zu, &=%p -> %p)\n", len, strPtr, s);
120    }
121    fflush(stderr);
122}
123
124
125#define BUGEX_VALSIZES 4
126static unsigned short bugex_valsize[] = { sizeof(char), sizeof(short), sizeof(int), sizeof(long), 0 };
127enum bugex_valtype { BUGEX_CHAR, BUGEX_SHORT, BUGEX_INT, BUGEX_LONG, BUGEX_UNKNOWN };
128
129static void bugex_dump_value(void *valuePtr, const char *valueName, size_t size, const char *file, size_t lineno) {
130    int                vs;
131    enum bugex_valtype type = BUGEX_UNKNOWN;
132
133    if (size == bugex_valsize[BUGEX_INT]) {
134        type = BUGEX_INT; // prefer int
135    }
136    else {
137        for (vs = 0; vs < BUGEX_VALSIZES; ++vs) {
138            if (size == bugex_valsize[vs]) {
139                type = (enum bugex_valtype)vs;
140            }
141        }
142    }
143
144    fprintf(stderr, "%s:%zu: ", file, lineno);
145
146    switch (type) {
147        case BUGEX_CHAR: {
148            unsigned char c = *(unsigned char*)valuePtr;
149            int           i = (int)(signed char)c;
150
151            fprintf(stderr, "(char)  %s = '%c' = %i", valueName, c, i);
152            if (i<0) fprintf(stderr, " = %u", (unsigned int)c);
153            fprintf(stderr, " (&=%p)", valuePtr);
154            break;
155        }
156        case BUGEX_SHORT: {
157            unsigned short s  = *(unsigned short *)valuePtr;
158            signed short   ss = (signed short)s;
159           
160            fprintf(stderr, "(short) %s = %hi", valueName, (int)ss);
161            if (ss<0) fprintf(stderr, " = %hu", s);
162            fprintf(stderr, " = 0x%hx (&=%p)", s, valuePtr);
163            break;
164        }
165        case BUGEX_INT: {
166            unsigned int u = *(unsigned int *)valuePtr;
167            int          i = (int)u;
168
169            fprintf(stderr, "(int) %s = %i", valueName, i);
170            if (i<0) fprintf(stderr, " = %u", u);
171            fprintf(stderr, " = 0x%x (&=%p)", u, valuePtr);
172            break;
173        }
174        case BUGEX_LONG: {
175            unsigned long l = *(unsigned long *)valuePtr;
176            fprintf(stderr, "(long)  %s = %li = %lu = 0x%lx (&=%p)", valueName, (signed long)l, (unsigned long)l, (unsigned long)l, valuePtr);
177            break;
178        }
179        default: {
180            fprintf(stderr, "value '%s' has unknown size (use cast operator!)", valueName);
181            break;
182        }
183    }
184    fprintf(stderr, "\n");
185    fflush(stderr);
186}
187
188#endif // BUGEX_DUMPS
Note: See TracBrowser for help on using the repository browser.