summaryrefslogtreecommitdiff
path: root/libvaladoc/errorreporter.vala
diff options
context:
space:
mode:
Diffstat (limited to 'libvaladoc/errorreporter.vala')
-rw-r--r--libvaladoc/errorreporter.vala392
1 files changed, 392 insertions, 0 deletions
diff --git a/libvaladoc/errorreporter.vala b/libvaladoc/errorreporter.vala
new file mode 100644
index 000000000..5b9543e62
--- /dev/null
+++ b/libvaladoc/errorreporter.vala
@@ -0,0 +1,392 @@
+/* errorreporter.vala
+ *
+ * Copyright (C) 2008-2011 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Brosch Florian <flo.brosch@gmail.com>
+ */
+
+using Gee;
+
+
+public class Valadoc.ErrorReporter : Object {
+ private int _warnings = 0;
+ private int _errors = 0;
+
+ /**
+ * SGR end tag
+ */
+ private const string ANSI_COLOR_END = "\x1b[0m";
+
+ /**
+ * SGR start tag for source location
+ */
+ private string locus_color_start = "";
+
+ /**
+ * SGR end tag for source location
+ */
+ private unowned string locus_color_end = "";
+
+ /**
+ * SGR start tag for warning titles
+ */
+ private string warning_color_start = "";
+
+ /**
+ * SGR end tag for warning titles
+ */
+ private unowned string warning_color_end = "";
+
+ /**
+ * SGR start tag for error titles
+ */
+ private string error_color_start = "";
+
+ /**
+ * SGR end tag for error titles
+ */
+ private unowned string error_color_end = "";
+
+ /**
+ * SGR start tag for note titles
+ */
+ private string note_color_start = "";
+
+ /**
+ * SGR end tag for note titles
+ */
+ private unowned string note_color_end = "";
+
+ /**
+ * SGR start tag for caret line (^^^)
+ */
+ private string caret_color_start = "";
+
+ /**
+ * SGR end tag for caret line (^^^)
+ */
+ private unowned string caret_color_end = "";
+
+ /**
+ * SGR start tag for quotes line ('', ``, `')
+ */
+ private string quote_color_start = "";
+
+ /**
+ * SGR end tag for quotes line ('', ``, `')
+ */
+ private unowned string quote_color_end = "";
+
+
+ public int warnings_offset {
+ get;
+ set;
+ }
+
+ public int errors_offset {
+ get;
+ set;
+ }
+
+ public unowned GLib.FileStream stream {
+ get;
+ set;
+ }
+
+ public Settings? settings {
+ get;
+ set;
+ }
+
+ public int errors {
+ get {
+ return this._errors + errors_offset;
+ }
+ }
+
+ public int warnings {
+ get {
+ return this._warnings + warnings_offset;
+ }
+ }
+
+
+ public ErrorReporter (Settings? settings = null) {
+ this.stream = GLib.stderr;
+ this.settings = settings;
+ }
+
+ /**
+ * Set all colors by string
+ *
+ * {{{
+ * "error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01"
+ * }}}
+ */
+ public bool set_colors (string str) {
+ Regex val_regex;
+ try {
+ val_regex = new Regex ("^\\s*[0-9]+(;[0-9]*)*\\s*$");
+ } catch (RegexError e) {
+ assert_not_reached ();
+ }
+
+ string error_color = null;
+ string warning_color = null;
+ string note_color = null;
+ string caret_color = null;
+ string locus_color = null;
+ string quote_color = null;
+
+ string[] fragments = str.split (":");
+ foreach (unowned string fragment in fragments) {
+ string[] eq = fragment.split ("=", 2);
+ if (eq.length != 2) {
+ return false;
+ }
+
+ if (!val_regex.match (eq[1])) {
+ return false;
+ }
+
+
+ unowned string checked_value = eq[1]._strip ();
+ switch (eq[0]._strip ()) {
+ case "error":
+ error_color = checked_value;
+ break;
+
+ case "warning":
+ warning_color = checked_value;
+ break;
+
+ case "note":
+ note_color = checked_value;
+ break;
+
+ case "caret":
+ caret_color = checked_value;
+ break;
+
+ case "locus":
+ locus_color = checked_value;
+ break;
+
+ case "quote":
+ quote_color = checked_value;
+ break;
+
+ default:
+ return false;
+ }
+ }
+
+ if (is_atty (this.stream.fileno ())) {
+ if (error_color != null) {
+ this.error_color_start = "\x1b[0" + error_color + "m";
+ this.error_color_end = ANSI_COLOR_END;
+ }
+
+ if (warning_color != null) {
+ this.warning_color_start = "\x1b[0" + warning_color + "m";
+ this.warning_color_end = ANSI_COLOR_END;
+ }
+
+ if (note_color != null) {
+ this.note_color_start = "\x1b[0" + note_color + "m";
+ this.note_color_end = ANSI_COLOR_END;
+ }
+
+ if (caret_color != null) {
+ this.caret_color_start = "\x1b[0" + caret_color + "m";
+ this.caret_color_end = ANSI_COLOR_END;
+ }
+
+ if (locus_color != null) {
+ this.locus_color_start = "\x1b[0" + locus_color + "m";
+ this.locus_color_end = ANSI_COLOR_END;
+ }
+
+ if (quote_color != null) {
+ this.quote_color_start = "\x1b[0" + quote_color + "m";
+ this.quote_color_end = ANSI_COLOR_END;
+ }
+ }
+ return true;
+ }
+
+ [CCode (has_target = false)]
+ private delegate int AttyFunc (int fd);
+
+ private bool is_atty (int fd) {
+ Module module = Module.open (null, ModuleFlags.BIND_LAZY);
+ if (module == null) {
+ return false;
+ }
+
+ void* _func;
+ module.symbol ("isatty", out _func);
+ if (_func == null) {
+ return false;
+ }
+
+ AttyFunc? func = (AttyFunc) _func;
+ return func (fd) == 1;
+ }
+
+ [PrintfFormat]
+ private inline void msg (string type, string type_color_start, string type_color_end, string file, long line, long startpos, long endpos,
+ string errline, string msg_format, va_list args)
+ {
+ this.stream.printf ("%s%s:%lu.%lu-%lu.%lu:%s %s%s:%s ",
+ locus_color_start, file, line, startpos, line, endpos, locus_color_end,
+ type_color_start, type, type_color_end);
+ print_highlighted_message (msg_format.vprintf (args));
+ this.stream.putc ('\n');
+
+ if (startpos <= endpos) {
+ this.stream.printf ("%s\n", errline);
+
+ this.stream.puts (caret_color_start);
+ for (int i = 0; i < errline.char_count ()+1; i++) {
+ if (errline[i] == '\t') {
+ this.stream.printf ("\t");
+ } else if (i >= startpos - 1 && i < endpos - 1) {
+ this.stream.printf ("^");
+ } else {
+ this.stream.printf (" ");
+ }
+ }
+ this.stream.puts (caret_color_end);
+ this.stream.printf ("\n");
+ }
+ }
+
+ private void print_highlighted_message (string message) {
+ int start = 0;
+ int cur = 0;
+
+ while (message[cur] != '\0') {
+ if (message[cur] == '\'' || message[cur] == '`') {
+ unowned string end_chars = (message[cur] == '`')? "`'" : "'";
+ this.stream.puts (message.substring (start, cur - start));
+ start = cur;
+ cur++;
+
+ while (message[cur] != '\0' && end_chars.index_of_char (message[cur]) < 0) {
+ cur++;
+ }
+ if (message[cur] == '\0') {
+ this.stream.puts (message.substring (start, cur - start));
+ start = cur;
+ } else {
+ cur++;
+ this.stream.printf ("%s%s%s", quote_color_start, message.substring (start, cur - start), quote_color_end);
+ start = cur;
+ }
+ } else {
+ cur++;
+ }
+ }
+
+ this.stream.puts (message.offset (start));
+ }
+
+ [PrintfFormat]
+ public void simple_warning (string? location, string msg_format, ...) {
+ var args = va_list();
+
+ if (location != null) {
+ this.stream.puts (locus_color_start);
+ this.stream.puts (location);
+ this.stream.puts (": ");
+ this.stream.puts (locus_color_end);
+ }
+
+ this.stream.puts (warning_color_start);
+ this.stream.puts ("warning: ");
+ this.stream.puts (warning_color_end);
+
+ print_highlighted_message (msg_format.vprintf (args));
+ this.stream.putc ('\n');
+ this._warnings++;
+ }
+
+ [PrintfFormat]
+ public void simple_error (string? location, string msg_format, ...) {
+ var args = va_list();
+
+ if (location != null) {
+ this.stream.puts (locus_color_start);
+ this.stream.puts (location);
+ this.stream.puts (": ");
+ this.stream.puts (locus_color_end);
+ this.stream.putc (' ');
+ }
+
+ this.stream.puts (error_color_start);
+ this.stream.puts ("error: ");
+ this.stream.puts (error_color_end);
+
+ print_highlighted_message (msg_format.vprintf (args));
+ this.stream.putc ('\n');
+ this._errors++;
+ }
+
+ [PrintfFormat]
+ public void simple_note (string? location, string msg_format, ...) {
+ if (_settings == null || _settings.verbose) {
+ var args = va_list();
+
+ if (location != null) {
+ this.stream.puts (locus_color_start);
+ this.stream.puts (location);
+ this.stream.puts (": ");
+ this.stream.puts (locus_color_end);
+ this.stream.putc (' ');
+ }
+
+ this.stream.puts (note_color_start);
+ this.stream.puts ("note: ");
+ this.stream.puts (note_color_end);
+
+ print_highlighted_message (msg_format.vprintf (args));
+ this.stream.putc ('\n');
+ this._warnings++;
+ }
+ }
+
+ [PrintfFormat]
+ public void error (string file, long line, long startpos, long endpos, string errline,
+ string msg_format, ...)
+ {
+ var args = va_list();
+ this.msg ("error", error_color_start, error_color_end, file, line, startpos, endpos, errline, msg_format, args);
+ this._errors++;
+ }
+
+ [PrintfFormat]
+ public void warning (string file, long line, long startpos, long endpos, string errline,
+ string msg_format, ...)
+ {
+ var args = va_list();
+ this.msg ("warning", warning_color_start, warning_color_end, file, line, startpos, endpos, errline, msg_format, args);
+ this._warnings++;
+ }
+}
+