manage nodes generation, add Scanner Loader & Processor classes

This commit is contained in:
a-sansara 2018-07-31 18:42:49 +02:00 committed by a-Sansara
parent 7ca8f68987
commit 62419bf3f7
13 changed files with 687 additions and 280 deletions

View File

@ -4,30 +4,19 @@ using Pluie;
int main (string[] args)
{
Echo.init(true);
Echo.init(false);
var path = "resources/test.yml";
var done = false;
of.title ("Pluie Yaml Parser", Pluie.Yaml.VERSION, "a-sansara");
of.action ("Reading file", path);
of.echo ();
var reader = new Io.Reader (path);
while (reader.readable) {
of.echo ("%s %s".printf (
of.c (ECHO.DATE ).s ("%03d |".printf (reader.line)),
of.c (ECHO.OPTION_SEP).s (reader.read ()))
);
var loader = new Yaml.Loader (path, true, true);
if ((done = loader.done)) {
Yaml.NodeRoot root = loader.get_nodes ();
}
of.echo ("EOF");
of.state (true);
of.action ("Parsing file", path);
var processor = new Yaml.Processor (path);
done = processor.done;
of.state (done);
of.rs (done);
of.echo ();
return (int) done;

View File

@ -33,7 +33,10 @@ sources = [
'src/vala/Pluie/Io.Reader.vala',
'src/vala/Pluie/Io.StreamLineMark.vala',
'src/vala/Pluie/Yaml.global.vala',
'src/vala/Pluie/Yaml.Document.vala',
'src/vala/Pluie/Yaml.Event.vala',
'src/vala/Pluie/Yaml.Loader.vala',
'src/vala/Pluie/Yaml.Scanner.vala',
'src/vala/Pluie/Yaml.Processor.vala',
'src/vala/Pluie/Yaml.BaseNode.vala',
'src/vala/Pluie/Yaml.Node.vala',

View File

@ -12,6 +12,8 @@ public class Pluie.Yaml.BaseNode : Object, Pluie.Yaml.Node
*/
public string uuid { get; internal set; }
public string anchor { get; internal set; }
/**
* find mode related to Yaml.FIND_MODE, default is Yaml.FIND_MODE.SQUARE_BRACKETS
*/
@ -75,6 +77,23 @@ public class Pluie.Yaml.BaseNode : Object, Pluie.Yaml.Node
this.uuid = Yaml.uuid ();
}
/**
*
*/
protected virtual void set_anchor_id (string id)
{
this.anchor = id;
}
/**
* clone current node
* @param the name of clone
*/
public virtual Yaml.Node clone_node (string? name = null)
{
return new BaseNode.standard (this.parent, this.indent);
}
/**
* stuff on changing parent node
* @param child the childto add
@ -172,17 +191,17 @@ public class Pluie.Yaml.BaseNode : Object, Pluie.Yaml.Node
public string to_string (bool withIndent = true)
{
return "%s%s%s%s%s%s%s%s".printf (
return "%s%s%s%s%s%s%s".printf (
this.node_type.is_root () ? "" : of.s_indent ((int8) (withIndent ? this.indent : 0)),
of.c (ECHO.OPTION).s ("<"),
of.c (ECHO.OPTION_SEP).s (this.node_type.infos ()),
this.name != null ? " %s".printf (this.name)
: (this.node_type.is_scallar () ? " %s".printf (this.data) : ""),
: (this.node_type.is_scalar () ? " %s".printf (this.data) : ""),
"[%x]".printf (this.ref_count),
this.parent == null ? "" : this.parent.name+"|"+this.indent.to_string(),
//~ " (%d) ".printf (this.indent),
of.c (ECHO.OPTION).s (">"),
of.c (ECHO.DATE).s (" %s".printf(this.uuid))
of.c (ECHO.OPTION).s (">")/*,
of.c (ECHO.DATE).s (" %s".printf(this.uuid))*/
);
}

View File

