/** * parse_criteria: * @crit_val: #GnmValue * @date_conv: #GODateConventions * * Returns: (transfer full): GnmCriteria which caller must free. * * ">=value" * "<=value" * "<>value" * "<value" * ">value" * "=value" * "pattern" **/ GnmCriteria * parse_criteria (GnmValue const *crit_val, GODateConventions const *date_conv, gboolean anchor_end) { int len; char const *criteria; GnmCriteria *res = g_new0 (GnmCriteria, 1); GnmValue *empty; res->iter_flags = CELL_ITER_IGNORE_BLANK; res->date_conv = date_conv; if (VALUE_IS_NUMBER (crit_val)) { res->fun = criteria_test_equal; res->x = value_dup (crit_val); return res; } criteria = value_peek_string (crit_val); if (strncmp (criteria, "<=", 2) == 0) { res->fun = criteria_test_less_or_equal; len = 2; } else if (strncmp (criteria, ">=", 2) == 0) { res->fun = criteria_test_greater_or_equal; len = 2; } else if (strncmp (criteria, "<>", 2) == 0) { /* "<>" by itself is special: */ res->fun = (criteria[2] == 0) ? criteria_test_nonempty : criteria_test_unequal; len = 2; } else if (*criteria == '<') { res->fun = criteria_test_less; len = 1; } else if (*criteria == '=') { /* "=" by itself is special: */ res->fun = (criteria[1] == 0) ? criteria_test_empty : criteria_test_equal; len = 1; } else if (*criteria == '>') { res->fun = criteria_test_greater; len = 1; } else { res->fun = criteria_test_match; res->has_rx = (gnm_regcomp_XL (&res->rx, criteria, GO_REG_ICASE, TRUE, anchor_end) == GO_REG_OK); len = 0; } res->x = format_match_number (criteria + len, NULL, date_conv); if (res->x == NULL) res->x = value_new_string (criteria + len); else if (len == 0 && VALUE_IS_NUMBER (res->x)) res->fun = criteria_test_equal; empty = value_new_empty (); if (res->fun (empty, res)) res->iter_flags &= ~CELL_ITER_IGNORE_BLANK; value_release (empty); res->ref_count = 1; return res; }
static GnmExpr const * contents_as_expr (GnmExprTop const *texpr, GnmValue const *val) { if (texpr) return gnm_expr_copy (texpr->expr); if (VALUE_IS_EMPTY (val)) return gnm_expr_new_constant (value_new_float (0.0)); if (VALUE_IS_NUMBER (val)) return gnm_expr_new_constant (value_dup (val)); return NULL; }
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; }
static gnm_float get_value (GnmNlsolve *nl) { GnmValue const *v; gnm_cell_eval (nl->target); v = nl->target->value; if (VALUE_IS_NUMBER (v) || VALUE_IS_EMPTY (v)) { gnm_float y = value_get_as_float (v); return nl->maximize ? 0 - y : y; } else return gnm_nan; }
static void paste_cell_with_operation (Sheet *dst_sheet, int target_col, int target_row, GnmExprRelocateInfo const *rinfo, GnmCellCopy const *src, int paste_flags) { GnmCell *dst; GnmExprOp op; if (src->texpr == NULL && !VALUE_IS_EMPTY (src->val) && !VALUE_IS_NUMBER (src->val)) return; dst = sheet_cell_fetch (dst_sheet, target_col, target_row); if (!cell_has_expr_or_number_or_blank (dst)) return; op = paste_op_to_expr_op (paste_flags); /* FIXME : This does not handle arrays, linked cells, ranges, etc. */ if ((paste_flags & PASTE_CONTENTS) && (NULL != src->texpr || gnm_cell_has_expr (dst))) { GnmExpr const *old_expr = contents_as_expr (dst->base.texpr, dst->value); GnmExpr const *copied_expr = contents_as_expr (src->texpr, src->val); GnmExprTop const *res = gnm_expr_top_new (gnm_expr_new_binary (old_expr, op, copied_expr)); GnmExprTop const *relo = gnm_expr_top_relocate (res, rinfo, FALSE); if (relo) { gnm_cell_set_expr (dst, relo); gnm_expr_top_unref (relo); } else gnm_cell_set_expr (dst, res); gnm_expr_top_unref (res); } else { GnmValue *value; GnmEvalPos pos; GnmExpr const *expr = gnm_expr_new_binary ( gnm_expr_new_constant (value_dup (dst->value)), op, gnm_expr_new_constant (value_dup (src->val))); GnmExprTop const *texpr = gnm_expr_top_new (expr); eval_pos_init_cell (&pos, dst); pos.dep = NULL; /* no dynamic deps */ value = gnm_expr_top_eval (texpr, &pos, GNM_EXPR_EVAL_SCALAR_NON_EMPTY); gnm_expr_top_unref (texpr); gnm_cell_set_value (dst, value); } }
static GnmExpr const * xlsx_func_dist_handler (GnmExprList *args, guint n_args, char const *name, char const *name_p, char const *name_d) { if (gnm_expr_list_length (args) != n_args) { GnmFunc *f = gnm_func_lookup_or_add_placeholder (name); return gnm_expr_new_funcall (f, args); } else { GnmFunc *f_if = gnm_func_lookup_or_add_placeholder ("if"); GnmFunc *f_p = gnm_func_lookup_or_add_placeholder (name_p); GnmFunc *f_d = gnm_func_lookup_or_add_placeholder (name_d); GnmExprList *arg_cum, *args_c; GnmExpr const *cum; GnmValue const *constant; arg_cum = g_slist_nth (args, n_args - 1); args = g_slist_remove_link (args, arg_cum); cum = arg_cum->data; gnm_expr_list_free (arg_cum); constant = gnm_expr_get_constant (cum); if (constant == NULL || !VALUE_IS_NUMBER (constant)) { args_c = gnm_expr_list_copy (args); return gnm_expr_new_funcall3 (f_if, cum, gnm_expr_new_funcall (f_p, args), gnm_expr_new_funcall (f_d, args_c)); } else if (value_is_zero (constant)) { gnm_expr_free (cum); return gnm_expr_new_funcall (f_d, args); } else { gnm_expr_free (cum); return gnm_expr_new_funcall (f_p, args); } } }
gnm_float datetime_value_to_serial_raw (GnmValue const *v, GODateConventions const *conv) { gnm_float serial; if (VALUE_IS_NUMBER (v)) serial = value_get_as_float (v); else { char const *str = value_peek_string (v); GnmValue *conversion = format_match_number (str, go_format_default_date (), conv); if (conversion) { serial = value_get_as_float (conversion); value_release (conversion); } else serial = G_MAXINT; } if (serial < 0 && !gnm_datetime_allow_negative ()) serial = G_MAXINT; return serial; }
/** * xlsx_func_r_q_output_handler: * * @out: #GnmConventionsOut * @func: #GnmExprFunction * @n: last index used for a parameter * @n_p: index of the probability argument, usually 0 * @name: * * Print the appropriate simple function call */ static gboolean xlsx_func_r_q_output_handler (GnmConventionsOut *out, GnmExprFunction const *func, int n, int n_p, char const *name, char const *name_rt) { GnmExprConstPtr const *ptr = func->argv; GString *target = out->accum; int use_lower_tail; /* 0: never; 1: always; 2: sometimes */ int use_log; /* 0: never; 1: always; 2: sometimes */ if (func->argc <= n || func->argc > (n+3)) return FALSE; if (func->argc > n+1) { GnmValue const *constant = gnm_expr_get_constant (ptr[n+1]); if (constant == NULL || !VALUE_IS_NUMBER (constant)) use_lower_tail = 2; else use_lower_tail = value_is_zero (constant) ? 0 : 1; } else use_lower_tail = 1; if (func->argc > n+2) { GnmValue const *constant = gnm_expr_get_constant (ptr[n+2]); if (constant == NULL || !VALUE_IS_NUMBER (constant)) use_log = 2; else use_log = value_is_zero (constant) ? 0 : 1; } else use_log = 0; if (use_lower_tail < 2 && use_log == 0) { /* R.Qx(a,b,c) --> name(a,b,c) */ /* R.Qx(a,b,c) --> name(1-a,b,c) */ xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, use_lower_tail, 0); return TRUE; } else if (use_lower_tail < 2 && use_log == 1) { /* R.Qx(a,b,c) --> name(exp(a),b,c) */ /* R.Qx(a,b,c) --> name(1-exp(a),b,c) */ xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, use_lower_tail, 1); return TRUE; } else if (/* use_lower_tail == 2 && */ use_log == 0) { /* R.Qx(a,b,c,d) --> if(d,name(a,b,c), name(1-a,b,c)) */ g_string_append (target, "if("); gnm_expr_as_gstring (ptr[n+1], out); g_string_append_c (target, ','); xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, 1, 0); g_string_append_c (target, ','); xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, 0, 0); g_string_append_c (target, ')'); return TRUE; } else if (use_lower_tail < 2 /* && use_log == 2 */) { /* R.Qx(a,b,c,d,e) --> if(e,name(1-exp(a),b,c),name(1-a,b,c))*/ /* R.Qx(a,b,c,d,e) --> if(e,name(exp(a),b,c),name(a,b,c))*/ g_string_append (target, "if("); gnm_expr_as_gstring (ptr[n+2], out); g_string_append_c (target, ','); xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, use_lower_tail, 1); g_string_append_c (target, ','); xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, use_lower_tail, 0); g_string_append_c (target, ')'); return TRUE; } else /*if (use_lower_tail == 2 && use_log == 2 */ { /* R.Qx(a,b,c,d,e) --> if(d,if(e,name(exp(a),b,c),name(a,b,c)), if(e,name(1-exp(a),b,c),name(1-a,b,c)))*/ g_string_append (target, "if("); gnm_expr_as_gstring (ptr[n+1], out); g_string_append (target, ",if("); gnm_expr_as_gstring (ptr[n+2], out); g_string_append_c (target, ','); xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, 1, 1); g_string_append_c (target, ','); xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, 1, 0); g_string_append (target, "),if("); gnm_expr_as_gstring (ptr[n+2], out); g_string_append_c (target, ','); xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, 0, 1); g_string_append_c (target, ','); xlsx_write_r_q_func (out, name, name_rt, ptr, n, n_p, 0, 0); g_string_append (target, "))"); return TRUE; } }
static gboolean tool_random_engine_run_discrete_last_check (G_GNUC_UNUSED data_analysis_output_t *dao, tools_data_random_t *info, discrete_random_tool_t *param, discrete_random_tool_local_t **continuity) { discrete_random_tool_local_t *data; GnmValue *range = param->range; gnm_float cumprob = 0; int j = 0; int i; data = *continuity = g_new0 (discrete_random_tool_local_t, 1); data->n = range->v_range.cell.b.row - range->v_range.cell.a.row + 1; data->cumul_p = g_new (gnm_float, data->n); data->values = g_new0 (GnmValue *, data->n); for (i = range->v_range.cell.a.row; i <= range->v_range.cell.b.row; i++, j++) { GnmValue *v; gnm_float thisprob; GnmCell *cell = sheet_cell_get (range->v_range.cell.a.sheet, range->v_range.cell.a.col + 1, i); if (cell == NULL || (v = cell->value) == NULL || !VALUE_IS_NUMBER (v)) { gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->wbc), _("The probability input range " "contains a non-numeric value.\n" "All probabilities must be " "non-negative numbers.")); goto random_tool_discrete_out; } if ((thisprob = value_get_as_float (v)) < 0) { gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->wbc), _("The probability input range " "contains a negative number.\n" "All probabilities must be " "non-negative!")); goto random_tool_discrete_out; } cumprob += thisprob; data->cumul_p[j] = cumprob; cell = sheet_cell_get (range->v_range.cell.a.sheet, range->v_range.cell.a.col, i); if (cell == NULL || cell->value == NULL) { gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->wbc), _("None of the values in the value " "range may be empty!")); goto random_tool_discrete_out; } data->values[j] = value_dup (cell->value); } if (cumprob != 0) { /* Rescale... */ for (i = 0; i < data->n; i++) { data->cumul_p[i] /= cumprob; } return FALSE; } gnm_cmd_context_error_calc (GO_CMD_CONTEXT (info->wbc), _("The probabilities may not all be 0!")); random_tool_discrete_out: tool_random_engine_run_discrete_clear_continuity (continuity); return TRUE; }