expr.c 39.2 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_constant (Value *v)
51
{
52 53 54
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
Morten Welinder's avatar
Morten Welinder committed
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
	if (ans) {
		ans->ref_count = 1;
		ans->oper = OPER_CONSTANT;
		ans->u.constant = v;
	}
	return ans;
}

ExprTree *
expr_tree_new_unary  (Operation op, ExprTree *e)
{
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
	if (ans) {
		ans->ref_count = 1;
		ans->oper = op;
		ans->u.value = e;
	}
	return ans;
}


ExprTree *
expr_tree_new_binary (ExprTree *l, Operation op, ExprTree *r)
{
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
	if (ans) {
		ans->ref_count = 1;
		ans->oper = op;
		ans->u.binary.value_a = l;
		ans->u.binary.value_b = r;
	}
	return ans;
}

ExprTree *
expr_tree_new_funcall (Symbol *sym, GList *args)
{
	ExprTree *ans;
	g_return_val_if_fail (sym, NULL);

	ans = g_new (ExprTree, 1);
	if (ans) {
		ans->ref_count = 1;
		ans->oper = OPER_FUNCALL;
		ans->u.function.symbol = sym;;
		ans->u.function.arg_list = args;
	}
	return ans;
}

ExprTree *
expr_tree_new_var (const CellRef *cr)
{
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
	if (ans) {
		ans->ref_count = 1;
		ans->oper = OPER_VAR;
		ans->u.ref = *cr;
	}
120 121 122
	return ans;
}

Morten Welinder's avatar
Morten Welinder committed
123 124 125 126 127 128 129 130 131 132 133 134 135
ExprTree *
expr_tree_new_error (const char *txt)
{
	ExprTree *val, *call;
	Symbol *func;

	val = expr_tree_new_constant (value_new_string (txt));
	func = symbol_lookup (global_symbol_table, "ERROR");
	symbol_ref (func);
	return expr_tree_new_funcall (func, g_list_prepend (NULL, val));
}


Arturo Espinosa's avatar
Arturo Espinosa committed
136 137 138 139
/*
 * expr_tree_ref:
 * Increments the ref_count for part of a tree
 */
140 141 142 143 144 145
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
146
	tree->ref_count++;
Arturo Espinosa's avatar
Arturo Espinosa committed
147 148 149 150 151
}

static void
do_expr_tree_unref (ExprTree *tree)
{
Morten Welinder's avatar
Morten Welinder committed
152 153 154
	if (--tree->ref_count > 0)
		return;

Arturo Espinosa's avatar
Arturo Espinosa committed
155
	switch (tree->oper){
156
	case OPER_VAR:
Arturo Espinosa's avatar
Arturo Espinosa committed
157
		break;
158

159
	case OPER_CONSTANT:
Morten Welinder's avatar
Morten Welinder committed
160
		value_release (tree->u.constant);
Arturo Espinosa's avatar
Arturo Espinosa committed
161
		break;
162

Morten Welinder's avatar
Morten Welinder committed
163 164 165 166 167 168 169
	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
170
		break;
Morten Welinder's avatar
Morten Welinder committed
171
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
172

173
	case OPER_ANY_BINARY:
Arturo Espinosa's avatar
Arturo Espinosa committed
174 175 176 177
		do_expr_tree_unref (tree->u.binary.value_a);
		do_expr_tree_unref (tree->u.binary.value_b);
		break;

178
	case OPER_ANY_UNARY:
Arturo Espinosa's avatar
Arturo Espinosa committed
179 180
		do_expr_tree_unref (tree->u.value);
		break;
181 182 183
	default:
		g_warning ("do_expr_tree_unref error\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
184
	}
185

Morten Welinder's avatar
Morten Welinder committed
186
	g_free (tree);
187 188
}

Morten Welinder's avatar
Morten Welinder committed
189 190 191 192 193 194
/*
 * 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.)
 */
195 196 197 198 199 200
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
201
	do_expr_tree_unref (tree);
202 203
}

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
204 205 206 207
/*
 * simplistic value rendering
 */
