[gtksourceview] language: fix loading of references languages via resources



commit 47ba7b41fd5822da86553fdc663e68c70f96d2b8
Author: Christian Hergert <chergert redhat com>
Date:   Thu Jan 27 22:27:19 2022 -0800

    language: fix loading of references languages via resources
    
    This finishes the support for loading language files via resources and
    more thouroughly tests it.
    
    Fixes #253

 gtksourceview/gtksourcelanguage-parser-2.c | 37 ++++++++++++++++++++++++------
 testsuite/test-languagemanager.c           | 22 ++++++++++++++----
 testsuite/testsuite-2.lang                 | 26 +++++++++++++++++++++
 testsuite/testsuite.gresource.xml          |  1 +
 testsuite/testsuite.lang                   |  2 ++
 5 files changed, 77 insertions(+), 11 deletions(-)
---
diff --git a/gtksourceview/gtksourcelanguage-parser-2.c b/gtksourceview/gtksourcelanguage-parser-2.c
index 8521535a..73c045df 100644
--- a/gtksourceview/gtksourcelanguage-parser-2.c
+++ b/gtksourceview/gtksourcelanguage-parser-2.c
@@ -1604,22 +1604,42 @@ file_parse (const gchar               *filename,
 {
        ParserState *parser_state;
        xmlTextReader *reader = NULL;
+       GBytes *bytes = NULL;
        int fd = -1;
        GError *tmp_error = NULL;
        GtkSourceLanguageManager *lm;
        const gchar *rng_lang_schema;
 
+       g_return_val_if_fail (filename != NULL, FALSE);
        g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
        DEBUG (g_message ("loading file '%s'", filename));
 
-       /*
-        * Use fd instead of filename so that it's utf8 safe on w32.
-        */
-       fd = g_open (filename, O_RDONLY, 0);
+       if (g_str_has_prefix (filename, "resource://"))
+       {
+               const char *path = filename + strlen ("resource://");
 
-       if (fd != -1)
-               reader = xmlReaderForFd (fd, filename, NULL, 0);
+               bytes = g_resources_lookup_data (path, 0, NULL);
+
+               if (bytes != NULL)
+               {
+                       reader = xmlReaderForMemory (g_bytes_get_data (bytes, NULL),
+                                                    g_bytes_get_size (bytes),
+                                                    NULL, NULL, 0);
+               }
+       }
+       else
+       {
+               /*
+                * Use fd instead of filename so that it's utf8 safe on w32.
+                */
+               fd = g_open (filename, O_RDONLY, 0);
+
+               if (fd != -1)
+               {
+                       reader = xmlReaderForFd (fd, filename, NULL, 0);
+               }
+       }
 
        if (reader == NULL)
        {
@@ -1697,13 +1717,16 @@ file_parse (const gchar               *filename,
        if (tmp_error != NULL)
                goto error;
 
-       close (fd);
+       if (fd != -1)
+               close (fd);
+       g_clear_pointer (&bytes, g_bytes_unref);
 
        return TRUE;
 
 error:
        if (fd != -1)
                close (fd);
+       g_clear_pointer (&bytes, g_bytes_unref);
        g_propagate_error (error, tmp_error);
        return FALSE;
 }
diff --git a/testsuite/test-languagemanager.c b/testsuite/test-languagemanager.c
index 7ca0aa62..1d22d22b 100644
--- a/testsuite/test-languagemanager.c
+++ b/testsuite/test-languagemanager.c
@@ -191,19 +191,33 @@ static void
 test_resources (void)
 {
        GtkSourceLanguageManager *lm = gtk_source_language_manager_new ();
-       const char * const search_path[] = { "resource:///language-specs/", NULL };
+       GtkSourceLanguage *l;
+       GtkSourceBuffer *buffer;
+       const char * search_path[] = { "resource:///language-specs/", NULL, NULL };
        const char * const *ids;
+       char *dir;
+
+       dir = g_build_filename (TOP_SRCDIR, "data", "language-specs", NULL);
+       search_path[1] = dir;
 
        g_resources_register (testsuite_get_resource ());
 
        gtk_source_language_manager_set_search_path (lm, search_path);
        ids = gtk_source_language_manager_get_language_ids (lm);
 
-       g_assert_nonnull (ids);
-       g_assert_cmpstr (ids[0], ==, "testsuite");
-       g_assert_null (ids[1]);
+       g_assert_true (g_strv_contains (ids, "testsuite"));
+       g_assert_true (g_strv_contains (ids, "testsuite-2"));
+
+       l = gtk_source_language_manager_get_language (lm, "testsuite");
+       g_assert_nonnull (l);
+       g_assert_cmpstr ("testsuite", ==, gtk_source_language_get_id (l));
+
+       buffer = gtk_source_buffer_new (NULL);
+       gtk_source_buffer_set_language (buffer, l);
 
+       g_object_unref (buffer);
        g_object_unref (lm);
+       g_free (dir);
 }
 
 int
diff --git a/testsuite/testsuite-2.lang b/testsuite/testsuite-2.lang
new file mode 100644
index 00000000..4b6f5915
--- /dev/null
+++ b/testsuite/testsuite-2.lang
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ This file is part of GtkSourceView
+
+ GtkSourceView is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ GtkSourceView is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+-->
+<language id="testsuite-2" name="testsuite-2" version="2.0" _section="Other" hidden="true">
+  <definitions>
+    <context id="integer" style-ref="testsuite:integer">
+      <match>\b[0-9]+\b</match>
+    </context>
+  </definitions>
+</language>
diff --git a/testsuite/testsuite.gresource.xml b/testsuite/testsuite.gresource.xml
index 831cfda9..9567a9b5 100644
--- a/testsuite/testsuite.gresource.xml
+++ b/testsuite/testsuite.gresource.xml
@@ -2,5 +2,6 @@
 <gresources>
   <gresource prefix="/language-specs">
     <file>testsuite.lang</file>
+    <file>testsuite-2.lang</file>
   </gresource>
 </gresources>
diff --git a/testsuite/testsuite.lang b/testsuite/testsuite.lang
index f91c01ad..49cdc8f7 100644
--- a/testsuite/testsuite.lang
+++ b/testsuite/testsuite.lang
@@ -21,6 +21,7 @@
   <styles>
     <style id="escaped-character" name="Escaped character"     map-to="def:special-char"/>
     <style id="string"            name="String"                map-to="def:string"/>
+    <style id="integer"           name="Integer"               map-to="def:number"/>
   </styles>
   <definitions>
     <context id="string" style-ref="string" class="string" class-disabled="no-spell-check">
@@ -37,6 +38,7 @@
     <context id="testsuite" class="no-spell-check">
       <include>
         <context ref="string"/>
+        <context ref="testsuite-2:integer"/>
       </include>
     </context>
   </definitions>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]