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

Contents of /trunk/src/xml_parser.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 210 - (hide annotations) (download)
Sun Apr 17 17:08:11 2005 UTC (8 years, 2 months ago) by lemsx1
File MIME type: text/plain
File size: 11309 byte(s)
a less buggy version... still needs to solve issues
1 lemsx1 177 /**********************************************************************
2 otavio 158 * xml_parser.cc
3     *
4 lemsx1 177 * 2005-04-15 18:58 EDT
5     * Copyright 2005 Luis Mondesi <lemsx1@gmail.com>
6     **********************************************************************/
7 otavio 158
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 lemsx1 203 #define DEBUG 1
25    
26 lemsx1 177 #include <stdio.h>
27     #include <glib.h>
28 otavio 158
29 lemsx1 184 #include "common_macros.h"
30 otavio 158 #include "xml_parser.h"
31    
32 lemsx1 184 static gchar* default_filename = SPLASHY_CONFIG_FILE; /* default filename */
33 lemsx1 187
34 lemsx1 177 static int depth = 0;
35    
36 lemsx1 210 /**
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 lemsx1 187 /* private functions */
45 lemsx1 206 static void
46 lemsx1 187 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 lemsx1 206 g_return_if_fail ( element_name != NULL );
54    
55 lemsx1 188 DEBUG_PRINT ("ELEMENT: '%s'", element_name);
56 lemsx1 187
57 lemsx1 206 gint i = 0;
58    
59 lemsx1 187 /* use _list alias for gpointer user_data. less typing */
60 lemsx1 201
61 lemsx1 209 GList* _list = (GList*) user_data;
62 lemsx1 187
63     /* create bucket for this node */
64     SplashyXMLNode* _node = g_new0 ( SplashyXMLNode,1 );
65     /* save name */
66 lemsx1 209 _node->name = g_string_new(element_name);
67 lemsx1 206 /* init text to nothing. we will get this later */
68     _node->text = NULL;
69 lemsx1 187 /* 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 lemsx1 188 DEBUG_PRINT ( "NAME: %s", attribute_names[i] );
86     DEBUG_PRINT ( "VALUE: %s", attribute_values[i] );
87 lemsx1 187 SplashyXMLAttr* _attr = g_new0 ( SplashyXMLAttr,1 );
88 lemsx1 209 _attr->name = g_string_new(attribute_names[i]);
89     _attr->value = g_string_new(attribute_values[i]);
90 lemsx1 187 g_list_append( _node->attrs,(gpointer)_attr );
91     ++i;
92     }
93     ++depth;
94     g_list_append( _list,(gpointer)_node );
95     }
96    
97 lemsx1 206 static void
98 lemsx1 187 end_element_handler (GMarkupParseContext *context,
99     const gchar *element_name,
100     gpointer user_data,
101     GError **error)
102     {
103     --depth;
104 lemsx1 188 DEBUG_PRINT ("END: '%s'", element_name);
105 lemsx1 187 }
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 lemsx1 206 g_return_if_fail ( text_len > 0 );
115 lemsx1 209 /*
116     * Strings parse by gmarkup parser are not nul-terminated!
117     * thus we need to use text_len to terminate this strings
118     * properly
119     * aka: text[text_len] = '\0';
120     */
121    
122 lemsx1 207 /* TODO we need to test new-lines only */
123     /* g_return_if_fail ( g_ascii_isalnum( text[0] ) ); */
124 lemsx1 206
125 lemsx1 188 DEBUG_PRINT ("TEXT: '%s'", text);
126 lemsx1 209
127 lemsx1 187 GList* _list = (GList *) user_data;
128 lemsx1 209
129 lemsx1 187 /* assume that only one thread of this program is running,
130     * then the last node appended to the list _list is the
131     * tag for which we will be saving our text
132     * TODO find a better way to do this (if any)
133     */
134 lemsx1 206 GList* _last_node = NULL;
135     _last_node = g_list_last( _list );
136     if ( _last_node != NULL )
137     {
138 lemsx1 210 SplashyXMLNode* _splashy_node = (SplashyXMLNode *)_last_node->data;
139     _splashy_node->text= g_string_new(text);
140    
141     /*
142     if ( _is_valid_char(text) )
143     {
144     _splashy_node->got_text = TRUE;
145     }
146     */
147    
148     DEBUG_PRINT ("text_handler() _last_node Tag '%s'",_splashy_node->name->str);
149     DEBUG_PRINT ("text_handler() _last_node Text '%s'",_splashy_node->text->str);
150 lemsx1 206 }
151 lemsx1 187 }
152    
153     static void
154     passthrough_handler (GMarkupParseContext *context,
155     const gchar *passthrough_text,
156     gsize text_len,
157     gpointer user_data,
158     GError **error)
159     {
160 lemsx1 188 DEBUG_PRINT ("PASS: '%s'", passthrough_text);
161 lemsx1 187 }
162    
163     static void
164     error_handler (GMarkupParseContext *context,
165     GError *error,
166     gpointer user_data)
167     {
168     fprintf (stderr, "ERROR: %s\n", error->message);
169     }
170    
171     /* our parser */
172     static GMarkupParser parser = {
173     start_element_handler,
174     end_element_handler,
175     text_handler,
176     passthrough_handler,
177     error_handler
178     };
179    
180     /**
181     * @ingroup core
182 lemsx1 184 * Slurps all tags from a given filename
183     * @arg _filename filename path to read
184     * @return true on success
185     */
186 lemsx1 202 gboolean
187 lemsx1 201 _read()
188 lemsx1 184 {
189 lemsx1 201 g_return_val_if_fail( splashy_xml_config != NULL, FALSE);
190    
191 lemsx1 209 DEBUG_PRINT ( "ENTERING read(%s)",splashy_xml_config->config_path->str );
192 lemsx1 177 gchar *contents;
193     gsize length;
194     GError *error;
195     GMarkupParseContext *context;
196    
197     error = NULL;
198    
199 lemsx1 209 if (!g_file_get_contents (splashy_xml_config->config_path->str,
200 lemsx1 177 &contents,
201     &length,
202     &error))
203     {
204     fprintf (stderr, "%s\n", error->message);
205     g_error_free (error);
206 lemsx1 184 return FALSE;
207 lemsx1 177 }
208    
209 lemsx1 209 context = g_markup_parse_context_new (&parser, 0,
210 lemsx1 201 splashy_xml_config->priv, NULL);
211 lemsx1 177
212     if (!g_markup_parse_context_parse (context, contents, length, NULL))
213     {
214     g_markup_parse_context_free (context);
215 lemsx1 184 return FALSE;
216 lemsx1 177 }
217    
218     if (!g_markup_parse_context_end_parse (context, NULL))
219     {
220     g_markup_parse_context_free (context);
221 lemsx1 184 return FALSE;
222 lemsx1 177 }
223     g_markup_parse_context_free (context);
224 lemsx1 209
225     /* FIXME g_free(contents); */
226    
227 lemsx1 184 /* now we have all the 'contents' we wanted */
228 lemsx1 204 DEBUG_PRINT ( "EXITING _read(%s)","" );
229 lemsx1 187 return TRUE; /* assuming that if we reach here, no error happend */
230 lemsx1 177 }
231    
232 lemsx1 204 /**
233     * @ingroup core
234     * Initializes a SplashyConfig struct using _filename as config file
235     * @arg _filename filename path to read
236     * @return true on success
237     */
238 lemsx1 209 gboolean
239 lemsx1 204 init_config(const gchar* _filename)
240     {
241     DEBUG_PRINT ( "ENTERING init_config(%s)",_filename );
242     /* sanity check */
243     if ( splashy_xml_config ) return TRUE; /* splashy_xml_config has been initialized */
244     DEBUG_PRINT ( "CREATING SplashyConfig %s","" );
245     /* use our default struct. @see xml_parser.h */
246     splashy_xml_config = g_new0( SplashyConfig,1 );
247 lemsx1 209 splashy_xml_config->config_path= g_string_new(_filename);
248 lemsx1 204
249     DEBUG_PRINT ( "CREATING GList %s","" );
250     splashy_xml_config->priv = g_new0( GList,1 );
251    
252     /* slurp our config file to splashy_xml_config */
253     return _read();
254     }
255    
256 lemsx1 206 gint
257     _comp_node_to_tag(gconstpointer node, gconstpointer tag)
258 lemsx1 184 {
259 lemsx1 188
260 lemsx1 206 /* sanity checks:
261     * 1. test if the node is valid
262     * 2. test if the tag is valid
263     */
264     g_return_val_if_fail( (GList*)node != NULL,1 );
265     g_return_val_if_fail( ((GList*)node)->data != NULL,1 );
266     g_return_val_if_fail( ((SplashyXMLNode*)((GList*)node)->data)->name != NULL,1 );
267 lemsx1 209 g_return_val_if_fail( (GString*)tag != NULL,1 );
268 lemsx1 206
269 lemsx1 209 GString* _name = NULL;
270 lemsx1 206 _name = ((SplashyXMLNode*)((GList*)node)->data)->name;
271 lemsx1 209
272     DEBUG_PRINT ( "_comp_node_to_tag name %s",_name->str );
273    
274     if ( g_string_equal ( tag,_name ) )
275 lemsx1 187 {
276 lemsx1 188 DEBUG_PRINT ( "EXITING _comp_node_to_tag(%s)","TRUE" );
277 lemsx1 187 return 0; /* matched */
278     }
279 lemsx1 188
280     DEBUG_PRINT ( "EXITING _comp_node_to_tag(%s)","FALSE" );
281 lemsx1 187 return 1; /* didn't match */
282 lemsx1 184 }
283 lemsx1 209
284 lemsx1 210 /**
285     * @desc debugging function
286     */
287 lemsx1 209 void
288     spl_print_element ( gpointer data, gpointer user_data)
289     {
290     g_return_if_fail ( (GList*)data != NULL );
291    
292 lemsx1 210 SplashyXMLNode* _splashy_node = (SplashyXMLNode*) data;
293    
294     g_return_if_fail ( _splashy_node != NULL );
295     g_return_if_fail ( _splashy_node->name != NULL );
296     g_return_if_fail ( _splashy_node->text != NULL );
297    
298     g_print("TAG '%s'\n", _splashy_node->name->str);
299     g_print("VAL '%s'\n", _splashy_node->text->str);
300    
301     /*GString* _tag = ((TagText*)user_data)->tag;
302     GString* _name_tag = _splashy_node->name;*/
303 lemsx1 209
304 lemsx1 210 const gchar* _text = ((TagText*)user_data)->text;
305     const gchar* debug_text = "yoohoo";
306    
307     /*if ( g_string_equal (_tag,_name_tag) )
308     {*/
309     _text = debug_text; // _splashy_node->text->str;
310     //}
311 lemsx1 209 }
312 lemsx1 202 const gchar*
313 lemsx1 209 spl_get_text(GString* tag)
314 lemsx1 177 {
315 lemsx1 188 if ( ! splashy_xml_config )
316     {
317 lemsx1 204 DEBUG_PRINT ( "Initializing Splashy %s","" );
318     init_config( default_filename );
319 lemsx1 188 }
320 lemsx1 210
321     TagText* _tag = g_new0( TagText,1 );
322     _tag->tag = tag;
323     _tag->text = NULL;
324    
325     g_list_foreach( splashy_xml_config->priv, spl_print_element, (gpointer)_tag);
326    
327     return _tag->text;
328 lemsx1 177 }
329    
330 lemsx1 202 gint
331 lemsx1 209 spl_get_int(GString* tag)
332 lemsx1 177 {
333 lemsx1 187 gint ret=0;
334 lemsx1 204 /* const gchar* this_tag = spl_get_text(tag); */
335 lemsx1 177 /* this_tag typecast to gint */
336     return ret;
337     }
338 lemsx1 187
339 lemsx1 177 /* EOF */
340 lemsx1 202 /*
341     * For testing compile with:
342 lemsx1 204 * gcc -g -Wall `pkg-config --libs --cflags glib-2.0` -o test xml_parser.c
343 lemsx1 202 * And then run ./test
344     */
345     int
346     main(int argc, char* argv[])
347     {
348 lemsx1 209 GString* tag = g_string_new("x");
349 lemsx1 206
350 lemsx1 205 const gchar* text = NULL;
351 lemsx1 206 text = spl_get_text(tag);
352 lemsx1 201
353 lemsx1 210 DEBUG_PRINT ( "main() text '%s'",text );
354    
355 lemsx1 205 if ( text != NULL )
356 lemsx1 202 {
357     g_print("%s",text);
358     } else {
359     g_print("No text found %d",depth);
360     }
361     return 0;
362     }
363    

  ViewVC Help
Powered by ViewVC 1.1.5