Compilation: kill warning.
[gnumeric.git] / src / value.c
blob30e1993c32c811e3c976e28840891d59c6d02491
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 ((GnmValue *)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;
228 * value_new_string_str:
229 * @str: (transfer full): string to use for value
231 * Returns: (transfer full): a new value object.
233 GnmValue *
234 value_new_string_str (GOString *str)
236 GnmValueStr *v;
238 g_return_val_if_fail (str != NULL, NULL);
240 v = CHUNK_ALLOC (GnmValueStr, value_string_pool);
241 *((GnmValueType *)&(v->type)) = VALUE_STRING;
242 v->fmt = NULL;
243 v->val = str;
244 return (GnmValue *)v;
248 * value_new_string:
249 * @str: string to use for value
251 * Returns: (transfer full): a new value object.
253 GnmValue *
254 value_new_string (char const *str)
256 return value_new_string_str (go_string_new (str));
260 * value_new_string_nocopy:
261 * @str: (transfer full): string to use for value
263 * Returns: (transfer full): a new value object.
265 GnmValue *
266 value_new_string_nocopy (char *str)
268 return value_new_string_str (go_string_new_nocopy (str));
271 GnmValue *
272 value_new_cellrange_unsafe (GnmCellRef const *a, GnmCellRef const *b)
274 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
275 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
276 v->fmt = NULL;
277 v->cell.a = *a;
278 v->cell.b = *b;
279 return (GnmValue *)v;
283 * value_new_cellrange:
285 * Create a new range reference.
287 * Attempt to do a sanity check for inverted ranges.
288 * NOTE : This is no longer necessary and will be removed.
289 * mixed mode references create the possibility of inversion.
290 * users of these values need to use the utility routines to
291 * evaluate the ranges in their context and normalize then.
293 GnmValue *
294 value_new_cellrange (GnmCellRef const *a, GnmCellRef const *b,
295 int eval_col, int eval_row)
297 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
298 int tmp;
300 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
301 v->fmt = NULL;
302 v->cell.a = *a;
303 v->cell.b = *b;
305 /* Sanity checking to avoid inverted ranges */
306 tmp = a->col;
307 if (a->col_relative != b->col_relative) {
308 /* Make a tmp copy of a in the same mode as b */
309 if (a->col_relative)
310 tmp += eval_col;
311 else
312 tmp -= eval_col;
314 if (tmp > b->col) {
315 v->cell.a.col = b->col;
316 v->cell.a.col_relative = b->col_relative;
317 v->cell.b.col = a->col;
318 v->cell.b.col_relative = a->col_relative;
321 tmp = a->row;
322 if (a->row_relative != b->row_relative) {
323 /* Make a tmp copy of a in the same mode as b */
324 if (a->row_relative)
325 tmp += eval_row;
326 else
327 tmp -= eval_row;
329 if (tmp > b->row) {
330 v->cell.a.row = b->row;
331 v->cell.a.row_relative = b->row_relative;
332 v->cell.b.row = a->row;
333 v->cell.b.row_relative = a->row_relative;
336 return (GnmValue *)v;
339 GnmValue *
340 value_new_cellrange_r (Sheet *sheet, GnmRange const *r)
342 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
343 GnmCellRef *a, *b;
345 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
346 v->fmt = NULL;
347 a = &v->cell.a;
348 b = &v->cell.b;
350 a->sheet = sheet;
351 b->sheet = sheet;
352 a->col = r->start.col;
353 a->row = r->start.row;
354 b->col = r->end.col;
355 b->row = r->end.row;
356 a->col_relative = b->col_relative = FALSE;
357 a->row_relative = b->row_relative = FALSE;
359 return (GnmValue *)v;
363 * value_new_cellrange_str:
364 * @sheet: the sheet where the cell range is evaluated. This really only needed if
365 * the range given does not include a sheet specification.
366 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
368 * Parse @str using the convention associated with @sheet.
369 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
370 * succesfully parsed or NULL on failure.
372 GnmValue *
373 value_new_cellrange_str (Sheet *sheet, char const *str)
375 GnmParsePos pp;
376 GnmExprParseFlags flags = GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS |
377 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES;
379 g_return_val_if_fail (IS_SHEET (sheet), NULL);
380 g_return_val_if_fail (str != NULL, NULL);
382 parse_pos_init_sheet (&pp, sheet);
383 return value_new_cellrange_parsepos_str (&pp, str, flags);
387 * value_new_cellrange_parsepos_str:
388 * @pp: if a relative range is specified, then it will be interpreted relative
389 * to this position (affects only A1-style relative references).
390 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
392 * Parse @str using the convention associated with @sheet.
393 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
394 * succesfully parsed or NULL on failure.
396 GnmValue *
397 value_new_cellrange_parsepos_str (GnmParsePos const *pp, char const *str,
398 GnmExprParseFlags flags)
400 GnmExprTop const *texpr;
401 GnmConventions const *convs = NULL;
403 g_return_val_if_fail (pp != NULL, NULL);
404 g_return_val_if_fail (str != NULL, NULL);
406 if (pp->sheet)
407 convs = pp->sheet->convs;
409 texpr = gnm_expr_parse_str (str, pp, flags, convs, NULL);
411 if (texpr != NULL) {
412 GnmValue *value = gnm_expr_top_get_range (texpr);
413 gnm_expr_top_unref (texpr);
414 return value;
417 return NULL;
420 GnmValue *
421 value_new_array_non_init (guint cols, guint rows)
423 GnmValueArray *v = CHUNK_ALLOC (GnmValueArray, value_array_pool);
424 *((GnmValueType *)&(v->type)) = VALUE_ARRAY;
425 v->fmt = NULL;
426 v->x = cols;
427 v->y = rows;
428 v->vals = g_new (GnmValue **, cols);
429 return (GnmValue *)v;
432 GnmValue *
433 value_new_array (guint cols, guint rows)
435 guint x, y;
436 GnmValueArray *v = (GnmValueArray *)value_new_array_non_init (cols, rows);
438 for (x = 0; x < cols; x++) {
439 v->vals[x] = g_new (GnmValue *, rows);
440 for (y = 0; y < rows; y++)
441 v->vals[x][y] = value_new_int (0);
443 return (GnmValue *)v;
446 GnmValue *
447 value_new_array_empty (guint cols, guint rows)
449 guint x, y;
450 GnmValueArray *v = (GnmValueArray *)value_new_array_non_init (cols, rows);
452 for (x = 0; x < cols; x++) {
453 v->vals[x] = g_new (GnmValue *, rows);
454 for (y = 0; y < rows; y++)
455 v->vals[x][y] = value_new_empty ();
457 return (GnmValue *)v;
461 * Returns TRUE, FALSE, or -1.
463 static int
464 value_parse_boolean (char const *str, gboolean translated)
466 if (translated) {
467 /* FIXME: ascii??? */
468 if (0 == g_ascii_strcasecmp (str, go_locale_boolean_name (TRUE)))
469 return +TRUE;
470 else if (0 == g_ascii_strcasecmp (str, go_locale_boolean_name (FALSE)))
471 return +FALSE;
472 else
473 return -1;
474 } else {
475 if (0 == g_ascii_strcasecmp (str, "TRUE"))
476 return +TRUE;
477 else if (0 == g_ascii_strcasecmp (str, "FALSE"))
478 return +FALSE;
479 else
480 return -1;
485 GnmValue *
486 value_new_from_string (GnmValueType t, char const *str, GOFormat *sf,
487 gboolean translated)
489 GnmValue *res = NULL;
492 * We need the following cast to avoid a warning from gcc over
493 * VALUE_INTEGER (which is not in GnmValueType).
495 switch ((guint8)t) {
496 case VALUE_EMPTY:
497 res = value_new_empty ();
498 break;
500 case VALUE_BOOLEAN: {
501 int i = value_parse_boolean (str, translated);
502 if (i != -1)
503 res = value_new_bool ((gboolean)i);
504 break;
507 case VALUE_INTEGER:
508 case VALUE_FLOAT: {
509 char *end;
510 gnm_float d;
512 d = gnm_strto (str, &end);
513 if (d != 0 && d > -GNM_MIN && d < GNM_MIN)
514 errno = 0;
516 if (str != end && *end == '\0' && errno != ERANGE)
517 res = value_new_float (d);
518 break;
521 case VALUE_ERROR:
523 * Tricky. We are currently storing errors in translated
524 * format, so we might have to undo that.
526 if (!translated) {
527 size_t i;
528 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++)
529 if (strcmp (standard_errors[i].C_name, str) == 0) {
530 res = value_new_error_std (NULL, (GnmStdError)i);
531 break;
534 if (!res)
535 res = value_new_error (NULL, str);
536 break;
538 case VALUE_STRING:
539 res = value_new_string (str);
540 break;
542 case VALUE_ARRAY:
543 case VALUE_CELLRANGE:
544 default:
545 /* This happen with corrupted files. */
546 return NULL;
549 if (res)
550 value_set_fmt (res, sf);
551 return res;
555 * value_release:
556 * @v: (transfer full) (allow-none): value to dispose of
558 * Free the value.
560 void
561 value_release (GnmValue *value)
563 if (NULL == value)
564 return;
566 if (VALUE_FMT (value) != NULL)
567 go_format_unref (VALUE_FMT (value));
569 switch (value->v_any.type) {
570 case VALUE_EMPTY:
571 case VALUE_BOOLEAN:
572 /* We did not allocate anything, there is nothing to free */
573 return;
575 case VALUE_FLOAT:
576 CHUNK_FREE (value_float_pool, &value->v_float);
577 return;
579 case VALUE_ERROR:
580 /* Do not release VALUE_TERMINATE, it is a magic number */
581 if (value == VALUE_TERMINATE) {
582 g_warning ("Someone freed VALUE_TERMINATE -- shame on them.");
583 return;
586 go_string_unref (value->v_err.mesg);
587 CHUNK_FREE (value_error_pool, &value->v_err);
588 return;
590 case VALUE_STRING:
591 go_string_unref (value->v_str.val);
592 CHUNK_FREE (value_string_pool, &value->v_str);
593 return;
595 case VALUE_ARRAY: {
596 GnmValueArray *v = &value->v_array;
597 int x, y;
599 for (x = 0; x < v->x; x++) {
600 for (y = 0; y < v->y; y++)
601 value_release (v->vals[x][y]);
602 g_free (v->vals[x]);
605 g_free (v->vals);
606 CHUNK_FREE (value_array_pool, v);
607 return;
610 case VALUE_CELLRANGE:
611 CHUNK_FREE (value_range_pool, &value->v_range);
612 return;
614 default:
616 * If we don't recognize the type this is probably garbage.
617 * Do not free it to avoid heap corruption
619 g_warning ("value_release problem.");
620 return;
622 g_assert_not_reached ();
626 * value_dup:
627 * @v: #GnmValue
629 * Returns a copy of @v. @v == NULL will return NULL
631 GnmValue *
632 value_dup (GnmValue const *src)
634 GnmValue *res;
636 if (src == NULL)
637 return NULL;
639 switch (src->v_any.type){
640 case VALUE_EMPTY:
641 res = value_new_empty ();
642 break;
644 case VALUE_BOOLEAN:
645 res = value_new_bool (src->v_bool.val);
646 break;
648 case VALUE_FLOAT:
649 res = value_new_float (src->v_float.val);
650 break;
652 case VALUE_ERROR:
653 res = value_new_error_str (NULL, /* &src->v_err.src, */
654 src->v_err.mesg);
655 break;
657 case VALUE_STRING:
658 go_string_ref (src->v_str.val);
659 res = value_new_string_str (src->v_str.val);
660 break;
662 case VALUE_CELLRANGE:
663 res = value_new_cellrange_unsafe (&src->v_range.cell.a,
664 &src->v_range.cell.b);
665 break;
667 case VALUE_ARRAY: {
668 int x, y;
669 GnmValueArray *array = (GnmValueArray *)value_new_array_non_init (
670 src->v_array.x, src->v_array.y);
672 for (x = 0; x < array->x; x++) {
673 array->vals[x] = g_new (GnmValue *, array->y);
674 for (y = 0; y < array->y; y++)
675 array->vals[x][y] = value_dup (src->v_array.vals[x][y]);
677 res = (GnmValue *)array;
678 break;
681 default:
682 g_warning ("value_dup problem.");
683 res = value_new_empty ();
685 value_set_fmt (res, VALUE_FMT (src));
686 return res;
689 static GnmValDiff
690 value_compare_real (GnmValue const *a, GnmValue const *b,
691 gboolean case_sensitive,
692 gboolean default_locale);
696 * value_cmp:
697 * @ptr_a:
698 * @ptr_b:
700 * qsort style comparison function for ascending order
703 value_cmp (void const *ptr_a, void const *ptr_b)
705 GnmValue const *a = *(GnmValue const **)ptr_a;
706 GnmValue const *b = *(GnmValue const **)ptr_b;
707 switch (value_compare_real (a, b, TRUE, TRUE)) {
708 case IS_EQUAL : return 0;
709 case IS_LESS : return -1;
710 case IS_GREATER : return 1;
711 default :
712 break;
714 return a->v_any.type - b->v_any.type;
718 * value_cmp_reverse:
719 * @ptr_a:
720 * @ptr_b:
722 * qsort style comparison function for descending order.
725 value_cmp_reverse (void const *ptr_a, void const *ptr_b)
727 return -value_cmp (ptr_a, ptr_b);
730 gboolean
731 value_equal (GnmValue const *a, GnmValue const *b)
733 if (a->v_any.type != b->v_any.type)
734 return FALSE;
736 switch (a->v_any.type) {
737 case VALUE_BOOLEAN:
738 return a->v_bool.val == b->v_bool.val;
740 case VALUE_STRING:
741 return go_string_equal (a->v_str.val, b->v_str.val);
743 case VALUE_ERROR:
744 return go_string_equal (a->v_err.mesg, b->v_err.mesg);
746 case VALUE_FLOAT:
747 return a->v_float.val == b->v_float.val;
749 case VALUE_EMPTY:
750 return TRUE;
752 case VALUE_CELLRANGE:
753 return gnm_cellref_equal (&a->v_range.cell.a, &b->v_range.cell.a) &&
754 gnm_cellref_equal (&a->v_range.cell.b, &b->v_range.cell.b);
756 case VALUE_ARRAY:
757 if (a->v_array.x == b->v_array.x && a->v_array.y == b->v_array.y) {
758 int x, y;
760 for (y = 0; y < a->v_array.y; y++)
761 for (x = 0; x < a->v_array.x; x++)
762 if (!value_equal (a->v_array.vals[x][y],
763 b->v_array.vals[x][y]))
764 return FALSE;
765 return TRUE;
766 } else
767 return FALSE;
769 #ifndef DEBUG_SWITCH_ENUM
770 default:
771 g_assert_not_reached ();
772 return FALSE;
773 #endif
777 guint
778 value_hash (GnmValue const *v)
780 switch (v->v_any.type) {
781 case VALUE_BOOLEAN:
782 return v->v_bool.val ? 0x555aaaa : 0xaaa5555;
784 case VALUE_STRING:
785 return go_string_hash (v->v_str.val);
787 case VALUE_ERROR:
788 return go_string_hash (v->v_err.mesg);
790 case VALUE_FLOAT: {
791 int expt;
792 gnm_float mant = gnm_frexp (gnm_abs (v->v_float.val), &expt);
793 guint h = ((guint)(0x80000000u * mant)) ^ expt;
794 if (v->v_float.val >= 0)
795 h ^= 0x55555555;
796 return h;
799 case VALUE_EMPTY:
800 return 42;
802 case VALUE_CELLRANGE:
803 /* FIXME: take sheet into account? */
804 return (gnm_cellref_hash (&v->v_range.cell.a) * 3) ^
805 gnm_cellref_hash (&v->v_range.cell.b);
807 case VALUE_ARRAY: {
808 int i;
809 guint h = (v->v_array.x * 257) ^ (v->v_array.y + 42);
811 /* For speed, just walk the diagonal. */
812 for (i = 0; i < v->v_array.x && i < v->v_array.y; i++) {
813 h *= 5;
814 if (v->v_array.vals[i][i])
815 h ^= value_hash (v->v_array.vals[i][i]);
817 return h;
820 #ifndef DEBUG_SWITCH_ENUM
821 default:
822 g_assert_not_reached ();
823 return 0;
824 #endif
829 gboolean
830 value_get_as_bool (GnmValue const *v, gboolean *err)
832 if (err)
833 *err = FALSE;
835 if (v == NULL)
836 return FALSE;
838 switch (v->v_any.type) {
839 case VALUE_EMPTY:
840 return FALSE;
842 case VALUE_BOOLEAN:
843 return v->v_bool.val;
845 case VALUE_STRING: {
846 int i = value_parse_boolean (value_peek_string (v), FALSE);
847 if (i == -1) {
848 if (err)
849 *err = TRUE;
850 return FALSE;
852 return (gboolean)i;
855 case VALUE_FLOAT:
856 return v->v_float.val != 0.0;
858 default:
859 g_warning ("Unhandled value in value_get_as_bool.");
861 case VALUE_CELLRANGE:
862 case VALUE_ARRAY:
863 case VALUE_ERROR:
864 if (err)
865 *err = TRUE;
867 return FALSE;
871 * use only if you are sure the value is ok
873 gboolean
874 value_get_as_checked_bool (GnmValue const *v)
876 gboolean result, err;
878 result = value_get_as_bool (v, &err);
880 g_return_val_if_fail (!err, FALSE);
882 return result;
886 * value_get_as_gstring:
887 * @v: #GnmValue
888 * @target: #GString
889 * @conv: #GnmConventions
891 * A simple value formatter to convert @v into a string stored in @target
892 * according to @conv. See format_value_gstring for something more elaborate
893 * that handles formats too.
895 void
896 value_get_as_gstring (GnmValue const *v, GString *target,
897 GnmConventions const *conv)
899 if (v == NULL)
900 return;
902 switch (v->v_any.type){
903 case VALUE_EMPTY:
904 return;
906 case VALUE_ERROR: {
907 GnmStdError e = value_error_classify (v);
908 if (e == GNM_ERROR_UNKNOWN) {
909 g_string_append_c (target, '#');
910 go_strescape (target, v->v_err.mesg->str);
911 } else
912 g_string_append (target, value_error_name (e, conv->output.translated));
913 return;
916 case VALUE_BOOLEAN: {
917 gboolean b = v->v_bool.val;
918 g_string_append (target,
919 conv->output.translated
920 ? go_locale_boolean_name (b)
921 : (b ? "TRUE" : "FALSE"));
922 return;
925 case VALUE_STRING:
926 g_string_append (target, v->v_str.val->str);
927 return;
929 case VALUE_FLOAT:
930 if (conv->output.decimal_digits < 0)
931 go_dtoa (target, "!" GNM_FORMAT_g, v->v_float.val);
932 else
933 g_string_append_printf (target, "%.*" GNM_FORMAT_g,
934 conv->output.decimal_digits,
935 v->v_float.val);
936 return;
938 case VALUE_ARRAY: {
939 GnmValue const *val;
940 gunichar row_sep, col_sep;
941 int x, y;
943 if (conv->array_row_sep)
944 row_sep = conv->array_row_sep;
945 else
946 row_sep = go_locale_get_row_sep ();
947 if (conv->array_col_sep)
948 col_sep = conv->array_col_sep;
949 else
950 col_sep = go_locale_get_col_sep ();
952 g_string_append_c (target, '{');
953 for (y = 0; y < v->v_array.y; y++){
954 if (y)
955 g_string_append_unichar (target, row_sep);
957 for (x = 0; x < v->v_array.x; x++){
958 val = v->v_array.vals[x][y];
960 if (x)
961 g_string_append_unichar (target, col_sep);
963 /* quote strings */
964 if (!val) {
965 /* This is not supposed to happen, but
966 let's not crash anyway. */
967 g_string_append (target, "?");
968 } else if (VALUE_IS_STRING (val))
969 go_strescape (target, val->v_str.val->str);
970 else
971 value_get_as_gstring (val, target, conv);
974 g_string_append_c (target, '}');
975 return;
978 case VALUE_CELLRANGE: {
979 char *tmp;
980 /* Note: this makes only sense for absolute references or
981 * references relative to A1
983 GnmRange range;
984 range_init_value (&range, v);
985 tmp = global_range_name (v->v_range.cell.a.sheet, &range);
986 g_string_append (target, tmp);
987 g_free (tmp);
988 return;
991 default:
992 break;
995 g_assert_not_reached ();
1000 * value_get_as_string:
1001 * @v:
1003 * simplistic value rendering
1005 * Returns a string that must be freed.
1007 char *
1008 value_get_as_string (GnmValue const *v)
1010 GString *res = g_string_sized_new (10);
1011 value_get_as_gstring (v, res, gnm_conventions_default);
1012 return g_string_free (res, FALSE);
1016 * Result will stay valid until (a) the value is disposed of, or (b) two
1017 * further calls to this function are made.
1019 char const *
1020 value_peek_string (GnmValue const *v)
1022 g_return_val_if_fail (v, "");
1024 if (VALUE_IS_STRING (v))
1025 return v->v_str.val->str;
1026 else if (VALUE_IS_ERROR (v))
1027 return v->v_err.mesg->str;
1028 else {
1029 static char *cache[2] = { NULL, NULL };
1030 static int next = 0;
1031 char const *s;
1033 g_free (cache[next]);
1034 s = cache[next] = value_get_as_string (v);
1035 next = (next + 1) % G_N_ELEMENTS (cache);
1036 return s;
1041 * FIXME FIXME FIXME : Support errors
1044 value_get_as_int (GnmValue const *v)
1046 if (v == NULL)
1047 return 0;
1048 switch (v->v_any.type) {
1049 case VALUE_EMPTY:
1050 return 0;
1052 case VALUE_STRING:
1053 return atoi (v->v_str.val->str);
1055 case VALUE_CELLRANGE:
1056 g_warning ("Getting range as a int: what to do?");
1057 return 0;
1059 case VALUE_ARRAY:
1060 return 0;
1062 case VALUE_FLOAT:
1063 return (int) gnm_fake_trunc (v->v_float.val);
1065 case VALUE_BOOLEAN:
1066 return v->v_bool.val ? 1 : 0;
1068 case VALUE_ERROR:
1069 return 0;
1071 default:
1072 g_warning ("value_get_as_int unknown type 0x%x (%d).", v->v_any.type, v->v_any.type);
1073 return 0;
1075 return 0;
1079 * FIXME FIXME FIXME : Support errors
1081 gnm_float
1082 value_get_as_float (GnmValue const *v)
1084 if (v == NULL)
1085 return 0.;
1087 switch (v->v_any.type) {
1088 case VALUE_EMPTY:
1089 return 0.;
1091 case VALUE_STRING:
1092 return gnm_strto (v->v_str.val->str, NULL);
1094 case VALUE_CELLRANGE:
1095 g_warning ("Getting range as a double: what to do?");
1096 return 0.0;
1098 case VALUE_ARRAY:
1099 return 0.0;
1101 case VALUE_FLOAT:
1102 return (gnm_float) v->v_float.val;
1104 case VALUE_BOOLEAN:
1105 return v->v_bool.val ? 1. : 0.;
1107 case VALUE_ERROR:
1108 return 0.;
1110 default:
1111 g_warning ("value_get_as_float type error.");
1112 break;
1114 return 0.0;
1117 gboolean
1118 value_is_zero (GnmValue const *v)
1120 return gnm_abs (value_get_as_float (v)) < 64 * GNM_EPSILON;
1123 GnmRangeRef const *
1124 value_get_rangeref (GnmValue const *v)
1126 g_return_val_if_fail (VALUE_IS_CELLRANGE (v), NULL);
1127 return &v->v_range.cell;
1132 * value_coerce_to_number:
1133 * @v:
1134 * @valid:
1136 * If the value can be used as a number return that number
1137 * otherwise free it at return an appropriate error
1139 GnmValue *
1140 value_coerce_to_number (GnmValue *v, gboolean *valid, GnmEvalPos const *ep)
1142 g_return_val_if_fail (v != NULL, NULL);
1144 *valid = FALSE;
1145 if (VALUE_IS_STRING (v)) {
1146 GnmValue *tmp = format_match_number (value_peek_string (v), NULL,
1147 workbook_date_conv (ep->sheet->workbook));
1148 value_release (v);
1149 if (tmp == NULL)
1150 return value_new_error_VALUE (ep);
1151 v = tmp;
1152 } else if (VALUE_IS_ERROR (v))
1153 return v;
1155 if (!VALUE_IS_NUMBER (v)) {
1156 value_release (v);
1157 return value_new_error_VALUE (ep);
1160 *valid = TRUE;
1161 return v;
1164 void
1165 value_array_set (GnmValue *array, int col, int row, GnmValue *v)
1167 g_return_if_fail (v);
1168 g_return_if_fail (VALUE_IS_ARRAY (array));
1169 g_return_if_fail (col>=0);
1170 g_return_if_fail (row>=0);
1171 g_return_if_fail (array->v_array.y > row);
1172 g_return_if_fail (array->v_array.x > col);
1174 value_release (array->v_array.vals[col][row]);
1175 array->v_array.vals[col][row] = v;
1178 static GnmValDiff
1179 compare_bool_bool (GnmValue const *va, GnmValue const *vb)
1181 gboolean err; /* Ignored */
1182 gboolean const a = value_get_as_bool (va, &err);
1183 gboolean const b = value_get_as_bool (vb, &err);
1184 if (a)
1185 return b ? IS_EQUAL : IS_GREATER;
1186 return b ? IS_LESS : IS_EQUAL;
1189 static GnmValDiff
1190 compare_float_float (GnmValue const *va, GnmValue const *vb)
1192 gnm_float const a = value_get_as_float (va);
1193 gnm_float const b = value_get_as_float (vb);
1194 if (a == b)
1195 return IS_EQUAL;
1196 else if (a < b)
1197 return IS_LESS;
1198 else
1199 return IS_GREATER;
1202 static GnmValDiff
1203 compare_error_error (GnmValue const *va, GnmValue const *vb)
1205 GnmStdError ea = value_error_classify (va);
1206 GnmStdError eb = value_error_classify (vb);
1207 int i;
1209 if (ea != eb)
1210 return ea < eb ? IS_LESS : IS_GREATER;
1212 if (ea != GNM_ERROR_UNKNOWN)
1213 return IS_EQUAL;
1215 /* Two unknown errors. Just compare strings. */
1216 i = strcmp (value_peek_string (va), value_peek_string (vb));
1217 return (i > 0 ? IS_GREATER : (i < 0 ? IS_LESS : IS_EQUAL));
1222 * value_diff:
1223 * @a: value a
1224 * @b: value b
1226 * IGNORES format.
1228 * Returns a non-negative difference between 2 values
1230 gnm_float
1231 value_diff (GnmValue const *a, GnmValue const *b)
1233 GnmValueType ta, tb;
1235 /* Handle trivial (including empty/empty) and double NULL */
1236 if (a == b)
1237 return 0.;
1239 ta = VALUE_IS_EMPTY (a) ? VALUE_EMPTY : a->v_any.type;
1240 tb = VALUE_IS_EMPTY (b) ? VALUE_EMPTY : b->v_any.type;
1242 /* string > empty */
1243 if (ta == VALUE_STRING) {
1244 switch (tb) {
1245 /* Strings are > (empty, or number) */
1246 case VALUE_EMPTY :
1247 if (*a->v_str.val->str == '\0')
1248 return 0.;
1249 return DBL_MAX;
1251 /* If both are strings compare as string */
1252 case VALUE_STRING :
1253 if (go_string_equal (a->v_str.val, b->v_str.val))
1254 return 0.;
1256 case VALUE_FLOAT: case VALUE_BOOLEAN:
1257 default :
1258 return DBL_MAX;
1261 } else if (tb == VALUE_STRING) {
1262 switch (ta) {
1263 /* (empty, or number) < String */
1264 case VALUE_EMPTY :
1265 if (*b->v_str.val->str == '\0')
1266 return 0.;
1268 case VALUE_FLOAT : case VALUE_BOOLEAN :
1269 default :
1270 return DBL_MAX;
1274 /* Booleans > all numbers (Why did excel do this ?? ) */
1275 if (ta == VALUE_BOOLEAN && tb == VALUE_FLOAT)
1276 return DBL_MAX;
1277 if (tb == VALUE_BOOLEAN && ta == VALUE_FLOAT)
1278 return DBL_MAX;
1280 switch ((ta > tb) ? ta : tb) {
1281 case VALUE_EMPTY: /* Empty Empty compare */
1282 return 0.;
1284 case VALUE_BOOLEAN:
1285 return (compare_bool_bool (a, b) == IS_EQUAL) ? 0. : DBL_MAX;
1287 case VALUE_FLOAT: {
1288 gnm_float const da = value_get_as_float (a);
1289 gnm_float const db = value_get_as_float (b);
1290 return gnm_abs (da - db);
1292 default:
1293 return TYPE_MISMATCH;
1297 static int
1298 gnm_string_cmp (gconstpointer gstr_a, gconstpointer gstr_b)
1300 return (gstr_a == gstr_b)
1302 : g_utf8_collate (((GOString const *)gstr_a)->str,
1303 ((GOString const *)gstr_b)->str);
1306 static int
1307 gnm_string_cmp_ignorecase (gconstpointer gstr_a, gconstpointer gstr_b)
1309 gchar *a;
1310 gchar *b;
1311 int res;
1313 if (gstr_a == gstr_b)
1314 return 0;
1316 a = g_utf8_casefold (((GOString const *)gstr_a)->str, -1);
1317 b = g_utf8_casefold (((GOString const *)gstr_b)->str, -1);
1319 res = g_utf8_collate (a, b);
1321 g_free (a);
1322 g_free (b);
1324 return res;
1328 /* This depends on the actual values of the enums. */
1329 #define PAIR(ta_,tb_) ((ta_) + (((tb_) >> 3) - 1))
1330 #define CPAIR(ta_,tb_) (1 ? PAIR((ta_),(tb_)) : sizeof (struct { int sanity_check[((ta_) >= (tb_)) * 2 - 1]; } ))
1333 * value_compare:
1335 * @a: value a
1336 * @b: value b
1337 * @case_sensitive: are string comparisons case sensitive.
1339 * IGNORES format.
1341 static GnmValDiff
1342 value_compare_real (GnmValue const *a, GnmValue const *b,
1343 gboolean case_sensitive,
1344 gboolean default_locale)
1346 GnmValueType ta, tb;
1347 gboolean flip;
1348 GnmValDiff res;
1350 /* Handle trivial and double NULL case */
1351 if (a == b)
1352 return IS_EQUAL;
1354 ta = VALUE_IS_EMPTY (a) ? VALUE_EMPTY : a->v_any.type;
1355 tb = VALUE_IS_EMPTY (b) ? VALUE_EMPTY : b->v_any.type;
1357 flip = (tb > ta);
1358 if (flip) {
1359 GnmValueType t = ta;
1360 GnmValue const *v = a;
1361 ta = tb;
1362 tb = t;
1363 a = b;
1364 b = v;
1367 switch (PAIR (ta,tb)) {
1368 case CPAIR (VALUE_EMPTY,VALUE_EMPTY):
1369 /* In most cases this is handled by the trivial case. */
1370 /* We can get here if one of a and b is NULL and the */
1371 /* is not but contains an empty value. */
1372 return IS_EQUAL;
1374 /* ---------------------------------------- */
1376 case CPAIR (VALUE_BOOLEAN,VALUE_EMPTY): /* Blank is FALSE */
1377 case CPAIR (VALUE_BOOLEAN,VALUE_BOOLEAN):
1378 res = compare_bool_bool (a, b);
1379 break;
1381 /* ---------------------------------------- */
1383 case CPAIR (VALUE_FLOAT,VALUE_BOOLEAN):
1384 /* Number < boolean (Why did excel do this ?? ) */
1385 res = IS_LESS;
1386 break;
1387 case CPAIR (VALUE_FLOAT,VALUE_EMPTY): /* Blank is 0 */
1388 case CPAIR (VALUE_FLOAT,VALUE_FLOAT):
1389 res = compare_float_float (a, b);
1390 break;
1392 /* ---------------------------------------- */
1394 case CPAIR (VALUE_ERROR,VALUE_EMPTY):
1395 case CPAIR (VALUE_ERROR,VALUE_BOOLEAN):
1396 case CPAIR (VALUE_ERROR,VALUE_FLOAT):
1397 /* Error > others */
1398 res = IS_GREATER;
1399 break;
1401 case CPAIR (VALUE_ERROR,VALUE_ERROR):
1402 res = compare_error_error (a, b);
1403 break;
1405 /* ---------------------------------------- */
1407 case CPAIR (VALUE_STRING,VALUE_EMPTY): /* Blank is empty string */
1408 /* String > empty, except empty string */
1409 res = a->v_str.val->str[0] == '\0' ? IS_EQUAL : IS_GREATER;
1410 break;
1412 case CPAIR (VALUE_STRING,VALUE_BOOLEAN):
1413 /* String < boolean */
1414 res = IS_LESS;
1415 break;
1417 case CPAIR (VALUE_STRING,VALUE_FLOAT):
1418 /* String > number */
1419 res = IS_GREATER;
1420 break;
1422 case CPAIR (VALUE_STRING,VALUE_ERROR):
1423 /* String < error */
1424 res = IS_LESS;
1425 break;
1427 case CPAIR (VALUE_STRING,VALUE_STRING): {
1428 GOString const *sa = a->v_str.val;
1429 GOString const *sb = b->v_str.val;
1430 int i = (default_locale
1431 ? (case_sensitive
1432 ? go_string_cmp (sa, sb)
1433 : go_string_cmp_ignorecase (sa, sb))
1434 : (case_sensitive
1435 ? gnm_string_cmp (sa, sb)
1436 : gnm_string_cmp_ignorecase (sa, sb)));
1437 res = (i > 0 ? IS_GREATER : (i < 0 ? IS_LESS : IS_EQUAL));
1438 break;
1441 /* ---------------------------------------- */
1443 default:
1444 res = TYPE_MISMATCH;
1447 if (flip) {
1448 if (res == IS_LESS)
1449 res = IS_GREATER;
1450 else if (res == IS_GREATER)
1451 res = IS_LESS;
1454 return res;
1456 #undef PAIR
1459 GnmValDiff
1460 value_compare (GnmValue const *a, GnmValue const *b, gboolean case_sensitive)
1462 return value_compare_real (a, b, case_sensitive, TRUE);
1465 GnmValDiff
1466 value_compare_no_cache (GnmValue const *a, GnmValue const *b,
1467 gboolean case_sensitive)
1469 return value_compare_real (a, b, case_sensitive, FALSE);
1472 void
1473 value_set_fmt (GnmValue *v, GOFormat const *fmt)
1475 if (fmt == VALUE_FMT (v))
1476 return;
1477 g_return_if_fail (!VALUE_IS_EMPTY (v) && !VALUE_IS_BOOLEAN (v));
1478 if (fmt != NULL)
1479 go_format_ref (fmt);
1480 if (VALUE_FMT (v) != NULL)
1481 go_format_unref (VALUE_FMT (v));
1482 v->v_any.fmt = fmt;
1485 /****************************************************************************/
1487 GType
1488 gnm_value_get_type (void)
1490 static GType t = 0;
1492 if (t == 0)
1493 t = g_boxed_type_register_static ("GnmValue",
1494 (GBoxedCopyFunc)value_dup,
1495 (GBoxedFreeFunc)value_release);
1496 return t;
1498 /****************************************************************************/
1500 GnmValueErr const value_terminate_err = { VALUE_ERROR, NULL, NULL };
1501 static GnmValueFloat const the_value_zero = { VALUE_FLOAT, NULL, 0 };
1502 GnmValue const *value_zero = (GnmValue const *)&the_value_zero;
1504 void
1505 value_init (void)
1507 size_t i;
1509 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++) {
1510 standard_errors[i].locale_name = _(standard_errors[i].C_name);
1511 standard_errors[i].locale_name_str =
1512 go_string_new (standard_errors[i].locale_name);
1515 #if USE_VALUE_POOLS
1516 value_float_pool =
1517 go_mem_chunk_new ("value float pool",
1518 sizeof (GnmValueFloat),
1519 16 * 1024 - 128);
1521 value_error_pool =
1522 go_mem_chunk_new ("value error pool",
1523 sizeof (GnmValueErr),
1524 16 * 1024 - 128);
1526 value_string_pool =
1527 go_mem_chunk_new ("value string pool",
1528 sizeof (GnmValueStr),
1529 16 * 1024 - 128);
1531 value_range_pool =
1532 go_mem_chunk_new ("value range pool",
1533 sizeof (GnmValueRange),
1534 16 * 1024 - 128);
1536 value_array_pool =
1537 go_mem_chunk_new ("value array pool",
1538 sizeof (GnmValueArray),
1539 16 * 1024 - 128);
1540 #endif
1543 void
1544 value_shutdown (void)
1546 size_t i;
1548 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++) {
1549 go_string_unref (standard_errors[i].locale_name_str);
1550 standard_errors[i].locale_name_str = NULL;
1553 #if USE_VALUE_POOLS
1554 go_mem_chunk_destroy (value_float_pool, FALSE);
1555 value_float_pool = NULL;
1557 go_mem_chunk_destroy (value_error_pool, FALSE);
1558 value_error_pool = NULL;
1560 go_mem_chunk_destroy (value_string_pool, FALSE);
1561 value_string_pool = NULL;
1563 go_mem_chunk_destroy (value_range_pool, FALSE);
1564 value_range_pool = NULL;
1566 go_mem_chunk_destroy (value_array_pool, FALSE);
1567 value_array_pool = NULL;
1568 #else
1569 if (value_allocations)
1570 g_printerr ("Leaking %d values.\n", value_allocations);
1571 #endif
1574 /****************************************************************************/