Commit fa7e253a authored by Almer S. Tigelaar's avatar Almer S. Tigelaar Committed by Almer S. Tigelaar

Add detailed parser error messages.

2001-04-15  Almer S. Tigelaar  <almer@gnome.org>

	* src/parser.y : Add detailed parser error messages.

	* src/workbook-edit.c (workbook_finish_editing) : Abort
	if the expression is invalid and return a boolean indicating
	success or failure.

	* src/expr.c (expr_parse_string): Set error message to the
	result of gnumeric_expr_parser.

	* src/parse-util.c (parse_error_init) : Properly initialize
	begin and end character.

	* src/gnumeric-sheet.c (gnumeric_sheet_key_mode_sheet): Don't
	change the cursor position if workbook_finish_editing failed.
	(move_cursor): Idem.

	* src/item-grid.c (item_grid_button_1): Idem.
parent 021cb3d3
2001-04-15 Almer S. Tigelaar <almer@gnome.org>
* src/parser.y : Add detailed parser error messages.
* src/workbook-edit.c (workbook_finish_editing) : Abort
if the expression is invalid and return a boolean indicating
success or failure.
* src/expr.c (expr_parse_string): Set error message to the
result of gnumeric_expr_parser.
* src/parse-util.c (parse_error_init) : Properly initialize
begin and end character.
* src/gnumeric-sheet.c (gnumeric_sheet_key_mode_sheet): Don't
change the cursor position if workbook_finish_editing failed.
(move_cursor): Idem.
* src/item-grid.c (item_grid_button_1): Idem.
2001-04-15 Almer S. Tigelaar <almer@gnome.org>
* src/preview-grid.c
......
2001-04-15 Almer S. Tigelaar <almer@gnome.org>
* src/parser.y : Add detailed parser error messages.
* src/workbook-edit.c (workbook_finish_editing) : Abort
if the expression is invalid and return a boolean indicating
success or failure.
* src/expr.c (expr_parse_string): Set error message to the
result of gnumeric_expr_parser.
* src/parse-util.c (parse_error_init) : Properly initialize
begin and end character.
* src/gnumeric-sheet.c (gnumeric_sheet_key_mode_sheet): Don't
change the cursor position if workbook_finish_editing failed.
(move_cursor): Idem.
* src/item-grid.c (item_grid_button_1): Idem.
2001-04-15 Almer S. Tigelaar <almer@gnome.org>
* src/preview-grid.c
......
2001-04-15 Almer S. Tigelaar <almer@gnome.org>
* src/parser.y : Add detailed parser error messages.
* src/workbook-edit.c (workbook_finish_editing) : Abort
if the expression is invalid and return a boolean indicating
success or failure.
* src/expr.c (expr_parse_string): Set error message to the
result of gnumeric_expr_parser.
* src/parse-util.c (parse_error_init) : Properly initialize
begin and end character.
* src/gnumeric-sheet.c (gnumeric_sheet_key_mode_sheet): Don't
change the cursor position if workbook_finish_editing failed.
(move_cursor): Idem.
* src/item-grid.c (item_grid_button_1): Idem.
2001-04-15 Almer S. Tigelaar <almer@gnome.org>
* src/preview-grid.c
......
2001-04-15 Almer S. Tigelaar <almer@gnome.org>
* src/parser.y : Add detailed parser error messages.
* src/workbook-edit.c (workbook_finish_editing) : Abort
if the expression is invalid and return a boolean indicating
success or failure.
* src/expr.c (expr_parse_string): Set error message to the
result of gnumeric_expr_parser.
* src/parse-util.c (parse_error_init) : Properly initialize
begin and end character.
* src/gnumeric-sheet.c (gnumeric_sheet_key_mode_sheet): Don't
change the cursor position if workbook_finish_editing failed.
(move_cursor): Idem.
* src/item-grid.c (item_grid_button_1): Idem.
2001-04-15 Almer S. Tigelaar <almer@gnome.org>
* src/preview-grid.c
......
2001-04-15 Almer S. Tigelaar <almer@gnome.org>
* src/parser.y : Add detailed parser error messages.
* src/workbook-edit.c (workbook_finish_editing) : Abort
if the expression is invalid and return a boolean indicating
success or failure.
* src/expr.c (expr_parse_string): Set error message to the
result of gnumeric_expr_parser.
* src/parse-util.c (parse_error_init) : Properly initialize
begin and end character.
* src/gnumeric-sheet.c (gnumeric_sheet_key_mode_sheet): Don't
change the cursor position if workbook_finish_editing failed.
(move_cursor): Idem.
* src/item-grid.c (item_grid_button_1): Idem.
2001-04-15 Almer S. Tigelaar <almer@gnome.org>
* src/preview-grid.c
......
......@@ -194,9 +194,10 @@ expr_parse_string (char const *expr_text, ParsePos const *pp,
tree = gnumeric_expr_parser (expr_text, pp, TRUE, FALSE, desired_format,
parse_error_init (&perr));
/* TODO : use perr when we populate it */
if (tree == NULL)
*error_msg = _("Syntax error");
*error_msg = perr.message;
else
*error_msg = NULL;
parse_error_free (&perr);
......
......@@ -72,11 +72,13 @@ move_cursor (GnumericSheet *gsheet, int col, int row, gboolean clear_selection)
* If you dont know what this means, just mail me.
*/
/* Set the cursor BEFORE making it visible to decrease flicker */
if (workbook_finish_editing (gsheet->scg->wbcg, TRUE) == FALSE)
return;
if (clear_selection)
sheet_selection_reset (sheet);
/* Set the cursor BEFORE making it visible to decrease flicker */
workbook_finish_editing (gsheet->scg->wbcg, TRUE);
sheet_cursor_set (sheet, col, row, col, row, col, row);
sheet_make_cell_visible (sheet, col, row);
......@@ -623,16 +625,18 @@ gnumeric_sheet_key_mode_sheet (GnumericSheet *gsheet, GdkEventKey *event)
case GDK_ISO_Left_Tab:
case GDK_KP_Tab:
{
/* Figure out the direction */
gboolean const direction = (event->state & GDK_SHIFT_MASK) ? FALSE : TRUE;
gboolean const horizontal = (event->keyval == GDK_KP_Enter ||
event->keyval == GDK_Return) ? FALSE : TRUE;
/* Be careful to restore the editing sheet if we are editing */
if (wbcg->editing)
sheet = wbcg->editing_sheet;
workbook_finish_editing (wbcg, TRUE);
sheet_selection_walk_step (sheet, direction, horizontal);
if (workbook_finish_editing (wbcg, TRUE)) {
/* Figure out the direction */
gboolean const direction = (event->state & GDK_SHIFT_MASK) ? FALSE : TRUE;
gboolean const horizontal = (event->keyval == GDK_KP_Enter ||
event->keyval == GDK_Return) ? FALSE : TRUE;
sheet_selection_walk_step (sheet, direction, horizontal);
}
break;
}
......
......@@ -72,11 +72,13 @@ move_cursor (GnumericSheet *gsheet, int col, int row, gboolean clear_selection)
* If you dont know what this means, just mail me.
*/
/* Set the cursor BEFORE making it visible to decrease flicker */
if (workbook_finish_editing (gsheet->scg->wbcg, TRUE) == FALSE)
return;
if (clear_selection)
sheet_selection_reset (sheet);
/* Set the cursor BEFORE making it visible to decrease flicker */
workbook_finish_editing (gsheet->scg->wbcg, TRUE);
sheet_cursor_set (sheet, col, row, col, row, col, row);
sheet_make_cell_visible (sheet, col, row);
......@@ -623,16 +625,18 @@ gnumeric_sheet_key_mode_sheet (GnumericSheet *gsheet, GdkEventKey *event)
case GDK_ISO_Left_Tab:
case GDK_KP_Tab:
{
/* Figure out the direction */
gboolean const direction = (event->state & GDK_SHIFT_MASK) ? FALSE : TRUE;
gboolean const horizontal = (event->keyval == GDK_KP_Enter ||
event->keyval == GDK_Return) ? FALSE : TRUE;
/* Be careful to restore the editing sheet if we are editing */
if (wbcg->editing)
sheet = wbcg->editing_sheet;
workbook_finish_editing (wbcg, TRUE);
sheet_selection_walk_step (sheet, direction, horizontal);
if (workbook_finish_editing (wbcg, TRUE)) {
/* Figure out the direction */
gboolean const direction = (event->state & GDK_SHIFT_MASK) ? FALSE : TRUE;
gboolean const horizontal = (event->keyval == GDK_KP_Enter ||
event->keyval == GDK_Return) ? FALSE : TRUE;
sheet_selection_walk_step (sheet, direction, horizontal);
}
break;
}
......
......@@ -766,8 +766,11 @@ item_grid_button_1 (SheetControlGUI *scg, GdkEventButton *event,
if (workbook_edit_has_guru (gsheet->scg->wbcg))
return 1;
/* This was a regular click on a cell on the spreadsheet. Select it. */
workbook_finish_editing (gsheet->scg->wbcg, TRUE);
/* This was a regular click on a cell on the spreadsheet. Select it.
* but only if the entered expression is valid
*/
if (workbook_finish_editing (gsheet->scg->wbcg, TRUE) == FALSE)
return 1;
if (!(event->state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)))
sheet_selection_reset (scg->sheet);
......
......@@ -553,7 +553,10 @@ parse_text_value_or_expr (EvalPos const *pos, char const *text,
ParseError *
parse_error_init (ParseError *pe)
{
pe->message = NULL;
pe->message = NULL;
pe->begin_char = -1;
pe->end_char = -1;
return pe;
}
......
......@@ -42,7 +42,7 @@ char const * gnumeric_char_start_expr_p (char const * c);
/* In parser.y */
typedef struct {
char *message;
int start_char, end_char;
int begin_char, end_char;
} ParseError;
ParseError *parse_error_init (ParseError *pe);
void parse_error_free (ParseError *pe);
......
......@@ -8,6 +8,7 @@
* Miguel de Icaza (miguel@gnu.org)
* Jody Goldberg (jgoldberg@home.com)
* Morten Welinder (terra@diku.dk)
* Almer S. Tigelaar (almer@gnome.org)
*/
#include <config.h>
#include <ctype.h>
......@@ -194,6 +195,11 @@ typedef struct {
/* The expression being parsed */
char const *expr_text;
/* A backup of the above, this will always point to the real
* expression beginning to calculate the offset in the expression
*/
char const *expr_backup;
/* Location where the parsing is taking place */
ParsePos const *pos;
......@@ -209,6 +215,8 @@ typedef struct {
/* The suggested format to use for this expression */
StyleFormat **desired_format;
ExprTree *result;
ParseError *error;
} ParserState;
/* The error returned from the */
......@@ -320,10 +328,14 @@ parse_string_as_value_or_name (ExprTree *str)
}
static int
gnumeric_parse_error (void)
gnumeric_parse_error (ParserState *state, char *message, int end, int relative_begin)
{
/* TODO : Get rid of ParseErr and replace it with something richer. */
/* parser_error = PARSE_ERR_SYNTAX; */
g_return_val_if_fail (state->error != NULL, ERROR);
state->error->message = message;
state->error->begin_char = end - relative_begin;
state->error->end_char = end;
return ERROR;
}
......@@ -419,12 +431,18 @@ exp: CONSTANT { $$ = $1; }
NamedExpression *expr_name;
char *name = $2->constant.value->v_str.val->str;
ParsePos pos = *state->pos;
pos.sheet = $1;
expr_name = expr_name_lookup (&pos, name);
unregister_allocation ($2); expr_tree_unref ($2);
if (expr_name == NULL)
return gnumeric_parse_error ();
if (expr_name == NULL) {
int retval = gnumeric_parse_error (
state, g_strdup_printf (_("Expression '%s' does not exist on sheet '%s'"), name, $1->name_quoted),
(state->expr_text - state->expr_backup), strlen (name) - 1);
unregister_allocation ($2); expr_tree_unref ($2);
return retval;
} else
unregister_allocation ($2); expr_tree_unref ($2);
$$ = register_expr_allocation (expr_tree_new_name (expr_name));
}
;
......@@ -434,10 +452,17 @@ string_opt_quote : STRING
;
sheetref: string_opt_quote SHEET_SEP {
Sheet *sheet = sheet_lookup_by_name (state->pos->wb, $1->constant.value->v_str.val->str);
unregister_allocation ($1); expr_tree_unref ($1);
if (sheet == NULL)
return gnumeric_parse_error ();
char *name = $1->constant.value->v_str.val->str;
Sheet *sheet = sheet_lookup_by_name (state->pos->wb, name);
if (sheet == NULL) {
int retval = gnumeric_parse_error (
state, g_strdup_printf (_("Unknown sheet '%s'"), name),
(state->expr_text - state->expr_backup) - 1, strlen (name) - 1);
unregister_allocation ($1); expr_tree_unref ($1);
return retval;
} else
unregister_allocation ($1); expr_tree_unref ($1);
$$ = sheet;
}
......@@ -453,14 +478,22 @@ sheetref: string_opt_quote SHEET_SEP {
Workbook * wb =
application_workbook_get_by_name ($2->constant.value->v_str.val->str);
Sheet *sheet = NULL;
char *sheetname = $4->constant.value->v_str.val->str;
if (wb != NULL)
sheet = sheet_lookup_by_name (wb, $4->constant.value->v_str.val->str);
unregister_allocation ($4); expr_tree_unref ($4);
sheet = sheet_lookup_by_name (wb, sheetname);
unregister_allocation ($2); expr_tree_unref ($2);
if (sheet == NULL)
return gnumeric_parse_error ();
if (sheet == NULL) {
int retval = gnumeric_parse_error (
state, g_strdup_printf (_("Unknown sheet '%s'"), sheetname),
(state->expr_text - state->expr_backup) - 1, strlen (sheetname) - 1);
unregister_allocation ($4); expr_tree_unref ($4);
return retval;
} else
unregister_allocation ($4); expr_tree_unref ($4);
$$ = sheet;
}
;
......@@ -543,8 +576,11 @@ array_row: array_exp {
unregister_allocation ($1);
$$ = g_list_prepend ($3, $1);
register_expr_list_allocation ($$);
} else
return gnumeric_parse_error ();
} else {
return gnumeric_parse_error (
state, g_strdup_printf (_("The character %c can not be used to separate array elements"),
state->array_col_separator), (state->expr_text - state->expr_backup), 1);
}
}
| array_exp '\\' array_row {
if (state->array_col_separator == '\\') {
......@@ -552,8 +588,12 @@ array_row: array_exp {
unregister_allocation ($1);
$$ = g_list_prepend ($3, $1);
register_expr_list_allocation ($$);
} else
return gnumeric_parse_error ();
} else {
/* FIXME: Is this the right error to display? */
return gnumeric_parse_error (
state, g_strdup_printf (_("The character %c can not be used to separate array elements"),
state->array_col_separator), (state->expr_text - state->expr_backup), 1);
}
}
| { $$ = NULL; }
;
......@@ -658,8 +698,13 @@ yylex (void)
if (errno != ERANGE) {
v = value_new_float ((gnum_float)d);
state->expr_text = end;
} else {
return gnumeric_parse_error (
state, g_strdup (_("The number is out of range")),
state->expr_text - state->expr_backup - 1, end - start);
}
}
} else
g_warning ("%s is not a double, but was expected to be one", start);
} else {
/* This could be a row range ref or an integer */
char *end;
......@@ -677,8 +722,15 @@ yylex (void)
}
v = value_new_int (l);
state->expr_text = end;
} else {
if (l == LONG_MIN || l == LONG_MAX) {
return gnumeric_parse_error (
state, g_strdup (_("The number is out of range")),
state->expr_text - state->expr_backup - 1, end - start);
}
}
}
} else
g_warning ("%s is not an integer, but was expected to be one", start);
}
/* Very odd string, Could be a bound problem. Trigger an error */
......@@ -703,8 +755,11 @@ yylex (void)
state->expr_text++;
state->expr_text++;
}
if (!*state->expr_text)
return gnumeric_parse_error ();
if (!*state->expr_text) {
return gnumeric_parse_error (
state, g_strdup (_("Could not find matching closing quote")),
(p - state->expr_backup), 1);
}
s = string = (char *) alloca (1 + state->expr_text - p);
while (p != state->expr_text){
......@@ -784,8 +839,9 @@ gnumeric_expr_parser (char const *expr_text, ParsePos const *pos,
{
ParserState pstate;
pstate.expr_text = expr_text;
pstate.pos = pos;
pstate.expr_text = expr_text;
pstate.expr_backup = expr_text;
pstate.pos = pos;
pstate.decimal_point = format_get_decimal ();
pstate.separator = format_get_arg_sep ();
......@@ -799,6 +855,8 @@ gnumeric_expr_parser (char const *expr_text, ParsePos const *pos,
if (pstate.desired_format)
*pstate.desired_format = NULL;
pstate.error = error;
if (deallocate_stack == NULL)
deallocate_init ();
......
......@@ -69,14 +69,14 @@ workbook_edit_set_sensitive (WorkbookControlGUI *wbcg, gboolean flag1, gboolean
#endif
}
void
gboolean
workbook_finish_editing (WorkbookControlGUI *wbcg, gboolean const accept)
{
Sheet *sheet;
WorkbookControl *wbc;
WorkbookView *wbv;
g_return_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg));
g_return_val_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg), FALSE);
wbc = WORKBOOK_CONTROL (wbcg);
wbv = wb_control_view (wbc);
......@@ -89,28 +89,44 @@ workbook_finish_editing (WorkbookControlGUI *wbcg, gboolean const accept)
gtk_widget_destroy (wbcg->edit_line.guru);
if (!wbcg->editing)
return;
return TRUE;
g_return_if_fail (wbcg->editing_sheet != NULL);
/* Stop editing */
g_return_val_if_fail (wbcg->editing_sheet != NULL, TRUE);
sheet = wbcg->editing_sheet;
wbcg->editing = FALSE;
wbcg->editing_sheet = NULL;
wbcg->editing_cell = NULL;
workbook_edit_set_sensitive (wbcg, FALSE, TRUE);
/* Save the results before changing focus */
if (accept) {
const char *txt = workbook_edit_get_display_text (wbcg);
/* Store the old value for undo */
/*
* TODO: What should we do in case of failure ?
* maybe another parameter that will force an end ?
*/
cmd_set_text (wbc, sheet, &sheet->edit_pos, txt);
if (gnumeric_char_start_expr_p (txt) != NULL) {
ParsePos pp;
ParseError perr;
parse_pos_init (&pp, wb_control_workbook (wbc), sheet,
sheet->edit_pos.col, sheet->edit_pos.row);
parse_error_init (&perr);
gnumeric_expr_parser (txt, &pp, TRUE, FALSE, NULL, &perr);
/*
* We check to see if any error has occured by querying
* if an error message is set. The return value of
* gnumeric_expr_parser is no good for this purpose
*/
if (perr.message != NULL) {
gtk_entry_select_region (workbook_get_entry (wbcg), perr.begin_char, perr.end_char);
gnome_error_dialog_parented (perr.message, wbcg->toplevel);
parse_error_free (&perr);
return FALSE;
} else
cmd_set_text (wbc, sheet, &sheet->edit_pos, txt);
parse_error_free (&perr);
} else
/* Store the old value for undo */
cmd_set_text (wbc, sheet, &sheet->edit_pos, txt);
} else {
/* Redraw the cell contents in case there was a span */
int const c = sheet->edit_pos.col;
......@@ -120,6 +136,13 @@ workbook_finish_editing (WorkbookControlGUI *wbcg, gboolean const accept)
/* Reload the entry widget with the original contents */
wb_view_edit_line_set (wbv, wbc);
}
/* Stop editing */
wbcg->editing = FALSE;
wbcg->editing_sheet = NULL;
wbcg->editing_cell = NULL;
workbook_edit_set_sensitive (wbcg, FALSE, TRUE);
/*
* restore focus to original sheet in case things were being selected
......@@ -134,6 +157,8 @@ workbook_finish_editing (WorkbookControlGUI *wbcg, gboolean const accept)
if (accept)
workbook_recalc (wb_control_workbook (WORKBOOK_CONTROL (wbcg)));
return TRUE;
}
static void
......
......@@ -6,7 +6,7 @@
void workbook_start_editing_at_cursor (WorkbookControlGUI *wbcg,
gboolean blankp, gboolean cursorp);
void workbook_finish_editing (WorkbookControlGUI *wbcg, gboolean const accept);
gboolean workbook_finish_editing (WorkbookControlGUI *wbcg, gboolean const accept);
gboolean workbook_editing_expr (WorkbookControlGUI const *wbcg);
GtkEntry *workbook_get_entry (WorkbookControlGUI const *wbcg);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment