lightweight DB() macro added
[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 #include <stdarg.h>
12 #include <string.h>
13
14 #include "irprintf.h"
15 #include "debug.h"
16
17 #include "hashptr.h"
18 #include "obst.h"
19 #include "set.h"
20
21 #ifdef WITH_LIBCORE
22
23 #include "irargs_t.h"
24
25 static void firm_dbg_default_printer(struct obstack *obst, const char *fmt, va_list args)
26 {
27   static lc_arg_env_t *env = NULL;
28
29   if(!env)
30     env = firm_get_arg_env();
31
32   lc_evoprintf(env, obst, fmt, args);
33
34 }
35
36 firm_dbg_module_t *firm_dbg_register(const char *name)
37 {
38   return lc_dbg_register_with_printer(name, firm_dbg_default_printer);
39 }
40
41 #else
42
43 static struct obstack dbg_obst;
44 static set *module_set;
45
46 struct _firm_dbg_module_t {
47   unsigned mask;
48   const char *name;
49   FILE *file;
50 };
51
52 static int module_cmp(const void *p1, const void *p2, size_t size)
53 {
54   const firm_dbg_module_t *m1 = p1;
55   const firm_dbg_module_t *m2 = p2;
56   return strcmp(m1->name, m2->name);
57 }
58
59 static void firm_dbg_init(void)
60 {
61   obstack_init(&dbg_obst);
62   module_set = new_set(module_cmp, 16);
63 }
64
65 firm_dbg_module_t *firm_dbg_register(const char *name)
66 {
67   firm_dbg_module_t mod;
68   mod.mask = 0;
69   mod.name = name;
70   mod.file = stderr;
71
72   if(!module_set)
73     firm_dbg_init();
74
75   return set_insert(module_set, &mod, sizeof(mod), HASH_STR(name, strlen(name)));
76 }
77
78 void firm_dbg_set_mask(firm_dbg_module_t *module, unsigned mask)
79 {
80   module->mask = mask;
81 }
82
83 unsigned firm_dbg_get_mask(const firm_dbg_module_t *module)
84 {
85   return module->mask;
86 }
87
88 void firm_dbg_set_file(firm_dbg_module_t *module, FILE *file)
89 {
90   module->file = file;
91 }
92
93 typedef struct _msg_info_t {
94   const char *msg;
95   const firm_dbg_module_t *mod;
96 } msg_info_t;
97
98 static void *make_msg_info(const firm_dbg_module_t *mod, const char *fmt, va_list args)
99 {
100   static const char msg_header[] = "%s(%d) %s: ";
101   msg_info_t *res = obstack_alloc(&dbg_obst, sizeof(*res));
102
103   obstack_grow(&dbg_obst, msg_header, sizeof(msg_header) - 1);
104   ir_obst_vprintf(&dbg_obst, fmt, args);
105   obstack_1grow(&dbg_obst, '\0');
106
107   res->msg = obstack_finish(&dbg_obst);
108   res->mod = mod;
109   return res;
110 }
111
112 void *_firm_dbg_make_msg(const firm_dbg_module_t *mod, unsigned mask, const char *fmt, ...)
113 {
114   void *res = NULL;
115
116   if(mask == 0 || (mod->mask & mask)) {
117     va_list args;
118     va_start(args, fmt);
119     res = make_msg_info(mod, fmt, args);
120     va_end(args);
121   }
122
123   return res;
124 }
125
126 void _firm_dbg_print_msg(const char *filename, int line, const char *func, void *mi_ptr)
127 {
128   msg_info_t *mi = mi_ptr;
129   if(mi) {
130     fprintf(mi->mod->file, mi->msg, filename, line, func);
131     obstack_free(&dbg_obst, mi);
132   }
133 }
134
135 void _firm_dbg_print(const firm_dbg_module_t *mod, unsigned mask, const char *fmt, ...)
136 {
137   if(mask == 0 || (mod->mask & mask)) {
138     va_list args;
139     char *res;
140     va_start(args, fmt);
141     ir_obst_vprintf(&dbg_obst, fmt, args);
142     obstack_1grow(&dbg_obst, '\0');
143     res = obstack_finish(&dbg_obst);
144     fprintf(mod->file, res);
145     obstack_free(&dbg_obst, res);
146     va_end(args);
147   }
148 }
149
150 #endif /* WITH_LIBCORE */