expr.c 39.4 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
ExprTree *
19 20
expr_parse_string (const char *expr, Sheet *sheet, int col, int row,
		   const char **desired_format, char **error_msg)
21
{
22
	ExprTree *tree;
23
	g_return_val_if_fail (expr != NULL, NULL);
24 25

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

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

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

46

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

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

Arturo Espinosa's avatar
Arturo Espinosa committed
62 63 64 65
/*
 * expr_tree_ref:
 * Increments the ref_count for part of a tree
 */
66 67 68 69 70 71
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
72
	tree->ref_count++;
Arturo Espinosa's avatar
Arturo Espinosa committed
73 74 75 76 77
}

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

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

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

Morten Welinder's avatar
Morten Welinder committed
89 90 91 92 93 94 95
	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
96
		break;
Morten Welinder's avatar
Morten Welinder committed
97
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
98

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

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

Morten Welinder's avatar
Morten Welinder committed
112
	g_free (tree);
113 114
}

Morten Welinder's avatar
Morten Welinder committed
115 116 117 118 119 120
/*
 * 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.)
 */
121 122 123 124 125 126
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
127
	do_expr_tree_unref (tree);
128 129
}

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

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

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

	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
147
		return g_strdup ("ARRAY");
148

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
149
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
150
		break;
151 152 153
	default:
		g_warning ("value_string problem\n");
		break;
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
154
	}
155

Arturo Espinosa's avatar
Arturo Espinosa committed
156
	return g_strdup ("Internal problem");
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
157 158
}

159 160 161
void
value_release (Value *value)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
162
	g_return_if_fail (value != NULL);
163

164 165 166 167 168 169 170
	switch (value->type){
	case VALUE_STRING:
		string_unref (value->v.str);
		break;

	case VALUE_INTEGER:
		mpz_clear (value->v.v_int);
171
		break;
172

173 174 175 176
	case VALUE_FLOAT:
		mpf_clear (value->v.v_float);
		break;

177 178
	case VALUE_ARRAY:{
		guint i;
179

180 181
		for (i = 0; i < value->v.array.x; i++)
			g_free (value->v.array.vals [i]);
182

183
		g_free (value->v.array.vals);
Morten Welinder's avatar
Morten Welinder committed
184
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
185
	}
186

Arturo Espinosa's avatar
Arturo Espinosa committed
187 188
	case VALUE_CELLRANGE:
		break;
189

190 191 192
	default:
		g_warning ("value_release problem\n");
		break;
193
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
194
	g_free (value);
195
}
196

Arturo Espinosa's avatar
Arturo Espinosa committed
197 198 199 200
/*
 * Copies a Value.
 */
void
201
value_copy_to (Value *dest, const Value *source)
Arturo Espinosa's avatar
Arturo Espinosa committed
202 203 204 205 206
{
	g_return_if_fail (dest != NULL);
	g_return_if_fail (source != NULL);

	dest->type = source->type;
207

Arturo Espinosa's avatar
Arturo Espinosa committed
208 209 210 211 212 213 214 215 216 217 218 219 220 221
	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
222
	case VALUE_ARRAY: {
223
		value_array_copy_to (dest, source);
Arturo Espinosa's avatar
Arturo Espinosa committed
224 225 226 227 228
		break;
	}
	case VALUE_CELLRANGE:
		dest->v.cell_range = source->v.cell_range;
		break;
229 230 231
	default:
		g_warning ("value_copy_to problem\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
232 233 234
	}
}

Arturo Espinosa's avatar
Arturo Espinosa committed
235 236 237 238
/*
 * Makes a copy of a Value
 */
Value *
239
value_duplicate (const Value *value)
Arturo Espinosa's avatar
Arturo Espinosa committed
240 241 242 243 244 245
{
	Value *new_value;

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

Arturo Espinosa's avatar
Arturo Espinosa committed
247 248 249
	return new_value;
}

250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
Value *
value_float (float_t f)
{
	Value *v = g_new (Value, 1);

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

	return v;
}

