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 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 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 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 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 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 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 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 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 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