First partial pass at getting teapot working on Mac OS X

This commit is contained in:
Glen Whitney 2019-09-05 03:24:24 -04:00
parent c52219f827
commit 8074130224
29 changed files with 1032 additions and 1256 deletions

View File

@ -9,6 +9,7 @@ option(ENABLE_HELP "Enable built-in documentation" ON)
option(ENABLE_UTF8 "Enable UTF-8 support" ON)
option(ENABLE_STATIC "Link FLTK statically" OFF)
add_compile_options(-Wall -Wextra -Wshadow -Wconversion -Wno-unused-parameter)
include_directories("${Teapot_BINARY_DIR}/")
add_subdirectory(src)

View File

@ -38,22 +38,25 @@ if (CURSES_FOUND)
endif ()
find_package(FLTK)
find_package(JPEG)
if (FLTK_FOUND)
fltk_wrap_ui(fteapot fteapot.fl)
include_directories(${FLTK_INCLUDE_DIR})
add_executable(fteapot WIN32 tpt_choose.cxx ${fteapot_FLTK_UI_SRCS})
target_compile_options(fteapot PRIVATE -Wno-shadow -Wno-conversion -Wno-sign-conversion)
set(fteapot_DEB_DEPENDS ", libstdc++6 (>= 4.1.1), libfltk1.3")
if (ENABLE_HELP)
set(fteapot_DEB_DEPENDS "${fteapot_DEB_DEPENDS}, libfltk-images1.3")
if (ENABLE_STATIC)
target_link_libraries(fteapot teapotlib fltk fltk_images ${LIB_PORTABLEXDR})
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${JPEG_LIBRARIES} ${LIB_PORTABLEXDR})
else ()
target_link_libraries(fteapot teapotlib fltk fltk_images ${LIB_PORTABLEXDR})
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${JPEG_LIBRARIES} ${LIB_PORTABLEXDR})
endif ()
else ()
if (ENABLE_STATIC)
target_link_libraries(fteapot teapotlib fltk fltk_images ${LIB_PORTABLEXDR})
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${LIB_PORTABLEXDR})
else ()
target_link_libraries(fteapot teapotlib fltk ${LIB_PORTABLEXDR})
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${LIB_PORTABLEXDR})
endif ()
endif ()
install(TARGETS fteapot DESTINATION bin)

View File

