Commit ef28d5f2 authored by Miguel de Icaza's avatar Miguel de Icaza Committed by Arturo Espinosa

Numbers are parsed correctly. Bits of Oleo number parsing plugged in.

1998-07-21  Miguel de Icaza  <miguel@nuclecu.unam.mx>

	* src/parser.y (yylex): Numbers are parsed correctly.  Bits of
	Oleo number parsing plugged in.

	* src/util.c, src/util.h: New files with assorted number utilities.

	* src/numbers.h: New file: takes care of using gmp or regular
	double/int.

	* src/expr.c (eval_release_node): Implement.
	(eval_release_value): New function.

	* src/sheet.c (sheet_col_selection_changed,
	sheet_row_selection_changed): Implement.
	(sheet_selection_clear, sheet_selection_clear_only): Splitted
	functionality into two routines.
	(sheet_selection_clear_only): Remove any marks from the bars.
	(sheet_row_set_selection, sheet_col_set_selection): Implement.

	* src/item-bar.c (is_pointer_on_division): Return the column
	changed.

	* src/item-grid.c (item_grid_draw_cell): Fix the computation for
	right indentation.
parent 8a0efba8
1998-07-21 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/parser.y (yylex): Numbers are parsed correctly. Bits of
Oleo number parsing plugged in.
* src/util.c, src/util.h: New files with assorted number utilities.
* src/numbers.h: New file: takes care of using gmp or regular
double/int.
* src/expr.c (eval_release_node): Implement.
(eval_release_value): New function.
* src/sheet.c (sheet_col_selection_changed,
sheet_row_selection_changed): Implement.
(sheet_selection_clear, sheet_selection_clear_only): Splitted
functionality into two routines.
(sheet_selection_clear_only): Remove any marks from the bars.
(sheet_row_set_selection, sheet_col_set_selection): Implement.
* src/item-bar.c (is_pointer_on_division): Return the column
changed.
* src/item-grid.c (item_grid_draw_cell): Fix the computation for
right indentation.
1998-07-17 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/gnumeric-sheet.c (gnumeric_sheet_key): Add support for
......
1998-07-21 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/parser.y (yylex): Numbers are parsed correctly. Bits of
Oleo number parsing plugged in.
* src/util.c, src/util.h: New files with assorted number utilities.
* src/numbers.h: New file: takes care of using gmp or regular
double/int.
* src/expr.c (eval_release_node): Implement.
(eval_release_value): New function.
* src/sheet.c (sheet_col_selection_changed,
sheet_row_selection_changed): Implement.
(sheet_selection_clear, sheet_selection_clear_only): Splitted
functionality into two routines.
(sheet_selection_clear_only): Remove any marks from the bars.
(sheet_row_set_selection, sheet_col_set_selection): Implement.
* src/item-bar.c (is_pointer_on_division): Return the column
changed.
* src/item-grid.c (item_grid_draw_cell): Fix the computation for
right indentation.
1998-07-17 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/gnumeric-sheet.c (gnumeric_sheet_key): Add support for
......
1998-07-21 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/parser.y (yylex): Numbers are parsed correctly. Bits of
Oleo number parsing plugged in.
* src/util.c, src/util.h: New files with assorted number utilities.
* src/numbers.h: New file: takes care of using gmp or regular
double/int.
* src/expr.c (eval_release_node): Implement.
(eval_release_value): New function.
* src/sheet.c (sheet_col_selection_changed,
sheet_row_selection_changed): Implement.
(sheet_selection_clear, sheet_selection_clear_only): Splitted
functionality into two routines.
(sheet_selection_clear_only): Remove any marks from the bars.
(sheet_row_set_selection, sheet_col_set_selection): Implement.
* src/item-bar.c (is_pointer_on_division): Return the column
changed.
* src/item-grid.c (item_grid_draw_cell): Fix the computation for
right indentation.
1998-07-17 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/gnumeric-sheet.c (gnumeric_sheet_key): Add support for
......
1998-07-21 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/parser.y (yylex): Numbers are parsed correctly. Bits of
Oleo number parsing plugged in.
* src/util.c, src/util.h: New files with assorted number utilities.
* src/numbers.h: New file: takes care of using gmp or regular
double/int.
* src/expr.c (eval_release_node): Implement.
(eval_release_value): New function.
* src/sheet.c (sheet_col_selection_changed,
sheet_row_selection_changed): Implement.
(sheet_selection_clear, sheet_selection_clear_only): Splitted
functionality into two routines.
(sheet_selection_clear_only): Remove any marks from the bars.
(sheet_row_set_selection, sheet_col_set_selection): Implement.
* src/item-bar.c (is_pointer_on_division): Return the column
changed.
* src/item-grid.c (item_grid_draw_cell): Fix the computation for
right indentation.
1998-07-17 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/gnumeric-sheet.c (gnumeric_sheet_key): Add support for
......
......@@ -3,7 +3,7 @@ CFLAGS += -g -Wall \
-Wmissing-prototypes -Wmissing-declarations
bin_PROGRAMS = gnumeric
noinst_PROGRAMS = test-format test-token
noinst_PROGRAMS = test-format
INCLUDES = \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
......@@ -35,6 +35,8 @@ gnumeric_SOURCES = \
style.h \
symbol.h \
symbol.c \
utils.c \
utils.h \
workbook.c
gnumeric_LDADD = \
......@@ -48,12 +50,12 @@ test_format_LDADD = \
$(GNOME_LIBDIR) \
$(GNOMEUI_LIBS)
test_token_SOURCES = \
test-token.c \
token.c \
token.h
test_token_LDADD = \
$(GNOME_LIBDIR) \
$(GNOMEUI_LIBS) -lgmp
#test_token_SOURCES = \
# test-token.c \
# token.c \
# token.h##
#
#test_token_LDADD = \
# $(GNOME_LIBDIR) \
# $(GNOMEUI_LIBS) -lgmp
#include <config.h>
#include <gnome.h>
#include <gnumeric.h>
......
#include <config.h>
#include <glib.h>
#include <gmp.h>
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-i18n.h>
#include "numbers.h"
#include "symbol.h"
#include "expr.h"
char *parser_expr;
char **parser_error_message;
ParseErr parser_error;
EvalNode *parser_result;
EvalNode *
eval_parse_string (char *expr, int col, int row, char **error_msg)
{
parser_expr = expr;
parser_error_message = error_msg;
parser_error = PARSE_OK;
yyparse ();
switch (parser_error){
case PARSE_OK:
*error_msg = NULL;
break;
case PARSE_ERR_NO_QUOTE:
*error_msg = _("Missing quote");
break;
}
return NULL;
}
static void
eval_release_value (Value *value)
{
switch (value->type){
case VALUE_STRING:
symbol_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;
default:
g_warning ("Unknown value type passed to eval_release_value\n");
}
}
void
eval_release_node (EvalNode *node)
{
g_return_if_fail (node != NULL);
switch (node->oper){
case OP_CONSTANT:
eval_release_value (node->u.constant);
break;
case OP_FUNCALL:
symbol_unref (node->u.function.symbol);
break;
case OP_ADD:
case OP_SUB:
case OP_MULT:
case OP_DIV:
case OP_EXP:
case OP_CONCAT:
eval_release_node (node->u.binary.value_a);
eval_release_node (node->u.binary.value_b);
break;
case OP_NEG:
eval_release_node (node->u.value);
break;
default:
g_warning ("Unknown ExprNode type passed to eval_release_node\n");
}
}
......@@ -12,13 +12,13 @@ typedef enum {
OP_FUNCALL,
OP_CONSTANT,
OP_CAST_TO_STRING,
OP_NEG
} Operation;
typedef enum {
VALUE_STRING,
VALUE_NUMBER,
VALUE_INTEGER,
VALUE_FLOAT,
VALUE_CELLRANGE
} ValueType;
......@@ -40,7 +40,8 @@ typedef struct {
} cell;
Symbol *str;
mpf_t number; /* floating point */
float_t v_float; /* floating point */
int_t v_int;
} v;
} Value;
......@@ -65,9 +66,14 @@ struct EvalNode {
typedef struct EvalNode EvalNode;
typedef enum {
PARSE_OK,
PARSE_ERR_NO_QUOTE
} ParseErr;
/* For talking to yyparse */
extern char *parser_expr;
extern char **parser_error_message;
extern ParseErr parser_error;
extern EvalNode *parser_result;
EvalNode *eval_parse_string (char *expr, int col, int row, char **error_msg);
......
#include <gmp.h>
#include "numbers.h"
#include "style.h"
#include "symbol.h"
#include "expr.h"
......
#include <config.h>
#include <stdlib.h>
#include <glib.h>
#include <string.h>
#include "numbers.h"
#include "symbol.h"
#include "expr.h"
#include "utils.h"
#define SMALL_BUF_SIZE 40
static char small_buffer [SMALL_BUF_SIZE];
void
float_get_from_range (char *start, char *end, float_t *t)
{
char *p;
int size = end - start;
if (size < SMALL_BUF_SIZE-1){
p = small_buffer;
strncpy (small_buffer, start, size);
small_buffer [size] = 0;
} else {
p = g_malloc (size + 1);
strcpy (p, start);
p [size] = 0;
}
#ifdef GNUMERIC_USE_GMP
mpf_init_set_str (*t, p, 10);
#else
*t = atof (p);
#endif
if (p != small_buffer)
g_free (p);
}
void
int_get_from_range (char *start, char *end, int_t *t)
{
char *p;
int size = end - start;
if (size < SMALL_BUF_SIZE-1){
p = small_buffer;
strncpy (small_buffer, start, size);
small_buffer [size] = 0;
} else {
p = g_malloc (size + 1);
strcpy (p, start);
p [size] = 0;
}
#ifdef GNUMERIC_USE_GMP
mpz_init_set_str (*t, p, 10);
#else
*t = atoi (p);
#endif
if (p != small_buffer)
g_free (p);
}
#ifndef G_UTILS_H
#define G_UTILS_H
/* Gets an integer in the buffer in start to end */
void int_get_from_range (char *start, char *end, int_t *t);
void float_get_from_range (char *start, char *end, float_t *t);
#endif
......@@ -248,6 +248,12 @@ is_pointer_on_division (ItemBar *item_bar, int pos, int *the_total, int *the_ele
return cri;
}
if (total > pos){
if (the_element)
*the_element = i;
return NULL;
}
}
return NULL;
}
......@@ -367,7 +373,7 @@ item_bar_event (GnomeCanvasItem *item, GdkEvent *e)
} else {
gtk_signal_emit (GTK_OBJECT (item),
item_bar_signals [SELECTION_CHANGED],
item_bar->resize_pos);
ele);
}
break;
......
......@@ -225,7 +225,7 @@ item_grid_draw_cell (GdkDrawable *drawable, ItemGrid *item_grid,
case HALIGN_RIGHT:
if (col > 0)
clip_left = sheet_cell_get (sheet, col-1, row);
x_offset = cell->col->pixels - (cell->width - cell->col->margin_b);
x_offset = cell->col->pixels - cell->width - (cell->col->margin_b + cell->col->margin_a);
break;
case HALIGN_CENTER:
......@@ -233,7 +233,7 @@ item_grid_draw_cell (GdkDrawable *drawable, ItemGrid *item_grid,
clip_left = sheet_cell_get (sheet, col-1, row);
if (col < SHEET_MAX_COLS-1)
clip_right = sheet_cell_get (sheet, col-1, row);
x_offset = (cell->width - cell->col->pixels)/2;
x_offset = (cell->col->pixels - cell->width)/2;
break;
case HALIGN_FILL:
......@@ -267,7 +267,7 @@ item_grid_draw_cell (GdkDrawable *drawable, ItemGrid *item_grid,
gdk_gc_set_clip_rectangle (gc, NULL);
gdk_draw_rectangle (drawable, white_gc, TRUE,
x1 + cell->col->margin_a,
x1 + x_offset,
y1 + cell->row->margin_a,
cell->width - (cell->col->margin_a + cell->col->margin_b),
height - (cell->row->margin_a + cell->row->margin_b));
......
#include <config.h>
#include <gnome.h>
#include "gnumeric.h"
......
#include <config.h>
#include <gnome.h>
#include "gnumeric.h"
......
#ifdef GNUMERIC_USE_GMP
#include <gmp.h>
typedef mpf_t float_t;
typedef mpz_t int_t;
#else
typedef double float_t;
typedef int int_t;
#define mpz_clear(x)
#define mpf_clear(x)
#endif
%{
/*
* Gnumeric Parser
*
* (C) 1998 the Free Software Foundation
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*/
#include <glib.h>
#include <gmp.h>
#include "numbers.h"
#include "symbol.h"
#include "expr.h"
#include "utils.h"
#include <ctype.h>
static GList *alloc_list;
/* Allocation with disposal-on-error */
static void *alloc_buffer (int size);
static void dump_node (EvalNode *node);
static void register_symbol (Symbol *sym);
static void alloc_clean (void);
static void *v_new (void);
#define ERROR -1
/* Types of items we know how to dispose on error */
typedef enum {
ALLOC_SYMBOL,
ALLOC_VALUE,
ALLOC_BUFFER,
} AllocType;
/* How we keep track of them */
typedef struct {
AllocType type;
void *data;
} AllocRec;
/* This keeps a list of AllocRecs */
static GList *alloc_list;
/* Debugging */
static void dump_constant (EvalNode *node);
static void dump_node (EvalNode *node);
/* Bison/Yacc internals */
static int yylex (void);
static int yyerror (char *s);
#define p_new(type) \
((type *) alloc_buffer ((unsigned) sizeof (type)))
%}
%union {
EvalNode *node;
CellRef *cell;
......@@ -96,19 +130,70 @@ arg_list: {}
int yylex (void)
{
int c;
char *p, *tmp;
int is_float;
c = getchar ();
if (isdigit (c)){
while(isspace (*parser_expr))
parser_expr++;
c = *parser_expr++;
if (c == '(' || c == ',' || c == ')')
return c;
switch (c){
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '.': {
EvalNode *e = p_new (EvalNode);
Value *v = p_new (Value);
Value *v = v_new ();
is_float = c == '.';
p = parser_expr-1;
tmp = parser_expr;
while (isdigit (*tmp) || (!is_float && *tmp=='.' && ++is_float))
tmp++;
if (*tmp == 'e' || *tmp == 'E') {
is_float = 1;
tmp++;
if (*tmp == '-' || *tmp == '+')
tmp++;
while (isdigit (*tmp))
tmp++;
}
/* Ok, we have skipped over a number, now load its value */
if (is_float){
v->type = VALUE_FLOAT;
float_get_from_range (p, tmp, &v->v.v_float);
} else {
v->type = VALUE_INTEGER;
int_get_from_range (p, tmp, &v->v.v_int);
}
v->type = VALUE_NUMBER;
/* Return the value to the parser */
e->oper = OP_CONSTANT;
e->u.constant = v;
yylval.node = e;
parser_expr = tmp;
return NUMBER;
}
case '"':
p = parser_expr;
while(*parser_expr && *parser_expr != '"') {
if (*parser_expr == '\\' && parser_expr [1])
parser_expr++;
parser_expr++;
}
if(!*parser_expr){
parser_error = PARSE_ERR_NO_QUOTE;
return ERROR;
}
/* NOTE: This is non-functional */
}
if (isalpha (c)){
EvalNode *e = p_new (EvalNode);
Value *v = p_new (Value);
......@@ -151,16 +236,6 @@ yyerror (char *s)
return 0;
}
typedef enum {
ALLOC_SYMBOL,
ALLOC_BUFFER,
} AllocType;
typedef struct {
AllocType type;
void *data;
} AllocRec;
static void
register_symbol (Symbol *sym)
{
......@@ -184,6 +259,38 @@ alloc_buffer (int size)
return res;
}
void *
v_new (void)
{
AllocRec *a_info = g_new (AllocRec, 1);
char *res = g_malloc (sizeof (Value));
a_info->type = ALLOC_VALUE;
a_info->data = res;
alloc_list = g_list_prepend (alloc_list, a_info);
return res;
}
static void
clean_value (Value *v)
{
switch (v->type){
case VALUE_FLOAT:
mpf_clear (v->v.v_float);
break;
case VALUE_INTEGER:
mpz_clear (v->v.v_int);
break;
default:
g_warning ("Unknown value passed to clean_value\n");
break;
}
}
static void
alloc_clean (void)
{
......@@ -200,6 +307,9 @@ alloc_clean (void)
case ALLOC_SYMBOL:
symbol_unref ((Symbol *)rec->data);
break;
case ALLOC_VALUE:
clean_value ((Value *)rec->data);
}
}
......@@ -217,10 +327,14 @@ dump_constant (EvalNode *node)
printf ("STRING: %s\n", value->v.str->str);
break;
case VALUE_NUMBER:
case VALUE_INTEGER:
printf ("NUM: %d\n", 0);
break;
case VALUE_FLOAT:
printf ("Float: %f\n", 0.0);
break;
default:
printf ("Unhandled item type\n");
}
......@@ -266,10 +380,5 @@ dump_node (EvalNode *node)
printf ("NEGATIVE\n");
break;
case OP_CAST_TO_STRING:
dump_node (node->u.value);
printf ("CAST TO STRING\n");
break;
}
}
......@@ -6,6 +6,7 @@
* Miguel de Icaza (miguel@gnu.org)
*