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; }
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); }
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; }
/* * 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; }