Commit 19500e12 authored by Miguel de Icaza's avatar Miguel de Icaza Committed by Arturo Espinosa
Browse files

Add support for non-local cells here. I am impressed how simple this was.

1999-01-03  Miguel de Icaza  <miguel@nuclecu.unam.mx>

	* src/expr.c (eval_expr): Add support for non-local cells here.  I
	am impressed how simple this was.

	* src/parser.y: Add rules for cell references outside of the
	current sheet.

	* src/main.c: New option --debug.  Turns on the zoom in/zoom out
	buttons on the main sheet.

	* src/workbook.c: Include the zoom in/zoom out buttons conditionally.

	* src/xml-io.c (xmlGetCoordinates): Load using double numbers the
	information.

	* src/parser.y (yylex): Allow strings to be specified with "'"
	characters.
parent c92cf346
1999-01-03 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/expr.c (eval_expr): Add support for non-local cells here. I
am impressed how simple this was.
* src/parser.y: Add rules for cell references outside of the
current sheet.
* src/main.c: New option --debug. Turns on the zoom in/zoom out
buttons on the main sheet.
* src/workbook.c: Include the zoom in/zoom out buttons conditionally.
* src/xml-io.c (xmlGetCoordinates): Load using double numbers the
information.
* src/parser.y (yylex): Allow strings to be specified with "'"
characters.
1999-01-01 Miguel de Icaza <miguel@nuclecu.unam.mx> 1999-01-01 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-grid.c (item_grid_button_1): When starting a selection * src/item-grid.c (item_grid_button_1): When starting a selection
......
1999-01-03 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/expr.c (eval_expr): Add support for non-local cells here. I
am impressed how simple this was.
* src/parser.y: Add rules for cell references outside of the
current sheet.
* src/main.c: New option --debug. Turns on the zoom in/zoom out
buttons on the main sheet.
* src/workbook.c: Include the zoom in/zoom out buttons conditionally.
* src/xml-io.c (xmlGetCoordinates): Load using double numbers the
information.
* src/parser.y (yylex): Allow strings to be specified with "'"
characters.
1999-01-01 Miguel de Icaza <miguel@nuclecu.unam.mx> 1999-01-01 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-grid.c (item_grid_button_1): When starting a selection * src/item-grid.c (item_grid_button_1): When starting a selection
......
1999-01-03 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/expr.c (eval_expr): Add support for non-local cells here. I
am impressed how simple this was.
* src/parser.y: Add rules for cell references outside of the
current sheet.
* src/main.c: New option --debug. Turns on the zoom in/zoom out
buttons on the main sheet.
* src/workbook.c: Include the zoom in/zoom out buttons conditionally.
* src/xml-io.c (xmlGetCoordinates): Load using double numbers the
information.
* src/parser.y (yylex): Allow strings to be specified with "'"
characters.
1999-01-01 Miguel de Icaza <miguel@nuclecu.unam.mx> 1999-01-01 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-grid.c (item_grid_button_1): When starting a selection * src/item-grid.c (item_grid_button_1): When starting a selection
......
1999-01-03 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/expr.c (eval_expr): Add support for non-local cells here. I
am impressed how simple this was.
* src/parser.y: Add rules for cell references outside of the
current sheet.
* src/main.c: New option --debug. Turns on the zoom in/zoom out
buttons on the main sheet.
* src/workbook.c: Include the zoom in/zoom out buttons conditionally.
* src/xml-io.c (xmlGetCoordinates): Load using double numbers the
information.
* src/parser.y (yylex): Allow strings to be specified with "'"
characters.
1999-01-01 Miguel de Icaza <miguel@nuclecu.unam.mx> 1999-01-01 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/item-grid.c (item_grid_button_1): When starting a selection * src/item-grid.c (item_grid_button_1): When starting a selection
......
...@@ -877,6 +877,7 @@ eval_expr (void *asheet, ExprTree *tree, int eval_col, int eval_row, char **erro ...@@ -877,6 +877,7 @@ eval_expr (void *asheet, ExprTree *tree, int eval_col, int eval_row, char **erro
return eval_cell_value (sheet, tree->u.constant); return eval_cell_value (sheet, tree->u.constant);
case OPER_VAR:{ case OPER_VAR:{
Sheet *cell_sheet;
CellRef *ref; CellRef *ref;
Cell *cell; Cell *cell;
int col, row; int col, row;
...@@ -892,9 +893,11 @@ eval_expr (void *asheet, ExprTree *tree, int eval_col, int eval_row, char **erro ...@@ -892,9 +893,11 @@ eval_expr (void *asheet, ExprTree *tree, int eval_col, int eval_row, char **erro
} }
ref = &tree->u.constant->v.cell; ref = &tree->u.constant->v.cell;
cell_get_abs_col_row (&tree->u.constant->v.cell, eval_col, eval_row, &col, &row); cell_get_abs_col_row (ref, eval_col, eval_row, &col, &row);
cell = sheet_cell_get (sheet, col, row); cell_sheet = ref->sheet ? ref->sheet : sheet;
cell = sheet_cell_get (cell_sheet, col, row);
if (cell){ if (cell){
if (cell->generation != sheet->workbook->generation){ if (cell->generation != sheet->workbook->generation){
......
...@@ -2,25 +2,25 @@ ...@@ -2,25 +2,25 @@
#define GNUMERIC_EXPR_H #define GNUMERIC_EXPR_H
typedef enum { typedef enum {
OPER_EQUAL, OPER_EQUAL, /* Compare value equal */
OPER_GT, OPER_GT, /* Compare value greather than */
OPER_LT, OPER_LT, /* Compare value less than */
OPER_GTE, OPER_GTE, /* Compare value greather or equal than */
OPER_LTE, OPER_LTE, /* Compare value less or equal than */
OPER_NOT_EQUAL, OPER_NOT_EQUAL, /* Compare for non equivalence */
OPER_ADD, OPER_ADD, /* Add */
OPER_SUB, OPER_SUB, /* Substract */
OPER_MULT, OPER_MULT, /* Multiply */
OPER_DIV, OPER_DIV, /* Divide */
OPER_EXP, OPER_EXP, /* Exponentiate */
OPER_CONCAT, OPER_CONCAT, /* String concatenation */
OPER_FUNCALL, OPER_FUNCALL, /* Function call invocation */
OPER_CONSTANT, OPER_CONSTANT, /* Constant value */
OPER_VAR, OPER_VAR, /* Cell content lookup (variable) */
OPER_NEG, OPER_NEG, /* Sign inversion */
} Operation; } Operation;
typedef enum { typedef enum {
......
...@@ -15,13 +15,18 @@ ...@@ -15,13 +15,18 @@
#include <libguile.h> #include <libguile.h>
#endif #endif
/* The debugging level */
int gnumeric_debugging = 0;
static char *dump_file_name = NULL; static char *dump_file_name = NULL;
static char **startup_files = NULL; static char **startup_files = NULL;
poptContext ctx; poptContext ctx;
const struct poptOption gnumeric_popt_options [] = { const struct poptOption gnumeric_popt_options [] = {
{ "dump-func-defs", '\0', POPT_ARG_STRING, &dump_file_name, 0, { "dump-func-defs", '\0', POPT_ARG_STRING, &dump_file_name, 0,
N_("Dumps the function definitions"), N_("FILE") }, N_("Dumps the function definitions"), N_("FILE") },
{ "debug", '\0', POPT_ARG_INT, &gnumeric_debugging, 0,
N_("Enables some debugging functions"), N_("LEVEL") },
{ NULL, '\0', 0, NULL, 0 } { NULL, '\0', 0, NULL, 0 }
}; };
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
extern const struct poptOption gnumeric_popt_options []; extern const struct poptOption gnumeric_popt_options [];
extern poptContext ctx; extern poptContext ctx;
extern int gnumeric_debugging;
void gnumeric_arg_parse (int argc, char *argv []); void gnumeric_arg_parse (int argc, char *argv []);
......
...@@ -15,13 +15,18 @@ ...@@ -15,13 +15,18 @@
#include <libguile.h> #include <libguile.h>
#endif #endif
/* The debugging level */
int gnumeric_debugging = 0;
static char *dump_file_name = NULL; static char *dump_file_name = NULL;
static char **startup_files = NULL; static char **startup_files = NULL;
poptContext ctx; poptContext ctx;
const struct poptOption gnumeric_popt_options [] = { const struct poptOption gnumeric_popt_options [] = {
{ "dump-func-defs", '\0', POPT_ARG_STRING, &dump_file_name, 0, { "dump-func-defs", '\0', POPT_ARG_STRING, &dump_file_name, 0,
N_("Dumps the function definitions"), N_("FILE") }, N_("Dumps the function definitions"), N_("FILE") },
{ "debug", '\0', POPT_ARG_INT, &gnumeric_debugging, 0,
N_("Enables some debugging functions"), N_("LEVEL") },
{ NULL, '\0', 0, NULL, 0 } { NULL, '\0', 0, NULL, 0 }
}; };
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
extern const struct poptOption gnumeric_popt_options []; extern const struct poptOption gnumeric_popt_options [];
extern poptContext ctx; extern poptContext ctx;
extern int gnumeric_debugging;
void gnumeric_arg_parse (int argc, char *argv []); void gnumeric_arg_parse (int argc, char *argv []);
......
...@@ -8,14 +8,10 @@ ...@@ -8,14 +8,10 @@
* Miguel de Icaza (miguel@gnu.org) * Miguel de Icaza (miguel@gnu.org)
*/ */
#include <config.h> #include <config.h>
#include <glib.h>
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include "numbers.h" #include <gnome.h>
#include "symbol.h" #include "gnumeric.h"
#include "str.h"
#include "expr.h"
#include "utils.h"
#include "number-match.h" #include "number-match.h"
/* Allocation with disposal-on-error */ /* Allocation with disposal-on-error */
...@@ -73,10 +69,12 @@ build_binop (ExprTree *l, Operation op, ExprTree *r) ...@@ -73,10 +69,12 @@ build_binop (ExprTree *l, Operation op, ExprTree *r)
ExprTree *tree; ExprTree *tree;
CellRef *cell; CellRef *cell;
GList *list; GList *list;
Sheet *sheetref;
} }
%type <tree> exp %type <tree> exp
%type <list> arg_list %type <list> arg_list
%token <tree> NUMBER STRING FUNCALL CONSTANT CELLREF GTE LTE NE %token <tree> NUMBER STRING FUNCALL CONSTANT CELLREF GTE LTE NE
%token <sheetref> SHEETREF
%left '<' '>' '=' GTE LTE NE %left '<' '>' '=' GTE LTE NE
%left '-' '+' '&' %left '-' '+' '&'
...@@ -143,6 +141,11 @@ exp: NUMBER { $$ = $1 } ...@@ -143,6 +141,11 @@ exp: NUMBER { $$ = $1 }
forget_tree ($3); forget_tree ($3);
} }
| SHEETREF '!' CELLREF {
$$ = $3;
$$->u.constant->v.cell.sheet = $1;
}
| FUNCALL '(' arg_list ')' { | FUNCALL '(' arg_list ')' {
$$ = $1; $$ = $1;
$$->u.function.arg_list = $3; $$->u.function.arg_list = $3;
...@@ -234,12 +237,20 @@ return_cellref (char *p) ...@@ -234,12 +237,20 @@ return_cellref (char *p)
} }
static int static int
return_symbol (char *string) return_sheetref (Sheet *sheet)
{
yylval.sheetref = sheet;
return SHEETREF;
}
static int
old_return_symbol (char *string)
{ {
ExprTree *e = p_new (ExprTree); ExprTree *e = p_new (ExprTree);
Symbol *sym; Symbol *sym;
int type; int type;
#warning remove me after testing the new code.
e->ref_count = 1; e->ref_count = 1;
sym = symbol_lookup (global_symbol_table, string); sym = symbol_lookup (global_symbol_table, string);
type = STRING; type = STRING;
...@@ -249,7 +260,13 @@ return_symbol (char *string) ...@@ -249,7 +260,13 @@ return_symbol (char *string)
Value *v = v_new (); Value *v = v_new ();
double fv; double fv;
char *format; char *format;
/*
* Try to match the entered text against any
* of the known number formating codes, if this
* succeeds, we store this as a float + format,
* otherwise, we return a string.
*/
if (format_match (string, &fv, &format)){ if (format_match (string, &fv, &format)){
v->type = VALUE_FLOAT; v->type = VALUE_FLOAT;
v->v.v_float = fv; v->v.v_float = fv;
...@@ -266,15 +283,16 @@ return_symbol (char *string) ...@@ -266,15 +283,16 @@ return_symbol (char *string)
else else
{ {
symbol_ref (sym); symbol_ref (sym);
if (sym->type == SYMBOL_FUNCTION) switch (sym->type){
{ case SYMBOL_FUNCTION:
e->oper = OPER_FUNCALL; e->oper = OPER_FUNCALL;
type = FUNCALL; type = FUNCALL;
e->u.function.symbol = sym; e->u.function.symbol = sym;
e->u.function.arg_list = NULL; e->u.function.arg_list = NULL;
} break;
else
{ case SYMBOL_VALUE:
case SYMBOL_STRING: {
Value *v, *dv; Value *v, *dv;
/* Make a copy of the value */ /* Make a copy of the value */
...@@ -285,7 +303,10 @@ return_symbol (char *string) ...@@ -285,7 +303,10 @@ return_symbol (char *string)
e->oper = OPER_CONSTANT; e->oper = OPER_CONSTANT;
e->u.constant = v; e->u.constant = v;
type = CONSTANT; type = CONSTANT;
break;
} }
} /* switch */
register_symbol (sym); register_symbol (sym);
} }
...@@ -294,15 +315,115 @@ return_symbol (char *string) ...@@ -294,15 +315,115 @@ return_symbol (char *string)
} }
static int static int
try_symbol (char *string) make_string_return (char *string)
{ {
int v; ExprTree *e;
Value *v;
double fv;
int type;
char *format;
e = p_new (ExprTree);
e->ref_count = 1;
v = v_new ();
/*
* Try to match the entered text against any
* of the known number formating codes, if this
* succeeds, we store this as a float + format,
* otherwise, we return a string.
*/
if (format_match (string, &fv, &format)){
v->type = VALUE_FLOAT;
v->v.v_float = fv;
if (!parser_desired_format)
parser_desired_format = format;
} else {
v->v.str = string_get (string);
v->type = VALUE_STRING;
}
v = return_cellref (string); e->oper = OPER_CONSTANT;
if (v) e->u.constant = v;
return v;
yylval.tree = e;
return return_symbol (string); return STRING;
}
static int
return_symbol (Symbol *sym)
{
ExprTree *e = p_new (ExprTree);
int type = STRING;
e->ref_count = 1;
symbol_ref (sym);
switch (sym->type){
case SYMBOL_FUNCTION:
e->oper = OPER_FUNCALL;
type = FUNCALL;
e->u.function.symbol = sym;
e->u.function.arg_list = NULL;
break;
case SYMBOL_VALUE:
case SYMBOL_STRING: {
Value *v, *dv;
/* Make a copy of the value */
dv = (Value *) sym->data;
v = v_new ();
value_copy_to (v, dv);
e->oper = OPER_CONSTANT;
e->u.constant = v;
type = CONSTANT;
break;
}
} /* switch */
register_symbol (sym);
yylval.tree = e;
return type;
}
/**
* try_symbol:
* @string: the string to try.
* @try_cellref: whether we know for sure if it is not a cellref
*
* Attempts to figure out what @string refers to.
* if @try_cellref is TRUE it will also attempt to match the
* string as a cellname reference.
*/
static int
try_symbol (char *string, gboolean try_cellref)
{
Symbol *sym;
int v;
if (try_cellref){
v = return_cellref (string);
if (v)
return v;
}
sym = symbol_lookup (global_symbol_table, string);
if (sym)
return return_symbol (sym);
else {
Sheet *sheet;
sheet = sheet_lookup_by_name (parser_sheet, string);
if (sheet)
return return_sheetref (sheet);
}
return make_string_return (string);
} }
int yylex (void) int yylex (void)
...@@ -358,12 +479,14 @@ int yylex (void) ...@@ -358,12 +479,14 @@ int yylex (void)
parser_expr = tmp; parser_expr = tmp;
return NUMBER; return NUMBER;
} }
case '\'':
case '"': { case '"': {
char *string, *s; char *string, *s;
int v; int v;
char *quotes_end = c;
p = parser_expr; p = parser_expr;
while(*parser_expr && *parser_expr != '"') { while(*parser_expr && *parser_expr != quotes_end) {
if (*parser_expr == '\\' && parser_expr [1]) if (*parser_expr == '\\' && parser_expr [1])
parser_expr++; parser_expr++;
parser_expr++; parser_expr++;
...@@ -385,7 +508,7 @@ int yylex (void) ...@@ -385,7 +508,7 @@ int yylex (void)
*s = 0; *s = 0;
parser_expr++; parser_expr++;
v = return_symbol (string); v = try_symbol (string, FALSE);
return v; return v;
} }
} }
...@@ -402,7 +525,7 @@ int yylex (void) ...@@ -402,7 +525,7 @@ int yylex (void)
str = alloca (len + 1); str = alloca (len + 1);
strncpy (str, start, len); strncpy (str, start, len);
str [len] = 0; str [len] = 0;
return try_symbol (str); return try_symbol (str, TRUE);
} }
if (c == '\n') if (c == '\n')
return 0; return 0;
......
...@@ -3188,7 +3188,7 @@ cellref_name (CellRef *cell_ref, Sheet *eval_sheet, int eval_col, int eval_row) ...@@ -3188,7 +3188,7 @@ cellref_name (CellRef *cell_ref, Sheet *eval_sheet, int eval_col, int eval_row)
char *s; char *s;
if (strchr (sheet->name, ' ')) if (strchr (sheet->name, ' '))
s = g_strconcat ("'", sheet->name, "'!", buffer, NULL); s = g_strconcat ("\"", sheet->name, "\"!", buffer, NULL);
else else
s = g_strconcat (sheet->name, "!", buffer, NULL); s = g_strconcat (sheet->name, "!", buffer, NULL);
...@@ -3205,3 +3205,36 @@ sheet_mark_clean (Sheet *sheet) ...@@ -3205,3 +3205,36 @@ sheet_mark_clean (Sheet *sheet)
sheet->modified = FALSE; sheet->modified = FALSE;
} }
/**
* sheet_lookup_by_name:
* @sheet: Local sheet.
* @name: a sheet name.
*
* This routine parses @name for a reference to another sheet
* in this workbook. If this fails, it will try to parse a
* filename in @name and load the given workbook and lookup
* the sheet name from that workbook.
*
* The routine might return NULL.
*/
Sheet *
sheet_lookup_by_name (Sheet *base, char *name)
{
Sheet *sheet;
g_return_val_if_fail (base != NULL, NULL);
g_return_val_if_fail (IS_SHEET (base), NULL);
/*
* FIXME: currently we only try to lookup the sheet name
* inside the workbook, we need to lookup external files as
* well.
*/
sheet = workbook_sheet_lookup (base->workbook, name);
if (sheet)
return sheet;
return NULL;
}