always use firm builtin debug facilities (libcore ones are more or less a copy of...
[libfirm] / ir / common / debug.c
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   Debug facility.
23  * @author  Michael Beck, Sebastian Hack
24  * @date    15.12.2004
25  * @version $Id$
26  */
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "firm_config.h"
32
33 #ifdef DEBUG_libfirm
34
35 #include <stdarg.h>
36 #include <string.h>
37
38 #include "irprintf.h"
39 #include "debug.h"
40
41 #include "hashptr.h"
42 #include "obst.h"
43 #include "set.h"
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   (void) size;
65
66   return strcmp(m1->name, m2->name);
67 }
68
69 /**
70  * initialize the debug module
71  */
72 static void firm_dbg_init(void)
73 {
74   obstack_init(&dbg_obst);
75   module_set = new_set(module_cmp, 16);
76 }
77
78 firm_dbg_module_t *firm_dbg_register(const char *name)
79 {
80   firm_dbg_module_t mod;
81   mod.mask = 0;
82   mod.name = name;
83   mod.file = stderr;
84
85   if(!module_set)
86     firm_dbg_init();
87
88   return set_insert(module_set, &mod, sizeof(mod), HASH_STR(name, strlen(name)));
89 }
90
91 void firm_dbg_set_mask(firm_dbg_module_t *module, unsigned mask)
92 {
93   module->mask = mask;
94 }
95
96 unsigned firm_dbg_get_mask(const firm_dbg_module_t *module)
97 {
98   return module->mask;
99 }
100
101 void firm_dbg_set_file(firm_dbg_module_t *module, FILE *file)
102 {
103   module->file = file;
104 }
105
106 /**
107  * A message info: a pair of debug handle and message
108  */
109 typedef struct _msg_info_t {
110   const char *msg;
111   const firm_dbg_module_t *mod;
112 } msg_info_t;
113
114 /**
115  * Formats a message given by a printf-like format and a va_list argument,
116  * puts the test on an obstack and return a msg_info.
117  */
118 static void *make_msg_info(const firm_dbg_module_t *mod, const char *fmt, va_list args)
119 {
120   static const char msg_header[] = "%s(%d) %s: ";
121   msg_info_t *res = obstack_alloc(&dbg_obst, sizeof(*res));
122
123   obstack_grow(&dbg_obst, msg_header, sizeof(msg_header) - 1);
124   ir_obst_vprintf(&dbg_obst, fmt, args);
125   obstack_1grow(&dbg_obst, '\0');
126
127   res->msg = obstack_finish(&dbg_obst);
128   res->mod = mod;
129   return res;
130 }
131
132 void *_firm_dbg_make_msg(const firm_dbg_module_t *mod, unsigned mask, const char *fmt, ...)
133 {
134   void *res = NULL;
135
136   if(mask == 0 || (mod->mask & mask)) {
137     va_list args;
138     va_start(args, fmt);
139     res = make_msg_info(mod, fmt, args);
140     va_end(args);
141   }
142
143   return res;
144 }
145
146 void _firm_dbg_print_msg(const char *filename, int line, const char *func, void *mi_ptr)
147 {
148   msg_info_t *mi = mi_ptr;
149   if(mi) {
150     fprintf(mi->mod->file, mi->msg, filename, line, func);
151     obstack_free(&dbg_obst, mi);
152   }
153 }
154
155 void _firm_dbg_print(const firm_dbg_module_t *mod, unsigned mask, const char *fmt, ...)
156 {
157   if(mask == 0 || (mod->mask & mask)) {
158     va_list args;
159     char *res;
160     va_start(args, fmt);
161     ir_obst_vprintf(&dbg_obst, fmt, args);
162     obstack_1grow(&dbg_obst, '\0');
163     res = obstack_finish(&dbg_obst);
164     fprintf(mod->file, res);
165     obstack_free(&dbg_obst, res);
166     va_end(args);
167   }
168 }
169
170 #else /* DEBUG_libfirm */
171
172 /* some picky compiler don't allow empty files */
173 static int __attribute__((unused)) dummy;
174
175 #endif /* DEBUG_libfirm */