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); } } }
static int zero_callback_max(struct value *ret_value, struct value *lhs, struct value_dict *arguments, size_t max, void *data) { size_t i; for (i = 0; i < max; ++i) { struct value element; if (value_init_element(&element, lhs, i) < 0) return -1; int zero = value_is_zero(&element, arguments); value_destroy(&element); if (zero) break; } struct arg_type_info *long_type = type_get_simple(ARGTYPE_LONG); value_init_detached(ret_value, NULL, long_type, 0); value_set_word(ret_value, i); return 0; }
/** * 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; } }