A first stab at refactoring

In general, the goal of these changes is to be more type-specific wherever
  possible, reduce duplicated code, and avoid magic numbers. The biggest
  individual change is to use Location triples of integers wherever possible
  rather than three separate int variables. Another very helpful change for
  understanding what is going on in the code is introducing the MarkState enum
  for tracking the process of marking and unmarking blocks of cell.

  The MarkState change was motivated by the issues with Ctrl-C,
  and this commit, in fact,
  resolves #28.

  Because of the lack of a test harness, it is possible that a change of
  this scope has created some bugs as well, but teapot was running OK for
  me at the time of the commit. However, I don't know how good my coverage of
  the changed code was -- I certainly did not save or load a Lotus 1-2-3 file!
This commit is contained in:
Glen Whitney 2019-07-27 00:14:26 -04:00
parent 2837cc2253
commit 255bd86bf5
20 changed files with 1521 additions and 1269 deletions

View File

@ -24,29 +24,35 @@
/*}}}*/ /*}}}*/
/* savecontext -- save as ConTeXt table */ /*{{{*/ /* savecontext -- save as ConTeXt table */ /*{{{*/
const char *savecontext(Sheet *sheet, const char *name, int body, int x1, int y1, int z1, int x2, int y2, int z2, unsigned int *count) const char *savecontext(Sheet *sheet, const char *name, int body,
const Location beg, const Location end,
unsigned int *count)
{ {
/* variables */ /*{{{*/ /* variables */ /*{{{*/
FILE *fp=(FILE*)0; /* cause runtime error */ FILE *fp=(FILE*)0; /* cause runtime error */
int x,y,z; Location w;
char buf[1024]; char buf[1024];
char num[20]; char num[20];
char fullname[PATH_MAX]; char fullname[PATH_MAX];
Cell *cell;
/*}}}*/ /*}}}*/
/* asserts */ /*{{{*/ /* asserts */ /*{{{*/
assert(sheet!=(Sheet*)0); assert(sheet != (Sheet*)0);
assert(name!=(const char*)0); assert(name != (const char*)0);
/*}}}*/ /*}}}*/
*count=0; *count=0;
for (z=z1; z<=z2; ++z) for (y=y1; y<=y2; ++y) if (shadowed(sheet,x1,y,z)) return _("Shadowed cells in first column"); w[X] = beg[X];
for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z]))
for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++(w[Y]))
if (shadowed(CELL_AT(sheet,w))) return _("Shadowed cells in first column");
if (!body && (fp=fopen(name,"w"))==(FILE*)0) return strerror(errno); if (!body && (fp=fopen(name,"w"))==(FILE*)0) return strerror(errno);
for (z=z1; z<=z2; ++z) for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z]))
{ {
if (body) if (body)
/* open new file */ /*{{{*/ /* open new file */ /*{{{*/
{ {
sprintf(num,".%d",z); sprintf(num, ".%d", w[Z]);
fullname[sizeof(fullname)-strlen(num)-1]='\0'; fullname[sizeof(fullname)-strlen(num)-1]='\0';
(void)strncpy(fullname,name,sizeof(fullname)-strlen(num)-1); (void)strncpy(fullname,name,sizeof(fullname)-strlen(num)-1);
@ -58,7 +64,7 @@ const char *savecontext(Sheet *sheet, const char *name, int body, int x1, int y1
/*}}}*/ /*}}}*/
else else
/* print header */ /*{{{*/ /* print header */ /*{{{*/
if (z==z1) if (w[Z] == beg[Z])
{ {
if (fputs_close("\\starttext\n",fp)==EOF) return strerror(errno); if (fputs_close("\\starttext\n",fp)==EOF) return strerror(errno);
} }
@ -70,31 +76,34 @@ const char *savecontext(Sheet *sheet, const char *name, int body, int x1, int y1
/* print bogus format */ /*{{{*/ /* print bogus format */ /*{{{*/
fprintf(fp,"\\starttable["); fprintf(fp,"\\starttable[");
for (x=x1; x<=x2; ++x) if (fputs_close("|l",fp)==EOF) return strerror(errno); for (w[X]=beg[X]; w[X]<=end[X]; ++(w[X]))
if (fputs_close("|l",fp)==EOF) return strerror(errno);
fprintf(fp,"|]\n"); fprintf(fp,"|]\n");
/*}}}*/ /*}}}*/
for (y=y1; y<=y2; ++y) for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++(w[Y]))
/* print contents */ /*{{{*/ /* print contents */ /*{{{*/
{ {
for (x=x1; x<=x2; ) for (w[X]=beg[X]; w[X]<=end[X]; )
{ {
int multicols; int multicols;
char *bufp; char *bufp;
if (x>x1 && fputs_close("\\NC",fp)==EOF) return strerror(errno); if (w[X] > beg[X] && fputs_close("\\NC",fp)==EOF) return strerror(errno);
for (multicols=x+1; multicols<sheet->dimx && shadowed(sheet,multicols,y,z); ++multicols); for (multicols=w[X]+1; multicols<sheet->dimx && SHADOWEDC(sheet,multicols,w[Y],w[Z]); ++multicols);
multicols=multicols-x; multicols=multicols-w[X];
if (multicols>1) fprintf(fp,"\\use{%d}",multicols); if (multicols>1) fprintf(fp,"\\use{%d}",multicols);
switch (getadjust(sheet,x,y,z)) cell = CELL_AT(sheet, w);
switch (getadjust(cell))
{ {
case LEFT: if (fputs_close("\\JustLeft ",fp)==EOF) return strerror(errno); break; case LEFT: if (fputs_close("\\JustLeft ",fp)==EOF) return strerror(errno); break;
case RIGHT: if (fputs_close("\\JustRight ",fp)==EOF) return strerror(errno); break; case RIGHT: if (fputs_close("\\JustRight ",fp)==EOF) return strerror(errno); break;
case CENTER: if (fputs_close("\\JustCenter ",fp)==EOF) return strerror(errno); break; case CENTER: if (fputs_close("\\JustCenter ",fp)==EOF) return strerror(errno); break;
default: assert(0); default: assert(0);
} }
printvalue(buf,sizeof(buf),0,0,getscientific(sheet,x,y,z),getprecision(sheet,x,y,z),sheet,x,y,z); printvalue(buf, sizeof(buf), 0, 0, getscientific(cell),
getprecision(cell), sheet, w);
/* if (fputs_close("}{",fp)==EOF) return strerror(errno);*/ /* if (fputs_close("}{",fp)==EOF) return strerror(errno);*/
if (transparent(sheet,x,y,z)) if (transparent(cell))
{ {
if (fputs_close(buf,fp)==EOF) return strerror(errno); if (fputs_close(buf,fp)==EOF) return strerror(errno);
} }
@ -113,10 +122,10 @@ const char *savecontext(Sheet *sheet, const char *name, int body, int x1, int y1
default: if (fputc_close(*bufp,fp)==EOF) return strerror(errno); default: if (fputc_close(*bufp,fp)==EOF) return strerror(errno);
} }
/* if (fputc_close('}',fp)==EOF) return strerror(errno);*/ /* if (fputc_close('}',fp)==EOF) return strerror(errno);*/
x+=multicols; w[X] += multicols;
++*count; ++*count;
} }
if (fputs_close(y<y2 ? "\\MR\n" : "\n\\stoptable\n",fp)==EOF) return strerror(errno); if (fputs_close(w[Y]<end[Y] ? "\\MR\n" : "\n\\stoptable\n",fp)==EOF) return strerror(errno);
} }
/*}}}*/ /*}}}*/
if (body) if (body)

View File

@ -3,6 +3,8 @@
#include "sheet.h" #include "sheet.h"
const char *savecontext(Sheet *sheet, const char *name, int body, int x1, int y1, int z1, int x2, int y2, int z2, unsigned int *count); const char *savecontext(Sheet *sheet, const char *name, int body,
const Location beg, const Location end,
unsigned int *count);
#endif #endif

153
display.c
View File

@ -19,6 +19,7 @@
#include <pwd.h> #include <pwd.h>
#include <termios.h> #include <termios.h>
#include <signal.h> #include <signal.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -60,6 +61,8 @@ static int do_attribute(Sheet *cursheet)
MenuChoice mainmenu[5]; MenuChoice mainmenu[5];
MenuChoice adjmenu[11]; MenuChoice adjmenu[11];
MarkState ms;
const char *prompt;
int c; int c;
/* create menus */ /* create menus */
@ -82,8 +85,16 @@ static int do_attribute(Sheet *cursheet)
do do
{ {
c = line_menu(cursheet->mark1x==-1 ? _("Cell attribute:") : _("Block attribute:"),mainmenu,0); ms = getmarkstate(cursheet);
if (cursheet->mark1x==-1 && c!=2 && locked(cursheet,cursheet->curx,cursheet->cury,cursheet->curz)) line_msg(_("Cell attribute:"),_("Cell is locked")); if (ms == UNMARKED) prompt = _("Cell attribute");
else prompt = _("Block attribute");
c = line_menu(prompt, mainmenu, 0);
/* There is a magic number "2" in the next line, presumably it represents
the selection of the lock attribute in the list of items above, in which
lock does indeed appear at index 2
*/
if (ms == UNMARKED && c != 2 && locked(curcell(cursheet)))
line_msg(_("Cell attribute:"),_("Cell is locked"));
else else
{ {
switch (c) switch (c)
@ -92,7 +103,7 @@ static int do_attribute(Sheet *cursheet)
case -1: c = KEY_CANCEL; break; case -1: c = KEY_CANCEL; break;
case 0: case 0:
{ {
switch (c=line_menu(cursheet->mark1x==-1 ? _("Cell attribute:") : _("Block attribute:"),adjmenu,0)) switch (c = line_menu(prompt, adjmenu,0))
{ {
case -2: case -2:
case -1: c = K_INVALID; break; case -1: c = K_INVALID; break;
@ -135,6 +146,7 @@ static int do_attribute(Sheet *cursheet)
return c; return c;
} }
/* do_file -- file menu */ /* do_file -- file menu */
static int do_file(Sheet *cursheet) static int do_file(Sheet *cursheet)
{ {
@ -406,7 +418,7 @@ void display_end(void)
endwin(); endwin();
} }
void redraw_cell(Sheet *sheet, int x, int y, int z) void redraw_cell(Sheet *sheet, const Location at )
{ {
redraw_sheet(sheet); redraw_sheet(sheet);
} }
@ -420,35 +432,41 @@ void redraw_sheet(Sheet *sheet)
char *buf=malloc(128); char *buf=malloc(128);
size_t bufsz=128; size_t bufsz=128;
const char *label; const char *label;
Location tmp;
Cell *cell;
MarkState ms;
char *err; char *err;
char moveonly; char moveonly;
assert(sheet!=(Sheet*)0); assert(sheet!=(Sheet*)0);
assert(sheet->curx>=0); assert(IN_OCTANT(sheet->cur));
assert(sheet->cury>=0);
assert(sheet->curz>=0);
assert(sheet->offx>=0); assert(sheet->offx>=0);
assert(sheet->offy>=0); assert(sheet->offy>=0);
/* correct offsets to keep cursor visible */ /* correct offsets to keep cursor visible */
while (shadowed(sheet,sheet->curx,sheet->cury,sheet->curz)) while (shadowed(curcell(sheet)))
{ {
--(sheet->curx); --(sheet->cur[X]);
assert(sheet->curx>=0); assert(sheet->cur[X] >= 0);
} }
if (sheet->cury-sheet->offy>(sheet->maxy-2-header)) sheet->offy=sheet->cury-sheet->maxy+2+header; if (sheet->cur[Y] - sheet->offy > (sheet->maxy - 2 - header))
if (sheet->cury<sheet->offy) sheet->offy=sheet->cury; sheet->offy = sheet->cur[Y] - sheet->maxy + 2 + header;
if (sheet->curx<sheet->offx) sheet->offx=sheet->curx; if (sheet->cur[Y] < sheet->offy) sheet->offy = sheet->cur[Y];
if (sheet->cur[X] < sheet->offx) sheet->offx = sheet->cur[X];
do do
{ {
again=0; again=0;
for (width=4*header,x=sheet->offx,col=0; width<=sheet->maxx; width+=columnwidth(sheet,x,sheet->curz),++x,++col); for (width = 4*header, x = sheet->offx, col=0;
width <= sheet->maxx;
width += columnwidth(sheet, x, sheet->cur[Z]), ++x, ++col);
--col; --col;
sheet->width=col; sheet->width = col;
if (sheet->curx!=sheet->offx) if (sheet->cur[X] != sheet->offx)
{ {
if (col==0) { ++sheet->offx; again=1; } if (col==0) { ++sheet->offx; again=1; }
else if (sheet->curx-sheet->offx>=col) { ++sheet->offx; again=1; } else if (sheet->cur[X] - sheet->offx >= col) {
++sheet->offx; again=1;
}
} }
} while (again); } while (again);
@ -456,10 +474,12 @@ void redraw_sheet(Sheet *sheet)
(void)wattron(stdscr,DEF_NUMBER); (void)wattron(stdscr,DEF_NUMBER);
/* draw x numbers */ /* draw x numbers */
for (width=4; width<sheet->maxx; ++width) mvwaddch(stdscr,0+sheet->oriy,sheet->orix+width,(chtype)(unsigned char)' '); for (width=4; width < sheet->maxx; ++width)
for (width=4,x=sheet->offx; width<sheet->maxx; width+=col,++x) mvwaddch(stdscr, 0+sheet->oriy, sheet->orix+width,
(chtype)(unsigned char)' ');
for (width=4, x=sheet->offx; width<sheet->maxx; width+=col,++x)
{ {
col=columnwidth(sheet,x,sheet->curz); col = columnwidth(sheet, x, sheet->cur[Z]);
if (bufsz<(size_t)(col*UTF8SZ+1)) buf=realloc(buf,bufsz=(size_t)(col*UTF8SZ+1)); if (bufsz<(size_t)(col*UTF8SZ+1)) buf=realloc(buf,bufsz=(size_t)(col*UTF8SZ+1));
snprintf(buf,bufsz,"%d",x); snprintf(buf,bufsz,"%d",x);
if (mbslen(buf)>col) { if (mbslen(buf)>col) {
@ -478,74 +498,86 @@ void redraw_sheet(Sheet *sheet)
(void)wattroff(stdscr,DEF_NUMBER); (void)wattroff(stdscr,DEF_NUMBER);
/* draw z number */ /* draw z number */
(void)mvwprintw(stdscr,sheet->oriy,sheet->orix,"%3d",sheet->curz); (void)mvwprintw(stdscr, sheet->oriy, sheet->orix, "%3d", sheet->cur[Z]);
} }
/* draw elements */ /* draw elements */
for (y=header; y<sheet->maxy-1; ++y) for (width=4*header,x=sheet->offx; width<sheet->maxx; width+=columnwidth(sheet,x,sheet->curz),++x) for (y=header; y<sheet->maxy-1; ++y)
for (width = 4*header, x = sheet->offx;
width < sheet->maxx;
width += columnwidth(sheet, x, sheet->cur[Z]),++x)
{ {
size_t size,realsize,fill,cutoff; size_t size,realsize,fill,cutoff;
int realx; int realx;
realx=x; realx = x;
cutoff=0; cutoff = 0;
if (x==sheet->offx) while (shadowed(sheet,realx,y-header+sheet->offy,sheet->curz)) if (x == sheet->offx)
while (SHADOWEDC(sheet,realx,y-header+sheet->offy,sheet->cur[Z]))
{ {
--realx; --realx;
cutoff+=columnwidth(sheet,realx,sheet->curz); cutoff+=columnwidth(sheet, realx, sheet->cur[Z]);
} }
if ((size=cellwidth(sheet,realx,y-header+sheet->offy,sheet->curz))) tmp[X] = realx; tmp[Y] = y - header + sheet->offy;
tmp[Z] = sheet->cur[Z]; cell = safe_cell_at(sheet, tmp);
if ((size = cellwidth(sheet, tmp)))
{ {
int invert; bool invert;
if (bufsz<(size*UTF8SZ+1)) buf=realloc(buf,bufsz=(size*UTF8SZ+1)); if (bufsz < (size*UTF8SZ+1))
printvalue(buf,(size*UTF8SZ+1),size,quote,getscientific(sheet,realx,y-header+sheet->offy,sheet->curz),getprecision(sheet,realx,y-header+sheet->offy,sheet->curz),sheet,realx,y-header+sheet->offy,sheet->curz); buf = realloc(buf, bufsz=(size*UTF8SZ+1));
adjust(getadjust(sheet,realx,y-header+sheet->offy,sheet->curz),buf,size); printvalue(buf, (size*UTF8SZ+1), size, quote, getscientific(cell),
getprecision(cell), sheet, tmp);
adjust(getadjust(cell), buf, size);
assert(size>=cutoff); assert(size>=cutoff);
if (width+((int)(size-cutoff))>=sheet->maxx) if (width+((int)(size-cutoff)) >= sheet->maxx)
{ {
*(buf+cutoff+sheet->maxx-width)='\0'; *(buf+cutoff+sheet->maxx-width)='\0';
realsize=sheet->maxx-width+cutoff; realsize=sheet->maxx-width+cutoff;
} }
else realsize=size; else realsize=size;
invert= ms = getmarkstate(sheet);
( invert =
(sheet->mark1x!=-1) && (ms != UNMARKED) && loc_in_box(tmp, sheet->mark1, sheet->mark2);
((x>=sheet->mark1x && x<=sheet->mark2x) || (x>=sheet->mark2x && x<=sheet->mark1x)) && if (x == sheet->cur[X] && (y-header+sheet->offy) == sheet->cur[Y])
((y-header+sheet->offy>=sheet->mark1y && y-header+sheet->offy<=sheet->mark2y) || (y-header+sheet->offy>=sheet->mark2y && y-header+sheet->offy<=sheet->mark1y)) && invert = (ms == MARKING) ? true : !invert;
((sheet->curz>=sheet->mark1z && sheet->curz<=sheet->mark2z) || (sheet->curz>=sheet->mark2z && sheet->curz<=sheet->mark1z))
);
if (x==sheet->curx && (y-header+sheet->offy)==sheet->cury) invert=(sheet->marking ? 1 : 1-invert);
if (invert) (void)wattron(stdscr,DEF_CELLCURSOR); if (invert) (void)wattron(stdscr,DEF_CELLCURSOR);
if (isbold(sheet,realx,y-header+sheet->offy,sheet->curz)) wattron(stdscr,A_BOLD); if (isbold(cell)) wattron(stdscr,A_BOLD);
if (underlined(sheet,realx,y-header+sheet->offy,sheet->curz)) wattron(stdscr,A_UNDERLINE); if (underlined(cell)) wattron(stdscr,A_UNDERLINE);
(void)mvwaddstr(stdscr,sheet->oriy+y,sheet->orix+width,buf+cutoff); (void)mvwaddstr(stdscr,sheet->oriy+y,sheet->orix+width,buf+cutoff);
for (fill=mbslen(buf+cutoff); fill<realsize; ++fill) (void)waddch(stdscr,(chtype)(unsigned char)' '); for (fill=mbslen(buf+cutoff); fill<realsize; ++fill)
(void)waddch(stdscr,(chtype)(unsigned char)' ');
wstandend(stdscr); wstandend(stdscr);
} }
} }
/* draw contents of current element */ /* draw contents of current element */
if (bufsz<(unsigned int)(sheet->maxx*UTF8SZ+1)) buf=realloc(buf,bufsz=(sheet->maxx*UTF8SZ+1)); if (bufsz < (unsigned int)(sheet->maxx*UTF8SZ+1))
label=getlabel(sheet,sheet->curx,sheet->cury,sheet->curz); buf = realloc(buf,bufsz=(sheet->maxx*UTF8SZ+1));
assert(label!=(const char*)0); label = getlabel(curcell(sheet));
moveonly=sheet->moveonly ? *_("V") : *_("E"); assert(label != (const char*)0);
if (*label=='\0') sprintf(pbuf,"%c @(%d,%d,%d)=",moveonly,sheet->curx,sheet->cury,sheet->curz); moveonly = sheet->moveonly ? *_("V") : *_("E");
else sprintf(pbuf,"%c @(%s)=",moveonly,label); if (*label=='\0')
sprintf(pbuf, "%c @(%d,%d,%d)=", moveonly,
sheet->cur[X], sheet->cur[Y], sheet->cur[Z]);
else sprintf(pbuf, "%c @(%s)=", moveonly, label);
(void)strncpy(buf,pbuf,bufsz); (void)strncpy(buf,pbuf,bufsz);
buf[bufsz-1] = 0; buf[bufsz-1] = 0;
if ((err=geterror(sheet,sheet->curx,sheet->cury,sheet->curz))!=(const char*)0) if ((err=geterror(sheet,sheet->cur)) != (const char*)0)
{ {
(void)strncpy(buf, err, bufsz); (void)strncpy(buf, err, bufsz);
free(err); free(err);
} }
else else
{ {
print(buf+strlen(buf),bufsz-strlen(buf),0,1,getscientific(sheet,sheet->curx,sheet->cury,sheet->curz),-1,getcont(sheet,sheet->curx,sheet->cury,sheet->curz,0)); cell = curcell(sheet);
if (getcont(sheet,sheet->curx,sheet->cury,sheet->curz,1) && mbslen(buf) < (size_t)(sheet->maxx+1-4)) print(buf+strlen(buf), bufsz-strlen(buf), 0, 1, getscientific(cell),
{ -1, getcont(cell, BASE));
strcat(buf," -> "); if (getcont(cell, ITERATIVE) && mbslen(buf) < (size_t)(sheet->maxx+1-4))
print(buf+strlen(buf),bufsz-strlen(buf),0,1,getscientific(sheet,sheet->curx,sheet->cury,sheet->curz),-1,getcont(sheet,sheet->curx,sheet->cury,sheet->curz,1)); {
strcat(buf," -> ");
print(buf+strlen(buf), bufsz-strlen(buf), 0, 1,
getscientific(cell), -1, getcont(cell, ITERATIVE));
} }
} }
*mbspos(buf, sheet->maxx) = 0; *mbspos(buf, sheet->maxx) = 0;
@ -615,7 +647,9 @@ int line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt, size_t *
case 'v': { case 'v': {
char valbuf[1024]; char valbuf[1024];
printvalue(valbuf,sizeof(valbuf),0,1,getscientific(sheet,sheet->curx,sheet->cury,sheet->curz),-1,sheet,sheet->curx,sheet->cury,sheet->curz); printvalue(valbuf, sizeof(valbuf), 0, 1,
getscientific(curcell(sheet)), -1,
sheet, sheet->cur);
if (strlen(buf)+strlen(valbuf) >= (size-1)) break; if (strlen(buf)+strlen(valbuf) >= (size-1)) break;
(void)memmove(src+strlen(valbuf), src, strlen(src)); (void)memmove(src+strlen(valbuf), src, strlen(src));
(void)memcpy(src, valbuf, strlen(valbuf)); (void)memcpy(src, valbuf, strlen(valbuf));
@ -627,7 +661,8 @@ int line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt, size_t *
case 'p': { case 'p': {
char valbuf[1024]; char valbuf[1024];
sprintf(valbuf,"(%d,%d,%d)",sheet->curx,sheet->cury,sheet->curz); sprintf(valbuf, "(%d,%d,%d)",
sheet->cur[X], sheet->cur[Y], sheet->cur[Z]);
if (strlen(buf)+strlen(valbuf) >= (size-1)) break; if (strlen(buf)+strlen(valbuf) >= (size-1)) break;
(void)memmove(src+strlen(valbuf), src, strlen(src)); (void)memmove(src+strlen(valbuf), src, strlen(src));
(void)memcpy(src, valbuf, strlen(valbuf)); (void)memcpy(src, valbuf, strlen(valbuf));

View File

@ -17,7 +17,7 @@ typedef struct
void display_main(Sheet *cursheet); void display_main(Sheet *cursheet);
void display_init(Sheet *cursheet, int always_redraw); void display_init(Sheet *cursheet, int always_redraw);
void display_end(void); void display_end(void);
void redraw_cell(Sheet *sheet, int x, int y, int z); void redraw_cell(Sheet *sheet, const Location at);
void redraw_sheet(Sheet *sheet); void redraw_sheet(Sheet *sheet);
const char *line_file(const char *file, const char *pattern, const char *title, int create); const char *line_file(const char *file, const char *pattern, const char *title, int create);
int line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt, size_t *x, size_t *offx); int line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt, size_t *x, size_t *offx);

4
eval.c
View File

@ -84,15 +84,17 @@ void tvecfree(Token **tvec)
free(tvec); free(tvec);
} }
/*}}}*/ /*}}}*/
/* tveclen -- return length of a vector of pointer to tokens */ /*{{{*/ /* tveclen -- return length of a vector of pointer to tokens */ /*{{{*/
size_t tveclen(Token **tvec) size_t tveclen(Token **tvec)
{ {
size_t len; size_t len;
if (tvec == EMPTY_TVEC) return 0; if (tvec == EMPTY_TVEC) return 0;
for (len=1; *tvec != NULLTOKEN; ++len,++tvec); for (len = 0; *tvec != NULLTOKEN; ++len,++tvec);
return len; return len;
} }
/*}}}*/ /*}}}*/
/* tadd -- + operator */ /*{{{*/ /* tadd -- + operator */ /*{{{*/
Token tadd(Token l, Token r) Token tadd(Token l, Token r)
{ {

View File

@ -104,22 +104,22 @@ do_callback(CONTEXT_NONE, 0, 0);} {}
} { } {
code {return cursheet;} {} code {return cursheet;} {}
} }
Function {draw_cell(TableContext context, int R, int C, int X, int Y, int W, int H)} {open return_type void Function {draw_cell(TableContext context, int R, int C, int xx, int yy, int W, int H)} {open return_type void
} { } {
code {char s[1024]; code {char s[1024];
//printf("DRAW: %i @%i,%i - (%i,%i) %ix%i\\n", context, C,R, X,Y, W,H); //printf("DRAW: %i @%i,%i - (%i,%i) %ix%i\\n", context, C,R, xx,yy, W,H);
switch (context) { switch (context) {
case CONTEXT_ENDPAGE: case CONTEXT_ENDPAGE:
W = X-x()-2; W = xx-x()-2;
H = Y-y()-2; H = yy-y()-2;
X = x()+2; xx = x()+2;
Y = y()+2; yy = y()+2;
fl_font(FL_HELVETICA | FL_BOLD, 14); fl_font(FL_HELVETICA | FL_BOLD, 14);
fl_push_clip(X, Y, W, H); fl_push_clip(xx, yy, W, H);
fl_draw_box(FL_DIAMOND_UP_BOX, X, Y, W, H, col_header_color()); fl_draw_box(FL_DIAMOND_UP_BOX, xx, yy, W, H, col_header_color());
fl_color(FL_INACTIVE_COLOR); fl_color(FL_INACTIVE_COLOR);
sprintf(s, "%d", cursheet->curz); sprintf(s, "%d", cursheet->cur[Z]);
fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER); fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER);
fl_pop_clip(); fl_pop_clip();
break; break;
@ -130,54 +130,59 @@ case CONTEXT_STARTPAGE:
case CONTEXT_COL_HEADER: case CONTEXT_COL_HEADER:
fl_font(FL_HELVETICA | FL_BOLD, 14); fl_font(FL_HELVETICA | FL_BOLD, 14);
fl_push_clip(X, Y, W, H); fl_push_clip(xx, yy, W, H);
fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, col_header_color()); fl_draw_box(FL_THIN_UP_BOX, xx, yy, W, H, col_header_color());
fl_color(FL_FOREGROUND_COLOR); fl_color(FL_FOREGROUND_COLOR);
sprintf(s, "%d", C); sprintf(s, "%d", C);
fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER); fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER);
fl_pop_clip(); fl_pop_clip();
return; return;
case CONTEXT_ROW_HEADER: case CONTEXT_ROW_HEADER:
fl_font(FL_HELVETICA | FL_BOLD, 14); fl_font(FL_HELVETICA | FL_BOLD, 14);
fl_push_clip(X, Y, W, H); fl_push_clip(xx, yy, W, H);
fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, row_header_color()); fl_draw_box(FL_THIN_UP_BOX, xx, yy, W, H, row_header_color());
fl_color(FL_FOREGROUND_COLOR); fl_color(FL_FOREGROUND_COLOR);
sprintf(s, "%d", R); sprintf(s, "%d", R);
fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER); fl_draw(s, xx, yy, W, H, FL_ALIGN_CENTER);
fl_pop_clip(); fl_pop_clip();
return; return;
case CONTEXT_CELL: { case CONTEXT_CELL: {
while (SHADOWED(cursheet, C, R, cursheet->curz)) X -= W = col_width(--C); while (SHADOWEDC(cursheet, C, R, cursheet->cur[Z])) xx -= W = col_width(--C);
int x = C+1; int x = C+1;
while (SHADOWED(cursheet,x,R,cursheet->curz)) W += col_width(x), x++; while (SHADOWEDC(cursheet,x,R,cursheet->cur[Z])) W += col_width(x), x++;
fl_push_clip(X, Y, W, H); fl_push_clip(xx, yy, W, H);
bool selected = false; bool selected = false;
if (cursheet->mark1x >= 0) { MarkState ms = getmarkstate(cursheet);
int x1 = cursheet->mark1x, x2 = cursheet->mark2x, y1 = cursheet->mark1y, y2 = cursheet->mark2y, z1 = cursheet->mark1z, z2 = cursheet->mark2z; Location test;
posorder(&x1, &x2); test[X] = C; test[Y] = R; test[Z] = cursheet->cur[Z];
posorder(&y1, &y2); if (ms != UNMARKED)
posorder(&z1, &z2); selected = loc_in_box(test, cursheet->mark1, cursheet->mark2);
selected = cursheet->mark1x >= 0 && C >= x1 && C <= x2 && R >= y1 && R <= y2 && cursheet->curz >= z1 && cursheet->curz <= z2; bool iscurrent = C == cursheet->cur[X] && R == cursheet->cur[Y];
} fl_draw_box(iscurrent ? FL_BORDER_BOX : FL_THIN_DOWN_BOX, xx, yy, W, H,
fl_draw_box(C == cursheet->curx && R == cursheet->cury?FL_BORDER_BOX:FL_THIN_DOWN_BOX, X, Y, W, H, selected?FL_SELECTION_COLOR:FL_BACKGROUND2_COLOR); selected ? FL_SELECTION_COLOR : FL_BACKGROUND2_COLOR);
if (Fl::focus() == this && C == cursheet->curx && R == cursheet->cury) draw_focus(FL_BORDER_BOX, X, Y, W, H); if (Fl::focus() == this && iscurrent)
draw_focus(FL_BORDER_BOX, xx, yy, W, H);
fl_pop_clip(); fl_pop_clip();
fl_push_clip(X+3, Y+3, W-6, H-6); Cell *cell = safe_cell_at(cursheet, test);
fl_color(FL_FOREGROUND_COLOR);
fl_font(FL_HELVETICA | (isbold(cursheet, C, R, cursheet->curz)? FL_BOLD:0), 14); fl_push_clip(xx+3, yy+3, W-6, H-6);
fl_color(FL_FOREGROUND_COLOR);
fl_font(FL_HELVETICA | (isbold(cell) ? FL_BOLD : 0), 14);
printvalue(s, sizeof(s), 0, 0, getscientific(cell),
getprecision(cell), cursheet, test);
printvalue(s, sizeof(s), 0, 0, getscientific(cursheet, C, R, cursheet->curz), getprecision(cursheet, C, R, cursheet->curz), cursheet, C, R, cursheet->curz);
int ww = 0, hh = 0; int ww = 0, hh = 0;
fl_measure(s, ww, hh, 0); fl_measure(s, ww, hh, 0);
if (ww > W-6) for (int i = 0; s[i]; i++) s[i] = '\#'; if (ww > W-6) for (int i = 0; s[i]; i++) s[i] = '\#';
int adj = getadjust(cursheet, C, R, cursheet->curz); int adj = getadjust(cell);
fl_draw(s, X+3, Y+3, W-6, H-6, adj == RIGHT?FL_ALIGN_RIGHT:adj == LEFT?FL_ALIGN_LEFT:FL_ALIGN_CENTER); fl_draw(s, xx+3, yy+3, W-6, H-6, adj == RIGHT?FL_ALIGN_RIGHT:adj == LEFT?FL_ALIGN_LEFT:FL_ALIGN_CENTER);
if (underlined(cursheet, C, R, cursheet->curz)) fl_xyline(X, Y+H-7, X+W); if (underlined(cell)) fl_xyline(xx, yy+H-7, xx+W);
fl_pop_clip(); fl_pop_clip();
return; return;
@ -200,12 +205,13 @@ if (cursheet->dimy > rows()) rows(cursheet->dimy);
adjust_outside(); adjust_outside();
for (int x = 0; x < cursheet->dimx; x++) { for (int x = 0; x < cursheet->dimx; x++) {
int w = columnwidth(cursheet, x, cursheet->curz)*10; int w = columnwidth(cursheet, x, cursheet->cur[Z])*10;
if (col_width(x) != w) col_width(x, w); if (col_width(x) != w) col_width(x, w);
} }
col_position(cursheet->offx); col_position(cursheet->offx);
row_position(cursheet->offy); row_position(cursheet->offy);
set_selection(cursheet->cury, cursheet->curx, cursheet->cury, cursheet->curx); set_selection(cursheet->cur[Y], cursheet->cur[X],
cursheet->cur[Y], cursheet->cur[X]);
move_cursor(0,0); move_cursor(0,0);
updating = false;} {} updating = false;} {}
} }
@ -218,12 +224,12 @@ updating = true;
get_selection(y1, x1, y2, x2); get_selection(y1, x1, y2, x2);
if (x1 != x2 || y1 != y2) { if (x1 != x2 || y1 != y2) {
cursheet->mark1x = x1; cursheet->mark1[X] = x1;
cursheet->mark1y = y1; cursheet->mark1[Y] = y1;
cursheet->mark2x = x2; cursheet->mark2[X] = x2;
cursheet->mark2y = y2; cursheet->mark2[Y] = y2;
cursheet->mark1z = cursheet->mark2z = cursheet->curz; cursheet->mark1[Z] = cursheet->mark2[Z] = cursheet->cur[Z];
cursheet->marking = 0; cursheet->marking = MARKED;
} }
moveto(cursheet, current_col, current_row, -1); moveto(cursheet, current_col, current_row, -1);
visible_cells(cursheet->offy, cursheet->maxy, cursheet->offx, cursheet->maxx); visible_cells(cursheet->offy, cursheet->maxy, cursheet->offx, cursheet->maxx);
@ -231,10 +237,11 @@ cursheet->maxx -= cursheet->offx;
cursheet->maxy -= cursheet->offy; cursheet->maxy -= cursheet->offy;
if (is_interactive_resize()) { if (is_interactive_resize()) {
for (int C = 0; C < cursheet->dimx; C++) { for (int C = 0; C < cursheet->dimx; C++) {
int w = (col_width(C) + 5)/10; int w = (col_width(C) + 5)/10;
if (w != columnwidth(cursheet, C, cursheet->curz)) setwidth(cursheet, C, cursheet->curz, w); if (w != columnwidth(cursheet, C, cursheet->cur[Z]))
} setwidth(cursheet, C, cursheet->cur[Z], w);
}
} }
@ -259,19 +266,22 @@ updating = false;
case FL_Tab: if (shift) { k = K_CLOCK; break; } case FL_Tab: if (shift) { k = K_CLOCK; break; }
case FL_Enter: case FL_Enter:
case FL_KP_Enter: k = alt?K_MENTER:K_ENTER; break; case FL_KP_Enter: k = alt?K_MENTER:K_ENTER; break;
case 'c': if (ctrl) { do_mark(cursheet, 2); cut = false; k = K_NONE; } break; case 'c': if (ctrl) { do_mark(cursheet, GET_MARK_CUR); cut = false; k = K_NONE; } break;
case 'v': k = ctrl?(cut?BLOCK_MOVE:BLOCK_COPY):(Key)'v'; break; case 'v': if (ctrl) { do_mark(cursheet, MARKED);
case 'x': if (ctrl) { do_mark(cursheet, 2); cut = true, k = K_NONE; } break; k = cut ? BLOCK_MOVE : BLOCK_COPY;
}
break;
case 'x': if (ctrl) { do_mark(cursheet, GET_MARK_CUR); cut = true, k = K_NONE; } break;
case 'r': if (ctrl) k = K_RECALC; break; case 'r': if (ctrl) k = K_RECALC; break;
case 'd': if (ctrl && shift && debug_level > 0) k = K_DUMPCELL; 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_Insert: if (ctrl) { do_mark(cursheet, GET_MARK_CUR); 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_Delete: if (shift) { do_mark(cursheet, GET_MARK_CUR); cut = true; } k = shift?K_NONE:BLOCK_CLEAR; break;
case FL_Home: k = ctrl?K_FIRSTL:shift?K_FSHEET:K_HOME; break; case FL_Home: k = ctrl?K_FIRSTL:shift?K_FSHEET:K_HOME; break;
case FL_End: k = ctrl?K_LASTL:shift?K_LSHEET:K_END; break; case FL_End: k = ctrl?K_LASTL:shift?K_LSHEET:K_END; break;
case FL_Up: if (shift && !cursheet->marking) do_mark(cursheet, 1); k = ctrl?K_PPAGE:K_UP; break; case FL_Up: if (shift) do_mark(cursheet, MARKING); k = ctrl?K_PPAGE:K_UP; break;
case FL_Down: if (shift && !cursheet->marking) do_mark(cursheet, 1); k = ctrl?K_NPAGE:K_DOWN; break; case FL_Down: if (shift) do_mark(cursheet, MARKING); k = ctrl?K_NPAGE:K_DOWN; break;
case FL_Right: if (shift && !cursheet->marking) do_mark(cursheet, 1); k = ctrl?K_FPAGE:K_RIGHT; break; case FL_Right: if (shift) do_mark(cursheet, MARKING); k = ctrl?K_FPAGE:K_RIGHT; break;
case FL_Left: if (shift && !cursheet->marking) do_mark(cursheet, 1); k = ctrl?K_BPAGE:K_LEFT; break; case FL_Left: if (shift) do_mark(cursheet, MARKING); k = ctrl?K_BPAGE:K_LEFT; break;
case FL_Page_Down: k = shift?K_NSHEET:ctrl?K_LASTL :K_NPAGE; break; case FL_Page_Down: k = shift?K_NSHEET:ctrl?K_LASTL :K_NPAGE; break;
case FL_Page_Up: k = shift?K_PSHEET:ctrl?K_FIRSTL:K_PPAGE; break; case FL_Page_Up: k = shift?K_PSHEET:ctrl?K_FIRSTL:K_PPAGE; break;
} }
@ -557,17 +567,23 @@ if (Fl::focus() && (Fl::focus() != table || enterkey || Fl::event_key(FL_Escape)
callback {Sheet *sheet = table->sheet(); callback {Sheet *sheet = table->sheet();
table->update_sheet(); table->update_sheet();
const char *label = getlabel(sheet,sheet->curx,sheet->cury,sheet->curz); const char *label = getlabel(curcell(sheet));
char moveonly=sheet->moveonly ? *_("V") : *_("E"); char moveonly=sheet->moveonly ? *_("V") : *_("E");
char buf[1024]; char buf[1024];
if (*label == 0) snprintf(buf, sizeof(buf), "%c @@(%d,%d,%d)=", moveonly, sheet->curx, sheet->cury, sheet->curz); if (*label == 0)
snprintf(buf, sizeof(buf), "%c @@(%d,%d,%d)=", moveonly,
sheet->cur[X], sheet->cur[Y], sheet->cur[Z]);
else snprintf(buf, sizeof(buf), "%c @@(%s)=", moveonly, label); else snprintf(buf, sizeof(buf), "%c @@(%s)=", moveonly, label);
if (moveonly && table->callback_context() == TeapotTable::ACTION) { if (moveonly && table->callback_context() == TeapotTable::ACTION) {
char valbuf[1024] = ""; char valbuf[1024] = "";
if (Fl::event_key() == 'p' || Fl::event_button1()) sprintf(valbuf, "(%i,%i,%i)", sheet->curx, sheet->cury, sheet->curz); if (Fl::event_key() == 'p' || Fl::event_button1())
else if (Fl::event_key() == 'v') printvalue(valbuf,sizeof(valbuf),0,1,getscientific(sheet,sheet->curx,sheet->cury,sheet->curz),-1,sheet,sheet->curx,sheet->cury,sheet->curz); sprintf(valbuf, "(%i,%i,%i)",
sheet->cur[X], sheet->cur[Y], sheet->cur[Z]);
else if (Fl::event_key() == 'v')
printvalue(valbuf, sizeof(valbuf), 0, 1,
getscientific(curcell(sheet)), -1, sheet, sheet->cur);
else if (Fl::event_key(FL_Tab)) line_input->take_focus(); else if (Fl::event_key(FL_Tab)) line_input->take_focus();
if (valbuf[0]) { if (valbuf[0]) {
line_input->insert(valbuf); line_input->insert(valbuf);
@ -578,37 +594,41 @@ if (moveonly && table->callback_context() == TeapotTable::ACTION) {
char *err; char *err;
char val[1024]; char val[1024];
if ((err = geterror(sheet, sheet->curx, sheet->cury, sheet->curz))) { if ((err = geterror(sheet, sheet->cur))) {
strncpy(val,err,sizeof(val)); strncpy(val,err,sizeof(val));
free(err); free(err);
val[sizeof(val)-1] = 0; val[sizeof(val)-1] = 0;
} else { } else {
print(val,sizeof(val),0,1,getscientific(sheet,sheet->curx,sheet->cury,sheet->curz),-1,getcont(sheet,sheet->curx,sheet->cury,sheet->curz,0)); print(val, sizeof(val), 0, 1, getscientific(curcell(sheet)), -1,
if (getcont(sheet,sheet->curx,sheet->cury,sheet->curz,1)) { getcont(curcell(sheet), BASE));
snprintf(val+strlen(val),sizeof(val)-strlen(val)," -> "); Token **iter = getcont(curcell(sheet), ITERATIVE);
print(val+strlen(val),sizeof(val)-strlen(val),0,1,getscientific(sheet,sheet->curx,sheet->cury,sheet->curz),-1,getcont(sheet,sheet->curx,sheet->cury,sheet->curz,1)); if (iter != EMPTY_TVEC) {
snprintf(val+strlen(val),sizeof(val)-strlen(val)," -> ");
print(val+strlen(val), sizeof(val)-strlen(val), 0, 1,
getscientific(curcell(sheet)), -1, iter);
} }
} }
line_edit(sheet, val, 0, buf, 0, 0); line_edit(sheet, val, 0, buf, 0, 0);
int x = sheet->curx, y = sheet->cury, z = sheet->curz; Cell *cell = curcell(sheet);
int adj = getadjust(sheet, x, y, z); int adj = getadjust(cell);
if (adj == LEFT) left->setonly(); if (adj == LEFT) left->setonly();
else if (adj == RIGHT) right->setonly(); else if (adj == RIGHT) right->setonly();
else if (adj == CENTER) center->setonly(); else if (adj == CENTER) center->setonly();
if (shadowed(sheet, x+1, y, z)) shadow->set(); if (SHADOWEDC(sheet, sheet->cur[X]+1, sheet->cur[Y], sheet->cur[Z]))
shadow->set();
else shadow->clear(); else shadow->clear();
if (::transparent(sheet, x, y, z)) transparent->set(); if (::transparent(cell)) transparent->set();
else transparent->clear(); else transparent->clear();
if (locked(sheet, x, y, z)) lock->set(); if (locked(cell)) lock->set();
else lock->clear(); else lock->clear();
if (ignored(sheet, x, y, z)) ignore->set(); if (ignored(cell)) ignore->set();
else ignore->clear(); else ignore->clear();
if (isbold(sheet, x, y, z)) bold->set(); if (isbold(cell)) bold->set();
else bold->clear(); else bold->clear();
if (underlined(sheet, x, y, z)) underline->set(); if (underlined(cell)) underline->set();
else underline->clear(); else underline->clear();
if (getscientific(sheet, x, y, z)) sci->set(); if (getscientific(cell)) sci->set();
else sci->clear();} else sci->clear();}
protected xywh {0 50 800 525} box DOWN_FRAME labeltype NO_LABEL resizable protected xywh {0 50 800 525} box DOWN_FRAME labeltype NO_LABEL resizable
code0 {table->sheet(sheet);} code0 {table->sheet(sheet);}
@ -758,7 +778,7 @@ t->update_table();
t->redraw();} {} t->redraw();} {}
} }
Function {redraw_cell(Sheet *sheet, int x, int y, int z)} {C return_type void Function {redraw_cell(Sheet *sheet, const Location /* at */)} {C return_type void
} { } {
code {redraw_sheet(sheet);} {} code {redraw_sheet(sheet);} {}
} }

195
func.c
View File

@ -303,11 +303,15 @@ static double deg2rad(double x)
} }
/*}}}*/ /*}}}*/
#define INTPATIBLE(t) (t.type == INT || t.type == EMPTY)
/* @ */ /*{{{*/ /* @ */ /*{{{*/
static Token at_func(int argc, const Token argv[]) static Token at_func(int argc, const Token argv[])
{ {
/* variables */ /*{{{*/ /* variables */ /*{{{*/
Token result; Token result;
Location tmp;
Dimensions dim;
/*}}}*/ /*}}}*/
/* asserts */ /*{{{*/ /* asserts */ /*{{{*/
@ -315,23 +319,36 @@ static Token at_func(int argc, const Token argv[])
/*}}}*/ /*}}}*/
if (argc==0) if (argc==0)
/* return value at current location */ /*{{{*/ /* return value at current location */ /*{{{*/
return (getvalue(upd_sheet,upd_x,upd_y,upd_z)); return (getvalue(upd_sheet, upd_l));
/*}}}*/ /*}}}*/
if (argc==1 && argv[0].type==LOCATION) if (argc==1 && argv[0].type==LOCATION)
/* return value at location pointed to by argument */ /*{{{*/ /* return value at location pointed to by argument */ /*{{{*/
return (getvalue(upd_sheet,argv[0].u.location[0],argv[0].u.location[1],argv[0].u.location[2])); return (getvalue(upd_sheet, argv[0].u.location));
/*}}}*/ /*}}}*/
else if (argc==1 && (argv[0].type==INT || argv[0].type==EMPTY)) LOCATION_GETS(tmp, upd_l);
if (argc==1 && (argv[0].type==INT || argv[0].type==EMPTY))
/* return value at x on current y,z */ /*{{{*/ /* return value at x on current y,z */ /*{{{*/
return (getvalue(upd_sheet,argv[0].type==INT ? argv[0].u.integer : upd_x,upd_y,upd_z)); {
if (argv[0].type == INT) tmp[X] = argv[0].u.integer;
return getvalue(upd_sheet, tmp);
}
/*}}}*/ /*}}}*/
else if (argc==2 && (argv[0].type==INT || argv[0].type==EMPTY) && (argv[1].type==INT || argv[1].type==EMPTY)) if (argc==2 && INTPATIBLE(argv[0]) && INTPATIBLE(argv[1]))
/* return value at x,y on current z */ /*{{{*/ /* return value at x,y on current z */ /*{{{*/
return (getvalue(upd_sheet,argv[0].type==INT ? argv[0].u.integer : upd_x,argv[1].type==INT ? argv[1].u.integer : upd_y,upd_z)); {
if (argv[0].type == INT) tmp[X] = argv[0].u.integer;
if (argv[1].type == INT) tmp[Y] = argv[1].u.integer;
return getvalue(upd_sheet, tmp);
}
/*}}}*/ /*}}}*/
else if (argc==3 && (argv[0].type==INT || argv[0].type==EMPTY) && (argv[1].type==INT || argv[1].type==EMPTY) && (argv[2].type==INT || argv[2].type==EMPTY)) if (argc==3 && INTPATIBLE(argv[0]) && INTPATIBLE(argv[1]) &&
INTPATIBLE(argv[2]))
/* return value at x,y,z */ /*{{{*/ /* return value at x,y,z */ /*{{{*/
return (getvalue(upd_sheet,argv[0].type==INT ? argv[0].u.integer : upd_x,argv[1].type==INT ? argv[1].u.integer : upd_y,argv[2].type==INT ? argv[2].u.integer : upd_z)); {
for (dim = X; dim < HYPER; ++dim)
if (argv[dim].type == INT) tmp[dim] = argv[dim].u.integer;
return getvalue(upd_sheet, tmp);
}
/*}}}*/ /*}}}*/
else else
/* return error */ /*{{{*/ /* return error */ /*{{{*/
@ -343,50 +360,48 @@ static Token at_func(int argc, const Token argv[])
/*}}}*/ /*}}}*/
} }
/*}}}*/ /*}}}*/
/* & */ /*{{{*/ /* & */ /*{{{*/
static Token adr_func(int argc, const Token argv[]) static Token adr_func(int argc, const Token argv[])
{ {
/* variables */ /*{{{*/ /* variables */ /*{{{*/
Token result; Token result;
Dimensions dim;
/*}}}*/ /*}}}*/
/* asserts */ /*{{{*/ /* asserts */ /*{{{*/
assert(argv!=(Token*)0); assert(argv != (Token*)0);
/*}}}*/ /*}}}*/
if (argc==3 && (argv[0].type==INT || argv[0].type==EMPTY) && (argv[1].type==INT || argv[1].type==EMPTY) && (argv[2].type==INT || argv[2].type==EMPTY))
LOCATION_GETS(result.u.location, upd_l);
if (argc==3 && INTPATIBLE(argv[0]) && INTPATIBLE(argv[1]) &&
INTPATIBLE(argv[2]))
/* result is location of the given position */ /*{{{*/ /* result is location of the given position */ /*{{{*/
{ {
result.type=LOCATION; result.type=LOCATION;
result.u.location[0]=(argv[0].type==INT ? argv[0].u.integer : upd_x); for (dim = X; dim < HYPER; ++dim)
result.u.location[1]=(argv[1].type==INT ? argv[1].u.integer : upd_y); if (argv[dim].type == INT) result.u.location[dim] = argv[dim].u.integer;
result.u.location[2]=(argv[2].type==INT ? argv[2].u.integer : upd_z);
} }
/*}}}*/ /*}}}*/
else if (argc==2 && (argv[0].type==INT || argv[0].type==EMPTY) && (argv[1].type==INT || argv[1].type==EMPTY)) else if (argc==2 && INTPATIBLE(argv[0]) && INTPATIBLE(argv[1]))
/* result is location of the given position in the current z layer */ /*{{{*/ /* result is location of the given position in the current z layer */ /*{{{*/
{ {
result.type=LOCATION; result.type=LOCATION;
result.u.location[0]=(argv[0].type==INT ? argv[0].u.integer : upd_x); for (dim = X; dim <= Y; ++dim)
result.u.location[1]=(argv[1].type==INT ? argv[1].u.integer : upd_y); if (argv[dim].type == INT) result.u.location[dim] = argv[dim].u.integer;
result.u.location[2]=upd_z;
} }
/*}}}*/ /*}}}*/
else if (argc==1 && (argv[0].type==INT || argv[0].type==EMPTY)) else if (argc==1 && INTPATIBLE(argv[0]))
/* result is location of the given position in the current y,z layer */ /*{{{*/ /* result is location of the given position in the current y,z layer */ /*{{{*/
{ {
result.type=LOCATION; result.type=LOCATION;
result.u.location[0]=(argv[0].type==INT ? argv[0].u.integer : upd_x); if (argv[0].type == INT) result.u.location[X] = argv[0].u.integer;
result.u.location[1]=upd_y;
result.u.location[2]=upd_z;
} }
/*}}}*/ /*}}}*/
else if (argc==0) else if (argc==0)
/* result is location of the current position */ /*{{{*/ /* result is location of the current position */ /*{{{*/
{ {
result.type=LOCATION; result.type=LOCATION;
result.u.location[0]=upd_x;
result.u.location[1]=upd_y;
result.u.location[2]=upd_z;
} }
/*}}}*/ /*}}}*/
else else
@ -399,6 +414,7 @@ static Token adr_func(int argc, const Token argv[])
return result; return result;
} }
/*}}}*/ /*}}}*/
/* x */ /*{{{*/ /* x */ /*{{{*/
static Token x_func(int argc, const Token argv[]) static Token x_func(int argc, const Token argv[])
{ {
@ -409,15 +425,15 @@ static Token x_func(int argc, const Token argv[])
if (argc==0) if (argc==0)
/* result is currently updated x position */ /*{{{*/ /* result is currently updated x position */ /*{{{*/
{ {
result.type=INT; result.type = INT;
result.u.integer=upd_x; result.u.integer = upd_l[X];
} }
/*}}}*/ /*}}}*/
else if (argc==1 && argv[0].type==LOCATION) else if (argc==1 && argv[0].type==LOCATION)
/* return x component of location */ /*{{{*/ /* return x component of location */ /*{{{*/
{ {
result.type=INT; result.type = INT;
result.u.integer=argv[0].u.location[0]; result.u.integer = argv[0].u.location[X];
} }
/*}}}*/ /*}}}*/
else else
@ -430,6 +446,7 @@ static Token x_func(int argc, const Token argv[])
return result; return result;
} }
/*}}}*/ /*}}}*/
/* y */ /*{{{*/ /* y */ /*{{{*/
static Token y_func(int argc, const Token argv[]) static Token y_func(int argc, const Token argv[])
{ {
@ -440,15 +457,15 @@ static Token y_func(int argc, const Token argv[])
if (argc==0) if (argc==0)
/* result is currently updated y position */ /*{{{*/ /* result is currently updated y position */ /*{{{*/
{ {
result.type=INT; result.type = INT;
result.u.integer=upd_y; result.u.integer = upd_l[Y];
} }
/*}}}*/ /*}}}*/
else if (argc==1 && argv[0].type==LOCATION) else if (argc==1 && argv[0].type==LOCATION)
/* return y component of location */ /*{{{*/ /* return y component of location */ /*{{{*/
{ {
result.type=INT; result.type = INT;
result.u.integer=argv[0].u.location[1]; result.u.integer = argv[0].u.location[Y];
} }
/*}}}*/ /*}}}*/
else else
@ -461,6 +478,7 @@ static Token y_func(int argc, const Token argv[])
return result; return result;
} }
/*}}}*/ /*}}}*/
/* z */ /*{{{*/ /* z */ /*{{{*/
static Token z_func(int argc, const Token argv[]) static Token z_func(int argc, const Token argv[])
{ {
@ -471,15 +489,15 @@ static Token z_func(int argc, const Token argv[])
if (argc==0) if (argc==0)
/* result is currently updated z position */ /*{{{*/ /* result is currently updated z position */ /*{{{*/
{ {
result.type=INT; result.type = INT;
result.u.integer=upd_z; result.u.integer = upd_l[Z];
} }
/*}}}*/ /*}}}*/
else if (argc==1 && argv[0].type==LOCATION) else if (argc == 1 && argv[0].type == LOCATION)
/* return z component of location */ /*{{{*/ /* return z component of location */ /*{{{*/
{ {
result.type=INT; result.type = INT;
result.u.integer=argv[0].u.location[2]; result.u.integer = argv[0].u.location[Z];
} }
/*}}}*/ /*}}}*/
else else
@ -492,6 +510,7 @@ static Token z_func(int argc, const Token argv[])
return result; return result;
} }
/*}}}*/ /*}}}*/
/* e */ /*{{{*/ /* e */ /*{{{*/
static Token e_func(int argc, const Token argv[]) static Token e_func(int argc, const Token argv[])
{ {
@ -534,8 +553,10 @@ static Token eval_func(int argc, const Token argv[])
{ {
Token **contents; Token **contents;
contents=getcont(upd_sheet,argv[0].u.location[0],argv[0].u.location[1],argv[0].u.location[2],2); contents = EMPTY_TVEC;
if (contents==(Token**)0) result.type=EMPTY; if (LOC_WITHIN(upd_sheet, argv[0].u.location))
contents = getcont(CELL_AT(upd_sheet,argv[0].u.location), CONTINGENT);
if (contents == EMPTY_TVEC) result.type = EMPTY;
else result=eval(contents); else result=eval(contents);
} }
/*}}}*/ /*}}}*/
@ -550,6 +571,7 @@ static Token eval_func(int argc, const Token argv[])
return result; return result;
} }
/*}}}*/ /*}}}*/
/* error */ /*{{{*/ /* error */ /*{{{*/
static Token error_func(int argc, const Token argv[]) static Token error_func(int argc, const Token argv[])
{ {
@ -577,23 +599,28 @@ static Token string_func(int argc, const Token argv[])
{ {
/* variables */ /*{{{*/ /* variables */ /*{{{*/
Token result; Token result;
Cell *cell;
char *buf; char *buf;
char staticbuf[4096];
size_t size; size_t size;
/*}}}*/ /*}}}*/
if (argc==1 && argv[0].type==LOCATION) /* cell to string */ /*{{{*/ if (argc==1 && argv[0].type==LOCATION) /* cell to string */ /*{{{*/
{ {
buf=(char*)0;
size=0;
do
{
if (buf!=(char*)0) free(buf);
size+=16;
buf=malloc(size);
printvalue(buf,size,0,0,getscientific(upd_sheet,argv[0].u.location[0],argv[0].u.location[1],argv[0].u.location[2]),getprecision(upd_sheet,argv[0].u.location[0],argv[0].u.location[1],argv[0].u.location[2]),upd_sheet,argv[0].u.location[0],argv[0].u.location[1],argv[0].u.location[2]);
} while (strlen(buf)==size-1);
result.type=STRING; result.type=STRING;
result.u.string=buf; if (LOC_WITHIN(upd_sheet, argv[0].u.location))
{
cell = CELL_AT(upd_sheet, argv[0].u.location);
printvalue(staticbuf, sizeof(staticbuf), 0, 0, getscientific(cell),
getprecision(cell), upd_sheet, argv[0].u.location);
result.u.string = malloc(strlen(staticbuf) + 1);
strcpy(result.u.string, staticbuf);
}
else
{
result.u.string = malloc(1);
result.u.string[0] = '\0';
}
} }
/*}}}*/ /*}}}*/
else if (argc==1 && argv[0].type==FLOAT) /* float to string */ /*{{{*/ else if (argc==1 && argv[0].type==FLOAT) /* float to string */ /*{{{*/
@ -648,7 +675,7 @@ static Token sum_func(int argc, const Token argv[])
if (argc==2 && argv[0].type==LOCATION && argv[1].type==LOCATION) /* result is sum */ /*{{{*/ if (argc==2 && argv[0].type==LOCATION && argv[1].type==LOCATION) /* result is sum */ /*{{{*/
{ {
/* variables */ /*{{{*/ /* variables */ /*{{{*/
int x,y,z; Location w;
int x1,y1,z1; int x1,y1,z1;
int x2,y2,z2; int x2,y2,z2;
Token tmp; Token tmp;
@ -658,13 +685,13 @@ static Token sum_func(int argc, const Token argv[])
y1=argv[0].u.location[1]; y2=argv[1].u.location[1]; posorder(&y1,&y2); y1=argv[0].u.location[1]; y2=argv[1].u.location[1]; posorder(&y1,&y2);
z1=argv[0].u.location[2]; z2=argv[1].u.location[2]; posorder(&z1,&z2); z1=argv[0].u.location[2]; z2=argv[1].u.location[2]; posorder(&z1,&z2);
result.type=EMPTY; result.type=EMPTY;
for (x=x1; x<=x2; ++x) for (w[X]=x1; w[X]<=x2; ++(w[X]))
for (y=y1; y<=y2; ++y) for (w[Y]=y1; w[Y]<=y2; ++(w[Y]))
for (z=z1; z<=z2; ++z) for (w[Z]=z1; w[Z]<=z2; ++(w[Z]))
{ {
Token t; Token t;
tmp=tadd(result,t=getvalue(upd_sheet,x,y,z)); tmp = tadd(result, t=getvalue(upd_sheet,w));
tfree(&t); tfree(&t);
tfree(&result); tfree(&result);
result=tmp; result=tmp;
@ -692,7 +719,7 @@ static Token n_func(int argc, const Token argv[])
/* result is number of elements */ /*{{{*/ /* result is number of elements */ /*{{{*/
{ {
/* variables */ /*{{{*/ /* variables */ /*{{{*/
int x,y,z; Location w;
int x1,y1,z1; int x1,y1,z1;
int x2,y2,z2; int x2,y2,z2;
Token tmp; Token tmp;
@ -703,16 +730,16 @@ static Token n_func(int argc, const Token argv[])
y1=argv[0].u.location[1]; y2=argv[1].u.location[1]; posorder(&y1,&y2); y1=argv[0].u.location[1]; y2=argv[1].u.location[1]; posorder(&y1,&y2);
z1=argv[0].u.location[2]; z2=argv[1].u.location[2]; posorder(&z1,&z2); z1=argv[0].u.location[2]; z2=argv[1].u.location[2]; posorder(&z1,&z2);
n=0; n=0;
for (x=x1; x<=x2; ++x) for (w[X]=x1; w[X]<=x2; ++(w[X]))
for (y=y1; y<=y2; ++y) for (w[Y]=y1; w[Y]<=y2; ++(w[Y]))
for (z=z1; z<=z2; ++z) for (w[Z]=z1; w[Z]<=z2; ++(w[Z]))
{ {
tmp=getvalue(upd_sheet,x,y,z); tmp = getvalue(upd_sheet, w);
if (tmp.type!=EMPTY) ++n; if (tmp.type != EMPTY) ++n;
tfree(&tmp); tfree(&tmp);
} }
result.type=INT; result.type = INT;
result.u.integer=n; result.u.integer = n;
} }
/*}}}*/ /*}}}*/
else else
@ -725,6 +752,7 @@ static Token n_func(int argc, const Token argv[])
return result; return result;
} }
/*}}}*/ /*}}}*/
/* int */ /*{{{*/ /* int */ /*{{{*/
static Token int_func(int argc, const Token argv[]) static Token int_func(int argc, const Token argv[])
{ {
@ -888,14 +916,14 @@ static Token minmax_func(int argc, const Token argv[], int min)
{ {
/* variables */ /*{{{*/ /* variables */ /*{{{*/
Token result; Token result;
int resultx,resulty,resultz; Location minloc;
/*}}}*/ /*}}}*/
if (argc==2 && argv[0].type==LOCATION && argv[1].type==LOCATION) if (argc==2 && argv[0].type==LOCATION && argv[1].type==LOCATION)
/* result is min/max */ /*{{{*/ /* result is min/max */ /*{{{*/
{ {
/* variables */ /*{{{*/ /* variables */ /*{{{*/
int x,y,z; Location w;
int x1,y1,z1; int x1,y1,z1;
int x2,y2,z2; int x2,y2,z2;
Token tmp; Token tmp;
@ -904,28 +932,27 @@ static Token minmax_func(int argc, const Token argv[], int min)
x1=argv[0].u.location[0]; x2=argv[1].u.location[0]; posorder(&x1,&x2); x1=argv[0].u.location[0]; x2=argv[1].u.location[0]; posorder(&x1,&x2);
y1=argv[0].u.location[1]; y2=argv[1].u.location[1]; posorder(&y1,&y2); y1=argv[0].u.location[1]; y2=argv[1].u.location[1]; posorder(&y1,&y2);
z1=argv[0].u.location[2]; z2=argv[1].u.location[2]; posorder(&z1,&z2); z1=argv[0].u.location[2]; z2=argv[1].u.location[2]; posorder(&z1,&z2);
result=getvalue(upd_sheet,x1,y1,z1);
resultx=x1; minloc[X] = x1; minloc[Y] = y1; minloc[Z] = z1;
resulty=y1; result = getvalue(upd_sheet, minloc);
resultz=z1;
for (x=x1; x<=x2; ++x) for (w[X]=x1; w[X]<=x2; ++(w[X]))
for (y=y1; y<=y2; ++y) for (w[Y]=y1; w[Y]<=y2; ++(w[Y]))
for (z=z1; z<=z2; ++z) for (w[Z]=z1; w[Z]<=z2; ++(w[Z]))
{ {
Token t; Token t;
tmp=(min ? tle(result,t=getvalue(upd_sheet,x,y,z)) : tge(result,t=getvalue(upd_sheet,x,y,z))); t = getvalue(upd_sheet, w);
tmp = (min ? tle(result,t) : tge(result, t));
if (tmp.type==INT) if (tmp.type==INT)
/* successful comparison */ /*{{{*/ /* successful comparison */ /*{{{*/
{ {
tfree(&tmp); tfree(&tmp);
if (tmp.u.integer==0) if (tmp.u.integer == 0)
{ {
tfree(&result); tfree(&result);
result=t; result=t;
resultx=x; LOCATION_GETS(minloc, w);
resulty=y;
resultz=z;
} }
else tfree(&t); else tfree(&t);
} }
@ -941,9 +968,7 @@ static Token minmax_func(int argc, const Token argv[], int min)
} }
tfree(&result); tfree(&result);
result.type=LOCATION; result.type=LOCATION;
result.u.location[0]=resultx; LOCATION_GETS(result.u.location, minloc);
result.u.location[1]=resulty;
result.u.location[2]=resultz;
return result; return result;
} }
/*}}}*/ /*}}}*/
@ -1108,7 +1133,7 @@ static Token clock_func(int argc, const Token argv[])
if (argc==2 && argv[0].type==INT && argv[1].type==LOCATION) /* clock(condition,location) */ /*{{{*/ if (argc==2 && argv[0].type==INT && argv[1].type==LOCATION) /* clock(condition,location) */ /*{{{*/
{ {
if (argv[0].u.integer) clk(upd_sheet,argv[1].u.location[0],argv[1].u.location[1],argv[1].u.location[2]); if (argv[0].u.integer) clk(upd_sheet, argv[1].u.location);
result.type=EMPTY; result.type=EMPTY;
} }
/*}}}*/ /*}}}*/
@ -1117,7 +1142,7 @@ static Token clock_func(int argc, const Token argv[])
if (argv[0].u.integer) if (argv[0].u.integer)
{ {
/* variables */ /*{{{*/ /* variables */ /*{{{*/
int x,y,z; Location w;
int x1,y1,z1; int x1,y1,z1;
int x2,y2,z2; int x2,y2,z2;
/*}}}*/ /*}}}*/
@ -1125,9 +1150,11 @@ static Token clock_func(int argc, const Token argv[])
x1=argv[1].u.location[0]; x2=argv[2].u.location[0]; posorder(&x1,&x2); x1=argv[1].u.location[0]; x2=argv[2].u.location[0]; posorder(&x1,&x2);
y1=argv[1].u.location[1]; y2=argv[2].u.location[1]; posorder(&y1,&y2); y1=argv[1].u.location[1]; y2=argv[2].u.location[1]; posorder(&y1,&y2);
z1=argv[1].u.location[2]; z2=argv[2].u.location[2]; posorder(&z1,&z2); z1=argv[1].u.location[2]; z2=argv[2].u.location[2]; posorder(&z1,&z2);
for (x=x1; x<=x2; ++x)
for (y=y1; y<=y2; ++y) for (w[X]=x1; w[X]<=x2; ++(w[X]))
for (z=z1; z<=z2; ++z) clk(upd_sheet,x,y,z); for (w[Y]=y1; w[Y]<=y2; ++(w[Y]))
for (w[Z]=z1; w[Z]<=z2; ++(w[Z]))
clk(upd_sheet, w);
} }
result.type=EMPTY; result.type=EMPTY;
} }

View File

@ -24,28 +24,34 @@
/*}}}*/ /*}}}*/
/* savehtml -- save as HTML table */ /*{{{*/ /* savehtml -- save as HTML table */ /*{{{*/
const char *savehtml(Sheet *sheet, const char *name, int body, int x1, int y1, int z1, int x2, int y2, int z2, unsigned int *count) const char *savehtml(Sheet *sheet, const char *name, int body,
const Location beg, const Location end,
unsigned int *count)
{ {
/* variables */ /*{{{*/ /* variables */ /*{{{*/
FILE *fp=(FILE*)0; /* cause runtime error */ FILE *fp=(FILE*)0; /* cause runtime error */
int x,y,z; Location w;
char buf[1024]; char buf[1024];
char num[20]; char num[20];
char fullname[PATH_MAX]; char fullname[PATH_MAX];
Cell *cell;
/*}}}*/ /*}}}*/
/* asserts */ /*{{{*/ /* asserts */ /*{{{*/
assert(sheet!=(Sheet*)0); assert(sheet != (Sheet*)0);
assert(name!=(const char*)0); assert(name != (const char*)0);
/*}}}*/ /*}}}*/
*count=0; *count=0;
for (z=z1; z<=z2; ++z) for (y=y1; y<=y2; ++y) if (shadowed(sheet,x1,y,z)) return _("Shadowed cells in first column"); w[X] = beg[X];
for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z]))
for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++(w[Y]))
if (shadowed(CELL_AT(sheet,w))) return _("Shadowed cells in first column");
if (!body && (fp=fopen(name,"w"))==(FILE*)0) return strerror(errno); if (!body && (fp=fopen(name,"w"))==(FILE*)0) return strerror(errno);
for (z=z1; z<=z2; ++z) for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z]))
{ {
if (body) /* open new file */ /*{{{*/ if (body) /* open new file */ /*{{{*/
{ {
sprintf(num,".%d",z); sprintf(num, ".%d", w[Z]);
fullname[sizeof(fullname)-strlen(num)-1]='\0'; fullname[sizeof(fullname)-strlen(num)-1]='\0';
(void)strncpy(fullname,name,sizeof(fullname)-strlen(num)-1); (void)strncpy(fullname,name,sizeof(fullname)-strlen(num)-1);
@ -60,27 +66,29 @@ const char *savehtml(Sheet *sheet, const char *name, int body, int x1, int y1, i
/*}}}*/ /*}}}*/
if (fputs_close("<table>\n",fp)==EOF) return strerror(errno); if (fputs_close("<table>\n",fp)==EOF) return strerror(errno);
for (y=y1; y<=y2; ++y) /* print contents */ /*{{{*/ for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++(w[Y])) /* print contents */ /*{{{*/
{ {
if (fputs_close("<tr>",fp)==EOF) return strerror(errno); if (fputs_close("<tr>",fp)==EOF) return strerror(errno);
for (x=x1; x<=x2; ) for (w[X]=beg[X]; w[X]<=end[X]; )
{ {
int multicols; int multicols;
char *bufp; char *bufp;
for (multicols=x+1; multicols<sheet->dimx && shadowed(sheet,multicols,y,z); ++multicols); for (multicols=w[X]+1; multicols<sheet->dimx && SHADOWEDC(sheet,multicols,w[Y],w[Z]); ++multicols);
multicols=multicols-x; multicols = multicols - w[X];
if (multicols>1) fprintf(fp,"<td colspan=%d",multicols); if (multicols>1) fprintf(fp,"<td colspan=%d",multicols);
else fprintf(fp,"<td"); else fprintf(fp,"<td");
switch (getadjust(sheet,x,y,z)) cell = CELL_AT(sheet, w);
switch (getadjust(cell))
{ {
case LEFT: if (fputs_close(" align=left>",fp)==EOF) return strerror(errno); break; case LEFT: if (fputs_close(" align=left>",fp)==EOF) return strerror(errno); break;
case RIGHT: if (fputs_close(" align=right>",fp)==EOF) return strerror(errno); break; case RIGHT: if (fputs_close(" align=right>",fp)==EOF) return strerror(errno); break;
case CENTER: if (fputs_close(" align=center>",fp)==EOF) return strerror(errno); break; case CENTER: if (fputs_close(" align=center>",fp)==EOF) return strerror(errno); break;
default: assert(0); default: assert(0);
} }
printvalue(buf,sizeof(buf),0,0,getscientific(sheet,x,y,z),getprecision(sheet,x,y,z),sheet,x,y,z); printvalue(buf, sizeof(buf), 0, 0, getscientific(cell),
if (transparent(sheet,x,y,z)) getprecision(cell), sheet, w);
if (transparent(cell))
{ {
if (fputs_close(buf,fp)==EOF) return strerror(errno); if (fputs_close(buf,fp)==EOF) return strerror(errno);
} }
@ -93,7 +101,7 @@ const char *savehtml(Sheet *sheet, const char *name, int body, int x1, int y1, i
default: if (fputc_close(*bufp,fp)==EOF) return strerror(errno); default: if (fputc_close(*bufp,fp)==EOF) return strerror(errno);
} }
if (fputs_close("</td>",fp)==EOF) return strerror(errno); if (fputs_close("</td>",fp)==EOF) return strerror(errno);
x+=multicols; w[X] += multicols;
++*count; ++*count;
} }
if (fputs_close("</tr>\n",fp)==EOF) return strerror(errno); if (fputs_close("</tr>\n",fp)==EOF) return strerror(errno);

View File

@ -3,6 +3,8 @@
#include "sheet.h" #include "sheet.h"
const char *savehtml(Sheet *sheet, const char *name, int body, int x1, int y1, int z1, int x2, int y2, int z2, unsigned int *count); const char *savehtml(Sheet *sheet, const char *name, int body,
const Location beg, const Location end,
unsigned int *count);
#endif #endif

51
latex.c
View File

@ -24,29 +24,36 @@
/*}}}*/ /*}}}*/
/* savelatex -- save as LaTeX table */ /*{{{*/ /* savelatex -- save as LaTeX table */ /*{{{*/
const char *savelatex(Sheet *sheet, const char *name, int body, int x1, int y1, int z1, int x2, int y2, int z2, unsigned int *count) const char *savelatex(Sheet *sheet, const char *name, int body,
const Location beg, const Location end,
unsigned int *count)
{ {
/* variables */ /*{{{*/ /* variables */ /*{{{*/
FILE *fp=(FILE*)0; /* cause runtime error */ FILE *fp=(FILE*)0; /* cause runtime error */
int x,y,z; Location w;
char buf[1024]; char buf[1024];
char num[20]; char num[20];
char fullname[PATH_MAX]; char fullname[PATH_MAX];
Cell *cell;
/*}}}*/
/* asserts */ /*{{{*/
assert(sheet != (Sheet*)0);
assert(name != (const char*)0);
/*}}}*/ /*}}}*/
/* asserts */ /*{{{*/
assert(sheet!=(Sheet*)0);
assert(name!=(const char*)0);
/*}}}*/
*count=0; *count=0;
for (z=z1; z<=z2; ++z) for (y=y1; y<=y2; ++y) if (shadowed(sheet,x1,y,z)) return _("Shadowed cells in first column"); w[X] = beg[X];
for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z]))
for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++(w[Y]))
if (shadowed(CELL_AT(sheet,w))) return _("Shadowed cells in first column");
if (!body && (fp=fopen(name,"w"))==(FILE*)0) return strerror(errno); if (!body && (fp=fopen(name,"w"))==(FILE*)0) return strerror(errno);
for (z=z1; z<=z2; ++z) for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z]))
{ {
if (body) if (body)
/* open new file */ /*{{{*/ /* open new file */ /*{{{*/
{ {
sprintf(num,".%d",z); sprintf(num, ".%d", w[Z]);
fullname[sizeof(fullname)-strlen(num)-1]='\0'; fullname[sizeof(fullname)-strlen(num)-1]='\0';
(void)strncpy(fullname,name,sizeof(fullname)-strlen(num)-1); (void)strncpy(fullname,name,sizeof(fullname)-strlen(num)-1);
@ -58,7 +65,7 @@ const char *savelatex(Sheet *sheet, const char *name, int body, int x1, int y1,
/*}}}*/ /*}}}*/
else else
/* print header */ /*{{{*/ /* print header */ /*{{{*/
if (z==z1) if (w[Z] == beg[Z])
{ {
if (fputs_close("\\documentclass{article}\n\\usepackage{longtable}\n\\begin{document}\n\\setlongtables\n\\vfill\n",fp)==EOF) return strerror(errno); if (fputs_close("\\documentclass{article}\n\\usepackage{longtable}\n\\begin{document}\n\\setlongtables\n\\vfill\n",fp)==EOF) return strerror(errno);
} }
@ -70,31 +77,33 @@ const char *savelatex(Sheet *sheet, const char *name, int body, int x1, int y1,
/* print bogus format */ /*{{{*/ /* print bogus format */ /*{{{*/
fprintf(fp,"\\begin{longtable}{"); fprintf(fp,"\\begin{longtable}{");
for (x=x1; x<=x2; ++x) if (fputc_close('l',fp)==EOF) return strerror(errno); for (w[X]=beg[X]; w[X]<=end[X]; ++(w[X])) if (fputc_close('l',fp)==EOF) return strerror(errno);
fprintf(fp,"}\n"); fprintf(fp,"}\n");
/*}}}*/ /*}}}*/
for (y=y1; y<=y2; ++y) for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++(w[Y]))
/* print contents */ /*{{{*/ /* print contents */ /*{{{*/
{ {
for (x=x1; x<=x2; ) for (w[X]=beg[X]; w[X]<=end[X]; )
{ {
int multicols; int multicols;
char *bufp; char *bufp;
if (x>x1 && fputc_close('&',fp)==EOF) return strerror(errno); if (w[X]>beg[X] && fputc_close('&',fp)==EOF) return strerror(errno);
for (multicols=x+1; multicols<sheet->dimx && shadowed(sheet,multicols,y,z); ++multicols); for (multicols = w[X]+1; multicols<sheet->dimx && SHADOWEDC(sheet,multicols,w[Y],w[Z]); ++multicols);
multicols=multicols-x; multicols = multicols - w[X];
fprintf(fp,"\\multicolumn{%d}{",multicols); fprintf(fp,"\\multicolumn{%d}{",multicols);
switch (getadjust(sheet,x,y,z)) cell = CELL_AT(sheet, w);
switch (getadjust(cell))
{ {
case LEFT: if (fputc_close('l',fp)==EOF) return strerror(errno); break; case LEFT: if (fputc_close('l',fp)==EOF) return strerror(errno); break;
case RIGHT: if (fputc_close('r',fp)==EOF) return strerror(errno); break; case RIGHT: if (fputc_close('r',fp)==EOF) return strerror(errno); break;
case CENTER: if (fputc_close('c',fp)==EOF) return strerror(errno); break; case CENTER: if (fputc_close('c',fp)==EOF) return strerror(errno); break;
default: assert(0); default: assert(0);
} }
printvalue(buf,sizeof(buf),0,0,getscientific(sheet,x,y,z),getprecision(sheet,x,y,z),sheet,x,y,z); printvalue(buf, sizeof(buf), 0, 0, getscientific(cell),
getprecision(cell), sheet, w);
if (fputs_close("}{",fp)==EOF) return strerror(errno); if (fputs_close("}{",fp)==EOF) return strerror(errno);
if (transparent(sheet,x,y,z)) if (transparent(cell))
{ {
if (fputs_close(buf,fp)==EOF) return strerror(errno); if (fputs_close(buf,fp)==EOF) return strerror(errno);
} }
@ -113,10 +122,10 @@ const char *savelatex(Sheet *sheet, const char *name, int body, int x1, int y1,
default: if (fputc_close(*bufp,fp)==EOF) return strerror(errno); default: if (fputc_close(*bufp,fp)==EOF) return strerror(errno);
} }
if (fputc_close('}',fp)==EOF) return strerror(errno); if (fputc_close('}',fp)==EOF) return strerror(errno);
x+=multicols; w[X] += multicols;
++*count; ++*count;
} }
if (fputs_close(y<y2 ? "\\\\\n" : "\n\\end{longtable}\n",fp)==EOF) return strerror(errno); if (fputs_close(w[Y]<end[Y] ? "\\\\\n" : "\n\\end{longtable}\n",fp)==EOF) return strerror(errno);
} }
/*}}}*/ /*}}}*/
if (body) if (body)

View File

@ -3,6 +3,8 @@
#include "sheet.h" #include "sheet.h"
const char *savelatex(Sheet *sheet, const char *name, int body, int x1, int y1, int z1, int x2, int y2, int z2, unsigned int *count); const char *savelatex(Sheet *sheet, const char *name, int body,
const Location beg, const Location end,
unsigned int *count);
#endif #endif

594
main.c

File diff suppressed because it is too large Load Diff

5
main.h
View File

@ -86,9 +86,10 @@ typedef enum {
extern int do_sheetcmd(Sheet *cursheet, Key c, int moveonly); extern int do_sheetcmd(Sheet *cursheet, Key c, int moveonly);
extern int doanyway(Sheet *sheet, const char *msg); extern int doanyway(Sheet *sheet, const char *msg);
extern void moveto(Sheet *sheet, int x, int y, int z); extern void moveto(Sheet *sheet, int x, int y, int z);
extern void movetoloc(Sheet *sheet, const Location dest);
extern void relmoveto(Sheet *sheet, int x, int y, int z); extern void relmoveto(Sheet *sheet, int x, int y, int z);
extern void do_mark(Sheet *cursheet, int force); extern void do_mark(Sheet *cursheet, MarkState ms);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

37
sc.c
View File

@ -33,6 +33,7 @@ static int s2t_term(Sheet *sheet);
static int s2t_loc(Sheet *sheet, const char **s, char **t) static int s2t_loc(Sheet *sheet, const char **s, char **t)
{ {
int x,y; int x,y;
Location tmp;
char label[10],*l; char label[10],*l;
l=label; l=label;
@ -63,7 +64,8 @@ static int s2t_loc(Sheet *sheet, const char **s, char **t)
*(*t)++=*(*s)++; *(*t)++=*(*s)++;
} }
*l='\0'; *l='\0';
if (*getlabel(sheet,x,y,0)=='\0') setlabel(sheet,x,y,0,label,0); tmp[X] = x; tmp[Y] = y; tmp[Z] = 0;
if (*getlabel(CELL_AT(sheet, tmp))=='\0') setlabel(sheet, tmp, label, 0);
return 1; return 1;
} }
/*}}}*/ /*}}}*/
@ -207,6 +209,8 @@ const char *loadsc(Sheet *sheet, const char *name)
int line; int line;
size_t width; size_t width;
const char *err; const char *err;
Cell *cell;
Location tmp;
int x,y; int x,y;
/*}}}*/ /*}}}*/
@ -229,10 +233,12 @@ const char *loadsc(Sheet *sheet, const char *name)
sscanf(buf+7,"%s %d %d %d",colstr,&colwidth,&precision,&whoknows); sscanf(buf+7,"%s %d %d %d",colstr,&colwidth,&precision,&whoknows);
col=(colstr[0]-'A'); if (colstr[1]) col=col*26+(colstr[1]-'A'); col=(colstr[0]-'A'); if (colstr[1]) col=col*26+(colstr[1]-'A');
initcell(sheet,col,0,0); OLOCATION(tmp);
CELL_AT(sheet,col,0,0)->adjust=RIGHT; tmp[X] = col;
CELL_AT(sheet,col,0,0)->precision=precision; cell = initcell(sheet, tmp);
setwidth(sheet,col,0,colwidth); cell->adjust = RIGHT;
cell->precision = precision;
setwidth(sheet, col, 0, colwidth);
} }
/*}}}*/ /*}}}*/
else if (strncmp(buf,"leftstring ",11)==0 || strncmp(buf,"rightstring ",12)==0) /* rightstring/leftstring cell = "string" */ /*{{{*/ else if (strncmp(buf,"leftstring ",11)==0 || strncmp(buf,"rightstring ",12)==0) /* rightstring/leftstring cell = "string" */ /*{{{*/
@ -253,9 +259,10 @@ const char *loadsc(Sheet *sheet, const char *name)
err=errbuf; err=errbuf;
goto eek; goto eek;
} }
initcell(sheet,x,y,0); tmp[X] = x; tmp[Y] = y; tmp[Z] = 0;
CELL_AT(sheet,x,y,0)->adjust=strncmp(buf,"leftstring ",11) ? RIGHT : LEFT; cell = initcell(sheet, tmp);
CELL_AT(sheet,x,y,0)->contents=contents; cell->adjust = strncmp(buf,"leftstring ",11) ? RIGHT : LEFT;
cell->contents[BASE] = contents;
} }
/*}}}*/ /*}}}*/
else if (strncmp(buf,"let ",4)==0) /* let cell = expression */ /*{{{*/ else if (strncmp(buf,"let ",4)==0) /* let cell = expression */ /*{{{*/
@ -269,7 +276,8 @@ const char *loadsc(Sheet *sheet, const char *name)
s=buf+4; s=buf+4;
x=*s++-'A'; if (*s>='A' && *s<='Z') x=x*26+(*s++-'A'); x=*s++-'A'; if (*s>='A' && *s<='Z') x=x*26+(*s++-'A');
y=*s++-'0'; while (*s>='0' && *s<='9') y=10*y+(*s++-'0'); y=*s++-'0'; while (*s>='0' && *s<='9') y=10*y+(*s++-'0');
if (getcont(sheet,x,y,0,0)==(Token**)0) tmp[X] = x; tmp[Y] = y; tmp[Z] = 0;
if (getcont(CELL_ATC(sheet,x,y,0),BASE)==(Token**)0)
{ {
s+=3; s+=3;
s2t_s=s; s2t_t=newbuf; s2t_s=s; s2t_t=newbuf;
@ -292,9 +300,10 @@ const char *loadsc(Sheet *sheet, const char *name)
err=errbuf; err=errbuf;
goto eek; goto eek;
} }
initcell(sheet,x,y,0); tmp[X] = x; tmp[Y] = y; tmp[Z] = 0;
CELL_AT(sheet,x,y,0)->adjust=RIGHT; cell = initcell(sheet, tmp);
CELL_AT(sheet,x,y,0)->contents=contents; cell->adjust = RIGHT;
cell->contents[BASE] = contents;
} }
} }
/*}}}*/ /*}}}*/
@ -306,8 +315,8 @@ const char *loadsc(Sheet *sheet, const char *name)
{ {
int prec; int prec;
prec=getprecision(sheet,x,0,0)==def_precision ? 2 : getprecision(sheet,x,0,0); prec=getprecision(CELL_ATC(sheet,x,0,0))==def_precision ? 2 : getprecision(CELL_ATC(sheet,x,0,0));
for (y=1; y<sheet->dimy; ++y) if (CELL_AT(sheet,x,y,0)) CELL_AT(sheet,x,y,0)->precision=prec; for (y=1; y<sheet->dimy; ++y) if (CELL_ATC(sheet,x,y,0)) CELL_ATC(sheet,x,y,0)->precision=prec;
} }
/*}}}*/ /*}}}*/
eek: eek:

View File

@ -46,6 +46,18 @@ int identcode(const char *s, size_t len)
} }
/*}}}*/ /*}}}*/
/* loc_in_box -- returns true if test is in the box determined by b and c */
bool loc_in_box(const Location test,
const Location b, const Location c)
{
for (Dimensions dim = X; dim < HYPER; ++dim)
{
if (test[dim] < b[dim] && test[dim] < c[dim]) return false;
if (test[dim] > b[dim] && test[dim] > c[dim]) return false;
}
return true;
}
/* charstring -- match quoted string and return token */ /*{{{*/ /* charstring -- match quoted string and return token */ /*{{{*/
static Token *charstring(const char **s) static Token *charstring(const char **s)
{ {

View File

@ -2,6 +2,7 @@
#define SCANNER_H #define SCANNER_H
#include <sys/types.h> #include <sys/types.h>
#include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -18,6 +19,22 @@ extern const char *Type_Name[];
typedef enum { PLUS, MINUS, MUL, DIV, OP, CP, COMMA, LT, LE, GE, GT, ISEQUAL, ABOUTEQ, NE, POW, MOD } Operator; typedef enum { PLUS, MINUS, MUL, DIV, OP, CP, COMMA, LT, LE, GE, GT, ISEQUAL, ABOUTEQ, NE, POW, MOD } Operator;
typedef int Location[3]; /* NOTE: Locations are passed by REFERENCE not value */
/* I.e., to accapt a Location argument, declare the parameter to be of type
const Location*
*/
typedef enum { X=0, Y=1, Z=2, HYPER} Dimensions;
#define OLOCATION(loc) ((void)memset(loc, 0, sizeof(Location)))
#define IN_OCTANT(loc) (loc[X]>=0 && loc[Y]>=0 && loc[Z]>=0)
#define LOCATION_GETS(la,lb) ((void)memcpy(la, lb, sizeof(Location)))
#define SAME_LOC(la,lb) (memcmp(la,lb,sizeof(Location))==0)
#define LOCATION_SUB(la,lb) (la)[X]-=(lb)[X]; (la)[Y]-=(lb)[Y]; (la)[Z]-=(lb)[Z];
bool loc_in_box(const Location test,
const Location b, const Location c);
typedef struct typedef struct
{ {
Type type; Type type;
@ -29,7 +46,7 @@ typedef struct
Operator op; Operator op;
char *lident; char *lident;
int fident; int fident;
int location[3]; Location location;
char *err; char *err;
} u; } u;
} Token; } Token;

1266
sheet.c

File diff suppressed because it is too large Load Diff

129
sheet.h
View File

@ -7,14 +7,6 @@
extern "C" { extern "C" {
#endif #endif
#define LOC_WITHIN(s,x,y,z) (x<s->dimx && y<s->dimy && z<s->dimz)
#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; x<s->dimx; ++x) for (y=0; y<s->dimy; ++y) for (z=0; z<s->dimz; ++z
typedef enum { LEFT=0, RIGHT=1, CENTER=2, AUTOADJUST=3 } Adjust; typedef enum { LEFT=0, RIGHT=1, CENTER=2, AUTOADJUST=3 } Adjust;
typedef enum { IN_X, IN_Y, IN_Z } Direction; typedef enum { IN_X, IN_Y, IN_Z } Direction;
@ -32,10 +24,11 @@ typedef struct
int sortkey; /* OR-ed value of the above constants */ int sortkey; /* OR-ed value of the above constants */
} Sortkey; } Sortkey;
typedef enum { BASE=0, ITERATIVE=1, CONTINGENT=2 } ContentVariety;
typedef struct typedef struct
{ {
Token **contents; Token **contents[CONTINGENT];
Token **ccontents;
char *label; char *label;
Token value; Token value;
Token resvalue; Token resvalue;
@ -54,20 +47,24 @@ typedef struct
unsigned int underline:1; unsigned int underline:1;
} Cell; } Cell;
#define NULLCELL ((Cell*)0)
struct Label struct Label
{ {
const char *label; const char *label;
int x,y,z; Location location;
struct Label *next; struct Label *next;
}; };
typedef enum { MARK_CYCLE = 0, GET_MARK_CUR = 1, GET_MARK_ALL = 2,
MARKING = 3, MARKED = 4, UNMARKED = 5 } MarkState;
typedef struct typedef struct
{ {
struct Label *labelcache[LABEL_CACHE]; struct Label *labelcache[LABEL_CACHE];
int curx, cury, curz; Location cur;
int mark1x, mark1y, mark1z; Location mark1, mark2;
int mark2x, mark2y, mark2z; MarkState marking;
int marking;
int offx, offy; int offx, offy;
Cell **sheet; Cell **sheet;
int *column; int *column;
@ -81,64 +78,84 @@ typedef struct
void *display; void *display;
} Sheet; } Sheet;
#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)
extern Sheet *upd_sheet; extern Sheet *upd_sheet;
extern int upd_x; extern Location upd_l;
extern int upd_y;
extern int upd_z;
extern int max_eval; extern int max_eval;
void initialize_sheet(Sheet *sheet);
void resize(Sheet *sheet, int x, int y, int z); void resize(Sheet *sheet, int x, int y, int z);
void initcell(Sheet *sheet, int x, int y, int z); Cell *initcell(Sheet *sheet, const Location at);
Cell *safe_cell_at(Sheet *sheet, const Location at);
Cell *curcell(Sheet *sheet);
void cachelabels(Sheet *sheet); void cachelabels(Sheet *sheet);
void freesheet(Sheet *sheet, int all); void freesheet(Sheet *sheet, int all);
void forceupdate(Sheet *sheet); void forceupdate(Sheet *sheet);
MarkState getmarkstate(Sheet *sheet);
void dump_current_cell(Sheet *sheet); void dump_current_cell(Sheet *sheet);
void freecell(Sheet *sheet, int x, int y, int z); void freecell(Sheet *sheet, const Location at);
int columnwidth(Sheet *sheet, int x, int z); int columnwidth(Sheet *sheet, int x, int z);
void setwidth(Sheet *sheet, int x, int z, int width); void setwidth(Sheet *sheet, int x, int z, int width);
int cellwidth(Sheet *sheet, int x, int y, int z); int cellwidth(Sheet *sheet, const Location at);
void putcont(Sheet *sheet, int x, int y, int z, Token **t, int c); void putcont(Sheet *sheet, const Location at, Token **t, ContentVariety v);
Token **getcont(Sheet *sheet, int x, int y, int z, int c); Token **getcont(const Cell *cell, ContentVariety v);
Token getvalue(Sheet *sheet, int x, int y, int z); Token getvalue(Sheet *sheet, const Location at);
void update(Sheet *sheet); void update(Sheet *sheet);
char *geterror(Sheet *sheet, int x, int y, int z); 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, int x, int y, int z); void printvalue(char *s, size_t size, size_t chars, int quote, int scientific, int precision, Sheet *sheet, const Location at);
Adjust getadjust(Sheet *sheet, int x, int y, int z); Adjust getadjust(const Cell *cell);
void setadjust(Sheet *sheet, int x, int y, int z, Adjust adjust); void setadjust(Sheet *sheet, const Location at, Adjust adjust);
void shadow(Sheet *sheet, int x, int y, int z, int yep); void shadow(Sheet *sheet, const Location at, int yep);
int shadowed(Sheet *sheet, int x, int y, int z); int shadowed(const Cell *cell);
void bold(Sheet *sheet, int x, int y, int z, int yep); void bold(Sheet *sheet, const Location at, int yep);
int isbold(Sheet *sheet, int x, int y, int z); int isbold(const Cell *cell);
void underline(Sheet *sheet, int x, int y, int z, int yep); void underline(Sheet *sheet, const Location at, int yep);
int underlined(Sheet *sheet, int x, int y, int z); int underlined(const Cell *cell);
void lockcell(Sheet *sheet, int x, int y, int z, int yep); void lockcell(Sheet *sheet, const Location at, int yep);
int locked(Sheet *sheet, int x, int y, int z); int locked(const Cell *cell);
int transparent(Sheet *sheet, int x, int y, int z); int transparent(const Cell *cell);
void maketrans(Sheet *sheet, int x, int y, int z, int yep); void maketrans(Sheet *sheet, const Location at, int yep);
void igncell(Sheet *sheet, int x, int y, int z, int yep); void igncell(Sheet *sheet, const Location at, int yep);
int ignored(Sheet *sheet, int x, int y, int z); int ignored(const Cell *cell);
void clk(Sheet *sheet, int x, int y, int z); void clk(Sheet *sheet, const Location at);
void setscientific(Sheet *sheet, int x, int y, int z, int yep); void setscientific(Sheet *sheet, const Location at, int yep);
int getscientific(Sheet *sheet, int x, int y, int z); int getscientific(const Cell *cell);
void setprecision(Sheet *sheet, int x, int y, int z, int precision); void setprecision(Sheet *sheet, const Location at, int precision);
int getprecision(Sheet *sheet, int x, int y, int z); int getprecision(const Cell* cell);
const char *getlabel(Sheet *sheet, int x, int y, int z); const char *getlabel(const Cell* cell);
void setlabel(Sheet *sheet, int x, int y, int z, const char *buf, int update); void setlabel(Sheet *sheet, const Location at, const char *buf, int update);
Token findlabel(Sheet *sheet, const char *label); Token findlabel(Sheet *sheet, const char *label);
void relabel(Sheet *sheet, const char *oldlabel, const char *newlabel, int x, int y, int z); void relabel(Sheet* sheet, const Location at,
const char *oldlabel, const char *newlabel);
const char *savexdr(Sheet *sheet, const char *name, unsigned int *count); const char *savexdr(Sheet *sheet, const char *name, unsigned int *count);
const char *savetbl(Sheet *sheet, const char *name, int body, int x1, int y1, int z1, int x2, int y2, int z2, unsigned int *count); 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, int x1, int y1, int z1, int x2, int y2, int z2, 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, int x1, int y1, int z1, int x2, int y2, int z2, unsigned int *count); const char *savecsv(Sheet *sheet, const char *name, char sep, const Location beg, const Location end, unsigned int *count);
const char *saveport(Sheet *sheet, const char *name, unsigned int *count); const char *saveport(Sheet *sheet, const char *name, unsigned int *count);
const char *loadxdr(Sheet *sheet, const char *name); const char *loadxdr(Sheet *sheet, const char *name);
const char *loadport(Sheet *sheet, const char *name); const char *loadport(Sheet *sheet, const char *name);
const char *loadcsv(Sheet *sheet, const char *name); const char *loadcsv(Sheet *sheet, const char *name);
void insertcube(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, Direction ins);
void deletecube(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, Direction ins); void insertcube(Sheet *sheet, const Location beg, const Location end, Direction ins);
void moveblock(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3, int copy); void deletecube(Sheet *sheet, const Location beg, const Location end, Direction ins);
const char *sortblock(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, Direction dir, Sortkey *sk, size_t sklen); void moveblock(Sheet *sheet, const Location beg, const Location end, const Location dest, int copy);
void mirrorblock(Sheet *sheet, int x1, int y1, int z1, int x2, int y2, int z2, Direction dir); 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);
#ifdef __cplusplus #ifdef __cplusplus
} }

