gnumeric r16489 - in trunk: . plugins/fn-lookup src
- From: mortenw svn gnome org
- To: svn-commits-list gnome org
- Subject: gnumeric r16489 - in trunk: . plugins/fn-lookup src
- Date: Sun, 6 Apr 2008 18:59:29 +0100 (BST)
Author: mortenw
Date: Sun Apr 6 18:59:28 2008
New Revision: 16489
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16489&view=rev
Log:
2008-04-06 Morten Welinder <terra gnome org>
* src/collect.c (collect_strings): Change return type to GPtrArray
so we can actually tell if there was an error. All callers
changed. Fixes CONCATENATE.
(string_range_function): Make the subject function take a
GPtrArray for simplicity. All callers changed.
Modified:
trunk/ChangeLog
trunk/NEWS
trunk/plugins/fn-lookup/functions.c
trunk/src/collect.c
trunk/src/collect.h
trunk/src/rangefunc-strings.c
trunk/src/rangefunc-strings.h
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Sun Apr 6 18:59:28 2008
@@ -63,6 +63,7 @@
* Fix SUMIF problems. [#523250]
* Allow opening multiple files in open dialog. [#524479]
* Fix check for bogus xls files. [#524926]
+ * Fix CONCATENATE's empty case.
Nick Lamb:
* Honour detachable-toolbar preference. [#321867]
Modified: trunk/plugins/fn-lookup/functions.c
==============================================================================
--- trunk/plugins/fn-lookup/functions.c (original)
+++ trunk/plugins/fn-lookup/functions.c Sun Apr 6 18:59:28 2008
@@ -135,26 +135,37 @@
}
static int
+calc_length (GnmValue const *data, GnmEvalPos const *ep, gboolean vertical)
+{
+ if (vertical)
+ return value_area_get_height (data, ep);
+ else
+ return value_area_get_width (data, ep);
+}
+
+static const GnmValue *
+get_elem (GnmValue const *data, guint ui,
+ GnmEvalPos const *ep, gboolean vertical)
+{
+ if (vertical)
+ return value_area_fetch_x_y (data, 0, ui, ep);
+ else
+ return value_area_fetch_x_y (data, ui, 0, ep);
+}
+
+static int
find_index_linear (GnmFuncEvalInfo *ei,
GnmValue const *find, GnmValue const *data,
- gint type, gboolean height)
+ gint type, gboolean vertical)
{
GnmValue const *index_val = NULL;
GnmValDiff comp;
int length, lp, index = -1;
- if (height)
- length = value_area_get_height (data, ei->pos);
- else
- length = value_area_get_width (data, ei->pos);
+ length = calc_length (data, ei->pos, vertical);
for (lp = 0; lp < length; lp++){
- GnmValue const *v;
-
- if (height)
- v = value_area_fetch_x_y (data, 0, lp, ei->pos);
- else
- v = value_area_fetch_x_y (data, lp, 0, ei->pos);
+ GnmValue const *v = get_elem (data, lp, ei->pos, vertical);
g_return_val_if_fail (v != NULL, -1);
@@ -198,16 +209,12 @@
static int
find_index_bisection (GnmFuncEvalInfo *ei,
GnmValue const *find, GnmValue const *data,
- gint type, gboolean height)
+ gint type, gboolean vertical)
{
GnmValDiff comp = TYPE_MISMATCH;
int high, low = 0, prev = -1, mid = -1;
- if (height)
- high = value_area_get_height (data, ei->pos);
- else
- high = value_area_get_width (data, ei->pos);
- high--;
+ high = calc_length (data, ei->pos, vertical) - 1;
if (high < low) {
return -1;
@@ -236,10 +243,7 @@
while (!find_compare_type_valid (find, v) && mid != -1) {
gboolean rev = FALSE;
- if (height)
- v = value_area_get_x_y (data, 0, mid, ei->pos);
- else
- v = value_area_get_x_y (data, mid, 0, ei->pos);
+ v = get_elem (data, mid, ei->pos, vertical);
if (find_compare_type_valid (find, v))
break;
@@ -292,10 +296,7 @@
adj = mid - 1;
}
- if (height)
- v = value_area_fetch_x_y (data, 0, adj, ei->pos);
- else
- v = value_area_fetch_x_y (data, adj, 0, ei->pos);
+ v = get_elem (data, adj, ei->pos, vertical);
g_return_val_if_fail (v != NULL, -1);
Modified: trunk/src/collect.c
==============================================================================
--- trunk/src/collect.c (original)
+++ trunk/src/collect.c Sun Apr 6 18:59:28 2008
@@ -23,11 +23,11 @@
/* ------------------------------------------------------------------------- */
typedef struct {
- guint alloc_count;
- gnm_float *data;
- guint count;
- CollectFlags flags;
- GSList *info;
+ guint alloc_count;
+ gnm_float *data;
+ guint count;
+ CollectFlags flags;
+ GSList *info;
GODateConventions const *date_conv;
} collect_floats_t;
@@ -35,23 +35,19 @@
callback_function_collect (GnmEvalPos const *ep, GnmValue const *value,
void *closure)
{
- gnm_float x;
- collect_floats_t *cl = (collect_floats_t *)closure;
+ gnm_float x = 0;
+ collect_floats_t *cl = closure;
+ gboolean ignore = FALSE;
- if (value == NULL) {
- if (cl->flags & COLLECT_IGNORE_BLANKS)
- goto callback_function_collect_store_info;
- x = 0.;
- } else switch (value->type) {
+ switch (value ? value->type : VALUE_EMPTY) {
case VALUE_EMPTY:
if (cl->flags & COLLECT_IGNORE_BLANKS)
- goto callback_function_collect_store_info;
- x = 0.;
+ ignore = TRUE;
break;
case VALUE_BOOLEAN:
if (cl->flags & COLLECT_IGNORE_BOOLS)
- goto callback_function_collect_store_info;
+ ignore = TRUE;
else if (cl->flags & COLLECT_ZEROONE_BOOLS)
x = (value->v_bool.val) ? 1. : 0.;
else
@@ -64,9 +60,7 @@
case VALUE_ERROR:
if (cl->flags & COLLECT_IGNORE_ERRORS)
- goto callback_function_collect_store_info;
- else if (cl->flags & COLLECT_ZERO_ERRORS)
- x = 0.;
+ ignore = TRUE;
else
return value_new_error_VALUE (ep);
break;
@@ -90,7 +84,7 @@
if (bad)
return value_new_error_VALUE (ep);
} else if (cl->flags & COLLECT_IGNORE_STRINGS)
- goto callback_function_collect_store_info;
+ ignore = TRUE;
else if (cl->flags & COLLECT_ZERO_STRINGS)
x = 0;
else
@@ -100,29 +94,23 @@
default:
g_warning ("Trouble in callback_function_collect. (%d)",
value->type);
- goto callback_function_collect_store_info;
+ ignore = TRUE;
}
- if (cl->count == cl->alloc_count) {
- cl->alloc_count *= 2;
- cl->data = g_realloc (cl->data, cl->alloc_count * sizeof (gnm_float));
+ if (ignore) {
+ if (cl->flags & COLLECT_INFO)
+ cl->info = g_slist_prepend (cl->info, GUINT_TO_POINTER (cl->count));
+ else {
+ return NULL;
+ }
}
- cl->data[cl->count++] = x;
- return NULL;
-
- callback_function_collect_store_info:
-
- if (!(cl->flags & COLLECT_INFO))
- return NULL;
-
if (cl->count == cl->alloc_count) {
- cl->alloc_count *= 2;
- cl->data = g_realloc (cl->data, cl->alloc_count * sizeof (gnm_float));
+ cl->alloc_count = cl->alloc_count * 2 + 20;
+ cl->data = g_renew (gnm_float, cl->data, cl->alloc_count);
}
- cl->info = g_slist_prepend (cl->info, GUINT_TO_POINTER (cl->count));
- cl->data[cl->count++] = 0;
+ cl->data[cl->count++] = x;
return NULL;
}
@@ -156,7 +144,6 @@
GnmEvalPos const *ep, CollectFlags flags,
int *n, GnmValue **error, GSList **info)
{
- GnmValue * err;
collect_floats_t cl;
CellIterFlags iter_flags = CELL_ITER_ALL;
@@ -172,26 +159,29 @@
if (flags & COLLECT_IGNORE_SUBTOTAL)
iter_flags |= CELL_ITER_IGNORE_SUBTOTAL;
- cl.alloc_count = 20;
- cl.data = g_new (gnm_float, cl.alloc_count);
+ cl.alloc_count = 0;
+ cl.data = NULL;
cl.count = 0;
cl.flags = flags;
cl.info = NULL;
cl.date_conv = workbook_date_conv (ep->sheet->workbook);
- err = function_iterate_argument_values
+ *error = function_iterate_argument_values
(ep, &callback_function_collect, &cl,
argc, argv,
TRUE, iter_flags);
-
- if (err) {
- g_assert (VALUE_IS_ERROR (err));
+ if (*error) {
+ g_assert (VALUE_IS_ERROR (*error));
g_free (cl.data);
g_slist_free (cl.info);
- *error = err;
return NULL;
}
+ if (cl.data == NULL) {
+ cl.alloc_count = 1;
+ cl.data = g_new (gnm_float, cl.alloc_count);
+ }
+
if (info)
*info = cl.info;
*n = cl.count;
@@ -250,7 +240,7 @@
vals = collect_floats (argc, argv, ei->pos, flags, &n, &error, NULL);
if (!vals)
- return (error != VALUE_TERMINATE) ? error : NULL;
+ return error;
err = func (vals, n, &res);
g_free (vals);
@@ -439,49 +429,38 @@
/* ------------------------------------------------------------------------- */
typedef struct {
- GSList *data;
- CollectFlags flags;
+ GPtrArray *data;
+ CollectFlags flags;
} collect_strings_t;
static GnmValue *
callback_function_collect_strings (GnmEvalPos const *ep, GnmValue const *value,
void *closure)
{
- char *text = NULL;
+ char *text;
collect_strings_t *cl = closure;
- if (value == NULL) {
+ if (VALUE_IS_EMPTY (value)) {
if (cl->flags & COLLECT_IGNORE_BLANKS)
- return NULL;
- text = g_strdup ("");
- } else switch (value->type) {
- case VALUE_EMPTY:
- case VALUE_BOOLEAN:
- case VALUE_FLOAT:
- case VALUE_STRING:
- text = value_get_as_string (value);
- break;
- case VALUE_CELLRANGE :
- case VALUE_ARRAY :
- text = value_get_as_string (value);
- break;
- case VALUE_ERROR:
- if (cl->flags & COLLECT_IGNORE_ERRORS)
- return NULL;
- else if (cl->flags & COLLECT_ZERO_ERRORS)
- text = g_strdup ("");
+ text = NULL;
else
- return value_new_error_VALUE (ep);
- break;
- default:
- g_assert_not_reached ();
- break;
- }
+ text = g_strdup ("");
+ } else
+ text = value_get_as_string (value);
+
+ if (text)
+ g_ptr_array_add (cl->data, text);
- cl->data = g_slist_prepend (cl->data, text);
return NULL;
}
+static void
+collect_strings_free (GPtrArray *data)
+{
+ g_ptr_array_foreach (data, (GFunc)g_free, NULL);
+ g_ptr_array_free (data, TRUE);
+}
+
/*
* collect_strings:
*
@@ -493,37 +472,37 @@
* NULL in case of error, error will be set
* Non-NULL in case of success.
*
- * Evaluate a list of expressions and return the result as an array of
- * gnm_float.
+ * Evaluate a list of expressions and return the result as a GPtrArray of
+ * strings.
*/
-static GSList *
+static GPtrArray *
collect_strings (int argc, GnmExprConstPtr const *argv,
GnmEvalPos const *ep, CollectFlags flags,
GnmValue **error)
{
- GnmValue * err;
collect_strings_t cl;
+ CellIterFlags iter_flags = CELL_ITER_ALL;
- cl.data = NULL;
+ if (flags & COLLECT_IGNORE_BLANKS)
+ iter_flags = CELL_ITER_IGNORE_BLANK;
+
+ cl.data = g_ptr_array_new ();
cl.flags = flags;
- err = function_iterate_argument_values
+ *error = function_iterate_argument_values
(ep, &callback_function_collect_strings, &cl,
argc, argv,
- TRUE, (flags & COLLECT_IGNORE_BLANKS) ? CELL_ITER_IGNORE_BLANK : CELL_ITER_ALL);
-
- if (err) {
- g_assert (VALUE_IS_ERROR (err));
- go_slist_free_custom (cl.data, g_free);
- *error = err;
+ TRUE, iter_flags);
+ if (*error) {
+ g_assert (VALUE_IS_ERROR (*error));
+ collect_strings_free (cl.data);
return NULL;
}
- return g_slist_reverse (cl.data);
+ return cl.data;
}
-
GnmValue *
string_range_function (int argc, GnmExprConstPtr const *argv,
GnmFuncEvalInfo *ei,
@@ -532,16 +511,17 @@
GnmStdError func_error)
{
GnmValue *error = NULL;
- GSList *vals;
+ GPtrArray *vals;
char *res = NULL;
int err;
vals = collect_strings (argc, argv, ei->pos, flags, &error);
if (!vals)
- return (error != VALUE_TERMINATE) ? error : NULL;
+ return error;
err = func (vals, &res);
- go_slist_free_custom (vals, g_free);
+
+ collect_strings_free (vals);
if (err) {
g_free (res);
Modified: trunk/src/collect.h
==============================================================================
--- trunk/src/collect.h (original)
+++ trunk/src/collect.h Sun Apr 6 18:59:28 2008
@@ -16,17 +16,17 @@
COLLECT_ZEROONE_BOOLS = 0x20,
COLLECT_IGNORE_ERRORS = 0x100,
- COLLECT_ZERO_ERRORS = 0x200,
COLLECT_IGNORE_BLANKS = 0x1000,
COLLECT_IGNORE_SUBTOTAL = 0x2000,
- COLLECT_INFO = 0x8000
-} CollectFlags;
+ /* Not for general usage. */
+ COLLECT_INFO = 0x1000000
+} CollectFlags;
typedef int (*float_range_function_t) (gnm_float const *, int, gnm_float *);
typedef int (*float_range_function2_t) (gnm_float const *, gnm_float const *, int, gnm_float *);
-typedef int (*string_range_function_t) (GSList *, char**);
+typedef int (*string_range_function_t) (GPtrArray *, char**);
/*gnm_float *collect_floats (int argc, GnmExprConstPtr const *argv,
GnmEvalPos const *ep, CollectFlags flags,
@@ -52,6 +52,7 @@
float_range_function2_t func,
CollectFlags flags,
GnmStdError func_error);
+
GnmValue *string_range_function (int argc, GnmExprConstPtr const *argv,
GnmFuncEvalInfo *ei,
string_range_function_t func,
@@ -62,6 +63,7 @@
GArray *gnm_strip_missing (GArray * data, GSList **missing);
+
G_END_DECLS
#endif /* _GNM_COLLECT_H_ */
Modified: trunk/src/rangefunc-strings.c
==============================================================================
--- trunk/src/rangefunc-strings.c (original)
+++ trunk/src/rangefunc-strings.c Sun Apr 6 18:59:28 2008
@@ -11,20 +11,21 @@
#include <string.h>
-static void
-cb_concatenate (char const *text, GString *str)
-{
- g_string_append (str, text);
-}
-
int
-range_concatenate (GSList *data, char **res)
+range_concatenate (GPtrArray *data, char **res)
{
- GString *str = g_string_new (NULL);
+ unsigned ui;
+ size_t len = 0;
+ GString *str;
- g_slist_foreach (data, (GFunc) cb_concatenate, str);
+ for (ui = 0; ui < data->len; ui++)
+ len += strlen (g_ptr_array_index (data, ui));
+
+ str = g_string_sized_new (len);
+
+ for (ui = 0; ui < data->len; ui++)
+ g_string_append (str, g_ptr_array_index (data, ui));
*res = g_string_free (str, FALSE);
return 0;
}
-
Modified: trunk/src/rangefunc-strings.h
==============================================================================
--- trunk/src/rangefunc-strings.h (original)
+++ trunk/src/rangefunc-strings.h Sun Apr 6 18:59:28 2008
@@ -6,7 +6,7 @@
G_BEGIN_DECLS
-int range_concatenate (GSList *data, char **res);
+int range_concatenate (GPtrArray *data, char **res);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]