@ -69,37 +69,6 @@ const char *getlabel(const Cell* cell)
return cell->label;
}
/* copytokens -- copy a sequence of tokens, possibly reallocating dest */
static void copytokens(Token*** totoks, Token** fromtoks)
{
size_t from_len = tveclen(fromtoks);
if (from_len == 0)
{
tvecfree(*totoks);
*totoks = EMPTY_TVEC;
return;
}
size_t to_len = tveclen(*totoks);
if (from_len > to_len || *totoks == fromtoks)
{
if (*totoks != fromtoks) tvecfree(*totoks);
*totoks = malloc((from_len+1)*sizeof(Token*));
(*totoks)[from_len] = NULLTOKEN;
} else {
tvecfreetoks(*totoks);
}
for (size_t i = 0; i<from_len; ++i) /* destination already has NULLTOKEN at end */
{
if (fromtoks[i] == NULLTOKEN) (*totoks)[i] = NULLTOKEN;
else
{
(*totoks)[i] = malloc(sizeof(Token));
*((*totoks)[i]) = tcopy(*(fromtoks[i]));
}
}
}
/* freecellcontents -- free the resources of the cell at destruction time */
void freecellcontents(Cell *faded)
{

View File

@ -87,7 +87,8 @@ const char *savecontext(Sheet *sheet, const char *name, int body,
if (w[X] > beg[X] && fputs_close("\\NC", fp) == EOF)
return strerror(errno);
Location mw; LOCATION_GETS(mw, w);
for (++(mw[X]); mw[X] < sheet->dimx && shadowed(sheet, mw); ++(mw[X]));
for (++(mw[X]); ((size_t)mw[X]) < sheet->dim[X] && shadowed(sheet, mw);
++(mw[X]));
int multicols = mw[X] - w[X];
if (multicols > 1) fprintf(fp,"\\use{%d}", multicols);
Style cs = getstyle(sheet, w);

View File

@ -117,23 +117,21 @@ FltT csv_double(const char *s, const char **end)
/* csv_string -- convert almost any string to string */ /*{{{*/
char *csv_string(const char *s, const char **end)
{
static char *string;
static int strings,stringsz;
assert(s!=(const char*)0);
assert(end!=(const char**)0);
strings=0;
stringsz=0;
string=(char*)0;
if (!isprint((int)*s) || (!semicol && *s==',') || (semicol && *s==';')) return (char*)0;
assert(s != NULL);
assert(end != (const char**)0);
size_t strings = 0;
size_t stringsz = 0;
char * string = NULL;
if (!isprint((int)*s) || (!semicol && *s == ',') || (semicol && *s == ';'))
return NULL;
if (*s=='"')
{
++s;
while (*s!='\0' && *s!='\n' && *s!='"')
{
if ((strings+2)>=stringsz)
if ((strings+2) >= stringsz)
{
string=realloc(string,stringsz+=32);
string = realloc(string, stringsz += 32);
}
string[strings]=*s;
++strings;

View File

@ -45,8 +45,9 @@ Token tcopy(Token n)
case FUNCALL:
if (n.u.funcall.argc > 0)
{
result.u.funcall.argv = malloc(n.u.funcall.argc*sizeof(Token));
for (size_t ai = 0; ai < n.u.funcall.argc; ++ai)
result.u.funcall.argv =
malloc(((unsigned int)n.u.funcall.argc)*sizeof(Token));
for (int ai = 0; ai < n.u.funcall.argc; ++ai)
result.u.funcall.argv[ai] = tcopy(n.u.funcall.argv[ai]);
} else result.u.funcall.argv = NULLTOKEN;
break;
@ -89,7 +90,7 @@ void tfree_protected(Token *n, const Token dontfree)
if (difftype || n->u.funcall.argv != dontfree.u.funcall.argv)
{
for (int ai = n->u.funcall.argc-1; ai >= 0; --ai)
if (n->u.funcall.fident = FUNC_AND && ai > 0
if (n->u.funcall.fident == FUNC_AND && ai > 0
&& n->u.funcall.argv[ai].type == FUNCALL
&& n->u.funcall.argv[ai-1].type == FUNCALL
&& n->u.funcall.argv[ai].u.funcall.argc == 2
@ -280,17 +281,16 @@ Token tadd(Token l, Token r)
Token tconcat(Token l, Token r)
{
/* variables */ /*{{{*/
static int conc_buf_len = 1024;
static size_t conc_buf_len = 4096;
Token result;
char buf[conc_buf_len];
const char *buferr = _("Internal string concatenation buffer too small");
int len;
/*}}}*/
if (l.type == EEK) return tcopy(l);
if (r.type == EEK) return tcopy(r);
len = printtok(buf, conc_buf_len, 0, DIRECT_STRING,
DEF_FLOATFORM, def_precision, TRUNCATED_ERROR, &l);
size_t len = printtok(buf, conc_buf_len, 0, DIRECT_STRING, DEF_FLOATFORM,
def_precision, TRUNCATED_ERROR, &l);
if (len > conc_buf_len - 2)
{
duperror(&result, buferr);
@ -380,13 +380,13 @@ Token tdiv(Token l, Token r)
return result;
}
/*}}}*/
if (l.type == EMPTY && TOKISNUM(r))
if (r.type == INT)
{
if (l.type == EMPTY && TOKISNUM(r)) {
if (r.type == INT) {
result.type = INT; result.u.integer = 0; return result;
} else {
result.type = FLOAT; result.u.flt = 0.0; return result;
}
}
if (l.type==INT && r.type==INT)
/* result is quotient of left int and right int */ /*{{{*/
{
@ -445,13 +445,13 @@ Token tmod(Token l, Token r)
duperror(&result, _("modulo 0"));
return result;
}
if (l.type == EMPTY && TOKISNUM(r))
if (r.type == INT)
{
if (l.type == EMPTY && TOKISNUM(r)) {
if (r.type == INT) {
result.type = INT; result.u.integer = 0; return result;
} else {
result.type = FLOAT; result.u.flt = 0.0; return result;
}
}
if (l.type == INT && r.type == INT) /* result is remainder of left int and right int */ /*{{{*/
{
result.type = INT;
@ -567,17 +567,33 @@ Token tmul(Token l, Token r)
else if (l.type == LOCATION && r.type == INT)
/* result is each component of location times right */ /*{{{*/
{
if (r.u.integer < COORD_MIN || r.u.integer > COORD_MAX) {
result.type = EEK;
const char* templ =
_("Attempt to multiply Location by out of range int: " INT_T_FMT);
result.u.err = malloc(strlen(templ) + 64);
sprintf(result.u.err, templ, r.u.integer);
return result;
}
result.type = LOCATION;
for (Dimensions dim = X; dim < HYPER; ++dim)
result.u.location[dim] = l.u.location[dim] * r.u.integer;
result.u.location[dim] = l.u.location[dim] * (CoordT)r.u.integer;
}
/*}}}*/
else if (l.type == INT && r.type == LOCATION)
/* result is each component of right location times left */ /*{{{*/
{
if (l.u.integer < COORD_MIN || l.u.integer > COORD_MAX) {
result.type = EEK;
const char* templ =
_("Attempt to multiply Location by out of range int: " INT_T_FMT);
result.u.err = malloc(strlen(templ) + 64);
sprintf(result.u.err, templ, l.u.integer);
return result;
}
result.type = LOCATION;
for (Dimensions dim = X; dim < HYPER; ++dim)
result.u.location[dim] = l.u.integer * r.u.location[dim];
result.u.location[dim] = r.u.location[dim] * (CoordT)l.u.integer;
}
/*}}}*/
else if (l.type == LOCATION && r.type == LOCATION)
@ -593,9 +609,8 @@ Token tmul(Token l, Token r)
|| (l.type == STRING && r.type == INT))
/* result is n copies of string concatenated together */ /*{{{*/
{
int copies;
IntT copies;
char *pat;
char *newval = NULL;
if (l.type == INT)
{
copies = l.u.integer; pat = strdup(r.u.string);
@ -610,16 +625,17 @@ Token tmul(Token l, Token r)
{
char *tmp = strdup(pat);
int j = 0;
for (int i = len - 1; i >= 0; --i, ++j) tmp[j] = pat[i];
for (int i = (int)len - 1; i >= 0; --i, ++j) tmp[j] = pat[i];
free(pat);
pat = tmp;
copies = -copies;
}
result.type = STRING;
result.u.string = malloc(len * copies + 1);
for (size_t c = 0; c < copies; ++c)
result.u.string = malloc(len * (size_t)copies + 1);
for (size_t c = 0; c < (size_t)copies; ++c)
strcpy(result.u.string + c*len, pat);
result.u.string[copies*len] = '\0';
result.u.string[len*(size_t)copies] = '\0';
free(pat);
}
}
else return operand_type_error(cntxt, l.type, r.type);
@ -669,12 +685,13 @@ Token tpow(Token l, Token r)
&& ((r.type == INT && r.u.integer >= 0) || r.type == EMPTY))
/* int^int, return int or error if 0^0 */ /*{{{*/
{
IntT x,y;
IntT x;
UIntT y;
if (l.type == EMPTY) x=0;
if (l.type == EMPTY) x = 0;
else x = l.u.integer;
if (r.type == EMPTY) y=0;
else y = r.u.integer;
if (r.type == EMPTY) y = 0;
else y = (UIntT)r.u.integer;
if (x == 0 && y == 0) duperror(&result, _("0^0 is not defined"));
else
{
@ -939,11 +956,11 @@ static bool nearly_equal(FltT a1, FltT a2)
FltT A2 = ABSFLT(a2);
FltT max = A1 > A2 ? A1 : A2;
FltT eps = FLTEPS;
FltT diff = ABSFLT(a1-a2);
FltT diff = ABSFLT(a1 - a2);
FltT thelog = LOG2FLT(max);
int expn = thelog;
int expn = (int)thelog;
FltT scale = POWFLT(2.0, expn);
return ABSFLT(a1 - a2) <= eps * scale;
return diff <= eps * scale;
}
/* tabouteq -- ~= operator */ /*{{{*/

View File

@ -33,7 +33,10 @@ extern char *strdup(const char* s);
#include "parser.h"
#include "scanner.h"
#include "sheet.h"
#include "style.h"
#include "token.h"
/*}}}*/
/* #defines */ /*{{{*/
/* There is a BSD extensions, but they are possibly more exact. */
#ifdef M_E
@ -396,10 +399,18 @@ static Token adr_func(FunctionIdentifier self, int argc, const Token argv[])
while (i < argc && i - offset < HYPER)
{
if (argv[i].type == EEK) return argv[i];
if (argv[i].type == INT)
if (absolute) result.u.location[i-offset] = argv[i].u.integer;
else result.u.location[i-offset] += argv[i].u.integer;
else if (argv[i].type != EMPTY) break;
if (argv[i].type == INT) {
if (argv[i].u.integer < COORD_MIN || argv[i].u.integer > COORD_MAX) {
const char* templ = _("Attempt to use out-of-range coordinate ("
INT_T_FMT ") in Location");
result.type = EEK;
result.u.err = malloc(strlen(templ) + 64);
sprintf(result.u.err, templ, argv[i].u.integer);
return result;
}
if (absolute) result.u.location[i-offset] = (CoordT)argv[i].u.integer;
else result.u.location[i-offset] += (CoordT)argv[i].u.integer;
} else if (argv[i].type != EMPTY) break;
++i;
}
if (i < argc) {
@ -510,9 +521,9 @@ static Token dim_func(FunctionIdentifier self, int argc, const Token argv[])
/*}}}*/
return result;
}
/*}}}/
/*}}}*/
/* find_macro -- search for a cell satisfying some expression */ /*{{{*/
/* find_macro -- search for a cell satisfying some expression */ /*{{{*/
static Token find_macro(FunctionIdentifier self, int argc, const Token argv[])
{
const char *usage = _("Usage: find(expr, loc_stride[, loc_start])");
@ -564,13 +575,13 @@ static Token find_macro(FunctionIdentifier self, int argc, const Token argv[])
static Token bit_func(FunctionIdentifier self, int argc, const Token argv[])
{
Token result;
int accum;
IntT accum;
if (self == FUNC_BITAND) accum = -1;
else accum = 0;
for (size_t i = 0; i < argc; ++i) {
for (int i = 0; i < argc; ++i) {
if (!INTPATIBLE(argv[i]))
return duperror(&result, _("Bitwise functions need integer arguments."));
int val = 0;
IntT val = 0;
if (argv[i].type == INT) val = argv[i].u.integer;
if (self == FUNC_BITAND) accum = accum & val;
else accum = accum | val;
@ -598,6 +609,7 @@ static Token constant_func(FunctionIdentifier fi, int argc, const Token argv[])
result.type = EEK;
result.u.err = malloc(strlen(usage) + MAX_FUNC_NAME_LENGTH + 1);
sprintf(result.u.err, usage, tfunc[fi].name);
return result;
}
/*}}}*/
@ -856,7 +868,7 @@ static Token string_func(FunctionIdentifier self, int argc, const Token argv[])
{
/* variables */ /*{{{*/
Token result, arg;
int precision = def_precision;
PrecisionLevel precision = def_precision;
bool ff = DEF_FLOATFORM;
bool bad_args = false;
char staticbuf[4096];
@ -877,7 +889,18 @@ static Token string_func(FunctionIdentifier self, int argc, const Token argv[])
}
/* FALL THROUGH */
case 2:
if (argv[1].type == INT) precision = argv[1].u.integer;
if (argv[1].type == INT) {
if (argv[1].u.integer < MIN_PRECISION || argv[1].u.integer > MAX_PRECISION)
{
const char *templ = _("Integer value (" INT_T_FMT
") out of range for precision value");
result.type = EEK;
result.u.err = malloc(strlen(templ) + 64);
sprintf(result.u.err, templ, argv[1].u.integer);
return result;
}
precision = (PrecisionLevel)argv[1].u.integer;
}
else if (argv[1].type != EMPTY) bad_args = true; break;
/* FALL THROUGH */
case 1:
@ -893,7 +916,7 @@ static Token string_func(FunctionIdentifier self, int argc, const Token argv[])
return duperror(&result, staticbuf);
}
result.type = STRING;
size_t size = printtok(staticbuf, sizeof(staticbuf), -1, DIRECT_STRING, ff,
size_t size = printtok(staticbuf, sizeof(staticbuf), 0, DIRECT_STRING, ff,
precision, VERBOSE_ERROR, &arg);
tfree(&arg);
if (size > sizeof(staticbuf) - 2)
@ -984,9 +1007,17 @@ static Token precision_func(FunctionIdentifier self,
Token result;
if (argc != 1 || argv[0].type != INT)
return duperror(&result, _("Usage: precision(int)"));
if (argv[0].u.integer < MIN_PRECISION || argv[1].u.integer > MAX_PRECISION) {
const char *templ = _("Integer value (" INT_T_FMT
") out of range for precision value");
result.type = EEK;
result.u.err = malloc(strlen(templ) + 64);
sprintf(result.u.err, templ, argv[0].u.integer);
return result;
}
result.type = STYLE;
clearstyle(&(result.u.style));
result.u.style.precision = argv[0].u.integer;
result.u.style.precision = (PrecisionLevel)argv[0].u.integer;
return result;
}
/*}}}*/
@ -1004,9 +1035,17 @@ static Token aspect_func(FunctionIdentifier self, int argc, const Token argv[])
sprintf(result.u.err, templ, tfunc[self].name);
return result;
}
if (argv[0].u.integer < NO_COLOR_SET || argv[1].u.integer > MAX_MAX_COLORS) {
const char *templ = _("Integer value (" INT_T_FMT
") out of range for color number");
result.type = EEK;
result.u.err = malloc(strlen(templ) + 64);
sprintf(result.u.err, templ, argv[0].u.integer);
return result;
}
result.type = STYLE;
clearstyle(&(result.u.style));
result.u.style.aspect[ca] = argv[0].u.integer;
result.u.style.aspect[ca] = (ColorNum)argv[0].u.integer;
return result;
}
/*}}}*/
@ -1328,8 +1367,8 @@ static Token len_func(FunctionIdentifier self, int argc, const Token argv[])
if (argc==1 && argv[0].type==STRING)
/* result is length */ /*{{{*/
{
result.type=INT;
result.u.integer=strlen(argv[0].u.string);
result.type = INT;
result.u.integer = (IntT)strlen(argv[0].u.string);
}
/*}}}*/
else duperror(&result, _("Usage: len(string)"));
@ -1510,12 +1549,12 @@ static Token poly_func(FunctionIdentifier self, int argc, const Token argv[])
result.type = EMPTY;
if (argc < 2) return duperror(&result, usage);
for (size_t i = 0; i < argc; ++i)
for (int i = 0; i < argc; ++i)
if (argv[i].type != INT && argv[i].type != FLOAT)
return duperror(&result, usage);
result = tcopy(argv[1]);
for (size_t i = 2; i < argc; ++i)
for (int i = 2; i < argc; ++i)
{
tmp = tmul(result,argv[0]);
tfree_protected(&result, tmp);
@ -1531,7 +1570,7 @@ static Token poly_func(FunctionIdentifier self, int argc, const Token argv[])
static Token sci_disp(FunctionIdentifier self, int argc, const Token argv[])
{
FltT (*fsci)(FltT);
FltT (*fsci)(FltT) = NULL;
switch (self) {
case FUNC_SQRT: fsci = SQRTFLT; break;
case FUNC_SIN: fsci = SINFLT; break;
@ -1603,14 +1642,14 @@ static Token substr_func(FunctionIdentifier self, int argc, const Token argv[])
{
char ss[1024];
int b = argv[1].u.integer;
int l = strlen(argv[0].u.string);
int e = l;
IntT b = argv[1].u.integer;
IntT l = (IntT)strlen(argv[0].u.string);
IntT e = l;
if (argc == 3) e = argv[2].u.integer;
if ( b < 0 ) b = 0;
if ( b > l ) b = l;
if ( e > l ) e = l;
int n = e - b + 1;
int n = (int)(e - b + 1);
if ( n >= 1024 ) n = 1024 - 1;
if (n > 0) {
ss[n] = '\0';
@ -1619,7 +1658,7 @@ static Token substr_func(FunctionIdentifier self, int argc, const Token argv[])
result.u.string=strdup(ss);
}
else {
result.type=EMPTY;
result.type = EMPTY;
}
}
else duperror(&result, usage);

View File

@ -28,31 +28,24 @@ const char *savehtml(Sheet *sheet, const char *name, int body,
const Location beg, const Location end,
unsigned int *count)
{
/* variables */ /*{{{*/
FILE *fp=(FILE*)0; /* cause runtime error */
Location w;
char buf[1024];
char num[20];
char fullname[PATH_MAX];
Cell *cell;
/*}}}*/
/* asserts */ /*{{{*/
assert(sheet != (Sheet*)0);
assert(name != (const char*)0);
/*}}}*/
*count=0;
assert(name != NULL);
*count = 0;
Location w;
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(sheet, w)) return _("Shadowed cells in first column");
if (!body && (fp=fopen(name,"w"))==(FILE*)0) return strerror(errno);
FILE *fp = (FILE*)0; /* cause runtime error */
if (!body && (fp = fopen(name,"w")) == (FILE*)0) return strerror(errno);
for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z]))
{
if (body) /* open new file */ /*{{{*/
{
char num[20];
sprintf(num, ".%d", w[Z]);
char fullname[PATH_MAX];
fullname[sizeof(fullname)-strlen(num)-1]='\0';
(void)strncpy(fullname,name,sizeof(fullname)-strlen(num)-1);
fullname[sizeof(fullname)-1]='\0';
@ -72,7 +65,8 @@ const char *savehtml(Sheet *sheet, const char *name, int body,
for (w[X]=beg[X]; w[X]<=end[X]; )
{
Location mw; LOCATION_GETS(mw, w);
for (++(mw[X]); mw[X] < sheet->dimx && shadowed(sheet, mw); ++(mw[X]));
for (++(mw[X]); (size_t)(mw[X]) < sheet->dim[X] && shadowed(sheet, mw);
++(mw[X]));
int multicols = mw[X] - w[X];
if (multicols > 1) fprintf(fp,"<td colspan=%d",multicols);
else fprintf(fp,"<td");
@ -84,6 +78,7 @@ const char *savehtml(Sheet *sheet, const char *name, int body,
case CENTER: if (fputs_close(" align=center>",fp)==EOF) return strerror(errno); break;
default: assert(0);
}
char buf[1024];
printvalue(buf, sizeof(buf), 0, DIRECT_STRING, cs.fform, cs.precision,
sheet, w);
if (cs.transparent)

View File

@ -28,33 +28,25 @@ const char *savelatex(Sheet *sheet, const char *name, int body,
const Location beg, const Location end,
unsigned int *count)
{
/* variables */ /*{{{*/
FILE *fp=(FILE*)0; /* cause runtime error */
Location w;
char buf[1024];
char num[20];
char fullname[PATH_MAX];
Cell *cell;
/*}}}*/
/* asserts */ /*{{{*/
assert(sheet != (Sheet*)0);
assert(name != (const char*)0);
/*}}}*/
assert(name != NULL);
*count=0;
Location w;
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(sheet, w)) return _("Shadowed cells in first column");
FILE *fp = (FILE*)0; /* cause runtime error */
if (!body && (fp=fopen(name,"w"))==(FILE*)0) return strerror(errno);
for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z]))
{
if (body)
/* open new file */ /*{{{*/
{
char num[20];
sprintf(num, ".%d", w[Z]);
char fullname[PATH_MAX];
fullname[sizeof(fullname)-strlen(num)-1]='\0';
(void)strncpy(fullname,name,sizeof(fullname)-strlen(num)-1);
fullname[sizeof(fullname)-1]='\0';
@ -88,7 +80,8 @@ const char *savelatex(Sheet *sheet, const char *name, int body,
if (w[X] > beg[X] && fputc_close('&', fp) == EOF)
return strerror(errno);
Location mw; LOCATION_GETS(mw,w);
for (mw[X]++; mw[X] < sheet->dimx && shadowed(sheet, mw); mw[X]++);
for (mw[X]++; (size_t)(mw[X]) < sheet->dim[X] && shadowed(sheet, mw);
mw[X]++);
int multicols = mw[X] - w[X];
fprintf(fp, "\\multicolumn{%d}{", multicols);
Style cs = getstyle(sheet, w);
@ -99,6 +92,7 @@ const char *savelatex(Sheet *sheet, const char *name, int body,
case CENTER: if (fputc_close('c',fp)==EOF) return strerror(errno); break;
default: assert(0);
}
char buf[1024];
printvalue(buf, sizeof(buf), 0, DIRECT_STRING, cs.fform, cs.precision,
sheet, w);
if (fputs_close("}{", fp) == EOF) return strerror(errno);

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,8 @@
#ifndef MAIN_H
#define MAIN_H
#include <limits.h>
#include "config.h"
#define _(x) (x)
@ -23,7 +25,9 @@ extern unsigned int batchln;
actions the user has triggered (by whatever means available), or a Unicode
character that was entered
*/
typedef enum {
typedef enum
{
K_MAX = INT_MAX,
K_NONE = 0,
K_INVALID = -1,
K_BACKSPACE = -2,
@ -91,11 +95,11 @@ typedef enum {
K_EDIT_STYLE_EXPR = -64
} Key;
extern int do_sheetcmd(Sheet *cursheet, Key c, int moveonly);
extern int do_sheetcmd(Sheet *cursheet, Key c, bool moveonly);
extern bool doanyway(Sheet *sheet, const char *msg);
extern void moveto(Sheet *sheet, int x, int y, int z);
extern void moveto(Sheet *sheet, CoordT x, CoordT y, CoordT 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, CoordT x, CoordT y, CoordT z);
extern void do_mark(Sheet *cursheet, MarkState ms);
void fillwith(Sheet *she);

View File

@ -47,6 +47,12 @@ void posorder(int *x, int *y)
}
/*}}}*/
/* poscorners -- make the corners of a block be in posorder componentwise */ /*{{{*/
void poscorners(Location a, Location b)
{
for (Dimensions dim = X; dim < HYPER; ++dim) posorder(&(a[dim]), &(b[dim]));
}
/* finite -- return error message about number or null */ /*{{{*/
static volatile int caughtfpe;

View File

@ -10,6 +10,7 @@ extern "C" {
#endif
void posorder(int *x, int *y);
void poscorners(Location a, Location b);
const char *dblfinite(FltT x);
int fputc_close(char c, FILE *fp);
int fputs_close(const char *s, FILE *fp);

View File

@ -52,8 +52,8 @@ static Token full_eval_funcall(Token *t)
if (tfunc[t->u.funcall.fident].eval_as == MACRO)
eval_argv = t->u.funcall.argv;
else {
eval_argv = malloc(t->u.funcall.argc*sizeof(Token));
for (size_t ai = 0; ai < t->u.funcall.argc; ++ai) {
eval_argv = malloc(((size_t)(t->u.funcall.argc))*sizeof(Token));
for (int ai = 0; ai < t->u.funcall.argc; ++ai) {
eval_argv[ai] = evaltoken(t->u.funcall.argv[ai], FULL);
}
}
@ -61,7 +61,7 @@ static Token full_eval_funcall(Token *t)
if (tfunc[t->u.funcall.fident].eval_as == FUNCT) {
/* To allow a function to return one of its arguments, we need
to be sure not to free that argument: */
for (size_t ai = 0; ai < t->u.funcall.argc; ++ai)
for (int ai = 0; ai < t->u.funcall.argc; ++ai)
tfree_protected(&eval_argv[ai], result);
free(eval_argv);
}
@ -185,13 +185,13 @@ static Token primary(Token *n[], int *i, EvalMethod meth)
} else {
argv[argc] = term(n, i, meth);
if (argv[argc].type == EEK) {
for (size_t pa = 0; pa < argc; +pa) tfree(argv + pa);
for (int pa = 0; pa < argc; ++pa) tfree(argv + pa);
return argv[argc];
}
}
} else {
duperror(&result, _("too many arguments"));
for (size_t j=0; j < argc; ++j) tfree(&argv[j]);
for (int j=0; j < argc; ++j) tfree(&argv[j]);
return result;
}
++argc;
@ -202,7 +202,7 @@ static Token primary(Token *n[], int *i, EvalMethod meth)
if (n[*i] == NULLTOKEN || n[*i]->type != OPERATOR || n[*i]->u.op != CP)
/* ) expected */ /*{{{*/
{
for (size_t j = 0; j < argc; ++j) tfree(&argv[j]);
for (int j = 0; j < argc; ++j) tfree(&argv[j]);
duperror(&result, _(") expected"));
return result;
}
@ -213,7 +213,7 @@ static Token primary(Token *n[], int *i, EvalMethod meth)
result = tfuncall(fident, argc, argv);
/* To allow a function to return one of its arguments, we need
to be sure not to free that argument: */
for (size_t j = 0; j < argc; ++j) tfree_protected(&argv[j], result);
for (int j = 0; j < argc; ++j) tfree_protected(&argv[j], result);
return result;
}
result.type = FUNCALL;
@ -221,8 +221,8 @@ static Token primary(Token *n[], int *i, EvalMethod meth)
result.u.funcall.argc = argc;
if (argc > 0)
{
result.u.funcall.argv = malloc(argc*sizeof(Token));
for (size_t ai = 0; ai < argc; ++ai)
result.u.funcall.argv = malloc(((size_t)argc)*sizeof(Token));
for (int ai = 0; ai < argc; ++ai)
result.u.funcall.argv[ai] = argv[ai];
} else result.u.funcall.argv = NULLTOKEN;
return result;
@ -352,6 +352,8 @@ static Token powterm(Token *n[], int *i, EvalMethod meth)
if (meth == FULL)
{
Token result;
result.type = EEK;
result.u.err = strdup(_("Internal error, should not happen."));
switch (op)
{
case MUL: result = tmul(l,r); break;

View File

@ -211,7 +211,6 @@ const char *loadsc(Sheet *sheet, const char *name)
const char *err;
Cell *cell;
Location tmp;
int x,y;
/*}}}*/
if ((fp=fopen(name,"r"))==(FILE*)0) return strerror(errno);
@ -239,25 +238,22 @@ const char *loadsc(Sheet *sheet, const char *name)
Style csty;
clearstyle(&csty);
csty.adjust = RIGHT;
csty.precision = precision;
csty.precision = (PrecisionLevel)precision;
overridestyle(sheet, tmp, csty);
setwidth(sheet, col, 0, colwidth);
setwidth(sheet, col, 0, (ColWidT)colwidth);
}
/*}}}*/
else if (strncmp(buf, "leftstring ", 11) == 0
|| strncmp(buf, "rightstring ", 12) == 0) /* rightstring/leftstring cell = "string" */ /*{{{*/
{
int x,y;
char *s;
Token **contents;
if (strncmp(buf, "leftstring ", 11) == 0) s = buf+11; else s = buf+12;
x = *s++ - 'A';
int x = *s++ - 'A';
if (*s >= 'A' && *s <= 'Z' ) x = x*26 + (*s++ - 'A');
y = *s++ - '0';
int y = *s++ - '0';
while (*s >= '0' && *s <= '9') y = 10*y + (*s++-'0');
s+=3;
contents = scan(&s);
Token **contents = scan(&s);
if (contents == EMPTY_TVEC)
{
tvecfree(contents);
@ -287,8 +283,8 @@ const char *loadsc(Sheet *sheet, const char *name)
{
char newbuf[512];
char *s = buf+4;
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');
int x = *s++-'A'; if (*s >= 'A' && *s <= 'Z') x = x*26 + (*s++-'A');
int y = *s++-'0'; while (*s >= '0' && *s <= '9') y = 10*y + (*s++-'0');
tmp[X] = x; tmp[Y] = y; tmp[Z] = 0;
if (gettok(CELL_ATC(sheet,x,y,0), BASE_CONT).type == EMPTY)
{
@ -334,12 +330,12 @@ const char *loadsc(Sheet *sheet, const char *name)
/* set precisions for each column */ /*{{{*/
Location colhead;
OLOCATION(&colhead);
for (; colhead[X] < sheet->dimx; colhead[X]++)
for (; (size_t)(colhead[X]) < sheet->dim[X]; colhead[X]++)
{
int prec = getprecision(sheet, colhead) == def_precision
PrecisionLevel prec = getprecision(sheet, colhead) == def_precision
? 2 : getprecision(sheet, colhead);
for (y = 1; y < sheet->dimy; ++y) {
Location l; l[X] = x; l[Y] = y; l[Z] = 0;
for (CoordT y = 1; (size_t)y < sheet->dim[Y]; ++y) {
Location l; l[X] = colhead[X]; l[Y] = y; l[Z] = 0;
if (CELL_AT(sheet,l))
setprecision(sheet, l, prec);
}

View File

@ -181,7 +181,7 @@ Token **scan(char **s)
/* compute number of tokens */ /*{{{*/
r = *s;
while (*r == ' ') ++r;
int i = 0;
size_t i = 0;
for (; *r != '\0'; ++i)
{
const char *or;
@ -202,7 +202,7 @@ Token **scan(char **s)
/* store tokens */ /*{{{*/
r = *s;
while (*r==' ') ++r;
for (int j = 0; j < i; ++j)
for (size_t j = 0; j < i; ++j)
{
while (*r == ' ') ++r;
n = charstring(&r);

View File

@ -81,8 +81,8 @@ static void dump_cell(Sheet *sheet, int x, int y, int z)
}
if (!LOC_WITHINC(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);
printf("TEADUMP: Requested cell &(%d,%d,%d) outside sheet dims %zu,%zu,%zu.\n",
x, y, z, sheet->dim[X], sheet->dim[Y], sheet->dim[Z]);
return;
}
c = CELL_ATC(sheet, x, y, z);
@ -120,23 +120,23 @@ void dump_current_cell(Sheet *sheet)
/*}}}*/
/* 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)
static void swapblock(Sheet *sheet1, Location l1, Sheet *sheet2, Location l2,
Location dist)
{
int xoff, yoff, zoff;
assert(sheet1!=(Sheet*)0);
assert(sheet2!=(Sheet*)0);
resize(sheet1, x1+xdist-1, y1+ydist-1, z1+zdist-1, NULL);
resize(sheet2, x2+xdist-1, y2+ydist-1, z2+zdist-1, NULL);
for (xoff=0; xoff<xdist; ++xoff)
for (yoff=0; yoff<ydist; ++yoff)
for (zoff=0; zoff<zdist; ++zoff)
assert(sheet1 != (Sheet*)0);
assert(sheet2 != (Sheet*)0);
resize(sheet1, l1[X]+dist[X]-1, l1[Y]+dist[Y]-1, l1[Z]+dist[Z]-1, NULL);
resize(sheet2, l2[X]+dist[X]-1, l2[Y]+dist[Y]-1, l2[Z]+dist[Z]-1, NULL);
Location off;
for (off[Z] = 0; off[Z] < dist[Z]; off[Z]++)
for (off[Y] = 0; off[Y] < dist[Y]; off[Y]++)
for (off[X] = 0; off[X] < dist[X]; off[X]++)
{
Cell *t;
t = CELL_ATC(sheet1,x1+xoff,y1+yoff,z1+zoff);
CELL_ATC(sheet1,x1+xoff,y1+yoff,z1+zoff) = CELL_ATC(sheet2,x2+xoff,y2+yoff,z2+zoff);
CELL_ATC(sheet2,x2+xoff,y2+yoff,z2+zoff) = t;
Location a; LOCATION_GETS(a,l1); LOCATION_ADD(a,off);
Cell *t = CELL_AT(sheet1, a);
Location b; LOCATION_GETS(b,l2); LOCATION_ADD(b,off);
CELL_AT(sheet1,a) = CELL_AT(sheet2,b);
CELL_AT(sheet2,b) = t;
}
sheet1->changed = true;
sheet2->changed = true;
@ -174,15 +174,17 @@ than second, 0 if they are equal and 1 if the first is bigger than the
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)
static int cmpcell(Sheet *sheet1, const Location l1,
Sheet *sheet2, const Location l2, int sortkey)
{
int ascending = (sortkey & ASCENDING) ? 1 : -1;
Token leftval = gettok(safe_cell_atc(sheet1, x1, y1, z1), CURR_VAL);
Token rightval = gettok(safe_cell_atc(sheet2, x2, y2, z2), CURR_VAL);
Token leftval = gettok(safe_cell_at(sheet1, l1), CURR_VAL);
Token rightval = gettok(safe_cell_at(sheet2, l2), CURR_VAL);
/* empty cells are smaller than any non-empty cell */ /*{{{*/
if (leftval.type == EMPTY)
if (leftval.type == EMPTY) {
if (rightval.type == EMPTY) return 0;
else return -ascending;
}
if (rightval.type == EMPTY) return ascending;
/*}}}*/
switch (leftval.type)
@ -221,9 +223,9 @@ void initialize_sheet(Sheet *sheet) {
assert(sheet != (Sheet*)0);
OLOCATION(sheet->cur);
sheet->offx = sheet->offy = 0;
sheet->dimx = sheet->dimy = sheet->dimz = 0;
sheet->dim[X] = sheet->dim[Y] = sheet->dim[Z] = 0;
sheet->sheet = (Cell**)0;
sheet->column = (int*)0;
sheet->column = (ColWidT*)0;
sheet->orix = sheet->oriy = 0;
sheet->maxx = sheet->maxy = 0;
sheet->name = (char*)0;
@ -244,26 +246,24 @@ void initialize_sheet(Sheet *sheet) {
/*}}}*/
/* resize -- check if sheet needs to be resized in any dimension */ /*{{{*/
void resize(Sheet *sheet, int x, int y, int z, bool *qextended)
void resize(Sheet *sheet, CoordT x, CoordT y, CoordT z, bool *qextended)
{
assert(x>=0);
assert(y>=0);
assert(z>=0);
assert(sheet!=(Sheet*)0);
assert(x >= 0);
assert(y >= 0);
assert(z >= 0);
assert(sheet != (Sheet*)0);
if (!LOC_WITHINC(sheet,x,y,z))
{
/* variables */ /*{{{*/
Sheet dummy;
/*}}}*/
sheet->changed = true;
if (qextended) *qextended = true;
dummy.dimx = (x >= sheet->dimx ? x+1 : sheet->dimx);
dummy.dimy = (y >= sheet->dimy ? y+1 : sheet->dimy);
dummy.dimz = (z >= sheet->dimz ? z+1 : sheet->dimz);
dummy.dim[X] = ((size_t)x >= sheet->dim[X] ? (size_t)(x+1) : sheet->dim[X]);
dummy.dim[Y] = ((size_t)y >= sheet->dim[Y] ? (size_t)(y+1) : sheet->dim[Y]);
dummy.dim[Z] = ((size_t)z >= sheet->dim[Z] ? (size_t)(z+1) : sheet->dim[Z]);
/* allocate new sheet */ /*{{{*/
dummy.sheet = malloc(dummy.dimx*dummy.dimy*dummy.dimz*sizeof(Cell*));
dummy.sheet = malloc(dummy.dim[X]*dummy.dim[Y]*dummy.dim[Z]*sizeof(Cell*));
for (ALL_COORDS_IN_SHEETC(&dummy,x,y,z))
{
if (LOC_WITHINC(sheet,x,y,z)) CELL_ATC(&dummy,x,y,z) = CELL_ATC(sheet,x,y,z);
@ -273,22 +273,24 @@ void resize(Sheet *sheet, int x, int y, int z, bool *qextended)
sheet->sheet = dummy.sheet;
/*}}}*/
/* allocate new columns */ /*{{{*/
if (x>sheet->dimx || z>=sheet->dimz)
if ((size_t)x > sheet->dim[X] || (size_t)z >= sheet->dim[Z])
{
dummy.column=malloc(dummy.dimx*dummy.dimz*sizeof(int));
for (x=0; x<dummy.dimx; ++x) for (z=0; z<dummy.dimz; ++z)
{
if (x<sheet->dimx && z<sheet->dimz)
*(dummy.column+x*dummy.dimz+z)=*(sheet->column+x*sheet->dimz+z);
else *(dummy.column+x*dummy.dimz+z)=DEF_COLUMNWIDTH;
}
if (sheet->column!=(int*)0) free(sheet->column);
dummy.column = malloc(dummy.dim[X] * dummy.dim[Z] * sizeof(ColWidT));
for (x=0; (size_t)x < dummy.dim[X]; ++x)
for (z=0; (size_t)z < dummy.dim[Z]; ++z)
{
if ((size_t)x < sheet->dim[X] && (size_t)z < sheet->dim[Z])
*(dummy.column + ((size_t)x)*dummy.dim[Z] + (size_t)z)
= *(sheet->column + ((size_t)x)*sheet->dim[Z] + z);
else
*(dummy.column + ((size_t)x)*dummy.dim[Z] + (size_t)z)
= DEF_COLUMNWIDTH;
}
if (sheet->column != (ColWidT*)0) free(sheet->column);
sheet->column = dummy.column;
}
/*}}}*/
sheet->dimx = dummy.dimx;
sheet->dimy = dummy.dimy;
sheet->dimz = dummy.dimz;
for (Dimensions dd = X; dd < HYPER; ++dd) sheet->dim[dd] = dummy.dim[dd];
}
}
/*}}}*/
@ -367,9 +369,7 @@ void cachelabels(Sheet *sheet)
for (ALL_LOCS_IN_SHEET(sheet,w))
/* cache all labels */ /*{{{*/
{
const char *l;
l = getlabel(CELL_AT(sheet,w));
const char *l = getlabel(CELL_AT(sheet,w));
if (*l)
{
unsigned long hx;
@ -394,63 +394,38 @@ void cachelabels(Sheet *sheet)
/* freesheet -- free all cells of an entire spread sheet */ /*{{{*/
void freesheet(Sheet *sheet, int all)
{
/* variables */ /*{{{*/
assert(sheet != (Sheet*)0);
sheet->changed = FALSE;
Location w;
/*}}}*/
assert(sheet!=(Sheet*)0);
sheet->changed=0;
for (ALL_LOCS_IN_SHEET(sheet,w))
{
freecellofsheet(sheet,w);
}
for (ALL_LOCS_IN_SHEET(sheet,w)) freecellofsheet(sheet,w);
if (all)
{
int i;
for (i=0; i<LABEL_CACHE; ++i) /* free all buckets */ /*{{{*/
{
struct Label *run;
for (run=sheet->labelcache[i]; run!=(struct Label*)0;)
{
struct Label *runnext;
runnext=run->next;
for (int i=0; i < LABEL_CACHE; ++i) /* free all buckets */ /*{{{*/
for (struct Label *run = sheet->labelcache[i]; run != (struct Label*)0;) {
struct Label *runnext = run->next;
free(run);
run=runnext;
}
}
/*}}}*/
run = runnext;
} /*}}}*/
if (sheet->sheet) free(sheet->sheet);
if (sheet->column) free(sheet->column);
if (sheet->name) free(sheet->name);
if (!batch)
{
display_end(sheet);
}
}
else
{
int x,z;
for (x=0; x<sheet->dimx; ++x) for (z=0; z<sheet->dimz; ++z)
{
*(sheet->column+x*sheet->dimz+z)=DEF_COLUMNWIDTH;
}
if (!batch) display_end(sheet);
} else {
for (size_t x = 0; x < sheet->dim[X]; ++x)
for (size_t z = 0; z < sheet->dim[Z]; ++z)
*(sheet->column + x*sheet->dim[Z] + z) = DEF_COLUMNWIDTH;
cachelabels(sheet);
forceupdate(sheet);
}
}
/*}}}*/
/* forceupdate -- clear all clock and update flags */ /*{{{*/
void forceupdate(Sheet *sheet)
{
int i;
Cell *cell;
assert(sheet!=(Sheet*)0);
assert(sheet != (Sheet*)0);
if (sheet->sheet == (Cell **)0) return;
size_t i; Cell *cell;
for (ALL_CELLS_IN_SHEET(sheet,i,cell))
if (cell != NULLCELL) {
cell->updated = cell->clock_t0 = cell->clock_t1 = cell->clock_t2 = false;
@ -476,22 +451,23 @@ void freecellofsheet(Sheet *sheet, const Location at)
/*}}}*/
/* columnwidth -- get width of column */ /*{{{*/
int columnwidth(Sheet *sheet, int x, int z)
ColWidT columnwidth(Sheet *sheet, CoordT x, CoordT z)
{
assert(sheet!=(Sheet*)0);
if (x<sheet->dimx && z<sheet->dimz) return (*(sheet->column+x*sheet->dimz+z));
if ((size_t)x < sheet->dim[X] && (size_t)z < sheet->dim[Z])
return (*(sheet->column + ((size_t)x)*sheet->dim[Z] + (size_t)z));
else return DEF_COLUMNWIDTH;
}
/*}}}*/
/* setwidth -- set width of column */ /*{{{*/
bool setwidth(Sheet *sheet, int x, int z, int width)
bool setwidth(Sheet *sheet, CoordT x, CoordT z, ColWidT width)
{
assert(sheet!=(Sheet*)0);
assert(sheet != (Sheet*)0);
bool isbigger = false;
resize(sheet, x, 1, z, &isbigger);
if (isbigger) sheet->changed = true;
int *storage = sheet->column + x*sheet->dimz + z;
ColWidT *storage = sheet->column + (size_t)x*sheet->dim[Z] + (size_t)z;
if (*storage != width) {
*storage = width;
sheet->changed = true;
@ -502,11 +478,11 @@ bool setwidth(Sheet *sheet, int x, int z, int width)
/*}}}*/
/* cellwidth -- get width of a cell */ /*{{{*/
int cellwidth(Sheet *sheet, const Location at)
ColWidT cellwidth(Sheet *sheet, const Location at)
{
if (shadowed(sheet,at)) return 0;
Location near; LOCATION_GETS(near,at);
int width = columnwidth(sheet,at[X],at[Z]);
ColWidT width = columnwidth(sheet,at[X],at[Z]);
for (near[X]++; shadowed(sheet,near);
width += columnwidth(sheet,near[X]++,near[Z]));
return width;
@ -634,7 +610,7 @@ void update(Sheet *sheet)
}
else if (iterating == 0) ++iterating;
Cell *cell;
int i;
size_t i;
for (ALL_CELLS_IN_SHEET(sheet,i,cell))
{
if (cell && cell->clock_t2)
@ -688,7 +664,8 @@ char *geterror(Sheet *sheet, const Location at)
/* printvalue -- get ASCII representation of value */ /*{{{*/
size_t printvalue(char *s, size_t size, size_t chars, StringFormat sf,
FloatFormat ff, int precision, Sheet *sheet, const Location at)
FloatFormat ff, PrecisionLevel precision,
Sheet *sheet, const Location at)
{
assert(sheet != (Sheet*)0);
Token t = recompvalue(sheet, at);
@ -822,7 +799,7 @@ bool overridestyle(Sheet *sheet, const Location at, Style sty) {
Token fsty; fsty.type = FUNCALL;
fsty.u.funcall.fident = FUNC_PLUS_SYMBOL;
fsty.u.funcall.argc = 2;
fsty.u.funcall.argv = malloc(fsty.u.funcall.argc*sizeof(Token));
fsty.u.funcall.argv = malloc(2*sizeof(Token));
fsty.u.funcall.argv[0] = tsty;
fsty.u.funcall.argv[1] = stok;
thecell->tok[STYLE_CONT] = fsty;
@ -1043,7 +1020,6 @@ const char *savetbl(Sheet *sheet, const char *name, int body,
for (w[X]=beg[X]; w[X]<=end[X]; ++(w[X]))
{
if (w[X] > beg [X] && fputc_close(' ',fp)==EOF) return strerror(errno);
Cell *cw = CELL_AT(sheet,w);
Style sw = getstyle(sheet,w);
if (sw.shadowed && fputc_close('s',fp)==EOF) return strerror(errno);
if (sw.bold && fputc_close('b',fp)==EOF) return strerror(errno);
@ -1068,8 +1044,6 @@ const char *savetbl(Sheet *sheet, const char *name, int body,
if (w[X] > beg[X] && fputc_close('\t',fp)==EOF) return strerror(errno);
if (cw != NULLCELL)
{
char *bufp;
printvalue(buf, sizeof(buf), 0, DIRECT_STRING, sw.fform,
sw.precision, sheet, w);
if (sw.transparent)
@ -1274,14 +1248,14 @@ const char *saveport(Sheet *sheet, const char *name, unsigned int *count)
*count = 0;
if ((fp = fopen(name,"w")) == (FILE*)0) return strerror(errno);
fprintf(fp,"# This is a work sheet generated with teapot %s.\n",VERSION);
for (int z = sheet->dimz - 1; z >= 0; --z)
for (CoordT z = (CoordT)(sheet->dim[Z] - 1); z >= 0; --z)
{
for (int y = sheet->dimy - 1; y >= 0; --y)
for (CoordT y = (CoordT)(sheet->dim[Y] - 1); y >= 0; --y)
{
for (int x = sheet->dimx - 1; x >= 0; --x)
for (CoordT x = (CoordT)(sheet->dim[X] - 1); x >= 0; --x)
{
if (y == 0 && columnwidth(sheet,x,z) != DEF_COLUMNWIDTH)
fprintf(fp,"W%d %d %d\n",x,z,columnwidth(sheet,x,z));
fprintf(fp,"W%d %d %zu\n", x, z, columnwidth(sheet,x,z));
Cell *cell = CELL_ATC(sheet,x,y,z);
if (cell != NULLCELL)
{
@ -1330,7 +1304,7 @@ const char *loadport(Sheet *sheet, const char *name)
while (fgets(buf, sizeof(buf), fp) != NULL)
{
/* remove nl */ /*{{{*/
int width = strlen(buf);
size_t width = strlen(buf);
if (width > 0 && buf[width-1] == '\n') buf[--width] = '\0';
/*}}}*/
switch (buf[0])
@ -1346,29 +1320,29 @@ const char *loadport(Sheet *sheet, const char *name)
/* parse x y and z */ /*{{{*/
const char *os = buf + 1;
char *ns = buf + 1;
loc[X] = strtol(os, &ns, 0);
if (os==ns)
{
sprintf(errbuf,_("Parse error for x position in line %d"),line);
err=errbuf;
goto eek;
}
while (*ns==' ') ++ns;
os=ns;
loc[Y] = strtol(os, &ns, 0);
if (os==ns)
{
sprintf(errbuf,_("Parse error for y position in line %d"),line);
err=errbuf;
goto eek;
}
while (*ns==' ') ++ns;
os=ns;
loc[Z] = strtol(os, &ns, 0);
loc[X] = (CoordT)strtol(os, &ns, 0);
if (os == ns)
{
sprintf(errbuf,_("Parse error for z position in line %d"),line);
err=errbuf;
sprintf(errbuf, _("Parse error for x position in line %d"), line);
err = errbuf;
goto eek;
}
while (*ns == ' ') ++ns;
os = ns;
loc[Y] = (CoordT)strtol(os, &ns, 0);
if (os == ns)
{
sprintf(errbuf, _("Parse error for y position in line %d"), line);
err = errbuf;
goto eek;
}
while (*ns == ' ') ++ns;
os=ns;
loc[Z] = (CoordT)strtol(os, &ns, 0);
if (os == ns)
{
sprintf(errbuf, _("Parse error for z position in line %d"), line);
err = errbuf;
goto eek;
}
/*}}}*/
@ -1419,13 +1393,12 @@ const char *loadport(Sheet *sheet, const char *name)
/* L -- label */ /*{{{*/
case 'L':
{
char buf[1024],*p;
p=buf;
char lbuf[1024];
char *p = lbuf;
++ns;
while (*ns && *ns!=' ') { *p=*ns; ++p; ++ns; }
*p='\0';
loaded.label=strdup(buf);
while (*ns && *ns!=' ') { *p = *ns; ++p; ++ns; }
*p = '\0';
loaded.label = strdup(lbuf);
break;
}
/*}}}*/
@ -1434,11 +1407,12 @@ const char *loadport(Sheet *sheet, const char *name)
{
os=++ns;
loaded.tok[STYLE_CONT].type = STYLE;
loaded.tok[STYLE_CONT].u.style.precision = strtol(os, &ns, 0);
if (os==ns)
loaded.tok[STYLE_CONT].u.style.precision =
(PrecisionLevel)strtol(os, &ns, 0);
if (os == ns)
{
sprintf(errbuf,_("Parse error for precision in line %d"),line);
err=errbuf;
sprintf(errbuf, _("Parse error for precision in line %d"), line);
err = errbuf;
goto eek;
}
break;
@ -1448,7 +1422,7 @@ const char *loadport(Sheet *sheet, const char *name)
case 'H':
{
os = ++ns;
size_t na = strtol(os, &ns, 0);
size_t na = (size_t)strtol(os, &ns, 0);
if (os == ns || na > NUM_COLOR_ASPECTS)
{
sprintf(errbuf, _("Parse error for number of hues in line %d"),
@ -1457,14 +1431,15 @@ const char *loadport(Sheet *sheet, const char *name)
goto eek;
}
loaded.tok[STYLE_CONT].type = STYLE;
for (size_t a = 0; a < na; ++a)
for (unsigned int a = 0; a < na; ++a)
{
while (*ns && (*ns == ' ')) { ++ns; }
os = ns;
loaded.tok[STYLE_CONT].u.style.aspect[a] = strtol(os, &ns, 0);
loaded.tok[STYLE_CONT].u.style.aspect[a] =
(ColorNum)strtol(os, &ns, 0);
if (os == ns)
{
sprintf(errbuf, _("Parse error in hue %d on line %d"),
sprintf(errbuf, _("Parse error in hue %ud on line %d"),
a, line);
err = errbuf;
goto eek;
@ -1603,35 +1578,35 @@ const char *loadport(Sheet *sheet, const char *name)
/* parse x and z */ /*{{{*/
const char *os = buf+1;
char *ns = buf+1;
int cx = strtol(os, &ns, 0);
if (os==ns)
CoordT cx = (CoordT)strtol(os, &ns, 0);
if (os == ns)
{
sprintf(errbuf,_("Parse error for x position in line %d"),line);
err=errbuf;
sprintf(errbuf, _("Parse error for x position in line %d"), line);
err = errbuf;
goto eek;
}
while (*ns==' ') ++ns;
os=ns;
int cz = strtol(os, &ns, 0);
if (os==ns)
while (*ns == ' ') ++ns;
os = ns;
CoordT cz = (CoordT)strtol(os, &ns, 0);
if (os == ns)
{
sprintf(errbuf,_("Parse error for z position in line %d"),line);
err=errbuf;
sprintf(errbuf, _("Parse error for z position in line %d"), line);
err = errbuf;
goto eek;
}
/*}}}*/
/* parse width */ /*{{{*/
while (*ns==' ') ++ns;
os=ns;
width = strtol(os, &ns, 0);
if (os==ns)
while (*ns == ' ') ++ns;
os = ns;
ColWidT cwidth = (ColWidT)strtol(os, &ns, 0);
if (os == ns)
{
sprintf(errbuf,_("Parse error for width in line %d"),line);
err=errbuf;
sprintf(errbuf, _("Parse error for width in line %d"), line);
err = errbuf;
goto eek;
}
/*}}}*/
setwidth(sheet,cx,cz,width);
setwidth(sheet, cx, cz, cwidth);
break;
}
/*}}}*/
@ -1641,8 +1616,8 @@ const char *loadport(Sheet *sheet, const char *name)
/* default -- error */ /*{{{*/
default:
{
sprintf(errbuf,_("Unknown tag %c in line %d"),buf[0],line);
err=errbuf;
sprintf(errbuf, _("Unknown tag %c in line %d"), buf[0], line);
err = errbuf;
goto eek;
}
/*}}}*/
@ -1664,21 +1639,13 @@ const char *loadport(Sheet *sheet, const char *name)
/* loadcsv -- load/merge CSVs */ /*{{{*/
const char *loadcsv(Sheet *sheet, const char *name)
{
/* variables */ /*{{{*/
FILE *fp;
Token **t;
const char *err;
Location where;
char ln[4096];
const char *str;
FltT value;
IntT lvalue;
int separator = 0;
/*}}}*/
bool separator = false;
if ((fp=fopen(name,"r"))==(FILE*)0) return strerror(errno);
err=(const char*)0;
LOCATION_GETS(where, sheet->cur);
FILE *fp;
if ((fp = fopen(name,"r")) == (FILE*)0) return strerror(errno);
const char *err = NULL;
Location where; LOCATION_GETS(where, sheet->cur);
char ln[4096];
for (; fgets(ln,sizeof(ln),fp); ++(where[Y]))
{
const char *s;
@ -1690,7 +1657,7 @@ const char *loadcsv(Sheet *sheet, const char *name)
while ((pos = strchr(pos, ','))) pos++, ccnt++;
pos = ln;
while ((pos = strchr(pos, ';'))) pos++, scnt++;
if (ccnt || scnt) separator = 1;
if (ccnt || scnt) separator = true;
csv_setopt(scnt > ccnt);
}
@ -1701,7 +1668,7 @@ const char *loadcsv(Sheet *sheet, const char *name)
Token t;
t.type = EMPTY;
lvalue = csv_long(s, &cend);
IntT lvalue = csv_long(s, &cend);
if (s != cend) /* ok, it is a integer */ /*{{{*/
{
t.type = INT;
@ -1711,7 +1678,7 @@ const char *loadcsv(Sheet *sheet, const char *name)
/*}}}*/
else
{
value = csv_double(s, &cend);
FltT value = csv_double(s, &cend);
if (s != cend) /* ok, it is a double */ /*{{{*/
{
t.type = FLOAT;
@ -1721,7 +1688,7 @@ const char *loadcsv(Sheet *sheet, const char *name)
/*}}}*/
else
{
str = csv_string(s, &cend);
const char *str = csv_string(s, &cend);
if (s != cend) /* ok, it is a string */ /*{{{*/
{
t.type = STRING;
@ -1749,148 +1716,54 @@ const char *loadcsv(Sheet *sheet, const char *name)
/*}}}*/
/* insertcube -- insert a block */ /*{{{*/
void insertcube(Sheet *sheet, const Location beg, const Location end,
Direction ins)
void insertcube(Sheet *sh, const Location beg, const Location end, Dimensions dm)
{
/* variables */ /*{{{*/
int x,y,z;
/*}}}*/
switch (ins)
{
/* IN_X */ /*{{{*/
case IN_X:
Location start; LOCATION_GETS(start,end);
Location fini; LOCATION_GETS(fini,beg);
start[dm] = (CoordT)(sh->dim[dm]) + end[dm] - beg[dm];
fini[dm] = end[dm]+1;
Location w;
for (w[Z] = start[Z]; w[Z] >= fini[Z]; w[Z]--)
for (w[Y] = start[Y]; w[Y] >= fini[Y]; w[Y]--)
for (w[X] = start[X]; w[X] >= fini[X]; w[Z]--)
{
int right;
right=sheet->dimx+end[X]-beg[X];
for (z=beg[Z]; z<=end[Z]; ++z) for (y=beg[Y]; y<=end[Y]; ++y) for (x=right; x>end[X]; --x)
{
resize(sheet, x, y, z, NULL);
CELL_ATC(sheet,x,y,z) = CELL_ATC(sheet,x-(end[X]-beg[X]+1),y,z);
CELL_ATC(sheet,x-(end[X]-beg[X]+1),y,z) = NULLCELL;
}
break;
resize(sh, w[X], w[Y], w[Z], NULL);
Location from; LOCATION_GETS(from,w);
from[dm] -= end[dm]-beg[dm]+1;
CELL_AT(sh,w) = CELL_AT(sh,from);
CELL_AT(sh,from) = NULLCELL;
}
/*}}}*/
/* IN_Y */ /*{{{*/
case IN_Y:
{
int down;
down=sheet->dimy+end[Y]-beg[Y];
for (z=beg[Z]; z<=end[Z]; ++z) for (x=beg[X]; x<=end[X]; ++x) for (y=down; y>end[Y]; --y)
{
resize(sheet, x, y, z, NULL);
CELL_ATC(sheet,x,y,z) = CELL_ATC(sheet,x,y-(end[Y]-beg[Y]+1),z);
CELL_ATC(sheet,x,y-(end[Y]-beg[Y]+1),z) = NULLCELL;
}
break;
}
/*}}}*/
/* IN_Z */ /*{{{*/
case IN_Z:
{
int bottom;
bottom=sheet->dimz+end[Z]-beg[Z];
for (y=beg[Y]; y<=end[Y]; ++y) for (x=beg[X]; x<=end[X]; ++x) for (z=bottom; z>end[Z]; --z)
{
resize(sheet, x, y, z, NULL);
CELL_ATC(sheet,x,y,z) = CELL_ATC(sheet,x,y,z-(end[Z]-beg[Z]+1));
CELL_ATC(sheet,x,y,z-(end[Z]-beg[Z]+1)) = NULLCELL;
}
break;
}
/*}}}*/
/* default */ /*{{{*/
default: assert(0);
/*}}}*/
}
sheet->changed=1;
cachelabels(sheet);
forceupdate(sheet);
sh->changed = true;
cachelabels(sh);
forceupdate(sh);
}
/*}}}*/
/* deletecube -- delete a block */ /*{{{*/
void deletecube(Sheet *sheet, const Location beg, const Location end,
Direction del)
void deletecube(Sheet *sh, const Location beg, const Location end, Dimensions dm)
{
/* variables */ /*{{{*/
Location w;
Location fm;
/*}}}*/
/* free cells in marked block */ /*{{{*/
for (w[X]=beg[X]; w[X]<=end[X]; ++w[X])
for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++w[Y])
for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++w[Z])
freecellofsheet(sheet, w);
for (w[Z] = beg[Z]; w[Z] <= end[Z]; w[Z]++)
for (w[Y] = beg[Y]; w[Y] <= end[Y]; w[Y]++)
for (w[X] = beg[X]; w[X] <= end[X]; w[X]++)
freecellofsheet(sh, w);
/*}}}*/
switch (del)
{
/* IN_X */ /*{{{*/
case IN_X:
Location fini; LOCATION_GETS(fini, end);
fini[dm] = (CoordT)(sh->dim[dm]) - (end[dm]-beg[dm]+1);
for (w[Z] = beg[Z]; w[Z] <= fini[Z]; w[Z]++)
for (w[Y] = beg[Y]; w[Y] <= fini[Y]; w[Y]++)
for (w[X] = beg[X]; w[X] <= fini[X]; w[X]++)
{
for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++w[Z])
for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++w[Y])
for (w[X]=beg[X]; w[X]<=sheet->dimx-(end[X]-beg[X]+1); ++w[X])
{
LOCATION_GETS(fm, w);
fm[X] += end[X]-beg[X]+1;
if (LOC_WITHIN(sheet,fm))
{
CELL_AT(sheet,w) = CELL_AT(sheet,fm);
CELL_AT(sheet,fm) = NULLCELL;
}
}
break;
Location fm; LOCATION_GETS(fm, w);
fm[dm] += end[dm]-beg[dm]+1;
if (LOC_WITHIN(sh,fm)) {
CELL_AT(sh,w) = CELL_AT(sh,fm); CELL_AT(sh,fm) = NULLCELL;
}
}
/*}}}*/
/* IN_Y */ /*{{{*/
case IN_Y:
{
for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++w[Z])
for (w[X]=beg[X]; w[X]<=end[X]; ++w[X])
for (w[Y]=beg[Y]; w[Y]<=sheet->dimy-(end[Y]-beg[Y]+1); ++w[Y])
{
LOCATION_GETS(fm, w);
fm[Y] += end[Y]-beg[Y]+1;
if (LOC_WITHIN(sheet,fm))
{
CELL_AT(sheet,w) = CELL_AT(sheet,fm);
CELL_AT(sheet,fm) = NULLCELL;
}
}
break;
}
/*}}}*/
/* IN_Z */ /*{{{*/
case IN_Z:
{
for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++w[Y])
for (w[X]=beg[X]; w[X]<=end[X]; ++w[X])
for (w[Z]=beg[Z]; w[Z]<=sheet->dimz-(end[Z]-beg[Z]+1); ++w[Z])
{
LOCATION_GETS(fm, w);
fm[Z] += end[Z]-beg[Z]+1;
if (LOC_WITHIN(sheet,fm))
{
CELL_AT(sheet,w) = CELL_AT(sheet,fm);
CELL_AT(sheet,fm) = NULLCELL;
}
}
break;
}
/*}}}*/
/* default */ /*{{{*/
default: assert(0);
/*}}}*/
}
sheet->changed=1;
cachelabels(sheet);
forceupdate(sheet);
sh->changed = true;
cachelabels(sh);
forceupdate(sh);
}
/*}}}*/
@ -1946,115 +1819,74 @@ you can sort a cube plane-wise.
*/
/*}}}*/
const char *sortblock(Sheet *sheet, const Location beg, const Location end,
Direction dir, Sortkey *sk, size_t sklen)
Dimensions dm, Sortkey *sk, size_t sklen)
{
/* variables */ /*{{{*/
int x1, y1, z1, x2, y2, z2;
int x,y,z;
int incx=0,incy=0,incz=0;
int distx,disty,distz;
int i,r=-3,work;
bool norel = false;
/*}}}*/
assert(sklen > 0);
/* unpack corners */
x1 = beg[X]; y1 = beg[Y]; z1 = beg[Z];
x2 = end[X]; y2 = end[Y]; z2 = end[Z];
/* asserts */ /*{{{*/
assert(sklen>0);
assert(x1>=0);
assert(x2>=0);
assert(y1>=0);
assert(y2>=0);
assert(z1>=0);
assert(z2>=0);
/*}}}*/
norel=0;
posorder(&x1,&x2);
posorder(&y1,&y2);
posorder(&z1,&z2);
distx=(x2-x1+1);
disty=(y2-y1+1);
distz=(z2-z1+1);
switch (dir)
{
case IN_X: incx=1; --x2; incy=0; incz=0; distx=1; break;
case IN_Y: incx=0; incy=1; --y2; incz=0; disty=1; break;
case IN_Z: incx=0; incy=0; incz=1; --z2; distz=1; break;
default: assert(0);
}
assert(incx || incy || incz);
Location wbeg, wend;
LOCATION_GETS(wbeg, beg);
LOCATION_GETS(wend, end);
poscorners(wbeg, wend);
Location dist; LOCATION_GETS(dist, wend);
LOCATION_SUB(dist, wbeg);
Location one = {1, 1, 1};
LOCATION_ADD(dist, one);
Location inc; OLOCATION(inc);
inc[dm] = 1; wend[dm]--; dist[dm] = 1;
bool norel = false;
bool work;
do
{
work=0;
for (x=x1,y=y1,z=z1; x<=x2&&y<=y2&&z<=z2; x+=incx,y+=incy,z+=incz)
{
for (i=0; i<sklen; ++i)
work = false;
Location w;
for (LOCATION_GETS(w,wbeg); LOCATION_LEQ(w,wend); LOCATION_ADD(w,inc)) {
int r = -3;
for (size_t i = 0; i < sklen; ++i)
{
r = cmpcell(sheet,x+sk[i].x,y+sk[i].y,z+sk[i].z,sheet,x+incx+sk[i].x,y+incy+sk[i].y,z+incz+sk[i].z,sk[i].sortkey);
Location here, there;
LOCATION_GETS(here, w);
LOCATION_ADD(here, sk[i].soff);
LOCATION_GETS(there, here);
LOCATION_ADD(there, inc);
r = cmpcell(sheet, here, sheet, there, sk[i].sortkey);
if (r == NOT_COMPARABLE) norel = true;
else if (r==-1 || r==1) break;
else assert(r==0);
else if (r == -1 || r == 1) break;
else assert(r == 0);
}
if (r==1)
if (r == 1)
{
swapblock(sheet,dir==IN_X ? x : x1,dir==IN_Y ? y : y1,dir==IN_Z ? z : z1,sheet,dir==IN_X ? x+incx : x1,dir==IN_Y ? y+incy : y1,dir==IN_Z ? z+incz : z1,distx,disty,distz);
work=1;
Location la; LOCATION_GETS(la,wbeg); la[dm] = w[dm];
Location lb; LOCATION_GETS(lb,wbeg); lb[dm] = w[dm]+inc[dm];
swapblock(sheet, la, sheet, lb, dist);
work = true;
}
}
x2-=incx;
y2-=incy;
z2-=incz;
LOCATION_SUB(wend, inc);
} while (work);
cachelabels(sheet);
forceupdate(sheet);
sheet->changed = true;
if (norel) return _("uncomparable elements");
else return (const char*)0;
else return NULL;
}
/*}}}*/
/* mirrorblock -- mirror a block */ /*{{{*/
void mirrorblock(Sheet *sheet, const Location beg, const Location end,
Direction dir)
void mirrorblock(Sheet *sh, const Location beg, const Location end, Dimensions dm)
{
switch (dir)
{
case IN_X: /* left-right */ /*{{{*/
{
int x,middle=(end[X]-beg[X]+1)/2;
for (x=0; x<middle; ++x)
{
swapblock(sheet,beg[X]+x,beg[Y],beg[Z],sheet,end[X]-x,beg[Y],beg[Z], 1,end[Y]-beg[Y]+1,end[Z]-beg[Z]+1);
}
break;
}
/*}}}*/
case IN_Y: /* upside-down */ /*{{{*/
{
int y,middle=(end[Y]-beg[Y]+1)/2;
for (y=0; y<middle; ++y)
{
swapblock(sheet,beg[X],beg[Y]+y,beg[Z],sheet,beg[X],end[Y]-y,beg[Z], end[X]-beg[X]+1,1,end[Z]-beg[Z]+1);
}
break;
}
/*}}}*/
case IN_Z: /* front-back */ /*{{{*/
{
int z,middle=(end[Z]-beg[Z]+1)/2;
for (z=0; z<middle; ++z)
{
swapblock(sheet,beg[X],beg[Y],beg[Z]+z,sheet,beg[X],beg[Y],end[Z]-z, end[X]-beg[X]+1,end[Y]-beg[Y]+1,1);
}
break;
}
/*}}}*/
default: assert(0);
Location dist; LOCATION_GETS(dist, end); LOCATION_SUB(dist, beg);
Location one = {1, 1, 1}; LOCATION_ADD(dist, one);
for (CoordT c = 0; c < (end[dm]-beg[dm]+1)/2; ++c) {
Location la; LOCATION_GETS(la, beg); la[dm] += c;
Location lb; LOCATION_GETS(lb, end); lb[dm] -= c;
swapblock(sh, la, sh, lb, dist);
}
sheet->changed=1;
cachelabels(sheet);
forceupdate(sheet);
sh->changed = true;
cachelabels(sh);
forceupdate(sh);
}
/*}}}*/

View File

@ -7,19 +7,17 @@
extern "C" {
#endif
typedef enum { IN_X, IN_Y, IN_Z } Direction;
/* must be a prime */
#define LABEL_CACHE 29
#define ASCENDING 001
typedef size_t ColWidT;
typedef struct
{
int x;
int y;
int z;
int sortkey; /* OR-ed value of the above constants */
Location soff;
CoordT sortkey; /* OR-ed value of the above constants */
} Sortkey;
struct Label
@ -37,15 +35,16 @@ typedef struct
struct Label *labelcache[LABEL_CACHE];
Location cur;
Location mark1, mark2;
int offx, offy;
CoordT offx, offy;
Cell **sheet;
int *column;
int dimx, dimy, dimz;
int orix, oriy, maxx, maxy;
int width;
ColWidT *column;
size_t dim[HYPER];
size_t orix, oriy;
CoordT maxx, maxy;
size_t width;
char *name;
void *display;
int max_colors;
size_t max_colors;
void *palette;
MarkState marking;
unsigned int changed:1;
@ -53,25 +52,25 @@ typedef struct
unsigned int clk:1;
} 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 LOC_WITHINC(s,x,y,z) ((size_t)x<(s)->dim[X] && (size_t)y<(s)->dim[Y] && (size_t)z<(s)->dim[Z])
#define LOC_WITHIN(s,l) LOCATION_LT((size_t)l,(s)->dim)
#define CELL_ATC(s,x,y,z) (*((s)->sheet + ((size_t)(z))*(s)->dim[Y]*(s)->dim[X] + ((size_t)(y))*(s)->dim[X] + (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 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_COORDS_IN_SHEETC(s,x,y,z) z=0; (size_t)(z)<(s)->dim[Z]; ++z) for (y=0; (size_t)(y)<(s)->dim[Y]; ++y) for (x=0; (size_t)(x)<(s)->dim[X]; ++x
#define ALL_LOCS_IN_SHEET(s,l) ALL_COORDS_IN_SHEETC(s,l[X],l[Y],l[Z])
#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)
#define ALL_CELLS_IN_SHEET(s,i,c) i=0,c=*((s)->sheet); i<(s)->dim[X]*(s)->dim[Y]*(s)->dim[Z]; ++i, c=*((s)->sheet+i)
extern Sheet *upd_sheet;
extern Location upd_l;
extern int max_eval;
void initialize_sheet(Sheet *sheet);
void resize(Sheet *sheet, int x, int y, int z, bool *qextended);
void resize(Sheet *sheet, CoordT x, CoordT y, CoordT z, bool *qextended);
Cell *initcellofsheet(Sheet *sheet, const Location at, bool *qnew);
void copycelltosheet(const Cell *fromcell, Sheet *sheet2,
const Location to, LabelHandling lh);
@ -84,16 +83,17 @@ void forceupdate(Sheet *sheet);
MarkState getmarkstate(Sheet *sheet);
void dump_current_cell(Sheet *sheet);
void freecellofsheet(Sheet *sheet, const Location at);
int columnwidth(Sheet *sheet, int x, int z);
bool setwidth(Sheet *sheet, int x, int z, int width);
int cellwidth(Sheet *sheet, const Location at);
ColWidT columnwidth(Sheet *sheet, CoordT x, CoordT z);
bool setwidth(Sheet *sheet, CoordT x, CoordT z, ColWidT width);
ColWidT cellwidth(Sheet *sheet, const Location at);
void puttok(Sheet *sheet, const Location at, Token t, TokVariety v);
Token recompvalue(Sheet *sheet, const Location at);
Token evaluate_at(Token t, Sheet *sheet, const Location at);
void update(Sheet *sheet);
char *geterror(Sheet *sheet, const Location at);
size_t printvalue(char *s, size_t size, size_t chars, StringFormat sf,
FloatFormat ff, int precision, Sheet *sheet, const Location at);
FloatFormat ff, PrecisionLevel precision,
Sheet *sheet, const Location at);
Style getstyle(Sheet *sheet, const Location at);
Adjust getadjust(Sheet *sheet, const Location at);
bool shadowed(Sheet *sheet, const Location at);
@ -127,11 +127,13 @@ const char *saveport(Sheet *sheet, const char *name, unsigned int *count);
const char *loadport(Sheet *sheet, const char *name);
const char *loadcsv(Sheet *sheet, const char *name);
void insertcube(Sheet *sheet, const Location beg, const Location end, Direction ins);
void deletecube(Sheet *sheet, const Location beg, const Location end, Direction ins);
void moveblock(Sheet *sheet, const Location beg, const Location end, const Location dest, int copy);
const char *sortblock(Sheet *sheet, const Location beg, const Location end, Direction dir, Sortkey *sk, size_t sklen);
void mirrorblock(Sheet *sheet, const Location beg, const Location end, Direction dir);
void insertcube(Sheet *sh, const Location beg, const Location end, Dimensions dm);
void deletecube(Sheet *sh, const Location beg, const Location end, Dimensions dm);
void moveblock(Sheet *sheet, const Location beg, const Location end,
const Location dest, int copy);
const char *sortblock(Sheet *sheet, const Location beg, const Location end,
Dimensions dm, Sortkey *sk, size_t sklen);
void mirrorblock(Sheet *sh, const Location beg, const Location end, Dimensions dm);
#ifdef __cplusplus
}

View File

@ -53,4 +53,5 @@ bool style_equal(Style l, Style r) {
if (l.bold_set && (l.bold != r.bold)) return false;
if (l.underline_set != r.underline_set) return false;
if (l.underline_set && (l.underline != r.underline)) return false;
return true;
}

View File

@ -1,6 +1,7 @@
#ifndef STYLE_H
#define STYLE_H
#include <limits.h>
#include <stdbool.h>
#ifdef __cplusplus
@ -9,6 +10,9 @@ extern "C" {
typedef short PrecisionLevel;
#define NO_PRECISION 0
#define MIN_PRECISION -FLT_T_DIG
#define MAX_PRECISION SHRT_MAX
#define PRECISION_FORMAT "%hd"
/* Note AUTOADJUST is treated exactly as though no Adjust value is set. */
typedef enum { AUTOADJUST = 0, LEFT, RIGHT, CENTER } Adjust;
@ -26,6 +30,7 @@ extern const char FloatFormat_Char[];
typedef unsigned char ColorNum;
#define NO_COLOR_SET 0
#define MAX_MAX_COLORS UCHAR_MAX
#define COLOR_FORMAT "%hhu"
typedef enum { FOREGROUND = 0, BACKGROUND, NUM_COLOR_ASPECTS } ColorAspect;
extern const char *ColorAspect_Name[];

View File

@ -90,7 +90,7 @@ Token duperror(Token* tok, const char* erro)
/* print_fident -- print a field identifier to a dest and return the number
of characters written
*/ /*{{{*/
static int print_fident(char* dest, size_t space, FunctionIdentifier id)
static size_t print_fident(char* dest, size_t space, FunctionIdentifier id)
{
size_t identlen = strlen(tfunc[id].name);
if ((identlen+1) < space) strcpy(dest, tfunc[id].name);
@ -105,7 +105,7 @@ static int print_fident(char* dest, size_t space, FunctionIdentifier id)
/* print_string -- print a string value to a dest and return the number of
characters written
*/ /*{{{*/
static int print_string(char* dest, size_t space,
static size_t print_string(char* dest, size_t space,
const char *str, StringFormat sf)
{
size_t cur = 0;
@ -120,28 +120,19 @@ static int print_string(char* dest, size_t space,
}
/*}}}*/
static int print_chars(char* d, size_t l, const char *s)
static size_t print_chars(char* d, size_t l, const char *s)
{
return print_string(d, l, s, DIRECT_STRING);
}
/* print_int -- print an int value */ /*{{{*/
size_t print_int(char *dest, size_t size, IntT val)
{
char buf[64];
size_t buflen = sprintf(buf, INT_T_FMT, val);
assert(buflen < sizeof(buf));
(void)strncpy(dest, buf, size);
return buflen;
}
/* printtok -- print a single token, passed by address, although not changed */ /*{{{*/
size_t ptokatprec(char *dest, size_t size, size_t field_width, StringFormat sf,
FloatFormat ff, int digits, ErrorFormat ef, const Token *tok,
FunctionPrecedence atprec)
/* ptokatprec -- like printtok but with an ambient precedence */
static size_t ptokatprec(char *dest, size_t size, size_t field_width,
StringFormat sf, FloatFormat ff, PrecisionLevel digits,
ErrorFormat ef, const Token *tok,
FunctionPrecedence atprec)
{
if (debug_level > 2) {
printf("..Entering printtok; bufsize %d, field_width %d, qs %d, ff %s,"
printf("..Entering printtok; bufsize %zu, field_width %zu, qs %d, ff %s,"
"prec %d, verr %d\n",
size, field_width, sf, FloatFormat_Name[ff], digits, ef);
}
@ -151,60 +142,61 @@ size_t ptokatprec(char *dest, size_t size, size_t field_width, StringFormat sf,
switch (tok->type)
{
case STRING: cur += print_string(dest, size, tok->u.string, sf); break;
case INT: cur += print_int(dest, size, tok->u.integer); break;
case INT: cur += (size_t)snprintf(dest, size, INT_T_FMT, tok->u.integer); break;
case FLOAT: /*{{{*/
{
/* variables */ /*{{{*/
char buf[1100], buf2[1100], *use, *p;
size_t len, len2;
/*}}}*/
char buf[1100], buf2[1100];
if (digits == 0) digits = def_precision;
else if (digits < 0) digits += FLT_T_DIG + 1;
if (digits > sizeof(buf) - 20) digits = sizeof(buf) - 20;
assert(digits > 0);
if ((size_t)digits > sizeof(buf) - FLT_T_DIG - 1)
digits = (PrecisionLevel)(sizeof(buf) - FLT_T_DIG - 1);
int len = 0, len2;
char *use = NULL;
switch (ff) {
case FLT_DECIMAL:
len = sprintf(buf, FLT_T_STD_FMT, digits, tok->u.flt);
use = buf;
break;
case FLT_SCIENTIFIC:
len = sprintf(buf, FLT_T_SCI_FMT, digits, tok->u.flt);
use = buf;
break;
case FLT_COMPACT:
len = sprintf(buf, FLT_T_CPT_FMT, digits, tok->u.flt);
/* Unfortunately, %g is so clever that sometimes it omits the
decimal; it also has a penchant for not switching to scientific
notation until the magnitude gets very large. So we try to
counteract these bad tendencies here. If there is no decimal,
we take the shorter of %.1f and %e with the same number of digits.
*/
use = buf;
if (strchr(buf, '.') == NULL) {
len = sprintf(buf, FLT_T_STD_FMT, 1, tok->u.flt);
len2 = sprintf(buf2, FLT_T_SCI_FMT, digits, tok->u.flt);
/* remove trailing 0s from sci format to be fair */
size_t epos = strchr(buf2, 'e') - buf2;
size_t tpos = epos;
while (tpos > 1 && buf2[tpos-1] == '0' && buf2[tpos-2] != '.') --tpos;
if (tpos < epos) {
memmove(buf2+tpos, buf2+epos, len2-epos+1);
len2 -= epos - tpos;
case FLT_DECIMAL:
len = sprintf(buf, FLT_T_STD_FMT, digits, tok->u.flt);
use = buf;
break;
case FLT_SCIENTIFIC:
len = sprintf(buf, FLT_T_SCI_FMT, digits, tok->u.flt);
use = buf;
break;
case FLT_COMPACT:
len = sprintf(buf, FLT_T_CPT_FMT, digits, tok->u.flt);
/* Unfortunately, %g is so clever that sometimes it omits the
decimal; it also has a penchant for not switching to scientific
notation until the magnitude gets very large. So we try to
counteract these bad tendencies here. If there is no decimal,
we take the shorter of %.1f and %e with the same number of digits.
*/
use = buf;
if (strchr(buf, '.') == NULL) {
len = sprintf(buf, FLT_T_STD_FMT, 1, tok->u.flt);
len2 = sprintf(buf2, FLT_T_SCI_FMT, digits, tok->u.flt);
/* remove trailing 0s from sci format to be fair */
long epos = strchr(buf2, 'e') - buf2;
long tpos = epos;
while (tpos > 1 && buf2[tpos-1] == '0' && buf2[tpos-2] != '.') --tpos;
if (tpos < epos) {
memmove(buf2+tpos, buf2+epos, len2-epos+1);
len2 -= epos - tpos;
}
if (len2 < len) { use = buf2; len = len2; }
}
if (len2 < len) { use = buf2; len = len2; }
}
break;
case FLT_HEXACT:
len = sprintf(buf, FLT_T_HEX_FMT, tok->u.flt);
use = buf;
break;
break;
case FLT_HEXACT:
len = sprintf(buf, FLT_T_HEX_FMT, tok->u.flt);
use = buf;
break;
default: assert(0);
}
assert(len < sizeof(buf));
p = use + len;
char *p = use + len;
while (*--p == ' ') { *p = '\0'; --len; }
(void)strncpy(dest, use, size);
cur += len;
cur += (size_t)len;
break;
}
/*}}}*/
@ -251,7 +243,7 @@ size_t ptokatprec(char *dest, size_t size, size_t field_width, StringFormat sf,
case PREFIX_FUNC: {
cur += print_fident(dest+cur, size-cur-1, fid);
if (cur < size) dest[cur++] = '(';
for (size_t ai = 0; ai < tok->u.funcall.argc && cur < size-1; ++ai)
for (int ai = 0; ai < tok->u.funcall.argc && cur < size-1; ++ai)
{
if (ai > 0 && cur < size) dest[cur++] = ',';
/* The commas eliminate the need for precedence worries in arguments*/
@ -324,7 +316,7 @@ size_t ptokatprec(char *dest, size_t size, size_t field_width, StringFormat sf,
char powbuf[4096];
size_t arglen = ptokatprec(powbuf, sizeof(powbuf), 0, sf, ff,
digits, ef, tok->u.funcall.argv, fp);
assert(arglen < sizeof(powbuf)-1);
if (arglen >= sizeof(powbuf)-1) assert(0);
if (powbuf[0] == '-') {
parenarg = true;
if (cur < size) dest[cur++] = '(';
@ -361,7 +353,8 @@ size_t ptokatprec(char *dest, size_t size, size_t field_width, StringFormat sf,
size_t shownfields = 0;
if (tok->u.style.precision != NO_PRECISION) {
cur += print_chars(dest+cur, size-cur-1, "precision(");
cur += print_int(dest+cur, size-cur-1, tok->u.style.precision);
cur += (size_t)snprintf(dest+cur, size-cur-1, PRECISION_FORMAT,
tok->u.style.precision);
if (cur < size) dest[cur++] = ')';
++shownfields;
}
@ -370,7 +363,8 @@ size_t ptokatprec(char *dest, size_t size, size_t field_width, StringFormat sf,
if (shownfields > 0 && cur < size) dest[cur++] = ',';
cur += print_chars(dest+cur, size-cur-1, ColorAspect_Name[ca]);
if (cur < size) dest[cur++] = '(';
cur += print_int(dest+cur, size-cur-1, tok->u.style.aspect[ca]);
cur += (size_t)snprintf(dest+cur, size-cur-1, COLOR_FORMAT,
tok->u.style.aspect[ca]);
if (cur < size) dest[cur++] = ')';
++shownfields;
}
@ -461,14 +455,14 @@ size_t ptokatprec(char *dest, size_t size, size_t field_width, StringFormat sf,
dest[size-1] = 0;
cur = size;
}
int mlen = mbslen(dest);
size_t mlen = mbslen(dest);
if (field_width && mlen > field_width) {
if (field_width < 6) {
for (cur = 0; cur < field_width; ++cur) dest[cur] = '#';
dest[cur] = 0;
} else {
char *ov = mbspos(dest+cur, -5);
cur = ov - dest;
cur = (size_t)(ov - dest);
cur += print_chars(dest+cur, size-cur-1, "...##");
}
}
@ -479,7 +473,7 @@ size_t ptokatprec(char *dest, size_t size, size_t field_width, StringFormat sf,
/* printtok -- print a single token, passed by address, although not changed */ /*{{{*/
size_t printtok(char* dest, size_t size, size_t field_width,
StringFormat sf, FloatFormat ff,
int digits, ErrorFormat ef, const Token *tok)
PrecisionLevel digits, ErrorFormat ef, const Token *tok)
{
return ptokatprec(dest, size, field_width, sf, ff, digits, ef, tok,
NO_PRECEDENCE);
@ -500,7 +494,7 @@ const char *dbgprint(const Token* tok) {
/* print -- print token sequence */ /*{{{*/
void print(char *s, size_t size, size_t chars, StringFormat sf, FloatFormat ff,
int digits, Token **n)
PrecisionLevel digits, Token **n)
{
size_t cur;

View File

@ -1,6 +1,7 @@
#ifndef TOKEN_H
#define TOKEN_H
#include <float.h>
#include <stdbool.h>
#include "func.h"
@ -36,19 +37,21 @@ typedef enum
#define IS_RELATION_OP(op) (((op)>= LT) && ((op)<=NE))
extern const char *Op_Name[];
typedef int Location[3]; /* NOTE: Locations are passed by REFERENCE not value */
/* I.e., to accept a Location argument, declare the parameter to be of type
const Location*
*/
typedef enum { X=0, Y=1, Z=2, HYPER} Dimensions;
typedef int CoordT;
#define COORD_MIN INT_MIN
#define COORD_MAX INT_MAX
typedef CoordT Location[HYPER];
/* NOTE: Locations are passed by REFERENCE not value */
#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];
#define LOCATION_ADD(la,lb) (la)[X]+=(lb)[X]; (la)[Y]+=(lb)[Y]; (la)[Z]+=(lb)[Z];
#define LOCATION_SUB(la,lb) (la)[X]-=(lb)[X], (la)[Y]-=(lb)[Y], (la)[Z]-=(lb)[Z]
#define LOCATION_ADD(la,lb) (la)[X]+=(lb)[X], (la)[Y]+=(lb)[Y], (la)[Z]+=(lb)[Z]
#define LOCATION_LT(la,lb) (la[X]<lb[X] && la[Y]<lb[Y] && la[Z]<lb[Z])
#define LOCATION_LEQ(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);
@ -95,6 +98,7 @@ typedef long double FltT;
#define CEILFLT ceill
#define ROUNDFLT rintl
#define TRUNCFLT truncl
#define LDEXP_FLT ldexpl
#else
typedef double FltT;
/* To switch the internal type used to store a floating value, it is
@ -129,6 +133,7 @@ typedef double FltT;
#define CEILFLT ceil
#define ROUNDFLT rint
#define TRUNCFLT trunc
#define LDEXP_FLT ldexp
#endif
typedef long long IntT;
@ -177,10 +182,11 @@ void cleartoken(Token* tok);
typedef enum {DIRECT_STRING, QUOTE_STRING} StringFormat;
typedef enum {TRUNCATED_ERROR, VERBOSE_ERROR, RESTORE_ERROR} ErrorFormat;
size_t printtok(char *dest, size_t size, size_t field_width, StringFormat sf,
FloatFormat ff, int digits, ErrorFormat ef, const Token *tok);
FloatFormat ff, PrecisionLevel digits, ErrorFormat ef,
const Token *tok);
const char *dbgprint(const Token *tok); /* for use in debugging */
void print(char *s, size_t size, size_t chars, StringFormat sf, FloatFormat ff,
int digits, Token **n);
PrecisionLevel digits, Token **n);
#ifdef __cplusplus
}

View File

@ -10,6 +10,7 @@
#include <errno.h>
#include <limits.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
extern char *strdup(const char *s);
@ -38,7 +39,8 @@ extern char *strdup(const char *s);
#define EXCEL 0x0406
/*}}}*/
static int unrpn(const char *s, const int *offset, int top, Token **t, int *tokens);
static int unrpn(const char *s, const int *offset, int top, Token **t,
size_t *tokens);
#if WK1DEBUG
static FILE *se;
@ -47,9 +49,10 @@ static FILE *se;
/* it -- convert string to int */ /*{{{*/
static int it(const char *s)
{
return (((unsigned int)((const unsigned char)*s))|(*(s+1)<<8));
return (((int)((const unsigned char)*s))|(*(s+1)<<8));
}
/*}}}*/
/* dbl -- convert string to double */ /*{{{*/
static FltT dbl(const unsigned char *s)
{
@ -78,7 +81,7 @@ static FltT dbl(const unsigned char *s)
fprintf(se,"%02x %02x %02x %02x %02x %02x %02x %02x ",s[0],s[1],s[2],s[3],s[4],s[5],s[6],s[7]);
fprintf(se,"%f (exp 2^%d)\r\n",sg*ldexp(x,e),e);
#endif
return (sg*ldexp(x,e));
return sg * LDEXP_FLT(x,e);
}
/*}}}*/
@ -154,7 +157,7 @@ static void format(unsigned char s, Cell *cell)
}
/*}}}*/
/* pair -- convert coordinate pair */ /*{{{*/
static int pair(const char *s, Token **t, int *tokens)
static int pair(const char *s, Token **t, size_t *tokens)
{
int x,y;
@ -333,14 +336,14 @@ static int pair(const char *s, Token **t, int *tokens)
}
/*}}}*/
/* sumup -- sum up arguments */ /*{{{*/
static int sumup(const char *s, const int *offset, int top, Token **t, int *tokens, int argc)
static int sumup(const char *s, const int *offset, int top, Token **t, size_t *tokens, int argc)
{
int low;
if (top<0) return -1;
if (argc>1)
{
low=unrpn(s,offset,top,(Token**)0,(int*)0);
low = unrpn(s, offset, top, (Token**)0, (size_t*)0);
if (low<0) return -1;
sumup(s,offset,low-1,t,tokens,argc-1);
if (t)
@ -369,7 +372,7 @@ static int sumup(const char *s, const int *offset, int top, Token **t, int *toke
}
if (tokens) *tokens+=2;
}
low=unrpn(s,offset,top,t,tokens);
low = unrpn(s, offset, top, t, tokens);
if (s[offset[top]]==2)
{
if (t)
@ -387,7 +390,7 @@ static int sumup(const char *s, const int *offset, int top, Token **t, int *toke
}
/*}}}*/
/* unrpn -- convert RPN expression to infix */ /*{{{*/
static int unrpn(const char *s, const int *offset, int top, Token **t, int *tokens)
static int unrpn(const char *s, const int *offset, int top, Token **t, size_t *tokens)
{
int low;
@ -419,7 +422,7 @@ static int unrpn(const char *s, const int *offset, int top, Token **t, int *toke
t[*tokens]->u.fident = FUNC_AT_SYMBOL;
}
if (tokens) ++(*tokens);
if (pair(s+offset[top]+1,t,tokens)==-1) low=-1; else low=top;
if (pair(s+offset[top]+1, t, tokens)==-1) low=-1; else low=top;
break;
}
/*}}}*/
@ -440,9 +443,9 @@ static int unrpn(const char *s, const int *offset, int top, Token **t, int *toke
{
if ((t[*tokens]=malloc(sizeof(Token)))==(Token*)0 || (t[*tokens+1]=malloc(sizeof(Token)))==(Token*)0) return -1;
t[*tokens]->type = OPERATOR;
t[*tokens]->u.fident = COMMA;
t[*tokens]->u.op = COMMA;
t[*tokens+1]->type = FIDENT;
t[*tokens+1]->u.op = FUNC_AMPERSAND;
t[*tokens+1]->u.fident = FUNC_AMPERSAND;
#if WK1DEBUG
fprintf(se,"[,&]");
#endif
@ -523,8 +526,8 @@ static int unrpn(const char *s, const int *offset, int top, Token **t, int *toke
{
if (t)
{
low=unrpn(s,offset,top-1,(Token**)0,(int*)0);
low=unrpn(s,offset,low-1,t,tokens);
low = unrpn(s, offset, top-1, (Token**)0, (size_t*)0);
low = unrpn(s, offset, low-1, t, tokens);
if (low<0) return -1;
if ((t[*tokens]=malloc(sizeof(Token)))==(Token*)0) return -1;
t[*tokens]->type=OPERATOR;
@ -695,7 +698,7 @@ const char *loadwk1(Sheet *sheet, const char *name)
/* variables */ /*{{{*/
FILE *fp;
const char *err;
int head[4];
uint32_t head[4];
char *body=(char*)0,*newbody;
size_t bodymaxlen=0;
size_t bodylen;
@ -712,18 +715,24 @@ const char *loadwk1(Sheet *sheet, const char *name)
while (1)
{
/* read header */ /*{{{*/
if ((head[0]=getc(fp))==EOF) break;
if ((head[1]=getc(fp))==EOF) { err=_("The record header appears to be truncated"); goto ouch; }
if ((head[2]=getc(fp))==EOF) { err=_("The record header appears to be truncated"); goto ouch; }
if ((head[3]=getc(fp))==EOF) { err=_("The record header appears to be truncated"); goto ouch; }
bodylen=head[2]|(head[3]<<8);
int temp = getc(fp);
if (temp == EOF) break;
else head[0] = (uint32_t)temp;
for (size_t i = 1; i < sizeof(head)/sizeof(uint32_t); ++i) {
temp = getc(fp);
if (temp == EOF) {
err=_("The record header appears to be truncated"); goto ouch;
}
head[i] = (uint32_t)temp;
}
bodylen = head[2] | (head[3]<<8);
/*}}}*/
/* read body */ /*{{{*/
if (bodylen>bodymaxlen)
if (bodylen > bodymaxlen)
{
newbody=realloc(body,bodymaxlen=bodylen);
if (newbody==(char*)0) { err=_("Out of memory"); goto ouch; }
else body=newbody;
newbody = realloc(body, bodymaxlen=bodylen);
if (newbody == NULL) { err=_("Out of memory"); goto ouch; }
else body = newbody;
}
if (bodylen) if (fread(body,bodylen,1,fp)!=1) { err=_("The record body appears to be truncated"); goto ouch; }
/*}}}*/
@ -900,11 +909,10 @@ const char *loadwk1(Sheet *sheet, const char *name)
{
int i,j,size;
int *offset;
int tokens;
Token **t;
assert(bodylen > 15);
if ((offset = malloc(it(body+13)*sizeof(int))) == 0)
if ((offset = malloc(((size_t)it(body+13))*sizeof(int))) == 0)
{
err = _("Out of memory");
goto ouch;
@ -956,7 +964,7 @@ const char *loadwk1(Sheet *sheet, const char *name)
#if WK1DEBUG
fprintf(se,"\r\n");
#endif
tokens=0; unrpn(body,offset,j-1,(Token**)0,&tokens);
size_t tokens = 0; unrpn(body, offset, j-1, (Token**)0, &tokens);
if ((t=malloc(tokens*sizeof(Token*)))==(Token**)0)
{
free(offset);

View File

@ -42,7 +42,7 @@ typedef struct Old_token_struc
{
char *string;
double flt;
long integer;
int32_t integer;
Operator op;
char *lident;
int fident;
@ -87,7 +87,7 @@ static bool_t xdr_token(XDR *xdrs, OldToken *t)
/* INT */ /*{{{*/
case INT:
{
return xdr_long(xdrs,&(t->u.integer));
return xdr_int32_t(xdrs,&(t->u.integer));
}
/*}}}*/
/* OPERATOR */ /*{{{*/
@ -142,11 +142,9 @@ static bool_t xdr_tokenptr(XDR *xdrs, OldToken **t)
/* xdr_tokenptrvec */ /*{{{*/
static bool_t xdr_tokenptrvec(XDR *xdrs, OldToken ***t)
{
assert(t != (OldToken***)0);
if (xdrs->x_op != XDR_DECODE) assert(0);
unsigned int len;
int result;
assert(t!=(OldToken***)0);
if (xdrs->x_op!=XDR_DECODE) assert(0);
if (!xdr_u_int(xdrs, &len)) return false;
*t = malloc(sizeof(OldToken*) * (len+1));
(*t)[len] = (OldToken*)0;
@ -239,7 +237,7 @@ bool_t xdr_cell(XDR *xdrs, Cell *cell)
/* x = cell->adjust; ONLY DECODING */
result = xdr_int(xdrs, &x);
cleartoken(cell->tok + STYLE_CONT);
Adjust a = x;
Adjust a = (Adjust)x;
if (a != AUTOADJUST) {
cell->tok[STYLE_CONT].type = STYLE;
cell->tok[STYLE_CONT].u.style.adjust = a;
@ -291,9 +289,12 @@ bool_t xdr_cell(XDR *xdrs, Cell *cell)
/*}}}*/
/* xdr_column */ /*{{{*/
bool_t xdr_column(XDR *xdrs, int *x, int *z, int *width)
bool_t xdr_column(XDR *xdrs, int *x, int *z, ColWidT *width)
{
return (xdr_int(xdrs, x) && xdr_int(xdrs, z) && xdr_int(xdrs, width));
int dummy = 0;
bool_t retval = xdr_int(xdrs, x) && xdr_int(xdrs, z) && xdr_int(xdrs, &dummy);
*width = (ColWidT)dummy;
return retval;
}
/*}}}*/
@ -304,12 +305,10 @@ bool_t xdr_column(XDR *xdrs, int *x, int *z, int *width)
bool_t xdr_magic(XDR *xdrs)
{
long m0,m1,m2;
m0=MAGIC0;
m1=MAGIC1;
m2=MAGIC2;
return (xdr_long(xdrs,&m0) && m0==MAGIC0 && xdr_long(xdrs,&m1) && m1==MAGIC1 && xdr_long(xdrs,&m2) && m2==MAGIC2);
int32_t m0 = MAGIC0, m1 = MAGIC1, m2 = MAGIC2;
return ( xdr_int32_t(xdrs, &m0) && m0 == MAGIC0
&& xdr_int32_t(xdrs, &m1) && m1 == MAGIC1
&& xdr_int32_t(xdrs, &m2) && m2 == MAGIC2);
}
/*}}}*/
@ -317,11 +316,11 @@ bool_t xdr_magic(XDR *xdrs)
const char *savexdr(Sheet *sheet, const char *name, unsigned int *count)
{
return _("Saving in xdr format is no longer supported. Use portable text.");
/* variables */ /*{{{*/
/* The below code no longer compiles, so saving it as a comment for reference
FILE *fp;
XDR xdrs;
int x,y,z;
/*}}}*/
*count=0;
if ((fp=fopen(name,"w"))==(FILE*)0) return strerror(errno);
@ -367,6 +366,7 @@ const char *savexdr(Sheet *sheet, const char *name, unsigned int *count)
if (fclose(fp)==EOF) return strerror(errno);
sheet->changed=0;
return (const char*)0;
*/
}
/*}}}*/
@ -377,7 +377,7 @@ const char *loadxdr(Sheet *sheet, const char *name)
FILE *fp;
XDR xdrs;
Location w;
int width;
ColWidT width;
int u;
int olderror;
Cell *nc;

View File

@ -14,7 +14,7 @@
#include "sheet.h"
bool_t xdr_cell(XDR *xdrs, Cell *cell);
bool_t xdr_column(XDR *xdrs, int *x, int *z, int *width);
bool_t xdr_column(XDR *xdrs, int *x, int *z, ColWidT *width);
bool_t xdr_magic(XDR *xdrs);
const char *savexdr(Sheet *sheet, const char *name, unsigned int *count);

View File

@ -3,6 +3,7 @@
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
extern char *strdup(const char* s);
#include <string.h>
#include "complete.h"
@ -10,9 +11,9 @@
void completefile(char *file, char *pos, size_t size)
{
struct dirent *direntp;
char *dir, *slash, *complete;
char *dir, *complete;
char next;
int required, atmost;
size_t required;
DIR *dirp;
next = *pos;
@ -39,9 +40,11 @@ void completefile(char *file, char *pos, size_t size)
}
while ((direntp = readdir(dirp))) {
if ((direntp->d_name[0] != '.' || complete[0] == '.') && !strncmp(complete, direntp->d_name, required)) {
if ((direntp->d_name[0] != '.' || complete[0] == '.')
&& !strncmp(complete, direntp->d_name, required)) {
if (!next && strlen(direntp->d_name) > required) {
strncpy(pos, direntp->d_name+required, size-(pos-file));
strncpy(pos, direntp->d_name+required,
size - (size_t)(pos-file));
file[size-1] = 0;
break;
} else if (direntp->d_name[required] == next && !strcmp(pos+1, direntp->d_name+required+1)) {

View File

@ -1,10 +1,3 @@
#ifndef NO_POSIX_SOURCE
#undef _POSIX_SOURCE
#define _POSIX_SOURCE 1
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 2
#endif
#include <sys/types.h>
#include <sys/wait.h>
#include <assert.h>
@ -162,26 +155,21 @@ static int do_attribute(Sheet *cursheet)
static int do_file(Sheet *cursheet)
{
int c = 0;
do
{
const char *menu[] =
{ _("lL)oad"), _("sS)ave"), _("nN)ame"), NULL };
switch (c = line_menu(_("File:"), menu, 0))
{
case -2:
case -1: c = KEY_CANCEL; break;
case 0: c = K_LOADMENU; break;
case 1: c = K_SAVEMENU; break;
case 2: c = K_NAME; break;
default: assert(0);
}
do {
const char *menu[] = { _("lL)oad"), _("sS)ave"), _("nN)ame"), NULL };
switch (c = line_menu(_("File:"), menu, 0)) {
case -2:
case -1: c = KEY_CANCEL; break;
case 0: c = K_LOADMENU; break;
case 1: c = K_SAVEMENU; break;
case 2: c = K_NAME; break;
default: assert(0);
}
} while (c == K_INVALID);
if (c == KEY_CANCEL) c = K_INVALID;
return c;
}
/* do_shell -- spawn a shell */
static int do_shell(void)
{
@ -189,11 +177,11 @@ static int do_shell(void)
struct sigaction interrupt;
refresh();
interrupt.sa_flags=0;
interrupt.sa_flags = 0;
sigemptyset(&interrupt.sa_mask);
interrupt.sa_handler=SIG_IGN;
sigaction(SIGINT,&interrupt,(struct sigaction *)0);
sigaction(SIGQUIT,&interrupt,(struct sigaction *)0);
interrupt.sa_handler = SIG_IGN;
sigaction(SIGINT, &interrupt, (struct sigaction *)0);
sigaction(SIGQUIT, &interrupt, (struct sigaction *)0);
switch (pid=fork())
{
/* -1 */
@ -341,8 +329,8 @@ void display_main(Sheet *cursheet)
Key k;
int quit = 0;
cursheet->maxx=COLS;
cursheet->maxy=LINES-1;
cursheet->maxx = COLS;
cursheet->maxy = LINES-1;
do
{
@ -366,7 +354,7 @@ void display_main(Sheet *cursheet)
#define CHANNEL_MAX 1000
typedef short CursesColor[3];
void display_init(Sheet *cursheet, int always_redraw)
void display_init(Sheet *cursheet, bool imp_redraw)
{
initscr();
start_color();
@ -383,14 +371,15 @@ void display_init(Sheet *cursheet, int always_redraw)
clear();
refresh();
#ifdef HAVE_TYPEAHEAD
if (always_redraw) typeahead(-1);
if (imp_redraw) typeahead(-1);
#endif
/* allocate and initialize the palette */
if (COLORS < cursheet->max_colors) { cursheet->max_colors = COLORS; }
assert(COLORS > 0);
if ((size_t)COLORS < cursheet->max_colors) cursheet->max_colors = (size_t)COLORS;
cursheet->palette = (void *)malloc(cursheet->max_colors*sizeof(CursesColor));
memset(cursheet->palette, '\0', cursheet->max_colors*sizeof(CursesColor));
CursesColor *palt = (CursesColor *)(cursheet->palette);
for (size_t i = 0; i <= DefaultCN[BACKGROUND]; ++i)
for (ColorNum i = 0; i <= DefaultCN[BACKGROUND]; ++i)
(void)color_content(i, &(palt[i][0]), &(palt[i][1]), &(palt[i][2]));
}
@ -412,8 +401,7 @@ void redraw_cell(Sheet *sheet, const Location at )
/* redraw_sheet -- draw a sheet with cell cursor */
void redraw_sheet(Sheet *sheet)
{
int width,col,x,y,again;
int x,y;
char pbuf[80];
char *buf=malloc(128);
size_t bufsz=128;
@ -424,10 +412,10 @@ void redraw_sheet(Sheet *sheet)
char *err;
char moveonly;
assert(sheet!=(Sheet*)0);
assert(sheet != (Sheet*)0);
assert(IN_OCTANT(sheet->cur));
assert(sheet->offx>=0);
assert(sheet->offy>=0);
assert(sheet->offx >= 0);
assert(sheet->offy >= 0);
/* correct offsets to keep cursor visible */
while (shadowed(sheet, sheet->cur))
@ -435,39 +423,44 @@ void redraw_sheet(Sheet *sheet)
--(sheet->cur[X]);
assert(sheet->cur[X] >= 0);
}
if (sheet->cur[Y] - sheet->offy > (sheet->maxy - 2 - header))
sheet->offy = sheet->cur[Y] - sheet->maxy + 2 + header;
if (sheet->cur[Y] - sheet->offy > sheet->maxy - 2 - (header ? 1 : 0))
sheet->offy = sheet->cur[Y] - sheet->maxy + 2 + (header ? 1 : 0);
if (sheet->cur[Y] < sheet->offy) sheet->offy = sheet->cur[Y];
if (sheet->cur[X] < sheet->offx) sheet->offx = sheet->cur[X];
size_t width = header ? 4 : 0;
bool again;
size_t col;
do
{
again=0;
for (width = 4*header, x = sheet->offx, col=0;
width <= sheet->maxx;
again = false;
col = 0;
for (x = sheet->offx;
width <= (size_t)(sheet->maxx);
width += columnwidth(sheet, x, sheet->cur[Z]), ++x, ++col);
--col;
sheet->width = col;
if (sheet->cur[X] != sheet->offx)
{
if (col==0) { ++sheet->offx; again=1; }
else if (sheet->cur[X] - sheet->offx >= col) {
++sheet->offx; again=1;
if (col==0) { ++sheet->offx; again = true; }
else if ((size_t)(sheet->cur[X] - sheet->offx) >= col) {
sheet->offx++; again = true;
}
}
} while (again);
unsigned short curcp = 1;
short curcp = 1;
init_pair(curcp, DefaultCN[FOREGROUND], COLOR_YELLOW);
if (header) {
(void)wattron(stdscr,DEF_NUMBER);
/* draw x numbers */
for (width=4; width < sheet->maxx; ++width)
for (width=4; width < (size_t)(sheet->maxx); ++width)
mvwaddch(stdscr, 0+sheet->oriy, sheet->orix+width,
(chtype)(unsigned char)' ');
for (width=4, x=sheet->offx; width<sheet->maxx; width+=col,++x)
for (width = 4, x = sheet->offx; width < (size_t)(sheet->maxx);
width += col, ++x)
{
unsigned short usecp = 0;
short usecp = 0;
if (x == sheet->cur[X]) usecp = curcp;
col = columnwidth(sheet, x, sheet->cur[Z]);
if (bufsz<(size_t)(col*UTF8SZ+1)) buf=realloc(buf,bufsz=(size_t)(col*UTF8SZ+1));
@ -477,50 +470,50 @@ void redraw_sheet(Sheet *sheet)
buf[col]='\0';
}
adjust(CENTER,buf,(size_t)col);
assert(sheet->maxx>=width);
if ((sheet->maxx-width)<col) buf[sheet->maxx-width]='\0';
assert((size_t)sheet->maxx >= width);
if ((size_t)(sheet->maxx)-width < col)
buf[(size_t)(sheet->maxx)-width] = '\0';
wcolor_set(stdscr, usecp, NULL);
mvwaddstr(stdscr,sheet->oriy,sheet->orix+width,buf);
mvwaddstr(stdscr, sheet->oriy, sheet->orix+width, buf);
wcolor_set(stdscr, 0, NULL);
}
/* draw y numbers */
for (y=1; y<(sheet->maxy-1); ++y) {
unsigned short usecp = 0;
int realy = y-1+sheet->offy;
for (y=1; y < sheet->maxy - 1; ++y) {
short usecp = 0;
CoordT realy = y - 1 + sheet->offy;
if (realy == sheet->cur[Y]) usecp = curcp;
wcolor_set(stdscr, usecp, NULL);
(void)mvwprintw(stdscr,sheet->oriy+y,sheet->orix,"%-4d",y-1+sheet->offy);
(void)mvwprintw(stdscr, y + (CoordT)(sheet->oriy), (CoordT)(sheet->orix),
"%-4d", y-1 + (int)(sheet->offy));
wcolor_set(stdscr, 0, NULL);
}
(void)wattroff(stdscr,DEF_NUMBER);
/* draw z number */
(void)mvwprintw(stdscr, sheet->oriy, sheet->orix, "%3d", sheet->cur[Z]);
(void)mvwprintw(stdscr, (CoordT)(sheet->oriy), (CoordT)(sheet->orix),
"%3d", sheet->cur[Z]);
}
++curcp;
/* 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->cur[Z]),++x)
for (y = header ? 1 : 0; y < sheet->maxy - 1; ++y)
for (width = header ? 4 : 0, x = sheet->offx;
width < (size_t)sheet->maxx;
width += columnwidth(sheet, x, sheet->cur[Z]), ++x)
{
size_t size,realsize,fill,cutoff;
int realx;
realx = x;
cutoff = 0;
size_t size,realsize,fill, cutoff = 0;
int realx = x;
if (x == sheet->offx) {
Location fil;
fil[X] = realx;
fil[Y] = y - header + sheet->offy;
fil[Y] = y - (header ? 1 : 0) + sheet->offy;
fil[Z] = sheet->cur[Z];
while (shadowed(sheet, fil)) {
--realx; fil[X] = realx;
cutoff += columnwidth(sheet, realx, sheet->cur[Z]);
}
}
tmp[X] = realx; tmp[Y] = y - header + sheet->offy;
tmp[X] = realx; tmp[Y] = y - (header ? 1 : 0) + sheet->offy;
tmp[Z] = sheet->cur[Z];
cell = safe_cell_at(sheet, tmp);
Style sc = getstyle(sheet, tmp);
@ -534,20 +527,20 @@ void redraw_sheet(Sheet *sheet)
sc.precision, sheet, tmp);
adjust(sc.adjust, buf, size);
assert(size>=cutoff);
if (width+((int)(size-cutoff)) >= sheet->maxx)
if (width + size - cutoff >= (size_t)(sheet->maxx))
{
*(buf+cutoff+sheet->maxx-width)='\0';
realsize=sheet->maxx-width+cutoff;
*(buf + cutoff + (size_t)sheet->maxx - width) = '\0';
realsize = (size_t)(sheet->maxx) - width + cutoff;
}
else realsize=size;
else realsize = size;
ms = getmarkstate(sheet);
int usecp = 0;
short usecp = 0;
ColorNum fg = sc.aspect[FOREGROUND];
if (fg == NO_COLOR_SET) fg = DefaultCN[FOREGROUND];
ColorNum bg = sc.aspect[BACKGROUND];
if (bg == NO_COLOR_SET) bg = DefaultCN[BACKGROUND];
while (usecp < curcp) {
unsigned short pfg, pbg;
short pfg, pbg;
pair_content(usecp, &pfg, &pbg);
if (fg == pfg && bg == pbg) break;
++usecp;
@ -556,12 +549,14 @@ void redraw_sheet(Sheet *sheet)
wcolor_set(stdscr, usecp, NULL);
invert =
(ms != UNMARKED) && loc_in_box(tmp, sheet->mark1, sheet->mark2);
if (x == sheet->cur[X] && (y-header+sheet->offy) == sheet->cur[Y])
if (x == sheet->cur[X]
&& (y - (header ? 1 : 0) + sheet->offy == sheet->cur[Y]))
invert = (ms == MARKING) ? true : !invert;
if (invert) (void)wattron(stdscr,DEF_CELLCURSOR);
if (sc.bold) wattron(stdscr,A_BOLD);
if (sc.underline) wattron(stdscr,A_UNDERLINE);
(void)mvwaddstr(stdscr,sheet->oriy+y,sheet->orix+width,buf+cutoff);
(void)mvwaddstr(stdscr, y+(CoordT)(sheet->oriy), sheet->orix + width,
buf+cutoff);
for (fill=mbslen(buf+cutoff); fill<realsize; ++fill)
(void)waddch(stdscr,(chtype)(unsigned char)' ');
wcolor_set(stdscr, 0, NULL);
@ -570,8 +565,8 @@ void redraw_sheet(Sheet *sheet)
}
/* draw contents of current element */
if (bufsz < (unsigned int)(sheet->maxx*UTF8SZ+1))
buf = realloc(buf,bufsz=(sheet->maxx*UTF8SZ+1));
if (bufsz < (size_t)(sheet->maxx)*UTF8SZ + 1)
buf = realloc(buf, bufsz = (size_t)(sheet->maxx)*UTF8SZ + 1);
label = getlabel(curcell(sheet));
assert(label != (const char*)0);
moveonly = sheet->moveonly ? *_("V") : *_("E");
@ -593,7 +588,7 @@ void redraw_sheet(Sheet *sheet)
printtok(buf+strlen(buf), bufsz-strlen(buf), 0, QUOTE_STRING,
FLT_COMPACT, -1, TRUNCATED_ERROR, &bc);
Token ic = gettok(cell, ITER_CONT);
if (ic.type != EMPTY && mbslen(buf) < (size_t)(sheet->maxx+1-4))
if (ic.type != EMPTY && mbslen(buf) < (size_t)(sheet->maxx + 1 - 4))
{
strcat(buf," -> ");
printtok(buf+strlen(buf), bufsz-strlen(buf), 0, QUOTE_STRING,
@ -601,8 +596,9 @@ void redraw_sheet(Sheet *sheet)
}
}
*mbspos(buf, sheet->maxx) = 0;
(void)mvwaddstr(stdscr,sheet->oriy+sheet->maxy-1,sheet->orix,buf);
for (col=mbslen(buf); col<sheet->maxx; ++col) (void)waddch(stdscr,' ');
(void)mvwaddstr(stdscr, sheet->oriy+(size_t)(sheet->maxy)-1, sheet->orix, buf);
for (col = mbslen(buf); col < (size_t)sheet->maxx; ++col)
(void)waddch(stdscr, ' ');
}
@ -622,43 +618,44 @@ const char *line_file(const char *file, const char *pattern, const char *title,
/* line_edit -- line editor function */
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)
{
size_t promptlen;
char *src, *dest;
int i,mx,my,insert;
chtype c;
assert(buf!=(char*)0);
assert(prompt!=(char*)0);
assert(x!=(size_t*)0);
assert(offx!=(size_t*)0);
assert(buf != NULL);
assert(prompt != NULL);
assert(x != (size_t*)0);
assert(offx != (size_t*)0);
(void)curs_set(1);
mx=COLS;
my=LINES;
promptlen=mbslen(prompt)+1;
(void)mvwaddstr(stdscr,LINES-1,0,prompt); (void)waddch(stdscr,(chtype)(unsigned char)' ');
insert=1;
bool insert = true;
int mx = COLS;
CoordT promptlen = (CoordT)(mbslen(prompt)+1);
(void)mvwaddstr(stdscr,LINES-1,0,prompt); (void)waddch(stdscr,(chtype)(unsigned char)' ');
int c;
do {
/* correct offx to cursor stays visible */
if (*x<*offx) *offx=*x;
if ((*x-*offx)>(mx-promptlen-1)) *offx=*x-mx+promptlen+1;
/* correct offx so cursor stays visible */
if (*x < *offx) *offx = *x;
if ((CoordT)(*x - *offx) > (mx-promptlen-1))
*offx = *x - (size_t)mx + (size_t)promptlen + 1;
/* display buffer */
(void)wmove(stdscr,LINES-1,(int)promptlen);
src = mbspos(buf, *offx);
dest = mbspos(buf, *offx+COLS-promptlen);
for (; *src && src < dest; src++) (void)waddch(stdscr,(chtype)(unsigned char)(*src));
if (i!=mx) (void)wclrtoeol(stdscr);
(void)wmove(stdscr, LINES-1, promptlen);
src = mbspos(buf, (int)(*offx));
dest = mbspos(buf, (int)(*offx) + COLS - promptlen);
int i = 0;
for (; *src && src < dest; ++i, ++src)
(void)waddch(stdscr, (chtype)(unsigned char)(*src));
if (i != mx) (void)wclrtoeol(stdscr);
/* show cursor */
(void)wmove(stdscr,LINES-1,(int)(*x-*offx+promptlen));
(void)wmove(stdscr, LINES-1, (CoordT)(*x-*offx) + promptlen);
src = dest = mbspos(buf, *x);
c=wgetc();
if (sheet!=(Sheet*)0 && sheet->moveonly) switch (c) {
src = dest = mbspos(buf, (int)(*x));
c = wgetc();
if (sheet != (Sheet*)0 && sheet->moveonly) switch (c) {
/* ^o -- switch back to line editor */
case '\t':
case '\017': sheet->moveonly=0; break;
@ -736,31 +733,29 @@ int line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt, size_t *
/* IC */
case KEY_IC:
insert=1-insert;
insert = !insert;
break;
/* EIC */
case KEY_EIC:
insert=0;
insert = false;
break;
/* control t */
case '\024':
if (*x > 0) {
char c, *end;
dest = mbspos(src, -1);
if (*x == mbslen(buf)) {
src = dest;
dest = mbspos(src, -1);
(*x)--;
}
end = mbspos(src, 1);
char *end = mbspos(src, 1);
while (src != end) {
c = *src;
char k = *src;
memmove(dest+1, dest, src-dest);
*dest = c;
*dest = k;
src++;
dest++;
}
@ -804,30 +799,33 @@ int line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt, size_t *
break;
/* default */
default:
if (((unsigned int)c) < ' ' || ((unsigned int)c) >= 256) break;
if (strlen(buf) >= (size-1)) {
if (is_mbcont(c)) {
dest = mbspos(src, -1);
memmove(dest, src, strlen(src)+1);
}
break;
}
if (insert || is_mbcont(c)) memmove(src+1, src, strlen(src)+1);
else {
if (is_mbchar(*src)) memmove(src+1, mbspos(src, 1), strlen(mbspos(src, 1))+1);
if (!*src) *(src+1) = '\0';
}
*src = (char)c;
if (!is_mbcont(c)) (*x)++;
break;
default: {
if (((unsigned int)c) < ' ' || ((unsigned int)c) >= 256) break;
bool iscont = is_mbcont((unsigned char)c);
if (strlen(buf) >= (size-1)) {
if (iscont) {
dest = mbspos(src, -1);
memmove(dest, src, strlen(src)+1);
}
break;
}
if (insert || iscont) memmove(src+1, src, strlen(src)+1);
else {
if (is_mbchar((unsigned char)(*src)))
memmove(src+1, mbspos(src, 1), strlen(mbspos(src, 1))+1);
if (!*src) *(src+1) = '\0';
}
*src = (char)c;
if (!iscont) (*x)++;
break;
}
}
} while (c != K_ENTER && c != KEY_CANCEL
&& (c != K_UP || (sheet!=(Sheet*)0 && sheet->moveonly)));
} while (c != K_ENTER && c != KEY_CANCEL && (c != K_UP || (sheet!=(Sheet*)0 && sheet->moveonly)));
if (sheet) sheet->moveonly=0;
if (sheet) sheet->moveonly = false;
(void)curs_set(0);
(void)wmove(stdscr,LINES-1,0);
(void)wmove(stdscr, LINES-1, 0);
(void)wclrtoeol(stdscr);
switch (c) {
@ -849,8 +847,6 @@ int line_ok(const char *prompt, int curx)
/* line_binary -- two choices with cancel */
int line_binary(const char *prompt, const char* op1, const char* op2, int curx)
{
int result;
assert(curx == 0 || curx == 1);
const char* menu[] = { _("cC)ancel"), op1, op2, NULL };
@ -880,20 +876,20 @@ int line_menu(const char *prompt, const char **choice, int curx)
int maxx = 0;
while (choice[maxx] != NULL) ++maxx;
int offx = 0;
chtype c;
int c;
do
{
int x, width;
int x;
(void)wmove(stdscr, LINES-1, (int)promptlen);
/* correct offset so choice is visible */
if (curx <= offx) offx = curx;
else do
{
width = promptlen;
size_t width = promptlen;
x = offx;
while (x < maxx && width + ((int)mbslen(choice[x]+1)) + 1 <= COLS)
while (x < maxx && width + mbslen(choice[x]+1) + 1 <= (size_t)COLS)
{
width += (int)(mbslen(choice[x]+1)) + 1;
width += mbslen(choice[x]+1) + 1;
++x;
}
--x;
@ -901,8 +897,8 @@ int line_menu(const char *prompt, const char **choice, int curx)
} while (x < curx);
/* show visible choices */
for (width = promptlen, x = offx;
x < maxx && width + ((int)mbslen(choice[x]+1)) + 1 <= COLS;
size_t width = promptlen;
for (x = offx; x < maxx && width + mbslen(choice[x]+1) + 1 <= (size_t)COLS;
width += mbslen(choice[x]+1) + 1, ++x)
{
(void)waddch(stdscr, (chtype)(unsigned char)' ');
@ -911,7 +907,7 @@ int line_menu(const char *prompt, const char **choice, int curx)
if (x == curx) (void)wattroff(stdscr,DEF_MENU);
}
if (width < COLS) (void)wclrtoeol(stdscr);
if (width < (size_t)COLS) (void)wclrtoeol(stdscr);
switch (c = wgetc())
{
/* KEY_LEFT -- move to previous item */
@ -993,7 +989,7 @@ void show_text(const char *text)
end = strchr(++text, '\n');
if (*text == '\f') break;
if (end) *end = 0;
(void)move(i,(COLS-mbslen(text))/2);
(void)move(i, (COLS - (CoordT)mbslen(text))/2);
(void)addstr(text);
text = end;
}
@ -1018,9 +1014,7 @@ bool keypressed(void)
/* wgetc */
static Key wgetc(void)
{
chtype c;
int c;
doupdate();
refresh();

View File

@ -9,7 +9,7 @@ extern "C" {
#endif
void display_main(Sheet *cursheet);
void display_init(Sheet *cursheet, int always_redraw);
void display_init(Sheet *cursheet, bool imp_redraw);
void display_end(Sheet *sheet);
void redraw_cell(Sheet *sheet, const Location at);
void redraw_sheet(Sheet *sheet);

View File

@ -143,14 +143,13 @@ class TeapotTable {open : {public Fl_Table}}
if (ms != UNMARKED)
selected = loc_in_box(test, cursheet->mark1, cursheet->mark2);
bool iscurrent = (C == cursheet->cur[X] && R == cursheet->cur[Y]);
Cell *cell = safe_cell_at(cursheet, test);
Style sc = getstyle(cursheet, test);
ColorNum bgcn = sc.aspect[BACKGROUND];
if (bgcn == NO_COLOR_SET) bgcn = DefaultCN[BACKGROUND];
Fl_Color cellbg = ((Fl_Color *)(cursheet->palette))[bgcn];
if (selected) cellbg = tpt_selection_version(cellbg);
if (!LOC_WITHIN(cursheet,test))
cellbg = fl_color_average(cellbg, FL_BLACK, 0.97);
cellbg = fl_color_average(cellbg, FL_BLACK, 0.97f);
fl_draw_box(iscurrent ? FL_BORDER_BOX : FL_THIN_DOWN_BOX,
xx, yy, W, H, cellbg);
if (Fl::focus() == this && iscurrent)
@ -207,17 +206,17 @@ class TeapotTable {open : {public Fl_Table}}
if (updating) return;
updating = true;
if (debug_level > 2)
printf("update_table: %ix%i@%i,%i; %i[%i], %i[%i]\\n",
cursheet->dimx, cursheet->dimy,
printf("update_table: %zux%zu@%i,%i; %i[%i], %i[%i]\\n",
cursheet->dim[X], cursheet->dim[Y],
cursheet->cur[X], cursheet->cur[Y],
cursheet->offx, cursheet->maxx,
cursheet->offy, cursheet->maxy);
if (cursheet->dimx > cols()) cols(cursheet->dimx);
if (cursheet->dimy > rows()) rows(cursheet->dimy);
if (cursheet->dim[X] > (size_t)cols()) cols(cursheet->dim[X]);
if (cursheet->dim[Y] > (size_t)rows()) rows(cursheet->dim[Y]);
adjust_outside();
for (int x = 0; x < cursheet->dimx; x++) {
for (int x = 0; (size_t)x < cursheet->dim[X]; x++) {
int w = columnwidth(cursheet, x, cursheet->cur[Z])*10;
if (col_width(x) != w) col_width(x, w);
}
@ -253,8 +252,8 @@ class TeapotTable {open : {public Fl_Table}}
cursheet->maxy -= cursheet->offy;
if (is_interactive_resize()) {
for (int C = 0; C < cursheet->dimx; C++) {
int w = (col_width(C) + 5)/10;
for (size_t C = 0; C < cursheet->dim[X]; ++C) {
size_t w = (col_width(C) + 5)/10;
if (w != columnwidth(cursheet, C, cursheet->cur[Z]))
setwidth(cursheet, C, cursheet->cur[Z], w);
}
@ -392,8 +391,8 @@ class TeapotTable {open : {public Fl_Table}}
if (debug_level > 2)
printf("adj: (%i,%i)-(%i,%i) %ix%i\\n", x1, y1, x2, y2,
cols(), rows());
if (x2+2 < cols() && cols() > cursheet->dimx)
cols(x2+2 < cursheet->dimx?cursheet->dimx:x2+2);
if (x2+2 < cols() && (size_t)cols() > cursheet->dim[X])
cols((size_t)x2+2 < cursheet->dim[X] ? cursheet->dim[X] : x2+2);
else if (x2+1 == cols()) {
int xpos = col_scroll_position(cols());
int w = col_width(cols()-1);
@ -402,8 +401,8 @@ class TeapotTable {open : {public Fl_Table}}
cols(x2+1);
}
if (y2+2 < rows() && rows() > cursheet->dimy)
rows(y2+2 < cursheet->dimy?cursheet->dimy:y2+2);
if (y2+2 < rows() && (size_t)rows() > cursheet->dim[Y])
rows((size_t)y2+2 < cursheet->dim[Y] ? cursheet->dim[Y] : y2+2);
else if (y2+1 == rows()) {
int ypos = row_scroll_position(rows());
int h = row_height(rows()-1);
@ -726,6 +725,7 @@ class MainWindow {open}
case LEFT: left->setonly(); break;
case RIGHT: right->setonly(); break;
case CENTER: center->setonly(); break;
case AUTOADJUST: ;
}
Location nb; LOCATION_GETS(nb, sheet->cur); nb[X]++;
if (shadowed(sheet, nb))
@ -746,6 +746,7 @@ class MainWindow {open}
case FLT_SCIENTIFIC: sci->setonly(); break;
case FLT_COMPACT: cpt->setonly(); break;
case FLT_HEXACT: hex->setonly(); break;
case FLT_NO_FORMAT: ;
}
}
protected xywh {0 50 800 525} box DOWN_FRAME
@ -814,7 +815,7 @@ class MainWindow {open}
Function
{tpt_selection_version(Fl_Color base)} {open return_type {Fl_Color}} {code
{
return fl_color_average(base, FL_SELECTION_COLOR, 0.85);
return fl_color_average(base, FL_SELECTION_COLOR, 0.85f);
} {} }
Function
@ -954,7 +955,7 @@ Function
} {} }
Function
{display_init(Sheet *sheet, int always_redraw)}
{display_init(Sheet *sheet, bool always_redraw)}
{open C return_type void} {code
{
Fl::get_system_colors();