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; }
void pretty_print(env_t *env, VALUE v, int i) { if (VALUE_IS_ERROR(v)) { printf("<error>\n"); } else if (IS_LIST(v)) { printf("(\n"); int j; for (j = 0; j < list_len(v); j++) { indent(i + 1); pretty_print(env, list_get(v, j), i + 1); } indent(i); printf(")\n"); } else { if (VALUE_IS_INT(v)) { printf("%lld\n", INTVAL(v)); } else if (VALUE_IS_BOOL(v)) { printf("#%c\n", BOOLVAL(v) ? 't' : 'f'); } else if (VALUE_IS_NIL(v)) { printf("#nil\n"); } else if (VALUE_IS_IDENT(v)) { printf("%s\n", intern_table_get_str(&env->intern, IDENT(v))); } else if (VALUE_IS_ATOM(v)) { printf(":%s\n", intern_table_get_str(&env->intern, ATOM(v))); } else if (IS_STRING(v)) { printf("\"%s\"\n", string_chars(v)); } else { printf("<unknown %p>\n", v); } } }
static CritType criteria_inspect_values (GnmValue const *x, gnm_float *xr, gnm_float *yr, GnmCriteria *crit, gboolean coerce_to_float) { GnmValue const *y = crit->x; if (x == NULL || y == NULL) return CRIT_NULL; switch (y->v_any.type) { case VALUE_BOOLEAN: /* If we're searching for a bool -- even one that is from a string search value -- we match only bools. */ if (!VALUE_IS_BOOLEAN (x)) return CRIT_WRONGTYPE; *xr = value_get_as_float (x); *yr = value_get_as_float (y); return CRIT_FLOAT; case VALUE_EMPTY: return CRIT_WRONGTYPE; case VALUE_STRING: if (!VALUE_IS_STRING (x)) return CRIT_WRONGTYPE; return CRIT_STRING; default: g_warning ("This should not happen. Please report."); return CRIT_WRONGTYPE; case VALUE_FLOAT: { GnmValue *vx; *yr = value_get_as_float (y); if (VALUE_IS_BOOLEAN (x) || VALUE_IS_ERROR (x)) return CRIT_WRONGTYPE; else if (VALUE_IS_FLOAT (x)) { *xr = value_get_as_float (x); return CRIT_FLOAT; } if (!coerce_to_float) return CRIT_WRONGTYPE; vx = format_match (value_peek_string (x), NULL, crit->date_conv); if (VALUE_IS_EMPTY (vx) || VALUE_IS_BOOLEAN (y) != VALUE_IS_BOOLEAN (vx)) { value_release (vx); return CRIT_WRONGTYPE; } *xr = value_get_as_float (vx); value_release (vx); return CRIT_FLOAT; } } }
static GnmValue * cb_sylk_write_cell (GnmCellIter const *iter, SylkWriter *state) { GnmValue const *v; GnmExprTop const *texpr; GnmExprArrayCorner const *array; if (iter->pp.eval.row != state->cur_row) gsf_output_printf (state->output, "C;Y%d;X%d", (state->cur_row = iter->pp.eval.row) + 1, iter->pp.eval.col + 1); else gsf_output_printf (state->output, "C;X%d", iter->pp.eval.col + 1); if (NULL != (v = iter->cell->value)) { if (VALUE_IS_STRING (v)) { gsf_output_write (state->output, 3, ";K\""); sylk_write (state, v->v_str.val->str); gsf_output_write (state->output, 1, "\""); } else if (VALUE_IS_NUMBER (v) || VALUE_IS_ERROR (v)) { GString *res = g_string_sized_new (10); value_get_as_gstring (v, res, state->convs); gsf_output_write (state->output, 2, ";K"); gsf_output_write (state->output, res->len, res->str); g_string_free (res, TRUE); } /* ignore the rest */ } if (NULL != (texpr = iter->cell->base.texpr)) { if (NULL != (array = gnm_expr_top_get_array_corner (texpr))) { gsf_output_printf (state->output, ";R%d;C%d;M", iter->pp.eval.row + array->rows, iter->pp.eval.col + array->cols); } else if (gnm_expr_top_is_array_elem (texpr, NULL, NULL)) { gsf_output_write (state->output, 2, ";I"); texpr = NULL; } else gsf_output_write (state->output, 2, ";E"); if (texpr != NULL) { GnmConventionsOut out; out.accum = g_string_new (NULL); out.pp = &iter->pp; out.convs = state->convs; gnm_expr_top_as_gstring (texpr, &out); sylk_write (state, out.accum->str); g_string_free (out.accum, TRUE); } } gsf_output_write (state->output, 2, "\r\n"); return NULL; }
GnmValue * gnm_ifs_func (GPtrArray *data, GPtrArray *crits, GnmValue const *vals, float_range_function_t fun, GnmStdError err, GnmEvalPos const *ep, CollectFlags flags) { int sx, sy, x, y; unsigned ui, N = 0, nalloc = 0; gnm_float *xs = NULL; GnmValue *res = NULL; gnm_float fres; g_return_val_if_fail (data->len == crits->len, NULL); if (flags & ~(COLLECT_IGNORE_STRINGS | COLLECT_IGNORE_BOOLS | COLLECT_IGNORE_BLANKS | COLLECT_IGNORE_ERRORS)) { g_warning ("unsupported flags in gnm_ifs_func %x", flags); } sx = value_area_get_width (vals, ep); sy = value_area_get_height (vals, ep); for (ui = 0; ui < data->len; ui++) { GnmValue const *datai = g_ptr_array_index (data, ui); if (value_area_get_width (datai, ep) != sx || value_area_get_height (datai, ep) != sy) return value_new_error_VALUE (ep); } for (y = 0; y < sy; y++) { for (x = 0; x < sx; x++) { GnmValue const *v; gboolean match = TRUE; for (ui = 0; match && ui < crits->len; ui++) { GnmCriteria *crit = g_ptr_array_index (crits, ui); GnmValue const *datai = g_ptr_array_index (data, ui); v = value_area_get_x_y (datai, x, y, ep); match = crit->fun (v, crit); } if (!match) continue; // Match. Maybe collect the data point. v = value_area_get_x_y (vals, x, y, ep); if ((flags & COLLECT_IGNORE_STRINGS) && VALUE_IS_STRING (v)) continue; if ((flags & COLLECT_IGNORE_BOOLS) && VALUE_IS_BOOLEAN (v)) continue; if ((flags & COLLECT_IGNORE_BLANKS) && VALUE_IS_EMPTY (v)) continue; if ((flags & COLLECT_IGNORE_ERRORS) && VALUE_IS_ERROR (v)) continue; if (VALUE_IS_ERROR (v)) { res = value_dup (v); goto out; } if (N >= nalloc) { nalloc = (2 * nalloc) + 100; xs = g_renew (gnm_float, xs, nalloc); } xs[N++] = value_get_as_float (v); } } if (fun (xs, N, &fres)) { res = value_new_error_std (ep, err); } else res = value_new_float (fres); out: g_free (xs); return res; }
/* * 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; }
/* * Write _current_ sheet of the workbook to a DIF format file */ void dif_file_save (GOFileSaver const *fs, GOIOContext *io_context, WorkbookView const *wbv, GsfOutput *out) { GnmLocale *locale; Sheet *sheet; GnmRange r; gint row, col; gboolean ok = TRUE; sheet = wb_view_cur_sheet (wbv); if (sheet == NULL) { go_io_error_string (io_context, _("Cannot get default sheet.")); return; } r = sheet_get_extent (sheet, FALSE, TRUE); /* Write out the standard headers */ gsf_output_puts (out, "TABLE\n" "0,1\n" "\"GNUMERIC\"\n"); gsf_output_printf (out, "VECTORS\n" "0,%d\n" "\"\"\n", r.end.col+1); gsf_output_printf (out, "TUPLES\n" "0,%d\n" "\"\"\n", r.end.row+1); gsf_output_puts (out, "DATA\n" "0,0\n" "\"\"\n"); locale = gnm_push_C_locale (); /* Process all cells */ for (row = r.start.row; ok && row <= r.end.row; row++) { gsf_output_puts (out, "-1,0\n" "BOT\n"); for (col = r.start.col; col <= r.end.col; col++) { GnmCell *cell = sheet_cell_get (sheet, col, row); if (gnm_cell_is_empty (cell)) { gsf_output_puts(out, "1,0\n" "\"\"\n"); } else if (VALUE_IS_BOOLEAN (cell->value)) { if (value_get_as_checked_bool (cell->value)) gsf_output_puts(out, "0,1\n" "TRUE\n"); else gsf_output_puts(out, "0,0\n" "FALSE\n"); } else if (VALUE_IS_ERROR (cell->value)) { if (value_error_classify (cell->value) == GNM_ERROR_NA) gsf_output_puts(out, "0,0\n" "NA\n"); else gsf_output_puts(out, "0,0\n" "ERROR\n"); } else if (VALUE_IS_FLOAT (cell->value)) gsf_output_printf (out, "0,%" GNM_FORMAT_g "\n" "V\n", value_get_as_float (cell->value)); else { gchar *str = gnm_cell_get_rendered_text (cell); ok = gsf_output_printf (out, "1,0\n" "\"%s\"\n", str); g_free (str); } } } gsf_output_puts (out, "-1,0\n" "EOD\n"); gnm_pop_C_locale (locale); if (!ok) go_io_error_string (io_context, _("Error while saving DIF file.")); }
static GnmValue * gnumeric_iferror (GnmFuncEvalInfo *ei, GnmValue const * const *argv) { return value_dup (VALUE_IS_ERROR (argv[0]) ? argv[1] : argv[0]); }