コード例 #1
0
ファイル: collect.c プロジェクト: paulfitz/gnumeric
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;
}
コード例 #2
0
ファイル: io.c プロジェクト: jaz303/lispy
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);
    	}
    }
}
コード例 #3
0
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;
	}
	}
}
コード例 #4
0
ファイル: sylk-write.c プロジェクト: UIKit0/gnumeric
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;
}
コード例 #5
0
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;
}
コード例 #6
0
ファイル: collect.c プロジェクト: paulfitz/gnumeric
/*
 * 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;
}
コード例 #7
0
ファイル: dif.c プロジェクト: GNOME/gnumeric
/*
 * 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."));
}
コード例 #8
0
static GnmValue *
gnumeric_iferror (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
{
	return value_dup (VALUE_IS_ERROR (argv[0]) ? argv[1] : argv[0]);
}