* gmakrup.c: Minimal XML markup reader.
*
* Unlike the GLib one, this can not be restarted with more text
- * as the Mono use does not require it
+ * as the Mono use does not require it.
+ *
+ * Actually, with further thought, I think that this could be made
+ * to restart very easily. The pos == end condition would mean
+ * "return to caller" and only at end parse this would be a fatal
+ * error.
+ *
+ * Not that it matters to Mono, but it is very simple to change.
*
* Author:
* Miguel de Icaza (miguel@novell.com)
void
g_markup_parse_context_free (GMarkupParseContext *context)
{
+ GSList *l;
+
+ g_return_if_fail (context != NULL);
+
+ if (context->user_data_dnotify != NULL)
+ (context->user_data_dnotify) (context->user_data);
+
+ if (context->text != NULL)
+ g_string_free (context->text, TRUE);
+ for (l = context->level; l; l = l->next)
+ g_free (l->data);
+ g_slist_free (context->level);
g_free (context);
}
*full_stop = 0;
return p;
}
- if (*p == '/' && ((p+1) < end && *p == '>')){
+ if (*p == '/' && ((p+1) < end && *(p+1) == '>')){
*full_stop = 1;
return p+1;
} else {
*names = g_realloc (*names, sizeof (char **) * (nnames+1));
*values = g_realloc (*values, sizeof (char **) * (nnames+1));
(*names) [nnames-1] = name;
- (*values) [nnames-1] = name;
+ (*values) [nnames-1] = value;
(*names) [nnames] = NULL;
(*values) [nnames] = NULL;
}
g_strfreev (values);
}
- if (*error != NULL)
+ if (error != NULL && *error != NULL)
goto fail;
if (full_stop){
if (context->parser.end_element != NULL){
context->parser.end_element (context, ename, context->user_data, error);
- if (*error != NULL)
+ if (error != NULL && *error != NULL)
goto fail;
}
} else
if (context->parser.text != NULL){
context->parser.text (context, context->text->str, context->text->len,
context->user_data, error);
- if (*error != NULL)
+ if (error != NULL && *error != NULL)
goto fail;
}
char *text = current->data;
context->parser.end_element (context, text, context->user_data, error);
- if (*error != NULL)
+ if (error != NULL && *error != NULL)
goto fail;
}
context->level = context->level->next;
- g_slist_free (current);
+ g_slist_free_1 (current);
break;
} /* case CLOSING_ELEMENT */
return FALSE;
}
+gboolean
+g_markup_parse_context_end_parse (GMarkupParseContext *context, GError **error)
+{
+ g_return_val_if_fail (context != NULL, FALSE);
+ /*
+ * In our case, we always signal errors during parse, not at the end
+ * see the notes at the top of this file for details on how this
+ * could be moved here
+ */
+ return TRUE;
+}
return NULL;
}
-RESULT invalid_documents (void)
+RESULT
+invalid_documents (void)
{
/* These should fail */
do_bad_test ("<1>");
return OK;
}
-
-RESULT valid_documents (void)
+RESULT
+valid_documents (void)
{
/* These should fail */
do_ok_test ("<a>");
return OK;
}
+/*
+ * This is a test for the kind of files that the code in mono/domain.c
+ * parses; This code comes from Mono
+ */
+typedef struct {
+ GSList *supported_runtimes;
+ char *required_runtime;
+ int configuration_count;
+ int startup_count;
+} AppConfigInfo;
+
+static char *
+get_attribute_value (const gchar **attribute_names,
+ const gchar **attribute_values,
+ const char *att_name)
+{
+ int n;
+ for (n=0; attribute_names[n] != NULL; n++) {
+ if (strcmp (attribute_names[n], att_name) == 0)
+ return g_strdup (attribute_values[n]);
+ }
+ return NULL;
+}
+
+static void
+start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ AppConfigInfo* app_config = (AppConfigInfo*) user_data;
+
+ if (strcmp (element_name, "configuration") == 0) {
+ app_config->configuration_count++;
+ return;
+ }
+ if (strcmp (element_name, "startup") == 0) {
+ app_config->startup_count++;
+ return;
+ }
+
+ if (app_config->configuration_count != 1 || app_config->startup_count != 1)
+ return;
+
+ if (strcmp (element_name, "requiredRuntime") == 0) {
+ app_config->required_runtime = get_attribute_value (attribute_names, attribute_values, "version");
+ } else if (strcmp (element_name, "supportedRuntime") == 0) {
+ char *version = get_attribute_value (attribute_names, attribute_values, "version");
+ app_config->supported_runtimes = g_slist_append (app_config->supported_runtimes, version);
+ }
+}
+
+static void
+end_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ AppConfigInfo* app_config = (AppConfigInfo*) user_data;
+
+ if (strcmp (element_name, "configuration") == 0) {
+ app_config->configuration_count--;
+ } else if (strcmp (element_name, "startup") == 0) {
+ app_config->startup_count--;
+ }
+}
+
+static const GMarkupParser
+mono_parser = {
+ start_element,
+ end_element,
+ NULL,
+ NULL,
+ NULL
+};
+
+AppConfigInfo *
+domain_test (char *text)
+{
+ AppConfigInfo *app_config = g_new0 (AppConfigInfo, 1);
+ GMarkupParseContext *context;
+
+ context = g_markup_parse_context_new (&mono_parser, 0, app_config, NULL);
+ if (g_markup_parse_context_parse (context, text, strlen (text), NULL)) {
+ g_markup_parse_context_end_parse (context, NULL);
+ }
+ g_markup_parse_context_free (context);
+
+ return app_config;
+}
+
+void
+domain_free (AppConfigInfo *info)
+{
+ GSList *l;
+ if (info->required_runtime)
+ g_free (info->required_runtime);
+ for (l = info->supported_runtimes; l != NULL; l = l->next){
+ g_free (l->data);
+ }
+ g_slist_free (info->supported_runtimes);
+ g_free (info);
+}
+
+RESULT
+mono_domain (void)
+{
+ AppConfigInfo *info;
+
+ info = domain_test ("<configuration><startup><requiredRuntime version=\"v1\"></requiredRuntime></startup></configuration>");
+ if (info->required_runtime == NULL)
+ return FAILED ("No required runtime section");
+ if (strcmp (info->required_runtime, "v1") != 0)
+ return FAILED ("Got a runtime version %s, expected v1", info->required_runtime);
+ domain_free (info);
+
+ info = domain_test ("<configuration><startup><requiredRuntime version=\"v1\"/></configuration>");
+ if (info->required_runtime == NULL)
+ return FAILED ("No required runtime section on auto-close section");
+ if (strcmp (info->required_runtime, "v1") != 0)
+ return FAILED ("Got a runtime version %s, expected v1", info->required_runtime);
+ domain_free (info);
+
+ info = domain_test ("<configuration><startup><supportedRuntime version=\"v1\"><supportedRuntime version=\"v2\"/></startup></configuration>");
+ if ((strcmp ((char*)info->supported_runtimes->data, "v1") == 0)){
+ if (info->supported_runtimes->next == NULL)
+ return FAILED ("Expected 2 supported runtimes");
+
+ if ((strcmp ((char*)info->supported_runtimes->next->data, "v2") != 0))
+ return FAILED ("Expected v1, v2, got %s", info->supported_runtimes->next->data);
+ if (info->supported_runtimes->next->next != NULL)
+ return FAILED ("Expected v1, v2, got more");
+ } else
+ return FAILED ("Expected `v1', got %s", info->supported_runtimes->data);
+ domain_free (info);
+
+ return NULL;
+}
+
static Test markup_tests [] = {
{"invalid_documents", invalid_documents},
{"good_documents", valid_documents},
+ {"mono_domain", mono_domain},
{NULL, NULL}
};