1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * value.c: Utilies for handling, creating, removing values.
6 * Miguel de Icaza (miguel@gnu.org).
7 * Michael Meeks (mmeeks@gnu.org)
8 * Jody Goldberg (jgolderg@home.com)
9 * Copyright (C) 2000-2009 Morten Welinder (terra@gnome.org)
12 #include <gnumeric-config.h>
13 #include <glib/gi18n-lib.h>
17 #include "parse-util.h"
19 #include "gnm-format.h"
28 #include <number-match.h>
29 #include <goffice/goffice.h>
36 #ifndef USE_VALUE_POOLS
37 #define USE_VALUE_POOLS 0
41 static GOMemChunk
*value_float_pool
;
42 static GOMemChunk
*value_error_pool
;
43 static GOMemChunk
*value_string_pool
;
44 static GOMemChunk
*value_range_pool
;
45 static GOMemChunk
*value_array_pool
;
46 #define CHUNK_ALLOC(T,p) ((T*)go_mem_chunk_alloc (p))
47 #define CHUNK_FREE(p,v) go_mem_chunk_free ((p), (v))
49 static int value_allocations
= 0;
50 #define CHUNK_ALLOC(T,c) (value_allocations++, g_slice_new (T))
51 #define CHUNK_FREE(p,v) (value_allocations--, g_slice_free1 (sizeof(*v),(v)))
57 char const *locale_name
;
58 GOString
*locale_name_str
;
59 } standard_errors
[] = {
60 { N_("#NULL!"), NULL
, NULL
},
61 { N_("#DIV/0!"), NULL
, NULL
},
62 { N_("#VALUE!"), NULL
, NULL
},
63 { N_("#REF!"), NULL
, NULL
},
64 { N_("#NAME?"), NULL
, NULL
},
65 { N_("#NUM!"), NULL
, NULL
},
66 { N_("#N/A"), NULL
, NULL
},
67 { N_("#UNKNOWN!"), NULL
, NULL
}
71 value_new_empty (void)
73 /* This is a constant. No need to allocate any memory. */
74 static const GnmValueAny v
= { VALUE_EMPTY
, NULL
};
75 return (GnmValue
*)&v
;
79 value_new_bool (gboolean b
)
81 /* These are constant. No need to allocate any memory. */
82 static const GnmValueBool vf
= { VALUE_BOOLEAN
, NULL
, FALSE
};
83 static const GnmValueBool vt
= { VALUE_BOOLEAN
, NULL
, TRUE
};
84 return (GnmValue
*) (b
? &vt
: &vf
);
90 return value_new_float (i
);
94 value_new_float (gnm_float f
)
97 GnmValueFloat
*v
= CHUNK_ALLOC (GnmValueFloat
, value_float_pool
);
98 *((GnmValueType
*)&(v
->type
)) = VALUE_FLOAT
;
101 return (GnmValue
*)v
;
103 /* FIXME: bogus ep sent here. What to do? */
104 return value_new_error_NUM (NULL
);
109 value_new_error (G_GNUC_UNUSED GnmEvalPos
const *ep
, char const *mesg
)
111 GnmValueErr
*v
= CHUNK_ALLOC (GnmValueErr
, value_error_pool
);
112 *((GnmValueType
*)&(v
->type
)) = VALUE_ERROR
;
114 v
->mesg
= go_string_new (mesg
);
115 return (GnmValue
*)v
;
119 value_new_error_str (G_GNUC_UNUSED GnmEvalPos
const *ep
, GOString
*mesg
)
121 GnmValueErr
*v
= CHUNK_ALLOC (GnmValueErr
, value_error_pool
);
122 *((GnmValueType
*)&(v
->type
)) = VALUE_ERROR
;
124 v
->mesg
= go_string_ref (mesg
);
125 return (GnmValue
*)v
;
129 value_new_error_std (GnmEvalPos
const *pos
, GnmStdError err
)
131 size_t i
= (size_t)err
;
132 g_return_val_if_fail (i
< G_N_ELEMENTS (standard_errors
), NULL
);
134 return value_new_error_str (pos
, standard_errors
[i
].locale_name_str
);
139 value_new_error_NULL (GnmEvalPos
const *pos
)
141 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_NULL
].locale_name_str
);
145 value_new_error_DIV0 (GnmEvalPos
const *pos
)
147 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_DIV0
].locale_name_str
);
151 value_new_error_VALUE (GnmEvalPos
const *pos
)
153 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_VALUE
].locale_name_str
);
157 value_new_error_REF (GnmEvalPos
const *pos
)
159 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_REF
].locale_name_str
);
163 value_new_error_NAME (GnmEvalPos
const *pos
)
165 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_NAME
].locale_name_str
);
169 value_new_error_NUM (GnmEvalPos
const *pos
)
171 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_NUM
].locale_name_str
);
175 value_new_error_NA (GnmEvalPos
const *pos
)
177 return value_new_error_str (pos
, standard_errors
[GNM_ERROR_NA
].locale_name_str
);
181 value_error_name (GnmStdError err
, gboolean translated
)
183 size_t i
= (size_t)err
;
184 g_return_val_if_fail (i
< G_N_ELEMENTS (standard_errors
), NULL
);
187 return standard_errors
[i
].locale_name
;
189 return standard_errors
[i
].C_name
;
193 * value_error_set_pos:
197 * Change the position of a ValueError.
200 value_error_set_pos (GnmValueErr
*err
, G_GNUC_UNUSED GnmEvalPos
const *pos
)
202 g_return_val_if_fail (err
!= NULL
, NULL
);
203 g_return_val_if_fail (VALUE_IS_ERROR ((GnmValue
*)err
), NULL
);
205 /* err->src = *pos; */
206 return (GnmValue
*)err
;
210 value_error_classify (GnmValue
const *v
)
214 g_return_val_if_fail (v
!= NULL
, GNM_ERROR_UNKNOWN
);
216 if (!VALUE_IS_ERROR (v
))
217 return GNM_ERROR_UNKNOWN
;
219 for (i
= 0; i
< G_N_ELEMENTS (standard_errors
); i
++)
220 if (standard_errors
[i
].locale_name_str
== v
->v_err
.mesg
)
221 return (GnmStdError
)i
;
223 return GNM_ERROR_UNKNOWN
;
228 * value_new_string_str:
229 * @str: (transfer full): string to use for value
231 * Returns: (transfer full): a new value object.
234 value_new_string_str (GOString
*str
)
238 g_return_val_if_fail (str
!= NULL
, NULL
);
240 v
= CHUNK_ALLOC (GnmValueStr
, value_string_pool
);
241 *((GnmValueType
*)&(v
->type
)) = VALUE_STRING
;
244 return (GnmValue
*)v
;
249 * @str: string to use for value
251 * Returns: (transfer full): a new value object.
254 value_new_string (char const *str
)
256 return value_new_string_str (go_string_new (str
));
260 * value_new_string_nocopy:
261 * @str: (transfer full): string to use for value
263 * Returns: (transfer full): a new value object.
266 value_new_string_nocopy (char *str
)
268 return value_new_string_str (go_string_new_nocopy (str
));
272 value_new_cellrange_unsafe (GnmCellRef
const *a
, GnmCellRef
const *b
)
274 GnmValueRange
*v
= CHUNK_ALLOC (GnmValueRange
, value_range_pool
);
275 *((GnmValueType
*)&(v
->type
)) = VALUE_CELLRANGE
;
279 return (GnmValue
*)v
;
283 * value_new_cellrange:
285 * Create a new range reference.
287 * Attempt to do a sanity check for inverted ranges.
288 * NOTE : This is no longer necessary and will be removed.
289 * mixed mode references create the possibility of inversion.
290 * users of these values need to use the utility routines to
291 * evaluate the ranges in their context and normalize then.
294 value_new_cellrange (GnmCellRef
const *a
, GnmCellRef
const *b
,
295 int eval_col
, int eval_row
)
297 GnmValueRange
*v
= CHUNK_ALLOC (GnmValueRange
, value_range_pool
);
300 *((GnmValueType
*)&(v
->type
)) = VALUE_CELLRANGE
;
305 /* Sanity checking to avoid inverted ranges */
307 if (a
->col_relative
!= b
->col_relative
) {
308 /* Make a tmp copy of a in the same mode as b */
315 v
->cell
.a
.col
= b
->col
;
316 v
->cell
.a
.col_relative
= b
->col_relative
;
317 v
->cell
.b
.col
= a
->col
;
318 v
->cell
.b
.col_relative
= a
->col_relative
;
322 if (a
->row_relative
!= b
->row_relative
) {
323 /* Make a tmp copy of a in the same mode as b */
330 v
->cell
.a
.row
= b
->row
;
331 v
->cell
.a
.row_relative
= b
->row_relative
;
332 v
->cell
.b
.row
= a
->row
;
333 v
->cell
.b
.row_relative
= a
->row_relative
;
336 return (GnmValue
*)v
;
340 value_new_cellrange_r (Sheet
*sheet
, GnmRange
const *r
)
342 GnmValueRange
*v
= CHUNK_ALLOC (GnmValueRange
, value_range_pool
);
345 *((GnmValueType
*)&(v
->type
)) = VALUE_CELLRANGE
;
352 a
->col
= r
->start
.col
;
353 a
->row
= r
->start
.row
;
356 a
->col_relative
= b
->col_relative
= FALSE
;
357 a
->row_relative
= b
->row_relative
= FALSE
;
359 return (GnmValue
*)v
;
363 * value_new_cellrange_str:
364 * @sheet: the sheet where the cell range is evaluated. This really only needed if
365 * the range given does not include a sheet specification.
366 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
368 * Parse @str using the convention associated with @sheet.
369 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
370 * succesfully parsed or NULL on failure.
373 value_new_cellrange_str (Sheet
*sheet
, char const *str
)
376 GnmExprParseFlags flags
= GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS
|
377 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES
;
379 g_return_val_if_fail (IS_SHEET (sheet
), NULL
);
380 g_return_val_if_fail (str
!= NULL
, NULL
);
382 parse_pos_init_sheet (&pp
, sheet
);
383 return value_new_cellrange_parsepos_str (&pp
, str
, flags
);
387 * value_new_cellrange_parsepos_str:
388 * @pp: if a relative range is specified, then it will be interpreted relative
389 * to this position (affects only A1-style relative references).
390 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
392 * Parse @str using the convention associated with @sheet.
393 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
394 * succesfully parsed or NULL on failure.
397 value_new_cellrange_parsepos_str (GnmParsePos
const *pp
, char const *str
,
398 GnmExprParseFlags flags
)
400 GnmExprTop
const *texpr
;
401 GnmConventions
const *convs
= NULL
;
403 g_return_val_if_fail (pp
!= NULL
, NULL
);
404 g_return_val_if_fail (str
!= NULL
, NULL
);
407 convs
= pp
->sheet
->convs
;
409 texpr
= gnm_expr_parse_str (str
, pp
, flags
, convs
, NULL
);
412 GnmValue
*value
= gnm_expr_top_get_range (texpr
);
413 gnm_expr_top_unref (texpr
);
421 value_new_array_non_init (guint cols
, guint rows
)
423 GnmValueArray
*v
= CHUNK_ALLOC (GnmValueArray
, value_array_pool
);
424 *((GnmValueType
*)&(v
->type
)) = VALUE_ARRAY
;
428 v
->vals
= g_new (GnmValue
**, cols
);
429 return (GnmValue
*)v
;
433 value_new_array (guint cols
, guint rows
)
436 GnmValueArray
*v
= (GnmValueArray
*)value_new_array_non_init (cols
, rows
);
438 for (x
= 0; x
< cols
; x
++) {
439 v
->vals
[x
] = g_new (GnmValue
*, rows
);
440 for (y
= 0; y
< rows
; y
++)
441 v
->vals
[x
][y
] = value_new_int (0);
443 return (GnmValue
*)v
;
447 value_new_array_empty (guint cols
, guint rows
)
450 GnmValueArray
*v
= (GnmValueArray
*)value_new_array_non_init (cols
, rows
);
452 for (x
= 0; x
< cols
; x
++) {
453 v
->vals
[x
] = g_new (GnmValue
*, rows
);
454 for (y
= 0; y
< rows
; y
++)
455 v
->vals
[x
][y
] = value_new_empty ();
457 return (GnmValue
*)v
;
461 * Returns TRUE, FALSE, or -1.
464 value_parse_boolean (char const *str
, gboolean translated
)
467 /* FIXME: ascii??? */
468 if (0 == g_ascii_strcasecmp (str
, go_locale_boolean_name (TRUE
)))
470 else if (0 == g_ascii_strcasecmp (str
, go_locale_boolean_name (FALSE
)))
475 if (0 == g_ascii_strcasecmp (str
, "TRUE"))
477 else if (0 == g_ascii_strcasecmp (str
, "FALSE"))
486 value_new_from_string (GnmValueType t
, char const *str
, GOFormat
*sf
,
489 GnmValue
*res
= NULL
;
492 * We need the following cast to avoid a warning from gcc over
493 * VALUE_INTEGER (which is not in GnmValueType).
497 res
= value_new_empty ();
500 case VALUE_BOOLEAN
: {
501 int i
= value_parse_boolean (str
, translated
);
503 res
= value_new_bool ((gboolean
)i
);
512 d
= gnm_strto (str
, &end
);
513 if (d
!= 0 && d
> -GNM_MIN
&& d
< GNM_MIN
)
516 if (str
!= end
&& *end
== '\0' && errno
!= ERANGE
)
517 res
= value_new_float (d
);
523 * Tricky. We are currently storing errors in translated
524 * format, so we might have to undo that.
528 for (i
= 0; i
< G_N_ELEMENTS (standard_errors
); i
++)
529 if (strcmp (standard_errors
[i
].C_name
, str
) == 0) {
530 res
= value_new_error_std (NULL
, (GnmStdError
)i
);
535 res
= value_new_error (NULL
, str
);
539 res
= value_new_string (str
);
543 case VALUE_CELLRANGE
:
545 /* This happen with corrupted files. */
550 value_set_fmt (res
, sf
);
556 * @v: (transfer full) (allow-none): value to dispose of
561 value_release (GnmValue
*value
)
566 if (VALUE_FMT (value
) != NULL
)
567 go_format_unref (VALUE_FMT (value
));
569 switch (value
->v_any
.type
) {
572 /* We did not allocate anything, there is nothing to free */
576 CHUNK_FREE (value_float_pool
, &value
->v_float
);
580 /* Do not release VALUE_TERMINATE, it is a magic number */
581 if (value
== VALUE_TERMINATE
) {
582 g_warning ("Someone freed VALUE_TERMINATE -- shame on them.");
586 go_string_unref (value
->v_err
.mesg
);
587 CHUNK_FREE (value_error_pool
, &value
->v_err
);
591 go_string_unref (value
->v_str
.val
);
592 CHUNK_FREE (value_string_pool
, &value
->v_str
);
596 GnmValueArray
*v
= &value
->v_array
;
599 for (x
= 0; x
< v
->x
; x
++) {
600 for (y
= 0; y
< v
->y
; y
++)
601 value_release (v
->vals
[x
][y
]);
606 CHUNK_FREE (value_array_pool
, v
);
610 case VALUE_CELLRANGE
:
611 CHUNK_FREE (value_range_pool
, &value
->v_range
);
616 * If we don't recognize the type this is probably garbage.
617 * Do not free it to avoid heap corruption
619 g_warning ("value_release problem.");
622 g_assert_not_reached ();
629 * Returns a copy of @v. @v == NULL will return NULL
632 value_dup (GnmValue
const *src
)
639 switch (src
->v_any
.type
){
641 res
= value_new_empty ();
645 res
= value_new_bool (src
->v_bool
.val
);
649 res
= value_new_float (src
->v_float
.val
);
653 res
= value_new_error_str (NULL
, /* &src->v_err.src, */
658 go_string_ref (src
->v_str
.val
);
659 res
= value_new_string_str (src
->v_str
.val
);
662 case VALUE_CELLRANGE
:
663 res
= value_new_cellrange_unsafe (&src
->v_range
.cell
.a
,
664 &src
->v_range
.cell
.b
);
669 GnmValueArray
*array
= (GnmValueArray
*)value_new_array_non_init (
670 src
->v_array
.x
, src
->v_array
.y
);
672 for (x
= 0; x
< array
->x
; x
++) {
673 array
->vals
[x
] = g_new (GnmValue
*, array
->y
);
674 for (y
= 0; y
< array
->y
; y
++)
675 array
->vals
[x
][y
] = value_dup (src
->v_array
.vals
[x
][y
]);
677 res
= (GnmValue
*)array
;
682 g_warning ("value_dup problem.");
683 res
= value_new_empty ();
685 value_set_fmt (res
, VALUE_FMT (src
));
690 value_compare_real (GnmValue
const *a
, GnmValue
const *b
,
691 gboolean case_sensitive
,
692 gboolean default_locale
);
700 * qsort style comparison function for ascending order
703 value_cmp (void const *ptr_a
, void const *ptr_b
)
705 GnmValue
const *a
= *(GnmValue
const **)ptr_a
;
706 GnmValue
const *b
= *(GnmValue
const **)ptr_b
;
707 switch (value_compare_real (a
, b
, TRUE
, TRUE
)) {
708 case IS_EQUAL
: return 0;
709 case IS_LESS
: return -1;
710 case IS_GREATER
: return 1;
714 return a
->v_any
.type
- b
->v_any
.type
;
722 * qsort style comparison function for descending order.
725 value_cmp_reverse (void const *ptr_a
, void const *ptr_b
)
727 return -value_cmp (ptr_a
, ptr_b
);
731 value_equal (GnmValue
const *a
, GnmValue
const *b
)
733 if (a
->v_any
.type
!= b
->v_any
.type
)
736 switch (a
->v_any
.type
) {
738 return a
->v_bool
.val
== b
->v_bool
.val
;
741 return go_string_equal (a
->v_str
.val
, b
->v_str
.val
);
744 return go_string_equal (a
->v_err
.mesg
, b
->v_err
.mesg
);
747 return a
->v_float
.val
== b
->v_float
.val
;
752 case VALUE_CELLRANGE
:
753 return gnm_cellref_equal (&a
->v_range
.cell
.a
, &b
->v_range
.cell
.a
) &&
754 gnm_cellref_equal (&a
->v_range
.cell
.b
, &b
->v_range
.cell
.b
);
757 if (a
->v_array
.x
== b
->v_array
.x
&& a
->v_array
.y
== b
->v_array
.y
) {
760 for (y
= 0; y
< a
->v_array
.y
; y
++)
761 for (x
= 0; x
< a
->v_array
.x
; x
++)
762 if (!value_equal (a
->v_array
.vals
[x
][y
],
763 b
->v_array
.vals
[x
][y
]))
769 #ifndef DEBUG_SWITCH_ENUM
771 g_assert_not_reached ();
778 value_hash (GnmValue
const *v
)
780 switch (v
->v_any
.type
) {
782 return v
->v_bool
.val
? 0x555aaaa : 0xaaa5555;
785 return go_string_hash (v
->v_str
.val
);
788 return go_string_hash (v
->v_err
.mesg
);
792 gnm_float mant
= gnm_frexp (gnm_abs (v
->v_float
.val
), &expt
);
793 guint h
= ((guint
)(0x80000000u
* mant
)) ^ expt
;
794 if (v
->v_float
.val
>= 0)
802 case VALUE_CELLRANGE
:
803 /* FIXME: take sheet into account? */
804 return (gnm_cellref_hash (&v
->v_range
.cell
.a
) * 3) ^
805 gnm_cellref_hash (&v
->v_range
.cell
.b
);
809 guint h
= (v
->v_array
.x
* 257) ^ (v
->v_array
.y
+ 42);
811 /* For speed, just walk the diagonal. */
812 for (i
= 0; i
< v
->v_array
.x
&& i
< v
->v_array
.y
; i
++) {
814 if (v
->v_array
.vals
[i
][i
])
815 h
^= value_hash (v
->v_array
.vals
[i
][i
]);
820 #ifndef DEBUG_SWITCH_ENUM
822 g_assert_not_reached ();
830 value_get_as_bool (GnmValue
const *v
, gboolean
*err
)
838 switch (v
->v_any
.type
) {
843 return v
->v_bool
.val
;
846 int i
= value_parse_boolean (value_peek_string (v
), FALSE
);
856 return v
->v_float
.val
!= 0.0;
859 g_warning ("Unhandled value in value_get_as_bool.");
861 case VALUE_CELLRANGE
:
871 * use only if you are sure the value is ok
874 value_get_as_checked_bool (GnmValue
const *v
)
876 gboolean result
, err
;
878 result
= value_get_as_bool (v
, &err
);
880 g_return_val_if_fail (!err
, FALSE
);
886 * value_get_as_gstring:
889 * @conv: #GnmConventions
891 * A simple value formatter to convert @v into a string stored in @target
892 * according to @conv. See format_value_gstring for something more elaborate
893 * that handles formats too.
896 value_get_as_gstring (GnmValue
const *v
, GString
*target
,
897 GnmConventions
const *conv
)
902 switch (v
->v_any
.type
){
907 GnmStdError e
= value_error_classify (v
);
908 if (e
== GNM_ERROR_UNKNOWN
) {
909 g_string_append_c (target
, '#');
910 go_strescape (target
, v
->v_err
.mesg
->str
);
912 g_string_append (target
, value_error_name (e
, conv
->output
.translated
));
916 case VALUE_BOOLEAN
: {
917 gboolean b
= v
->v_bool
.val
;
918 g_string_append (target
,
919 conv
->output
.translated
920 ? go_locale_boolean_name (b
)
921 : (b
? "TRUE" : "FALSE"));
926 g_string_append (target
, v
->v_str
.val
->str
);
930 if (conv
->output
.decimal_digits
< 0)
931 go_dtoa (target
, "!" GNM_FORMAT_g
, v
->v_float
.val
);
933 g_string_append_printf (target
, "%.*" GNM_FORMAT_g
,
934 conv
->output
.decimal_digits
,
940 gunichar row_sep
, col_sep
;
943 if (conv
->array_row_sep
)
944 row_sep
= conv
->array_row_sep
;
946 row_sep
= go_locale_get_row_sep ();
947 if (conv
->array_col_sep
)
948 col_sep
= conv
->array_col_sep
;
950 col_sep
= go_locale_get_col_sep ();
952 g_string_append_c (target
, '{');
953 for (y
= 0; y
< v
->v_array
.y
; y
++){
955 g_string_append_unichar (target
, row_sep
);
957 for (x
= 0; x
< v
->v_array
.x
; x
++){
958 val
= v
->v_array
.vals
[x
][y
];
961 g_string_append_unichar (target
, col_sep
);
965 /* This is not supposed to happen, but
966 let's not crash anyway. */
967 g_string_append (target
, "?");
968 } else if (VALUE_IS_STRING (val
))
969 go_strescape (target
, val
->v_str
.val
->str
);
971 value_get_as_gstring (val
, target
, conv
);
974 g_string_append_c (target
, '}');
978 case VALUE_CELLRANGE
: {
980 /* Note: this makes only sense for absolute references or
981 * references relative to A1
984 range_init_value (&range
, v
);
985 tmp
= global_range_name (v
->v_range
.cell
.a
.sheet
, &range
);
986 g_string_append (target
, tmp
);
995 g_assert_not_reached ();
1000 * value_get_as_string:
1003 * simplistic value rendering
1005 * Returns a string that must be freed.
1008 value_get_as_string (GnmValue
const *v
)
1010 GString
*res
= g_string_sized_new (10);
1011 value_get_as_gstring (v
, res
, gnm_conventions_default
);
1012 return g_string_free (res
, FALSE
);
1016 * Result will stay valid until (a) the value is disposed of, or (b) two
1017 * further calls to this function are made.
1020 value_peek_string (GnmValue
const *v
)
1022 g_return_val_if_fail (v
, "");
1024 if (VALUE_IS_STRING (v
))
1025 return v
->v_str
.val
->str
;
1026 else if (VALUE_IS_ERROR (v
))
1027 return v
->v_err
.mesg
->str
;
1029 static char *cache
[2] = { NULL
, NULL
};
1030 static int next
= 0;
1033 g_free (cache
[next
]);
1034 s
= cache
[next
] = value_get_as_string (v
);
1035 next
= (next
+ 1) % G_N_ELEMENTS (cache
);
1041 * FIXME FIXME FIXME : Support errors
1044 value_get_as_int (GnmValue
const *v
)
1048 switch (v
->v_any
.type
) {
1053 return atoi (v
->v_str
.val
->str
);
1055 case VALUE_CELLRANGE
:
1056 g_warning ("Getting range as a int: what to do?");
1063 return (int) gnm_fake_trunc (v
->v_float
.val
);
1066 return v
->v_bool
.val
? 1 : 0;
1072 g_warning ("value_get_as_int unknown type 0x%x (%d).", v
->v_any
.type
, v
->v_any
.type
);
1079 * FIXME FIXME FIXME : Support errors
1082 value_get_as_float (GnmValue
const *v
)
1087 switch (v
->v_any
.type
) {
1092 return gnm_strto (v
->v_str
.val
->str
, NULL
);
1094 case VALUE_CELLRANGE
:
1095 g_warning ("Getting range as a double: what to do?");
1102 return (gnm_float
) v
->v_float
.val
;
1105 return v
->v_bool
.val
? 1. : 0.;
1111 g_warning ("value_get_as_float type error.");
1118 value_is_zero (GnmValue
const *v
)
1120 return gnm_abs (value_get_as_float (v
)) < 64 * GNM_EPSILON
;
1124 value_get_rangeref (GnmValue
const *v
)
1126 g_return_val_if_fail (VALUE_IS_CELLRANGE (v
), NULL
);
1127 return &v
->v_range
.cell
;
1132 * value_coerce_to_number:
1136 * If the value can be used as a number return that number
1137 * otherwise free it at return an appropriate error
1140 value_coerce_to_number (GnmValue
*v
, gboolean
*valid
, GnmEvalPos
const *ep
)
1142 g_return_val_if_fail (v
!= NULL
, NULL
);
1145 if (VALUE_IS_STRING (v
)) {
1146 GnmValue
*tmp
= format_match_number (value_peek_string (v
), NULL
,
1147 workbook_date_conv (ep
->sheet
->workbook
));
1150 return value_new_error_VALUE (ep
);
1152 } else if (VALUE_IS_ERROR (v
))
1155 if (!VALUE_IS_NUMBER (v
)) {
1157 return value_new_error_VALUE (ep
);
1165 value_array_set (GnmValue
*array
, int col
, int row
, GnmValue
*v
)
1167 g_return_if_fail (v
);
1168 g_return_if_fail (VALUE_IS_ARRAY (array
));
1169 g_return_if_fail (col
>=0);
1170 g_return_if_fail (row
>=0);
1171 g_return_if_fail (array
->v_array
.y
> row
);
1172 g_return_if_fail (array
->v_array
.x
> col
);
1174 value_release (array
->v_array
.vals
[col
][row
]);
1175 array
->v_array
.vals
[col
][row
] = v
;
1179 compare_bool_bool (GnmValue
const *va
, GnmValue
const *vb
)
1181 gboolean err
; /* Ignored */
1182 gboolean
const a
= value_get_as_bool (va
, &err
);
1183 gboolean
const b
= value_get_as_bool (vb
, &err
);
1185 return b
? IS_EQUAL
: IS_GREATER
;
1186 return b
? IS_LESS
: IS_EQUAL
;
1190 compare_float_float (GnmValue
const *va
, GnmValue
const *vb
)
1192 gnm_float
const a
= value_get_as_float (va
);
1193 gnm_float
const b
= value_get_as_float (vb
);
1203 compare_error_error (GnmValue
const *va
, GnmValue
const *vb
)
1205 GnmStdError ea
= value_error_classify (va
);
1206 GnmStdError eb
= value_error_classify (vb
);
1210 return ea
< eb
? IS_LESS
: IS_GREATER
;
1212 if (ea
!= GNM_ERROR_UNKNOWN
)
1215 /* Two unknown errors. Just compare strings. */
1216 i
= strcmp (value_peek_string (va
), value_peek_string (vb
));
1217 return (i
> 0 ? IS_GREATER
: (i
< 0 ? IS_LESS
: IS_EQUAL
));
1228 * Returns a non-negative difference between 2 values
1231 value_diff (GnmValue
const *a
, GnmValue
const *b
)
1233 GnmValueType ta
, tb
;
1235 /* Handle trivial (including empty/empty) and double NULL */
1239 ta
= VALUE_IS_EMPTY (a
) ? VALUE_EMPTY
: a
->v_any
.type
;
1240 tb
= VALUE_IS_EMPTY (b
) ? VALUE_EMPTY
: b
->v_any
.type
;
1242 /* string > empty */
1243 if (ta
== VALUE_STRING
) {
1245 /* Strings are > (empty, or number) */
1247 if (*a
->v_str
.val
->str
== '\0')
1251 /* If both are strings compare as string */
1253 if (go_string_equal (a
->v_str
.val
, b
->v_str
.val
))
1256 case VALUE_FLOAT
: case VALUE_BOOLEAN
:
1261 } else if (tb
== VALUE_STRING
) {
1263 /* (empty, or number) < String */
1265 if (*b
->v_str
.val
->str
== '\0')
1268 case VALUE_FLOAT
: case VALUE_BOOLEAN
:
1274 /* Booleans > all numbers (Why did excel do this ?? ) */
1275 if (ta
== VALUE_BOOLEAN
&& tb
== VALUE_FLOAT
)
1277 if (tb
== VALUE_BOOLEAN
&& ta
== VALUE_FLOAT
)
1280 switch ((ta
> tb
) ? ta
: tb
) {
1281 case VALUE_EMPTY
: /* Empty Empty compare */
1285 return (compare_bool_bool (a
, b
) == IS_EQUAL
) ? 0. : DBL_MAX
;
1288 gnm_float
const da
= value_get_as_float (a
);
1289 gnm_float
const db
= value_get_as_float (b
);
1290 return gnm_abs (da
- db
);
1293 return TYPE_MISMATCH
;
1298 gnm_string_cmp (gconstpointer gstr_a
, gconstpointer gstr_b
)
1300 return (gstr_a
== gstr_b
)
1302 : g_utf8_collate (((GOString
const *)gstr_a
)->str
,
1303 ((GOString
const *)gstr_b
)->str
);
1307 gnm_string_cmp_ignorecase (gconstpointer gstr_a
, gconstpointer gstr_b
)
1313 if (gstr_a
== gstr_b
)
1316 a
= g_utf8_casefold (((GOString
const *)gstr_a
)->str
, -1);
1317 b
= g_utf8_casefold (((GOString
const *)gstr_b
)->str
, -1);
1319 res
= g_utf8_collate (a
, b
);
1328 /* This depends on the actual values of the enums. */
1329 #define PAIR(ta_,tb_) ((ta_) + (((tb_) >> 3) - 1))
1330 #define CPAIR(ta_,tb_) (1 ? PAIR((ta_),(tb_)) : sizeof (struct { int sanity_check[((ta_) >= (tb_)) * 2 - 1]; } ))
1337 * @case_sensitive: are string comparisons case sensitive.
1342 value_compare_real (GnmValue
const *a
, GnmValue
const *b
,
1343 gboolean case_sensitive
,
1344 gboolean default_locale
)
1346 GnmValueType ta
, tb
;
1350 /* Handle trivial and double NULL case */
1354 ta
= VALUE_IS_EMPTY (a
) ? VALUE_EMPTY
: a
->v_any
.type
;
1355 tb
= VALUE_IS_EMPTY (b
) ? VALUE_EMPTY
: b
->v_any
.type
;
1359 GnmValueType t
= ta
;
1360 GnmValue
const *v
= a
;
1367 switch (PAIR (ta
,tb
)) {
1368 case CPAIR (VALUE_EMPTY
,VALUE_EMPTY
):
1369 /* In most cases this is handled by the trivial case. */
1370 /* We can get here if one of a and b is NULL and the */
1371 /* is not but contains an empty value. */
1374 /* ---------------------------------------- */
1376 case CPAIR (VALUE_BOOLEAN
,VALUE_EMPTY
): /* Blank is FALSE */
1377 case CPAIR (VALUE_BOOLEAN
,VALUE_BOOLEAN
):
1378 res
= compare_bool_bool (a
, b
);
1381 /* ---------------------------------------- */
1383 case CPAIR (VALUE_FLOAT
,VALUE_BOOLEAN
):
1384 /* Number < boolean (Why did excel do this ?? ) */
1387 case CPAIR (VALUE_FLOAT
,VALUE_EMPTY
): /* Blank is 0 */
1388 case CPAIR (VALUE_FLOAT
,VALUE_FLOAT
):
1389 res
= compare_float_float (a
, b
);
1392 /* ---------------------------------------- */
1394 case CPAIR (VALUE_ERROR
,VALUE_EMPTY
):
1395 case CPAIR (VALUE_ERROR
,VALUE_BOOLEAN
):
1396 case CPAIR (VALUE_ERROR
,VALUE_FLOAT
):
1397 /* Error > others */
1401 case CPAIR (VALUE_ERROR
,VALUE_ERROR
):
1402 res
= compare_error_error (a
, b
);
1405 /* ---------------------------------------- */
1407 case CPAIR (VALUE_STRING
,VALUE_EMPTY
): /* Blank is empty string */
1408 /* String > empty, except empty string */
1409 res
= a
->v_str
.val
->str
[0] == '\0' ? IS_EQUAL
: IS_GREATER
;
1412 case CPAIR (VALUE_STRING
,VALUE_BOOLEAN
):
1413 /* String < boolean */
1417 case CPAIR (VALUE_STRING
,VALUE_FLOAT
):
1418 /* String > number */
1422 case CPAIR (VALUE_STRING
,VALUE_ERROR
):
1423 /* String < error */
1427 case CPAIR (VALUE_STRING
,VALUE_STRING
): {
1428 GOString
const *sa
= a
->v_str
.val
;
1429 GOString
const *sb
= b
->v_str
.val
;
1430 int i
= (default_locale
1432 ? go_string_cmp (sa
, sb
)
1433 : go_string_cmp_ignorecase (sa
, sb
))
1435 ? gnm_string_cmp (sa
, sb
)
1436 : gnm_string_cmp_ignorecase (sa
, sb
)));
1437 res
= (i
> 0 ? IS_GREATER
: (i
< 0 ? IS_LESS
: IS_EQUAL
));
1441 /* ---------------------------------------- */
1444 res
= TYPE_MISMATCH
;
1450 else if (res
== IS_GREATER
)
1460 value_compare (GnmValue
const *a
, GnmValue
const *b
, gboolean case_sensitive
)
1462 return value_compare_real (a
, b
, case_sensitive
, TRUE
);
1466 value_compare_no_cache (GnmValue
const *a
, GnmValue
const *b
,
1467 gboolean case_sensitive
)
1469 return value_compare_real (a
, b
, case_sensitive
, FALSE
);
1473 value_set_fmt (GnmValue
*v
, GOFormat
const *fmt
)
1475 if (fmt
== VALUE_FMT (v
))
1477 g_return_if_fail (!VALUE_IS_EMPTY (v
) && !VALUE_IS_BOOLEAN (v
));
1479 go_format_ref (fmt
);
1480 if (VALUE_FMT (v
) != NULL
)
1481 go_format_unref (VALUE_FMT (v
));
1485 /****************************************************************************/
1488 gnm_value_get_type (void)
1493 t
= g_boxed_type_register_static ("GnmValue",
1494 (GBoxedCopyFunc
)value_dup
,
1495 (GBoxedFreeFunc
)value_release
);
1498 /****************************************************************************/
1500 GnmValueErr
const value_terminate_err
= { VALUE_ERROR
, NULL
, NULL
};
1501 static GnmValueFloat
const the_value_zero
= { VALUE_FLOAT
, NULL
, 0 };
1502 GnmValue
const *value_zero
= (GnmValue
const *)&the_value_zero
;
1509 for (i
= 0; i
< G_N_ELEMENTS (standard_errors
); i
++) {
1510 standard_errors
[i
].locale_name
= _(standard_errors
[i
].C_name
);
1511 standard_errors
[i
].locale_name_str
=
1512 go_string_new (standard_errors
[i
].locale_name
);
1517 go_mem_chunk_new ("value float pool",
1518 sizeof (GnmValueFloat
),
1522 go_mem_chunk_new ("value error pool",
1523 sizeof (GnmValueErr
),
1527 go_mem_chunk_new ("value string pool",
1528 sizeof (GnmValueStr
),
1532 go_mem_chunk_new ("value range pool",
1533 sizeof (GnmValueRange
),
1537 go_mem_chunk_new ("value array pool",
1538 sizeof (GnmValueArray
),
1544 value_shutdown (void)
1548 for (i
= 0; i
< G_N_ELEMENTS (standard_errors
); i
++) {
1549 go_string_unref (standard_errors
[i
].locale_name_str
);
1550 standard_errors
[i
].locale_name_str
= NULL
;
1554 go_mem_chunk_destroy (value_float_pool
, FALSE
);
1555 value_float_pool
= NULL
;
1557 go_mem_chunk_destroy (value_error_pool
, FALSE
);
1558 value_error_pool
= NULL
;
1560 go_mem_chunk_destroy (value_string_pool
, FALSE
);
1561 value_string_pool
= NULL
;
1563 go_mem_chunk_destroy (value_range_pool
, FALSE
);
1564 value_range_pool
= NULL
;
1566 go_mem_chunk_destroy (value_array_pool
, FALSE
);
1567 value_array_pool
= NULL
;
1569 if (value_allocations
)
1570 g_printerr ("Leaking %d values.\n", value_allocations
);
1574 /****************************************************************************/