gnumeric r16473 - in branches/gnumeric-1-8: . plugins/fn-database plugins/fn-math src
- From: mortenw svn gnome org
- To: svn-commits-list gnome org
- Subject: gnumeric r16473 - in branches/gnumeric-1-8: . plugins/fn-database plugins/fn-math src
- Date: Tue, 25 Mar 2008 00:16:20 +0000 (GMT)
Author: mortenw
Date: Tue Mar 25 00:16:19 2008
New Revision: 16473
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16473&view=rev
Log:
2008-03-20 Morten Welinder <terra gnome org>
* src/value.c (criteria_test_equal, criteria_test_unequal,
criteria_test_less, criteria_test_less_or_equal,
criteria_test_greater, criteria_test_greater_or_equal): Handle
string values that can be interpreted as numbers. Take extra
date_conv argument. All callers changed.
Modified:
branches/gnumeric-1-8/ChangeLog
branches/gnumeric-1-8/NEWS
branches/gnumeric-1-8/plugins/fn-database/functions.c
branches/gnumeric-1-8/plugins/fn-math/functions.c
branches/gnumeric-1-8/src/value.c
branches/gnumeric-1-8/src/value.h
Modified: branches/gnumeric-1-8/NEWS
==============================================================================
--- branches/gnumeric-1-8/NEWS (original)
+++ branches/gnumeric-1-8/NEWS Tue Mar 25 00:16:19 2008
@@ -3,6 +3,9 @@
Nick Lamb:
* Honour detachable-toolbar preference. [#321867]
+Morten:
+ * Fix SUMIF problems. [#523250]
+
--------------------------------------------------------------------------
Gnumeric 1.8.2
Modified: branches/gnumeric-1-8/plugins/fn-database/functions.c
==============================================================================
--- branches/gnumeric-1-8/plugins/fn-database/functions.c (original)
+++ branches/gnumeric-1-8/plugins/fn-database/functions.c Tue Mar 25 00:16:19 2008
@@ -28,6 +28,7 @@
#include <str.h>
#include <cell.h>
#include <sheet.h>
+#include <workbook.h>
#include <value.h>
#include <number-match.h>
#include <collect.h>
@@ -56,6 +57,8 @@
int row, first_row, last_row;
gboolean add_flag;
GnmCell *cell;
+ GODateConventions const *date_conv =
+ workbook_date_conv (sheet->workbook);
cells = NULL;
/* TODO : Why ignore the first row ? What if there is no header ? */
@@ -85,7 +88,7 @@
if (tmp != NULL)
gnm_cell_eval (tmp);
if (gnm_cell_is_empty (tmp) ||
- !cond->fun (tmp->value, cond->x)) {
+ !cond->fun (tmp->value, cond->x, date_conv)) {
add_flag = FALSE;
break;
}
Modified: branches/gnumeric-1-8/plugins/fn-math/functions.c
==============================================================================
--- branches/gnumeric-1-8/plugins/fn-math/functions.c (original)
+++ branches/gnumeric-1-8/plugins/fn-math/functions.c Tue Mar 25 00:16:19 2008
@@ -555,6 +555,7 @@
typedef struct {
GnmCriteriaFunc test;
GnmValue *test_value;
+ GODateConventions const *date_conv;
int count;
} CountIfClosure;
@@ -566,7 +567,7 @@
gnm_cell_eval (cell);
if ((VALUE_IS_NUMBER (cell->value) ||
VALUE_IS_STRING (cell->value)) &&
- (res->test) (cell->value, res->test_value))
+ (res->test) (cell->value, res->test_value, res->date_conv))
res->count++;
}
@@ -592,6 +593,8 @@
(!VALUE_IS_NUMBER (argv[1]) && !VALUE_IS_STRING (argv[1])))
return value_new_error_VALUE (ei->pos);
+ res.date_conv = sheet ? workbook_date_conv (sheet->workbook) : NULL;
+
res.count = 0;
parse_criteria (argv[1], &res.test, &res.test_value, &iter_flags,
workbook_date_conv (ei->pos->sheet->workbook));
@@ -636,6 +639,7 @@
typedef struct {
GnmCriteriaFunc test;
GnmValue *test_value;
+ GODateConventions const *date_conv;
Sheet *target_sheet;
GnmCellPos offset;
@@ -651,7 +655,7 @@
gnm_cell_eval (cell);
if ((VALUE_IS_NUMBER (cell->value) || VALUE_IS_STRING (cell->value)) &&
- (res->test) (cell->value, res->test_value)) {
+ (res->test) (cell->value, res->test_value, res->date_conv)) {
if (NULL != res->target_sheet) {
cell = sheet_cell_get (res->target_sheet,
iter->pp.eval.col + res->offset.col,
@@ -695,6 +699,8 @@
(!VALUE_IS_NUMBER (argv[1]) && !VALUE_IS_STRING (argv[1])))
return value_new_error_VALUE (ei->pos);
+ res.date_conv = sheet ? workbook_date_conv (sheet->workbook) : NULL;
+
col_end = r->cell.b.col;
row_end = r->cell.b.row;
if (NULL != argv[2]) {
Modified: branches/gnumeric-1-8/src/value.c
==============================================================================
--- branches/gnumeric-1-8/src/value.c (original)
+++ branches/gnumeric-1-8/src/value.c Tue Mar 25 00:16:19 2008
@@ -1337,77 +1337,149 @@
/****************************************************************************/
-static gboolean
-criteria_test_equal (GnmValue const *x, GnmValue const *y)
+typedef enum { CRIT_NULL, CRIT_FLOAT, CRIT_BADFLOAT, CRIT_STRING } CritType;
+
+static CritType
+criteria_inspect_values (GnmValue const *x, GnmValue const *y,
+ gnm_float *xr, gnm_float *yr,
+ GODateConventions const *date_conv)
{
+ GnmValue *vx;
+
if (x == NULL || y == NULL)
- return FALSE;
- if (VALUE_IS_NUMBER (x) && VALUE_IS_NUMBER (y))
- return (value_get_as_float (x) == value_get_as_float (y));
- else
- return (VALUE_IS_STRING (x) &&
- VALUE_IS_STRING (y) &&
- g_ascii_strcasecmp (x->v_str.val->str, y->v_str.val->str) == 0);
+ return CRIT_NULL;
+
+ if (!VALUE_IS_NUMBER (y))
+ return CRIT_STRING;
+ *yr = value_get_as_float (y);
+
+ if (VALUE_IS_NUMBER (x)) {
+ *xr = value_get_as_float (x);
+ return CRIT_FLOAT;
+ }
+
+ vx = format_match (value_peek_string (x), NULL, date_conv);
+ if (!vx)
+ return CRIT_BADFLOAT;
+
+ *xr = value_get_as_float (vx);
+ value_release (vx);
+ return CRIT_FLOAT;
}
+
static gboolean
-criteria_test_unequal (GnmValue const *x, GnmValue const *y)
+criteria_test_equal (GnmValue const *x, GnmValue const *y,
+ GODateConventions const *date_conv)
{
- if (x == NULL)
- return y != NULL;
- if (y == NULL)
- return TRUE;
- if (VALUE_IS_NUMBER (x) && VALUE_IS_NUMBER (y))
- return (value_get_as_float (x) != value_get_as_float (y));
- else
- /* Hmm... Is this really right? number vs string, not unequal? */
- return (VALUE_IS_STRING (x) &&
- VALUE_IS_STRING (y) &&
- g_ascii_strcasecmp (x->v_str.val->str, y->v_str.val->str) != 0);
+ gnm_float xf, yf;
+
+ switch (criteria_inspect_values (x, y, &xf, &yf, date_conv)) {
+ default:
+ g_assert_not_reached ();
+ case CRIT_NULL:
+ case CRIT_BADFLOAT:
+ return FALSE;
+ case CRIT_FLOAT:
+ return xf == yf;
+ case CRIT_STRING:
+ /* FIXME: _ascii_??? */
+ return g_ascii_strcasecmp (value_peek_string (x),
+ value_peek_string (y)) == 0;
+ }
}
static gboolean
-criteria_test_less (GnmValue const *x, GnmValue const *y)
+criteria_test_unequal (GnmValue const *x, GnmValue const *y,
+ GODateConventions const *date_conv)
{
- if (x == NULL || y == NULL)
- return FALSE;
- if (VALUE_IS_NUMBER (x) && VALUE_IS_NUMBER (y))
- return (value_get_as_float (x) < value_get_as_float (y));
- else
+ gnm_float xf, yf;
+
+ switch (criteria_inspect_values (x, y, &xf, &yf, date_conv)) {
+ default:
+ g_assert_not_reached ();
+ case CRIT_NULL:
+ case CRIT_BADFLOAT:
return FALSE;
+ case CRIT_FLOAT:
+ return xf != yf;
+ case CRIT_STRING:
+ /* FIXME: _ascii_??? */
+ return g_ascii_strcasecmp (value_peek_string (x),
+ value_peek_string (y)) != 0;
+ }
}
static gboolean
-criteria_test_greater (GnmValue const *x, GnmValue const *y)
+criteria_test_less (GnmValue const *x, GnmValue const *y,
+ GODateConventions const *date_conv)
{
- if (x == NULL || y == NULL)
- return FALSE;
- if (VALUE_IS_NUMBER (x) && VALUE_IS_NUMBER (y))
- return (value_get_as_float (x) > value_get_as_float (y));
- else
+ gnm_float xf, yf;
+
+ switch (criteria_inspect_values (x, y, &xf, &yf, date_conv)) {
+ default:
+ g_assert_not_reached ();
+ case CRIT_NULL:
+ case CRIT_BADFLOAT:
+ case CRIT_STRING:
return FALSE;
+ case CRIT_FLOAT:
+ return xf < yf;
+ }
}
static gboolean
-criteria_test_less_or_equal (GnmValue const *x, GnmValue const *y)
+criteria_test_greater (GnmValue const *x, GnmValue const *y,
+ GODateConventions const *date_conv)
{
- if (x == NULL || y == NULL)
- return FALSE;
- if (VALUE_IS_NUMBER (x) && VALUE_IS_NUMBER (y))
- return (value_get_as_float (x) <= value_get_as_float (y));
- else
+ gnm_float xf, yf;
+
+ switch (criteria_inspect_values (x, y, &xf, &yf, date_conv)) {
+ default:
+ g_assert_not_reached ();
+ case CRIT_NULL:
+ case CRIT_BADFLOAT:
+ case CRIT_STRING:
return FALSE;
+ case CRIT_FLOAT:
+ return xf > yf;
+ }
}
static gboolean
-criteria_test_greater_or_equal (GnmValue const *x, GnmValue const *y)
+criteria_test_less_or_equal (GnmValue const *x, GnmValue const *y,
+ GODateConventions const *date_conv)
{
- if (x == NULL || y == NULL)
+ gnm_float xf, yf;
+
+ switch (criteria_inspect_values (x, y, &xf, &yf, date_conv)) {
+ default:
+ g_assert_not_reached ();
+ case CRIT_NULL:
+ case CRIT_BADFLOAT:
+ case CRIT_STRING:
return FALSE;
- if (VALUE_IS_NUMBER (x) && VALUE_IS_NUMBER (y))
- return (value_get_as_float (x) >= value_get_as_float (y));
- else
+ case CRIT_FLOAT:
+ return xf <= yf;
+ }
+}
+
+static gboolean
+criteria_test_greater_or_equal (GnmValue const *x, GnmValue const *y,
+ GODateConventions const *date_conv)
+{
+ gnm_float xf, yf;
+
+ switch (criteria_inspect_values (x, y, &xf, &yf, date_conv)) {
+ default:
+ g_assert_not_reached ();
+ case CRIT_NULL:
+ case CRIT_BADFLOAT:
+ case CRIT_STRING:
return FALSE;
+ case CRIT_FLOAT:
+ return xf >= yf;
+ }
}
/*
@@ -1643,6 +1715,8 @@
char const *t1, *t2;
GnmCell *test_cell;
GnmCriteria const *cond;
+ GODateConventions const *date_conv =
+ workbook_date_conv (sheet->workbook);
for (row = first_row; row <= last_row; row++) {
add_flag = TRUE;
@@ -1655,7 +1729,7 @@
if (test_cell != NULL) {
gnm_cell_eval (test_cell);
if (!gnm_cell_is_empty (test_cell) &&
- !cond->fun (test_cell->value, cond->x)) {
+ !cond->fun (test_cell->value, cond->x, date_conv)) {
add_flag = FALSE;
break;
}
Modified: branches/gnumeric-1-8/src/value.h
==============================================================================
--- branches/gnumeric-1-8/src/value.h (original)
+++ branches/gnumeric-1-8/src/value.h Tue Mar 25 00:16:19 2008
@@ -186,7 +186,8 @@
void value_array_set (GnmValue *array, int col, int row, GnmValue *v);
/* FIXME: this stuff below ought to go elsewhere. */
-typedef gboolean (*GnmCriteriaFunc) (GnmValue const *x, GnmValue const *y);
+typedef gboolean (*GnmCriteriaFunc) (GnmValue const *x, GnmValue const *y,
+ GODateConventions const *date_conv);
typedef struct {
GnmCriteriaFunc fun;
GnmValue *x;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]