/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @software : pluie-yaml * @version : 0.5 * @type : library * @date : 2018 * @licence : GPLv3.0 * @author : a-Sansara <[dev]at[pluie]dot[org]> * @copyright : pluie.org * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of pluie-yaml. * * pluie-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. * * pluie-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 pluie-yaml. If not, see . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ using GLib; using Gee; using Pluie; /** * a Yaml Loader class */ public class Pluie.Yaml.Loader { /** * Scanner */ Yaml.Scanner scanner { public get; internal set; } /** * indicate if file has been sucessfully loaded */ public bool done { get; internal set; } /** * Reader used to load content yaml file */ Io.Reader reader; /** * @param path the path of file to parse * @param displayFile display original file * @param displayNode display corresponding Yaml Node Graph */ public Loader (string path, bool displayFile = false, bool displayNode = false ) { this.reader = new Io.Reader (path); this.scanner = new Yaml.Scanner (path); 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); } } else { var evt = this.scanner.get_error_event (); of.error ("line %d (%s)".printf (evt.line, evt.data["error"])); this.displayFile (evt.line); } } /** * return resulting Yaml root node */ public Yaml.Node? get_nodes () { return this.scanner.get_nodes (); } /** * display original file */ public void displayFile (int errorLine = 0) { 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; bool err = false; bool before = false; while (this.reader.readable) { 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); } else if (!before) break; } of.echo (errorLine == 0 ? "EOF" : ""); of.state (errorLine == 0); } /** * 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; } }