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

18
19
Value *value_zero = NULL;

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

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

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

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

48

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

148
149
150
151
152
	case VALUE_ARRAY: {
		GString *str = g_string_new ("{");
		guint lpx, lpy;
		char *ans;

153
154
155
156
		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];

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
				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;
	}
178

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

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

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

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

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

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

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

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

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

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

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

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

	dest->type = source->type;
240

Arturo Espinosa's avatar
Arturo Espinosa committed
241
242
243
244
245
246
247
248
249
250
251
252
253
254
	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
255
	case VALUE_ARRAY: {
256
		value_array_copy_to (dest, source);
Arturo Espinosa's avatar
Arturo Espinosa committed
257
258
259
260
261
		break;
	}
	case VALUE_CELLRANGE:
		dest->v.cell_range = source->v.cell_range;
		break;
262
263
264
	default:
		g_warning ("value_copy_to problem\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
265
266
267
	}
}

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

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

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

283
Value *
Michael Meeks's avatar
Michael Meeks committed
284
value_new_float (float_t f)
285
286
287
288
289
290
291
292
293
294
{
	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
295
value_new_int (int i)
296
297
298
299
300
301
302
303
304
{
	Value *v = g_new (Value, 1);

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

	return v;
}

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

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

	return v;
}

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

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

325
326
327
	return v;
}

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

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

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

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

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

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

355
356
	switch (v->type) {
	case VALUE_STRING:
Morten Welinder's avatar
Morten Welinder committed
357
358
		/* FIXME FIXME FIXME */
		/* Use locale to support TRUE, FALSE */
Arturo Espinosa's avatar
Arturo Espinosa committed
359
360
		return atoi (v->v.str->str);

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

368
	case VALUE_FLOAT:
Arturo Espinosa's avatar
Arturo Espinosa committed
369
370
		return v->v.v_float != 0.0;

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

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

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

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

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

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

415
	case VALUE_CELLRANGE:
Morten Welinder's avatar
Morten Welinder committed
416
		g_warning ("Getting range as a int: what to do?");
417
		return 0;
418

419
	case VALUE_INTEGER:
420
421
		return v->v.v_int;

422
	case VALUE_ARRAY:
423
		return 0;
424

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

434
435
436
Value *
value_array_new (guint width, guint height)
{
437
	int x, y;
438
439
440
441
442

	Value *v = g_new (Value, 1);
	v->type = VALUE_ARRAY;
	v->v.array.x = width;
	v->v.array.y = height;
443
	v->v.array.vals = g_new (Value **, width);
444
445

	for (x = 0; x < width; x++){
446
447
448
		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);
449
450
451
452
	}
	return v;
}

Michael Meeks's avatar
Michael Meeks committed
453
454
455
456
void
value_array_set (Value *array, guint col, guint row, Value *v)
{
	g_return_if_fail (v);
457
	g_return_if_fail (array->type == VALUE_ARRAY);
Michael Meeks's avatar
Michael Meeks committed
458
459
	g_return_if_fail (col>=0);
	g_return_if_fail (row>=0);
460
461
	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
462

463
464
465
	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
466
467
}

468
469
470
void
value_array_resize (Value *v, guint width, guint height)
{
471
	int x, y, xcpy, ycpy;
472
	Value *newval;
473
	Value ***tmp;
474

Michael Meeks's avatar
Michael Meeks committed
475
	g_warning ("Totally untested");
476
477
478
479
480
481
482
483
	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
484
		xcpy = width;
485
486
487
488
489
490

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

491
492
493
494
495
	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;
496
	v->v.array.vals = newval->v.array.vals;
497
	newval->v.array.vals = tmp;
498
499
	value_release (newval);

500
501
502
503
504
505
506
	v->v.array.x = width;
	v->v.array.y = height;
}

void
value_array_copy_to (Value *v, const Value *src)
{
507
	int x, y;
508
509
510
511
512

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

515
516
517
518
	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]);
519
520
521
522
523
524
525
526
527
	}
}

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

529
530
	if (v->type == VALUE_ARRAY)
		return v->v.array.x;
531
532
533
534
535
536
537
538
	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;
	}
539
540
541
542
543
544
545
546
}

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

548
549
	if (v->type == VALUE_ARRAY)
		return v->v.array.y;
550
551
552
553
554
555
556
557
	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;
	}
558
559
560
561
562
563
564
565
}

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
566
			     value_new_int (0));
567
568

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

577
578
		a = &v->v.cell_range.cell_a;
		b = &v->v.cell_range.cell_b;
579
580
581
582
583
584
		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
585
		g_return_val_if_fail (a->sheet,       value_zero);
586
587
588
589
590

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

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

594
595
596
		if (cell && cell->value)
			return cell->value;
	}
Michael Meeks's avatar
Michael Meeks committed
597
	
