expr.c 43.6 KB
Newer Older
Miguel de Icaza's avatar
Miguel de Icaza committed
1
/*
Morten Welinder's avatar
Morten Welinder committed
2
 * expr.c: Expression evaluation in Gnumeric
Miguel de Icaza's avatar
Miguel de Icaza committed
3 4 5 6
 *
 * 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 21
EvalPosition *
eval_pos_init (EvalPosition *fp, Sheet *s, int col, int row)
22
{
23 24 25 26 27 28 29 30 31
	g_return_val_if_fail (s, NULL);
	g_return_val_if_fail (fp, NULL);
	g_return_val_if_fail (IS_SHEET (s), NULL);

	fp->sheet = s;
	fp->eval_col = col;
	fp->eval_row = row;
	return fp;
}
32

33 34 35 36 37 38 39 40 41 42 43 44 45
EvalPosition *
eval_pos_cell (EvalPosition *fp, Cell *cell)
{
	g_return_val_if_fail (fp, NULL);
	g_return_val_if_fail (cell, NULL);
	g_return_val_if_fail (cell->sheet, NULL);
	g_return_val_if_fail (IS_SHEET (cell->sheet), NULL);

	return eval_pos_init (fp,
			      cell->sheet,
			      cell->col->pos,
			      cell->row->pos);
}
46

47 48 49 50 51 52 53 54 55 56
FunctionEvalInfo *
func_eval_info_init (FunctionEvalInfo *s, Sheet *sheet, int col, int row)
{
	g_return_val_if_fail (s, NULL);
       
	eval_pos_init (&s->pos, sheet, col, row);
	s->error = error_message_new ();
	s->func_def = 0;
	return s;
}
57

58 59 60 61 62 63 64 65 66 67
FunctionEvalInfo *
func_eval_info_cell (FunctionEvalInfo *s, Cell *cell)
{
	g_return_val_if_fail (s, NULL);
	g_return_val_if_fail (cell, NULL);

	return func_eval_info_init (s,
				  cell->sheet,
				  cell->col->pos,
				  cell->row->pos);
68 69
}

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
FunctionEvalInfo *
func_eval_info_pos (FunctionEvalInfo *s, const EvalPosition *fp)
{
	g_return_val_if_fail (s, NULL);
	g_return_val_if_fail (fp, NULL);

	return func_eval_info_init (s,
				    fp->sheet,
				    fp->eval_col,
				    fp->eval_row);
}

ErrorMessage *error_message_new (void)
{
	ErrorMessage *em = g_new (ErrorMessage, 1);

86
	em->err_msg      = 0;
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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
	em->err_alloced  = 0;
	em->small_err[0] = '\0';
	return em;
}

#define ERROR_MESSAGE_CLEAN(em) do { em->err_msg = NULL; \
                                     if (em->err_alloced) { \
					     g_free (em->err_alloced); \
					     em->err_alloced = NULL; \
				     } \
                                     em->small_err[0] = '\0'; \
				} while (0)

void
error_message_set (ErrorMessage *em, const char *message)
{
	g_return_if_fail (em);
	ERROR_MESSAGE_CLEAN (em);

	em->err_msg = message;
}

void
error_message_set_alloc (ErrorMessage *em, char *message)
{
	g_return_if_fail (em);
	ERROR_MESSAGE_CLEAN (em);

	em->err_alloced  = message;
}

void
error_message_set_small (ErrorMessage *em, const char *message)
{
	g_return_if_fail (em);
	g_return_if_fail (message);
	g_return_if_fail (strlen(message) < 19);
	ERROR_MESSAGE_CLEAN (em);

	strcpy (em->small_err, message);
}

const char *
error_message_txt (ErrorMessage *em)
{
	if (!em)
		return _("Internal Error");

	if (em->err_msg)
		return em->err_msg;
	if (em->err_alloced)
		return em->err_msg;
	return em->small_err;
}

/* Can be turned into a #define for speed later */
gboolean
error_message_is_set (ErrorMessage *em)
{
	g_return_val_if_fail (em, FALSE);
	
	if (em->err_msg || em->err_alloced ||
	    em->small_err[0] != '\0')
		return TRUE;
	return FALSE;
}

