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_UTF8 "Enable UTF-8 support" ON)
option(ENABLE_STATIC "Link FLTK statically" OFF) option(ENABLE_STATIC "Link FLTK statically" OFF)
add_compile_options(-Wall -Wextra -Wshadow -Wconversion -Wno-unused-parameter)
include_directories("${Teapot_BINARY_DIR}/") include_directories("${Teapot_BINARY_DIR}/")
add_subdirectory(src) add_subdirectory(src)

View File

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

View File

@ -69,37 +69,6 @@ const char *getlabel(const Cell* cell)
return cell->label; 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 */ /* freecellcontents -- free the resources of the cell at destruction time */
void freecellcontents(Cell *faded) 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) if (w[X] > beg[X] && fputs_close("\\NC", fp) == EOF)
return strerror(errno); return strerror(errno);
Location mw; LOCATION_GETS(mw, w); 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]; int multicols = mw[X] - w[X];
if (multicols > 1) fprintf(fp,"\\use{%d}", multicols); if (multicols > 1) fprintf(fp,"\\use{%d}", multicols);
Style cs = getstyle(sheet, w); 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 */ /*{{{*/ /* csv_string -- convert almost any string to string */ /*{{{*/
char *csv_string(const char *s, const char **end) char *csv_string(const char *s, const char **end)
{ {
static char *string; assert(s != NULL);
static int strings,stringsz; assert(end != (const char**)0);
size_t strings = 0;
assert(s!=(const char*)0); size_t stringsz = 0;
assert(end!=(const char**)0); char * string = NULL;
strings=0; if (!isprint((int)*s) || (!semicol && *s == ',') || (semicol && *s == ';'))
stringsz=0; return NULL;
string=(char*)0;
if (!isprint((int)*s) || (!semicol && *s==',') || (semicol && *s==';')) return (char*)0;
if (*s=='"') if (*s=='"')
{ {
++s; ++s;
while (*s!='\0' && *s!='\n' && *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; string[strings]=*s;
++strings; ++strings;

View File

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

View File

@ -33,7 +33,10 @@ extern char *strdup(const char* s);
#include "parser.h" #include "parser.h"
#include "scanner.h" #include "scanner.h"
#include "sheet.h" #include "sheet.h"
#include "style.h"
#include "token.h"
/*}}}*/ /*}}}*/
/* #defines */ /*{{{*/ /* #defines */ /*{{{*/
/* There is a BSD extensions, but they are possibly more exact. */ /* There is a BSD extensions, but they are possibly more exact. */
#ifdef M_E #ifdef M_E
@ -396,10 +399,18 @@ static Token adr_func(FunctionIdentifier self, int argc, const Token argv[])
while (i < argc && i - offset < HYPER) while (i < argc && i - offset < HYPER)
{ {
if (argv[i].type == EEK) return argv[i]; if (argv[i].type == EEK) return argv[i];
if (argv[i].type == INT) if (argv[i].type == INT) {
if (absolute) result.u.location[i-offset] = argv[i].u.integer; if (argv[i].u.integer < COORD_MIN || argv[i].u.integer > COORD_MAX) {
else result.u.location[i-offset] += argv[i].u.integer; const char* templ = _("Attempt to use out-of-range coordinate ("
else if (argv[i].type != EMPTY) break; 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; ++i;
} }
if (i < argc) { if (i < argc) {
@ -510,9 +521,9 @@ static Token dim_func(FunctionIdentifier self, int argc, const Token argv[])
/*}}}*/ /*}}}*/
return result; 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[]) static Token find_macro(FunctionIdentifier self, int argc, const Token argv[])
{ {
const char *usage = _("Usage: find(expr, loc_stride[, loc_start])"); 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[]) static Token bit_func(FunctionIdentifier self, int argc, const Token argv[])
{ {
Token result; Token result;
int accum; IntT accum;
if (self == FUNC_BITAND) accum = -1; if (self == FUNC_BITAND) accum = -1;
else accum = 0; else accum = 0;
for (size_t i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
if (!INTPATIBLE(argv[i])) if (!INTPATIBLE(argv[i]))
return duperror(&result, _("Bitwise functions need integer arguments.")); 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 (argv[i].type == INT) val = argv[i].u.integer;
if (self == FUNC_BITAND) accum = accum & val; if (self == FUNC_BITAND) accum = accum & val;
else 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.type = EEK;
result.u.err = malloc(strlen(usage) + MAX_FUNC_NAME_LENGTH + 1); result.u.err = malloc(strlen(usage) + MAX_FUNC_NAME_LENGTH + 1);
sprintf(result.u.err, usage, tfunc[fi].name); 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 */ /*{{{*/ /* variables */ /*{{{*/
Token result, arg; Token result, arg;
int precision = def_precision; PrecisionLevel precision = def_precision;
bool ff = DEF_FLOATFORM; bool ff = DEF_FLOATFORM;
bool bad_args = false; bool bad_args = false;
char staticbuf[4096]; char staticbuf[4096];
@ -877,7 +889,18 @@ static Token string_func(FunctionIdentifier self, int argc, const Token argv[])
} }
/* FALL THROUGH */ /* FALL THROUGH */
case 2: 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; else if (argv[1].type != EMPTY) bad_args = true; break;
/* FALL THROUGH */ /* FALL THROUGH */
case 1: case 1:
@ -893,7 +916,7 @@ static Token string_func(FunctionIdentifier self, int argc, const Token argv[])
return duperror(&result, staticbuf); return duperror(&result, staticbuf);
} }
result.type = STRING; 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); precision, VERBOSE_ERROR, &arg);
tfree(&arg); tfree(&arg);
if (size > sizeof(staticbuf) - 2) if (size > sizeof(staticbuf) - 2)
@ -984,9 +1007,17 @@ static Token precision_func(FunctionIdentifier self,
Token result; Token result;
if (argc != 1 || argv[0].type != INT) if (argc != 1 || argv[0].type != INT)
return duperror(&result, _("Usage: precision(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; result.type = STYLE;
clearstyle(&(result.u.style)); clearstyle(&(result.u.style));
result.u.style.precision = argv[0].u.integer; result.u.style.precision = (PrecisionLevel)argv[0].u.integer;
return result; 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); sprintf(result.u.err, templ, tfunc[self].name);
return result; 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; result.type = STYLE;
clearstyle(&(result.u.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; return result;
} }
/*}}}*/ /*}}}*/
@ -1328,8 +1367,8 @@ static Token len_func(FunctionIdentifier self, int argc, const Token argv[])
if (argc==1 && argv[0].type==STRING) if (argc==1 && argv[0].type==STRING)
/* result is length */ /*{{{*/ /* result is length */ /*{{{*/
{ {
result.type=INT; result.type = INT;
result.u.integer=strlen(argv[0].u.string); result.u.integer = (IntT)strlen(argv[0].u.string);
} }
/*}}}*/ /*}}}*/
else duperror(&result, _("Usage: len(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; result.type = EMPTY;
if (argc < 2) return duperror(&result, usage); 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) if (argv[i].type != INT && argv[i].type != FLOAT)
return duperror(&result, usage); return duperror(&result, usage);
result = tcopy(argv[1]); result = tcopy(argv[1]);
for (size_t i = 2; i < argc; ++i) for (int i = 2; i < argc; ++i)
{ {
tmp = tmul(result,argv[0]); tmp = tmul(result,argv[0]);
tfree_protected(&result, tmp); 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[]) static Token sci_disp(FunctionIdentifier self, int argc, const Token argv[])
{ {
FltT (*fsci)(FltT); FltT (*fsci)(FltT) = NULL;
switch (self) { switch (self) {
case FUNC_SQRT: fsci = SQRTFLT; break; case FUNC_SQRT: fsci = SQRTFLT; break;
case FUNC_SIN: fsci = SINFLT; 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]; char ss[1024];
int b = argv[1].u.integer; IntT b = argv[1].u.integer;
int l = strlen(argv[0].u.string); IntT l = (IntT)strlen(argv[0].u.string);
int e = l; IntT e = l;
if (argc == 3) e = argv[2].u.integer; if (argc == 3) e = argv[2].u.integer;
if ( b < 0 ) b = 0; if ( b < 0 ) b = 0;
if ( b > l ) b = l; if ( b > l ) b = l;
if ( e > l ) e = 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 >= 1024 ) n = 1024 - 1;
if (n > 0) { if (n > 0) {
ss[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); result.u.string=strdup(ss);
} }
else { else {
result.type=EMPTY; result.type = EMPTY;
} }
} }
else duperror(&result, usage); 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, const Location beg, const Location end,
unsigned int *count) 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(sheet != (Sheet*)0);
assert(name != (const char*)0); assert(name != NULL);
/*}}}*/
*count=0; *count = 0;
Location w;
w[X] = beg[X]; w[X] = beg[X];
for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z])) for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z]))
for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++(w[Y])) for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++(w[Y]))
if (shadowed(sheet, w)) return _("Shadowed cells in first column"); 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])) for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z]))
{ {
if (body) /* open new file */ /*{{{*/ if (body) /* open new file */ /*{{{*/
{ {
char num[20];
sprintf(num, ".%d", w[Z]); sprintf(num, ".%d", w[Z]);
char fullname[PATH_MAX];
fullname[sizeof(fullname)-strlen(num)-1]='\0'; fullname[sizeof(fullname)-strlen(num)-1]='\0';
(void)strncpy(fullname,name,sizeof(fullname)-strlen(num)-1); (void)strncpy(fullname,name,sizeof(fullname)-strlen(num)-1);
fullname[sizeof(fullname)-1]='\0'; 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]; ) for (w[X]=beg[X]; w[X]<=end[X]; )
{ {
Location mw; LOCATION_GETS(mw, w); 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]; int multicols = mw[X] - w[X];
if (multicols > 1) fprintf(fp,"<td colspan=%d",multicols); if (multicols > 1) fprintf(fp,"<td colspan=%d",multicols);
else fprintf(fp,"<td"); else fprintf(fp,"<td");
@ -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; case CENTER: if (fputs_close(" align=center>",fp)==EOF) return strerror(errno); break;
default: assert(0); default: assert(0);
} }
char buf[1024];
printvalue(buf, sizeof(buf), 0, DIRECT_STRING, cs.fform, cs.precision, printvalue(buf, sizeof(buf), 0, DIRECT_STRING, cs.fform, cs.precision,
sheet, w); sheet, w);
if (cs.transparent) 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, const Location beg, const Location end,
unsigned int *count) 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(sheet != (Sheet*)0);
assert(name != (const char*)0); assert(name != NULL);
/*}}}*/
*count=0; *count=0;
Location w;
w[X] = beg[X]; w[X] = beg[X];
for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z])) for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z]))
for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++(w[Y])) for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++(w[Y]))
if (shadowed(sheet, w)) return _("Shadowed cells in first column"); 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); if (!body && (fp=fopen(name,"w"))==(FILE*)0) return strerror(errno);
for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z])) for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++(w[Z]))
{ {
if (body) if (body)
/* open new file */ /*{{{*/ /* open new file */ /*{{{*/
{ {
char num[20];
sprintf(num, ".%d", w[Z]); sprintf(num, ".%d", w[Z]);
char fullname[PATH_MAX];
fullname[sizeof(fullname)-strlen(num)-1]='\0'; fullname[sizeof(fullname)-strlen(num)-1]='\0';
(void)strncpy(fullname,name,sizeof(fullname)-strlen(num)-1); (void)strncpy(fullname,name,sizeof(fullname)-strlen(num)-1);
fullname[sizeof(fullname)-1]='\0'; 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) if (w[X] > beg[X] && fputc_close('&', fp) == EOF)
return strerror(errno); return strerror(errno);
Location mw; LOCATION_GETS(mw,w); 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]; int multicols = mw[X] - w[X];
fprintf(fp, "\\multicolumn{%d}{", multicols); fprintf(fp, "\\multicolumn{%d}{", multicols);
Style cs = getstyle(sheet, w); 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; case CENTER: if (fputc_close('c',fp)==EOF) return strerror(errno); break;
default: assert(0); default: assert(0);
} }
char buf[1024];
printvalue(buf, sizeof(buf), 0, DIRECT_STRING, cs.fform, cs.precision, printvalue(buf, sizeof(buf), 0, DIRECT_STRING, cs.fform, cs.precision,
sheet, w); sheet, w);
if (fputs_close("}{", fp) == EOF) return strerror(errno); 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 #ifndef MAIN_H
#define MAIN_H #define MAIN_H
#include <limits.h>
#include "config.h" #include "config.h"
#define _(x) (x) #define _(x) (x)
@ -23,7 +25,9 @@ extern unsigned int batchln;
actions the user has triggered (by whatever means available), or a Unicode actions the user has triggered (by whatever means available), or a Unicode
character that was entered character that was entered
*/ */
typedef enum { typedef enum
{
K_MAX = INT_MAX,
K_NONE = 0, K_NONE = 0,
K_INVALID = -1, K_INVALID = -1,
K_BACKSPACE = -2, K_BACKSPACE = -2,
@ -91,11 +95,11 @@ typedef enum {
K_EDIT_STYLE_EXPR = -64 K_EDIT_STYLE_EXPR = -64
} Key; } 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 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 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); extern void do_mark(Sheet *cursheet, MarkState ms);
void fillwith(Sheet *she); 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 */ /*{{{*/ /* finite -- return error message about number or null */ /*{{{*/
static volatile int caughtfpe; static volatile int caughtfpe;

