Commit 18e5debc authored by Jody Goldberg's avatar Jody Goldberg Committed by Jody Goldberg

Fix http://bugs.gnome.org/db/85/8506.html

Mixed mode references are evil.

A bit of interface improvement for gtk-combo-text

2000-04-06  Jody Goldberg <jgoldberg@home.com>

	* src/functions/fn-string.c : Add func 'expression' to return text of
	  formula.

	* src/parser.y : It is illegal to write A1:Sheet2!A3.

	* src/value.c (value_new_cellrange) : Take the eval pos so that we can
	  correctly invert mixed mode references when necessary.

	* src/expr.c (cell_ref_make_abs) : New routine.
	(expr_relocate) : Handle changes in value_new_cellrange.
	* src/func.c (function_marshal_arg) : Ditto.
	* src/ranges.c (range_parse) : Ditto.

	* src/corba-sheet.c (Sheet_cell_set_value) : No need to check these
	  references.  They seem to be hard coded to be relative.

	* src/functions/fn-lookup.c (gnumeric_offset) : Begin to handle
	  relative references.

	* src/sheet.c (cellref_get) : Simplify the logic a smidge.

	* src/workbook.c (workbook_finish_editing) : Restore the edit area
	  manually for now.  We may need to make the update flags finer grain.
parent 237ff618
......@@ -7,6 +7,10 @@ Release Critical
Long term breakage
------------------
- The implication of mixed mode references ($B$2:C3)
is large. We need to validate references when pasting a
copy to check for inversion.
- Copy with destination larger than source does not duplicate the styles.
- Cut/Paste of a cell with bold onto a cell with underline yields a cell with
both ??
......
2000-04-06 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-string.c : Add func 'expression' to return text of
formula.
* src/parser.y : It is illegal to write A1:Sheet2!A3.
* src/value.c (value_new_cellrange) : Take the eval pos so that we can
correctly invert mixed mode references when necessary.
* src/expr.c (cell_ref_make_abs) : New routine.
(expr_relocate) : Handle changes in value_new_cellrange.
* src/func.c (function_marshal_arg) : Ditto.
* src/ranges.c (range_parse) : Ditto.
* src/corba-sheet.c (Sheet_cell_set_value) : No need to check these
references. They seem to be hard coded to be relative.
* src/functions/fn-lookup.c (gnumeric_offset) : Begin to handle
relative references.
* src/sheet.c (cellref_get) : Simplify the logic a smidge.
* src/workbook.c (workbook_finish_editing) : Restore the edit area
manually for now. We may need to make the update flags finer grain.
......
2000-04-06 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-string.c : Add func 'expression' to return text of
formula.
* src/parser.y : It is illegal to write A1:Sheet2!A3.
* src/value.c (value_new_cellrange) : Take the eval pos so that we can
correctly invert mixed mode references when necessary.
* src/expr.c (cell_ref_make_abs) : New routine.
(expr_relocate) : Handle changes in value_new_cellrange.
* src/func.c (function_marshal_arg) : Ditto.
* src/ranges.c (range_parse) : Ditto.
* src/corba-sheet.c (Sheet_cell_set_value) : No need to check these
references. They seem to be hard coded to be relative.
* src/functions/fn-lookup.c (gnumeric_offset) : Begin to handle
relative references.
* src/sheet.c (cellref_get) : Simplify the logic a smidge.
* src/workbook.c (workbook_finish_editing) : Restore the edit area
manually for now. We may need to make the update flags finer grain.
......
2000-04-06 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-string.c : Add func 'expression' to return text of
formula.
* src/parser.y : It is illegal to write A1:Sheet2!A3.
* src/value.c (value_new_cellrange) : Take the eval pos so that we can
correctly invert mixed mode references when necessary.
* src/expr.c (cell_ref_make_abs) : New routine.
(expr_relocate) : Handle changes in value_new_cellrange.
* src/func.c (function_marshal_arg) : Ditto.
* src/ranges.c (range_parse) : Ditto.
* src/corba-sheet.c (Sheet_cell_set_value) : No need to check these
references. They seem to be hard coded to be relative.
* src/functions/fn-lookup.c (gnumeric_offset) : Begin to handle
relative references.
* src/sheet.c (cellref_get) : Simplify the logic a smidge.
* src/workbook.c (workbook_finish_editing) : Restore the edit area
manually for now. We may need to make the update flags finer grain.
......
2000-04-06 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-string.c : Add func 'expression' to return text of
formula.
* src/parser.y : It is illegal to write A1:Sheet2!A3.
* src/value.c (value_new_cellrange) : Take the eval pos so that we can
correctly invert mixed mode references when necessary.
* src/expr.c (cell_ref_make_abs) : New routine.
(expr_relocate) : Handle changes in value_new_cellrange.
* src/func.c (function_marshal_arg) : Ditto.
* src/ranges.c (range_parse) : Ditto.
* src/corba-sheet.c (Sheet_cell_set_value) : No need to check these
references. They seem to be hard coded to be relative.
* src/functions/fn-lookup.c (gnumeric_offset) : Begin to handle
relative references.
* src/sheet.c (cellref_get) : Simplify the logic a smidge.
* src/workbook.c (workbook_finish_editing) : Restore the edit area
manually for now. We may need to make the update flags finer grain.
......
2000-04-06 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-string.c : Add func 'expression' to return text of
formula.
* src/parser.y : It is illegal to write A1:Sheet2!A3.
* src/value.c (value_new_cellrange) : Take the eval pos so that we can
correctly invert mixed mode references when necessary.
* src/expr.c (cell_ref_make_abs) : New routine.
(expr_relocate) : Handle changes in value_new_cellrange.
* src/func.c (function_marshal_arg) : Ditto.
* src/ranges.c (range_parse) : Ditto.
* src/corba-sheet.c (Sheet_cell_set_value) : No need to check these
references. They seem to be hard coded to be relative.
* src/functions/fn-lookup.c (gnumeric_offset) : Begin to handle
relative references.
* src/sheet.c (cellref_get) : Simplify the logic a smidge.
* src/workbook.c (workbook_finish_editing) : Restore the edit area
manually for now. We may need to make the update flags finer grain.
......
2000-04-06 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-string.c : Add func 'expression' to return text of
formula.
* src/parser.y : It is illegal to write A1:Sheet2!A3.
* src/value.c (value_new_cellrange) : Take the eval pos so that we can
correctly invert mixed mode references when necessary.
* src/expr.c (cell_ref_make_abs) : New routine.
(expr_relocate) : Handle changes in value_new_cellrange.
* src/func.c (function_marshal_arg) : Ditto.
* src/ranges.c (range_parse) : Ditto.
* src/corba-sheet.c (Sheet_cell_set_value) : No need to check these
references. They seem to be hard coded to be relative.
* src/functions/fn-lookup.c (gnumeric_offset) : Begin to handle
relative references.
* src/sheet.c (cellref_get) : Simplify the logic a smidge.
* src/workbook.c (workbook_finish_editing) : Restore the edit area
manually for now. We may need to make the update flags finer grain.
......
2000-04-06 Jody Goldberg <jgoldberg@home.com>
* src/functions/fn-string.c : Add func 'expression' to return text of
formula.
* src/parser.y : It is illegal to write A1:Sheet2!A3.
* src/value.c (value_new_cellrange) : Take the eval pos so that we can
correctly invert mixed mode references when necessary.
* src/expr.c (cell_ref_make_abs) : New routine.
(expr_relocate) : Handle changes in value_new_cellrange.
* src/func.c (function_marshal_arg) : Ditto.
* src/ranges.c (range_parse) : Ditto.
* src/corba-sheet.c (Sheet_cell_set_value) : No need to check these
references. They seem to be hard coded to be relative.
* src/functions/fn-lookup.c (gnumeric_offset) : Begin to handle
relative references.
* src/sheet.c (cellref_get) : Simplify the logic a smidge.
* src/workbook.c (workbook_finish_editing) : Restore the edit area
manually for now. We may need to make the update flags finer grain.
......
2000-04-06 Jody Goldberg <jgoldberg@home.com>
* ms-formula-read.c (ms_excel_parse_formula) : Adjust to change in
value_new_range.
2000-04-04 Jody Goldberg <jgoldberg@home.com>
* ms-obj.c (ms_obj_read_biff8_obj) : Be more careful about when to
......
......@@ -908,7 +908,7 @@ ms_excel_parse_formula (ExcelWorkbook *wb, ExcelSheet *sheet, guint8 const *mem,
fn_col, fn_row, 0) ;
make_inter_sheet_ref (wb, extn_idx, first, last) ;
parse_list_push_raw (&stack, value_new_cellrange (first, last));
parse_list_push_raw (&stack, value_new_cellrange (first, last, fn_col, fn_row));
ptg_length = 10 ;
} else {
guint16 extn_idx, first_idx, second_idx;
......@@ -922,7 +922,7 @@ ms_excel_parse_formula (ExcelWorkbook *wb, ExcelSheet *sheet, guint8 const *mem,
second_idx = MS_OLE_GET_GUINT16(cur + 12);
make_inter_sheet_ref_v7 (wb, extn_idx, first_idx,
second_idx, first, last) ;
parse_list_push_raw (&stack, value_new_cellrange (first, last));
parse_list_push_raw (&stack, value_new_cellrange (first, last, fn_col, fn_row));
ptg_length = 20 ;
}
if (first) g_free (first) ;
......@@ -947,7 +947,7 @@ ms_excel_parse_formula (ExcelWorkbook *wb, ExcelSheet *sheet, guint8 const *mem,
ptg_length = 6 ;
}
parse_list_push_raw (&stack, value_new_cellrange (first, last));
parse_list_push_raw (&stack, value_new_cellrange (first, last, fn_col, fn_row));
if (first) g_free (first) ;
if (last) g_free (last) ;
......
......@@ -869,13 +869,12 @@ gnumeric_offset (FunctionEvalInfo *ei, Value **args)
g_return_val_if_fail (args [0]->type == VALUE_CELLRANGE, NULL);
memcpy (&a, &args[0]->v.cell_range.cell_a, sizeof (CellRef));
cell_ref_make_abs (&a, &args[0]->v.cell_range.cell_a, ei->pos);
cell_ref_make_abs (&b, &args[0]->v.cell_range.cell_b, ei->pos);
a.row += value_get_as_int (args[1]);
a.col += value_get_as_int (args[2]);
memcpy (&b, &a, sizeof(CellRef));
width = (args[3] != NULL)
? value_get_as_int (args[3])
: value_area_get_width (ei->pos, args [0]);
......@@ -900,7 +899,7 @@ gnumeric_offset (FunctionEvalInfo *ei, Value **args)
b.row += width-1;
b.col += height-1;
return value_new_cellrange (&a, &b);
return value_new_cellrange (&a, &b, ei->pos->eval.col, ei->pos->eval.row);
}
/***************************************************************************/
......
......@@ -16,7 +16,6 @@
#include "format.h"
#include "number-match.h"
/***************************************************************************/
static char *help_char = {
......@@ -780,6 +779,56 @@ gnumeric_text (FunctionEvalInfo *ei, Value **args)
}
/***************************************************************************/
static char *help_expression = {
N_("@FUNCTION=EXPRESSION\n"
"@SYNTAX=EXPRESSION(cell)\n"
"@DESCRIPTION="
"EXPRESSION returns expression in @cell as a string, or"
"empty if the cell is not an expression.\n"
"@EXAMPLES=\n"
"in A1 EXPRESSION(A2) equals 'EXPRESSION(A3)'.\n"
"in A2 EXPRESSION(A3) equals empty.\n"
"\n"
"@SEEALSO=TEXT")
};
static Value *
gnumeric_expression (FunctionEvalInfo *ei, Value **args)
{
Value const * const v = args[0];
if (v->type == VALUE_CELLRANGE) {
Cell *cell;
CellRef a, b;
cell_ref_make_abs (&a, &v->v.cell_range.cell_a, ei->pos);
cell_ref_make_abs (&b, &v->v.cell_range.cell_b, ei->pos);
if (a.col != b.col || a.row == b.row || a.sheet != b.sheet)
return value_new_error (ei->pos, gnumeric_err_REF);
cell = sheet_cell_get (eval_sheet (a.sheet, ei->pos->sheet),
a.col, a.row);
if (cell->parsed_node) {
ParsePosition pos;
char * expr_string =
expr_decode_tree (cell->parsed_node,
parse_pos_init (&pos,
ei->pos->sheet->workbook,
ei->pos->eval.col,
ei->pos->eval.row));
Value * res = value_new_string (expr_string);
g_free (expr_string);
return res;
}
}
return value_new_empty ();
}
/***************************************************************************/
static char *help_trim = {
......@@ -1335,6 +1384,8 @@ string_functions_init (void)
&help_t, gnumeric_t);
function_add_args (cat, "text", "?s", "value,format_text",
&help_text, gnumeric_text);
function_add_args (cat, "expression", "r", "cell",
&help_expression, gnumeric_expression);
function_add_args (cat, "trim", "s", "text",
&help_trim, gnumeric_trim);
function_add_args (cat, "upper", "s", "text",
......
2000-04-06 Jody Goldberg <jgoldberg@home.com>
* lotus-formula.c (lotus_parse_formula) : Adjust to changes in
value_new_cellrange.
2000-03-31 Michael Meeks <michael@helixcode.com>
* lotus.c (read_workbook): kill old old comments.
......
......@@ -336,7 +336,7 @@ lotus_parse_formula (Sheet *sheet, guint32 col, guint32 row,
get_cellref (&a, data + i + 1, data + i + 3, col, row);
get_cellref (&b, data + i + 5, data + i + 7, col, row);
v = value_new_cellrange (&a, &b);
v = value_new_cellrange (&a, &b, col, row);
parse_list_push_raw (&stack, v);
i += 9;
break;
......
2000-04-06 Jody Goldberg <jgoldberg@home.com>
* python.c (range_from_python) : Take an EvalPos for use in
value_new_cellrange.
(row_from_python) : Take an evalpos for use in value_from_python.
(array_from_python) : Take an evalpos for use in row_from_python.
(value_from_python) : Take an evalpos for use in range_from_python.
(call_function) : Adjust to changes in value_new_cellrange.
2000-04-05 Jody Goldberg <jgoldberg@home.com>
* python.c (marshal_func_nodes) : Use eval_expr_nonempty, but permit
......
......@@ -27,7 +27,7 @@
#define CELL_RANGE_CLASS "CellRange"
static PyObject *value_to_python (Value *v);
static Value *value_from_python (PyObject *o);
static Value *value_from_python (PyObject *o, EvalPosition const * const pos);
/* This is standard idiom for defining exceptions in extension modules. */
static PyObject *GnumericError;
......@@ -423,7 +423,7 @@ cleanup:
* NULL on failure.
*/
static Value *
range_from_python (PyObject *o)
range_from_python (PyObject *o, EvalPosition const * const pos)
{
PyObject *range = NULL;
CellRef a, b;
......@@ -436,7 +436,7 @@ range_from_python (PyObject *o)
cell_ref_from_python, &a,
cell_ref_from_python, &b))
goto cleanup;
ret = value_new_cellrange (&a, &b);
ret = value_new_cellrange (&a, &b, pos->eval.col, pos->eval.row);
cleanup:
Py_DECREF (range);
......@@ -478,7 +478,8 @@ array_check (PyObject *o)
*
* Row n, col m is [n][m]. */
static int
row_from_python (PyObject *o, int rowno, Value *array)
row_from_python (PyObject *o, int rowno, Value *array,
EvalPosition const * const pos)
{
PyObject *item;
int i;
......@@ -487,7 +488,8 @@ row_from_python (PyObject *o, int rowno, Value *array)
for (i = 0; i < cols; i++) {
if ((item = PyList_GetItem (o, i)) == NULL)
return -1;
array->v.array.vals[i][rowno] = value_from_python (item);
array->v.array.vals[i][rowno] =
value_from_python (item, pos);
}
return 0;
}
......@@ -502,7 +504,7 @@ row_from_python (PyObject *o, int rowno, Value *array)
* Row n, col m is [n][m].
*/
static Value *
array_from_python (PyObject *o)
array_from_python (PyObject *o, EvalPosition const *pos)
{
Value *v = NULL, *array = NULL;
PyObject *row = NULL;
......@@ -525,7 +527,7 @@ array_from_python (PyObject *o)
"Rectangular array expected");
goto cleanup;
}
if ((row_from_python (row, j, array)) != 0)
if ((row_from_python (row, j, array, pos)) != 0)
goto cleanup;
}
v = array;
......@@ -544,7 +546,7 @@ cleanup:
* NULL on failure.
*/
static Value *
value_from_python (PyObject *o)
value_from_python (PyObject *o, EvalPosition const * const pos)
{
Value *v = NULL;
......@@ -559,9 +561,9 @@ value_from_python (PyObject *o)
} else if (boolean_check (o)) {
v = boolean_from_python (o);
} else if (array_check (o)) {
v = array_from_python (o);
v = array_from_python (o, pos);
} else if (range_check (o)) {
v = range_from_python (o);
v = range_from_python (o, pos);
} else {
PyErr_SetString (PyExc_TypeError, _("Unknown Python type"));
}
......@@ -608,7 +610,7 @@ call_function (FunctionEvalInfo *ei, PyObject *args)
result = PyEval_CallObject (((FuncData *)(l->data))->codeobj, args);
if (result) {
v = value_from_python (result);
v = value_from_python (result, ei->pos);
Py_DECREF (result);
}
if (PyErr_Occurred ()) {
......@@ -746,7 +748,7 @@ apply (PyObject *m, PyObject *py_args)
item = PySequence_GetItem (seq, i);
if (item == NULL)
goto cleanup;
values[i] = value_from_python (item);
values[i] = value_from_python (item, ei->pos);
if (PyErr_Occurred ()) {
Py_DECREF (item);
goto cleanup;
......
......@@ -331,7 +331,8 @@ Sheet_cell_set_value (PortableServer_Servant servant,
b.col_relative = 0;
a.row_relative = 0;
b.row_relative = 0;
v = value_new_cellrange (&a, &b);
/* We can dummy these out because everything is absolute */
v = value_new_cellrange (&a, &b, 0, 0);
break;
}
......
......@@ -10,6 +10,7 @@
#include <glade/glade.h>
#include "dialogs.h"
#include "expr.h"
#include "expr-name.h"
#include "workbook.h"
#include "gnumeric-util.h"
......
......@@ -1100,6 +1100,25 @@ eval_expr (EvalPosition const * const pos, ExprTree const *tree,
return res;
}
void
cell_ref_make_abs (CellRef * const dest,
CellRef const * const src,
EvalPosition const * const ep)
{
g_return_if_fail (dest != NULL);
g_return_if_fail (src != NULL);
g_return_if_fail (ep != NULL);
*dest = *src;
if (src->col_relative)
dest->col += ep->eval.col;
if (src->row_relative)
dest->row += ep->eval.row;
dest->row_relative = dest->col_relative = FALSE;
}
int
cell_ref_get_abs_col (CellRef const * const ref, EvalPosition const * const pos)
{
......@@ -1111,7 +1130,6 @@ cell_ref_get_abs_col (CellRef const * const ref, EvalPosition const * const pos)
return ref->col;
}
int
cell_ref_get_abs_row (CellRef const * const ref, EvalPosition const * const pos)
{
......@@ -1649,7 +1667,8 @@ expr_relocate (const ExprTree *expr,
Value * res;
/* Dont allow creation of 3D references */
if (ref_a.sheet == ref_b.sheet)
res = value_new_cellrange (&ref_a, &ref_b);
res = value_new_cellrange (&ref_a, &ref_b,
pos->eval.col, pos->eval.row);
else
res = value_new_error (NULL, gnumeric_err_REF);
return expr_tree_new_constant (res);
......
......@@ -131,8 +131,11 @@ struct _ExprName {
} t;
};
int cell_ref_get_abs_col (CellRef const * const cell_ref,
EvalPosition const * const src_fp);
void cell_ref_make_abs (CellRef * const dest,
CellRef const * const src,
EvalPosition const * const ep);
int cell_ref_get_abs_col (CellRef const * const ref,
EvalPosition const * const pos);
int cell_ref_get_abs_row (CellRef const * const cell_ref,
EvalPosition const * const src_fp);
void cell_get_abs_col_row (CellRef const * const cell_ref,
......
......@@ -343,7 +343,9 @@ function_marshal_arg (FunctionEvalInfo *ei,
if (t->oper == OPER_VAR &&
(arg_type == 'A' ||
arg_type == 'r'))
v = value_new_cellrange (&t->u.ref, &t->u.ref);
v = value_new_cellrange (&t->u.ref, &t->u.ref,
ei->pos->eval.col,
ei->pos->eval.row);
else
/* force scalars whenever we are certain */
v = eval_expr (ei->pos, t,
......
......@@ -869,13 +869,12 @@ gnumeric_offset (FunctionEvalInfo *ei, Value **args)
g_return_val_if_fail (args [0]->type == VALUE_CELLRANGE, NULL);
memcpy (&a, &args[0]->v.cell_range.cell_a, sizeof (CellRef));
cell_ref_make_abs (&a, &args[0]->v.cell_range.cell_a, ei->pos);
cell_ref_make_abs (&b, &args[0]->v.cell_range.cell_b, ei->pos);
a.row += value_get_as_int (args[1]);
a.col += value_get_as_int (args[2]);
memcpy (&b, &a, sizeof(CellRef));
width = (args[3] != NULL)
? value_get_as_int (args[3])
: value_area_get_width (ei->pos, args [0]);
......@@ -900,7 +899,7 @@ gnumeric_offset (FunctionEvalInfo *ei, Value **args)
b.row += width-1;
b.col += height-1;
return value_new_cellrange (&a, &b);
return value_new_cellrange (&a, &b, ei->pos->eval.col, ei->pos->eval.row);
}
/***************************************************************************/
......
......@@ -62,8 +62,9 @@ accumulate_regions (Sheet *sheet,
b.col = end_col;
b.row = end_row;
/* Dummy up the eval pos it does not matter */
accum->res = g_slist_prepend (accum->res,
value_new_cellrange(&a, &b));
value_new_cellrange(&a, &b, 0, 0));
accum->index++;
}
......
......@@ -16,7 +16,6 @@
#include "format.h"
#include "number-match.h"
/***************************************************************************/
static char *help_char = {
......@@ -780,6 +779,56 @@ gnumeric_text (FunctionEvalInfo *ei, Value **args)
}
/***************************************************************************/
static char *help_expression = {
N_("@FUNCTION=EXPRESSION\n"
"@SYNTAX=EXPRESSION(cell)\n"
"@DESCRIPTION="
"EXPRESSION returns expression in @cell as a string, or"
"empty if the cell is not an expression.\n"
"@EXAMPLES=\n"
"in A1 EXPRESSION(A2) equals 'EXPRESSION(A3)'.\n"
"in A2 EXPRESSION(A3) equals empty.\n"
"\n"
"@SEEALSO=TEXT")
};
static Value *
gnumeric_expression (FunctionEvalInfo *ei, Value **args)
{
Value const * const v = args[0];
if (v->type == VALUE_CELLRANGE) {
Cell *cell;
CellRef a, b;
cell_ref_make_abs (&a, &v->v.cell_range.cell_a, ei->pos);
cell_ref_make_abs (&b, &v->v.cell_range.cell_b, ei->pos);
if (a.col != b.col || a.row == b.row || a.sheet != b.sheet)
return value_new_error (ei->pos, gnumeric_err_REF);
cell = sheet_cell_get (eval_sheet (a.sheet, ei->pos->sheet),
a.col, a.row);
if (cell->parsed_node) {
ParsePosition pos;
char * expr_string =
expr_decode_tree (cell->parsed_node,
parse_pos_init (&pos,
ei->pos->sheet->workbook,
ei->pos->eval.col,
ei->pos->eval.row));
Value * res = value_new_string (expr_string);
g_free (expr_string);
return res;
}
}
return value_new_empty ();
}
/***************************************************************************/
static char *help_trim = {
......@@ -1335,6 +1384,8 @@ string_functions_init (void)
&help_t, gnumeric_t);
function_add_args (cat, "text", "?s", "value,format_text",
&help_text, gnumeric_text);
function_add_args (cat, "expression", "r", "cell",
&help_expression, gnumeric_expression);
function_add_args (cat, "trim", "s", "text",
&help_trim, gnumeric_trim);
function_add_args (cat, "upper", "s", "text",
......
......@@ -294,12 +294,14 @@ int yyparse(void);
ExprTree *tree;
CellRef *cell;
GList *list;
Sheet *sheet;
}
%type <tree> exp array_exp
%type <list> arg_list array_row, array_cols
%token <tree> NUMBER STRING FUNCALL CONSTANT CELLREF GTE LTE NE
%token SEPARATOR
%type <tree> cellref
%type <sheet> sheetref opt_sheetref
%left '&'
%left '<' '>' '=' GTE LTE NE
......@@ -370,16 +372,6 @@ exp: NUMBER { $$ = $1; }
free_expr_list_list ($2);
}
| cellref ':' cellref {
unregister_allocation ($3);
unregister_allocation ($1);
$$ = register_expr_allocation
(expr_tree_new_constant
(value_new_cellrange (&($1->u.ref), &($3->u.ref))));
expr_tree_unref ($3);
expr_tree_unref ($1);
}
| FUNCALL '(' arg_list ')' {
unregister_allocation ($3);
$$ = $1;
......@@ -387,25 +379,18 @@ exp: NUMBER { $$ = $1; }
}
;
cellref: CELLREF {
$$ = $1;
}
| STRING '!' CELLREF {
sheetref: STRING '!' {
Sheet *sheet = sheet_lookup_by_name (parser_wb, $1->u.constant->v.str->str);
/* TODO : Get rid of ParseErr and replace it with something richer. */
unregister_allocation ($3);
unregister_allocation ($1); expr_tree_unref ($1);
if (sheet == NULL) {
parser_error = PARSE_ERR_SYNTAX;
return ERROR;
}
$$ = $3;
$$->u.ref.sheet = sheet;
register_expr_allocation($$);
$$ = sheet;
}
| '[' STRING ']' STRING '!' CELLREF {
| '[' STRING ']' STRING '!' {
/* TODO : Get rid of ParseErr and replace it with something richer.
* The replace ment should include more detail as to what the error
* was, and where in the expr string to highlight.
......@@ -421,7 +406,6 @@ cellref: CELLREF {
if (wb != NULL)
sheet = sheet_lookup_by_name (wb, $4->u.constant->v.str->str);
unregister_allocation ($6);
unregister_allocation ($4); expr_tree_unref ($4);
unregister_allocation ($2); expr_tree_unref ($2);
if (sheet == NULL) {
......@@ -429,9 +413,46 @@ cellref: CELLREF {
parser_error = PARSE_ERR_SYNTAX;
return ERROR;
}
$$ = $6;
$$->u.ref.sheet = sheet;