diff --git a/eval.c b/eval.c
index 6783a40..554ac5f 100644
--- a/eval.c
+++ b/eval.c
@@ -63,25 +63,36 @@ void tfree(Token *n)
n->u.lident=(char*)0;
}
}
+/*}}}*/
+/* tvecfreetoks -- free the tokens in vector of pointer to tokens */ /*{{{*/
+void tvecfreetoks(Token **tvec)
+{
+ if (tvec!=EMPTY_TVEC)
+ while (*tvec != NULLTOKEN)
+ {
+ tfree(*tvec);
+ free(*tvec);
+ *(tvec++) = NULLTOKEN;
+ }
+}
+
/*}}}*/
/* tvecfree -- free a vector of pointer to tokens entirely */ /*{{{*/
void tvecfree(Token **tvec)
{
- if (tvec!=(Token**)0)
- {
- /* variables */ /*{{{*/
- Token **t;
- /*}}}*/
-
- for (t=tvec; *t!=(Token*)0; ++t)
- {
- tfree(*t);
- free(*t);
- }
- free(tvec);
- }
+ tvecfreetoks(tvec);
+ free(tvec);
}
/*}}}*/
+/* tveclen -- return length of a vector of pointer to tokens */ /*{{{*/
+size_t tveclen(Token **tvec)
+{
+ size_t len;
+ if (tvec == EMPTY_TVEC) return 0;
+ for (len=1; *tvec != NULLTOKEN; ++len,++tvec);
+ return len;
+}
+/*}}}*/
/* tadd -- + operator */ /*{{{*/
Token tadd(Token l, Token r)
{
diff --git a/eval.h b/eval.h
index 9f3cc87..868602f 100644
--- a/eval.h
+++ b/eval.h
@@ -5,7 +5,9 @@
Token tcopy(Token n);
void tfree(Token *n);
+void tvecfreetoks(Token **tvec);
void tvecfree(Token **tvec);
+size_t tveclen(Token **tvec);
Token tpow(Token l, Token r);
Token tdiv(Token l, Token r);
Token tmod(Token l, Token r);
diff --git a/fteapot.fl b/fteapot.fl
index cb73a78..a5867f9 100644
--- a/fteapot.fl
+++ b/fteapot.fl
@@ -68,12 +68,6 @@ decl {\#include "misc.h"} {private global
decl {\#include "display.h"} {public global
}
-decl {\#define SHEET(s,x,y,z) (*(s->sheet+(x)*s->dimz*s->dimy+(y)*s->dimz+(z)))} {private global
-}
-
-decl {\#define SHADOWED(sheet,x,y,z) (xdimx && ydimy && zdimz && SHEET(sheet,x,y,z)!=(Cell*)0 && SHEET(sheet,x,y,z)->shadowed)} {private global
-}
-
class TeapotTable {open : {public Fl_Table}
} {
decl {Sheet *cursheet;} {protected local
@@ -269,6 +263,7 @@ updating = false;
case 'v': k = ctrl?(cut?BLOCK_MOVE:BLOCK_COPY):(Key)'v'; break;
case 'x': if (ctrl) { do_mark(cursheet, 2); cut = true, k = K_NONE; } break;
case 'r': if (ctrl) k = K_RECALC; break;
+ case 'd': if (ctrl && shift && debug_level > 0) k = K_DUMPCELL; break;
case FL_Insert: if (ctrl) { do_mark(cursheet, 2); cut = false; } k = !shift?K_NONE:cut?BLOCK_MOVE:BLOCK_COPY; break;
case FL_Delete: if (shift) { do_mark(cursheet, 2); cut = true; } k = shift?K_NONE:BLOCK_CLEAR; break;
case FL_Home: k = ctrl?K_FIRSTL:shift?K_FSHEET:K_HOME; break;
diff --git a/main.c b/main.c
index 4041655..cd50488 100644
--- a/main.c
+++ b/main.c
@@ -50,6 +50,7 @@ unsigned int batchln=0;
int def_precision=DEF_PRECISION;
int quote=0;
int header=1;
+int debug_level=0;
static int usexdr=1;
/*}}}*/
@@ -1632,6 +1633,7 @@ int do_sheetcmd(Sheet *cursheet, Key c, int moveonly)
#else
case K_HELP: show_text(_("Sorry, manual is not installed.")); break;
#endif
+ case K_DUMPCELL: dump_current_cell(cursheet); break;
case K_ABOUT: show_text(_("About teapot\n\n"
" ` ',` ' ' \n"
" ` ' ` ' ' \n"
@@ -1655,10 +1657,13 @@ int do_sheetcmd(Sheet *cursheet, Key c, int moveonly)
"\n"
"Original Version: Michael Haardt
\n"
"Current Maintainer: Joerg Walter
\n"
+ "Contibutions by: Glen Whitney
\b"
"Home Page: http://www.syntax-k.de/projekte/teapot/
\n"
+ "This distribution: https://code.studioinfinity.org/glen/teapot-spreadsheet/
\n"
"\n"
"Copyright 1995-2006 Michael Haardt,
\n"
- "Copyright 2009-2010 Joerg Walter (info@syntax-k.de)
\n"
+ "Copyright 2009-2010 Joerg Walter (info@syntax-k.de)
"
+ "Copyright 2019 Glen Whitney\n"
"\f"
"This program is free software: you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
@@ -1765,7 +1770,7 @@ int main(int argc, char *argv[])
find_helpfile(helpfile, sizeof(helpfile), argv[0]);
/* parse options */ /*{{{*/
- while ((o=getopt(argc,argv,"abhnrqHp:?"))!=EOF) switch (o)
+ while ((o=getopt(argc,argv,"abdhnrqHp:?"))!=EOF) switch (o)
{
/* a -- use ascii as default */ /*{{{*/
case 'a':
@@ -1777,6 +1782,9 @@ int main(int argc, char *argv[])
/* b -- run batch */ /*{{{*/
case 'b': batch=1; break;
/*}}}*/
+ /* d -- increase debug level */ /*{{{*/
+ case 'd': ++debug_level; break;
+ /*}}}*/
/* n -- no quoted strings */ /*{{{*/
case 'n': quote=0; break;
/*}}}*/
@@ -1813,10 +1821,12 @@ int main(int argc, char *argv[])
default:
{
fprintf(stderr,_(
- "Usage: %s [-a] [-b] [-n] [-H] [-r] [-p digits] [file]\n"
+ "Usage: %s [-a] [-b] [-d]* [-h] [-n|-q] [-H] [-r] [-p digits] [file]\n"
" -a: use ASCII file format as default\n"
" -b: batch mode\n"
- " -q: display strings in quotes\n"
+ " -d: increase debug level, once for each occurrence\n"
+ " -h: print this message and exit\n"
+ " -n|-q: DO NOT or DO display strings in quotes, respectively\n"
" -H: hide row/column headers\n"
" -r: redraw more often\n"
" -p: set decimal precision\n"
diff --git a/main.h b/main.h
index 0f38923..626c115 100644
--- a/main.h
+++ b/main.h
@@ -15,6 +15,7 @@ extern int batch;
extern int def_precision;
extern int quote;
extern int header;
+extern int debug_level;
extern unsigned int batchln;
/* A variable of type Key is either a special symbol from this enum, representing
@@ -78,7 +79,8 @@ typedef enum {
BLOCK_MIRROR = -53,
K_ABOUT = -54,
K_HELP = -55,
- ADJUST_UNDERLINE = -56
+ K_DUMPCELL = -56,
+ ADJUST_UNDERLINE = -57
} Key;
extern int do_sheetcmd(Sheet *cursheet, Key c, int moveonly);
diff --git a/parser.c b/parser.c
index 58095c3..9338bf2 100644
--- a/parser.c
+++ b/parser.c
@@ -314,3 +314,15 @@ Token eval(Token **n)
return result;
}
/*}}}*/
+
+/* eval_safe -- like eval, but handles null pointer to token sequence */ /*{{{*/
+Token eval_safe(Token **n)
+{
+ Token result;
+ if (n == EMPTY_TVEC)
+ {
+ result.type = EMPTY;
+ return result;
+ }
+ return eval(n);
+}
diff --git a/parser.h b/parser.h
index 89653f2..5e25f31 100644
--- a/parser.h
+++ b/parser.h
@@ -3,6 +3,7 @@
#include "scanner.h"
-Token eval(Token *n[]);
+Token eval_safe(Token **n); /* OK to call on null ptr */
+Token eval(Token *n[]); /* Don't call with null ptr */
#endif
diff --git a/sc.c b/sc.c
index 179fb59..37a6639 100644
--- a/sc.c
+++ b/sc.c
@@ -230,8 +230,8 @@ const char *loadsc(Sheet *sheet, const char *name)
sscanf(buf+7,"%s %d %d %d",colstr,&colwidth,&precision,&whoknows);
col=(colstr[0]-'A'); if (colstr[1]) col=col*26+(colstr[1]-'A');
initcell(sheet,col,0,0);
- SHEET(sheet,col,0,0)->adjust=RIGHT;
- SHEET(sheet,col,0,0)->precision=precision;
+ CELL_AT(sheet,col,0,0)->adjust=RIGHT;
+ CELL_AT(sheet,col,0,0)->precision=precision;
setwidth(sheet,col,0,colwidth);
}
/*}}}*/
@@ -254,8 +254,8 @@ const char *loadsc(Sheet *sheet, const char *name)
goto eek;
}
initcell(sheet,x,y,0);
- SHEET(sheet,x,y,0)->adjust=strncmp(buf,"leftstring ",11) ? RIGHT : LEFT;
- SHEET(sheet,x,y,0)->contents=contents;
+ CELL_AT(sheet,x,y,0)->adjust=strncmp(buf,"leftstring ",11) ? RIGHT : LEFT;
+ CELL_AT(sheet,x,y,0)->contents=contents;
}
/*}}}*/
else if (strncmp(buf,"let ",4)==0) /* let cell = expression */ /*{{{*/
@@ -293,8 +293,8 @@ const char *loadsc(Sheet *sheet, const char *name)
goto eek;
}
initcell(sheet,x,y,0);
- SHEET(sheet,x,y,0)->adjust=RIGHT;
- SHEET(sheet,x,y,0)->contents=contents;
+ CELL_AT(sheet,x,y,0)->adjust=RIGHT;
+ CELL_AT(sheet,x,y,0)->contents=contents;
}
}
/*}}}*/
@@ -307,7 +307,7 @@ const char *loadsc(Sheet *sheet, const char *name)
int prec;
prec=getprecision(sheet,x,0,0)==def_precision ? 2 : getprecision(sheet,x,0,0);
- for (y=1; ydimy; ++y) if (SHEET(sheet,x,y,0)) SHEET(sheet,x,y,0)->precision=prec;
+ for (y=1; ydimy; ++y) if (CELL_AT(sheet,x,y,0)) CELL_AT(sheet,x,y,0)->precision=prec;
}
/*}}}*/
eek:
diff --git a/scanner.c b/scanner.c
index aec7bae..115c764 100644
--- a/scanner.c
+++ b/scanner.c
@@ -24,6 +24,7 @@ extern double strtod(const char *nptr, char **endptr); /* SunOS 4 hack */
#include "func.h"
#include "main.h"
#include "misc.h"
+#include "utf8.h"
#include "scanner.h"
/*}}}*/
@@ -225,38 +226,34 @@ Token **scan(const char **s)
return na;
}
/*}}}*/
-/* print -- print token sequence */ /*{{{*/
-void print(char *s, size_t size, size_t chars, int quote, int scientific, int precision, Token **n)
+/* printtok -- print a single token, passed by address, although not changed */ /*{{{*/
+size_t printtok(char* dest, size_t size, size_t field_width,
+ int quote_strings, int use_scientific,
+ int precision, int verbose_error, Token *tok)
{
size_t cur;
-
- cur=0;
- if (n!=(Token**)0) for (; curtype)
+
+ if (debug_level > 2) {
+ printf("..Entering printtok; bufsize %d, field_width %d, qs %d, us %d, prec %d, verr %d\n", size, field_width, quote_strings, use_scientific, precision, verbose_error);
+ }
+ cur = 0;
+ if (tok != NULLTOKEN) switch (tok->type)
{
/* EMPTY */ /*{{{*/
- case EMPTY: assert(cur==0); *(s+cur)='\0'; ++cur; break;
+ case EMPTY: if (size > 0) dest[cur++] = '\0'; break;
/*}}}*/
/* STRING */ /*{{{*/
case STRING:
{
- char *str=(*n)->u.string;
+ char *str = tok->u.string;
- if (quote)
+ if (quote_strings && curu.integer);
+ buflen=sprintf(buf,"%ld",tok->u.integer);
assert(buflenu.flt);
+ len=sprintf(buf, use_scientific ? "%.*e" : "%.*f",
+ precision == -1 ? DBL_DIG-2 : precision,
+ tok->u.flt);
assert(lenbuf && *p=='0' && *(p-1)!='.') { *p='\0'; --p; --len; }
}
p=buf+len;
while (*--p==' ') { *p='\0'; --len; }
- (void)strncpy(s+cur,buf,size-cur-1);
+ (void)strncpy(dest+cur,buf,size-cur-1);
cur+=len;
break;
}
@@ -300,8 +299,11 @@ void print(char *s, size_t size, size_t chars, int quote, int scientific, int pr
{
static const char *ops[]={ "+", "-", "*", "/", "(", ")", ",", "<", "<=", ">=", ">", "==", "~=", "!=", "^", "%" };
- if ((size-cur)>1) *(s+cur++)=*ops[(*n)->u.op];
- if (*(ops[(*n)->u.op]+1) && (size-cur)>1) *(s+cur++)=*(ops[(*n)->u.op]+1);
+ if ((size-cur)>1)
+ {
+ dest[cur++]=*ops[tok->u.op];
+ if (*(ops[tok->u.op]+1) && size>cur) dest[cur++]=*(ops[tok->u.op]+1);
+ }
break;
}
/*}}}*/
@@ -310,9 +312,9 @@ void print(char *s, size_t size, size_t chars, int quote, int scientific, int pr
{
size_t identlen;
- identlen=strlen((*n)->u.lident);
- if ((cur+identlen+1)<=size) strcpy(s+cur,(*n)->u.lident);
- else (void)strncpy(s+cur,(*n)->u.lident,size-cur-1);
+ identlen=strlen(tok->u.lident);
+ if ((cur+identlen+1)<=size) strcpy(dest+cur,tok->u.lident);
+ else (void)strncpy(dest+cur,tok->u.lident,size-cur-1);
cur+=identlen;
break;
}
@@ -321,10 +323,12 @@ void print(char *s, size_t size, size_t chars, int quote, int scientific, int pr
case FIDENT:
{
size_t identlen;
-
- identlen=strlen(tfunc[(*n)->u.fident].name);
- if ((cur+identlen+1)<=size) strcpy(s+cur,tfunc[(*n)->u.fident].name);
- else (void)strncpy(s+cur,tfunc[(*n)->u.fident].name,size-cur-1);
+ if (debug_level > 2) {
+ printf("...Found function [%s].\n", tfunc[tok->u.fident].name);
+ }
+ identlen=strlen(tfunc[tok->u.fident].name);
+ if ((cur+identlen+1)<=size) strcpy(dest+cur,tfunc[tok->u.fident].name);
+ else (void)strncpy(dest+cur,tfunc[tok->u.fident].name,size-cur-1);
cur+=identlen;
break;
}
@@ -334,8 +338,8 @@ void print(char *s, size_t size, size_t chars, int quote, int scientific, int pr
{
char buf[60];
- sprintf(buf,"&(%d,%d,%d)",(*n)->u.location[0],(*n)->u.location[1],(*n)->u.location[2]);
- (void)strncpy(s+cur,buf,size-cur-1);
+ sprintf(buf,"&(%d,%d,%d)",tok->u.location[0],tok->u.location[1],tok->u.location[2]);
+ (void)strncpy(dest+cur,buf,size-cur-1);
cur+=strlen(buf);
break;
}
@@ -343,8 +347,19 @@ void print(char *s, size_t size, size_t chars, int quote, int scientific, int pr
/* EEK */ /*{{{*/
case EEK:
{
- (void)strncpy(s+cur,_("ERROR"),size-cur-1);
- cur+=5;
+ size_t errlen;
+
+ (void)strncpy(dest+cur,_("ERROR"),size-cur-1);
+ cur += strlen(_("ERROR"));
+ if (verbose_error)
+ {
+ (void)strncpy(dest+cur, ": ", size-cur-1);
+ cur += 2;
+ errlen = strlen(tok->u.err);
+ if ((cur+errlen+1) <= size) strcpy(dest+cur, tok->u.err);
+ else (void)strncpy(dest+cur, tok->u.err, size-cur-1);
+ cur += errlen;
+ }
break;
}
/*}}}*/
@@ -352,6 +367,27 @@ void print(char *s, size_t size, size_t chars, int quote, int scientific, int pr
default: assert(0);
/*}}}*/
}
+ if (cur field_width) {
+ for (cur = 0; cur < field_width; ++cur) dest[cur] = '#';
+ dest[cur] = 0;
+ }
+ return cur;
+}
+/*}}}*/
+/* print -- print token sequence */ /*{{{*/
+void print(char *s, size_t size, size_t chars, int quote, int scientific, int precision, Token **n)
+{
+ size_t cur;
+
+ cur=0;
+ if (n != EMPTY_TVEC) for (; cur chars) {
diff --git a/scanner.h b/scanner.h
index f7cb0e8..501ebdc 100644
--- a/scanner.h
+++ b/scanner.h
@@ -32,8 +32,14 @@ typedef struct
} u;
} Token;
+#define NULLTOKEN ((Token*)0)
+#define EMPTY_TVEC ((Token**)0)
+
int identcode(const char *s, size_t len);
Token **scan(const char **s);
+size_t printtok(char* dest, size_t size, size_t field_width,
+ int quote_strings, int use_scientific,
+ int precision, int verbose_error, Token *tok);
void print(char *s, size_t size, size_t chars, int quote, int scientific, int precision, Token **n);
#ifdef __cplusplus
diff --git a/sheet.c b/sheet.c
index 6cd7625..052ada8 100644
--- a/sheet.c
+++ b/sheet.c
@@ -25,8 +25,6 @@
/*}}}*/
/* #defines */ /*{{{*/
-#define SHEET(s,x,y,z) (*(s->sheet+(x)*s->dimz*s->dimy+(y)*s->dimz+(z)))
-
#define HASH(x,s) \
{ \
const unsigned char *S=(const unsigned char*)s; \
@@ -36,7 +34,6 @@
x%=LABEL_CACHE; \
}
-#define SHADOWED(sheet,x,y,z) (xdimx && ydimy && zdimz && SHEET(sheet,x,y,z)!=(Cell*)0 && SHEET(sheet,x,y,z)->shadowed)
/*}}}*/
/* variables */ /*{{{*/
@@ -49,62 +46,139 @@ int upd_z;
int max_eval;
/*}}}*/
+/* copytokens -- copy a sequence of tokens, possibly reallocating dest */ /*{{{*/
+static void copytokens(Token*** totoks, Token** fromtoks)
+{
+ /* variables */ /*{{{*/
+ size_t from_len, i;
+ /*}}}*/
+
+ from_len = tveclen(fromtoks);
+ if (from_len == 0)
+ {
+ tvecfree(*totoks);
+ *totoks = EMPTY_TVEC;
+ return;
+ }
+ from_len;
+ if (from_len > tveclen(*totoks))
+ {
+ tvecfree(*totoks);
+ *totoks = malloc((from_len+1)*sizeof(Token*));
+ (*totoks)[from_len] = NULLTOKEN;
+ } else {
+ tvecfreetoks(*totoks);
+ }
+ for (i=0; idimx && y1dimy && z1dimz)
+ if (LOC_WITHIN(sheet1,x1,y1,z1))
{
sheet2->changed=1;
- if (SHEET(sheet1,x1,y1,z1)==(Cell*)0) freecell(sheet2,x2,y2,z2);
+ fromcell = CELL_AT(sheet1,x1,y1,z1);
+ if (fromcell == NULLCELL) freecell(sheet2,x2,y2,z2);
else
/* copy first cell to second */ /*{{{*/
{
freecell(sheet2,x2,y2,z2);
initcell(sheet2,x2,y2,z2);
- memcpy(SHEET(sheet2,x2,y2,z2),SHEET(sheet1,x1,y1,z1),sizeof(Cell));
- if (SHEET(sheet1,x1,y1,z1)->contents!=(Token**)0)
- {
- for (len=1,run=SHEET(sheet1,x1,y1,z1)->contents; *run!=(Token*)0; ++len,++run);
- SHEET(sheet2,x2,y2,z2)->contents=malloc(len*sizeof(Token*));
- for (i=0; icontents+i)==(Token*)0) *(SHEET(sheet2,x2,y2,z2)->contents+i)=(Token*)0;
- else
- {
- *(SHEET(sheet2,x2,y2,z2)->contents+i)=malloc(sizeof(Token));
- **(SHEET(sheet2,x2,y2,z2)->contents+i)=tcopy(**(SHEET(sheet1,x1,y1,z1)->contents+i));
- }
- }
- }
- if (SHEET(sheet1,x1,y1,z1)->ccontents!=(Token**)0)
- {
- for (len=1,run=SHEET(sheet1,x1,y1,z1)->ccontents; *run!=(Token*)0; ++len,++run);
- SHEET(sheet2,x2,y2,z2)->ccontents=malloc(len*sizeof(Token*));
- for (i=0; iccontents+i)==(Token*)0) *(SHEET(sheet2,x2,y2,z2)->ccontents+i)=(Token*)0;
- else
- {
- *(SHEET(sheet2,x2,y2,z2)->ccontents+i)=malloc(sizeof(Token));
- **(SHEET(sheet2,x2,y2,z2)->ccontents+i)=tcopy(**(SHEET(sheet1,x1,y1,z1)->ccontents+i));
- }
- }
- }
- if (SHEET(sheet1,x1,y1,z1)->label!=(char*)0) SHEET(sheet2,x2,y2,z2)->label=strcpy(malloc(strlen(SHEET(sheet1,x1,y1,z1)->label)+1),SHEET(sheet1,x1,y1,z1)->label);
- SHEET(sheet2,x2,y2,z2)->value.type=EMPTY;
+ tocell = CELL_AT(sheet2,x2,y2,z2);
+ memcpy(tocell, fromcell, sizeof(Cell));
+ copytokens(&(tocell->contents), fromcell->contents);
+ copytokens(&(tocell->ccontents), fromcell->ccontents);
+ if (fromcell->label != (char*)0)
+ tocell->label = strcpy(malloc(strlen(fromcell->label)+1),
+ fromcell->label);
+ tocell->value.type=EMPTY;
}
/*}}}*/
}
else freecell(sheet2,x2,y2,z2);
}
/*}}}*/
+/* dump_cell -- write internal contents of cell to standard out */ /*{{{*/
+static void dump_cell(Sheet *sheet, int x, int y, int z)
+{
+ Cell* c;
+ char buf[2048];
+
+ assert(sheet != (Sheet*)0);
+ if (x < 0 || y < 0 || z < 0)
+ {
+ printf("TEADUMP: Requested cell &(%d,%d,%d) has negative coordinates.\n",
+ x, y, z);
+ return;
+ }
+ if (!LOC_WITHIN(sheet, x, y, z))
+ {
+ printf("TEADUMP: Requested cell &(%d,%d,%d) outside sheet dims %d,%d,%d.\n",
+ x, y, z, sheet->dimx, sheet->dimy, sheet->dimz);
+ return;
+ }
+ c = CELL_AT(sheet, x, y, z);
+ if (c == NULLCELL)
+ {
+ printf("TEADUMP: Cell at &(%d,%d,%d) is empty.\n", x, y, z);
+ return;
+ }
+ printf("TEADUMP of &(%d,%d,%d):\n", x, y, z);
+ print(buf, sizeof(buf), 0, 1, 0, -1, c->contents);
+ printf(" Base expr: %s.\n", buf);
+ print(buf, sizeof(buf), 0, 1, 0, -1, c->ccontents);
+ printf(" Update expr: %s.\n", buf);
+ if (c->label == (char *)0) printf("\n No label.\n");
+ else printf("\n Label: %s.\n", c->label);
+ printtok(buf, sizeof(buf), 0, 1, 0, -1, 1, &(c->value));
+ printf(" Current value: %s.\n", buf);
+ printtok(buf, sizeof(buf), 0, 1, 0, -1, 1, &(c->resvalue));
+ printf(" Stored result value: %s.\n Adjustment: ", buf);
+ switch (c->adjust) {
+ case LEFT: printf("LEFT\n"); break;
+ case RIGHT: printf("RIGHT\n"); break;
+ case CENTER: printf("CENTER\n"); break;
+ case AUTOADJUST: printf("AUTO\n"); break;
+ }
+ printf(" Precision: %d\n Attributes: ", c->precision);
+ if (c->updated) printf("updated ");
+ if (c->shadowed) printf("shadowed ");
+ if (c->scientific) printf("scientific ");
+ if (c->locked) printf("locked ");
+ if (c->transparent) printf("transparent ");
+ if (c->ignored) printf("ignored ");
+ if (c->clock_t0) printf("clock_t0 ");
+ if (c->clock_t1) printf("clock_t1 ");
+ if (c->clock_t2) printf("clock_t2 ");
+ if (c->bold) printf("bold ");
+ if (c->underline) printf("underline ");
+ printf("\n\n");
+}
+/*}}}*/
+/* dump_current_cell -- dump_cell of the current_cell */ /*{{{*/
+void dump_current_cell(Sheet *sheet)
+{
+ assert(sheet != (Sheet *)0);
+ dump_cell(sheet, sheet->curx, sheet->cury, sheet->curz);
+}
+/*}}}*/
/* swapblock -- swap two non-overlapping blocks of cells */ /*{{{*/
static void swapblock(Sheet *sheet1, int x1, int y1, int z1, Sheet *sheet2, int x2, int y2, int z2, int xdist, int ydist, int zdist)
{
@@ -120,9 +194,9 @@ static void swapblock(Sheet *sheet1, int x1, int y1, int z1, Sheet *sheet2, int
{
Cell *t;
- t=SHEET(sheet1,x1+xoff,y1+yoff,z1+zoff);
- SHEET(sheet1,x1+xoff,y1+yoff,z1+zoff)=SHEET(sheet2,x2+xoff,y2+yoff,z2+zoff);
- SHEET(sheet2,x2+xoff,y2+yoff,z2+zoff)=t;
+ t = CELL_AT(sheet1,x1+xoff,y1+yoff,z1+zoff);
+ CELL_AT(sheet1,x1+xoff,y1+yoff,z1+zoff) = CELL_AT(sheet2,x2+xoff,y2+yoff,z2+zoff);
+ CELL_AT(sheet2,x2+xoff,y2+yoff,z2+zoff) = t;
}
sheet1->changed=1;
sheet2->changed=1;
@@ -138,26 +212,29 @@ second. A result of 2 means they are not comparable.
/*}}}*/
static int cmpcell(Sheet *sheet1, int x1, int y1, int z1, Sheet *sheet2, int x2, int y2, int z2, int sortkey)
{
+ Cell *leftcell, *rightcell;
assert(sheet1!=(Sheet*)0);
assert(sheet2!=(Sheet*)0);
/* empty cells are smaller than any non-empty cell */ /*{{{*/
- if (x1>=sheet1->dimx || y1>=sheet1->dimy || z1>=sheet1->dimz || SHEET(sheet1,x1,y1,z1)==(Cell*)0 || SHEET(sheet1,x1,y1,z1)->value.type==EMPTY)
+ if (!CELL_IS_GOOD(sheet1,x1,y1,z1) || CELL_AT(sheet1,x1,y1,z1)->value.type==EMPTY)
{
- if (x2>=sheet2->dimx || y2>=sheet2->dimy || z2>=sheet2->dimz || SHEET(sheet2,x2,y2,z2)==(Cell*)0 || SHEET(sheet2,x2,y2,z2)->value.type==EMPTY) return 0;
+ if (!CELL_IS_GOOD(sheet2,x2,y2,z2) || CELL_AT(sheet2,x2,y2,z2)->value.type==EMPTY) return 0;
else return (sortkey&ASCENDING ? -1 : 1);
}
- if (x2>=sheet2->dimx || y2>=sheet2->dimy || z2>=sheet2->dimz || SHEET(sheet2,x2,y2,z2)==(Cell*)0 || SHEET(sheet2,x2,y2,z2)->value.type==EMPTY) return (sortkey&ASCENDING ? 1 : -1);
+ if (!CELL_IS_GOOD(sheet2,x2,y2,z2) || CELL_AT(sheet2,x2,y2,z2)->value.type==EMPTY) return (sortkey&ASCENDING ? 1 : -1);
/*}}}*/
- switch (SHEET(sheet1,x1,y1,z1)->value.type)
+ leftcell = CELL_AT(sheet1,x1,y1,z1);
+ rightcell = CELL_AT(sheet2,x2,y2,z2);
+ switch (leftcell->value.type)
{
/* STRING */ /*{{{*/
case STRING:
{
- if (SHEET(sheet2,x2,y2,z2)->value.type==STRING)
+ if (rightcell->value.type==STRING)
{
int r;
- r=strcmp(SHEET(sheet1,x1,y1,z1)->value.u.string,SHEET(sheet2,x2,y2,z2)->value.u.string);
+ r=strcmp(leftcell->value.u.string, rightcell->value.u.string);
if (r<0) return (sortkey&ASCENDING ? -1 : 1);
else if (r==0) return 0;
else return (sortkey&ASCENDING ? 1 : -1);
@@ -168,16 +245,16 @@ static int cmpcell(Sheet *sheet1, int x1, int y1, int z1, Sheet *sheet2, int x2,
/* FLOAT */ /*{{{*/
case FLOAT:
{
- if (SHEET(sheet2,x2,y2,z2)->value.type==FLOAT)
+ if (rightcell->value.type==FLOAT)
{
- if (SHEET(sheet1,x1,y1,z1)->value.u.fltvalue.u.flt) return (sortkey&ASCENDING ? -1 : 1);
- else if (SHEET(sheet1,x1,y1,z1)->value.u.flt==SHEET(sheet2,x2,y2,z2)->value.u.flt) return 0;
+ if (leftcell->value.u.fltvalue.u.flt) return (sortkey&ASCENDING ? -1 : 1);
+ else if (leftcell->value.u.flt==rightcell->value.u.flt) return 0;
else return (sortkey&ASCENDING ? 1 : -1);
}
- if (SHEET(sheet2,x2,y2,z2)->value.type==INT)
+ if (rightcell->value.type==INT)
{
- if (SHEET(sheet1,x1,y1,z1)->value.u.fltvalue.u.integer) return (sortkey&ASCENDING ? -1 : 1);
- else if (SHEET(sheet1,x1,y1,z1)->value.u.flt==SHEET(sheet2,x2,y2,z2)->value.u.integer) return 0;
+ if (leftcell->value.u.fltvalue.u.integer) return (sortkey&ASCENDING ? -1 : 1);
+ else if (leftcell->value.u.flt==rightcell->value.u.integer) return 0;
else return (sortkey&ASCENDING ? 1 : -1);
}
return 2;
@@ -186,16 +263,16 @@ static int cmpcell(Sheet *sheet1, int x1, int y1, int z1, Sheet *sheet2, int x2,
/* INT */ /*{{{*/
case INT:
{
- if (SHEET(sheet2,x2,y2,z2)->value.type==INT)
+ if (rightcell->value.type==INT)
{
- if (SHEET(sheet1,x1,y1,z1)->value.u.integervalue.u.integer) return (sortkey&ASCENDING ? -1 : 1);
- else if (SHEET(sheet1,x1,y1,z1)->value.u.integer==SHEET(sheet2,x2,y2,z2)->value.u.integer) return 0;
+ if (leftcell->value.u.integervalue.u.integer) return (sortkey&ASCENDING ? -1 : 1);
+ else if (leftcell->value.u.integer==rightcell->value.u.integer) return 0;
else return (sortkey&ASCENDING ? 1 : -1);
}
- if (SHEET(sheet2,x2,y2,z2)->value.type==FLOAT)
+ if (rightcell->value.type==FLOAT)
{
- if (SHEET(sheet1,x1,y1,z1)->value.u.integervalue.u.flt) return (sortkey&ASCENDING ? -1 : 1);
- else if (SHEET(sheet1,x1,y1,z1)->value.u.integer==SHEET(sheet2,x2,y2,z2)->value.u.flt) return 0;
+ if (leftcell->value.u.integervalue.u.flt) return (sortkey&ASCENDING ? -1 : 1);
+ else if (leftcell->value.u.integer==rightcell->value.u.flt) return 0;
else return (sortkey&ASCENDING ? 1 : -1);
}
return 2;
@@ -213,7 +290,7 @@ void resize(Sheet *sheet, int x, int y, int z)
assert(y>=0);
assert(z>=0);
assert(sheet!=(Sheet*)0);
- if (x>=sheet->dimx || y>=sheet->dimy || z>=sheet->dimz)
+ if (!LOC_WITHIN(sheet,x,y,z))
{
/* variables */ /*{{{*/
Cell **newsheet;
@@ -229,8 +306,8 @@ void resize(Sheet *sheet, int x, int y, int z)
newsheet=malloc(ndimx*ndimy*ndimz*sizeof(Cell*));
for (x=0; xdimx && ydimy && zdimz) *(newsheet+x*ndimz*ndimy+y*ndimz+z)=SHEET(sheet,x,y,z);
- else *(newsheet+x*ndimz*ndimy+y*ndimz+z)=(Cell*)0;
+ if (LOC_WITHIN(sheet,x,y,z)) *(newsheet+x*ndimz*ndimy+y*ndimz+z)=CELL_AT(sheet,x,y,z);
+ else *(newsheet+x*ndimz*ndimy+y*ndimz+z)= NULLCELL;
}
if (sheet->sheet!=(Cell**)0) free(sheet->sheet);
sheet->sheet=newsheet;
@@ -257,30 +334,33 @@ void resize(Sheet *sheet, int x, int y, int z)
/* initcell -- initialise new cell, if it does not exist yet */ /*{{{*/
void initcell(Sheet *sheet, int x, int y, int z)
{
+ Cell *nc;
+
assert(x>=0);
assert(y>=0);
assert(z>=0);
resize(sheet,x,y,z);
- if (SHEET(sheet,x,y,z)==(Cell*)0)
+ if (CELL_AT(sheet,x,y,z) == NULLCELL)
{
sheet->changed=1;
- SHEET(sheet,x,y,z)=malloc(sizeof(Cell));
- SHEET(sheet,x,y,z)->contents=(Token**)0;
- SHEET(sheet,x,y,z)->ccontents=(Token**)0;
- SHEET(sheet,x,y,z)->label=(char*)0;
- SHEET(sheet,x,y,z)->adjust=AUTOADJUST;
- SHEET(sheet,x,y,z)->precision=-1;
- SHEET(sheet,x,y,z)->shadowed=0;
- SHEET(sheet,x,y,z)->bold=0;
- SHEET(sheet,x,y,z)->underline=0;
- SHEET(sheet,x,y,z)->scientific=DEF_SCIENTIFIC;
- SHEET(sheet,x,y,z)->value.type=EMPTY;
- SHEET(sheet,x,y,z)->resvalue.type=EMPTY;
- SHEET(sheet,x,y,z)->locked=0;
- SHEET(sheet,x,y,z)->ignored=0;
- SHEET(sheet,x,y,z)->clock_t0=0;
- SHEET(sheet,x,y,z)->clock_t1=0;
- SHEET(sheet,x,y,z)->clock_t2=0;
+ nc = malloc(sizeof(Cell));
+ CELL_AT(sheet,x,y,z) = nc;
+ nc->contents = EMPTY_TVEC;
+ nc->ccontents = EMPTY_TVEC;
+ nc->label=(char*)0;
+ nc->adjust=AUTOADJUST;
+ nc->precision=-1;
+ nc->shadowed=0;
+ nc->bold=0;
+ nc->underline=0;
+ nc->scientific=DEF_SCIENTIFIC;
+ nc->value.type=EMPTY;
+ nc->resvalue.type=EMPTY;
+ nc->locked=0;
+ nc->ignored=0;
+ nc->clock_t0=0;
+ nc->clock_t1=0;
+ nc->clock_t2=0;
}
}
/*}}}*/
@@ -305,7 +385,7 @@ void cachelabels(Sheet *sheet)
sheet->labelcache[i]=(struct Label*)0;
}
/*}}}*/
- for (x=0; xdimx; ++x) for (y=0; ydimy; ++y) for (z=0; zdimz; ++z)
+ for (ALL_CELLS_IN_SHEET(sheet,x,y,z))
/* cache all labels */ /*{{{*/
{
const char *l;
@@ -343,7 +423,7 @@ void freesheet(Sheet *sheet, int all)
assert(sheet!=(Sheet*)0);
sheet->changed=0;
- for (x=0; xdimx; ++x) for (y=0; ydimy; ++y) for (z=0; zdimz; ++z)
+ for (ALL_CELLS_IN_SHEET(sheet,x,y,z))
{
freecell(sheet,x,y,z);
}
@@ -386,7 +466,7 @@ void forceupdate(Sheet *sheet)
int i;
assert(sheet!=(Sheet*)0);
- for (i=0; idimx*sheet->dimy*sheet->dimz; ++i) if (*(sheet->sheet+i)!=(Cell*)0)
+ for (i=0; idimx*sheet->dimy*sheet->dimz; ++i) if (*(sheet->sheet+i) != NULLCELL)
{
(*(sheet->sheet+i))->updated=0;
(*(sheet->sheet+i))->clock_t0=0;
@@ -399,14 +479,17 @@ void forceupdate(Sheet *sheet)
/* freecell -- free one cell */ /*{{{*/
void freecell(Sheet *sheet, int x, int y, int z)
{
+ Cell *c;
assert(sheet!=(Sheet*)0);
- if (sheet->sheet!=(Cell**)0 && xdimx && ydimy && zdimz && SHEET(sheet,x,y,z)!=(Cell*)0)
+ if (sheet->sheet!=(Cell**)0 && CELL_IS_GOOD(sheet,x,y,z))
{
- tvecfree(SHEET(sheet,x,y,z)->contents);
- tvecfree(SHEET(sheet,x,y,z)->ccontents);
- tfree(&(SHEET(sheet,x,y,z)->value));
- free(SHEET(sheet,x,y,z));
- SHEET(sheet,x,y,z)=(Cell*)0;
+ c = CELL_AT(sheet,x,y,z);
+ tvecfree(c->contents);
+ tvecfree(c->ccontents);
+ tfree(&(c->value));
+ tfree(&(c->resvalue));
+ free(c);
+ CELL_AT(sheet,x,y,z) = NULLCELL;
sheet->changed=1;
}
}
@@ -448,13 +531,13 @@ void putcont(Sheet *sheet, int x, int y, int z, Token **t, int c)
initcell(sheet,x,y,z);
if (c)
{
- tvecfree(SHEET(sheet,x,y,z)->ccontents);
- SHEET(sheet,x,y,z)->ccontents=t;
+ tvecfree(CELL_AT(sheet,x,y,z)->ccontents);
+ CELL_AT(sheet,x,y,z)->ccontents=t;
}
else
{
- tvecfree(SHEET(sheet,x,y,z)->contents);
- SHEET(sheet,x,y,z)->contents=t;
+ tvecfree(CELL_AT(sheet,x,y,z)->contents);
+ CELL_AT(sheet,x,y,z)->contents=t;
}
redraw_cell(sheet, x, y, z);
}
@@ -462,10 +545,9 @@ void putcont(Sheet *sheet, int x, int y, int z, Token **t, int c)
/* getcont -- get contents */ /*{{{*/
Token **getcont(Sheet *sheet, int x, int y, int z, int c)
{
- if (x>=sheet->dimx || y>=sheet->dimy || z>=sheet->dimz) return (Token**)0;
- else if (SHEET(sheet,x,y,z)==(Cell*)0) return (Token**)0;
- else if (c==2) return (SHEET(sheet,x,y,z)->clock_t0 && SHEET(sheet,x,y,z)->ccontents ? SHEET(sheet,x,y,z)->ccontents : SHEET(sheet,x,y,z)->contents);
- else return (c ? SHEET(sheet,x,y,z)->ccontents : SHEET(sheet,x,y,z)->contents);
+ if (!CELL_IS_GOOD(sheet,x,y,z)) return EMPTY_TVEC;
+ else if (c==2) return (CELL_AT(sheet,x,y,z)->clock_t0 && CELL_AT(sheet,x,y,z)->ccontents ? CELL_AT(sheet,x,y,z)->ccontents : CELL_AT(sheet,x,y,z)->contents);
+ else return (c ? CELL_AT(sheet,x,y,z)->ccontents : CELL_AT(sheet,x,y,z)->contents);
}
/*}}}*/
/* getvalue -- get tcopy()ed value */ /*{{{*/
@@ -482,67 +564,70 @@ Token getvalue(Sheet *sheet, int x, int y, int z)
{
result.type=EEK;
result.u.err=mystrmalloc(_("Negative index"));
+ return result;
}
/*}}}*/
- else if (getcont(sheet,x,y,z,2)==(Token**)0)
- /* return empty value */ /*{{{*/
- result.type=EMPTY;
- /*}}}*/
- else
+ result.type = EMPTY;
+ /* Can always short-circuit an out-of-bounds or empty cell */
+ if (!CELL_IS_GOOD(sheet,x,y,z)) return result;
+ /* only short-circuit on empty contents of a good cell if we are NOT
+ depending on this call to update the current value
+ */
+ if (!upd_clock && getcont(sheet,x,y,z,2) == EMPTY_TVEC) return result;
/* update value of this cell if needed and return it */ /*{{{*/
+ orig_upd_clock = upd_clock;
+ if (CELL_AT(sheet,x,y,z)->ignored)
{
- orig_upd_clock=upd_clock;
- if (SHEET(sheet,x,y,z)->ignored)
- {
- /* variables */ /*{{{*/
- Token oldvalue;
- /*}}}*/
+ /* variables */ /*{{{*/
+ Token oldvalue;
+ /*}}}*/
- oldvalue=SHEET(sheet,x,y,z)->value;
- SHEET(sheet,x,y,z)->updated=1;
- SHEET(sheet,x,y,z)->value.type=EMPTY;
+ oldvalue=CELL_AT(sheet,x,y,z)->value;
+ CELL_AT(sheet,x,y,z)->updated=1;
+ CELL_AT(sheet,x,y,z)->value.type=EMPTY;
+ tfree(&oldvalue);
+ }
+ else if (CELL_AT(sheet,x,y,z)->updated==0)
+ {
+ /* variables */ /*{{{*/
+ Sheet *old_sheet;
+ int old_x,old_y,old_z,old_max_eval;
+ Token oldvalue;
+ /*}}}*/
+
+ old_sheet=upd_sheet;
+ old_x=upd_x;
+ old_y=upd_y;
+ old_z=upd_z;
+ old_max_eval=max_eval;
+ upd_sheet=sheet;
+ upd_x=x;
+ upd_y=y;
+ upd_z=z;
+ max_eval=MAX_EVALNEST;
+ if (CELL_AT(sheet,x,y,z)->clock_t1==0)
+ {
+ CELL_AT(sheet,x,y,z)->updated = 1;
+ oldvalue = CELL_AT(sheet,x,y,z)->value;
+ upd_clock = 0;
+ CELL_AT(sheet,x,y,z)->value = eval_safe(getcont(sheet, x, y, z, 2));
tfree(&oldvalue);
}
- else if (SHEET(sheet,x,y,z)->updated==0)
+ else if (upd_clock)
{
- /* variables */ /*{{{*/
- Sheet *old_sheet;
- int old_x,old_y,old_z,old_max_eval;
- Token oldvalue;
- /*}}}*/
-
- old_sheet=upd_sheet;
- old_x=upd_x;
- old_y=upd_y;
- old_z=upd_z;
- old_max_eval=max_eval;
- upd_sheet=sheet;
- upd_x=x;
- upd_y=y;
- upd_z=z;
- max_eval=MAX_EVALNEST;
- if (SHEET(sheet,x,y,z)->clock_t1==0)
- {
- SHEET(sheet,x,y,z)->updated=1;
- oldvalue=SHEET(sheet,x,y,z)->value;
- upd_clock=0;
- SHEET(sheet,x,y,z)->value=eval(getcont(sheet,x,y,z,2));
- tfree(&oldvalue);
- }
- else if (upd_clock)
- {
- SHEET(sheet,x,y,z)->updated=1;
- upd_clock=0;
- SHEET(sheet,x,y,z)->resvalue=eval(getcont(sheet,x,y,z,2));
- }
- upd_sheet=old_sheet;
- upd_x=old_x;
- upd_y=old_y;
- upd_z=old_z;
- max_eval=old_max_eval;
+ CELL_AT(sheet,x,y,z)->updated=1;
+ upd_clock=0;
+ oldvalue=CELL_AT(sheet,x,y,z)->resvalue;
+ CELL_AT(sheet,x,y,z)->resvalue = eval_safe(getcont(sheet,x,y,z,2));
+ tfree(&oldvalue);
}
- if (!orig_upd_clock) result=tcopy(SHEET(sheet,x,y,z)->value);
+ upd_sheet=old_sheet;
+ upd_x=old_x;
+ upd_y=old_y;
+ upd_z=old_z;
+ max_eval=old_max_eval;
}
+ if (!orig_upd_clock) result=tcopy(CELL_AT(sheet,x,y,z)->value);
/*}}}*/
return result;
}
@@ -564,28 +649,29 @@ void update(Sheet *sheet)
++iterating;
}
else if (iterating==0) ++iterating;
- for (x=0; xdimx; ++x) for (y=0; ydimy; ++y) for (z=0; zdimz; ++z)
+ for (ALL_CELLS_IN_SHEET(sheet,x,y,z))
{
- if (SHEET(sheet,x,y,z) && SHEET(sheet,x,y,z)->clock_t2)
+ if (CELL_AT(sheet,x,y,z) && CELL_AT(sheet,x,y,z)->clock_t2)
{
- SHEET(sheet,x,y,z)->updated=0;
- SHEET(sheet,x,y,z)->clock_t0=1;
- SHEET(sheet,x,y,z)->clock_t1=1;
- SHEET(sheet,x,y,z)->clock_t2=0;
+ CELL_AT(sheet,x,y,z)->updated=0;
+ CELL_AT(sheet,x,y,z)->clock_t0=1;
+ CELL_AT(sheet,x,y,z)->clock_t1=1;
+ CELL_AT(sheet,x,y,z)->clock_t2=0;
}
}
- for (x=0; xdimx; ++x) for (y=0; ydimy; ++y) for (z=0; zdimz; ++z)
+ for (ALL_CELLS_IN_SHEET(sheet,x,y,z))
{
upd_clock=1;
getvalue(sheet,x,y,z);
}
- for (x=0; xdimx; ++x) for (y=0; ydimy; ++y) for (z=0; zdimz; ++z)
+ for (ALL_CELLS_IN_SHEET(sheet,x,y,z))
{
- if (SHEET(sheet,x,y,z) && SHEET(sheet,x,y,z)->clock_t1)
+ if (CELL_AT(sheet,x,y,z) && CELL_AT(sheet,x,y,z)->clock_t1)
{
- tfree(&(SHEET(sheet,x,y,z)->value));
- SHEET(sheet,x,y,z)->value=SHEET(sheet,x,y,z)->resvalue;
- SHEET(sheet,x,y,z)->clock_t1=0;
+ tfree(&(CELL_AT(sheet,x,y,z)->value));
+ CELL_AT(sheet,x,y,z)->value = CELL_AT(sheet,x,y,z)->resvalue;
+ CELL_AT(sheet,x,y,z)->resvalue.type = EMPTY;
+ CELL_AT(sheet,x,y,z)->clock_t1 = 0;
}
}
upd_clock=0;
@@ -615,12 +701,11 @@ char *geterror(Sheet *sheet, int x, int y, int z)
/* printvalue -- get ASCII representation of value */ /*{{{*/
void printvalue(char *s, size_t size, size_t chars, int quote, int scientific, int precision, Sheet *sheet, int x, int y, int z)
{
- Token *tv[2],t;
+ Token t;
assert(sheet!=(Sheet*)0);
- t=getvalue(sheet,x,y,z); tv[0]=&t;
- tv[1]=(Token*)0;
- print(s,size,chars,quote,scientific,precision,tv);
+ t=getvalue(sheet,x,y,z);
+ printtok(s,size,chars,quote,scientific,precision,0,&t);
tfree(&t);
}
/*}}}*/
@@ -628,12 +713,12 @@ void printvalue(char *s, size_t size, size_t chars, int quote, int scientific, i
Adjust getadjust(Sheet *sheet, int x, int y, int z)
{
assert(sheet!=(Sheet*)0);
- if (x>=sheet->dimx || y>=sheet->dimy || z>=sheet->dimz || SHEET(sheet,x,y,z)==(Cell*)0)
+ if (!CELL_IS_GOOD(sheet,x,y,z))
{
return LEFT;
}
- else if (SHEET(sheet,x,y,z)->adjust==AUTOADJUST) return (SHEET(sheet,x,y,z)->value.type==INT || SHEET(sheet,x,y,z)->value.type==FLOAT ? RIGHT : LEFT);
- else return (SHEET(sheet,x,y,z)->adjust);
+ else if (CELL_AT(sheet,x,y,z)->adjust==AUTOADJUST) return (CELL_AT(sheet,x,y,z)->value.type==INT || CELL_AT(sheet,x,y,z)->value.type==FLOAT ? RIGHT : LEFT);
+ else return (CELL_AT(sheet,x,y,z)->adjust);
}
/*}}}*/
/* setadjust -- set cell adjustment */ /*{{{*/
@@ -643,7 +728,7 @@ void setadjust(Sheet *sheet, int x, int y, int z, Adjust adjust)
sheet->changed=1;
resize(sheet,x,y,z);
initcell(sheet,x,y,z);
- SHEET(sheet,x,y,z)->adjust=adjust;
+ CELL_AT(sheet,x,y,z)->adjust=adjust;
}
/*}}}*/
@@ -652,7 +737,7 @@ void shadow(Sheet *sheet, int x, int y, int z, int yep)
{
sheet->changed=1;
initcell(sheet,x,y,z);
- SHEET(sheet,x,y,z)->shadowed=yep;
+ CELL_AT(sheet,x,y,z)->shadowed=yep;
}
/*}}}*/
/* shadowed -- is cell shadowed? */ /*{{{*/
@@ -666,13 +751,13 @@ void bold(Sheet *sheet, int x, int y, int z, int yep)
{
sheet->changed=1;
initcell(sheet,x,y,z);
- SHEET(sheet,x,y,z)->bold=yep;
+ CELL_AT(sheet,x,y,z)->bold=yep;
}
/*}}}*/
/* isbold -- is cell bold? */ /*{{{*/
int isbold(Sheet *sheet, int x, int y, int z)
{
- return (xdimx && ydimy && zdimz && SHEET(sheet,x,y,z)!=(Cell*)0 && SHEET(sheet,x,y,z)->bold);
+ return (CELL_IS_GOOD(sheet,x,y,z) && CELL_AT(sheet,x,y,z)->bold);
}
/*}}}*/
/* underline -- underline */ /*{{{*/
@@ -680,13 +765,13 @@ void underline(Sheet *sheet, int x, int y, int z, int yep)
{
sheet->changed=1;
initcell(sheet,x,y,z);
- SHEET(sheet,x,y,z)->underline=yep;
+ CELL_AT(sheet,x,y,z)->underline=yep;
}
/*}}}*/
/* isunderline -- is cell underlined? */ /*{{{*/
int underlined(Sheet *sheet, int x, int y, int z)
{
- return (xdimx && ydimy && zdimz && SHEET(sheet,x,y,z)!=(Cell*)0 && SHEET(sheet,x,y,z)->underline);
+ return (CELL_IS_GOOD(sheet,x,y,z) && CELL_AT(sheet,x,y,z)->underline);
}
/*}}}*/
/* lockcell -- lock cell */ /*{{{*/
@@ -694,19 +779,19 @@ void lockcell(Sheet *sheet, int x, int y, int z, int yep)
{
sheet->changed=1;
initcell(sheet,x,y,z);
- SHEET(sheet,x,y,z)->locked=yep;
+ CELL_AT(sheet,x,y,z)->locked=yep;
}
/*}}}*/
/* locked -- is cell locked? */ /*{{{*/
int locked(Sheet *sheet, int x, int y, int z)
{
- return (xdimx && ydimy && zdimz && SHEET(sheet,x,y,z)!=(Cell*)0 && SHEET(sheet,x,y,z)->locked);
+ return (CELL_IS_GOOD(sheet,x,y,z) && CELL_AT(sheet,x,y,z)->locked);
}
/*}}}*/
/* transparent -- is cell transparent? */ /*{{{*/
int transparent(Sheet *sheet, int x, int y, int z)
{
- return (xdimx && ydimy && zdimz && SHEET(sheet,x,y,z)!=(Cell*)0 && SHEET(sheet,x,y,z)->transparent);
+ return (CELL_IS_GOOD(sheet,x,y,z) && CELL_AT(sheet,x,y,z)->transparent);
}
/*}}}*/
/* maketrans -- make cell transparent */ /*{{{*/
@@ -714,7 +799,7 @@ void maketrans(Sheet *sheet, int x, int y, int z, int yep)
{
sheet->changed=1;
initcell(sheet,x,y,z);
- SHEET(sheet,x,y,z)->transparent=yep;
+ CELL_AT(sheet,x,y,z)->transparent=yep;
}
/*}}}*/
/* igncell -- ignore cell */ /*{{{*/
@@ -722,13 +807,13 @@ void igncell(Sheet *sheet, int x, int y, int z, int yep)
{
sheet->changed=1;
initcell(sheet,x,y,z);
- SHEET(sheet,x,y,z)->ignored=yep;
+ CELL_AT(sheet,x,y,z)->ignored=yep;
}
/*}}}*/
/* ignored -- is cell ignored? */ /*{{{*/
int ignored(Sheet *sheet, int x, int y, int z)
{
- return (xdimx && ydimy && zdimz && SHEET(sheet,x,y,z)!=(Cell*)0 && SHEET(sheet,x,y,z)->ignored);
+ return (CELL_IS_GOOD(sheet,x,y,z) && CELL_AT(sheet,x,y,z)->ignored);
}
/*}}}*/
/* clk -- clock cell */ /*{{{*/
@@ -738,9 +823,9 @@ void clk(Sheet *sheet, int x, int y, int z)
assert(x>=0 && xdimx);
assert(y>=0 && ydimy);
assert(z>=0 && zdimz);
- if (SHEET(sheet,x,y,z))
+ if (CELL_AT(sheet,x,y,z))
{
- SHEET(sheet,x,y,z)->clock_t2=1;
+ CELL_AT(sheet,x,y,z)->clock_t2=1;
sheet->clk=1;
}
}
@@ -751,13 +836,13 @@ void setscientific(Sheet *sheet, int x, int y, int z, int yep)
sheet->changed=1;
resize(sheet,x,y,z);
initcell(sheet,x,y,z);
- SHEET(sheet,x,y,z)->scientific=yep;
+ CELL_AT(sheet,x,y,z)->scientific=yep;
}
/*}}}*/
/* getscientific -- should value be displayed in scientific notation? */ /*{{{*/
int getscientific(Sheet *sheet, int x, int y, int z)
{
- if (xdimx && ydimy && zdimz && SHEET(sheet,x,y,z)!=(Cell*)0) return SHEET(sheet,x,y,z)->scientific;
+ if (CELL_IS_GOOD(sheet,x,y,z)) return CELL_AT(sheet,x,y,z)->scientific;
else return DEF_SCIENTIFIC;
}
/*}}}*/
@@ -767,21 +852,21 @@ void setprecision(Sheet *sheet, int x, int y, int z, int precision)
sheet->changed=1;
resize(sheet,x,y,z);
initcell(sheet,x,y,z);
- SHEET(sheet,x,y,z)->precision=precision;
+ CELL_AT(sheet,x,y,z)->precision=precision;
}
/*}}}*/
/* getprecision -- get cell precision */ /*{{{*/
int getprecision(Sheet *sheet, int x, int y, int z)
{
- if (xdimx && ydimy && zdimz && SHEET(sheet,x,y,z)!=(Cell*)0) return (SHEET(sheet,x,y,z)->precision==-1 ? def_precision : SHEET(sheet,x,y,z)->precision);
+ if (CELL_IS_GOOD(sheet,x,y,z)) return (CELL_AT(sheet,x,y,z)->precision==-1 ? def_precision : CELL_AT(sheet,x,y,z)->precision);
else return def_precision;
}
/*}}}*/
/* getlabel -- get cell label */ /*{{{*/
const char *getlabel(Sheet *sheet, int x, int y, int z)
{
- if (x>=sheet->dimx || y>=sheet->dimy || z>=sheet->dimz || SHEET(sheet,x,y,z)==(Cell*)0 || SHEET(sheet,x,y,z)->label==(char*)0) return "";
- else return (SHEET(sheet,x,y,z)->label);
+ if (!CELL_IS_GOOD(sheet,x,y,z) || CELL_AT(sheet,x,y,z)->label==(char*)0) return "";
+ else return (CELL_AT(sheet,x,y,z)->label);
}
/*}}}*/
/* setlabel -- set cell label */ /*{{{*/
@@ -790,9 +875,9 @@ void setlabel(Sheet *sheet, int x, int y, int z, const char *buf, int update)
sheet->changed=1;
resize(sheet,x,y,z);
initcell(sheet,x,y,z);
- if (SHEET(sheet,x,y,z)->label!=(char*)0) free(SHEET(sheet,x,y,z)->label);
- if (*buf!='\0') SHEET(sheet,x,y,z)->label=strcpy(malloc(strlen(buf)+1),buf);
- else SHEET(sheet,x,y,z)->label=(char*)0;
+ if (CELL_AT(sheet,x,y,z)->label!=(char*)0) free(CELL_AT(sheet,x,y,z)->label);
+ if (*buf!='\0') CELL_AT(sheet,x,y,z)->label=strcpy(malloc(strlen(buf)+1),buf);
+ else CELL_AT(sheet,x,y,z)->label=(char*)0;
if (update)
{
cachelabels(sheet);
@@ -848,25 +933,28 @@ void relabel(Sheet *sheet, const char *oldlabel, const char *newlabel, int x, in
assert(y>=0);
assert(z>=0);
/*}}}*/
- if (!(x>=sheet->dimx || y>=sheet->dimy || z>=sheet->dimz || SHEET(sheet,x,y,z)==(Cell*)0 || SHEET(sheet,x,y,z)->contents==(Token**)0))
+ if (CELL_IS_GOOD(sheet,x,y,z))
{
- for (run=SHEET(sheet,x,y,z)->contents; *run!=(Token*)0; ++run)
+ if (CELL_AT(sheet,x,y,z)->contents != EMPTY_TVEC)
{
- if ((*run)->type==LIDENT && strcmp((*run)->u.lident,oldlabel)==0)
+ for (run=CELL_AT(sheet,x,y,z)->contents; *run!=NULLTOKEN; ++run)
{
- free((*run)->u.lident);
- (*run)->u.lident=mystrmalloc(newlabel);
+ if ((*run)->type==LIDENT && strcmp((*run)->u.lident,oldlabel)==0)
+ {
+ free((*run)->u.lident);
+ (*run)->u.lident=mystrmalloc(newlabel);
+ }
}
}
- }
- if (!(x>=sheet->dimx || y>=sheet->dimy || z>=sheet->dimz || SHEET(sheet,x,y,z)==(Cell*)0 || SHEET(sheet,x,y,z)->ccontents==(Token**)0))
- {
- for (run=SHEET(sheet,x,y,z)->ccontents; *run!=(Token*)0; ++run)
+ if (CELL_AT(sheet,x,y,z)->ccontents != EMPTY_TVEC)
{
- if ((*run)->type==LIDENT && strcmp((*run)->u.lident,oldlabel)==0)
+ for (run=CELL_AT(sheet,x,y,z)->ccontents; *run!=NULLTOKEN; ++run)
{
- free((*run)->u.lident);
- (*run)->u.lident=mystrmalloc(newlabel);
+ if ((*run)->type==LIDENT && strcmp((*run)->u.lident,oldlabel)==0)
+ {
+ free((*run)->u.lident);
+ (*run)->u.lident=mystrmalloc(newlabel);
+ }
}
}
}
@@ -910,10 +998,10 @@ const char *savexdr(Sheet *sheet, const char *name, unsigned int *count)
}
for (y=sheet->dimy-1; y>=0; --y)
{
- if (SHEET(sheet,x,y,z)!=(Cell*)0)
+ if (CELL_AT(sheet,x,y,z)!=NULLCELL)
{
u=1;
- if (xdr_int(&xdrs,&u)==0 || xdr_int(&xdrs,&x)==0 || xdr_int(&xdrs,&y)==0 || xdr_int(&xdrs,&z)==0 || xdr_cell(&xdrs,SHEET(sheet,x,y,z))==0)
+ if (xdr_int(&xdrs,&u)==0 || xdr_int(&xdrs,&x)==0 || xdr_int(&xdrs,&y)==0 || xdr_int(&xdrs,&z)==0 || xdr_cell(&xdrs,CELL_AT(sheet,x,y,z))==0)
{
xdr_destroy(&xdrs);
(void)fclose(fp);
@@ -997,7 +1085,7 @@ const char *savetbl(Sheet *sheet, const char *name, int body, int x1, int y1, in
if (!shadowed(sheet,x,y,z))
{
if (x>x1 && fputc_close('\t',fp)==EOF) return strerror(errno);
- if (SHEET(sheet,x,y,z)!=(Cell*)0)
+ if (CELL_AT(sheet,x,y,z)!=NULLCELL)
{
char *bufp;
@@ -1084,7 +1172,7 @@ const char *savetext(Sheet *sheet, const char *name, int x1, int y1, int z1, int
for (x=x1; x<=x2; ++x)
{
size=cellwidth(sheet,x,y,z);
- if (SHEET(sheet,x,y,z)!=(Cell*)0)
+ if (CELL_AT(sheet,x,y,z)!=NULLCELL)
{
char *buf;
@@ -1139,13 +1227,13 @@ const char *savecsv(Sheet *sheet, const char *name, char sep, int x1, int y1, in
for (x=x1; x<=x2; ++x)
{
if (x>x1) if (fputc_close(sep,fp)==EOF) return strerror(errno);
- if (SHEET(sheet,x,y,z)!=(Cell*)0)
+ if (CELL_AT(sheet,x,y,z)!=NULLCELL)
{
char *buf,*s;
buf=malloc(255*UTF8SZ+1);
printvalue(buf,255*UTF8SZ+1,255,0,getscientific(sheet,x,y,z),getprecision(sheet,x,y,z),sheet,x,y,z);
- if (SHEET(sheet,x,y,z)->value.type==STRING && fputc_close('"',fp)==EOF)
+ if (CELL_AT(sheet,x,y,z)->value.type==STRING && fputc_close('"',fp)==EOF)
{
free(buf);
return strerror(errno);
@@ -1159,7 +1247,7 @@ const char *savecsv(Sheet *sheet, const char *name, char sep, int x1, int y1, in
}
}
free(buf);
- if (SHEET(sheet,x,y,z)->value.type==STRING && fputc_close('"',fp)==EOF) return strerror(errno);
+ if (CELL_AT(sheet,x,y,z)->value.type==STRING && fputc_close('"',fp)==EOF) return strerror(errno);
}
++*count;
}
@@ -1193,32 +1281,32 @@ const char *saveport(Sheet *sheet, const char *name, unsigned int *count)
for (x=sheet->dimx-1; x>=0; --x)
{
if (y==0) if (columnwidth(sheet,x,z)!=DEF_COLUMNWIDTH) fprintf(fp,"W%d %d %d\n",x,z,columnwidth(sheet,x,z));
- if (SHEET(sheet,x,y,z)!=(Cell*)0)
+ if (CELL_AT(sheet,x,y,z)!=NULLCELL)
{
fprintf(fp,"C%d %d %d ",x,y,z);
- if (SHEET(sheet,x,y,z)->adjust!=AUTOADJUST) fprintf(fp,"A%c ","lrc"[SHEET(sheet,x,y,z)->adjust]);
- if (SHEET(sheet,x,y,z)->label) fprintf(fp,"L%s ",SHEET(sheet,x,y,z)->label);
- if (SHEET(sheet,x,y,z)->precision!=-1) fprintf(fp,"P%d ",SHEET(sheet,x,y,z)->precision);
- if (SHEET(sheet,x,y,z)->shadowed) fprintf(fp,"S ");
- if (SHEET(sheet,x,y,z)->bold) fprintf(fp,"B ");
- if (SHEET(sheet,x,y,z)->underline) fprintf(fp,"U ");
- if (SHEET(sheet,x,y,z)->scientific!=DEF_SCIENTIFIC) fprintf(fp,"E ");
- if (SHEET(sheet,x,y,z)->locked) fprintf(fp,"C ");
- if (SHEET(sheet,x,y,z)->transparent) fprintf(fp,"T ");
- if (SHEET(sheet,x,y,z)->contents)
+ if (CELL_AT(sheet,x,y,z)->adjust!=AUTOADJUST) fprintf(fp,"A%c ","lrc"[CELL_AT(sheet,x,y,z)->adjust]);
+ if (CELL_AT(sheet,x,y,z)->label) fprintf(fp,"L%s ",CELL_AT(sheet,x,y,z)->label);
+ if (CELL_AT(sheet,x,y,z)->precision!=-1) fprintf(fp,"P%d ",CELL_AT(sheet,x,y,z)->precision);
+ if (CELL_AT(sheet,x,y,z)->shadowed) fprintf(fp,"S ");
+ if (CELL_AT(sheet,x,y,z)->bold) fprintf(fp,"B ");
+ if (CELL_AT(sheet,x,y,z)->underline) fprintf(fp,"U ");
+ if (CELL_AT(sheet,x,y,z)->scientific!=DEF_SCIENTIFIC) fprintf(fp,"E ");
+ if (CELL_AT(sheet,x,y,z)->locked) fprintf(fp,"C ");
+ if (CELL_AT(sheet,x,y,z)->transparent) fprintf(fp,"T ");
+ if (CELL_AT(sheet,x,y,z)->contents)
{
char buf[4096];
if (fputc_close(':',fp)==EOF) return strerror(errno);
- print(buf,sizeof(buf),0,1,SHEET(sheet,x,y,z)->scientific,SHEET(sheet,x,y,z)->precision,SHEET(sheet,x,y,z)->contents);
+ print(buf,sizeof(buf),0,1,CELL_AT(sheet,x,y,z)->scientific,CELL_AT(sheet,x,y,z)->precision,CELL_AT(sheet,x,y,z)->contents);
if (fputs_close(buf,fp)==EOF) return strerror(errno);
}
- if (SHEET(sheet,x,y,z)->ccontents)
+ if (CELL_AT(sheet,x,y,z)->ccontents)
{
char buf[4096];
if (fputs_close("\\\n",fp)==EOF) return strerror(errno);
- print(buf,sizeof(buf),0,1,SHEET(sheet,x,y,z)->scientific,SHEET(sheet,x,y,z)->precision,SHEET(sheet,x,y,z)->ccontents);
+ print(buf,sizeof(buf),0,1,CELL_AT(sheet,x,y,z)->scientific,CELL_AT(sheet,x,y,z)->precision,CELL_AT(sheet,x,y,z)->ccontents);
if (fputs_close(buf,fp)==EOF) return strerror(errno);
}
if (fputc_close('\n',fp)==EOF) return strerror(errno);
@@ -1479,18 +1567,18 @@ const char *loadport(Sheet *sheet, const char *name)
}
/*}}}*/
initcell(sheet,x,y,z);
- SHEET(sheet,x,y,z)->adjust=adjust;
- SHEET(sheet,x,y,z)->label=label;
- SHEET(sheet,x,y,z)->precision=precision;
- SHEET(sheet,x,y,z)->shadowed=shadowed;
- SHEET(sheet,x,y,z)->bold=bold;
- SHEET(sheet,x,y,z)->underline=underline;
- SHEET(sheet,x,y,z)->scientific=scientific;
- SHEET(sheet,x,y,z)->locked=locked;
- SHEET(sheet,x,y,z)->transparent=transparent;
- SHEET(sheet,x,y,z)->ignored=ignored;
- SHEET(sheet,x,y,z)->contents=contents;
- SHEET(sheet,x,y,z)->ccontents=ccontents;
+ CELL_AT(sheet,x,y,z)->adjust=adjust;
+ CELL_AT(sheet,x,y,z)->label=label;
+ CELL_AT(sheet,x,y,z)->precision=precision;
+ CELL_AT(sheet,x,y,z)->shadowed=shadowed;
+ CELL_AT(sheet,x,y,z)->bold=bold;
+ CELL_AT(sheet,x,y,z)->underline=underline;
+ CELL_AT(sheet,x,y,z)->scientific=scientific;
+ CELL_AT(sheet,x,y,z)->locked=locked;
+ CELL_AT(sheet,x,y,z)->transparent=transparent;
+ CELL_AT(sheet,x,y,z)->ignored=ignored;
+ CELL_AT(sheet,x,y,z)->contents=contents;
+ CELL_AT(sheet,x,y,z)->ccontents=ccontents;
break;
}
/*}}}*/
@@ -1607,7 +1695,7 @@ const char *loadxdr(Sheet *sheet, const char *name)
return strerror(olderror);
}
initcell(sheet,x,y,z);
- if (xdr_cell(&xdrs,SHEET(sheet,x,y,z))==0)
+ if (xdr_cell(&xdrs,CELL_AT(sheet,x,y,z))==0)
{
freecell(sheet,x,y,z);
olderror=errno;
@@ -1743,8 +1831,8 @@ void insertcube(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, Di
for (z=z1; z<=z2; ++z) for (y=y1; y<=y2; ++y) for (x=right; x>x2; --x)
{
resize(sheet,x,y,z);
- SHEET(sheet,x,y,z)=SHEET(sheet,x-(x2-x1+1),y,z);
- SHEET(sheet,x-(x2-x1+1),y,z)=(Cell*)0;
+ CELL_AT(sheet,x,y,z)=CELL_AT(sheet,x-(x2-x1+1),y,z);
+ CELL_AT(sheet,x-(x2-x1+1),y,z)=NULLCELL;
}
break;
}
@@ -1758,8 +1846,8 @@ void insertcube(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, Di
for (z=z1; z<=z2; ++z) for (x=x1; x<=x2; ++x) for (y=down; y>y2; --y)
{
resize(sheet,x,y,z);
- SHEET(sheet,x,y,z)=SHEET(sheet,x,y-(y2-y1+1),z);
- SHEET(sheet,x,y-(y2-y1+1),z)=(Cell*)0;
+ CELL_AT(sheet,x,y,z)=CELL_AT(sheet,x,y-(y2-y1+1),z);
+ CELL_AT(sheet,x,y-(y2-y1+1),z)=NULLCELL;
}
break;
}
@@ -1773,8 +1861,8 @@ void insertcube(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, Di
for (y=y1; y<=y2; ++y) for (x=x1; x<=x2; ++x) for (z=bottom; z>z2; --z)
{
resize(sheet,x,y,z);
- SHEET(sheet,x,y,z)=SHEET(sheet,x,y,z-(z2-z1+1));
- SHEET(sheet,x,y,z-(z2-z1+1))=(Cell*)0;
+ CELL_AT(sheet,x,y,z)=CELL_AT(sheet,x,y,z-(z2-z1+1));
+ CELL_AT(sheet,x,y,z-(z2-z1+1))=NULLCELL;
}
break;
}
@@ -1810,8 +1898,8 @@ void deletecube(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, Di
{
if (x+(x2-x1+1)dimx && ydimy && zdimz)
{
- SHEET(sheet,x,y,z)=SHEET(sheet,x+(x2-x1+1),y,z);
- SHEET(sheet,x+(x2-x1+1),y,z)=(Cell*)0;
+ CELL_AT(sheet,x,y,z)=CELL_AT(sheet,x+(x2-x1+1),y,z);
+ CELL_AT(sheet,x+(x2-x1+1),y,z)=NULLCELL;
}
}
break;
@@ -1824,8 +1912,8 @@ void deletecube(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, Di
{
if (xdimx && y+(y2-y1+1)dimy && zdimz)
{
- SHEET(sheet,x,y,z)=SHEET(sheet,x,y+(y2-y1+1),z);
- SHEET(sheet,x,y+(y2-y1+1),z)=(Cell*)0;
+ CELL_AT(sheet,x,y,z)=CELL_AT(sheet,x,y+(y2-y1+1),z);
+ CELL_AT(sheet,x,y+(y2-y1+1),z)=NULLCELL;
}
}
break;
@@ -1838,8 +1926,8 @@ void deletecube(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, Di
{
if (xdimx && ydimy && z+(z2-z1+1)dimz)
{
- SHEET(sheet,x,y,z)=SHEET(sheet,x,y,z+(z2-z1+1));
- SHEET(sheet,x,y,z+(z2-z1+1))=(Cell*)0;
+ CELL_AT(sheet,x,y,z)=CELL_AT(sheet,x,y,z+(z2-z1+1));
+ CELL_AT(sheet,x,y,z+(z2-z1+1))=NULLCELL;
}
}
break;
@@ -1884,8 +1972,8 @@ void moveblock(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, int
if (x1+xdimx && y1+ydimy && z1+zdimz)
{
resize(sheet,x3+x,y3+y,z3+z);
- SHEET(sheet,x3+x,y3+y,z3+z)=SHEET(sheet,x1+x,y1+y,z1+z);
- SHEET(sheet,x1+x,y1+y,z1+z)=(Cell*)0;
+ CELL_AT(sheet,x3+x,y3+y,z3+z)=CELL_AT(sheet,x1+x,y1+y,z1+z);
+ CELL_AT(sheet,x1+x,y1+y,z1+z)=NULLCELL;
}
else
{
diff --git a/sheet.h b/sheet.h
index 1ee5898..94e27eb 100644
--- a/sheet.h
+++ b/sheet.h
@@ -7,7 +7,13 @@
extern "C" {
#endif
-#define SHEET(s,x,y,z) (*(s->sheet+(x)*s->dimz*s->dimy+(y)*s->dimz+(z)))
+#define LOC_WITHIN(s,x,y,z) (xdimx && ydimy && zdimz)
+#define CELL_AT(s,x,y,z) (*(s->sheet+(x)*s->dimz*s->dimy+(y)*s->dimz+(z)))
+#define NULLCELL ((Cell*)0)
+#define CELL_IS_NULL(s,x,y,z) (CELL_AT(s,x,y,z) == NULLCELL)
+#define CELL_IS_GOOD(s,x,y,z) (LOC_WITHIN(s,x,y,z) && !CELL_IS_NULL(s,x,y,z))
+#define SHADOWED(s,x,y,z) (CELL_IS_GOOD(s,x,y,z) && CELL_AT(s,x,y,z)->shadowed)
+#define ALL_CELLS_IN_SHEET(s,x,y,z) x=0; xdimx; ++x) for (y=0; ydimy; ++y) for (z=0; zdimz; ++z
typedef enum { LEFT=0, RIGHT=1, CENTER=2, AUTOADJUST=3 } Adjust;
@@ -86,6 +92,7 @@ void initcell(Sheet *sheet, int x, int y, int z);
void cachelabels(Sheet *sheet);
void freesheet(Sheet *sheet, int all);
void forceupdate(Sheet *sheet);
+void dump_current_cell(Sheet *sheet);
void freecell(Sheet *sheet, int x, int y, int z);
int columnwidth(Sheet *sheet, int x, int z);
void setwidth(Sheet *sheet, int x, int z, int width);
diff --git a/teapot.1 b/teapot.1
index 3a0dbc7..70ad9b5 100644
--- a/teapot.1
+++ b/teapot.1
@@ -2,7 +2,7 @@
.\" Copyright(c) 2010 by wave++ "Yuri D'Elia"
.\" Distributed under GNU GPL WITHOUT ANY WARRANTY.
.\"
-.Dd Dicember 8, 2010
+.Dd December 8, 2010
.Dt TEAPOT 1
.\"
.\"
@@ -12,10 +12,12 @@
.\"
.\"
.Sh SYNOPSIS
-.Nm
-.Op Fl abHqr
+\fBfteapot|teapot\fP
+.Op Fl abdhHr
+.Op Fl n|q
.Op Fl p Ar digits
.Op Ar file
+.YS
.\"
.\"
.Sh DESCRIPTION
@@ -25,12 +27,19 @@ dimensions with linear addressing, relative references, formula references,
type safety of computations, iterative expressions and platform independent
file format.
.Pp
+.Pp
+When invoked as 'teapot' the program uses a console-based text interface; when
+invoked as 'fteapot' it uses a windowed graphical interface. The
+.Pa file
+argument, if given, specifies an initial file to load upon startup.
+.Pp
This document only describes command-line arguments. Please refer to the
complete manual that can be found under
.Pa /usr/share/doc/teapot
-in both html and pdf format.
-The manual can also be viewed from within the graphical version, fteapot,
-using the Help menu.
+(or other standard documentation location on your system) in both html
+and pdf format, teapot.pdf.
+The manual can also be viewed from within the graphical version using
+the Help menu.
.\"
.\"
.Sh OPTIONS
@@ -39,10 +48,16 @@ using the Help menu.
Use ASCII instead of XDR as default file format when loading or saving.
.It Fl b
Read batch commands from standard input.
+.It Fl d
+Increment the debug level, once per occurrence; teapot may produce various
+output on standard out when this is specified, and additional key bindings
+may be in effect.
+.It Fl h
+Print a brief usage message.
.It Fl H
Hide row and column headers.
-.It Fl q
-Display strings quoted.
+.It Fl n|q
+Display strings definitely NOT quoted or definitely quoted, respectively.
.It Fl r
Redraw the terminal window more often.
.It Fl p Ar digits
@@ -67,6 +82,11 @@ Copyright (C) 2009-2012
J\(:org Walter
.Me
.Pp
+Copyright (C) 2019
+.Mt glen@studioinfinity.org
+Glen Whitney
+.Me
+.Pp
Manual page written by
.Mt wavexx@users.sf.net
Yuri D'Elia
diff --git a/wk1.c b/wk1.c
index 72574cf..d51c28f 100644
--- a/wk1.c
+++ b/wk1.c
@@ -836,7 +836,7 @@ const char *loadwk1(Sheet *sheet, const char *name)
{
if (bodylen!=5) { err=_("Invalid record body length"); goto ouch; }
initcell(sheet,it(body+1),it(body+3),0);
- format((unsigned char)body[0],SHEET(sheet,it(body+1),it(body+3),0));
+ format((unsigned char)body[0],CELL_AT(sheet,it(body+1),it(body+3),0));
break;
}
/*}}}*/
@@ -853,7 +853,7 @@ const char *loadwk1(Sheet *sheet, const char *name)
t[0]->type=INT;
t[0]->u.integer=it(body+5);
putcont(sheet,it(body+1),it(body+3),0,t,0);
- format((unsigned char)body[0],SHEET(sheet,it(body+1),it(body+3),0));
+ format((unsigned char)body[0],CELL_AT(sheet,it(body+1),it(body+3),0));
break;
}
/*}}}*/
@@ -870,7 +870,7 @@ const char *loadwk1(Sheet *sheet, const char *name)
t[0]->type=FLOAT;
t[0]->u.flt=dbl((unsigned char*)body+5);
putcont(sheet,it(body+1),it(body+3),0,t,0);
- format((unsigned char)body[0],SHEET(sheet,it(body+1),it(body+3),0));
+ format((unsigned char)body[0],CELL_AT(sheet,it(body+1),it(body+3),0));
break;
}
/*}}}*/
@@ -887,7 +887,7 @@ const char *loadwk1(Sheet *sheet, const char *name)
t[0]->type=STRING;
t[0]->u.string=mystrmalloc(body+6);
putcont(sheet,it(body+1),it(body+3),0,t,0);
- format((unsigned char)body[0],SHEET(sheet,it(body+1),it(body+3),0));
+ format((unsigned char)body[0],CELL_AT(sheet,it(body+1),it(body+3),0));
break;
}
/*}}}*/
@@ -944,7 +944,7 @@ const char *loadwk1(Sheet *sheet, const char *name)
#if WK1DEBUG
fprintf(se,", value %f",dbl((unsigned char*)body+5));
#endif
- format((unsigned char)body[0],SHEET(sheet,it(body+1),it(body+3),0));
+ format((unsigned char)body[0],CELL_AT(sheet,it(body+1),it(body+3),0));
#if WK1DEBUG
fprintf(se,"\r\n");
#endif
@@ -969,8 +969,8 @@ const char *loadwk1(Sheet *sheet, const char *name)
#endif
free(offset);
initcell(sheet,it(body+1),it(body+3),0);
- SHEET(sheet,it(body+1),it(body+3),0)->value.type=FLOAT;
- SHEET(sheet,it(body+1),it(body+3),0)->value.u.flt=dbl((unsigned char*)body+5);
+ CELL_AT(sheet,it(body+1),it(body+3),0)->value.type=FLOAT;
+ CELL_AT(sheet,it(body+1),it(body+3),0)->value.u.flt=dbl((unsigned char*)body+5);
putcont(sheet,it(body+1),it(body+3),0,t,0);
}
break;
@@ -1092,7 +1092,7 @@ const char *loadwk1(Sheet *sheet, const char *name)
t[0]->type=STRING;
t[0]->u.string=mystrmalloc(body+5);
putcont(sheet,it(body+1),it(body+3),0,t,0);
- format((unsigned char)body[0],SHEET(sheet,it(body+1),it(body+3),0));
+ format((unsigned char)body[0],CELL_AT(sheet,it(body+1),it(body+3),0));
break;
}
/*}}}*/