char *
Michael Meeks's avatar
Michael Meeks committed
208
value_get_as_string (const Value *value)
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
209 210 211 212 213 214
{
	switch (value->type){
	case VALUE_STRING:
		return g_strdup (value->v.str->str);

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

	case VALUE_FLOAT:
Morten Welinder's avatar
Morten Welinder committed
218
		return g_strdup_printf ("%.*g", DBL_DIG, value->v.v_float);
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
219

220 221 222 223 224
	case VALUE_ARRAY: {
		GString *str = g_string_new ("{");
		guint lpx, lpy;
		char *ans;

225 226 227 228
		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];

229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
				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;
	}
250

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
251
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
252
		break;
253 254 255
	default:
		g_warning ("value_string problem\n");
		break;
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
256
	}
257

Arturo Espinosa's avatar
Arturo Espinosa committed
258
	return g_strdup ("Internal problem");
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
259 260
}

261 262 263
void
value_release (Value *value)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
264
	g_return_if_fail (value != NULL);
265

266 267 268 269 270 271 272
	switch (value->type){
	case VALUE_STRING:
		string_unref (value->v.str);
		break;

	case VALUE_INTEGER:
		mpz_clear (value->v.v_int);
273
		break;
274

275 276 277 278
	case VALUE_FLOAT:
		mpf_clear (value->v.v_float);
		break;

279
	case VALUE_ARRAY:{
280
		guint lpx, lpy;
281

282
		for (lpx = 0; lpx < value->v.array.x; lpx++){
283
			for (lpy = 0; lpy < value->v.array.y; lpy++)
284
				value_release (value->v.array.vals [lpx][lpy]);
285 286
			g_free (value->v.array.vals [lpx]);
		}
287

288
		g_free (value->v.array.vals);
Morten Welinder's avatar
Morten Welinder committed
289
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
290
	}
291

Arturo Espinosa's avatar
Arturo Espinosa committed
292 293
	case VALUE_CELLRANGE:
		break;
294

295 296 297
	default:
		g_warning ("value_release problem\n");
		break;
298
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
299
	g_free (value);
300
}
301

Arturo Espinosa's avatar
Arturo Espinosa committed
302 303 304 305
/*
 * Copies a Value.
 */
void
306
value_copy_to (Value *dest, const Value *source)
Arturo Espinosa's avatar
Arturo Espinosa committed
307 308 309 310 311
{
	g_return_if_fail (dest != NULL);
	g_return_if_fail (source != NULL);

	dest->type = source->type;
312

Arturo Espinosa's avatar
Arturo Espinosa committed
313 314 315 316 317 318 319 320 321 322 323 324 325 326
	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
327
	case VALUE_ARRAY: {
328
		value_array_copy_to (dest, source);
Arturo Espinosa's avatar
Arturo Espinosa committed
329 330 331 332 333
		break;
	}
	case VALUE_CELLRANGE:
		dest->v.cell_range = source->v.cell_range;
		break;
334 335 336
	default:
		g_warning ("value_copy_to problem\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
337 338 339
	}
}

Arturo Espinosa's avatar
Arturo Espinosa committed
340 341 342 343
/*
 * Makes a copy of a Value
 */
Value *
344
value_duplicate (const Value *value)
Arturo Espinosa's avatar
Arturo Espinosa committed
345 346 347 348 349 350
{
	Value *new_value;

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

Arturo Espinosa's avatar
Arturo Espinosa committed
352 353 354
	return new_value;
}