@ -0,0 +1,20 @@
using Pluie;
/**
* a class representing a single/pair mapping node
*/
public class Pluie.Yaml.Document : Yaml.NodeMap
{
/**
* construct a single/pair mapping node
* @param parent the parent node
* @param indent the current indentation in node representation string
* @param name the current name (key) of sequence node
* @param data the current scalar data
*/
public Document (Yaml.Node? parent = null, int indent = 0, string? name = null, string? data = null)
{
this.standard (null, -4, NODE_TYPE.ROOT);
this.name = "PluieYamlRootNode";
}
}

View File

@ -0,0 +1,63 @@
using GLib;
using Gee;
using Pluie;
/**
* a tiny Yaml Parser whose purpose is not to comply with all yaml specifications but to parse yaml configuration files
* todo improve description of what is expected
*/
public class Pluie.Yaml.Loader
{
/**
* Scanner
*/
Yaml.Scanner scanner { public get; internal set; }
public bool done { get; internal set; }
/**
* Reader used to load content yaml file
*/
Io.Reader reader;
/**
* @param path the path of file to parse
*/
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) {
this.get_nodes ().display_childs ();
of.state(true);
}
}
/**
*
*/
public Yaml.NodeRoot get_nodes ()
{
return this.scanner.get_nodes ();
}
/**
*
*/
public void displayFile ()
{
of.action ("Reading file", this.reader.path);
of.echo ();
while (this.reader.readable) {
of.echo ("%s %s".printf (
of.c (ECHO.DATE ).s ("%03d |".printf (this.reader.line)),
of.c (ECHO.OPTION_SEP).s (this.reader.read ()))
);
}
of.echo ("EOF");
of.state (true);
}
}

View File

@ -48,6 +48,12 @@ public interface Pluie.Yaml.Node : Object
*/
protected abstract bool remove_child (Yaml.Node child);
/**
* clone curent node
* @param name the name of clone node
*/
public abstract Yaml.Node clone_node (string? name = null);
/**
* check if node has child nodes
*/

View File

@ -57,13 +57,21 @@ public class Pluie.Yaml.NodeMap : Yaml.BaseNode, Yaml.NodeCollection
/**
* display childs
*/
public void display_childs ()
public void display_childs (bool root=true)
{
of.action ("display_childs map\n");
if (root == true) {
of.action ("display root node\n");
}
of.echo (this.to_string ());
if (this.map.size > 0) {
foreach (string key in this.map.keys) {
of.echo (this.map.get(key).to_string ());
var n = this.map.get(key);
if (n.node_type.is_mapping ()) (n as Yaml.NodeMap).display_childs (false);
else if (n.node_type.is_sequence ()) (n as Yaml.NodeSequence).display_childs (false);
else if (n.node_type.is_single_pair ()) {
of.echo (n.to_string ());
of.echo ((n as Yaml.NodeSinglePair).scalar ().to_string ());
}
}
}
else {
@ -138,4 +146,20 @@ public class Pluie.Yaml.NodeMap : Yaml.BaseNode, Yaml.NodeCollection
return target;
}
/**
* clone current node
* @param the name of clone
*/
public override Yaml.Node clone_node (string? name = null)
{
var key = name != null ? name : this.name;
Yaml.Node clone = new Yaml.NodeMap (this.parent, this.indent, key);
foreach (string k in this.map.keys) {
var n = this.map.get(k).clone_node();
n.parent = clone;
clone.add(n);
}
return clone;
}
}

View File

@ -17,4 +17,12 @@ public class Pluie.Yaml.NodeScalar : Yaml.BaseNode
this.data = data;
}
/**
* clone current node
* @param the name of clone
*/
public override Yaml.Node clone_node (string? name = null)
{
return new Yaml.NodeScalar (this.parent, this.indent, this.data);
}
}

View File

