Commit c1086a85 authored by Michael Meeks's avatar Michael Meeks

Fix for copy and paste, Sort function, fixed lookup functions,

MOD function, updated function writing docs, fix to function number
parser so doesn't overflow.
parent 14de52b4
1999-03-30 Michael Meeks <michael@imaginator.com>
* src/sheet.c (sheet_selection_first_range): This returns
the co-ordinates of the first range, and a flag as to whether
the selection is simply one range. This keeps things simple
for sort.
* src/utils.c (col_from_name): Created.
* src/utils.h: Added prototype.
* src/dialog-cell-sort.c: Created
* src/workbook.c (workbook_menu_format): Added 'Sort'.
(sort_cells_cmd): Created.
* src/dialogs.h: Added dialog_cell_sort.
1999-03-30 Michael Meeks <michael@imaginator.com>
* src/fn-lookup.c (gnumeric_vlookup, gnumeric_hlookup):
Removed check for same sheets in each cell reference, in
intersheet references only a->sheet points to the other sheet.
* src/func.c (function_iterate_do_value): Change CELLRANGE's
sheet reference to cell_range.cell_a.sheet, since could be an
inter-sheet reference. This fixes: Sum(Sheet1!A1:B3)
* src/fn-eng.c: Cleaned function documentation.
* docs/C/writing-functions.smgl: Updated for option function
arguments.
* src/fn-math.c (gnumeric_mod): Implemented.
1999-03-30 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/expr.c (eval_expr): Fix from Ian Campbell for fixing the
......@@ -7,6 +42,40 @@
* src/fn-stat.c: Added large, median, pearson, and small.
1999-03-28 Michael Meeks <michael@imaginator.com>
* src/parser.y (yylex): Added digits count to stop
overflow of integers above 9 digits.
1999-03-27 Michael Meeks <michael@imaginator.com>
* src/sheet.c (fail_if_found): Renamed to
(fail_if_not_selected): Added check for selection
(sheet_is_region_empty): Renamed to
(sheet_is_region_empty_or_selected): Better
described new function.
* src/item-cursor.c (item_cursor_target_region_ok):
Uses sheet_is_region_empty_or_selected.
1999-03-27 Michael Meeks <michael@imaginator.com>
* src/expr.c (eval_funcall): Add vital 'break'
statement :-)
1999-03-27 Michael Meeks <michael@imaginator.com>
* src/eval.c (cell_eval): Set default value of
error_msg so cell doesn't get null text on
g_return_val_if_fail (condition, NULL) ;
* src/sheet.c (sheet_update_auto_expr):
Internationalized ERROR string.
* src/fn-lookup.c (gnumeric_column, gnumeric_columns)
(gnumeric_row, gnumeric_rows): Hacked; best can do for
now.
1999-03-26 Michael Meeks <michael@imaginator.com>
* src/fn-eng.c (gnumeric_delta): Fix memory leak
......
1999-03-30 Michael Meeks <michael@imaginator.com>
* src/sheet.c (sheet_selection_first_range): This returns
the co-ordinates of the first range, and a flag as to whether
the selection is simply one range. This keeps things simple
for sort.
* src/utils.c (col_from_name): Created.
* src/utils.h: Added prototype.
* src/dialog-cell-sort.c: Created
* src/workbook.c (workbook_menu_format): Added 'Sort'.
(sort_cells_cmd): Created.
* src/dialogs.h: Added dialog_cell_sort.
1999-03-30 Michael Meeks <michael@imaginator.com>
* src/fn-lookup.c (gnumeric_vlookup, gnumeric_hlookup):
Removed check for same sheets in each cell reference, in
intersheet references only a->sheet points to the other sheet.
* src/func.c (function_iterate_do_value): Change CELLRANGE's
sheet reference to cell_range.cell_a.sheet, since could be an
inter-sheet reference. This fixes: Sum(Sheet1!A1:B3)
* src/fn-eng.c: Cleaned function documentation.
* docs/C/writing-functions.smgl: Updated for option function
arguments.
* src/fn-math.c (gnumeric_mod): Implemented.
1999-03-30 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/expr.c (eval_expr): Fix from Ian Campbell for fixing the
......@@ -7,6 +42,40 @@
* src/fn-stat.c: Added large, median, pearson, and small.
1999-03-28 Michael Meeks <michael@imaginator.com>
* src/parser.y (yylex): Added digits count to stop
overflow of integers above 9 digits.
1999-03-27 Michael Meeks <michael@imaginator.com>
* src/sheet.c (fail_if_found): Renamed to
(fail_if_not_selected): Added check for selection
(sheet_is_region_empty): Renamed to
(sheet_is_region_empty_or_selected): Better
described new function.
* src/item-cursor.c (item_cursor_target_region_ok):
Uses sheet_is_region_empty_or_selected.
1999-03-27 Michael Meeks <michael@imaginator.com>
* src/expr.c (eval_funcall): Add vital 'break'
statement :-)
1999-03-27 Michael Meeks <michael@imaginator.com>
* src/eval.c (cell_eval): Set default value of
error_msg so cell doesn't get null text on
g_return_val_if_fail (condition, NULL) ;
* src/sheet.c (sheet_update_auto_expr):
Internationalized ERROR string.
* src/fn-lookup.c (gnumeric_column, gnumeric_columns)
(gnumeric_row, gnumeric_rows): Hacked; best can do for
now.
1999-03-26 Michael Meeks <michael@imaginator.com>
* src/fn-eng.c (gnumeric_delta): Fix memory leak
......
1999-03-30 Michael Meeks <michael@imaginator.com>
* src/sheet.c (sheet_selection_first_range): This returns
the co-ordinates of the first range, and a flag as to whether
the selection is simply one range. This keeps things simple
for sort.
* src/utils.c (col_from_name): Created.
* src/utils.h: Added prototype.
* src/dialog-cell-sort.c: Created
* src/workbook.c (workbook_menu_format): Added 'Sort'.
(sort_cells_cmd): Created.
* src/dialogs.h: Added dialog_cell_sort.
1999-03-30 Michael Meeks <michael@imaginator.com>
* src/fn-lookup.c (gnumeric_vlookup, gnumeric_hlookup):
Removed check for same sheets in each cell reference, in
intersheet references only a->sheet points to the other sheet.
* src/func.c (function_iterate_do_value): Change CELLRANGE's
sheet reference to cell_range.cell_a.sheet, since could be an
inter-sheet reference. This fixes: Sum(Sheet1!A1:B3)
* src/fn-eng.c: Cleaned function documentation.
* docs/C/writing-functions.smgl: Updated for option function
arguments.
* src/fn-math.c (gnumeric_mod): Implemented.
1999-03-30 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/expr.c (eval_expr): Fix from Ian Campbell for fixing the
......@@ -7,6 +42,40 @@
* src/fn-stat.c: Added large, median, pearson, and small.
1999-03-28 Michael Meeks <michael@imaginator.com>
* src/parser.y (yylex): Added digits count to stop
overflow of integers above 9 digits.
1999-03-27 Michael Meeks <michael@imaginator.com>
* src/sheet.c (fail_if_found): Renamed to
(fail_if_not_selected): Added check for selection
(sheet_is_region_empty): Renamed to
(sheet_is_region_empty_or_selected): Better
described new function.
* src/item-cursor.c (item_cursor_target_region_ok):
Uses sheet_is_region_empty_or_selected.
1999-03-27 Michael Meeks <michael@imaginator.com>
* src/expr.c (eval_funcall): Add vital 'break'
statement :-)
1999-03-27 Michael Meeks <michael@imaginator.com>
* src/eval.c (cell_eval): Set default value of
error_msg so cell doesn't get null text on
g_return_val_if_fail (condition, NULL) ;
* src/sheet.c (sheet_update_auto_expr):
Internationalized ERROR string.
* src/fn-lookup.c (gnumeric_column, gnumeric_columns)
(gnumeric_row, gnumeric_rows): Hacked; best can do for
now.
1999-03-26 Michael Meeks <michael@imaginator.com>
* src/fn-eng.c (gnumeric_delta): Fix memory leak
......
1999-03-30 Michael Meeks <michael@imaginator.com>
* src/sheet.c (sheet_selection_first_range): This returns
the co-ordinates of the first range, and a flag as to whether
the selection is simply one range. This keeps things simple
for sort.
* src/utils.c (col_from_name): Created.
* src/utils.h: Added prototype.
* src/dialog-cell-sort.c: Created
* src/workbook.c (workbook_menu_format): Added 'Sort'.
(sort_cells_cmd): Created.
* src/dialogs.h: Added dialog_cell_sort.
1999-03-30 Michael Meeks <michael@imaginator.com>
* src/fn-lookup.c (gnumeric_vlookup, gnumeric_hlookup):
Removed check for same sheets in each cell reference, in
intersheet references only a->sheet points to the other sheet.
* src/func.c (function_iterate_do_value): Change CELLRANGE's
sheet reference to cell_range.cell_a.sheet, since could be an
inter-sheet reference. This fixes: Sum(Sheet1!A1:B3)
* src/fn-eng.c: Cleaned function documentation.
* docs/C/writing-functions.smgl: Updated for option function
arguments.
* src/fn-math.c (gnumeric_mod): Implemented.
1999-03-30 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/expr.c (eval_expr): Fix from Ian Campbell for fixing the
......@@ -7,6 +42,40 @@
* src/fn-stat.c: Added large, median, pearson, and small.
1999-03-28 Michael Meeks <michael@imaginator.com>
* src/parser.y (yylex): Added digits count to stop
overflow of integers above 9 digits.
1999-03-27 Michael Meeks <michael@imaginator.com>
* src/sheet.c (fail_if_found): Renamed to
(fail_if_not_selected): Added check for selection
(sheet_is_region_empty): Renamed to
(sheet_is_region_empty_or_selected): Better
described new function.
* src/item-cursor.c (item_cursor_target_region_ok):
Uses sheet_is_region_empty_or_selected.
1999-03-27 Michael Meeks <michael@imaginator.com>
* src/expr.c (eval_funcall): Add vital 'break'
statement :-)
1999-03-27 Michael Meeks <michael@imaginator.com>
* src/eval.c (cell_eval): Set default value of
error_msg so cell doesn't get null text on
g_return_val_if_fail (condition, NULL) ;
* src/sheet.c (sheet_update_auto_expr):
Internationalized ERROR string.
* src/fn-lookup.c (gnumeric_column, gnumeric_columns)
(gnumeric_row, gnumeric_rows): Hacked; best can do for
now.
1999-03-26 Michael Meeks <michael@imaginator.com>
* src/fn-eng.c (gnumeric_delta): Fix memory leak
......
......@@ -102,10 +102,13 @@ add2numbers (FunctionDefinition *fn_def, Value *argv [], char **error_string)
return result;
}
Note that the typechecking is done in the routine itself, it is not
done by the upper layers. If there is an error during the function
processing, *error_string should be set to the error message
describing what went wrong and the NULL value should be returned.
Note that although typechecking is done in upper layers, both INTEGER
and FLOAT types are passed through the 'f' function declaration token.
It is of course good practice to provide a sensible default: case.
If there is an error during the function processing, *error_string
should be set to the error message describing what went wrong and the
NULL value should be returned.
Return values and Strings.
--------------------------
......@@ -147,14 +150,53 @@ When you are done with a String, you should call the string_unref
routine on the String.
Functions with some optional arguments
--------------------------------------
Gnumeric support three types of functions:
* Fixed number of arguments ( dealt with above )
* Optional argument functions and
* Variable argument functions.
The difference between the latter two is that eg. the SUM ()
function will take an indefinate amount of arguments, whereas the
ERF function is best described ERF(lower limit[,upper_limit]).
In this instance, it is not worth the complexity of manualy
traversing the raw expression tree as in SUM. Instead using the
standard type checking the argument can be specified as optional,
and if unspecified a NULL will be passed in the appropriate
argv[] entry. Hence for erf (fn-eng.c):
{ "erf", "f|f", "lower,upper", &help_erf, NULL, gnumeric_erf },
Note "f|f" specifying 'upper' is optional. Any arguments that
appear after a '|' symbol in the function definition string are
deemed optional.
Hence in the code, it is vital to check optional pointers
before assuming they are valid hence:
static Value *
gnumeric_erf (struct FunctionDefinition *i, Value *argv [], char **error_string)
{
float_t ans, lower, upper=0.0 ;
lower = value_get_as_double(argv[0]) ;
if (argv[1])
upper = value_get_as_double(argv[1]) ;
...
}
Note there must be a default value for optional arguments.
Here upper has a default value of 0.0.
Functions with a variable number of arguments
---------------------------------------------
Gnumeric supports two types of functions: those that take a fixed
number of arguments and those that do take a variable number of
arguments. In the former case, the Gnumeric engine does some work to
simplify function coding, in the later case, the function writer is
pretty much presented with the raw expression tree data as a list.
In this case, the function writer is presented with the raw expression
tree data as a list, to traverse himself.
If you want to implement a function that takes a variable number of
arguments you have to change your FunctionDefinition: instead of
......@@ -196,3 +238,7 @@ in which context the expression should be evaluated (ie, from which
cell it is being invoked) and it is used when invoking the expr_eval
function.
1999-03-30 Michael Meeks <michael@imaginator.com>
* ms-formula.c (ms_excel_parse_formula): Rehashed function
and operator search function so it uses a flat array instead
of a linear search.
fully populated formula_func_data array, and removed unused /
constant fields.
* ms-formula.h: Removed dead wood from OP_DATAa & FUNC_DATA
structs.
1999-03-26 Michael Meeks <michael@imaginator.com>
* ms-formula.c: Removed duplicate for fn 0x65
......
......@@ -74,6 +74,7 @@ extern void free_ms_biff_bof_data (BIFF_BOF_DATA *data) ;
#define BIFF_FOOTER 0x15
#define BIFF_EXTERNCOUNT 0x16 /* number of external references*/
#define BIFF_EXTERNSHEET 0x17
#define BIFF_SELECTION 0x1d
#define BIFF_FORMAT 0x1e
#define BIFF_ARRAY 0x21
#define BIFF_EXTERNNAME 0x23
......
......@@ -1858,6 +1858,11 @@ ms_excelReadWorkbook (MS_OLE * file)
}
break ;
}
case BIFF_SELECTION: /* S59DE2.HTM */
{
printf ("FIXME: Selection data\n") ;
break ;
}
case BIFF_FORMAT: /* S59D8E.HTM */
{
BIFF_FORMAT_DATA *d = g_new(BIFF_FORMAT_DATA,1) ;
......
......@@ -1858,6 +1858,11 @@ ms_excelReadWorkbook (MS_OLE * file)
}
break ;
}
case BIFF_SELECTION: /* S59DE2.HTM */
{
printf ("FIXME: Selection data\n") ;
break ;
}
case BIFF_FORMAT: /* S59D8E.HTM */
{
BIFF_FORMAT_DATA *d = g_new(BIFF_FORMAT_DATA,1) ;
......
This diff is collapsed.
......@@ -50,7 +50,6 @@ typedef struct _FORMULA_ARRAY_DATA
typedef struct _FORMULA_OP_DATA
{
BYTE formula_ptg ;
gboolean infix ; /* ie. not unary */
char *mid ;
int precedence ;
......@@ -58,12 +57,8 @@ typedef struct _FORMULA_OP_DATA
typedef struct _FORMULA_FUNC_DATA
{
int function_idx ;
char *prefix ;
char *mid ;
char *suffix ;
int num_args ; /* -1 for multi-arg */
int precedence ;
} FORMULA_FUNC_DATA ;
#endif
This diff is collapsed.
......@@ -50,7 +50,6 @@ typedef struct _FORMULA_ARRAY_DATA
typedef struct _FORMULA_OP_DATA
{
BYTE formula_ptg ;
gboolean infix ; /* ie. not unary */
char *mid ;
int precedence ;
......@@ -58,12 +57,8 @@ typedef struct _FORMULA_OP_DATA
typedef struct _FORMULA_FUNC_DATA
{
int function_idx ;
char *prefix ;
char *mid ;
char *suffix ;
int num_args ; /* -1 for multi-arg */
int precedence ;
} FORMULA_FUNC_DATA ;
#endif
......@@ -161,7 +161,7 @@ gnumeric_bin2dec (struct FunctionDefinition *i, Value *argv [], char **error_str
static char *help_bin2oct = {
N_("@FUNCTION=BIN2OCT\n"
"@SYNTAX=BIN2OCT(number,places)\n"
"@SYNTAX=BIN2OCT(number[,places])\n"
"@DESCRIPTION="
"The BIN2OCT function converts a binary number to an octal number."
......@@ -180,7 +180,7 @@ gnumeric_bin2oct (struct FunctionDefinition *i, Value *argv [], char **error_str
static char *help_bin2hex = {
N_("@FUNCTION=BIN2HEX\n"
"@SYNTAX=BIN2HEX(number,places)\n"
"@SYNTAX=BIN2HEX(number[,places])\n"
"@DESCRIPTION="
"The BIN2HEX function converts a binary number to a hexadecimal number."
......@@ -199,7 +199,7 @@ gnumeric_bin2hex (struct FunctionDefinition *i, Value *argv [], char **error_str
static char *help_dec2bin = {
N_("@FUNCTION=DEC2BIN\n"
"@SYNTAX=DEC2BIN(number,places)\n"
"@SYNTAX=DEC2BIN(number[,places])\n"
"@DESCRIPTION="
"The DEC2BIN function converts a binary number to an octal number."
......@@ -218,7 +218,7 @@ gnumeric_dec2bin (struct FunctionDefinition *i, Value *argv [], char **error_str
static char *help_dec2oct = {
N_("@FUNCTION=DEC2OCT\n"
"@SYNTAX=DEC2OCT(number,places)\n"
"@SYNTAX=DEC2OCT(number[,places])\n"
"@DESCRIPTION="
"The DEC2OCT function converts a binary number to an octal number."
......@@ -237,7 +237,7 @@ gnumeric_dec2oct (struct FunctionDefinition *i, Value *argv [], char **error_str
static char *help_dec2hex = {
N_("@FUNCTION=DEC2HEX\n"
"@SYNTAX=DEC2HEX(number,places)\n"
"@SYNTAX=DEC2HEX(number[,places])\n"
"@DESCRIPTION="
"The DEC2HEX function converts a binary number to an octal number."
......@@ -274,7 +274,7 @@ gnumeric_oct2dec (struct FunctionDefinition *i, Value *argv [], char **error_str
static char *help_oct2bin = {
N_("@FUNCTION=OCT2BIN\n"
"@SYNTAX=OCT2BIN(number,places)\n"
"@SYNTAX=OCT2BIN(number[,places])\n"
"@DESCRIPTION="
"The OCT2BIN function converts a binary number to a hexadecimal number."
......@@ -293,7 +293,7 @@ gnumeric_oct2bin (struct FunctionDefinition *i, Value *argv [], char **error_str
static char *help_oct2hex = {
N_("@FUNCTION=OCT2HEX\n"
"@SYNTAX=OCT2HEX(number,places)\n"
"@SYNTAX=OCT2HEX(number[,places])\n"
"@DESCRIPTION="
"The OCT2HEX function converts a binary number to a hexadecimal number."
......@@ -312,7 +312,7 @@ gnumeric_oct2hex (struct FunctionDefinition *i, Value *argv [], char **error_str
static char *help_hex2bin = {
N_("@FUNCTION=HEX2BIN\n"
"@SYNTAX=HEX2BIN(number,places)\n"
"@SYNTAX=HEX2BIN(number[,places])\n"
"@DESCRIPTION="
"The HEX2BIN function converts a binary number to a hexadecimal number."
......@@ -331,7 +331,7 @@ gnumeric_hex2bin (struct FunctionDefinition *i, Value *argv [], char **error_str
static char *help_hex2oct = {
N_("@FUNCTION=HEX2OCT\n"
"@SYNTAX=HEX2OCT(number,places)\n"
"@SYNTAX=HEX2OCT(number[,places])\n"
"@DESCRIPTION="
"The HEX2OCT function converts a binary number to a hexadecimal number."
......@@ -436,7 +436,7 @@ gnumeric_bessely (struct FunctionDefinition *i, Value *argv [], char **error_str
static char *help_erf = {
N_("@FUNCTION=ERF\n"
"@SYNTAX=ERF(lower limit, upper_limit)\n"
"@SYNTAX=ERF(lower limit[,upper_limit])\n"
"@DESCRIPTION="
"The ERF function returns the integral of the error function between the limits. "
......@@ -498,7 +498,7 @@ gnumeric_erfc (struct FunctionDefinition *i, Value *argv [], char **error_string
static char *help_delta = {
N_("@FUNCTION=DELTA\n"
"@SYNTAX=DELTA(x,y)\n"
"@SYNTAX=DELTA(x[,y])\n"
"@DESCRIPTION="
"The DELTA function test for numerical eqivilance of two arguments returning 1 in equality "
......@@ -569,7 +569,7 @@ gnumeric_delta (struct FunctionDefinition *i, Value *argv [], char **error_strin
static char *help_gestep = {
N_("@FUNCTION=GESTEP\n"
"@SYNTAX=GESTEP(x,y)\n"
"@SYNTAX=GESTEP(x[,y])\n"
"@DESCRIPTION="
"The GESTEP function test for if x is >= y, returning 1 if it is so, and 0 otherwise "
......
......@@ -100,7 +100,8 @@ gnumeric_vlookup (struct FunctionDefinition *i, Value *argv [], char **error_str
a = &argv[1]->v.cell_range.cell_a ;
b = &argv[1]->v.cell_range.cell_b ;
g_return_val_if_fail (a->sheet != NULL, NULL) ;
g_return_val_if_fail (a->sheet == b->sheet, NULL) ;
/* a->sheet must be used as inter-sheet references specify the other sheet in 'a' */
/* g_return_val_if_fail (a->sheet == b->sheet, NULL) ; */
g_return_val_if_fail (!a->col_relative, NULL) ;
g_return_val_if_fail (!b->col_relative, NULL) ;
g_return_val_if_fail (!a->row_relative, NULL) ;
......@@ -189,7 +190,8 @@ gnumeric_hlookup (struct FunctionDefinition *i, Value *argv [], char **error_str
a = &argv[1]->v.cell_range.cell_a ;
b = &argv[1]->v.cell_range.cell_b ;
g_return_val_if_fail (a->sheet != NULL, NULL) ;
g_return_val_if_fail (a->sheet == b->sheet, NULL) ;
/* a->sheet must be used as inter-sheet references specify the other sheet in 'a' */
/* g_return_val_if_fail (a->sheet == b->sheet, NULL) ; */
g_return_val_if_fail (!a->col_relative, NULL) ;
g_return_val_if_fail (!b->col_relative, NULL) ;
g_return_val_if_fail (!a->row_relative, NULL) ;
......
......@@ -921,6 +921,47 @@ gnumeric_max (void *tsheet, GList *expr_node_list, int eval_col, int eval_row, c
return closure.result;
}
static char *help_mod = {
N_("@FUNCTION=MOD\n"
"@SYNTAX=MOD(number,divisor)\n"
"@DESCRIPTION="
"Implements modulo arithmetic."
"Returns the remainder when divisor is divided into abs(number)."
"\n"
"Returns #DIV/0! if divisor is zero."
"@SEEALSO=INT,FLOOR,CEIL")
};
static Value *
gnumeric_mod (struct FunctionDefinition *i, Value *argv [], char **error_string)
{
int a,b;
a = value_get_as_int (argv[0]) ;
b = value_get_as_int (argv[1]) ;
/* Obscure handling of C's mod function */
if (a<0) a = -a ;
if (a<0) { /* -0 */
*error_string = _("#NUM!") ;
return NULL ;
}
if (b<0) {
a = -a ;
b = -b ;
}
if (b<0) { /* -0 */
*error_string = _("#NUM!") ;
return NULL ;
}
if (b==0) {
*error_string = _("#DIV/0!") ;
return NULL ;
}
return value_int(a%b) ;
}