Value *
value_int (int i)
{
	Value *v = g_new (Value, 1);

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

	return v;
}

272
Value *
273
value_str (const char *str)
274 275 276 277 278 279 280 281 282
{
	Value *v = g_new (Value, 1);

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

	return v;
}

283
Value *
Morten Welinder's avatar
Morten Welinder committed
284
value_cellrange (const CellRef *a, const CellRef *b)
285 286
{
	Value *v = g_new (Value, 1);
Morten Welinder's avatar
Morten Welinder committed
287

288
	v->type = VALUE_CELLRANGE;
Morten Welinder's avatar
Morten Welinder committed
289 290 291
	v->v.cell_range.cell_a = *a;
	v->v.cell_range.cell_b = *b;

292 293 294
	return v;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
295 296 297 298
/*
 * Casts a value to float if it is integer, and returns
 * a new Value * if required
 */
299
Value *
300
value_cast_to_float (Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
301 302
{
	Value *newv;
303

Arturo Espinosa's avatar
Arturo Espinosa committed
304 305 306 307
	g_return_val_if_fail (VALUE_IS_NUMBER (v), NULL);

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

Arturo Espinosa's avatar
Arturo Espinosa committed
309 310 311
	newv = g_new (Value, 1);
	newv->type = VALUE_FLOAT;
	mpf_set_z (newv->v.v_float, v->v.v_int);
312
	value_release (v);
313

Arturo Espinosa's avatar
Arturo Espinosa committed
314 315 316
	return newv;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
317
int
318
value_get_bool (const Value *v, int *err)
Arturo Espinosa's avatar
Arturo Espinosa committed
319 320 321
{
	*err = 0;

322 323
	switch (v->type) {
	case VALUE_STRING:
Arturo Espinosa's avatar
Arturo Espinosa committed
324 325
		return atoi (v->v.str->str);

326
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
327 328
		*err = 1;
		return 0;
329 330
		
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
331 332
		return v->v.v_int != 0;

333
	case VALUE_FLOAT:
Arturo Espinosa's avatar
Arturo Espinosa committed
334 335
		return v->v.v_float != 0.0;

336
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
337
		return 0;
338 339 340 341
	default:
		g_warning ("Unhandled value in value_get_boolean");
		break;
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
342 343 344
	return 0;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
345
float_t
346
value_get_as_double (const Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
347
{
348 349 350
	switch (v->type)
	{
	case VALUE_STRING:
Arturo Espinosa's avatar
Arturo Espinosa committed
351 352
		return atof (v->v.str->str);

353
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
354 355 356
		g_warning ("Getting range as a double: what to do?");
		return 0.0;

357
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
358
		return (float_t) v->v.v_int;
359 360
		
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
361
		return 0.0;
362

363 364 365 366 367 368 369
	case VALUE_FLOAT:
		return (float_t) v->v.v_float;
	default:
		g_warning ("value_get_as_double type error\n");
		break;
	}
	return 0.0;
Arturo Espinosa's avatar
Arturo Espinosa committed
370 371
}

372
int
373
value_get_as_int (const Value *v)
374
{
375 376 377
	switch (v->type)
	{
	case VALUE_STRING:
378 379
		return atoi (v->v.str->str);

380
	case VALUE_CELLRANGE:
381 382 383
		g_warning ("Getting range as a double: what to do?");
		return 0.0;

384
	case VALUE_INTEGER:
385 386
		return v->v.v_int;

387
	case VALUE_ARRAY:
388
		return 0.0;
389

390 391 392 393 394 395
	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
396
	return 0.0;
397 398
}

399 400 401
Value *
value_array_new (guint width, guint height)
{
402
	int x, y;
403 404 405 406 407 408

	Value *v = g_new (Value, 1);
	v->type = VALUE_ARRAY;
	v->v.array.x = width;
	v->v.array.y = height;
	v->v.array.vals = g_new (Value *, width);
409 410 411 412 413 414 415

	for (x = 0; x < width; x++){
		v->v.array.vals [x] = g_new (Value, height);

		for (y = 0; y < height; y++){
			v->v.array.vals[x][y].type = VALUE_INTEGER;
			v->v.array.vals[x][y].v.v_int = 0;
416 417 418 419 420
		}
	}
	return v;
}

Michael Meeks's avatar
Michael Meeks committed
421 422 423 424 425 426 427 428 429 430 431 432 433
void
value_array_set (Value *array, guint col, guint row, Value *v)
{
	g_return_if_fail (v);
	g_return_if_fail (v->type == VALUE_ARRAY);
	g_return_if_fail (col>=0);
	g_return_if_fail (row>=0);
	g_return_if_fail (v->v.array.y <= row);
	g_return_if_fail (v->v.array.x <= col);

	memcpy (&array->v.array.vals[col][row], v, sizeof (Value));
}

434 435 436
void
value_array_resize (Value *v, guint width, guint height)
{
437
	int x, xcpy, ycpy;
438 439 440 441 442 443 444 445 446 447
	Value *newval;

	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
448
		xcpy = width;
449 450 451 452 453 454

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

455 456 457 458
	for (x = 0; x < xcpy; x++){
		memcpy (newval->v.array.vals [x],
			v->v.array.vals [x],
			sizeof (Value) * ycpy);
459 460 461 462
	}
	v->v.array.vals = newval->v.array.vals;
	v->v.array.x = width;
	v->v.array.y = height;
463
	value_release (newval);
464 465 466 467 468
}

void
value_array_copy_to (Value *v, const Value *src)
{
469
	int x;
470 471 472 473 474 475

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

	for (x = 0; x < v->v.array.x; x++){
		v->v.array.vals [x] = g_new (Value,v->v.array.y);
479

480 481 482
		memcpy (v->v.array.vals   [x],
			src->v.array.vals [x],
			sizeof(Value)*v->v.array.y);
483 484 485 486 487 488 489 490 491
	}
}

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

493 494 495 496 497 498 499 500 501 502 503 504 505
	if (v->type == VALUE_ARRAY)
		return v->v.array.x;
	else
		return v->v.cell_range.cell_b.col -
		       v->v.cell_range.cell_a.col + 1;
}

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

507 508 509 510 511 512 513 514 515 516 517 518 519
	if (v->type == VALUE_ARRAY)
		return v->v.array.y;
	else
		return v->v.cell_range.cell_b.row -
		       v->v.cell_range.cell_a.row + 1;
}

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,
520 521 522
			      value_int (0));

	if (v->type == VALUE_ARRAY){
523
		g_return_val_if_fail (v->v.array.x < x &&
524 525 526
				      v->v.array.y < y,
				      value_int (0));
		return &v->v.array.vals [x][y];
527 528 529
	} else {
		CellRef *a, *b;
		Cell *cell;
530

531 532 533
		a = &v->v.cell_range.cell_a;
		b = &v->v.cell_range.cell_b;
		g_return_val_if_fail (!a->col_relative,
534
				      value_int (0));
535
		g_return_val_if_fail (!b->col_relative,
536
				      value_int (0));
537
		g_return_val_if_fail (!a->row_relative,
538
				      value_int (0));
539
		g_return_val_if_fail (!b->row_relative,
540
				      value_int (0));
541
		g_return_val_if_fail (a->col<=b->col,
542
				      value_int (0));
543
		g_return_val_if_fail (a->row<=b->row,
544
				      value_int (0));
545

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

548 549 550
		if (cell && cell->value)
			return cell->value;
	}
Michael Meeks's avatar
Michael Meeks committed
551 552
	
	g_warning ("Leaked on array\n");
553
	return value_int (0);
554 555
}

556 557 558 559 560 561
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)
562
		cell_ref->col = eval_col + cell_ref->col;
563 564 565

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

Arturo Espinosa's avatar
Arturo Espinosa committed
567 568
	cell_ref->row_relative = 0;
	cell_ref->col_relative = 0;
569 570
}

571 572 573 574 575 576 577 578 579 580 581 582 583 584
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
585 586
static Value *
eval_cell_value (Sheet *sheet, Value *value)
587
{
Arturo Espinosa's avatar
Arturo Espinosa committed
588
	Value *res;
589

Arturo Espinosa's avatar
Arturo Espinosa committed
590 591
	res = g_new (Value, 1);
	res->type = value->type;
592

Arturo Espinosa's avatar
Arturo Espinosa committed
593 594 595
	switch (res->type){
	case VALUE_STRING:
		res->v.str = value->v.str;
596
		string_ref (res->v.str);
Arturo Espinosa's avatar
Arturo Espinosa committed
597
		break;
598

Arturo Espinosa's avatar
Arturo Espinosa committed
599
	case VALUE_INTEGER:
600
		res->v.v_int = value->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
601
		break;
602

Arturo Espinosa's avatar
Arturo Espinosa committed
603
	case VALUE_FLOAT:
604
		res->v.v_float = value->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
605
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
606 607 608 609 610 611

	case VALUE_ARRAY:
		g_warning ("VALUE_ARRAY not handled in eval_cell_value\n");
		res->type = VALUE_INTEGER;
		res->v.v_int = 0;
		break;
612

Arturo Espinosa's avatar
Arturo Espinosa committed
613 614 615
	case VALUE_CELLRANGE:
		res->v.cell_range = value->v.cell_range;
		break;
616 617 618
	default:
		g_warning ("eval_cell_value error\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
619 620 621 622
	}
	return res;
}

623 624 625 626
static void
free_values (Value **values, int top)
{
	int i;
627

628 629 630 631 632
	for (i = 0; i < top; i++)
		value_release (values [i]);
	g_free (values);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
633 634 635 636 637 638 639
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;
640

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

Arturo Espinosa's avatar
Arturo Espinosa committed
643 644 645 646 647 648 649 650 651 652 653 654
	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
655 656 657
		int fn_argc_min = 0, fn_argc_max = 0, var_len = 0;
		char *arg_type = fd->args;
		char *argptr = fd->args;
658

659
		/* Get variable limits */
Arturo Espinosa's avatar
Arturo Espinosa committed
660 661 662 663
		while (*argptr){
			if (*argptr++ == '|'){
				var_len = 1;
				continue;
664 665
			}
			if (!var_len)
Arturo Espinosa's avatar
Arturo Espinosa committed
666 667
				fn_argc_min++;
			fn_argc_max++;
668
		}
669

Arturo Espinosa's avatar
Arturo Espinosa committed
670
		if (argc > fn_argc_max || argc < fn_argc_min){
Arturo Espinosa's avatar
Arturo Espinosa committed
671 672 673 674
			*error_string = _("Invalid number of arguments");
			return NULL;
		}

675
		values = g_new (Value *, fn_argc_max);
676

677
		for (arg = 0; l; l = l->next, arg++, arg_type++){
Arturo Espinosa's avatar
Arturo Espinosa committed
678
			ExprTree *t = (ExprTree *) l->data;
679
			int type_mismatch = 0;
680

Arturo Espinosa's avatar
Arturo Espinosa committed
681 682
			if (*arg_type=='|')
				arg_type++;
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698

			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);
				v = value_cellrange (&t->u.ref,
						     &t->u.ref);
				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;
			}
699

Arturo Espinosa's avatar
Arturo Espinosa committed
700
			switch (*arg_type){
701
			case 'f':
702

703 704 705 706
				if (v->type != VALUE_INTEGER &&
				    v->type != VALUE_FLOAT)
					type_mismatch = 1;
				break;
707
			case 's':
708 709
				if (v->type != VALUE_STRING)
					type_mismatch = 1;
Arturo Espinosa's avatar
Arturo Espinosa committed
710
				break;
711
			case 'r':
712 713 714 715 716
				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);
717
				}
Arturo Espinosa's avatar
Arturo Espinosa committed
718
				break;
719 720 721 722 723 724 725 726
			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
727 728 729 730 731

				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);
				}
