wrapped debugging modules with DEBUG_ONLY
[libfirm] / ir / common / debug.c
1 /**
2  * Debug facility.
3  * @author Michael Beck, Sebastian Hack
4  * @date 15.12.2004
5  */
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #ifdef DEBUG_libfirm
12
13 #include <stdarg.h>
14 #include <string.h>
15
16 #include "irprintf.h"
17 #include "debug.h"
18
19 #include "hashptr.h"
20 #include "obst.h"
21 #include "set.h"
22
23 #ifdef WITH_LIBCORE
24
25 #include "irargs_t.h"
26
27 static void firm_dbg_default_printer(struct obstack *obst, const char *fmt, va_list args)
28 {
29   static lc_arg_env_t *env = NULL;
30
31   if(!env)
32     env = firm_get_arg_env();
33
34   lc_evoprintf(env, obst, fmt, args);
35
36 }
37
38 firm_dbg_module_t *firm_dbg_register(const char *name)
39 {
40   return lc_dbg_register_with_printer(name, firm_dbg_default_printer);
41 }
42
43 #else
44
45 static struct obstack dbg_obst;
46 static set *module_set;
47
48 /**
49  * A debug module.
50  */
51 struct _firm_dbg_module_t {
52   unsigned mask;
53   const char *name;
54   FILE *file;
55 };
56
57 /**
58  * Compares two modules by comparing it's names
59  */
60 static int module_cmp(const void *p1, const void *p2, size_t size)
61 {
62   const firm_dbg_module_t *m1 = p1;
63   const firm_dbg_module_t *m2 = p2;
64   return strcmp(m1->name, m2->name);
65 }
66
67 /**
68  * initialize the debug module
69  */
70 static void firm_dbg_init(void)
71 {
72   obstack_init(&dbg_obst);
73   module_set = new_set(module_cmp, 16);
74 }
75
76 firm_dbg_module_t *firm_dbg_register(const char *name)
77 {
78   firm_dbg_module_t mod;
79   mod.mask = 0;
80   mod.name = name;
81   mod.file = stderr;
82
83   if(!module_set)
84     firm_dbg_init();
85
86   return set_insert(module_set, &mod, sizeof(mod), HASH_STR(name, strlen(name)));
87 }
88
89 void firm_dbg_set_mask(firm_dbg_module_t *module, unsigned mask)
90 {
91   module->mask = mask;
92 }
93
94 unsigned firm_dbg_get_mask(const firm_dbg_module_t *module)
95 {
96   return module->mask;
97 }
98
99 void firm_dbg_set_file(firm_dbg_module_t *module, FILE *file)
100 {
101   module->file = file;
102 }
103
104 /**
105  * A message info: a pair of debug handle and message
106  */
107 typedef struct _msg_info_t {
108   const char *msg;
109   const firm_dbg_module_t *mod;
110 } msg_info_t;
111
112 /**
113  * Formats a message given by a printf-like format and a va_list argument,
114  * puts the test on an obstack and return a msg_info.
115  */
116 static void *make_msg_info(const firm_dbg_module_t *mod, const char *fmt, va_list args)
117 {
118   static const char msg_header[] = "%s(%d) %s: ";
119   msg_info_t *res = obstack_alloc(&dbg_obst, sizeof(*res));
120
121   obstack_grow(&dbg_obst, msg_header, sizeof(msg_header) - 1);
122   ir_obst_vprintf(&dbg_obst, fmt, args);
123   obstack_1grow(&dbg_obst, '\0');
124
125   res->msg = obstack_finish(&dbg_obst);
126   res->mod = mod;
127   return res;
128 }
129
130 void *_firm_dbg_make_msg(const firm_dbg_module_t *mod, unsigned mask, const char *fmt, ...)
131 {
132   void *res = NULL;
133
134   if(mask == 0 || (mod->mask & mask)) {
135     va_list args;
136     va_start(args, fmt);
137     res = make_msg_info(mod, fmt, args);
138     va_end(args);
139   }
140
141   return res;
142 }
143
144 void _firm_dbg_print_msg(const char *filename, int line, const char *func, void *mi_ptr)
145 {
146   msg_info_t *mi = mi_ptr;
147   if(mi) {
148     fprintf(mi->mod->file, mi->msg, filename, line, func);
149     obstack_free(&dbg_obst, mi);
150   }
151 }
152
153 void _firm_dbg_print(const firm_dbg_module_t *mod, unsigned mask, const char *fmt, ...)
154 {
155   if(mask == 0 || (mod->mask & mask)) {
156     va_list args;
157     char *res;
158     va_start(args, fmt);
159     ir_obst_vprintf(&dbg_obst, fmt, args);
160     obstack_1grow(&dbg_obst, '\0');
161     res = obstack_finish(&dbg_obst);
162     fprintf(mod->file, res);
163     obstack_free(&dbg_obst, res);
164     va_end(args);
165   }
166 }
167
168 #endif /* WITH_LIBCORE */
169
170 #else /* DEBUG_libfirm */
171
172 /* some picky compiler don't allow empty files */
173 static int dummy;
174
175 #endif /* DEBUG_libfirm */