1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* config-loader-expat.c expat XML loader
4 * Copyright (C) 2003 Red Hat, Inc.
6 * Licensed under the Academic Free License version 1.2
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "config-parser.h"
25 #include <dbus/dbus-internals.h>
29 expat_malloc (size_t size)
31 return dbus_malloc (size);
35 expat_realloc (void *ptr, size_t size)
37 return dbus_realloc (ptr, size);
41 expat_free (void *ptr)
46 static XML_Memory_Handling_Suite memsuite =
55 BusConfigParser *parser;
63 expat_StartElementHandler (void *userData,
65 const XML_Char **atts)
67 ExpatParseContext *context = userData;
72 /* Expat seems to suck and can't abort the parse if we
73 * throw an error. Expat 2.0 is supposed to fix this.
78 /* "atts" is key, value, key, value, NULL */
79 for (i = 0; atts[i] != NULL; ++i)
82 _dbus_assert (i % 2 == 0);
83 names = dbus_new0 (char *, i / 2 + 1);
84 values = dbus_new0 (char *, i / 2 + 1);
86 if (names == NULL || values == NULL)
88 dbus_set_error (context->error, DBUS_ERROR_NO_MEMORY, NULL);
89 context->failed = TRUE;
96 while (atts[i] != NULL)
98 _dbus_assert (i % 2 == 0);
99 names [i / 2] = (char*) atts[i];
100 values[i / 2 + 1] = (char*) atts[i+1];
105 if (!bus_config_parser_start_element (context->parser,
107 (const char **) names,
108 (const char **) values,
113 context->failed = TRUE;
122 expat_EndElementHandler (void *userData,
123 const XML_Char *name)
125 ExpatParseContext *context = userData;
129 if (_dbus_string_get_length (&context->content) > 0)
131 if (!bus_config_parser_content (context->parser,
135 context->failed = TRUE;
138 _dbus_string_set_length (&context->content, 0);
141 if (!bus_config_parser_end_element (context->parser,
145 context->failed = TRUE;
150 /* s is not 0 terminated. */
152 expat_CharacterDataHandler (void *userData,
156 ExpatParseContext *context = userData;
160 if (!_dbus_string_append_len (&context->content,
163 dbus_set_error (context->error, DBUS_ERROR_NO_MEMORY, NULL);
164 context->failed = TRUE;
171 bus_config_load (const DBusString *file,
175 const char *filename;
176 BusConfigParser *parser;
177 ExpatParseContext context;
179 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
183 context.error = error;
184 context.failed = FALSE;
186 _dbus_string_get_const_data (file, &filename);
188 if (!_dbus_string_init (&context.content, _DBUS_INT_MAX))
190 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
194 expat = XML_ParserCreate_MM ("UTF-8", &memsuite, NULL);
197 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
201 parser = bus_config_parser_new ();
204 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
208 XML_SetUserData (expat, &context);
209 XML_SetElementHandler (expat,
210 expat_StartElementHandler,
211 expat_EndElementHandler);
212 XML_SetCharacterDataHandler (expat,
213 expat_CharacterDataHandler);
217 const char *data_str;
219 if (!_dbus_string_init (&data, _DBUS_INT_MAX))
221 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
225 if (!_dbus_file_get_contents (&data, file, error))
227 _dbus_string_free (&data);
231 _dbus_string_get_const_data (&data, &data_str);
233 if (!XML_Parse (expat, data_str, _dbus_string_get_length (&data), TRUE))
235 if (context.error != NULL &&
236 !dbus_error_is_set (context.error))
240 e = XML_GetErrorCode (expat);
241 if (e == XML_ERROR_NO_MEMORY)
242 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
244 dbus_set_error (error, DBUS_ERROR_FAILED,
245 "Error in file %s, line %d, column %d: %s\n",
247 XML_GetCurrentLineNumber (expat),
248 XML_GetCurrentColumnNumber (expat),
249 XML_ErrorString (e));
252 _dbus_string_free (&data);
256 _dbus_string_free (&data);
262 if (!bus_config_parser_finished (parser, error))
265 _dbus_string_free (&context.content);
266 XML_ParserFree (expat);
268 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
272 _DBUS_ASSERT_ERROR_IS_SET (error);
274 _dbus_string_free (&context.content);
276 XML_ParserFree (expat);
278 bus_config_parser_unref (parser);