Commit 84056a9a authored by Jody Goldberg's avatar Jody Goldberg

Updates to support VALUE_EMPTY, finish VALUE_BOOLEAN, VALUE_ERROR

Better approximation of excel operator handling.
parent 744b63eb
1999-08-01 Jody Goldberg <jgoldberg@home.com>
* samples/operator.xls : Test workbook for operators.
* src/Gnumeric.idl : Add VALUE_ERROR, VALUE_BOOLEAN, VALUE_EMPTY
in a few more places
* src/fn-lookup.c : Ditto.
* src/fn-math.c : Ditto.
* src/fn-stat.c : Ditto.
* src/fn-string.c : Ditto.
* src/dialog-cell-sort.c : Ditto.
* src/corba-sheet.c : Ditto.
* src/fn-eng.c : Support VALUE_BOOLEAN and simplify comparison logic in
DELTA and GESTEP.
* src/expr.c (compare_bool_bool) : New function.
(compare_int_int, compare_float_float) : Take (Value *) and do cast
internally.
(is_null_string) : Rename to value_is_empty_cell, support VALUE_EMPTY.
and move to src/value.c.
(compare) : Rework to bring into closer compliance with XL.
(expr_eval_real) : Ditto, replace 'Type [Mm]ismatch' with '#!VALUE'.
use eval_expr rather than eval_expr_real for arithmetic binary
operators. Use value_get_as_float rather than value_cast_to_float.
(eval_expr) : Remap 'VALUE_EMPTY' to int(0)
* src/value.h : Adjust enumeration so that BOOLEAN < INTEGER < FLOAT
remove value_cast_to_float
* src/value.c (value_get_as_*) : Support NULL values.
(value_cast_to_float) : Remove.
* src/sheet.c (sheet_cell_formula_unlink) : Add precondition to handle
problems using deleted cells.
1999-08-01 Morten Welinder <terra@diku.dk>
* src/fn-stat.c (gnumeric_covar, gnumeric_correl): Simplify using
......
......@@ -16,7 +16,7 @@ Michael:
Jody:
* Enable Array formulas.
* Add VALUE_BOOLEAN, VALUE_ERROR.
* Added EOMONTH, WORKDAY.
* Added EOMONTH, WORKDAY, NETWORKDAYS.
* Work on functions : ROW, COLUMN, ISLOGICAL, ISERR, ISBLANK,
DATEVALUE
* Support implict intersection 'feature' of XL for functions, not
......
1999-08-01 Jody Goldberg <jgoldberg@home.com>
* samples/operator.xls : Test workbook for operators.
* src/Gnumeric.idl : Add VALUE_ERROR, VALUE_BOOLEAN, VALUE_EMPTY
in a few more places
* src/fn-lookup.c : Ditto.
* src/fn-math.c : Ditto.
* src/fn-stat.c : Ditto.
* src/fn-string.c : Ditto.
* src/dialog-cell-sort.c : Ditto.
* src/corba-sheet.c : Ditto.
* src/fn-eng.c : Support VALUE_BOOLEAN and simplify comparison logic in
DELTA and GESTEP.
* src/expr.c (compare_bool_bool) : New function.
(compare_int_int, compare_float_float) : Take (Value *) and do cast
internally.
(is_null_string) : Rename to value_is_empty_cell, support VALUE_EMPTY.
and move to src/value.c.
(compare) : Rework to bring into closer compliance with XL.
(expr_eval_real) : Ditto, replace 'Type [Mm]ismatch' with '#!VALUE'.
use eval_expr rather than eval_expr_real for arithmetic binary
operators. Use value_get_as_float rather than value_cast_to_float.
(eval_expr) : Remap 'VALUE_EMPTY' to int(0)
* src/value.h : Adjust enumeration so that BOOLEAN < INTEGER < FLOAT
remove value_cast_to_float
* src/value.c (value_get_as_*) : Support NULL values.
(value_cast_to_float) : Remove.
* src/sheet.c (sheet_cell_formula_unlink) : Add precondition to handle
problems using deleted cells.
1999-08-01 Morten Welinder <terra@diku.dk>
* src/fn-stat.c (gnumeric_covar, gnumeric_correl): Simplify using
......
1999-07-30 Jody Goldberg <jgoldberg@home.com>
* ms-excel-read.c (ms_excel_read_error) : Delete
(ms_excel_read_cell) : Use VALUE_ERROR, and VALUE_EMPTY.
(ms_excel_read_selection) : Split out into seperate function.
* ms-formula-read.c (ms_excel_parse_formula,
make_function) : VALUE_ERROR.
1999-07-31 Morten Welinder <terra@diku.dk>
* ms-excel-read.c (ms_excel_read_formula): Kill warning that is no
......
......@@ -1537,8 +1537,7 @@ ms_excel_read_formula (BiffQuery *q, ExcelSheet *sheet)
dump (q->data+6, 8);
}
#endif
/* FIXME FIXME FIXME : This should be empty, not null string */
val = value_new_string ("");
val = value_new_empty ();
break;
default :
......@@ -1652,29 +1651,6 @@ ms_excel_sheet_new (ExcelWorkbook *wb, char *name)
return ans;
}
static void
ms_excel_read_error (BiffQuery *q, ExcelSheet *sheet)
{
ExprTree *e;
guint8 const val = MS_OLE_GET_GUINT8(q->data + 6);
Value *v = NULL;
guint16 const xf_index = EX_GETXF (q);
Cell *cell = sheet_cell_fetch (sheet->gnum_sheet,
EX_GETCOL (q), EX_GETROW (q));
char const *const err_str = biff_get_error_text (val);
v = value_new_string (err_str);
e = expr_tree_new_error (err_str);
sheet->blank = FALSE;
cell_set_formula_tree_simple (cell, e);
if (cell->value)
value_release (cell->value);
cell->value = v;
expr_tree_unref (e);
ms_excel_set_cell_xf (sheet, cell, xf_index);
}
static void
ms_excel_sheet_insert_val (ExcelSheet *sheet, int xfidx,
int col, int row, Value *v)
......@@ -2047,45 +2023,49 @@ static void
ms_excel_read_cell (BiffQuery *q, ExcelSheet *sheet)
{
switch (q->ls_op) {
case BIFF_BLANK: /*
* FIXME: Not a good way of doing blanks ?
*/
/*
* printf ("Cell [%d, %d] XF = %x\n", EX_GETCOL(q), EX_GETROW(q),
* EX_GETXF(q));
*/
ms_excel_sheet_insert (sheet, EX_GETXF (q), EX_GETCOL (q), EX_GETROW (q), 0);
case BIFF_BLANK:
#if 0
printf ("Cell [%d, %d] XF = %x\n", EX_GETCOL(q), EX_GETROW(q),
EX_GETXF(q));
#endif
ms_excel_sheet_insert_val (sheet, EX_GETXF (q),
EX_GETCOL (q), EX_GETROW (q),
value_new_empty());
break;
case BIFF_MULBLANK: /*
* S59DA7.HTM is extremely unclear, this is an educated guess
*/
{
if (q->opcode == BIFF_DV) {
printf ("Unimplemented DV: data validation criteria, FIXME\n");
break;
} else {
int row, col, lastcol;
int incr;
guint8 const *ptr;
/*
* dump (ptr, q->length);
*/
row = EX_GETROW (q);
col = EX_GETCOL (q);
ptr = (q->data + 4);
lastcol = MS_OLE_GET_GUINT16 (q->data + q->length - 2);
/* printf ("Cells in row %d are blank starting at col %d until col %d (0x%x)\n",
row, col, lastcol, lastcol); */
incr = (lastcol > col) ? 1 : -1;
while (col != lastcol) {
ms_excel_sheet_insert (sheet, MS_OLE_GET_GUINT16 (ptr), col, EX_GETROW (q), 0);
col += incr;
ptr += 2;
}
case BIFF_MULBLANK:
/* S59DA7.HTM is extremely unclear, this is an educated guess */
if (q->opcode == BIFF_DV) {
printf ("Unimplemented DV: data validation criteria, FIXME\n");
break;
} else {
int row, col, lastcol;
int incr;
guint8 const *ptr;
/*
* dump (ptr, q->length);
*/
row = EX_GETROW (q);
col = EX_GETCOL (q);
ptr = (q->data + 4);
lastcol = MS_OLE_GET_GUINT16 (q->data + q->length - 2);
#if 0
printf ("Cells in row %d are blank starting at col %d until col %d (0x%x)\n",
row, col, lastcol, lastcol);
#endif
incr = (lastcol > col) ? 1 : -1;
while (col != lastcol) {
ms_excel_sheet_insert_val (sheet,
MS_OLE_GET_GUINT16 (ptr),
col, EX_GETROW (q),
value_new_empty());
col += incr;
ptr += 2;
}
}
break;
case BIFF_RSTRING: /* See: S59DDC.HTM */
{
char *txt;
......@@ -2094,7 +2074,8 @@ ms_excel_read_cell (BiffQuery *q, ExcelSheet *sheet)
dump (q->data, q->length);
printf ("Rstring\n");
*/
ms_excel_sheet_insert (sheet, EX_GETXF (q), EX_GETCOL (q), EX_GETROW (q),
ms_excel_sheet_insert (sheet, EX_GETXF (q),
EX_GETCOL (q), EX_GETROW (q),
(txt = biff_get_text (q->data + 8, EX_GETSTRLEN (q), NULL)));
g_free (txt);
break;
......@@ -2259,15 +2240,17 @@ ms_excel_read_cell (BiffQuery *q, ExcelSheet *sheet)
case BIFF_BOOLERR: /* S59D5F.HTM */
{
Value *v;
guint8 const val = MS_OLE_GET_GUINT8(q->data + 6);
if (MS_OLE_GET_GUINT8(q->data + 7)) {
ms_excel_read_error (q, sheet);
} else {
/* Boolean */
Value *v;
v = value_new_bool (MS_OLE_GET_GUINT8(q->data + 6));
ms_excel_sheet_insert_val (sheet, EX_GETXF (q), EX_GETCOL (q),
EX_GETROW (q), v);
}
/* FIXME : Init EvalPos */
v = value_new_error (NULL,
biff_get_error_text (val));
} else
v = value_new_bool (val);
ms_excel_sheet_insert_val (sheet,
EX_GETXF (q), EX_GETCOL (q),
EX_GETROW (q), v);
break;
}
default:
......@@ -2277,6 +2260,56 @@ ms_excel_read_cell (BiffQuery *q, ExcelSheet *sheet)
}
}
/* S59DE2.HTM */
static void
ms_excel_read_selection (ExcelSheet *sheet, BiffQuery *q)
{
int const pane_number = MS_OLE_GET_GUINT8 (q->data);
int const act_row = MS_OLE_GET_GUINT16 (q->data + 1);
int const act_col = MS_OLE_GET_GUINT16 (q->data + 3);
int num_refs = MS_OLE_GET_GUINT16 (q->data + 7);
guint8 *refs;
#ifndef NO_DEBUG_EXCEL
if (ms_excel_read_debug > 1) {
printf ("Start selection\n");
if (ms_excel_read_debug > 6)
printf ("Cursor : %d %d\n", act_col, act_row);
}
#endif
if (pane_number != 3) {
printf ("FIXME: no pane support\n");
return;
}
sheet_selection_reset_only (sheet->gnum_sheet);
for (refs = q->data + 9; num_refs > 0; refs += 6, num_refs--) {
int const start_row = MS_OLE_GET_GUINT16(refs + 0);
int const start_col = MS_OLE_GET_GUINT8(refs + 4);
int const end_row = MS_OLE_GET_GUINT16(refs + 2);
int const end_col = MS_OLE_GET_GUINT8(refs + 5);
#ifndef NO_DEBUG_EXCEL
if (ms_excel_read_debug > 6)
printf ("Ref %d = %d %d %d %d\n", num_refs,
start_col, start_row, end_col, end_row);
#endif
/* FIXME : This should not trigger a recalc */
sheet_selection_append_range (sheet->gnum_sheet,
start_col, start_row,
start_col, start_row,
end_col, end_row);
}
sheet_cursor_set (sheet->gnum_sheet,
act_col, act_row, act_col, act_row, act_col, act_row);
#ifndef NO_DEBUG_EXCEL
if (ms_excel_read_debug > 1) {
printf ("Done selection\n");
}
#endif
}
static void
ms_excel_read_sheet (ExcelSheet *sheet, BiffQuery *q, ExcelWorkbook *wb)
{
......@@ -2317,49 +2350,9 @@ ms_excel_read_sheet (ExcelSheet *sheet, BiffQuery *q, ExcelWorkbook *wb)
ms_obj_read_obj (q, wb);
break;
case BIFF_SELECTION: /* S59DE2.HTM */
{
int pane_number;
int act_row, act_col;
int num_refs;
guint8 *refs;
#ifndef NO_DEBUG_EXCEL
if (ms_excel_read_debug > 1) {
printf ("Start selection\n");
}
#endif
pane_number = MS_OLE_GET_GUINT8 (q->data);
act_row = MS_OLE_GET_GUINT16 (q->data + 1);
act_col = MS_OLE_GET_GUINT16 (q->data + 3);
num_refs = MS_OLE_GET_GUINT16 (q->data + 7);
refs = q->data + 9;
/* printf ("Cursor : %d %d\n", act_col, act_row); */
if (pane_number != 3) {
printf ("FIXME: no pane support\n");
break;
}
sheet_selection_reset_only (sheet->gnum_sheet);
while (num_refs>0) {
int start_row = MS_OLE_GET_GUINT16(refs + 0);
int start_col = MS_OLE_GET_GUINT8(refs + 4);
int end_row = MS_OLE_GET_GUINT16(refs + 2);
int end_col = MS_OLE_GET_GUINT8(refs + 5);
/* printf ("Ref %d = %d %d %d %d\n", num_refs, start_col, start_row, end_col, end_row); */
sheet_selection_append_range (sheet->gnum_sheet, start_col, start_row,
start_col, start_row,
end_col, end_row);
refs+=6;
num_refs--;
}
sheet_cursor_set (sheet->gnum_sheet, act_col, act_row, act_col, act_row, act_col, act_row);
#ifndef NO_DEBUG_EXCEL
if (ms_excel_read_debug > 1) {
printf ("Done selection\n");
}
#endif
break;
}
case BIFF_SELECTION:
ms_excel_read_selection (sheet, q);
break;
case BIFF_MS_O_DRAWING:
case BIFF_MS_O_DRAWING_GROUP:
......@@ -2471,13 +2464,6 @@ ms_excel_read_sheet (ExcelSheet *sheet, BiffQuery *q, ExcelWorkbook *wb)
default:
switch (q->opcode) {
case BIFF_STRING :
/* FIXME FIXME FIXME */
/* this should not happen. Need to check the
* shared formula handling to see how to deal
* with this */
break;
case BIFF_CODENAME :
break;
......
......@@ -685,8 +685,9 @@ make_function (ParseList **stack, int fn_idx, int numargs)
tmp->u.constant->type != VALUE_STRING) {
if (tmp) expr_tree_unref (tmp);
parse_list_free (&args);
parse_list_push (stack,
expr_tree_new_error (_("Broken function")));
parse_list_push_raw (stack,
value_new_error (NULL,
_("Broken function")));
printf ("So much for that theory.\n");
return FALSE;
}
......@@ -736,7 +737,7 @@ make_function (ParseList **stack, int fn_idx, int numargs)
txt = g_strdup_printf ("[Function '%s']",
fd->prefix?fd->prefix:"?");
printf ("Unknown %s\n", txt);
parse_list_push (stack, expr_tree_new_error (txt));
parse_list_push_raw (stack, value_new_error (NULL, txt));
g_free (txt);
parse_list_free (&args);
......@@ -1242,9 +1243,7 @@ ms_excel_parse_formula (ExcelWorkbook *wb, ExcelSheet *sheet, guint8 const *mem,
return NULL; /* To tell name stuff */
}
errtxt = biff_get_error_text (err_num);
/* FIXME: we do not have errors as first-class values, so we
must build an expression that generates the error. */
parse_list_push (&stack, expr_tree_new_error (errtxt));
parse_list_push_raw (&stack, value_new_error (NULL, errtxt));
ptg_length = 1 ;
break ;
}
......
......@@ -40,6 +40,7 @@ get_date (const Value *v)
return (serial > 0.0) ? g_date_new_serial (serial) : NULL;
}
static float_t
get_serial_time (Value *v)
{
......@@ -381,8 +382,8 @@ gnumeric_year (FunctionEvalInfo *ei, Value **argv)
int res = 1900;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = g_date_year (date);
g_date_free (date);
res = g_date_year (date);
g_date_free (date);
}
return value_new_int (res);
}
......@@ -408,8 +409,8 @@ gnumeric_month (FunctionEvalInfo *ei, Value **argv)
int res = 1;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = g_date_month (date);
g_date_free (date);
res = g_date_month (date);
g_date_free (date);
}
return value_new_int (res);
}
......@@ -435,8 +436,8 @@ gnumeric_day (FunctionEvalInfo *ei, Value **argv)
int res = 1;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = g_date_day (date);
g_date_free (date);
res = g_date_day (date);
g_date_free (date);
}
return value_new_int (res);
}
......@@ -462,8 +463,8 @@ gnumeric_weekday (FunctionEvalInfo *ei, Value **argv)
int res = 1;
GDate *date = get_date (argv[0]);
if (date != NULL) {
res = (g_date_weekday (date) + 1) % 7;
g_date_free (date);
res = (g_date_weekday (date) + 1) % 7;
g_date_free (date);
}
return value_new_int (res);
}
......@@ -634,6 +635,9 @@ gnumeric_workday (FunctionEvalInfo *ei, Value **argv)
days = value_get_as_int (argv[1]);
if (argv[2] != NULL)
return value_new_error (&ei->pos, _("Unimplemented"));
/* FIXME : How to deal with starting dates that are weekends
* or holidays ?? */
for (; days < 0 ; ++days) {
......@@ -680,9 +684,12 @@ static char * help_networkdays = {
"@SEEALSO=WORKDAY")
};
/* A utility routine to return the 1st weekend >= the serial if its valid */
/*
* A utility routine to return the 1st monday <= the serial if its valid
* Returns -1 on error
*/
static int
get_serial_weekday (Value const * v)
get_serial_weekday (Value const * v, int * offset)
{
GDate * date;
int serial = get_serial_date (v);
......@@ -690,12 +697,11 @@ get_serial_weekday (Value const * v)
return serial;
date = g_date_new_serial (serial);
if (g_date_valid(date)) {
GDateWeekday weekday = g_date_weekday(date);
if (weekday == G_DATE_SATURDAY)
serial += 2;
else if (weekday == G_DATE_SUNDAY)
serial += 1;
}
/* Jan 1 1900 was a monday so we won't go < 0 */
*offset = (int)g_date_weekday(date) - 1;
serial -= *offset;
} else
serial = -1;
g_date_free (date);
return serial;
}
......@@ -703,25 +709,32 @@ get_serial_weekday (Value const * v)
static Value *
gnumeric_networkdays (FunctionEvalInfo *ei, Value **argv)
{
int start_serial = get_serial_weekday (argv[0]);
int end_serial = get_serial_weekday (argv[1]);
int start_offset, end_offset;
int start_serial = get_serial_weekday (argv[0], &start_offset);
int end_serial = get_serial_weekday (argv[1], &end_offset);
int res, mult = 1;
/* Dummy out for now */
return value_new_error (&ei->pos, _("Unimplemented"));
if (argv[2] != NULL)
return value_new_error (&ei->pos, _("Unimplemented"));
if (start_serial < 0 || end_serial < 0)
return value_new_error (&ei->pos, gnumeric_err_NUM);
return value_new_error (&ei->pos, "We're working on it");
res = end_serial - start_serial;
if (res < 0) {
res = -res;
mult = -1;
}
/* FIXME : Remove weekends */
/* Remove weekends */
res -= ((res/7)*2);
return value_new_int (res*mult);
/* FIXME : Remove holidays */
return value_new_int (res*mult - start_offset + end_offset);
}
/***************************************************************************/
......
......@@ -70,9 +70,16 @@ val_to_base (FunctionEvalInfo *ei, Value **argv, int num_argv,
places = 0;
switch (value->type){
case VALUE_ERROR :
return value_duplicate(value);
case VALUE_STRING:
str = value->v.str->str;
break;
case VALUE_BOOLEAN :
snprintf (buffer, sizeof (buffer)-1, "%d", value->v.v_bool?1:0);
str = buffer;
break;
case VALUE_INTEGER:
snprintf (buffer, sizeof (buffer)-1, "%d", value->v.v_int);
str = buffer;
......@@ -81,6 +88,7 @@ val_to_base (FunctionEvalInfo *ei, Value **argv, int num_argv,
snprintf (buffer, sizeof (buffer)-1, "%8.0f", value->v.v_float);
str = buffer;
break;
case VALUE_EMPTY:
default:
return value_new_error (&ei->pos, gnumeric_err_NUM);
}
......@@ -1514,7 +1522,8 @@ static char *help_delta = {
static Value *
gnumeric_delta (FunctionEvalInfo *ei, Value **argv)
{
int ans = 0;
Value *err = NULL;
gboolean ans;
Value *vx, *vy;
vx = argv[0];
......@@ -1523,49 +1532,27 @@ gnumeric_delta (FunctionEvalInfo *ei, Value **argv)
else
vy = value_new_int (0);
switch (vx->type)
/* Promote to the largest value */
switch ((vx->type > vy->type) ? vx->type : vy->type)
{
case VALUE_BOOLEAN:
/* Only happens when both are bool */
ans = vx->v.v_bool == vy->v.v_bool;
break;
case VALUE_EMPTY:
case VALUE_INTEGER:
switch (vy->type)
{
case VALUE_INTEGER:
if (vx->v.v_int == vy->v.v_int)
ans = 1;
break;
case VALUE_FLOAT:
if (vy->v.v_float == (float_t)vx->v.v_int)
ans = 1;
break;
default:
return value_new_error (&ei->pos, _("Impossible"));
return NULL;
}
ans = value_get_as_int(vx) == value_get_as_int(vy);
break;
case VALUE_FLOAT:
switch (vy->type)
{
case VALUE_INTEGER:
if (vx->v.v_float == (float_t)vy->v.v_int)
ans = 1;
break;
case VALUE_FLOAT:
if (vy->v.v_float == vx->v.v_float)
ans = 1;
break;
default:
return value_new_error (&ei->pos, _("Impossible"));
return NULL;
}
ans = value_get_as_float(vx) == value_get_as_float(vy);
break;
default:
return value_new_error (&ei->pos, _("Impossible"));
return NULL;
err = value_new_error (&ei->pos, _("Impossible"));
}
if (!argv[1])
value_release (vy);
return value_new_int (ans);
return (err != NULL) ? err : value_new_int (ans ? 1 : 0);
}
static char *help_gestep = {
......@@ -1586,7 +1573,8 @@ static char *help_gestep = {
static Value *
gnumeric_gestep (FunctionEvalInfo *ei, Value **argv)
{
int ans = 0;
Value *err = NULL;
gboolean ans;
Value *vx, *vy;
vx = argv[0];
......@@ -1595,46 +1583,27 @@ gnumeric_gestep (FunctionEvalInfo *ei, Value **argv)
else
vy = value_new_int (0);
switch (vx->type)
/* Promote to the largest value */
switch ((vx->type > vy->type) ? vx->type : vy->type)
{
case VALUE_BOOLEAN:
/* Only happens when both are bool */
ans = vx->v.v_bool >= vy->v.v_bool;
break;
case VALUE_EMPTY:
case VALUE_INTEGER:
switch (vy->type)
{
case VALUE_INTEGER:
if (vx->v.v_int >= vy->v.v_int)
ans = 1;
break;
case VALUE_FLOAT:
if (vy->v.v_float < (float_t)vx->v.v_int)
ans = 1;
break;
default:
return value_new_error (&ei->pos, _("Impossible"));
}
ans = value_get_as_int(vx) >= value_get_as_int(vy);
break;
case VALUE_FLOAT:
switch (vy->type)
{
case VALUE_INTEGER:
if (vx->v.v_float >= (float_t)vy->v.v_int)
ans = 1;
break;
case VALUE_FLOAT:
if (vy->v.v_float < vx->v.v_float)
ans = 1;
break;
default:
return value_new_error (&ei->pos, _("Impossible"));
}
ans = value_get_as_float(vx) >= value_get_as_float(vy);
break;
default:
return value_new_error (&ei->pos, _("Impossible"));
return NULL;
err = value_new_error (&ei->pos, _("Impossible"));
}
if (!argv[1])
value_release (vy);
return value_new_int (ans);
return (err != NULL) ? err : value_new_int (ans ? 1 : 0);
}
void eng_functions_init()
......
......@@ -50,6 +50,7 @@ get_value_class (FunctionEvalInfo *ei, ExprTree *expr)
case VALUE_ARRAY:
res = VALUE_CLASS_ARRAY;
break;
case VALUE_EMPTY:
default:
res = VALUE_CLASS_BOGUS;
break;
......
......@@ -160,7 +160,7 @@ gnumeric_if (FunctionEvalInfo *ei, GList *expr_node_list)