View File

@ -10,6 +10,7 @@ extern "C" {
#endif #endif
void posorder(int *x, int *y); void posorder(int *x, int *y);
void poscorners(Location a, Location b);
const char *dblfinite(FltT x); const char *dblfinite(FltT x);
int fputc_close(char c, FILE *fp); int fputc_close(char c, FILE *fp);
int fputs_close(const char *s, 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) if (tfunc[t->u.funcall.fident].eval_as == MACRO)
eval_argv = t->u.funcall.argv; eval_argv = t->u.funcall.argv;
else { else {
eval_argv = malloc(t->u.funcall.argc*sizeof(Token)); eval_argv = malloc(((size_t)(t->u.funcall.argc))*sizeof(Token));
for (size_t ai = 0; ai < t->u.funcall.argc; ++ai) { for (int ai = 0; ai < t->u.funcall.argc; ++ai) {
eval_argv[ai] = evaltoken(t->u.funcall.argv[ai], FULL); 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) { if (tfunc[t->u.funcall.fident].eval_as == FUNCT) {
/* To allow a function to return one of its arguments, we need /* To allow a function to return one of its arguments, we need
to be sure not to free that argument: */ 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); tfree_protected(&eval_argv[ai], result);
free(eval_argv); free(eval_argv);
} }
@ -185,13 +185,13 @@ static Token primary(Token *n[], int *i, EvalMethod meth)
} else { } else {
argv[argc] = term(n, i, meth); argv[argc] = term(n, i, meth);
if (argv[argc].type == EEK) { 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]; return argv[argc];
} }
} }
} else { } else {
duperror(&result, _("too many arguments")); 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; return result;
} }
++argc; ++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) if (n[*i] == NULLTOKEN || n[*i]->type != OPERATOR || n[*i]->u.op != CP)
/* ) expected */ /*{{{*/ /* ) 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")); duperror(&result, _(") expected"));
return result; return result;
} }
@ -213,7 +213,7 @@ static Token primary(Token *n[], int *i, EvalMethod meth)
result = tfuncall(fident, argc, argv); result = tfuncall(fident, argc, argv);
/* To allow a function to return one of its arguments, we need /* To allow a function to return one of its arguments, we need
to be sure not to free that argument: */ 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; return result;
} }
result.type = FUNCALL; result.type = FUNCALL;
@ -221,8 +221,8 @@ static Token primary(Token *n[], int *i, EvalMethod meth)
result.u.funcall.argc = argc; result.u.funcall.argc = argc;
if (argc > 0) if (argc > 0)
{ {
result.u.funcall.argv = malloc(argc*sizeof(Token)); result.u.funcall.argv = malloc(((size_t)argc)*sizeof(Token));
for (size_t ai = 0; ai < argc; ++ai) for (int ai = 0; ai < argc; ++ai)
result.u.funcall.argv[ai] = argv[ai]; result.u.funcall.argv[ai] = argv[ai];
} else result.u.funcall.argv = NULLTOKEN; } else result.u.funcall.argv = NULLTOKEN;
return result; return result;
@ -352,6 +352,8 @@ static Token powterm(Token *n[], int *i, EvalMethod meth)
if (meth == FULL) if (meth == FULL)
{ {
Token result; Token result;
result.type = EEK;
result.u.err = strdup(_("Internal error, should not happen."));
switch (op) switch (op)
{ {
case MUL: result = tmul(l,r); break; case MUL: result = tmul(l,r); break;

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
#ifndef STYLE_H #ifndef STYLE_H
#define STYLE_H #define STYLE_H
#include <limits.h>
#include <stdbool.h> #include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus
@ -9,6 +10,9 @@ extern "C" {
typedef short PrecisionLevel; typedef short PrecisionLevel;
#define NO_PRECISION 0 #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. */ /* Note AUTOADJUST is treated exactly as though no Adjust value is set. */
typedef enum { AUTOADJUST = 0, LEFT, RIGHT, CENTER } Adjust; typedef enum { AUTOADJUST = 0, LEFT, RIGHT, CENTER } Adjust;
@ -26,6 +30,7 @@ extern const char FloatFormat_Char[];
typedef unsigned char ColorNum; typedef unsigned char ColorNum;
#define NO_COLOR_SET 0 #define NO_COLOR_SET 0
#define MAX_MAX_COLORS UCHAR_MAX #define MAX_MAX_COLORS UCHAR_MAX
#define COLOR_FORMAT "%hhu"
typedef enum { FOREGROUND = 0, BACKGROUND, NUM_COLOR_ASPECTS } ColorAspect; typedef enum { FOREGROUND = 0, BACKGROUND, NUM_COLOR_ASPECTS } ColorAspect;
extern const char *ColorAspect_Name[]; 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 /* print_fident -- print a field identifier to a dest and return the number
of characters written 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); size_t identlen = strlen(tfunc[id].name);
if ((identlen+1) < space) strcpy(dest, 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 /* print_string -- print a string value to a dest and return the number of
characters written 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) const char *str, StringFormat sf)
{ {
size_t cur = 0; 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); return print_string(d, l, s, DIRECT_STRING);
} }
/* print_int -- print an int value */ /*{{{*/ /* ptokatprec -- like printtok but with an ambient precedence */
size_t print_int(char *dest, size_t size, IntT val) static size_t ptokatprec(char *dest, size_t size, size_t field_width,
{ StringFormat sf, FloatFormat ff, PrecisionLevel digits,
char buf[64]; ErrorFormat ef, const Token *tok,
size_t buflen = sprintf(buf, INT_T_FMT, val); FunctionPrecedence atprec)
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)
{ {
if (debug_level > 2) { 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", "prec %d, verr %d\n",
size, field_width, sf, FloatFormat_Name[ff], digits, ef); 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) switch (tok->type)
{ {
case STRING: cur += print_string(dest, size, tok->u.string, sf); break; 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: /*{{{*/ case FLOAT: /*{{{*/
{ {
/* variables */ /*{{{*/ char buf[1100], buf2[1100];
char buf[1100], buf2[1100], *use, *p;
size_t len, len2;
/*}}}*/
if (digits == 0) digits = def_precision; if (digits == 0) digits = def_precision;
else if (digits < 0) digits += FLT_T_DIG + 1; 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) { switch (ff) {
case FLT_DECIMAL: case FLT_DECIMAL:
len = sprintf(buf, FLT_T_STD_FMT, digits, tok->u.flt); len = sprintf(buf, FLT_T_STD_FMT, digits, tok->u.flt);
use = buf; use = buf;
break; break;
case FLT_SCIENTIFIC: case FLT_SCIENTIFIC:
len = sprintf(buf, FLT_T_SCI_FMT, digits, tok->u.flt); len = sprintf(buf, FLT_T_SCI_FMT, digits, tok->u.flt);
use = buf; use = buf;
break; break;
case FLT_COMPACT: case FLT_COMPACT:
len = sprintf(buf, FLT_T_CPT_FMT, digits, tok->u.flt); len = sprintf(buf, FLT_T_CPT_FMT, digits, tok->u.flt);
/* Unfortunately, %g is so clever that sometimes it omits the /* Unfortunately, %g is so clever that sometimes it omits the
decimal; it also has a penchant for not switching to scientific decimal; it also has a penchant for not switching to scientific
notation until the magnitude gets very large. So we try to notation until the magnitude gets very large. So we try to
counteract these bad tendencies here. If there is no decimal, counteract these bad tendencies here. If there is no decimal,
we take the shorter of %.1f and %e with the same number of digits. we take the shorter of %.1f and %e with the same number of digits.
*/ */
use = buf; use = buf;
if (strchr(buf, '.') == NULL) { if (strchr(buf, '.') == NULL) {
len = sprintf(buf, FLT_T_STD_FMT, 1, tok->u.flt); len = sprintf(buf, FLT_T_STD_FMT, 1, tok->u.flt);
len2 = sprintf(buf2, FLT_T_SCI_FMT, digits, tok->u.flt); len2 = sprintf(buf2, FLT_T_SCI_FMT, digits, tok->u.flt);
/* remove trailing 0s from sci format to be fair */ /* remove trailing 0s from sci format to be fair */
size_t epos = strchr(buf2, 'e') - buf2; long epos = strchr(buf2, 'e') - buf2;
size_t tpos = epos; long tpos = epos;
while (tpos > 1 && buf2[tpos-1] == '0' && buf2[tpos-2] != '.') --tpos; while (tpos > 1 && buf2[tpos-1] == '0' && buf2[tpos-2] != '.') --tpos;
if (tpos < epos) { if (tpos < epos) {
memmove(buf2+tpos, buf2+epos, len2-epos+1); memmove(buf2+tpos, buf2+epos, len2-epos+1);
len2 -= epos - tpos; len2 -= epos - tpos;
}
if (len2 < len) { use = buf2; len = len2; }
} }
if (len2 < len) { use = buf2; len = len2; } break;
} case FLT_HEXACT:
break; len = sprintf(buf, FLT_T_HEX_FMT, tok->u.flt);
case FLT_HEXACT: use = buf;
len = sprintf(buf, FLT_T_HEX_FMT, tok->u.flt); break;
use = buf; default: assert(0);
break;
} }
assert(len < sizeof(buf)); assert(len < sizeof(buf));
p = use + len; char *p = use + len;
while (*--p == ' ') { *p = '\0'; --len; } while (*--p == ' ') { *p = '\0'; --len; }
(void)strncpy(dest, use, size); (void)strncpy(dest, use, size);
cur += len; cur += (size_t)len;
break; break;
} }
/*}}}*/ /*}}}*/
@ -251,7 +243,7 @@ size_t ptokatprec(char *dest, size_t size, size_t field_width, StringFormat sf,
case PREFIX_FUNC: { case PREFIX_FUNC: {
cur += print_fident(dest+cur, size-cur-1, fid); cur += print_fident(dest+cur, size-cur-1, fid);
if (cur < size) dest[cur++] = '('; 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++] = ','; if (ai > 0 && cur < size) dest[cur++] = ',';
/* The commas eliminate the need for precedence worries in arguments*/ /* 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]; char powbuf[4096];
size_t arglen = ptokatprec(powbuf, sizeof(powbuf), 0, sf, ff, size_t arglen = ptokatprec(powbuf, sizeof(powbuf), 0, sf, ff,
digits, ef, tok->u.funcall.argv, fp); digits, ef, tok->u.funcall.argv, fp);
assert(arglen < sizeof(powbuf)-1); if (arglen >= sizeof(powbuf)-1) assert(0);
if (powbuf[0] == '-') { if (powbuf[0] == '-') {
parenarg = true; parenarg = true;
if (cur < size) dest[cur++] = '('; 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; size_t shownfields = 0;
if (tok->u.style.precision != NO_PRECISION) { if (tok->u.style.precision != NO_PRECISION) {
cur += print_chars(dest+cur, size-cur-1, "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++] = ')'; if (cur < size) dest[cur++] = ')';
++shownfields; ++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++] = ','; if (shownfields > 0 && cur < size) dest[cur++] = ',';
cur += print_chars(dest+cur, size-cur-1, ColorAspect_Name[ca]); cur += print_chars(dest+cur, size-cur-1, ColorAspect_Name[ca]);
if (cur < size) dest[cur++] = '('; 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++] = ')'; if (cur < size) dest[cur++] = ')';
++shownfields; ++shownfields;
} }
@ -461,14 +455,14 @@ size_t ptokatprec(char *dest, size_t size, size_t field_width, StringFormat sf,
dest[size-1] = 0; dest[size-1] = 0;
cur = size; cur = size;
} }
int mlen = mbslen(dest); size_t mlen = mbslen(dest);
if (field_width && mlen > field_width) { if (field_width && mlen > field_width) {
if (field_width < 6) { if (field_width < 6) {
for (cur = 0; cur < field_width; ++cur) dest[cur] = '#'; for (cur = 0; cur < field_width; ++cur) dest[cur] = '#';
dest[cur] = 0; dest[cur] = 0;
} else { } else {
char *ov = mbspos(dest+cur, -5); char *ov = mbspos(dest+cur, -5);
cur = ov - dest; cur = (size_t)(ov - dest);
cur += print_chars(dest+cur, size-cur-1, "...##"); 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 */ /*{{{*/ /* printtok -- print a single token, passed by address, although not changed */ /*{{{*/
size_t printtok(char* dest, size_t size, size_t field_width, size_t printtok(char* dest, size_t size, size_t field_width,
StringFormat sf, FloatFormat ff, 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, return ptokatprec(dest, size, field_width, sf, ff, digits, ef, tok,
NO_PRECEDENCE); NO_PRECEDENCE);
@ -500,7 +494,7 @@ const char *dbgprint(const Token* tok) {
/* print -- print token sequence */ /*{{{*/ /* print -- print token sequence */ /*{{{*/
void print(char *s, size_t size, size_t chars, StringFormat sf, FloatFormat ff, 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; size_t cur;

View File

@ -1,6 +1,7 @@
#ifndef TOKEN_H #ifndef TOKEN_H
#define TOKEN_H #define TOKEN_H
#include <float.h>
#include <stdbool.h> #include <stdbool.h>
#include "func.h" #include "func.h"
@ -36,19 +37,21 @@ typedef enum
#define IS_RELATION_OP(op) (((op)>= LT) && ((op)<=NE)) #define IS_RELATION_OP(op) (((op)>= LT) && ((op)<=NE))
extern const char *Op_Name[]; 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 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 OLOCATION(loc) ((void)memset(loc, 0, sizeof(Location)))
#define IN_OCTANT(loc) (loc[X]>=0 && loc[Y]>=0 && loc[Z]>=0) #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 LOCATION_GETS(la,lb) ((void)memcpy(la, lb, sizeof(Location)))
#define SAME_LOC(la,lb) (memcmp(la,lb,sizeof(Location))==0) #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_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_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, bool loc_in_box(const Location test,
const Location b, const Location c); const Location b, const Location c);
@ -95,6 +98,7 @@ typedef long double FltT;
#define CEILFLT ceill #define CEILFLT ceill
#define ROUNDFLT rintl #define ROUNDFLT rintl
#define TRUNCFLT truncl #define TRUNCFLT truncl
#define LDEXP_FLT ldexpl
#else #else
typedef double FltT; typedef double FltT;
/* To switch the internal type used to store a floating value, it is /* To switch the internal type used to store a floating value, it is
@ -129,6 +133,7 @@ typedef double FltT;
#define CEILFLT ceil #define CEILFLT ceil
#define ROUNDFLT rint #define ROUNDFLT rint
#define TRUNCFLT trunc #define TRUNCFLT trunc
#define LDEXP_FLT ldexp
#endif #endif
typedef long long IntT; typedef long long IntT;
@ -177,10 +182,11 @@ void cleartoken(Token* tok);
typedef enum {DIRECT_STRING, QUOTE_STRING} StringFormat; typedef enum {DIRECT_STRING, QUOTE_STRING} StringFormat;
typedef enum {TRUNCATED_ERROR, VERBOSE_ERROR, RESTORE_ERROR} ErrorFormat; typedef enum {TRUNCATED_ERROR, VERBOSE_ERROR, RESTORE_ERROR} ErrorFormat;
size_t printtok(char *dest, size_t size, size_t field_width, StringFormat sf, 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 */ const char *dbgprint(const Token *tok); /* for use in debugging */
void print(char *s, size_t size, size_t chars, StringFormat sf, FloatFormat ff, void print(char *s, size_t size, size_t chars, StringFormat sf, FloatFormat ff,
int digits, Token **n); PrecisionLevel digits, Token **n);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

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

View File

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

View File

@ -14,7 +14,7 @@
#include "sheet.h" #include "sheet.h"
bool_t xdr_cell(XDR *xdrs, Cell *cell); 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); bool_t xdr_magic(XDR *xdrs);
const char *savexdr(Sheet *sheet, const char *name, unsigned int *count); const char *savexdr(Sheet *sheet, const char *name, unsigned int *count);

View File

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

View File

@ -9,7 +9,7 @@ extern "C" {
#endif #endif
void display_main(Sheet *cursheet); 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 display_end(Sheet *sheet);
void redraw_cell(Sheet *sheet, const Location at); void redraw_cell(Sheet *sheet, const Location at);
void redraw_sheet(Sheet *sheet); void redraw_sheet(Sheet *sheet);

View File

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