more firm_config includes removed
[libfirm] / ir / common / debug.c
1 /*
2  * Copyright (C) 1995-2008 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 #ifdef DEBUG_libfirm
32
33 #include <stdarg.h>
34 #include <string.h>
35
36 #include "irprintf.h"
37 #include "debug.h"
38
39 #include "hashptr.h"
40 #include "obst.h"
41 #include "set.h"
42
43 static struct obstack dbg_obst;
44 static set *module_set;
45
46 /**
47  * A debug module.
48  */
49 struct _firm_dbg_module_t {
50   unsigned mask;
51   const char *name;
52   FILE *file;
53 };
54
55 /**
56  * Compares two modules by comparing it's names
57  */
58 static int module_cmp(const void *p1, const void *p2, size_t size)
59 {
60   const firm_dbg_module_t *m1 = p1;
61   const firm_dbg_module_t *m2 = p2;
62   (void) size;
63
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 #else /* DEBUG_libfirm */
169
170 /* some picky compiler don't allow empty files */
171 static int __attribute__((unused)) dummy;
172
173 #endif /* DEBUG_libfirm */