GUI: Move .ui files from goffice resources to glib resources
[gnumeric.git] / src / value.c
blobaf27c5e6ab0a4095c9d38772711cb6e68fc79ebe
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);
181 * value_error_name:
182 * @err: #GnmStdError
183 * @translated: If %TRUE, use localized name.
185 * Returns: (transfer none): the name of @err, possibly localized.
187 char const *
188 value_error_name (GnmStdError err, gboolean translated)
190 size_t i = (size_t)err;
191 g_return_val_if_fail (i < G_N_ELEMENTS (standard_errors), NULL);
193 if (translated)
194 return standard_errors[i].locale_name;
195 else
196 return standard_errors[i].C_name;
200 * value_error_set_pos:
201 * @err:
202 * @pos:
204 * Change the position of a ValueError.
206 * Returns: (transfer none): @err as a #GnmValue.
208 GnmValue *
209 value_error_set_pos (GnmValueErr *err, G_GNUC_UNUSED GnmEvalPos const *pos)
211 g_return_val_if_fail (err != NULL, NULL);
212 g_return_val_if_fail (VALUE_IS_ERROR ((GnmValue *)err), NULL);
214 /* err->src = *pos; */
215 return (GnmValue *)err;
218 GnmStdError
219 value_error_classify (GnmValue const *v)
221 size_t i;
223 g_return_val_if_fail (v != NULL, GNM_ERROR_UNKNOWN);
225 if (!VALUE_IS_ERROR (v))
226 return GNM_ERROR_UNKNOWN;
228 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++)
229 if (standard_errors[i].locale_name_str == v->v_err.mesg)
230 return (GnmStdError)i;
232 return GNM_ERROR_UNKNOWN;
237 * value_new_string_str:
238 * @str: (transfer full): string to use for value
240 * Returns: (transfer full): a new value object.
242 GnmValue *
243 value_new_string_str (GOString *str)
245 GnmValueStr *v;
247 g_return_val_if_fail (str != NULL, NULL);
249 v = CHUNK_ALLOC (GnmValueStr, value_string_pool);
250 *((GnmValueType *)&(v->type)) = VALUE_STRING;
251 v->fmt = NULL;
252 v->val = str;
253 return (GnmValue *)v;
257 * value_new_string:
258 * @str: string to use for value
260 * Returns: (transfer full): a new value object.
262 GnmValue *
263 value_new_string (char const *str)
265 return value_new_string_str (go_string_new (str));
269 * value_new_string_nocopy:
270 * @str: (transfer full): string to use for value
272 * Returns: (transfer full): a new value object.
274 GnmValue *
275 value_new_string_nocopy (char *str)
277 return value_new_string_str (go_string_new_nocopy (str));
280 GnmValue *
281 value_new_cellrange_unsafe (GnmCellRef const *a, GnmCellRef const *b)
283 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
284 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
285 v->fmt = NULL;
286 v->cell.a = *a;
287 v->cell.b = *b;
288 return (GnmValue *)v;
292 * value_new_cellrange:
294 * Create a new range reference.
296 * Attempt to do a sanity check for inverted ranges.
297 * NOTE : This is no longer necessary and will be removed.
298 * mixed mode references create the possibility of inversion.
299 * users of these values need to use the utility routines to
300 * evaluate the ranges in their context and normalize then.
302 GnmValue *
303 value_new_cellrange (GnmCellRef const *a, GnmCellRef const *b,
304 int eval_col, int eval_row)
306 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
307 int tmp;
309 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
310 v->fmt = NULL;
311 v->cell.a = *a;
312 v->cell.b = *b;
314 /* Sanity checking to avoid inverted ranges */
315 tmp = a->col;
316 if (a->col_relative != b->col_relative) {
317 /* Make a tmp copy of a in the same mode as b */
318 if (a->col_relative)
319 tmp += eval_col;
320 else
321 tmp -= eval_col;
323 if (tmp > b->col) {
324 v->cell.a.col = b->col;
325 v->cell.a.col_relative = b->col_relative;
326 v->cell.b.col = a->col;
327 v->cell.b.col_relative = a->col_relative;
330 tmp = a->row;
331 if (a->row_relative != b->row_relative) {
332 /* Make a tmp copy of a in the same mode as b */
333 if (a->row_relative)
334 tmp += eval_row;
335 else
336 tmp -= eval_row;
338 if (tmp > b->row) {
339 v->cell.a.row = b->row;
340 v->cell.a.row_relative = b->row_relative;
341 v->cell.b.row = a->row;
342 v->cell.b.row_relative = a->row_relative;
345 return (GnmValue *)v;
348 GnmValue *
349 value_new_cellrange_r (Sheet *sheet, GnmRange const *r)
351 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
352 GnmCellRef *a, *b;
354 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
355 v->fmt = NULL;
356 a = &v->cell.a;
357 b = &v->cell.b;
359 a->sheet = sheet;
360 b->sheet = sheet;
361 a->col = r->start.col;
362 a->row = r->start.row;
363 b->col = r->end.col;
364 b->row = r->end.row;
365 a->col_relative = b->col_relative = FALSE;
366 a->row_relative = b->row_relative = FALSE;
368 return (GnmValue *)v;
372 * value_new_cellrange_str:
373 * @sheet: the sheet where the cell range is evaluated. This really only needed if
374 * the range given does not include a sheet specification.
375 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
377 * Parse @str using the convention associated with @sheet.
378 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
379 * succesfully parsed or %NULL on failure.
381 GnmValue *
382 value_new_cellrange_str (Sheet *sheet, char const *str)
384 GnmParsePos pp;
385 GnmExprParseFlags flags = GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS |
386 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES;
388 g_return_val_if_fail (IS_SHEET (sheet), NULL);
389 g_return_val_if_fail (str != NULL, NULL);
391 parse_pos_init_sheet (&pp, sheet);
392 return value_new_cellrange_parsepos_str (&pp, str, flags);
396 * value_new_cellrange_parsepos_str:
397 * @pp: if a relative range is specified, then it will be interpreted relative
398 * to this position (affects only A1-style relative references).
399 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
401 * Parse @str using the convention associated with @sheet.
402 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
403 * succesfully parsed or %NULL on failure.
405 GnmValue *
406 value_new_cellrange_parsepos_str (GnmParsePos const *pp, char const *str,
407 GnmExprParseFlags flags)
409 GnmExprTop const *texpr;
410 GnmConventions const *convs = NULL;
412 g_return_val_if_fail (pp != NULL, NULL);
413 g_return_val_if_fail (str != NULL, NULL);
415 if (pp->sheet)
416 convs = pp->sheet->convs;
418 texpr = gnm_expr_parse_str (str, pp, flags, convs, NULL);
420 if (texpr != NULL) {
421 GnmValue *value = gnm_expr_top_get_range (texpr);
422 gnm_expr_top_unref (texpr);
423 return value;
426 return NULL;
429 GnmValue *
430 value_new_array_non_init (guint cols, guint rows)
432 GnmValueArray *v = CHUNK_ALLOC (GnmValueArray, value_array_pool);
433 *((GnmValueType *)&(v->type)) = VALUE_ARRAY;
434 v->fmt = NULL;
435 v->x = cols;
436 v->y = rows;
437 v->vals = g_new (GnmValue **, cols);
438 return (GnmValue *)v;
441 GnmValue *
442 value_new_array (guint cols, guint rows)
444 guint x, y;
445 GnmValueArray *v = (GnmValueArray *)value_new_array_non_init (cols, rows);
447 for (x = 0; x < cols; x++) {
448 v->vals[x] = g_new (GnmValue *, rows);
449 for (y = 0; y < rows; y++)
450 v->vals[x][y] = value_new_int (0);
452 return (GnmValue *)v;
455 GnmValue *
456 value_new_array_empty (guint cols, guint rows)
458 guint x, y;
459 GnmValueArray *v = (GnmValueArray *)value_new_array_non_init (cols, rows);
461 for (x = 0; x < cols; x++) {
462 v->vals[x] = g_new (GnmValue *, rows);
463 for (y = 0; y < rows; y++)
464 v->vals[x][y] = value_new_empty ();
466 return (GnmValue *)v;
470 * Returns TRUE, FALSE, or -1.
472 static int
473 value_parse_boolean (char const *str, gboolean translated)
475 if (translated) {
476 /* FIXME: ascii??? */
477 if (0 == g_ascii_strcasecmp (str, go_locale_boolean_name (TRUE)))
478 return +TRUE;
479 else if (0 == g_ascii_strcasecmp (str, go_locale_boolean_name (FALSE)))
480 return +FALSE;
481 else
482 return -1;
483 } else {
484 if (0 == g_ascii_strcasecmp (str, "TRUE"))
485 return +TRUE;
486 else if (0 == g_ascii_strcasecmp (str, "FALSE"))
487 return +FALSE;
488 else
489 return -1;
494 GnmValue *
495 value_new_from_string (GnmValueType t, char const *str, GOFormat *sf,
496 gboolean translated)
498 GnmValue *res = NULL;
501 * We need the following cast to avoid a warning from gcc over
502 * VALUE_INTEGER (which is not in GnmValueType).
504 switch ((guint8)t) {
505 case VALUE_EMPTY:
506 res = value_new_empty ();
507 break;
509 case VALUE_BOOLEAN: {
510 int i = value_parse_boolean (str, translated);
511 if (i != -1)
512 res = value_new_bool ((gboolean)i);
513 break;
516 case VALUE_INTEGER:
517 case VALUE_FLOAT: {
518 char *end;
519 gnm_float d;
521 d = gnm_strto (str, &end);
522 if (d != 0 && d > -GNM_MIN && d < GNM_MIN)
523 errno = 0;
525 if (str != end && *end == '\0' && errno != ERANGE)
526 res = value_new_float (d);
527 break;
530 case VALUE_ERROR:
532 * Tricky. We are currently storing errors in translated
533 * format, so we might have to undo that.
535 if (!translated) {
536 size_t i;
537 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++)
538 if (strcmp (standard_errors[i].C_name, str) == 0) {
539 res = value_new_error_std (NULL, (GnmStdError)i);
540 break;
543 if (!res)
544 res = value_new_error (NULL, str);
545 break;
547 case VALUE_STRING:
548 res = value_new_string (str);
549 break;
551 case VALUE_ARRAY:
552 case VALUE_CELLRANGE:
553 default:
554 /* This happen with corrupted files. */
555 return NULL;
558 if (res)
559 value_set_fmt (res, sf);
560 return res;
564 * value_release:
565 * @v: (transfer full) (allow-none): value to dispose of
567 * Free the value.
569 void
570 value_release (GnmValue *value)
572 if (NULL == value)
573 return;
575 if (VALUE_FMT (value) != NULL)
576 go_format_unref (VALUE_FMT (value));
578 switch (value->v_any.type) {
579 case VALUE_EMPTY:
580 case VALUE_BOOLEAN:
581 /* We did not allocate anything, there is nothing to free */
582 return;
584 case VALUE_FLOAT:
585 CHUNK_FREE (value_float_pool, &value->v_float);
586 return;
588 case VALUE_ERROR:
589 /* Do not release VALUE_TERMINATE, it is a magic number */
590 if (value == VALUE_TERMINATE) {
591 g_warning ("Someone freed VALUE_TERMINATE -- shame on them.");
592 return;
595 go_string_unref (value->v_err.mesg);
596 CHUNK_FREE (value_error_pool, &value->v_err);
597 return;
599 case VALUE_STRING:
600 go_string_unref (value->v_str.val);
601 CHUNK_FREE (value_string_pool, &value->v_str);
602 return;
604 case VALUE_ARRAY: {
605 GnmValueArray *v = &value->v_array;
606 int x, y;
608 for (x = 0; x < v->x; x++) {
609 for (y = 0; y < v->y; y++)
610 value_release (v->vals[x][y]);
611 g_free (v->vals[x]);
614 g_free (v->vals);
615 CHUNK_FREE (value_array_pool, v);
616 return;
619 case VALUE_CELLRANGE:
620 CHUNK_FREE (value_range_pool, &value->v_range);
621 return;
623 default:
625 * If we don't recognize the type this is probably garbage.
626 * Do not free it to avoid heap corruption
628 g_warning ("value_release problem.");
629 return;
631 g_assert_not_reached ();
635 * value_dup:
636 * @v: (nullable): #GnmValue
638 * Returns: (transfer full) (nullable): a copy of @v.
640 GnmValue *
641 value_dup (GnmValue const *src)
643 GnmValue *res;
645 if (src == NULL)
646 return NULL;
648 switch (src->v_any.type){
649 case VALUE_EMPTY:
650 res = value_new_empty ();
651 break;
653 case VALUE_BOOLEAN:
654 res = value_new_bool (src->v_bool.val);
655 break;
657 case VALUE_FLOAT:
658 res = value_new_float (src->v_float.val);
659 break;
661 case VALUE_ERROR:
662 res = value_new_error_str (NULL, /* &src->v_err.src, */
663 src->v_err.mesg);
664 break;
666 case VALUE_STRING:
667 go_string_ref (src->v_str.val);
668 res = value_new_string_str (src->v_str.val);
669 break;
671 case VALUE_CELLRANGE:
672 res = value_new_cellrange_unsafe (&src->v_range.cell.a,
673 &src->v_range.cell.b);
674 break;
676 case VALUE_ARRAY: {
677 int x, y;
678 GnmValueArray *array = (GnmValueArray *)value_new_array_non_init (
679 src->v_array.x, src->v_array.y);
681 for (x = 0; x < array->x; x++) {
682 array->vals[x] = g_new (GnmValue *, array->y);
683 for (y = 0; y < array->y; y++)
684 array->vals[x][y] = value_dup (src->v_array.vals[x][y]);
686 res = (GnmValue *)array;
687 break;
690 default:
691 g_warning ("value_dup problem.");
692 res = value_new_empty ();
694 value_set_fmt (res, VALUE_FMT (src));
695 return res;
698 static GnmValDiff
699 value_compare_real (GnmValue const *a, GnmValue const *b,
700 gboolean case_sensitive,
701 gboolean default_locale);
705 * value_cmp:
706 * @ptr_a:
707 * @ptr_b:
709 * qsort style comparison function for ascending order
712 value_cmp (void const *ptr_a, void const *ptr_b)
714 GnmValue const *a = *(GnmValue const **)ptr_a;
715 GnmValue const *b = *(GnmValue const **)ptr_b;
716 switch (value_compare_real (a, b, TRUE, TRUE)) {
717 case IS_EQUAL : return 0;
718 case IS_LESS : return -1;
719 case IS_GREATER : return 1;
720 default:
721 break;
723 return a->v_any.type - b->v_any.type;
727 * value_cmp_reverse:
728 * @ptr_a:
729 * @ptr_b:
731 * qsort style comparison function for descending order.
734 value_cmp_reverse (void const *ptr_a, void const *ptr_b)
736 return -value_cmp (ptr_a, ptr_b);
739 gboolean
740 value_equal (GnmValue const *a, GnmValue const *b)
742 if (a->v_any.type != b->v_any.type)
743 return FALSE;
745 switch (a->v_any.type) {
746 case VALUE_BOOLEAN:
747 return a->v_bool.val == b->v_bool.val;
749 case VALUE_STRING:
750 return go_string_equal (a->v_str.val, b->v_str.val);
752 case VALUE_ERROR:
753 return go_string_equal (a->v_err.mesg, b->v_err.mesg);
755 case VALUE_FLOAT:
756 return a->v_float.val == b->v_float.val;
758 case VALUE_EMPTY:
759 return TRUE;
761 case VALUE_CELLRANGE:
762 return gnm_cellref_equal (&a->v_range.cell.a, &b->v_range.cell.a) &&
763 gnm_cellref_equal (&a->v_range.cell.b, &b->v_range.cell.b);
765 case VALUE_ARRAY:
766 if (a->v_array.x == b->v_array.x && a->v_array.y == b->v_array.y) {
767 int x, y;
769 for (y = 0; y < a->v_array.y; y++)
770 for (x = 0; x < a->v_array.x; x++)
771 if (!value_equal (a->v_array.vals[x][y],
772 b->v_array.vals[x][y]))
773 return FALSE;
774 return TRUE;
775 } else
776 return FALSE;
778 #ifndef DEBUG_SWITCH_ENUM
779 default:
780 g_assert_not_reached ();
781 return FALSE;
782 #endif
786 guint
787 value_hash (GnmValue const *v)
789 switch (v->v_any.type) {
790 case VALUE_BOOLEAN:
791 return v->v_bool.val ? 0x555aaaa : 0xaaa5555;
793 case VALUE_STRING:
794 return go_string_hash (v->v_str.val);
796 case VALUE_ERROR:
797 return go_string_hash (v->v_err.mesg);
799 case VALUE_FLOAT: {
800 int expt;
801 gnm_float mant = gnm_frexp (gnm_abs (v->v_float.val), &expt);
802 guint h = ((guint)(0x80000000u * mant)) ^ expt;
803 if (v->v_float.val >= 0)
804 h ^= 0x55555555;
805 return h;
808 case VALUE_EMPTY:
809 return 42;
811 case VALUE_CELLRANGE:
812 /* FIXME: take sheet into account? */
813 return (gnm_cellref_hash (&v->v_range.cell.a) * 3) ^
814 gnm_cellref_hash (&v->v_range.cell.b);
816 case VALUE_ARRAY: {
817 int i;
818 guint h = (v->v_array.x * 257) ^ (v->v_array.y + 42);
820 /* For speed, just walk the diagonal. */
821 for (i = 0; i < v->v_array.x && i < v->v_array.y; i++) {
822 h *= 5;
823 if (v->v_array.vals[i][i])
824 h ^= value_hash (v->v_array.vals[i][i]);
826 return h;
829 #ifndef DEBUG_SWITCH_ENUM
830 default:
831 g_assert_not_reached ();
832 return 0;
833 #endif
838 GnmValueType
839 value_type_of (const GnmValue *v)
841 return v->v_any.type;
845 gboolean
846 value_get_as_bool (GnmValue const *v, gboolean *err)
848 if (err)
849 *err = FALSE;
851 if (v == NULL)
852 return FALSE;
854 switch (v->v_any.type) {
855 case VALUE_EMPTY:
856 return FALSE;
858 case VALUE_BOOLEAN:
859 return v->v_bool.val;
861 case VALUE_STRING: {
862 int i = value_parse_boolean (value_peek_string (v), FALSE);
863 if (i == -1) {
864 if (err)
865 *err = TRUE;
866 return FALSE;
868 return (gboolean)i;
871 case VALUE_FLOAT:
872 return v->v_float.val != 0.0;
874 default:
875 g_warning ("Unhandled value in value_get_as_bool.");
877 case VALUE_CELLRANGE:
878 case VALUE_ARRAY:
879 case VALUE_ERROR:
880 if (err)
881 *err = TRUE;
883 return FALSE;
887 * use only if you are sure the value is ok
889 gboolean
890 value_get_as_checked_bool (GnmValue const *v)
892 gboolean result, err;
894 result = value_get_as_bool (v, &err);
896 g_return_val_if_fail (!err, FALSE);
898 return result;
902 * value_get_as_gstring:
903 * @v: #GnmValue
904 * @target: #GString
905 * @conv: #GnmConventions
907 * A simple value formatter to convert @v into a string stored in @target
908 * according to @conv. See format_value_gstring for something more elaborate
909 * that handles formats too.
911 void
912 value_get_as_gstring (GnmValue const *v, GString *target,
913 GnmConventions const *conv)
915 if (v == NULL)
916 return;
918 switch (v->v_any.type){
919 case VALUE_EMPTY:
920 return;
922 case VALUE_ERROR: {
923 GnmStdError e = value_error_classify (v);
924 if (e == GNM_ERROR_UNKNOWN) {
925 g_string_append_c (target, '#');
926 go_strescape (target, v->v_err.mesg->str);
927 } else
928 g_string_append (target, value_error_name (e, conv->output.translated));
929 return;
932 case VALUE_BOOLEAN: {
933 gboolean b = v->v_bool.val;
934 g_string_append (target,
935 conv->output.translated
936 ? go_locale_boolean_name (b)
937 : (b ? "TRUE" : "FALSE"));
938 return;
941 case VALUE_STRING:
942 g_string_append (target, v->v_str.val->str);
943 return;
945 case VALUE_FLOAT:
946 if (conv->output.decimal_digits < 0)
947 go_dtoa (target, "!" GNM_FORMAT_g, v->v_float.val);
948 else
949 g_string_append_printf (target, "%.*" GNM_FORMAT_g,
950 conv->output.decimal_digits,
951 v->v_float.val);
952 return;
954 case VALUE_ARRAY: {
955 GnmValue const *val;
956 gunichar row_sep, col_sep;
957 int x, y;
959 if (conv->array_row_sep)
960 row_sep = conv->array_row_sep;
961 else
962 row_sep = go_locale_get_row_sep ();
963 if (conv->array_col_sep)
964 col_sep = conv->array_col_sep;
965 else
966 col_sep = go_locale_get_col_sep ();
968 g_string_append_c (target, '{');
969 for (y = 0; y < v->v_array.y; y++){
970 if (y)
971 g_string_append_unichar (target, row_sep);
973 for (x = 0; x < v->v_array.x; x++){
974 val = v->v_array.vals[x][y];
976 if (x)
977 g_string_append_unichar (target, col_sep);
979 /* quote strings */
980 if (!val) {
981 /* This is not supposed to happen, but
982 let's not crash anyway. */
983 g_string_append (target, "?");
984 } else if (VALUE_IS_STRING (val))
985 go_strescape (target, val->v_str.val->str);
986 else
987 value_get_as_gstring (val, target, conv);
990 g_string_append_c (target, '}');
991 return;
994 case VALUE_CELLRANGE: {
995 char *tmp;
996 /* Note: this makes only sense for absolute references or
997 * references relative to A1
999 GnmRange range;
1000 range_init_value (&range, v);
1001 tmp = global_range_name (v->v_range.cell.a.sheet, &range);
1002 g_string_append (target, tmp);
1003 g_free (tmp);
1004 return;
1007 default:
1008 break;
1011 g_assert_not_reached ();
1016 * value_get_as_string:
1017 * @v: #GnmValue
1019 * Simplistic value rendering
1021 * Returns: (transfer full): a string rendering of @v.
1023 char *
1024 value_get_as_string (GnmValue const *v)
1026 GString *res = g_string_sized_new (10);
1027 value_get_as_gstring (v, res, gnm_conventions_default);
1028 return g_string_free (res, FALSE);
1032 * value_peek_string:
1033 * @v: a #GnmValue
1035 * Returns: (transfer none): A string representation of the value. The
1036 * result will stay valid until either (a) the value is disposed of, or
1037 * (b) two further calls to this function are made.
1039 // NOTE: "(transfer none)" papers over an introspection bug
1040 char const *
1041 value_peek_string (GnmValue const *v)
1043 g_return_val_if_fail (v, "");
1045 if (VALUE_IS_STRING (v))
1046 return v->v_str.val->str;
1047 else if (VALUE_IS_ERROR (v))
1048 return v->v_err.mesg->str;
1049 else {
1050 static char *cache[2] = { NULL, NULL };
1051 static int next = 0;
1052 char const *s;
1054 g_free (cache[next]);
1055 s = cache[next] = value_get_as_string (v);
1056 next = (next + 1) % G_N_ELEMENTS (cache);
1057 return s;
1062 * value_stringify:
1063 * @v: a #GnmValue
1065 * Returns: (transfer full): A string representation of the value suitable
1066 * for use in a Python __repr__ function.
1068 char *
1069 value_stringify (GnmValue const *v)
1071 GString *res = g_string_sized_new (30);
1073 g_string_append_c (res, '{');
1075 switch (v->v_any.type) {
1076 case VALUE_EMPTY:
1077 g_string_append (res, "EMPTY,");
1078 g_string_append (res, "None");
1079 break;
1081 case VALUE_STRING:
1082 g_string_append (res, "STRING,");
1083 go_strescape (res, value_peek_string (v));
1084 break;
1086 case VALUE_CELLRANGE:
1087 g_string_append (res, "CELLRANGE,");
1088 g_string_append (res, value_peek_string (v));
1089 return 0;
1091 case VALUE_ARRAY:
1092 g_string_append (res, "ARRAY,");
1093 g_string_append (res, value_peek_string (v));
1094 break;
1096 case VALUE_FLOAT:
1097 g_string_append (res, "FLOAT,");
1098 g_string_append (res, value_peek_string (v));
1099 break;
1101 case VALUE_BOOLEAN:
1102 g_string_append (res, "BOOLEAN,");
1103 g_string_append_c (res, v->v_bool.val ? '1' : '0');
1104 break;
1106 case VALUE_ERROR:
1107 g_string_append (res, "ERROR,");
1108 go_strescape (res, value_peek_string (v));
1109 break;
1111 default:
1112 g_string_append (res, "?,?");
1113 break;
1116 if (VALUE_FMT (v) != NULL) {
1117 g_string_append_c (res, ',');
1118 go_strescape (res, go_format_as_XL (VALUE_FMT (v)));
1121 g_string_append_c (res, '}');
1123 return g_string_free (res, FALSE);
1129 * value_get_as_int:
1130 * @v: (nullable): a #GnmValue
1132 * Returns: @v interpreted as an integer.
1135 value_get_as_int (GnmValue const *v)
1137 if (v == NULL)
1138 return 0;
1139 switch (v->v_any.type) {
1140 case VALUE_EMPTY:
1141 return 0;
1143 case VALUE_STRING:
1144 return atoi (v->v_str.val->str);
1146 case VALUE_CELLRANGE:
1147 g_warning ("Getting range as a int: what to do?");
1148 return 0;
1150 case VALUE_ARRAY:
1151 return 0;
1153 case VALUE_FLOAT:
1154 return (int) gnm_fake_trunc (v->v_float.val);
1156 case VALUE_BOOLEAN:
1157 return v->v_bool.val ? 1 : 0;
1159 case VALUE_ERROR:
1160 return 0;
1162 default:
1163 g_warning ("value_get_as_int unknown type 0x%x (%d).", v->v_any.type, v->v_any.type);
1164 return 0;
1166 return 0;
1170 * value_get_as_float:
1171 * @v: (nullable): a #GnmValue
1173 * Returns: @v interpreted as a floating point value.
1175 gnm_float
1176 value_get_as_float (GnmValue const *v)
1178 if (v == NULL)
1179 return 0.;
1181 switch (v->v_any.type) {
1182 case VALUE_EMPTY:
1183 return 0.;
1185 case VALUE_STRING:
1186 return gnm_strto (v->v_str.val->str, NULL);
1188 case VALUE_CELLRANGE:
1189 g_warning ("Getting range as a double: what to do?");
1190 return 0.0;
1192 case VALUE_ARRAY:
1193 return 0.0;
1195 case VALUE_FLOAT:
1196 return (gnm_float) v->v_float.val;
1198 case VALUE_BOOLEAN:
1199 return v->v_bool.val ? 1. : 0.;
1201 case VALUE_ERROR:
1202 return 0.;
1204 default:
1205 g_warning ("value_get_as_float type error.");
1206 break;
1208 return 0.0;
1211 gboolean
1212 value_is_zero (GnmValue const *v)
1214 return gnm_abs (value_get_as_float (v)) < 64 * GNM_EPSILON;
1217 GnmRangeRef const *
1218 value_get_rangeref (GnmValue const *v)
1220 g_return_val_if_fail (VALUE_IS_CELLRANGE (v), NULL);
1221 return &v->v_range.cell;
1226 * value_coerce_to_number:
1227 * @v:
1228 * @valid:
1230 * If the value can be used as a number return that number
1231 * otherwise free it at return an appropriate error
1233 GnmValue *
1234 value_coerce_to_number (GnmValue *v, gboolean *valid, GnmEvalPos const *ep)
1236 g_return_val_if_fail (v != NULL, NULL);
1238 *valid = FALSE;
1239 if (VALUE_IS_STRING (v)) {
1240 GnmValue *tmp =
1241 format_match_number (value_peek_string (v), NULL,
1242 sheet_date_conv (ep->sheet));
1243 value_release (v);
1244 if (tmp == NULL)
1245 return value_new_error_VALUE (ep);
1246 v = tmp;
1247 } else if (VALUE_IS_ERROR (v))
1248 return v;
1250 if (!VALUE_IS_NUMBER (v)) {
1251 value_release (v);
1252 return value_new_error_VALUE (ep);
1255 *valid = TRUE;
1256 return v;
1259 void
1260 value_array_set (GnmValue *array, int col, int row, GnmValue *v)
1262 g_return_if_fail (v);
1263 g_return_if_fail (VALUE_IS_ARRAY (array));
1264 g_return_if_fail (col>=0);
1265 g_return_if_fail (row>=0);
1266 g_return_if_fail (array->v_array.y > row);
1267 g_return_if_fail (array->v_array.x > col);
1269 value_release (array->v_array.vals[col][row]);
1270 array->v_array.vals[col][row] = v;
1273 static GnmValDiff
1274 compare_bool_bool (GnmValue const *va, GnmValue const *vb)
1276 gboolean err; /* Ignored */
1277 gboolean const a = value_get_as_bool (va, &err);
1278 gboolean const b = value_get_as_bool (vb, &err);
1279 if (a)
1280 return b ? IS_EQUAL : IS_GREATER;
1281 return b ? IS_LESS : IS_EQUAL;
1284 static GnmValDiff
1285 compare_float_float (GnmValue const *va, GnmValue const *vb)
1287 gnm_float const a = value_get_as_float (va);
1288 gnm_float const b = value_get_as_float (vb);
1289 if (a == b)
1290 return IS_EQUAL;
1291 else if (a < b)
1292 return IS_LESS;
1293 else
1294 return IS_GREATER;
1297 static GnmValDiff
1298 compare_error_error (GnmValue const *va, GnmValue const *vb)
1300 GnmStdError ea = value_error_classify (va);
1301 GnmStdError eb = value_error_classify (vb);
1302 int i;
1304 if (ea != eb)
1305 return ea < eb ? IS_LESS : IS_GREATER;
1307 if (ea != GNM_ERROR_UNKNOWN)
1308 return IS_EQUAL;
1310 /* Two unknown errors. Just compare strings. */
1311 i = strcmp (value_peek_string (va), value_peek_string (vb));
1312 return (i > 0 ? IS_GREATER : (i < 0 ? IS_LESS : IS_EQUAL));
1317 * value_diff:
1318 * @a: value a
1319 * @b: value b
1321 * IGNORES format.
1323 * Returns a non-negative difference between 2 values
1325 gnm_float
1326 value_diff (GnmValue const *a, GnmValue const *b)
1328 GnmValueType ta, tb;
1330 /* Handle trivial (including empty/empty) and double NULL */
1331 if (a == b)
1332 return 0.;
1334 ta = VALUE_IS_EMPTY (a) ? VALUE_EMPTY : a->v_any.type;
1335 tb = VALUE_IS_EMPTY (b) ? VALUE_EMPTY : b->v_any.type;
1337 /* string > empty */
1338 if (ta == VALUE_STRING) {
1339 switch (tb) {
1340 /* Strings are > (empty, or number) */
1341 case VALUE_EMPTY:
1342 if (*a->v_str.val->str == '\0')
1343 return 0.;
1344 return DBL_MAX;
1346 /* If both are strings compare as string */
1347 case VALUE_STRING:
1348 if (go_string_equal (a->v_str.val, b->v_str.val))
1349 return 0.;
1351 case VALUE_FLOAT: case VALUE_BOOLEAN:
1352 default:
1353 return DBL_MAX;
1356 } else if (tb == VALUE_STRING) {
1357 switch (ta) {
1358 /* (empty, or number) < String */
1359 case VALUE_EMPTY:
1360 if (*b->v_str.val->str == '\0')
1361 return 0.;
1363 case VALUE_FLOAT : case VALUE_BOOLEAN:
1364 default:
1365 return DBL_MAX;
1369 /* Booleans > all numbers (Why did excel do this ?? ) */
1370 if (ta == VALUE_BOOLEAN && tb == VALUE_FLOAT)
1371 return DBL_MAX;
1372 if (tb == VALUE_BOOLEAN && ta == VALUE_FLOAT)
1373 return DBL_MAX;
1375 switch ((ta > tb) ? ta : tb) {
1376 case VALUE_EMPTY: /* Empty Empty compare */
1377 return 0.;
1379 case VALUE_BOOLEAN:
1380 return (compare_bool_bool (a, b) == IS_EQUAL) ? 0. : DBL_MAX;
1382 case VALUE_FLOAT: {
1383 gnm_float const da = value_get_as_float (a);
1384 gnm_float const db = value_get_as_float (b);
1385 return gnm_abs (da - db);
1387 default:
1388 return TYPE_MISMATCH;
1392 static int
1393 gnm_string_cmp (gconstpointer gstr_a, gconstpointer gstr_b)
1395 return (gstr_a == gstr_b)
1397 : g_utf8_collate (((GOString const *)gstr_a)->str,
1398 ((GOString const *)gstr_b)->str);
1401 static int
1402 gnm_string_cmp_ignorecase (gconstpointer gstr_a, gconstpointer gstr_b)
1404 gchar *a;
1405 gchar *b;
1406 int res;
1408 if (gstr_a == gstr_b)
1409 return 0;
1411 a = g_utf8_casefold (((GOString const *)gstr_a)->str, -1);
1412 b = g_utf8_casefold (((GOString const *)gstr_b)->str, -1);
1414 res = g_utf8_collate (a, b);
1416 g_free (a);
1417 g_free (b);
1419 return res;
1423 /* This depends on the actual values of the enums. */
1424 #define PAIR(ta_,tb_) ((ta_) + (((tb_) >> 3) - 1))
1425 #define CPAIR(ta_,tb_) (1 ? PAIR((ta_),(tb_)) : sizeof (struct { int sanity_check[((ta_) >= (tb_)) * 2 - 1]; } ))
1428 * value_compare:
1430 * @a: value a
1431 * @b: value b
1432 * @case_sensitive: are string comparisons case sensitive.
1434 * IGNORES format.
1436 static GnmValDiff
1437 value_compare_real (GnmValue const *a, GnmValue const *b,
1438 gboolean case_sensitive,
1439 gboolean default_locale)
1441 GnmValueType ta, tb;
1442 gboolean flip;
1443 GnmValDiff res;
1445 /* Handle trivial and double NULL case */
1446 if (a == b)
1447 return IS_EQUAL;
1449 ta = VALUE_IS_EMPTY (a) ? VALUE_EMPTY : a->v_any.type;
1450 tb = VALUE_IS_EMPTY (b) ? VALUE_EMPTY : b->v_any.type;
1452 flip = (tb > ta);
1453 if (flip) {
1454 GnmValueType t = ta;
1455 GnmValue const *v = a;
1456 ta = tb;
1457 tb = t;
1458 a = b;
1459 b = v;
1462 switch (PAIR (ta,tb)) {
1463 case CPAIR (VALUE_EMPTY,VALUE_EMPTY):
1464 /* In most cases this is handled by the trivial case. */
1465 /* We can get here if one of a and b is NULL and the */
1466 /* is not but contains an empty value. */
1467 return IS_EQUAL;
1469 /* ---------------------------------------- */
1471 case CPAIR (VALUE_BOOLEAN,VALUE_EMPTY): /* Blank is FALSE */
1472 case CPAIR (VALUE_BOOLEAN,VALUE_BOOLEAN):
1473 res = compare_bool_bool (a, b);
1474 break;
1476 /* ---------------------------------------- */
1478 case CPAIR (VALUE_FLOAT,VALUE_BOOLEAN):
1479 /* Number < boolean (Why did excel do this ?? ) */
1480 res = IS_LESS;
1481 break;
1482 case CPAIR (VALUE_FLOAT,VALUE_EMPTY): /* Blank is 0 */
1483 case CPAIR (VALUE_FLOAT,VALUE_FLOAT):
1484 res = compare_float_float (a, b);
1485 break;
1487 /* ---------------------------------------- */
1489 case CPAIR (VALUE_ERROR,VALUE_EMPTY):
1490 case CPAIR (VALUE_ERROR,VALUE_BOOLEAN):
1491 case CPAIR (VALUE_ERROR,VALUE_FLOAT):
1492 /* Error > others */
1493 res = IS_GREATER;
1494 break;
1496 case CPAIR (VALUE_ERROR,VALUE_ERROR):
1497 res = compare_error_error (a, b);
1498 break;
1500 /* ---------------------------------------- */
1502 case CPAIR (VALUE_STRING,VALUE_EMPTY): /* Blank is empty string */
1503 /* String > empty, except empty string */
1504 res = a->v_str.val->str[0] == '\0' ? IS_EQUAL : IS_GREATER;
1505 break;
1507 case CPAIR (VALUE_STRING,VALUE_BOOLEAN):
1508 /* String < boolean */
1509 res = IS_LESS;
1510 break;
1512 case CPAIR (VALUE_STRING,VALUE_FLOAT):
1513 /* String > number */
1514 res = IS_GREATER;
1515 break;
1517 case CPAIR (VALUE_STRING,VALUE_ERROR):
1518 /* String < error */
1519 res = IS_LESS;
1520 break;
1522 case CPAIR (VALUE_STRING,VALUE_STRING): {
1523 GOString const *sa = a->v_str.val;
1524 GOString const *sb = b->v_str.val;
1525 int i = (default_locale
1526 ? (case_sensitive
1527 ? go_string_cmp (sa, sb)
1528 : go_string_cmp_ignorecase (sa, sb))
1529 : (case_sensitive
1530 ? gnm_string_cmp (sa, sb)
1531 : gnm_string_cmp_ignorecase (sa, sb)));
1532 res = (i > 0 ? IS_GREATER : (i < 0 ? IS_LESS : IS_EQUAL));
1533 break;
1536 /* ---------------------------------------- */
1538 default:
1539 res = TYPE_MISMATCH;
1542 if (flip) {
1543 if (res == IS_LESS)
1544 res = IS_GREATER;
1545 else if (res == IS_GREATER)
1546 res = IS_LESS;
1549 return res;
1551 #undef PAIR
1554 GnmValDiff
1555 value_compare (GnmValue const *a, GnmValue const *b, gboolean case_sensitive)
1557 return value_compare_real (a, b, case_sensitive, TRUE);
1560 GnmValDiff
1561 value_compare_no_cache (GnmValue const *a, GnmValue const *b,
1562 gboolean case_sensitive)
1564 return value_compare_real (a, b, case_sensitive, FALSE);
1568 * value_set_format:
1569 * @v: #GnmValue
1570 * @fmt: (nullable): #GOFormat
1572 * Sets @v's format.
1574 void
1575 value_set_fmt (GnmValue *v, GOFormat const *fmt)
1577 if (fmt == VALUE_FMT (v))
1578 return;
1579 g_return_if_fail (!VALUE_IS_EMPTY (v) && !VALUE_IS_BOOLEAN (v));
1580 if (fmt != NULL)
1581 go_format_ref (fmt);
1582 if (VALUE_FMT (v) != NULL)
1583 go_format_unref (VALUE_FMT (v));
1584 v->v_any.fmt = fmt;
1587 /****************************************************************************/
1589 GType
1590 gnm_value_get_type (void)
1592 static GType t = 0;
1594 if (t == 0)
1595 t = g_boxed_type_register_static ("GnmValue",
1596 (GBoxedCopyFunc)value_dup,
1597 (GBoxedFreeFunc)value_release);
1598 return t;
1600 /****************************************************************************/
1602 GnmValueErr const value_terminate_err = { VALUE_ERROR, NULL, NULL };
1603 static GnmValueFloat const the_value_zero = { VALUE_FLOAT, NULL, 0 };
1604 GnmValue const *value_zero = (GnmValue const *)&the_value_zero;
1607 * value_init: (skip)
1609 void
1610 value_init (void)
1612 size_t i;
1614 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++) {
1615 standard_errors[i].locale_name = _(standard_errors[i].C_name);
1616 standard_errors[i].locale_name_str =
1617 go_string_new (standard_errors[i].locale_name);
1620 #if USE_VALUE_POOLS
1621 value_float_pool =
1622 go_mem_chunk_new ("value float pool",
1623 sizeof (GnmValueFloat),
1624 16 * 1024 - 128);
1626 value_error_pool =
1627 go_mem_chunk_new ("value error pool",
1628 sizeof (GnmValueErr),
1629 16 * 1024 - 128);
1631 value_string_pool =
1632 go_mem_chunk_new ("value string pool",
1633 sizeof (GnmValueStr),
1634 16 * 1024 - 128);
1636 value_range_pool =
1637 go_mem_chunk_new ("value range pool",
1638 sizeof (GnmValueRange),
1639 16 * 1024 - 128);
1641 value_array_pool =
1642 go_mem_chunk_new ("value array pool",
1643 sizeof (GnmValueArray),
1644 16 * 1024 - 128);
1645 #endif
1649 * value_shutdown: (skip)
1651 void
1652 value_shutdown (void)
1654 size_t i;
1656 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++) {
1657 go_string_unref (standard_errors[i].locale_name_str);
1658 standard_errors[i].locale_name_str = NULL;
1661 #if USE_VALUE_POOLS
1662 go_mem_chunk_destroy (value_float_pool, FALSE);
1663 value_float_pool = NULL;
1665 go_mem_chunk_destroy (value_error_pool, FALSE);
1666 value_error_pool = NULL;
1668 go_mem_chunk_destroy (value_string_pool, FALSE);
1669 value_string_pool = NULL;
1671 go_mem_chunk_destroy (value_range_pool, FALSE);
1672 value_range_pool = NULL;
1674 go_mem_chunk_destroy (value_array_pool, FALSE);
1675 value_array_pool = NULL;
1676 #else
1677 if (value_allocations)
1678 g_printerr ("Leaking %d values.\n", value_allocations);
1679 #endif
1682 /****************************************************************************/