598
	return value_zero;
599
600
}

601
602
603
604
605
606
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)
607
		cell_ref->col = eval_col + cell_ref->col;
608
609
610

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

Arturo Espinosa's avatar
Arturo Espinosa committed
612
613
	cell_ref->row_relative = 0;
	cell_ref->col_relative = 0;
614
615
}

616
617
618
619
620
621
622
623
624
625
626
627
628
629
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;
	}
}

630
#if 0
Arturo Espinosa's avatar
Arturo Espinosa committed
631
632
static Value *
eval_cell_value (Sheet *sheet, Value *value)
633
{
Arturo Espinosa's avatar
Arturo Espinosa committed
634
	Value *res;
635

Arturo Espinosa's avatar
Arturo Espinosa committed
636
637
	res = g_new (Value, 1);
	res->type = value->type;
638

Arturo Espinosa's avatar
Arturo Espinosa committed
639
640
641
	switch (res->type){
	case VALUE_STRING:
		res->v.str = value->v.str;
642
		string_ref (res->v.str);
Arturo Espinosa's avatar
Arturo Espinosa committed
643
		break;
644

Arturo Espinosa's avatar
Arturo Espinosa committed
645
	case VALUE_INTEGER:
646
		res->v.v_int = value->v.v_int;
Arturo Espinosa's avatar
Arturo Espinosa committed
647
		break;
648

Arturo Espinosa's avatar
Arturo Espinosa committed
649
	case VALUE_FLOAT:
650
		res->v.v_float = value->v.v_float;
Arturo Espinosa's avatar
Arturo Espinosa committed
651
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
652
653

	case VALUE_ARRAY:
Michael Meeks's avatar
Michael Meeks committed
654
		res = value_duplicate (value);
Arturo Espinosa's avatar
Arturo Espinosa committed
655
		break;
656

Arturo Espinosa's avatar
Arturo Espinosa committed
657
658
659
	case VALUE_CELLRANGE:
		res->v.cell_range = value->v.cell_range;
		break;
660
661
662
	default:
		g_warning ("eval_cell_value error\n");
		break;
Arturo Espinosa's avatar
Arturo Espinosa committed
663
664
665
	}
	return res;
}
666
#endif
Arturo Espinosa's avatar
Arturo Espinosa committed
667

668
669
670
671
static void
free_values (Value **values, int top)
{
	int i;
672

673
	for (i = 0; i < top; i++)
674
675
		if (values[i])
			value_release (values [i]);
676
677
678
	g_free (values);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
679
680
681
682
683
684
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;
685
	Value *v = NULL;
686

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

Arturo Espinosa's avatar
Arturo Espinosa committed
689
690
691
692
693
694
695
696
697
698
699
700
	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
701
702
703
		int fn_argc_min = 0, fn_argc_max = 0, var_len = 0;
		char *arg_type = fd->args;
		char *argptr = fd->args;
704

705
		/* Get variable limits */
Arturo Espinosa's avatar
Arturo Espinosa committed
706
707
708
709
		while (*argptr){
			if (*argptr++ == '|'){
				var_len = 1;
				continue;
710
711
			}
			if (!var_len)
Arturo Espinosa's avatar
Arturo Espinosa committed
712
713
				fn_argc_min++;
			fn_argc_max++;
714
		}
715

Arturo Espinosa's avatar
Arturo Espinosa committed
716
		if (argc > fn_argc_max || argc < fn_argc_min){
Arturo Espinosa's avatar
Arturo Espinosa committed
717
718
719
720
			*error_string = _("Invalid number of arguments");
			return NULL;
		}

721
		values = g_new (Value *, fn_argc_max);
722

723
		for (arg = 0; l; l = l->next, arg++, arg_type++){
Arturo Espinosa's avatar
Arturo Espinosa committed
724
			ExprTree *t = (ExprTree *) l->data;
725
			int type_mismatch = 0;
726
			Value *v;
727

Arturo Espinosa's avatar
Arturo Espinosa committed
728
729
			if (*arg_type=='|')
				arg_type++;
730
731
732
733
734
735
736
737
738

			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
739
740
				v =value_new_cellrange (&t->u.ref,
							 &t->u.ref);
741
742
743
744
745
				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;
			}
746

Arturo Espinosa's avatar
Arturo Espinosa committed
747
			switch (*arg_type){
748
			case 'f':
749

750
751
752
753
				if (v->type != VALUE_INTEGER &&
				    v->type != VALUE_FLOAT)
					type_mismatch = 1;
				break;
754
			case 's':
755
756
				if (v->type != VALUE_STRING)
					type_mismatch = 1;
Arturo Espinosa's avatar
Arturo Espinosa committed
757
				break;
758
			case 'r':
759
760
761
762
763
				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);
764
				}