355
Value *
Michael Meeks's avatar
Michael Meeks committed
356
value_new_float (float_t f)
357 358 359 360 361 362 363 364 365 366
{
	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
367
value_new_int (int i)
368 369 370 371 372 373 374 375 376
{
	Value *v = g_new (Value, 1);

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

	return v;
}

377 378 379 380 381 382 383 384
Value *
value_new_bool (gboolean b)
{
	/* Currently our booleans are really just ints.  This will have to
	   change if we want Excel's ISLOGICAL.  */
	return value_new_int (b ? 1 : 0);
}

385
Value *
Michael Meeks's avatar
Michael Meeks committed
386
value_new_string (const char *str)
387 388 389 390 391 392 393 394 395
{
	Value *v = g_new (Value, 1);

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

	return v;
}

396
Value *
Michael Meeks's avatar
Michael Meeks committed
397
value_new_cellrange (const CellRef *a, const CellRef *b)
398 399
{
	Value *v = g_new (Value, 1);
Morten Welinder's avatar
Morten Welinder committed
400

401
	v->type = VALUE_CELLRANGE;
Morten Welinder's avatar
Morten Welinder committed
402 403 404
	v->v.cell_range.cell_a = *a;
	v->v.cell_range.cell_b = *b;

405 406 407
	return v;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
408 409 410 411
/*
 * Casts a value to float if it is integer, and returns
 * a new Value * if required
 */
412
Value *
413
value_cast_to_float (Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
414 415
{
	Value *newv;
416

Arturo Espinosa's avatar
Arturo Espinosa committed
417 418 419 420
	g_return_val_if_fail (VALUE_IS_NUMBER (v), NULL);

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

Arturo Espinosa's avatar
Arturo Espinosa committed
422 423 424
	newv = g_new (Value, 1);
	newv->type = VALUE_FLOAT;
	mpf_set_z (newv->v.v_float, v->v.v_int);
425
	value_release (v);
426

Arturo Espinosa's avatar
Arturo Espinosa committed
427 428 429
	return newv;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
430
int
Michael Meeks's avatar
Michael Meeks committed
431
value_get_as_bool (const Value *v, int *err)
Arturo Espinosa's avatar
Arturo Espinosa committed
432 433 434
{
	*err = 0;

435 436
	switch (v->type) {
	case VALUE_STRING:
Morten Welinder's avatar
Morten Welinder committed
437 438
		/* FIXME FIXME FIXME */
		/* Use locale to support TRUE, FALSE */
Arturo Espinosa's avatar
Arturo Espinosa committed
439 440
		return atoi (v->v.str->str);

441
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
442 443
		*err = 1;
		return 0;
444 445
		
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
446 447
		return v->v.v_int != 0;

448
	case VALUE_FLOAT:
Arturo Espinosa's avatar
Arturo Espinosa committed
449 450
		return v->v.v_float != 0.0;

451
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
452
		return 0;
453 454 455 456
	default:
		g_warning ("Unhandled value in value_get_boolean");
		break;
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
457 458 459
	return 0;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
460
float_t
Michael Meeks's avatar
Michael Meeks committed
461
value_get_as_float (const Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
462
{
463 464 465
	switch (v->type)
	{
	case VALUE_STRING:
Arturo Espinosa's avatar
Arturo Espinosa committed
466 467
		return atof (v->v.str->str);

468
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
469 470 471
		g_warning ("Getting range as a double: what to do?");
		return 0.0;

472
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
473
		return (float_t) v->v.v_int;
474 475
		
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
476
		return 0.0;
477

478 479 480
	case VALUE_FLOAT:
		return (float_t) v->v.v_float;
	default:
Michael Meeks's avatar
Michael Meeks committed
481
		g_warning ("value_get_as_float type error\n");
482 483 484
		break;
	}
	return 0.0;
Arturo Espinosa's avatar
Arturo Espinosa committed
485 486
}

487
int
488
value_get_as_int (const Value *v)
489
{
490 491 492
	switch (v->type)
	{
	case VALUE_STRING:
493 494
		return atoi (v->v.str->str);

495
	case VALUE_CELLRANGE:
Morten Welinder's avatar
Morten Welinder committed
496
		g_warning ("Getting range as a int: what to do?");
497
		return 0;
498

499
	case VALUE_INTEGER:
500 501
		return v->v.v_int;

502
	case VALUE_ARRAY:
503
		return 0;
504

505 506 507 508
	case VALUE_FLOAT:
		return (int) v->v.v_float;
	default:
		g_warning ("value_get_as_int unknown type\n");
509
		return 0;
510
	}
Michael Meeks's avatar
Michael Meeks committed
511
	return 0.0;
512 513
}

514 515 516
Value *
value_array_new (guint width, guint height)
{
517
	int x, y;
518 519 520 521 522

	Value *v = g_new (Value, 1);
	v->type = VALUE_ARRAY;
	v->v.array.x = width;
	v->v.array.y = height;
523
	v->v.array.vals = g_new (Value **, width);
524 525

	for (x = 0; x < width; x++){
526 527 528
		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);
529 530 531 532
	}
	return v;
}

Michael Meeks's avatar
Michael Meeks committed
533 534 535 536
void
value_array_set (Value *array, guint col, guint row, Value *v)
{
	g_return_if_fail (v);
537
	g_return_if_fail (array->type == VALUE_ARRAY);
Michael Meeks's avatar
Michael Meeks committed
538 539
	g_return_if_fail (col>=0);
	g_return_if_fail (row>=0);
540 541
	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
542

543 544 545
	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
546 547
}

548 549 550
void
value_array_resize (Value *v, guint width, guint height)
{
551
	int x, y, xcpy, ycpy;
552
	Value *newval;
553
	Value ***tmp;
554

Michael Meeks's avatar
Michael Meeks committed
555
	g_warning ("Totally untested");
556 557 558 559 560 561 562 563
	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
564
		xcpy = width;
565 566 567 568 569 570

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

571 572 573 574 575
	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;
576
	v->v.array.vals = newval->v.array.vals;
577
	newval->v.array.vals = tmp;
578 579
	value_release (newval);

580 581 582 583 584 585 586
	v->v.array.x = width;
	v->v.array.y = height;
}

void
value_array_copy_to (Value *v, const Value *src)
{
587
	int x, y;
588 589 590 591 592

	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;
593
	v->v.array.vals = g_new (Value **, v->v.array.x);
594

595 596 597 598
	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]);
599 600 601 602 603 604 605 606 607
	}
}

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);
608

609 610
	if (v->type == VALUE_ARRAY)
		return v->v.array.x;
611 612 613 614 615 616 617 618
	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;
	}
619 620 621 622 623 624 625 626
}

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);
627

