expr.c 40.9 KB
Newer Older
Miguel de Icaza's avatar
Miguel de Icaza committed
1 2 3 4 5 6
/*
 * expr.c: Expression evaluation in Gnumeriuc
 *
 * Author:
 *   Miguel de Icaza (miguel@gnu.org).
 */
7
#include <config.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
8
#include <gnome.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
9
#include <math.h>
10
#include <string.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
11
#include "gnumeric.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
12
#include "expr.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
13
#include "eval.h"
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
14
#include "format.h"
15
#include "func.h"
16
#include "utils.h"
17

18 19
Value *value_zero = NULL;

20
ExprTree *
21 22
expr_parse_string (const char *expr, Sheet *sheet, int col, int row,
		   const char **desired_format, char **error_msg)
23
{
24
	ExprTree *tree;
25
	g_return_val_if_fail (expr != NULL, NULL);
26 27

	switch (gnumeric_expr_parser (expr, sheet, col, row, desired_format, &tree)) {
28 29
	case PARSE_OK:
		*error_msg = NULL;
30 31
		tree->ref_count = 1;
		return tree;
32

Arturo Espinosa's avatar
Arturo Espinosa committed
33 34 35
	case PARSE_ERR_SYNTAX:
		*error_msg = _("Syntax error");
		break;
36

37 38 39
	case PARSE_ERR_NO_QUOTE:
		*error_msg = _("Missing quote");
		break;
40
	default:
Arturo Espinosa's avatar
Arturo Espinosa committed
41 42 43
		g_assert_not_reached ();
		*error_msg = _("Impossible!");
		break;
44
	}
45 46 47
	return NULL;
}

48

