2019-07-22 20:32:33 +00:00
|
|
|
#ifndef SHEET_H
|
|
|
|
#define SHEET_H
|
|
|
|
|
|
|
|
#include "scanner.h"
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef enum { LEFT=0, RIGHT=1, CENTER=2, AUTOADJUST=3 } Adjust;
|
|
|
|
|
|
|
|
typedef enum { IN_X, IN_Y, IN_Z } Direction;
|
|
|
|
|
|
|
|
/* must be a prime */
|
|
|
|
#define LABEL_CACHE 29
|
|
|
|
|
|
|
|
#define ASCENDING 001
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int x;
|
|
|
|
int y;
|
|
|
|
int z;
|
|
|
|
int sortkey; /* OR-ed value of the above constants */
|
|
|
|
} Sortkey;
|
|
|
|
|
2019-07-27 04:14:26 +00:00
|
|
|
typedef enum { BASE=0, ITERATIVE=1, CONTINGENT=2 } ContentVariety;
|
|
|
|
|
2019-07-22 20:32:33 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2019-07-27 04:14:26 +00:00
|
|
|
Token **contents[CONTINGENT];
|
2019-07-22 20:32:33 +00:00
|
|
|
char *label;
|
|
|
|
Token value;
|
|
|
|
Token resvalue;
|
|
|
|
Adjust adjust;
|
|
|
|
int precision;
|
|
|
|
unsigned int updated:1;
|
|
|
|
unsigned int shadowed:1;
|
|
|
|
unsigned int scientific:1;
|
|
|
|
unsigned int locked:1;
|
|
|
|
unsigned int transparent:1;
|
|
|
|
unsigned int ignored:1;
|
|
|
|
unsigned int clock_t0:1;
|
|
|
|
unsigned int clock_t1:1;
|
|
|
|
unsigned int clock_t2:1;
|
|
|
|
unsigned int bold:1;
|
|
|
|
unsigned int underline:1;
|
|
|
|
} Cell;
|
|
|
|
|
2019-07-27 04:14:26 +00:00
|
|
|
#define NULLCELL ((Cell*)0)
|
|
|
|
|
2019-07-22 20:32:33 +00:00
|
|
|
struct Label
|
|
|
|
{
|
|
|
|
const char *label;
|
2019-07-27 04:14:26 +00:00
|
|
|
Location location;
|
2019-07-22 20:32:33 +00:00
|
|
|
struct Label *next;
|
|
|
|
};
|
|
|
|
|
2019-07-27 04:14:26 +00:00
|
|
|
typedef enum { MARK_CYCLE = 0, GET_MARK_CUR = 1, GET_MARK_ALL = 2,
|
|
|
|
MARKING = 3, MARKED = 4, UNMARKED = 5 } MarkState;
|
|
|
|
|
2019-07-22 20:32:33 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
struct Label *labelcache[LABEL_CACHE];
|
2019-07-27 04:14:26 +00:00
|
|
|
Location cur;
|
|
|
|
Location mark1, mark2;
|
|
|
|
MarkState marking;
|
2019-07-22 20:32:33 +00:00
|
|
|
int offx, offy;
|
|
|
|
Cell **sheet;
|
|
|
|
int *column;
|
|
|
|
int dimx, dimy, dimz;
|
|
|
|
int orix, oriy, maxx, maxy;
|
|
|
|
int width;
|
|
|
|
char *name;
|
|
|
|
unsigned int changed:1;
|
|
|
|
unsigned int moveonly:1;
|
|
|
|
unsigned int clk:1;
|
|
|
|
void *display;
|
|
|
|
} Sheet;
|
|
|
|
|
2019-07-27 04:14:26 +00:00
|
|
|
#define LOC_WITHINC(s,x,y,z) (x<s->dimx && y<s->dimy && z<s->dimz)
|
|
|
|
#define LOC_WITHIN(s,l) (LOC_WITHINC(s,l[X],l[Y],l[Z]))
|
|
|
|
#define CELL_ATC(s,x,y,z) (*((s)->sheet + (z)*(s)->dimy*(s)->dimx + (y)*(s)->dimx +(x)))
|
|
|
|
#define CELL_AT(s,l) (CELL_ATC(s,l[X],l[Y],l[Z]))
|
|
|
|
#define CELL_IS_NULLC(s,x,y,z) (CELL_ATC(s,x,y,z) == NULLCELL)
|
|
|
|
#define CELL_IS_NULL(s,l) (CELL_AT(s,l) == NULLCELL)
|
|
|
|
#define CELL_IS_GOODC(s,x,y,z) (LOC_WITHINC(s,x,y,z) && !CELL_IS_NULLC(s,x,y,z))
|
|
|
|
#define CELL_IS_GOOD(s,l) (LOC_WITHIN(s,l) && !CELL_IS_NULL(s,l))
|
|
|
|
#define SHADOWEDC(s,x,y,z) (CELL_IS_GOODC(s,x,y,z) && CELL_ATC(s,x,y,z)->shadowed)
|
|
|
|
#define SHADOWED(s,l) (CELL_IS_GOOD(s,l) && CELL_AT(s,l)->shadowed)
|
|
|
|
#define ALL_COORDS_IN_SHEETC(s,x,y,z) x=0; x<(s)->dimx; ++x) for (y=0; y<(s)->dimy; ++y) for (z=0; z<(s)->dimz; ++z
|
|
|
|
#define ALL_LOCS_IN_SHEET(s,l) l[Z]=0; l[Z]<(s)->dimz; ++(l[Z])) for (l[Y]=0; l[Y]<(s)->dimy; ++(l[Y])) for (l[X]=0; l[X]<(s)->dimx; ++(l[X])
|
|
|
|
#define ALL_LOCS_IN_REGION(s,l) l[Z]=(s)->mark1[Z]; l[Z]<=(s)->mark2[Z]; ++(l[Z])) for (l[Y]=(s)->mark1[Y]; l[Y]<=(s)->mark2[Y]; ++(l[Y])) for (l[X]=(s)->mark1[X]; l[X]<=(s)->mark2[X]; ++(l[X])
|
|
|
|
#define ALL_CELLS_IN_SHEET(s,i,c) i=0,c=*((s)->sheet); i<(s)->dimx*(s)->dimy*(s)->dimz; ++i, c=*((s)->sheet+i)
|
|
|
|
|
2019-07-22 20:32:33 +00:00
|
|
|
extern Sheet *upd_sheet;
|
2019-07-27 04:14:26 +00:00
|
|
|
extern Location upd_l;
|
2019-07-22 20:32:33 +00:00
|
|
|
extern int max_eval;
|
|
|
|
|
2019-07-27 04:14:26 +00:00
|
|
|
void initialize_sheet(Sheet *sheet);
|
2019-07-22 20:32:33 +00:00
|
|
|
void resize(Sheet *sheet, int x, int y, int z);
|
2019-07-27 04:14:26 +00:00
|
|
|
Cell *initcell(Sheet *sheet, const Location at);
|
|
|
|
Cell *safe_cell_at(Sheet *sheet, const Location at);
|
|
|
|
Cell *curcell(Sheet *sheet);
|
2019-07-22 20:32:33 +00:00
|
|
|
void cachelabels(Sheet *sheet);
|
|
|
|
void freesheet(Sheet *sheet, int all);
|
|
|
|
void forceupdate(Sheet *sheet);
|
2019-07-27 04:14:26 +00:00
|
|
|
MarkState getmarkstate(Sheet *sheet);
|
Prevent phantom values when clocking, resetting, and clocking again
In the end it turned out that the cause of the phantom values was
short-cutting in getvalue() when the contents of a cell were empty,
preventing the update of the internal cache of the value of the cell.
However, tracking this down (and getting the associated memory management
correct) necessitated implementing a debugging mode in which I could
dump the internal states of cells and print various other stuff to standard
output. It also involved understanding the meaning of various pointers in
the code, in the process of which I renamed some commonly used macros,
particularly the former SHEET(s,x,y,z) which was not returning a Sheet at
all but rather a pointer to a Cell. So this macro is now called CELL_AT. I
also replaced several very repeatedly used patterns of checking the validity
of locations and pointers with macros, now defined in sheet.h.
Therefore, unfortunately the (relatively small in the end) bugfix for this
major issue is entangled with numerous textual changes to the code made
in tracking it down.
Fixes #18.
Closes #19.
2019-07-24 17:47:39 +00:00
|
|
|
void dump_current_cell(Sheet *sheet);
|
2019-07-27 04:14:26 +00:00
|
|
|
void freecell(Sheet *sheet, const Location at);
|
2019-07-22 20:32:33 +00:00
|
|
|
int columnwidth(Sheet *sheet, int x, int z);
|
|
|
|
void setwidth(Sheet *sheet, int x, int z, int width);
|
2019-07-27 04:14:26 +00:00
|
|
|
int cellwidth(Sheet *sheet, const Location at);
|
|
|
|
void putcont(Sheet *sheet, const Location at, Token **t, ContentVariety v);
|
|
|
|
Token **getcont(const Cell *cell, ContentVariety v);
|
|
|
|
Token getvalue(Sheet *sheet, const Location at);
|
2019-07-22 20:32:33 +00:00
|
|
|
void update(Sheet *sheet);
|
2019-07-27 04:14:26 +00:00
|
|
|
char *geterror(Sheet *sheet, const Location at);
|
|
|
|
void printvalue(char *s, size_t size, size_t chars, int quote, int scientific, int precision, Sheet *sheet, const Location at);
|
|
|
|
Adjust getadjust(const Cell *cell);
|
|
|
|
void setadjust(Sheet *sheet, const Location at, Adjust adjust);
|
|
|
|
void shadow(Sheet *sheet, const Location at, int yep);
|
|
|
|
int shadowed(const Cell *cell);
|
|
|
|
void bold(Sheet *sheet, const Location at, int yep);
|
|
|
|
int isbold(const Cell *cell);
|
|
|
|
void underline(Sheet *sheet, const Location at, int yep);
|
|
|
|
int underlined(const Cell *cell);
|
|
|
|
void lockcell(Sheet *sheet, const Location at, int yep);
|
|
|
|
int locked(const Cell *cell);
|
|
|
|
int transparent(const Cell *cell);
|
|
|
|
void maketrans(Sheet *sheet, const Location at, int yep);
|
|
|
|
void igncell(Sheet *sheet, const Location at, int yep);
|
|
|
|
int ignored(const Cell *cell);
|
|
|
|
void clk(Sheet *sheet, const Location at);
|
|
|
|
void setscientific(Sheet *sheet, const Location at, int yep);
|
|
|
|
int getscientific(const Cell *cell);
|
|
|
|
void setprecision(Sheet *sheet, const Location at, int precision);
|
|
|
|
int getprecision(const Cell* cell);
|
|
|
|
const char *getlabel(const Cell* cell);
|
|
|
|
void setlabel(Sheet *sheet, const Location at, const char *buf, int update);
|
2019-07-22 20:32:33 +00:00
|
|
|
Token findlabel(Sheet *sheet, const char *label);
|
2019-07-27 04:14:26 +00:00
|
|
|
void relabel(Sheet* sheet, const Location at,
|
|
|
|
const char *oldlabel, const char *newlabel);
|
|
|
|
|
2019-07-22 20:32:33 +00:00
|
|
|
const char *savexdr(Sheet *sheet, const char *name, unsigned int *count);
|
2019-07-27 04:14:26 +00:00
|
|
|
const char *savetbl(Sheet *sheet, const char *name, int body, const Location beg, const Location end, unsigned int *count);
|
|
|
|
const char *savetext(Sheet *sheet, const char *name, const Location beg, const Location end, unsigned int *count);
|
|
|
|
const char *savecsv(Sheet *sheet, const char *name, char sep, const Location beg, const Location end, unsigned int *count);
|
2019-07-22 20:32:33 +00:00
|
|
|
const char *saveport(Sheet *sheet, const char *name, unsigned int *count);
|
|
|
|
const char *loadxdr(Sheet *sheet, const char *name);
|
|
|
|
const char *loadport(Sheet *sheet, const char *name);
|
|
|
|
const char *loadcsv(Sheet *sheet, const char *name);
|
2019-07-27 04:14:26 +00:00
|
|
|
|
|
|
|
void insertcube(Sheet *sheet, const Location beg, const Location end, Direction ins);
|
|
|
|
void deletecube(Sheet *sheet, const Location beg, const Location end, Direction ins);
|
|
|
|
void moveblock(Sheet *sheet, const Location beg, const Location end, const Location dest, int copy);
|
|
|
|
const char *sortblock(Sheet *sheet, const Location beg, const Location end, Direction dir, Sortkey *sk, size_t sklen);
|
|
|
|
void mirrorblock(Sheet *sheet, const Location beg, const Location end, Direction dir);
|
2019-07-22 20:32:33 +00:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|