732 733
				break;
			}
734
			if (type_mismatch){
735 736 737
				free_values (values, arg);
				*error_string = _("Type mismatch");
				return NULL;
738
			}
Arturo Espinosa's avatar
Arturo Espinosa committed
739 740
			values [arg] = v;
		}
Arturo Espinosa's avatar
Arturo Espinosa committed
741 742
		while (arg < fn_argc_max)
			values [arg++] = NULL;
743
		v = fd->fn (fd, values, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
744 745

	free_list:
746
		for (i = 0; i < arg; i++){
Arturo Espinosa's avatar
Arturo Espinosa committed
747 748
			if (values [i] != NULL)
				value_release (values [i]);
749
		}
Arturo Espinosa's avatar
Arturo Espinosa committed
750 751 752 753 754 755
		g_free (values);
		return v;
	}
	return v;
}

756 757 758 759 760
Value *
function_def_call_with_values (Sheet *sheet, FunctionDefinition *fd, int argc,
			       Value *values [], char **error_string)
{
	Value *retval;
761

762 763 764 765 766 767 768 769 770 771 772
	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);
773

774
			for (i = 0; i < argc; i++){
775
				tree [i].oper = OPER_CONSTANT;
776 777
				tree [i].ref_count = 1;
				tree [i].u.constant = values [i];
778

779 780 781
				l = g_list_append (l, &(tree[i]));
			}
		}
