First partial pass at getting teapot working on Mac OS X
This commit is contained in:
parent
c52219f827
commit
8074130224
@ -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)
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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 */ /*{{{*/
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -1,13 +1,3 @@
|
|||||||
/* #includes */ /*{{{C}}}*//*{{{*/
|
|
||||||
#ifndef NO_POSIX_SOURCE
|
|
||||||
#undef _POSIX_SOURCE
|
|
||||||
#define _POSIX_SOURCE 1
|
|
||||||
#undef _POSIX_C_SOURCE
|
|
||||||
#define _POSIX_C_SOURCE 2
|
|
||||||
#undef _XOPEN_SOURCE
|
|
||||||
#define _XOPEN_SOURCE 500
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DMALLOC
|
#ifdef DMALLOC
|
||||||
#include "dmalloc.h"
|
#include "dmalloc.h"
|
||||||
#endif
|
#endif
|
||||||
@ -19,12 +9,9 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
extern char *optarg;
|
|
||||||
extern int optind,opterr,optopt;
|
|
||||||
int getopt(int argc, char * const *argv, const char *optstring);
|
|
||||||
extern char *strdup(const char* s);
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -44,7 +31,6 @@ extern char *strdup(const char* s);
|
|||||||
#include "sheet.h"
|
#include "sheet.h"
|
||||||
#include "wk1.h"
|
#include "wk1.h"
|
||||||
#include "xdr.h"
|
#include "xdr.h"
|
||||||
/*}}}*/
|
|
||||||
|
|
||||||
/* variables */ /*{{{*/
|
/* variables */ /*{{{*/
|
||||||
char helpfile[PATH_MAX];
|
char helpfile[PATH_MAX];
|
||||||
@ -58,33 +44,46 @@ int debug_level = 0;
|
|||||||
static bool usexdr = false;
|
static bool usexdr = false;
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
void moveto(Sheet *sheet, int x, int y, int z)
|
void moveto(Sheet *sheet, CoordT x, CoordT y, CoordT z)
|
||||||
{
|
{
|
||||||
int need_redraw = 0;
|
bool need_redraw = false;
|
||||||
int xdir = x > sheet->cur[X]?1:-1;
|
bool need_cell = false;
|
||||||
|
CoordT xdir = x > sheet->cur[X] ? 1 : -1;
|
||||||
|
|
||||||
|
if (x >= 0 && x != sheet->cur[X]) { need_cell = true; sheet->cur[X] = x; }
|
||||||
|
if (y >= 0 && y != sheet->cur[Y]) { need_cell = true; sheet->cur[Y] = y; }
|
||||||
|
if (z >= 0 && z != sheet->cur[Z]) { need_redraw = true; sheet->cur[Z] = z; }
|
||||||
|
|
||||||
if (x >= 0) sheet->cur[X] = x;
|
|
||||||
if (y >= 0) sheet->cur[Y] = y;
|
|
||||||
if (z >= 0) need_redraw++, sheet->cur[Z] = z;
|
|
||||||
while (sheet->cur[X] > 0 && shadowed(sheet, sheet->cur))
|
while (sheet->cur[X] > 0 && shadowed(sheet, sheet->cur))
|
||||||
sheet->cur[X] += xdir;
|
sheet->cur[X] += xdir;
|
||||||
|
|
||||||
if (getmarkstate(sheet) == MARKING) LOCATION_GETS(sheet->mark2, sheet->cur);
|
if (getmarkstate(sheet) == MARKING) LOCATION_GETS(sheet->mark2, sheet->cur);
|
||||||
|
|
||||||
if (sheet->cur[X] <= sheet->offx && sheet->offx) need_redraw++, sheet->offx = (sheet->cur[X]?sheet->cur[X]-1:0);
|
if (sheet->cur[X] <= sheet->offx && sheet->offx > 0) {
|
||||||
if (sheet->cur[Y] <= sheet->offy && sheet->offy) need_redraw++, sheet->offy = (sheet->cur[Y]?sheet->cur[Y]-1:0);
|
need_redraw = true;
|
||||||
if (sheet->cur[X] >= sheet->offx+sheet->maxx) need_redraw++, sheet->offx = sheet->cur[X]-sheet->maxx+2;
|
sheet->offx = (sheet->cur[X] > 0) ? sheet->cur[X]-1 : 0;
|
||||||
if (sheet->cur[Y] >= sheet->offy+sheet->maxy) need_redraw++, sheet->offy = sheet->cur[Y]-sheet->maxy+2;
|
}
|
||||||
|
if (sheet->cur[Y] <= sheet->offy && sheet->offy > 0) {
|
||||||
|
need_redraw = true;
|
||||||
|
sheet->offy = (sheet->cur[Y] > 0) ? sheet->cur[Y]-1 : 0;
|
||||||
|
}
|
||||||
|
if (sheet->cur[X] >= sheet->offx + sheet->maxx) {
|
||||||
|
need_redraw = true;
|
||||||
|
sheet->offx = sheet->cur[X] - sheet->maxx + 2;
|
||||||
|
}
|
||||||
|
if (sheet->cur[Y] >= sheet->offy + sheet->maxy) {
|
||||||
|
need_redraw = true;
|
||||||
|
sheet->offy = sheet->cur[Y] - sheet->maxy + 2;
|
||||||
|
}
|
||||||
if (need_redraw) redraw_sheet(sheet);
|
if (need_redraw) redraw_sheet(sheet);
|
||||||
else if (x != sheet->cur[X] || y != sheet->cur[Y] || z != sheet->cur[Z]) redraw_cell(sheet, sheet->cur);
|
else if (need_cell) redraw_cell(sheet, sheet->cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
void movetoloc(Sheet *sheet, const Location dest) {
|
void movetoloc(Sheet *sheet, const Location dest) {
|
||||||
moveto(sheet, dest[X], dest[Y], dest[Z]);
|
moveto(sheet, dest[X], dest[Y], dest[Z]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void relmoveto(Sheet *sheet, int x, int y, int z)
|
void relmoveto(Sheet *sheet, CoordT x, CoordT y, CoordT z)
|
||||||
{
|
{
|
||||||
moveto(sheet, sheet->cur[X]+x, sheet->cur[Y]+y, (z?sheet->cur[Z]+z:-1));
|
moveto(sheet, sheet->cur[X]+x, sheet->cur[Y]+y, (z?sheet->cur[Z]+z:-1));
|
||||||
}
|
}
|
||||||
@ -97,11 +96,11 @@ static int line_numedit(int *n, const char *prompt)
|
|||||||
char buf[20];
|
char buf[20];
|
||||||
Token *t = NULLTOKEN;
|
Token *t = NULLTOKEN;
|
||||||
sprintf(buf, "%d", *n);
|
sprintf(buf, "%d", *n);
|
||||||
char *s = buf+strlen(buf);
|
char *s = buf + strlen(buf);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
free(t);
|
free(t);
|
||||||
size_t x = s - buf;
|
size_t x = (size_t)(s - buf);
|
||||||
size_t offx = 0;
|
size_t offx = 0;
|
||||||
int c = line_edit((Sheet*)0, buf, sizeof(buf), prompt, &x, &offx);
|
int c = line_edit((Sheet*)0, buf, sizeof(buf), prompt, &x, &offx);
|
||||||
if (c < 0) return c;
|
if (c < 0) return c;
|
||||||
@ -109,20 +108,21 @@ static int line_numedit(int *n, const char *prompt)
|
|||||||
t = scan_integer(&s);
|
t = scan_integer(&s);
|
||||||
} while (*s != '\0');
|
} while (*s != '\0');
|
||||||
if (t == NULLTOKEN) *n = -1;
|
if (t == NULLTOKEN) *n = -1;
|
||||||
else { *n = t->u.integer; free(t); }
|
else { *n = (int)(t->u.integer); free(t); }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
/* line_lidedit -- label identifier line editor function */ /*{{{*/
|
/* line_lidedit -- label identifier line editor function */ /*{{{*/
|
||||||
static int line_idedit(char *ident, size_t size, const char *prompt, size_t *x, size_t *offx)
|
static int line_idedit(char *ident, size_t size, const char *prompt,
|
||||||
|
size_t *x, size_t *offx)
|
||||||
{
|
{
|
||||||
Token *t = NULLTOKEN;
|
Token *t = NULLTOKEN;
|
||||||
char *s = ident+strlen(ident);
|
char *s = ident + strlen(ident);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
free(t);
|
free(t);
|
||||||
*x = s - ident;
|
*x = (size_t)(s - ident);
|
||||||
int c = line_edit((Sheet*)0, ident, size, prompt, x, offx);
|
int c = line_edit((Sheet*)0, ident, size, prompt, x, offx);
|
||||||
if (c < 0) return c;
|
if (c < 0) return c;
|
||||||
s = ident;
|
s = ident;
|
||||||
@ -168,15 +168,15 @@ static int do_edit(Sheet *cursheet, Key c, char *expr, TokVariety tv)
|
|||||||
prompt = _("Cell contents:");
|
prompt = _("Cell contents:");
|
||||||
if (tv == ITER_CONT) prompt = _("Clocked cell contents");
|
if (tv == ITER_CONT) prompt = _("Clocked cell contents");
|
||||||
if (tv == STYLE_CONT) prompt = _("Style expression");
|
if (tv == STYLE_CONT) prompt = _("Style expression");
|
||||||
if (*s != '\0')
|
if (*s != '\0') {
|
||||||
if (t == EMPTY_TVEC)
|
if (t == EMPTY_TVEC)
|
||||||
line_msg(prompt, "XXX invalid expression");
|
line_msg(prompt, "XXX invalid expression");
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
newcont = eval_safe(t, LITERAL);
|
newcont = eval_safe(t, LITERAL);
|
||||||
if (newcont.type = EEK)
|
if (newcont.type == EEK)
|
||||||
line_msg(prompt, "XXX unparseable expression");
|
line_msg(prompt, "XXX unparseable expression");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
tvecfree(t);
|
tvecfree(t);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -209,13 +209,13 @@ static int do_edit(Sheet *cursheet, Key c, char *expr, TokVariety tv)
|
|||||||
else if (isalpha(c))
|
else if (isalpha(c))
|
||||||
{
|
{
|
||||||
buf[0] = '"';
|
buf[0] = '"';
|
||||||
buf[1] = c;
|
buf[1] = (char)c;
|
||||||
buf[2] = 0;
|
buf[2] = 0;
|
||||||
s=buf+2;
|
s=buf+2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (c < 256) buf[0]=c;
|
if (c < 256) buf[0] = (char)c;
|
||||||
else buf[0] = 0;
|
else buf[0] = 0;
|
||||||
buf[1]='\0';
|
buf[1]='\0';
|
||||||
s=buf+1;
|
s=buf+1;
|
||||||
@ -309,7 +309,7 @@ static int do_label(Sheet *sheet)
|
|||||||
static int do_columnwidth(Sheet *cursheet)
|
static int do_columnwidth(Sheet *cursheet)
|
||||||
{
|
{
|
||||||
do_mark(cursheet, GET_MARK_CUR);
|
do_mark(cursheet, GET_MARK_CUR);
|
||||||
int n = columnwidth(cursheet, cursheet->mark1[X], cursheet->mark1[Z]);
|
int n = (int)columnwidth(cursheet, cursheet->mark1[X], cursheet->mark1[Z]);
|
||||||
do {
|
do {
|
||||||
int c = line_numedit(&n, _("Column width:"));
|
int c = line_numedit(&n, _("Column width:"));
|
||||||
if (c < 0) return c;
|
if (c < 0) return c;
|
||||||
@ -317,7 +317,7 @@ static int do_columnwidth(Sheet *cursheet)
|
|||||||
/*}}}*/
|
/*}}}*/
|
||||||
for (int x = cursheet->mark1[X]; x <= cursheet->mark2[X]; ++x)
|
for (int x = cursheet->mark1[X]; x <= cursheet->mark2[X]; ++x)
|
||||||
for (int z = cursheet->mark1[Z]; z <= cursheet->mark2[Z]; ++z)
|
for (int z = cursheet->mark1[Z]; z <= cursheet->mark2[Z]; ++z)
|
||||||
setwidth(cursheet,x,z,n);
|
setwidth(cursheet,x,z,(ColWidT)n);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
@ -377,7 +377,7 @@ static void do_attribute(Sheet *cursheet, Key action)
|
|||||||
int c = line_numedit(&n, prompt);
|
int c = line_numedit(&n, prompt);
|
||||||
if (c < 0) return;
|
if (c < 0) return;
|
||||||
for (ALL_LOCS_IN_REGION(cursheet,w))
|
for (ALL_LOCS_IN_REGION(cursheet,w))
|
||||||
changed = setprecision(cursheet, w, n) || changed;
|
changed = setprecision(cursheet, w, (PrecisionLevel)n) || changed;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
@ -400,13 +400,12 @@ static void do_attribute(Sheet *cursheet, Key action)
|
|||||||
/* 6 -- shadow */ /*{{{*/
|
/* 6 -- shadow */ /*{{{*/
|
||||||
case ADJUST_SHADOW:
|
case ADJUST_SHADOW:
|
||||||
{
|
{
|
||||||
int n;
|
Location rt;
|
||||||
Location r;
|
LOCATION_GETS(rt, cursheet->mark1); ++rt[X];
|
||||||
LOCATION_GETS(r, cursheet->mark1); ++r[X];
|
int n = 0;
|
||||||
if (onecell) n = !(fs.shadowed);
|
if (!(fs.shadowed) && !shadowed(cursheet, rt)) n = 1;
|
||||||
else n = line_binary(_("Set block to:"),
|
if (!onecell) n = line_binary(_("Set block to:"),
|
||||||
_("uU)nshadowed"), _("sS)hadowed"),
|
_("uU)nshadowed"), _("sS)hadowed"), n);
|
||||||
!(fs.shadowed));
|
|
||||||
if (cursheet->mark1[X] == 0 && n == 1) {
|
if (cursheet->mark1[X] == 0 && n == 1) {
|
||||||
line_msg(_("Shadow cell:"),_("You can not shadow cells in column 0"));
|
line_msg(_("Shadow cell:"),_("You can not shadow cells in column 0"));
|
||||||
break;
|
break;
|
||||||
@ -415,19 +414,19 @@ static void do_attribute(Sheet *cursheet, Key action)
|
|||||||
if (n >= 0) {
|
if (n >= 0) {
|
||||||
for (ALL_LOCS_IN_REGION(cursheet,w))
|
for (ALL_LOCS_IN_REGION(cursheet,w))
|
||||||
{
|
{
|
||||||
Location r;
|
Location assoc;
|
||||||
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
LOCATION_GETS(r, w);
|
LOCATION_GETS(assoc, w);
|
||||||
if (!shadowed(cursheet, r)) ++(r[X]);
|
if (!shadowed(cursheet, assoc)) assoc[X]++;
|
||||||
for (; shadowed(cursheet, r); ++(r[X]))
|
for (; shadowed(cursheet, assoc); assoc[X]++)
|
||||||
changed = shadow(cursheet, r, false) || changed;
|
changed = shadow(cursheet, assoc, false) || changed;
|
||||||
}
|
}
|
||||||
else if (w[X]>0) changed = shadow(cursheet, w, true) || changed;
|
else if (w[X] > 0) changed = shadow(cursheet, w, true) || changed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (n>0) do_mark(cursheet, UNMARKED);
|
if (n > 0) do_mark(cursheet, UNMARKED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
@ -595,7 +594,6 @@ static int do_savecontext(Sheet *cursheet, const char *name)
|
|||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
const char *msg;
|
const char *msg;
|
||||||
int standalone=0;
|
int standalone=0;
|
||||||
int x1,y1,z1,x2,y2,z2;
|
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
|
||||||
do_mark(cursheet, GET_MARK_ALL);
|
do_mark(cursheet, GET_MARK_ALL);
|
||||||
@ -624,7 +622,6 @@ static int do_savehtml(Sheet *cursheet, const char *name)
|
|||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
const char *msg;
|
const char *msg;
|
||||||
int standalone=0;
|
int standalone=0;
|
||||||
int x1,y1,z1,x2,y2,z2;
|
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
|
||||||
do_mark(cursheet, GET_MARK_ALL);
|
do_mark(cursheet, GET_MARK_ALL);
|
||||||
@ -650,7 +647,6 @@ static int do_savetext(Sheet *cursheet, const char *name)
|
|||||||
{
|
{
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
const char *msg;
|
const char *msg;
|
||||||
int x1,y1,z1,x2,y2,z2;
|
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
|
||||||
do_mark(cursheet, GET_MARK_ALL);
|
do_mark(cursheet, GET_MARK_ALL);
|
||||||
@ -746,10 +742,7 @@ static int do_loadcsv(Sheet *cursheet)
|
|||||||
/* do_mark -- set mark */ /*{{{*/
|
/* do_mark -- set mark */ /*{{{*/
|
||||||
void do_mark(Sheet *cursheet, MarkState ms)
|
void do_mark(Sheet *cursheet, MarkState ms)
|
||||||
{
|
{
|
||||||
MarkState ps;
|
MarkState ps = getmarkstate(cursheet);
|
||||||
Dimensions dim;
|
|
||||||
|
|
||||||
ps = getmarkstate(cursheet);
|
|
||||||
|
|
||||||
if (ms == MARK_CYCLE)
|
if (ms == MARK_CYCLE)
|
||||||
{
|
{
|
||||||
@ -779,8 +772,7 @@ void do_mark(Sheet *cursheet, MarkState ms)
|
|||||||
}
|
}
|
||||||
case MARKING:
|
case MARKING:
|
||||||
{
|
{
|
||||||
for (dim = X; dim < HYPER; ++dim)
|
poscorners(cursheet->mark1, cursheet->mark2);
|
||||||
posorder(&(cursheet->mark1[dim]), &(cursheet->mark2[dim]));
|
|
||||||
ms = MARKED;
|
ms = MARKED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -795,9 +787,8 @@ void do_mark(Sheet *cursheet, MarkState ms)
|
|||||||
else if (ms == GET_MARK_ALL)
|
else if (ms == GET_MARK_ALL)
|
||||||
{
|
{
|
||||||
OLOCATION(cursheet->mark1);
|
OLOCATION(cursheet->mark1);
|
||||||
cursheet->mark2[X] = cursheet->dimx - 1;
|
for (Dimensions dd = X; dd < HYPER; ++dd)
|
||||||
cursheet->mark2[Y] = cursheet->dimy - 1;
|
cursheet->mark2[dd] = (CoordT)(cursheet->dim[dd] - 1);
|
||||||
cursheet->mark2[Z] = cursheet->dimz - 1;
|
|
||||||
ms = UNMARKED;
|
ms = UNMARKED;
|
||||||
}
|
}
|
||||||
else assert(ms == MARKED);
|
else assert(ms == MARKED);
|
||||||
@ -906,15 +897,13 @@ static int do_clear(Sheet *sheet)
|
|||||||
/* do_insert -- insert block */ /*{{{*/
|
/* do_insert -- insert block */ /*{{{*/
|
||||||
static int do_insert(Sheet *sheet)
|
static int do_insert(Sheet *sheet)
|
||||||
{
|
{
|
||||||
int reply;
|
|
||||||
/* ask for direction of insertion */ /*{{{*/
|
|
||||||
{
|
|
||||||
const char* menu[] =
|
const char* menu[] =
|
||||||
{ _("cC)olumn"), _("rR)ow"), _("dD)epth"), NULL };
|
{ [X] = _("cC)olumn"), [Y] = _("rR)ow"),[Z] = _("lL)ayer"), NULL };
|
||||||
reply = line_menu(_("Insert:"), menu, 0);
|
int repl = line_menu(_("Insert:"), menu, 0);
|
||||||
if (reply<0) return reply;
|
if (repl < 0) return repl;
|
||||||
}
|
assert(repl < HYPER);
|
||||||
/*}}}*/
|
Dimensions reply = (Dimensions)repl;
|
||||||
|
|
||||||
do_mark(sheet, GET_MARK_CUR);
|
do_mark(sheet, GET_MARK_CUR);
|
||||||
Location beg, end;
|
Location beg, end;
|
||||||
LOCATION_GETS(beg, sheet->mark1);
|
LOCATION_GETS(beg, sheet->mark1);
|
||||||
@ -923,81 +912,49 @@ static int do_insert(Sheet *sheet)
|
|||||||
if (onecell)
|
if (onecell)
|
||||||
/* ask if current cell or whole dimension should be used */ /*{{{*/
|
/* ask if current cell or whole dimension should be used */ /*{{{*/
|
||||||
{
|
{
|
||||||
const char *menu[3];
|
const char *menu2[3];
|
||||||
/* show menu */ /*{{{*/
|
/* show menu */ /*{{{*/
|
||||||
switch (reply)
|
switch (reply)
|
||||||
{
|
{
|
||||||
case 0: menu[0] = _("wW)hole column"); break;
|
case X: menu2[0] = _("wW)hole column"); break;
|
||||||
case 1: menu[0] = _("wW)hole line"); break;
|
case Y: menu2[0] = _("wW)hole line"); break;
|
||||||
case 2: menu[0] = _("wW)hole sheet"); break;
|
case Z: menu2[0] = _("wW)hole layer"); break;
|
||||||
default: assert(0);
|
case HYPER: assert(0);
|
||||||
}
|
}
|
||||||
menu[1] = _("sS)ingle cell");
|
menu2[1] = _("sS)ingle cell");
|
||||||
menu[2] = NULL;
|
menu2[2] = NULL;
|
||||||
int r = line_menu(_("Insert:"), menu, 0);
|
int r = line_menu(_("Insert:"), menu2, 0);
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
switch (r)
|
switch (r)
|
||||||
{
|
{
|
||||||
/* 0 -- use whole dimension */ /*{{{*/
|
case 0: /* use whole dimension */ /*{{{*/
|
||||||
case 0:
|
|
||||||
{
|
{
|
||||||
switch (reply)
|
switch (reply)
|
||||||
{
|
{
|
||||||
/* 0 -- use whole column */ /*{{{*/
|
case X: /* use whole column */
|
||||||
case 0:
|
beg[Y] = 0; end[Y] = (CoordT)(sheet->dim[Y]); break;
|
||||||
{
|
case Y: /* use whole line */
|
||||||
beg[Y] = 0; end[Y] = sheet->dimy;
|
beg[X] = 0; end[X] = (CoordT)(sheet->dim[X]); break;
|
||||||
|
case Z: /* use whole layer */
|
||||||
|
beg[X] = 0; end[X] = (CoordT)(sheet->dim[X]);
|
||||||
|
beg[Y] = 0; end[Y] = (CoordT)(sheet->dim[Y]);
|
||||||
|
break;
|
||||||
|
case HYPER: assert(0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* 1 -- use whole line */ /*{{{*/
|
case 1: /* use current cell */
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
beg[X] = 0; end[X] = sheet->dimx;
|
|
||||||
break;
|
break;
|
||||||
}
|
/* -2,-1 -- go up or abort */
|
||||||
/*}}}*/
|
case -2: case -1: return r;
|
||||||
/* 2 -- use whole layer */ /*{{{*/
|
/* default -- should not happen */
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
beg[X] = 0; end[X] = sheet->dimx;
|
|
||||||
beg[Y] = 0; end[Y] = sheet->dimy;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*}}}*/
|
|
||||||
/* default -- should not happen */ /*{{{*/
|
|
||||||
default: assert(0);
|
default: assert(0);
|
||||||
/*}}}*/
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* 1 -- use current cell */ /*{{{*/
|
|
||||||
case 1: break;
|
|
||||||
/*}}}*/
|
|
||||||
/* -2,-1 -- go up or abort */ /*{{{*/
|
|
||||||
case -2:
|
|
||||||
case -1: return r;
|
|
||||||
/*}}}*/
|
|
||||||
/* default -- should not happen */ /*{{{*/
|
|
||||||
default: assert(0);
|
|
||||||
/*}}}*/
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/*}}}*/
|
insertcube(sheet, beg, end, reply);
|
||||||
switch (reply)
|
|
||||||
{
|
|
||||||
/* 0 -- columns */ /*{{{*/
|
|
||||||
case 0: insertcube(sheet, beg, end, IN_X); break;
|
|
||||||
/*}}}*/
|
|
||||||
/* 1 -- rows */ /*{{{*/
|
|
||||||
case 1: insertcube(sheet, beg, end, IN_Y); break;
|
|
||||||
/*}}}*/
|
|
||||||
/* 2 -- depth */ /*{{{*/
|
|
||||||
case 2: insertcube(sheet, beg, end, IN_Z); break;
|
|
||||||
/*}}}*/
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
@ -1005,16 +962,14 @@ static int do_insert(Sheet *sheet)
|
|||||||
/* do_delete -- delete block */ /*{{{*/
|
/* do_delete -- delete block */ /*{{{*/
|
||||||
static int do_delete(Sheet *sheet)
|
static int do_delete(Sheet *sheet)
|
||||||
{
|
{
|
||||||
int reply;
|
firstmenu: /* ask for direction of deletion */ /*{{{*/
|
||||||
|
assert(sheet != (Sheet*)0);
|
||||||
firstmenu:
|
|
||||||
/* ask for direction of deletion */ /*{{{*/
|
|
||||||
{
|
|
||||||
const char* menu[] =
|
const char* menu[] =
|
||||||
{ _("cC)olumn"), _("rR)ow"), _("dD)epth"), NULL };
|
{ [X] = _("cC)olumn"), [Y] = _("rR)ow"), [Z] = _("lL)ayer"), NULL };
|
||||||
reply = line_menu(_("Delete:"), menu, 0);
|
int repl = line_menu(_("Delete:"), menu, 0);
|
||||||
if (reply < 0) return reply;
|
if (repl < 0) return repl;
|
||||||
}
|
assert(repl < HYPER);
|
||||||
|
Dimensions reply = (Dimensions)repl;
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
do_mark(sheet, GET_MARK_CUR);
|
do_mark(sheet, GET_MARK_CUR);
|
||||||
@ -1025,19 +980,18 @@ static int do_delete(Sheet *sheet)
|
|||||||
if (onecell)
|
if (onecell)
|
||||||
/* ask if range is the current cell or whole dimension should be used */ /*{{{*/
|
/* ask if range is the current cell or whole dimension should be used */ /*{{{*/
|
||||||
{
|
{
|
||||||
const char *menu[3];
|
const char *menu2[3];
|
||||||
|
|
||||||
/* show menu */ /*{{{*/
|
/* show menu */ /*{{{*/
|
||||||
switch (reply)
|
switch (reply)
|
||||||
{
|
{
|
||||||
case 0: menu[0] = _("wW)hole column"); break;
|
case X: menu2[0] = _("wW)hole column"); break;
|
||||||
case 1: menu[0] = _("wW)hole line"); break;
|
case Y: menu2[0] = _("wW)hole line"); break;
|
||||||
case 2: menu[0] = _("wW)hole sheet"); break;
|
case Z: menu2[0] = _("wW)hole layer"); break;
|
||||||
default: assert(0);
|
case HYPER: assert(0);
|
||||||
}
|
}
|
||||||
menu[1] = _("sS)ingle cell");
|
menu2[1] = _("sS)ingle cell");
|
||||||
menu[2] = NULL;
|
menu2[2] = NULL;
|
||||||
int r = line_menu(_("Delete:"), menu, 0);
|
int r = line_menu(_("Delete:"), menu2, 0);
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
switch (r)
|
switch (r)
|
||||||
{
|
{
|
||||||
@ -1046,64 +1000,30 @@ static int do_delete(Sheet *sheet)
|
|||||||
{
|
{
|
||||||
switch (reply)
|
switch (reply)
|
||||||
{
|
{
|
||||||
/* 0 -- use whole column */ /*{{{*/
|
case X: /* use whole column */
|
||||||
case 0:
|
beg[Y] = 0; end[Y] = (CoordT)(sheet->dim[Y]); break;
|
||||||
{
|
case Y: /* use whole line */
|
||||||
beg[Y] = 0; end[Y] = sheet->dimy;
|
beg[X] = 0; end[X] = (CoordT)(sheet->dim[X]); break;
|
||||||
break;
|
case 2: /* use whole layer */
|
||||||
}
|
beg[X] = 0; end[X] = (CoordT)(sheet->dim[X]);
|
||||||
/*}}}*/
|
beg[Y] = 0; end[Y] = (CoordT)(sheet->dim[Y]);
|
||||||
/* 1 -- use whole line */ /*{{{*/
|
case HYPER: assert(0);
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
beg[X] = 0; end[X] = sheet->dimx;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*}}}*/
|
|
||||||
/* 2 -- use whole layer */ /*{{{*/
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
beg[X] = 0; end[X] = sheet->dimx;
|
|
||||||
beg[Y] = 0; end[Y] = sheet->dimy;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*}}}*/
|
|
||||||
/* default -- should not happen */ /*{{{*/
|
|
||||||
default: assert(0);
|
|
||||||
/*}}}*/
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* 1 -- use current cell */ /*{{{*/
|
case 1: /* use current cell */
|
||||||
case 1: break;
|
break;
|
||||||
/*}}}*/
|
case -1: /* abort */
|
||||||
/* -1 -- abort */ /*{{{*/
|
|
||||||
case -1: return -1;
|
|
||||||
/*}}}*/
|
|
||||||
/* -2 -- go back to previous menu */ /*{{{*/
|
|
||||||
case -2: goto firstmenu;
|
|
||||||
/*}}}*/
|
|
||||||
/* default -- should not happen */ /*{{{*/
|
|
||||||
default: assert(0);
|
|
||||||
/*}}}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*}}}*/
|
|
||||||
/*}}}*/
|
|
||||||
switch(reply)
|
|
||||||
{
|
|
||||||
/* 0 -- columns */ /*{{{*/
|
|
||||||
case 0: deletecube(sheet, beg, end, IN_X); break;
|
|
||||||
/*}}}*/
|
|
||||||
/* 1 -- rows */ /*{{{*/
|
|
||||||
case 1: deletecube(sheet, beg, end, IN_Y); break;
|
|
||||||
/*}}}*/
|
|
||||||
/* 2 -- depth */ /*{{{*/
|
|
||||||
case 2: deletecube(sheet, beg, end, IN_Z); break;
|
|
||||||
/*}}}*/
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
|
case -2: goto firstmenu;
|
||||||
|
default: assert(0);
|
||||||
|
}
|
||||||
|
/*}}}*/
|
||||||
|
}
|
||||||
|
/*}}}*/
|
||||||
|
deletecube(sheet, beg, end, reply);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
@ -1121,25 +1041,19 @@ static int do_move(Sheet *sheet, int copy, int force)
|
|||||||
moveblock(sheet, sheet->mark1, sheet->mark2, sheet->cur, copy);
|
moveblock(sheet, sheet->mark1, sheet->mark2, sheet->cur, copy);
|
||||||
if (!copy) sheet->marking = UNMARKED;
|
if (!copy) sheet->marking = UNMARKED;
|
||||||
}
|
}
|
||||||
if (c<0) return c; else return -1;
|
if (c<0) return c; else return 0;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
/* do_fill -- fill a block */ /*{{{*/
|
/* do_fill -- fill a block */ /*{{{*/
|
||||||
static int do_fill(Sheet *sheet)
|
static int do_fill(Sheet *sheet)
|
||||||
{
|
{
|
||||||
/* variables */ /*{{{*/
|
if (getmarkstate(sheet) == UNMARKED)
|
||||||
int cols,rows,layers;
|
line_msg(_("Fill block:"), _("No block marked"));
|
||||||
int x,y,z;
|
|
||||||
Location wid, go;
|
|
||||||
int c;
|
|
||||||
/*}}}*/
|
|
||||||
|
|
||||||
if (getmarkstate(sheet) == UNMARKED) line_msg(_("Fill block:"),_("No block marked"));
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
do_mark(sheet, MARKED);
|
do_mark(sheet, MARKED);
|
||||||
cols=rows=layers=1;
|
int cols = 1, rows = 1, layers = 1;
|
||||||
firstmenu:
|
firstmenu:
|
||||||
do {
|
do {
|
||||||
int c = line_numedit(&cols, _("Number of column-wise repetitions:"));
|
int c = line_numedit(&cols, _("Number of column-wise repetitions:"));
|
||||||
@ -1158,15 +1072,21 @@ static int do_fill(Sheet *sheet)
|
|||||||
if (c == -1) return -1;
|
if (c == -1) return -1;
|
||||||
else if (c == -2) goto secondmenu;
|
else if (c == -2) goto secondmenu;
|
||||||
} while (layers <= 0);
|
} while (layers <= 0);
|
||||||
|
Location wid;
|
||||||
LOCATION_GETS(wid, sheet->mark2);
|
LOCATION_GETS(wid, sheet->mark2);
|
||||||
LOCATION_SUB(wid, sheet->mark1);
|
LOCATION_SUB(wid, sheet->mark1);
|
||||||
wid[X]++; wid[Y]++; wid[Z]++;
|
wid[X]++; wid[Y]++; wid[Z]++;
|
||||||
LOCATION_GETS(go, sheet->cur);
|
Location go;
|
||||||
for (z=0; z<layers; ++z, go[Z] += wid[Z])
|
go[Z] = sheet->cur[Z];
|
||||||
for (y=0, go[Y] = sheet->cur[Y]; y<rows; ++y, go[Y] += wid[Y])
|
for (int z = 0; z < layers; ++z, go[Z] += wid[Z]) {
|
||||||
for (x=0, go[X] = sheet->cur[X]; x<cols; ++x, go[X] += wid[X])
|
go[Y] = sheet->cur[Y];
|
||||||
|
for (int y = 0; y < rows; ++y, go[Y] += wid[Y]) {
|
||||||
|
go[X] = sheet->cur[X];
|
||||||
|
for (int x = 0; x < cols; ++x, go[X] += wid[X])
|
||||||
moveblock(sheet, sheet->mark1, sheet->mark2, go, 1);
|
moveblock(sheet, sheet->mark1, sheet->mark2, go, 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
@ -1191,28 +1111,22 @@ static int do_sort(Sheet *sheet)
|
|||||||
do_mark(sheet, GET_MARK_ALL);
|
do_mark(sheet, GET_MARK_ALL);
|
||||||
/* build menus */ /*{{{*/
|
/* build menus */ /*{{{*/
|
||||||
const char* menu1[] =
|
const char* menu1[] =
|
||||||
{ _("cC)olumn"), _("rR)ow"), _("dD)epth"), NULL };
|
{ [X] = _("cC)olumn"), [Y] = _("rR)ow"), [Z] = _("dD)epth"), NULL };
|
||||||
const char* menu2[] =
|
const char* menu2[] =
|
||||||
{ _("sS)ort region"), _("aA)dd key"), NULL };
|
{ _("sS)ort region"), _("aA)dd key"), NULL };
|
||||||
const char* menu3[] =
|
const char* menu3[] =
|
||||||
{ _("aA)scending"), _("dD)escending"), NULL };
|
{ _("aA)scending"), _("dD)escending"), NULL };
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
int last = -1;
|
Dimensions in_dir = HYPER;
|
||||||
Direction in_dir = (Direction)-2; /* cause run time error */
|
|
||||||
int dir;
|
int dir;
|
||||||
/* ask for sort direction */ /*{{{*/
|
/* ask for sort direction */ /*{{{*/
|
||||||
zero:
|
zero:
|
||||||
dir = line_menu(_("Sort block:"), menu1, 0);
|
dir = line_menu(_("Sort block:"), menu1, 0);
|
||||||
switch (dir)
|
if (dir < 0) return dir;
|
||||||
{
|
assert(dir < HYPER);
|
||||||
case 0: in_dir = IN_X; break;
|
in_dir = (Dimensions)dir;
|
||||||
case 1: in_dir = IN_Y; break;
|
int last = 0;
|
||||||
case 2: in_dir = IN_Z; break;
|
|
||||||
case -2: case -1: return dir;
|
|
||||||
default: assert(0);
|
|
||||||
}
|
|
||||||
last=0;
|
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
Sortkey sk[MAX_SORTKEYS];
|
Sortkey sk[MAX_SORTKEYS];
|
||||||
unsigned int key = 0;
|
unsigned int key = 0;
|
||||||
@ -1220,34 +1134,27 @@ static int do_sort(Sheet *sheet)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* ask for positions */ /*{{{*/
|
/* ask for positions */ /*{{{*/
|
||||||
one: if (in_dir==IN_X) sk[key].x=0; else /* ask for x position */ /*{{{*/
|
one:
|
||||||
{
|
sk[key].soff[X] = 0;
|
||||||
sk[key].x = 0;
|
if (in_dir != X) do {
|
||||||
do
|
int c = line_numedit(&(sk[key].soff[X]), _("X position of key vector:"));
|
||||||
{
|
|
||||||
int c = line_numedit(&(sk[key].x), _("X position of key vector:"));
|
|
||||||
if (c == -1) return -1;
|
if (c == -1) return -1;
|
||||||
else if (c == -2) switch (last)
|
else if (c == -2) switch (last) {
|
||||||
{
|
|
||||||
case -1: return -2;
|
case -1: return -2;
|
||||||
case 0: goto zero;
|
case 0: goto zero;
|
||||||
case 2: goto two;
|
case 2: goto two;
|
||||||
case 3: goto three;
|
case 3: goto three;
|
||||||
case 5: goto five;
|
case 5: goto five;
|
||||||
}
|
}
|
||||||
} while (sk[key].x < 0);
|
} while (sk[key].soff[X] < 0);
|
||||||
last = 1;
|
last = 1;
|
||||||
}
|
|
||||||
/*}}}*/
|
two:
|
||||||
two: if (in_dir==IN_Y) sk[key].y=0; else /* ask for y position */ /*{{{*/
|
sk[key].soff[Y] = 0;
|
||||||
{
|
if (in_dir != Y) do {
|
||||||
sk[key].y = 0;
|
int c = line_numedit(&(sk[key].soff[Y]), _("Y position of key vector:"));
|
||||||
do
|
|
||||||
{
|
|
||||||
int c = line_numedit(&(sk[key].y), _("Y position of key vector:"));
|
|
||||||
if (c == -1) return -1;
|
if (c == -1) return -1;
|
||||||
else if (c == -2) switch (last)
|
else if (c == -2) switch (last) {
|
||||||
{
|
|
||||||
case -1: return -2;
|
case -1: return -2;
|
||||||
case 0: goto zero;
|
case 0: goto zero;
|
||||||
case 1: goto one;
|
case 1: goto one;
|
||||||
@ -1255,19 +1162,15 @@ static int do_sort(Sheet *sheet)
|
|||||||
case 5: goto five;
|
case 5: goto five;
|
||||||
default: assert(0);
|
default: assert(0);
|
||||||
}
|
}
|
||||||
} while (sk[key].y < 0);
|
} while (sk[key].soff[Y] < 0);
|
||||||
last = 2;
|
last = 2;
|
||||||
}
|
|
||||||
/*}}}*/
|
three:
|
||||||
three: if (in_dir==IN_Z) sk[key].z=0; else /* ask for z position */ /*{{{*/
|
sk[key].soff[Z] = 0;
|
||||||
{
|
if (in_dir != Z) do {
|
||||||
sk[key].z = 0;
|
int c = line_numedit(&(sk[key].soff[Y]), _("Z position of key vector:"));
|
||||||
do
|
|
||||||
{
|
|
||||||
int c = line_numedit(&(sk[key].z), _("Z position of key vector:"));
|
|
||||||
if (c == -1) return -1;
|
if (c == -1) return -1;
|
||||||
else if (c == -2) switch (last)
|
else if (c == -2) switch (last) {
|
||||||
{
|
|
||||||
case -1: return -2;
|
case -1: return -2;
|
||||||
case 0: goto zero;
|
case 0: goto zero;
|
||||||
case 1: goto one;
|
case 1: goto one;
|
||||||
@ -1275,13 +1178,12 @@ static int do_sort(Sheet *sheet)
|
|||||||
case 5: goto five;
|
case 5: goto five;
|
||||||
default: assert(0);
|
default: assert(0);
|
||||||
}
|
}
|
||||||
} while (sk[key].z < 0);
|
} while (sk[key].soff[Z] < 0);
|
||||||
last = 3;
|
last = 3;
|
||||||
}
|
|
||||||
/*}}}*/
|
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* ask for sort key */ /*{{{*/
|
/* ask for sort key */ /*{{{*/
|
||||||
four: sk[key].sortkey=0;
|
four:
|
||||||
|
sk[key].sortkey=0;
|
||||||
int ckey = line_menu(_("Sort block:"), menu3, 0);
|
int ckey = line_menu(_("Sort block:"), menu3, 0);
|
||||||
switch (ckey)
|
switch (ckey)
|
||||||
{
|
{
|
||||||
@ -1301,10 +1203,11 @@ static int do_sort(Sheet *sheet)
|
|||||||
last = 4;
|
last = 4;
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
++key;
|
++key;
|
||||||
|
|
||||||
five:
|
five:
|
||||||
if (key == MAX_SORTKEYS) /* ask for sort comfirmation */ /*{{{*/
|
if (key == MAX_SORTKEYS) /* ask for sort comfirmation */ /*{{{*/
|
||||||
{
|
{
|
||||||
int c = line_ok(_("Sort block:"),0);
|
int c = line_ok(_("Sort block:"), 0);
|
||||||
if (c == -1) return -1;
|
if (c == -1) return -1;
|
||||||
else if (c == -2) goto four;
|
else if (c == -2) goto four;
|
||||||
else if (c == 0) doit = true;
|
else if (c == 0) doit = true;
|
||||||
@ -1324,69 +1227,60 @@ static int do_sort(Sheet *sheet)
|
|||||||
} while (!doit);
|
} while (!doit);
|
||||||
const char *msg =
|
const char *msg =
|
||||||
sortblock(sheet, sheet->mark1, sheet->mark2, in_dir, sk, key);
|
sortblock(sheet, sheet->mark1, sheet->mark2, in_dir, sk, key);
|
||||||
if (msg != NULL) line_msg(_("Sort block:"), msg);
|
if (msg != NULL) { line_msg(_("Sort block:"), msg); return -1; }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
/* do_batchsort -- sort block in a batch*/ /*{{{*/
|
/* do_batchsort -- sort block in a batch*/ /*{{{*/
|
||||||
static void do_batchsort(Sheet *sheet, Direction dir, char* arg)
|
static void do_batchsort(Sheet *sheet, Dimensions dm, char* arg)
|
||||||
{
|
{
|
||||||
Sortkey sk[MAX_SORTKEYS];
|
Sortkey sk[MAX_SORTKEYS];
|
||||||
int x1,y1,z1,x2,y2,z2;
|
|
||||||
unsigned int key = 0;
|
unsigned int key = 0;
|
||||||
char* next;
|
char* next;
|
||||||
while( *arg != '\0' )
|
while( *arg != '\0' )
|
||||||
{
|
{
|
||||||
while (isspace((int)*arg)) arg++;
|
while (isspace((int)*arg)) arg++;
|
||||||
sk[key].x=sk[key].y=sk[key].z=sk[key].sortkey=0;
|
OLOCATION(sk[key].soff);
|
||||||
|
sk[key].sortkey = 0;
|
||||||
switch (*arg)
|
switch (*arg)
|
||||||
{
|
{
|
||||||
case 'a': sk[key].sortkey|=ASCENDING; arg++; break;
|
case 'a': sk[key].sortkey |= ASCENDING; arg++; break;
|
||||||
case 'd': sk[key].sortkey&=~ASCENDING; arg++; break;
|
case 'd': sk[key].sortkey &= ~ASCENDING; arg++; break;
|
||||||
}
|
}
|
||||||
if ( *arg != '\0' && dir != IN_X ) { sk[key].x=strtol(arg, &next, 10); arg = next; }
|
if ( *arg != '\0' && dm != X ) {
|
||||||
if ( *arg != '\0' && dir != IN_Y ) { sk[key].y=strtol(arg, &next, 10); arg = next; }
|
sk[key].soff[X] = (CoordT)strtol(arg, &next, 10); arg = next;
|
||||||
if ( *arg != '\0' && dir != IN_Z ) { sk[key].z=strtol(arg, &next, 10); arg = next; }
|
}
|
||||||
key++;
|
if ( *arg != '\0' && dm != Y ) {
|
||||||
|
sk[key].soff[Y] = (CoordT)strtol(arg, &next, 10); arg = next;
|
||||||
|
}
|
||||||
|
if ( *arg != '\0' && dm != Z ) {
|
||||||
|
sk[key].soff[Z] = (CoordT)strtol(arg, &next, 10); arg = next;
|
||||||
|
}
|
||||||
|
++key;
|
||||||
}
|
}
|
||||||
do_mark(sheet, GET_MARK_ALL);
|
do_mark(sheet, GET_MARK_ALL);
|
||||||
sortblock(sheet, sheet->mark1, sheet->mark2, dir, sk, key);
|
sortblock(sheet, sheet->mark1, sheet->mark2, dm, sk, key);
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
/* do_mirror -- mirror block */ /*{{{*/
|
/* do_mirror -- mirror block */ /*{{{*/
|
||||||
static int do_mirror(Sheet *sheet)
|
static int do_mirror(Sheet *sheet)
|
||||||
{
|
{
|
||||||
/* variables */ /*{{{*/
|
|
||||||
int x1,y1,z1,x2,y2,z2,reply;
|
|
||||||
/*}}}*/
|
|
||||||
|
|
||||||
do_mark(sheet, GET_MARK_ALL);
|
do_mark(sheet, GET_MARK_ALL);
|
||||||
/* ask for direction of mirroring */ /*{{{*/
|
/* ask for direction of mirroring */ /*{{{*/
|
||||||
{
|
|
||||||
const char *menu[] =
|
const char *menu[] =
|
||||||
{ _("lL)eft-right"), _("uU)pside-down"), _("fF)ront-back"), NULL};
|
{ [X] = _("lL)eft-right"), [Y] = _("uU)pside-down"),
|
||||||
reply = line_menu(_("Mirror block:"), menu, 0);
|
[Z] = _("aA)bove-below"), NULL};
|
||||||
|
int reply = line_menu(_("Mirror block:"), menu, 0);
|
||||||
if (reply < 0) return reply;
|
if (reply < 0) return reply;
|
||||||
}
|
assert(reply < HYPER);
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
switch (reply)
|
mirrorblock(sheet, sheet->mark1, sheet->mark2, (Dimensions)reply);
|
||||||
{
|
|
||||||
/* 0 -- left-right */ /*{{{*/
|
|
||||||
case 0: mirrorblock(sheet, sheet->mark1, sheet->mark2, IN_X); break;
|
|
||||||
/*}}}*/
|
|
||||||
/* 1 -- upside-down */ /*{{{*/
|
|
||||||
case 1: mirrorblock(sheet, sheet->mark1, sheet->mark2, IN_Y); break;
|
|
||||||
/*}}}*/
|
|
||||||
/* 2 -- front-back */ /*{{{*/
|
|
||||||
case 2: mirrorblock(sheet, sheet->mark1, sheet->mark2, IN_Z); break;
|
|
||||||
/*}}}*/
|
|
||||||
default: assert(0);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
/* do_goto -- go to a specific cell */ /*{{{*/
|
/* do_goto -- go to a specific cell */ /*{{{*/
|
||||||
static int do_goto(Sheet *sheet, const char *expr)
|
static int do_goto(Sheet *sheet, const char *expr)
|
||||||
{
|
{
|
||||||
@ -1422,7 +1316,7 @@ static int do_goto(Sheet *sheet, const char *expr)
|
|||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
/* do_sheetcmd -- process one key press */ /*{{{*/
|
/* do_sheetcmd -- process one key press */ /*{{{*/
|
||||||
int do_sheetcmd(Sheet *cursheet, Key c, int moveonly)
|
int do_sheetcmd(Sheet *cursheet, Key c, bool moveonly)
|
||||||
{
|
{
|
||||||
switch ((int)c)
|
switch ((int)c)
|
||||||
{
|
{
|
||||||
@ -1494,7 +1388,8 @@ int do_sheetcmd(Sheet *cursheet, Key c, int moveonly)
|
|||||||
case K_LASTL:
|
case K_LASTL:
|
||||||
case '>':
|
case '>':
|
||||||
{
|
{
|
||||||
moveto(cursheet, -1, (cursheet->dimy ? cursheet->dimy-1 : 0), -1);
|
moveto(cursheet,
|
||||||
|
-1, ((cursheet->dim[Y] > 0) ? (CoordT)(cursheet->dim[Y]-1) : 0), -1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
@ -1508,11 +1403,12 @@ int do_sheetcmd(Sheet *cursheet, Key c, int moveonly)
|
|||||||
/* END -- move to end of line */ /*{{{*/
|
/* END -- move to end of line */ /*{{{*/
|
||||||
case K_END:
|
case K_END:
|
||||||
{
|
{
|
||||||
moveto(cursheet, (cursheet->dimx ? cursheet->dimx-1 : 0), -1, -1);
|
moveto(cursheet,
|
||||||
|
((cursheet->dim[X] > 0) ? (CoordT)(cursheet->dim[X]-1) : 0), -1, -1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* + -- move one sheet down */ /*{{{*/
|
/* + -- move one layer down */ /*{{{*/
|
||||||
case K_NSHEET:
|
case K_NSHEET:
|
||||||
case '+':
|
case '+':
|
||||||
{
|
{
|
||||||
@ -1520,7 +1416,7 @@ int do_sheetcmd(Sheet *cursheet, Key c, int moveonly)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* - -- move one sheet up */ /*{{{*/
|
/* - -- move one layer up */ /*{{{*/
|
||||||
case K_PSHEET:
|
case K_PSHEET:
|
||||||
case '-':
|
case '-':
|
||||||
{
|
{
|
||||||
@ -1528,15 +1424,16 @@ int do_sheetcmd(Sheet *cursheet, Key c, int moveonly)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* * -- move to bottom sheet */ /*{{{*/
|
/* * -- move to bottom layer */ /*{{{*/
|
||||||
case K_LSHEET:
|
case K_LSHEET:
|
||||||
case '*':
|
case '*':
|
||||||
{
|
{
|
||||||
moveto(cursheet, -1, -1, (cursheet->dimz ? cursheet->dimz-1 : 0));
|
moveto(cursheet,
|
||||||
|
-1, -1, ((cursheet->dim[Z] > 0) ? (CoordT)(cursheet->dim[Z]-1) : 0));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* _ -- move to top sheet */ /*{{{*/
|
/* _ -- move to top layer */ /*{{{*/
|
||||||
case K_FSHEET:
|
case K_FSHEET:
|
||||||
case '_':
|
case '_':
|
||||||
{
|
{
|
||||||
@ -1671,7 +1568,7 @@ int do_sheetcmd(Sheet *cursheet, Key c, int moveonly)
|
|||||||
/* NPAGE -- page down */ /*{{{*/
|
/* NPAGE -- page down */ /*{{{*/
|
||||||
case K_NPAGE:
|
case K_NPAGE:
|
||||||
{
|
{
|
||||||
cursheet->offy+=(cursheet->maxy-3);
|
cursheet->offy += (cursheet->maxy-3);
|
||||||
relmoveto(cursheet, 0, cursheet->maxy-3, 0);
|
relmoveto(cursheet, 0, cursheet->maxy-3, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1679,26 +1576,32 @@ int do_sheetcmd(Sheet *cursheet, Key c, int moveonly)
|
|||||||
/* PPAGE -- page up */ /*{{{*/
|
/* PPAGE -- page up */ /*{{{*/
|
||||||
case K_PPAGE:
|
case K_PPAGE:
|
||||||
{
|
{
|
||||||
cursheet->offy = (cursheet->offy>=(cursheet->maxy-3) ? cursheet->offy-(cursheet->maxy-3) : 0);
|
cursheet->offy = cursheet->offy >= cursheet->maxy - 3
|
||||||
relmoveto(cursheet, 0, (cursheet->cur[Y] >= (cursheet->maxy-3) ? -(cursheet->maxy-3) : -cursheet->cur[Y]), 0);
|
? cursheet->offy - cursheet->maxy + 3 : 0;
|
||||||
|
relmoveto(cursheet, 0,
|
||||||
|
cursheet->cur[Y] >= (cursheet->maxy - 3)
|
||||||
|
? -(cursheet->maxy - 3) : -cursheet->cur[Y],
|
||||||
|
0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* FPAGE -- page right */ /*{{{*/
|
/* FPAGE -- page right */ /*{{{*/
|
||||||
case K_FPAGE:
|
case K_FPAGE:
|
||||||
{
|
{
|
||||||
cursheet->offx+=cursheet->width;
|
cursheet->offx += cursheet->width;
|
||||||
relmoveto(cursheet, cursheet->width, 0, 0);
|
relmoveto(cursheet, (CoordT)(cursheet->width), 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* BPAGE -- page left */ /*{{{*/
|
/* BPAGE -- page left */ /*{{{*/
|
||||||
case K_BPAGE:
|
case K_BPAGE:
|
||||||
{
|
cursheet->offx = (size_t)(cursheet->offx) >= cursheet->width
|
||||||
cursheet->offx=(cursheet->offx>=cursheet->width ? cursheet->offx-cursheet->width : 0);
|
? cursheet->offx - (CoordT)(cursheet->width) : 0;
|
||||||
relmoveto(cursheet, (cursheet->cur[X]>=cursheet->width ? -cursheet->width : -cursheet->cur[X]), 0, 0);
|
relmoveto(cursheet,
|
||||||
|
((size_t)(cursheet->cur[X]) >= cursheet->width
|
||||||
|
? -((CoordT)(cursheet->width)) : -cursheet->cur[X]),
|
||||||
|
0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* SAVEQUIT -- save and quit */ /*{{{*/
|
/* SAVEQUIT -- save and quit */ /*{{{*/
|
||||||
case K_SAVEQUIT:
|
case K_SAVEQUIT:
|
||||||
@ -1763,14 +1666,15 @@ int main(int argc, char *argv[])
|
|||||||
long n;
|
long n;
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
n=strtol(optarg,&end,0);
|
n = strtol(optarg,&end,0);
|
||||||
if (*end || n < 0 || n > LDBL_DIG)
|
if (*end || n < 0 || n > FLT_T_DIG)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
_("teapot: precision must be between 0 and %d.\n"), LDBL_DIG);
|
_("teapot: default precision must be between 0 and %d.\n"),
|
||||||
|
FLT_T_DIG);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
def_precision=n;
|
def_precision = (PrecisionLevel)n;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
@ -1865,13 +1769,13 @@ int main(int argc, char *argv[])
|
|||||||
else if (strcmp(cmd,"load-csv")==0) { loadcsv(cursheet,arg); forceupdate(cursheet); }
|
else if (strcmp(cmd,"load-csv")==0) { loadcsv(cursheet,arg); forceupdate(cursheet); }
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* sort in x direction */ /*{{{*/
|
/* sort in x direction */ /*{{{*/
|
||||||
else if (strcmp(cmd,"sort-x")==0) do_batchsort(cursheet, IN_X, arg);
|
else if (strcmp(cmd,"sort-x")==0) do_batchsort(cursheet, X, arg);
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* sort in y direction */ /*{{{*/
|
/* sort in y direction */ /*{{{*/
|
||||||
else if (strcmp(cmd,"sort-y")==0) do_batchsort(cursheet, IN_Y, arg);
|
else if (strcmp(cmd,"sort-y")==0) do_batchsort(cursheet, Y, arg);
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* sort in z direction */ /*{{{*/
|
/* sort in z direction */ /*{{{*/
|
||||||
else if (strcmp(cmd,"sort-z")==0) do_batchsort(cursheet, IN_Z, arg);
|
else if (strcmp(cmd,"sort-z")==0) do_batchsort(cursheet, Z, arg);
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
/* this is an unknown command */ /*{{{*/
|
/* this is an unknown command */ /*{{{*/
|
||||||
else line_msg(_("Unknown batch command:"),cmd);
|
else line_msg(_("Unknown batch command:"),cmd);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
if ((size_t)x < sheet->dim[X] && (size_t)z < sheet->dim[Z])
|
||||||
*(dummy.column+x*dummy.dimz+z)=*(sheet->column+x*sheet->dimz+z);
|
*(dummy.column + ((size_t)x)*dummy.dim[Z] + (size_t)z)
|
||||||
else *(dummy.column+x*dummy.dimz+z)=DEF_COLUMNWIDTH;
|
= *(sheet->column + ((size_t)x)*sheet->dim[Z] + z);
|
||||||
|
else
|
||||||
|
*(dummy.column + ((size_t)x)*dummy.dim[Z] + (size_t)z)
|
||||||
|
= DEF_COLUMNWIDTH;
|
||||||
}
|
}
|
||||||
if (sheet->column!=(int*)0) free(sheet->column);
|
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]--)
|
||||||
|
for (w[Y] = start[Y]; w[Y] >= fini[Y]; w[Y]--)
|
||||||
|
for (w[X] = start[X]; w[X] >= fini[X]; w[Z]--)
|
||||||
{
|
{
|
||||||
/* IN_X */ /*{{{*/
|
resize(sh, w[X], w[Y], w[Z], NULL);
|
||||||
case IN_X:
|
Location from; LOCATION_GETS(from,w);
|
||||||
{
|
from[dm] -= end[dm]-beg[dm]+1;
|
||||||
int right;
|
CELL_AT(sh,w) = CELL_AT(sh,from);
|
||||||
|
CELL_AT(sh,from) = NULLCELL;
|
||||||
right=sheet->dimx+end[X]-beg[X];
|
|
||||||
for (z=beg[Z]; z<=end[Z]; ++z) for (y=beg[Y]; y<=end[Y]; ++y) for (x=right; x>end[X]; --x)
|
|
||||||
{
|
|
||||||
resize(sheet, x, y, z, NULL);
|
|
||||||
CELL_ATC(sheet,x,y,z) = CELL_ATC(sheet,x-(end[X]-beg[X]+1),y,z);
|
|
||||||
CELL_ATC(sheet,x-(end[X]-beg[X]+1),y,z) = NULLCELL;
|
|
||||||
}
|
}
|
||||||
break;
|
sh->changed = true;
|
||||||
}
|
cachelabels(sh);
|
||||||
/*}}}*/
|
forceupdate(sh);
|
||||||
/* IN_Y */ /*{{{*/
|
|
||||||
case IN_Y:
|
|
||||||
{
|
|
||||||
int down;
|
|
||||||
|
|
||||||
down=sheet->dimy+end[Y]-beg[Y];
|
|
||||||
for (z=beg[Z]; z<=end[Z]; ++z) for (x=beg[X]; x<=end[X]; ++x) for (y=down; y>end[Y]; --y)
|
|
||||||
{
|
|
||||||
resize(sheet, x, y, z, NULL);
|
|
||||||
CELL_ATC(sheet,x,y,z) = CELL_ATC(sheet,x,y-(end[Y]-beg[Y]+1),z);
|
|
||||||
CELL_ATC(sheet,x,y-(end[Y]-beg[Y]+1),z) = NULLCELL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*}}}*/
|
|
||||||
/* IN_Z */ /*{{{*/
|
|
||||||
case IN_Z:
|
|
||||||
{
|
|
||||||
int bottom;
|
|
||||||
|
|
||||||
bottom=sheet->dimz+end[Z]-beg[Z];
|
|
||||||
for (y=beg[Y]; y<=end[Y]; ++y) for (x=beg[X]; x<=end[X]; ++x) for (z=bottom; z>end[Z]; --z)
|
|
||||||
{
|
|
||||||
resize(sheet, x, y, z, NULL);
|
|
||||||
CELL_ATC(sheet,x,y,z) = CELL_ATC(sheet,x,y,z-(end[Z]-beg[Z]+1));
|
|
||||||
CELL_ATC(sheet,x,y,z-(end[Z]-beg[Z]+1)) = NULLCELL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*}}}*/
|
|
||||||
/* default */ /*{{{*/
|
|
||||||
default: assert(0);
|
|
||||||
/*}}}*/
|
|
||||||
}
|
|
||||||
sheet->changed=1;
|
|
||||||
cachelabels(sheet);
|
|
||||||
forceupdate(sheet);
|
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
/* 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);
|
||||||
|
for (w[Z] = beg[Z]; w[Z] <= fini[Z]; w[Z]++)
|
||||||
|
for (w[Y] = beg[Y]; w[Y] <= fini[Y]; w[Y]++)
|
||||||
|
for (w[X] = beg[X]; w[X] <= fini[X]; w[X]++)
|
||||||
{
|
{
|
||||||
/* IN_X */ /*{{{*/
|
Location fm; LOCATION_GETS(fm, w);
|
||||||
case IN_X:
|
fm[dm] += end[dm]-beg[dm]+1;
|
||||||
{
|
if (LOC_WITHIN(sh,fm)) {
|
||||||
for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++w[Z])
|
CELL_AT(sh,w) = CELL_AT(sh,fm); CELL_AT(sh,fm) = NULLCELL;
|
||||||
for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++w[Y])
|
|
||||||
for (w[X]=beg[X]; w[X]<=sheet->dimx-(end[X]-beg[X]+1); ++w[X])
|
|
||||||
{
|
|
||||||
LOCATION_GETS(fm, w);
|
|
||||||
fm[X] += end[X]-beg[X]+1;
|
|
||||||
if (LOC_WITHIN(sheet,fm))
|
|
||||||
{
|
|
||||||
CELL_AT(sheet,w) = CELL_AT(sheet,fm);
|
|
||||||
CELL_AT(sheet,fm) = NULLCELL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
sh->changed = true;
|
||||||
}
|
cachelabels(sh);
|
||||||
/*}}}*/
|
forceupdate(sh);
|
||||||
/* IN_Y */ /*{{{*/
|
|
||||||
case IN_Y:
|
|
||||||
{
|
|
||||||
for (w[Z]=beg[Z]; w[Z]<=end[Z]; ++w[Z])
|
|
||||||
for (w[X]=beg[X]; w[X]<=end[X]; ++w[X])
|
|
||||||
for (w[Y]=beg[Y]; w[Y]<=sheet->dimy-(end[Y]-beg[Y]+1); ++w[Y])
|
|
||||||
{
|
|
||||||
LOCATION_GETS(fm, w);
|
|
||||||
fm[Y] += end[Y]-beg[Y]+1;
|
|
||||||
if (LOC_WITHIN(sheet,fm))
|
|
||||||
{
|
|
||||||
CELL_AT(sheet,w) = CELL_AT(sheet,fm);
|
|
||||||
CELL_AT(sheet,fm) = NULLCELL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*}}}*/
|
|
||||||
/* IN_Z */ /*{{{*/
|
|
||||||
case IN_Z:
|
|
||||||
{
|
|
||||||
for (w[Y]=beg[Y]; w[Y]<=end[Y]; ++w[Y])
|
|
||||||
for (w[X]=beg[X]; w[X]<=end[X]; ++w[X])
|
|
||||||
for (w[Z]=beg[Z]; w[Z]<=sheet->dimz-(end[Z]-beg[Z]+1); ++w[Z])
|
|
||||||
{
|
|
||||||
LOCATION_GETS(fm, w);
|
|
||||||
fm[Z] += end[Z]-beg[Z]+1;
|
|
||||||
if (LOC_WITHIN(sheet,fm))
|
|
||||||
{
|
|
||||||
CELL_AT(sheet,w) = CELL_AT(sheet,fm);
|
|
||||||
CELL_AT(sheet,fm) = NULLCELL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*}}}*/
|
|
||||||
/* default */ /*{{{*/
|
|
||||||
default: assert(0);
|
|
||||||
/*}}}*/
|
|
||||||
}
|
|
||||||
sheet->changed=1;
|
|
||||||
cachelabels(sheet);
|
|
||||||
forceupdate(sheet);
|
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
@ -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;
|
Location wbeg, wend;
|
||||||
int incx=0,incy=0,incz=0;
|
LOCATION_GETS(wbeg, beg);
|
||||||
int distx,disty,distz;
|
LOCATION_GETS(wend, end);
|
||||||
int i,r=-3,work;
|
|
||||||
|
poscorners(wbeg, wend);
|
||||||
|
|
||||||
|
Location dist; LOCATION_GETS(dist, wend);
|
||||||
|
LOCATION_SUB(dist, wbeg);
|
||||||
|
Location one = {1, 1, 1};
|
||||||
|
LOCATION_ADD(dist, one);
|
||||||
|
|
||||||
|
Location inc; OLOCATION(inc);
|
||||||
|
inc[dm] = 1; wend[dm]--; dist[dm] = 1;
|
||||||
|
|
||||||
bool norel = false;
|
bool norel = false;
|
||||||
/*}}}*/
|
bool work;
|
||||||
|
|
||||||
/* unpack corners */
|
|
||||||
x1 = beg[X]; y1 = beg[Y]; z1 = beg[Z];
|
|
||||||
x2 = end[X]; y2 = end[Y]; z2 = end[Z];
|
|
||||||
|
|
||||||
/* asserts */ /*{{{*/
|
|
||||||
assert(sklen>0);
|
|
||||||
assert(x1>=0);
|
|
||||||
assert(x2>=0);
|
|
||||||
assert(y1>=0);
|
|
||||||
assert(y2>=0);
|
|
||||||
assert(z1>=0);
|
|
||||||
assert(z2>=0);
|
|
||||||
/*}}}*/
|
|
||||||
norel=0;
|
|
||||||
posorder(&x1,&x2);
|
|
||||||
posorder(&y1,&y2);
|
|
||||||
posorder(&z1,&z2);
|
|
||||||
distx=(x2-x1+1);
|
|
||||||
disty=(y2-y1+1);
|
|
||||||
distz=(z2-z1+1);
|
|
||||||
switch (dir)
|
|
||||||
{
|
|
||||||
case IN_X: incx=1; --x2; incy=0; incz=0; distx=1; break;
|
|
||||||
case IN_Y: incx=0; incy=1; --y2; incz=0; disty=1; break;
|
|
||||||
case IN_Z: incx=0; incy=0; incz=1; --z2; distz=1; break;
|
|
||||||
default: assert(0);
|
|
||||||
}
|
|
||||||
assert(incx || incy || incz);
|
|
||||||
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)) {
|
||||||
|
int r = -3;
|
||||||
|
for (size_t i = 0; i < sklen; ++i)
|
||||||
{
|
{
|
||||||
for (i=0; i<sklen; ++i)
|
Location here, there;
|
||||||
{
|
LOCATION_GETS(here, w);
|
||||||
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_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;
|
sh->changed = true;
|
||||||
}
|
cachelabels(sh);
|
||||||
/*}}}*/
|
forceupdate(sh);
|
||||||
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;
|
|
||||||
cachelabels(sheet);
|
|
||||||
forceupdate(sheet);
|
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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[];
|
||||||
|
@ -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);
|
|
||||||
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)
|
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,17 +142,18 @@ 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);
|
||||||
@ -184,8 +176,8 @@ size_t ptokatprec(char *dest, size_t size, size_t field_width, StringFormat sf,
|
|||||||
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);
|
||||||
@ -198,13 +190,13 @@ size_t ptokatprec(char *dest, size_t size, size_t field_width, StringFormat sf,
|
|||||||
len = sprintf(buf, FLT_T_HEX_FMT, tok->u.flt);
|
len = sprintf(buf, FLT_T_HEX_FMT, tok->u.flt);
|
||||||
use = buf;
|
use = buf;
|
||||||
break;
|
break;
|
||||||
|
default: assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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)) {
|
||||||
|
252
src/display.c
252
src/display.c
@ -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,13 +155,9 @@ 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[] =
|
|
||||||
{ _("lL)oad"), _("sS)ave"), _("nN)ame"), NULL };
|
|
||||||
switch (c = line_menu(_("File:"), menu, 0))
|
|
||||||
{
|
|
||||||
case -2:
|
case -2:
|
||||||
case -1: c = KEY_CANCEL; break;
|
case -1: c = KEY_CANCEL; break;
|
||||||
case 0: c = K_LOADMENU; break;
|
case 0: c = K_LOADMENU; break;
|
||||||
@ -181,7 +170,6 @@ static int do_file(Sheet *cursheet)
|
|||||||
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;
|
||||||
|
bool iscont = is_mbcont((unsigned char)c);
|
||||||
if (strlen(buf) >= (size-1)) {
|
if (strlen(buf) >= (size-1)) {
|
||||||
if (is_mbcont(c)) {
|
if (iscont) {
|
||||||
dest = mbspos(src, -1);
|
dest = mbspos(src, -1);
|
||||||
memmove(dest, src, strlen(src)+1);
|
memmove(dest, src, strlen(src)+1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (insert || is_mbcont(c)) memmove(src+1, src, strlen(src)+1);
|
if (insert || iscont) memmove(src+1, src, strlen(src)+1);
|
||||||
else {
|
else {
|
||||||
if (is_mbchar(*src)) memmove(src+1, mbspos(src, 1), strlen(mbspos(src, 1))+1);
|
if (is_mbchar((unsigned char)(*src)))
|
||||||
|
memmove(src+1, mbspos(src, 1), strlen(mbspos(src, 1))+1);
|
||||||
if (!*src) *(src+1) = '\0';
|
if (!*src) *(src+1) = '\0';
|
||||||
}
|
}
|
||||||
*src = (char)c;
|
*src = (char)c;
|
||||||
if (!is_mbcont(c)) (*x)++;
|
if (!iscont) (*x)++;
|
||||||
break;
|
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();
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user