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