@ -96,13 +96,23 @@ public class Pluie.Yaml.NodeSequence : Yaml.BaseNode, Yaml.NodeCollection
/**
* display childs
*/
public void display_childs ()
public void display_childs (bool root = true)
{
if (root) {
of.action ("display_childs sequence\n");
}
of.echo (this.to_string ());
if (this.list!= null && this.list.size > 0) {
foreach (Yaml.Node child in this.list) {
if (child.node_type.is_mapping ()) (child as Yaml.NodeMap).display_childs (false);
else if (child.node_type.is_sequence ()) (child as Yaml.NodeSequence).display_childs (false);
else if (child.node_type.is_single_pair ()) {
of.echo (child.to_string ());
of.echo ((child as Yaml.NodeSinglePair).scalar ().to_string ());
}
else {
of.echo (child.to_string ());
}
}
}
else {
@ -114,7 +124,7 @@ public class Pluie.Yaml.NodeSequence : Yaml.BaseNode, Yaml.NodeCollection
* count childnodes
*/
public int get_size () {
return this.list.size;
return this.list == null ? 0 : this.list.size;
}
/**
@ -154,4 +164,23 @@ public class Pluie.Yaml.NodeSequence : Yaml.BaseNode, Yaml.NodeCollection
}
return target;
}
/**
* clone current node
* @param the name of clone
*/
public override Yaml.Node clone_node (string? name = null)
{
var key = name != null ? name : this.name;
Yaml.Node clone = new Yaml.NodeSequence (this.parent, this.indent, key);
if (this.list!= null && this.list.size > 0) {
foreach (Yaml.Node child in this.list) {
var n = child.clone_node();
n.parent = clone;
clone.add(n);
}
}
return clone;
}
}

View File

@ -31,4 +31,15 @@ public class Pluie.Yaml.NodeSinglePair : Yaml.NodeMap
{
return this.map["singlepair"];
}
/**
* clone current node
* @param the name of clone
*/
public override Yaml.Node clone_node (string? name = null)
{
var key = name != null ? name : this.name;
Yaml.Node clone = new Yaml.NodeSinglePair (this.parent, this.indent, key, this.scalar ().data);
return clone;
}
}

View File