628 629
	if (v->type == VALUE_ARRAY)
		return v->v.array.y;
630 631 632 633 634 635 636 637
	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;
	}
638 639 640 641 642 643 644 645
}

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
646
			     value_new_int (0));
647 648

	if (v->type == VALUE_ARRAY){
649
		g_return_val_if_fail (v->v.array.x < x &&
650
				      v->v.array.y < y,
Michael Meeks's avatar
Michael Meeks committed
651
				     value_new_int (0));
652
		return v->v.array.vals [x][y];
653 654 655
	} else {
		CellRef *a, *b;
		Cell *cell;
656

657 658
		a = &v->v.cell_range.cell_a;
		b = &v->v.cell_range.cell_b;
659 660 661 662 663 664
		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);
Michael Meeks's avatar
Michael Meeks committed
665
		g_return_val_if_fail (a->sheet,       value_zero);
666 667 668 669 670

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

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

674 675 676
		if (cell && cell->value)
			return cell->value;
	}
Michael Meeks's avatar
Michael Meeks committed
677
	
678
	return value_zero;
679 680
}

681 682 683 684 685 686
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)
687
		cell_ref->col = eval_col + cell_ref->col;
688 689 690

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

Arturo Espinosa's avatar
Arturo Espinosa committed
692 693
	cell_ref->row_relative = 0;
	cell_ref->col_relative = 0;
694 695
}

696 697 698 699 700 701 702 703 704 705 706 707 708 709
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;
	}
}

