Exemplo n.º 1
0
/**
 * 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;
}
Exemplo n.º 2
0
static void
gnm_preview_grid_init (GnmPreviewGrid *pg)
{
	pg->sheet = g_object_new (GNM_SHEET_TYPE,
				  "rows", 256,
				  "columns", 256,
				  NULL);
	pg->gridlines = FALSE;
	pg->defaults.col_width = 64;
	pg->defaults.row_height = 17;
	pg->defaults.style = gnm_style_new_default ();
	pg->defaults.value = value_new_empty ();
}
Exemplo n.º 3
0
static GnmValue *
value_new_from_psi_cell(const psiconv_sheet_cell psi_cell)
{
	switch (psi_cell->type) {
	case psiconv_cell_int :
		return value_new_int(psi_cell->data.dat_int);
	case psiconv_cell_float :
		return value_new_float(psi_cell->data.dat_float);
	case psiconv_cell_string :
		return psi_new_string(psi_cell->data.dat_string);
	case psiconv_cell_bool :
		return value_new_bool(psi_cell->data.dat_bool);
	case psiconv_cell_blank :
		return value_new_empty();
	case psiconv_cell_error :
		/* TODO: value_new_error */
		return value_new_empty();
	default :
		/* TODO: value_new_error */
		return value_new_empty();
	}
	return NULL;
}
Exemplo n.º 4
0
/**
 * find_rows_that_match:
 * @sheet: #Sheet
 * @first_col: first column.
 * @first_row: first row.
 * @last_col: last column.
 * @last_row: laset row.
 * @criterias: (element-type GnmDBCriteria): the criteria to use.
 * @unique_only:
 *
 * Finds the rows from the given database that match the criteria.
 * Returns: (element-type int) (transfer full): the list of matching rows.
 **/
