diff --git a/lastpluie-yaml-0.5.tar.gz b/lastpluie-yaml-0.5.tar.gz new file mode 100644 index 0000000..45dfc78 Binary files /dev/null and b/lastpluie-yaml-0.5.tar.gz differ diff --git a/meson.build b/meson.build index 1e57ce7..2352cd4 100644 --- a/meson.build +++ b/meson.build @@ -49,6 +49,7 @@ configure_file( install_data([ 'resources/main.yml', 'resources/tag.yml', + 'resources/bug.yml', 'resources/test.yml', 'resources/test.json' ], diff --git a/resources/bug.yml b/resources/bug.yml new file mode 100644 index 0000000..aa9890f --- /dev/null +++ b/resources/bug.yml @@ -0,0 +1,82 @@ +%YAML 1.2 +%TAG !v! tag:pluie.org,2018:vala/ +--- +!v!Pluie.Berel.Meta meta : + !v!Gee.ArrayList keys : + - software : berel; + - version : 0.24 + - type : program + - date : 2018 + - license : GPLv3.0; + - author : a-Sansara; <[dev]at[pluie]dot[org]> + - copyright : pluie.org; + + !v!Gee.ArrayList headers : + - !v!Pluie.Berel.HeaderDef sh : + file : + - build.sh + startline : 2 # to embed shebang before header tpl + sepline : + motif : "# " + repeat : 40 + comment : + start : "#^#" + end : "#^#" + begin : "# " + - !v!Pluie.Berel.HeaderDef meson : + file : + - meson.build + - src/meson.build + sepline : + motif : "# " + repeat : 40 + comment : + start : "#^#" + end : "#^#" + begin : "# " + - !v!Pluie.Berel.HeaderDef vala : + dir : + - src + extension : + - .vala + sepline : + motif : " *" + repeat : 40 + comment : + start : "/*^" + end : "^*/" + begin : " * " + + tpl : | + ^sepline^ + + ^keys^ + + ^sepline^ + + This file is part of ^software.name^. + + ^software.name^ is free software (free as in speech) : you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + ^software.name^ 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 General Public License for + more details. + + You should have received a copy of the GNU General Public License + along with ^software.name^. If not, see . + + ^sepline^ + + product: + - sku : BL394D + quantity : 4 + description : Basketball + price : 450.00 + - sku : BL394D + quantity : 4 + description : Basketball + price : 450.00 diff --git a/samples/yaml-bug.vala b/samples/yaml-bug.vala new file mode 100644 index 0000000..51d3275 --- /dev/null +++ b/samples/yaml-bug.vala @@ -0,0 +1,55 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * @software : pluie-yaml + * @version : 0.5 + * @type : library + * @date : 2018 + * @licence : GPLv3.0 + * @author : a-Sansara <[dev]at[pluie]dot[org]> + * @copyright : pluie.org + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * This file is part of pluie-yaml. + * + * pluie-yaml is free software (free as in speech) : you can redistribute it + * and/or modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * pluie-yaml 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 General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with pluie-yaml. If not, see . + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + */ + + +using GLib; +using Gee; +using Pluie; + +int main (string[] args) +{ + Echo.init(false); + + var path = Yaml.DATA_PATH + "/bug.yml"; + var done = false; + + of.title ("Pluie Yaml Library", Pluie.Yaml.VERSION, "a-sansara"); + Pluie.Yaml.DEBUG = false; + var loader = new Yaml.Loader (path, true, true); + if ((done = loader.done)) { + var root = loader.get_nodes (); + done = root != null; + } + + of.rs (done); + of.echo (); + return (int) done; + +} diff --git a/samples/yaml-tag.vala b/samples/yaml-tag.vala index 533bf32..f3cfb35 100644 --- a/samples/yaml-tag.vala +++ b/samples/yaml-tag.vala @@ -41,7 +41,7 @@ int main (string[] args) var done = false; of.title ("Pluie Yaml Library", Pluie.Yaml.VERSION, "a-sansara"); - Pluie.Yaml.DEBUG = false; + Pluie.Yaml.DEBUG = true; Yaml.Object? obj = null; var config = new Yaml.Config (path, true); var root = config.root_node (); diff --git a/src/vala/Pluie/Yaml.Loader.vala b/src/vala/Pluie/Yaml.Loader.vala index 4cc49b4..1364a1c 100644 --- a/src/vala/Pluie/Yaml.Loader.vala +++ b/src/vala/Pluie/Yaml.Loader.vala @@ -36,20 +36,23 @@ using Pluie; */ public class Pluie.Yaml.Loader { + /** + * Flag PACK_NESTED_ENTRIES + */ + public static bool PACK_NESTED_ENTRIES { public get; public set; default = false; } /** * Yaml.Scanner used to retriew yaml events */ - Yaml.Scanner scanner { public get; internal set; } - + Yaml.Scanner scanner { public get; internal set; } /** * indicate if file has been sucessfully loaded */ - public bool done { get; internal set; } + public bool done { get; internal set; } /** * Reader used to load content yaml file */ - Io.Reader reader; + Io.Reader reader; /** * default constructor of Yaml.Loader @@ -84,7 +87,33 @@ public class Pluie.Yaml.Loader */ public Yaml.Node? get_nodes () { - return this.scanner.get_nodes (); + Yaml.Node? n = this.scanner.get_nodes (); + if (PACK_NESTED_ENTRIES) { + this.pack_entries (n); + } + return n; + } + + /** + * + */ + private void pack_entries (Yaml.Node? node = null) + { + bool restart = false; + if (node != null) { + if (node.ntype.is_sequence ()) { + foreach (var child in node) { + if (child.ntype.is_mapping () && child.name[0] == '_' && child.count () == 1) { + var sub = child.first ().clone_node (); + node.replace_node (child, sub); + restart = true; + break; + } + } + if (restart) pack_entries (node); + } + else foreach (var child in node) this.pack_entries (child); + } } /** diff --git a/src/vala/Pluie/Yaml.Node.vala b/src/vala/Pluie/Yaml.Node.vala index 22e23dd..0d6d1c4 100644 --- a/src/vala/Pluie/Yaml.Node.vala +++ b/src/vala/Pluie/Yaml.Node.vala @@ -76,6 +76,8 @@ public class Pluie.Yaml.Node : Yaml.AbstractChild, Pluie.Yaml.Collection } catch (Yaml.AddNodeError e) { of.warn (e.message); + Yaml.dbg (this.to_string ()); + this.display_childs (); } return done; } @@ -261,6 +263,21 @@ public class Pluie.Yaml.Node : Yaml.AbstractChild, Pluie.Yaml.Collection return v; } + /** + * + */ + public void replace_node (Yaml.Node child, Yaml.Node new_child) + { + int index = this.list.index_of (child); + if (index > -1) { + new_child.level = this.level + 1; + new_child.parent = this; + new_child.update_level (); + this.list.remove_at (index); + this.list.insert (index, new_child); + } + } + /** * display childs * @param withTitle display a title before the childs node presentation diff --git a/src/vala/Pluie/Yaml.Processor.vala b/src/vala/Pluie/Yaml.Processor.vala index 1b3b34c..d73b401 100644 --- a/src/vala/Pluie/Yaml.Processor.vala +++ b/src/vala/Pluie/Yaml.Processor.vala @@ -46,6 +46,21 @@ public class Pluie.Yaml.Processor */ bool change; + /** + * indicates if document start begin + */ + bool begin; + + /** + * indicates if new node is a sequence entry + */ + bool isEntry; + + /** + * indicates if new node is a sequence entry mapping + */ + bool isEntryMapping; + /** * indicates if begon a flow sequence */ @@ -174,7 +189,7 @@ public class Pluie.Yaml.Processor this.reset (); for (var has_next = this.iterator.next (); has_next; has_next = this.iterator.next ()) { this.event = this.iterator.get (); - Yaml.dbg (" 0>>>>> [EVENT event [%d] %s <<<<< %s".printf (this.indexEvt++, this.event.evtype.infos (), Log.METHOD)); + Yaml.dbg (" [[[ EVENT %d %s ]]]".printf (this.indexEvt++, this.event.evtype.infos ())); if (this.event.evtype.is_tag_directive ()) { this.on_tag_directive (); } @@ -182,28 +197,48 @@ public class Pluie.Yaml.Processor this.on_error (); break; } - if (this.event.evtype.is_mapping_end () || this.event.evtype.is_sequence_end ()) { - this.on_block_end (); - continue; - } - if (this.event.evtype.is_entry ()) { - this.on_entry (); - } - if (this.beginFlowSeq && this.event.evtype.is_scalar ()) { - if (!this.change) { - this.on_scalar (true); + if (!this.begin) { + if (this.event.evtype.is_document_start ()) { + this.begin = true; + // to do + this.next_event (); + continue; } - this.beginFlowSeq = false; } - if (this.event.evtype.is_key () && (this.event = this.get_value_key_event ()) != null) { - this.on_key (); - } - if (this.event.evtype.is_value () && (this.event = this.get_value_event ()) != null) { - this.on_value (); + else { + if (this.event.evtype.is_mapping_end () || this.event.evtype.is_sequence_end ()) { + this.on_block_end (); + continue; + } + if (this.event.evtype.is_key () && (this.event = this.get_value_key_event ()) != null) { + this.on_key (); + } + if (this.event.evtype.is_anchor ()) { + this.event = this.next_event (); + this.on_anchor (); + } + if (this.event.evtype.is_alias ()) { + this.event = this.next_event (); + this.on_alias (); + } + else if (this.event.evtype.is_entry ()) { + this.on_entry (); + } + else if (this.event.evtype.is_mapping_start ()) { + this.create_mapping (this.isEntry); + } + else if (this.event.evtype.is_sequence_start ()) { + this.on_sequence_start (); + } + else if (this.event.evtype.is_value ()) { + continue; + } + else if (this.event.evtype.is_scalar ()) { + this.on_scalar (); + } this.add_anchor_if_needed (); - this.ckey = null; + this.on_update (); } - this.on_update (); } this.done = error_event == null && this.root != null; return done; @@ -227,6 +262,9 @@ public class Pluie.Yaml.Processor this.beginFlowSeq = false; this.nextValueEvt = null; this.indexEvt = 0; + this.isEntry = false; + this.begin = false; + this.isEntryMapping = false; } /** @@ -242,6 +280,19 @@ public class Pluie.Yaml.Processor return evt; } + /** + * retriew the next Yaml Event without use of iterator + */ + private Yaml.Event? get_next_event () + { + Yaml.Event? evt = null; + var i = this.indexEvt; + if (i < this.events.size) { + evt = this.events.get (i); + } + return evt; + } + /** * retriew the next Yaml Value Event closest to Key Event */ @@ -275,13 +326,15 @@ public class Pluie.Yaml.Processor private Yaml.Event? get_next_value_event () { Yaml.Event? evt = null; - var i = this.indexEvt+1; + var i = this.indexEvt; + Yaml.dbg (" >>> %s from %d".printf (Log.METHOD, i)); var search = true; while (search) { if (i < this.events.size) { var e = this.events.get (i++); if (e != null && e.evtype.is_value ()) { evt = this.events.get (i); + Yaml.dbg (" >>> %s > %d : %s".printf (Log.METHOD, i, evt.evtype.infos ())); break; } } @@ -321,17 +374,19 @@ public class Pluie.Yaml.Processor */ private void on_block_end () { - Yaml.dbg (" ===== ON BLOCK END ===== "); + Yaml.dbg (" ===== >> ON BLOCK END ===== "); Yaml.dbg (" - parent_node : %s (%s)".printf (this.parent_node.name, this.parent_node.ntype.infos ())); Yaml.dbg (" - prev_node : %s (%s - collection ? %s)".printf (this.prev_node.name, this.prev_node.ntype.infos (), this.prev_node.ntype.is_collection ().to_string ())); bool suite = true; if (this.prev_node.ntype.is_mapping () && this.prev_node.parent != null && this.prev_node.parent.ntype.is_sequence ()) { if (!(this.prev_node.parent as Yaml.Sequence).close_block) { (this.prev_node.parent as Yaml.Sequence).close_block = true; - suite = false; + Yaml.dbg (" SET FALSE SUITE"); +//~ suite = false; } } if (suite) { + Yaml.dbg (" SUITE"); if (this.prev_node.ntype.is_scalar () || (this.prev_node.ntype.is_single_pair () && this.prev_node.parent != null && this.prev_node.parent.ntype.is_mapping ())) { this.prev_node = this.prev_node.parent; } @@ -340,6 +395,10 @@ public class Pluie.Yaml.Processor : this.root; this.prev_node = this.parent_node; } + Yaml.dbg (" - parent_node : %s (%s)".printf (this.parent_node.name, this.parent_node.ntype.infos ())); + Yaml.dbg (" - prev_node : %s (%s - collection ? %s)".printf (this.prev_node.name, this.prev_node.ntype.infos (), this.prev_node.ntype.is_collection ().to_string ())); + Yaml.dbg (this.prev_node.to_string ()); + Yaml.dbg (" ===== << ON BLOCK END ====================== "); } /** @@ -347,15 +406,13 @@ public class Pluie.Yaml.Processor */ private void on_entry () { - this.event = this.next_event(); - Yaml.Event? e = null; - // look up for sequence enrty nested block - e = get_next_value_event (); - if (this.event.evtype.is_mapping_start () && (e!= null && !e.evtype.is_mapping_start () && !e.evtype.is_scalar ())) { - this.on_mapping_start (!e.evtype.is_scalar ()); - } - else if (this.event.evtype.is_scalar ()) { - this.on_scalar (true); + this.isEntry = true; + this.ckey = null; + var e = this.get_next_event (); + if (e!= null && e.evtype.is_mapping_start ()) { + this.isEntryMapping = true; + this.create_mapping (true); + this.next_event (); } } @@ -387,7 +444,10 @@ public class Pluie.Yaml.Processor private void on_key () { this.on_tag (true); - this.ckey = this.event.data["data"]; + if (this.event.evtype.is_scalar ()) { + this.ckey = this.event.data["data"]; + Yaml.dbg (" >> node name : %s".printf (this.ckey)); + } } /** @@ -395,22 +455,21 @@ public class Pluie.Yaml.Processor */ private void on_value () { - this.on_tag (false); - if (this.event.evtype.is_scalar ()) { - this.on_scalar (); + var e = this.get_next_event(); + if (e.evtype.is_scalar ()) { + this.event = this.next_event (); + this.on_tag (false); + this.node = new Yaml.Scalar (this.parent_node, this.event.data["data"]); + this.change = true; } - else if (this.event.evtype.is_anchor ()) { + else if (e.evtype.is_anchor ()) { + this.event = this.next_event (); this.on_anchor (); } - else if (this.event.evtype.is_alias ()) { + else if (e.evtype.is_alias ()) { + this.event = this.next_event (); this.on_alias (); } - if (this.event.evtype.is_mapping_start ()) { - this.on_mapping_start (); - } - else if (this.event.evtype.is_sequence_start ()) { - this.on_sequence_start (); - } } /** @@ -418,16 +477,13 @@ public class Pluie.Yaml.Processor */ private void on_scalar (bool entry = false) { - if (!entry) { - if (this.ckey != null) { - this.node = new Yaml.Mapping.with_scalar (this.parent_node, this.ckey, this.event.data["data"]); - this.change = true; - } + if (this.ckey != null && this.parent_node.ntype.is_mapping ()) { + this.node = new Yaml.Mapping.with_scalar (this.parent_node, this.ckey, this.event.data["data"]); } else { - this.node = new Yaml.Scalar (this.parent_node, this.event.data["data"]); - this.change = true; + this.node = new Yaml.Scalar (this.parent_node, this.event.data["data"]); } + this.change = true; } /** @@ -436,7 +492,6 @@ public class Pluie.Yaml.Processor private void on_anchor () { this.idAnchor = this.event.data["id"]; - this.event = this.next_event (); } /** @@ -460,7 +515,7 @@ public class Pluie.Yaml.Processor { this.node = new Yaml.Sequence (this.parent_node, this.ckey); this.change = true; - this.beginFlowSeq = true; +//~ this.beginFlowSeq = true; } /** @@ -468,11 +523,26 @@ public class Pluie.Yaml.Processor */ private void on_mapping_start (bool entry = false) { - if (entry) { - this.create_mapping (entry); - this.ckey = null; + this.ckey = null; + this.event = this.next_event (); + if (this.event.evtype.is_key ()) { + this.event = this.next_event (); + this.on_tag (true); + if (this.event.evtype.is_scalar ()) { + this.ckey = this.event.data["data"]; + Yaml.dbg (" >> node name : %s".printf (this.ckey)); + } + var e = this.get_next_value_event(); +//~ Yaml.dbg (e.evtype.infos ()); + if (e!=null) { + if ( e.evtype.is_sequence_start ()) { + this.on_sequence_start (); + } + else { + this.create_mapping (this.isEntry); + } + } } - else this.create_mapping (); } /** @@ -480,7 +550,7 @@ public class Pluie.Yaml.Processor */ private void create_mapping (bool entry = false) { - if (entry) { + if (entry && this.ckey == null) { this.ckey = "_%d".printf(this.parent_node.count()); } this.node = new Yaml.Mapping (this.parent_node, this.ckey); @@ -506,7 +576,9 @@ public class Pluie.Yaml.Processor private void on_update () { if (this.node != null) { + Yaml.dbg (Log.METHOD); Yaml.dbg (this.node.name); + Yaml.dbg (this.node.ntype.infos ()); } if (this.change) { if (this.node.parent.ntype.is_sequence ()) { @@ -537,7 +609,9 @@ public class Pluie.Yaml.Processor this.keyTag = null; this.valueTag = null; this.node = null; + this.isEntryMapping = false; this.change = false; + this.isEntry = false; } } diff --git a/src/vala/Pluie/Yaml.global.vala b/src/vala/Pluie/Yaml.global.vala index b990d17..baf4c2a 100644 --- a/src/vala/Pluie/Yaml.global.vala +++ b/src/vala/Pluie/Yaml.global.vala @@ -319,6 +319,14 @@ namespace Pluie.Yaml return this == EVT.NONE; } + /** + * @return event is document start event + */ + public bool is_document_start () + { + return this == EVT.DOCUMENT_START; + } + } /**