[gnome-builder] xml-pack: support gtk4 relaxng validation



commit edbd4f7ddbe1eb8c0faa1f5cb7cf1fed0fff00ab
Author: Günther Wagner <info gunibert de>
Date:   Sat Feb 12 18:44:38 2022 +0100

    xml-pack: support gtk4 relaxng validation

 src/plugins/xml-pack/ide-xml-parser.c        |  39 ++-
 src/plugins/xml-pack/schemas/gtk4builder.rng | 491 +++++++++++++++++++++++++++
 src/plugins/xml-pack/xml-pack.gresource.xml  |   1 +
 3 files changed, 528 insertions(+), 3 deletions(-)
---
diff --git a/src/plugins/xml-pack/ide-xml-parser.c b/src/plugins/xml-pack/ide-xml-parser.c
index 164dc0160..57fdbc7d3 100644
--- a/src/plugins/xml-pack/ide-xml-parser.c
+++ b/src/plugins/xml-pack/ide-xml-parser.c
@@ -108,6 +108,28 @@ ide_xml_parser_file_is_ui (GFile       *file,
   return FALSE;
 }
 
+static gboolean
+ide_xml_parser_file_is_gtk3 (GFile       *file,
+                             const gchar *data,
+                             gsize        size)
+{
+  g_autofree gchar *buffer = NULL;
+  gsize buffer_size;
+
+  g_assert (G_IS_FILE (file));
+  g_assert (data != NULL);
+  g_assert (size > 0);
+
+  buffer_size = (size < 512) ? size : 512;
+  buffer = g_strndup (data, buffer_size);
+
+  if (strstr (buffer, "<requires lib=\"gtk\" version=\"3") != NULL ||
+      strstr (buffer, "<requires lib='gtk' version='3") != NULL)
+    return TRUE;
+
+  return FALSE;
+}
+
 IdeDiagnostic *
 ide_xml_parser_create_diagnostic (ParserState            *state,
                                   const gchar            *msg,
@@ -495,8 +517,8 @@ ide_xml_parser_processing_instruction_sax_cb (ParserState   *state,
           else
             goto fail;
 
-          /* We skip adding gtkbuilder.rng here and add it from gresources after the parsing */
-          if (g_str_has_suffix (schema_url, "gtkbuilder.rng"))
+          /* We skip adding gtkbuilder.rng and gtk4builder.rng here and add it from gresources after the 
parsing */
+          if (g_str_has_suffix (schema_url, "gtkbuilder.rng") || g_str_has_suffix (schema_url, 
"gtk4builder.rng"))
             return;
 
           entry = ide_xml_schema_cache_entry_new ();
@@ -592,7 +614,10 @@ ide_xml_parser_get_analysis_worker (IdeTask      *task,
     }
   ide_xml_analysis_set_diagnostics (analysis, diagnostics);
 
-  if (state->file_is_ui)
+  /* by default use gtk4builder.rng and only gtkbuilder.rng if explicitly stated in the ui file.
+   * As gtkbuilder.rng is a subset of gtk4builder.rng this probably never makes problems.
+   */
+  if (state->file_is_ui && ide_xml_parser_file_is_gtk3 (state->file, doc_data, doc_size))
     {
       entry = ide_xml_schema_cache_entry_new ();
       entry->kind = SCHEMA_KIND_RNG;
@@ -600,6 +625,14 @@ ide_xml_parser_get_analysis_worker (IdeTask      *task,
       g_object_set_data (G_OBJECT (entry->file), "kind", GUINT_TO_POINTER (entry->kind));
       g_ptr_array_add (state->schemas, entry);
     }
+  else if (state->file_is_ui)
+    {
+      entry = ide_xml_schema_cache_entry_new ();
+      entry->kind = SCHEMA_KIND_RNG;
+      entry->file = g_file_new_for_uri ("resource:///plugins/xml-pack/schemas/gtk4builder.rng");
+      g_object_set_data (G_OBJECT (entry->file), "kind", GUINT_TO_POINTER (entry->kind));
+      g_ptr_array_add (state->schemas, entry);
+    }
 
   if (state->schemas != NULL && state->schemas->len > 0)
     ide_xml_analysis_set_schemas (analysis, g_steal_pointer (&state->schemas));
diff --git a/src/plugins/xml-pack/schemas/gtk4builder.rng b/src/plugins/xml-pack/schemas/gtk4builder.rng
new file mode 100644
index 000000000..8e1973fc0
--- /dev/null
+++ b/src/plugins/xml-pack/schemas/gtk4builder.rng
@@ -0,0 +1,491 @@
+<?xml version="1.0"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"; ns="">
+  <start>
+    <element name="interface">
+      <optional>
+        <attribute name="domain">
+          <text/>
+        </attribute>
+      </optional>
+      <zeroOrMore>
+        <choice>
+          <ref name="requires"/>
+          <ref name="object"/>
+          <ref name="template"/>
+          <ref name="menu"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </start>
+  <define name="requires">
+    <element name="requires">
+      <attribute name="lib">
+        <text/>
+      </attribute>
+      <attribute name="version">
+        <text/>
+      </attribute>
+    </element>
+  </define>
+  <define name="object">
+    <element name="object">
+      <optional>
+        <attribute name="id">
+          <data type="ID" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"/>
+        </attribute>
+      </optional>
+      <attribute name="class">
+        <text/>
+      </attribute>
+      <optional>
+        <attribute name="type-func">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="constructor">
+          <text/>
+        </attribute>
+      </optional>
+      <zeroOrMore>
+        <choice>
+          <ref name="property"/>
+          <ref name="signal"/>
+          <ref name="child"/>
+          <ref name="constraints"/>
+          <ref name="ANY"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="template">
+    <element name="template">
+      <attribute name="class">
+        <text/>
+      </attribute>
+      <attribute name="parent">
+        <text/>
+      </attribute>
+      <zeroOrMore>
+        <choice>
+          <ref name="property"/>
+          <ref name="signal"/>
+          <ref name="child"/>
+          <ref name="ANY"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="property">
+    <element name="property">
+      <attribute name="name">
+        <text/>
+      </attribute>
+      <optional>
+        <attribute name="translatable">
+          <choice>
+            <value>yes</value>
+            <value>no</value>
+          </choice>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="comments">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="context">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <group>
+          <attribute name="bind-source">
+            <text/>
+          </attribute>
+          <optional>
+            <attribute name="bind-property">
+              <text/>
+            </attribute>
+          </optional>
+          <optional>
+            <attribute name="bind-flags">
+              <text/>
+            </attribute>
+          </optional>
+        </group>
+      </optional>
+      <choice>
+        <text/>
+        <ref name="object"/>
+        <ref name="constant"/>
+        <ref name="lookup"/>
+        <ref name="closure"/>
+      </choice>
+    </element>
+  </define>
+  <define name="signal">
+    <element name="signal">
+      <attribute name="name">
+        <text/>
+      </attribute>
+      <attribute name="handler">
+        <text/>
+      </attribute>
+      <optional>
+        <attribute name="after">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="swapped">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="object">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="last_modification_time">
+          <text/>
+        </attribute>
+      </optional>
+      <empty/>
+    </element>
+  </define>
+  <define name="child">
+    <element name="child">
+      <optional>
+        <attribute name="type">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="internal-child">
+          <text/>
+        </attribute>
+      </optional>
+      <zeroOrMore>
+        <choice>
+          <ref name="object"/>
+          <ref name="ANY"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="menu">
+    <element name="menu">
+      <attribute name="id">
+        <data type="ID" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"/>
+      </attribute>
+      <optional>
+        <attribute name="domain">
+          <text/>
+        </attribute>
+      </optional>
+      <zeroOrMore>
+        <choice>
+          <ref name="item"/>
+          <ref name="submenu"/>
+          <ref name="section"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="item">
+    <element name="item">
+      <optional>
+        <attribute name="id">
+          <data type="ID" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"/>
+        </attribute>
+      </optional>
+      <zeroOrMore>
+        <choice>
+          <ref name="attribute_"/>
+          <ref name="link"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="attribute_">
+    <element name="attribute">
+      <attribute name="name">
+        <text/>
+      </attribute>
+      <optional>
+        <attribute name="type">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="translatable">
+          <choice>
+            <value>yes</value>
+            <value>no</value>
+          </choice>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="context">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="comments">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <text/>
+      </optional>
+    </element>
+  </define>
+  <define name="link">
+    <element name="link">
+      <optional>
+        <attribute name="id">
+          <data type="ID" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"/>
+        </attribute>
+      </optional>
+      <attribute name="name">
+        <text/>
+      </attribute>
+      <zeroOrMore>
+        <ref name="item"/>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="submenu">
+    <element name="submenu">
+      <optional>
+        <attribute name="id">
+          <data type="ID" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"/>
+        </attribute>
+      </optional>
+      <zeroOrMore>
+        <choice>
+          <ref name="attribute_"/>
+          <ref name="item"/>
+          <ref name="submenu"/>
+          <ref name="section"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="section">
+    <element name="section">
+      <optional>
+        <attribute name="id">
+          <data type="ID" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"/>
+        </attribute>
+      </optional>
+      <zeroOrMore>
+        <choice>
+          <ref name="attribute_"/>
+          <ref name="item"/>
+          <ref name="submenu"/>
+          <ref name="section"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="ANY">
+    <element>
+      <anyName>
+        <except>
+          <name>interface</name>
+          <name>requires</name>
+          <name>object</name>
+          <name>property</name>
+          <name>signal</name>
+          <name>child</name>
+          <name>menu</name>
+          <name>item</name>
+          <name>attribute</name>
+          <name>link</name>
+          <name>submenu</name>
+          <name>section</name>
+          <name>lookup</name>
+          <name>closure</name>
+          <name>constant</name>
+          <name>constraint</name>
+          <name>guide</name>
+        </except>
+      </anyName>
+      <zeroOrMore>
+        <attribute>
+          <anyName/>
+          <text/>
+        </attribute>
+      </zeroOrMore>
+      <interleave>
+        <zeroOrMore>
+          <ref name="ALL"/>
+        </zeroOrMore>
+        <optional>
+          <text/>
+        </optional>
+      </interleave>
+    </element>
+  </define>
+  <define name="ALL">
+    <element>
+      <anyName/>
+      <zeroOrMore>
+        <attribute>
+          <anyName/>
+          <text/>
+        </attribute>
+      </zeroOrMore>
+      <interleave>
+        <zeroOrMore>
+          <ref name="ALL"/>
+        </zeroOrMore>
+        <optional>
+          <text/>
+        </optional>
+      </interleave>
+    </element>
+  </define>
+  <define name="constant">
+    <element name="constant">
+      <attribute name="type">
+        <text/>
+      </attribute>
+      <optional>
+        <text/>
+      </optional>
+    </element>
+  </define>
+  <define name="lookup">
+    <element name="lookup">
+      <optional>
+        <attribute name="name">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="type">
+          <text/>
+        </attribute>
+      </optional>
+      <choice>
+        <text/>
+        <ref name="constant"/>
+      </choice>
+    </element>
+  </define>
+  <define name="closure">
+    <element name="closure">
+      <attribute name="type">
+        <text/>
+      </attribute>
+      <attribute name="function">
+        <text/>
+      </attribute>
+      <zeroOrMore>
+        <choice>
+          <ref name="constant"/>
+          <ref name="lookup"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+  <define name="guide">
+    <element name="guide">
+      <optional>
+        <attribute name="name">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="min-width">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="min-height">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="nat-width">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="nat-height">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="max-width">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="max-height">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="strength">
+          <text/>
+        </attribute>
+      </optional>
+    </element>
+  </define>
+  <define name="constraint">
+    <element name="constraint">
+      <attribute name="target">
+        <text/>
+      </attribute>
+      <attribute name="target-attribute">
+        <text/>
+      </attribute>
+      <optional>
+        <group>
+          <attribute name="source">
+            <text/>
+          </attribute>
+          <attribute name="source-attribute">
+            <text/>
+          </attribute>
+        </group>
+      </optional>
+      <optional>
+        <attribute name="relation">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="constant">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="multiplier">
+          <text/>
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="strength">
+          <text/>
+        </attribute>
+      </optional>
+    </element>
+  </define>
+  <define name="constraints">
+    <element name="constraints">
+      <zeroOrMore>
+        <choice>
+          <ref name="guide"/>
+          <ref name="constraint"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+</grammar>
diff --git a/src/plugins/xml-pack/xml-pack.gresource.xml b/src/plugins/xml-pack/xml-pack.gresource.xml
index e54ca183d..4219e5c9e 100644
--- a/src/plugins/xml-pack/xml-pack.gresource.xml
+++ b/src/plugins/xml-pack/xml-pack.gresource.xml
@@ -3,5 +3,6 @@
   <gresource prefix="/plugins/xml-pack">
     <file>xml-pack.plugin</file>
     <file>schemas/gtkbuilder.rng</file>
+    <file>schemas/gtk4builder.rng</file>
   </gresource>
 </gresources>


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