49
ExprTree *
Morten Welinder's avatar
Morten Welinder committed
50
expr_tree_new (void)
51
{
52 53 54 55 56 57
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
	if (!ans)
		return NULL;
	
58 59 60 61 62 63
	ans->ref_count = 1;
	ans->oper = OPER_CONSTANT;
	ans->u.constant = NULL;
	return ans;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
64 65 66 67
/*
 * expr_tree_ref:
 * Increments the ref_count for part of a tree
 */
68 69 70 71 72 73
void
expr_tree_ref (ExprTree *tree)
{
	g_return_if_fail (tree != NULL);
	g_return_if_fail (tree->ref_count > 0);

Morten Welinder's avatar
Morten Welinder committed
74
	tree->ref_count++;
Arturo Espinosa's avatar
Arturo Espinosa committed
75 76 77 78 79
}

static void
do_expr_tree_unref (ExprTree *tree)
{
Morten Welinder's avatar
Morten Welinder committed
80 81 82
	if (--tree->ref_count > 0)
		return;

Arturo Espinosa's avatar
Arturo Espinosa committed
83
	switch (tree->oper){
84
	case OPER_VAR:
Arturo Espinosa's avatar
Arturo Espinosa committed
85
		break;
86

87
	case OPER_CONSTANT:
Morten Welinder's avatar
Morten Welinder committed
88
		value_release (tree->u.constant);
Arturo Espinosa's avatar
Arturo Espinosa committed
89
		break;
90

Morten Welinder's avatar
Morten Welinder committed
91 92 93 94 95 96 97
	case OPER_FUNCALL: {
		GList *l;

		for (l = tree->u.function.arg_list; l; l = l->next)
			do_expr_tree_unref (l->data);
		g_list_free (tree->u.function.arg_list);
		symbol_unref (tree->u.function.symbol);
Arturo Espinosa's avatar
Arturo Espinosa committed
98
		break;
Morten Welinder's avatar
Morten Welinder committed
99
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
100

101
	case OPER_ANY_BINARY:
Arturo Espinosa's avatar
Arturo Espinosa committed
102 103 104 105
		do_expr_tree_unref (tree->u.binary.value_a);
		do_expr_tree_unref (tree->u.binary.value_b);
		break;

106
	case OPER_ANY_UNARY:
Arturo Espinosa's avatar
Arturo Espinosa committed
107 108
		do_expr_tree_unref (tree->u.value);
		break;
109 110 111
	default:
		g_warning ("do_expr_tree_unref error\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
112
	}
113

Morten Welinder's avatar
Morten Welinder committed
114
	g_free (tree);
115 116
}

Morten Welinder's avatar
Morten Welinder committed
117 118 119 120 121 122
/*
 * expr_tree_unref:
 * Decrements the ref_count for part of a tree.  (All trees are expected
 * to have been created with a ref-count of one, so when we hit zero, we
 * go down over the tree and unref the tree and its leaves stuff.)
 */
123 124 125 126 127 128
void
expr_tree_unref (ExprTree *tree)
{
	g_return_if_fail (tree != NULL);
	g_return_if_fail (tree->ref_count > 0);

Arturo Espinosa's avatar
Arturo Espinosa committed
129
	do_expr_tree_unref (tree);
130 131
}

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
132 133 134 135
/*
 * simplistic value rendering
 */
char *
Michael Meeks's avatar
Michael Meeks committed
136
value_get_as_string (const Value *value)
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
137 138 139 140 141 142
{
	switch (value->type){
	case VALUE_STRING:
		return g_strdup (value->v.str->str);

	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
143
		return g_strdup_printf ("%d", value->v.v_int);
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
144 145

	case VALUE_FLOAT:
Arturo Espinosa's avatar
Arturo Espinosa committed
146
		return g_strdup_printf ("%g", value->v.v_float);
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
147

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
	case VALUE_ARRAY: {
		GString *str = g_string_new ("{");
		guint lpx, lpy;
		char *ans;

		for (lpy=0;lpy<value->v.array.y;lpy++) {
			for (lpx=0;lpx<value->v.array.x;lpx++) {
				const Value *v = value->v.array.vals[lpx][lpy];
				g_return_val_if_fail (v->type == VALUE_STRING ||
						      v->type == VALUE_FLOAT ||
						      v->type == VALUE_INTEGER,
						      "Duff Array contents");
				if (lpx)
					g_string_sprintfa (str, ",");
				if (v->type == VALUE_STRING)
					g_string_sprintfa (str, "\"%s\"",
							   v->v.str->str);
				else
					g_string_sprintfa (str, "%g",
							   value_get_as_float (v));
			}
			if (lpy<value->v.array.y-1)
				g_string_sprintfa (str, ";");
		}
		g_string_sprintfa (str, "}");
		ans = str->str;
		g_string_free (str, FALSE);
		return ans;
	}
177

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
178
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
179
		break;
180 181 182
	default:
		g_warning ("value_string problem\n");
		break;
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
183
	}
184

Arturo Espinosa's avatar
Arturo Espinosa committed
185
	return g_strdup ("Internal problem");
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
186 187
}

188 189 190
void
value_release (Value *value)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
191
	g_return_if_fail (value != NULL);
192

193 194 195 196 197 198 199
	switch (value->type){
	case VALUE_STRING:
		string_unref (value->v.str);
		break;

	case VALUE_INTEGER:
		mpz_clear (value->v.v_int);
200
		break;
201

202 203 204 205
	case VALUE_FLOAT:
		mpf_clear (value->v.v_float);
		break;

206
	case VALUE_ARRAY:{
207
		guint lpx, lpy;
208

209 210 211 212 213
		for (lpx = 0; lpx < value->v.array.x; lpx++) {
			for (lpy = 0; lpy < value->v.array.y; lpy++)
				value_release (value->v.array.vals[lpx][lpy]);
			g_free (value->v.array.vals [lpx]);
		}
214

215
		g_free (value->v.array.vals);
Morten Welinder's avatar
Morten Welinder committed
216
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
217
	}
218

Arturo Espinosa's avatar
Arturo Espinosa committed
219 220
	case VALUE_CELLRANGE:
		break;
221

222 223 224
	default:
		g_warning ("value_release problem\n");
		break;
225
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
226
	g_free (value);
227
}
228

Arturo Espinosa's avatar
Arturo Espinosa committed
229 230 231 232
/*
 * Copies a Value.
 */
void
233
value_copy_to (Value *dest, const Value *source)
Arturo Espinosa's avatar
Arturo Espinosa committed
234 235 236 237 238
{
	g_return_if_fail (dest != NULL);
	g_return_if_fail (source != NULL);

	dest->type = source->type;
239

Arturo Espinosa's avatar
Arturo Espinosa committed
240 241 242 243 244 245 246 247 248 249 250 251 252 253
	switch (source->type){
	case VALUE_STRING:
		dest->v.str = source->v.str;
		string_ref (dest->v.str);
		break;

	case VALUE_INTEGER:
		dest->v.v_int = source->v.v_int;
		break;

	case VALUE_FLOAT:
		dest->v.v_float = source->v.v_float;
		break;

Arturo Espinosa's avatar
Arturo Espinosa committed
254
	case VALUE_ARRAY: {
255
		value_array_copy_to (dest, source);
Arturo Espinosa's avatar
Arturo Espinosa committed
256 257 258 259 260
		break;
	}
	case VALUE_CELLRANGE:
		dest->v.cell_range = source->v.cell_range;
		break;
261 262 263
	default:
		g_warning ("value_copy_to problem\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
264 265 266
	}
}

Arturo Espinosa's avatar
Arturo Espinosa committed
267 268 269 270
/*
 * Makes a copy of a Value
 */
Value *
271
value_duplicate (const Value *value)
Arturo Espinosa's avatar
Arturo Espinosa committed
272 273 274 275 276 277
{
	Value *new_value;

	g_return_val_if_fail (value != NULL, NULL);
	new_value = g_new (Value, 1);
	value_copy_to (new_value, value);
278

Arturo Espinosa's avatar
Arturo Espinosa committed
279 280 281
	return new_value;
}

282
Value *
Michael Meeks's avatar
Michael Meeks committed
283
value_new_float (float_t f)
284 285 286 287 288 289 290 291 292 293
{
	Value *v = g_new (Value, 1);

	v->type = VALUE_FLOAT;
	v->v.v_float = f;

	return v;
}

Value *
Michael Meeks's avatar
Michael Meeks committed
294
value_new_int (int i)
295 296 297 298 299 300 301 302 303
{
	Value *v = g_new (Value, 1);

	v->type = VALUE_INTEGER;
	v->v.v_int = i;

	return v;
}

304
Value *
Michael Meeks's avatar
Michael Meeks committed
305
value_new_string (const char *str)
306 307 308 309 310 311 312 313 314
{
	Value *v = g_new (Value, 1);

	v->type = VALUE_STRING;
	v->v.str = string_get (str);

	return v;
}

315
Value *
Michael Meeks's avatar
Michael Meeks committed
316
value_new_cellrange (const CellRef *a, const CellRef *b)
317 318
{
	Value *v = g_new (Value, 1);
Morten Welinder's avatar
Morten Welinder committed
319

320
	v->type = VALUE_CELLRANGE;
Morten Welinder's avatar
Morten Welinder committed
321 322 323
	v->v.cell_range.cell_a = *a;
	v->v.cell_range.cell_b = *b;

324 325 326
	return v;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
327 328 329 330
/*
 * Casts a value to float if it is integer, and returns
 * a new Value * if required
 */
331
Value *
332
value_cast_to_float (Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
333 334
{
	Value *newv;
335

Arturo Espinosa's avatar
Arturo Espinosa committed
336 337 338 339
	g_return_val_if_fail (VALUE_IS_NUMBER (v), NULL);

	if (v->type == VALUE_FLOAT)
		return v;
340

Arturo Espinosa's avatar
Arturo Espinosa committed
341 342 343
	newv = g_new (Value, 1);
	newv->type = VALUE_FLOAT;
	mpf_set_z (newv->v.v_float, v->v.v_int);
344
	value_release (v);
345

Arturo Espinosa's avatar
Arturo Espinosa committed
346 347 348
	return newv;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
349
int
Michael Meeks's avatar
Michael Meeks committed
350
value_get_as_bool (const Value *v, int *err)
Arturo Espinosa's avatar
Arturo Espinosa committed
351 352 353
{
	*err = 0;

354 355
	switch (v->type) {
	case VALUE_STRING:
Arturo Espinosa's avatar
Arturo Espinosa committed
356 357
		return atoi (v->v.str->str);

358
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
359 360
		*err = 1;
		return 0;
361 362
		
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
363 364
		return v->v.v_int != 0;

365
	case VALUE_FLOAT:
Arturo Espinosa's avatar
Arturo Espinosa committed
366 367
		return v->v.v_float != 0.0;

368
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
369
		return 0;
370 371 372 373
	default:
		g_warning ("Unhandled value in value_get_boolean");
		break;
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
374 375 376
	return 0;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
377
float_t
Michael Meeks's avatar
Michael Meeks committed
378
value_get_as_float (const Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
379
{
380 381 382
	switch (v->type)
	{
	case VALUE_STRING:
Arturo Espinosa's avatar
Arturo Espinosa committed
383 384
		return atof (v->v.str->str);

385
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
386 387 388
		g_warning ("Getting range as a double: what to do?");
		return 0.0;

389
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
390
		return (float_t) v->v.v_int;
391 392
		
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
393
		return 0.0;
394

395 396 397
	case VALUE_FLOAT:
		return (float_t) v->v.v_float;
	default:
Michael Meeks's avatar
Michael Meeks committed
398
		g_warning ("value_get_as_float type error\n");
399 400 401
		break;
	}
	return 0.0;
Arturo Espinosa's avatar
Arturo Espinosa committed
402 403
}

404
int
405
value_get_as_int (const Value *v)
406
{
407 408 409
	switch (v->type)
	{
	case VALUE_STRING:
410 411
		return atoi (v->v.str->str);

412
	case VALUE_CELLRANGE:
413 414 415
		g_warning ("Getting range as a double: what to do?");
		return 0.0;

416
	case VALUE_INTEGER:
417 418
		return v->v.v_int;

419
	case VALUE_ARRAY:
420
		return 0.0;
421

422 423 424 425 426 427
	case VALUE_FLOAT:
		return (int) v->v.v_float;
	default:
		g_warning ("value_get_as_int unknown type\n");
		break;
	}
Michael Meeks's avatar
Michael Meeks committed
428
	return 0.0;
429 430
}

431 432 433
Value *
value_array_new (guint width, guint height)
{
434
	int x, y;
435 436 437 438 439

	Value *v = g_new (Value, 1);
	v->type = VALUE_ARRAY;
	v->v.array.x = width;
	v->v.array.y = height;
440
	v->v.array.vals = g_new (Value **, width);
441 442

	for (x = 0; x < width; x++){
443 444 445
		v->v.array.vals [x] = g_new (Value *, height);
		for (y = 0; y < height; y++)
			v->v.array.vals[x][y] = value_new_int (0);
446 447 448 449
	}
	return v;
}

Michael Meeks's avatar
Michael Meeks committed
450 451 452 453
void
value_array_set (Value *array, guint col, guint row, Value *v)
{
	g_return_if_fail (v);
454
	g_return_if_fail (array->type == VALUE_ARRAY);
Michael Meeks's avatar
Michael Meeks committed
455 456
	g_return_if_fail (col>=0);
	g_return_if_fail (row>=0);
457 458
	g_return_if_fail (array->v.array.y > row);
	g_return_if_fail (array->v.array.x > col);
Michael Meeks's avatar
Michael Meeks committed
459

460 461 462
	if (array->v.array.vals[col][row])
		value_release (array->v.array.vals[col][row]);
	array->v.array.vals[col][row] = v;
Michael Meeks's avatar
Michael Meeks committed
463 464
}

465 466 467
void
value_array_resize (Value *v, guint width, guint height)
{
468
	int x, y, xcpy, ycpy;
469
	Value *newval;
470
	Value ***tmp;
471 472 473 474 475 476 477 478 479

	g_return_if_fail (v);
	g_return_if_fail (v->type == VALUE_ARRAY);

	newval = value_array_new (width, height);

	if (width>v->v.array.x)
		xcpy = v->v.array.x;
	else
480
		xcpy = width;
481 482 483 484 485 486

	if (height>v->v.array.y)
		ycpy = v->v.array.y;
	else
		ycpy = height;

487 488 489 490 491
	for (x = 0; x < xcpy; x++)
		for (y = 0; y < ycpy; y++)
			value_array_set (newval, x, y, v->v.array.vals[x][y]);

	tmp = v->v.array.vals;
492
	v->v.array.vals = newval->v.array.vals;
493 494 495
	newval->v.array.vals = tmp ;
	value_release (newval);

496 497 498 499 500 501 502
	v->v.array.x = width;
	v->v.array.y = height;
}

void
value_array_copy_to (Value *v, const Value *src)
{
503
	int x, y;
504 505 506 507 508

	g_return_if_fail (src->type == VALUE_ARRAY);
	v->type = VALUE_ARRAY;
	v->v.array.x = src->v.array.x;
	v->v.array.y = src->v.array.y;
509
	v->v.array.vals = g_new (Value **, v->v.array.x);
510

511 512 513 514
	for (x = 0; x < v->v.array.x; x++) {
		v->v.array.vals [x] = g_new (Value *, v->v.array.y);
		for (y = 0; y < v->v.array.y; y++)
			v->v.array.vals [x][y] = value_duplicate (src->v.array.vals [x][y]);
515 516 517 518 519 520 521 522 523
	}
}

guint
value_area_get_width (Value *v)
{
	g_return_val_if_fail (v, 0);
	g_return_val_if_fail (v->type == VALUE_ARRAY ||
			      v->type == VALUE_CELLRANGE, 1);
524

525 526
	if (v->type == VALUE_ARRAY)
		return v->v.array.x;
527 528 529 530 531 532 533 534
	else {
		guint ans = v->v.cell_range.cell_b.col -
			    v->v.cell_range.cell_a.col + 1;
		if (v->v.cell_range.cell_a.sheet && 
		    v->v.cell_range.cell_a.sheet->max_col_used < ans)
			ans = v->v.cell_range.cell_a.sheet->max_col_used+1;
		return ans;
	}
535 536 537 538 539 540 541 542
}

guint
value_area_get_height (Value *v)
{
	g_return_val_if_fail (v, 0);
	g_return_val_if_fail (v->type == VALUE_ARRAY ||
			      v->type == VALUE_CELLRANGE, 1);
543

544 545
	if (v->type == VALUE_ARRAY)
		return v->v.array.y;
546 547 548 549 550 551 552 553
	else {
		guint ans = v->v.cell_range.cell_b.row -
		            v->v.cell_range.cell_a.row + 1;
		if (v->v.cell_range.cell_a.sheet && 
		    v->v.cell_range.cell_a.sheet->max_row_used < ans)
			ans = v->v.cell_range.cell_a.sheet->max_row_used+1;
		return ans;
	}
554 555 556 557 558 559 560 561
}

const Value *
value_area_get_at_x_y (Value *v, guint x, guint y)
{
	g_return_val_if_fail (v, 0);
	g_return_val_if_fail (v->type == VALUE_ARRAY ||
			      v->type == VALUE_CELLRANGE,
Michael Meeks's avatar
Michael Meeks committed
562
			     value_new_int (0));
563 564

	if (v->type == VALUE_ARRAY){
565
		g_return_val_if_fail (v->v.array.x < x &&
566
				      v->v.array.y < y,
Michael Meeks's avatar
Michael Meeks committed
567
				     value_new_int (0));
568
		return v->v.array.vals [x][y];
569 570 571
	} else {
		CellRef *a, *b;
		Cell *cell;
572

573 574
		a = &v->v.cell_range.cell_a;
		b = &v->v.cell_range.cell_b;
575 576 577 578 579 580 581 582 583 584 585
		g_return_val_if_fail (!a->col_relative, value_zero);
		g_return_val_if_fail (!b->col_relative, value_zero);
		g_return_val_if_fail (!a->row_relative, value_zero);
		g_return_val_if_fail (!b->row_relative, value_zero);
		g_return_val_if_fail (a->col<=b->col, value_zero);
		g_return_val_if_fail (a->row<=b->row, value_zero);

		/* Speedup */
		if (a->sheet->max_col_used < a->col+x ||
		    a->sheet->max_row_used < a->row+y)
			return value_zero;
586

587
		cell = sheet_cell_get (a->sheet, a->col+x, a->row+y);
588

589 590 591
		if (cell && cell->value)
			return cell->value;
	}
Michael Meeks's avatar
Michael Meeks committed
592
	
593
	return value_zero;
594 595
}

596 597 598 599 600 601
static void
cell_ref_make_absolute (CellRef *cell_ref, int eval_col, int eval_row)
{
	g_return_if_fail (cell_ref != NULL);

	if (cell_ref->col_relative)
602
		cell_ref->col = eval_col + cell_ref->col;
603 604 605

	if (cell_ref->row_relative)
		cell_ref->row = eval_row + cell_ref->row;
606

Arturo Espinosa's avatar
Arturo Espinosa committed
607 608
	cell_ref->row_relative = 0;
	cell_ref->col_relative = 0;
609 610
}

611 612 613 614 615 616 617 618 619 620 621 622 623 624
static void
cell_ref_restore_absolute (CellRef *cell_ref, const CellRef *orig, int eval_col, int eval_row)
{
	if (orig->col_relative) {
		cell_ref->col -= eval_col;
		cell_ref->col_relative = 1;
	}

	if (orig->row_relative) {
		cell_ref->row -= eval_row;
		cell_ref->row_relative = 1;
	}
}

Arturo Espinosa's avatar
Arturo Espinosa committed
625 626
static Value *
eval_cell_value (Sheet *sheet, Value *value)
627
{
Arturo Espinosa's avatar
Arturo Espinosa committed
628
	Value *res;
629

Arturo Espinosa's avatar
Arturo Espinosa committed
630 631
	res = g_new (Value, 1);
	res->type = value->type;
632

Arturo Espinosa's avatar
Arturo Espinosa committed
633 634 635
	switch (res->type){
	case VALUE_STRING:
		res->v.str = value->v.str;
636
		string_ref (res->v.str);
Arturo Espinosa's avatar
Arturo Espinosa committed
637
		break;
638

Arturo Espinosa's avatar
Arturo Espinosa committed
639
	case VALUE_INTEGER:
640
		res->v.v_int = value->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
641
		break;
642

Arturo Espinosa's avatar
Arturo Espinosa committed
643
	case VALUE_FLOAT:
644
		res->v.v_float = value->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
645
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
646 647

	case VALUE_ARRAY:
648 649 650
		g_warning ("Check VALUE_ARRAY handling in eval_cell_value vs. Excel\n");
		/* Return top left corner... */
		res = value_duplicate (value->v.array.vals[0][0]);
Arturo Espinosa's avatar
Arturo Espinosa committed
651
		break;
652

Arturo Espinosa's avatar
Arturo Espinosa committed
653 654 655
	case VALUE_CELLRANGE:
		res->v.cell_range = value->v.cell_range;
		break;
656 657 658
	default:
		g_warning ("eval_cell_value error\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
659 660 661 662
	}
	return res;
}

663 664 665 666
static void
free_values (Value **values, int top)
{
	int i;
667

668 669 670 671 672
	for (i = 0; i < top; i++)
		value_release (values [i]);
	g_free (values);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
673 674 675 676 677 678 679
static Value *
eval_funcall (Sheet *sheet, ExprTree *tree, int eval_col, int eval_row, char **error_string)
{
	FunctionDefinition *fd;
	GList *l;
	int argc, arg, i;
	Value *v;
680

Arturo Espinosa's avatar
Arturo Espinosa committed
681
	fd = (FunctionDefinition *) tree->u.function.symbol->data;
682

Arturo Espinosa's avatar
Arturo Espinosa committed
683 684 685 686 687 688 689 690 691 692 693 694
	l = tree->u.function.arg_list;
	argc = g_list_length (l);

	if (fd->expr_fn)
	{
		/* Functions that deal with ExprNodes */
		v = fd->expr_fn (sheet, l, eval_col, eval_row, error_string);
	}
	else
	{
		/* Functions that take pre-computed Values */
		Value **values;
Arturo Espinosa's avatar
Arturo Espinosa committed
695 696 697
		int fn_argc_min = 0, fn_argc_max = 0, var_len = 0;
		char *arg_type = fd->args;
		char *argptr = fd->args;
698

699
		/* Get variable limits */
Arturo Espinosa's avatar
Arturo Espinosa committed
700 701 702 703
		while (*argptr){
			if (*argptr++ == '|'){
				var_len = 1;
				continue;
704 705
			}
			if (!var_len)
Arturo Espinosa's avatar
Arturo Espinosa committed
706 707
				fn_argc_min++;
			fn_argc_max++;
708
		}
709

Arturo Espinosa's avatar
Arturo Espinosa committed
710
		if (argc > fn_argc_max || argc < fn_argc_min){
Arturo Espinosa's avatar
Arturo Espinosa committed
711 712 713 714
			*error_string = _("Invalid number of arguments");
			return NULL;
		}

715
		values = g_new (Value *, fn_argc_max);
716

717
		for (arg = 0; l; l = l->next, arg++, arg_type++){
Arturo Espinosa's avatar
Arturo Espinosa committed
718
			ExprTree *t = (ExprTree *) l->data;
719
			int type_mismatch = 0;
720

Arturo Espinosa's avatar
Arturo Espinosa committed
721 722
			if (*arg_type=='|')
				arg_type++;
723 724 725 726 727 728 729 730 731

			if ((*arg_type != 'A' &&          /* This is so a cell reference */
			     *arg_type != 'r') ||         /* can be converted to a cell range */
			    !t || (t->oper != OPER_VAR)) { /* without being evaluated */
				if ((v = eval_expr (sheet, t, eval_col,
						    eval_row, error_string))==NULL)
					goto free_list;
			} else {
				g_assert (t->oper == OPER_VAR);
Michael Meeks's avatar
Michael Meeks committed
732 733
				v =value_new_cellrange (&t->u.ref,
							 &t->u.ref);
734 735 736 737 738
				if (!v->v.cell_range.cell_a.sheet)
					v->v.cell_range.cell_a.sheet = sheet;
				if (!v->v.cell_range.cell_b.sheet)
					v->v.cell_range.cell_b.sheet = sheet;
			}
739

Arturo Espinosa's avatar
Arturo Espinosa committed
740
			switch (*arg_type){
741
			case 'f':
742

743 744 745 746
				if (v->type != VALUE_INTEGER &&
				    v->type != VALUE_FLOAT)
					type_mismatch = 1;
				break;
747
			case 's':
748 749
				if (v->type != VALUE_STRING)
					type_mismatch = 1;
Arturo Espinosa's avatar
Arturo Espinosa committed
750
				break;
751
			case 'r':
752 753 754 755 756
				if (v->type != VALUE_CELLRANGE)
					type_mismatch = 1;
				else {
					cell_ref_make_absolute (&v->v.cell_range.cell_a, eval_col, eval_row);
					cell_ref_make_absolute (&v->v.cell_range.cell_b, eval_col, eval_row);
757
				}
Arturo Espinosa's avatar
Arturo Espinosa committed
758
				break;
759 760 761 762 763 764 765 766
			case 'a':
				if (v->type != VALUE_ARRAY)
					type_mismatch = 1;
				break;
			case 'A':
				if (v->type != VALUE_ARRAY &&
				    v->type != VALUE_CELLRANGE)
					type_mismatch = 1;
Michael Meeks's avatar
Michael Meeks committed
767 768 769 770 771

				if (v->type == VALUE_CELLRANGE) {
					cell_ref_make_absolute (&v->v.cell_range.cell_a, eval_col, eval_row);
					cell_ref_make_absolute (&v->v.cell_range.cell_b, eval_col, eval_row);
				}
772 773
				break;
			}
774
			if (type_mismatch){
775 776 777
				free_values (values, arg);
				*error_string = _("Type mismatch");
				return NULL;
778
			}
Arturo Espinosa's avatar
Arturo Espinosa committed
779 780
			values [arg] = v;
		}
Arturo Espinosa's avatar
Arturo Espinosa committed
781 782
		while (arg < fn_argc_max)
			values [arg++] = NULL;
783
		v = fd->fn (fd, values, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
784 785

	free_list:
786
		for (i = 0; i < arg; i++){
Arturo Espinosa's avatar
Arturo Espinosa committed
787 788
			if (values [i] != NULL)
				value_release (values [i]);
789
		}
Arturo Espinosa's avatar
Arturo Espinosa committed
790 791 792 793 794 795
		g_free (values);
		return v;
	}
	return v;
}

796 797 798 799 800
Value *
function_def_call_with_values (Sheet *sheet, FunctionDefinition *fd, int argc,
			       Value *values [], char **error_string)
{
	Value *retval;
801

802 803 804 805 806 807 808 809 810 811 812
	if (fd->expr_fn){
		/*
		 * If function deals with ExprNodes, create some
		 * temporary ExprNodes with constants.
		 */
		ExprTree *tree = NULL;
		GList *l = NULL;
		int i;

		if (argc){
			tree = g_new (ExprTree, argc);
813

814
			for (i = 0; i < argc; i++){
815
				tree [i].oper = OPER_CONSTANT;
816 817
				tree [i].ref_count = 1;
				tree [i].u.constant = values [i];
818

819 820 821
				l = g_list_append (l, &(tree[i]));
			}
		}
822

823 824 825 826 827 828 829
		retval = fd->expr_fn (sheet, l, 0, 0, error_string);

		if (tree){
			g_free (tree);
			g_list_free (l);
		}

830
	} else
831 832 833 834 835 836 837 838 839 840
		retval = fd->fn (fd, values, error_string);

	return retval;
}

/*
 * Use this to invoke a register function: the only drawback is that
 * you have to compute/expand all of the values to use this
 */
Value *
841
function_call_with_values (Sheet *sheet, const char *name, int argc, Value *values[], char **error_string)
842 843 844 845 846 847 848 849 850
{
	FunctionDefinition *fd;
	Value *retval;
	Symbol *sym;

	g_return_val_if_fail (sheet != NULL, NULL);
	g_return_val_if_fail (IS_SHEET (sheet), NULL);
	g_return_val_if_fail (name != NULL, NULL);

Miguel de Icaza's avatar
Miguel de Icaza committed
851
	sym = symbol_lookup (global_symbol_table, name);
852
	if (sym == NULL){
853
		*error_string = _("Function does not exist");
854 855
		return NULL;
	}
856
	if (sym->type != SYMBOL_FUNCTION){
857
		*error_string = _("Calling non-function");
858 859
		return NULL;
	}
860

861 862 863 864 865 866 867 868 869 870
	fd = sym->data;

	symbol_ref (sym);
	retval = function_def_call_with_values (sheet, fd, argc, values, error_string);

	symbol_unref (sym);

	return retval;
}

871
typedef enum {
Arturo Espinosa's avatar
Arturo Espinosa committed
872 873
	IS_EQUAL,
	IS_LESS,
874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898
	IS_GREATER,
	TYPE_ERROR
} compare_t;

static compare_t
compare_int_int (int a, int b)
{
	if (a == b)
		return IS_EQUAL;
	else if (a < b)
		return IS_LESS;
	else
		return IS_GREATER;
}

static compare_t
compare_float_float (float_t a, float_t b)
{
	if (a == b)
		return IS_EQUAL;
	else if (a < b)
		return IS_LESS;
	else
		return IS_GREATER;
}
Arturo Espinosa's avatar
Arturo Espinosa committed
899

900 901 902 903
/*
 * Compares two (Value *) and returns one of compare_t
 */
static compare_t
Arturo Espinosa's avatar
Arturo Espinosa committed
904 905
compare (Value *a, Value *b)
{
906 907
	if (a->type == VALUE_INTEGER){
		int f;
908

909 910 911 912 913 914 915 916
		switch (b->type){
		case VALUE_INTEGER:
			return compare_int_int (a->v.v_int, b->v.v_int);

		case VALUE_FLOAT:
			return compare_float_float (a->v.v_int, b->v.v_float);

		case VALUE_STRING:
Michael Meeks's avatar
Michael Meeks committed
917
			f =value_get_as_float (b);
918 919 920 921 922 923
			return compare_float_float (a->v.v_int, f);

		default:
			return TYPE_ERROR;
		}
	}
924

925 926 927 928 929 930 931 932 933 934 935
	if (a->type == VALUE_FLOAT){
		float_t f;

		switch (b->type){
		case VALUE_INTEGER:
			return compare_float_float (a->v.v_float, b->v.v_int);

		case VALUE_FLOAT:
			return compare_float_float (a->v.v_float, b->v.v_float);

		case VALUE_STRING:
Michael Meeks's avatar
Michael Meeks committed
936
			f =value_get_as_float (b);
937 938 939 940 941 942 943 944 945 946