782

783 784 785 786 787 788 789
		retval = fd->expr_fn (sheet, l, 0, 0, error_string);

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

790
	} else
791 792 793 794 795 796 797 798 799 800
		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 *
801
function_call_with_values (Sheet *sheet, const char *name, int argc, Value *values[], char **error_string)
802 803 804 805 806 807 808 809 810
{
	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
811
	sym = symbol_lookup (global_symbol_table, name);
812
	if (sym == NULL){
813
		*error_string = _("Function does not exist");
814 815
		return NULL;
	}
816
	if (sym->type != SYMBOL_FUNCTION){
817
		*error_string = _("Calling non-function");
818 819
		return NULL;
	}
820

821 822 823 824 825 826 827 828 829 830
	fd = sym->data;

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

	symbol_unref (sym);

	return retval;
}

831
typedef enum {
Arturo Espinosa's avatar
Arturo Espinosa committed
832 833
	IS_EQUAL,
	IS_LESS,
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858
	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
859

860 861 862 863
/*
 * Compares two (Value *) and returns one of compare_t
 */
static compare_t
Arturo Espinosa's avatar
Arturo Espinosa committed
864 865
compare (Value *a, Value *b)
{
866 867
	if (a->type == VALUE_INTEGER){
		int f;
868

869 870 871 872 873 874 875 876 877 878 879 880 881 882 883
		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:
			f = value_get_as_double (b);
			return compare_float_float (a->v.v_int, f);

		default:
			return TYPE_ERROR;
		}
	}
884

885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916
	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:
			f = value_get_as_double (b);
			return compare_float_float (a->v.v_float, f);

		default:
			return TYPE_ERROR;
		}
	}

	if (a->type == VALUE_STRING && b->type == VALUE_STRING){
		int t;

		t = strcasecmp (a->v.str->str, b->v.str->str);
		if (t == 0)
			return IS_EQUAL;
		else if (t > 0)
			return IS_GREATER;
		else
			return IS_LESS;
	}

	return TYPE_ERROR;