void
error_message_free (ErrorMessage *em)
{
	if (em->err_alloced) {
		g_free (em->err_alloced);
		em->err_alloced = 0;
	}
	g_free (em);
}
163

164
ExprTree *
Morten Welinder's avatar
Morten Welinder committed
165
expr_tree_new_constant (Value *v)
166
{
167 168 169
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
Morten Welinder's avatar
Morten Welinder committed
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
	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;
}
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
       
Value *
function_error (FunctionEvalInfo *fe, char *error_string)
{
	g_return_val_if_fail (fe, NULL);
	g_return_val_if_fail (error_string, NULL);

	error_message_set (fe->error, error_string);
	return NULL;
}

Value *
function_error_alloc (FunctionEvalInfo *fe, char *error_string)
{
	g_return_val_if_fail (fe, NULL);
	g_return_val_if_fail (error_string, NULL);

	error_message_set_alloc (fe->error, error_string);
	return NULL;
}

ExprTree *
expr_parse_string (const char *expr, const EvalPosition *fp,
		   const char **desired_format, char **error_msg)
{
	ExprTree *tree;
	g_return_val_if_fail (expr != NULL, NULL);

	switch (gnumeric_expr_parser (expr, fp, desired_format, &tree)) {
	case PARSE_OK:
		*error_msg = NULL;
		tree->ref_count = 1;
		return tree;

	case PARSE_ERR_SYNTAX:
		*error_msg = _("Syntax error");
		break;

	case PARSE_ERR_NO_QUOTE:
		*error_msg = _("Missing quote");
		break;
	default:
		g_assert_not_reached ();
		*error_msg = _("Impossible!");
		break;
	}
	return NULL;
}


/*ExprTree *
expr_tree_new (void)
{
	ExprTree *ans;

	ans = g_new (ExprTree, 1);
	if (!ans)
		return NULL;
	
	ans->ref_count = 1;
	ans->oper = OPER_CONSTANT;
	ans->u.constant = NULL;
	return ans;
}*/
Morten Welinder's avatar
Morten Welinder committed
287 288 289 290 291 292 293 294 295 296 297 298

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;
	}
299 300 301
	return ans;
}

Morten Welinder's avatar
Morten Welinder committed
302 303 304 305
ExprTree *
expr_tree_new_error (const char *txt)
{
	Symbol *func;
Morten Welinder's avatar
Morten Welinder committed
306 307 308 309 310 311 312 313 314
	GList *args = NULL;

	if (strcmp (txt, gnumeric_err_NA) == 0) {
		func = symbol_lookup (global_symbol_table, "NA");
	} else {
		func = symbol_lookup (global_symbol_table, "ERROR");
		args = g_list_prepend (NULL,
				       expr_tree_new_constant (value_new_string (txt)));
	}
Morten Welinder's avatar
Morten Welinder committed
315 316

	symbol_ref (func);
Morten Welinder's avatar
Morten Welinder committed
317
	return expr_tree_new_funcall (func, args);
Morten Welinder's avatar
Morten Welinder committed
318 319
}

Arturo Espinosa's avatar
Arturo Espinosa committed
320 321 322 323
/*
 * expr_tree_ref:
 * Increments the ref_count for part of a tree
 */
324 325 326 327 328 329
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
330
	tree->ref_count++;
Arturo Espinosa's avatar
Arturo Espinosa committed
331 332 333 334 335
}

