Ejemplo n.º 1
0
/**
 * expr_name_as_string :
 * @nexpr :
 * @pp : optionally null.
 *
 * returns a string that the caller needs to free.
 */
char *
expr_name_as_string (GnmNamedExpr const *nexpr, GnmParsePos const *pp,
		     GnmConventions const *fmt)
{
	if (pp == NULL)
		pp = &nexpr->pos;
	return gnm_expr_top_as_string (nexpr->texpr, pp, fmt);
}
Ejemplo n.º 2
0
static GnmValue *
cb_get_content (GnmCellIter const *iter, GsfOutput *buf)
{
	GnmCell *cell;

	if (NULL != (cell = iter->cell)) {
		char *tmp;
		if (gnm_cell_has_expr (cell))
			tmp = gnm_expr_top_as_string (cell->base.texpr,
				&iter->pp, iter->pp.sheet->convs);
		else if (VALUE_FMT (cell->value) != NULL)
			tmp = format_value (NULL, cell->value, -1,
				workbook_date_conv (iter->pp.wb));
		else
			tmp = value_get_as_string (cell->value);

		gsf_output_write (buf, strlen (tmp), tmp);
		g_free (tmp);
	}
	gsf_output_write (buf, 1, "\n");

	return NULL;
}
Ejemplo n.º 3
0
/**
 * gnm_validation_eval:
 * @wbc:
 * @mstyle:
 * @sheet:
 *
 * validation set in the GnmStyle if applicable.
 **/
ValidationStatus
gnm_validation_eval (WorkbookControl *wbc, GnmStyle const *mstyle,
		 Sheet *sheet, GnmCellPos const *pos, gboolean *showed_dialog)
{
	GnmValidation const *v;
	GnmCell *cell;
	GnmValue *val;
	gnm_float x;
	int nok, i;
	GnmEvalPos ep;

	if (showed_dialog) *showed_dialog = FALSE;

	v = gnm_style_get_validation (mstyle);
	if (v == NULL)
		return GNM_VALIDATION_STATUS_VALID;

	if (v->type == GNM_VALIDATION_TYPE_ANY)
		return GNM_VALIDATION_STATUS_VALID;

	cell = sheet_cell_get (sheet, pos->col, pos->row);
	if (cell != NULL)
		gnm_cell_eval (cell);

	if (gnm_cell_is_empty (cell)) {
		if (v->allow_blank)
			return GNM_VALIDATION_STATUS_VALID;
		BARF (g_strdup_printf (_("Cell %s is not permitted to be blank"),
				       cell_name (cell)));
	}

	val = cell->value;
	switch (val->type) {
	case VALUE_ERROR:
		if (typeinfo[v->type].errors_not_allowed)
			BARF (g_strdup_printf (_("Cell %s is not permitted to contain error values"),
					       cell_name (cell)));
		break;

	case VALUE_BOOLEAN:
		if (typeinfo[v->type].bool_always_ok)
			return GNM_VALIDATION_STATUS_VALID;
		break;

	case VALUE_STRING:
		if (typeinfo[v->type].strings_not_allowed)
			BARF (g_strdup_printf (_("Cell %s is not permitted to contain strings"),
					       cell_name (cell)));
		break;

	default:
		break;
	}

	eval_pos_init_cell (&ep, cell);

	switch (v->type) {
	case GNM_VALIDATION_TYPE_AS_INT:
		x = value_get_as_float (val);
		if (gnm_fake_floor (x) == gnm_fake_ceil (x))
			break;
		else
			BARF (g_strdup_printf (_("'%s' is not an integer"),
					       value_peek_string (val)));

	case GNM_VALIDATION_TYPE_AS_NUMBER:
		x = value_get_as_float (val);
		break;

	case GNM_VALIDATION_TYPE_AS_DATE: /* What the hell does this do?  */
		x = value_get_as_float (val);
		if (x < 0)
			BARF (g_strdup_printf (_("'%s' is not a valid date"),
					       value_peek_string (val)));
		break;


	case GNM_VALIDATION_TYPE_AS_TIME: /* What the hell does this do?  */
		x = value_get_as_float (val);
		break;

	case GNM_VALIDATION_TYPE_IN_LIST: {
		GnmExprTop const *texpr = v->deps[0].texpr;
		if (texpr) {
			GnmValue *list = gnm_expr_top_eval
				(texpr, &ep,
				 GNM_EXPR_EVAL_PERMIT_NON_SCALAR | GNM_EXPR_EVAL_PERMIT_EMPTY);
			GnmValue *res = value_area_foreach (list, &ep, CELL_ITER_IGNORE_BLANK,
				 (GnmValueIterFunc) cb_validate_custom, val);
			value_release (list);
			if (res == NULL) {
				GnmParsePos pp;
				char *expr_str = gnm_expr_top_as_string
					(texpr,
					 parse_pos_init_evalpos (&pp, &ep),
					 ep.sheet->convs);
				char *msg = g_strdup_printf (_("%s does not contain the new value."), expr_str);
				g_free (expr_str);
				BARF (msg);
			}
		}
		return GNM_VALIDATION_STATUS_VALID;
	}

	case GNM_VALIDATION_TYPE_TEXT_LENGTH:
		/* XL appears to use a very basic value->string mapping that
		 * ignores formatting.
		 * eg len (12/13/01) == len (37238) = 5
		 * This seems wrong for
		 */
		x = g_utf8_strlen (value_peek_string (val), -1);
		break;

	case GNM_VALIDATION_TYPE_CUSTOM: {
		gboolean valid;
		GnmExprTop const *texpr = v->deps[0].texpr;

		if (!texpr)
			return GNM_VALIDATION_STATUS_VALID;

		val = gnm_expr_top_eval (texpr, &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
		valid = value_get_as_bool (val, NULL);
		value_release (val);

		if (valid)
			return GNM_VALIDATION_STATUS_VALID;
		else {
			GnmParsePos pp;
			char *expr_str = gnm_expr_top_as_string
				(texpr,
				 parse_pos_init_evalpos (&pp, &ep),
				 ep.sheet->convs);
			char *msg = g_strdup_printf (_("%s is not true."), expr_str);
			g_free (expr_str);
			BARF (msg);
		}
	}

	default:
		g_assert_not_reached ();
		return GNM_VALIDATION_STATUS_VALID;
	}

	if (v->op == GNM_VALIDATION_OP_NONE)
		return GNM_VALIDATION_STATUS_VALID;

	nok = 0;
	for (i = 0; i < opinfo[v->op].nops; i++) {
		GnmExprTop const *texpr_i = v->deps[i].texpr;
		GnmExprTop const *texpr;
		GnmValue *cres;

		if (!texpr_i) {
			nok++;
			continue;
		}

		texpr = gnm_expr_top_new
			(gnm_expr_new_binary
			 (gnm_expr_new_constant (value_new_float (x)),
			  opinfo[v->op].ops[i],
			  gnm_expr_copy (texpr_i->expr)));
		cres = gnm_expr_top_eval
			(texpr, &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
		if (value_get_as_bool (cres, NULL))
			nok++;
		value_release (cres);
		gnm_expr_top_unref (texpr);
	}

	if (nok < opinfo[v->op].ntrue)
		BARF (g_strdup_printf (_("%s is out of permitted range"),
				       value_peek_string (val)));

	return GNM_VALIDATION_STATUS_VALID;
}