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 (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
;
227 /* NOTE : absorbs the reference */
229 value_new_string_str (GOString
*str
)
233 g_return_val_if_fail (str
!= NULL
, NULL
);
235 v
= CHUNK_ALLOC (GnmValueStr
, value_string_pool
);
236 *((GnmValueType
*)&(v
->type
)) = VALUE_STRING
;
239 return (GnmValue
*)v
;
243 value_new_string (char const *str
)
245 return value_new_string_str (go_string_new (str
));
249 value_new_string_nocopy (char *str
)
251 return value_new_string_str (go_string_new_nocopy (str
));
255 value_new_cellrange_unsafe (GnmCellRef
const *a
, GnmCellRef
const *b
)
257 GnmValueRange
*v
= CHUNK_ALLOC (GnmValueRange
, value_range_pool
);
258 *((GnmValueType
*)&(v
->type
)) = VALUE_CELLRANGE
;
262 return (GnmValue
*)v
;
266 * value_new_cellrange:
268 * Create a new range reference.
270 * Attempt to do a sanity check for inverted ranges.
271 * NOTE : This is no longer necessary and will be removed.
272 * mixed mode references create the possibility of inversion.
273 * users of these values need to use the utility routines to
274 * evaluate the ranges in their context and normalize then.
277 value_new_cellrange (GnmCellRef
const *a
, GnmCellRef
const *b
,
278 int eval_col
, int eval_row
)
280 GnmValueRange
*v
= CHUNK_ALLOC (GnmValueRange
, value_range_pool
);
283 *((GnmValueType
*)&(v
->type
)) = VALUE_CELLRANGE
;
288 /* Sanity checking to avoid inverted ranges */
290 if (a
->col_relative
!= b
->col_relative
) {
291 /* Make a tmp copy of a in the same mode as b */
298 v
->cell
.a
.col
= b
->col
;
299 v
->cell
.a
.col_relative
= b
->col_relative
;
300 v
->cell
.b
.col
= a
->col
;
301 v
->cell
.b
.col_relative
= a
->col_relative
;
305 if (a
->row_relative
!= b
->row_relative
) {
306 /* Make a tmp copy of a in the same mode as b */
313 v
->cell
.a
.row
= b
->row
;
314 v
->cell
.a
.row_relative
= b
->row_relative
;
315 v
->cell
.b
.row
= a
->row
;
316 v
->cell
.b
.row_relative
= a
->row_relative
;
319 return (GnmValue
*)v
;
323 value_new_cellrange_r (Sheet
*sheet
, GnmRange
const *r
)
325 GnmValueRange
*v
= CHUNK_ALLOC (GnmValueRange
, value_range_pool
);
328 *((GnmValueType
*)&(v
->type
)) = VALUE_CELLRANGE
;
335 a
->col
= r
->start
.col
;
336 a
->row
= r
->start
.row
;
339 a
->col_relative
= b
->col_relative
= FALSE
;
340 a
->row_relative
= b
->row_relative
= FALSE
;
342 return (GnmValue
*)v
;
346 * value_new_cellrange_str:
347 * @sheet: the sheet where the cell range is evaluated. This really only needed if
348 * the range given does not include a sheet specification.
349 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
351 * Parse @str using the convention associated with @sheet.
352 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
353 * succesfully parsed or NULL on failure.
356 value_new_cellrange_str (Sheet
*sheet
, char const *str
)
359 GnmExprParseFlags flags
= GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS
|
360 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES
;
362 g_return_val_if_fail (IS_SHEET (sheet
), NULL
);
363 g_return_val_if_fail (str
!= NULL
, NULL
);
365 parse_pos_init_sheet (&pp
, sheet
);
366 return value_new_cellrange_parsepos_str (&pp
, str
, flags
);
370 * value_new_cellrange_parsepos_str:
371 * @pp: if a relative range is specified, then it will be interpreted relative
372 * to this position (affects only A1-style relative references).
373 * @str: a range specification (ex: "A1", "A1:C3", "Sheet1!A1:C3", "R1C1").
375 * Parse @str using the convention associated with @sheet.
376 * Returns a (GnmValue *) of type VALUE_CELLRANGE if the @range was
377 * succesfully parsed or NULL on failure.
380 value_new_cellrange_parsepos_str (GnmParsePos
const *pp
, char const *str
,
381 GnmExprParseFlags flags
)
383 GnmExprTop
const *texpr
;
384 GnmConventions
const *convs
= NULL
;
386 g_return_val_if_fail (pp
!= NULL
, NULL
);
387 g_return_val_if_fail (str
!= NULL
, NULL
);
390 convs
= pp
->sheet
->convs
;
392 texpr
= gnm_expr_parse_str (str
, pp
, flags
, convs
, NULL
);
395 GnmValue
*value
= gnm_expr_top_get_range (texpr
);
396 gnm_expr_top_unref (texpr
);
404 value_new_array_non_init (guint cols
, guint rows
)
406 GnmValueArray
*v
= CHUNK_ALLOC (GnmValueArray
, value_array_pool
);
407 *((GnmValueType
*)&(v
->type
)) = VALUE_ARRAY
;
411 v
->vals
= g_new (GnmValue
**, cols
);
412 return (GnmValue
*)v
;
416 value_new_array (guint cols
, guint rows
)
419 GnmValueArray
*v
= (GnmValueArray
*)value_new_array_non_init (cols
, rows
);
421 for (x
= 0; x
< cols
; x
++) {
422 v
->vals
[x
] = g_new (GnmValue
*, rows
);
423 for (y
= 0; y
< rows
; y
++)
424 v
->vals
[x
][y
] = value_new_int (0);
426 return (GnmValue
*)v
;
430 value_new_array_empty (guint cols
, guint rows
)
433 GnmValueArray
*v
= (GnmValueArray
*)value_new_array_non_init (cols
, rows
);
435 for (x
= 0; x
< cols
; x
++) {
436 v
->vals
[x
] = g_new (GnmValue
*, rows
);
437 for (y
= 0; y
< rows
; y
++)
438 v
->vals
[x
][y
] = NULL
;
440 return (GnmValue
*)v
;
444 * Returns TRUE, FALSE, or -1.
447 value_parse_boolean (char const *str
, gboolean translated
)
450 /* FIXME: ascii??? */
451 if (0 == g_ascii_strcasecmp (str
, go_locale_boolean_name (TRUE
)))
453 else if (0 == g_ascii_strcasecmp (str
, go_locale_boolean_name (FALSE
)))
458 if (0 == g_ascii_strcasecmp (str
, "TRUE"))
460 else if (0 == g_ascii_strcasecmp (str
, "FALSE"))
469 value_new_from_string (GnmValueType t
, char const *str
, GOFormat
*sf
,
472 GnmValue
*res
= NULL
;
475 * We need the following cast to avoid a warning from gcc over
476 * VALUE_INTEGER (which is not in GnmValueType).
480 res
= value_new_empty ();
483 case VALUE_BOOLEAN
: {
484 int i
= value_parse_boolean (str
, translated
);
486 res
= value_new_bool ((gboolean
)i
);
495 d
= gnm_strto (str
, &end
);
496 if (str
!= end
&& *end
== '\0' && errno
!= ERANGE
)
497 res
= value_new_float (d
);
503 * Tricky. We are currently storing errors in translated
504 * format, so we might have to undo that.
508 for (i
= 0; i
< G_N_ELEMENTS (standard_errors
); i
++)
509 if (strcmp (standard_errors
[i
].C_name
, str
) == 0) {
510 res
= value_new_error_std (NULL
, (GnmStdError
)i
);
515 res
= value_new_error (NULL
, str
);
519 res
= value_new_string (str
);
523 case VALUE_CELLRANGE
:
525 /* This happen with corrupted files. */
530 value_set_fmt (res
, sf
);
535 value_release (GnmValue
*value
)
540 if (VALUE_FMT (value
) != NULL
)
541 go_format_unref (VALUE_FMT (value
));
543 switch (value
->type
) {
546 /* We did not allocate anything, there is nothing to free */
550 CHUNK_FREE (value_float_pool
, &value
->v_float
);
554 /* Do not release VALUE_TERMINATE, it is a magic number */
555 if (value
== VALUE_TERMINATE
) {
556 g_warning ("Someone freed VALUE_TERMINATE -- shame on them.");
560 go_string_unref (value
->v_err
.mesg
);
561 CHUNK_FREE (value_error_pool
, &value
->v_err
);
565 go_string_unref (value
->v_str
.val
);
566 CHUNK_FREE (value_string_pool
, &value
->v_str
);
570 GnmValueArray
*v
= &value
->v_array
;
573 for (x
= 0; x
< v
->x
; x
++) {
574 for (y
= 0; y
< v
->y
; y
++)
575 value_release (v
->vals
[x
][y
]);
580 CHUNK_FREE (value_array_pool
, v
);
584 case VALUE_CELLRANGE
:
585 CHUNK_FREE (value_range_pool
, &value
->v_range
);
590 * If we don't recognize the type this is probably garbage.
591 * Do not free it to avoid heap corruption
593 g_warning ("value_release problem.");
596 g_assert_not_reached ();
603 * Returns a copy of @v. @v == NULL will return NULL
606 value_dup (GnmValue
const *src
)
615 res
= value_new_empty ();
619 res
= value_new_bool (src
->v_bool
.val
);
623 res
= value_new_float (src
->v_float
.val
);
627 res
= value_new_error_str (NULL
, /* &src->v_err.src, */
632 go_string_ref (src
->v_str
.val
);
633 res
= value_new_string_str (src
->v_str
.val
);
636 case VALUE_CELLRANGE
:
637 res
= value_new_cellrange_unsafe (&src
->v_range
.cell
.a
,
638 &src
->v_range
.cell
.b
);
643 GnmValueArray
*array
= (GnmValueArray
*)value_new_array_non_init (
644 src
->v_array
.x
, src
->v_array
.y
);
646 for (x
= 0; x
< array
->x
; x
++) {
647 array
->vals
[x
] = g_new (GnmValue
*, array
->y
);
648 for (y
= 0; y
< array
->y
; y
++)
649 array
->vals
[x
][y
] = value_dup (src
->v_array
.vals
[x
][y
]);
651 res
= (GnmValue
*)array
;
656 g_warning ("value_dup problem.");
657 res
= value_new_empty ();
659 value_set_fmt (res
, VALUE_FMT (src
));
664 value_compare_real (GnmValue
const *a
, GnmValue
const *b
,
665 gboolean case_sensitive
,
666 gboolean default_locale
);
674 * qsort style comparison function.
677 value_cmp (void const *ptr_a
, void const *ptr_b
)
679 GnmValue
const *a
= *(GnmValue
const **)ptr_a
;
680 GnmValue
const *b
= *(GnmValue
const **)ptr_b
;
681 switch (value_compare_real (a
, b
, TRUE
, TRUE
)) {
682 case IS_EQUAL
: return 0;
683 case IS_LESS
: return -1;
684 case IS_GREATER
: return 1;
688 return a
->type
- b
->type
;
692 value_cmp_reverse (void const *ptr_a
, void const *ptr_b
)
694 return -value_cmp (ptr_a
, ptr_b
);
698 value_equal (GnmValue
const *a
, GnmValue
const *b
)
700 if (a
->type
!= b
->type
)
705 return a
->v_bool
.val
== b
->v_bool
.val
;
708 return go_string_equal (a
->v_str
.val
, b
->v_str
.val
);
711 return go_string_equal (a
->v_err
.mesg
, b
->v_err
.mesg
);
714 return a
->v_float
.val
== b
->v_float
.val
;
719 case VALUE_CELLRANGE
:
720 return gnm_cellref_equal (&a
->v_range
.cell
.a
, &b
->v_range
.cell
.a
) &&
721 gnm_cellref_equal (&a
->v_range
.cell
.b
, &b
->v_range
.cell
.b
);
724 if (a
->v_array
.x
== b
->v_array
.x
&& a
->v_array
.y
== b
->v_array
.y
) {
727 for (y
= 0; y
< a
->v_array
.y
; y
++)
728 for (x
= 0; x
< a
->v_array
.x
; x
++)
729 if (!value_equal (a
->v_array
.vals
[x
][y
],
730 b
->v_array
.vals
[x
][y
]))
736 #ifndef DEBUG_SWITCH_ENUM
738 g_assert_not_reached ();
745 value_hash (GnmValue
const *v
)
749 return v
->v_bool
.val
? 0x555aaaa : 0xaaa5555;
752 return go_string_hash (v
->v_str
.val
);
755 return go_string_hash (v
->v_err
.mesg
);
759 gnm_float mant
= gnm_frexp (gnm_abs (v
->v_float
.val
), &expt
);
760 guint h
= ((guint
)(0x80000000u
* mant
)) ^ expt
;
761 if (v
->v_float
.val
>= 0)
769 case VALUE_CELLRANGE
:
770 /* FIXME: take sheet into account? */
771 return (gnm_cellref_hash (&v
->v_range
.cell
.a
) * 3) ^
772 gnm_cellref_hash (&v
->v_range
.cell
.b
);
776 guint h
= (v
->v_array
.x
* 257) ^ (v
->v_array
.y
+ 42);
778 /* For speed, just walk the diagonal. */
779 for (i
= 0; i
< v
->v_array
.x
&& i
< v
->v_array
.y
; i
++) {
781 if (v
->v_array
.vals
[i
][i
])
782 h
^= value_hash (v
->v_array
.vals
[i
][i
]);
787 #ifndef DEBUG_SWITCH_ENUM
789 g_assert_not_reached ();
797 value_get_as_bool (GnmValue
const *v
, gboolean
*err
)
810 return v
->v_bool
.val
;
813 int i
= value_parse_boolean (value_peek_string (v
), FALSE
);
823 return v
->v_float
.val
!= 0.0;
826 g_warning ("Unhandled value in value_get_as_bool.");
828 case VALUE_CELLRANGE
:
838 * use only if you are sure the value is ok
841 value_get_as_checked_bool (GnmValue
const *v
)
843 gboolean result
, err
;
845 result
= value_get_as_bool (v
, &err
);
847 g_return_val_if_fail (!err
, FALSE
);
853 * value_get_as_gstring:
856 * @conv: #GnmConventions
858 * A simple value formatter to convert @v into a string stored in @target
859 * according to @conv. See format_value_gstring for something more elaborate
860 * that handles formats too.
863 value_get_as_gstring (GnmValue
const *v
, GString
*target
,
864 GnmConventions
const *conv
)
874 GnmStdError e
= value_error_classify (v
);
875 if (e
== GNM_ERROR_UNKNOWN
) {
876 g_string_append_c (target
, '#');
877 go_strescape (target
, v
->v_err
.mesg
->str
);
879 g_string_append (target
, value_error_name (e
, conv
->output
.translated
));
883 case VALUE_BOOLEAN
: {
884 gboolean b
= v
->v_bool
.val
;
885 g_string_append (target
,
886 conv
->output
.translated
887 ? go_locale_boolean_name (b
)
888 : (b
? "TRUE" : "FALSE"));
893 g_string_append (target
, v
->v_str
.val
->str
);
897 g_string_append_printf (target
, "%.*" GNM_FORMAT_g
,
898 conv
->output
.decimal_digits
,
904 gunichar row_sep
, col_sep
;
907 if (conv
->array_row_sep
)
908 row_sep
= conv
->array_row_sep
;
910 row_sep
= go_locale_get_row_sep ();
911 if (conv
->array_col_sep
)
912 col_sep
= conv
->array_col_sep
;
914 col_sep
= go_locale_get_col_sep ();
916 g_string_append_c (target
, '{');
917 for (y
= 0; y
< v
->v_array
.y
; y
++){
919 g_string_append_unichar (target
, row_sep
);
921 for (x
= 0; x
< v
->v_array
.x
; x
++){
922 val
= v
->v_array
.vals
[x
][y
];
925 g_string_append_unichar (target
, col_sep
);
929 /* This is not supposed to happen, but
930 let's not crash anyway. */
931 g_string_append (target
, "?");
932 } else if (VALUE_IS_STRING (val
))
933 go_strescape (target
, val
->v_str
.val
->str
);
935 value_get_as_gstring (val
, target
, conv
);
938 g_string_append_c (target
, '}');
942 case VALUE_CELLRANGE
: {
944 /* Note: this makes only sense for absolute references or
945 * references relative to A1
948 range_init_value (&range
, v
);
949 tmp
= global_range_name (v
->v_range
.cell
.a
.sheet
, &range
);
950 g_string_append (target
, tmp
);
959 g_assert_not_reached ();
964 * value_get_as_string:
967 * simplistic value rendering
969 * Returns a string that must be freed.
972 value_get_as_string (GnmValue
const *v
)
974 GString
*res
= g_string_sized_new (10);
975 value_get_as_gstring (v
, res
, gnm_conventions_default
);
976 return g_string_free (res
, FALSE
);
980 * Result will stay valid until (a) the value is disposed of, or (b) two
981 * further calls to this function are made.
984 value_peek_string (GnmValue
const *v
)
986 g_return_val_if_fail (v
, "");
988 if (VALUE_IS_STRING (v
))
989 return v
->v_str
.val
->str
;
990 else if (VALUE_IS_ERROR (v
))
991 return v
->v_err
.mesg
->str
;
993 static char *cache
[2] = { NULL
, NULL
};
997 g_free (cache
[next
]);
998 s
= cache
[next
] = value_get_as_string (v
);
999 next
= (next
+ 1) % G_N_ELEMENTS (cache
);
1005 * FIXME FIXME FIXME : Support errors
1008 value_get_as_int (GnmValue
const *v
)
1017 return atoi (v
->v_str
.val
->str
);
1019 case VALUE_CELLRANGE
:
1020 g_warning ("Getting range as a int: what to do?");
1027 return (int) gnm_fake_trunc (v
->v_float
.val
);
1030 return v
->v_bool
.val
? 1 : 0;
1036 g_warning ("value_get_as_int unknown type 0x%x (%d).", v
->type
, v
->type
);
1043 * FIXME FIXME FIXME : Support errors
1046 value_get_as_float (GnmValue
const *v
)
1056 return gnm_strto (v
->v_str
.val
->str
, NULL
);
1058 case VALUE_CELLRANGE
:
1059 g_warning ("Getting range as a double: what to do?");
1066 return (gnm_float
) v
->v_float
.val
;
1069 return v
->v_bool
.val
? 1. : 0.;
1075 g_warning ("value_get_as_float type error.");
1082 value_is_zero (GnmValue
const *v
)
1084 return gnm_abs (value_get_as_float (v
)) < 64 * GNM_EPSILON
;
1088 value_get_rangeref (GnmValue
const *v
)
1090 g_return_val_if_fail (v
->type
== VALUE_CELLRANGE
, NULL
);
1091 return &v
->v_range
.cell
;
1096 * value_coerce_to_number:
1100 * If the value can be used as a number return that number
1101 * otherwise free it at return an appropriate error
1104 value_coerce_to_number (GnmValue
*v
, gboolean
*valid
, GnmEvalPos
const *ep
)
1106 g_return_val_if_fail (v
!= NULL
, NULL
);
1109 if (VALUE_IS_STRING (v
)) {
1110 GnmValue
*tmp
= format_match_number (value_peek_string (v
), NULL
,
1111 workbook_date_conv (ep
->sheet
->workbook
));
1114 return value_new_error_VALUE (ep
);
1116 } else if (VALUE_IS_ERROR (v
))
1119 if (!VALUE_IS_NUMBER (v
)) {
1121 return value_new_error_VALUE (ep
);
1129 value_array_set (GnmValue
*array
, int col
, int row
, GnmValue
*v
)
1131 g_return_if_fail (v
);
1132 g_return_if_fail (array
->type
== VALUE_ARRAY
);
1133 g_return_if_fail (col
>=0);
1134 g_return_if_fail (row
>=0);
1135 g_return_if_fail (array
->v_array
.y
> row
);
1136 g_return_if_fail (array
->v_array
.x
> col
);
1138 value_release (array
->v_array
.vals
[col
][row
]);
1139 array
->v_array
.vals
[col
][row
] = v
;
1143 compare_bool_bool (GnmValue
const *va
, GnmValue
const *vb
)
1145 gboolean err
; /* Ignored */
1146 gboolean
const a
= value_get_as_bool (va
, &err
);
1147 gboolean
const b
= value_get_as_bool (vb
, &err
);
1149 return b
? IS_EQUAL
: IS_GREATER
;
1150 return b
? IS_LESS
: IS_EQUAL
;
1154 compare_float_float (GnmValue
const *va
, GnmValue
const *vb
)
1156 gnm_float
const a
= value_get_as_float (va
);
1157 gnm_float
const b
= value_get_as_float (vb
);
1173 * Returns a non-negative difference between 2 values
1176 value_diff (GnmValue
const *a
, GnmValue
const *b
)
1178 GnmValueType ta
, tb
;
1180 /* Handle trivial (including empty/empty) and double NULL */
1184 ta
= VALUE_IS_EMPTY (a
) ? VALUE_EMPTY
: a
->type
;
1185 tb
= VALUE_IS_EMPTY (b
) ? VALUE_EMPTY
: b
->type
;
1187 /* string > empty */
1188 if (ta
== VALUE_STRING
) {
1190 /* Strings are > (empty, or number) */
1192 if (*a
->v_str
.val
->str
== '\0')
1196 /* If both are strings compare as string */
1198 if (go_string_equal (a
->v_str
.val
, b
->v_str
.val
))
1201 case VALUE_FLOAT
: case VALUE_BOOLEAN
:
1206 } else if (tb
== VALUE_STRING
) {
1208 /* (empty, or number) < String */
1210 if (*b
->v_str
.val
->str
== '\0')
1213 case VALUE_FLOAT
: case VALUE_BOOLEAN
:
1219 /* Booleans > all numbers (Why did excel do this ?? ) */
1220 if (ta
== VALUE_BOOLEAN
&& tb
== VALUE_FLOAT
)
1222 if (tb
== VALUE_BOOLEAN
&& ta
== VALUE_FLOAT
)
1225 switch ((ta
> tb
) ? ta
: tb
) {
1226 case VALUE_EMPTY
: /* Empty Empty compare */
1230 return (compare_bool_bool (a
, b
) == IS_EQUAL
) ? 0. : DBL_MAX
;
1233 gnm_float
const da
= value_get_as_float (a
);
1234 gnm_float
const db
= value_get_as_float (b
);
1235 return gnm_abs (da
- db
);
1238 return TYPE_MISMATCH
;
1243 gnm_string_cmp (gconstpointer gstr_a
, gconstpointer gstr_b
)
1245 return (gstr_a
== gstr_b
)
1247 : g_utf8_collate (((GOString
const *)gstr_a
)->str
,
1248 ((GOString
const *)gstr_b
)->str
);
1252 gnm_string_cmp_ignorecase (gconstpointer gstr_a
, gconstpointer gstr_b
)
1258 if (gstr_a
== gstr_b
)
1261 a
= g_utf8_casefold (((GOString
const *)gstr_a
)->str
, -1);
1262 b
= g_utf8_casefold (((GOString
const *)gstr_b
)->str
, -1);
1264 res
= g_utf8_collate (a
, b
);
1278 * @case_sensitive: are string comparisons case sensitive.
1283 value_compare_real (GnmValue
const *a
, GnmValue
const *b
,
1284 gboolean case_sensitive
,
1285 gboolean default_locale
)
1287 GnmValueType ta
, tb
;
1290 /* Handle trivial and double NULL case */
1294 ta
= VALUE_IS_EMPTY (a
) ? VALUE_EMPTY
: a
->type
;
1295 tb
= VALUE_IS_EMPTY (b
) ? VALUE_EMPTY
: b
->type
;
1297 /* string > empty */
1298 if (ta
== VALUE_STRING
) {
1300 /* Strings are > (empty, or number) */
1302 if (*a
->v_str
.val
->str
== '\0')
1308 /* Strings are < FALSE ?? */
1309 case VALUE_BOOLEAN
:
1312 /* If both are strings compare as string */
1314 t
= (default_locale
) ?
1317 (a
->v_str
.val
, b
->v_str
.val
)
1318 : go_string_cmp_ignorecase
1319 (a
->v_str
.val
, b
->v_str
.val
))
1322 (a
->v_str
.val
, b
->v_str
.val
)
1323 : gnm_string_cmp_ignorecase
1324 (a
->v_str
.val
, b
->v_str
.val
));
1334 return TYPE_MISMATCH
;
1336 } else if (tb
== VALUE_STRING
) {
1338 /* (empty, or number) < String */
1340 if (*b
->v_str
.val
->str
== '\0')
1346 /* Strings are < FALSE ?? */
1347 case VALUE_BOOLEAN
:
1351 return TYPE_MISMATCH
;
1355 /* Booleans > all numbers (Why did excel do this ?? ) */
1356 if (ta
== VALUE_BOOLEAN
&& tb
== VALUE_FLOAT
)
1358 if (tb
== VALUE_BOOLEAN
&& ta
== VALUE_FLOAT
)
1361 switch ((ta
> tb
) ? ta
: tb
) {
1362 case VALUE_EMPTY
: /* Empty Empty compare */
1366 return compare_bool_bool (a
, b
);
1369 return compare_float_float (a
, b
);
1371 return TYPE_MISMATCH
;
1376 value_compare (GnmValue
const *a
, GnmValue
const *b
, gboolean case_sensitive
)
1378 return value_compare_real (a
, b
, case_sensitive
, TRUE
);
1382 value_compare_no_cache (GnmValue
const *a
, GnmValue
const *b
,
1383 gboolean case_sensitive
)
1385 return value_compare_real (a
, b
, case_sensitive
, FALSE
);
1389 value_set_fmt (GnmValue
*v
, GOFormat
const *fmt
)
1391 if (fmt
== VALUE_FMT (v
))
1393 g_return_if_fail (v
->type
!= VALUE_EMPTY
&& v
->type
!= VALUE_BOOLEAN
);
1395 go_format_ref (fmt
);
1396 if (VALUE_FMT (v
) != NULL
)
1397 go_format_unref (VALUE_FMT (v
));
1401 /****************************************************************************/
1403 typedef enum { CRIT_NULL
, CRIT_FLOAT
, CRIT_WRONGTYPE
, CRIT_STRING
} CritType
;
1406 criteria_inspect_values (GnmValue
const *x
, gnm_float
*xr
, gnm_float
*yr
,
1410 GnmValue
const *y
= crit
->x
;
1412 if (x
== NULL
|| y
== NULL
)
1417 /* If we're searching for a bool -- even one that is
1418 from a string search value -- we match only bools. */
1419 if (!VALUE_IS_BOOLEAN (x
))
1420 return CRIT_WRONGTYPE
;
1421 *xr
= value_get_as_float (x
);
1422 *yr
= value_get_as_float (y
);
1430 g_warning ("This should not happen. Please report.");
1431 return CRIT_WRONGTYPE
;
1434 *yr
= value_get_as_float (y
);
1436 if (VALUE_IS_BOOLEAN (x
))
1437 return CRIT_WRONGTYPE
;
1438 else if (VALUE_IS_FLOAT (x
)) {
1439 *xr
= value_get_as_float (x
);
1443 vx
= format_match (value_peek_string (x
), NULL
, crit
->date_conv
);
1444 if (VALUE_IS_EMPTY (vx
) ||
1445 VALUE_IS_BOOLEAN (y
) != VALUE_IS_BOOLEAN (vx
)) {
1447 return CRIT_WRONGTYPE
;
1450 *xr
= value_get_as_float (vx
);
1458 criteria_test_equal (GnmValue
const *x
, GnmCriteria
*crit
)
1461 GnmValue
const *y
= crit
->x
;
1463 switch (criteria_inspect_values (x
, &xf
, &yf
, crit
)) {
1465 g_assert_not_reached ();
1467 case CRIT_WRONGTYPE
:
1472 /* FIXME: _ascii_??? */
1473 return g_ascii_strcasecmp (value_peek_string (x
),
1474 value_peek_string (y
)) == 0;
1479 criteria_test_unequal (GnmValue
const *x
, GnmCriteria
*crit
)
1483 switch (criteria_inspect_values (x
, &xf
, &yf
, crit
)) {
1485 g_assert_not_reached ();
1487 case CRIT_WRONGTYPE
:
1492 /* FIXME: _ascii_??? */
1493 return g_ascii_strcasecmp (value_peek_string (x
),
1494 value_peek_string (crit
->x
)) != 0;
1499 criteria_test_less (GnmValue
const *x
, GnmCriteria
*crit
)
1503 switch (criteria_inspect_values (x
, &xf
, &yf
, crit
)) {
1505 g_assert_not_reached ();
1507 case CRIT_WRONGTYPE
:
1516 criteria_test_greater (GnmValue
const *x
, GnmCriteria
*crit
)
1520 switch (criteria_inspect_values (x
, &xf
, &yf
, crit
)) {
1522 g_assert_not_reached ();
1524 case CRIT_WRONGTYPE
:
1533 criteria_test_less_or_equal (GnmValue
const *x
, GnmCriteria
*crit
)
1537 switch (criteria_inspect_values (x
, &xf
, &yf
, crit
)) {
1539 g_assert_not_reached ();
1541 case CRIT_WRONGTYPE
:
1550 criteria_test_greater_or_equal (GnmValue
const *x
, GnmCriteria
*crit
)
1554 switch (criteria_inspect_values (x
, &xf
, &yf
, crit
)) {
1556 g_assert_not_reached ();
1558 case CRIT_WRONGTYPE
:
1567 criteria_test_match (GnmValue
const *x
, GnmCriteria
*crit
)
1572 return go_regexec (&crit
->rx
, value_peek_string (x
), 0, NULL
, 0) ==
1577 criteria_test_empty (GnmValue
const *x
, GnmCriteria
*crit
)
1579 return VALUE_IS_EMPTY (x
);
1583 criteria_test_nonempty (GnmValue
const *x
, GnmCriteria
*crit
)
1585 return !VALUE_IS_EMPTY (x
);
1589 * Finds a column index of a field.
1592 find_column_of_field (GnmEvalPos
const *ep
,
1593 GnmValue
const *database
, GnmValue
const *field
)
1598 int begin_col
, end_col
, row
, n
, column
;
1601 offset
= database
->v_range
.cell
.a
.col
;
1603 if (VALUE_IS_FLOAT (field
))
1604 return value_get_as_int (field
) + offset
- 1;
1606 if (!VALUE_IS_STRING (field
))
1609 sheet
= eval_sheet (database
->v_range
.cell
.a
.sheet
, ep
->sheet
);
1610 field_name
= value_get_as_string (field
);
1613 /* find the column that is labeled after `field_name' */
1614 begin_col
= database
->v_range
.cell
.a
.col
;
1615 end_col
= database
->v_range
.cell
.b
.col
;
1616 row
= database
->v_range
.cell
.a
.row
;
1618 for (n
= begin_col
; n
<= end_col
; n
++) {
1622 cell
= sheet_cell_get (sheet
, n
, row
);
1625 gnm_cell_eval (cell
);
1628 ? value_peek_string (cell
->value
)
1630 match
= (g_ascii_strcasecmp (field_name
, txt
) == 0);
1637 g_free (field_name
);
1642 free_criteria (GnmCriteria
*criteria
)
1644 if (!criteria
|| criteria
->ref_count
-- > 1)
1646 value_release (criteria
->x
);
1647 if (criteria
->has_rx
)
1648 go_regfree (&criteria
->rx
);
1652 static GnmCriteria
*
1653 gnm_criteria_ref (GnmCriteria
*criteria
)
1655 criteria
->ref_count
++;
1660 gnm_criteria_get_type (void)
1665 t
= g_boxed_type_register_static ("GnmCriteria",
1666 (GBoxedCopyFunc
)gnm_criteria_ref
,
1667 (GBoxedFreeFunc
)free_criteria
);
1674 * @criterias: (element-type GnmCriteria) (transfer full): the criteria to be
1676 * Frees the allocated memory.
1679 free_criterias (GSList
*criterias
)
1681 GSList
*list
= criterias
;
1683 while (criterias
!= NULL
) {
1684 GnmDBCriteria
*criteria
= criterias
->data
;
1685 g_slist_free_full (criteria
->conditions
,
1686 (GFreeFunc
)free_criteria
);
1688 criterias
= criterias
->next
;
1690 g_slist_free (list
);
1695 * @crit_val: #GnmValue
1696 * @date_conv: #GODateConventions
1698 * Returns: (transfer full): GnmCriteria which caller must free.
1709 parse_criteria (GnmValue
const *crit_val
, GODateConventions
const *date_conv
)
1712 char const *criteria
;
1713 GnmCriteria
*res
= g_new0 (GnmCriteria
, 1);
1716 res
->iter_flags
= CELL_ITER_IGNORE_BLANK
;
1717 res
->date_conv
= date_conv
;
1719 if (VALUE_IS_NUMBER (crit_val
)) {
1720 res
->fun
= criteria_test_equal
;
1721 res
->x
= value_dup (crit_val
);
1725 criteria
= value_peek_string (crit_val
);
1726 if (strncmp (criteria
, "<=", 2) == 0) {
1727 res
->fun
= criteria_test_less_or_equal
;
1729 } else if (strncmp (criteria
, ">=", 2) == 0) {
1730 res
->fun
= criteria_test_greater_or_equal
;
1732 } else if (strncmp (criteria
, "<>", 2) == 0) {
1733 /* "<>" by itself is special: */
1734 res
->fun
= (criteria
[2] == 0) ? criteria_test_nonempty
: criteria_test_unequal
;
1736 } else if (*criteria
== '<') {
1737 res
->fun
= criteria_test_less
;
1739 } else if (*criteria
== '=') {
1740 /* "=" by itself is special: */
1741 res
->fun
= (criteria
[1] == 0) ? criteria_test_empty
: criteria_test_equal
;
1743 } else if (*criteria
== '>') {
1744 res
->fun
= criteria_test_greater
;
1747 res
->fun
= criteria_test_match
;
1748 res
->has_rx
= (gnm_regcomp_XL (&res
->rx
, criteria
, GO_REG_ICASE
, TRUE
, TRUE
) == GO_REG_OK
);
1752 res
->x
= format_match_number (criteria
+ len
, NULL
, date_conv
);
1754 res
->x
= value_new_string (criteria
+ len
);
1755 else if (len
== 0 && VALUE_IS_NUMBER (res
->x
))
1756 res
->fun
= criteria_test_equal
;
1758 empty
= value_new_empty ();
1759 if (res
->fun (empty
, res
))
1760 res
->iter_flags
&= ~CELL_ITER_IGNORE_BLANK
;
1761 value_release (empty
);
1769 parse_criteria_range (Sheet
*sheet
, int b_col
, int b_row
, int e_col
, int e_row
,
1772 GSList
*criterias
= NULL
;
1773 GODateConventions
const *date_conv
=
1774 workbook_date_conv (sheet
->workbook
);
1777 for (i
= b_row
; i
<= e_row
; i
++) {
1778 GnmDBCriteria
*new_criteria
= g_new (GnmDBCriteria
, 1);
1779 GSList
*conditions
= NULL
;
1781 for (j
= b_col
; j
<= e_col
; j
++) {
1783 GnmCell
*cell
= sheet_cell_get (sheet
, j
, i
);
1785 gnm_cell_eval (cell
);
1786 if (gnm_cell_is_empty (cell
))
1789 cond
= parse_criteria (cell
->value
, date_conv
);
1790 cond
->column
= (field_ind
!= NULL
)
1791 ? field_ind
[j
- b_col
]
1793 conditions
= g_slist_prepend (conditions
, cond
);
1796 new_criteria
->conditions
= g_slist_reverse (conditions
);
1797 criterias
= g_slist_prepend (criterias
, new_criteria
);
1800 return g_slist_reverse (criterias
);
1804 * parse_database_criteria:
1806 * @database: #GnmValue
1807 * @criteria: #GnmValue
1809 * Parses the criteria cell range.
1810 * Returns: (element-type GnmDBCriteria) (transfer full):
1813 parse_database_criteria (GnmEvalPos
const *ep
, GnmValue
const *database
, GnmValue
const *criteria
)
1818 int b_col
, b_row
, e_col
, e_row
;
1821 g_return_val_if_fail (criteria
->type
== VALUE_CELLRANGE
, NULL
);
1823 sheet
= eval_sheet (criteria
->v_range
.cell
.a
.sheet
, ep
->sheet
);
1824 b_col
= criteria
->v_range
.cell
.a
.col
;
1825 b_row
= criteria
->v_range
.cell
.a
.row
;
1826 e_col
= criteria
->v_range
.cell
.b
.col
;
1827 e_row
= criteria
->v_range
.cell
.b
.row
;
1829 if (e_col
< b_col
) {
1835 /* Find the index numbers for the columns of criterias */
1836 field_ind
= g_alloca (sizeof (int) * (e_col
- b_col
+ 1));
1837 for (i
= b_col
; i
<= e_col
; i
++) {
1838 cell
= sheet_cell_get (sheet
, i
, b_row
);
1841 gnm_cell_eval (cell
);
1842 if (gnm_cell_is_empty (cell
))
1844 field_ind
[i
- b_col
] =
1845 find_column_of_field (ep
, database
, cell
->value
);
1846 if (field_ind
[i
- b_col
] == -1)
1850 return parse_criteria_range (sheet
, b_col
, b_row
+ 1,
1851 e_col
, e_row
, field_ind
);
1855 * find_rows_that_match:
1857 * @first_col: first column.
1858 * @first_row: first row.
1859 * @last_col: last column.
1860 * @last_row: laset row.
1861 * @criterias: (element-type GnmDBCriteria): the criteria to use.
1864 * Finds the rows from the given database that match the criteria.
1865 * Returns: (element-type int) (transfer full): the list of matching rows.
1868 find_rows_that_match (Sheet
*sheet
, int first_col
, int first_row
,
1869 int last_col
, int last_row
,
1870 GSList
*criterias
, gboolean unique_only
)
1872 GSList
*rows
= NULL
;
1873 GSList
const *crit_ptr
, *cond_ptr
;
1876 char const *t1
, *t2
;
1879 for (row
= first_row
; row
<= last_row
; row
++) {
1881 for (crit_ptr
= criterias
; crit_ptr
; crit_ptr
= crit_ptr
->next
) {
1882 GnmDBCriteria
const *crit
= crit_ptr
->data
;
1884 for (cond_ptr
= crit
->conditions
;
1885 cond_ptr
!= NULL
; cond_ptr
= cond_ptr
->next
) {
1886 GnmCriteria
*cond
= cond_ptr
->data
;
1887 test_cell
= sheet_cell_get (sheet
, cond
->column
, row
);
1888 if (test_cell
!= NULL
)
1889 gnm_cell_eval (test_cell
);
1890 if (gnm_cell_is_empty (test_cell
) ||
1891 !cond
->fun (test_cell
->value
, cond
)) {
1908 for (c
= rows
; c
!= NULL
; c
= c
->next
) {
1909 trow
= *((gint
*) c
->data
);
1910 for (i
= first_col
; i
<= last_col
; i
++) {
1911 test_cell
= sheet_cell_get (sheet
, i
, trow
);
1912 cell
= sheet_cell_get (sheet
, i
, row
);
1914 /* FIXME: this is probably not right, but crashing is more wrong. */
1915 if (test_cell
== NULL
|| cell
== NULL
)
1919 ? value_peek_string (cell
->value
)
1921 t2
= test_cell
->value
1922 ? value_peek_string (test_cell
->value
)
1924 if (strcmp (t1
, t2
) != 0)
1932 p
= g_new (gint
, 1);
1934 rows
= g_slist_prepend (rows
, (gpointer
) p
);
1940 return g_slist_reverse (rows
);
1943 /****************************************************************************/
1946 gnm_value_get_type (void)
1951 t
= g_boxed_type_register_static ("GnmValue",
1952 (GBoxedCopyFunc
)value_dup
,
1953 (GBoxedFreeFunc
)value_release
);
1956 /****************************************************************************/
1958 GnmValueErr
const value_terminate_err
= { VALUE_ERROR
, NULL
, NULL
};
1959 static GnmValueFloat
const the_value_zero
= { VALUE_FLOAT
, NULL
, 0 };
1960 GnmValue
const *value_zero
= (GnmValue
const *)&the_value_zero
;
1967 for (i
= 0; i
< G_N_ELEMENTS (standard_errors
); i
++) {
1968 standard_errors
[i
].locale_name
= _(standard_errors
[i
].C_name
);
1969 standard_errors
[i
].locale_name_str
=
1970 go_string_new (standard_errors
[i
].locale_name
);
1975 go_mem_chunk_new ("value float pool",
1976 sizeof (GnmValueFloat
),
1980 go_mem_chunk_new ("value error pool",
1981 sizeof (GnmValueErr
),
1985 go_mem_chunk_new ("value string pool",
1986 sizeof (GnmValueStr
),
1990 go_mem_chunk_new ("value range pool",
1991 sizeof (GnmValueRange
),
1995 go_mem_chunk_new ("value array pool",
1996 sizeof (GnmValueArray
),
2002 value_shutdown (void)
2006 for (i
= 0; i
< G_N_ELEMENTS (standard_errors
); i
++) {
2007 go_string_unref (standard_errors
[i
].locale_name_str
);
2008 standard_errors
[i
].locale_name_str
= NULL
;
2012 go_mem_chunk_destroy (value_float_pool
, FALSE
);
2013 value_float_pool
= NULL
;
2015 go_mem_chunk_destroy (value_error_pool
, FALSE
);
2016 value_error_pool
= NULL
;
2018 go_mem_chunk_destroy (value_string_pool
, FALSE
);
2019 value_string_pool
= NULL
;
2021 go_mem_chunk_destroy (value_range_pool
, FALSE
);
2022 value_range_pool
= NULL
;
2024 go_mem_chunk_destroy (value_array_pool
, FALSE
);
2025 value_array_pool
= NULL
;
2027 if (value_allocations
)
2028 g_printerr ("Leaking %d values.\n", value_allocations
);
2032 /****************************************************************************/