static void
do_expr_tree_unref (ExprTree *tree)
{
Morten Welinder's avatar
Morten Welinder committed
336 337 338
	if (--tree->ref_count > 0)
		return;

Arturo Espinosa's avatar
Arturo Espinosa committed
339
	switch (tree->oper){
340
	case OPER_VAR:
Arturo Espinosa's avatar
Arturo Espinosa committed
341
		break;
342

343
	case OPER_CONSTANT:
Morten Welinder's avatar
Morten Welinder committed
344
		value_release (tree->u.constant);
Arturo Espinosa's avatar
Arturo Espinosa committed
345
		break;
346

Morten Welinder's avatar
Morten Welinder committed
347 348 349 350 351 352 353
	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
354
		break;
Morten Welinder's avatar
Morten Welinder committed
355
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
356

357
	case OPER_ANY_BINARY:
Arturo Espinosa's avatar
Arturo Espinosa committed
358 359 360 361
		do_expr_tree_unref (tree->u.binary.value_a);
		do_expr_tree_unref (tree->u.binary.value_b);
		break;

362
	case OPER_ANY_UNARY:
Arturo Espinosa's avatar
Arturo Espinosa committed
363 364
		do_expr_tree_unref (tree->u.value);
		break;
365 366 367
	default:
		g_warning ("do_expr_tree_unref error\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
368
	}
369

Morten Welinder's avatar
Morten Welinder committed
370
	g_free (tree);
371 372
}

Morten Welinder's avatar
Morten Welinder committed
373 374 375 376 377 378
/*
 * 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.)
 */
379 380 381 382 383 384
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
385
	do_expr_tree_unref (tree);
386 387
}

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
388 389 390 391
/*
 * simplistic value rendering
 */
char *
Michael Meeks's avatar
Michael Meeks committed
392
value_get_as_string (const Value *value)
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
393 394 395 396 397 398
{
	switch (value->type){
	case VALUE_STRING:
		return g_strdup (value->v.str->str);

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

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

404 405 406 407 408
	case VALUE_ARRAY: {
		GString *str = g_string_new ("{");
		guint lpx, lpy;
		char *ans;

409 410 411 412
		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];

413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
				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;
	}
434

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
435
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
436
		break;
437 438 439
	default:
		g_warning ("value_string problem\n");
		break;
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
440
	}
441

Arturo Espinosa's avatar
Arturo Espinosa committed
442
	return g_strdup ("Internal problem");
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
443 444
}

445 446 447
void
value_release (Value *value)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
448
	g_return_if_fail (value != NULL);
449

450 451 452 453 454 455 456
	switch (value->type){
	case VALUE_STRING:
		string_unref (value->v.str);
		break;

	case VALUE_INTEGER:
		mpz_clear (value->v.v_int);
457
		break;
458

459 460 461 462
	case VALUE_FLOAT:
		mpf_clear (value->v.v_float);
		break;

463
	case VALUE_ARRAY:{
464
		guint lpx, lpy;
465

466
		for (lpx = 0; lpx < value->v.array.x; lpx++){
467
			for (lpy = 0; lpy < value->v.array.y; lpy++)
468
				value_release (value->v.array.vals [lpx][lpy]);
469 470
			g_free (value->v.array.vals [lpx]);
		}
471

472
		g_free (value->v.array.vals);
Morten Welinder's avatar
Morten Welinder committed
473
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
474
	}
475

Arturo Espinosa's avatar
Arturo Espinosa committed
476 477
	case VALUE_CELLRANGE:
		break;
478

479 480 481
	default:
		g_warning ("value_release problem\n");
		break;
482
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
483
	g_free (value);
484
}
485

Arturo Espinosa's avatar
Arturo Espinosa committed
486 487 488 489
/*
 * Copies a Value.
 */
void
490
value_copy_to (Value *dest, const Value *source)
Arturo Espinosa's avatar
Arturo Espinosa committed
491 492 493 494 495
{
	g_return_if_fail (dest != NULL);
	g_return_if_fail (source != NULL);

	dest->type = source->type;
496

Arturo Espinosa's avatar
Arturo Espinosa committed
497 498 499 500 501 502 503 504 505 506 507 508 509 510
	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
511
	case VALUE_ARRAY: {
512
		value_array_copy_to (dest, source);
Arturo Espinosa's avatar
Arturo Espinosa committed
513 514 515 516 517
		break;
	}
	case VALUE_CELLRANGE:
		dest->v.cell_range = source->v.cell_range;
		break;
518 519 520
	default:
		g_warning ("value_copy_to problem\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
521 522 523
	}
}

