Commit e45a0e6b authored by Almer S. Tigelaar's avatar Almer S. Tigelaar Committed by Almer S. Tigelaar
Browse files

Seek for matching )'s for ('s and vice versa. (find_bracket): The meat for

2001-05-01  Almer S. Tigelaar  <almer@gnome.org>

 	* src/parser.y (yylex): Seek for matching )'s for ('s and
 	vice versa.
 	(find_bracket): The meat for the above functionality
 	(find_char): Split out from yylex, might be useful in other
 	places. Currently used to scan for matching quotes.
	(gnumeric_expr_parser): If the ExprTree is null, assume that
	an error has occurred, set a general "invalid expression" and
	mark the whole expression. Also display more detail when both
	the expression and error message are non-null.
parent 401c3250
......@@ -62,9 +62,6 @@ Long term breakage
- format.c: we should resolve all the separators at gnumeric_setlocale time,
not every time we need them.
- When setting the width of columns, the undo/redo text should be more
informative like "Setting width of columns A through E".
- when guessing the format of a possible value we should try the format
associated with the cell FIRST rather than later. eg enter '10-1' (without
quotes) in a cell with an assigned format of Text. This should be treated as
......
2001-05-01 Almer S. Tigelaar <almer@gnome.org>
* src/parser.y (yylex): Seek for matching )'s for ('s and
vice versa.
(find_bracket): The meat for the above functionality
(find_char): Split out from yylex, might be useful in other
places. Currently used to scan for matching quotes.
(gnumeric_expr_parser): If the ExprTree is null, assume that
an error has occurred, set a general "invalid expression" and
mark the whole expression. Also display more detail when both
the expression and error message are non-null.
2001-05-01 Almer S. Tigelaar <almer@gnome.org>
* src/application.[ch] (application_clipboard_unant): Use
......
2001-05-01 Almer S. Tigelaar <almer@gnome.org>
* src/parser.y (yylex): Seek for matching )'s for ('s and
vice versa.
(find_bracket): The meat for the above functionality
(find_char): Split out from yylex, might be useful in other
places. Currently used to scan for matching quotes.
(gnumeric_expr_parser): If the ExprTree is null, assume that
an error has occurred, set a general "invalid expression" and
mark the whole expression. Also display more detail when both
the expression and error message are non-null.
2001-05-01 Almer S. Tigelaar <almer@gnome.org>
* src/application.[ch] (application_clipboard_unant): Use
......
2001-05-01 Almer S. Tigelaar <almer@gnome.org>
* src/parser.y (yylex): Seek for matching )'s for ('s and
vice versa.
(find_bracket): The meat for the above functionality
(find_char): Split out from yylex, might be useful in other
places. Currently used to scan for matching quotes.
(gnumeric_expr_parser): If the ExprTree is null, assume that
an error has occurred, set a general "invalid expression" and
mark the whole expression. Also display more detail when both
the expression and error message are non-null.
2001-05-01 Almer S. Tigelaar <almer@gnome.org>
* src/application.[ch] (application_clipboard_unant): Use
......
2001-05-01 Almer S. Tigelaar <almer@gnome.org>
* src/parser.y (yylex): Seek for matching )'s for ('s and
vice versa.
(find_bracket): The meat for the above functionality
(find_char): Split out from yylex, might be useful in other
places. Currently used to scan for matching quotes.
(gnumeric_expr_parser): If the ExprTree is null, assume that
an error has occurred, set a general "invalid expression" and
mark the whole expression. Also display more detail when both
the expression and error message are non-null.
2001-05-01 Almer S. Tigelaar <almer@gnome.org>
* src/application.[ch] (application_clipboard_unant): Use
......
2001-05-01 Almer S. Tigelaar <almer@gnome.org>
* src/parser.y (yylex): Seek for matching )'s for ('s and
vice versa.
(find_bracket): The meat for the above functionality
(find_char): Split out from yylex, might be useful in other
places. Currently used to scan for matching quotes.
(gnumeric_expr_parser): If the ExprTree is null, assume that
an error has occurred, set a general "invalid expression" and
mark the whole expression. Also display more detail when both
the expression and error message are non-null.
2001-05-01 Almer S. Tigelaar <almer@gnome.org>
* src/application.[ch] (application_clipboard_unant): Use
......
......@@ -640,6 +640,83 @@ parse_ref_or_string (const char *string)
return STRING;
}
/**
* find_char:
* @str:
* @c:
*
* Returns a pointer to character c in str.
* Callers should check weather p points to a \0 !
**/
static const char *
find_char (const char *str, char c)
{
const char *p = str;
for (p = str; *p && *p != c; p++) {
if (*p == '\\' && p[1])
p++;
}
return p;
}
/**
* find_bracket
* @str: String to search
* @bropen: Opening bracket
* @brclose: Closing bracket
* @seek_close: Should we verify if there are enough closing brackets? (if not, verify opening brackets)
* @stop_after: If not -1 will stop after scanning this number of chars. Useful when seek_close is FALSE.
*
* This routine will attempt to find out wethere the bracket just before @str (or just after the end of @str)
* has matching closing (or opening) bracket. If it has it will return TRUE, otherwise it will
* return FALSE.
**/
static gboolean
find_bracket (const char *str, char bropen, char brclose, gboolean seek_close, int stop_after)
{
const char *p = str;
int brk_cnt = 1;
int stop_cnt = 0;
for (p = str; *p; seek_close ? p++ : p--) {
if (*p == '\\' && p[1]) {
seek_close ? p++ : p--;
if (stop_after != -1)
if (++stop_cnt > stop_after)
break;
}
if (*p == bropen)
seek_close ? brk_cnt++ : brk_cnt--;
if (*p == brclose)
seek_close ? brk_cnt-- : brk_cnt++;
if (brk_cnt == 0)
return TRUE;
if (stop_after != -1)
if (++stop_cnt > stop_after)
break;
}
/*
* 1 Means that this bracket is the offending bracket
* w/o a matching closing or opening bracket.
* If the number is higher than one this means that the
* 'problematic' bracket is nested deeper in the expression,
* in that case we return TRUE! (and wait for the next call which
* should operate on a more deeply nested bracket)
*/
if (brk_cnt == 1)
return FALSE;
else /* No need to check for brk_cnt < 1 that will never happen */
return TRUE;
}
int
yylex (void)
{
......@@ -652,8 +729,31 @@ yylex (void)
start = state->expr_text;
c = (unsigned char) (*state->expr_text++);
if (c == '(' || c == ')')
return c;
/* There must be a matching ) for every ( */
if (c == '(') {
if (!find_bracket (state->expr_text, '(', ')', TRUE, -1)) {
gnumeric_parse_error (
state, g_strdup (_("Could not find matching closing bracket")),
(state->expr_text - state->expr_backup) + 1, 1);
return INVALID_TOKEN;
}
return c;
}
/* There must be a matching ( for every ) */
if (c == ')') {
if (!find_bracket (state->expr_text - 2, '(', ')', FALSE,
state->expr_text - state->expr_backup)) {
gnumeric_parse_error (
state, g_strdup (_("Could not find matching opening bracket")),
(state->expr_text - state->expr_backup) + 1, 1);
return INVALID_TOKEN;
}
return c;
}
if (state->use_excel_reference_conventions) {
if (c == ':')
......@@ -764,16 +864,12 @@ yylex (void)
char quotes_end = c;
Value *v;
p = state->expr_text;
while(*state->expr_text && *state->expr_text != quotes_end) {
if (*state->expr_text == '\\' && state->expr_text [1])
state->expr_text++;
state->expr_text++;
}
if (!*state->expr_text) {
gnumeric_parse_error (
state, g_strdup (_("Could not find matching closing quote")),
(p - state->expr_backup) + 1, 1);
p = state->expr_text;
state->expr_text = find_char (state->expr_text, quotes_end);
if (!*state->expr_text) {
gnumeric_parse_error (
state, g_strdup (_("Could not find matching closing quote")),
(p - state->expr_backup) + 1, 1);
return INVALID_TOKEN;
}
......@@ -918,8 +1014,23 @@ gnumeric_expr_parser (char const *expr_text, ParsePos const *pos,
deallocate_uninit ();
#endif
if (pstate.error->message && pstate.result)
/* Something went wrong, but no detailed error
* message was provided, create a general "catch all"
* error message
*/
if (!pstate.error->message && !pstate.result) {
gnumeric_parse_error (
&pstate, g_strdup (_("Invalid expression")),
pstate.expr_text - pstate.expr_backup,
pstate.expr_text - pstate.expr_backup - 1);
}
/* If this happens, something is very wrong */
if (pstate.error->message && pstate.result) {
g_warning ("An error occurred and the ExprTree is non-null! This should not happen");
g_warning ("Error message is %s (%d, %d)", pstate.error->message, pstate.error->begin_char,
pstate.error->end_char);
}
return pstate.result;
}
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