Updated Czech translation
[gnumeric.git] / src / value.c
blob3704d4b9a4fa8f57aeb5b110d82a3de37fdce178
1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * value.c: Utilies for handling, creating, removing values.
5 * Authors:
6 * Miguel de Icaza (miguel@gnu.org).
7 * Michael Meeks (mmeeks@gnu.org)
8 * Jody Goldberg (jgolderg@home.com)
9 * Copyright (C) 2000-2009 Morten Welinder (terra@gnome.org)
12 #include <gnumeric-config.h>
13 #include <glib/gi18n-lib.h>
14 #include "gnumeric.h"
15 #include "value.h"
17 #include "parse-util.h"
18 #include "style.h"
19 #include "gnm-format.h"
20 #include "position.h"
21 #include "mathfunc.h"
22 #include "gutils.h"
23 #include "workbook.h"
24 #include "expr.h"
25 #include <ranges.h>
26 #include <sheet.h>
27 #include <cell.h>
28 #include <number-match.h>
29 #include <goffice/goffice.h>
31 #include <stdlib.h>
32 #include <errno.h>
33 #include <math.h>
34 #include <string.h>
36 #ifndef USE_VALUE_POOLS
37 #define USE_VALUE_POOLS 0
38 #endif
40 #if USE_VALUE_POOLS
41 static GOMemChunk *value_float_pool;
42 static GOMemChunk *value_error_pool;
43 static GOMemChunk *value_string_pool;
44 static GOMemChunk *value_range_pool;
45 static GOMemChunk *value_array_pool;
46 #define CHUNK_ALLOC(T,p) ((T*)go_mem_chunk_alloc (p))
47 #define CHUNK_FREE(p,v) go_mem_chunk_free ((p), (v))
48 #else
49 static int value_allocations = 0;
50 #define CHUNK_ALLOC(T,c) (value_allocations++, g_slice_new (T))
51 #define CHUNK_FREE(p,v) (value_allocations--, g_slice_free1 (sizeof(*v),(v)))
52 #endif
55 static struct {
56 char const *C_name;
57 char const *locale_name;
58 GOString *locale_name_str;
59 } standard_errors[] = {
60 { N_("#NULL!"), NULL, NULL },
61 { N_("#DIV/0!"), NULL, NULL },
62 { N_("#VALUE!"), NULL, NULL },
63 { N_("#REF!"), NULL, NULL },
64 { N_("#NAME?"), NULL, NULL },
65 { N_("#NUM!"), NULL, NULL },
66 { N_("#N/A"), NULL, NULL },
67 { N_("#UNKNOWN!"), NULL, NULL }
70 GnmValue *
71 value_new_empty (void)
73 /* This is a constant. No need to allocate any memory. */
74 static const GnmValueAny v = { VALUE_EMPTY, NULL };
75 return (GnmValue *)&v;
78 GnmValue *
79 value_new_bool (gboolean b)
81 /* These are constant. No need to allocate any memory. */
82 static const GnmValueBool vf = { VALUE_BOOLEAN, NULL, FALSE };
83 static const GnmValueBool vt = { VALUE_BOOLEAN, NULL, TRUE };
84 return (GnmValue*) (b ? &vt : &vf);
87 GnmValue *
88 value_new_int (int i)
90 return value_new_float (i);
93 GnmValue *
94 value_new_float (gnm_float f)
96 if (gnm_finite (f)) {
97 GnmValueFloat *v = CHUNK_ALLOC (GnmValueFloat, value_float_pool);
98 *((GnmValueType *)&(v->type)) = VALUE_FLOAT;
99 v->fmt = NULL;
100 v->val = f;
101 return (GnmValue *)v;
102 } else {
103 /* FIXME: bogus ep sent here. What to do? */
104 return value_new_error_NUM (NULL);
108 GnmValue *
109 value_new_error (G_GNUC_UNUSED GnmEvalPos const *ep, char const *mesg)
111 GnmValueErr *v = CHUNK_ALLOC (GnmValueErr, value_error_pool);
112 *((GnmValueType *)&(v->type)) = VALUE_ERROR;
113 v->fmt = NULL;
114 v->mesg = go_string_new (mesg);
115 return (GnmValue *)v;
118 GnmValue *
119 value_new_error_str (G_GNUC_UNUSED GnmEvalPos const *ep, GOString *mesg)
121 GnmValueErr *v = CHUNK_ALLOC (GnmValueErr, value_error_pool);
122 *((GnmValueType *)&(v->type)) = VALUE_ERROR;
123 v->fmt = NULL;
124 v->mesg = go_string_ref (mesg);
125 return (GnmValue *)v;
128 GnmValue *
129 value_new_error_std (GnmEvalPos const *pos, GnmStdError err)
131 size_t i = (size_t)err;
132 g_return_val_if_fail (i < G_N_ELEMENTS (standard_errors), NULL);
134 return value_new_error_str (pos, standard_errors[i].locale_name_str);
138 GnmValue *
139 value_new_error_NULL (GnmEvalPos const *pos)
141 return value_new_error_str (pos, standard_errors[GNM_ERROR_NULL].locale_name_str);
144 GnmValue *
145 value_new_error_DIV0 (GnmEvalPos const *pos)
147 return value_new_error_str (pos, standard_errors[GNM_ERROR_DIV0].locale_name_str);
150 GnmValue *
151 value_new_error_VALUE (GnmEvalPos const *pos)
153 return value_new_error_str (pos, standard_errors[GNM_ERROR_VALUE].locale_name_str);
156 GnmValue *
157 value_new_error_REF (GnmEvalPos const *pos)
159 return value_new_error_str (pos, standard_errors[GNM_ERROR_REF].locale_name_str);
162 GnmValue *
163 value_new_error_NAME (GnmEvalPos const *pos)
165 return value_new_error_str (pos, standard_errors[GNM_ERROR_NAME].locale_name_str);
168 GnmValue *
169 value_new_error_NUM (GnmEvalPos const *pos)
171 return value_new_error_str (pos, standard_errors[GNM_ERROR_NUM].locale_name_str);
174 GnmValue *
175 value_new_error_NA (GnmEvalPos const *pos)
177 return value_new_error_str (pos, standard_errors[GNM_ERROR_NA].locale_name_str);
180 char const *
181 value_error_name (GnmStdError err, gboolean translated)
183 size_t i = (size_t)err;
184 g_return_val_if_fail (i < G_N_ELEMENTS (standard_errors), NULL);
186 if (translated)
187 return standard_errors[i].locale_name;
188 else
189 return standard_errors[i].C_name;
193 * value_error_set_pos:
194 * @err:
195 * @pos:
197 * Change the position of a ValueError.
199 GnmValue *
200 value_error_set_pos (GnmValueErr *err, G_GNUC_UNUSED GnmEvalPos const *pos)
202 g_return_val_if_fail (err != NULL, NULL);
203 g_return_val_if_fail (VALUE_IS_ERROR (err), NULL);
205 /* err->src = *pos; */
206 return (GnmValue *)err;
209 GnmStdError
210 value_error_classify (GnmValue const *v)
212 size_t i;
214 g_return_val_if_fail (v != NULL, GNM_ERROR_UNKNOWN);
216 if (!VALUE_IS_ERROR (v))
217 return GNM_ERROR_UNKNOWN;
219 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++)
220 if (standard_errors[i].locale_name_str == v->v_err.mesg)
221 return (GnmStdError)i;
223 return GNM_ERROR_UNKNOWN;
227 /* NOTE : absorbs the reference */
228 GnmValue *
229 value_new_string_str (GOString *str)
231 GnmValueStr *v;
233 g_return_val_if_fail (str != NULL, NULL);
235 v = CHUNK_ALLOC (GnmValueStr, value_string_pool);
236 *((GnmValueType *)&(v->type)) = VALUE_STRING;
237 v->fmt = NULL;
238 v->val = str;
239 return (GnmValue *)v;
242 GnmValue *
243 value_new_string (char const *str)
245 return value_new_string_str (go_string_new (str));
248 GnmValue *
249 value_new_string_nocopy (char *str)
251 return value_new_string_str (go_string_new_nocopy (str));
254 GnmValue *
255 value_new_cellrange_unsafe (GnmCellRef const *a, GnmCellRef const *b)
257 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
258 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
259 v->fmt = NULL;
260 v->cell.a = *a;
261 v->cell.b = *b;
262 return (GnmValue *)v;
266 * value_new_cellrange:
268 * Create a new range reference.
270 * Attempt to do a sanity check for inverted ranges.
271 * NOTE : This is no longer necessary and will be removed.
272 * mixed mode references create the possibility of inversion.
273 * users of these values need to use the utility routines to
274 * evaluate the ranges in their context and normalize then.
276 GnmValue *
277 value_new_cellrange (GnmCellRef const *a, GnmCellRef const *b,
278 int eval_col, int eval_row)
280 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
281 int tmp;
283 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
284 v->fmt = NULL;
285 v->cell.a = *a;
286 v->cell.b = *b;
288 /* Sanity checking to avoid inverted ranges */
289 tmp = a->col;
290 if (a->col_relative != b->col_relative) {
291 /* Make a tmp copy of a in the same mode as b */
292 if (a->col_relative)
293 tmp += eval_col;
294 else
295 tmp -= eval_col;
297 if (tmp > b->col) {
298 v->cell.a.col = b->col;
299 v->cell.a.col_relative = b->col_relative;
300 v->cell.b.col = a->col;
301 v->cell.b.col_relative = a->col_relative;
304 tmp = a->row;
305 if (a->row_relative != b->row_relative) {
306 /* Make a tmp copy of a in the same mode as b */
307 if (a->row_relative)
308 tmp += eval_row;
309 else
310 tmp -= eval_row;
312 if (tmp > b->row) {
313 v->cell.a.row = b->row;
314 v->cell.a.row_relative = b->row_relative;
315 v->cell.b.row = a->row;
316 v->cell.b.row_relative = a->row_relative;
319 return (GnmValue *)v;
322 GnmValue *
323 value_new_cellrange_r (Sheet *sheet, GnmRange const *r)
325 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
326 GnmCellRef *a, *b;
328 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
329 v->fmt = NULL;
330 a = &v->cell.a;
331 b = &v->cell.b;
333 a->sheet = sheet;
334 b->sheet = sheet;
335 a->col = r->start.col;
336 a->row = r->start.row;
337 b->col = r->end.col;
338 b->row = r->end.row;
339 a->col_relative = b->col_relative = FALSE;
340 a->row_relative = b->row_relative = FALSE;
342 return (GnmValue *)v;
346 * value_new_cellrange_str:
347 * @sheet: the sheet where the cell range is evaluated. This really only needed if
348 * the range given does not include a sheet specification.
349 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
351 * Parse @str using the convention associated with @sheet.
352 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
353 * succesfully parsed or NULL on failure.
355 GnmValue *
356 value_new_cellrange_str (Sheet *sheet, char const *str)
358 GnmParsePos pp;
359 GnmExprParseFlags flags = GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS |
360 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES;
362 g_return_val_if_fail (IS_SHEET (sheet), NULL);
363 g_return_val_if_fail (str != NULL, NULL);
365 parse_pos_init_sheet (&pp, sheet);
366 return value_new_cellrange_parsepos_str (&pp, str, flags);
370 * value_new_cellrange_parsepos_str:
371 * @pp: if a relative range is specified, then it will be interpreted relative
372 * to this position (affects only A1-style relative references).
373 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
375 * Parse @str using the convention associated with @sheet.
376 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
377 * succesfully parsed or NULL on failure.
379 GnmValue *
380 value_new_cellrange_parsepos_str (GnmParsePos const *pp, char const *str,
381 GnmExprParseFlags flags)
383 GnmExprTop const *texpr;
384 GnmConventions const *convs = NULL;
386 g_return_val_if_fail (pp != NULL, NULL);
387 g_return_val_if_fail (str != NULL, NULL);
389 if (pp->sheet)
390 convs = pp->sheet->convs;
392 texpr = gnm_expr_parse_str (str, pp, flags, convs, NULL);
394 if (texpr != NULL) {
395 GnmValue *value = gnm_expr_top_get_range (texpr);
396 gnm_expr_top_unref (texpr);
397 return value;
400 return NULL;
403 GnmValue *
404 value_new_array_non_init (guint cols, guint rows)
406 GnmValueArray *v = CHUNK_ALLOC (GnmValueArray, value_array_pool);
407 *((GnmValueType *)&(v->type)) = VALUE_ARRAY;
408 v->fmt = NULL;
409 v->x = cols;
410 v->y = rows;
411 v->vals = g_new (GnmValue **, cols);
412 return (GnmValue *)v;
415 GnmValue *
416 value_new_array (guint cols, guint rows)
418 guint x, y;
419 GnmValueArray *v = (GnmValueArray *)value_new_array_non_init (cols, rows);
421 for (x = 0; x < cols; x++) {
422 v->vals[x] = g_new (GnmValue *, rows);
423 for (y = 0; y < rows; y++)
424 v->vals[x][y] = value_new_int (0);
426 return (GnmValue *)v;
429 GnmValue *
430 value_new_array_empty (guint cols, guint rows)
432 guint x, y;
433 GnmValueArray *v = (GnmValueArray *)value_new_array_non_init (cols, rows);
435 for (x = 0; x < cols; x++) {
436 v->vals[x] = g_new (GnmValue *, rows);
437 for (y = 0; y < rows; y++)
438 v->vals[x][y] = NULL;
440 return (GnmValue *)v;
444 * Returns TRUE, FALSE, or -1.
446 static int
447 value_parse_boolean (char const *str, gboolean translated)
449 if (translated) {
450 /* FIXME: ascii??? */
451 if (0 == g_ascii_strcasecmp (str, go_locale_boolean_name (TRUE)))
452 return +TRUE;
453 else if (0 == g_ascii_strcasecmp (str, go_locale_boolean_name (FALSE)))
454 return +FALSE;
455 else
456 return -1;
457 } else {
458 if (0 == g_ascii_strcasecmp (str, "TRUE"))
459 return +TRUE;
460 else if (0 == g_ascii_strcasecmp (str, "FALSE"))
461 return +FALSE;
462 else
463 return -1;
468 GnmValue *
469 value_new_from_string (GnmValueType t, char const *str, GOFormat *sf,
470 gboolean translated)
472 GnmValue *res = NULL;
475 * We need the following cast to avoid a warning from gcc over
476 * VALUE_INTEGER (which is not in GnmValueType).
478 switch ((guint8)t) {
479 case VALUE_EMPTY:
480 res = value_new_empty ();
481 break;
483 case VALUE_BOOLEAN: {
484 int i = value_parse_boolean (str, translated);
485 if (i != -1)
486 res = value_new_bool ((gboolean)i);
487 break;
490 case VALUE_INTEGER:
491 case VALUE_FLOAT: {
492 char *end;
493 gnm_float d;
495 d = gnm_strto (str, &end);
496 if (str != end && *end == '\0' && errno != ERANGE)
497 res = value_new_float (d);
498 break;
501 case VALUE_ERROR:
503 * Tricky. We are currently storing errors in translated
504 * format, so we might have to undo that.
506 if (!translated) {
507 size_t i;
508 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++)
509 if (strcmp (standard_errors[i].C_name, str) == 0) {
510 res = value_new_error_std (NULL, (GnmStdError)i);
511 break;
514 if (!res)
515 res = value_new_error (NULL, str);
516 break;
518 case VALUE_STRING:
519 res = value_new_string (str);
520 break;
522 case VALUE_ARRAY:
523 case VALUE_CELLRANGE:
524 default:
525 /* This happen with corrupted files. */
526 return NULL;
529 if (res)
530 value_set_fmt (res, sf);
531 return res;
534 void
535 value_release (GnmValue *value)
537 if (NULL == value)
538 return;
540 if (VALUE_FMT (value) != NULL)
541 go_format_unref (VALUE_FMT (value));
543 switch (value->type) {
544 case VALUE_EMPTY:
545 case VALUE_BOOLEAN:
546 /* We did not allocate anything, there is nothing to free */
547 return;
549 case VALUE_FLOAT:
550 CHUNK_FREE (value_float_pool, &value->v_float);
551 return;
553 case VALUE_ERROR:
554 /* Do not release VALUE_TERMINATE, it is a magic number */
555 if (value == VALUE_TERMINATE) {
556 g_warning ("Someone freed VALUE_TERMINATE -- shame on them.");
557 return;
560 go_string_unref (value->v_err.mesg);
561 CHUNK_FREE (value_error_pool, &value->v_err);
562 return;
564 case VALUE_STRING:
565 go_string_unref (value->v_str.val);
566 CHUNK_FREE (value_string_pool, &value->v_str);
567 return;
569 case VALUE_ARRAY: {
570 GnmValueArray *v = &value->v_array;
571 int x, y;
573 for (x = 0; x < v->x; x++) {
574 for (y = 0; y < v->y; y++)
575 value_release (v->vals[x][y]);
576 g_free (v->vals[x]);
579 g_free (v->vals);
580 CHUNK_FREE (value_array_pool, v);
581 return;
584 case VALUE_CELLRANGE:
585 CHUNK_FREE (value_range_pool, &value->v_range);
586 return;
588 default:
590 * If we don't recognize the type this is probably garbage.
591 * Do not free it to avoid heap corruption
593 g_warning ("value_release problem.");
594 return;
596 g_assert_not_reached ();
600 * value_dup:
601 * @v: #GnmValue
603 * Returns a copy of @v. @v == NULL will return NULL
605 GnmValue *
606 value_dup (GnmValue const *src)
608 GnmValue *res;
610 if (src == NULL)
611 return NULL;
613 switch (src->type){
614 case VALUE_EMPTY:
615 res = value_new_empty ();
616 break;
618 case VALUE_BOOLEAN:
619 res = value_new_bool (src->v_bool.val);
620 break;
622 case VALUE_FLOAT:
623 res = value_new_float (src->v_float.val);
624 break;
626 case VALUE_ERROR:
627 res = value_new_error_str (NULL, /* &src->v_err.src, */
628 src->v_err.mesg);
629 break;
631 case VALUE_STRING:
632 go_string_ref (src->v_str.val);
633 res = value_new_string_str (src->v_str.val);
634 break;
636 case VALUE_CELLRANGE:
637 res = value_new_cellrange_unsafe (&src->v_range.cell.a,
638 &src->v_range.cell.b);
639 break;
641 case VALUE_ARRAY: {
642 int x, y;
643 GnmValueArray *array = (GnmValueArray *)value_new_array_non_init (
644 src->v_array.x, src->v_array.y);
646 for (x = 0; x < array->x; x++) {
647 array->vals[x] = g_new (GnmValue *, array->y);
648 for (y = 0; y < array->y; y++)
649 array->vals[x][y] = value_dup (src->v_array.vals[x][y]);
651 res = (GnmValue *)array;
652 break;
655 default:
656 g_warning ("value_dup problem.");
657 res = value_new_empty ();
659 value_set_fmt (res, VALUE_FMT (src));
660 return res;
663 static GnmValDiff
664 value_compare_real (GnmValue const *a, GnmValue const *b,
665 gboolean case_sensitive,
666 gboolean default_locale);
670 * value_cmp:
671 * @ptr_a:
672 * @ptr_b:
674 * qsort style comparison function.
677 value_cmp (void const *ptr_a, void const *ptr_b)
679 GnmValue const *a = *(GnmValue const **)ptr_a;
680 GnmValue const *b = *(GnmValue const **)ptr_b;
681 switch (value_compare_real (a, b, TRUE, TRUE)) {
682 case IS_EQUAL : return 0;
683 case IS_LESS : return -1;
684 case IS_GREATER : return 1;
685 default :
686 break;
688 return a->type - b->type;
692 value_cmp_reverse (void const *ptr_a, void const *ptr_b)
694 return -value_cmp (ptr_a, ptr_b);
697 gboolean
698 value_equal (GnmValue const *a, GnmValue const *b)
700 if (a->type != b->type)
701 return FALSE;
703 switch (a->type) {
704 case VALUE_BOOLEAN:
705 return a->v_bool.val == b->v_bool.val;
707 case VALUE_STRING:
708 return go_string_equal (a->v_str.val, b->v_str.val);
710 case VALUE_ERROR:
711 return go_string_equal (a->v_err.mesg, b->v_err.mesg);
713 case VALUE_FLOAT:
714 return a->v_float.val == b->v_float.val;
716 case VALUE_EMPTY:
717 return TRUE;
719 case VALUE_CELLRANGE:
720 return gnm_cellref_equal (&a->v_range.cell.a, &b->v_range.cell.a) &&
721 gnm_cellref_equal (&a->v_range.cell.b, &b->v_range.cell.b);
723 case VALUE_ARRAY:
724 if (a->v_array.x == b->v_array.x && a->v_array.y == b->v_array.y) {
725 int x, y;
727 for (y = 0; y < a->v_array.y; y++)
728 for (x = 0; x < a->v_array.x; x++)
729 if (!value_equal (a->v_array.vals[x][y],
730 b->v_array.vals[x][y]))
731 return FALSE;
732 return TRUE;
733 } else
734 return FALSE;
736 #ifndef DEBUG_SWITCH_ENUM
737 default:
738 g_assert_not_reached ();
739 return FALSE;
740 #endif
744 guint
745 value_hash (GnmValue const *v)
747 switch (v->type) {
748 case VALUE_BOOLEAN:
749 return v->v_bool.val ? 0x555aaaa : 0xaaa5555;
751 case VALUE_STRING:
752 return go_string_hash (v->v_str.val);
754 case VALUE_ERROR:
755 return go_string_hash (v->v_err.mesg);
757 case VALUE_FLOAT: {
758 int expt;
759 gnm_float mant = gnm_frexp (gnm_abs (v->v_float.val), &expt);
760 guint h = ((guint)(0x80000000u * mant)) ^ expt;
761 if (v->v_float.val >= 0)
762 h ^= 0x55555555;
763 return h;
766 case VALUE_EMPTY:
767 return 42;
769 case VALUE_CELLRANGE:
770 /* FIXME: take sheet into account? */
771 return (gnm_cellref_hash (&v->v_range.cell.a) * 3) ^
772 gnm_cellref_hash (&v->v_range.cell.b);
774 case VALUE_ARRAY: {
775 int i;
776 guint h = (v->v_array.x * 257) ^ (v->v_array.y + 42);
778 /* For speed, just walk the diagonal. */
779 for (i = 0; i < v->v_array.x && i < v->v_array.y; i++) {
780 h *= 5;
781 if (v->v_array.vals[i][i])
782 h ^= value_hash (v->v_array.vals[i][i]);
784 return h;
787 #ifndef DEBUG_SWITCH_ENUM
788 default:
789 g_assert_not_reached ();
790 return 0;
791 #endif
796 gboolean
797 value_get_as_bool (GnmValue const *v, gboolean *err)
799 if (err)
800 *err = FALSE;
802 if (v == NULL)
803 return FALSE;
805 switch (v->type) {
806 case VALUE_EMPTY:
807 return FALSE;
809 case VALUE_BOOLEAN:
810 return v->v_bool.val;
812 case VALUE_STRING: {
813 int i = value_parse_boolean (value_peek_string (v), FALSE);
814 if (i == -1) {
815 if (err)
816 *err = TRUE;
817 return FALSE;
819 return (gboolean)i;
822 case VALUE_FLOAT:
823 return v->v_float.val != 0.0;
825 default:
826 g_warning ("Unhandled value in value_get_as_bool.");
828 case VALUE_CELLRANGE:
829 case VALUE_ARRAY:
830 case VALUE_ERROR:
831 if (err)
832 *err = TRUE;
834 return FALSE;
838 * use only if you are sure the value is ok
840 gboolean
841 value_get_as_checked_bool (GnmValue const *v)
843 gboolean result, err;
845 result = value_get_as_bool (v, &err);
847 g_return_val_if_fail (!err, FALSE);
849 return result;
853 * value_get_as_gstring:
854 * @v: #GnmValue
855 * @target: #GString
856 * @conv: #GnmConventions
858 * A simple value formatter to convert @v into a string stored in @target
859 * according to @conv. See format_value_gstring for something more elaborate
860 * that handles formats too.
862 void
863 value_get_as_gstring (GnmValue const *v, GString *target,
864 GnmConventions const *conv)
866 if (v == NULL)
867 return;
869 switch (v->type){
870 case VALUE_EMPTY:
871 return;
873 case VALUE_ERROR: {
874 GnmStdError e = value_error_classify (v);
875 if (e == GNM_ERROR_UNKNOWN) {
876 g_string_append_c (target, '#');
877 go_strescape (target, v->v_err.mesg->str);
878 } else
879 g_string_append (target, value_error_name (e, conv->output.translated));
880 return;
883 case VALUE_BOOLEAN: {
884 gboolean b = v->v_bool.val;
885 g_string_append (target,
886 conv->output.translated
887 ? go_locale_boolean_name (b)
888 : (b ? "TRUE" : "FALSE"));
889 return;
892 case VALUE_STRING:
893 g_string_append (target, v->v_str.val->str);
894 return;
896 case VALUE_FLOAT:
897 g_string_append_printf (target, "%.*" GNM_FORMAT_g,
898 conv->output.decimal_digits,
899 v->v_float.val);
900 return;
902 case VALUE_ARRAY: {
903 GnmValue const *val;
904 gunichar row_sep, col_sep;
905 int x, y;
907 if (conv->array_row_sep)
908 row_sep = conv->array_row_sep;
909 else
910 row_sep = go_locale_get_row_sep ();
911 if (conv->array_col_sep)
912 col_sep = conv->array_col_sep;
913 else
914 col_sep = go_locale_get_col_sep ();
916 g_string_append_c (target, '{');
917 for (y = 0; y < v->v_array.y; y++){
918 if (y)
919 g_string_append_unichar (target, row_sep);
921 for (x = 0; x < v->v_array.x; x++){
922 val = v->v_array.vals[x][y];
924 if (x)
925 g_string_append_unichar (target, col_sep);
927 /* quote strings */
928 if (!val) {
929 /* This is not supposed to happen, but
930 let's not crash anyway. */
931 g_string_append (target, "?");
932 } else if (VALUE_IS_STRING (val))
933 go_strescape (target, val->v_str.val->str);
934 else
935 value_get_as_gstring (val, target, conv);
938 g_string_append_c (target, '}');
939 return;
942 case VALUE_CELLRANGE: {
943 char *tmp;
944 /* Note: this makes only sense for absolute references or
945 * references relative to A1
947 GnmRange range;
948 range_init_value (&range, v);
949 tmp = global_range_name (v->v_range.cell.a.sheet, &range);
950 g_string_append (target, tmp);
951 g_free (tmp);
952 return;
955 default:
956 break;
959 g_assert_not_reached ();
964 * value_get_as_string:
965 * @v:
967 * simplistic value rendering
969 * Returns a string that must be freed.
971 char *
972 value_get_as_string (GnmValue const *v)
974 GString *res = g_string_sized_new (10);
975 value_get_as_gstring (v, res, gnm_conventions_default);
976 return g_string_free (res, FALSE);
980 * Result will stay valid until (a) the value is disposed of, or (b) two
981 * further calls to this function are made.
983 char const *
984 value_peek_string (GnmValue const *v)
986 g_return_val_if_fail (v, "");
988 if (VALUE_IS_STRING (v))
989 return v->v_str.val->str;
990 else if (VALUE_IS_ERROR (v))
991 return v->v_err.mesg->str;
992 else {
993 static char *cache[2] = { NULL, NULL };
994 static int next = 0;
995 char const *s;
997 g_free (cache[next]);
998 s = cache[next] = value_get_as_string (v);
999 next = (next + 1) % G_N_ELEMENTS (cache);
1000 return s;
1005 * FIXME FIXME FIXME : Support errors
1008 value_get_as_int (GnmValue const *v)
1010 if (v == NULL)
1011 return 0;
1012 switch (v->type) {
1013 case VALUE_EMPTY:
1014 return 0;
1016 case VALUE_STRING:
1017 return atoi (v->v_str.val->str);
1019 case VALUE_CELLRANGE:
1020 g_warning ("Getting range as a int: what to do?");
1021 return 0;
1023 case VALUE_ARRAY:
1024 return 0;
1026 case VALUE_FLOAT:
1027 return (int) gnm_fake_trunc (v->v_float.val);
1029 case VALUE_BOOLEAN:
1030 return v->v_bool.val ? 1 : 0;
1032 case VALUE_ERROR:
1033 return 0;
1035 default:
1036 g_warning ("value_get_as_int unknown type 0x%x (%d).", v->type, v->type);
1037 return 0;
1039 return 0;
1043 * FIXME FIXME FIXME : Support errors
1045 gnm_float
1046 value_get_as_float (GnmValue const *v)
1048 if (v == NULL)
1049 return 0.;
1051 switch (v->type) {
1052 case VALUE_EMPTY:
1053 return 0.;
1055 case VALUE_STRING:
1056 return gnm_strto (v->v_str.val->str, NULL);
1058 case VALUE_CELLRANGE:
1059 g_warning ("Getting range as a double: what to do?");
1060 return 0.0;
1062 case VALUE_ARRAY:
1063 return 0.0;
1065 case VALUE_FLOAT:
1066 return (gnm_float) v->v_float.val;
1068 case VALUE_BOOLEAN:
1069 return v->v_bool.val ? 1. : 0.;
1071 case VALUE_ERROR:
1072 return 0.;
1074 default:
1075 g_warning ("value_get_as_float type error.");
1076 break;
1078 return 0.0;
1081 gboolean
1082 value_is_zero (GnmValue const *v)
1084 return gnm_abs (value_get_as_float (v)) < 64 * GNM_EPSILON;
1087 GnmRangeRef const *
1088 value_get_rangeref (GnmValue const *v)
1090 g_return_val_if_fail (v->type == VALUE_CELLRANGE, NULL);
1091 return &v->v_range.cell;
1096 * value_coerce_to_number:
1097 * @v:
1098 * @valid:
1100 * If the value can be used as a number return that number
1101 * otherwise free it at return an appropriate error
1103 GnmValue *
1104 value_coerce_to_number (GnmValue *v, gboolean *valid, GnmEvalPos const *ep)
1106 g_return_val_if_fail (v != NULL, NULL);
1108 *valid = FALSE;
1109 if (VALUE_IS_STRING (v)) {
1110 GnmValue *tmp = format_match_number (value_peek_string (v), NULL,
1111 workbook_date_conv (ep->sheet->workbook));
1112 value_release (v);
1113 if (tmp == NULL)
1114 return value_new_error_VALUE (ep);
1115 v = tmp;
1116 } else if (VALUE_IS_ERROR (v))
1117 return v;
1119 if (!VALUE_IS_NUMBER (v)) {
1120 value_release (v);
1121 return value_new_error_VALUE (ep);
1124 *valid = TRUE;
1125 return v;
1128 void
1129 value_array_set (GnmValue *array, int col, int row, GnmValue *v)
1131 g_return_if_fail (v);
1132 g_return_if_fail (array->type == VALUE_ARRAY);
1133 g_return_if_fail (col>=0);
1134 g_return_if_fail (row>=0);
1135 g_return_if_fail (array->v_array.y > row);
1136 g_return_if_fail (array->v_array.x > col);
1138 value_release (array->v_array.vals[col][row]);
1139 array->v_array.vals[col][row] = v;
1142 static GnmValDiff
1143 compare_bool_bool (GnmValue const *va, GnmValue const *vb)
1145 gboolean err; /* Ignored */
1146 gboolean const a = value_get_as_bool (va, &err);
1147 gboolean const b = value_get_as_bool (vb, &err);
1148 if (a)
1149 return b ? IS_EQUAL : IS_GREATER;
1150 return b ? IS_LESS : IS_EQUAL;
1153 static GnmValDiff
1154 compare_float_float (GnmValue const *va, GnmValue const *vb)
1156 gnm_float const a = value_get_as_float (va);
1157 gnm_float const b = value_get_as_float (vb);
1158 if (a == b)
1159 return IS_EQUAL;
1160 else if (a < b)
1161 return IS_LESS;
1162 else
1163 return IS_GREATER;
1167 * value_diff:
1168 * @a: value a
1169 * @b: value b
1171 * IGNORES format.
1173 * Returns a non-negative difference between 2 values
1175 gnm_float
1176 value_diff (GnmValue const *a, GnmValue const *b)
1178 GnmValueType ta, tb;
1180 /* Handle trivial (including empty/empty) and double NULL */
1181 if (a == b)
1182 return 0.;
1184 ta = VALUE_IS_EMPTY (a) ? VALUE_EMPTY : a->type;
1185 tb = VALUE_IS_EMPTY (b) ? VALUE_EMPTY : b->type;
1187 /* string > empty */
1188 if (ta == VALUE_STRING) {
1189 switch (tb) {
1190 /* Strings are > (empty, or number) */
1191 case VALUE_EMPTY :
1192 if (*a->v_str.val->str == '\0')
1193 return 0.;
1194 return DBL_MAX;
1196 /* If both are strings compare as string */
1197 case VALUE_STRING :
1198 if (go_string_equal (a->v_str.val, b->v_str.val))
1199 return 0.;
1201 case VALUE_FLOAT: case VALUE_BOOLEAN:
1202 default :
1203 return DBL_MAX;
1206 } else if (tb == VALUE_STRING) {
1207 switch (ta) {
1208 /* (empty, or number) < String */
1209 case VALUE_EMPTY :
1210 if (*b->v_str.val->str == '\0')
1211 return 0.;
1213 case VALUE_FLOAT : case VALUE_BOOLEAN :
1214 default :
1215 return DBL_MAX;
1219 /* Booleans > all numbers (Why did excel do this ?? ) */
1220 if (ta == VALUE_BOOLEAN && tb == VALUE_FLOAT)
1221 return DBL_MAX;
1222 if (tb == VALUE_BOOLEAN && ta == VALUE_FLOAT)
1223 return DBL_MAX;
1225 switch ((ta > tb) ? ta : tb) {
1226 case VALUE_EMPTY: /* Empty Empty compare */
1227 return 0.;
1229 case VALUE_BOOLEAN:
1230 return (compare_bool_bool (a, b) == IS_EQUAL) ? 0. : DBL_MAX;
1232 case VALUE_FLOAT: {
1233 gnm_float const da = value_get_as_float (a);
1234 gnm_float const db = value_get_as_float (b);
1235 return gnm_abs (da - db);
1237 default:
1238 return TYPE_MISMATCH;
1242 static int
1243 gnm_string_cmp (gconstpointer gstr_a, gconstpointer gstr_b)
1245 return (gstr_a == gstr_b)
1247 : g_utf8_collate (((GOString const *)gstr_a)->str,
1248 ((GOString const *)gstr_b)->str);
1251 static int
1252 gnm_string_cmp_ignorecase (gconstpointer gstr_a, gconstpointer gstr_b)
1254 gchar *a;
1255 gchar *b;
1256 int res;
1258 if (gstr_a == gstr_b)
1259 return 0;
1261 a = g_utf8_casefold (((GOString const *)gstr_a)->str, -1);
1262 b = g_utf8_casefold (((GOString const *)gstr_b)->str, -1);
1264 res = g_utf8_collate (a, b);
1266 g_free (a);
1267 g_free (b);
1269 return res;
1274 * value_compare:
1276 * @a: value a
1277 * @b: value b
1278 * @case_sensitive: are string comparisons case sensitive.
1280 * IGNORES format.
1282 static GnmValDiff
1283 value_compare_real (GnmValue const *a, GnmValue const *b,
1284 gboolean case_sensitive,
1285 gboolean default_locale)
1287 GnmValueType ta, tb;
1288 int t;
1290 /* Handle trivial and double NULL case */
1291 if (a == b)
1292 return IS_EQUAL;
1294 ta = VALUE_IS_EMPTY (a) ? VALUE_EMPTY : a->type;
1295 tb = VALUE_IS_EMPTY (b) ? VALUE_EMPTY : b->type;
1297 /* string > empty */
1298 if (ta == VALUE_STRING) {
1299 switch (tb) {
1300 /* Strings are > (empty, or number) */
1301 case VALUE_EMPTY :
1302 if (*a->v_str.val->str == '\0')
1303 return IS_EQUAL;
1305 case VALUE_FLOAT:
1306 return IS_GREATER;
1308 /* Strings are < FALSE ?? */
1309 case VALUE_BOOLEAN :
1310 return IS_LESS;
1312 /* If both are strings compare as string */
1313 case VALUE_STRING :
1314 t = (default_locale) ?
1315 (case_sensitive
1316 ? go_string_cmp
1317 (a->v_str.val, b->v_str.val)
1318 : go_string_cmp_ignorecase
1319 (a->v_str.val, b->v_str.val))
1320 : (case_sensitive
1321 ? gnm_string_cmp
1322 (a->v_str.val, b->v_str.val)
1323 : gnm_string_cmp_ignorecase
1324 (a->v_str.val, b->v_str.val));
1326 if (t > 0)
1327 return IS_GREATER;
1328 else if (t < 0)
1329 return IS_LESS;
1330 else
1331 return IS_EQUAL;
1333 default :
1334 return TYPE_MISMATCH;
1336 } else if (tb == VALUE_STRING) {
1337 switch (ta) {
1338 /* (empty, or number) < String */
1339 case VALUE_EMPTY :
1340 if (*b->v_str.val->str == '\0')
1341 return IS_EQUAL;
1343 case VALUE_FLOAT :
1344 return IS_LESS;
1346 /* Strings are < FALSE ?? */
1347 case VALUE_BOOLEAN :
1348 return IS_GREATER;
1350 default :
1351 return TYPE_MISMATCH;
1355 /* Booleans > all numbers (Why did excel do this ?? ) */
1356 if (ta == VALUE_BOOLEAN && tb == VALUE_FLOAT)
1357 return IS_GREATER;
1358 if (tb == VALUE_BOOLEAN && ta == VALUE_FLOAT)
1359 return IS_LESS;
1361 switch ((ta > tb) ? ta : tb) {
1362 case VALUE_EMPTY: /* Empty Empty compare */
1363 return IS_EQUAL;
1365 case VALUE_BOOLEAN:
1366 return compare_bool_bool (a, b);
1368 case VALUE_FLOAT:
1369 return compare_float_float (a, b);
1370 default:
1371 return TYPE_MISMATCH;
1375 GnmValDiff
1376 value_compare (GnmValue const *a, GnmValue const *b, gboolean case_sensitive)
1378 return value_compare_real (a, b, case_sensitive, TRUE);
1381 GnmValDiff
1382 value_compare_no_cache (GnmValue const *a, GnmValue const *b,
1383 gboolean case_sensitive)
1385 return value_compare_real (a, b, case_sensitive, FALSE);
1388 void
1389 value_set_fmt (GnmValue *v, GOFormat const *fmt)
1391 if (fmt == VALUE_FMT (v))
1392 return;
1393 g_return_if_fail (v->type != VALUE_EMPTY && v->type != VALUE_BOOLEAN);
1394 if (fmt != NULL)
1395 go_format_ref (fmt);
1396 if (VALUE_FMT (v) != NULL)
1397 go_format_unref (VALUE_FMT (v));
1398 v->v_any.fmt = fmt;
1401 /****************************************************************************/
1403 typedef enum { CRIT_NULL, CRIT_FLOAT, CRIT_WRONGTYPE, CRIT_STRING } CritType;
1405 static CritType
1406 criteria_inspect_values (GnmValue const *x, gnm_float *xr, gnm_float *yr,
1407 GnmCriteria *crit)
1409 GnmValue *vx;
1410 GnmValue const *y = crit->x;
1412 if (x == NULL || y == NULL)
1413 return CRIT_NULL;
1415 switch (y->type) {
1416 case VALUE_BOOLEAN:
1417 /* If we're searching for a bool -- even one that is
1418 from a string search value -- we match only bools. */
1419 if (!VALUE_IS_BOOLEAN (x))
1420 return CRIT_WRONGTYPE;
1421 *xr = value_get_as_float (x);
1422 *yr = value_get_as_float (y);
1423 return CRIT_FLOAT;
1425 case VALUE_EMPTY:
1426 case VALUE_STRING:
1427 return CRIT_STRING;
1429 default:
1430 g_warning ("This should not happen. Please report.");
1431 return CRIT_WRONGTYPE;
1433 case VALUE_FLOAT:
1434 *yr = value_get_as_float (y);
1436 if (VALUE_IS_BOOLEAN (x))
1437 return CRIT_WRONGTYPE;
1438 else if (VALUE_IS_FLOAT (x)) {
1439 *xr = value_get_as_float (x);
1440 return CRIT_FLOAT;
1443 vx = format_match (value_peek_string (x), NULL, crit->date_conv);
1444 if (VALUE_IS_EMPTY (vx) ||
1445 VALUE_IS_BOOLEAN (y) != VALUE_IS_BOOLEAN (vx)) {
1446 value_release (vx);
1447 return CRIT_WRONGTYPE;
1450 *xr = value_get_as_float (vx);
1451 value_release (vx);
1452 return CRIT_FLOAT;
1457 static gboolean
1458 criteria_test_equal (GnmValue const *x, GnmCriteria *crit)
1460 gnm_float xf, yf;
1461 GnmValue const *y = crit->x;
1463 switch (criteria_inspect_values (x, &xf, &yf, crit)) {
1464 default:
1465 g_assert_not_reached ();
1466 case CRIT_NULL:
1467 case CRIT_WRONGTYPE:
1468 return FALSE;
1469 case CRIT_FLOAT:
1470 return xf == yf;
1471 case CRIT_STRING:
1472 /* FIXME: _ascii_??? */
1473 return g_ascii_strcasecmp (value_peek_string (x),
1474 value_peek_string (y)) == 0;
1478 static gboolean
1479 criteria_test_unequal (GnmValue const *x, GnmCriteria *crit)
1481 gnm_float xf, yf;
1483 switch (criteria_inspect_values (x, &xf, &yf, crit)) {
1484 default:
1485 g_assert_not_reached ();
1486 case CRIT_NULL:
1487 case CRIT_WRONGTYPE:
1488 return FALSE;
1489 case CRIT_FLOAT:
1490 return xf != yf;
1491 case CRIT_STRING:
1492 /* FIXME: _ascii_??? */
1493 return g_ascii_strcasecmp (value_peek_string (x),
1494 value_peek_string (crit->x)) != 0;
1498 static gboolean
1499 criteria_test_less (GnmValue const *x, GnmCriteria *crit)
1501 gnm_float xf, yf;
1503 switch (criteria_inspect_values (x, &xf, &yf, crit)) {
1504 default:
1505 g_assert_not_reached ();
1506 case CRIT_NULL:
1507 case CRIT_WRONGTYPE:
1508 case CRIT_STRING:
1509 return FALSE;
1510 case CRIT_FLOAT:
1511 return xf < yf;
1515 static gboolean
1516 criteria_test_greater (GnmValue const *x, GnmCriteria *crit)
1518 gnm_float xf, yf;
1520 switch (criteria_inspect_values (x, &xf, &yf, crit)) {
1521 default:
1522 g_assert_not_reached ();
1523 case CRIT_NULL:
1524 case CRIT_WRONGTYPE:
1525 case CRIT_STRING:
1526 return FALSE;
1527 case CRIT_FLOAT:
1528 return xf > yf;
1532 static gboolean
1533 criteria_test_less_or_equal (GnmValue const *x, GnmCriteria *crit)
1535 gnm_float xf, yf;
1537 switch (criteria_inspect_values (x, &xf, &yf, crit)) {
1538 default:
1539 g_assert_not_reached ();
1540 case CRIT_NULL:
1541 case CRIT_WRONGTYPE:
1542 case CRIT_STRING:
1543 return FALSE;
1544 case CRIT_FLOAT:
1545 return xf <= yf;
1549 static gboolean
1550 criteria_test_greater_or_equal (GnmValue const *x, GnmCriteria *crit)
1552 gnm_float xf, yf;
1554 switch (criteria_inspect_values (x, &xf, &yf, crit)) {
1555 default:
1556 g_assert_not_reached ();
1557 case CRIT_NULL:
1558 case CRIT_WRONGTYPE:
1559 case CRIT_STRING:
1560 return FALSE;
1561 case CRIT_FLOAT:
1562 return xf >= yf;
1566 static gboolean
1567 criteria_test_match (GnmValue const *x, GnmCriteria *crit)
1569 if (!crit->has_rx)
1570 return FALSE;
1572 return go_regexec (&crit->rx, value_peek_string (x), 0, NULL, 0) ==
1573 GO_REG_OK;
1576 static gboolean
1577 criteria_test_empty (GnmValue const *x, GnmCriteria *crit)
1579 return VALUE_IS_EMPTY (x);
1582 static gboolean
1583 criteria_test_nonempty (GnmValue const *x, GnmCriteria *crit)
1585 return !VALUE_IS_EMPTY (x);
1589 * Finds a column index of a field.
1592 find_column_of_field (GnmEvalPos const *ep,
1593 GnmValue const *database, GnmValue const *field)
1595 Sheet *sheet;
1596 GnmCell *cell;
1597 gchar *field_name;
1598 int begin_col, end_col, row, n, column;
1599 int offset;
1601 offset = database->v_range.cell.a.col;
1603 if (VALUE_IS_FLOAT (field))
1604 return value_get_as_int (field) + offset - 1;
1606 if (!VALUE_IS_STRING (field))
1607 return -1;
1609 sheet = eval_sheet (database->v_range.cell.a.sheet, ep->sheet);
1610 field_name = value_get_as_string (field);
1611 column = -1;
1613 /* find the column that is labeled after `field_name' */
1614 begin_col = database->v_range.cell.a.col;
1615 end_col = database->v_range.cell.b.col;
1616 row = database->v_range.cell.a.row;
1618 for (n = begin_col; n <= end_col; n++) {
1619 char const *txt;
1620 gboolean match;
1622 cell = sheet_cell_get (sheet, n, row);
1623 if (cell == NULL)
1624 continue;
1625 gnm_cell_eval (cell);
1627 txt = cell->value
1628 ? value_peek_string (cell->value)
1629 : "";
1630 match = (g_ascii_strcasecmp (field_name, txt) == 0);
1631 if (match) {
1632 column = n;
1633 break;
1637 g_free (field_name);
1638 return column;
1641 void
1642 free_criteria (GnmCriteria *criteria)
1644 if (!criteria || criteria->ref_count-- > 1)
1645 return;
1646 value_release (criteria->x);
1647 if (criteria->has_rx)
1648 go_regfree (&criteria->rx);
1649 g_free (criteria);
1652 static GnmCriteria *
1653 gnm_criteria_ref (GnmCriteria *criteria)
1655 criteria->ref_count++;
1656 return criteria;
1659 GType
1660 gnm_criteria_get_type (void)
1662 static GType t = 0;
1664 if (t == 0) {
1665 t = g_boxed_type_register_static ("GnmCriteria",
1666 (GBoxedCopyFunc)gnm_criteria_ref,
1667 (GBoxedFreeFunc)free_criteria);
1669 return t;
1673 * free_criterias:
1674 * @criterias: (element-type GnmCriteria) (transfer full): the criteria to be
1675 * freed.
1676 * Frees the allocated memory.
1678 void
1679 free_criterias (GSList *criterias)
1681 GSList *list = criterias;
1683 while (criterias != NULL) {
1684 GnmDBCriteria *criteria = criterias->data;
1685 g_slist_free_full (criteria->conditions,
1686 (GFreeFunc)free_criteria);
1687 g_free (criteria);
1688 criterias = criterias->next;
1690 g_slist_free (list);
1694 * parse_criteria:
1695 * @crit_val: #GnmValue
1696 * @date_conv: #GODateConventions
1698 * Returns: (transfer full): GnmCriteria which caller must free.
1700 * ">=value"
1701 * "<=value"
1702 * "<>value"
1703 * "<value"
1704 * ">value"
1705 * "=value"
1706 * "pattern"
1708 GnmCriteria *
1709 parse_criteria (GnmValue const *crit_val, GODateConventions const *date_conv)
1711 int len;
1712 char const *criteria;
1713 GnmCriteria *res = g_new0 (GnmCriteria, 1);
1714 GnmValue *empty;
1716 res->iter_flags = CELL_ITER_IGNORE_BLANK;
1717 res->date_conv = date_conv;
1719 if (VALUE_IS_NUMBER (crit_val)) {
1720 res->fun = criteria_test_equal;
1721 res->x = value_dup (crit_val);
1722 return res;
1725 criteria = value_peek_string (crit_val);
1726 if (strncmp (criteria, "<=", 2) == 0) {
1727 res->fun = criteria_test_less_or_equal;
1728 len = 2;
1729 } else if (strncmp (criteria, ">=", 2) == 0) {
1730 res->fun = criteria_test_greater_or_equal;
1731 len = 2;
1732 } else if (strncmp (criteria, "<>", 2) == 0) {
1733 /* "<>" by itself is special: */
1734 res->fun = (criteria[2] == 0) ? criteria_test_nonempty : criteria_test_unequal;
1735 len = 2;
1736 } else if (*criteria == '<') {
1737 res->fun = criteria_test_less;
1738 len = 1;
1739 } else if (*criteria == '=') {
1740 /* "=" by itself is special: */
1741 res->fun = (criteria[1] == 0) ? criteria_test_empty : criteria_test_equal;
1742 len = 1;
1743 } else if (*criteria == '>') {
1744 res->fun = criteria_test_greater;
1745 len = 1;
1746 } else {
1747 res->fun = criteria_test_match;
1748 res->has_rx = (gnm_regcomp_XL (&res->rx, criteria, GO_REG_ICASE, TRUE, TRUE) == GO_REG_OK);
1749 len = 0;
1752 res->x = format_match_number (criteria + len, NULL, date_conv);
1753 if (res->x == NULL)
1754 res->x = value_new_string (criteria + len);
1755 else if (len == 0 && VALUE_IS_NUMBER (res->x))
1756 res->fun = criteria_test_equal;
1758 empty = value_new_empty ();
1759 if (res->fun (empty, res))
1760 res->iter_flags &= ~CELL_ITER_IGNORE_BLANK;
1761 value_release (empty);
1762 res->ref_count = 1;
1764 return res;
1768 static GSList *
1769 parse_criteria_range (Sheet *sheet, int b_col, int b_row, int e_col, int e_row,
1770 int *field_ind)
1772 GSList *criterias = NULL;
1773 GODateConventions const *date_conv =
1774 workbook_date_conv (sheet->workbook);
1775 int i, j;
1777 for (i = b_row; i <= e_row; i++) {
1778 GnmDBCriteria *new_criteria = g_new (GnmDBCriteria, 1);
1779 GSList *conditions = NULL;
1781 for (j = b_col; j <= e_col; j++) {
1782 GnmCriteria *cond;
1783 GnmCell *cell = sheet_cell_get (sheet, j, i);
1784 if (cell != NULL)
1785 gnm_cell_eval (cell);
1786 if (gnm_cell_is_empty (cell))
1787 continue;
1789 cond = parse_criteria (cell->value, date_conv);
1790 cond->column = (field_ind != NULL)
1791 ? field_ind[j - b_col]
1792 : j - b_col;
1793 conditions = g_slist_prepend (conditions, cond);
1796 new_criteria->conditions = g_slist_reverse (conditions);
1797 criterias = g_slist_prepend (criterias, new_criteria);
1800 return g_slist_reverse (criterias);
1804 * parse_database_criteria:
1805 * @ep: #GnmEvalPos
1806 * @database: #GnmValue
1807 * @criteria: #GnmValue
1809 * Parses the criteria cell range.
1810 * Returns: (element-type GnmDBCriteria) (transfer full):
1812 GSList *
1813 parse_database_criteria (GnmEvalPos const *ep, GnmValue const *database, GnmValue const *criteria)
1815 Sheet *sheet;
1816 GnmCell *cell;
1817 int i;
1818 int b_col, b_row, e_col, e_row;
1819 int *field_ind;
1821 g_return_val_if_fail (criteria->type == VALUE_CELLRANGE, NULL);
1823 sheet = eval_sheet (criteria->v_range.cell.a.sheet, ep->sheet);
1824 b_col = criteria->v_range.cell.a.col;
1825 b_row = criteria->v_range.cell.a.row;
1826 e_col = criteria->v_range.cell.b.col;
1827 e_row = criteria->v_range.cell.b.row;
1829 if (e_col < b_col) {
1830 int tmp = b_col;
1831 b_col = e_col;
1832 e_col = tmp;
1835 /* Find the index numbers for the columns of criterias */
1836 field_ind = g_alloca (sizeof (int) * (e_col - b_col + 1));
1837 for (i = b_col; i <= e_col; i++) {
1838 cell = sheet_cell_get (sheet, i, b_row);
1839 if (cell == NULL)
1840 continue;
1841 gnm_cell_eval (cell);
1842 if (gnm_cell_is_empty (cell))
1843 continue;
1844 field_ind[i - b_col] =
1845 find_column_of_field (ep, database, cell->value);
1846 if (field_ind[i - b_col] == -1)
1847 return NULL;
1850 return parse_criteria_range (sheet, b_col, b_row + 1,
1851 e_col, e_row, field_ind);
1855 * find_rows_that_match:
1856 * @sheet: #Sheet
1857 * @first_col: first column.
1858 * @first_row: first row.
1859 * @last_col: last column.
1860 * @last_row: laset row.
1861 * @criterias: (element-type GnmDBCriteria): the criteria to use.
1862 * @unique_only:
1864 * Finds the rows from the given database that match the criteria.
1865 * Returns: (element-type int) (transfer full): the list of matching rows.
1867 GSList *
1868 find_rows_that_match (Sheet *sheet, int first_col, int first_row,
1869 int last_col, int last_row,
1870 GSList *criterias, gboolean unique_only)
1872 GSList *rows = NULL;
1873 GSList const *crit_ptr, *cond_ptr;
1874 int row;
1875 gboolean add_flag;
1876 char const *t1, *t2;
1877 GnmCell *test_cell;
1879 for (row = first_row; row <= last_row; row++) {
1880 add_flag = TRUE;
1881 for (crit_ptr = criterias; crit_ptr; crit_ptr = crit_ptr->next) {
1882 GnmDBCriteria const *crit = crit_ptr->data;
1883 add_flag = TRUE;
1884 for (cond_ptr = crit->conditions;
1885 cond_ptr != NULL ; cond_ptr = cond_ptr->next) {
1886 GnmCriteria *cond = cond_ptr->data;
1887 test_cell = sheet_cell_get (sheet, cond->column, row);
1888 if (test_cell != NULL)
1889 gnm_cell_eval (test_cell);
1890 if (gnm_cell_is_empty (test_cell) ||
1891 !cond->fun (test_cell->value, cond)) {
1892 add_flag = FALSE;
1893 break;
1897 if (add_flag)
1898 break;
1900 if (add_flag) {
1901 gint *p;
1903 if (unique_only) {
1904 GSList *c;
1905 GnmCell *cell;
1906 gint i, trow;
1908 for (c = rows; c != NULL; c = c->next) {
1909 trow = *((gint *) c->data);
1910 for (i = first_col; i <= last_col; i++) {
1911 test_cell = sheet_cell_get (sheet, i, trow);
1912 cell = sheet_cell_get (sheet, i, row);
1914 /* FIXME: this is probably not right, but crashing is more wrong. */
1915 if (test_cell == NULL || cell == NULL)
1916 continue;
1918 t1 = cell->value
1919 ? value_peek_string (cell->value)
1920 : "";
1921 t2 = test_cell->value
1922 ? value_peek_string (test_cell->value)
1923 : "";
1924 if (strcmp (t1, t2) != 0)
1925 goto row_ok;
1927 goto filter_row;
1928 row_ok:
1932 p = g_new (gint, 1);
1933 *p = row;
1934 rows = g_slist_prepend (rows, (gpointer) p);
1935 filter_row:
1940 return g_slist_reverse (rows);
1943 /****************************************************************************/
1945 GType
1946 gnm_value_get_type (void)
1948 static GType t = 0;
1950 if (t == 0)
1951 t = g_boxed_type_register_static ("GnmValue",
1952 (GBoxedCopyFunc)value_dup,
1953 (GBoxedFreeFunc)value_release);
1954 return t;
1956 /****************************************************************************/
1958 GnmValueErr const value_terminate_err = { VALUE_ERROR, NULL, NULL };
1959 static GnmValueFloat const the_value_zero = { VALUE_FLOAT, NULL, 0 };
1960 GnmValue const *value_zero = (GnmValue const *)&the_value_zero;
1962 void
1963 value_init (void)
1965 size_t i;
1967 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++) {
1968 standard_errors[i].locale_name = _(standard_errors[i].C_name);
1969 standard_errors[i].locale_name_str =
1970 go_string_new (standard_errors[i].locale_name);
1973 #if USE_VALUE_POOLS
1974 value_float_pool =
1975 go_mem_chunk_new ("value float pool",
1976 sizeof (GnmValueFloat),
1977 16 * 1024 - 128);
1979 value_error_pool =
1980 go_mem_chunk_new ("value error pool",
1981 sizeof (GnmValueErr),
1982 16 * 1024 - 128);
1984 value_string_pool =
1985 go_mem_chunk_new ("value string pool",
1986 sizeof (GnmValueStr),
1987 16 * 1024 - 128);
1989 value_range_pool =
1990 go_mem_chunk_new ("value range pool",
1991 sizeof (GnmValueRange),
1992 16 * 1024 - 128);
1994 value_array_pool =
1995 go_mem_chunk_new ("value array pool",
1996 sizeof (GnmValueArray),
1997 16 * 1024 - 128);
1998 #endif
2001 void
2002 value_shutdown (void)
2004 size_t i;
2006 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++) {
2007 go_string_unref (standard_errors[i].locale_name_str);
2008 standard_errors[i].locale_name_str = NULL;
2011 #if USE_VALUE_POOLS
2012 go_mem_chunk_destroy (value_float_pool, FALSE);
2013 value_float_pool = NULL;
2015 go_mem_chunk_destroy (value_error_pool, FALSE);
2016 value_error_pool = NULL;
2018 go_mem_chunk_destroy (value_string_pool, FALSE);
2019 value_string_pool = NULL;
2021 go_mem_chunk_destroy (value_range_pool, FALSE);
2022 value_range_pool = NULL;
2024 go_mem_chunk_destroy (value_array_pool, FALSE);
2025 value_array_pool = NULL;
2026 #else
2027 if (value_allocations)
2028 g_printerr ("Leaking %d values.\n", value_allocations);
2029 #endif
2032 /****************************************************************************/