/[splashy]/trunk/src/xml_parser.c
ViewVC logotype

Contents of /trunk/src/xml_parser.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 214 - (show annotations) (download)
Sun Apr 17 18:28:30 2005 UTC (8 years, 1 month ago) by lemsx1
File MIME type: text/plain
File size: 11238 byte(s)
saves the new start of the lists
1 /**********************************************************************
2 * xml_parser.cc
3 *
4 * 2005-04-15 18:58 EDT
5 * Copyright 2005 Luis Mondesi <lemsx1@gmail.com>
6 **********************************************************************/
7
8 /*
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24 #define DEBUG 1
25
26 #include <stdio.h>
27 #include <glib.h>
28
29 #include "common_macros.h"
30 #include "xml_parser.h"
31
32 static gchar* default_filename = SPLASHY_CONFIG_FILE; /* default filename */
33
34 static int depth = 0;
35
36 /**
37 * @desc used by spl_get_text when finding tag names in nodes
38 */
39 typedef struct _tag_text {
40 GString* tag;
41 const gchar* text;
42 } TagText;
43
44 /* private functions */
45 static void
46 start_element_handler (GMarkupParseContext *context,
47 const gchar *element_name,
48 const gchar **attribute_names,
49 const gchar **attribute_values,
50 gpointer user_data,
51 GError **error)
52 {
53 g_return_if_fail ( element_name != NULL );
54
55 DEBUG_PRINT ("ELEMENT: '%s'", element_name);
56
57 gint i = 0;
58
59 /* use _list alias for gpointer user_data. less typing */
60
61 GList* _list = (GList*) user_data;
62
63 /* create bucket for this node */
64 SplashyXMLNode* _node = g_new0 ( SplashyXMLNode,1 );
65 /* save name */
66 _node->name = g_string_new(element_name);
67 /* init text to nothing. we will get this later */
68 _node->text = NULL;
69 /* create bucket for attributes */
70 _node->attrs = g_new0( GList,1 );
71 /* save our depth. we might need this later... */
72 _node->depth=depth;
73 /* make some assumptions */
74 _node->got_attr=FALSE;
75 _node->got_text=FALSE;
76
77 /* if attributes are found, save for future reference */
78 if ( attribute_names[0] != NULL )
79 {
80 _node->got_attr=TRUE;
81 }
82
83 while ( _node->got_attr && attribute_names[i] != NULL)
84 {
85 DEBUG_PRINT ( "NAME: %s", attribute_names[i] );
86 DEBUG_PRINT ( "VALUE: %s", attribute_values[i] );
87 SplashyXMLAttr* _attr = g_new0 ( SplashyXMLAttr,1 );
88 _attr->name = g_string_new(attribute_names[i]);
89 _attr->value = g_string_new(attribute_values[i]);
90 _node->attrs = g_list_append( _node->attrs,(gpointer)_attr );
91 ++i;
92 }
93 ++depth;
94 splashy_xml_config->priv = g_list_append( _list,(gpointer)_node );
95 }
96
97 static void
98 end_element_handler (GMarkupParseContext *context,
99 const gchar *element_name,
100 gpointer user_data,
101 GError **error)
102 {
103 --depth;
104 DEBUG_PRINT ("END: '%s'", element_name);
105 }
106
107 static void
108 text_handler (GMarkupParseContext *context,
109 const gchar *text,
110 gsize text_len,
111 gpointer user_data,
112 GError **error)
113 {
114 g_return_if_fail ( text_len > 0 );
115 //g_return_if_fail ( g_ascii_strncasecmp(text,'\0',1) == 0 );
116
117 /* NOTE
118 * Strings parse by gmarkup parser are not nul-terminated!
119 */
120
121 DEBUG_PRINT ("TEXT: '%s'", text);
122
123 GList* _list = (GList *) user_data;
124
125 /* assume that only one thread of this program is running,
126 * then the last node appended to the list _list is the
127 * tag for which we will be saving our text
128 * TODO find a better way to do this (if any)
129 */
130 GList* _last_node = NULL;
131 _last_node = g_list_last( _list );
132 if ( _last_node != NULL )
133 {
134 SplashyXMLNode* _splashy_node = (SplashyXMLNode *)_last_node->data;
135 _splashy_node->text= g_string_new(text);
136
137 /*
138 if ( _is_valid_char(text) )
139 {
140 _splashy_node->got_text = TRUE;
141 }
142 */
143
144 DEBUG_PRINT ("text_handler() _last_node Tag '%s'",_splashy_node->name->str);
145 DEBUG_PRINT ("text_handler() _last_node Text '%s'",_splashy_node->text->str);
146 }
147 }
148
149 static void
150 passthrough_handler (GMarkupParseContext *context,
151 const gchar *passthrough_text,
152 gsize text_len,
153 gpointer user_data,
154 GError **error)
155 {
156 DEBUG_PRINT ("PASS: '%s'", passthrough_text);
157 }
158
159 static void
160 error_handler (GMarkupParseContext *context,
161 GError *error,
162 gpointer user_data)
163 {
164 fprintf (stderr, "ERROR: %s\n", error->message);
165 }
166
167 /* our parser */
168 static GMarkupParser parser = {
169 start_element_handler,
170 end_element_handler,
171 text_handler,
172 passthrough_handler,
173 error_handler
174 };
175
176 /**
177 * @ingroup core
178 * Slurps all tags from a given filename
179 * @arg _filename filename path to read
180 * @return true on success
181 */
182 gboolean
183 _read()
184 {
185 g_return_val_if_fail( splashy_xml_config != NULL, FALSE);
186
187 DEBUG_PRINT ( "ENTERING read(%s)",splashy_xml_config->config_path->str );
188 gchar *contents;
189 gsize length;
190 GError *error;
191 GMarkupParseContext *context;
192
193 error = NULL;
194
195 if (!g_file_get_contents (splashy_xml_config->config_path->str,
196 &contents,
197 &length,
198 &error))
199 {
200 fprintf (stderr, "%s\n", error->message);
201 g_error_free (error);
202 return FALSE;
203 }
204
205 context = g_markup_parse_context_new (&parser, 0,
206 splashy_xml_config->priv, NULL);
207
208 if (!g_markup_parse_context_parse (context, contents, length, NULL))
209 {
210 g_markup_parse_context_free (context);
211 return FALSE;
212 }
213
214 if (!g_markup_parse_context_end_parse (context, NULL))
215 {
216 g_markup_parse_context_free (context);
217 return FALSE;
218 }
219 g_markup_parse_context_free (context);
220
221 /* FIXME g_free(contents); */
222
223 /* now we have all the 'contents' we wanted */
224 DEBUG_PRINT ( "EXITING _read(%s)","" );
225 return TRUE; /* assuming that if we reach here, no error happend */
226 }
227
228 /**
229 * @ingroup core
230 * Initializes a SplashyConfig struct using _filename as config file
231 * @arg _filename filename path to read
232 * @return true on success
233 */
234 gboolean
235 init_config(const gchar* _filename)
236 {
237 DEBUG_PRINT ( "ENTERING init_config(%s)",_filename );
238 /* sanity check */
239 if ( splashy_xml_config ) return TRUE; /* splashy_xml_config has been initialized */
240 DEBUG_PRINT ( "CREATING SplashyConfig %s","" );
241 /* use our default struct. @see xml_parser.h */
242 splashy_xml_config = g_new0( SplashyConfig,1 );
243 splashy_xml_config->config_path= g_string_new(_filename);
244
245 DEBUG_PRINT ( "CREATING GList %s","" );
246 splashy_xml_config->priv = g_new0( GList,1 );
247
248 /* slurp our config file to splashy_xml_config */
249 return _read();
250 }
251
252 gint
253 _comp_node_to_tag(gconstpointer node, gconstpointer tag)
254 {
255
256 /* sanity checks:
257 * 1. test if the node is valid
258 * 2. test if the tag is valid
259 */
260 g_return_val_if_fail( (GList*)node != NULL,1 );
261 g_return_val_if_fail( ((GList*)node)->data != NULL,1 );
262 g_return_val_if_fail( ((SplashyXMLNode*)((GList*)node)->data)->name != NULL,1 );
263 g_return_val_if_fail( (GString*)tag != NULL,1 );
264
265 GString* _name = NULL;
266 _name = ((SplashyXMLNode*)((GList*)node)->data)->name;
267
268 DEBUG_PRINT ( "_comp_node_to_tag name %s",_name->str );
269
270 if ( g_string_equal ( tag,_name ) )
271 {
272 DEBUG_PRINT ( "EXITING _comp_node_to_tag(%s)","TRUE" );
273 return 0; /* matched */
274 }
275
276 DEBUG_PRINT ( "EXITING _comp_node_to_tag(%s)","FALSE" );
277 return 1; /* didn't match */
278 }
279
280 /**
281 * @desc debugging function
282 */
283 void
284 spl_print_element ( gpointer data, gpointer user_data)
285 {
286 g_return_if_fail ( (GList*)data != NULL );
287
288 SplashyXMLNode* _splashy_node = (SplashyXMLNode*) data;
289
290 g_return_if_fail ( _splashy_node != NULL );
291 g_return_if_fail ( _splashy_node->name != NULL );
292 g_return_if_fail ( _splashy_node->text != NULL );
293
294 g_print("TAG '%s'\n", _splashy_node->name->str);
295 g_print("VAL '%s'\n", _splashy_node->text->str);
296
297 GString* _tag = ((TagText*)user_data)->tag;
298 GString* _name_tag = _splashy_node->name;
299
300 const gchar* debug_text = "yoohoo"; /* FIXME */
301
302 if ( g_string_equal (_tag,_name_tag) )
303 {
304 g_print( "%s==%s\n",_tag->str,_name_tag->str);
305 ((TagText*)user_data)->text = g_strdup(debug_text); // _splashy_node->text->str;
306 }
307 }
308 const gchar*
309 spl_get_text(GString* tag)
310 {
311 if ( ! splashy_xml_config )
312 {
313 DEBUG_PRINT ( "Initializing Splashy %s","" );
314 init_config( default_filename );
315 }
316
317 TagText* _tag = g_new0( TagText,1 );
318 _tag->tag = tag;
319 _tag->text = NULL;
320
321 g_list_foreach( splashy_xml_config->priv, spl_print_element, (gpointer)_tag);
322
323 return _tag->text;
324 }
325
326 gint
327 spl_get_int(GString* tag)
328 {
329 gint ret=0;
330 /* const gchar* this_tag = spl_get_text(tag); */
331 /* this_tag typecast to gint */
332 return ret;
333 }
334
335 /* EOF */
336 /*
337 * For testing compile with:
338 * gcc -g -Wall `pkg-config --libs --cflags glib-2.0` -o test xml_parser.c
339 * And then run ./test
340 */
341 int
342 main(int argc, char* argv[])
343 {
344 GString* tag = g_string_new("x");
345
346 const gchar* text = NULL;
347 text = spl_get_text(tag);
348
349 DEBUG_PRINT ( "main() text '%s'",text );
350
351 if ( text != NULL )
352 {
353 g_print("%s\n",text);
354 } else {
355 g_print("No text found %d\n",depth);
356 }
357 return 0;
358 }
359

  ViewVC Help
Powered by ViewVC 1.1.5