1 /******************************************************************************
2 * MODULE     : pico_xml.c
3 * DESCRIPTION: Small filter helping to cut an XML flow between root tags
4 * COPYRIGHT  : (C) 2014  François Poulain, Joris van der Hoeven
5 *******************************************************************************
6 * This software falls under the GNU general public license version 3 or later.
7 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
8 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
9 ******************************************************************************/
10 
11 #include <stdio.h>
12 #include "pico_xml.h"
13 
14 void
init_xml_state(xml_state * xs)15 init_xml_state (xml_state *xs) {
16   xs->old_c= 0;
17   xs->deepness= 0;
18   xs->opened_tag= 0;
19   xs->closing_tag= 0;
20   xs->has_content= 0;
21 }
22 
23 void
print_xml_state(xml_state * xs)24 print_xml_state (xml_state *xs) {
25       fprintf (stderr, "old_c= %c (0x%x), deepness= %d, opened_tag= %d, \
26           closing_tag= %d, has_content= %d\n\n", xs->old_c, xs->old_c,
27           xs->deepness, xs->opened_tag, xs->closing_tag, xs->has_content);
28 }
29 
30 void
update_xml_state(xml_state * xs,int c)31 update_xml_state (xml_state *xs, int c) {
32       if (xs->opened_tag < 0 || xs->deepness < 0)
33         init_xml_state (xs);
34 
35       if (c == '<') {
36         xs->opened_tag++;
37         xs->has_content= 1;
38       }
39       else if (c == '>' && xs->closing_tag) {
40         xs->opened_tag--;
41         xs->deepness--;
42         xs->closing_tag= 0;
43       }
44       else if (c == '>' && xs->old_c == '/') {
45         xs->opened_tag--;
46       }
47       else if (c == '>') {
48         xs->opened_tag--;
49         xs->deepness++;
50       }
51       else if (c == '/' && xs->old_c == '<')
52         xs->closing_tag= 1;
53 
54       xs->old_c= c;
55 }
56 
57 int
ended_xml_root_tag(xml_state * xs)58 ended_xml_root_tag (xml_state *xs) {
59   return xs->has_content && xs->opened_tag == 0 && xs->deepness == 0;
60 }
61