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
}
70 value_new_empty (void)
72 /* This is a constant. No need to allocate any memory. */
73 static const GnmValueAny v
= { VALUE_EMPTY
, NULL
};
74 return (GnmValue
*)&v
;
78 value_new_bool (gboolean b
)
80 /* These are constant. No need to allocate any memory. */
81 static const GnmValueBool vf
= { VALUE_BOOLEAN
, NULL
, FALSE
};
82 static const GnmValueBool vt
= { VALUE_BOOLEAN
, NULL
, TRUE
};
83 return (GnmValue
*) (b
? &vt
: &vf
);
89 return value_new_float (i
);
93 value_new_float (gnm_float f
)
96 GnmValueFloat
*v
= CHUNK_ALLOC (GnmValueFloat
, value_float_pool
);
97 *((GnmValueType
*)&(v
->type
)) = VALUE_FLOAT
;
100 return (GnmValue
*)v
;
102 /* FIXME: bogus ep sent here. What to do? */
103 return value_new_error_NUM (NULL
);
108 value_new_error (G_GNUC_UNUSED GnmEvalPos
const *ep
, char const *mesg
)
110 GnmValueErr
*v
= CHUNK_ALLOC (GnmValueErr
, value_error_pool
);
111 *((GnmValueType
*)&(v
->type
)) = VALUE_ERROR
;
113 v
->mesg
= go_string_new (mesg
);
114 return (GnmValue
*)v
;
118 value_new_error_str (G_GNUC_UNUSED GnmEvalPos
const *ep
, GOString
*mesg
)
120 GnmValueErr
*v
= CHUNK_ALLOC (GnmValueErr
, value_error_pool
);
121 *((GnmValueType
*)&(v
->type
)) = VALUE_ERROR
;
123 v
->mesg
= go_string_ref (mesg
);
124 return (GnmValue
*)v
;
128 value_new_error_std (GnmEvalPos
const *pos
, GnmStdError err
)
130 size_t i
= (size_t)err
;
131 g_return_val_if_fail (i
< G_N_ELEMENTS (standard_errors
), NULL
);
133 return value_new_error_str (pos
, standard_errors
[i
].locale_name_str
);
138 value_new_error_NULL (GnmEvalPos
const *pos
)
140 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_NULL
].locale_name_str
);
144 value_new_error_DIV0 (GnmEvalPos
const *pos
)
146 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_DIV0
].locale_name_str
);
150 value_new_error_VALUE (GnmEvalPos
const *pos
)
152 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_VALUE
].locale_name_str
);
156 value_new_error_REF (GnmEvalPos
const *pos
)
158 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_REF
].locale_name_str
);
162 value_new_error_NAME (GnmEvalPos
const *pos
)
164 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_NAME
].locale_name_str
);
168 value_new_error_NUM (GnmEvalPos
const *pos
)
170 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_NUM
].locale_name_str
);
174 value_new_error_NA (GnmEvalPos
const *pos
)
176 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_NA
].locale_name_str
);
182 * @translated: If %TRUE, use localized name.
184 * Returns: (transfer none): the name of @err, possibly localized.
187 value_error_name (GnmStdError err
, gboolean translated
)
189 size_t i
= (size_t)err
;
190 g_return_val_if_fail (i
< G_N_ELEMENTS (standard_errors
), NULL
);
193 return standard_errors
[i
].locale_name
;
195 return standard_errors
[i
].C_name
;
199 * value_error_set_pos:
203 * Change the position of a ValueError.
205 * Returns: (transfer none): @err as a #GnmValue.
208 value_error_set_pos (GnmValueErr
*err
, G_GNUC_UNUSED GnmEvalPos
const *pos
)
210 g_return_val_if_fail (err
!= NULL
, NULL
);
211 g_return_val_if_fail (VALUE_IS_ERROR ((GnmValue
*)err
), NULL
);
213 /* err->src = *pos; */
214 return (GnmValue
*)err
;
218 value_error_classify (GnmValue
const *v
)
222 g_return_val_if_fail (v
!= NULL
, GNM_ERROR_UNKNOWN
);
224 if (!VALUE_IS_ERROR (v
))
225 return GNM_ERROR_UNKNOWN
;
227 for (i
= 0; i
< G_N_ELEMENTS (standard_errors
); i
++)
228 if (standard_errors
[i
].locale_name_str
== v
->v_err
.mesg
)
229 return (GnmStdError
)i
;
231 return GNM_ERROR_UNKNOWN
;
236 * value_new_string_str:
237 * @str: (transfer full): string to use for value
239 * Returns: (transfer full): a new value object.
242 value_new_string_str (GOString
*str
)
246 g_return_val_if_fail (str
!= NULL
, NULL
);
248 v
= CHUNK_ALLOC (GnmValueStr
, value_string_pool
);
249 *((GnmValueType
*)&(v
->type
)) = VALUE_STRING
;
252 return (GnmValue
*)v
;
257 * @str: string to use for value
259 * Returns: (transfer full): a new value object.
262 value_new_string (char const *str
)
264 return value_new_string_str (go_string_new (str
));
268 * value_new_string_nocopy:
269 * @str: (transfer full): string to use for value
271 * Returns: (transfer full): a new value object.
274 value_new_string_nocopy (char *str
)
276 return value_new_string_str (go_string_new_nocopy (str
));
280 value_new_cellrange_unsafe (GnmCellRef
const *a
, GnmCellRef
const *b
)
282 GnmValueRange
*v
= CHUNK_ALLOC (GnmValueRange
, value_range_pool
);
283 *((GnmValueType
*)&(v
->type
)) = VALUE_CELLRANGE
;
287 return (GnmValue
*)v
;
291 * value_new_cellrange:
293 * Create a new range reference.
295 * Attempt to do a sanity check for inverted ranges.
296 * NOTE : This is no longer necessary and will be removed.
297 * mixed mode references create the possibility of inversion.
298 * users of these values need to use the utility routines to
299 * evaluate the ranges in their context and normalize then.
302 value_new_cellrange (GnmCellRef
const *a
, GnmCellRef
const *b
,
303 int eval_col
, int eval_row
)
305 GnmValueRange
*v
= CHUNK_ALLOC (GnmValueRange
, value_range_pool
);
308 *((GnmValueType
*)&(v
->type
)) = VALUE_CELLRANGE
;
313 /* Sanity checking to avoid inverted ranges */
315 if (a
->col_relative
!= b
->col_relative
) {
316 /* Make a tmp copy of a in the same mode as b */
323 v
->cell
.a
.col
= b
->col
;
324 v
->cell
.a
.col_relative
= b
->col_relative
;
325 v
->cell
.b
.col
= a
->col
;
326 v
->cell
.b
.col_relative
= a
->col_relative
;
330 if (a
->row_relative
!= b
->row_relative
) {
331 /* Make a tmp copy of a in the same mode as b */
338 v
->cell
.a
.row
= b
->row
;
339 v
->cell
.a
.row_relative
= b
->row_relative
;
340 v
->cell
.b
.row
= a
->row
;
341 v
->cell
.b
.row_relative
= a
->row_relative
;
344 return (GnmValue
*)v
;
348 value_new_cellrange_r (Sheet
*sheet
, GnmRange
const *r
)
350 GnmValueRange
*v
= CHUNK_ALLOC (GnmValueRange
, value_range_pool
);
353 *((GnmValueType
*)&(v
->type
)) = VALUE_CELLRANGE
;
360 a
->col
= r
->start
.col
;
361 a
->row
= r
->start
.row
;
364 a
->col_relative
= b
->col_relative
= FALSE
;
365 a
->row_relative
= b
->row_relative
= FALSE
;
367 return (GnmValue
*)v
;
371 * value_new_cellrange_str:
372 * @sheet: the sheet where the cell range is evaluated. This really only needed if
373 * the range given does not include a sheet specification.
374 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
376 * Parse @str using the convention associated with @sheet.
377 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
378 * succesfully parsed or %NULL on failure.
381 value_new_cellrange_str (Sheet
*sheet
, char const *str
)
384 GnmExprParseFlags flags
= GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS
|
385 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES
;
387 g_return_val_if_fail (IS_SHEET (sheet
), NULL
);
388 g_return_val_if_fail (str
!= NULL
, NULL
);
390 parse_pos_init_sheet (&pp
, sheet
);
391 return value_new_cellrange_parsepos_str (&pp
, str
, flags
);
395 * value_new_cellrange_parsepos_str:
396 * @pp: if a relative range is specified, then it will be interpreted relative
397 * to this position (affects only A1-style relative references).
398 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
400 * Parse @str using the convention associated with @sheet.
401 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
402 * succesfully parsed or %NULL on failure.
405 value_new_cellrange_parsepos_str (GnmParsePos
const *pp
, char const *str
,
406 GnmExprParseFlags flags
)
408 GnmExprTop
const *texpr
;
409 GnmConventions
const *convs
= NULL
;
411 g_return_val_if_fail (pp
!= NULL
, NULL
);
412 g_return_val_if_fail (str
!= NULL
, NULL
);
415 convs
= pp
->sheet
->convs
;
417 texpr
= gnm_expr_parse_str (str
, pp
, flags
, convs
, NULL
);
420 GnmValue
*value
= gnm_expr_top_get_range (texpr
);
421 gnm_expr_top_unref (texpr
);
429 value_new_array_non_init (guint cols
, guint rows
)
431 GnmValueArray
*v
= CHUNK_ALLOC (GnmValueArray
, value_array_pool
);
432 *((GnmValueType
*)&(v
->type
)) = VALUE_ARRAY
;
436 v
->vals
= g_new (GnmValue
**, cols
);
437 return (GnmValue
*)v
;
441 value_new_array (guint cols
, guint rows
)
444 GnmValueArray
*v
= (GnmValueArray
*)value_new_array_non_init (cols
, rows
);
446 for (x
= 0; x
< cols
; x
++) {
447 v
->vals
[x
] = g_new (GnmValue
*, rows
);
448 for (y
= 0; y
< rows
; y
++)
449 v
->vals
[x
][y
] = value_new_int (0);
451 return (GnmValue
*)v
;
455 value_new_array_empty (guint cols
, guint rows
)
458 GnmValueArray
*v
= (GnmValueArray
*)value_new_array_non_init (cols
, rows
);
460 for (x
= 0; x
< cols
; x
++) {
461 v
->vals
[x
] = g_new (GnmValue
*, rows
);
462 for (y
= 0; y
< rows
; y
++)
463 v
->vals
[x
][y
] = value_new_empty ();
465 return (GnmValue
*)v
;
469 * Returns TRUE, FALSE, or -1.
472 value_parse_boolean (char const *str
, gboolean translated
)
475 /* FIXME: ascii??? */
476 if (0 == g_ascii_strcasecmp (str
, go_locale_boolean_name (TRUE
)))
478 else if (0 == g_ascii_strcasecmp (str
, go_locale_boolean_name (FALSE
)))
483 if (0 == g_ascii_strcasecmp (str
, "TRUE"))
485 else if (0 == g_ascii_strcasecmp (str
, "FALSE"))
494 value_new_from_string (GnmValueType t
, char const *str
, GOFormat
*sf
,
497 GnmValue
*res
= NULL
;
500 * We need the following cast to avoid a warning from gcc over
501 * VALUE_INTEGER (which is not in GnmValueType).
505 res
= value_new_empty ();
508 case VALUE_BOOLEAN
: {
509 int i
= value_parse_boolean (str
, translated
);
511 res
= value_new_bool ((gboolean
)i
);
520 d
= gnm_strto (str
, &end
);
521 if (d
!= 0 && d
> -GNM_MIN
&& d
< GNM_MIN
)
524 if (str
!= end
&& *end
== '\0' && errno
!= ERANGE
)
525 res
= value_new_float (d
);
531 * Tricky. We are currently storing errors in translated
532 * format, so we might have to undo that.
536 for (i
= 0; i
< G_N_ELEMENTS (standard_errors
); i
++)
537 if (strcmp (standard_errors
[i
].C_name
, str
) == 0) {
538 res
= value_new_error_std (NULL
, (GnmStdError
)i
);
543 res
= value_new_error (NULL
, str
);
547 res
= value_new_string (str
);
551 case VALUE_CELLRANGE
:
553 /* This happen with corrupted files. */
558 value_set_fmt (res
, sf
);
564 * @v: (transfer full) (allow-none): value to dispose of
569 value_release (GnmValue
*value
)
574 if (VALUE_FMT (value
) != NULL
)
575 go_format_unref (VALUE_FMT (value
));
577 switch (value
->v_any
.type
) {
580 /* We did not allocate anything, there is nothing to free */
584 CHUNK_FREE (value_float_pool
, &value
->v_float
);
588 /* Do not release VALUE_TERMINATE, it is a magic number */
589 if (value
== VALUE_TERMINATE
) {
590 g_warning ("Someone freed VALUE_TERMINATE -- shame on them.");
594 go_string_unref (value
->v_err
.mesg
);
595 CHUNK_FREE (value_error_pool
, &value
->v_err
);
599 go_string_unref (value
->v_str
.val
);
600 CHUNK_FREE (value_string_pool
, &value
->v_str
);
604 GnmValueArray
*v
= &value
->v_array
;
607 for (x
= 0; x
< v
->x
; x
++) {
608 for (y
= 0; y
< v
->y
; y
++)
609 value_release (v
->vals
[x
][y
]);
614 CHUNK_FREE (value_array_pool
, v
);
618 case VALUE_CELLRANGE
:
619 CHUNK_FREE (value_range_pool
, &value
->v_range
);
624 * If we don't recognize the type this is probably garbage.
625 * Do not free it to avoid heap corruption
627 g_warning ("value_release problem.");
630 g_assert_not_reached ();
635 * @v: (nullable): #GnmValue
637 * Returns: (transfer full) (nullable): a copy of @v.
640 value_dup (GnmValue
const *src
)
647 switch (src
->v_any
.type
){
649 res
= value_new_empty ();
653 res
= value_new_bool (src
->v_bool
.val
);
657 res
= value_new_float (src
->v_float
.val
);
661 res
= value_new_error_str (NULL
, /* &src->v_err.src, */
666 go_string_ref (src
->v_str
.val
);
667 res
= value_new_string_str (src
->v_str
.val
);
670 case VALUE_CELLRANGE
:
671 res
= value_new_cellrange_unsafe (&src
->v_range
.cell
.a
,
672 &src
->v_range
.cell
.b
);
677 GnmValueArray
*array
= (GnmValueArray
*)value_new_array_non_init (
678 src
->v_array
.x
, src
->v_array
.y
);
680 for (x
= 0; x
< array
->x
; x
++) {
681 array
->vals
[x
] = g_new (GnmValue
*, array
->y
);
682 for (y
= 0; y
< array
->y
; y
++)
683 array
->vals
[x
][y
] = value_dup (src
->v_array
.vals
[x
][y
]);
685 res
= (GnmValue
*)array
;
690 g_warning ("value_dup problem.");
691 res
= value_new_empty ();
693 value_set_fmt (res
, VALUE_FMT (src
));
698 value_compare_real (GnmValue
const *a
, GnmValue
const *b
,
699 gboolean case_sensitive
,
700 gboolean default_locale
);
708 * qsort style comparison function for ascending order
711 value_cmp (void const *ptr_a
, void const *ptr_b
)
713 GnmValue
const *a
= *(GnmValue
const **)ptr_a
;
714 GnmValue
const *b
= *(GnmValue
const **)ptr_b
;
715 switch (value_compare_real (a
, b
, TRUE
, TRUE
)) {
716 case IS_EQUAL
: return 0;
717 case IS_LESS
: return -1;
718 case IS_GREATER
: return 1;
722 return a
->v_any
.type
- b
->v_any
.type
;
730 * qsort style comparison function for descending order.
733 value_cmp_reverse (void const *ptr_a
, void const *ptr_b
)
735 return -value_cmp (ptr_a
, ptr_b
);
739 value_equal (GnmValue
const *a
, GnmValue
const *b
)
741 if (a
->v_any
.type
!= b
->v_any
.type
)
744 switch (a
->v_any
.type
) {
746 return a
->v_bool
.val
== b
->v_bool
.val
;
749 return go_string_equal (a
->v_str
.val
, b
->v_str
.val
);
752 return go_string_equal (a
->v_err
.mesg
, b
->v_err
.mesg
);
755 return a
->v_float
.val
== b
->v_float
.val
;
760 case VALUE_CELLRANGE
:
761 return gnm_cellref_equal (&a
->v_range
.cell
.a
, &b
->v_range
.cell
.a
) &&
762 gnm_cellref_equal (&a
->v_range
.cell
.b
, &b
->v_range
.cell
.b
);
765 if (a
->v_array
.x
== b
->v_array
.x
&& a
->v_array
.y
== b
->v_array
.y
) {
768 for (y
= 0; y
< a
->v_array
.y
; y
++)
769 for (x
= 0; x
< a
->v_array
.x
; x
++)
770 if (!value_equal (a
->v_array
.vals
[x
][y
],
771 b
->v_array
.vals
[x
][y
]))
777 #ifndef DEBUG_SWITCH_ENUM
779 g_assert_not_reached ();
786 value_hash (GnmValue
const *v
)
788 switch (v
->v_any
.type
) {
790 return v
->v_bool
.val
? 0x555aaaa : 0xaaa5555;
793 return go_string_hash (v
->v_str
.val
);
796 return go_string_hash (v
->v_err
.mesg
);
800 gnm_float mant
= gnm_frexp (gnm_abs (v
->v_float
.val
), &expt
);
801 guint h
= ((guint
)(0x80000000u
* mant
)) ^ expt
;
802 if (v
->v_float
.val
>= 0)
810 case VALUE_CELLRANGE
:
811 /* FIXME: take sheet into account? */
812 return (gnm_cellref_hash (&v
->v_range
.cell
.a
) * 3) ^
813 gnm_cellref_hash (&v
->v_range
.cell
.b
);
817 guint h
= (v
->v_array
.x
* 257) ^ (v
->v_array
.y
+ 42);
819 /* For speed, just walk the diagonal. */
820 for (i
= 0; i
< v
->v_array
.x
&& i
< v
->v_array
.y
; i
++) {
822 if (v
->v_array
.vals
[i
][i
])
823 h
^= value_hash (v
->v_array
.vals
[i
][i
]);
828 #ifndef DEBUG_SWITCH_ENUM
830 g_assert_not_reached ();
838 value_type_of (const GnmValue
*v
)
840 return v
->v_any
.type
;
845 value_get_as_bool (GnmValue
const *v
, gboolean
*err
)
853 switch (v
->v_any
.type
) {
858 return v
->v_bool
.val
;
861 int i
= value_parse_boolean (value_peek_string (v
), FALSE
);
871 return v
->v_float
.val
!= 0.0;
874 g_warning ("Unhandled value in value_get_as_bool.");
876 case VALUE_CELLRANGE
:
886 * use only if you are sure the value is ok
889 value_get_as_checked_bool (GnmValue
const *v
)
891 gboolean result
, err
;
893 result
= value_get_as_bool (v
, &err
);
895 g_return_val_if_fail (!err
, FALSE
);
901 * value_get_as_gstring:
904 * @conv: #GnmConventions
906 * A simple value formatter to convert @v into a string stored in @target
907 * according to @conv. See format_value_gstring for something more elaborate
908 * that handles formats too.
911 value_get_as_gstring (GnmValue
const *v
, GString
*target
,
912 GnmConventions
const *conv
)
917 switch (v
->v_any
.type
){
922 GnmStdError e
= value_error_classify (v
);
923 if (e
== GNM_ERROR_UNKNOWN
) {
924 g_string_append_c (target
, '#');
925 go_strescape (target
, v
->v_err
.mesg
->str
);
927 g_string_append (target
, value_error_name (e
, conv
->output
.translated
));
931 case VALUE_BOOLEAN
: {
932 gboolean b
= v
->v_bool
.val
;
933 g_string_append (target
,
934 conv
->output
.translated
935 ? go_locale_boolean_name (b
)
936 : (b
? "TRUE" : "FALSE"));
941 g_string_append (target
, v
->v_str
.val
->str
);
945 if (conv
->output
.decimal_digits
< 0)
946 go_dtoa (target
, "!" GNM_FORMAT_g
, v
->v_float
.val
);
948 g_string_append_printf (target
, "%.*" GNM_FORMAT_g
,
949 conv
->output
.decimal_digits
,
955 gunichar row_sep
, col_sep
;
958 if (conv
->array_row_sep
)
959 row_sep
= conv
->array_row_sep
;
961 row_sep
= go_locale_get_row_sep ();
962 if (conv
->array_col_sep
)
963 col_sep
= conv
->array_col_sep
;
965 col_sep
= go_locale_get_col_sep ();
967 g_string_append_c (target
, '{');
968 for (y
= 0; y
< v
->v_array
.y
; y
++){
970 g_string_append_unichar (target
, row_sep
);
972 for (x
= 0; x
< v
->v_array
.x
; x
++){
973 val
= v
->v_array
.vals
[x
][y
];
976 g_string_append_unichar (target
, col_sep
);
980 /* This is not supposed to happen, but
981 let's not crash anyway. */
982 g_string_append (target
, "?");
983 } else if (VALUE_IS_STRING (val
))
984 go_strescape (target
, val
->v_str
.val
->str
);
986 value_get_as_gstring (val
, target
, conv
);
989 g_string_append_c (target
, '}');
993 case VALUE_CELLRANGE
: {
995 /* Note: this makes only sense for absolute references or
996 * references relative to A1
999 range_init_value (&range
, v
);
1000 tmp
= global_range_name (v
->v_range
.cell
.a
.sheet
, &range
);
1001 g_string_append (target
, tmp
);
1010 g_assert_not_reached ();
1015 * value_get_as_string:
1018 * Simplistic value rendering
1020 * Returns: (transfer full): a string rendering of @v.
1023 value_get_as_string (GnmValue
const *v
)
1025 GString
*res
= g_string_sized_new (10);
1026 value_get_as_gstring (v
, res
, gnm_conventions_default
);
1027 return g_string_free (res
, FALSE
);
1031 * value_peek_string:
1034 * Returns: (transfer none): A string representation of the value. The
1035 * result will stay valid until either (a) the value is disposed of, or
1036 * (b) two further calls to this function are made.
1038 // NOTE: "(transfer none)" papers over an introspection bug
1040 value_peek_string (GnmValue
const *v
)
1042 g_return_val_if_fail (v
, "");
1044 if (VALUE_IS_STRING (v
))
1045 return v
->v_str
.val
->str
;
1046 else if (VALUE_IS_ERROR (v
))
1047 return v
->v_err
.mesg
->str
;
1049 static char *cache
[2] = { NULL
, NULL
};
1050 static int next
= 0;
1053 g_free (cache
[next
]);
1054 s
= cache
[next
] = value_get_as_string (v
);
1055 next
= (next
+ 1) % G_N_ELEMENTS (cache
);
1064 * Returns: (transfer full): A string representation of the value suitable
1065 * for use in a Python __repr__ function.
1068 value_stringify (GnmValue
const *v
)
1070 GString
*res
= g_string_sized_new (30);
1072 g_string_append_c (res
, '{');
1074 switch (v
->v_any
.type
) {
1076 g_string_append (res
, "EMPTY,");
1077 g_string_append (res
, "None");
1081 g_string_append (res
, "STRING,");
1082 go_strescape (res
, value_peek_string (v
));
1085 case VALUE_CELLRANGE
:
1086 g_string_append (res
, "CELLRANGE,");
1087 g_string_append (res
, value_peek_string (v
));
1091 g_string_append (res
, "ARRAY,");
1092 g_string_append (res
, value_peek_string (v
));
1096 g_string_append (res
, "FLOAT,");
1097 g_string_append (res
, value_peek_string (v
));
1101 g_string_append (res
, "BOOLEAN,");
1102 g_string_append_c (res
, v
->v_bool
.val
? '1' : '0');
1106 g_string_append (res
, "ERROR,");
1107 go_strescape (res
, value_peek_string (v
));
1111 g_string_append (res
, "?,?");
1115 if (VALUE_FMT (v
) != NULL
) {
1116 g_string_append_c (res
, ',');
1117 go_strescape (res
, go_format_as_XL (VALUE_FMT (v
)));
1120 g_string_append_c (res
, '}');
1122 return g_string_free (res
, FALSE
);
1129 * @v: (nullable): a #GnmValue
1131 * Returns: @v interpreted as an integer.
1134 value_get_as_int (GnmValue
const *v
)
1138 switch (v
->v_any
.type
) {
1143 return atoi (v
->v_str
.val
->str
);
1145 case VALUE_CELLRANGE
:
1146 g_warning ("Getting range as a int: what to do?");
1153 return (int) gnm_fake_trunc (v
->v_float
.val
);
1156 return v
->v_bool
.val
? 1 : 0;
1162 g_warning ("value_get_as_int unknown type 0x%x (%d).", v
->v_any
.type
, v
->v_any
.type
);
1169 * value_get_as_float:
1170 * @v: (nullable): a #GnmValue
1172 * Returns: @v interpreted as a floating point value.
1175 value_get_as_float (GnmValue
const *v
)
1180 switch (v
->v_any
.type
) {
1185 return gnm_strto (v
->v_str
.val
->str
, NULL
);
1187 case VALUE_CELLRANGE
:
1188 g_warning ("Getting range as a double: what to do?");
1195 return (gnm_float
) v
->v_float
.val
;
1198 return v
->v_bool
.val
? 1. : 0.;
1204 g_warning ("value_get_as_float type error.");
1211 value_is_zero (GnmValue
const *v
)
1213 return gnm_abs (value_get_as_float (v
)) < 64 * GNM_EPSILON
;
1217 value_get_rangeref (GnmValue
const *v
)
1219 g_return_val_if_fail (VALUE_IS_CELLRANGE (v
), NULL
);
1220 return &v
->v_range
.cell
;
1225 * value_coerce_to_number:
1229 * If the value can be used as a number return that number
1230 * otherwise free it at return an appropriate error
1233 value_coerce_to_number (GnmValue
*v
, gboolean
*valid
, GnmEvalPos
const *ep
)
1235 g_return_val_if_fail (v
!= NULL
, NULL
);
1238 if (VALUE_IS_STRING (v
)) {
1240 format_match_number (value_peek_string (v
), NULL
,
1241 sheet_date_conv (ep
->sheet
));
1244 return value_new_error_VALUE (ep
);
1246 } else if (VALUE_IS_ERROR (v
))
1249 if (!VALUE_IS_NUMBER (v
)) {
1251 return value_new_error_VALUE (ep
);
1259 value_array_set (GnmValue
*array
, int col
, int row
, GnmValue
*v
)
1261 g_return_if_fail (v
);
1262 g_return_if_fail (VALUE_IS_ARRAY (array
));
1263 g_return_if_fail (col
>=0);
1264 g_return_if_fail (row
>=0);
1265 g_return_if_fail (array
->v_array
.y
> row
);
1266 g_return_if_fail (array
->v_array
.x
> col
);
1268 value_release (array
->v_array
.vals
[col
][row
]);
1269 array
->v_array
.vals
[col
][row
] = v
;
1273 compare_bool_bool (GnmValue
const *va
, GnmValue
const *vb
)
1275 gboolean err
; /* Ignored */
1276 gboolean
const a
= value_get_as_bool (va
, &err
);
1277 gboolean
const b
= value_get_as_bool (vb
, &err
);
1279 return b
? IS_EQUAL
: IS_GREATER
;
1280 return b
? IS_LESS
: IS_EQUAL
;
1284 compare_float_float (GnmValue
const *va
, GnmValue
const *vb
)
1286 gnm_float
const a
= value_get_as_float (va
);
1287 gnm_float
const b
= value_get_as_float (vb
);
1297 compare_error_error (GnmValue
const *va
, GnmValue
const *vb
)
1299 GnmStdError ea
= value_error_classify (va
);
1300 GnmStdError eb
= value_error_classify (vb
);
1304 return ea
< eb
? IS_LESS
: IS_GREATER
;
1306 if (ea
!= GNM_ERROR_UNKNOWN
)
1309 /* Two unknown errors. Just compare strings. */
1310 i
= strcmp (value_peek_string (va
), value_peek_string (vb
));
1311 return (i
> 0 ? IS_GREATER
: (i
< 0 ? IS_LESS
: IS_EQUAL
));
1322 * Returns a non-negative difference between 2 values
1325 value_diff (GnmValue
const *a
, GnmValue
const *b
)
1327 GnmValueType ta
, tb
;
1329 /* Handle trivial (including empty/empty) and double NULL */
1333 ta
= VALUE_IS_EMPTY (a
) ? VALUE_EMPTY
: a
->v_any
.type
;
1334 tb
= VALUE_IS_EMPTY (b
) ? VALUE_EMPTY
: b
->v_any
.type
;
1336 /* string > empty */
1337 if (ta
== VALUE_STRING
) {
1339 /* Strings are > (empty, or number) */
1341 if (*a
->v_str
.val
->str
== '\0')
1345 /* If both are strings compare as string */
1347 if (go_string_equal (a
->v_str
.val
, b
->v_str
.val
))
1350 case VALUE_FLOAT
: case VALUE_BOOLEAN
:
1355 } else if (tb
== VALUE_STRING
) {
1357 /* (empty, or number) < String */
1359 if (*b
->v_str
.val
->str
== '\0')
1362 case VALUE_FLOAT
: case VALUE_BOOLEAN
:
1368 /* Booleans > all numbers (Why did excel do this ?? ) */
1369 if (ta
== VALUE_BOOLEAN
&& tb
== VALUE_FLOAT
)
1371 if (tb
== VALUE_BOOLEAN
&& ta
== VALUE_FLOAT
)
1374 switch ((ta
> tb
) ? ta
: tb
) {
1375 case VALUE_EMPTY
: /* Empty Empty compare */
1379 return (compare_bool_bool (a
, b
) == IS_EQUAL
) ? 0. : DBL_MAX
;
1382 gnm_float
const da
= value_get_as_float (a
);
1383 gnm_float
const db
= value_get_as_float (b
);
1384 return gnm_abs (da
- db
);
1387 return TYPE_MISMATCH
;
1392 gnm_string_cmp (gconstpointer gstr_a
, gconstpointer gstr_b
)
1394 return (gstr_a
== gstr_b
)
1396 : g_utf8_collate (((GOString
const *)gstr_a
)->str
,
1397 ((GOString
const *)gstr_b
)->str
);
1401 gnm_string_cmp_ignorecase (gconstpointer gstr_a
, gconstpointer gstr_b
)
1407 if (gstr_a
== gstr_b
)
1410 a
= g_utf8_casefold (((GOString
const *)gstr_a
)->str
, -1);
1411 b
= g_utf8_casefold (((GOString
const *)gstr_b
)->str
, -1);
1413 res
= g_utf8_collate (a
, b
);
1422 /* This depends on the actual values of the enums. */
1423 #define PAIR(ta_,tb_) ((ta_) + (((tb_) >> 3) - 1))
1424 #define CPAIR(ta_,tb_) (1 ? PAIR((ta_),(tb_)) : sizeof (struct { int sanity_check[((ta_) >= (tb_)) * 2 - 1]; } ))
1431 * @case_sensitive: are string comparisons case sensitive.
1436 value_compare_real (GnmValue
const *a
, GnmValue
const *b
,
1437 gboolean case_sensitive
,
1438 gboolean default_locale
)
1440 GnmValueType ta
, tb
;
1444 /* Handle trivial and double NULL case */
1448 ta
= VALUE_IS_EMPTY (a
) ? VALUE_EMPTY
: a
->v_any
.type
;
1449 tb
= VALUE_IS_EMPTY (b
) ? VALUE_EMPTY
: b
->v_any
.type
;
1453 GnmValueType t
= ta
;
1454 GnmValue
const *v
= a
;
1461 switch (PAIR (ta
,tb
)) {
1462 case CPAIR (VALUE_EMPTY
,VALUE_EMPTY
):
1463 /* In most cases this is handled by the trivial case. */
1464 /* We can get here if one of a and b is NULL and the */
1465 /* is not but contains an empty value. */
1468 /* ---------------------------------------- */
1470 case CPAIR (VALUE_BOOLEAN
,VALUE_EMPTY
): /* Blank is FALSE */
1471 case CPAIR (VALUE_BOOLEAN
,VALUE_BOOLEAN
):
1472 res
= compare_bool_bool (a
, b
);
1475 /* ---------------------------------------- */
1477 case CPAIR (VALUE_FLOAT
,VALUE_BOOLEAN
):
1478 /* Number < boolean (Why did excel do this ?? ) */
1481 case CPAIR (VALUE_FLOAT
,VALUE_EMPTY
): /* Blank is 0 */
1482 case CPAIR (VALUE_FLOAT
,VALUE_FLOAT
):
1483 res
= compare_float_float (a
, b
);
1486 /* ---------------------------------------- */
1488 case CPAIR (VALUE_ERROR
,VALUE_EMPTY
):
1489 case CPAIR (VALUE_ERROR
,VALUE_BOOLEAN
):
1490 case CPAIR (VALUE_ERROR
,VALUE_FLOAT
):
1491 /* Error > others */
1495 case CPAIR (VALUE_ERROR
,VALUE_ERROR
):
1496 res
= compare_error_error (a
, b
);
1499 /* ---------------------------------------- */
1501 case CPAIR (VALUE_STRING
,VALUE_EMPTY
): /* Blank is empty string */
1502 /* String > empty, except empty string */
1503 res
= a
->v_str
.val
->str
[0] == '\0' ? IS_EQUAL
: IS_GREATER
;
1506 case CPAIR (VALUE_STRING
,VALUE_BOOLEAN
):
1507 /* String < boolean */
1511 case CPAIR (VALUE_STRING
,VALUE_FLOAT
):
1512 /* String > number */
1516 case CPAIR (VALUE_STRING
,VALUE_ERROR
):
1517 /* String < error */
1521 case CPAIR (VALUE_STRING
,VALUE_STRING
): {
1522 GOString
const *sa
= a
->v_str
.val
;
1523 GOString
const *sb
= b
->v_str
.val
;
1524 int i
= (default_locale
1526 ? go_string_cmp (sa
, sb
)
1527 : go_string_cmp_ignorecase (sa
, sb
))
1529 ? gnm_string_cmp (sa
, sb
)
1530 : gnm_string_cmp_ignorecase (sa
, sb
)));
1531 res
= (i
> 0 ? IS_GREATER
: (i
< 0 ? IS_LESS
: IS_EQUAL
));
1535 /* ---------------------------------------- */
1538 res
= TYPE_MISMATCH
;
1544 else if (res
== IS_GREATER
)
1554 value_compare (GnmValue
const *a
, GnmValue
const *b
, gboolean case_sensitive
)
1556 return value_compare_real (a
, b
, case_sensitive
, TRUE
);
1560 value_compare_no_cache (GnmValue
const *a
, GnmValue
const *b
,
1561 gboolean case_sensitive
)
1563 return value_compare_real (a
, b
, case_sensitive
, FALSE
);
1569 * @fmt: (nullable): #GOFormat
1574 value_set_fmt (GnmValue
*v
, GOFormat
const *fmt
)
1576 if (fmt
== VALUE_FMT (v
))
1578 g_return_if_fail (!VALUE_IS_EMPTY (v
) && !VALUE_IS_BOOLEAN (v
));
1580 go_format_ref (fmt
);
1581 if (VALUE_FMT (v
) != NULL
)
1582 go_format_unref (VALUE_FMT (v
));
1586 /****************************************************************************/
1589 gnm_value_get_type (void)
1594 t
= g_boxed_type_register_static ("GnmValue",
1595 (GBoxedCopyFunc
)value_dup
,
1596 (GBoxedFreeFunc
)value_release
);
1599 /****************************************************************************/
1601 GnmValueErr
const value_terminate_err
= { VALUE_ERROR
, NULL
, NULL
};
1602 static GnmValueFloat
const the_value_zero
= { VALUE_FLOAT
, NULL
, 0 };
1603 GnmValue
const *value_zero
= (GnmValue
const *)&the_value_zero
;
1606 * value_init: (skip)
1613 for (i
= 0; i
< G_N_ELEMENTS (standard_errors
); i
++) {
1614 standard_errors
[i
].locale_name
= _(standard_errors
[i
].C_name
);
1615 standard_errors
[i
].locale_name_str
=
1616 go_string_new (standard_errors
[i
].locale_name
);
1621 go_mem_chunk_new ("value float pool",
1622 sizeof (GnmValueFloat
),
1626 go_mem_chunk_new ("value error pool",
1627 sizeof (GnmValueErr
),
1631 go_mem_chunk_new ("value string pool",
1632 sizeof (GnmValueStr
),
1636 go_mem_chunk_new ("value range pool",
1637 sizeof (GnmValueRange
),
1641 go_mem_chunk_new ("value array pool",
1642 sizeof (GnmValueArray
),
1648 * value_shutdown: (skip)
1651 value_shutdown (void)
1655 for (i
= 0; i
< G_N_ELEMENTS (standard_errors
); i
++) {
1656 go_string_unref (standard_errors
[i
].locale_name_str
);
1657 standard_errors
[i
].locale_name_str
= NULL
;
1661 go_mem_chunk_destroy (value_float_pool
, FALSE
);
1662 value_float_pool
= NULL
;
1664 go_mem_chunk_destroy (value_error_pool
, FALSE
);
1665 value_error_pool
= NULL
;
1667 go_mem_chunk_destroy (value_string_pool
, FALSE
);
1668 value_string_pool
= NULL
;
1670 go_mem_chunk_destroy (value_range_pool
, FALSE
);
1671 value_range_pool
= NULL
;
1673 go_mem_chunk_destroy (value_array_pool
, FALSE
);
1674 value_array_pool
= NULL
;
1676 if (value_allocations
)
1677 g_printerr ("Leaking %d values.\n", value_allocations
);
1681 /****************************************************************************/