Added new firm debug functions.
[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 static struct obstack dbg_obst;
22 static set *module_set;
23
24 struct _firm_dbg_module_t {
25         unsigned mask;
26         const char *name;
27         FILE *file;
28 };
29
30 static int module_cmp(const void *p1, const void *p2, size_t size)
31 {
32         const firm_dbg_module_t *m1 = p1;
33         const firm_dbg_module_t *m2 = p2;
34         return strcmp(m1->name, m2->name);
35 }
36
37 static void firm_dbg_init(void)
38 {
39         obstack_init(&dbg_obst);
40         module_set = new_set(module_cmp, 16);
41 }
42
43 firm_dbg_module_t *firm_dbg_register(const char *name)
44 {
45         firm_dbg_module_t mod;
46         mod.mask = 0;
47         mod.name = name;
48         mod.file = stderr;
49
50         if(!module_set)
51                 firm_dbg_init();
52
53         return set_insert(module_set, &mod, sizeof(mod), HASH_STR(name, strlen(name)));
54 }
55
56 void firm_dbg_set_mask(firm_dbg_module_t *module, unsigned mask)
57 {
58         module->mask = mask;
59 }
60
61 unsigned firm_dbg_get_mask(const firm_dbg_module_t *module)
62 {
63         return module->mask;
64 }
65
66 void firm_dbg_set_file(firm_dbg_module_t *module, FILE *file)
67 {
68         module->file = file;
69 }
70
71 typedef struct _msg_info_t {
72         const char *msg;
73         const firm_dbg_module_t *mod;
74 } msg_info_t;
75
76 static void *make_msg_info(const firm_dbg_module_t *mod, const char *fmt, va_list args)
77 {
78         static const char msg_header[] = "%s(%d) %s: ";
79         msg_info_t *res = obstack_alloc(&dbg_obst, sizeof(*res));
80
81         obstack_grow(&dbg_obst, msg_header, sizeof(msg_header) - 1);
82         ir_obst_vprintf(&dbg_obst, fmt, args);
83         res->msg = obstack_finish(&dbg_obst);
84         res->mod = mod;
85         return res;
86 }
87
88 void *_firm_dbg_make_msg(const firm_dbg_module_t *mod, unsigned mask, const char *fmt, ...)
89 {
90         void *res = NULL;
91
92         if(mask == 0 || (mod->mask & mask)) {
93                 va_list args;
94                 va_start(args, fmt);
95                 res = make_msg_info(mod, fmt, args);
96                 va_end(args);
97         }
98
99         return res;
100 }
101
102 void _firm_dbg_print_msg(const char *filename, int line, const char *func, void *mi_ptr)
103 {
104         msg_info_t *mi = mi_ptr;
105         if(mi) {
106                 fprintf(mi->mod->file, mi->msg, filename, line, func);
107                 obstack_free(&dbg_obst, mi);
108         }
109 }