Arturo Espinosa's avatar
Arturo Espinosa committed
765
				break;
766
767
768
769
770
771
772
773
			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
774
775
776
777
778

				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);
				}
779
780
				break;
			}
781
			values [arg] = v;
782
			if (type_mismatch){
783
				free_values (values, arg + 1);
784
785
				*error_string = _("Type mismatch");
				return NULL;
786
			}
Arturo Espinosa's avatar
Arturo Espinosa committed
787
		}
Arturo Espinosa's avatar
Arturo Espinosa committed
788
789
		while (arg < fn_argc_max)
			values [arg++] = NULL;
790
		v = fd->fn (fd, values, error_string);
Arturo Espinosa's avatar
Arturo Espinosa committed
791
792

	free_list:
793
		free_values (values, arg);
Arturo Espinosa's avatar
Arturo Espinosa committed
794
795
796
797
	}
	return v;
}

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

804
805
806
807
808
809
810
811
812
813
814
	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);
815

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

821
822
823
				l = g_list_append (l, &(tree[i]));
			}
		}
824

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

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

832
	} else
833
834
835
836
837
838
839
840
841
842
		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 *
843
function_call_with_values (Sheet *sheet, const char *name, int argc, Value *values[], char **error_string)
844
845
846
847
848
849
850
851
852
{
	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
853
	sym = symbol_lookup (global_symbol_table, name);
854
	if (sym == NULL){
855
		*error_string = _("Function does not exist");
856
857
		return NULL;
	}
858
	if (sym->type != SYMBOL_FUNCTION){
859
		*error_string = _("Calling non-function");
860
861
		return NULL;
	}
862

863
864
865
866
867
868
869
870
871
872
	fd = sym->data;

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

	symbol_unref (sym);

	return retval;
}

873
typedef enum {
Arturo Espinosa's avatar
Arturo Espinosa committed
874
875
	IS_EQUAL,
	IS_LESS,
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
	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
901

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

911
912
913
914
915
916
917
918
		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:
919
			f = value_get_as_float (b);
920
921
922
923
924
925
			return compare_float_float (a->v.v_int, f);

		default:
			return TYPE_ERROR;
		}
	}
926

927
928
929
930
931
932
933
934
935
936
937
	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:
938
			f = value_get_as_float (b);
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
			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
959
960
}

Arturo Espinosa's avatar
Arturo Espinosa committed
961
Value *
962
eval_expr (Sheet *sheet, ExprTree *tree, int eval_col, int eval_row, char **error_string)
Arturo Espinosa's avatar
Arturo Espinosa committed
963
964
{
	Value *a, *b, *res;
Arturo Espinosa's avatar
Arturo Espinosa committed
965
966

	g_return_val_if_fail (tree != NULL, NULL);
967
	g_return_val_if_fail (sheet != NULL, NULL);
Arturo Espinosa's avatar
Arturo Espinosa committed
968
	g_return_val_if_fail (error_string != NULL, NULL);
969
	g_return_val_if_fail (IS_SHEET (sheet), NULL);
970

971
	switch (tree->oper){
972
973
974
975
976
977
	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
978
		int comp;
979

Arturo Espinosa's avatar
Arturo Espinosa committed
980
981
982
983
984
985
986
987
988
989
990
991
		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;
		}
		comp = compare (a, b);
992
993
		value_release (a);
		value_release (b);
Arturo Espinosa's avatar
Arturo Espinosa committed
994

995
996
997
998
		if (comp == TYPE_ERROR){
			*error_string = _("Type error");
			return NULL;
		}
999

Arturo Espinosa's avatar
Arturo Espinosa committed
1000
		switch (tree->oper){
1001
		case OPER_EQUAL:
1002
			res = value_new_int (comp == IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
1003
1004
			break;

1005
		case OPER_GT:
1006
			res = value_new_int (comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
1007
1008
			break;

1009
		case OPER_LT:
1010
			res = value_new_int (comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
1011
1012
			break;

1013
		case OPER_LTE:
1014
			res = value_new_int (comp == IS_EQUAL || comp == IS_LESS);
Arturo Espinosa's avatar
Arturo Espinosa committed
1015
1016
			break;

1017
		case OPER_GTE:
1018
			res = value_new_int (comp == IS_EQUAL || comp == IS_GREATER);
Arturo Espinosa's avatar
Arturo Espinosa committed
1019
1020
			break;

1021
		case OPER_NOT_EQUAL:
1022
			res = value_new_int (comp != IS_EQUAL);
Arturo Espinosa's avatar
Arturo Espinosa committed
1023
			break;
1024

Arturo Espinosa's avatar
Arturo Espinosa committed
1025
		default:
1026
1027
1028
			g_assert_not_reached ();
			*error_string = "Internal error";
			res = NULL;
Arturo Espinosa's avatar