Arturo Espinosa's avatar
Arturo Espinosa committed
524 525 526 527
/*
 * Makes a copy of a Value
 */
Value *
528
value_duplicate (const Value *value)
Arturo Espinosa's avatar
Arturo Espinosa committed
529 530 531 532 533 534
{
	Value *new_value;

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

Arturo Espinosa's avatar
Arturo Espinosa committed
536 537 538
	return new_value;
}

539
Value *
Michael Meeks's avatar
Michael Meeks committed
540
value_new_float (float_t f)
541 542 543 544 545 546 547 548 549 550
{
	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
551
value_new_int (int i)
552 553 554 555 556 557 558 559 560
{
	Value *v = g_new (Value, 1);

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

	return v;
}

561 562 563 564 565 566 567 568
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);
}

569
Value *
Michael Meeks's avatar
Michael Meeks committed
570
value_new_string (const char *str)
571 572 573 574 575 576 577 578 579
{
	Value *v = g_new (Value, 1);

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

	return v;
}

580
Value *
Michael Meeks's avatar
Michael Meeks committed
581
value_new_cellrange (const CellRef *a, const CellRef *b)
582 583
{
	Value *v = g_new (Value, 1);
Morten Welinder's avatar
Morten Welinder committed
584

585
	v->type = VALUE_CELLRANGE;
Morten Welinder's avatar
Morten Welinder committed
586 587 588
	v->v.cell_range.cell_a = *a;
	v->v.cell_range.cell_b = *b;

589 590 591
	return v;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
592 593 594 595
/*
 * Casts a value to float if it is integer, and returns
 * a new Value * if required
 */
596
Value *
597
value_cast_to_float (Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
598 599
{
	Value *newv;
600

Arturo Espinosa's avatar
Arturo Espinosa committed
601 602 603 604
	g_return_val_if_fail (VALUE_IS_NUMBER (v), NULL);

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

Arturo Espinosa's avatar
Arturo Espinosa committed
606 607 608
	newv = g_new (Value, 1);
	newv->type = VALUE_FLOAT;
	mpf_set_z (newv->v.v_float, v->v.v_int);
609
	value_release (v);
610

Arturo Espinosa's avatar
Arturo Espinosa committed
611 612 613
	return newv;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
614
int
Michael Meeks's avatar
Michael Meeks committed
615
value_get_as_bool (const Value *v, int *err)
Arturo Espinosa's avatar
Arturo Espinosa committed
616 617 618
{
	*err = 0;

619 620
	switch (v->type) {
	case VALUE_STRING:
Morten Welinder's avatar
Morten Welinder committed
621 622
		/* FIXME FIXME FIXME */
		/* Use locale to support TRUE, FALSE */
Arturo Espinosa's avatar
Arturo Espinosa committed
623 624
		return atoi (v->v.str->str);

625
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
626 627
		*err = 1;
		return 0;
628 629
		
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
630 631
		return v->v.v_int != 0;

632
	case VALUE_FLOAT:
Arturo Espinosa's avatar
Arturo Espinosa committed
633 634
		return v->v.v_float != 0.0;

635
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
636
		return 0;
637 638 639 640
	default:
		g_warning ("Unhandled value in value_get_boolean");
		break;
	}
Arturo Espinosa's avatar
Arturo Espinosa committed
641 642 643
	return 0;
}

Arturo Espinosa's avatar
Arturo Espinosa committed
644
float_t
Michael Meeks's avatar
Michael Meeks committed
645
value_get_as_float (const Value *v)
Arturo Espinosa's avatar
Arturo Espinosa committed
646
{
647 648 649
	switch (v->type)
	{
	case VALUE_STRING:
Arturo Espinosa's avatar
Arturo Espinosa committed
650 651
		return atof (v->v.str->str);

652
	case VALUE_CELLRANGE:
Arturo Espinosa's avatar
Arturo Espinosa committed
653 654 655
		g_warning ("Getting range as a double: what to do?");
		return 0.0;

656
	case VALUE_INTEGER:
Arturo Espinosa's avatar
Arturo Espinosa committed
657
		return (float_t) v->v.v_int;
658 659
		
	case VALUE_ARRAY:
Arturo Espinosa's avatar
Arturo Espinosa committed
660
		return 0.0;
661

662 663 664
	case VALUE_FLOAT:
		return (float_t) v->v.v_float;
	default:
Michael Meeks's avatar
Michael Meeks committed
665
		g_warning ("value_get_as_float type error\n");
666 667 668
		break;
	}
	return 0.0;
Arturo Espinosa's avatar
Arturo Espinosa committed
669 670
}

671
int
672
value_get_as_int (const Value *v)
673
{
674 675 676
	switch (v->type)
	{
	case VALUE_STRING:
677 678
		return atoi (v->v.str->str);

679
	case VALUE_CELLRANGE:
Morten Welinder's avatar
Morten Welinder committed
680
		g_warning ("Getting range as a int: what to do?");
681
		return 0;
682

683
	case VALUE_INTEGER:
684 685
		return v->v.v_int;

686
	case VALUE_ARRAY:
687
		return 0;
688

689 690 691 692
	case VALUE_FLOAT:
		return (int) v->v.v_float;
	default:
		g_warning ("value_get_as_int unknown type\n");
693
		return 0;
694
	}
Michael Meeks's avatar
Michael Meeks committed
695
	return 0.0;
696 697
}

698 699 700
Value *
value_array_new (guint width, guint height)
{
701
	int x, y;
702 703 704 705 706

	Value *v = g_new (Value, 1);
	v->type = VALUE_ARRAY;
	v->v.array.x = width;
	v->v.array.y = height;
707
	v->v.array.vals = g_new (Value **, width);
708 709

	for (x = 0; x < width; x++){
710 711 712
		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);
713 714 715 716
	}
	return v;
}

Michael Meeks's avatar
Michael Meeks committed
717 718 719 720
void
value_array_set (Value *array, guint col, guint row, Value *v)
{
	g_return_if_fail (v);
721
	g_return_if_fail (array->type == VALUE_ARRAY);
Michael Meeks's avatar
Michael Meeks committed
722 723
	g_return_if_fail (col>=0);
	g_return_if_fail (row>=0);
724 725
	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
726

727 728 729
	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
730 731
}

732 733 734
void
value_array_resize (Value *v, guint width, guint height)
{
735
	int x, y, xcpy, ycpy;
736
	Value *newval;
737
	Value ***tmp;
738

Michael Meeks's avatar
Michael Meeks committed
739
	g_warning ("Totally untested");
740 741 742 743 744 745 746 747
	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
748
		xcpy = width;
749 750 751 752 753 754

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

755 756 757 758 759
	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;
760
	v->v.array.vals = newval->v.array.vals;
761
	newval->v.array.vals = tmp;
762 763
	value_release (newval);

764 765 766 767 768 769 770
	v->v.array.x = width;
	v->v.array.y = height;
}

void
value_array_copy_to (Value *v, const Value *src)
{
771
	int x, y;
772 773 774 775 776

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

779 780 781 782
	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]);
783 784 785 786 787 788 789 790 791
	}
}

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

