Move plugin init code
[gnumeric.git] / src / value.c
blobcfaf072d79e5b96cdff1e24a84f247248fab7c00
1 /*
2 * value.c: Utilies for handling, creating, removing values.
4 * Authors:
5 * Miguel de Icaza (miguel@gnu.org).
6 * Michael Meeks (mmeeks@gnu.org)
7 * Jody Goldberg (jgolderg@home.com)
8 * Copyright (C) 2000-2009 Morten Welinder (terra@gnome.org)
9 */
11 #include <gnumeric-config.h>
12 #include <glib/gi18n-lib.h>
13 #include <gnumeric.h>
14 #include <value.h>
16 #include <parse-util.h>
17 #include <style.h>
18 #include <gnm-format.h>
19 #include <position.h>
20 #include <mathfunc.h>
21 #include <gutils.h>
22 #include <workbook.h>
23 #include <expr.h>
24 #include <ranges.h>
25 #include <sheet.h>
26 #include <cell.h>
27 #include <number-match.h>
28 #include <goffice/goffice.h>
30 #include <stdlib.h>
31 #include <errno.h>
32 #include <math.h>
33 #include <string.h>
35 #ifndef USE_VALUE_POOLS
36 #define USE_VALUE_POOLS 0
37 #endif
39 #if USE_VALUE_POOLS
40 static GOMemChunk *value_float_pool;
41 static GOMemChunk *value_error_pool;
42 static GOMemChunk *value_string_pool;
43 static GOMemChunk *value_range_pool;
44 static GOMemChunk *value_array_pool;
45 #define CHUNK_ALLOC(T,p) ((T*)go_mem_chunk_alloc (p))
46 #define CHUNK_FREE(p,v) go_mem_chunk_free ((p), (v))
47 #else
48 static int value_allocations = 0;
49 #define CHUNK_ALLOC(T,c) (value_allocations++, g_slice_new (T))
50 #define CHUNK_FREE(p,v) (value_allocations--, g_slice_free1 (sizeof(*v),(v)))
51 #endif
54 static struct {
55 char const *C_name;
56 char const *locale_name;
57 GOString *locale_name_str;
58 } standard_errors[] = {
59 { N_("#NULL!"), NULL, NULL },
60 { N_("#DIV/0!"), NULL, NULL },
61 { N_("#VALUE!"), NULL, NULL },
62 { N_("#REF!"), NULL, NULL },
63 { N_("#NAME?"), NULL, NULL },
64 { N_("#NUM!"), NULL, NULL },
65 { N_("#N/A"), NULL, NULL },
66 { N_("#UNKNOWN!"), NULL, NULL }
69 GnmValue *
70 value_new_empty (void)
72 /* This is a constant. No need to allocate any memory. */
73 static const GnmValueAny v = { VALUE_EMPTY, NULL };
74 return (GnmValue *)&v;
77 GnmValue *
78 value_new_bool (gboolean b)
80 /* These are constant. No need to allocate any memory. */
81 static const GnmValueBool vf = { VALUE_BOOLEAN, NULL, FALSE };
82 static const GnmValueBool vt = { VALUE_BOOLEAN, NULL, TRUE };
83 return (GnmValue*) (b ? &vt : &vf);
86 GnmValue *
87 value_new_int (int i)
89 return value_new_float (i);
92 GnmValue *
93 value_new_float (gnm_float f)
95 if (gnm_finite (f)) {
96 GnmValueFloat *v = CHUNK_ALLOC (GnmValueFloat, value_float_pool);
97 *((GnmValueType *)&(v->type)) = VALUE_FLOAT;
98 v->fmt = NULL;
99 v->val = f;
100 return (GnmValue *)v;
101 } else {
102 /* FIXME: bogus ep sent here. What to do? */
103 return value_new_error_NUM (NULL);
107 GnmValue *
108 value_new_error (G_GNUC_UNUSED GnmEvalPos const *ep, char const *mesg)
110 GnmValueErr *v = CHUNK_ALLOC (GnmValueErr, value_error_pool);
111 *((GnmValueType *)&(v->type)) = VALUE_ERROR;
112 v->fmt = NULL;
113 v->mesg = go_string_new (mesg);
114 return (GnmValue *)v;
117 GnmValue *
118 value_new_error_str (G_GNUC_UNUSED GnmEvalPos const *ep, GOString *mesg)
120 GnmValueErr *v = CHUNK_ALLOC (GnmValueErr, value_error_pool);
121 *((GnmValueType *)&(v->type)) = VALUE_ERROR;
122 v->fmt = NULL;
123 v->mesg = go_string_ref (mesg);
124 return (GnmValue *)v;
127 GnmValue *
128 value_new_error_std (GnmEvalPos const *pos, GnmStdError err)
130 size_t i = (size_t)err;
131 g_return_val_if_fail (i < G_N_ELEMENTS (standard_errors), NULL);
133 return value_new_error_str (pos, standard_errors[i].locale_name_str);
137 GnmValue *
138 value_new_error_NULL (GnmEvalPos const *pos)
140 return value_new_error_str (pos, standard_errors[GNM_ERROR_NULL].locale_name_str);
143 GnmValue *
144 value_new_error_DIV0 (GnmEvalPos const *pos)
146 return value_new_error_str (pos, standard_errors[GNM_ERROR_DIV0].locale_name_str);
149 GnmValue *
150 value_new_error_VALUE (GnmEvalPos const *pos)
152 return value_new_error_str (pos, standard_errors[GNM_ERROR_VALUE].locale_name_str);
155 GnmValue *
156 value_new_error_REF (GnmEvalPos const *pos)
158 return value_new_error_str (pos, standard_errors[GNM_ERROR_REF].locale_name_str);
161 GnmValue *
162 value_new_error_NAME (GnmEvalPos const *pos)
164 return value_new_error_str (pos, standard_errors[GNM_ERROR_NAME].locale_name_str);
167 GnmValue *
168 value_new_error_NUM (GnmEvalPos const *pos)
170 return value_new_error_str (pos, standard_errors[GNM_ERROR_NUM].locale_name_str);
173 GnmValue *
174 value_new_error_NA (GnmEvalPos const *pos)
176 return value_new_error_str (pos, standard_errors[GNM_ERROR_NA].locale_name_str);
180 * value_error_name:
181 * @err: #GnmStdError
182 * @translated: If %TRUE, use localized name.
184 * Returns: (transfer none): the name of @err, possibly localized.
186 char const *
187 value_error_name (GnmStdError err, gboolean translated)
189 size_t i = (size_t)err;
190 g_return_val_if_fail (i < G_N_ELEMENTS (standard_errors), NULL);
192 if (translated)
193 return standard_errors[i].locale_name;
194 else
195 return standard_errors[i].C_name;
199 * value_error_set_pos:
200 * @err:
201 * @pos:
203 * Change the position of a ValueError.
205 * Returns: (transfer none): @err as a #GnmValue.
207 GnmValue *
208 value_error_set_pos (GnmValueErr *err, G_GNUC_UNUSED GnmEvalPos const *pos)
210 g_return_val_if_fail (err != NULL, NULL);
211 g_return_val_if_fail (VALUE_IS_ERROR ((GnmValue *)err), NULL);
213 /* err->src = *pos; */
214 return (GnmValue *)err;
217 GnmStdError
218 value_error_classify (GnmValue const *v)
220 size_t i;
222 g_return_val_if_fail (v != NULL, GNM_ERROR_UNKNOWN);
224 if (!VALUE_IS_ERROR (v))
225 return GNM_ERROR_UNKNOWN;
227 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++)
228 if (standard_errors[i].locale_name_str == v->v_err.mesg)
229 return (GnmStdError)i;
231 return GNM_ERROR_UNKNOWN;
236 * value_new_string_str:
237 * @str: (transfer full): string to use for value
239 * Returns: (transfer full): a new value object.
241 GnmValue *
242 value_new_string_str (GOString *str)
244 GnmValueStr *v;
246 g_return_val_if_fail (str != NULL, NULL);
248 v = CHUNK_ALLOC (GnmValueStr, value_string_pool);
249 *((GnmValueType *)&(v->type)) = VALUE_STRING;
250 v->fmt = NULL;
251 v->val = str;
252 return (GnmValue *)v;
256 * value_new_string:
257 * @str: string to use for value
259 * Returns: (transfer full): a new value object.
261 GnmValue *
262 value_new_string (char const *str)
264 return value_new_string_str (go_string_new (str));
268 * value_new_string_nocopy:
269 * @str: (transfer full): string to use for value
271 * Returns: (transfer full): a new value object.
273 GnmValue *
274 value_new_string_nocopy (char *str)
276 return value_new_string_str (go_string_new_nocopy (str));
279 GnmValue *
280 value_new_cellrange_unsafe (GnmCellRef const *a, GnmCellRef const *b)
282 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
283 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
284 v->fmt = NULL;
285 v->cell.a = *a;
286 v->cell.b = *b;
287 return (GnmValue *)v;
291 * value_new_cellrange:
293 * Create a new range reference.
295 * Attempt to do a sanity check for inverted ranges.
296 * NOTE : This is no longer necessary and will be removed.
297 * mixed mode references create the possibility of inversion.
298 * users of these values need to use the utility routines to
299 * evaluate the ranges in their context and normalize then.
301 GnmValue *
302 value_new_cellrange (GnmCellRef const *a, GnmCellRef const *b,
303 int eval_col, int eval_row)
305 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
306 int tmp;
308 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
309 v->fmt = NULL;
310 v->cell.a = *a;
311 v->cell.b = *b;
313 /* Sanity checking to avoid inverted ranges */
314 tmp = a->col;
315 if (a->col_relative != b->col_relative) {
316 /* Make a tmp copy of a in the same mode as b */
317 if (a->col_relative)
318 tmp += eval_col;
319 else
320 tmp -= eval_col;
322 if (tmp > b->col) {
323 v->cell.a.col = b->col;
324 v->cell.a.col_relative = b->col_relative;
325 v->cell.b.col = a->col;
326 v->cell.b.col_relative = a->col_relative;
329 tmp = a->row;
330 if (a->row_relative != b->row_relative) {
331 /* Make a tmp copy of a in the same mode as b */
332 if (a->row_relative)
333 tmp += eval_row;
334 else
335 tmp -= eval_row;
337 if (tmp > b->row) {
338 v->cell.a.row = b->row;
339 v->cell.a.row_relative = b->row_relative;
340 v->cell.b.row = a->row;
341 v->cell.b.row_relative = a->row_relative;
344 return (GnmValue *)v;
347 GnmValue *
348 value_new_cellrange_r (Sheet *sheet, GnmRange const *r)
350 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
351 GnmCellRef *a, *b;
353 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
354 v->fmt = NULL;
355 a = &v->cell.a;
356 b = &v->cell.b;
358 a->sheet = sheet;
359 b->sheet = sheet;
360 a->col = r->start.col;
361 a->row = r->start.row;
362 b->col = r->end.col;
363 b->row = r->end.row;
364 a->col_relative = b->col_relative = FALSE;
365 a->row_relative = b->row_relative = FALSE;
367 return (GnmValue *)v;
371 * value_new_cellrange_str:
372 * @sheet: the sheet where the cell range is evaluated. This really only needed if
373 * the range given does not include a sheet specification.
374 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
376 * Parse @str using the convention associated with @sheet.
377 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
378 * succesfully parsed or %NULL on failure.
380 GnmValue *
381 value_new_cellrange_str (Sheet *sheet, char const *str)
383 GnmParsePos pp;
384 GnmExprParseFlags flags = GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS |
385 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES;
387 g_return_val_if_fail (IS_SHEET (sheet), NULL);
388 g_return_val_if_fail (str != NULL, NULL);
390 parse_pos_init_sheet (&pp, sheet);
391 return value_new_cellrange_parsepos_str (&pp, str, flags);
395 * value_new_cellrange_parsepos_str:
396 * @pp: if a relative range is specified, then it will be interpreted relative
397 * to this position (affects only A1-style relative references).
398 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
400 * Parse @str using the convention associated with @sheet.
401 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
402 * succesfully parsed or %NULL on failure.
404 GnmValue *
405 value_new_cellrange_parsepos_str (GnmParsePos const *pp, char const *str,
406 GnmExprParseFlags flags)
408 GnmExprTop const *texpr;
409 GnmConventions const *convs = NULL;
411 g_return_val_if_fail (pp != NULL, NULL);
412 g_return_val_if_fail (str != NULL, NULL);
414 if (pp->sheet)
415 convs = pp->sheet->convs;
417 texpr = gnm_expr_parse_str (str, pp, flags, convs, NULL);
419 if (texpr != NULL) {
420 GnmValue *value = gnm_expr_top_get_range (texpr);
421 gnm_expr_top_unref (texpr);
422 return value;
425 return NULL;
428 GnmValue *
429 value_new_array_non_init (guint cols, guint rows)
431 GnmValueArray *v = CHUNK_ALLOC (GnmValueArray, value_array_pool);
432 *((GnmValueType *)&(v->type)) = VALUE_ARRAY;
433 v->fmt = NULL;
434 v->x = cols;
435 v->y = rows;
436 v->vals = g_new (GnmValue **, cols);
437 return (GnmValue *)v;
440 GnmValue *
441 value_new_array (guint cols, guint rows)
443 guint x, y;
444 GnmValueArray *v = (GnmValueArray *)value_new_array_non_init (cols, rows);
446 for (x = 0; x < cols; x++) {
447 v->vals[x] = g_new (GnmValue *, rows);
448 for (y = 0; y < rows; y++)
449 v->vals[x][y] = value_new_int (0);
451 return (GnmValue *)v;
454 GnmValue *
455 value_new_array_empty (guint cols, guint rows)
457 guint x, y;
458 GnmValueArray *v = (GnmValueArray *)value_new_array_non_init (cols, rows);
460 for (x = 0; x < cols; x++) {
461 v->vals[x] = g_new (GnmValue *, rows);
462 for (y = 0; y < rows; y++)
463 v->vals[x][y] = value_new_empty ();
465 return (GnmValue *)v;
469 * Returns TRUE, FALSE, or -1.
471 static int
472 value_parse_boolean (char const *str, gboolean translated)
474 if (translated) {
475 /* FIXME: ascii??? */
476 if (0 == g_ascii_strcasecmp (str, go_locale_boolean_name (TRUE)))
477 return +TRUE;
478 else if (0 == g_ascii_strcasecmp (str, go_locale_boolean_name (FALSE)))
479 return +FALSE;
480 else
481 return -1;
482 } else {
483 if (0 == g_ascii_strcasecmp (str, "TRUE"))
484 return +TRUE;
485 else if (0 == g_ascii_strcasecmp (str, "FALSE"))
486 return +FALSE;
487 else
488 return -1;
493 GnmValue *
494 value_new_from_string (GnmValueType t, char const *str, GOFormat *sf,
495 gboolean translated)
497 GnmValue *res = NULL;
500 * We need the following cast to avoid a warning from gcc over
501 * VALUE_INTEGER (which is not in GnmValueType).
503 switch ((guint8)t) {
504 case VALUE_EMPTY:
505 res = value_new_empty ();
506 break;
508 case VALUE_BOOLEAN: {
509 int i = value_parse_boolean (str, translated);
510 if (i != -1)
511 res = value_new_bool ((gboolean)i);
512 break;
515 case VALUE_INTEGER:
516 case VALUE_FLOAT: {
517 char *end;
518 gnm_float d;
520 d = gnm_strto (str, &end);
521 if (d != 0 && d > -GNM_MIN && d < GNM_MIN)
522 errno = 0;
524 if (str != end && *end == '\0' && errno != ERANGE)
525 res = value_new_float (d);
526 break;
529 case VALUE_ERROR:
531 * Tricky. We are currently storing errors in translated
532 * format, so we might have to undo that.
534 if (!translated) {
535 size_t i;
536 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++)
537 if (strcmp (standard_errors[i].C_name, str) == 0) {
538 res = value_new_error_std (NULL, (GnmStdError)i);
539 break;
542 if (!res)
543 res = value_new_error (NULL, str);
544 break;
546 case VALUE_STRING:
547 res = value_new_string (str);
548 break;
550 case VALUE_ARRAY:
551 case VALUE_CELLRANGE:
552 default:
553 /* This happen with corrupted files. */
554 return NULL;
557 if (res)
558 value_set_fmt (res, sf);
559 return res;
563 * value_release:
564 * @v: (transfer full) (allow-none): value to dispose of
566 * Free the value.
568 void
569 value_release (GnmValue *value)
571 if (NULL == value)
572 return;
574 if (VALUE_FMT (value) != NULL)
575 go_format_unref (VALUE_FMT (value));
577 switch (value->v_any.type) {
578 case VALUE_EMPTY:
579 case VALUE_BOOLEAN:
580 /* We did not allocate anything, there is nothing to free */
581 return;
583 case VALUE_FLOAT:
584 CHUNK_FREE (value_float_pool, &value->v_float);
585 return;
587 case VALUE_ERROR:
588 /* Do not release VALUE_TERMINATE, it is a magic number */
589 if (value == VALUE_TERMINATE) {
590 g_warning ("Someone freed VALUE_TERMINATE -- shame on them.");
591 return;
594 go_string_unref (value->v_err.mesg);
595 CHUNK_FREE (value_error_pool, &value->v_err);
596 return;
598 case VALUE_STRING:
599 go_string_unref (value->v_str.val);
600 CHUNK_FREE (value_string_pool, &value->v_str);
601 return;
603 case VALUE_ARRAY: {
604 GnmValueArray *v = &value->v_array;
605 int x, y;
607 for (x = 0; x < v->x; x++) {
608 for (y = 0; y < v->y; y++)
609 value_release (v->vals[x][y]);
610 g_free (v->vals[x]);
613 g_free (v->vals);
614 CHUNK_FREE (value_array_pool, v);
615 return;
618 case VALUE_CELLRANGE:
619 CHUNK_FREE (value_range_pool, &value->v_range);
620 return;
622 default:
624 * If we don't recognize the type this is probably garbage.
625 * Do not free it to avoid heap corruption
627 g_warning ("value_release problem.");
628 return;
630 g_assert_not_reached ();
634 * value_dup:
635 * @v: (nullable): #GnmValue
637 * Returns: (transfer full) (nullable): a copy of @v.
639 GnmValue *
640 value_dup (GnmValue const *src)
642 GnmValue *res;
644 if (src == NULL)
645 return NULL;
647 switch (src->v_any.type){
648 case VALUE_EMPTY:
649 res = value_new_empty ();
650 break;
652 case VALUE_BOOLEAN:
653 res = value_new_bool (src->v_bool.val);
654 break;
656 case VALUE_FLOAT:
657 res = value_new_float (src->v_float.val);
658 break;
660 case VALUE_ERROR:
661 res = value_new_error_str (NULL, /* &src->v_err.src, */
662 src->v_err.mesg);
663 break;
665 case VALUE_STRING:
666 go_string_ref (src->v_str.val);
667 res = value_new_string_str (src->v_str.val);
668 break;
670 case VALUE_CELLRANGE:
671 res = value_new_cellrange_unsafe (&src->v_range.cell.a,
672 &src->v_range.cell.b);
673 break;
675 case VALUE_ARRAY: {
676 int x, y;
677 GnmValueArray *array = (GnmValueArray *)value_new_array_non_init (
678 src->v_array.x, src->v_array.y);
680 for (x = 0; x < array->x; x++) {
681 array->vals[x] = g_new (GnmValue *, array->y);
682 for (y = 0; y < array->y; y++)
683 array->vals[x][y] = value_dup (src->v_array.vals[x][y]);
685 res = (GnmValue *)array;
686 break;
689 default:
690 g_warning ("value_dup problem.");
691 res = value_new_empty ();
693 value_set_fmt (res, VALUE_FMT (src));
694 return res;
697 static GnmValDiff
698 value_compare_real (GnmValue const *a, GnmValue const *b,
699 gboolean case_sensitive,
700 gboolean default_locale);
704 * value_cmp:
705 * @ptr_a:
706 * @ptr_b:
708 * qsort style comparison function for ascending order
711 value_cmp (void const *ptr_a, void const *ptr_b)
713 GnmValue const *a = *(GnmValue const **)ptr_a;
714 GnmValue const *b = *(GnmValue const **)ptr_b;
715 switch (value_compare_real (a, b, TRUE, TRUE)) {
716 case IS_EQUAL : return 0;
717 case IS_LESS : return -1;
718 case IS_GREATER : return 1;
719 default:
720 break;
722 return a->v_any.type - b->v_any.type;
726 * value_cmp_reverse:
727 * @ptr_a:
728 * @ptr_b:
730 * qsort style comparison function for descending order.
733 value_cmp_reverse (void const *ptr_a, void const *ptr_b)
735 return -value_cmp (ptr_a, ptr_b);
738 gboolean
739 value_equal (GnmValue const *a, GnmValue const *b)
741 if (a->v_any.type != b->v_any.type)
742 return FALSE;
744 switch (a->v_any.type) {
745 case VALUE_BOOLEAN:
746 return a->v_bool.val == b->v_bool.val;
748 case VALUE_STRING:
749 return go_string_equal (a->v_str.val, b->v_str.val);
751 case VALUE_ERROR:
752 return go_string_equal (a->v_err.mesg, b->v_err.mesg);
754 case VALUE_FLOAT:
755 return a->v_float.val == b->v_float.val;
757 case VALUE_EMPTY:
758 return TRUE;
760 case VALUE_CELLRANGE:
761 return gnm_cellref_equal (&a->v_range.cell.a, &b->v_range.cell.a) &&
762 gnm_cellref_equal (&a->v_range.cell.b, &b->v_range.cell.b);
764 case VALUE_ARRAY:
765 if (a->v_array.x == b->v_array.x && a->v_array.y == b->v_array.y) {
766 int x, y;
768 for (y = 0; y < a->v_array.y; y++)
769 for (x = 0; x < a->v_array.x; x++)
770 if (!value_equal (a->v_array.vals[x][y],
771 b->v_array.vals[x][y]))
772 return FALSE;
773 return TRUE;
774 } else
775 return FALSE;
777 #ifndef DEBUG_SWITCH_ENUM
778 default:
779 g_assert_not_reached ();
780 return FALSE;
781 #endif
785 guint
786 value_hash (GnmValue const *v)
788 switch (v->v_any.type) {
789 case VALUE_BOOLEAN:
790 return v->v_bool.val ? 0x555aaaa : 0xaaa5555;
792 case VALUE_STRING:
793 return go_string_hash (v->v_str.val);
795 case VALUE_ERROR:
796 return go_string_hash (v->v_err.mesg);
798 case VALUE_FLOAT: {
799 int expt;
800 gnm_float mant = gnm_frexp (gnm_abs (v->v_float.val), &expt);
801 guint h = ((guint)(0x80000000u * mant)) ^ expt;
802 if (v->v_float.val >= 0)
803 h ^= 0x55555555;
804 return h;
807 case VALUE_EMPTY:
808 return 42;
810 case VALUE_CELLRANGE:
811 /* FIXME: take sheet into account? */
812 return (gnm_cellref_hash (&v->v_range.cell.a) * 3) ^
813 gnm_cellref_hash (&v->v_range.cell.b);
815 case VALUE_ARRAY: {
816 int i;
817 guint h = (v->v_array.x * 257) ^ (v->v_array.y + 42);
819 /* For speed, just walk the diagonal. */
820 for (i = 0; i < v->v_array.x && i < v->v_array.y; i++) {
821 h *= 5;
822 if (v->v_array.vals[i][i])
823 h ^= value_hash (v->v_array.vals[i][i]);
825 return h;
828 #ifndef DEBUG_SWITCH_ENUM
829 default:
830 g_assert_not_reached ();
831 return 0;
832 #endif
837 GnmValueType
838 value_type_of (const GnmValue *v)
840 return v->v_any.type;
844 gboolean
845 value_get_as_bool (GnmValue const *v, gboolean *err)
847 if (err)
848 *err = FALSE;
850 if (v == NULL)
851 return FALSE;
853 switch (v->v_any.type) {
854 case VALUE_EMPTY:
855 return FALSE;
857 case VALUE_BOOLEAN:
858 return v->v_bool.val;
860 case VALUE_STRING: {
861 int i = value_parse_boolean (value_peek_string (v), FALSE);
862 if (i == -1) {
863 if (err)
864 *err = TRUE;
865 return FALSE;
867 return (gboolean)i;
870 case VALUE_FLOAT:
871 return v->v_float.val != 0.0;
873 default:
874 g_warning ("Unhandled value in value_get_as_bool.");
876 case VALUE_CELLRANGE:
877 case VALUE_ARRAY:
878 case VALUE_ERROR:
879 if (err)
880 *err = TRUE;
882 return FALSE;
886 * use only if you are sure the value is ok
888 gboolean
889 value_get_as_checked_bool (GnmValue const *v)
891 gboolean result, err;
893 result = value_get_as_bool (v, &err);
895 g_return_val_if_fail (!err, FALSE);
897 return result;
901 * value_get_as_gstring:
902 * @v: #GnmValue
903 * @target: #GString
904 * @conv: #GnmConventions
906 * A simple value formatter to convert @v into a string stored in @target
907 * according to @conv. See format_value_gstring for something more elaborate
908 * that handles formats too.
910 void
911 value_get_as_gstring (GnmValue const *v, GString *target,
912 GnmConventions const *conv)
914 if (v == NULL)
915 return;
917 switch (v->v_any.type){
918 case VALUE_EMPTY:
919 return;
921 case VALUE_ERROR: {
922 GnmStdError e = value_error_classify (v);
923 if (e == GNM_ERROR_UNKNOWN) {
924 g_string_append_c (target, '#');
925 go_strescape (target, v->v_err.mesg->str);
926 } else
927 g_string_append (target, value_error_name (e, conv->output.translated));
928 return;
931 case VALUE_BOOLEAN: {
932 gboolean b = v->v_bool.val;
933 g_string_append (target,
934 conv->output.translated
935 ? go_locale_boolean_name (b)
936 : (b ? "TRUE" : "FALSE"));
937 return;
940 case VALUE_STRING:
941 g_string_append (target, v->v_str.val->str);
942 return;
944 case VALUE_FLOAT:
945 if (conv->output.decimal_digits < 0)
946 go_dtoa (target, "!" GNM_FORMAT_g, v->v_float.val);
947 else
948 g_string_append_printf (target, "%.*" GNM_FORMAT_g,
949 conv->output.decimal_digits,
950 v->v_float.val);
951 return;
953 case VALUE_ARRAY: {
954 GnmValue const *val;
955 gunichar row_sep, col_sep;
956 int x, y;
958 if (conv->array_row_sep)
959 row_sep = conv->array_row_sep;
960 else
961 row_sep = go_locale_get_row_sep ();
962 if (conv->array_col_sep)
963 col_sep = conv->array_col_sep;
964 else
965 col_sep = go_locale_get_col_sep ();
967 g_string_append_c (target, '{');
968 for (y = 0; y < v->v_array.y; y++){
969 if (y)
970 g_string_append_unichar (target, row_sep);
972 for (x = 0; x < v->v_array.x; x++){
973 val = v->v_array.vals[x][y];
975 if (x)
976 g_string_append_unichar (target, col_sep);
978 /* quote strings */
979 if (!val) {
980 /* This is not supposed to happen, but
981 let's not crash anyway. */
982 g_string_append (target, "?");
983 } else if (VALUE_IS_STRING (val))
984 go_strescape (target, val->v_str.val->str);
985 else
986 value_get_as_gstring (val, target, conv);
989 g_string_append_c (target, '}');
990 return;
993 case VALUE_CELLRANGE: {
994 char *tmp;
995 /* Note: this makes only sense for absolute references or
996 * references relative to A1
998 GnmRange range;
999 range_init_value (&range, v);
1000 tmp = global_range_name (v->v_range.cell.a.sheet, &range);
1001 g_string_append (target, tmp);
1002 g_free (tmp);
1003 return;
1006 default:
1007 break;
1010 g_assert_not_reached ();
1015 * value_get_as_string:
1016 * @v: #GnmValue
1018 * Simplistic value rendering
1020 * Returns: (transfer full): a string rendering of @v.
1022 char *
1023 value_get_as_string (GnmValue const *v)
1025 GString *res = g_string_sized_new (10);
1026 value_get_as_gstring (v, res, gnm_conventions_default);
1027 return g_string_free (res, FALSE);
1031 * value_peek_string:
1032 * @v: a #GnmValue
1034 * Returns: (transfer none): A string representation of the value. The
1035 * result will stay valid until either (a) the value is disposed of, or
1036 * (b) two further calls to this function are made.
1038 // NOTE: "(transfer none)" papers over an introspection bug
1039 char const *
1040 value_peek_string (GnmValue const *v)
1042 g_return_val_if_fail (v, "");
1044 if (VALUE_IS_STRING (v))
1045 return v->v_str.val->str;
1046 else if (VALUE_IS_ERROR (v))
1047 return v->v_err.mesg->str;
1048 else {
1049 static char *cache[2] = { NULL, NULL };
1050 static int next = 0;
1051 char const *s;
1053 g_free (cache[next]);
1054 s = cache[next] = value_get_as_string (v);
1055 next = (next + 1) % G_N_ELEMENTS (cache);
1056 return s;
1061 * value_stringify:
1062 * @v: a #GnmValue
1064 * Returns: (transfer full): A string representation of the value suitable
1065 * for use in a Python __repr__ function.
1067 char *
1068 value_stringify (GnmValue const *v)
1070 GString *res = g_string_sized_new (30);
1072 g_string_append_c (res, '{');
1074 switch (v->v_any.type) {
1075 case VALUE_EMPTY:
1076 g_string_append (res, "EMPTY,");
1077 g_string_append (res, "None");
1078 break;
1080 case VALUE_STRING:
1081 g_string_append (res, "STRING,");
1082 go_strescape (res, value_peek_string (v));
1083 break;
1085 case VALUE_CELLRANGE:
1086 g_string_append (res, "CELLRANGE,");
1087 g_string_append (res, value_peek_string (v));
1088 return 0;
1090 case VALUE_ARRAY:
1091 g_string_append (res, "ARRAY,");
1092 g_string_append (res, value_peek_string (v));
1093 break;
1095 case VALUE_FLOAT:
1096 g_string_append (res, "FLOAT,");
1097 g_string_append (res, value_peek_string (v));
1098 break;
1100 case VALUE_BOOLEAN:
1101 g_string_append (res, "BOOLEAN,");
1102 g_string_append_c (res, v->v_bool.val ? '1' : '0');
1103 break;
1105 case VALUE_ERROR:
1106 g_string_append (res, "ERROR,");
1107 go_strescape (res, value_peek_string (v));
1108 break;
1110 default:
1111 g_string_append (res, "?,?");
1112 break;
1115 if (VALUE_FMT (v) != NULL) {
1116 g_string_append_c (res, ',');
1117 go_strescape (res, go_format_as_XL (VALUE_FMT (v)));
1120 g_string_append_c (res, '}');
1122 return g_string_free (res, FALSE);
1128 * value_get_as_int:
1129 * @v: (nullable): a #GnmValue
1131 * Returns: @v interpreted as an integer.
1134 value_get_as_int (GnmValue const *v)
1136 if (v == NULL)
1137 return 0;
1138 switch (v->v_any.type) {
1139 case VALUE_EMPTY:
1140 return 0;
1142 case VALUE_STRING:
1143 return atoi (v->v_str.val->str);
1145 case VALUE_CELLRANGE:
1146 g_warning ("Getting range as a int: what to do?");
1147 return 0;
1149 case VALUE_ARRAY:
1150 return 0;
1152 case VALUE_FLOAT:
1153 return (int) gnm_fake_trunc (v->v_float.val);
1155 case VALUE_BOOLEAN:
1156 return v->v_bool.val ? 1 : 0;
1158 case VALUE_ERROR:
1159 return 0;
1161 default:
1162 g_warning ("value_get_as_int unknown type 0x%x (%d).", v->v_any.type, v->v_any.type);
1163 return 0;
1165 return 0;
1169 * value_get_as_float:
1170 * @v: (nullable): a #GnmValue
1172 * Returns: @v interpreted as a floating point value.
1174 gnm_float
1175 value_get_as_float (GnmValue const *v)
1177 if (v == NULL)
1178 return 0.;
1180 switch (v->v_any.type) {
1181 case VALUE_EMPTY:
1182 return 0.;
1184 case VALUE_STRING:
1185 return gnm_strto (v->v_str.val->str, NULL);
1187 case VALUE_CELLRANGE:
1188 g_warning ("Getting range as a double: what to do?");
1189 return 0.0;
1191 case VALUE_ARRAY:
1192 return 0.0;
1194 case VALUE_FLOAT:
1195 return (gnm_float) v->v_float.val;
1197 case VALUE_BOOLEAN:
1198 return v->v_bool.val ? 1. : 0.;
1200 case VALUE_ERROR:
1201 return 0.;
1203 default:
1204 g_warning ("value_get_as_float type error.");
1205 break;
1207 return 0.0;
1210 gboolean
1211 value_is_zero (GnmValue const *v)
1213 return gnm_abs (value_get_as_float (v)) < 64 * GNM_EPSILON;
1216 GnmRangeRef const *
1217 value_get_rangeref (GnmValue const *v)
1219 g_return_val_if_fail (VALUE_IS_CELLRANGE (v), NULL);
1220 return &v->v_range.cell;
1225 * value_coerce_to_number:
1226 * @v:
1227 * @valid:
1229 * If the value can be used as a number return that number
1230 * otherwise free it at return an appropriate error
1232 GnmValue *
1233 value_coerce_to_number (GnmValue *v, gboolean *valid, GnmEvalPos const *ep)
1235 g_return_val_if_fail (v != NULL, NULL);
1237 *valid = FALSE;
1238 if (VALUE_IS_STRING (v)) {
1239 GnmValue *tmp =
1240 format_match_number (value_peek_string (v), NULL,
1241 sheet_date_conv (ep->sheet));
1242 value_release (v);
1243 if (tmp == NULL)
1244 return value_new_error_VALUE (ep);
1245 v = tmp;
1246 } else if (VALUE_IS_ERROR (v))
1247 return v;
1249 if (!VALUE_IS_NUMBER (v)) {
1250 value_release (v);
1251 return value_new_error_VALUE (ep);
1254 *valid = TRUE;
1255 return v;
1258 void
1259 value_array_set (GnmValue *array, int col, int row, GnmValue *v)
1261 g_return_if_fail (v);
1262 g_return_if_fail (VALUE_IS_ARRAY (array));
1263 g_return_if_fail (col>=0);
1264 g_return_if_fail (row>=0);
1265 g_return_if_fail (array->v_array.y > row);
1266 g_return_if_fail (array->v_array.x > col);
1268 value_release (array->v_array.vals[col][row]);
1269 array->v_array.vals[col][row] = v;
1272 static GnmValDiff
1273 compare_bool_bool (GnmValue const *va, GnmValue const *vb)
1275 gboolean err; /* Ignored */
1276 gboolean const a = value_get_as_bool (va, &err);
1277 gboolean const b = value_get_as_bool (vb, &err);
1278 if (a)
1279 return b ? IS_EQUAL : IS_GREATER;
1280 return b ? IS_LESS : IS_EQUAL;
1283 static GnmValDiff
1284 compare_float_float (GnmValue const *va, GnmValue const *vb)
1286 gnm_float const a = value_get_as_float (va);
1287 gnm_float const b = value_get_as_float (vb);
1288 if (a == b)
1289 return IS_EQUAL;
1290 else if (a < b)
1291 return IS_LESS;
1292 else
1293 return IS_GREATER;
1296 static GnmValDiff
1297 compare_error_error (GnmValue const *va, GnmValue const *vb)
1299 GnmStdError ea = value_error_classify (va);
1300 GnmStdError eb = value_error_classify (vb);
1301 int i;
1303 if (ea != eb)
1304 return ea < eb ? IS_LESS : IS_GREATER;
1306 if (ea != GNM_ERROR_UNKNOWN)
1307 return IS_EQUAL;
1309 /* Two unknown errors. Just compare strings. */
1310 i = strcmp (value_peek_string (va), value_peek_string (vb));
1311 return (i > 0 ? IS_GREATER : (i < 0 ? IS_LESS : IS_EQUAL));
1316 * value_diff:
1317 * @a: value a
1318 * @b: value b
1320 * IGNORES format.
1322 * Returns a non-negative difference between 2 values
1324 gnm_float
1325 value_diff (GnmValue const *a, GnmValue const *b)
1327 GnmValueType ta, tb;
1329 /* Handle trivial (including empty/empty) and double NULL */
1330 if (a == b)
1331 return 0.;
1333 ta = VALUE_IS_EMPTY (a) ? VALUE_EMPTY : a->v_any.type;
1334 tb = VALUE_IS_EMPTY (b) ? VALUE_EMPTY : b->v_any.type;
1336 /* string > empty */
1337 if (ta == VALUE_STRING) {
1338 switch (tb) {
1339 /* Strings are > (empty, or number) */
1340 case VALUE_EMPTY:
1341 if (*a->v_str.val->str == '\0')
1342 return 0.;
1343 return DBL_MAX;
1345 /* If both are strings compare as string */
1346 case VALUE_STRING:
1347 if (go_string_equal (a->v_str.val, b->v_str.val))
1348 return 0.;
1350 case VALUE_FLOAT: case VALUE_BOOLEAN:
1351 default:
1352 return DBL_MAX;
1355 } else if (tb == VALUE_STRING) {
1356 switch (ta) {
1357 /* (empty, or number) < String */
1358 case VALUE_EMPTY:
1359 if (*b->v_str.val->str == '\0')
1360 return 0.;
1362 case VALUE_FLOAT : case VALUE_BOOLEAN:
1363 default:
1364 return DBL_MAX;
1368 /* Booleans > all numbers (Why did excel do this ?? ) */
1369 if (ta == VALUE_BOOLEAN && tb == VALUE_FLOAT)
1370 return DBL_MAX;
1371 if (tb == VALUE_BOOLEAN && ta == VALUE_FLOAT)
1372 return DBL_MAX;
1374 switch ((ta > tb) ? ta : tb) {
1375 case VALUE_EMPTY: /* Empty Empty compare */
1376 return 0.;
1378 case VALUE_BOOLEAN:
1379 return (compare_bool_bool (a, b) == IS_EQUAL) ? 0. : DBL_MAX;
1381 case VALUE_FLOAT: {
1382 gnm_float const da = value_get_as_float (a);
1383 gnm_float const db = value_get_as_float (b);
1384 return gnm_abs (da - db);
1386 default:
1387 return TYPE_MISMATCH;
1391 static int
1392 gnm_string_cmp (gconstpointer gstr_a, gconstpointer gstr_b)
1394 return (gstr_a == gstr_b)
1396 : g_utf8_collate (((GOString const *)gstr_a)->str,
1397 ((GOString const *)gstr_b)->str);
1400 static int
1401 gnm_string_cmp_ignorecase (gconstpointer gstr_a, gconstpointer gstr_b)
1403 gchar *a;
1404 gchar *b;
1405 int res;
1407 if (gstr_a == gstr_b)
1408 return 0;
1410 a = g_utf8_casefold (((GOString const *)gstr_a)->str, -1);
1411 b = g_utf8_casefold (((GOString const *)gstr_b)->str, -1);
1413 res = g_utf8_collate (a, b);
1415 g_free (a);
1416 g_free (b);
1418 return res;
1422 /* This depends on the actual values of the enums. */
1423 #define PAIR(ta_,tb_) ((ta_) + (((tb_) >> 3) - 1))
1424 #define CPAIR(ta_,tb_) (1 ? PAIR((ta_),(tb_)) : sizeof (struct { int sanity_check[((ta_) >= (tb_)) * 2 - 1]; } ))
1427 * value_compare:
1429 * @a: value a
1430 * @b: value b
1431 * @case_sensitive: are string comparisons case sensitive.
1433 * IGNORES format.
1435 static GnmValDiff
1436 value_compare_real (GnmValue const *a, GnmValue const *b,
1437 gboolean case_sensitive,
1438 gboolean default_locale)
1440 GnmValueType ta, tb;
1441 gboolean flip;
1442 GnmValDiff res;
1444 /* Handle trivial and double NULL case */
1445 if (a == b)
1446 return IS_EQUAL;
1448 ta = VALUE_IS_EMPTY (a) ? VALUE_EMPTY : a->v_any.type;
1449 tb = VALUE_IS_EMPTY (b) ? VALUE_EMPTY : b->v_any.type;
1451 flip = (tb > ta);
1452 if (flip) {
1453 GnmValueType t = ta;
1454 GnmValue const *v = a;
1455 ta = tb;
1456 tb = t;
1457 a = b;
1458 b = v;
1461 switch (PAIR (ta,tb)) {
1462 case CPAIR (VALUE_EMPTY,VALUE_EMPTY):
1463 /* In most cases this is handled by the trivial case. */
1464 /* We can get here if one of a and b is NULL and the */
1465 /* is not but contains an empty value. */
1466 return IS_EQUAL;
1468 /* ---------------------------------------- */
1470 case CPAIR (VALUE_BOOLEAN,VALUE_EMPTY): /* Blank is FALSE */
1471 case CPAIR (VALUE_BOOLEAN,VALUE_BOOLEAN):
1472 res = compare_bool_bool (a, b);
1473 break;
1475 /* ---------------------------------------- */
1477 case CPAIR (VALUE_FLOAT,VALUE_BOOLEAN):
1478 /* Number < boolean (Why did excel do this ?? ) */
1479 res = IS_LESS;
1480 break;
1481 case CPAIR (VALUE_FLOAT,VALUE_EMPTY): /* Blank is 0 */
1482 case CPAIR (VALUE_FLOAT,VALUE_FLOAT):
1483 res = compare_float_float (a, b);
1484 break;
1486 /* ---------------------------------------- */
1488 case CPAIR (VALUE_ERROR,VALUE_EMPTY):
1489 case CPAIR (VALUE_ERROR,VALUE_BOOLEAN):
1490 case CPAIR (VALUE_ERROR,VALUE_FLOAT):
1491 /* Error > others */
1492 res = IS_GREATER;
1493 break;
1495 case CPAIR (VALUE_ERROR,VALUE_ERROR):
1496 res = compare_error_error (a, b);
1497 break;
1499 /* ---------------------------------------- */
1501 case CPAIR (VALUE_STRING,VALUE_EMPTY): /* Blank is empty string */
1502 /* String > empty, except empty string */
1503 res = a->v_str.val->str[0] == '\0' ? IS_EQUAL : IS_GREATER;
1504 break;
1506 case CPAIR (VALUE_STRING,VALUE_BOOLEAN):
1507 /* String < boolean */
1508 res = IS_LESS;
1509 break;
1511 case CPAIR (VALUE_STRING,VALUE_FLOAT):
1512 /* String > number */
1513 res = IS_GREATER;
1514 break;
1516 case CPAIR (VALUE_STRING,VALUE_ERROR):
1517 /* String < error */
1518 res = IS_LESS;
1519 break;
1521 case CPAIR (VALUE_STRING,VALUE_STRING): {
1522 GOString const *sa = a->v_str.val;
1523 GOString const *sb = b->v_str.val;
1524 int i = (default_locale
1525 ? (case_sensitive
1526 ? go_string_cmp (sa, sb)
1527 : go_string_cmp_ignorecase (sa, sb))
1528 : (case_sensitive
1529 ? gnm_string_cmp (sa, sb)
1530 : gnm_string_cmp_ignorecase (sa, sb)));
1531 res = (i > 0 ? IS_GREATER : (i < 0 ? IS_LESS : IS_EQUAL));
1532 break;
1535 /* ---------------------------------------- */
1537 default:
1538 res = TYPE_MISMATCH;
1541 if (flip) {
1542 if (res == IS_LESS)
1543 res = IS_GREATER;
1544 else if (res == IS_GREATER)
1545 res = IS_LESS;
1548 return res;
1550 #undef PAIR
1553 GnmValDiff
1554 value_compare (GnmValue const *a, GnmValue const *b, gboolean case_sensitive)
1556 return value_compare_real (a, b, case_sensitive, TRUE);
1559 GnmValDiff
1560 value_compare_no_cache (GnmValue const *a, GnmValue const *b,
1561 gboolean case_sensitive)
1563 return value_compare_real (a, b, case_sensitive, FALSE);
1567 * value_set_format:
1568 * @v: #GnmValue
1569 * @fmt: (nullable): #GOFormat
1571 * Sets @v's format.
1573 void
1574 value_set_fmt (GnmValue *v, GOFormat const *fmt)
1576 if (fmt == VALUE_FMT (v))
1577 return;
1578 g_return_if_fail (!VALUE_IS_EMPTY (v) && !VALUE_IS_BOOLEAN (v));
1579 if (fmt != NULL)
1580 go_format_ref (fmt);
1581 if (VALUE_FMT (v) != NULL)
1582 go_format_unref (VALUE_FMT (v));
1583 v->v_any.fmt = fmt;
1586 /****************************************************************************/
1588 GType
1589 gnm_value_get_type (void)
1591 static GType t = 0;
1593 if (t == 0)
1594 t = g_boxed_type_register_static ("GnmValue",
1595 (GBoxedCopyFunc)value_dup,
1596 (GBoxedFreeFunc)value_release);
1597 return t;
1599 /****************************************************************************/
1601 GnmValueErr const value_terminate_err = { VALUE_ERROR, NULL, NULL };
1602 static GnmValueFloat const the_value_zero = { VALUE_FLOAT, NULL, 0 };
1603 GnmValue const *value_zero = (GnmValue const *)&the_value_zero;
1606 * value_init: (skip)
1608 void
1609 value_init (void)
1611 size_t i;
1613 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++) {
1614 standard_errors[i].locale_name = _(standard_errors[i].C_name);
1615 standard_errors[i].locale_name_str =
1616 go_string_new (standard_errors[i].locale_name);
1619 #if USE_VALUE_POOLS
1620 value_float_pool =
1621 go_mem_chunk_new ("value float pool",
1622 sizeof (GnmValueFloat),
1623 16 * 1024 - 128);
1625 value_error_pool =
1626 go_mem_chunk_new ("value error pool",
1627 sizeof (GnmValueErr),
1628 16 * 1024 - 128);
1630 value_string_pool =
1631 go_mem_chunk_new ("value string pool",
1632 sizeof (GnmValueStr),
1633 16 * 1024 - 128);
1635 value_range_pool =
1636 go_mem_chunk_new ("value range pool",
1637 sizeof (GnmValueRange),
1638 16 * 1024 - 128);
1640 value_array_pool =
1641 go_mem_chunk_new ("value array pool",
1642 sizeof (GnmValueArray),
1643 16 * 1024 - 128);
1644 #endif
1648 * value_shutdown: (skip)
1650 void
1651 value_shutdown (void)
1653 size_t i;
1655 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++) {
1656 go_string_unref (standard_errors[i].locale_name_str);
1657 standard_errors[i].locale_name_str = NULL;
1660 #if USE_VALUE_POOLS
1661 go_mem_chunk_destroy (value_float_pool, FALSE);
1662 value_float_pool = NULL;
1664 go_mem_chunk_destroy (value_error_pool, FALSE);
1665 value_error_pool = NULL;
1667 go_mem_chunk_destroy (value_string_pool, FALSE);
1668 value_string_pool = NULL;
1670 go_mem_chunk_destroy (value_range_pool, FALSE);
1671 value_range_pool = NULL;
1673 go_mem_chunk_destroy (value_array_pool, FALSE);
1674 value_array_pool = NULL;
1675 #else
1676 if (value_allocations)
1677 g_printerr ("Leaking %d values.\n", value_allocations);
1678 #endif
1681 /****************************************************************************/