2 * value.c: Utilies for handling, creating, removing values.
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)
11 #include <gnumeric-config.h>
12 #include <glib/gi18n-lib.h>
16 #include <parse-util.h>
18 #include <gnm-format.h>
27 #include <number-match.h>
28 #include <goffice/goffice.h>
35 #ifndef USE_VALUE_POOLS
36 #define USE_VALUE_POOLS 0
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))
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)))
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
}
72 * Returns: (transfer full): a new empty value.
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
;
86 * Returns: (transfer full): a new boolean value.
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
);
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.
105 value_new_int (int i
)
107 return value_new_float (i
);
114 * Returns: (transfer full): a new floating-point value.
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
;
124 return (GnmValue
*)v
;
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.
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
;
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.
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
;
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.
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.
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
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.
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.
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.
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.
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.
255 value_new_error_NA (GnmEvalPos
const *pos
)
257 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_NA
].locale_name_str
);
263 * @translated: If %TRUE, use localized name.
265 * Returns: (transfer none): the name of @err, possibly localized.
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
);
274 return standard_errors
[i
].locale_name
;
276 return standard_errors
[i
].C_name
;
280 * value_error_set_pos:
284 * Change the position of a ValueError.
286 * Returns: (transfer none): @err as a #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
;
299 value_error_classify (GnmValue
const *v
)
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.
323 value_new_string_str (GOString
*str
)
327 g_return_val_if_fail (str
!= NULL
, NULL
);
329 v
= CHUNK_ALLOC (GnmValueStr
, value_string_pool
);
330 *((GnmValueType
*)&(v
->type
)) = VALUE_STRING
;
333 return (GnmValue
*)v
;
338 * @str: (transfer none): string to use for value
340 * Returns: (transfer full): a new string object.
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.
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.
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
;
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.
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
);
396 *((GnmValueType
*)&(v
->type
)) = VALUE_CELLRANGE
;
401 /* Sanity checking to avoid inverted ranges */
403 if (a
->col_relative
!= b
->col_relative
) {
404 /* Make a tmp copy of a in the same mode as b */
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
;
418 if (a
->row_relative
!= b
->row_relative
) {
419 /* Make a tmp copy of a in the same mode as b */
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:
439 * Returns: (transfer full): a new cell range value for @r
442 value_new_cellrange_r (Sheet
*sheet
, GnmRange
const *r
)
444 GnmValueRange
*v
= CHUNK_ALLOC (GnmValueRange
, value_range_pool
);
447 *((GnmValueType
*)&(v
->type
)) = VALUE_CELLRANGE
;
454 a
->col
= r
->start
.col
;
455 a
->row
= r
->start
.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.
475 value_new_cellrange_str (Sheet
*sheet
, char const *str
)
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.
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
);
509 convs
= pp
->sheet
->convs
;
511 texpr
= gnm_expr_parse_str (str
, pp
, flags
, convs
, NULL
);
514 GnmValue
*value
= gnm_expr_top_get_range (texpr
);
515 gnm_expr_top_unref (texpr
);
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.
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
;
537 v
->vals
= g_new (GnmValue
**, cols
);
538 return (GnmValue
*)v
;
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.
550 value_new_array (guint cols
, guint rows
)
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.
572 value_new_array_empty (guint cols
, guint rows
)
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.
589 value_parse_boolean (char const *str
, gboolean translated
)
592 /* FIXME: ascii??? */
593 if (0 == g_ascii_strcasecmp (str
, go_locale_boolean_name (TRUE
)))
595 else if (0 == g_ascii_strcasecmp (str
, go_locale_boolean_name (FALSE
)))
600 if (0 == g_ascii_strcasecmp (str
, "TRUE"))
602 else if (0 == g_ascii_strcasecmp (str
, "FALSE"))
611 value_new_from_string (GnmValueType t
, char const *str
, GOFormat
*sf
,
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).
622 res
= value_new_empty ();
625 case VALUE_BOOLEAN
: {
626 int i
= value_parse_boolean (str
, translated
);
628 res
= value_new_bool ((gboolean
)i
);
637 d
= gnm_strto (str
, &end
);
638 if (d
!= 0 && d
> -GNM_MIN
&& d
< GNM_MIN
)
641 if (str
!= end
&& *end
== '\0' && errno
!= ERANGE
)
642 res
= value_new_float (d
);
648 * Tricky. We are currently storing errors in translated
649 * format, so we might have to undo that.
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
);
660 res
= value_new_error (NULL
, str
);
664 res
= value_new_string (str
);
668 case VALUE_CELLRANGE
:
670 /* This happen with corrupted files. */
675 value_set_fmt (res
, sf
);
681 * @v: (transfer full) (allow-none): value to dispose of
686 value_release (GnmValue
*value
)
691 if (VALUE_FMT (value
) != NULL
)
692 go_format_unref (VALUE_FMT (value
));
694 switch (value
->v_any
.type
) {
697 /* We did not allocate anything, there is nothing to free */
701 CHUNK_FREE (value_float_pool
, &value
->v_float
);
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.");
711 go_string_unref (value
->v_err
.mesg
);
712 CHUNK_FREE (value_error_pool
, &value
->v_err
);
716 go_string_unref (value
->v_str
.val
);
717 CHUNK_FREE (value_string_pool
, &value
->v_str
);
721 GnmValueArray
*v
= &value
->v_array
;
724 for (x
= 0; x
< v
->x
; x
++) {
725 for (y
= 0; y
< v
->y
; y
++)
726 value_release (v
->vals
[x
][y
]);
731 CHUNK_FREE (value_array_pool
, v
);
735 case VALUE_CELLRANGE
:
736 CHUNK_FREE (value_range_pool
, &value
->v_range
);
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.");
747 g_assert_not_reached ();
752 * @v: (nullable): #GnmValue
754 * Returns: (transfer full) (nullable): a copy of @v.
757 value_dup (GnmValue
const *src
)
764 switch (src
->v_any
.type
){
766 res
= value_new_empty ();
770 res
= value_new_bool (src
->v_bool
.val
);
774 res
= value_new_float (src
->v_float
.val
);
778 res
= value_new_error_str (NULL
, /* &src->v_err.src, */
783 go_string_ref (src
->v_str
.val
);
784 res
= value_new_string_str (src
->v_str
.val
);
787 case VALUE_CELLRANGE
:
788 res
= value_new_cellrange_unsafe (&src
->v_range
.cell
.a
,
789 &src
->v_range
.cell
.b
);
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
;
807 g_warning ("value_dup problem.");
808 res
= value_new_empty ();
810 value_set_fmt (res
, VALUE_FMT (src
));
815 value_compare_real (GnmValue
const *a
, GnmValue
const *b
,
816 gboolean case_sensitive
,
817 gboolean default_locale
);
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;
839 return a
->v_any
.type
- b
->v_any
.type
;
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
);
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.
865 value_equal (GnmValue
const *a
, GnmValue
const *b
)
867 if (a
->v_any
.type
!= b
->v_any
.type
)
870 switch (a
->v_any
.type
) {
872 return a
->v_bool
.val
== b
->v_bool
.val
;
875 return go_string_equal (a
->v_str
.val
, b
->v_str
.val
);
878 return go_string_equal (a
->v_err
.mesg
, b
->v_err
.mesg
);
881 return a
->v_float
.val
== b
->v_float
.val
;
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
);
891 if (a
->v_array
.x
== b
->v_array
.x
&& a
->v_array
.y
== b
->v_array
.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
]))
903 #ifndef DEBUG_SWITCH_ENUM
905 g_assert_not_reached ();
915 * Returns: a reasonable hash value for @v.
918 value_hash (GnmValue
const *v
)
920 switch (v
->v_any
.type
) {
922 return v
->v_bool
.val
? 0x555aaaa : 0xaaa5555;
925 return go_string_hash (v
->v_str
.val
);
928 return go_string_hash (v
->v_err
.mesg
);
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)
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
);
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
++) {
954 if (v
->v_array
.vals
[i
][i
])
955 h
^= value_hash (v
->v_array
.vals
[i
][i
]);
960 #ifndef DEBUG_SWITCH_ENUM
962 g_assert_not_reached ();
970 value_type_of (const GnmValue
*v
)
972 return v
->v_any
.type
;
977 value_get_as_bool (GnmValue
const *v
, gboolean
*err
)
985 switch (v
->v_any
.type
) {
990 return v
->v_bool
.val
;
993 int i
= value_parse_boolean (value_peek_string (v
), FALSE
);
1003 return v
->v_float
.val
!= 0.0;
1006 g_warning ("Unhandled value in value_get_as_bool.");
1008 case VALUE_CELLRANGE
:
1018 * use only if you are sure the value is ok
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
);
1033 * value_get_as_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.
1043 value_get_as_gstring (GnmValue
const *v
, GString
*target
,
1044 GnmConventions
const *conv
)
1049 switch (v
->v_any
.type
){
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
);
1059 g_string_append (target
, value_error_name (e
, conv
->output
.translated
));
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"));
1073 g_string_append (target
, v
->v_str
.val
->str
);
1077 if (conv
->output
.decimal_digits
< 0)
1078 go_dtoa (target
, "!" GNM_FORMAT_g
, v
->v_float
.val
);
1080 g_string_append_printf (target
, "%.*" GNM_FORMAT_g
,
1081 conv
->output
.decimal_digits
,
1086 GnmValue
const *val
;
1087 gunichar row_sep
, col_sep
;
1090 if (conv
->array_row_sep
)
1091 row_sep
= conv
->array_row_sep
;
1093 row_sep
= go_locale_get_row_sep ();
1094 if (conv
->array_col_sep
)
1095 col_sep
= conv
->array_col_sep
;
1097 col_sep
= go_locale_get_col_sep ();
1099 g_string_append_c (target
, '{');
1100 for (y
= 0; y
< v
->v_array
.y
; 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
];
1108 g_string_append_unichar (target
, col_sep
);
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
);
1118 value_get_as_gstring (val
, target
, conv
);
1121 g_string_append_c (target
, '}');
1125 case VALUE_CELLRANGE
: {
1127 /* Note: this makes only sense for absolute references or
1128 * references relative to A1
1131 range_init_value (&range
, v
);
1132 tmp
= global_range_name (v
->v_range
.cell
.a
.sheet
, &range
);
1133 g_string_append (target
, tmp
);
1142 g_assert_not_reached ();
1147 * value_get_as_string:
1150 * Simplistic value rendering
1152 * Returns: (transfer full): a string rendering of @v.
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:
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
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
;
1181 static char *cache
[2] = { NULL
, NULL
};
1182 static int next
= 0;
1185 g_free (cache
[next
]);
1186 s
= cache
[next
] = value_get_as_string (v
);
1187 next
= (next
+ 1) % G_N_ELEMENTS (cache
);
1196 * Returns: (transfer full): A string representation of the value suitable
1197 * for use in a Python __repr__ function.
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
) {
1208 g_string_append (res
, "EMPTY,");
1209 g_string_append (res
, "None");
1213 g_string_append (res
, "STRING,");
1214 go_strescape (res
, value_peek_string (v
));
1217 case VALUE_CELLRANGE
:
1218 g_string_append (res
, "CELLRANGE,");
1219 g_string_append (res
, value_peek_string (v
));
1223 g_string_append (res
, "ARRAY,");
1224 g_string_append (res
, value_peek_string (v
));
1228 g_string_append (res
, "FLOAT,");
1229 g_string_append (res
, value_peek_string (v
));
1233 g_string_append (res
, "BOOLEAN,");
1234 g_string_append_c (res
, v
->v_bool
.val
? '1' : '0');
1238 g_string_append (res
, "ERROR,");
1239 go_strescape (res
, value_peek_string (v
));
1243 g_string_append (res
, "?,?");
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
);
1261 * @v: (nullable): a #GnmValue
1263 * Returns: @v interpreted as an integer.
1266 value_get_as_int (GnmValue
const *v
)
1270 switch (v
->v_any
.type
) {
1275 return atoi (v
->v_str
.val
->str
);
1277 case VALUE_CELLRANGE
:
1278 g_warning ("Getting range as a int: what to do?");
1285 return (int) gnm_fake_trunc (v
->v_float
.val
);
1288 return v
->v_bool
.val
? 1 : 0;
1294 g_warning ("value_get_as_int unknown type 0x%x (%d).", v
->v_any
.type
, v
->v_any
.type
);
1301 * value_get_as_float:
1302 * @v: (nullable): a #GnmValue
1304 * Returns: @v interpreted as a floating point value.
1307 value_get_as_float (GnmValue
const *v
)
1312 switch (v
->v_any
.type
) {
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?");
1327 return (gnm_float
) v
->v_float
.val
;
1330 return v
->v_bool
.val
? 1. : 0.;
1336 g_warning ("value_get_as_float type error.");
1344 * @v: (nullable): a #GnmValue
1346 * Returns: %TRUE if @v interpreted as a floating-point value is zero.
1349 value_is_zero (GnmValue
const *v
)
1351 return gnm_abs (value_get_as_float (v
)) < 64 * GNM_EPSILON
;
1355 * value_get_rangeref:
1358 * Returns: (transfer none): the cell range of a cell range value.
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:
1373 * If the value can be used as a number return that number
1374 * otherwise free it at return an appropriate error
1377 value_coerce_to_number (GnmValue
*v
, gboolean
*valid
, GnmEvalPos
const *ep
)
1379 g_return_val_if_fail (v
!= NULL
, NULL
);
1382 if (VALUE_IS_STRING (v
)) {
1384 format_match_number (value_peek_string (v
), NULL
,
1385 sheet_date_conv (ep
->sheet
));
1388 return value_new_error_VALUE (ep
);
1390 } else if (VALUE_IS_ERROR (v
))
1393 if (!VALUE_IS_NUMBER (v
)) {
1395 return value_new_error_VALUE (ep
);
1404 * @array: Array #GnmValue
1407 * @v: (transfer full): #GnmValue
1409 * Sets an element of an array value.
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
;
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
);
1432 return b
? IS_EQUAL
: IS_GREATER
;
1433 return b
? IS_LESS
: IS_EQUAL
;
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
);
1450 compare_error_error (GnmValue
const *va
, GnmValue
const *vb
)
1452 GnmStdError ea
= value_error_classify (va
);
1453 GnmStdError eb
= value_error_classify (vb
);
1457 return ea
< eb
? IS_LESS
: IS_GREATER
;
1459 if (ea
!= GNM_ERROR_UNKNOWN
)
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
));
1475 * Returns a non-negative difference between 2 values
1478 value_diff (GnmValue
const *a
, GnmValue
const *b
)
1480 GnmValueType ta
, tb
;
1482 /* Handle trivial (including empty/empty) and double NULL */
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
) {
1492 /* Strings are > (empty, or number) */
1494 if (*a
->v_str
.val
->str
== '\0')
1498 /* If both are strings compare as string */
1500 if (go_string_equal (a
->v_str
.val
, b
->v_str
.val
))
1503 case VALUE_FLOAT
: case VALUE_BOOLEAN
:
1508 } else if (tb
== VALUE_STRING
) {
1510 /* (empty, or number) < String */
1512 if (*b
->v_str
.val
->str
== '\0')
1515 case VALUE_FLOAT
: case VALUE_BOOLEAN
:
1521 /* Booleans > all numbers (Why did excel do this ?? ) */
1522 if (ta
== VALUE_BOOLEAN
&& tb
== VALUE_FLOAT
)
1524 if (tb
== VALUE_BOOLEAN
&& ta
== VALUE_FLOAT
)
1527 switch ((ta
> tb
) ? ta
: tb
) {
1528 case VALUE_EMPTY
: /* Empty Empty compare */
1532 return (compare_bool_bool (a
, b
) == IS_EQUAL
) ? 0. : DBL_MAX
;
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
);
1540 return TYPE_MISMATCH
;
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
);
1554 gnm_string_cmp_ignorecase (gconstpointer gstr_a
, gconstpointer gstr_b
)
1560 if (gstr_a
== gstr_b
)
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
);
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]; } ))
1584 * @case_sensitive: are string comparisons case sensitive.
1589 value_compare_real (GnmValue
const *a
, GnmValue
const *b
,
1590 gboolean case_sensitive
,
1591 gboolean default_locale
)
1593 GnmValueType ta
, tb
;
1597 /* Handle trivial and double NULL case */
1601 ta
= VALUE_IS_EMPTY (a
) ? VALUE_EMPTY
: a
->v_any
.type
;
1602 tb
= VALUE_IS_EMPTY (b
) ? VALUE_EMPTY
: b
->v_any
.type
;
1606 GnmValueType t
= ta
;
1607 GnmValue
const *v
= a
;
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. */
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
);
1628 /* ---------------------------------------- */
1630 case CPAIR (VALUE_FLOAT
,VALUE_BOOLEAN
):
1631 /* Number < boolean (Why did excel do this ?? ) */
1634 case CPAIR (VALUE_FLOAT
,VALUE_EMPTY
): /* Blank is 0 */
1635 case CPAIR (VALUE_FLOAT
,VALUE_FLOAT
):
1636 res
= compare_float_float (a
, b
);
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 */
1648 case CPAIR (VALUE_ERROR
,VALUE_ERROR
):
1649 res
= compare_error_error (a
, b
);
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
;
1659 case CPAIR (VALUE_STRING
,VALUE_BOOLEAN
):
1660 /* String < boolean */
1664 case CPAIR (VALUE_STRING
,VALUE_FLOAT
):
1665 /* String > number */
1669 case CPAIR (VALUE_STRING
,VALUE_ERROR
):
1670 /* String < error */
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
1679 ? go_string_cmp (sa
, sb
)
1680 : go_string_cmp_ignorecase (sa
, sb
))
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
));
1688 /* ---------------------------------------- */
1691 res
= TYPE_MISMATCH
;
1697 else if (res
== IS_GREATER
)
1707 value_compare (GnmValue
const *a
, GnmValue
const *b
, gboolean case_sensitive
)
1709 return value_compare_real (a
, b
, case_sensitive
, TRUE
);
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
);
1722 * @fmt: (nullable): #GOFormat
1727 value_set_fmt (GnmValue
*v
, GOFormat
const *fmt
)
1729 if (fmt
== VALUE_FMT (v
))
1731 g_return_if_fail (!VALUE_IS_EMPTY (v
) && !VALUE_IS_BOOLEAN (v
));
1733 go_format_ref (fmt
);
1734 if (VALUE_FMT (v
) != NULL
)
1735 go_format_unref (VALUE_FMT (v
));
1739 /****************************************************************************/
1742 gnm_value_get_type (void)
1747 t
= g_boxed_type_register_static ("GnmValue",
1748 (GBoxedCopyFunc
)value_dup
,
1749 (GBoxedFreeFunc
)value_release
);
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)
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
);
1774 go_mem_chunk_new ("value float pool",
1775 sizeof (GnmValueFloat
),
1779 go_mem_chunk_new ("value error pool",
1780 sizeof (GnmValueErr
),
1784 go_mem_chunk_new ("value string pool",
1785 sizeof (GnmValueStr
),
1789 go_mem_chunk_new ("value range pool",
1790 sizeof (GnmValueRange
),
1794 go_mem_chunk_new ("value array pool",
1795 sizeof (GnmValueArray
),
1801 * value_shutdown: (skip)
1804 value_shutdown (void)
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
;
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
;
1829 if (value_allocations
)
1830 g_printerr ("Leaking %d values.\n", value_allocations
);
1834 /****************************************************************************/