Commit 4b9287e0 authored by Jody Goldberg's avatar Jody Goldberg

Split the value_* routines into new file.

Fix some minor problems that I missed for VALUE_ERROR.
parent 4c5a6db7
1999-07-27 Jody Goldberg <jgoldberg@home.com>
* src/fn-math.c (gnumeric_transpose) : no need for an array
if the input is a singleton.
* src/expr.c : Add comment explaining the need for a re-org
to correctly handle implicit intersetion vs arrays with
operators. Move all value_* functions into.
* src/value.c : Here.
* src/func.c : Move const value initialization into value.c.
* src/clipboard.c (clipboard_prepend_cell) : Return Value * as per
change to VALUE_ERROR.
* src/style.h : Add STYLE_ORIENT_MAX to remove ugly magic number
that will change when we add support for diagonals.
* src/print-cell.c (print_cell_border, print_border) : Use enum
rather than hard coding the number of border types.
* TODO : Add implicit intersection for operators.
1999-07-25 Jody Goldberg <jgoldberg@home.com>
* plugins/guile/plugin.c,
......
1999-07-27 Jody Goldberg <jgoldberg@home.com>
* src/fn-math.c (gnumeric_transpose) : no need for an array
if the input is a singleton.
* src/expr.c : Add comment explaining the need for a re-org
to correctly handle implicit intersetion vs arrays with
operators. Move all value_* functions into.
* src/value.c : Here.
* src/func.c : Move const value initialization into value.c.
* src/clipboard.c (clipboard_prepend_cell) : Return Value * as per
change to VALUE_ERROR.
* src/style.h : Add STYLE_ORIENT_MAX to remove ugly magic number
that will change when we add support for diagonals.
* src/print-cell.c (print_cell_border, print_border) : Use enum
rather than hard coding the number of border types.
* TODO : Add implicit intersection for operators.
1999-07-25 Jody Goldberg <jgoldberg@home.com>
* plugins/guile/plugin.c,
......
......@@ -29,6 +29,13 @@ Gnumeric Spread Sheet task list
formula without changing to a different cell.
* Expresions
* Rework the handling of input ranges for functions/operators that take
scalars. To either take implicit intersection of calling cell and range
or to create array result and apply function/operator to each input
individually.
* Even More Functions
GROWTH, LINEST, LOGEST, PERCENTILE, QUARTILE, TREND.
......
1999-07-27 Jody Goldberg <jgoldberg@home.com>
* ms-excel-read.c (ms_excel_read_supporting_wb) : Make this
quieter, and add some comments explaining that we have no idea
what this does or how it works.
1999-07-26 Jody Goldberg <jgoldberg@home.com>
* ms-chart.c (BC_R(chartline)) : More state checking.
......
......@@ -18,6 +18,8 @@ libexcel_a_SOURCES = \
ms-biff.h \
biff-types.h \
escher-types.h \
gnumeric-chart.c \
gnumeric-chart.h \
ms-escher.c \
ms-escher.h \
ms-excel-read.c \
......
......@@ -2000,9 +2000,3 @@ ms_excel_read_chart (BiffQuery *q, ExcelWorkbook *wb, int obj_id)
ms_excel_chart (q, wb, bof);
ms_biff_bof_data_destroy (bof);
}
void
gnumeric_chart_destroy (GnumericChart * chart)
{
}
......@@ -2516,46 +2516,38 @@ find_workbook (MsOle *ptr)
/*
* see S59DEC.HM,
* but this whole thing seems sketchy.
* always get 03 00 01 04
*/
static void
ms_excel_read_supporting_wb (BIFF_BOF_DATA *ver, BiffQuery *q)
{
guint8 * data;
guint16 numTabs = MS_OLE_GET_GUINT16 (q->data);
guint8 encodeType = MS_OLE_GET_GUINT8 (q->data + 2);
printf("Supporting workbook with %d Tabs\n", numTabs);
data = q->data + 2;
{
guint8 encodeType = MS_OLE_GET_GUINT8(data);
++data;
/* TODO TODO TODO : Figure out what this is and if it is
* useful. We always get a record length of FOUR ??
* even when there are supposedly 10 tabs...
* Is this related to EXTERNNAME???
*/
#ifndef NO_DEBUG_EXCEL
if (ms_excel_read_debug > 0) {
printf("--> SUPBOOK VirtPath encoding = ");
switch (encodeType)
{
case 0x00 : /* chEmpty */
puts("chEmpty");
break;
case 0x01 : /* chEncode */
puts("chEncode");
#if 0
{
int i;
for (i = 0; i < 50; ++i)
printf("%3d (%c)(%x)\n", i, data[i], data[i]);
}
#endif
break;
case 0x02 : /* chSelf */
puts("chSelf");
break;
default :
printf("Unknown/Unencoded ??(%x '%c') %d\n",
encodeType, encodeType, q->length);
};
}
if (ms_excel_read_debug > 0) {
printf("Supporting workbook with %d Tabs\n", numTabs);
printf("--> SUPBOOK VirtPath encoding = ");
switch (encodeType)
{
case 0x00 : /* chEmpty */
puts("chEmpty");
break;
case 0x01 : /* chEncode */
puts("chEncode");
break;
case 0x02 : /* chSelf */
puts("chSelf");
break;
default :
printf("Unknown/Unencoded ??(%x '%c') %d\n",
encodeType, encodeType, q->length);
};
dump_biff (q);
}
#endif
......@@ -2563,13 +2555,8 @@ ms_excel_read_supporting_wb (BIFF_BOF_DATA *ver, BiffQuery *q)
for (data = q->data + 2; numTabs-- > 0; ) {
char * name;
guint32 byte_length, slen;
if (ver->version >= eBiffV8) {
slen = (guint32) MS_OLE_GET_GUINT16 (data);
name = biff_get_text (data += 2, slen, &byte_length);
} else {
slen = (guint32) MS_OLE_GET_GUINT8 (data);
name = biff_get_text (data += 1, slen, &byte_length);
}
slen = (guint32) MS_OLE_GET_GUINT16 (data);
name = biff_get_text (data += 2, slen, &byte_length);
puts(name);
}
#endif
......
......@@ -2320,6 +2320,10 @@ gnumeric_transpose (FunctionEvalInfo *ei, Value **argv)
int const cols = value_area_get_width (ep, matrix);
int const rows = value_area_get_height (ep, matrix);
/* Return the value directly for a singleton */
if (rows == 1 && cols == 1)
return value_duplicate(value_area_get_x_y (ep, matrix, 0, 0));
res = g_new (Value, 1);
res->type = VALUE_ARRAY;
res->v.array.x = rows;
......
......@@ -435,7 +435,7 @@ typedef struct {
CellRegion *r;
} append_cell_closure_t;
static int
static Value *
clipboard_prepend_cell (Sheet *sheet, int col, int row, Cell *cell, void *user_data)
{
append_cell_closure_t *c = user_data;
......@@ -450,7 +450,7 @@ clipboard_prepend_cell (Sheet *sheet, int col, int row, Cell *cell, void *user_d
c->r->list = g_list_prepend (c->r->list, copy);
return TRUE;
return NULL;
}
/**
......
......@@ -421,659 +421,6 @@ encode_cellref (GString *dest, const CellRef *ref, gboolean use_relative_syntax)
g_string_sprintfa (dest, "%d", ref->row+1);
}
/*
* value_cellrange_get_as_string:
* @value: a value containing a VALUE_CELLRANGE
* @use_relative_syntax: true if you want the result to contain relative indicators
*
* Returns: a string reprensenting the Value, for example:
* use_relative_syntax == TRUE: $a4:$b$1
* use_relative_syntax == FALSE: a4:b1
*/
char *
value_cellrange_get_as_string (const Value *value, gboolean use_relative_syntax)
{
GString *str;
char *ans;
CellRef const * a, * b;
g_return_val_if_fail (value != NULL, NULL);
g_return_val_if_fail (value->type == VALUE_CELLRANGE, NULL);
a = &value->v.cell_range.cell_a;
b = &value->v.cell_range.cell_b;
str = g_string_new ("");
encode_cellref (str, a, use_relative_syntax);
if ((a->col != b->col) || (a->row != b->row) ||
(a->col_relative != b->col_relative) || (a->sheet != b->sheet)){
g_string_append_c (str, ':');
encode_cellref (str, b, use_relative_syntax);
}
ans = str->str;
g_string_free (str, FALSE);
return ans;
}
/*
* simplistic value rendering
*/
char *
value_get_as_string (const Value *value)
{
struct lconv *locinfo;
char const * separator = ",";
locinfo = localeconv ();
if (locinfo->decimal_point &&
locinfo->decimal_point [0] == ',' &&
locinfo->decimal_point [1] == 0)
separator = ";";
switch (value->type){
case VALUE_ERROR:
return g_strdup (value->v.error.mesg->str);
case VALUE_BOOLEAN:
return g_strdup (value->v.v_bool ? _("TRUE") : _("FALSE"));
case VALUE_STRING:
return g_strdup (value->v.str->str);
case VALUE_INTEGER:
return g_strdup_printf ("%d", value->v.v_int);
case VALUE_FLOAT:
return g_strdup_printf ("%.*g", DBL_DIG, value->v.v_float);
case VALUE_ARRAY: {
GString *str = g_string_new ("{");
guint lpx, lpy;
char *ans;
for (lpy = 0; lpy < value->v.array.y; lpy++){
for (lpx = 0; lpx < value->v.array.x; lpx++){
const Value *v = value->v.array.vals [lpx][lpy];
g_return_val_if_fail (v->type == VALUE_STRING ||
v->type == VALUE_FLOAT ||
v->type == VALUE_INTEGER,
"Duff Array contents");
if (lpx)
g_string_sprintfa (str, separator);
if (v->type == VALUE_STRING)
g_string_sprintfa (str, "\"%s\"",
v->v.str->str);
else
g_string_sprintfa (str, "%g",
value_get_as_float (v));
}
if (lpy < value->v.array.y-1)
g_string_sprintfa (str, ";");
}
g_string_sprintfa (str, "}");
ans = str->str;
g_string_free (str, FALSE);
return ans;
}
case VALUE_CELLRANGE:
return value_cellrange_get_as_string (value, TRUE);
default:
g_warning ("value_string problem\n");
break;
}
return g_strdup ("Internal problem");
}
void
value_release (Value *value)
{
g_return_if_fail (value != NULL);
#if 0
/* FIXME FIXME FIXME : Catch if this happens */
g_return_if_fail (value != value_terminate());
#endif
switch (value->type){
case VALUE_BOOLEAN:
break;
case VALUE_ERROR:
string_unref (value->v.error.mesg);
break;
case VALUE_STRING:
string_unref (value->v.str);
break;
case VALUE_INTEGER:
mpz_clear (value->v.v_int);
break;
case VALUE_FLOAT:
mpf_clear (value->v.v_float);
break;
case VALUE_ARRAY:{
guint lpx, lpy;
for (lpx = 0; lpx < value->v.array.x; lpx++){
for (lpy = 0; lpy < value->v.array.y; lpy++)
value_release (value->v.array.vals [lpx][lpy]);
g_free (value->v.array.vals [lpx]);
}
g_free (value->v.array.vals);
break;
}
case VALUE_CELLRANGE:
break;
default:
/*
* If we don't recognize the type this is probably garbage.
* Dont free it to avoid heap corruption
*/
g_warning ("value_release problem\n");
return;
}
value->type = 9999;
g_free (value);
}
/*
* Copies a Value.
*/
void
value_copy_to (Value *dest, const Value *source)
{
g_return_if_fail (dest != NULL);
g_return_if_fail (source != NULL);
dest->type = source->type;
switch (source->type){
case VALUE_BOOLEAN:
dest->v.v_bool = source->v.v_bool;
break;
case VALUE_ERROR:
string_ref (dest->v.error.mesg = source->v.error.mesg);
break;
case VALUE_STRING:
dest->v.str = source->v.str;
string_ref (dest->v.str);
break;
case VALUE_INTEGER:
dest->v.v_int = source->v.v_int;
break;
case VALUE_FLOAT:
dest->v.v_float = source->v.v_float;
break;
case VALUE_ARRAY: {
value_array_copy_to (dest, source);
break;
}
case VALUE_CELLRANGE:
dest->v.cell_range = source->v.cell_range;
break;
default:
g_warning ("value_copy_to problem\n");
break;
}
}
/*
* Makes a copy of a Value
*/
Value *
value_duplicate (const Value *value)
{
Value *new_value;
g_return_val_if_fail (value != NULL, NULL);
new_value = g_new (Value, 1);
value_copy_to (new_value, value);
return new_value;
}
Value *
value_new_float (float_t f)
{
Value *v = g_new (Value, 1);
v->type = VALUE_FLOAT;
v->v.v_float = f;
return v;
}
Value *
value_new_int (int i)
{
Value *v = g_new (Value, 1);
v->type = VALUE_INTEGER;
v->v.v_int = i;
return v;
}
Value *
value_new_bool (gboolean b)
{
Value *v = g_new (Value, 1);
v->type = VALUE_BOOLEAN;
v->v.v_bool = b;
return v;
}
Value *
value_new_string (const char *str)
{
Value *v = g_new (Value, 1);
v->type = VALUE_STRING;
v->v.str = string_get (str);
return v;
}
Value *
value_new_cellrange (const CellRef *a, const CellRef *b)
{
Value *v = g_new (Value, 1);
v->type = VALUE_CELLRANGE;
v->v.cell_range.cell_a = *a;
v->v.cell_range.cell_b = *b;
return v;
}
Value *
value_new_error (EvalPosition const *ep, char const *mesg)
{
Value *v = g_new (Value, 1);
v->type = VALUE_ERROR;
v->v.error.mesg = string_get (mesg);
return v;
}
/*
* Casts a value to float if it is integer, and returns
* a new Value * if required
*/
Value *
value_cast_to_float (Value *v)
{
Value *newv;
g_return_val_if_fail (VALUE_IS_NUMBER (v), NULL);
if (v->type == VALUE_FLOAT)
return v;
if (v->type == VALUE_BOOLEAN) {
value_release (v);
return value_new_float(v->v.v_bool ? 1. : 0.);
}
newv = g_new (Value, 1);
newv->type = VALUE_FLOAT;
mpf_set_z (newv->v.v_float, v->v.v_int);
value_release (v);
return newv;
}
gboolean
value_get_as_bool (const Value *v, gboolean *err)
{
*err = FALSE;
switch (v->type) {
case VALUE_BOOLEAN:
return v->v.v_bool;
case VALUE_STRING:
/* FIXME FIXME FIXME */
/* Use locale to support TRUE, FALSE */
return atoi (v->v.str->str) != 0;
case VALUE_INTEGER:
return v->v.v_int != 0;
case VALUE_FLOAT:
return v->v.v_float != 0.0;
default:
g_warning ("Unhandled value in value_get_boolean");
case VALUE_EMPTY:
case VALUE_CELLRANGE:
case VALUE_ARRAY:
case VALUE_ERROR:
*err = TRUE;
}
return FALSE;
}
float_t
value_get_as_float (const Value *v)
{
switch (v->type)
{
case VALUE_STRING:
return atof (v->v.str->str);
case VALUE_CELLRANGE:
g_warning ("Getting range as a double: what to do?");
return 0.0;
case VALUE_INTEGER:
return (float_t) v->v.v_int;
case VALUE_ARRAY:
return 0.0;
case VALUE_FLOAT:
return (float_t) v->v.v_float;
case VALUE_BOOLEAN:
return v->v.v_bool ? 1. : 0.;
case VALUE_ERROR:
return 0.;
default:
g_warning ("value_get_as_float type error\n");
break;
}
return 0.0;
}
int
value_get_as_int (const Value *v)
{
switch (v->type)
{
case VALUE_STRING:
return atoi (v->v.str->str);
case VALUE_CELLRANGE:
g_warning ("Getting range as a int: what to do?");
return 0;
case VALUE_INTEGER:
return v->v.v_int;
case VALUE_ARRAY:
return 0;
case VALUE_FLOAT:
return (int) v->v.v_float;
case VALUE_BOOLEAN:
return v->v.v_bool ? 1 : 0;
case VALUE_ERROR:
return 0;
default:
g_warning ("value_get_as_int unknown type\n");
return 0;
}
return 0.0;
}
Value *
value_new_array (guint width, guint height)
{
int x, y;
Value *v = g_new (Value, 1);
v->type = VALUE_ARRAY;
v->v.array.x = width;
v->v.array.y = height;
v->v.array.vals = g_new (Value **, width);
for (x = 0; x < width; x++){
v->v.array.vals [x] = g_new (Value *, height);