[gcalctool/vala] Port Arth's recent error reporting change
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gcalctool/vala] Port Arth's recent error reporting change
- Date: Sun, 14 Oct 2012 03:13:18 +0000 (UTC)
commit ec0aadf3e77bcdafb394ddd6bcfd45e76d33ba8d
Author: Robert Ancell <robert ancell canonical com>
Date: Sun Oct 14 16:13:11 2012 +1300
Port Arth's recent error reporting change
src/equation-lexer.vala | 20 +++++-----
src/equation-parser.vala | 44 ++++++++++++++++-------
src/equation.vala | 4 +-
src/math-display.vala | 18 +++++++++
src/math-equation.vala | 91 ++++++++++++++++++++++++++++++++++++++++++++--
5 files changed, 149 insertions(+), 28 deletions(-)
---
diff --git a/src/equation-lexer.vala b/src/equation-lexer.vala
index b3d9fc8..a14c83a 100644
--- a/src/equation-lexer.vala
+++ b/src/equation-lexer.vala
@@ -365,7 +365,7 @@ public class Lexer
if ((type = prelexer.get_next_token ()) != LexerTokenType.PL_SUPER_DIGIT)
{
/* ERROR: expected LexerTokenType.PL_SUP_DIGIT */
- parser.set_error (ErrorCode.MP, prelexer.get_marked_substring ());
+ parser.set_error (ErrorCode.MP, prelexer.get_marked_substring (), prelexer.mark_index, prelexer.index);
return insert_token (LexerTokenType.UNKNOWN);
}
@@ -414,7 +414,7 @@ public class Lexer
return insert_token (LexerTokenType.PL_EOS);
/* ERROR: Unexpected token */
- parser.set_error (ErrorCode.INVALID, prelexer.get_marked_substring ());
+ parser.set_error (ErrorCode.INVALID, prelexer.get_marked_substring (), prelexer.mark_index, prelexer.index);
return insert_token (LexerTokenType.UNKNOWN);
}
@@ -455,7 +455,7 @@ public class Lexer
else
{
/* ERROR: expected LexerTokenType.PL_SECOND */
- parser.set_error (ErrorCode.MP, prelexer.get_marked_substring ());
+ parser.set_error (ErrorCode.MP, prelexer.get_marked_substring (), prelexer.mark_index, prelexer.index);
return insert_token (LexerTokenType.UNKNOWN);
}
}
@@ -470,7 +470,7 @@ public class Lexer
else
{
/* ERROR: expected LexerTokenType.PL_MINUTE | LexerTokenType.PL_DIGIT */
- parser.set_error (ErrorCode.MP, prelexer.get_marked_substring ());
+ parser.set_error (ErrorCode.MP, prelexer.get_marked_substring (), prelexer.mark_index, prelexer.index);
return insert_token (LexerTokenType.UNKNOWN);
}
}
@@ -496,7 +496,7 @@ public class Lexer
if (type != LexerTokenType.PL_DIGIT)
{
/* ERROR: expected LexerTokenType.PL_DIGIT */
- parser.set_error (ErrorCode.MP, prelexer.get_marked_substring ());
+ parser.set_error (ErrorCode.MP, prelexer.get_marked_substring (), prelexer.mark_index, prelexer.index);
return insert_token (LexerTokenType.UNKNOWN);
}
@@ -508,7 +508,7 @@ public class Lexer
else
{
/* ERROR: expected LexerTokenType.PL_MINUTE */
- parser.set_error (ErrorCode.MP, prelexer.get_marked_substring ());
+ parser.set_error (ErrorCode.MP, prelexer.get_marked_substring (), prelexer.mark_index, prelexer.index);
return insert_token (LexerTokenType.UNKNOWN);
}
}
@@ -519,7 +519,7 @@ public class Lexer
if (type != LexerTokenType.PL_DIGIT)
{
/* ERROR: expected LexerTokenType.PL_DIGIT */
- parser.set_error (ErrorCode.MP, prelexer.get_marked_substring ());
+ parser.set_error (ErrorCode.MP, prelexer.get_marked_substring (), prelexer.mark_index, prelexer.index);
return insert_token (LexerTokenType.UNKNOWN);
}
while ((type = prelexer.get_next_token ()) == LexerTokenType.PL_DIGIT);
@@ -528,7 +528,7 @@ public class Lexer
else
{
/* ERROR: expected LexerTokenType.PL_SECOND */
- parser.set_error (ErrorCode.MP, prelexer.get_marked_substring ());
+ parser.set_error (ErrorCode.MP, prelexer.get_marked_substring (), prelexer.mark_index, prelexer.index);
return insert_token (LexerTokenType.UNKNOWN);
}
}
@@ -560,7 +560,7 @@ public class Lexer
else
{
/* ERROR: expected LexerTokenType.PL_DIGIT | LexerTokenType.PL_HEX */
- parser.set_error (ErrorCode.MP, prelexer.get_marked_substring ());
+ parser.set_error (ErrorCode.MP, prelexer.get_marked_substring (), prelexer.mark_index, prelexer.index);
return insert_token (LexerTokenType.UNKNOWN);
}
}
@@ -626,7 +626,7 @@ public class Lexer
if (check_if_number ())
return insert_token (LexerTokenType.NUMBER);
/* ERROR: expected LexerTokenType.PL_DECIMAL | LexerTokenType.PL_DIGIT | LexerTokenType.PL_HEX */
- parser.set_error (ErrorCode.MP, prelexer.get_marked_substring ());
+ parser.set_error (ErrorCode.MP, prelexer.get_marked_substring (), prelexer.mark_index, prelexer.index);
return insert_token (LexerTokenType.UNKNOWN);
}
}
diff --git a/src/equation-parser.vala b/src/equation-parser.vala
index 65ddb56..2410d7b 100644
--- a/src/equation-parser.vala
+++ b/src/equation-parser.vala
@@ -161,7 +161,7 @@ public class VariableNode : ParseNode
var t = parser.get_variable (c.to_string ());
if (t == null)
{
- parser.set_error (ErrorCode.UNKNOWN_VARIABLE, token.text);
+ parser.set_error (ErrorCode.UNKNOWN_VARIABLE, token.text, token.start_index, token.end_index);
return null;
}
value = value.multiply (t);
@@ -199,7 +199,7 @@ public class VariableWithPowerNode : ParseNode
var t = parser.get_variable (c.to_string ());
if (t == null)
{
- parser.set_error (ErrorCode.UNKNOWN_VARIABLE, token.text);
+ parser.set_error (ErrorCode.UNKNOWN_VARIABLE, token.text, token.start_index, token.end_index);
return null;
}
@@ -226,7 +226,7 @@ public class FunctionNode : RNode
{
var ans = parser.get_function (token.text, r);
if (ans == null)
- parser.set_error (ErrorCode.UNKNOWN_FUNCTION, token.text);
+ parser.set_error (ErrorCode.UNKNOWN_FUNCTION, token.text, token.start_index, token.end_index);
return ans;
}
@@ -251,7 +251,7 @@ public class FunctionWithPowerNode : ParseNode
if (tmp == null)
{
value = null;
- parser.set_error (ErrorCode.UNKNOWN_FUNCTION, token.text);
+ parser.set_error (ErrorCode.UNKNOWN_FUNCTION, token.text, token.start_index, token.end_index);
return null;
}
@@ -282,7 +282,7 @@ public class FunctionWithNegativePowerNode : ParseNode
if (tmp == null)
{
value = null;
- parser.set_error (ErrorCode.UNKNOWN_FUNCTION, token.text);
+ parser.set_error (ErrorCode.UNKNOWN_FUNCTION, token.text, token.start_index, token.end_index);
return null;
}
@@ -538,7 +538,7 @@ public class NotNode : RNode
{
if (!mp_is_overflow (r, parser.wordlen))
{
- parser.set_error (ErrorCode.OVERFLOW, null);
+ parser.set_error (ErrorCode.OVERFLOW);
return new Number.integer (0);
}
@@ -616,7 +616,7 @@ public class ConvertNode : LRNode
var ans = parser.convert (tmp, from, to);
if (ans == null)
- parser.set_error (ErrorCode.UNKNOWN_CONVERSION, null);
+ parser.set_error (ErrorCode.UNKNOWN_CONVERSION);
return ans;
}
@@ -655,7 +655,7 @@ public class ConvertNumberNode : ParseNode
var ans = parser.convert (tmp, from, to);
if (ans == null)
- parser.set_error (ErrorCode.UNKNOWN_CONVERSION, null);
+ parser.set_error (ErrorCode.UNKNOWN_CONVERSION);
return ans;
}
@@ -663,6 +663,7 @@ public class ConvertNumberNode : ParseNode
public class Parser
{
+ private string input;
private ParseNode root;
private ParseNode right_most;
private Lexer lexer;
@@ -671,9 +672,12 @@ public class Parser
private uint depth_level;
private ErrorCode error;
private string error_token;
+ private int error_token_start;
+ private int error_token_end;
public Parser (string input, int number_base, int wordlen)
{
+ this.input = input;
lexer = new Lexer (input, this, number_base);
root = null;
depth_level = 0;
@@ -682,12 +686,16 @@ public class Parser
this.wordlen = wordlen;
error = ErrorCode.NONE;
error_token = null;
+ error_token_start = 0;
+ error_token_end = 0;
}
- public void set_error (ErrorCode errorno, string? token)
+ public void set_error (ErrorCode errorno, string? token = null, uint token_start = 0, uint token_end = 0)
{
error = errorno;
error_token = token;
+ error_token_start = input.char_count (token_start);
+ error_token_end = input.char_count (token_end);
}
public virtual bool variable_is_defined (string name)
@@ -720,7 +728,7 @@ public class Parser
}
/* Start parsing input string. And call evaluate on success. */
- public Number? parse (out ErrorCode error_code, out string? error_token)
+ public Number? parse (out ErrorCode error_code, out string? error_token, out uint error_start, out uint error_end)
{
/* Scan string and split into tokens */
lexer.scan ();
@@ -736,10 +744,12 @@ public class Parser
{
/* Full string is not parsed. */
if (error == 0)
- set_error (ErrorCode.INVALID, token.text);
+ set_error (ErrorCode.INVALID, token.text, token.start_index, token.end_index);
error_code = error;
error_token = this.error_token;
+ error_start = error_token_start;
+ error_end = error_token_end;
return null;
}
}
@@ -747,10 +757,12 @@ public class Parser
{
/* Full string is not parsed. */
if (error == 0)
- set_error (ErrorCode.INVALID, token.text);
+ set_error (ErrorCode.INVALID, token.text, token.start_index, token.end_index);
error_code = error;
error_token = this.error_token;
+ error_start = error_token_start;
+ error_end = error_token_end;
return null;
}
@@ -759,6 +771,8 @@ public class Parser
{
error_code = error;
error_token = this.error_token;
+ error_start = error_token_start;
+ error_end = error_token_end;
return null;
}
var ans = root.solve ();
@@ -766,11 +780,15 @@ public class Parser
{
error_code = ErrorCode.INVALID;
error_token = null;
+ error_start = error_token_start;
+ error_end = error_token_end;
return null;
}
error_code = ErrorCode.NONE;
error_token = null;
+ error_start = 0;
+ error_end = 0;
return ans;
}
@@ -1658,7 +1676,7 @@ public class Parser
/* Check if the token is a valid variable or not. */
if (!check_variable (token.text))
{
- set_error (ErrorCode.UNKNOWN_VARIABLE, token.text);
+ set_error (ErrorCode.UNKNOWN_VARIABLE, token.text, token.start_index, token.end_index);
return false;
}
token = lexer.get_next_token ();
diff --git a/src/equation.vala b/src/equation.vala
index fa327ea..d2a4465 100644
--- a/src/equation.vala
+++ b/src/equation.vala
@@ -114,12 +114,12 @@ public class Equation
this.expression = expression;
}
- public new Number? parse (out ErrorCode error_code = null, out string error_token = null)
+ public new Number? parse (out ErrorCode error_code = null, out string error_token = null, out uint error_start = null, out uint error_end = null)
{
var parser = new EquationParser (this, expression);
mp_clear_error ();
- var z = parser.parse (out error_code, out error_token);
+ var z = parser.parse (out error_code, out error_token, out error_start, out error_end);
/* Error during parsing */
if (error_code != ErrorCode.NONE)
diff --git a/src/math-display.vala b/src/math-display.vala
index 5c2884d..a466f26 100644
--- a/src/math-display.vala
+++ b/src/math-display.vala
@@ -76,6 +76,8 @@ public class MathDisplay : Gtk.Viewport
equation.notify["status"].connect ((pspec) => { status_changed_cb (); });
status_changed_cb ();
+
+ equation.notify["error-token-end"].connect ((pspec) => { error_status_changed_cb (); });
}
protected override bool key_press_event (Gdk.EventKey event)
@@ -334,4 +336,20 @@ public class MathDisplay : Gtk.Viewport
spinner.stop ();
}
}
+
+ private void error_status_changed_cb ()
+ {
+ /* If both start and end location of error token are the same, no need to select anything. */
+ if (equation.error_token_end - equation.error_token_start == 0)
+ return;
+
+ Gtk.TextIter start, end;
+ equation.get_start_iter (out start);
+ equation.get_start_iter (out end);
+
+ start.set_offset ((int) equation.error_token_start);
+ end.set_offset ((int) equation.error_token_end);
+
+ equation.select_range (start, end);
+ }
}
diff --git a/src/math-equation.vala b/src/math-equation.vala
index 6a94b0f..5163909 100644
--- a/src/math-equation.vala
+++ b/src/math-equation.vala
@@ -28,6 +28,8 @@ private class MathEquationState
public bool can_super_minus; /* true if entering minus can generate a superscript minus */
public bool entered_multiply; /* Last insert was a multiply character */
public string status; /* Equation status */
+ public uint error_token_start; /* Start offset of error token */
+ public uint error_token_end; /* End offset of error token */
}
private class SolveData
@@ -35,6 +37,8 @@ private class SolveData
public Number? number_result;
public string text_result;
public string error;
+ public uint error_start;
+ public uint error_end;
}
public class MathEquation : Gtk.TextBuffer
@@ -602,6 +606,36 @@ public class MathEquation : Gtk.TextBuffer
}
}
+ public uint error_token_start
+ {
+ get
+ {
+ /* Check if the previous answer is before start of error token.
+ * If so, subtract 3 (the length of string "ans") and add actual answer length (ans_end - ans_start) into it. */
+ int ans_start, ans_end;
+ get_ans_offsets (out ans_start, out ans_end);
+ if (ans_start != -1 && ans_start < state.error_token_start)
+ return state.error_token_start + ans_end - ans_start - 3;
+
+ return state.error_token_start;
+ }
+ }
+
+ public uint error_token_end
+ {
+ get
+ {
+ /* Check if the previous answer is before end of error token.
+ * If so, subtract 3 (the length of string "ans") and add actual answer length (ans_end - ans_start) into it. */
+ int ans_start, ans_end;
+ get_ans_offsets (out ans_start, out ans_end);
+ if (ans_start != -1 && ans_start < state.error_token_end)
+ return state.error_token_end + ans_end - ans_start - 3;
+
+ return state.error_token_end;
+ }
+ }
+
public bool is_empty
{
get { return get_char_count () == 0; }
@@ -790,14 +824,14 @@ public class MathEquation : Gtk.TextBuffer
}
}
- private Number? parse (string text, out ErrorCode error_code = null, out string error_token = null)
+ private Number? parse (string text, out ErrorCode error_code = null, out string error_token = null, out uint error_start, out uint error_end)
{
var equation = new MEquation (this, text);
equation.base = serializer.get_base ();
equation.wordlen = word_size;
equation.angle_units = angle_units;
- return equation.parse (out error_code, out error_token);
+ return equation.parse (out error_code, out error_token, out error_start, out error_end);
}
/*
@@ -826,7 +860,8 @@ public class MathEquation : Gtk.TextBuffer
ErrorCode error_code;
string error_token;
- var z = parse (text, out error_code, out error_token);
+ uint error_start, error_end;
+ var z = parse (text, out error_code, out error_token, out error_start, out error_end);
switch (error_code)
{
case ErrorCode.NONE:
@@ -841,11 +876,15 @@ public class MathEquation : Gtk.TextBuffer
case ErrorCode.UNKNOWN_VARIABLE:
solvedata.error = /* Error displayed to user when they an unknown variable is entered */
_("Unknown variable '%s'").printf (error_token);
+ solvedata.error_start = error_start;
+ solvedata.error_end = error_end;
break;
case ErrorCode.UNKNOWN_FUNCTION:
solvedata.error = /* Error displayed to user when an unknown function is entered */
_("Function '%s' is not defined").printf (error_token);
+ solvedata.error_start = error_start;
+ solvedata.error_end = error_end;
break;
case ErrorCode.UNKNOWN_CONVERSION:
@@ -857,7 +896,11 @@ public class MathEquation : Gtk.TextBuffer
if (mp_get_error () != null)
solvedata.error = mp_get_error ();
else if (error_token != null) /* Uncategorized error. Show error token to user */
+ {
solvedata.error = _("Malformed expression at token '%s'").printf (error_token);
+ solvedata.error_start = error_start;
+ solvedata.error_end = error_end;
+ }
else /* Unknown error. */
solvedata.error = _("Malformed expression");
break;
@@ -892,7 +935,17 @@ public class MathEquation : Gtk.TextBuffer
status = "";
if (result.error != null)
+ {
status = result.error;
+ state.error_token_start = result.error_start;
+ state.error_token_end = result.error_end;
+
+ /* Fix thousand separator offsets in the start and end offsets of error token. */
+ error_token_fix_thousands_separator ();
+
+ /* Notify the GUI about the change in error token locations. */
+ notify_property ("error-token-end");
+ }
else if (result.number_result != null)
set_number (result.number_result);
else if (result.text_result != null)
@@ -928,6 +981,38 @@ public class MathEquation : Gtk.TextBuffer
Timeout.add (100, show_in_progress);
}
+ /* Fix the offsets to consider thousand separators inserted by the gui. */
+ private void error_token_fix_thousands_separator ()
+ {
+ Gtk.TextIter start;
+ get_start_iter (out start);
+ var temp = start;
+ var end = start;
+
+ start.set_offset ((int) error_token_start);
+ end.set_offset ((int) error_token_end);
+
+ var str = serializer.get_thousands_separator ().to_string ();
+ var length = str.char_count ();
+
+ /* Move both start and end offsets for each thousand separator till the start of error token. */
+ while (temp.forward_search (str, Gtk.TextSearchFlags.TEXT_ONLY, null, out temp, start))
+ {
+ state.error_token_start += length;
+ state.error_token_end += length;
+ start.forward_chars (length);
+ start.forward_chars (length);
+ }
+
+ /* Starting from start, move only end offset for each thousand separator till the end of error token. */
+ temp = start;
+ while (temp.forward_search (str, Gtk.TextSearchFlags.TEXT_ONLY, null, out temp, end))
+ {
+ state.error_token_end += length;
+ end.forward_chars (length);
+ }
+ }
+
private void* factorize_real ()
{
var x = number;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]