<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>config-loader-expat.c Source File</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.2.15 --> <center> <a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="modules.html">Modules</a> <a class="qindex" href="annotated.html">Data Structures</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Data Fields</a> <a class="qindex" href="pages.html">Related Pages</a> </center> <hr><h1>config-loader-expat.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font> 00002 <font class="comment">/* config-loader-expat.c expat XML loader</font> 00003 <font class="comment"> *</font> 00004 <font class="comment"> * Copyright (C) 2003 Red Hat, Inc.</font> 00005 <font class="comment"> *</font> 00006 <font class="comment"> * Licensed under the Academic Free License version 1.2</font> 00007 <font class="comment"> *</font> 00008 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font> 00009 <font class="comment"> * it under the terms of the GNU General Public License as published by</font> 00010 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font> 00011 <font class="comment"> * (at your option) any later version.</font> 00012 <font class="comment"> *</font> 00013 <font class="comment"> * This program is distributed in the hope that it will be useful,</font> 00014 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font> 00015 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</font> 00016 <font class="comment"> * GNU General Public License for more details.</font> 00017 <font class="comment"> *</font> 00018 <font class="comment"> * You should have received a copy of the GNU General Public License</font> 00019 <font class="comment"> * along with this program; if not, write to the Free Software</font> 00020 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</font> 00021 <font class="comment"> *</font> 00022 <font class="comment"> */</font> 00023 00024 <font class="preprocessor">#include "config-parser.h"</font> 00025 <font class="preprocessor">#include <dbus/dbus-internals.h></font> 00026 <font class="preprocessor">#include <expat.h></font> 00027 00028 <font class="keyword">static</font> XML_Memory_Handling_Suite memsuite = 00029 { 00030 dbus_malloc, 00031 dbus_realloc, 00032 dbus_free 00033 }; 00034 <a name="l00035"></a><a class="code" href="structExpatParseContext.html">00035</a> <font class="keyword">typedef</font> <font class="keyword">struct</font> 00036 <font class="keyword"></font>{ 00037 <a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser; 00038 <font class="keyword">const</font> <font class="keywordtype">char</font> *filename; 00039 <a class="code" href="structDBusString.html">DBusString</a> content; 00040 <a class="code" href="structDBusError.html">DBusError</a> *error; 00041 dbus_bool_t failed; 00042 } <a class="code" href="structExpatParseContext.html">ExpatParseContext</a>; 00043 00044 <font class="keyword">static</font> dbus_bool_t 00045 process_content (<a class="code" href="structExpatParseContext.html">ExpatParseContext</a> *context) 00046 { 00047 <font class="keywordflow">if</font> (context-><a class="code" href="structExpatParseContext.html#m4">failed</a>) 00048 <font class="keywordflow">return</font> FALSE; 00049 00050 <font class="keywordflow">if</font> (_dbus_string_get_length (&context-><a class="code" href="structExpatParseContext.html#m2">content</a>) > 0) 00051 { 00052 <font class="keywordflow">if</font> (!bus_config_parser_content (context-><a class="code" href="structExpatParseContext.html#m0">parser</a>, 00053 &context-><a class="code" href="structExpatParseContext.html#m2">content</a>, 00054 context-><a class="code" href="structExpatParseContext.html#m3">error</a>)) 00055 { 00056 context-><a class="code" href="structExpatParseContext.html#m4">failed</a> = TRUE; 00057 <font class="keywordflow">return</font> FALSE; 00058 } 00059 _dbus_string_set_length (&context-><a class="code" href="structExpatParseContext.html#m2">content</a>, 0); 00060 } 00061 00062 <font class="keywordflow">return</font> TRUE; 00063 } 00064 00065 <font class="keyword">static</font> <font class="keywordtype">void</font> 00066 expat_StartElementHandler (<font class="keywordtype">void</font> *userData, 00067 <font class="keyword">const</font> XML_Char *name, 00068 <font class="keyword">const</font> XML_Char **atts) 00069 { 00070 <a class="code" href="structExpatParseContext.html">ExpatParseContext</a> *context = userData; 00071 <font class="keywordtype">int</font> i; 00072 <font class="keywordtype">char</font> **names; 00073 <font class="keywordtype">char</font> **values; 00074 00075 <font class="comment">/* Expat seems to suck and can't abort the parse if we</font> 00076 <font class="comment"> * throw an error. Expat 2.0 is supposed to fix this.</font> 00077 <font class="comment"> */</font> 00078 <font class="keywordflow">if</font> (context-><a class="code" href="structExpatParseContext.html#m4">failed</a>) 00079 <font class="keywordflow">return</font>; 00080 00081 <font class="keywordflow">if</font> (!process_content (context)) 00082 <font class="keywordflow">return</font>; 00083 00084 <font class="comment">/* "atts" is key, value, key, value, NULL */</font> 00085 <font class="keywordflow">for</font> (i = 0; atts[i] != NULL; ++i) 00086 ; <font class="comment">/* nothing */</font> 00087 00088 _dbus_assert (i % 2 == 0); 00089 names = dbus_new0 (<font class="keywordtype">char</font> *, i / 2 + 1); 00090 values = dbus_new0 (<font class="keywordtype">char</font> *, i / 2 + 1); 00091 00092 <font class="keywordflow">if</font> (names == NULL || values == NULL) 00093 { 00094 dbus_set_error (context-><a class="code" href="structExpatParseContext.html#m3">error</a>, DBUS_ERROR_NO_MEMORY, NULL); 00095 context-><a class="code" href="structExpatParseContext.html#m4">failed</a> = TRUE; 00096 dbus_free (names); 00097 dbus_free (values); 00098 <font class="keywordflow">return</font>; 00099 } 00100 00101 i = 0; 00102 <font class="keywordflow">while</font> (atts[i] != NULL) 00103 { 00104 _dbus_assert (i % 2 == 0); 00105 names [i / 2] = (<font class="keywordtype">char</font>*) atts[i]; 00106 values[i / 2] = (<font class="keywordtype">char</font>*) atts[i+1]; 00107 00108 i += 2; 00109 } 00110 00111 <font class="keywordflow">if</font> (!bus_config_parser_start_element (context-><a class="code" href="structExpatParseContext.html#m0">parser</a>, 00112 name, 00113 (<font class="keyword">const</font> <font class="keywordtype">char</font> **) names, 00114 (<font class="keyword">const</font> <font class="keywordtype">char</font> **) values, 00115 context-><a class="code" href="structExpatParseContext.html#m3">error</a>)) 00116 { 00117 dbus_free (names); 00118 dbus_free (values); 00119 context-><a class="code" href="structExpatParseContext.html#m4">failed</a> = TRUE; 00120 <font class="keywordflow">return</font>; 00121 } 00122 00123 dbus_free (names); 00124 dbus_free (values); 00125 } 00126 00127 <font class="keyword">static</font> <font class="keywordtype">void</font> 00128 expat_EndElementHandler (<font class="keywordtype">void</font> *userData, 00129 <font class="keyword">const</font> XML_Char *name) 00130 { 00131 <a class="code" href="structExpatParseContext.html">ExpatParseContext</a> *context = userData; 00132 00133 <font class="keywordflow">if</font> (!process_content (context)) 00134 <font class="keywordflow">return</font>; 00135 00136 <font class="keywordflow">if</font> (!bus_config_parser_end_element (context-><a class="code" href="structExpatParseContext.html#m0">parser</a>, 00137 name, 00138 context-><a class="code" href="structExpatParseContext.html#m3">error</a>)) 00139 { 00140 context-><a class="code" href="structExpatParseContext.html#m4">failed</a> = TRUE; 00141 <font class="keywordflow">return</font>; 00142 } 00143 } 00144 00145 <font class="comment">/* s is not 0 terminated. */</font> 00146 <font class="keyword">static</font> <font class="keywordtype">void</font> 00147 expat_CharacterDataHandler (<font class="keywordtype">void</font> *userData, 00148 <font class="keyword">const</font> XML_Char *s, 00149 <font class="keywordtype">int</font> len) 00150 { 00151 <a class="code" href="structExpatParseContext.html">ExpatParseContext</a> *context = userData; 00152 <font class="keywordflow">if</font> (context-><a class="code" href="structExpatParseContext.html#m4">failed</a>) 00153 <font class="keywordflow">return</font>; 00154 00155 <font class="keywordflow">if</font> (!_dbus_string_append_len (&context-><a class="code" href="structExpatParseContext.html#m2">content</a>, 00156 s, len)) 00157 { 00158 dbus_set_error (context-><a class="code" href="structExpatParseContext.html#m3">error</a>, DBUS_ERROR_NO_MEMORY, NULL); 00159 context-><a class="code" href="structExpatParseContext.html#m4">failed</a> = TRUE; 00160 <font class="keywordflow">return</font>; 00161 } 00162 } 00163 00164 00165 <a class="code" href="structBusConfigParser.html">BusConfigParser</a>* 00166 bus_config_load (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *file, 00167 dbus_bool_t is_toplevel, 00168 <a class="code" href="structDBusError.html">DBusError</a> *error) 00169 { 00170 XML_Parser expat; 00171 <font class="keyword">const</font> <font class="keywordtype">char</font> *filename; 00172 <a class="code" href="structBusConfigParser.html">BusConfigParser</a> *parser; 00173 <a class="code" href="structExpatParseContext.html">ExpatParseContext</a> context; 00174 <a class="code" href="structDBusString.html">DBusString</a> dirname; 00175 00176 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00177 00178 parser = NULL; 00179 expat = NULL; 00180 context.<a class="code" href="structExpatParseContext.html#m3">error</a> = error; 00181 context.<a class="code" href="structExpatParseContext.html#m4">failed</a> = FALSE; 00182 00183 filename = _dbus_string_get_const_data (file); 00184 00185 <font class="keywordflow">if</font> (!_dbus_string_init (&context.<a class="code" href="structExpatParseContext.html#m2">content</a>)) 00186 { 00187 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00188 <font class="keywordflow">return</font> NULL; 00189 } 00190 00191 <font class="keywordflow">if</font> (!_dbus_string_init (&dirname)) 00192 { 00193 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00194 _dbus_string_free (&context.<a class="code" href="structExpatParseContext.html#m2">content</a>); 00195 <font class="keywordflow">return</font> NULL; 00196 } 00197 00198 expat = XML_ParserCreate_MM (<font class="stringliteral">"UTF-8"</font>, &memsuite, NULL); 00199 <font class="keywordflow">if</font> (expat == NULL) 00200 { 00201 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00202 <font class="keywordflow">goto</font> failed; 00203 } 00204 00205 <font class="keywordflow">if</font> (!_dbus_string_get_dirname (file, &dirname)) 00206 { 00207 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00208 <font class="keywordflow">goto</font> failed; 00209 } 00210 00211 parser = bus_config_parser_new (&dirname, is_toplevel); 00212 <font class="keywordflow">if</font> (parser == NULL) 00213 { 00214 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00215 <font class="keywordflow">goto</font> failed; 00216 } 00217 context.<a class="code" href="structExpatParseContext.html#m0">parser</a> = parser; 00218 00219 XML_SetUserData (expat, &context); 00220 XML_SetElementHandler (expat, 00221 expat_StartElementHandler, 00222 expat_EndElementHandler); 00223 XML_SetCharacterDataHandler (expat, 00224 expat_CharacterDataHandler); 00225 00226 { 00227 <a class="code" href="structDBusString.html">DBusString</a> data; 00228 <font class="keyword">const</font> <font class="keywordtype">char</font> *data_str; 00229 00230 <font class="keywordflow">if</font> (!_dbus_string_init (&data)) 00231 { 00232 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00233 <font class="keywordflow">goto</font> failed; 00234 } 00235 00236 <font class="keywordflow">if</font> (!_dbus_file_get_contents (&data, file, error)) 00237 { 00238 _dbus_string_free (&data); 00239 <font class="keywordflow">goto</font> failed; 00240 } 00241 00242 data_str = _dbus_string_get_const_data (&data); 00243 00244 <font class="keywordflow">if</font> (!XML_Parse (expat, data_str, _dbus_string_get_length (&data), TRUE)) 00245 { 00246 <font class="keywordflow">if</font> (context.<a class="code" href="structExpatParseContext.html#m3">error</a> != NULL && 00247 !dbus_error_is_set (context.<a class="code" href="structExpatParseContext.html#m3">error</a>)) 00248 { 00249 <font class="keyword">enum</font> XML_Error e; 00250 00251 e = XML_GetErrorCode (expat); 00252 <font class="keywordflow">if</font> (e == XML_ERROR_NO_MEMORY) 00253 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00254 <font class="keywordflow">else</font> 00255 dbus_set_error (error, DBUS_ERROR_FAILED, 00256 <font class="stringliteral">"Error in file %s, line %d, column %d: %s\n"</font>, 00257 filename, 00258 XML_GetCurrentLineNumber (expat), 00259 XML_GetCurrentColumnNumber (expat), 00260 XML_ErrorString (e)); 00261 } 00262 00263 _dbus_string_free (&data); 00264 <font class="keywordflow">goto</font> failed; 00265 } 00266 00267 _dbus_string_free (&data); 00268 00269 <font class="keywordflow">if</font> (context.<a class="code" href="structExpatParseContext.html#m4">failed</a>) 00270 <font class="keywordflow">goto</font> failed; 00271 } 00272 00273 <font class="keywordflow">if</font> (!bus_config_parser_finished (parser, error)) 00274 <font class="keywordflow">goto</font> failed; 00275 00276 _dbus_string_free (&dirname); 00277 _dbus_string_free (&context.<a class="code" href="structExpatParseContext.html#m2">content</a>); 00278 XML_ParserFree (expat); 00279 00280 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00281 <font class="keywordflow">return</font> parser; 00282 00283 failed: 00284 _DBUS_ASSERT_ERROR_IS_SET (error); 00285 00286 _dbus_string_free (&dirname); 00287 _dbus_string_free (&context.<a class="code" href="structExpatParseContext.html#m2">content</a>); 00288 <font class="keywordflow">if</font> (expat) 00289 XML_ParserFree (expat); 00290 <font class="keywordflow">if</font> (parser) 00291 bus_config_parser_unref (parser); 00292 <font class="keywordflow">return</font> NULL; 00293 } </pre></div><hr><address align="right"><small>Generated on Mon Sep 29 21:30:59 2003 for D-BUS by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border=0 width=110 height=53></a>1.2.15 </small></address> </body> </html>