793 794
	if (v->type == VALUE_ARRAY)
		return v->v.array.x;
795 796 797 798 799 800 801 802
	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;
	}
803 804 805 806 807 808 809 810
}

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

812 813
	if (v->type == VALUE_ARRAY)
		return v->v.array.y;
814 815 816 817 818 819 820 821
	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;
	}
822 823 824 825 826 827 828 829
}

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
830
			     value_new_int (0));
831 832

	if (v->type == VALUE_ARRAY){
833
		g_return_val_if_fail (v->v.array.x < x &&
834
				      v->v.array.y < y,
Michael Meeks's avatar
Michael Meeks committed
835
				     value_new_int (0));
836
		return v->v.array.vals [x][y];
837 838 839
	} else {
		CellRef *a, *b;
		Cell *cell;
840

841 842
		a = &v->v.cell_range.cell_a;
		b = &v->v.cell_range.cell_b;
843 844 845 846 847 848
		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
849
		g_return_val_if_fail (a->sheet,       value_zero);
850 851 852 853 854

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

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

858 859 860
		if (cell && cell->value)
			return cell->value;
	}
Michael Meeks's avatar
Michael Meeks committed
861
	
862
	return value_zero;
863 864
}

865 866 867 868 869 870
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)
871
		cell_ref->col = eval_col + cell_ref->col;
