Beispiel #1
0
static void
wb_create_name (WorkbookControl *wbc, char const *text, GnmParsePos *pp)
{
	GnmRange const *r;
	GnmCellRef a, b;
	GnmExpr const *target_range;

	r = selection_first_range (wb_control_cur_sheet_view (wbc),
		                   GO_CMD_CONTEXT (wbc), _("Define Name"));
	if (r != NULL) {
		a.sheet = b.sheet = wb_control_cur_sheet (wbc);
		a.col = r->start.col;
		a.row = r->start.row;
		b.col = r->end.col;
		b.row = r->end.row;
		a.col_relative = a.row_relative = b.col_relative = b.row_relative = FALSE;
		pp->sheet = NULL; /* make it a global name */
		if (gnm_cellref_equal (&a, &b))
			target_range = gnm_expr_new_cellref (&a);
		else
			target_range = gnm_expr_new_constant (
				value_new_cellrange_unsafe (&a, &b));
		cmd_define_name (wbc, text, pp, gnm_expr_top_new (target_range), NULL);
	}
}
Beispiel #2
0
/* NOTE : Make sure to set up any merged regions in the target range BEFORE
 * this is called.
 */
static void
paste_link (GnmPasteTarget const *pt, int top, int left,
	    GnmCellRegion const *cr)
{
	GnmCellPos pos;
	GnmCellRef source_cell_ref;
	int x, y;

	/* Not possible to link to arbitrary (non gnumeric) sources yet. */
	/* TODO : eventually support interprocess gnumeric links */
	if (cr->origin_sheet == NULL)
		return;

	/* TODO : support relative links ? */
	source_cell_ref.col_relative = 0;
	source_cell_ref.row_relative = 0;
	source_cell_ref.sheet = (cr->origin_sheet != pt->sheet)
		? cr->origin_sheet : NULL;
	pos.col = left;
	for (x = 0 ; x < cr->cols ; x++, pos.col++) {
		source_cell_ref.col = cr->base.col + x;
		pos.row = top;
		for (y = 0 ; y < cr->rows ; y++, pos.row++) {
			GnmExprTop const *texpr;
			GnmCell *cell =
				sheet_cell_fetch (pt->sheet, pos.col, pos.row);

			/* This could easily be made smarter */
			if (!gnm_cell_is_merged (cell) &&
			    gnm_sheet_merge_contains_pos (pt->sheet, &pos))
					continue;
			source_cell_ref.row = cr->base.row + y;
			texpr = gnm_expr_top_new (gnm_expr_new_cellref (&source_cell_ref));
			gnm_cell_set_expr (cell, texpr);
			gnm_expr_top_unref (texpr);
		}
	}
}
Beispiel #3
0
static GnmExpr const *
parse_subexpr(const psiconv_formula psi_formula)
{
	int nrargs=0; /* -1 for variable */
	int kind=-1; /* 0 for dat, 1 for operator, 2 for formula, 3 for special,
	               -1 for unknown */
	psiconv_formula psi_form1,psi_form2;
	GnmExpr const *expr1=NULL,*expr2=NULL;

	switch(psi_formula->type) {
		/* Translates values */
		case psiconv_formula_dat_float:
		case psiconv_formula_dat_int:
		case psiconv_formula_dat_string:
		case psiconv_formula_dat_cellblock:
		case psiconv_formula_dat_vcellblock:
			nrargs = 0;
			kind = 0;
			break;
		/* Translates to binary operators */
		case psiconv_formula_op_lt:
		case psiconv_formula_op_le:
		case psiconv_formula_op_gt:
		case psiconv_formula_op_ge:
		case psiconv_formula_op_ne:
		case psiconv_formula_op_eq:
		case psiconv_formula_op_add:
		case psiconv_formula_op_sub:
		case psiconv_formula_op_mul:
		case psiconv_formula_op_div:
	/*	case psiconv_formula_op_pow: */
	/*	case psiconv_formula_op_and: */
	/*	case psiconv_formula_op_or:  */
	/*	case psiconv_formula_op_con: */
			nrargs = 2;
			kind = 1;
			break;
		/* Translates to unary operators */
		case psiconv_formula_op_pos:
		case psiconv_formula_op_neg:
		case psiconv_formula_op_not:
			nrargs = 1;
			kind = 1;
			break;
		/* Specially handled */
		case psiconv_formula_dat_cellref:
		case psiconv_formula_op_bra:
			nrargs = 1;
			kind = 3;
			break;
		/* Should never happen; caught by the default */
	/*	case psiconv_formula_mark_eof:   */
	/*	case psiconv_formula_mark_opsep: */
	/*	case psiconv_formula_mark_opend: */
		default:
			kind = -1;
			break;
	}

	if (kind == -1) {
		/* Unknown value */
		return NULL;
	} else if (kind == 0) {
		/* Handling data */
		GnmValue *v = NULL;
		switch(psi_formula->type) {
		case psiconv_formula_dat_float:
			v = value_new_float(psi_formula->data.dat_float);
			break;
		case psiconv_formula_dat_int:
			v = value_new_int(psi_formula->data.dat_int);
			break;
		case psiconv_formula_dat_string:
			v = psi_new_string(psi_formula->data.dat_string);
			break;
		case psiconv_formula_dat_cellblock: {
			GnmCellRef cr1, cr2;

			p_cellref_init (&cr1,
				psi_formula->data.dat_cellblock.first.row.offset,
				psi_formula->data.dat_cellblock.first.row.absolute,
				psi_formula->data.dat_cellblock.first.column.offset,
				psi_formula->data.dat_cellblock.first.column.absolute);
			p_cellref_init (&cr2,
				psi_formula->data.dat_cellblock.last.row.offset,
				psi_formula->data.dat_cellblock.last.row.absolute,
				psi_formula->data.dat_cellblock.last.column.offset,
				psi_formula->data.dat_cellblock.last.column.absolute);

			v = value_new_cellrange (&cr1, &cr2, 1, 1);
			break;
		}
		default:
			break;
		}
		if (!v)
			return NULL;
		return gnm_expr_new_constant(v);
	} else if (kind == 1) {
		/* Handling the operators */
		if (nrargs >= 1) {
			if (!(psi_form1 = psiconv_list_get
			                  (psi_formula->data.fun_operands,0)))
				return NULL;
			if (!(expr1 = parse_subexpr(psi_form1)))
				return NULL;
		}
		if (nrargs >= 2) {
			if (!(psi_form2 = psiconv_list_get
			                  (psi_formula->data.fun_operands,1))) {
				gnm_expr_free(expr1);
				return NULL;
			}
			if (!(expr2 = parse_subexpr(psi_form2))) {
				gnm_expr_free(expr1);
				return NULL;
			}
		}
		switch(psi_formula->type) {
		case psiconv_formula_op_lt:
			return gnm_expr_new_binary (expr1,GNM_EXPR_OP_LT,expr2);
		case psiconv_formula_op_le:
			return gnm_expr_new_binary (expr1,GNM_EXPR_OP_LTE,expr2);
		case psiconv_formula_op_gt:
			return gnm_expr_new_binary (expr1,GNM_EXPR_OP_GT,expr2);
		case psiconv_formula_op_ge:
			return gnm_expr_new_binary (expr1,GNM_EXPR_OP_GTE,expr2);
		case psiconv_formula_op_ne:
			return gnm_expr_new_binary (expr1,GNM_EXPR_OP_NOT_EQUAL,expr2);
		case psiconv_formula_op_eq:
			return gnm_expr_new_binary (expr1,GNM_EXPR_OP_EQUAL,expr2);
		case psiconv_formula_op_add:
			return gnm_expr_new_binary (expr1,GNM_EXPR_OP_ADD,expr2);
		case psiconv_formula_op_sub:
			return gnm_expr_new_binary (expr1,GNM_EXPR_OP_SUB,expr2);
		case psiconv_formula_op_mul:
			return gnm_expr_new_binary (expr1,GNM_EXPR_OP_MULT,expr2);
		case psiconv_formula_op_div:
			return gnm_expr_new_binary (expr1,GNM_EXPR_OP_DIV,expr2);
		case psiconv_formula_op_pos:
			return gnm_expr_new_unary (GNM_EXPR_OP_UNARY_PLUS,expr1);
		case psiconv_formula_op_neg:
			return gnm_expr_new_unary (GNM_EXPR_OP_UNARY_NEG,expr1);
		default:
			gnm_expr_free(expr1);
			gnm_expr_free(expr2);
			return NULL;
		}
	} else if (kind == 3) {
		switch(psi_formula->type) {
		case psiconv_formula_dat_cellref: {
			GnmCellRef cr;
			return gnm_expr_new_cellref (p_cellref_init (&cr,
				psi_formula->data.dat_cellref.row.offset,
			        psi_formula->data.dat_cellref.row.absolute,
			        psi_formula->data.dat_cellref.column.offset,
			        psi_formula->data.dat_cellref.column.absolute));
		}

		case psiconv_formula_op_bra:
			if (!(psi_form1 = psiconv_list_get
			                  (psi_formula->data.fun_operands,0)))
				return NULL;
			return parse_subexpr(psi_form1);
		default:
			break;
		}
	}

	return NULL;
}
Beispiel #4
0
static void
qpro_parse_formula (QProReadState *state, int col, int row,
		    guint8 const *data, guint8 const *end)
{
	guint16 magic, ref_offset;
#if 0
	int flags = GSF_LE_GET_GUINT16 (data + 8);
	int length = GSF_LE_GET_GUINT16 (data + 10);
#endif
	GnmValue   *val;
	GSList *stack = NULL;
	GnmExprTop const *texpr = NULL;
	guint8 const *refs, *fmla;

#ifdef DEBUG_MISSING
	dump_missing_functions ();
#endif

	Q_CHECK_CONDITION (end - data >= 14);
	magic = GSF_LE_GET_GUINT16 (data + 6) & 0x7ff8;
	ref_offset = GSF_LE_GET_GUINT16 (data + 12);

	fmla = data + 14;
	refs = fmla + ref_offset;
	Q_CHECK_CONDITION (refs <= end);

#if 0
	puts (cell_coord_name (col, row));
	gsf_mem_dump (data, 14);
	gsf_mem_dump (fmla, refs-fmla);
	gsf_mem_dump (refs, end-refs);
#endif

	while (fmla < refs && *fmla != QPRO_OP_EOF) {
		QProOperators op = *fmla++;
		GnmExpr const *expr = NULL;
#if 0
		g_print ("Operator %d.\n", op);
#endif
		switch (op) {
		case QPRO_OP_CONST_FLOAT:
			Q_CHECK_CONDITION (refs - fmla >= 8);
			expr = gnm_expr_new_constant (value_new_float (
				gsf_le_get_double (fmla)));
			fmla += 8;
			break;

		case QPRO_OP_CELLREF: {
			GnmCellRef ref;
			guint16 tmp;

			Q_CHECK_CONDITION (end - refs >= 6);
			tmp = GSF_LE_GET_GUINT16 (refs + 4);
			ref.sheet = NULL;
			ref.col = *((gint8 *)(refs + 2));
			ref.col_relative = (tmp & 0x4000) ? TRUE : FALSE;
			ref.row_relative = (tmp & 0x2000) ? TRUE : FALSE;
			if (ref.row_relative)
				ref.row = (int)(((gint16)((tmp & 0x1fff) << 3)) >> 3);
			else
				ref.row = tmp & 0x1fff;
			expr = gnm_expr_new_cellref (&ref);
			refs += 6;
			break;
		}

		case QPRO_OP_RANGEREF: {
			GnmCellRef a, b;
			guint16 tmp;

			Q_CHECK_CONDITION (end - refs >= 10);

			tmp = GSF_LE_GET_GUINT16 (refs + 4);
			a.sheet = NULL;
			a.col = *((gint8 *)(refs + 2));
			a.col_relative = (tmp & 0x4000) ? TRUE : FALSE;
			a.row_relative = (tmp & 0x2000) ? TRUE : FALSE;
			if (a.row_relative)
				a.row = (int)(((gint16)((tmp & 0x1fff) << 3)) >> 3);
			else
				a.row = tmp & 0x1fff;

			tmp = GSF_LE_GET_GUINT16 (refs + 8);
			b.sheet = NULL;
			b.col = *((gint8 *)(refs + 6));
			b.col_relative = (tmp & 0x4000) ? TRUE : FALSE;
			b.row_relative = (tmp & 0x2000) ? TRUE : FALSE;
			if (b.row_relative)
				b.row = (int)(((gint16)((tmp & 0x1fff) << 3)) >> 3);
			else
				b.row = tmp & 0x1fff;

			expr = gnm_expr_new_constant (
				value_new_cellrange_unsafe (&a, &b));
			refs += 10;
			break;
		}