4 * Runtime and assembly configuration file support routines.
6 * Author: Paolo Molaro (lupus@ximian.com)
8 * (C) 2002 Ximian, Inc.
13 #include "mono/metadata/loader.h"
14 #include "mono/metadata/mono-config.h"
16 static void start_element (GMarkupParseContext *context,
17 const gchar *element_name,
18 const gchar **attribute_names,
19 const gchar **attribute_values,
23 static void end_element (GMarkupParseContext *context,
24 const gchar *element_name,
28 static void parse_text (GMarkupParseContext *context,
34 static void passthrough (GMarkupParseContext *context,
40 static void parse_error (GMarkupParseContext *context,
44 static const GMarkupParser
53 static GHashTable *config_handlers;
55 /* when this interface is stable, export it. */
56 typedef struct MonoParseHandler MonoParseHandler;
58 struct MonoParseHandler {
59 const char *element_name;
60 void*(*init) (MonoImage *assembly);
61 void (*start) (gpointer user_data, const gchar *name,
62 const gchar **attributes,
63 const gchar **values);
64 void (*text) (gpointer user_data, const char *text, gsize test_len);
65 void (*end) (gpointer user_data, const char *name);
66 void (*finish) (gpointer user_data);
70 MonoParseHandler *current;
76 static void start_element (GMarkupParseContext *context,
77 const gchar *element_name,
78 const gchar **attribute_names,
79 const gchar **attribute_values,
83 ParseState *state = user_data;
84 if (!state->current) {
85 state->current = g_hash_table_lookup (config_handlers, element_name);
86 if (state->current && state->current->init)
87 state->user_data = state->current->init (state->assembly);
89 if (state->current && state->current->start)
90 state->current->start (state->user_data, element_name, attribute_names, attribute_values);
93 static void end_element (GMarkupParseContext *context,
94 const gchar *element_name,
98 ParseState *state = user_data;
100 if (state->current->end)
101 state->current->end (state->user_data, element_name);
102 if (strcmp (state->current->element_name, element_name) == 0) {
103 if (state->current->finish)
104 state->current->finish (state->user_data);
105 state->current = NULL;
106 state->user_data = NULL;
111 static void parse_text (GMarkupParseContext *context,
117 ParseState *state = user_data;
118 if (state->current && state->current->text)
119 state->current->text (state->user_data, text, text_len);
122 static void passthrough (GMarkupParseContext *context,
131 static void parse_error (GMarkupParseContext *context,
144 dllmap_init (MonoImage *assembly) {
145 DllInfo *info = g_new0 (DllInfo, 1);
146 info->assembly = assembly;
151 dllmap_start (gpointer user_data,
152 const gchar *element_name,
153 const gchar **attribute_names,
154 const gchar **attribute_values)
157 DllInfo *info = user_data;
159 if (strcmp (element_name, "dllmap") == 0) {
161 g_free (info->target);
162 info->dll = info->target = NULL;
163 for (i = 0; attribute_names [i]; ++i) {
164 if (strcmp (attribute_names [i], "dll") == 0)
165 info->dll = g_strdup (attribute_values [i]);
166 else if (strcmp (attribute_names [i], "target") == 0)
167 info->target = g_strdup (attribute_values [i]);
169 mono_dllmap_insert (info->assembly, info->dll, NULL, info->target, NULL);
170 } else if (strcmp (element_name, "dllentry") == 0) {
171 const char *name = NULL, *target = NULL, *dll = NULL;
172 for (i = 0; attribute_names [i]; ++i) {
173 if (strcmp (attribute_names [i], "dll") == 0)
174 dll = attribute_values [i];
175 else if (strcmp (attribute_names [i], "target") == 0)
176 target = attribute_values [i];
177 else if (strcmp (attribute_names [i], "name") == 0)
178 name = attribute_values [i];
182 mono_dllmap_insert (info->assembly, info->dll, name, dll, target);
187 dllmap_finish (gpointer user_data)
189 DllInfo *info = user_data;
192 g_free (info->target);
196 static const MonoParseHandler
206 static int inited = 0;
209 mono_config_init (void)
212 config_handlers = g_hash_table_new (g_str_hash, g_str_equal);
213 g_hash_table_insert (config_handlers, (gpointer) dllmap_handler.element_name, (gpointer) &dllmap_handler);
216 /* FIXME: error handling */
218 /* If assembly is NULL, parse in the global context */
220 mono_config_parse_file_with_context (ParseState *state, const char *filename)
222 GMarkupParseContext *context;
229 if (!g_file_get_contents (filename, &text, &len, NULL))
231 context = g_markup_parse_context_new (&mono_parser, 0, state, NULL);
232 if (g_markup_parse_context_parse (context, text, len, NULL)) {
233 g_markup_parse_context_end_parse (context, NULL);
235 g_markup_parse_context_free (context);
241 mono_config_parse_file (const char *filename)
243 ParseState state = {NULL};
244 mono_config_parse_file_with_context (&state, filename);
248 * use the equivalent lookup code from the GAC when available.
249 * Depending on state, this should give something like:
250 * aname/version-pubtoken/
255 get_assembly_filename (MonoImage *image, int state)
259 return g_strdup (image->assembly_name);
266 mono_config_for_assembly (MonoImage *assembly)
268 ParseState state = {NULL};
270 char *aname, *cfg, *cfg_name;
273 state.assembly = assembly;
274 cfg_name = g_strdup_printf ("%s.config", assembly->name);
275 mono_config_parse_file_with_context (&state, cfg_name);
278 cfg_name = g_strdup_printf ("%s.config", assembly->assembly_name);
280 home = g_get_home_dir ();
282 for (i = 0; (aname = get_assembly_filename (assembly, i)) != NULL; ++i) {
283 cfg = g_build_filename (mono_get_config_dir (), "mono", "assemblies", aname, cfg_name, NULL);
284 got_it += mono_config_parse_file_with_context (&state, cfg);
287 #ifndef PLATFORM_WIN32
288 cfg = g_build_filename (home, ".mono", "assemblies", aname, cfg_name, NULL);
289 got_it += mono_config_parse_file_with_context (&state, cfg);
300 * Pass a NULL filename to parse the default config files
301 * (or the file in the MONO_CONFIG env var).
304 mono_config_parse (const char *filename) {
310 mono_config_parse_file (filename);
314 home = g_getenv ("MONO_CONFIG");
316 mono_config_parse_file (home);
320 mono_cfg = g_build_filename (mono_get_config_dir (), "mono", "config", NULL);
321 mono_config_parse_file (mono_cfg);
324 #ifndef PLATFORM_WIN32
325 home = g_get_home_dir ();
326 user_cfg = g_strconcat (home, G_DIR_SEPARATOR_S, ".mono/config", NULL);
327 mono_config_parse_file (user_cfg);
332 static char *mono_cfg_dir = NULL;
335 mono_install_get_config_dir (void)
337 #ifdef PLATFORM_WIN32
341 mono_cfg_dir = g_getenv ("MONO_CFG_DIR");
344 #ifndef PLATFORM_WIN32
345 mono_cfg_dir = MONO_CFG_DIR;
347 prefix = g_path_get_dirname (mono_assembly_getrootdir ());
348 mono_cfg_dir = g_build_filename (prefix, "etc", NULL);
355 mono_get_config_dir (void)
358 mono_install_get_config_dir ();