diff --git a/samples/yaml-imports.vala b/samples/yaml-imports.vala index c2429e4..4d4aea5 100644 --- a/samples/yaml-imports.vala +++ b/samples/yaml-imports.vala @@ -35,8 +35,6 @@ int main (string[] args) { Echo.init(false); - var pwd = Environment.get_variable ("PWD"); -//~ var path = Path.build_filename (pwd, "resources/main.yml"); var path = "./resources/main.yml"; var done = false; @@ -59,10 +57,6 @@ int main (string[] args) of.rs (done); of.echo (); - - of.echo (pwd); - - return (int) done; } diff --git a/src/vala/Pluie/Yaml.Config.vala b/src/vala/Pluie/Yaml.Config.vala index e2ed9f1..d6ae935 100644 --- a/src/vala/Pluie/Yaml.Config.vala +++ b/src/vala/Pluie/Yaml.Config.vala @@ -3,31 +3,40 @@ */ public class Pluie.Yaml.Config { - const char IMPORTS_SPE = '^'; + /** + * + */ + const char IMPORTS_SPE = '^'; + /** * current path */ - public string? path { get; internal set; default = null; } + public string? path { get; internal set; default = null; } + + /** + * + */ + public bool displayFile { get; internal set; } /** * Yaml Loader */ - public Yaml.Loader loader { internal get; internal set; } + public Yaml.Loader loader { internal get; internal set; } /** * Yaml Finder */ - public Yaml.Finder finder { internal get; internal set; } + public Yaml.Finder finder { internal get; internal set; } /** * imports var */ - Gee.HashMap varmap { get; internal set; } + Gee.HashMap varmap { get; internal set; } /** * imports paths */ - Gee.HashMap paths { get; internal set; } + Gee.HashMap paths { get; internal set; } /** * construct a Yaml Config for specifiyed path @@ -36,6 +45,7 @@ public class Pluie.Yaml.Config { Yaml.BaseNode.mode = mode; this.path = path; + this.displayFile = displayFile; if (this.path != null) { this.loader = new Yaml.Loader (this.path, displayFile, false); Yaml.NodeRoot? root = this.loader.get_nodes (); @@ -84,22 +94,32 @@ public class Pluie.Yaml.Config } } this.update_var (node, dir); - - foreach(var entry in this.paths.entries) { - var config = new Yaml.Config(entry.value); - Yaml.NodeMap sub = config.loader.get_nodes (); - Yaml.NodeMap n = new Yaml.NodeMap (root, entry.key); - foreach(var subnode in sub.map.values) { - subnode.parent = null; - n.add(subnode); - } - root.add (n); - } - root.update_level(); + this.import_files(root); } } } + /** + * + */ + private void import_files (Yaml.NodeRoot root) + { + Yaml.NodeMap? sub = null; + Yaml.NodeMap? n = null; + Yaml.Config? conf = null; + foreach(var entry in this.paths.entries) { + conf = new Yaml.Config(entry.value, this.displayFile); + sub = conf.loader.get_nodes (); + n = new Yaml.NodeMap (root, entry.key); + foreach(var subnode in sub.map.values) { + subnode.parent = null; + n.add(subnode); + } + root.add (n); + } + root.update_level(); + } + /** * */ @@ -113,14 +133,20 @@ public class Pluie.Yaml.Config if (!Path.is_absolute (val)) { val = Path.build_filename(path, val); } - // update var - foreach (var v in this.varmap.entries) { - if (v.key != "path") { - entry.value.data = val.replace ("^%s^".printf (v.key), v.value); - this.paths[entry.key] = entry.value.data; - of.keyval (entry.key, entry.value.data); - } - } + this.resolve_var (entry.key, val); + } + } + } + + /** + * + */ + private void resolve_var (string key, string val) + { + foreach (var v in this.varmap.entries) { + if (v.key != "path") { + this.paths[key] = val.replace ("^%s^".printf (v.key), v.value); + if (Yaml.Scanner.DEBUG) of.keyval (key, this.paths[key]); } } } diff --git a/src/vala/Pluie/Yaml.Loader.vala b/src/vala/Pluie/Yaml.Loader.vala index c9abfab..f7a3cf8 100644 --- a/src/vala/Pluie/Yaml.Loader.vala +++ b/src/vala/Pluie/Yaml.Loader.vala @@ -59,18 +59,17 @@ public class Pluie.Yaml.Loader public Loader (string path, bool displayFile = false, bool displayNode = false ) { this.reader = new Io.Reader (path); - if (displayFile) { - this.displayFile (); - } this.scanner = new Yaml.Scanner (path); - if ((this.done = this.scanner.run()) && displayNode) { - var n = this.get_nodes (); - if (n != null) { - n.display_childs (); + if (displayFile) this.displayFile (); + + if ((this.done = this.scanner.run())) { + if (displayNode) { + var n = this.get_nodes (); + if (n != null) n.display_childs (); + of.state(n != null); } - of.state(n != null); } - if (!this.done) { + else { var evt = this.scanner.get_error_event (); of.error ("line %d (%s)".printf (evt.line, evt.data["error"])); this.displayFile (evt.line); @@ -80,11 +79,30 @@ public class Pluie.Yaml.Loader /** * return resulting Yaml root node */ - public Yaml.NodeRoot get_nodes () + public Yaml.NodeRoot? get_nodes () { return this.scanner.get_nodes (); } + /** + * bypass_ellipse + */ + private bool bypass_ellipse (int errorLine, int line) + { + bool bypass = false; + if (errorLine > 0 && line > 0) { + if (line < errorLine - 7) bypass = true; + else if (line == errorLine - 7 && line > 1) { + of.echo ("%s%s%s".printf ( + of.c (ECHO.MICROTIME ).s (" %03d ".printf (line-1)), + of.c (ECHO.DATE).s ("| "), + of.c (ECHO.COMMAND).s ("... ") + )); + } + } + return bypass; + } + /** * display original file */ @@ -93,39 +111,29 @@ public class Pluie.Yaml.Loader of.action (errorLine == 0 ? "Reading file" : "Invalid Yaml File", this.reader.path); of.echo (); this.reader.rewind(new Io.StreamLineMark(0, 0)); - int line = 0; - string? data = null; + int line = 0; + string? data = null; + bool err = false; + bool before = false; while (this.reader.readable) { - line = this.reader.line + 1; - data = this.reader.read (); - if (errorLine > 0 && line > 0) { - if (line < errorLine - 7) continue; - else if (line == errorLine - 7) { - of.echo ("%s%s%s".printf ( - of.c (ECHO.MICROTIME ).s (" %03d ".printf (line-1)), - of.c (ECHO.DATE).s ("| "), - of.c (ECHO.COMMAND).s ("... ") - )); - } - } - if (data !=null) { - ECHO color = data.strip()[0] != '#' ? ECHO.COMMAND : ECHO.COMMENT; - of.echo ("%s%s%s".printf ( - of.c (ECHO.MICROTIME ).s (" %03d ".printf (line)), - of.c (ECHO.DATE).s ("| "), - errorLine > 0 && line == errorLine - ? of.c (ECHO.FAIL).s (data) - : of.c (color).s (data) - ), errorLine == 0 || line < errorLine); - } - if (errorLine > 0 && line == errorLine) { + line = this.reader.line + 1; + data = this.reader.read (); + err = errorLine > 0 && line == errorLine; + before = errorLine == 0 || line < errorLine; + if (this.bypass_ellipse (errorLine, line)) continue; + ECHO color = data!=null && data.strip()[0] != '#' ? ECHO.COMMAND : ECHO.COMMENT; + of.echo ("%s%s%s".printf ( + of.c (ECHO.MICROTIME ).s (" %03d ".printf (line)), + of.c (ECHO.DATE).s ("| "), + err ? of.c (ECHO.FAIL).s (data) + : of.c (color).s (data) + ), before); + if (err) { int len = of.term_width - data.length - 13; stdout.printf (of.c (ECHO.FAIL).s (@" %$(len)s ".printf (" "))); of.echo (Color.off (), true); } - if (errorLine > 0 && line > errorLine) { - break; - } + else if (!before) break; } of.echo (errorLine == 0 ? "EOF" : ""); of.state (errorLine == 0); diff --git a/src/vala/Pluie/Yaml.Node.vala b/src/vala/Pluie/Yaml.Node.vala index 154d291..d445c51 100644 --- a/src/vala/Pluie/Yaml.Node.vala +++ b/src/vala/Pluie/Yaml.Node.vala @@ -114,7 +114,6 @@ public interface Pluie.Yaml.Node : Object */ public abstract void update_level (); - /** * get a presentation string of current Yaml.Node */ diff --git a/src/vala/Pluie/Yaml.Processor.vala b/src/vala/Pluie/Yaml.Processor.vala index ad19e72..07c3dbc 100644 --- a/src/vala/Pluie/Yaml.Processor.vala +++ b/src/vala/Pluie/Yaml.Processor.vala @@ -41,6 +41,26 @@ public class Pluie.Yaml.Processor */ public bool done; + /** + * indicates if new node has been created + */ + bool change; + + /** + * indicates if begon a flow sequence + */ + bool beginFlowSeq; + + /** + * current anchor id + */ + string? idAnchor; + + /** + * current key + */ + string? ckey; + /** * Events list */ @@ -51,6 +71,11 @@ public class Pluie.Yaml.Processor */ Gee.HashMap anchors { get; internal set; } + /** + * Error event + */ + Yaml.Event? event { get; internal set; } + /** * Error event */ @@ -77,9 +102,9 @@ public class Pluie.Yaml.Processor Yaml.Node node; /** - * previous level + * Yaml.Event Iterator */ - int prev_level; + Gee.Iterator iterator; /** * @@ -115,155 +140,262 @@ public class Pluie.Yaml.Processor /** * retriew the next Yaml Event - * @param the iterator */ - private Yaml.Event? next_event (Iterator it) + private Yaml.Event? next_event () { Yaml.Event? evt = null; - if (it.has_next () && it.next ()) { - evt = it.get (); + if (this.iterator.has_next () && this.iterator.next ()) { + evt = this.iterator.get (); } return evt; } /** * retriew the next Yaml Value Event closest to Key Event - * @param the iterator */ - private Yaml.Event? get_value_key_event (Iterator it) + private Yaml.Event? get_value_key_event () { Yaml.Event? evt = null; - var e = it.get (); + var e = this.iterator.get (); if (e != null && e.evtype.is_key ()) { - evt = this.next_event (it); + evt = this.next_event (); } return evt; } /** * retriew the next Yaml Value Event - * @param the iterator */ - private Yaml.Event? get_value_event (Iterator it) + private Yaml.Event? get_value_event () { Yaml.Event? evt = null; - var e = it.get (); + var e = this.iterator.get (); if (e != null && e.evtype.is_value ()) { - evt = this.next_event (it); + evt = this.next_event (); } return evt; } + /** + * + */ + public void reset () + { + this.root = new Yaml.NodeRoot (); + this.prev_node = this.root; + this.parent_node = this.root; + this.iterator = this.events.iterator (); + this.change = false; + this.ckey = null; + this.idAnchor = null; + this.beginFlowSeq = false; + } + /** * processing the events list and generate the corresponding Yaml Nodes */ public bool run () { - if (Pluie.Yaml.Scanner.DEBUG) this.read (); - this.root = new Yaml.NodeRoot (); - this.prev_node = this.root; - this.parent_node = this.root; - this.prev_level = this.root.level; - int level = this.root.level + 1; - var it = this.events.iterator (); - var change = false; - string? key = null; - string? id = null; - bool beginFlowSeq = false; - Yaml.Event? evt; - if (Pluie.Yaml.Scanner.DEBUG) of.action ("Processing events"); - for (var has_next = it.next (); has_next; has_next = it.next ()) { - evt = it.get (); - if (evt.evtype.is_error ()) { - error_event = evt; + if (Yaml.Scanner.DEBUG) { + this.read (); + of.action ("Processing events"); + } + this.reset (); + for (var has_next = this.iterator.next (); has_next; has_next = this.iterator.next ()) { + this.event = this.iterator.get (); + if (this.event.evtype.is_error ()) { + this.on_error (); break; } - if (evt.evtype.is_mapping_end () || evt.evtype.is_sequence_end ()) { - level -= 4; - this.parent_node = this.prev_node.parent != null && this.prev_node.parent != this.root - ? this.prev_node.parent.parent - : this.root; - this.prev_node = this.parent_node; + if (this.event.evtype.is_mapping_end () || this.event.evtype.is_sequence_end ()) { + this.on_block_end (); continue; } - if (evt.evtype.is_entry ()) { - evt = this.next_event(it); - if (evt.evtype.is_mapping_start ()) { - key = "_%d".printf((this.parent_node as Yaml.NodeSequence).get_size()); - this.node = new Yaml.NodeMap (this.parent_node, key); - key = null; - level += 1; - change = true; - } - else if (evt.evtype.is_scalar ()) { - var content = evt.data["data"]; - this.node = new Yaml.NodeScalar (this.parent_node, content); - change = true; - } + if (this.event.evtype.is_entry ()) { + this.on_entry (); } - if (beginFlowSeq && evt.evtype.is_scalar ()) { - var content = evt.data["data"]; - this.node = new Yaml.NodeScalar (this.parent_node, content); - change = true; - beginFlowSeq = false; + if (this.beginFlowSeq && this.event.evtype.is_scalar ()) { + this.on_scalar (true); + this.beginFlowSeq = false; } - if (evt.evtype.is_key () && (evt = this.get_value_key_event (it)) != null) { - key = evt.data["data"]; + if (this.event.evtype.is_key () && (this.event = this.get_value_key_event ()) != null) { + this.on_key (); } - if (evt.evtype.is_value () && (evt = this.get_value_event (it)) != null) { - if (evt.evtype.is_scalar ()) { - var content = evt.data["data"]; - if (key != null) { - this.node = new Yaml.NodeSinglePair (this.parent_node, key, content); - change = true; - } + if (this.event.evtype.is_value () && (this.event = this.get_value_event ()) != null) { + this.on_value (); + if (this.event.evtype.is_mapping_start ()) { + this.on_mapping_start (); } - else if (evt.evtype.is_anchor ()) { - id = evt.data["id"]; - evt = this.next_event (it); + else if (this.event.evtype.is_sequence_start ()) { + this.on_sequence_start (); } - else if (evt.evtype.is_alias ()) { - id = evt.data["id"]; - Yaml.Node? refnode = this.anchors.get(id); - if (refnode != null) { - this.node = refnode.clone_node (key); - this.parent_node.add (this.node); - this.prev_node = this.node; - this.prev_level = this.prev_node.level; - } - } - if (evt.evtype.is_mapping_start ()) { - this.node = new Yaml.NodeMap (this.parent_node, key); - level += 1; - change = true; - } - else if (evt.evtype.is_sequence_start ()) { - this.node = new Yaml.NodeSequence (this.parent_node, key); - level += 1; - change = true; - beginFlowSeq = true; - } - if (id != null) { - if (this.node != null) { - this.anchors.set(id, this.node); - } - id = null; - } - key = null; - } - if (change) { - this.parent_node.add (this.node); - if (this.node.node_type.is_collection ()) { - this.parent_node = this.node; - } - this.prev_node = this.node; - this.prev_level = this.prev_node.level; - this.node = null; - change = false; + this.add_anchor_if_needed (); + this.ckey = null; } + this.on_update (); } this.done = error_event == null && this.root != null; return done; } + /** + * + */ + private void on_error () + { + this.error_event = this.event; + } + + /** + * + */ + private void on_block_end () + { + this.parent_node = this.prev_node.parent != null && this.prev_node.parent != this.root + ? this.prev_node.parent.parent + : this.root; + this.prev_node = this.parent_node; + } + + /** + * + */ + private void on_entry () + { + this.event = this.next_event(); + if (this.event.evtype.is_mapping_start ()) { + this.on_mapping_start (true); + } + else if (this.event.evtype.is_scalar ()) { + this.on_scalar (true); + } + } + + /** + * + */ + private void on_key () + { + this.ckey = this.event.data["data"]; + } + + /** + * + */ + private void on_value () + { + if (this.event.evtype.is_scalar ()) { + this.on_scalar (); + } + else if (this.event.evtype.is_anchor ()) { + this.on_anchor (); + } + else if (this.event.evtype.is_alias ()) { + this.on_alias (); + } + } + + /** + * + */ + private void on_scalar (bool entry = false) + { + if (!entry) { + if (this.ckey != null) { + this.node = new Yaml.NodeSinglePair (this.parent_node, this.ckey, this.event.data["data"]); + this.change = true; + } + } + else { + this.node = new Yaml.NodeScalar (this.parent_node, this.event.data["data"]); + this.change = true; + } + } + + /** + * + */ + private void on_anchor () + { + this.idAnchor = this.event.data["id"]; + this.event = this.next_event (); + } + + /** + * + */ + private void on_alias () + { + this.idAnchor = this.event.data["id"]; + Yaml.Node? refnode = this.anchors.get(this.idAnchor); + if (refnode != null) { + this.node = refnode.clone_node (this.ckey); + this.parent_node.add (this.node); + this.prev_node = this.node; + } + } + + /** + * + */ + private void on_sequence_start () + { + this.node = new Yaml.NodeSequence (this.parent_node, this.ckey); + this.change = true; + this.beginFlowSeq = true; + } + + /** + * + */ + private void on_mapping_start (bool entry = false) + { + if (entry) { + this.create_mapping (entry); + this.ckey = null; + } + else this.create_mapping (); + } + + /** + * + */ + private void create_mapping (bool entry = false) + { + if (entry) { + this.ckey = "_%d".printf((this.parent_node as Yaml.NodeSequence).get_size()); + } + this.node = new Yaml.NodeMap (this.parent_node, this.ckey); + this.change = true; + } + + /** + * + */ + private void add_anchor_if_needed () + { + if (this.idAnchor != null) { + if (this.node != null) { + this.anchors.set(this.idAnchor, this.node); + } + this.idAnchor = null; + } + } + + /** + * + */ + private void on_update () + { + if (this.change) { + this.parent_node.add (this.node); + if (this.node.node_type.is_collection ()) { + this.parent_node = this.node; + } + this.prev_node = this.node; + this.node = null; + this.change = false; + } + } + } diff --git a/src/vala/Pluie/Yaml.Scanner.vala b/src/vala/Pluie/Yaml.Scanner.vala index 9988221..69e08ed 100644 --- a/src/vala/Pluie/Yaml.Scanner.vala +++ b/src/vala/Pluie/Yaml.Scanner.vala @@ -120,7 +120,7 @@ public class Pluie.Yaml.Scanner /** * return resulting Yaml root node */ - public Yaml.NodeRoot get_nodes () + public Yaml.NodeRoot? get_nodes () { return (this.processor.root as Yaml.NodeRoot); } @@ -134,18 +134,26 @@ public class Pluie.Yaml.Scanner } /** - * scan specifiyed file generated throught yaml.c - * @param optional file path to scan + * */ - public bool run (string? path = null) + public void before_run (string? path) { - Dbg.in (Log.METHOD, "path:'%s'".printf (path), Log.LINE, Log.FILE); if (path != null && this.reader.path != path) { this.reader.load (path); } else { this.reader.rewind(new Io.StreamLineMark(0, 0)); } + } + + /** + * scan specifiyed file generated throught yaml.c + * @param optional file path to scan + */ + public bool run (string? path = null) + { + Dbg.in (Log.METHOD, "path:'%s'".printf (path), Log.LINE, Log.FILE); + this.before_run (path); this.processor = new Yaml.Processor (); this.done = false; if (Pluie.Yaml.Scanner.DEBUG) of.action ("Scanning events", path);