add Yaml.Builder, provide mechanism to populate structure and other GLib.Object derived type
This commit is contained in:
parent
68d2c026d4
commit
e4c554df3d
58
README.md
58
README.md
|
@ -125,7 +125,7 @@ load a single document.
|
|||
```vala
|
||||
var path = "./config/main.yml";
|
||||
// uncomment to enable debug
|
||||
// Pluie.Yaml.Scanner.DEBUG = true;
|
||||
// Pluie.Yaml.DEBUG = true;
|
||||
var loader = new Yaml.Loader (path /* , displayFile, displayNode */);
|
||||
if ((done = loader.done)) {
|
||||
Yaml.Node root = loader.get_nodes ();
|
||||
|
@ -136,7 +136,7 @@ load a single document.
|
|||
|
||||
### finder
|
||||
|
||||
**lib-yaml** provide a `Yaml.Finder` to easily retriew a particular yaml node.
|
||||
**pluie-yaml** provide a `Yaml.Finder` to easily retriew a particular yaml node.
|
||||
Search path definition has two mode.
|
||||
The default mode is `Yaml.FIND_MODE.DOT`
|
||||
- child mapping node are separated by dot
|
||||
|
@ -270,13 +270,65 @@ on vala side :
|
|||
|
||||
```vala
|
||||
...
|
||||
Yaml.Example obj = (Yaml.Example) Yaml.Object.from_node (root.first ());
|
||||
var obj = (Yaml.Example) Yaml.Builder.from_node (root.first ());
|
||||
of.echo("obj.type_int : %d".printf (o.type_int));
|
||||
obj.type_object.method_a ()
|
||||
```
|
||||
|
||||
![pluie-yaml-tag](https://www.meta-tech.academy/img/libyaml-tag-ex.png)
|
||||
|
||||
### Builder
|
||||
|
||||
**pluie-yaml** has automatic mechanisms to build Yaml.Object instances (and derived classes)
|
||||
and set basics types properties, enum properties and based Yaml.Object properties.
|
||||
|
||||
Other types like struct or native GLib.Object (Gee.ArrayList for example) properties need some stuff in order to populate instances appropriately
|
||||
We cannot do introspection on Structure's properties, so you need to implement a method which will do the job.
|
||||
|
||||
First at all you need to register in the static construct, (properties) types that need some glue for instanciation.
|
||||
|
||||
```vala
|
||||
public class Example : Yaml.Object
|
||||
{
|
||||
static construct
|
||||
{
|
||||
Yaml.Object.register.add_type (typeof (Example), typeof (ExampleStruct));
|
||||
Yaml.Object.register.add_type (typeof (Example), typeof (Gee.ArrayList));
|
||||
}
|
||||
...
|
||||
```
|
||||
|
||||
Secondly you must override the `Yaml.Object populate_by_type (Glib.Typem Yaml.Node node)` original method.
|
||||
`populate_by_type` is called by the Yaml.Builder only if the type property is prealably registered.
|
||||
|
||||
Example of implementation from `src/vala/Pluie/Yaml.Example.vala` :
|
||||
|
||||
```
|
||||
public override void populate_by_type(GLib.Type type, Yaml.Node node)
|
||||
{
|
||||
switch (type) {
|
||||
case typeof (Yaml.ExampleStruct) :
|
||||
this.type_struct = ExampleStruct.from_yaml_node (node);
|
||||
break;
|
||||
case typeof (Gee.ArrayList) :
|
||||
this.type_gee_al = new Gee.ArrayList<string> ();
|
||||
if (!node.empty ()) {
|
||||
foreach (var child in node) {
|
||||
this.type_gee_al.add(child.data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
for more details see :
|
||||
* `src/vala/Pluie/Yaml.Example.vala`
|
||||
* `src/vala/Pluie/Yaml.ExampleChild.vala`
|
||||
* `src/vala/Pluie/Yaml.ExampleStruct.vala`
|
||||
* `samples/yaml-tag.vala`
|
||||
|
||||
code from samples/yaml-tag.vala :
|
||||
|
||||
![pluie-yaml-tag](https://www.meta-tech.academy/img/libyaml-tag-code.png)
|
||||
|
|
|
@ -64,21 +64,24 @@ sources = [
|
|||
'src/vala/Pluie/Yaml.global.vala',
|
||||
'src/vala/Pluie/Yaml.AbstractChild.vala',
|
||||
'src/vala/Pluie/Yaml.AbstractNode.vala',
|
||||
'src/vala/Pluie/Yaml.Builder.vala',
|
||||
'src/vala/Pluie/Yaml.Collection.vala',
|
||||
'src/vala/Pluie/Yaml.Config.vala',
|
||||
'src/vala/Pluie/Yaml.Event.vala',
|
||||
'src/vala/Pluie/Yaml.Example.vala',
|
||||
'src/vala/Pluie/Yaml.ExampleChild.vala',
|
||||
'src/vala/Pluie/Yaml.ExampleStruct.vala',
|
||||
'src/vala/Pluie/Yaml.Finder.vala',
|
||||
'src/vala/Pluie/Yaml.Loader.vala',
|
||||
'src/vala/Pluie/Yaml.Mapping.vala',
|
||||
'src/vala/Pluie/Yaml.Node.vala',
|
||||
'src/vala/Pluie/Yaml.Object.vala',
|
||||
'src/vala/Pluie/Yaml.Processor.vala',
|
||||
'src/vala/Pluie/Yaml.Register.vala',
|
||||
'src/vala/Pluie/Yaml.Root.vala',
|
||||
'src/vala/Pluie/Yaml.Scalar.vala',
|
||||
'src/vala/Pluie/Yaml.Scanner.vala',
|
||||
'src/vala/Pluie/Yaml.Sequence.vala',
|
||||
'src/vala/Pluie/Yaml.SubExample.vala',
|
||||
'src/vala/Pluie/Yaml.Tag.vala',
|
||||
'src/c/yaml.c'
|
||||
]
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
%YAML 1.2
|
||||
%TAG !yaml! tag:yaml.org,2002:
|
||||
%TAG !v! tag:pluie.org,2018:vala/
|
||||
---
|
||||
!v!Pluie.Yaml.Example test1 :
|
||||
|
@ -12,12 +11,21 @@
|
|||
type_uint : !v!uint 62005
|
||||
type_float : !v!float 42.36
|
||||
type_double : !v!double 95542123.4579512128
|
||||
type_enum : !v!Pluie.Yaml.NODE_TYPE SCALAR
|
||||
!v!Pluie.Yaml.SubExample type_object :
|
||||
type_enum : scalar # or int
|
||||
type_object :
|
||||
toto : totovalue1
|
||||
tata : tatavalue1
|
||||
titi : 123
|
||||
tutu : 1
|
||||
type_struct :
|
||||
red : !v!uint8 214
|
||||
green : !v!uint8 78
|
||||
blue : 153
|
||||
!v!Gee.ArrayList type_gee_al :
|
||||
- ab_1
|
||||
- ab_2
|
||||
- ab_3
|
||||
- ab_4
|
||||
|
||||
!v!Pluie.Yaml.Example test2 :
|
||||
myname : test2object
|
||||
|
@ -29,7 +37,8 @@
|
|||
type_uint : 63005
|
||||
type_float : 5.28
|
||||
type_double : 9.28
|
||||
!v!Pluie.Yaml.SubExample type_object :
|
||||
type_enum : PLUIE_YAML_NODE_TYPE_SCALAR
|
||||
!v!Pluie.Yaml.ExampleChild type_object :
|
||||
toto : totovalue2
|
||||
tata : tatavalue2
|
||||
titi : !v!int 456
|
||||
|
|
|
@ -39,7 +39,7 @@ int main (string[] args)
|
|||
var done = false;
|
||||
|
||||
of.title ("Pluie Yaml Library", Pluie.Yaml.VERSION, "a-sansara");
|
||||
Pluie.Yaml.Scanner.DEBUG = false;
|
||||
Pluie.Yaml.DEBUG = false;
|
||||
var loader = new Yaml.Loader (path, true, true);
|
||||
if ((done = loader.done)) {
|
||||
var root = loader.get_nodes ();
|
||||
|
|
|
@ -39,7 +39,7 @@ int main (string[] args)
|
|||
var done = false;
|
||||
|
||||
of.title ("Pluie Yaml Library", Pluie.Yaml.VERSION, "a-sansara");
|
||||
Pluie.Yaml.Scanner.DEBUG = false;
|
||||
Pluie.Yaml.DEBUG = false;
|
||||
var config = new Yaml.Config (path, true);
|
||||
var spath = "bo.host{0}";
|
||||
var root = config.root_node ();
|
||||
|
|
|
@ -39,7 +39,7 @@ int main (string[] args)
|
|||
var done = false;
|
||||
|
||||
of.title ("Pluie Yaml Library", Pluie.Yaml.VERSION, "a-sansara");
|
||||
//~ Pluie.Yaml.Scanner.DEBUG = false;
|
||||
//~ Pluie.Yaml.DEBUG = false;
|
||||
var loader = new Yaml.Loader (path, true);
|
||||
if ((done = loader.done)) {
|
||||
Yaml.Node root = loader.get_nodes ();
|
||||
|
|
|
@ -40,7 +40,7 @@ int main (string[] args)
|
|||
|
||||
of.title ("Pluie Yaml Library", Pluie.Yaml.VERSION, "a-sansara");
|
||||
|
||||
Pluie.Yaml.Scanner.DEBUG = false;
|
||||
Pluie.Yaml.DEBUG = false;
|
||||
var config = new Yaml.Config (path, true);
|
||||
var spath = "^imports";
|
||||
var node = config.get (spath);
|
||||
|
|
|
@ -39,7 +39,7 @@ int main (string[] args)
|
|||
var done = false;
|
||||
|
||||
of.title ("Pluie Yaml Library", Pluie.Yaml.VERSION, "a-sansara");
|
||||
Pluie.Yaml.Scanner.DEBUG = false;
|
||||
Pluie.Yaml.DEBUG = false;
|
||||
var loader = new Yaml.Loader (path, true, true);
|
||||
if ((done = loader.done)) {
|
||||
var root = loader.get_nodes ();
|
||||
|
|
|
@ -39,7 +39,7 @@ int main (string[] args)
|
|||
var done = false;
|
||||
|
||||
of.title ("Pluie Yaml Library", Pluie.Yaml.VERSION, "a-sansara");
|
||||
Pluie.Yaml.Scanner.DEBUG = false;
|
||||
Pluie.Yaml.DEBUG = false;
|
||||
Yaml.Object? obj = null;
|
||||
var config = new Yaml.Config (path, true);
|
||||
var root = config.root_node ();
|
||||
|
@ -50,7 +50,7 @@ int main (string[] args)
|
|||
foreach (var node in root) {
|
||||
of.action ("Yaml.Object from node", node.name);
|
||||
of.echo (node.to_string (false));
|
||||
if ((obj = Yaml.Object.from_node (node)) != null) {
|
||||
if ((obj = Yaml.Builder.from_node (node)) != null) {
|
||||
list[node.name] = obj;
|
||||
}
|
||||
else {
|
||||
|
@ -69,14 +69,22 @@ int main (string[] args)
|
|||
of.keyval("type_char" , "%c" .printf(o.type_char));
|
||||
of.keyval("type_string", "%s" .printf(o.type_string));
|
||||
of.keyval("type_uchar" , "%u" .printf(o.type_uchar));
|
||||
of.keyval("type_uint" , "%u" .printf(o.type_uint));
|
||||
of.keyval("type_float" , "%f" .printf(o.type_float));
|
||||
of.keyval("type_double", "%f" .printf(o.type_double));
|
||||
of.keyval("type_struct", "%s" .printf(o.type_struct.to_string ()));
|
||||
of.keyval("type_object", "%s" .printf(o.type_object.get_type ().name ()));
|
||||
of.keyval(" toto (string)", "%s" .printf(o.type_object.toto));
|
||||
of.keyval(" tapa (string)", "%s" .printf(o.type_object.tata));
|
||||
of.keyval(" titi (int)" , "%d" .printf(o.type_object.titi));
|
||||
of.keyval(" tutu (bool)" , "%s" .printf(o.type_object.tutu.to_string ()));
|
||||
of.keyval(" toto" , "%s (string)" .printf(o.type_object.toto));
|
||||
of.keyval(" tapa" , "%s (string)" .printf(o.type_object.tata));
|
||||
of.keyval(" titi" , "%d (int)" .printf(o.type_object.titi));
|
||||
of.keyval(" tutu" , "%s (bool)" .printf(o.type_object.tutu.to_string ()));
|
||||
o.type_object.method_a ();
|
||||
if (o.type_gee_al != null) {
|
||||
of.keyval("type_gee_al", "(%s)" .printf(o.type_gee_al.get_type ().name ()));
|
||||
foreach (string v in o.type_gee_al) {
|
||||
of.echo(" - item : %s".printf (v));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ int main (string[] args)
|
|||
var done = false;
|
||||
|
||||
of.title ("Pluie Yaml Library", Pluie.Yaml.VERSION, "a-sansara");
|
||||
Pluie.Yaml.Scanner.DEBUG = false;
|
||||
Pluie.Yaml.DEBUG = false;
|
||||
var config = new Yaml.Config (path, true);
|
||||
var node = config.root_node ();
|
||||
if ((done = node != null)) {
|
||||
|
|
|
@ -102,6 +102,4 @@ public abstract class Pluie.Yaml.AbstractNode : GLib.Object
|
|||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
259
src/vala/Pluie/Yaml.Builder.vala
Normal file
259
src/vala/Pluie/Yaml.Builder.vala
Normal file
|
@ -0,0 +1,259 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* @software : lib-yaml <https://git.pluie.org/pluie/lib-yaml>
|
||||
* @version : 0.4
|
||||
* @date : 2018
|
||||
* @licence : GPLv3.0 <http://www.gnu.org/licenses/>
|
||||
* @author : a-Sansara <[dev]at[pluie]dot[org]>
|
||||
* @copyright : pluie.org <http://www.pluie.org/>
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* This file is part of lib-yaml.
|
||||
*
|
||||
* lib-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.
|
||||
*
|
||||
* lib-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 lib-yaml. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*/
|
||||
|
||||
using GLib;
|
||||
using Gee;
|
||||
using Pluie;
|
||||
|
||||
/**
|
||||
* a Yaml.Builder class helping to build vala Yaml.Object from Yaml.Node
|
||||
*/
|
||||
public class Pluie.Yaml.Builder
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static GLib.Module? p_module;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static unowned GLib.Module p_open_module ()
|
||||
{
|
||||
if (p_module == null) {
|
||||
p_module = GLib.Module.open (null, 0);
|
||||
}
|
||||
return p_module;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static GLib.Type? type_from_string (string name)
|
||||
{
|
||||
GLib.Type? type = Type.from_name (name.replace(".", ""));
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* retriew GLib.Type related to specified vala name
|
||||
* @param name a valid vala identifier name
|
||||
*/
|
||||
public static Type type_from_vala (string name)
|
||||
{
|
||||
void * s;
|
||||
p_open_module ();
|
||||
if (!p_module.symbol (resolve_c_name(@"$(name).get_type"), out s)) {
|
||||
of.error ("cannot resolve type %s (not found)".printf (name));
|
||||
}
|
||||
return ((dlgType) s)();
|
||||
}
|
||||
|
||||
/**
|
||||
* retiew GLib.Type related to specified tag value.
|
||||
* Type may not be registered yet
|
||||
*/
|
||||
public static Type? type_from_tag (string tagValue)
|
||||
{
|
||||
var type = type_from_string (tagValue);
|
||||
if(type != null && type == Type.INVALID) {
|
||||
type = type_from_vala (tagValue);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* retriew corresponding c name related to specified vala name
|
||||
* @param name a valid vala identifier name
|
||||
*/
|
||||
public static string resolve_c_name (string name)
|
||||
{
|
||||
string? str = null;
|
||||
MatchInfo? mi = null;
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
bool begin = true;
|
||||
try {
|
||||
var reg = new Regex ("([^.]*).?");
|
||||
for (reg.match (name, 0, out mi) ; mi.matches () ; mi.next ()) {
|
||||
if ((str = mi.fetch (1)) != null && str.length > 0) {
|
||||
if (!begin) sb.append_unichar ('_');
|
||||
else begin = false;
|
||||
sb.append_unichar (str[0].tolower ());
|
||||
sb.append (str.substring(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (GLib.RegexError e) {
|
||||
of.error (e.message, true);
|
||||
}
|
||||
return !begin ? sb.str : name;
|
||||
}
|
||||
|
||||
[CCode (has_target = false)]
|
||||
private delegate Type dlgType();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static Yaml.Object? from_node (Yaml.Node node, Type otype = GLib.Type.INVALID)
|
||||
{
|
||||
Yaml.Object? obj = null;
|
||||
try {
|
||||
Type type = node.tag != null ? type_from_tag (node.tag.value) : otype;
|
||||
if (type != Type.INVALID) {
|
||||
Yaml.dbg_action ("vala type founded", "%s (%s)".printf (type.name (), type.to_string ()));
|
||||
if (type.is_object ()) {
|
||||
obj = (Yaml.Object) GLib.Object.new (type);
|
||||
if (node!= null && !node.empty ()) {
|
||||
GLib.ParamSpec? def = null;
|
||||
Yaml.Node? scalar = null;
|
||||
foreach (var child in node) {
|
||||
if ((def = obj.get_class ().find_property (child.name)) != null) {
|
||||
Yaml.dbg ("== prop [%s] type is : %s".printf (child.name, def.value_type.name ()));
|
||||
if (child.ntype.is_single_pair () && (scalar = child.first ()) != null) {
|
||||
set_from_scalar (ref obj, def.name, def.value_type, scalar.data);
|
||||
}
|
||||
else if (child.ntype.is_collection ()) {
|
||||
set_from_collection (ref obj, type, child, def.value_type);
|
||||
}
|
||||
}
|
||||
else {
|
||||
of.warn ("property %s not found".printf (child.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obj == null) {
|
||||
of.warn ("searched type not found : %s".printf (type.name ()));
|
||||
}
|
||||
}
|
||||
catch (GLib.Error e) {
|
||||
of.warn (e.message);
|
||||
}
|
||||
obj.yaml_init ();
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static void set_from_collection (ref Yaml.Object obj, GLib.Type parentType, Yaml.Node node, GLib.Type type)
|
||||
{
|
||||
if (type.is_a (typeof (Yaml.Object))) {
|
||||
obj.set (node.name, Yaml.Builder.from_node(node, type));
|
||||
}
|
||||
else if (Yaml.Object.register.is_registered_type(parentType, type)) {
|
||||
Yaml.dbg ("%s is a registered type".printf (type.name ()));
|
||||
obj.populate_by_type (type, node);
|
||||
}
|
||||
else {
|
||||
Dbg.error ("%s is not registered and cannot be populated".printf (type.name ()), Log.METHOD, Log.LINE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static void set_from_scalar (ref Yaml.Object obj, string name, GLib.Type type, string data)
|
||||
{
|
||||
GLib.Value v = GLib.Value(type);
|
||||
Yaml.dbg_action ("Auto setting property value %s".printf (of.c (ECHO.MICROTIME).s (type.name ())), name);
|
||||
Yaml.dbg (data);
|
||||
if (type.is_a(Type.ENUM))
|
||||
set_enum_value (ref v, type, data);
|
||||
else
|
||||
set_basic_type_value(ref v, type, data);
|
||||
obj.set_property(name, v);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static void set_basic_type_value (ref Value v, GLib.Type type, string data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Type.STRING :
|
||||
v.set_string(data);
|
||||
break;
|
||||
case Type.CHAR :
|
||||
v.set_schar((int8)data.data[0]);
|
||||
break;
|
||||
case Type.UCHAR :
|
||||
v.set_uchar((uint8)data.data[0]);
|
||||
break;
|
||||
case Type.BOOLEAN :
|
||||
v.set_boolean (data == "1" || data.down () == "true");
|
||||
break;
|
||||
case Type.INT :
|
||||
v.set_int(int.parse(data));
|
||||
break;
|
||||
case Type.UINT :
|
||||
v.set_uint((uint)long.parse(data));
|
||||
break;
|
||||
case Type.LONG :
|
||||
case Type.INT64 :
|
||||
v.set_long((long)int64.parse(data));
|
||||
break;
|
||||
case Type.ULONG :
|
||||
case Type.UINT64 :
|
||||
v.set_ulong((ulong)uint64.parse(data));
|
||||
break;
|
||||
case Type.FLOAT :
|
||||
v.set_float((float)double.parse(data));
|
||||
break;
|
||||
case Type.DOUBLE :
|
||||
v.set_double(double.parse(data));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static void set_enum_value (ref Value v, GLib.Type type, string data)
|
||||
{
|
||||
EnumClass kenum = (EnumClass) type.class_ref();
|
||||
unowned EnumValue? enumval = kenum.get_value_by_name(data);
|
||||
if (enumval == null) {
|
||||
enumval = kenum.get_value_by_nick(data.down());
|
||||
int64 e = 0;
|
||||
if(enumval == null) {
|
||||
if(!int64.try_parse(data, out e)) {
|
||||
Dbg.error ("invalid enum value %s".printf(data), Log.METHOD, Log.LINE);
|
||||
}
|
||||
else enumval = kenum.get_value((int)e);
|
||||
}
|
||||
}
|
||||
v.set_enum(enumval.value);
|
||||
//~ of.echo ("enumValue : %d".printf (enumval.value));
|
||||
}
|
||||
|
||||
}
|
|
@ -144,9 +144,7 @@ public class Pluie.Yaml.Config
|
|||
subnode.parent = null;
|
||||
n.add(subnode);
|
||||
}
|
||||
//~ root.add (n);
|
||||
}
|
||||
//~ root.update_level();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,7 +173,7 @@ public class Pluie.Yaml.Config
|
|||
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]);
|
||||
Yaml.dbg_keyval (key, this.paths[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,10 +26,12 @@
|
|||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*/
|
||||
using GLib;
|
||||
using Gee;
|
||||
using Pluie;
|
||||
|
||||
/**
|
||||
* a test class to implements yamlize
|
||||
|
||||
*/
|
||||
public class Pluie.Yaml.Example : Yaml.Object
|
||||
{
|
||||
|
@ -57,8 +59,16 @@ public class Pluie.Yaml.Example : Yaml.Object
|
|||
public int64 type_int64 { get; set; }
|
||||
public uint64 type_uint64 { get; set; }
|
||||
public bool type_bool { get; set; }
|
||||
public Yaml.SubExample type_object { get; set; }
|
||||
public Yaml.ExampleChild type_object { get; set; }
|
||||
public Yaml.NODE_TYPE type_enum { get; set; }
|
||||
public Yaml.ExampleStruct type_struct { get; set; }
|
||||
public Gee.ArrayList<string> type_gee_al { get; set; }
|
||||
|
||||
static construct
|
||||
{
|
||||
Yaml.Object.register.add_type (typeof (Yaml.Example), typeof (Yaml.ExampleStruct));
|
||||
Yaml.Object.register.add_type (typeof (Yaml.Example), typeof (Gee.ArrayList));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -69,4 +79,27 @@ public class Pluie.Yaml.Example : Yaml.Object
|
|||
Dbg.msg ("Yaml.Object %s (%s) instantiated".printf (this.myname, this.type_from_self ()), Log.LINE, Log.FILE);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public override void populate_by_type(GLib.Type type, Yaml.Node node)
|
||||
{
|
||||
try {
|
||||
if (type == typeof (Yaml.ExampleStruct)) {
|
||||
this.type_struct = ExampleStruct.from_yaml_node (node);
|
||||
}
|
||||
else if (type == typeof (Gee.ArrayList)) {
|
||||
this.type_gee_al = new Gee.ArrayList<string> ();
|
||||
if (!node.empty ()) {
|
||||
foreach (var child in node) {
|
||||
this.type_gee_al.add(child.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (GLib.Error e) {
|
||||
Dbg.error(e.message, Log.METHOD, Log.LINE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,9 +29,8 @@
|
|||
|
||||
/**
|
||||
* a test class to implements yamlize
|
||||
|
||||
*/
|
||||
public class Pluie.Yaml.SubExample : Yaml.Object
|
||||
public class Pluie.Yaml.ExampleChild : Yaml.Object
|
||||
{
|
||||
public string toto { get; set; }
|
||||
public string tata { get; set; }
|
|
@ -27,28 +27,32 @@
|
|||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*/
|
||||
|
||||
using GLib;
|
||||
using Gee;
|
||||
using Pluie;
|
||||
|
||||
int main (string[] args)
|
||||
public struct Pluie.Yaml.ExampleStruct
|
||||
{
|
||||
Echo.init(false);
|
||||
|
||||
var path = Yaml.DATA_PATH + "/tag.yml";
|
||||
var done = false;
|
||||
|
||||
of.title ("Pluie Yaml Library", Pluie.Yaml.VERSION, "a-sansara");
|
||||
Pluie.Yaml.Scanner.DEBUG = true;
|
||||
Yaml.Object? obj = null;
|
||||
var config = new Yaml.Config (path, true);
|
||||
var root = config.root_node ();
|
||||
root.display_childs ();
|
||||
// define a map with base Yaml.Object type rather than target type
|
||||
obj = Yaml.Object.from_node (root.first());
|
||||
|
||||
of.rs (done);
|
||||
of.echo ();
|
||||
return (int) done;
|
||||
|
||||
public uint red;
|
||||
public uint green;
|
||||
public uint blue;
|
||||
public static ExampleStruct from_yaml_node (Yaml.Node node)
|
||||
{
|
||||
var s = ExampleStruct ();
|
||||
foreach (var child in node) {
|
||||
var v = child.val (typeof (uint));
|
||||
switch (child.name) {
|
||||
case "red" :
|
||||
s.red = v.get_uint ();
|
||||
break;
|
||||
case "green" :
|
||||
s.green = v.get_uint ();
|
||||
break;
|
||||
case "blue" :
|
||||
s.blue = v.get_uint ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
public string to_string ()
|
||||
{
|
||||
return "%s(red:%u,green:%u,blue:%u)".printf ((typeof (ExampleStruct)).name (), this.red, this.green, this.blue);
|
||||
}
|
||||
}
|
|
@ -143,8 +143,12 @@ public class Pluie.Yaml.Mapping : Yaml.Node
|
|||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public Gee.ArrayList<string>? child_names ()
|
||||
{
|
||||
return this.keys;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -251,6 +251,17 @@ public class Pluie.Yaml.Node : Yaml.AbstractChild, Pluie.Yaml.Collection
|
|||
return new Yaml.Node (null, this.ntype, name);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public GLib.Value val (GLib.Type type)
|
||||
{
|
||||
var v = GLib.Value(type);
|
||||
if (this.ntype.is_single_pair ()) {
|
||||
Yaml.Builder.set_basic_type_value (ref v, type, this.first ().data);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* display childs
|
||||
|
|
|
@ -37,7 +37,15 @@ public abstract class Pluie.Yaml.Object : GLib.Object
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static GLib.Module? p_module;
|
||||
public static Yaml.Register register { get; private set; }
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static construct
|
||||
{
|
||||
register = new Yaml.Register();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -47,53 +55,6 @@ public abstract class Pluie.Yaml.Object : GLib.Object
|
|||
Dbg.msg ("Yaml.Object (%s) instantiated".printf (this.type_from_self ()), Log.LINE, Log.FILE);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static unowned GLib.Module p_open_module ()
|
||||
{
|
||||
if (p_module == null) {
|
||||
p_module = GLib.Module.open (null, 0);
|
||||
}
|
||||
return p_module;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static GLib.Type? type_from_string (string name)
|
||||
{
|
||||
GLib.Type? type = Type.from_name (name.replace(".", ""));
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* retriew GLib.Type related to specified vala name
|
||||
* @param name a valid vala identifier name
|
||||
*/
|
||||
public static Type type_from_vala (string name)
|
||||
{
|
||||
void * s;
|
||||
p_open_module ();
|
||||
if (!p_module.symbol (resolve_c_name(@"$(name).get_type"), out s)) {
|
||||
of.error ("cannot resolve type %s (not found)".printf (name));
|
||||
}
|
||||
return ((dlgType) s)();
|
||||
}
|
||||
|
||||
/**
|
||||
* retiew GLib.Type related to specified tag value.
|
||||
* Type may not be registered yet
|
||||
*/
|
||||
public static Type? type_from_tag (string tagValue)
|
||||
{
|
||||
var type = type_from_string (tagValue);
|
||||
if(type != null && type == Type.INVALID) {
|
||||
type = type_from_vala (tagValue);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* retiew GLib.Type related to instance
|
||||
*/
|
||||
|
@ -102,149 +63,13 @@ public abstract class Pluie.Yaml.Object : GLib.Object
|
|||
return Type.from_instance (this).name ();
|
||||
}
|
||||
|
||||
/**
|
||||
* retriew corresponding c name related to specified vala name
|
||||
* @param name a valid vala identifier name
|
||||
*/
|
||||
public static string resolve_c_name (string name)
|
||||
{
|
||||
string? str = null;
|
||||
MatchInfo? mi = null;
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
bool begin = true;
|
||||
try {
|
||||
var reg = new Regex ("([^.]*).?");
|
||||
for (reg.match (name, 0, out mi) ; mi.matches () ; mi.next ()) {
|
||||
if ((str = mi.fetch (1)) != null && str.length > 0) {
|
||||
if (!begin) sb.append_unichar ('_');
|
||||
else begin = false;
|
||||
sb.append_unichar (str[0].tolower ());
|
||||
sb.append (str.substring(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (GLib.RegexError e) {
|
||||
of.error (e.message, true);
|
||||
}
|
||||
return !begin ? sb.str : name;
|
||||
}
|
||||
|
||||
[CCode (has_target = false)]
|
||||
private delegate Type dlgType();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static Yaml.Object? from_node (Yaml.Node node)
|
||||
public virtual void populate_by_type(GLib.Type type, Yaml.Node node)
|
||||
{
|
||||
Yaml.Object? obj = null;
|
||||
try {
|
||||
if (node.tag != null) {
|
||||
if (Yaml.Scanner.DEBUG) of.action ("tag value", node.tag.value);
|
||||
Type? type = type_from_tag (node.tag.value);
|
||||
if (type != null && type.is_object ()) {
|
||||
if (Yaml.Scanner.DEBUG) of.echo ("object type founded : %s".printf (type.to_string ()));
|
||||
obj = (Yaml.Object) GLib.Object.new (type);
|
||||
if (node!= null && !node.empty ()) {
|
||||
GLib.ParamSpec? def = null;
|
||||
Yaml.Node? scalar = null;
|
||||
foreach (var child in node) {
|
||||
if ((def = obj.get_class ().find_property (child.name)) != null) {
|
||||
if (child.ntype.is_single_pair ()) {
|
||||
if ((scalar = child.first ()) != null) {
|
||||
obj.set_from_scalar (def.name, def.value_type, scalar);
|
||||
}
|
||||
}
|
||||
else if (child.ntype.is_mapping ()) {
|
||||
obj.set (child.name, from_node(child));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
of.echo ("searched type : %s".printf (type.to_string ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (GLib.Error e) {
|
||||
of.warn (e.message);
|
||||
}
|
||||
obj.yaml_init ();
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void set_from_scalar (string name, GLib.Type type, Yaml.Node node)
|
||||
{
|
||||
GLib.Value v = GLib.Value(type);
|
||||
var data = node.data;
|
||||
if (Yaml.Scanner.DEBUG) {
|
||||
of.action("Auto setting property value %s".printf (of.c (ECHO.MICROTIME).s (type.name ())), name);
|
||||
of.echo (data);
|
||||
}
|
||||
if (type.is_a(Type.ENUM)) {
|
||||
this.set_enum_value (ref v, type, data);
|
||||
}
|
||||
else {
|
||||
switch (type)
|
||||
{
|
||||
case Type.STRING :
|
||||
v.set_string(data);
|
||||
break;
|
||||
case Type.CHAR :
|
||||
v.set_schar((int8)data.data[0]);
|
||||
break;
|
||||
case Type.UCHAR :
|
||||
v.set_uchar((uint8)data.data[0]);
|
||||
break;
|
||||
case Type.BOOLEAN :
|
||||
v.set_boolean (data == "1" || data.down () == "true");
|
||||
break;
|
||||
case Type.INT :
|
||||
v.set_int(int.parse(data));
|
||||
break;
|
||||
case Type.UINT :
|
||||
v.set_uint((uint)long.parse(data));
|
||||
break;
|
||||
case Type.LONG :
|
||||
case Type.INT64 :
|
||||
v.set_long((long)int64.parse(data));
|
||||
break;
|
||||
case Type.ULONG :
|
||||
case Type.UINT64 :
|
||||
v.set_ulong((ulong)uint64.parse(data));
|
||||
break;
|
||||
case Type.FLOAT :
|
||||
v.set_float((float)double.parse(data));
|
||||
break;
|
||||
case Type.DOUBLE :
|
||||
v.set_double(double.parse(data));
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.set_property(name, v);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void set_enum_value (ref Value v, GLib.Type type, string data)
|
||||
{
|
||||
EnumClass eclass = (EnumClass) type.class_ref();
|
||||
unowned EnumValue? evalue = eclass.get_value_by_name(data);
|
||||
if (evalue == null) {
|
||||
evalue = eclass.get_value_by_nick(data.down());
|
||||
int64 e = 0;
|
||||
if(evalue == null) {
|
||||
if(!int64.try_parse(data, out e)) {
|
||||
Dbg.error ("invalid enum value %s".printf(data), Log.METHOD, Log.LINE);
|
||||
}
|
||||
}
|
||||
e = evalue.value;
|
||||
v.set_enum((int)e);
|
||||
if (type.is_a (typeof (Yaml.Object))) {
|
||||
this.set (node.name, Yaml.Builder.from_node(node, type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,10 +158,8 @@ public class Pluie.Yaml.Processor
|
|||
*/
|
||||
public bool run ()
|
||||
{
|
||||
if (Yaml.Scanner.DEBUG) {
|
||||
this.read ();
|
||||
of.action ("Processing events");
|
||||
}
|
||||
if (Yaml.DEBUG) this.read ();
|
||||
Yaml.dbg_action ("Processing events");
|
||||
this.reset ();
|
||||
for (var has_next = this.iterator.next (); has_next; has_next = this.iterator.next ()) {
|
||||
this.event = this.iterator.get ();
|
||||
|
@ -180,7 +178,9 @@ public class Pluie.Yaml.Processor
|
|||
this.on_entry ();
|
||||
}
|
||||
if (this.beginFlowSeq && this.event.evtype.is_scalar ()) {
|
||||
if (!this.change) {
|
||||
this.on_scalar (true);
|
||||
}
|
||||
this.beginFlowSeq = false;
|
||||
}
|
||||
if (this.event.evtype.is_key () && (this.event = this.get_value_key_event ()) != null) {
|
||||
|
@ -264,8 +264,7 @@ public class Pluie.Yaml.Processor
|
|||
*/
|
||||
private void on_tag_directive ()
|
||||
{
|
||||
if (Yaml.Scanner.DEBUG)
|
||||
of.action ("on_tag_directive %s".printf (this.event.data["handle"]), this.event.data["prefix"]);
|
||||
Yaml.dbg_action ("on_tag_directive %s".printf (this.event.data["handle"]), this.event.data["prefix"]);
|
||||
this.root.tag_directives[this.event.data["handle"]] = this.event.data["prefix"];
|
||||
}
|
||||
|
||||
|
@ -309,8 +308,7 @@ public class Pluie.Yaml.Processor
|
|||
private void on_tag (bool onKey = false)
|
||||
{
|
||||
if (this.event.evtype.is_tag ()) {
|
||||
if (Yaml.Scanner.DEBUG)
|
||||
of.keyval ("tag %s".printf (this.event.data["handle"]), this.event.data["suffix"]);
|
||||
Yaml.dbg_keyval ("tag %s".printf (this.event.data["handle"]), this.event.data["suffix"]);
|
||||
if (this.root.tag_directives.has_key (this.event.data["handle"])) {
|
||||
var tag = new Yaml.Tag (this.event.data["suffix"], this.event.data["handle"].replace("!", ""));
|
||||
if (onKey)
|
||||
|
@ -444,12 +442,12 @@ public class Pluie.Yaml.Processor
|
|||
private void on_update ()
|
||||
{
|
||||
if (this.node != null) {
|
||||
if (Yaml.Scanner.DEBUG) of.echo (this.node.name);
|
||||
Yaml.dbg (this.node.name);
|
||||
}
|
||||
if (this.change) {
|
||||
if (Yaml.Scanner.DEBUG) of.action ("on change", this.node.name);
|
||||
Yaml.dbg_action ("on change", this.node.name != null ? this.node.name : this.node.data);
|
||||
if (this.keyTag != null) {
|
||||
if (Yaml.Scanner.DEBUG) of.action ("setting tag", this.keyTag.@value);
|
||||
Yaml.dbg_action ("setting tag", this.keyTag.@value);
|
||||
this.node.tag = this.keyTag;
|
||||
}
|
||||
else if (this.valueTag != null) {
|
||||
|
|
93
src/vala/Pluie/Yaml.Register.vala
Normal file
93
src/vala/Pluie/Yaml.Register.vala
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* @software : lib-yaml <https://git.pluie.org/pluie/lib-yaml>
|
||||
* @version : 0.4
|
||||
* @date : 2018
|
||||
* @licence : GPLv3.0 <http://www.gnu.org/licenses/>
|
||||
* @author : a-Sansara <[dev]at[pluie]dot[org]>
|
||||
* @copyright : pluie.org <http://www.pluie.org/>
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* This file is part of lib-yaml.
|
||||
*
|
||||
* lib-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.
|
||||
*
|
||||
* lib-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 lib-yaml. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*/
|
||||
|
||||
using GLib;
|
||||
using Pluie;
|
||||
using Gee;
|
||||
|
||||
/**
|
||||
* a class registering type which could be populated
|
||||
*/
|
||||
public class Pluie.Yaml.Register : GLib.Object
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static Gee.HashMap<Type, Gee.ArrayList<GLib.Type>> reg { get; internal set; }
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static construct {
|
||||
Yaml.Register.reg = new Gee.HashMap<Type, Gee.ArrayList<GLib.Type>> ();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private Gee.ArrayList<GLib.Type> init_type_list ()
|
||||
{
|
||||
return new Gee.ArrayList<GLib.Type> ();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public Gee.ArrayList<GLib.Type>? get_type_list (GLib.Type type)
|
||||
{
|
||||
return reg.get (type);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public bool add_type (GLib.Type type, GLib.Type addedType)
|
||||
{
|
||||
if (!this.is_registered (type)) {
|
||||
reg.set (type, this.init_type_list ());
|
||||
}
|
||||
return reg.get (type).add (addedType);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public bool is_registered (GLib.Type type)
|
||||
{
|
||||
return reg.has_key (type);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public bool is_registered_type (GLib.Type type, GLib.Type checktype)
|
||||
{
|
||||
return this.is_registered (type) && reg.get (type).contains (checktype);
|
||||
}
|
||||
}
|
|
@ -37,7 +37,6 @@ extern void yaml_parse_file(string srcPath, string destPath);
|
|||
*/
|
||||
public class Pluie.Yaml.Scanner
|
||||
{
|
||||
public static bool DEBUG = false;
|
||||
/**
|
||||
* Regex pattern use to find EVENT
|
||||
*/
|
||||
|
@ -143,14 +142,14 @@ public class Pluie.Yaml.Scanner
|
|||
this.before_run (path);
|
||||
this.processor = new Yaml.Processor ();
|
||||
this.done = false;
|
||||
if (Pluie.Yaml.Scanner.DEBUG) of.action ("Scanning events", path);
|
||||
Yaml.dbg_action ("Scanning events", path);
|
||||
while (this.reader.readable) {
|
||||
this.scan_event (this.reader.read ());
|
||||
}
|
||||
this.done = true;
|
||||
if (Pluie.Yaml.Scanner.DEBUG) of.state (this.done);
|
||||
Yaml.dbg_state (this.done);
|
||||
this.done = this.done && this.processor.run ();
|
||||
if (Pluie.Yaml.Scanner.DEBUG) of.state (this.done);
|
||||
Yaml.dbg_state (this.done);
|
||||
Dbg.out (Log.METHOD, "done:%d".printf ((int)done), Log.LINE, Log.FILE);
|
||||
return this.done;
|
||||
}
|
||||
|
|
|
@ -31,9 +31,8 @@ using Gee;
|
|||
|
||||
/**
|
||||
* a test class to implements yamlize
|
||||
|
||||
*/
|
||||
public class Pluie.Yaml.Tag : GLib.Object
|
||||
public class Pluie.Yaml.Tag
|
||||
{
|
||||
public string handle { get; internal set; }
|
||||
public string @value { get; internal set; }
|
||||
|
|
|
@ -31,6 +31,8 @@ namespace Pluie
|
|||
{
|
||||
namespace Yaml
|
||||
{
|
||||
public static bool DEBUG = false;
|
||||
|
||||
public static bool DBG_SHOW_INDENT = true;
|
||||
public static bool DBG_SHOW_PARENT = false;
|
||||
public static bool DBG_SHOW_UUID = true;
|
||||
|
@ -40,6 +42,38 @@ namespace Pluie
|
|||
public static bool DBG_SHOW_TAG = true;
|
||||
public static bool DBG_SHOW_TYPE = true;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static void dbg_action (string msg, string? val = null)
|
||||
{
|
||||
if (Pluie.Yaml.DEBUG) of.action (msg, val);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static void dbg_keyval (string key, string val)
|
||||
{
|
||||
if (Pluie.Yaml.DEBUG) of.keyval (key, val);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static void dbg_state (bool done)
|
||||
{
|
||||
if (Pluie.Yaml.DEBUG) of.state (done);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static void dbg (string? msg = null)
|
||||
{
|
||||
if (Pluie.Yaml.DEBUG && msg != null) of.echo (msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* ParseError
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue
Block a user