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);
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;
}

View File

@ -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<string, string> varmap { get; internal set; }
Gee.HashMap<string, string> varmap { get; internal set; }
/**
* 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
@ -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]);
}
}
}

View File

@ -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);

View File

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

View File

@ -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<string, Yaml.Node> 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<Yaml.Event> iterator;
/**
*
@ -115,155 +140,262 @@ public class Pluie.Yaml.Processor
/**
* 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;
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<Yaml.Event> 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<Yaml.Event> 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;
}
}
}

View File

@ -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);