46
wk1.c
View File

@ -692,6 +692,8 @@ const char *loadwk1(Sheet *sheet, const char *name)
char *body=(char*)0,*newbody; char *body=(char*)0,*newbody;
size_t bodymaxlen=0; size_t bodymaxlen=0;
size_t bodylen; size_t bodylen;
Location tmp;
Cell *cell;
int found_bof=0,found_eof=0; int found_bof=0,found_eof=0;
/*}}}*/ /*}}}*/
@ -835,8 +837,9 @@ const char *loadwk1(Sheet *sheet, const char *name)
case 0xC: case 0xC:
{ {
if (bodylen!=5) { err=_("Invalid record body length"); goto ouch; } if (bodylen!=5) { err=_("Invalid record body length"); goto ouch; }
initcell(sheet,it(body+1),it(body+3),0); tmp[X] = it(body+1); tmp[Y] = it(body+3); tmp[Z] = 0;
format((unsigned char)body[0],CELL_AT(sheet,it(body+1),it(body+3),0)); cell = initcell(sheet, tmp);
format((unsigned char)body[0], cell);
break; break;
} }
/*}}}*/ /*}}}*/
@ -846,14 +849,15 @@ const char *loadwk1(Sheet *sheet, const char *name)
Token **t; Token **t;
assert(bodylen==7); assert(bodylen==7);
initcell(sheet,it(body+1),it(body+3),0); tmp[X] = it(body+1); tmp[Y] = it(body+3); tmp[Z] = 0;
cell = initcell(sheet, tmp);
t=malloc(2*sizeof(Token*)); t=malloc(2*sizeof(Token*));
t[0]=malloc(sizeof(Token)); t[0]=malloc(sizeof(Token));
t[1]=(Token*)0; t[1]=(Token*)0;
t[0]->type=INT; t[0]->type=INT;
t[0]->u.integer=it(body+5); t[0]->u.integer=it(body+5);
putcont(sheet,it(body+1),it(body+3),0,t,0); putcont(sheet, tmp, t, BASE);
format((unsigned char)body[0],CELL_AT(sheet,it(body+1),it(body+3),0)); format((unsigned char)body[0], cell);
break; break;
} }
/*}}}*/ /*}}}*/
@ -863,14 +867,15 @@ const char *loadwk1(Sheet *sheet, const char *name)
Token **t; Token **t;
assert(bodylen==13); assert(bodylen==13);
initcell(sheet,it(body+1),it(body+3),0); tmp[X] = it(body+1); tmp[Y] = it(body+3); tmp[Z] = 0;
cell = initcell(sheet, tmp);
t=malloc(2*sizeof(Token*)); t=malloc(2*sizeof(Token*));
t[0]=malloc(sizeof(Token)); t[0]=malloc(sizeof(Token));
t[1]=(Token*)0; t[1]=(Token*)0;
t[0]->type=FLOAT; t[0]->type=FLOAT;
t[0]->u.flt=dbl((unsigned char*)body+5); t[0]->u.flt=dbl((unsigned char*)body+5);
putcont(sheet,it(body+1),it(body+3),0,t,0); putcont(sheet, tmp, t, BASE);
format((unsigned char)body[0],CELL_AT(sheet,it(body+1),it(body+3),0)); format((unsigned char)body[0], cell);
break; break;
} }
/*}}}*/ /*}}}*/
@ -880,14 +885,15 @@ const char *loadwk1(Sheet *sheet, const char *name)
Token **t; Token **t;
assert(bodylen>=6 && bodylen<=245); assert(bodylen>=6 && bodylen<=245);
initcell(sheet,it(body+1),it(body+3),0); tmp[X] = it(body+1); tmp[Y] = it(body+3); tmp[Z] = 0;
cell = initcell(sheet, tmp);
t=malloc(2*sizeof(Token*)); t=malloc(2*sizeof(Token*));
t[0]=malloc(sizeof(Token)); t[0]=malloc(sizeof(Token));
t[1]=(Token*)0; t[1]=(Token*)0;
t[0]->type=STRING; t[0]->type=STRING;
t[0]->u.string=mystrmalloc(body+6); t[0]->u.string=mystrmalloc(body+6);
putcont(sheet,it(body+1),it(body+3),0,t,0); putcont(sheet, tmp, t, BASE);
format((unsigned char)body[0],CELL_AT(sheet,it(body+1),it(body+3),0)); format((unsigned char)body[0], cell);
break; break;
} }
/*}}}*/ /*}}}*/
@ -944,7 +950,7 @@ const char *loadwk1(Sheet *sheet, const char *name)
#if WK1DEBUG #if WK1DEBUG
fprintf(se,", value %f",dbl((unsigned char*)body+5)); fprintf(se,", value %f",dbl((unsigned char*)body+5));
#endif #endif
format((unsigned char)body[0],CELL_AT(sheet,it(body+1),it(body+3),0)); format((unsigned char)body[0],CELL_ATC(sheet,it(body+1),it(body+3),0));
#if WK1DEBUG #if WK1DEBUG
fprintf(se,"\r\n"); fprintf(se,"\r\n");
#endif #endif
@ -968,10 +974,11 @@ const char *loadwk1(Sheet *sheet, const char *name)
fprintf(se,"[<-- %d tokens]\r\n",tokens); fprintf(se,"[<-- %d tokens]\r\n",tokens);
#endif #endif
free(offset); free(offset);
initcell(sheet,it(body+1),it(body+3),0); tmp[X] = it(body+1); tmp[Y] = it(body+3); tmp[Z] = 0;
CELL_AT(sheet,it(body+1),it(body+3),0)->value.type=FLOAT; cell = initcell(sheet, tmp);
CELL_AT(sheet,it(body+1),it(body+3),0)->value.u.flt=dbl((unsigned char*)body+5); cell->value.type=FLOAT;
putcont(sheet,it(body+1),it(body+3),0,t,0); cell->value.u.flt=dbl((unsigned char*)body+5);
putcont(sheet, tmp, t, BASE);
} }
break; break;
} }
@ -1085,14 +1092,15 @@ const char *loadwk1(Sheet *sheet, const char *name)
Token **t; Token **t;
assert(bodylen>=6 && bodylen<=245); assert(bodylen>=6 && bodylen<=245);
initcell(sheet,it(body+1),it(body+3),0); tmp[X] = it(body+1); tmp[Y] = it(body+3); tmp[Z] = 0;
cell = initcell(sheet, tmp);
t=malloc(2*sizeof(Token*)); t=malloc(2*sizeof(Token*));
t[0]=malloc(sizeof(Token)); t[0]=malloc(sizeof(Token));
t[1]=(Token*)0; t[1]=(Token*)0;
t[0]->type=STRING; t[0]->type=STRING;
t[0]->u.string=mystrmalloc(body+5); t[0]->u.string=mystrmalloc(body+5);
putcont(sheet,it(body+1),it(body+3),0,t,0); putcont(sheet, tmp, t, BASE);
format((unsigned char)body[0],CELL_AT(sheet,it(body+1),it(body+3),0)); format((unsigned char)body[0], cell);
break; break;
} }
/*}}}*/ /*}}}*/

4
xdr.c
View File

@ -166,7 +166,9 @@ bool_t xdr_cell(XDR *xdrs, Cell *cell)
int result,x; int result,x;
assert(cell!=(Cell*)0); assert(cell!=(Cell*)0);
if (!(xdr_tokenptrvec(xdrs, &(cell->contents)) && xdr_tokenptrvec(xdrs, &(cell->ccontents)) /* && xdr_token(xdrs, &(cell->value)) */ )) return 0; if (!(xdr_tokenptrvec(xdrs, &(cell->contents[BASE]))
&& xdr_tokenptrvec(xdrs, &(cell->contents[ITERATIVE])) /* && xdr_token(xdrs, &(cell->value)) */ ))
return 0;
if (xdr_mystring(xdrs, &(cell->label))==0) return 0; if (xdr_mystring(xdrs, &(cell->label))==0) return 0;
x=cell->adjust; x=cell->adjust;
result=xdr_int(xdrs, &x); result=xdr_int(xdrs, &x);