/*	Copyright (C) 1990 Free Software Foundation, Inc.

This file is part of Oleo, the GNU Spreadsheet.

Oleo is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.

Oleo is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Oleo; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* The most important compile-time constant.  How many bits do we want to
   allocate for cell-references?  Useful values are 8 and 16 (at the moment)
   8 allows luser to access 255*255 cells (probably big enough)
   16 allows luser to access 65535*65535, which is more than will fit in
   the avaliable virtual memory on any 32-bit machine.
 */

#ifndef BITS_PER_CELLREF
#define BITS_PER_CELLREF 8
#endif

/* The location of a cell that can never be referenced */
#define NON_ROW		0
#define NON_COL		0

#define MIN_ROW		1
#define MIN_COL 	1

#if BITS_PER_CELLREF==16
typedef unsigned short CELLREF;
#define CELLREF_MASK 0xFFFF
#define MAX_ROW 65535
#define MAX_COL 65535

/* Do *not* assume that 'name' is aligned!  It probably isn't */
#define GET_ROW(name)		((((name)[0])<<8)|(name)[1])
#define GET_COL(name)		((((name)[2])<<8)|(name)[3])
#define PUT_ROW(name,val)	((name)[0]=((val)>>8)),((name)[1]=val)
#define PUT_COL(name,val)	((name)[2]=((val)>>8)),((name)[3]=val)
#define EXP_ADD			sizeof(CELLREF)*2
#else
#if BITS_PER_CELLREF==8
typedef unsigned char CELLREF;
#define CELLREF_MASK 0xFF
#define MAX_ROW	      255
#define MAX_COL       255

#define GET_ROW(name)		((name)[0])
#define GET_COL(name)		((name)[1])
#define PUT_ROW(name,val)	((name)[0]=(val))
#define PUT_COL(name,val)	((name)[1]=(val))
#define EXP_ADD			sizeof(CELLREF)*2
#else
FOO FOO FOO You need to define the obvious macros above
#endif
#endif

/* Struct rng is used to describe a region of cells */

struct rng {
	CELLREF lr,lc,hr,hc;
};

/* refs_fm contains a list of the other cells that reference this one */
/* The fm_refs array is actually variable-sized.  .refs_alloc tells how
   many entries were allocated for it */

struct ref_fm {
#ifdef SPLIT_REFS
	unsigned short refs_alloc;
#else
	unsigned short refs_refcnt;
	struct ref_fm *refs_next;
#endif
	unsigned short refs_used;
	struct ref_array {
		CELLREF ref_row;
		CELLREF ref_col;
	} fm_refs[1];
};

/* refs_to is a vector of locations in the cell's formula where the
   cell references other cells, ranges, or variables */
struct ref_to {
#ifdef SPLIT_REFS
	unsigned short refs_alloc;
#else
	unsigned short refs_refcnt;
	struct ref_to *refs_next;
#endif
	unsigned short refs_used;
	unsigned char to_refs[1];
};

#define GET_RNG(name,putit)	bcopy((VOIDSTAR)(name),(VOIDSTAR)(putit),sizeof(struct rng))
#define PUT_RNG(name,putit)	bcopy((VOIDSTAR)(putit),(VOIDSTAR)(name),sizeof(struct rng))
#define EXP_ADD_RNG		sizeof(struct rng)

#define ERR_MAX		17

extern struct obstack tmp_mem;
extern VOIDSTAR tmp_mem_start;

extern char* ename[];
extern const char tname[];
extern const char fname[];
extern const char iname[];
extern const char mname[];
extern const char nname[];

extern void error_msg EXT1N(char *);
extern void text_line EXT1N(char *);

extern char *strdup EXT1(const char *);
extern double astof EXT1(char **);
extern long astol EXT1(char **);
extern VOIDSTAR ck_malloc EXT1(size_t);
extern VOIDSTAR ck_realloc EXT2(void *,size_t);
extern void panic EXT1N(const char *);

extern VOIDSTAR init_stack EXT1(void);
extern void flush_stack EXT1(void *);
extern void push_stack EXT2(void *, void *);
extern VOIDSTAR pop_stack EXT1(void *);
extern int size_stack EXT1(void *);

extern void add_ref EXT2(CELLREF, CELLREF);
extern void add_range_ref EXT1(struct rng *);
extern void add_timer_ref EXT1(int);
extern void add_ref_to EXT1(int);

extern VOIDSTAR parse_hash;
extern char *hash_insert();

extern CELLREF cur_row;
extern CELLREF cur_col;

extern unsigned short get_width EXT1(CELLREF);
extern void set_width EXT2(CELLREF, unsigned short);

extern char *jst_to_str EXT1(int);
extern char *fmt_to_str EXT1(int);

#ifdef A0_REFS
extern char * col_to_str EXT1(CELLREF);
#endif

extern char *flt_to_str EXT1(double);
extern void push_refs EXT1(struct ref_fm *);
extern void no_more_cells EXT0();

extern double __plinf, __neinf, __nan;

extern char *range_name EXT1(struct rng *);
extern char *cell_name EXT2(CELLREF, CELLREF);

extern CELLREF curow,cucol;
extern CELLREF cur_row,cur_col;

extern int default_jst;
extern int default_fmt;

extern unsigned short current_cycle;

extern char *new_value EXT3(CELLREF, CELLREF, char *);

extern unsigned char parse_cell_or_range EXT2(char **,struct rng *);

extern void info_msg EXT1N(char *);

extern void for_all_vars EXT1(void (*)());

