Ejemplo n.º 1
0
static GPtrArray *
collect_strings (int argc, GnmExprConstPtr const *argv,
		 GnmEvalPos const *ep, CollectFlags flags,
		 GnmValue **error)
{
	collect_strings_t cl;
	CellIterFlags iter_flags = CELL_ITER_ALL;
	gboolean strict;

	/* We don't handle these flags */
	g_return_val_if_fail (!(flags & COLLECT_ZERO_ERRORS), NULL);
	g_return_val_if_fail (!(flags & COLLECT_ZERO_STRINGS), NULL);
	g_return_val_if_fail (!(flags & COLLECT_ZEROONE_BOOLS), NULL);
	g_return_val_if_fail (!(flags & COLLECT_ZERO_BLANKS), NULL);

	if (flags & COLLECT_IGNORE_BLANKS)
		iter_flags = CELL_ITER_IGNORE_BLANK;

	strict = (flags & (COLLECT_IGNORE_ERRORS | COLLECT_ZERO_ERRORS)) == 0;

	cl.data = g_ptr_array_new ();
	cl.flags = flags;

	*error = function_iterate_argument_values
		(ep, &callback_function_collect_strings, &cl,
		 argc, argv,
		 strict, iter_flags);
	if (*error) {
		g_assert (VALUE_IS_ERROR (*error));
		collect_strings_free (cl.data);
		return NULL;
	}

	return cl.data;
}
Ejemplo n.º 2
0
static GnmValue *
gnumeric_and (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
{
	int result = -1;

	/* Yes, AND is actually strict.  */
	GnmValue *v = function_iterate_argument_values
		(ei->pos, callback_function_and, &result,
		 argc, argv, TRUE, CELL_ITER_IGNORE_BLANK);
	if (v != NULL)
		return v;

	/* See if there was any value worth using */
	if (result == -1)
		return value_new_error_VALUE (ei->pos);

	return value_new_bool (result);
}
Ejemplo n.º 3
0
static GnmValue *
gnumeric_simtable (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
{
	simtable_t p;

	p.index = 0;
	p.value = NULL;

	function_iterate_argument_values
		(ei->pos, callback_function_simtable, &p,
		 argc, argv, FALSE, CELL_ITER_IGNORE_BLANK);

	/* See if there was any value worth using. */
	if (p.value == NULL)
		return value_new_error_NA (ei->pos);

	return p.value;
}
Ejemplo n.º 4
0
/*
 * collect_floats:
 *
 * exprlist:       List of expressions to evaluate.
 * cr:             Current location (for resolving relative cells).
 * flags:          COLLECT_IGNORE_STRINGS: silently ignore strings.
 *                 COLLECT_COERCE_STRINGS: coerce string into numbers
 *                 COLLECT_ZERO_STRINGS: count strings as 0.
 *                   (Alternative: return #VALUE!.)
 *                 COLLECT_IGNORE_BOOLS: silently ignore bools.
 *                 COLLECT_ZEROONE_BOOLS: count FALSE as 0, TRUE as 1.
 *                   (Alternative: return #VALUE!.)
 *		   COLLECT_IGNORE_SUBTOTAL : ignore expressions that include
 *			the function SUBTOTAL directly and ignore any content
 *			in filtered rows.
 * n:              Output parameter for number of floats.
 *
 * Return value:
 *   NULL in case of strict and a blank.
 *   A copy of the error in the case of strict and an error.
 *   Non-NULL in case of success.  Then n will be set.
 *
 * Evaluate a list of expressions and return the result as an array of
 * gnm_float.
 */
static gnm_float *
collect_floats (int argc, GnmExprConstPtr const *argv,
		GnmEvalPos const *ep, CollectFlags flags,
		int *n, GnmValue **error, GSList **info,
		gboolean *constp)
{
	collect_floats_t cl;
	CellIterFlags iter_flags = CELL_ITER_ALL;
	GnmValue *key = NULL;
	CollectFlags keyflags = flags & ~COLLECT_ORDER_IRRELEVANT;
	gboolean strict;

	if (constp)
		*constp = FALSE;

	if (info) {
		*info = NULL;
		g_return_val_if_fail (!(flags & COLLECT_SORT), NULL);
		flags |= COLLECT_INFO;
	} else {
		if (flags & COLLECT_IGNORE_BLANKS)
			iter_flags = CELL_ITER_IGNORE_BLANK;
		flags &= ~COLLECT_INFO;
	}

	/* ---------------------------------------- */
	/* Try cache. */

	if (argc == 1 &&
	    (flags & (COLLECT_INFO | COLLECT_IGNORE_SUBTOTAL)) == 0) {
		key = get_single_cache_key (argv[0], ep);
	}
	if (key) {
		SingleFloatsCacheEntry *ce =
			get_or_fake_cache_entry (key, keyflags, ep);
		if (ce) {
			value_release (key);
			if (ce->error) {
				*error = value_dup (ce->error);
				return NULL;
			}
			*n = ce->n;
			if (constp) {
				*constp = TRUE;
				return ce->data;
			}
			return g_memdup (ce->data, *n * sizeof (gnm_float));
		}
	}

	/* ---------------------------------------- */

	if (flags & COLLECT_IGNORE_SUBTOTAL)
		iter_flags |= (CELL_ITER_IGNORE_SUBTOTAL |
			       CELL_ITER_IGNORE_FILTERED);

	strict = (flags & (COLLECT_IGNORE_ERRORS | COLLECT_ZERO_ERRORS)) == 0;

	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);

	*error = function_iterate_argument_values
		(ep, &callback_function_collect, &cl,
		 argc, argv,
		 strict, iter_flags);
	if (*error) {
		g_assert (VALUE_IS_ERROR (*error));
		g_free (cl.data);
		cl.data = NULL;
		cl.count = 0;
		g_slist_free (cl.info);
		cl.info = NULL;
	} else {
		if (cl.data == NULL) {
			cl.alloc_count = 1;
			cl.data = g_new (gnm_float, cl.alloc_count);
		}

		if (flags & COLLECT_SORT) {
			qsort (cl.data, cl.count, sizeof (cl.data[0]),
			       float_compare);
		}
	}

	if (info)
		*info = cl.info;
	*n = cl.count;

	if (key) {
		SingleFloatsCacheEntry *ce = g_new (SingleFloatsCacheEntry, 1);
		SingleFloatsCacheEntry *ce2;
		ce->value = key;
		ce->flags = keyflags;
		ce->n = *n;
		ce->error = value_dup (*error);
		if (cl.data == NULL)
			ce->data = NULL;
		else if (constp) {
			*constp = TRUE;
			ce->data = cl.data;
		} else
			ce->data = g_memdup (cl.data, MAX (1, *n) * sizeof (gnm_float));
		prune_caches ();

		/*
		 * We looked for the entry earlier and it was not there.
		 * However, sub-calculation might have added it so be careful
		 * to adjust sizes and replace the not-so-old entry.
		 * See bug 627079.
		 */
		ce2 = g_hash_table_lookup (single_floats_cache, ce);
		if (ce2)
			total_cache_size -= 1 + ce2->n;

		g_hash_table_replace (single_floats_cache, ce, ce);
		total_cache_size += 1 + *n;
	}
	return cl.data;
}