@ -1,7 +1,6 @@
using GLib;
using Gee;
using Pluie;
extern void yaml_parse_file(string srcPath, string destPath);
/**
* a tiny Yaml Parser whose purpose is not to comply with all yaml specifications but to parse yaml configuration files
@ -9,147 +8,62 @@ extern void yaml_parse_file(string srcPath, string destPath);
*/
public class Pluie.Yaml.Processor
{
const string REG_EVENT = "^([0-9]+), ([0-9]+)(.*)$";
const string REG_VERSION = "^, ([0-9]+), ([0-9]+)$";
const string REG_TAG = "^, \"([^\"]*)\", \"([^\"]*)\"$";
const string REG_ERROR = "^, \"([^\"]*)\"$";
const string REG_SCALAR = "^, ([0-9]+), \"([^\"]*)\"$";
const string REG_ANCHOR = "^, \"([^\"]*)\"$";
const string REG_ALIAS = "^, \"([^\"]*)\"$";
/**
* enum linked to used RegExp in parse_line
*/
enum MIEVT
{
NONE,
LINE,
TYPE,
DATA
}
/**
* enum linked to used RegExp in parse_line
*/
enum MIEVT_VERSION
{
NONE,
MAJOR,
MINOR
}
/**
* enum linked to used RegExp in parse_line
*/
enum MIEVT_SCALAR
{
NONE,
STYLE,
DATA
}
/**
* enum linked to used RegExp in parse_line
*/
enum MIEVT_TAG
{
NONE,
HANDLE,
SUFFIX
}
/**
* enum linked to used RegExp in parse_line
*/
enum MIEVT_ANCHOR
{
NONE,
ID,
}
/**
* enum linked to used RegExp in parse_line
*/
enum MIEVT_ERROR
{
NONE,
DATA,
}
/**
* indicate if file has been sucessfully parsed
*/
public bool done;
/**
* indicate if parsing msut stop
*/
bool stop;
/**
* the mark use to rewind line throught Io.Reader
*/
Io.StreamLineMark? mark;
/**
* Reader used to load content yaml file
*/
Io.Reader reader;
/**
* Events list
*/
Gee.LinkedList<Yaml.Event> events { get; internal set; }
public Gee.LinkedList<Yaml.Event> events { get; internal set; }
/**
*Anchor map
*/
Gee.HashMap<string, int> anchors { get; internal set; }
Gee.HashMap<string, Yaml.Node> anchors { get; internal set; }
/**
* @param path the path of file to parse
* the root Yaml.Node
*/
public Processor (string path)
{
var destPath = Path.build_filename (Environment.get_tmp_dir (), Path.get_basename(path));
yaml_parse_file(path, destPath);
this.reader = new Io.Reader (destPath);
this.scan ();
}
public Yaml.Node root;
/**
* parse a file related to specifiyed path
* @param path the path to parse
* current previous Yaml.Node
*/
public bool scan (string? path = null)
Yaml.Node? prev_node;
/**
* current parent Yaml.Node
*/
Yaml.Node? parent_node;
/**
* current Yaml.Node
*/
Yaml.Node node;
/**
* previous indent
*/
int prev_indent;
/**
*
*/
public Processor ()
{
Dbg.in (Log.METHOD, "path:'%s'".printf (path), Log.LINE, Log.FILE);
if (path != null) {
this.reader.load (path);
}
else {
this.reader.rewind(new Io.StreamLineMark(0, 0));
}
this.events = new Gee.LinkedList<Yaml.Event>();
this.anchors = new Gee.HashMap<string, int>();
this.stop = this.done = false;
of.action ("Scanning events", path);
while (this.reader.readable) {
this.scan_line (this.reader.read ());
}
this.process_events ();
this.done = true;
Dbg.out (Log.METHOD, "done:%d".printf ((int)done), Log.LINE, Log.FILE);
return this.done;
this.anchors = new Gee.HashMap<string, Yaml.Node>();
}
/**
*
*/
private void process_events ()
public void read ()
{
of.action ("Reading events");
EVT? prevEvent = null;
foreach (Yaml.Event event in this.events) {
int len = 24 - event.evtype.infos ().length;
stdout.printf(" [ %s"+@" %$(len)s "+", %d, %s", event.evtype.infos (), " ", event.line, event.style != null ? event.style.to_string () : "0");
@ -167,166 +81,136 @@ public class Pluie.Yaml.Processor
}
}
/**
* set event version
* @param evtdata the current data event
* @param line the current line
* @throws GLib.RegexError
*/
private void set_event_version(string evtdata, int line) throws GLib.RegexError
{
MatchInfo mi = null;
Regex reg = new Regex (REG_VERSION);
HashMap<string, string>? data = null;
if (reg.match (evtdata, 0, out mi)) {
data = new HashMap<string, string>();
data.set("major", mi.fetch (MIEVT_VERSION.MAJOR));
data.set("minor", mi.fetch (MIEVT_VERSION.MINOR));
}
this.events.offer(new Yaml.Event(EVT.VERSION_DIRECTIVE, line, null, data));
}
/**
* set event tag
* @param evtdata the current data event
* @param line the current line
* @throws GLib.RegexError
*
*/
private void set_event_tag(string evtdata, int line) throws GLib.RegexError
private Yaml.Event? next_event (Iterator<Yaml.Event> it)
{
MatchInfo mi = null;
Regex reg = new Regex (REG_TAG);
HashMap<string, string>? data = null;
if (reg.match (evtdata, 0, out mi)) {
data = new HashMap<string, string>();
data.set("handle", mi.fetch (MIEVT_TAG.HANDLE));
data.set("suffix", mi.fetch (MIEVT_TAG.SUFFIX));
Yaml.Event? evt = null;
if (it.has_next () && it.next ()) {
evt = it.get ();
}
this.events.offer(new Yaml.Event(EVT.TAG, line, null, data));
return evt;
}
/**
* set event version
* @param evtdata the current data event
* @param line the current line
* @throws GLib.RegexError
*
*/
private void set_event_error(string evtdata, int line) throws GLib.RegexError
private Yaml.Event? get_value_key_event (Iterator<Yaml.Event> it)
{
MatchInfo mi = null;
Regex reg = new Regex (REG_ERROR);
HashMap<string, string>? data = null;
if (reg.match (evtdata, 0, out mi)) {
data = new HashMap<string, string>();
data.set("error", mi.fetch (MIEVT_ERROR.DATA));
Yaml.Event? evt = null;
var e = it.get ();
if (e != null && e.evtype.is_key ()) {
evt = this.next_event (it);
}
this.events.offer(new Yaml.Event(EVT.NONE, line, null, data));
return evt;
}
/**
* set event scalar
* @param evtdata the current data event
* @param line the current line
* @throws GLib.RegexError
*
*/
private void set_event_scalar(string evtdata, int line) throws GLib.RegexError
private Yaml.Event? get_value_event (Iterator<Yaml.Event> it)
{
MatchInfo mi = null;
Regex reg = new Regex (REG_SCALAR);
HashMap<string, string>? data = null;
int? style = null;
if (reg.match (evtdata, 0, out mi)) {
style = int.parse(mi.fetch (MIEVT_SCALAR.STYLE));
data = new HashMap<string, string>();
data.set("data", mi.fetch (MIEVT_SCALAR.DATA));
Yaml.Event? evt = null;
var e = it.get ();
if (e != null && e.evtype.is_value ()) {
evt = this.next_event (it);
}
this.events.offer(new Yaml.Event(EVT.SCALAR, line, style, data));
return evt;
}
/**
* set event anchor
* @param evtdata the current data event
* @param line the current line
* @throws GLib.RegexError
*
*/
private void set_event_anchor(string evtdata, int line) throws GLib.RegexError
public bool run ()
{
MatchInfo mi = null;
Regex reg = new Regex (REG_ANCHOR);
HashMap<string, string>? data = null;
if (reg.match (evtdata, 0, out mi)) {
data = new HashMap<string, string>();
data.set("id", mi.fetch (MIEVT_ANCHOR.ID));
this.root = new Yaml.NodeRoot ();
this.prev_node = this.root;
this.parent_node = this.root;
this.prev_indent = this.root.indent;
int indent = this.root.indent +4;
EVT? prevEvent = null;
var it = this.events.iterator ();
var change = false;
string? key = null;
string? id = null;
Yaml.Event? evt;
of.action ("Processing events");
for (var has_next = it.next (); has_next; has_next = it.next ()) {
evt = it.get ();
if (evt.evtype.is_mapping_end () || evt.evtype.is_sequence_end ()) {
indent -= 4;
this.parent_node = this.prev_node.parent != this.root ? this.prev_node.parent.parent : this.root;
this.prev_node = this.parent_node;
continue;
}
this.anchors.set(data.get("id"), this.events.size);
this.events.offer(new Yaml.Event(EVT.ANCHOR, line, null, data));
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, indent, key);
key = null;
indent += 4;
change = true;
}
}
if (evt.evtype.is_key () && (evt = this.get_value_key_event (it)) != null) {
key = evt.data["data"];
}
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, indent, key, content);
change = true;
}
}
else if (evt.evtype.is_anchor ()) {
id = evt.data["id"];
evt = this.next_event (it);
}
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_indent = this.prev_node.indent;
}
}
if (evt.evtype.is_mapping_start ()) {
this.node = new Yaml.NodeMap (this.parent_node, indent, key);
indent += 4;
change = true;
}
else if (evt.evtype.is_sequence_start ()) {
this.node = new Yaml.NodeSequence (this.parent_node, indent, key);
indent += 4;
change = 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_indent = this.prev_node.indent;
this.node = null;
change = false;
}
}
this.done = this.root != null;
return done;
}
/**
* set event alias
* @param evtdata the current data event
* @param line the current line
* @throws GLib.RegexError
*/
private void set_event_alias(string evtdata, int line) throws GLib.RegexError
{
MatchInfo mi = null;
Regex reg = new Regex (REG_ALIAS);
HashMap<string, string>? data = null;
if (reg.match (evtdata, 0, out mi)) {
data = new HashMap<string, string>();
data.set("id", mi.fetch (MIEVT_ANCHOR.ID));
}
this.events.offer(new Yaml.Event(EVT.ALIAS, line, null, data));
}
/**
* parse specifiyed line
* @param data the current line
*/
private void scan_line (string? data = null)
{
Dbg.in (Log.METHOD, null, Log.LINE, Log.FILE);
if (data == null) {
this.stop = true;
return;
}
try {
MatchInfo mi = null;
Regex reg = new Regex (REG_EVENT);
if (reg.match (data, 0, out mi)) {
int line = int.parse(mi.fetch (MIEVT.LINE));
int type = int.parse(mi.fetch (MIEVT.TYPE));
string evtdata = mi.fetch (MIEVT.DATA);
switch(type) {
case EVT.SCALAR :
this.set_event_scalar(evtdata, line);
break;
case EVT.ANCHOR :
this.set_event_anchor(evtdata, line);
break;
case EVT.ALIAS :
this.set_event_alias(evtdata, line);
break;
case EVT.TAG :
this.set_event_tag(evtdata, line);
break;
case EVT.VERSION_DIRECTIVE :
this.set_event_version(evtdata, line);
break;
case EVT.NONE :
this.set_event_error(evtdata, line);
break;
default :
this.events.offer(new Yaml.Event((Yaml.EVT)type, line, null, null));
break;
}
}
}
catch (GLib.RegexError e) {
Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
}
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
}
}

