refact Yaml Processor, Scanner, Loader & Config

This commit is contained in:
a-Sansara 2018-08-03 02:17:15 +02:00
parent 30197dde42
commit 7796fb2c5c
6 changed files with 349 additions and 182 deletions

View File

@ -35,8 +35,6 @@ int main (string[] args)
{ {
Echo.init(false); Echo.init(false);
var pwd = Environment.get_variable ("PWD");
//~ var path = Path.build_filename (pwd, "resources/main.yml");
var path = "./resources/main.yml"; var path = "./resources/main.yml";
var done = false; var done = false;
@ -59,10 +57,6 @@ int main (string[] args)
of.rs (done); of.rs (done);
of.echo (); of.echo ();
of.echo (pwd);
return (int) done; return (int) done;
} }

View File

@ -3,31 +3,40 @@
*/ */
public class Pluie.Yaml.Config public class Pluie.Yaml.Config
{ {
const char IMPORTS_SPE = '^'; /**
*
*/
const char IMPORTS_SPE = '^';
/** /**
* current path * 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 * Yaml Loader
*/ */
public Yaml.Loader loader { internal get; internal set; } public Yaml.Loader loader { internal get; internal set; }
/** /**
* Yaml Finder * Yaml Finder
*/ */
public Yaml.Finder finder { internal get; internal set; } public Yaml.Finder finder { internal get; internal set; }
/** /**
* imports var * imports var
*/ */
Gee.HashMap<string, string> varmap { get; internal set; } Gee.HashMap<string, string> varmap { get; internal set; }
/** /**
* imports paths * imports paths
*/ */
Gee.HashMap<string, string> paths { get; internal set; } Gee.HashMap<string, string> paths { get; internal set; }
/** /**
* construct a Yaml Config for specifiyed path * construct a Yaml Config for specifiyed path
@ -36,6 +45,7 @@ public class Pluie.Yaml.Config
{ {
Yaml.BaseNode.mode = mode; Yaml.BaseNode.mode = mode;
this.path = path; this.path = path;
this.displayFile = displayFile;
if (this.path != null) { if (this.path != null) {
this.loader = new Yaml.Loader (this.path, displayFile, false); this.loader = new Yaml.Loader (this.path, displayFile, false);
Yaml.NodeRoot? root = this.loader.get_nodes (); Yaml.NodeRoot? root = this.loader.get_nodes ();
@ -84,22 +94,32 @@ public class Pluie.Yaml.Config
} }
} }
this.update_var (node, dir); this.update_var (node, dir);
this.import_files(root);
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();
} }
} }
} }
/**
*
*/
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)) { if (!Path.is_absolute (val)) {
val = Path.build_filename(path, val); val = Path.build_filename(path, val);
} }
// update var this.resolve_var (entry.key, val);
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); /**
} *
} */
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]);
} }
} }
} }

View File