Arturo Espinosa's avatar
Arturo Espinosa committed
917 918
}

Arturo Espinosa's avatar
Arturo Espinosa committed
919
Value *
920
eval_expr (Sheet *sheet, ExprTree *tree, int eval_col, int eval_row, char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
921 922
{
	Value *a, *b, *res;
Arturo Espinosa's avatar
Arturo Espinosa committed
923 924

	g_return_val_if_fail (tree != NULL, NULL);
925
	g_return_val_if_fail (sheet != NULL, NULL);
Arturo Espinosa's avatar
Arturo Espinosa committed
926
	g_return_val_if_fail (error_string != NULL, NULL);
927
	g_return_val_if_fail (IS_SHEET (sheet), NULL);
928

929
	switch (tree->oper){
930 931 932 933 934 935
	case OPER_EQUAL:
	case OPER_NOT_EQUAL:
	case OPER_GT:
	case OPER_GTE:
	case OPER_LT:
	case OPER_LTE: {
Arturo Espinosa's avatar
Arturo Espinosa committed
936
		int comp;
937

Arturo Espinosa's avatar
Arturo Espinosa committed
938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953
		a = eval_expr (sheet, tree->u.binary.value_a,
			       eval_col, eval_row, error_string);
		b = eval_expr (sheet, tree->u.binary.value_b,
			       eval_col, eval_row, error_string);
		if (!(a && b)){
			if (a)
				value_release (a);
			if (b)
				value_release (b);
			return NULL;
		}
		res = g_new (Value, 1);
		res->type = VALUE_INTEGER;

		comp = compare (a, b);

954 955 956 957 958 959
		if (comp == TYPE_ERROR){
			value_release (a);
			value_release (b);
			*error_string = _("Type error");
			return NULL;
		}
960

Arturo Espinosa's avatar
Arturo Espinosa committed
961
		switch (tree->oper){
962
		case OPER_EQUAL:
Arturo Espinosa's avatar
Arturo Espinosa committed
963 964 965
			res->v.v_int = comp == IS_EQUAL;
			break;

966
		case OPER_GT:
967
			res->v.v_int = comp == IS_GREATER;
Arturo Espinosa's avatar
Arturo Espinosa committed
968 969
			break;

970
		case OPER_LT:
Arturo Espinosa's avatar
Arturo Espinosa committed
971 972 973
			res->v.v_int = comp == IS_LESS;
			break;

974
		case OPER_LTE:
Arturo Espinosa's avatar
Arturo Espinosa committed
975 976 977
			res->v.v_int = (comp == IS_EQUAL || comp == IS_LESS);
			break;

978
		case OPER_GTE:
979
			res->v.v_int = (comp == IS_EQUAL || comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
980 981
			break;

982
		case OPER_NOT_EQUAL:
Arturo Espinosa's avatar
Arturo Espinosa committed
983 984
			res->v.v_int = comp != IS_EQUAL;
			break;
985

Arturo Espinosa's avatar
Arturo Espinosa committed
986 987 988 989 990 991 992
		default:
			g_warning ("This should never be reached: comparission ops\n");
		}
		value_release (a);
		value_release (b);
		return res;
	}
993

994 995 996 997 998
	case OPER_ADD:
	case OPER_SUB:
	case OPER_MULT:
	case OPER_DIV:
	case OPER_EXP:
999 1000
		a = eval_expr (sheet, tree->u.binary.value_a,
			       eval_col, eval_row, error_string);
1001 1002 1003

		if (!a)
			return NULL;
1004

1005 1006
		b = eval_expr (sheet, tree->u.binary.value_b,
			       eval_col, eval_row, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
1007

1008 1009
		if (!b){
			value_release (a);
Arturo Espinosa's avatar
Arturo Espinosa committed
1010 1011
			return NULL;
		}
1012

Arturo Espinosa's avatar
Arturo Espinosa committed
1013
		if (!VALUE_IS_NUMBER (a) || !VALUE_IS_NUMBER (b)){
1014 1015
			value_release (a);
			value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
1016 1017 1018
			*error_string = _("Type mismatch");
			return NULL;
		}
1019

Arturo Espinosa's avatar
Arturo Espinosa committed
1020 1021
		res = g_new (Value, 1);
		if (a->type == VALUE_INTEGER && b->type == VALUE_INTEGER){
1022 1023
			int ia = a->v.v_int;
			int ib = b->v.v_int;
1024

Arturo Espinosa's avatar
Arturo Espinosa committed
1025
			res->type = VALUE_INTEGER;
1026

1027
			switch (tree->oper){
1028
			case OPER_SUB:
1029 1030 1031 1032
			case OPER_ADD: {
				int sum;

				if (tree->oper == OPER_SUB){
Arturo Espinosa's avatar
0.20  
Arturo Espinosa committed
1033
					ib = -ib;
1034 1035 1036
				}

				sum = ia + ib;
1037

1038
				if ((ia > 0) && (ib > 0)){
1039

1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
					if (sum < ia){
						res->type = VALUE_FLOAT;
						res->v.v_float = ((double)ia) + ib;
					} else
						res->v.v_int = sum;
				} else if ((ia < 0) && (ib < 0)){
					if (sum > ia){
						res->type = VALUE_FLOAT;
						res->v.v_float = ((double)ia) + ib;
					} else
						res->v.v_int = sum;
				} else
					res->v.v_int = sum;
1053

Arturo Espinosa's avatar
Arturo Espinosa committed
1054
				break;
1055
			}
1056

1057
			case OPER_MULT:
Arturo Espinosa's avatar
Arturo Espinosa committed
1058
				res->v.v_int = a->v.v_int * b->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
1059
				break;
Arturo Espinosa's avatar
Arturo Espinosa committed
1060

1061
			case OPER_DIV:
Arturo Espinosa's avatar
Arturo Espinosa committed
1062
				if (b->v.v_int == 0){
1063 1064 1065
					value_release (a);
					value_release (b);
					value_release (res);
Arturo Espinosa's avatar
Arturo Espinosa committed
1066 1067 1068
					*error_string = _("Division by zero");
					return NULL;
				}
1069 1070
				res->type = VALUE_FLOAT;
				res->v.v_float =  a->v.v_int / (float_t)b->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
1071
				break;
1072 1073

			case OPER_EXP:
Arturo Espinosa's avatar
Arturo Espinosa committed
1074
				res->v.v_int = pow (a->v.v_int, b->v.v_int);
Arturo Espinosa's avatar
Arturo Espinosa committed
1075 1076
				break;
			default:
1077
				break;
Arturo Espinosa's avatar
Arturo Espinosa committed
1078 1079 1080
			}
		} else {
			res->type = VALUE_FLOAT;
Arturo Espinosa's avatar
Arturo Espinosa committed
1081
			res->v.v_float = 0.0;
1082 1083
			a = value_cast_to_float (a);
			b = value_cast_to_float (b);
1084

1085
			switch (tree->oper){
1086
			case OPER_ADD:
Arturo Espinosa's avatar
Arturo Espinosa committed
1087
				res->v.v_float = a->v.v_float + b->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
1088
				break;
1089

1090
			case OPER_SUB:
Arturo Espinosa's avatar
Arturo Espinosa committed
1091
				res->v.v_float = a->v.v_float - b->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
1092
				break;
1093

1094
			case OPER_MULT:
Arturo Espinosa's avatar
Arturo Espinosa committed
1095
				res->v.v_float = a->v.v_float * b->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
1096
				break;
1097

1098
			case OPER_DIV:
Arturo Espinosa's avatar
Arturo Espinosa committed
1099
				if (b->v.v_float == 0.0){
1100 1101 1102
					value_release (a);
					value_release (b);
					value_release (res);
Arturo Espinosa's avatar
Arturo Espinosa committed
1103 1104 1105
					*error_string = _("Division by zero");
					return NULL;
				}
Arturo Espinosa's avatar
Arturo Espinosa committed
1106 1107

				res->v.v_float = a->v.v_float / b->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
1108
				break;
1109

1110
			case OPER_EXP:
Arturo Espinosa's avatar
Arturo Espinosa committed
1111
				res->v.v_float = pow (a->v.v_float, b->v.v_float);
Arturo Espinosa's avatar
Arturo Espinosa committed
1112 1113
				break;
			default:
1114
				break;
Arturo Espinosa's avatar
Arturo Espinosa committed
1115 1116
			}
		}
1117 1118
		value_release (a);
		value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
1119
		return res;