View File

@ -0,0 +1,270 @@
using GLib;
using Gee;
using Pluie;
extern void yaml_parse_file(string srcPath, string destPath);
/**
* a tiny Yaml Parser whose purpose is not to comply with all yaml specifications but to parse yaml configuration files
* todo improve description of what is expected
*/
public class Pluie.Yaml.Scanner
{
const string REG_EVENT = "^([0-9]+), ([0-9]+)(.*)$";
const string REG_VERSION = "^, ([0-9]+), ([0-9]+)$";
const string REG_TAG = "^, \"([^\"]*)\", \"([^\"]*)\"$";
const string REG_ERROR = "^, \"([^\"]*)\"$";
const string REG_SCALAR = "^, ([0-9]+), \"(.*)\"$";
const string REG_ANCHOR = "^, \"([^\"]*)\"$";
const string REG_ALIAS = "^, \"([^\"]*)\"$";
/**
* enum linked to MatchInfo REG_EVENT
*/
enum MIEVT { NONE, LINE, TYPE, DATA }
/**
* enum linked to MatchInfo REG_VERSION
*/
enum MIEVT_VERSION { NONE, MAJOR, MINOR }
/**
* enum linked to MatchInfo REG_SCALAR
*/
enum MIEVT_SCALAR { NONE, STYLE, DATA }
/**
* enum linked to MatchInfo REG_TAG
*/
enum MIEVT_TAG { NONE, HANDLE, SUFFIX }
/**
* enum linked to MatchInfo REG_ANCHOR
*/
enum MIEVT_ANCHOR { NONE, ID }
/**
* enum linked to MatchInfo REG_ERROR
*/
enum MIEVT_ERROR { NONE, DATA }
/**
* indicate if file has been sucessfully parsed
*/
public bool done { get; internal set; }
/**
* the mark use to rewind line throught Io.Reader
*/
Io.StreamLineMark? mark;
/**
* Reader used to load content yaml file
*/
Io.Reader reader;
/**
* Yaml Processor
*/
Yaml.Processor processor { get; internal set; }
/**
* @param path the path of file to parse
*/
public Scanner (string path)
{
var destPath = Path.build_filename (Environment.get_tmp_dir (), Path.get_basename(path));
yaml_parse_file(path, destPath);
this.reader = new Io.Reader (destPath);
}
/**
*
*/
public Yaml.NodeRoot get_nodes ()
{
return (this.processor.root as Yaml.NodeRoot);
}
/**
* parse a file related to specifiyed path
* @param path the path to parse
*/
public bool run (string? path = null)
{
Dbg.in (Log.METHOD, "path:'%s'".printf (path), Log.LINE, Log.FILE);
if (path != null) {
this.reader.load (path);
}
else {
this.reader.rewind(new Io.StreamLineMark(0, 0));
}
this.processor = new Yaml.Processor ();
this.done = false;
of.action ("Scanning events", path);
while (this.reader.readable) {
this.scan_event (this.reader.read ());
}
this.done = true;
of.state (this.done);
this.done = this.done && this.processor.run ();
of.state (this.done);
Dbg.out (Log.METHOD, "done:%d".printf ((int)done), Log.LINE, Log.FILE);
return this.done;
}
/**
* register event version
* @param evtdata the current data event
* @param line the current line
* @throws GLib.RegexError
*/
private void register_event_version(string evtdata, int line) throws GLib.RegexError
{
MatchInfo mi = null;
Regex reg = new Regex (REG_VERSION);
HashMap<string, string>? data = null;
if (reg.match (evtdata, 0, out mi)) {
data = new HashMap<string, string>();
data.set("major", mi.fetch (MIEVT_VERSION.MAJOR));
data.set("minor", mi.fetch (MIEVT_VERSION.MINOR));
}
this.processor.events.offer(new Yaml.Event(EVT.VERSION_DIRECTIVE, line, null, data));
}
/**
* register event tag
* @param evtdata the current data event
* @param line the current line
* @throws GLib.RegexError
*/
private void register_event_tag(string evtdata, int line) throws GLib.RegexError
{
MatchInfo mi = null;
Regex reg = new Regex (REG_TAG);
HashMap<string, string>? data = null;
if (reg.match (evtdata, 0, out mi)) {
data = new HashMap<string, string>();
data.set("handle", mi.fetch (MIEVT_TAG.HANDLE));
data.set("suffix", mi.fetch (MIEVT_TAG.SUFFIX));
}
this.processor.events.offer(new Yaml.Event(EVT.TAG, line, null, data));
}
/**
* register event version
* @param evtdata the current data event
* @param line the current line
* @throws GLib.RegexError
*/
private void register_event_error(string evtdata, int line) throws GLib.RegexError
{
MatchInfo mi = null;
Regex reg = new Regex (REG_ERROR);
HashMap<string, string>? data = null;
if (reg.match (evtdata, 0, out mi)) {
data = new HashMap<string, string>();
data.set("error", mi.fetch (MIEVT_ERROR.DATA));
}
this.processor.events.offer(new Yaml.Event(EVT.NONE, line, null, data));
}
/**
* register event scalar
* @param evtdata the current data event
* @param line the current line
* @throws GLib.RegexError
*/
private void register_event_scalar(string evtdata, int line) throws GLib.RegexError
{
MatchInfo mi = null;
Regex reg = new Regex (REG_SCALAR);
HashMap<string, string>? data = null;
int? style = null;
if (reg.match (evtdata, 0, out mi)) {
style = int.parse(mi.fetch (MIEVT_SCALAR.STYLE));
data = new HashMap<string, string>();
data.set("data", mi.fetch (MIEVT_SCALAR.DATA));
}
this.processor.events.offer(new Yaml.Event(EVT.SCALAR, line, style, data));
}
/**
* register event anchor
* @param evtdata the current data event
* @param line the current line
* @throws GLib.RegexError
*/
private void register_event_anchor(string evtdata, int line) throws GLib.RegexError
{
MatchInfo mi = null;
Regex reg = new Regex (REG_ANCHOR);
HashMap<string, string>? data = null;
if (reg.match (evtdata, 0, out mi)) {
data = new HashMap<string, string>();
data.set("id", mi.fetch (MIEVT_ANCHOR.ID));
}
this.processor.events.offer(new Yaml.Event(EVT.ANCHOR, line, null, data));
}
/**
* register event alias
* @param evtdata the current data event
* @param line the current line
* @throws GLib.RegexError
*/
private void register_event_alias(string evtdata, int line) throws GLib.RegexError
{
MatchInfo mi = null;
Regex reg = new Regex (REG_ALIAS);
HashMap<string, string>? data = null;
if (reg.match (evtdata, 0, out mi)) {
data = new HashMap<string, string>();
data.set("id", mi.fetch (MIEVT_ANCHOR.ID));
}
this.processor.events.offer(new Yaml.Event(EVT.ALIAS, line, null, data));
}
/**
* parse specifiyed line
* @param data the current line
*/
private void scan_event (string? data = null)
{
Dbg.in (Log.METHOD, null, Log.LINE, Log.FILE);
if (data == null) {
return;
}
try {
MatchInfo mi = null;
Regex reg = new Regex (REG_EVENT);
if (reg.match (data, 0, out mi)) {
int line = int.parse(mi.fetch (MIEVT.LINE));
int type = int.parse(mi.fetch (MIEVT.TYPE));
string evtdata = mi.fetch (MIEVT.DATA);
switch(type) {
case EVT.SCALAR :
this.register_event_scalar(evtdata, line);
break;
case EVT.ANCHOR :
this.register_event_anchor(evtdata, line);
break;
case EVT.ALIAS :
this.register_event_alias(evtdata, line);
break;
case EVT.TAG :
this.register_event_tag(evtdata, line);
break;
case EVT.VERSION_DIRECTIVE :
this.register_event_version(evtdata, line);
break;
case EVT.NONE :
this.register_event_error(evtdata, line);
break;
default :
this.processor.events.offer(new Yaml.Event((Yaml.EVT)type, line, null, null));
break;
}
}
}
catch (GLib.RegexError e) {
Dbg.error (e.message, Log.METHOD, Log.LINE, Log.FILE);
}
Dbg.out (Log.METHOD, null, Log.LINE, Log.FILE);
}
}