@ -59,18 +59,17 @@ public class Pluie.Yaml.Loader
public Loader (string path, bool displayFile = false, bool displayNode = false ) public Loader (string path, bool displayFile = false, bool displayNode = false )
{ {
this.reader = new Io.Reader (path); this.reader = new Io.Reader (path);
if (displayFile) {
this.displayFile ();
}
this.scanner = new Yaml.Scanner (path); this.scanner = new Yaml.Scanner (path);
if ((this.done = this.scanner.run()) && displayNode) { if (displayFile) this.displayFile ();
var n = this.get_nodes ();
if (n != null) { if ((this.done = this.scanner.run())) {
n.display_childs (); 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 (); var evt = this.scanner.get_error_event ();
of.error ("line %d (%s)".printf (evt.line, evt.data["error"])); of.error ("line %d (%s)".printf (evt.line, evt.data["error"]));
this.displayFile (evt.line); this.displayFile (evt.line);
@ -80,11 +79,30 @@ public class Pluie.Yaml.Loader
/** /**
* return resulting Yaml root node * return resulting Yaml root node
*/ */
public Yaml.NodeRoot get_nodes () public Yaml.NodeRoot? get_nodes ()
{ {
return this.scanner.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 * 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.action (errorLine == 0 ? "Reading file" : "Invalid Yaml File", this.reader.path);
of.echo (); of.echo ();
this.reader.rewind(new Io.StreamLineMark(0, 0)); this.reader.rewind(new Io.StreamLineMark(0, 0));
int line = 0; int line = 0;
string? data = null; string? data = null;
bool err = false;
bool before = false;
while (this.reader.readable) { while (this.reader.readable) {
line = this.reader.line + 1; line = this.reader.line + 1;
data = this.reader.read (); data = this.reader.read ();
if (errorLine > 0 && line > 0) { err = errorLine > 0 && line == errorLine;
if (line < errorLine - 7) continue; before = errorLine == 0 || line < errorLine;
else if (line == errorLine - 7) { if (this.bypass_ellipse (errorLine, line)) continue;
of.echo ("%s%s%s".printf ( ECHO color = data!=null && data.strip()[0] != '#' ? ECHO.COMMAND : ECHO.COMMENT;
of.c (ECHO.MICROTIME ).s (" %03d ".printf (line-1)), of.echo ("%s%s%s".printf (
of.c (ECHO.DATE).s ("| "), of.c (ECHO.MICROTIME ).s (" %03d ".printf (line)),
of.c (ECHO.COMMAND).s ("... ") of.c (ECHO.DATE).s ("| "),
)); err ? of.c (ECHO.FAIL).s (data)
} : of.c (color).s (data)
} ), before);
if (data !=null) { if (err) {
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) {
int len = of.term_width - data.length - 13; int len = of.term_width - data.length - 13;
stdout.printf (of.c (ECHO.FAIL).s (@" %$(len)s ".printf (" "))); stdout.printf (of.c (ECHO.FAIL).s (@" %$(len)s ".printf (" ")));
of.echo (Color.off (), true); of.echo (Color.off (), true);
} }
if (errorLine > 0 && line > errorLine) { else if (!before) break;
break;
}
} }
of.echo (errorLine == 0 ? "EOF" : ""); of.echo (errorLine == 0 ? "EOF" : "");
of.state (errorLine == 0); of.state (errorLine == 0);

View File

@ -114,7 +114,6 @@ public interface Pluie.Yaml.Node : Object
*/ */
public abstract void update_level (); public abstract void update_level ();
/** /**
* get a presentation string of current Yaml.Node * get a presentation string of current Yaml.Node
*/ */

View File

@ -41,6 +41,26 @@ public class Pluie.Yaml.Processor
*/ */
public bool done; 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 * Events list
*/ */
@ -51,6 +71,11 @@ public class Pluie.Yaml.Processor
*/ */
Gee.HashMap<string, Yaml.Node> anchors { get; internal set; } Gee.HashMap<string, Yaml.Node> anchors { get; internal set; }
/**
* Error event
*/
Yaml.Event? event { get; internal set; }
/** /**
* Error event * Error event
*/ */
@ -77,9 +102,9 @@ public class Pluie.Yaml.Processor
Yaml.Node node; Yaml.Node node;
/** /**
* previous level * Yaml.Event Iterator
*/ */
int prev_level; Gee.Iterator<Yaml.Event> iterator;
/** /**
* *
@ -115,155 +140,262 @@ public class Pluie.Yaml.Processor
/** /**
* retriew the next Yaml Event * retriew the next Yaml Event
* @param the iterator
*/ */
private Yaml.Event? next_event (Iterator<Yaml.Event> it) private Yaml.Event? next_event ()
{ {
Yaml.Event? evt = null; Yaml.Event? evt = null;
if (it.has_next () && it.next ()) { if (this.iterator.has_next () && this.iterator.next ()) {
evt = it.get (); evt = this.iterator.get ();
} }
return evt; return evt;
} }
/** /**
* retriew the next Yaml Value Event closest to Key Event * retriew the next Yaml Value Event closest to Key Event
* @param the iterator
*/ */
private Yaml.Event? get_value_key_event (Iterator<Yaml.Event> it) private Yaml.Event? get_value_key_event ()
{ {
Yaml.Event? evt = null; Yaml.Event? evt = null;
var e = it.get (); var e = this.iterator.get ();
if (e != null && e.evtype.is_key ()) { if (e != null && e.evtype.is_key ()) {
evt = this.next_event (it); evt = this.next_event ();
} }
return evt; return evt;
} }
/** /**
* retriew the next Yaml Value Event * retriew the next Yaml Value Event
* @param the iterator
*/ */
private Yaml.Event? get_value_event (Iterator<Yaml.Event> it) private Yaml.Event? get_value_event ()
{ {
Yaml.Event? evt = null; Yaml.Event? evt = null;
var e = it.get (); var e = this.iterator.get ();
if (e != null && e.evtype.is_value ()) { if (e != null && e.evtype.is_value ()) {
evt = this.next_event (it); evt = this.next_event ();
} }
return evt; 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 * processing the events list and generate the corresponding Yaml Nodes
*/ */
public bool run () public bool run ()
{ {
if (Pluie.Yaml.Scanner.DEBUG) this.read (); if (Yaml.Scanner.DEBUG) {
this.root = new Yaml.NodeRoot (); this.read ();
this.prev_node = this.root; of.action ("Processing events");
this.parent_node = this.root; }
this.prev_level = this.root.level; this.reset ();
int level = this.root.level + 1; for (var has_next = this.iterator.next (); has_next; has_next = this.iterator.next ()) {
var it = this.events.iterator (); this.event = this.iterator.get ();
var change = false; if (this.event.evtype.is_error ()) {
string? key = null; this.on_error ();
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;
break; break;
} }
if (evt.evtype.is_mapping_end () || evt.evtype.is_sequence_end ()) { if (this.event.evtype.is_mapping_end () || this.event.evtype.is_sequence_end ()) {
level -= 4; this.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;
continue; continue;
} }
if (evt.evtype.is_entry ()) { if (this.event.evtype.is_entry ()) {
evt = this.next_event(it); this.on_entry ();
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 (beginFlowSeq && evt.evtype.is_scalar ()) { if (this.beginFlowSeq && this.event.evtype.is_scalar ()) {
var content = evt.data["data"]; this.on_scalar (true);
this.node = new Yaml.NodeScalar (this.parent_node, content); this.beginFlowSeq = false;
change = true;
beginFlowSeq = false;
} }
if (evt.evtype.is_key () && (evt = this.get_value_key_event (it)) != null) { if (this.event.evtype.is_key () && (this.event = this.get_value_key_event ()) != null) {
key = evt.data["data"]; this.on_key ();
} }
if (evt.evtype.is_value () && (evt = this.get_value_event (it)) != null) { if (this.event.evtype.is_value () && (this.event = this.get_value_event ()) != null) {
if (evt.evtype.is_scalar ()) { this.on_value ();
var content = evt.data["data"]; if (this.event.evtype.is_mapping_start ()) {
if (key != null) { this.on_mapping_start ();
this.node = new Yaml.NodeSinglePair (this.parent_node, key, content);
change = true;
}
} }
else if (evt.evtype.is_anchor ()) { else if (this.event.evtype.is_sequence_start ()) {
id = evt.data["id"]; this.on_sequence_start ();
evt = this.next_event (it);
} }
else if (evt.evtype.is_alias ()) { this.add_anchor_if_needed ();
id = evt.data["id"]; this.ckey = null;
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.on_update ();
} }
this.done = error_event == null && this.root != null; this.done = error_event == null && this.root != null;
return done; 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;
}
}
} }

View File

@ -120,7 +120,7 @@ public class Pluie.Yaml.Scanner
/** /**
* return resulting Yaml root node * return resulting Yaml root node
*/ */
public Yaml.NodeRoot get_nodes () public Yaml.NodeRoot? get_nodes ()
{ {
return (this.processor.root as Yaml.NodeRoot); 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) { if (path != null && this.reader.path != path) {
this.reader.load (path); this.reader.load (path);
} }
else { else {
this.reader.rewind(new Io.StreamLineMark(0, 0)); 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.processor = new Yaml.Processor ();
this.done = false; this.done = false;
if (Pluie.Yaml.Scanner.DEBUG) of.action ("Scanning events", path); if (Pluie.Yaml.Scanner.DEBUG) of.action ("Scanning events", path);