872 873 874

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

Arturo Espinosa's avatar
Arturo Espinosa committed
876 877
	cell_ref->row_relative = 0;
	cell_ref->col_relative = 0;
878 879
}

880 881 882 883 884 885 886 887 888 889 890 891 892 893
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;
	}
}

894 895 896 897
static void
free_values (Value **values, int top)
{
	int i;
898

899
	for (i = 0; i < top; i++)
900 901
		if (values[i])
			value_release (values [i]);
902 903 904
	g_free (values);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
905
static Value *
906
eval_funcall (FunctionEvalInfo *s, ExprTree *tree)
Arturo Espinosa's avatar
Arturo Espinosa committed
907
{
908
	const Symbol *sym;
Arturo Espinosa's avatar
Arturo Espinosa committed
909 910 911
	FunctionDefinition *fd;
	GList *l;
	int argc, arg, i;
912
	Value *v = NULL;
913 914 915 916 917 918
	Sheet *sheet;
	int eval_col;
	int eval_row;

	g_return_val_if_fail (s, NULL);
	g_return_val_if_fail (tree, NULL);
919

920
	sym = tree->u.function.symbol;
921 922 923 924 925

	sheet    = s->pos.sheet;
	eval_col = s->pos.eval_col;
	eval_row = s->pos.eval_row;

Arturo Espinosa's avatar
Arturo Espinosa committed
926 927 928
	l = tree->u.function.arg_list;
	argc = g_list_length (l);

929 930 931
	if (sym->type != SYMBOL_FUNCTION)
		return function_error (s, _("Internal error"));

932
	fd = (FunctionDefinition *)sym->data;
Morten Welinder's avatar
Morten Welinder committed
933
	s->func_def = fd;
934

935 936 937 938
	if (fd->fn_type == FUNCTION_NODES) {
		/* Functions that deal with ExprNodes */		
		v = ((FunctionNodes *)fd->fn) (s, l);
	} else {
Arturo Espinosa's avatar
Arturo Espinosa committed
939 940
		/* Functions that take pre-computed Values */
		Value **values;
Arturo Espinosa's avatar
Arturo Espinosa committed
941
		int fn_argc_min = 0, fn_argc_max = 0, var_len = 0;
942 943
		const char *arg_type = fd->args;
		const char *argptr = fd->args;
944

945
		/* Get variable limits */
Arturo Espinosa's avatar
Arturo Espinosa committed
946 947 948 949
		while (*argptr){
			if (*argptr++ == '|'){
				var_len = 1;
				continue;
950 951
			}
			if (!var_len)
Arturo Espinosa's avatar
Arturo Espinosa committed
952 953
				fn_argc_min++;
			fn_argc_max++;
954
		}
955

956 957
		if (argc > fn_argc_max || argc < fn_argc_min) {
			error_message_set (s->error, _("Invalid number of arguments"));
Arturo Espinosa's avatar
Arturo Espinosa committed
958 959 960
			return NULL;
		}

961
		values = g_new (Value *, fn_argc_max);
962

963
		for (arg = 0; l; l = l->next, arg++, arg_type++){
Arturo Espinosa's avatar
Arturo Espinosa committed
964
			ExprTree *t = (ExprTree *) l->data;
965
			int type_mismatch = 0;
966
			Value *v;
967

Arturo Espinosa's avatar
Arturo Espinosa committed
968 969
			if (*arg_type=='|')
				arg_type++;
970 971 972 973

			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 */
Morten Welinder's avatar
Morten Welinder committed
974
				if ((v = eval_expr (s, t)) == NULL)
975 976 977
					goto free_list;
			} else {
				g_assert (t->oper == OPER_VAR);
978
				v = value_new_cellrange (&t->u.ref,
Michael Meeks's avatar
Michael Meeks committed
979
							 &t->u.ref);
980 981 982 983 984
				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;
			}
985

Arturo Espinosa's avatar
Arturo Espinosa committed
986
			switch (*arg_type){
987
			case 'f':
Morten Welinder's avatar
Morten Welinder committed
988
			case 'b':
989 990 991 992
				if (v->type != VALUE_INTEGER &&
				    v->type != VALUE_FLOAT)
					type_mismatch = 1;
				break;
993
			case 's':
994 995
				if (v->type != VALUE_STRING)
					type_mismatch = 1;
Arturo Espinosa's avatar
Arturo Espinosa committed
996
				break;
997
			case 'r':
998 999 1000 1001 1002
				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);
1003
				}
Arturo Espinosa's avatar
Arturo Espinosa committed
1004
				break;
1005 1006 1007 1008 1009 1010 1011 1012
			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
1013 1014 1015 1016 1017

				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);
				}