View File

@ -53,6 +53,87 @@ namespace Pluie
{
return this.to_string().substring("PLUIE_YAML_".length);
}
/**
* @return event is key
*/
public bool is_key ()
{
return this == EVT.KEY;
}
/**
* @return event is anchor
*/
public bool is_anchor ()
{
return this == EVT.ANCHOR;
}
/**
* @return event is alias
*/
public bool is_alias ()
{
return this == EVT.ALIAS;
}
/**
* @return event is key
*/
public bool is_value ()
{
return this == EVT.VALUE;
}
/**
* @return event is scalar
*/
public bool is_scalar ()
{
return this == EVT.SCALAR;
}
/**
* @return event is mapping start event
*/
public bool is_mapping_start ()
{
return this == EVT.BLOCK_MAPPING_START || this == EVT.FLOW_MAPPING_START;
}
/**
* @return event is sequence start event
*/
public bool is_sequence_start ()
{
return this == EVT.BLOCK_SEQUENCE_START || this == EVT.FLOW_SEQUENCE_START;
}
/**
* @return event is sequence end event
*/
public bool is_sequence_end ()
{
return this == EVT.BLOCK_END || this == EVT.FLOW_SEQUENCE_END;
}
/**
* @return event is sequence entry event
*/
public bool is_entry ()
{
return this == EVT.BLOCK_ENTRY || this == EVT.FLOW_ENTRY;
}
/**
* @return event is mapping end event
*/
public bool is_mapping_end ()
{
return this == EVT.BLOCK_END;
}
}
/**
@ -116,7 +197,7 @@ namespace Pluie
/**
* @return if current NODE_TYPE match a scalar node
*/
public bool is_scallar ()
public bool is_scalar ()
{
return this == SCALAR;
}