* TextBoxTest: More of these tests work now.
[mono-project.git] / mono / utils / mono-logger.c
blob11162fc19fdea26aed66671c403af632d2a31a2d
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <glib.h>
6 #include "mono-logger.h"
8 typedef struct {
9 GLogLevelFlags level;
10 MonoTraceMask mask;
11 } MonoLogLevelEntry;
13 static GLogLevelFlags current_level = G_LOG_LEVEL_ERROR;
14 static MonoTraceMask current_mask = MONO_TRACE_ALL;
16 static const char *mono_log_domain = "Mono";
17 static GQueue *level_stack = NULL;
19 /**
20 * mono_trace_init:
22 * Initializes the mono tracer.
24 static void
25 mono_trace_init (void)
27 if(level_stack == NULL) {
28 level_stack = g_queue_new();
30 mono_trace_set_mask_string(getenv("MONO_LOG_MASK"));
31 mono_trace_set_level_string(getenv("MONO_LOG_LEVEL"));
35 /**
36 * mono_trace_cleanup:
38 * Releases the mono tracer.
40 void
41 mono_trace_cleanup (void)
43 if(level_stack != NULL) {
44 while(!g_queue_is_empty (level_stack)) {
45 g_free (g_queue_pop_head (level_stack));
48 g_queue_free (level_stack);
49 level_stack = NULL;
53 /**
54 * mono_trace:
56 * @level: Verbose level of the specified message
57 * @mask: Type of the specified message
59 * Traces a new message, depending on the current logging level
60 * and trace mask.
62 void
63 mono_trace(GLogLevelFlags level, MonoTraceMask mask, const char *format, ...)
65 if(level_stack == NULL)
66 mono_trace_init();
68 if(level <= current_level && mask & current_mask) {
69 va_list args;
70 va_start (args, format);
71 g_logv (mono_log_domain, level, format, args);
72 va_end (args);
76 /**
77 * mono_tracev:
79 * @level: Verbose level of the specified message
80 * @mask: Type of the specified message
82 * Traces a new message, depending on the current logging level
83 * and trace mask.
85 void
86 mono_tracev (GLogLevelFlags level, MonoTraceMask mask, const char *format, va_list args)
88 if (level_stack == NULL)
89 mono_trace_init ();
91 if(level <= current_level && mask & current_mask)
92 g_logv (mono_log_domain, level, format, args);
95 /**
96 * mono_trace_set_level:
98 * @level: Verbose level to set
100 * Sets the current logging level. Every subsequent call to
101 * mono_trace will check the visibility of a message against this
102 * value.
104 void
105 mono_trace_set_level (GLogLevelFlags level)
107 if(level_stack == NULL)
108 mono_trace_init();
110 current_level = level;
114 * mono_trace_set_mask:
116 * @mask: Mask of visible message types.
118 * Sets the current logging level. Every subsequent call to
119 * mono_trace will check the visibility of a message against this
120 * value.
122 void
123 mono_trace_set_mask (MonoTraceMask mask)
125 if(level_stack == NULL)
126 mono_trace_init();
128 current_mask = mask;
132 * mono_trace_push:
134 * @level: Verbose level to set
135 * @mask: Mask of visible message types.
137 * Saves the current values of level and mask then calls mono_trace_set
138 * with the specified new values.
140 void
141 mono_trace_push (GLogLevelFlags level, MonoTraceMask mask)
143 if(level_stack == NULL)
144 g_error(G_GNUC_PRETTY_FUNCTION ": cannot use mono_trace_push without calling mono_trace_init first.");
145 else {
146 MonoLogLevelEntry *entry = g_malloc(sizeof(MonoLogLevelEntry));
147 entry->level = current_level;
148 entry->mask = current_mask;
150 g_queue_push_head (level_stack, (gpointer)entry);
152 /* Set the new level and mask
154 current_level = level;
155 current_mask = mask;
160 * mono_trace_pop:
162 * Restores level and mask values saved from a previous call to mono_trace_push.
164 void
165 mono_trace_pop (void)
167 if(level_stack == NULL)
168 g_error(G_GNUC_PRETTY_FUNCTION ": cannot use mono_trace_pop without calling mono_trace_init first.");
169 else {
170 if(!g_queue_is_empty (level_stack)) {
171 MonoLogLevelEntry *entry = (MonoLogLevelEntry*)g_queue_pop_head (level_stack);
173 /* Restore previous level and mask
175 current_level = entry->level;
176 current_mask = entry->mask;
178 g_free (entry);
184 void
185 mono_trace_set_level_string (const char *value)
187 int i = 0;
188 const char *valid_vals[] = {"error", "critical", "warning", "message", "info", "debug", NULL};
189 const GLogLevelFlags valid_ids[] = {G_LOG_LEVEL_ERROR, G_LOG_LEVEL_CRITICAL, G_LOG_LEVEL_WARNING,
190 G_LOG_LEVEL_MESSAGE, G_LOG_LEVEL_INFO, G_LOG_LEVEL_DEBUG };
192 if(!value)
193 return;
195 while(valid_vals[i]) {
196 if(!strcmp(valid_vals[i], value)){
197 mono_trace_set_level(valid_ids[i]);
198 return;
200 i++;
203 if(*value)
204 g_print("Unknown trace loglevel: %s\n", value);
207 void
208 mono_trace_set_mask_string (char *value)
210 int i;
211 char *tok;
212 guint32 flags = 0;
214 const char *valid_flags[] = {"asm", "type", "dll", "gc", "cfg", "aot", "all", NULL};
215 const MonoTraceMask valid_masks[] = {MONO_TRACE_ASSEMBLY, MONO_TRACE_TYPE, MONO_TRACE_DLLIMPORT,
216 MONO_TRACE_GC, MONO_TRACE_CONFIG, MONO_TRACE_AOT, MONO_TRACE_ALL };
218 if(!value)
219 return;
221 tok = strtok (value, ",");
223 if(!tok)
224 tok = value;
226 while (tok) {
227 for (i = 0; valid_flags[i]; i++) {
228 if (strcmp (tok, valid_flags[i]) == 0) {
229 flags |= valid_masks[i];
230 break;
233 if (!valid_flags[i])
234 g_print("Unknown trace flag: %s\n", tok);
236 tok = strtok (NULL, ",");
239 if(flags)
240 mono_trace_set_mask (flags);
244 * mono_trace_is_traced:
246 * Returns whenever a message with @level and @mask will be printed or not.
248 gboolean
249 mono_trace_is_traced (GLogLevelFlags level, MonoTraceMask mask)
251 return (level <= current_level && mask & current_mask);