• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #undef G_DISABLE_ASSERT
2 #undef G_LOG_DOMAIN
3 
4 #include <stdio.h>
5 #include <glib.h>
6 
7 static int depth = 0;
8 
9 static void
indent(int extra)10 indent (int extra)
11 {
12   int i = 0;
13   while (i < depth)
14     {
15       fputs ("  ", stdout);
16       ++i;
17     }
18 }
19 
20 static void
start_element_handler(GMarkupParseContext * context,const gchar * element_name,const gchar ** attribute_names,const gchar ** attribute_values,gpointer user_data,GError ** error)21 start_element_handler  (GMarkupParseContext *context,
22                         const gchar         *element_name,
23                         const gchar        **attribute_names,
24                         const gchar        **attribute_values,
25                         gpointer             user_data,
26                         GError             **error)
27 {
28   int i;
29 
30   indent (0);
31   printf ("ELEMENT '%s'\n", element_name);
32 
33   i = 0;
34   while (attribute_names[i] != NULL)
35     {
36       indent (1);
37 
38       printf ("%s=\"%s\"\n",
39               attribute_names[i],
40               attribute_values[i]);
41 
42       ++i;
43     }
44 
45   ++depth;
46 }
47 
48 static void
end_element_handler(GMarkupParseContext * context,const gchar * element_name,gpointer user_data,GError ** error)49 end_element_handler    (GMarkupParseContext *context,
50                         const gchar         *element_name,
51                         gpointer             user_data,
52                         GError             **error)
53 {
54   --depth;
55   indent (0);
56   printf ("END '%s'\n", element_name);
57   }
58 
59 static void
text_handler(GMarkupParseContext * context,const gchar * text,gsize text_len,gpointer user_data,GError ** error)60 text_handler                      (GMarkupParseContext *context,
61                         const gchar         *text,
62                         gsize                text_len,
63                         gpointer             user_data,
64                         GError             **error)
65 {
66   indent (0);
67   printf ("TEXT '%.*s'\n", (int)text_len, text);
68 }
69 
70 
71 static void
passthrough_handler(GMarkupParseContext * context,const gchar * passthrough_text,gsize text_len,gpointer user_data,GError ** error)72 passthrough_handler    (GMarkupParseContext *context,
73                         const gchar         *passthrough_text,
74                         gsize                text_len,
75                         gpointer             user_data,
76                         GError             **error)
77 {
78   indent (0);
79 
80   printf ("PASS '%.*s'\n", (int)text_len, passthrough_text);
81 }
82 
83 static void
error_handler(GMarkupParseContext * context,GError * error,gpointer user_data)84 error_handler          (GMarkupParseContext *context,
85                         GError              *error,
86                         gpointer             user_data)
87 {
88   fprintf (stderr, " %s\n", error->message);
89 }
90 
91 static const GMarkupParser parser = {
92   start_element_handler,
93   end_element_handler,
94   text_handler,
95   passthrough_handler,
96   error_handler
97 };
98 
99 static const GMarkupParser silent_parser = {
100   NULL,
101   NULL,
102   NULL,
103   NULL,
104   error_handler
105 };
106 
107 static int
test_in_chunks(const gchar * contents,gint length,gint chunk_size)108 test_in_chunks (const gchar *contents,
109                 gint         length,
110                 gint         chunk_size)
111 {
112   GMarkupParseContext *context;
113   int i = 0;
114 
115   context = g_markup_parse_context_new (&silent_parser, 0, NULL, NULL);
116 
117   while (i < length)
118     {
119       int this_chunk = MIN (length - i, chunk_size);
120 
121       if (!g_markup_parse_context_parse (context,
122                                          contents + i,
123                                          this_chunk,
124                                          NULL))
125         {
126           g_markup_parse_context_free (context);
127           return 1;
128         }
129 
130       i += this_chunk;
131     }
132 
133   if (!g_markup_parse_context_end_parse (context, NULL))
134     {
135       g_markup_parse_context_free (context);
136       return 1;
137     }
138 
139   g_markup_parse_context_free (context);
140 
141   return 0;
142 }
143 
144 static int
test_file(const gchar * filename)145 test_file (const gchar *filename)
146 {
147   gchar *contents;
148   gsize  length;
149   GError *error;
150   GMarkupParseContext *context;
151 
152   error = NULL;
153   if (!g_file_get_contents (filename,
154                             &contents,
155                             &length,
156                             &error))
157     {
158       fprintf (stderr, "%s\n", error->message);
159       g_error_free (error);
160       return 1;
161     }
162 
163   context = g_markup_parse_context_new (&parser, 0, NULL, NULL);
164 
165   if (!g_markup_parse_context_parse (context, contents, length, NULL))
166     {
167       g_markup_parse_context_free (context);
168       return 1;
169     }
170 
171   if (!g_markup_parse_context_end_parse (context, NULL))
172     {
173       g_markup_parse_context_free (context);
174       return 1;
175     }
176 
177   g_markup_parse_context_free (context);
178 
179   /* A byte at a time */
180   if (test_in_chunks (contents, length, 1) != 0)
181     return 1;
182 
183   /* 2 bytes */
184   if (test_in_chunks (contents, length, 2) != 0)
185     return 1;
186 
187   /*5 bytes */
188   if (test_in_chunks (contents, length, 5) != 0)
189     return 1;
190 
191   /* 12 bytes */
192   if (test_in_chunks (contents, length, 12) != 0)
193     return 1;
194 
195   /* 1024 bytes */
196   if (test_in_chunks (contents, length, 1024) != 0)
197     return 1;
198 
199   return 0;
200 }
201 
202 int
main(int argc,char * argv[])203 main (int   argc,
204       char *argv[])
205 {
206   if (argc > 1)
207     return test_file (argv[1]);
208   else
209     {
210       fprintf (stderr, "Give a markup file on the command line\n");
211       return 1;
212     }
213 }
214 
215