GnuCash  5.6-150-g038405b370+
sixtp-stack.cpp
1 /********************************************************************
2  * sixtp-stack.c *
3  * Copyright 2001 Gnumatic, Inc. *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact: *
17  * *
18  * Free Software Foundation Voice: +1-617-542-5942 *
19  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20  * Boston, MA 02110-1301, USA gnu@gnu.org *
21  * *
22  ********************************************************************/
23 #include <config.h>
24 #include "sixtp.h"
25 #include "sixtp-stack.h"
26 
27 void
28 sixtp_stack_frame_destroy (sixtp_stack_frame* sf)
29 {
30  GSList* lp;
31 
32  /* cleanup all the child data */
33  for (lp = sf->data_from_children; lp; lp = lp->next)
34  {
35  sixtp_child_result_destroy ((sixtp_child_result*) lp->data);
36  }
37  g_slist_free (sf->data_from_children);
38  sf->data_from_children = NULL;
39 
40  g_free (sf);
41 }
42 
44 sixtp_stack_frame_new (sixtp* next_parser, char* tag)
45 {
46  sixtp_stack_frame* new_frame;
47 
48  new_frame = g_new0 (sixtp_stack_frame, 1);
49  new_frame->parser = next_parser;
50  new_frame->tag = tag;
51  new_frame->data_for_children = NULL;
52  new_frame->data_from_children = NULL;
53  new_frame->frame_data = NULL;
54  new_frame->line = new_frame->col = -1;
55 
56  return new_frame;
57 }
58 
59 void
60 sixtp_stack_frame_print (sixtp_stack_frame* sf, gint indent, FILE* f)
61 {
62  gchar* is = g_strnfill (indent, ' ');
63 
64  fprintf (f, "%s(stack-frame %p\n", is, sf);
65  fprintf (f, "%s (line %d) (col %d)\n", is, sf->line, sf->col);
66  fprintf (f, "%s (parser %p)\n", is, sf->parser);
67  fprintf (f, "%s (tag %s)\n", is, sf->tag ? sf->tag : "(null)");
68  fprintf (f, "%s (data-for-children %p)\n", is,
69  sf->data_for_children);
70 
71  {
72  GSList* lp;
73  fprintf (f, "%s (data-from-children", is);
74  for (lp = sf->data_from_children; lp; lp = lp->next)
75  {
76  fputc (' ', f);
77  sixtp_child_result_print ((sixtp_child_result*) lp->data, f);
78  }
79  fprintf (f, ")\n");
80  }
81 
82  fprintf (f, "%s (frame-data %p))\n", is, sf->frame_data);
83  fflush (f);
84  g_free (is);
85 }
86 
87 GSList*
88 sixtp_pop_and_destroy_frame (GSList* frame_stack)
89 {
90  sixtp_stack_frame* dead_frame = (sixtp_stack_frame*) frame_stack->data;
91  GSList* result;
92 
93  result = g_slist_next (frame_stack);
94  sixtp_stack_frame_destroy (dead_frame);
95  g_slist_free_1 (frame_stack);
96  return (result);
97 }
98 
99 void
100 sixtp_print_frame_stack (GSList* stack, FILE* f)
101 {
102  /* first, some debugging output */
103  GSList* printcopy = g_slist_reverse (g_slist_copy (stack));
104  GSList* lp;
105  int indent = 0;
106 
107  for (lp = printcopy; lp; lp = lp->next)
108  {
109  sixtp_stack_frame* frame = (sixtp_stack_frame*) lp->data;
110  sixtp_stack_frame_print (frame, indent, f);
111  indent += 2;
112  }
113 
114 }
115 
116 
117 /* Parser context */
118 sixtp_parser_context*
119 sixtp_context_new (sixtp* initial_parser, gpointer global_data,
120  gpointer top_level_data)
121 {
122  sixtp_parser_context* ret;
123 
124  ret = g_new0 (sixtp_parser_context, 1);
125 
126  ret->handler.startElement = sixtp_sax_start_handler;
127  ret->handler.endElement = sixtp_sax_end_handler;
128  ret->handler.characters = sixtp_sax_characters_handler;
129  ret->handler.getEntity = sixtp_sax_get_entity_handler;
130 
131  ret->data.parsing_ok = TRUE;
132  ret->data.stack = NULL;
133  ret->data.global_data = global_data;
134 
135  ret->top_frame = sixtp_stack_frame_new (initial_parser, NULL);
136 
137  ret->top_frame_data = top_level_data;
138 
139  ret->data.stack = g_slist_prepend (ret->data.stack,
140  (gpointer) ret->top_frame);
141 
142  if (initial_parser->start_handler)
143  {
144  if (!initial_parser->start_handler (NULL,
145  &ret->top_frame_data,
146  &ret->data.global_data,
147  &ret->top_frame->data_for_children,
148  &ret->top_frame->frame_data,
149  NULL, NULL))
150  {
151  sixtp_handle_catastrophe (&ret->data);
152  sixtp_context_destroy (ret);
153  return NULL;
154  }
155  }
156 
157  return ret;
158 }
159 
160 void
161 sixtp_context_run_end_handler (sixtp_parser_context* ctxt)
162 {
163  if (ctxt->top_frame->parser->end_handler)
164  {
165  ctxt->data.parsing_ok &=
166  ctxt->top_frame->parser->end_handler (
167  ctxt->top_frame->data_for_children,
168  ctxt->top_frame->data_from_children,
169  NULL,
170  ctxt->top_frame_data,
171  ctxt->data.global_data,
172  &ctxt->top_frame->frame_data,
173  NULL);
174  }
175 }
176 
177 void
178 sixtp_context_destroy (sixtp_parser_context* context)
179 {
180  sixtp_stack_frame_destroy (context->top_frame);
181  g_slist_free (context->data.stack);
182  context->data.saxParserCtxt->userData = NULL;
183  context->data.saxParserCtxt->sax = NULL;
184  xmlFreeParserCtxt (context->data.saxParserCtxt);
185  context->data.saxParserCtxt = NULL;
186  g_free (context);
187 }
Definition: sixtp.h:129