GSList *
find_rows_that_match (Sheet *sheet, int first_col, int first_row,
		      int last_col, int last_row,
		      GSList *criterias, gboolean unique_only)
{
	GSList	     *rows = NULL;
	GSList const *crit_ptr, *cond_ptr;
	int        row;
	gboolean   add_flag;
	char const *t1, *t2;
	GnmCell   *test_cell;
	GnmValue const *empty = value_new_empty ();

	for (row = first_row; row <= last_row; row++) {
		add_flag = TRUE;
		for (crit_ptr = criterias; crit_ptr; crit_ptr = crit_ptr->next) {
			GnmDBCriteria const *crit = crit_ptr->data;
			add_flag = TRUE;
			for (cond_ptr = crit->conditions;
			     cond_ptr != NULL ; cond_ptr = cond_ptr->next) {
				GnmCriteria *cond = cond_ptr->data;
				test_cell = sheet_cell_get (sheet, cond->column, row);
				if (test_cell != NULL)
					gnm_cell_eval (test_cell);
				if (!cond->fun (test_cell ? test_cell->value : empty, cond)) {
					add_flag = FALSE;
					break;
				}
			}

			if (add_flag)
				break;
		}
		if (add_flag) {
			gint *p;

			if (unique_only) {
				GSList *c;
				GnmCell   *cell;
				gint    i, trow;

				for (c = rows; c != NULL; c = c->next) {
					trow = *((gint *) c->data);
					for (i = first_col; i <= last_col; i++) {
						test_cell = sheet_cell_get (sheet, i, trow);
						cell = sheet_cell_get (sheet, i, row);

						/* FIXME: this is probably not right, but crashing is more wrong.  */
						if (test_cell == NULL || cell == NULL)
							continue;

						t1 = cell->value
							? value_peek_string (cell->value)
							: "";
						t2 = test_cell->value
							? value_peek_string (test_cell->value)
							: "";
						if (strcmp (t1, t2) != 0)
							goto row_ok;
					}
					goto filter_row;
row_ok:
					;
				}
			}
			p = g_new (gint, 1);
			*p = row;
			rows = g_slist_prepend (rows, (gpointer) p);
filter_row:
			;
		}
	}

	return g_slist_reverse (rows);
}
Exemplo n.º 5
0
static GODataCache *
build_cache(void) 
{
	Workbook *wb;
	Sheet *sheet;
	GODataCache *cache;
	GnmRange *range;
	int row, col, numRows = 60, numCols = 5;
	
	wb = workbook_new();
	sheet = workbook_sheet_add (wb, -1, 1024, 1024);
	
	for (row = 0; row < numRows; row++) {
		for (col = 0; col < numCols; col++) {
			GnmCell * tempCell = sheet_cell_create(sheet, col, row);
			GnmValue * tempVal;
			if (col == 0) {
				if (row%4 == 0) {
					tempVal = value_new_string_nocopy((char *)"A");
				} else if (row%4 == 1) {
					tempVal = value_new_string_nocopy((char *)"B");
				} else if (row%4 == 2) {
					tempVal = value_new_string_nocopy((char *)"C");
				} else {
					tempVal = value_new_string_nocopy((char *)"D");
				}
			} else if (col == 1) {
				tempVal = value_new_int(row);
			} else if (col == 2) {
				if (row%5 == 0) {
					tempVal = value_new_float(14.4);
				} else if (row%5 == 1) {
					tempVal = value_new_float(18.8);
				} else if (row%5 == 2) {
					tempVal = value_new_float(7.6);
				} else if (row%5 == 3) {
					tempVal = value_new_float(3.3);
				} else {
					tempVal = value_new_float(11.6);
				}
			} else if (col == 3) {
				tempVal = value_new_int(row % 10);
			} else if (col == 4) {
				if (row == 0) {
					GnmEvalPos *pos = g_new(GnmEvalPos, 1);
					pos = eval_pos_init(pos, sheet, col, row);
					tempVal = value_new_error_DIV0(pos);
				} else if (row == 1) {
					GnmEvalPos *pos = g_new(GnmEvalPos, 1);
					pos = eval_pos_init(pos, sheet, col, row);
					tempVal = value_new_error_NA(pos);
				} else if (row == 2) {
					GnmEvalPos *pos = g_new(GnmEvalPos, 1);
					pos = eval_pos_init(pos, sheet, col, row);
					tempVal = value_new_error_REF(pos);
				} else if (row == 3) {
					tempVal = value_new_bool(TRUE);
				} else if (row == 4) {
					tempVal = value_new_bool(FALSE);
				} else if (row == 5) {
					tempVal = value_new_empty();
				} else {
					if (row%5 == 1) {
						tempVal = value_new_string_nocopy((char *)"a");
					} else if (row%5 == 2) {
						tempVal = value_new_string_nocopy((char *)"b");
					} else if (row%5 == 3) {
						tempVal = value_new_string_nocopy((char *)"c");
					} else if (row%5 == 4) {
						tempVal = value_new_string_nocopy((char *)"d");
					} else {
						tempVal = value_new_string_nocopy((char *)"e");
					}
				}
			}
			sheet_cell_set_value(tempCell, tempVal);
		}
	}
	
	cache = g_object_new(GO_DATA_CACHE_TYPE, NULL);
	range = g_new(GnmRange, 1);
	range = range_init(range, 0, 0, numCols - 1, numRows - 1);
	
	go_data_cache_build_cache(cache, sheet, range);
	
	g_object_unref (wb);
	
	return cache;
}
Exemplo n.º 6
0
static GnmValue *
new_gnm_value_from_xloper (const XLOPER*x)
{
	GnmValue * g = NULL;
	if (NULL != x) {
		switch (x->xltype & xltypeType) {
		case xltypeNum:
			g = value_new_float (x->val.num);
			break;
		case xltypeStr: {
			char *o = NULL;
			const char *s = x->val.str;
			if (NULL != s) {
				guint m = ((unsigned char)s[0]) + 1U;
				o = g_new (char, m);
				g_strlcpy (o, s + 1, m);
			}
			g = value_new_string_nocopy (o);
			break;
		}
		case xltypeBool:
			g = value_new_bool (x->val.boolean);
			break;
		case xltypeRef:
			unsupported_xloper_type (x);
			break;
		case xltypeErr:
			g = value_new_error_std (NULL, gnm_value_error_from_xloper (x));
			break;
		case xltypeFlow:
			unsupported_xloper_type (x);
			break;
		case xltypeMulti: {
			guint m = x->val.array.columns;
			guint n = x->val.array.rows;
			if (m > 0 && n > 0) {
				guint i;
				g = value_new_array_empty (m,n);
				for (i = 0; i < m; ++i) {
					guint j;
					for (j = 0; j < n; ++j) {
						g->v_array.vals[i][j] =
							new_gnm_value_from_xloper (x->val.array.lparray + i + j * m);
					}
				}
			} else {
				g = value_new_error_std (NULL, GNM_ERROR_VALUE);
			}
			break;
		}
		case xltypeMissing:
			break;
		case xltypeNil:
			g = value_new_empty ();
			break;
		case xltypeSRef:
			unsupported_xloper_type (x);
			break;
		case xltypeInt:
			g = value_new_int (x->val.w);
			break;
		default:
			unsupported_xloper_type (x);
		}
	} else {
Exemplo n.º 7
0
/**
 * value_area_get_x_y:
 * @v: const #GnmValue *
 * @x: column
 * @y: row
 * @ep: const #GnmEvalPos *
 *
 * An internal routine to get a cell from an array or range.
 * Ensures that elements of CELLRANGE are evaluated
 *
 * If any problems occur a NULL is returned.
 **/
GnmValue const *
value_area_get_x_y (GnmValue const *v, int x, int y, GnmEvalPos const *ep)
{
	g_return_val_if_fail (v, NULL);

	if (VALUE_IS_ARRAY (v)){
		g_return_val_if_fail (x < v->v_array.x &&
				      y < v->v_array.y,
				      NULL);
		return v->v_array.vals [x][y];
	} else if (VALUE_IS_CELLRANGE (v)) {
		GnmCellRef const * const a = &v->v_range.cell.a;
		GnmCellRef const * const b = &v->v_range.cell.b;
		int a_col = a->col;
		int a_row = a->row;
		int b_col = b->col;
		int b_row = b->row;
		GnmCell *cell;
		Sheet *sheet;

		/* Handle relative references */
		if (a->col_relative)
			a_col += ep->eval.col;
		if (a->row_relative)
			a_row += ep->eval.row;
		if (b->col_relative)
			b_col += ep->eval.col;
		if (b->row_relative)
			b_row += ep->eval.row;

		/* Handle inverted references */
		if (a_row > b_row) {
			int tmp = a_row;
			a_row = b_row;
			b_row = tmp;
		}
		if (a_col > b_col) {
			int tmp = a_col;
			a_col = b_col;
			b_col = tmp;
		}

		a_col += x;
		a_row += y;

		/*
		 * FIXME FIXME FIXME
		 * This should return NA but some of the math functions may
		 * rely on this for now.
		 */
		g_return_val_if_fail (a_row<=b_row, NULL);
		g_return_val_if_fail (a_col<=b_col, NULL);

		sheet = eval_sheet (a->sheet, ep->sheet);

		g_return_val_if_fail (IS_SHEET (sheet), NULL);

		/* Speedup */
		if (sheet->cols.max_used < a_col ||
		    sheet->rows.max_used < a_row)
			return value_new_empty ();

		cell = sheet_cell_get (sheet, a_col, a_row);
		if (cell != NULL) {
			gnm_cell_eval (cell);
			return cell->value;
		}

		return value_new_empty ();
	} else
		return v;

	return NULL;
}