[gnumeric] don't lex and parse quite that often
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] don't lex and parse quite that often
- Date: Fri, 30 Jul 2010 05:55:11 +0000 (UTC)
commit f8f5454f3f981d00ed4a0f1c7865b335755bb0f1
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date: Thu Jul 29 23:54:47 2010 -0600
don't lex and parse quite that often
2010-07-30 Andreas J. Guelzow <aguelzow pyrshep ca>
* gnumeric-expr-entry.c (gee_scan_for_range): use the saved expr_top
(gee_update_lexer_items): new
(gee_duplicate_lexer_items): new
(gee_check_tooltip): use the saved lexer_items
(cb_entry_changed): call gee_update_lexer_items
(gee_finalize): delete saved expr_top and lexer_items
(gee_find_lexer_token): make arguments pointers to const
(gnm_expr_entry_find_range): use the saved lexer_items
(gnm_expr_entry_enable_highlight): call gee_update_lexer_items
src/widgets/ChangeLog | 12 +++
src/widgets/gnumeric-expr-entry.c | 157 ++++++++++++++++++++++--------------
2 files changed, 108 insertions(+), 61 deletions(-)
---
diff --git a/src/widgets/ChangeLog b/src/widgets/ChangeLog
index 3a2d770..3f5c38b 100644
--- a/src/widgets/ChangeLog
+++ b/src/widgets/ChangeLog
@@ -1,3 +1,15 @@
+2010-07-30 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * gnumeric-expr-entry.c (gee_scan_for_range): use the saved expr_top
+ (gee_update_lexer_items): new
+ (gee_duplicate_lexer_items): new
+ (gee_check_tooltip): use the saved lexer_items
+ (cb_entry_changed): call gee_update_lexer_items
+ (gee_finalize): delete saved expr_top and lexer_items
+ (gee_find_lexer_token): make arguments pointers to const
+ (gnm_expr_entry_find_range): use the saved lexer_items
+ (gnm_expr_entry_enable_highlight): call gee_update_lexer_items
+
2010-07-28 Morten Welinder <terra gnome org>
* gnumeric-cell-renderer-text.c (gnumeric_cell_renderer_text_render):
diff --git a/src/widgets/gnumeric-expr-entry.c b/src/widgets/gnumeric-expr-entry.c
index 688a263..40cbb5d 100644
--- a/src/widgets/gnumeric-expr-entry.c
+++ b/src/widgets/gnumeric-expr-entry.c
@@ -110,7 +110,9 @@ struct _GnmExprEntry {
gboolean editing_canceled; /* as cell_editable */
gboolean ignore_changes; /* internal mutex */
- gboolean feedback_disabled;
+ gboolean feedback_disabled;
+ GnmLexerItem *lexer_items;
+ GnmExprTop const *texpr;
struct {
GtkWidget *tooltip;
GnmFunc *fd;
@@ -543,15 +545,9 @@ gee_scan_for_range (GnmExprEntry *gee)
parse_pos_init_editpos (&gee->pp, scg_view (gee->scg));
gee_destroy_feedback_range (gee);
if (!gee->feedback_disabled && gee_is_editing (gee)) {
- char const *text = gtk_entry_get_text (gee->entry);
- GnmParsePos pp;
- GnmExprTop const *texpr;
- parse_pos_init_sheet (&pp, sheet);
- if ((texpr = gnm_expr_parse_str
- ((text[0] == '=') ? text+1 : text, &pp, GNM_EXPR_PARSE_DEFAULT,
- sheet_get_conventions (sheet), NULL))!= NULL) {
+ if (gee->texpr != NULL) {
GSList *ptr;
- GSList *list = gnm_expr_top_get_ranges (texpr);
+ GSList *list = gnm_expr_top_get_ranges (gee->texpr);
for (ptr = list ; ptr != NULL ; ptr = ptr->next) {
GnmValue *v = ptr->data;
GnmRange r;
@@ -572,7 +568,6 @@ gee_scan_for_range (GnmExprEntry *gee)
}
go_slist_free_custom (list, (GFreeFunc)value_release);
- gnm_expr_top_unref (texpr);
}
gnm_expr_entry_find_range (gee);
if (gnm_expr_entry_get_rangesel (gee, &range, &parse_sheet) &&
@@ -855,6 +850,55 @@ func_def_cmp (gconstpointer a, gconstpointer b)
gnm_func_get_name (b));
}
+
+static void
+gee_update_lexer_items (GnmExprEntry *gee)
+{
+ GtkEditable *editable = GTK_EDITABLE (gee->entry);
+ char *str = gtk_editable_get_chars (editable, 0, -1);
+ GnmParsePos pp;
+ Sheet *sheet = scg_sheet (gee->scg);
+
+ g_free (gee->lexer_items);
+ gee->lexer_items = NULL;
+
+ if (gee->texpr != NULL) {
+ gnm_expr_top_unref (gee->texpr);
+ gee->texpr = NULL;
+ }
+
+ if (!gee->feedback_disabled) {
+ parse_pos_init_sheet (&pp, sheet);
+ gee->texpr = gnm_expr_parse_str
+ ((str[0] == '=') ? str+1 : str, &pp, GNM_EXPR_PARSE_DEFAULT,
+ sheet_get_conventions (sheet), NULL);
+ }
+
+ if (!(gee->flags & GNM_EE_SINGLE_RANGE)) {
+ gee->lexer_items = gnm_expr_lex_all
+ (str, &gee->pp,
+ GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS,
+ NULL);
+ if (gnm_debug_flag ("functooltip"))
+ gee_dump_lexer (gee->lexer_items);
+ }
+ g_free (str);
+}
+
+static GnmLexerItem *
+gee_duplicate_lexer_items (GnmLexerItem *gli)
+{
+ int n = 1;
+ GnmLexerItem *gli_c = gli;
+
+ while (gli_c->token != 0) {
+ gli_c++;
+ n++;
+ }
+
+ return g_memdup (gli, n * sizeof (GnmLexerItem));
+}
+
static void
gee_check_tooltip (GnmExprEntry *gee)
{
@@ -865,10 +909,10 @@ gee_check_tooltip (GnmExprEntry *gee)
gboolean stuff = FALSE, completion_se_set = FALSE;
GnmLexerItem *gli, *gli_c;
- if (!gee->tooltip.enabled || gee->is_cell_renderer ||
- (gee->flags & GNM_EE_SINGLE_RANGE) ||
- (gee->flags & GNM_EE_FORCE_ABS_REF))
+ if (gee->lexer_items == NULL) {
+ gee_delete_tooltip (gee, TRUE);
return;
+ }
end = gtk_editable_get_position (editable);
@@ -877,24 +921,18 @@ gee_check_tooltip (GnmExprEntry *gee)
return;
}
- /* We are not just looking at the text to the left of end */
- /* since the lexer can make more sense out of everything with */
- /* more info, especially for the completion. */
str = gtk_editable_get_chars (editable, 0, -1);
end_t = g_utf8_offset_to_pointer (str, end) - str;
- gli_c = gnm_expr_lex_all (str, &gee->pp,
- GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS,
- NULL);
- if (gnm_debug_flag ("functooltip"))
- gee_dump_lexer (gli_c);
+
+ gli_c = gli = gee_duplicate_lexer_items (gee->lexer_items);
/*
* If we have an open string at the end of the entry, we
* need to adjust.
*/
- for (gli = gli_c; gli->token != 0; gli++) {
+ for (; gli->token != 0; gli++) {
if (gli->start >= end_t) {
gli->token = 0;
break;
@@ -907,7 +945,8 @@ gee_check_tooltip (GnmExprEntry *gee)
stuff = TRUE;
break;
}
- gli--;
+ if (gli > gli_c)
+ gli--;
/* This creates the completion tooltip */
if (!stuff && gli->start > 0 && gli->token == STRING) {
@@ -1055,6 +1094,7 @@ cb_gee_notify_cursor_position (GnmExprEntry *gee)
static void
cb_entry_changed (GnmExprEntry *gee)
{
+ gee_update_lexer_items (gee);
gee_update_env (gee);
gee_update_calendar (gee);
gee_check_tooltip (gee);
@@ -1319,6 +1359,8 @@ gee_init (GnmExprEntry *gee)
gee->update_timeout_id = 0;
gee->update_policy = GTK_UPDATE_CONTINUOUS;
gee->feedback_disabled = FALSE;
+ gee->lexer_items = NULL;
+ gee->texpr = NULL;
gee->tooltip.tooltip = NULL;
gee->tooltip.fd = NULL;
gee->tooltip.handlerid = 0;
@@ -1358,6 +1400,8 @@ gee_finalize (GObject *obj)
go_format_unref (gee->constant_format);
gee_delete_tooltip (gee, TRUE);
+ g_free (gee->lexer_items);
+ gnm_expr_top_unref (gee->texpr);
((GObjectClass *)parent_class)->finalize (obj);
}
@@ -1640,8 +1684,8 @@ gee_rangesel_update_text (GnmExprEntry *gee)
}
static void
-gee_find_lexer_token (GnmLexerItem *gli, guint token_pos,
- GnmLexerItem **gli_before, GnmLexerItem **gli_after)
+gee_find_lexer_token (GnmLexerItem const *gli, guint token_pos,
+ GnmLexerItem const **gli_before, GnmLexerItem const **gli_after)
{
*gli_before = *gli_after = NULL;
if (gli->token == 0)
@@ -1687,7 +1731,7 @@ gnm_expr_entry_find_range (GnmExprEntry *gee)
GnmRangeRef range;
Rangesel *rs;
int len, token_pos;
- GnmLexerItem *gli, *gli_before, *gli_after;
+ GnmLexerItem const *gli, *gli_before, *gli_after;
g_return_val_if_fail (gee != NULL, FALSE);
@@ -1739,22 +1783,18 @@ gnm_expr_entry_find_range (GnmExprEntry *gee)
return TRUE;
}
- gli = gnm_expr_lex_all (ptr, &gee->pp,
- GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS,
- NULL);
-
- if (gnm_debug_flag ("rangeselection"))
- gee_dump_lexer (gli);
+ gli = gee->lexer_items;
+ while (gli->token != 0 && gli->start < (guint) (ptr - text))
+ gli++;
if (gli->token == 0) {
rs->text_start = g_utf8_pointer_to_offset
(text, ptr);
rs->text_end = len;
- g_free (gli);
return TRUE;
}
- token_pos = cursor - ptr;
+ token_pos = cursor - text;
gee_find_lexer_token (gli, (guint)token_pos, &gli_before, &gli_after);
@@ -1767,20 +1807,20 @@ gnm_expr_entry_find_range (GnmExprEntry *gee)
}
if (gli_before == NULL && gli_after == NULL)
- goto not_possible;
+ return FALSE;
if (gli_before == gli_after) {
if ((gli_after + 1)->token == TOKEN_PARENTHESIS_OPEN ||
(gli_after + 1)->token == TOKEN_BRACE_OPEN)
- goto not_possible;
+ return FALSE;
if (gli < gli_before &&
((gli_before - 1)->token == TOKEN_PARENTHESIS_CLOSED ||
(gli_before - 1)->token == TOKEN_BRACE_CLOSED))
- goto not_possible;
+ return FALSE;
rs->text_start = g_utf8_pointer_to_offset
- (text, ptr + gli_before->start);
+ (text, text + gli_before->start);
rs->text_end = g_utf8_pointer_to_offset
- (text, ptr + gli_before->end);
+ (text, text + gli_before->end);
} else if (gli_before != NULL && gli_after != NULL) {
switch (gli_before->token) {
case STRING:
@@ -1790,11 +1830,11 @@ gnm_expr_entry_find_range (GnmExprEntry *gee)
case INVALID_TOKEN:
if (gli_after->token == TOKEN_PARENTHESIS_OPEN ||
gli_after->token == TOKEN_BRACE_OPEN)
- goto not_possible;
+ return FALSE;
rs->text_start = g_utf8_pointer_to_offset
- (text, ptr + gli_before->start);
+ (text, text + gli_before->start);
rs->text_end = g_utf8_pointer_to_offset
- (text, ptr + gli_before->end);
+ (text, text + gli_before->end);
break;
default:
switch (gli_after->token) {
@@ -1804,15 +1844,15 @@ gnm_expr_entry_find_range (GnmExprEntry *gee)
case RANGEREF:
case INVALID_TOKEN:
rs->text_start = g_utf8_pointer_to_offset
- (text, ptr + gli_after->start);
+ (text, text + gli_after->start);
rs->text_end = g_utf8_pointer_to_offset
- (text, ptr + gli_after->end);
+ (text, text + gli_after->end);
break;
default:
rs->text_start = g_utf8_pointer_to_offset
- (text, ptr + gli_before->end);
+ (text, text + gli_before->end);
rs->text_end = g_utf8_pointer_to_offset
- (text, ptr + gli_after->start);
+ (text, text + gli_after->start);
break;
}
}
@@ -1825,16 +1865,16 @@ gnm_expr_entry_find_range (GnmExprEntry *gee)
case INVALID_TOKEN:
if ((gli_after + 1)->token == TOKEN_PARENTHESIS_OPEN ||
(gli_after + 1)->token == TOKEN_BRACE_OPEN)
- goto not_possible;
+ return FALSE;
rs->text_start = g_utf8_pointer_to_offset
- (text, ptr + gli_after->start);
+ (text, text + gli_after->start);
rs->text_end = g_utf8_pointer_to_offset
- (text, ptr + gli_after->end);
+ (text, text + gli_after->end);
break;
default:
rs->text_end = rs->text_start =
g_utf8_pointer_to_offset
- (text, ptr + gli_after->start);
+ (text, text + gli_after->start);
break;
}
else switch (gli_before->token) {
@@ -1846,20 +1886,19 @@ gnm_expr_entry_find_range (GnmExprEntry *gee)
if (gli < gli_before &&
((gli_before - 1)->token == TOKEN_PARENTHESIS_CLOSED ||
(gli_before - 1)->token == TOKEN_BRACE_CLOSED))
- goto not_possible;
+ return FALSE;
rs->text_start = g_utf8_pointer_to_offset
- (text, ptr + gli_before->start);
+ (text, text + gli_before->start);
rs->text_end = g_utf8_pointer_to_offset
- (text, ptr + gli_before->end);
+ (text, text + gli_before->end);
break;
case TOKEN_PARENTHESIS_CLOSED:
case TOKEN_BRACE_CLOSED:
- goto not_possible;
- break;
+ return FALSE;
default:
rs->text_end = rs->text_start =
g_utf8_pointer_to_offset
- (text, ptr + gli_before->start);
+ (text, text + gli_before->start);
break;
}
@@ -1875,12 +1914,7 @@ gnm_expr_entry_find_range (GnmExprEntry *gee)
rs->is_valid = TRUE;
rs->ref = range;
}
- g_free (gli);
return TRUE;
-
- not_possible:
- g_free (gli);
- return FALSE;
}
/**
@@ -2618,6 +2652,7 @@ gnm_expr_entry_enable_highlight (GnmExprEntry *gee)
{
g_return_if_fail (gee != NULL);
gee->feedback_disabled = FALSE;
+ gee_update_lexer_items (gee);
}
/*****************************************************************************/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]