Update Spanish translation
[gnumeric.git] / src / value.c
blobef8c025f369a7f74352096d43893fea2fe01480d
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 /**
70 * value_new_empty:
72 * Returns: (transfer full): a new empty value.
74 GnmValue *
75 value_new_empty (void)
77 /* This is a constant. No need to allocate any memory. */
78 static const GnmValueAny v = { VALUE_EMPTY, NULL };
79 return (GnmValue *)&v;
82 /**
83 * value_new_bool:
84 * @b: boolean
86 * Returns: (transfer full): a new boolean value.
88 GnmValue *
89 value_new_bool (gboolean b)
91 /* These are constant. No need to allocate any memory. */
92 static const GnmValueBool vf = { VALUE_BOOLEAN, NULL, FALSE };
93 static const GnmValueBool vt = { VALUE_BOOLEAN, NULL, TRUE };
94 return (GnmValue*) (b ? &vt : &vf);
97 /**
98 * value_new_int:
99 * @i: integer
101 * Returns: (transfer full): a new integer value. There is no separate
102 * integer type, so this is just an alias for value_new_float.
104 GnmValue *
105 value_new_int (int i)
107 return value_new_float (i);
111 * value_new_float:
112 * @f: number
114 * Returns: (transfer full): a new floating-point value.
116 GnmValue *
117 value_new_float (gnm_float f)
119 if (gnm_finite (f)) {
120 GnmValueFloat *v = CHUNK_ALLOC (GnmValueFloat, value_float_pool);
121 *((GnmValueType *)&(v->type)) = VALUE_FLOAT;
122 v->fmt = NULL;
123 v->val = f;
124 return (GnmValue *)v;
125 } else {
126 /* FIXME: bogus ep sent here. What to do? */
127 return value_new_error_NUM (NULL);
132 * value_new_error: (skip)
134 * Returns: (transfer full): a new error value.
136 GnmValue *
137 value_new_error (G_GNUC_UNUSED GnmEvalPos const *ep, char const *mesg)
139 GnmValueErr *v = CHUNK_ALLOC (GnmValueErr, value_error_pool);
140 *((GnmValueType *)&(v->type)) = VALUE_ERROR;
141 v->fmt = NULL;
142 v->mesg = go_string_new (mesg);
143 return (GnmValue *)v;
147 * value_new_error_str: (skip)
149 * Returns: (transfer full): a new error value.
151 GnmValue *
152 value_new_error_str (G_GNUC_UNUSED GnmEvalPos const *ep, GOString *mesg)
154 GnmValueErr *v = CHUNK_ALLOC (GnmValueErr, value_error_pool);
155 *((GnmValueType *)&(v->type)) = VALUE_ERROR;
156 v->fmt = NULL;
157 v->mesg = go_string_ref (mesg);
158 return (GnmValue *)v;
162 * value_new_error_std: (skip)
164 * Returns: (transfer full): a new error value.
166 GnmValue *
167 value_new_error_std (GnmEvalPos const *pos, GnmStdError err)
169 size_t i = (size_t)err;
170 g_return_val_if_fail (i < G_N_ELEMENTS (standard_errors), NULL);
172 return value_new_error_str (pos, standard_errors[i].locale_name_str);
176 * value_new_error_NULL: (skip)
178 * Returns: (transfer full): a new \#NULL! error value.
180 GnmValue *
181 value_new_error_NULL (GnmEvalPos const *pos)
183 return value_new_error_str (pos, standard_errors[GNM_ERROR_NULL].locale_name_str);
187 * value_new_error_DIV0: (skip)
189 * Returns: (transfer full): a new \#DIV0! error value. This is used for
190 * division by zero.
192 GnmValue *
193 value_new_error_DIV0 (GnmEvalPos const *pos)
195 return value_new_error_str (pos, standard_errors[GNM_ERROR_DIV0].locale_name_str);
199 * value_new_error_VALUE: (skip)
201 * Returns: (transfer full): a new \#VALUE! error value. This is used for
202 * example for type errors.
204 GnmValue *
205 value_new_error_VALUE (GnmEvalPos const *pos)
207 return value_new_error_str (pos, standard_errors[GNM_ERROR_VALUE].locale_name_str);
211 * value_new_error_REF: (skip)
213 * Returns: (transfer full): a new \#REF! error value. This is used for
214 * references that are no longer valid, for example because the column they
215 * were in got removed.
217 GnmValue *
218 value_new_error_REF (GnmEvalPos const *pos)
220 return value_new_error_str (pos, standard_errors[GNM_ERROR_REF].locale_name_str);
224 * value_new_error_NAME: (skip)
226 * Returns: (transfer full): a new \#NAME! error value. This is used for
227 * references to undefined names.
229 GnmValue *
230 value_new_error_NAME (GnmEvalPos const *pos)
232 return value_new_error_str (pos, standard_errors[GNM_ERROR_NAME].locale_name_str);
236 * value_new_error_NUM: (skip)
238 * Returns: (transfer full): a new \#NUM! error value. This is used
239 * for errors in numerical computations such as overflow or taking the
240 * logarithm of a negative number.
242 GnmValue *
243 value_new_error_NUM (GnmEvalPos const *pos)
245 return value_new_error_str (pos, standard_errors[GNM_ERROR_NUM].locale_name_str);
249 * value_new_error_NA: (skip)
251 * Returns: (transfer full): a new \#NA! error value. This is used for data
252 * that is not available.
254 GnmValue *
255 value_new_error_NA (GnmEvalPos const *pos)
257 return value_new_error_str (pos, standard_errors[GNM_ERROR_NA].locale_name_str);
261 * value_error_name:
262 * @err: #GnmStdError
263 * @translated: If %TRUE, use localized name.
265 * Returns: (transfer none): the name of @err, possibly localized.
267 char const *
268 value_error_name (GnmStdError err, gboolean translated)
270 size_t i = (size_t)err;
271 g_return_val_if_fail (i < G_N_ELEMENTS (standard_errors), NULL);
273 if (translated)
274 return standard_errors[i].locale_name;
275 else
276 return standard_errors[i].C_name;
280 * value_error_set_pos:
281 * @err:
282 * @pos:
284 * Change the position of a ValueError.
286 * Returns: (transfer none): @err as a #GnmValue.
288 GnmValue *
289 value_error_set_pos (GnmValueErr *err, G_GNUC_UNUSED GnmEvalPos const *pos)
291 g_return_val_if_fail (err != NULL, NULL);
292 g_return_val_if_fail (VALUE_IS_ERROR ((GnmValue *)err), NULL);
294 /* err->src = *pos; */
295 return (GnmValue *)err;
298 GnmStdError
299 value_error_classify (GnmValue const *v)
301 size_t i;
303 g_return_val_if_fail (v != NULL, GNM_ERROR_UNKNOWN);
305 if (!VALUE_IS_ERROR (v))
306 return GNM_ERROR_UNKNOWN;
308 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++)
309 if (standard_errors[i].locale_name_str == v->v_err.mesg)
310 return (GnmStdError)i;
312 return GNM_ERROR_UNKNOWN;
317 * value_new_string_str:
318 * @str: (transfer full): string to use for value
320 * Returns: (transfer full): a new string value.
322 GnmValue *
323 value_new_string_str (GOString *str)
325 GnmValueStr *v;
327 g_return_val_if_fail (str != NULL, NULL);
329 v = CHUNK_ALLOC (GnmValueStr, value_string_pool);
330 *((GnmValueType *)&(v->type)) = VALUE_STRING;
331 v->fmt = NULL;
332 v->val = str;
333 return (GnmValue *)v;
337 * value_new_string:
338 * @str: (transfer none): string to use for value
340 * Returns: (transfer full): a new string object.
342 GnmValue *
343 value_new_string (char const *str)
345 return value_new_string_str (go_string_new (str));
349 * value_new_string_nocopy: (skip)
350 * @str: (transfer full): string to use for value
352 * Returns: (transfer full): a new string object.
354 GnmValue *
355 value_new_string_nocopy (char *str)
357 return value_new_string_str (go_string_new_nocopy (str));
361 * value_new_cellrange_unsafe: (skip)
362 * @a: (transfer none): first #GnmCellRef
363 * @b: (transfer none): second #GnmCellRef
365 * Returns: (transfer full): a new cell range value.
367 GnmValue *
368 value_new_cellrange_unsafe (GnmCellRef const *a, GnmCellRef const *b)
370 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
371 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
372 v->fmt = NULL;
373 v->cell.a = *a;
374 v->cell.b = *b;
375 return (GnmValue *)v;
379 * value_new_cellrange:
381 * Create a new range reference.
383 * Attempt to do a sanity check for inverted ranges.
384 * NOTE : This is no longer necessary and will be removed.
385 * mixed mode references create the possibility of inversion.
386 * users of these values need to use the utility routines to
387 * evaluate the ranges in their context and normalize then.
389 GnmValue *
390 value_new_cellrange (GnmCellRef const *a, GnmCellRef const *b,
391 int eval_col, int eval_row)
393 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
394 int tmp;
396 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
397 v->fmt = NULL;
398 v->cell.a = *a;
399 v->cell.b = *b;
401 /* Sanity checking to avoid inverted ranges */
402 tmp = a->col;
403 if (a->col_relative != b->col_relative) {
404 /* Make a tmp copy of a in the same mode as b */
405 if (a->col_relative)
406 tmp += eval_col;
407 else
408 tmp -= eval_col;
410 if (tmp > b->col) {
411 v->cell.a.col = b->col;
412 v->cell.a.col_relative = b->col_relative;
413 v->cell.b.col = a->col;
414 v->cell.b.col_relative = a->col_relative;
417 tmp = a->row;
418 if (a->row_relative != b->row_relative) {
419 /* Make a tmp copy of a in the same mode as b */
420 if (a->row_relative)
421 tmp += eval_row;
422 else
423 tmp -= eval_row;
425 if (tmp > b->row) {
426 v->cell.a.row = b->row;
427 v->cell.a.row_relative = b->row_relative;
428 v->cell.b.row = a->row;
429 v->cell.b.row_relative = a->row_relative;
432 return (GnmValue *)v;
436 * value_new_cellrange_r:
437 * @r: #GnmRange
439 * Returns: (transfer full): a new cell range value for @r
441 GnmValue *
442 value_new_cellrange_r (Sheet *sheet, GnmRange const *r)
444 GnmValueRange *v = CHUNK_ALLOC (GnmValueRange, value_range_pool);
445 GnmCellRef *a, *b;
447 *((GnmValueType *)&(v->type)) = VALUE_CELLRANGE;
448 v->fmt = NULL;
449 a = &v->cell.a;
450 b = &v->cell.b;
452 a->sheet = sheet;
453 b->sheet = sheet;
454 a->col = r->start.col;
455 a->row = r->start.row;
456 b->col = r->end.col;
457 b->row = r->end.row;
458 a->col_relative = b->col_relative = FALSE;
459 a->row_relative = b->row_relative = FALSE;
461 return (GnmValue *)v;
465 * value_new_cellrange_str:
466 * @sheet: the sheet where the cell range is evaluated. This really only needed if
467 * the range given does not include a sheet specification.
468 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
470 * Parse @str using the convention associated with @sheet.
471 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
472 * succesfully parsed or %NULL on failure.
474 GnmValue *
475 value_new_cellrange_str (Sheet *sheet, char const *str)
477 GnmParsePos pp;
478 GnmExprParseFlags flags = GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS |
479 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES;
481 g_return_val_if_fail (IS_SHEET (sheet), NULL);
482 g_return_val_if_fail (str != NULL, NULL);
484 parse_pos_init_sheet (&pp, sheet);
485 return value_new_cellrange_parsepos_str (&pp, str, flags);
489 * value_new_cellrange_parsepos_str:
490 * @pp: if a relative range is specified, then it will be interpreted relative
491 * to this position (affects only A1-style relative references).
492 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
494 * Parse @str using the convention associated with @sheet.
495 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
496 * succesfully parsed or %NULL on failure.
498 GnmValue *
499 value_new_cellrange_parsepos_str (GnmParsePos const *pp, char const *str,
500 GnmExprParseFlags flags)
502 GnmExprTop const *texpr;
503 GnmConventions const *convs = NULL;
505 g_return_val_if_fail (pp != NULL, NULL);
506 g_return_val_if_fail (str != NULL, NULL);
508 if (pp->sheet)
509 convs = pp->sheet->convs;
511 texpr = gnm_expr_parse_str (str, pp, flags, convs, NULL);
513 if (texpr != NULL) {
514 GnmValue *value = gnm_expr_top_get_range (texpr);
515 gnm_expr_top_unref (texpr);
516 return value;
519 return NULL;
523 * value_new_array_non_init: (skip)
524 * @cols: number of columns
525 * @rows: number of rows
527 * Returns: (transfer full): a new array value of the given size.
529 GnmValue *
530 value_new_array_non_init (guint cols, guint rows)
532 GnmValueArray *v = CHUNK_ALLOC (GnmValueArray, value_array_pool);
533 *((GnmValueType *)&(v->type)) = VALUE_ARRAY;
534 v->fmt = NULL;
535 v->x = cols;
536 v->y = rows;
537 v->vals = g_new (GnmValue **, cols);
538 return (GnmValue *)v;
542 * value_new_array:
543 * @cols: number of columns
544 * @rows: number of rows
546 * Returns: (transfer full): a new array value of the given size with all
547 * elements equal to 0.
549 GnmValue *
550 value_new_array (guint cols, guint rows)
552 guint x, y;
553 GnmValueArray *v = (GnmValueArray *)value_new_array_non_init (cols, rows);
555 for (x = 0; x < cols; x++) {
556 v->vals[x] = g_new (GnmValue *, rows);
557 for (y = 0; y < rows; y++)
558 v->vals[x][y] = value_new_int (0);
560 return (GnmValue *)v;
564 * value_new_array_empty:
565 * @cols: number of columns
566 * @rows: number of rows
568 * Returns: (transfer full): a new array value of the given size with all
569 * elements equal the empty value.
571 GnmValue *
572 value_new_array_empty (guint cols, guint rows)
574 guint x, y;
575 GnmValueArray *v = (GnmValueArray *)value_new_array_non_init (cols, rows);
577 for (x = 0; x < cols; x++) {
578 v->vals[x] = g_new (GnmValue *, rows);
579 for (y = 0; y < rows; y++)
580 v->vals[x][y] = value_new_empty ();
582 return (GnmValue *)v;
586 * Returns TRUE, FALSE, or -1.
588 static int
589 value_parse_boolean (char const *str, gboolean translated)
591 if (translated) {
592 /* FIXME: ascii??? */
593 if (0 == g_ascii_strcasecmp (str, go_locale_boolean_name (TRUE)))
594 return +TRUE;
595 else if (0 == g_ascii_strcasecmp (str, go_locale_boolean_name (FALSE)))
596 return +FALSE;
597 else
598 return -1;
599 } else {
600 if (0 == g_ascii_strcasecmp (str, "TRUE"))
601 return +TRUE;
602 else if (0 == g_ascii_strcasecmp (str, "FALSE"))
603 return +FALSE;
604 else
605 return -1;
610 GnmValue *
611 value_new_from_string (GnmValueType t, char const *str, GOFormat *sf,
612 gboolean translated)
614 GnmValue *res = NULL;
617 * We need the following cast to avoid a warning from gcc over
618 * VALUE_INTEGER (which is not in GnmValueType).
620 switch ((guint8)t) {
621 case VALUE_EMPTY:
622 res = value_new_empty ();
623 break;
625 case VALUE_BOOLEAN: {
626 int i = value_parse_boolean (str, translated);
627 if (i != -1)
628 res = value_new_bool ((gboolean)i);
629 break;
632 case VALUE_INTEGER:
633 case VALUE_FLOAT: {
634 char *end;
635 gnm_float d;
637 d = gnm_strto (str, &end);
638 if (d != 0 && d > -GNM_MIN && d < GNM_MIN)
639 errno = 0;
641 if (str != end && *end == '\0' && errno != ERANGE)
642 res = value_new_float (d);
643 break;
646 case VALUE_ERROR:
648 * Tricky. We are currently storing errors in translated
649 * format, so we might have to undo that.
651 if (!translated) {
652 size_t i;
653 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++)
654 if (strcmp (standard_errors[i].C_name, str) == 0) {
655 res = value_new_error_std (NULL, (GnmStdError)i);
656 break;
659 if (!res)
660 res = value_new_error (NULL, str);
661 break;
663 case VALUE_STRING:
664 res = value_new_string (str);
665 break;
667 case VALUE_ARRAY:
668 case VALUE_CELLRANGE:
669 default:
670 /* This happen with corrupted files. */
671 return NULL;
674 if (res)
675 value_set_fmt (res, sf);
676 return res;
680 * value_release:
681 * @v: (transfer full) (allow-none): value to dispose of
683 * Free the value.
685 void
686 value_release (GnmValue *value)
688 if (NULL == value)
689 return;
691 if (VALUE_FMT (value) != NULL)
692 go_format_unref (VALUE_FMT (value));
694 switch (value->v_any.type) {
695 case VALUE_EMPTY:
696 case VALUE_BOOLEAN:
697 /* We did not allocate anything, there is nothing to free */
698 return;
700 case VALUE_FLOAT:
701 CHUNK_FREE (value_float_pool, &value->v_float);
702 return;
704 case VALUE_ERROR:
705 /* Do not release VALUE_TERMINATE, it is a magic number */
706 if (value == VALUE_TERMINATE) {
707 g_warning ("Someone freed VALUE_TERMINATE -- shame on them.");
708 return;
711 go_string_unref (value->v_err.mesg);
712 CHUNK_FREE (value_error_pool, &value->v_err);
713 return;
715 case VALUE_STRING:
716 go_string_unref (value->v_str.val);
717 CHUNK_FREE (value_string_pool, &value->v_str);
718 return;
720 case VALUE_ARRAY: {
721 GnmValueArray *v = &value->v_array;
722 int x, y;
724 for (x = 0; x < v->x; x++) {
725 for (y = 0; y < v->y; y++)
726 value_release (v->vals[x][y]);
727 g_free (v->vals[x]);
730 g_free (v->vals);
731 CHUNK_FREE (value_array_pool, v);
732 return;
735 case VALUE_CELLRANGE:
736 CHUNK_FREE (value_range_pool, &value->v_range);
737 return;
739 default:
741 * If we don't recognize the type this is probably garbage.
742 * Do not free it to avoid heap corruption
744 g_warning ("value_release problem.");
745 return;
747 g_assert_not_reached ();
751 * value_dup:
752 * @v: (nullable): #GnmValue
754 * Returns: (transfer full) (nullable): a copy of @v.
756 GnmValue *
757 value_dup (GnmValue const *src)
759 GnmValue *res;
761 if (src == NULL)
762 return NULL;
764 switch (src->v_any.type){
765 case VALUE_EMPTY:
766 res = value_new_empty ();
767 break;
769 case VALUE_BOOLEAN:
770 res = value_new_bool (src->v_bool.val);
771 break;
773 case VALUE_FLOAT:
774 res = value_new_float (src->v_float.val);
775 break;
777 case VALUE_ERROR:
778 res = value_new_error_str (NULL, /* &src->v_err.src, */
779 src->v_err.mesg);
780 break;
782 case VALUE_STRING:
783 go_string_ref (src->v_str.val);
784 res = value_new_string_str (src->v_str.val);
785 break;
787 case VALUE_CELLRANGE:
788 res = value_new_cellrange_unsafe (&src->v_range.cell.a,
789 &src->v_range.cell.b);
790 break;
792 case VALUE_ARRAY: {
793 int x, y;
794 GnmValueArray *array = (GnmValueArray *)value_new_array_non_init (
795 src->v_array.x, src->v_array.y);
797 for (x = 0; x < array->x; x++) {
798 array->vals[x] = g_new (GnmValue *, array->y);
799 for (y = 0; y < array->y; y++)
800 array->vals[x][y] = value_dup (src->v_array.vals[x][y]);
802 res = (GnmValue *)array;
803 break;
806 default:
807 g_warning ("value_dup problem.");
808 res = value_new_empty ();
810 value_set_fmt (res, VALUE_FMT (src));
811 return res;
814 static GnmValDiff
815 value_compare_real (GnmValue const *a, GnmValue const *b,
816 gboolean case_sensitive,
817 gboolean default_locale);
821 * value_cmp:
822 * @ptr_a:
823 * @ptr_b:
825 * qsort style comparison function for ascending order
828 value_cmp (void const *ptr_a, void const *ptr_b)
830 GnmValue const *a = *(GnmValue const **)ptr_a;
831 GnmValue const *b = *(GnmValue const **)ptr_b;
832 switch (value_compare_real (a, b, TRUE, TRUE)) {
833 case IS_EQUAL : return 0;
834 case IS_LESS : return -1;
835 case IS_GREATER : return 1;
836 default:
837 break;
839 return a->v_any.type - b->v_any.type;
843 * value_cmp_reverse:
844 * @ptr_a:
845 * @ptr_b:
847 * qsort style comparison function for descending order.
850 value_cmp_reverse (void const *ptr_a, void const *ptr_b)
852 return -value_cmp (ptr_a, ptr_b);
856 * value_equal:
857 * @a: first #GnmValue
858 * @b: second #GnmValue
860 * Returns: %TRUE if the two values are equal, %FALSE otherwise. Cell ranges
861 * are considered equal only if they are the same ranges, i.e., the contents
862 * of the ranges are not considered.
864 gboolean
865 value_equal (GnmValue const *a, GnmValue const *b)
867 if (a->v_any.type != b->v_any.type)
868 return FALSE;
870 switch (a->v_any.type) {
871 case VALUE_BOOLEAN:
872 return a->v_bool.val == b->v_bool.val;
874 case VALUE_STRING:
875 return go_string_equal (a->v_str.val, b->v_str.val);
877 case VALUE_ERROR:
878 return go_string_equal (a->v_err.mesg, b->v_err.mesg);
880 case VALUE_FLOAT:
881 return a->v_float.val == b->v_float.val;
883 case VALUE_EMPTY:
884 return TRUE;
886 case VALUE_CELLRANGE:
887 return gnm_cellref_equal (&a->v_range.cell.a, &b->v_range.cell.a) &&
888 gnm_cellref_equal (&a->v_range.cell.b, &b->v_range.cell.b);
890 case VALUE_ARRAY:
891 if (a->v_array.x == b->v_array.x && a->v_array.y == b->v_array.y) {
892 int x, y;
894 for (y = 0; y < a->v_array.y; y++)
895 for (x = 0; x < a->v_array.x; x++)
896 if (!value_equal (a->v_array.vals[x][y],
897 b->v_array.vals[x][y]))
898 return FALSE;
899 return TRUE;
900 } else
901 return FALSE;
903 #ifndef DEBUG_SWITCH_ENUM
904 default:
905 g_assert_not_reached ();
906 return FALSE;
907 #endif
912 * value_hash:
913 * @v: #GnmValue
915 * Returns: a reasonable hash value for @v.
917 guint
918 value_hash (GnmValue const *v)
920 switch (v->v_any.type) {
921 case VALUE_BOOLEAN:
922 return v->v_bool.val ? 0x555aaaa : 0xaaa5555;
924 case VALUE_STRING:
925 return go_string_hash (v->v_str.val);
927 case VALUE_ERROR:
928 return go_string_hash (v->v_err.mesg);
930 case VALUE_FLOAT: {
931 int expt;
932 gnm_float mant = gnm_frexp (gnm_abs (v->v_float.val), &expt);
933 guint h = ((guint)(0x80000000u * mant)) ^ expt;
934 if (v->v_float.val >= 0)
935 h ^= 0x55555555;
936 return h;
939 case VALUE_EMPTY:
940 return 42;
942 case VALUE_CELLRANGE:
943 /* FIXME: take sheet into account? */
944 return (gnm_cellref_hash (&v->v_range.cell.a) * 3) ^
945 gnm_cellref_hash (&v->v_range.cell.b);
947 case VALUE_ARRAY: {
948 int i;
949 guint h = (v->v_array.x * 257) ^ (v->v_array.y + 42);
951 /* For speed, just walk the diagonal. */
952 for (i = 0; i < v->v_array.x && i < v->v_array.y; i++) {
953 h *= 5;
954 if (v->v_array.vals[i][i])
955 h ^= value_hash (v->v_array.vals[i][i]);
957 return h;
960 #ifndef DEBUG_SWITCH_ENUM
961 default:
962 g_assert_not_reached ();
963 return 0;
964 #endif
969 GnmValueType
970 value_type_of (const GnmValue *v)
972 return v->v_any.type;
976 gboolean
977 value_get_as_bool (GnmValue const *v, gboolean *err)
979 if (err)
980 *err = FALSE;
982 if (v == NULL)
983 return FALSE;
985 switch (v->v_any.type) {
986 case VALUE_EMPTY:
987 return FALSE;
989 case VALUE_BOOLEAN:
990 return v->v_bool.val;
992 case VALUE_STRING: {
993 int i = value_parse_boolean (value_peek_string (v), FALSE);
994 if (i == -1) {
995 if (err)
996 *err = TRUE;
997 return FALSE;
999 return (gboolean)i;
1002 case VALUE_FLOAT:
1003 return v->v_float.val != 0.0;
1005 default:
1006 g_warning ("Unhandled value in value_get_as_bool.");
1008 case VALUE_CELLRANGE:
1009 case VALUE_ARRAY:
1010 case VALUE_ERROR:
1011 if (err)
1012 *err = TRUE;
1014 return FALSE;
1018 * use only if you are sure the value is ok
1020 gboolean
1021 value_get_as_checked_bool (GnmValue const *v)
1023 gboolean result, err;
1025 result = value_get_as_bool (v, &err);
1027 g_return_val_if_fail (!err, FALSE);
1029 return result;
1033 * value_get_as_gstring:
1034 * @v: #GnmValue
1035 * @target: #GString
1036 * @conv: #GnmConventions
1038 * A simple value formatter to convert @v into a string stored in @target
1039 * according to @conv. See format_value_gstring for something more elaborate
1040 * that handles formats too.
1042 void
1043 value_get_as_gstring (GnmValue const *v, GString *target,
1044 GnmConventions const *conv)
1046 if (v == NULL)
1047 return;
1049 switch (v->v_any.type){
1050 case VALUE_EMPTY:
1051 return;
1053 case VALUE_ERROR: {
1054 GnmStdError e = value_error_classify (v);
1055 if (e == GNM_ERROR_UNKNOWN) {
1056 g_string_append_c (target, '#');
1057 go_strescape (target, v->v_err.mesg->str);
1058 } else
1059 g_string_append (target, value_error_name (e, conv->output.translated));
1060 return;
1063 case VALUE_BOOLEAN: {
1064 gboolean b = v->v_bool.val;
1065 g_string_append (target,
1066 conv->output.translated
1067 ? go_locale_boolean_name (b)
1068 : (b ? "TRUE" : "FALSE"));
1069 return;
1072 case VALUE_STRING:
1073 g_string_append (target, v->v_str.val->str);
1074 return;
1076 case VALUE_FLOAT:
1077 if (conv->output.decimal_digits < 0)
1078 go_dtoa (target, "!" GNM_FORMAT_g, v->v_float.val);
1079 else
1080 g_string_append_printf (target, "%.*" GNM_FORMAT_g,
1081 conv->output.decimal_digits,
1082 v->v_float.val);
1083 return;
1085 case VALUE_ARRAY: {
1086 GnmValue const *val;
1087 gunichar row_sep, col_sep;
1088 int x, y;
1090 if (conv->array_row_sep)
1091 row_sep = conv->array_row_sep;
1092 else
1093 row_sep = go_locale_get_row_sep ();
1094 if (conv->array_col_sep)
1095 col_sep = conv->array_col_sep;
1096 else
1097 col_sep = go_locale_get_col_sep ();
1099 g_string_append_c (target, '{');
1100 for (y = 0; y < v->v_array.y; y++){
1101 if (y)
1102 g_string_append_unichar (target, row_sep);
1104 for (x = 0; x < v->v_array.x; x++){
1105 val = v->v_array.vals[x][y];
1107 if (x)
1108 g_string_append_unichar (target, col_sep);
1110 /* quote strings */
1111 if (!val) {
1112 /* This is not supposed to happen, but
1113 let's not crash anyway. */
1114 g_string_append (target, "?");
1115 } else if (VALUE_IS_STRING (val))
1116 go_strescape (target, val->v_str.val->str);
1117 else
1118 value_get_as_gstring (val, target, conv);
1121 g_string_append_c (target, '}');
1122 return;
1125 case VALUE_CELLRANGE: {
1126 char *tmp;
1127 /* Note: this makes only sense for absolute references or
1128 * references relative to A1
1130 GnmRange range;
1131 range_init_value (&range, v);
1132 tmp = global_range_name (v->v_range.cell.a.sheet, &range);
1133 g_string_append (target, tmp);
1134 g_free (tmp);
1135 return;
1138 default:
1139 break;
1142 g_assert_not_reached ();
1147 * value_get_as_string:
1148 * @v: #GnmValue
1150 * Simplistic value rendering
1152 * Returns: (transfer full): a string rendering of @v.
1154 char *
1155 value_get_as_string (GnmValue const *v)
1157 GString *res = g_string_sized_new (10);
1158 value_get_as_gstring (v, res, gnm_conventions_default);
1159 return g_string_free (res, FALSE);
1163 * value_peek_string:
1164 * @v: a #GnmValue
1166 * Returns: (transfer none): A string representation of the value. The
1167 * result will stay valid until either (a) the value is disposed of, or
1168 * (b) two further calls to this function are made.
1170 // NOTE: "(transfer none)" papers over an introspection bug
1171 char const *
1172 value_peek_string (GnmValue const *v)
1174 g_return_val_if_fail (v, "");
1176 if (VALUE_IS_STRING (v))
1177 return v->v_str.val->str;
1178 else if (VALUE_IS_ERROR (v))
1179 return v->v_err.mesg->str;
1180 else {
1181 static char *cache[2] = { NULL, NULL };
1182 static int next = 0;
1183 char const *s;
1185 g_free (cache[next]);
1186 s = cache[next] = value_get_as_string (v);
1187 next = (next + 1) % G_N_ELEMENTS (cache);
1188 return s;
1193 * value_stringify:
1194 * @v: a #GnmValue
1196 * Returns: (transfer full): A string representation of the value suitable
1197 * for use in a Python __repr__ function.
1199 char *
1200 value_stringify (GnmValue const *v)
1202 GString *res = g_string_sized_new (30);
1204 g_string_append_c (res, '{');
1206 switch (v->v_any.type) {
1207 case VALUE_EMPTY:
1208 g_string_append (res, "EMPTY,");
1209 g_string_append (res, "None");
1210 break;
1212 case VALUE_STRING:
1213 g_string_append (res, "STRING,");
1214 go_strescape (res, value_peek_string (v));
1215 break;
1217 case VALUE_CELLRANGE:
1218 g_string_append (res, "CELLRANGE,");
1219 g_string_append (res, value_peek_string (v));
1220 return 0;
1222 case VALUE_ARRAY:
1223 g_string_append (res, "ARRAY,");
1224 g_string_append (res, value_peek_string (v));
1225 break;
1227 case VALUE_FLOAT:
1228 g_string_append (res, "FLOAT,");
1229 g_string_append (res, value_peek_string (v));
1230 break;
1232 case VALUE_BOOLEAN:
1233 g_string_append (res, "BOOLEAN,");
1234 g_string_append_c (res, v->v_bool.val ? '1' : '0');
1235 break;
1237 case VALUE_ERROR:
1238 g_string_append (res, "ERROR,");
1239 go_strescape (res, value_peek_string (v));
1240 break;
1242 default:
1243 g_string_append (res, "?,?");
1244 break;
1247 if (VALUE_FMT (v) != NULL) {
1248 g_string_append_c (res, ',');
1249 go_strescape (res, go_format_as_XL (VALUE_FMT (v)));
1252 g_string_append_c (res, '}');
1254 return g_string_free (res, FALSE);
1260 * value_get_as_int:
1261 * @v: (nullable): a #GnmValue
1263 * Returns: @v interpreted as an integer.
1266 value_get_as_int (GnmValue const *v)
1268 if (v == NULL)
1269 return 0;
1270 switch (v->v_any.type) {
1271 case VALUE_EMPTY:
1272 return 0;
1274 case VALUE_STRING:
1275 return atoi (v->v_str.val->str);
1277 case VALUE_CELLRANGE:
1278 g_warning ("Getting range as a int: what to do?");
1279 return 0;
1281 case VALUE_ARRAY:
1282 return 0;
1284 case VALUE_FLOAT:
1285 return (int) gnm_fake_trunc (v->v_float.val);
1287 case VALUE_BOOLEAN:
1288 return v->v_bool.val ? 1 : 0;
1290 case VALUE_ERROR:
1291 return 0;
1293 default:
1294 g_warning ("value_get_as_int unknown type 0x%x (%d).", v->v_any.type, v->v_any.type);
1295 return 0;
1297 return 0;
1301 * value_get_as_float:
1302 * @v: (nullable): a #GnmValue
1304 * Returns: @v interpreted as a floating point value.
1306 gnm_float
1307 value_get_as_float (GnmValue const *v)
1309 if (v == NULL)
1310 return 0.;
1312 switch (v->v_any.type) {
1313 case VALUE_EMPTY:
1314 return 0.;
1316 case VALUE_STRING:
1317 return gnm_strto (v->v_str.val->str, NULL);
1319 case VALUE_CELLRANGE:
1320 g_warning ("Getting range as a double: what to do?");
1321 return 0.0;
1323 case VALUE_ARRAY:
1324 return 0.0;
1326 case VALUE_FLOAT:
1327 return (gnm_float) v->v_float.val;
1329 case VALUE_BOOLEAN:
1330 return v->v_bool.val ? 1. : 0.;
1332 case VALUE_ERROR:
1333 return 0.;
1335 default:
1336 g_warning ("value_get_as_float type error.");
1337 break;
1339 return 0.0;
1343 * value_is_zero:
1344 * @v: (nullable): a #GnmValue
1346 * Returns: %TRUE if @v interpreted as a floating-point value is zero.
1348 gboolean
1349 value_is_zero (GnmValue const *v)
1351 return gnm_abs (value_get_as_float (v)) < 64 * GNM_EPSILON;
1355 * value_get_rangeref:
1356 * @v: #gnmvalue
1358 * Returns: (transfer none): the cell range of a cell range value.
1360 GnmRangeRef const *
1361 value_get_rangeref (GnmValue const *v)
1363 g_return_val_if_fail (VALUE_IS_CELLRANGE (v), NULL);
1364 return &v->v_range.cell;
1369 * value_coerce_to_number:
1370 * @v:
1371 * @valid:
1373 * If the value can be used as a number return that number
1374 * otherwise free it at return an appropriate error
1376 GnmValue *
1377 value_coerce_to_number (GnmValue *v, gboolean *valid, GnmEvalPos const *ep)
1379 g_return_val_if_fail (v != NULL, NULL);
1381 *valid = FALSE;
1382 if (VALUE_IS_STRING (v)) {
1383 GnmValue *tmp =
1384 format_match_number (value_peek_string (v), NULL,
1385 sheet_date_conv (ep->sheet));
1386 value_release (v);
1387 if (tmp == NULL)
1388 return value_new_error_VALUE (ep);
1389 v = tmp;
1390 } else if (VALUE_IS_ERROR (v))
1391 return v;
1393 if (!VALUE_IS_NUMBER (v)) {
1394 value_release (v);
1395 return value_new_error_VALUE (ep);
1398 *valid = TRUE;
1399 return v;
1403 * value_array_set:
1404 * @array: Array #GnmValue
1405 * @col: column
1406 * @row: row
1407 * @v: (transfer full): #GnmValue
1409 * Sets an element of an array value.
1411 void
1412 value_array_set (GnmValue *array, int col, int row, GnmValue *v)
1414 g_return_if_fail (v);
1415 g_return_if_fail (VALUE_IS_ARRAY (array));
1416 g_return_if_fail (col>=0);
1417 g_return_if_fail (row>=0);
1418 g_return_if_fail (array->v_array.y > row);
1419 g_return_if_fail (array->v_array.x > col);
1421 value_release (array->v_array.vals[col][row]);
1422 array->v_array.vals[col][row] = v;
1425 static GnmValDiff
1426 compare_bool_bool (GnmValue const *va, GnmValue const *vb)
1428 gboolean err; /* Ignored */
1429 gboolean const a = value_get_as_bool (va, &err);
1430 gboolean const b = value_get_as_bool (vb, &err);
1431 if (a)
1432 return b ? IS_EQUAL : IS_GREATER;
1433 return b ? IS_LESS : IS_EQUAL;
1436 static GnmValDiff
1437 compare_float_float (GnmValue const *va, GnmValue const *vb)
1439 gnm_float const a = value_get_as_float (va);
1440 gnm_float const b = value_get_as_float (vb);
1441 if (a == b)
1442 return IS_EQUAL;
1443 else if (a < b)
1444 return IS_LESS;
1445 else
1446 return IS_GREATER;
1449 static GnmValDiff
1450 compare_error_error (GnmValue const *va, GnmValue const *vb)
1452 GnmStdError ea = value_error_classify (va);
1453 GnmStdError eb = value_error_classify (vb);
1454 int i;
1456 if (ea != eb)
1457 return ea < eb ? IS_LESS : IS_GREATER;
1459 if (ea != GNM_ERROR_UNKNOWN)
1460 return IS_EQUAL;
1462 /* Two unknown errors. Just compare strings. */
1463 i = strcmp (value_peek_string (va), value_peek_string (vb));
1464 return (i > 0 ? IS_GREATER : (i < 0 ? IS_LESS : IS_EQUAL));
1469 * value_diff:
1470 * @a: value a
1471 * @b: value b
1473 * IGNORES format.
1475 * Returns a non-negative difference between 2 values
1477 gnm_float
1478 value_diff (GnmValue const *a, GnmValue const *b)
1480 GnmValueType ta, tb;
1482 /* Handle trivial (including empty/empty) and double NULL */
1483 if (a == b)
1484 return 0.;
1486 ta = VALUE_IS_EMPTY (a) ? VALUE_EMPTY : a->v_any.type;
1487 tb = VALUE_IS_EMPTY (b) ? VALUE_EMPTY : b->v_any.type;
1489 /* string > empty */
1490 if (ta == VALUE_STRING) {
1491 switch (tb) {
1492 /* Strings are > (empty, or number) */
1493 case VALUE_EMPTY:
1494 if (*a->v_str.val->str == '\0')
1495 return 0.;
1496 return DBL_MAX;
1498 /* If both are strings compare as string */
1499 case VALUE_STRING:
1500 if (go_string_equal (a->v_str.val, b->v_str.val))
1501 return 0.;
1503 case VALUE_FLOAT: case VALUE_BOOLEAN:
1504 default:
1505 return DBL_MAX;
1508 } else if (tb == VALUE_STRING) {
1509 switch (ta) {
1510 /* (empty, or number) < String */
1511 case VALUE_EMPTY:
1512 if (*b->v_str.val->str == '\0')
1513 return 0.;
1515 case VALUE_FLOAT : case VALUE_BOOLEAN:
1516 default:
1517 return DBL_MAX;
1521 /* Booleans > all numbers (Why did excel do this ?? ) */
1522 if (ta == VALUE_BOOLEAN && tb == VALUE_FLOAT)
1523 return DBL_MAX;
1524 if (tb == VALUE_BOOLEAN && ta == VALUE_FLOAT)
1525 return DBL_MAX;
1527 switch ((ta > tb) ? ta : tb) {
1528 case VALUE_EMPTY: /* Empty Empty compare */
1529 return 0.;
1531 case VALUE_BOOLEAN:
1532 return (compare_bool_bool (a, b) == IS_EQUAL) ? 0. : DBL_MAX;
1534 case VALUE_FLOAT: {
1535 gnm_float const da = value_get_as_float (a);
1536 gnm_float const db = value_get_as_float (b);
1537 return gnm_abs (da - db);
1539 default:
1540 return TYPE_MISMATCH;
1544 static int
1545 gnm_string_cmp (gconstpointer gstr_a, gconstpointer gstr_b)
1547 return (gstr_a == gstr_b)
1549 : g_utf8_collate (((GOString const *)gstr_a)->str,
1550 ((GOString const *)gstr_b)->str);
1553 static int
1554 gnm_string_cmp_ignorecase (gconstpointer gstr_a, gconstpointer gstr_b)
1556 gchar *a;
1557 gchar *b;
1558 int res;
1560 if (gstr_a == gstr_b)
1561 return 0;
1563 a = g_utf8_casefold (((GOString const *)gstr_a)->str, -1);
1564 b = g_utf8_casefold (((GOString const *)gstr_b)->str, -1);
1566 res = g_utf8_collate (a, b);
1568 g_free (a);
1569 g_free (b);
1571 return res;
1575 /* This depends on the actual values of the enums. */
1576 #define PAIR(ta_,tb_) ((ta_) + (((tb_) >> 3) - 1))
1577 #define CPAIR(ta_,tb_) (1 ? PAIR((ta_),(tb_)) : sizeof (struct { int sanity_check[((ta_) >= (tb_)) * 2 - 1]; } ))
1580 * value_compare:
1582 * @a: value a
1583 * @b: value b
1584 * @case_sensitive: are string comparisons case sensitive.
1586 * IGNORES format.
1588 static GnmValDiff
1589 value_compare_real (GnmValue const *a, GnmValue const *b,
1590 gboolean case_sensitive,
1591 gboolean default_locale)
1593 GnmValueType ta, tb;
1594 gboolean flip;
1595 GnmValDiff res;
1597 /* Handle trivial and double NULL case */
1598 if (a == b)
1599 return IS_EQUAL;
1601 ta = VALUE_IS_EMPTY (a) ? VALUE_EMPTY : a->v_any.type;
1602 tb = VALUE_IS_EMPTY (b) ? VALUE_EMPTY : b->v_any.type;
1604 flip = (tb > ta);
1605 if (flip) {
1606 GnmValueType t = ta;
1607 GnmValue const *v = a;
1608 ta = tb;
1609 tb = t;
1610 a = b;
1611 b = v;
1614 switch (PAIR (ta,tb)) {
1615 case CPAIR (VALUE_EMPTY,VALUE_EMPTY):
1616 /* In most cases this is handled by the trivial case. */
1617 /* We can get here if one of a and b is NULL and the */
1618 /* is not but contains an empty value. */
1619 return IS_EQUAL;
1621 /* ---------------------------------------- */
1623 case CPAIR (VALUE_BOOLEAN,VALUE_EMPTY): /* Blank is FALSE */
1624 case CPAIR (VALUE_BOOLEAN,VALUE_BOOLEAN):
1625 res = compare_bool_bool (a, b);
1626 break;
1628 /* ---------------------------------------- */
1630 case CPAIR (VALUE_FLOAT,VALUE_BOOLEAN):
1631 /* Number < boolean (Why did excel do this ?? ) */
1632 res = IS_LESS;
1633 break;
1634 case CPAIR (VALUE_FLOAT,VALUE_EMPTY): /* Blank is 0 */
1635 case CPAIR (VALUE_FLOAT,VALUE_FLOAT):
1636 res = compare_float_float (a, b);
1637 break;
1639 /* ---------------------------------------- */
1641 case CPAIR (VALUE_ERROR,VALUE_EMPTY):
1642 case CPAIR (VALUE_ERROR,VALUE_BOOLEAN):
1643 case CPAIR (VALUE_ERROR,VALUE_FLOAT):
1644 /* Error > others */
1645 res = IS_GREATER;
1646 break;
1648 case CPAIR (VALUE_ERROR,VALUE_ERROR):
1649 res = compare_error_error (a, b);
1650 break;
1652 /* ---------------------------------------- */
1654 case CPAIR (VALUE_STRING,VALUE_EMPTY): /* Blank is empty string */
1655 /* String > empty, except empty string */
1656 res = a->v_str.val->str[0] == '\0' ? IS_EQUAL : IS_GREATER;
1657 break;
1659 case CPAIR (VALUE_STRING,VALUE_BOOLEAN):
1660 /* String < boolean */
1661 res = IS_LESS;
1662 break;
1664 case CPAIR (VALUE_STRING,VALUE_FLOAT):
1665 /* String > number */
1666 res = IS_GREATER;
1667 break;
1669 case CPAIR (VALUE_STRING,VALUE_ERROR):
1670 /* String < error */
1671 res = IS_LESS;
1672 break;
1674 case CPAIR (VALUE_STRING,VALUE_STRING): {
1675 GOString const *sa = a->v_str.val;
1676 GOString const *sb = b->v_str.val;
1677 int i = (default_locale
1678 ? (case_sensitive
1679 ? go_string_cmp (sa, sb)
1680 : go_string_cmp_ignorecase (sa, sb))
1681 : (case_sensitive
1682 ? gnm_string_cmp (sa, sb)
1683 : gnm_string_cmp_ignorecase (sa, sb)));
1684 res = (i > 0 ? IS_GREATER : (i < 0 ? IS_LESS : IS_EQUAL));
1685 break;
1688 /* ---------------------------------------- */
1690 default:
1691 res = TYPE_MISMATCH;
1694 if (flip) {
1695 if (res == IS_LESS)
1696 res = IS_GREATER;
1697 else if (res == IS_GREATER)
1698 res = IS_LESS;
1701 return res;
1703 #undef PAIR
1706 GnmValDiff
1707 value_compare (GnmValue const *a, GnmValue const *b, gboolean case_sensitive)
1709 return value_compare_real (a, b, case_sensitive, TRUE);
1712 GnmValDiff
1713 value_compare_no_cache (GnmValue const *a, GnmValue const *b,
1714 gboolean case_sensitive)
1716 return value_compare_real (a, b, case_sensitive, FALSE);
1720 * value_set_format:
1721 * @v: #GnmValue
1722 * @fmt: (nullable): #GOFormat
1724 * Sets @v's format.
1726 void
1727 value_set_fmt (GnmValue *v, GOFormat const *fmt)
1729 if (fmt == VALUE_FMT (v))
1730 return;
1731 g_return_if_fail (!VALUE_IS_EMPTY (v) && !VALUE_IS_BOOLEAN (v));
1732 if (fmt != NULL)
1733 go_format_ref (fmt);
1734 if (VALUE_FMT (v) != NULL)
1735 go_format_unref (VALUE_FMT (v));
1736 v->v_any.fmt = fmt;
1739 /****************************************************************************/
1741 GType
1742 gnm_value_get_type (void)
1744 static GType t = 0;
1746 if (t == 0)
1747 t = g_boxed_type_register_static ("GnmValue",
1748 (GBoxedCopyFunc)value_dup,
1749 (GBoxedFreeFunc)value_release);
1750 return t;
1752 /****************************************************************************/
1754 GnmValueErr const value_terminate_err = { VALUE_ERROR, NULL, NULL };
1755 static GnmValueFloat const the_value_zero = { VALUE_FLOAT, NULL, 0 };
1756 GnmValue const *value_zero = (GnmValue const *)&the_value_zero;
1759 * value_init: (skip)
1761 void
1762 value_init (void)
1764 size_t i;
1766 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++) {
1767 standard_errors[i].locale_name = _(standard_errors[i].C_name);
1768 standard_errors[i].locale_name_str =
1769 go_string_new (standard_errors[i].locale_name);
1772 #if USE_VALUE_POOLS
1773 value_float_pool =
1774 go_mem_chunk_new ("value float pool",
1775 sizeof (GnmValueFloat),
1776 16 * 1024 - 128);
1778 value_error_pool =
1779 go_mem_chunk_new ("value error pool",
1780 sizeof (GnmValueErr),
1781 16 * 1024 - 128);
1783 value_string_pool =
1784 go_mem_chunk_new ("value string pool",
1785 sizeof (GnmValueStr),
1786 16 * 1024 - 128);
1788 value_range_pool =
1789 go_mem_chunk_new ("value range pool",
1790 sizeof (GnmValueRange),
1791 16 * 1024 - 128);
1793 value_array_pool =
1794 go_mem_chunk_new ("value array pool",
1795 sizeof (GnmValueArray),
1796 16 * 1024 - 128);
1797 #endif
1801 * value_shutdown: (skip)
1803 void
1804 value_shutdown (void)
1806 size_t i;
1808 for (i = 0; i < G_N_ELEMENTS (standard_errors); i++) {
1809 go_string_unref (standard_errors[i].locale_name_str);
1810 standard_errors[i].locale_name_str = NULL;
1813 #if USE_VALUE_POOLS
1814 go_mem_chunk_destroy (value_float_pool, FALSE);
1815 value_float_pool = NULL;
1817 go_mem_chunk_destroy (value_error_pool, FALSE);
1818 value_error_pool = NULL;
1820 go_mem_chunk_destroy (value_string_pool, FALSE);
1821 value_string_pool = NULL;
1823 go_mem_chunk_destroy (value_range_pool, FALSE);
1824 value_range_pool = NULL;
1826 go_mem_chunk_destroy (value_array_pool, FALSE);
1827 value_array_pool = NULL;
1828 #else
1829 if (value_allocations)
1830 g_printerr ("Leaking %d values.\n", value_allocations);
1831 #endif
1834 /****************************************************************************/