710 711 712 713
static void
free_values (Value **values, int top)
{
	int i;
714

715
	for (i = 0; i < top; i++)
716 717
		if (values[i])
			value_release (values [i]);
718 719 720
	g_free (values);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
721 722 723 724 725 726
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;
727
	Value *v = NULL;
728

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

Arturo Espinosa's avatar
Arturo Espinosa committed
731 732 733 734 735 736 737 738 739 740 741 742
	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
743 744 745
		int fn_argc_min = 0, fn_argc_max = 0, var_len = 0;
		char *arg_type = fd->args;
		char *argptr = fd->args;
746

747
		/* Get variable limits */
Arturo Espinosa's avatar
Arturo Espinosa committed
748 749 750 751
		while (*argptr){
			if (*argptr++ == '|'){
				var_len = 1;
				continue;
752 753
			}
			if (!var_len)
Arturo Espinosa's avatar
Arturo Espinosa committed
754 755
				fn_argc_min++;
			fn_argc_max++;
756
		}
757

Arturo Espinosa's avatar
Arturo Espinosa committed
758
		if (argc > fn_argc_max || argc < fn_argc_min){
Arturo Espinosa's avatar
Arturo Espinosa committed
759 760 761 762
			*error_string = _("Invalid number of arguments");
			return NULL;
		}

763
		values = g_new (Value *, fn_argc_max);
764

765
		for (arg = 0; l; l = l->next, arg++, arg_type++){
Arturo Espinosa's avatar
Arturo Espinosa committed
766
			ExprTree *t = (ExprTree *) l->data;
767
			int type_mismatch = 0;
768
			Value *v;
769

Arturo Espinosa's avatar
Arturo Espinosa committed
770 771
			if (*arg_type=='|')
				arg_type++;
772 773 774 775 776 777 778 779 780

			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
781 782
				v =value_new_cellrange (&t->u.ref,
							 &t->u.ref);
783 784 785 786 787
				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;
			}
788

Arturo Espinosa's avatar
Arturo Espinosa committed
789
			switch (*arg_type){
790
			case 'f':
791

792 793 794 795
				if (v->type != VALUE_INTEGER &&
				    v->type != VALUE_FLOAT)
					type_mismatch = 1;
				break;
796
			case 's':
797 798
				if (v->type != VALUE_STRING)
					type_mismatch = 1;
Arturo Espinosa's avatar
Arturo Espinosa committed
799
				break;
800
			case 'r':
801 802 803 804 805
				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);
806
				}
Arturo Espinosa's avatar
Arturo Espinosa committed
807
				break;
808 809 810 811 812 813 814 815
			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
816 817 818 819 820

				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);
				}
821 822
				break;
			}
823
			values [arg] = v;
824
			if (type_mismatch){
825
				free_values (values, arg + 1);
826 827
				*error_string = _("Type mismatch");
				return NULL;
828
			}
Arturo Espinosa's avatar
Arturo Espinosa committed
829
		}
Arturo Espinosa's avatar
Arturo Espinosa committed
830 831
		while (arg < fn_argc_max)
			values [arg++] = NULL;
832
		v = fd->fn (fd, values, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
833 834

	free_list:
835
		free_values (values, arg);
Arturo Espinosa's avatar
Arturo Espinosa committed
836 837 838 839
	}
	return v;
}

840 841 842 843 844
Value *
function_def_call_with_values (Sheet *sheet, FunctionDefinition *fd, int argc,
			       Value *values [], char **error_string)
{
	Value *retval;
845

846 847 848 849 850 851 852 853 854 855 856
	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);
857

858
			for (i = 0; i < argc; i++){
859
				tree [i].oper = OPER_CONSTANT;
860 861
				tree [i].ref_count = 1;
				tree [i].u.constant = values [i];
862

863 864 865
				l = g_list_append (l, &(tree[i]));
			}
		}
866

867 868 869 870 871 872 873
		retval = fd->expr_fn (sheet, l, 0, 0, error_string);

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

874
	} else
875 876 877 878 879 880 881 882 883 884
		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 *
885
function_call_with_values (Sheet *sheet, const char *name, int argc, Value *values[], char **error_string)
886 887 888 889 890 891 892 893 894
{
	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
895
	sym = symbol_lookup (global_symbol_table, name);
896
	if (sym == NULL){
897
		*error_string = _("Function does not exist");
898 899
		return NULL;
	}
900
	if (sym->type != SYMBOL_FUNCTION){
901
		*error_string = _("Calling non-function");
902 903
		return NULL;
	}
904

905 906 907 908 909 910 911 912 913 914
	fd = sym->data;

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

	symbol_unref (sym);

	return retval;
}

915
typedef enum {
Arturo Espinosa's avatar
Arturo Espinosa committed
916 917
	IS_EQUAL,
	IS_LESS,
918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942
	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
943

944 945 946 947
/*
 * Compares two (Value *) and returns one of compare_t
 */
static compare_t
948
compare (const Value *a, const Value *b)
Arturo Espinosa's avatar
Arturo Espinosa committed