2006-09-04 Miguel de Icaza <miguel@novell.com>
authorMiguel de Icaza <miguel@gnome.org>
Tue, 5 Sep 2006 03:01:31 +0000 (03:01 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Tue, 5 Sep 2006 03:01:31 +0000 (03:01 -0000)
* src/gmarkup.c (g_markup_parse_context_end_parse): Add missing
method.
(g_markup_parse_context_free): Implement.
(parse_attributes): Store the value, not the attribute name
twice.
Properly check the /> section.
(g_markup_parse_context_parse): When checking for error, use the
"error!=NULL && *error != NULL" upon return from callbacks,
it is only then that its valid to check for *error for error
conditions.

Only release one element of the list.

* test/markup.c: Incorporate the kind of code that is used in Mono
for domain loading;  Will test the rest later.

svn path=/trunk/mono/; revision=64910

eglib/ChangeLog
eglib/TODO
eglib/src/glib.h
eglib/src/gmarkup.c
eglib/test/markup.c

index 2fd3014d68e08470da1ec6552c0150c0d96dcddb..61b980f50e7f255043053e736dbb82e9c608fdfa 100644 (file)
@@ -1,3 +1,21 @@
+2006-09-04  Miguel de Icaza  <miguel@novell.com>
+
+       * src/gmarkup.c (g_markup_parse_context_end_parse): Add missing
+       method. 
+       (g_markup_parse_context_free): Implement. 
+       (parse_attributes): Store the value, not the attribute name
+       twice. 
+       Properly check the /> section.
+       (g_markup_parse_context_parse): When checking for error, use the
+       "error!=NULL && *error != NULL" upon return from callbacks,
+       it is only then that its valid to check for *error for error
+       conditions. 
+       
+       Only release one element of the list.
+
+       * test/markup.c: Incorporate the kind of code that is used in Mono
+       for domain loading;  Will test the rest later. 
+
 2006-09-01  Miguel de Icaza  <miguel@novell.com>
 
        * src/gmarkup.c (g_markup_parse_context_parse): Add text parsing
index d2133f520d348d075e03a24726b3ac14ae0be94f..cfb752c5fa9f98b0f67dca59c2bd29ad1c2708bc 100644 (file)
 
 Important Groups:
 
-       * Markup: currently under development. 
-             2 g_markup_parse_context_parse
-             2 g_markup_parse_context_new
-             2 g_markup_parse_context_free
-             2 g_markup_parse_context_end_parse
-
        * Process launching
              3 g_shell_quote
              1 g_shell_unquote
index 5ef236f094d35d3510a40a473b4f6d5db3d0c003..c31a23692a369616462e66c5c74d0b2f19f67963 100644 (file)
@@ -637,6 +637,8 @@ void                 g_markup_parse_context_free  (GMarkupParseContext *context)
 gboolean             g_markup_parse_context_parse (GMarkupParseContext *context,
                                                   const gchar *text, gssize text_len,
                                                   GError **error);
+gboolean         g_markup_parse_context_end_parse (GMarkupParseContext *context,
+                                                  GError **error);
 
 #endif
 
index 47d859aa697f16ef2f7b29b2dd3565d7299ec4f4..95cbfd4aee098b22030ea087fa49839f13e07d2a 100644 (file)
@@ -2,7 +2,14 @@
  * 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)
@@ -71,6 +78,18 @@ g_markup_parse_context_new (const GMarkupParser *parser,
 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);
 }
 
@@ -140,7 +159,7 @@ parse_attributes (const char *p, const char *end, char ***names, char ***values,
                        *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 {
@@ -169,7 +188,7 @@ parse_attributes (const char *p, const char *end, char ***names, char ***values,
                        *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;                      
                }
@@ -278,13 +297,13 @@ g_markup_parse_context_parse (GMarkupParseContext *context,
                                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
@@ -311,7 +330,7 @@ g_markup_parse_context_parse (GMarkupParseContext *context,
                        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;
                        }
                        
@@ -335,11 +354,11 @@ g_markup_parse_context_parse (GMarkupParseContext *context,
                                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 */
                        
@@ -356,4 +375,15 @@ g_markup_parse_context_parse (GMarkupParseContext *context,
        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;
+}
index 11cc886ba42fb5c574895efe14fca94d1ccfb5fc..99ba945bc9ee5a70bbdcac1a9ae7e62232302209 100644 (file)
@@ -27,7 +27,8 @@ markup_test (const char *s)
        return NULL;
 }
 
-RESULT invalid_documents (void)
+RESULT
+invalid_documents (void)
 {
        /* These should fail */
        do_bad_test ("<1>");
@@ -40,8 +41,8 @@ RESULT invalid_documents (void)
        return OK;
 }
 
-
-RESULT valid_documents (void)
+RESULT
+valid_documents (void)
 {
        /* These should fail */
        do_ok_test ("<a>");
@@ -50,9 +51,151 @@ RESULT valid_documents (void)
        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}
 };