1018 1019
				break;
			}
1020
			values [arg] = v;
1021
			if (type_mismatch){
1022
				free_values (values, arg + 1);
1023
				error_message_set (s->error, _("Type mismatch"));
1024
				return NULL;
1025
			}
Arturo Espinosa's avatar
Arturo Espinosa committed
1026
		}
Arturo Espinosa's avatar
Arturo Espinosa committed
1027 1028
		while (arg < fn_argc_max)
			values [arg++] = NULL;
1029
		v = ((FunctionArgs *)fd->fn) (s, values);
Arturo Espinosa's avatar
Arturo Espinosa committed
1030 1031

	free_list:
1032
		free_values (values, arg);
Arturo Espinosa's avatar
Arturo Espinosa committed
1033 1034 1035 1036
	}
	return v;
}

1037
Value *
1038 1039 1040 1041 1042
function_def_call_with_values (const EvalPosition *ep,
			       FunctionDefinition *fd,
			       int                 argc,
			       Value              *values [],
			       ErrorMessage       *error)
1043 1044
{
	Value *retval;
1045 1046 1047 1048
	FunctionEvalInfo s;

	func_eval_info_pos (&s, ep);
	s.error = error;
1049

1050
	if (fd->fn_type == FUNCTION_NODES) {
1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
		/*
		 * 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);
1061

1062
			for (i = 0; i < argc; i++){
1063
				tree [i].oper = OPER_CONSTANT;
1064 1065
				tree [i].ref_count = 1;
				tree [i].u.constant = values [i];
1066

1067 1068 1069
				l = g_list_append (l, &(tree[i]));
			}
		}
1070

1071
		retval = ((FunctionNodes *)fd->fn) (&s, l);
1072 1073 1074 1075 1076 1077

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

1078
	} else
1079
		retval = ((FunctionArgs *)fd->fn) (&s, values);
1080 1081 1082 1083 1084 1085 1086 1087 1088

	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 *
1089 1090
function_call_with_values (const EvalPosition *ep, const char *name,
			   int argc, Value *values[], ErrorMessage *error)
1091 1092 1093 1094 1095
{
	FunctionDefinition *fd;
	Value *retval;
	Symbol *sym;

1096 1097
	g_return_val_if_fail (ep, NULL);
	g_return_val_if_fail (ep->sheet != NULL, NULL);
1098 1099
	g_return_val_if_fail (name != NULL, NULL);

Miguel de Icaza's avatar
Miguel de Icaza committed
1100
	sym = symbol_lookup (global_symbol_table, name);
1101
	if (sym == NULL){
1102
		error_message_set (error, _("Function does not exist"));
1103 1104
		return NULL;
	}