Alleviate compile warnings on Linux and finalize programmable styles

This change gets teapot to compile without warnings on OpenSUSE Tumbleweed
  with the extended warnings flags that were recently added. It also represents
  a more thoroughly (but not exhaustively) tested and debugged version of the
  expression-controlled style settings from an earlier commit. The facility
  should be ready for use.

  It also adds a better pretty-printer for Token values in gdb and extensive
  edits to the documentation. It fixes a bug in max/min introduced by the
  addition of the Bool type and the switchover to comparisons returning Bool.
  It modifies the display of values too long to fit in their cells to show an
  initial segment of their contents with a continuation mark rather than
  obscuring the contents completely.

  Closes #54.
  Closes #55.
  Closes #44.
  Closes #22.
  Closes #13.
This commit is contained in:
Glen Whitney 2019-09-09 10:33:41 -04:00
parent 8074130224
commit d5fbc0ef07
19 changed files with 277937 additions and 384 deletions

View File

@ -71,8 +71,8 @@ configure_file("${PROJECT_SOURCE_DIR}/config.h.in" "${PROJECT_BINARY_DIR}/config
include_directories("${PROJECT_BINARY_DIR}")
include_directories("${PROJECT_SOURCE_DIR}")
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ARCH-NOTFOUND CACHE ".deb Architecture" STRING)
set(CPACK_RPM_PACKAGE_ARCHITECTURE ARCH-NOTFOUND CACHE ".rpm Architecture" STRING)
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ARCH-NOTFOUND CACHE STRING ".deb Architecture")
set(CPACK_RPM_PACKAGE_ARCHITECTURE ARCH-NOTFOUND CACHE STRING ".rpm Architecture")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Table Editor And Planner, Or: Teapot!")
set(CPACK_PACKAGE_DESCRIPTION "A three-dimensional spreadsheet specialized in advanced calculations. Comes in GUI (FLTK) and console (curses) flavours.")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")

File diff suppressed because it is too large Load Diff

7427
examples/lifebyclock.tpa Normal file

File diff suppressed because it is too large Load Diff

269511
examples/lifebylayer.tpa Normal file

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,6 @@ if (CURSES_FOUND)
endif ()
find_package(FLTK)
find_package(JPEG)
if (FLTK_FOUND)
fltk_wrap_ui(fteapot fteapot.fl)
include_directories(${FLTK_INCLUDE_DIR})
@ -46,11 +45,20 @@ if (FLTK_FOUND)
target_compile_options(fteapot PRIVATE -Wno-shadow -Wno-conversion -Wno-sign-conversion)
set(fteapot_DEB_DEPENDS ", libstdc++6 (>= 4.1.1), libfltk1.3")
if (ENABLE_HELP)
find_package(JPEG)
set(fteapot_DEB_DEPENDS "${fteapot_DEB_DEPENDS}, libfltk-images1.3")
if (ENABLE_STATIC)
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${JPEG_LIBRARIES} ${LIB_PORTABLEXDR})
if (JPEG_FOUND)
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${JPEG_LIBRARIES} ${LIB_PORTABLEXDR})
else ()
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${LIB_PORTABLEXDR})
endif ()
else ()
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${JPEG_LIBRARIES} ${LIB_PORTABLEXDR})
if (JPEG_FOUND)
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${JPEG_LIBRARIES} ${LIB_PORTABLEXDR})
else ()
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${LIB_PORTABLEXDR})
endif ()
endif ()
else ()
if (ENABLE_STATIC)
@ -61,3 +69,12 @@ if (FLTK_FOUND)
endif ()
install(TARGETS fteapot DESTINATION bin)
endif ()
if (CMAKE_BUILD_TYPE STREQUAL Debug)
message(STATUS "-----------------------------------------------")
message(STATUS "Add the line 'add-auto-load-safe-path ${CMAKE_CURRENT_BINARY_DIR}' to ~/.gdbinit for enhanced debugging.")
message(STATUS "-----------------------------------------------")
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/teapot-gdb.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
file(RENAME ${CMAKE_CURRENT_BINARY_DIR}/teapot-gdb.py ${CMAKE_CURRENT_BINARY_DIR}/fteapot-gdb.py)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/teapot-gdb.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
endif ()

View File

@ -96,10 +96,13 @@ const char *savecontext(Sheet *sheet, const char *name, int body,
{
case LEFT:
if (fputs_close("\\JustLeft ", fp) == EOF) return strerror(errno);
break;
case RIGHT:
if (fputs_close("\\JustRight ", fp) == EOF) return strerror(errno);
break;
case CENTER:
if (fputs_close("\\JustCenter ", fp) == EOF) return strerror(errno);
break;
default: assert(0);
}
printvalue(buf, sizeof(buf), 0, DIRECT_STRING, cs.fform, cs.precision,

View File

@ -421,7 +421,7 @@ Token tdiv(Token l, Token r)
{
result.type = LOCATION;
for (size_t len = 0; len < 3; ++len)
result.u.location[len] = l.u.location[len] / r.u.integer;
result.u.location[len] = l.u.location[len] / (CoordT)(r.u.integer);
}
/*}}}*/
else return operand_type_error(cntxt, l.type, r.type);
@ -490,7 +490,7 @@ Token tmod(Token l, Token r)
{
result.type = LOCATION;
for (size_t len = 0; len < 3; ++len)
result.u.location[len] = l.u.location[len] % r.u.integer;
result.u.location[len] = l.u.location[len] % (CoordT)(r.u.integer);
}
/*}}}*/
else return operand_type_error(cntxt, l.type, r.type);

View File

@ -353,13 +353,18 @@ static Token excel_adr_func(int argc, const Token argv[])
for (Dimensions dim = X; dim < HYPER; ++dim)
{
int i = dim + 2;
int i = (int)(dim) + 2;
bool fixed = false;
if (i < argc)
{
if (argv[i].type == EEK) return argv[i];
if (!INTPATIBLE(argv[i])) return duperror(&result, usage);
if (argv[i].type == INT && argv[i].u.integer > 0) fixed = true;
switch (argv[i].type) {
case EEK: return argv[i];
case EMPTY: break;
case FIDENT:
if (argv[i].u.fident == FUNC_FIX) fixed = true;
break;
default: return duperror(&result, usage);
}
}
if (fixed) result.u.location[dim] = argv[0].u.location[dim];
else result.u.location[dim] +=
@ -447,7 +452,7 @@ static Token at_func(FunctionIdentifier self, int argc, const Token argv[])
/* don't free the location if it is the same as an argument, because
those get freed later: */
for (int i = 0; i < argc; ++i)
if (argv[i].type == EEK & argv[i].u.err == location.u.err) return result;
if (argv[i].type == EEK && argv[i].u.err == location.u.err) return result;
tfree(&location);
return result;
}
@ -599,8 +604,8 @@ static Token constant_func(FunctionIdentifier fi, int argc, const Token argv[])
if (argc < 1) {
result.type = FLOAT;
switch (fi) {
case FUNC_E: result.u.flt = CONST_E;
case FUNC_TAU: result.u.flt = 2*CONST_PI;
case FUNC_E: result.u.flt = CONST_E; break;
case FUNC_TAU: result.u.flt = 2*CONST_PI; break;
default: assert(0);
}
return result;
@ -878,7 +883,7 @@ static Token string_func(FunctionIdentifier self, int argc, const Token argv[])
case -1: return self_func(self, argc, argv);
case 0: arg = recompvalue(upd_sheet, upd_l); break;
case 3:
if (argv[2].type != FIDENT) bad_args = true; break;
if (argv[2].type != FIDENT) { bad_args = true; break; }
switch (argv[2].u.fident)
{
case FUNC_DECIMAL: ff = FLT_DECIMAL; break;
@ -901,7 +906,7 @@ static Token string_func(FunctionIdentifier self, int argc, const Token argv[])
}
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 */
case 1:
arg = tcopy(argv[0]);
@ -926,6 +931,29 @@ static Token string_func(FunctionIdentifier self, int argc, const Token argv[])
}
/*}}}*/
/* style */ /*{{{*/
static Token style_func(FunctionIdentifier self, int argc, const Token argv[])
{
Token arg;
switch (argc) {
case -1: return self_func(self, argc, argv);
case 0:
arg.type = LOCATION;
LOCATION_GETS(arg.u.location, upd_l);
break;
case 1:
if (argv[0].type == STYLE) return argv[0];
if (argv[0].type == LOCATION) { arg = argv[0]; break; }
/* FALL THROUGH */
default:
return duperror(&arg, _("Usage: style[([location|style])]"));
}
/* Here arg is a location */
Token result; result.type = STYLE;
result.u.style = getstyle(upd_sheet, arg.u.location);
return result;
}
/*}}}*/
/* error */ /*{{{*/
static Token error_func(FunctionIdentifier self, int argc, const Token argv[])
{
@ -973,6 +1001,7 @@ static Token is_func(FunctionIdentifier self, int argc, const Token argv[])
case FUNC_ERROR: result.u.bl = (val.type == EEK); break;
case FUNC_FUNCALL: result.u.bl = (val.type == FUNCALL); break;
case FUNC_BOOL: result.u.bl = (val.type == BOOL); break;
case FUNC_STYLE: result.u.bl = (val.type == STYLE); break;
case FUNC_NUMBER:
result.u.bl = val.type==FLOAT || val.type==INT || val.type==EMPTY;
break;
@ -1035,7 +1064,7 @@ static Token aspect_func(FunctionIdentifier self, int argc, const Token argv[])
sprintf(result.u.err, templ, tfunc[self].name);
return result;
}
if (argv[0].u.integer < NO_COLOR_SET || argv[1].u.integer > MAX_MAX_COLORS) {
if (argv[0].u.integer < NO_COLOR_SET || argv[0].u.integer > MAX_MAX_COLORS) {
const char *templ = _("Integer value (" INT_T_FMT
") out of range for color number");
result.type = EEK;
@ -1118,7 +1147,7 @@ STYLEFLAGFUNC(underline)
*/
static Token accum_func(FunctionIdentifier self, int argc, const Token argv[])
{
Token (*tbin)(Token, Token);
Token (*tbin)(Token, Token) = NULL;
int start = 0;
switch (self) {
case FUNC_CONCAT: tbin = tconcat; break;
@ -1228,15 +1257,14 @@ static void minmax_updt(FunctionIdentifier id, Location *loc, Token *tok,
const Location* newloc, const Token *newtok)
{
Token tmp = (id == FUNC_MIN) ? tle(*tok, *newtok) : tge(*tok, *newtok);
if (tmp.type == INT) /* Succesful comparison */
if (tmp.type == BOOL) /* Succesful comparison */
{
if (tmp.u.integer == 0)
if (!(tmp.u.bl))
{
tfree(tok);
*tok = *newtok;
LOCATION_GETS(*loc, *newloc);
}
tfree(&tmp);
} else { /* failed comparison */
tfree(tok);
*tok = tmp;
@ -1335,7 +1363,7 @@ static Token n_func(FunctionIdentifier self, int argc, const Token argv[])
as function calls */ /*{{{*/
static Token binop_func(FunctionIdentifier self, int argc, const Token argv[])
{
Token (*tbin)(Token, Token);
Token (*tbin)(Token, Token) = NULL;
switch (self) {
case FUNC_MINUS_SYMBOL: tbin = tsub; break;
case FUNC_SLASH: tbin = tdiv; break;
@ -1596,7 +1624,7 @@ static Token sci_disp(FunctionIdentifier self, int argc, const Token argv[])
/* nearby integer (rounding) function */ /*{{{*/
static Token near_func(FunctionIdentifier self, int argc, const Token argv[])
{
FltT (*frnd)(FltT);
FltT (*frnd)(FltT) = NULL;
switch (self) {
case FUNC_FLOOR: frnd = FLOORFLT; break;
case FUNC_CEIL: frnd = CEILFLT; break;
@ -1637,7 +1665,7 @@ static Token substr_func(FunctionIdentifier self, int argc, const Token argv[])
/*}}}*/
if (argc < 2 || argc > 3) return duperror(&result, usage);
if (argc == 3 && argv[2].type != INT) duperror(&result, usage);
if (argc == 3 && argv[2].type != INT) return duperror(&result, usage);
if (argv[0].type == STRING && argv[1].type == INT)
{
char ss[1024];
@ -1649,20 +1677,19 @@ static Token substr_func(FunctionIdentifier self, int argc, const Token argv[])
if ( b < 0 ) b = 0;
if ( b > l ) b = l;
if ( e > l ) e = l;
int n = (int)(e - b + 1);
if ( n >= 1024 ) n = 1024 - 1;
if (n > 0) {
ss[n] = '\0';
strncpy(ss, argv[0].u.string + b, n);
result.type=STRING;
result.u.string=strdup(ss);
}
else {
result.type = EMPTY;
if ( b < e ) {
result.type = EMPTY;
return result;
}
size_t n = (size_t)(e - b + 1);
if (n >= sizeof(ss)) n = sizeof(ss) - 1;
ss[n] = '\0';
strncpy(ss, argv[0].u.string + b, n);
result.type = STRING;
result.u.string = strdup(ss);
return result;
}
else duperror(&result, usage);
return result;
return duperror(&result, usage);
}
/*}}}*/
@ -1783,7 +1810,7 @@ Tfunc tfunc[]=
[FUNC_NUMBER] = { "number", number_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_OPERATOR] = { "operator", self_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_STRING] = { "string", string_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_STYLE] = { "style", style_func, PREFIX_FUNC, FUNCT, 0 },
/* Style functions */
[FUNC_PRECISION] = { "precision", precision_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_FOREGROUND] = { "foreground", aspect_func, PREFIX_FUNC, FUNCT, 0 },
@ -1849,6 +1876,6 @@ Tfunc tfunc[]=
[FUNC_DECIMAL] = { "decimal", self_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_HEXACT] = { "hexact", self_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_SCIENTIFIC] = { "scientific", self_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_FIX] = { "fix", self_func, PREFIX_FUNC, FUNCT, 0 },
};
/*}}}*/

View File

@ -45,13 +45,15 @@ typedef enum
FUNC_IS, FUNC_FIND, FUNC_PRECISION, FUNC_FOREGROUND, FUNC_BACKGROUND,
FUNC_JUSTIFY, FUNC_FLOATFMT, FUNC_SHADOWED, FUNC_TRANSPARENT, FUNC_BOLD,
FUNC_UNDERLINE, FUNC_CENTER,
FUNC_UNDERLINE, FUNC_CENTER, FUNC_STYLE,
FUNC_FIX,
N_FUNCTION_IDS
} FunctionIdentifier;
#define IS_RELATION_FUNC(f) (((f) >= FUNC_LESS_EQUAL) && ((f) <= FUNC_BANG_EQUAL))
#define IS_TYPE_FUNC(f) (((f) >= FUNC_BOOL && ((f) <= FUNC_OPERATOR)) || (f)==FUNC_ERROR || (f)==FUNC_FLOAT || (f)==FUNC_INT || (f)==FUNC_STRING)
#define IS_TYPE_FUNC(f) (((f) >= FUNC_BOOL && ((f) <= FUNC_OPERATOR)) || (f)==FUNC_ERROR || (f)==FUNC_FLOAT || (f)==FUNC_INT || (f)==FUNC_STRING || (f)==FUNC_STYLE)
/* Forward declaration of Token, since this header is used in scanner.h */
typedef struct Token_struc Token;

View File

@ -144,18 +144,13 @@ bool doanyway(Sheet *sheet, const char *msg)
/* do_edit -- set or modify cell contents */ /*{{{*/
static int do_edit(Sheet *cursheet, Key c, char *expr, TokVariety tv)
{
/* variables */ /*{{{*/
char buf[1024];
const char *prompt;
char *s;
size_t x,offx;
const char *promptfor[] = { [BASE_CONT] = _("Cell contents"),
[ITER_CONT] = _("Clocked cell contents"),
[STYLE_CONT] = _("Style expression")
};
Location scur;
Token **t;
Cell *cell = curcell(cursheet);
Token newcont;
Cell *cell;
/*}}}*/
cell = curcell(cursheet);
if (locked(cell)) line_msg(_("Edit cell:"),_("Cell is locked"));
else
{
@ -163,18 +158,15 @@ static int do_edit(Sheet *cursheet, Key c, char *expr, TokVariety tv)
LOCATION_GETS(scur, cursheet->cur);
if (expr)
{
s = expr;
t = scan(&s);
prompt = _("Cell contents:");
if (tv == ITER_CONT) prompt = _("Clocked cell contents");
if (tv == STYLE_CONT) prompt = _("Style expression");
char *s = expr;
Token **t = scan(&s);
if (*s != '\0') {
if (t == EMPTY_TVEC)
line_msg(prompt, "XXX invalid expression");
line_msg(promptfor[tv], "XXX invalid expression");
else {
newcont = eval_safe(t, LITERAL);
if (newcont.type == EEK)
line_msg(prompt, "XXX unparseable expression");
line_msg(promptfor[tv], "XXX unparseable expression");
}
}
tvecfree(t);
@ -182,7 +174,9 @@ static int do_edit(Sheet *cursheet, Key c, char *expr, TokVariety tv)
else
{
Token cntt;
offx=0;
size_t offx = 0;
char buf[1024];
char *s = NULL;
if (c == K_NONE)
{
cntt = gettok(cell, tv);
@ -222,16 +216,12 @@ static int do_edit(Sheet *cursheet, Key c, char *expr, TokVariety tv)
}
do
{
int r;
tfree(&newcont);
newcont.type = EEK;
newcont.u.err = (char *)0;
x = mbslen(buf)-mbslen(s);
prompt = _("Cell contents:");
if (tv == ITER_CONT) prompt = _("Clocked cell contents:");
if ((r = line_edit(cursheet, buf, sizeof(buf), prompt, &x, &offx)) < 0)
return r;
size_t x = mbslen(buf)-mbslen(s);
int r = line_edit(cursheet, buf, sizeof(buf), promptfor[tv], &x, &offx);
if (r < 0) return r;
s = buf;
if (buf[0] == '"' && buf[strlen(buf)-1] != '"'
&& strlen(buf)+1 < sizeof(buf))
@ -239,7 +229,7 @@ static int do_edit(Sheet *cursheet, Key c, char *expr, TokVariety tv)
buf[strlen(buf)+1] = 0;
buf[strlen(buf)] = '"';
}
t = scan(&s);
Token **t = scan(&s);
if (t != EMPTY_TVEC) {
newcont = eval_safe(t, LITERAL);
}
@ -341,8 +331,8 @@ static void do_attribute(Sheet *cursheet, Key action)
ColorAspect ca = FOREGROUND;
switch ((int)action)
{
case ADJUST_CENTER: ++adj; /* drop through */
case ADJUST_RIGHT: ++adj; /* drop through */
case ADJUST_CENTER: ++adj; /* FALL THROUGH */
case ADJUST_RIGHT: ++adj; /* FALL THROUGH */
case ADJUST_LEFT:
{
const char *templ = _("Change adjustment of block to %s?");
@ -354,9 +344,9 @@ static void do_attribute(Sheet *cursheet, Key action)
break;
}
/* set float format */ /*{{{*/
case ADJUST_HEXACT: ++ff; /* drop through */
case ADJUST_COMPACT: ++ff; /* drop through */
case ADJUST_SCIENTIFIC: ++ff; /* drop through */
case ADJUST_HEXACT: ++ff; /* FALL THROUGH */
case ADJUST_COMPACT: ++ff; /* FALL THROUGH */
case ADJUST_SCIENTIFIC: ++ff; /* FALL THROUGH */
case ADJUST_DECIMAL:
{
const char* templ = _("Change float format of block to %s?");
@ -1007,6 +997,7 @@ static int do_delete(Sheet *sheet)
case 2: /* 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;
@ -1588,7 +1579,7 @@ int do_sheetcmd(Sheet *cursheet, Key c, bool moveonly)
/* FPAGE -- page right */ /*{{{*/
case K_FPAGE:
{
cursheet->offx += cursheet->width;
cursheet->offx += (CoordT)cursheet->width;
relmoveto(cursheet, (CoordT)(cursheet->width), 0, 0);
break;
}

View File

@ -199,7 +199,8 @@ char *striphtml(const char *in)
in--;
while (in && (end = strchr(++in, '<'))) {
memcpy(out, in, end-in);
assert(end >= in);
memcpy(out, in, (size_t)(end-in));
out += end-in;
in = strchr(end+1, '>');
}

View File

@ -103,7 +103,6 @@ static Token primary(Token *n[], int *i, EvalMethod meth)
}
/*}}}*/
/* OPERATOR */ /*{{{*/
case OPERATOR:
{
switch (n[*i]->u.op)
@ -142,12 +141,9 @@ static Token primary(Token *n[], int *i, EvalMethod meth)
return result;
}
fident = identcode(Op_Name[n[*i]->u.op], strlen(Op_Name[n[*i]->u.op]));
/* FALL THROUGH TO PROCESS OPERATOR AS FUNCTION CALL */
}
}
/*}}}*/
/* FIDENT */ /*{{{*/
/* FALL THROUGH */
case FIDENT:
{
if (fident == -2) fident = n[*i]->u.fident;
@ -227,7 +223,6 @@ static Token primary(Token *n[], int *i, EvalMethod meth)
} else result.u.funcall.argv = NULLTOKEN;
return result;
}
/*}}}*/
/* FUNCALL */ /*{{{*/
case FUNCALL:

View File

@ -688,6 +688,7 @@ Style getstyle(Sheet *sheet, const Location at)
res.u.style.adjust = LEFT; return res.u.style;
}
Cell *cell = CELL_AT(sheet, at);
if (!(cell->updated)) recompvalue(sheet, at);
assert(cell->updated);
if (cell->tok[STYLE_VAL].type == STYLE) return cell->tok[STYLE_VAL].u.style;
Sheet *old_up_sh = upd_sheet;
@ -703,10 +704,11 @@ Style getstyle(Sheet *sheet, const Location at)
case EMPTY: sty = res.u.style; break;
default: {
char buf[4096];
const char *msg = _("Produced non-style value ");
strcpy(buf, msg);
printtok(buf+strlen(msg), sizeof(buf)-strlen(msg)-1, 0, QUOTE_STRING,
const char *msg = _("Produced non-style value at &(%d,%d,%d) '");
sprintf(buf, msg, at[X], at[Y], at[Z]);
printtok(buf+strlen(buf), sizeof(buf)-strlen(buf)-1, 0, QUOTE_STRING,
FLT_COMPACT, -1, VERBOSE_ERROR, &tsty);
strcat(buf, "'");
line_msg(_("Cell style expr:"), msg);
sty = res.u.style;
break;
@ -788,7 +790,8 @@ bool overridestyle(Sheet *sheet, const Location at, Style sty) {
case STYLE: {
Token tsty; tsty.type = STYLE; tsty.u.style = sty;
thecell->tok[STYLE_CONT] = tadd(tsty, stok);
if (style_equal(stok.u.style, thecell->tok[STYLE].u.style)) return false;
if (style_equal(stok.u.style, thecell->tok[STYLE_CONT].u.style))
return false;
tfree(&(thecell->tok[STYLE_VAL]));
return true;
}
@ -1194,8 +1197,8 @@ const char *savecsv(Sheet *sheet, const char *name, char sep,
Cell *cw = CELL_AT(sheet,w);
if (cw != NULLCELL)
{
static const int bufchar = 511;
static const int bufsz = bufchar*UTF8SZ + 1;
static const size_t bufchar = 511;
static const size_t bufsz = bufchar*UTF8SZ + 1;
char *buf = malloc(bufsz);
Style sw = getstyle(sheet, w);
printvalue(buf, bufsz, bufchar, DIRECT_STRING, sw.fform,
@ -1725,7 +1728,7 @@ void insertcube(Sheet *sh, const Location beg, const Location end, Dimensions dm
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]--)
for (w[X] = start[X]; w[X] >= fini[X]; w[X]--)
{
resize(sh, w[X], w[Y], w[Z], NULL);
Location from; LOCATION_GETS(from,w);

View File

@ -127,14 +127,16 @@ static size_t print_chars(char* d, size_t l, const char *s)
/* ptokatprec -- like printtok but with an ambient precedence */
static size_t ptokatprec(char *dest, size_t size, size_t field_width,
StringFormat sf, FloatFormat ff, PrecisionLevel digits,
StringFormat sf, FloatFormat ff, PrecisionLevel pl,
ErrorFormat ef, const Token *tok,
FunctionPrecedence atprec)
{
int digits = pl;
if (debug_level > 2) {
printf("..Entering printtok; bufsize %zu, field_width %zu, qs %d, ff %s,"
"prec %d, verr %d\n",
size, field_width, sf, FloatFormat_Name[ff], digits, ef);
printf("..Entering ptokatprec; bufsize %zu, field_width %zu, qs %d, ff %s,"
"precision %d, verr %d, precedence %d\n",
size, field_width, sf, FloatFormat_Name[ff], digits,
ef, (int)atprec);
}
if (size > 0 ) *dest = '\0';
if (tok == NULLTOKEN || tok->type == EMPTY) return 0;
@ -180,8 +182,8 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width,
long tpos = epos;
while (tpos > 1 && buf2[tpos-1] == '0' && buf2[tpos-2] != '.') --tpos;
if (tpos < epos) {
memmove(buf2+tpos, buf2+epos, len2-epos+1);
len2 -= epos - tpos;
memmove(buf2+tpos, buf2+epos, (size_t)(len2-epos+1));
len2 -= (int)(epos - tpos);
}
if (len2 < len) { use = buf2; len = len2; }
}
@ -192,7 +194,7 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width,
break;
default: assert(0);
}
assert(len < sizeof(buf));
assert((size_t)len < sizeof(buf));
char *p = use + len;
while (*--p == ' ') { *p = '\0'; --len; }
(void)strncpy(dest, use, size);
@ -248,7 +250,7 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width,
if (ai > 0 && cur < size) dest[cur++] = ',';
/* The commas eliminate the need for precedence worries in arguments*/
cur += ptokatprec(dest+cur, size-cur-1, field_width-cur, sf, ff,
digits, ef, tok->u.funcall.argv + ai,
pl, ef, tok->u.funcall.argv + ai,
NO_PRECEDENCE);
}
if (cur < size) dest[cur++] = ')';
@ -260,7 +262,7 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width,
if (fp < atprec && cur < size) dest[cur++] = '(';
cur += print_chars(dest+cur, size-cur-1, tfunc[fid].display_symbol);
cur += ptokatprec(dest+cur, size-cur-1, field_width-cur, sf, ff,
digits, ef, tok->u.funcall.argv, fp);
pl, ef, tok->u.funcall.argv, fp);
if (fp < atprec && cur < size) dest[cur++] = ')';
break;
}
@ -290,7 +292,7 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width,
}
if (specialrel) {
cur += ptokatprec(dest+cur, size-cur-1, field_width-cur, sf, ff,
digits, ef, tok->u.funcall.argv, INFIX_BOOL);
pl, ef, tok->u.funcall.argv, INFIX_BOOL);
for (int ai = 1; ai < tok->u.funcall.argc && cur < size-1; ++ ai) {
dest[cur++] = ' ';
const char *use =
@ -298,7 +300,7 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width,
cur += print_chars(dest+cur, size-cur-1, use);
if (cur < size) dest[cur++] = ' ';
cur += ptokatprec(dest+cur, size-cur-1, field_width-cur, sf, ff,
digits, ef,
pl, ef,
tok->u.funcall.argv[ai].u.funcall.argv + 1,
INFIX_REL);
}
@ -315,7 +317,7 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width,
} else if (fp > PREFIX_NEG) {
char powbuf[4096];
size_t arglen = ptokatprec(powbuf, sizeof(powbuf), 0, sf, ff,
digits, ef, tok->u.funcall.argv, fp);
pl, ef, tok->u.funcall.argv, fp);
if (arglen >= sizeof(powbuf)-1) assert(0);
if (powbuf[0] == '-') {
parenarg = true;
@ -323,7 +325,7 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width,
}
}
cur += ptokatprec(dest+cur, size-cur-1, field_width-cur, sf, ff,
digits, ef, tok->u.funcall.argv + ai, fp);
pl, ef, tok->u.funcall.argv + ai, fp);
if (parenarg && cur < size) dest[cur++] = ')';
}
}
@ -459,11 +461,12 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width,
if (field_width && mlen > field_width) {
if (field_width < 6) {
for (cur = 0; cur < field_width; ++cur) dest[cur] = '#';
dest[cur] = 0;
dest[cur] = '\0';
} else {
char *ov = mbspos(dest+cur, -5);
char *ov = mbspos(dest, (int)field_width - 5);
cur = (size_t)(ov - dest);
cur += print_chars(dest+cur, size-cur-1, "...##");
dest[cur] = '\0';
}
}
return cur;

View File

@ -58,8 +58,11 @@ static bool_t xdr_token(XDR *xdrs, OldToken *t)
if (xdrs->x_op == XDR_DECODE) memset(t,0,sizeof(OldToken));
else return false;
/* Since we are only decoding, we do not have to do anything to x
in advance; these lines are just kept for reference
x=t->type;
if (t->type==OPERATOR) x|=t->u.op<<8;
*/
result=xdr_int(xdrs,&x);
if ((x&0xff)==OPERATOR) t->u.op=(x>>8)&0xff;
t->type=x&0xff;
@ -154,12 +157,16 @@ static bool_t xdr_tokenptrvec(XDR *xdrs, OldToken ***t)
}
/*}}}*/
static bool_t xdr_myvoid(XDR *xdrs, void* data) {
return 1;
}
/* xdr_mystring */ /*{{{*/
static bool_t xdr_mystring(XDR *xdrs, char **str)
{
static struct xdr_discrim arms[3]=
{
{ 0, (xdrproc_t)xdr_void },
{ 0, (xdrproc_t)xdr_myvoid },
{ 1, (xdrproc_t)xdr_wrapstring },
{ -1, (xdrproc_t)0 }
};

View File

@ -326,15 +326,12 @@ static void do_bg(void)
void display_main(Sheet *cursheet)
{
Key k;
int quit = 0;
cursheet->maxx = COLS;
cursheet->maxy = LINES-1;
Key k;
do
{
quit = 0;
update(cursheet);
k = wgetc();
wmove(stdscr, LINES-1, 0);
@ -455,7 +452,7 @@ void redraw_sheet(Sheet *sheet)
(void)wattron(stdscr,DEF_NUMBER);
/* draw x numbers */
for (width=4; width < (size_t)(sheet->maxx); ++width)
mvwaddch(stdscr, 0+sheet->oriy, sheet->orix+width,
mvwaddch(stdscr, (int)(sheet->oriy), (int)(sheet->orix + width),
(chtype)(unsigned char)' ');
for (width = 4, x = sheet->offx; width < (size_t)(sheet->maxx);
width += col, ++x)
@ -474,7 +471,7 @@ void redraw_sheet(Sheet *sheet)
if ((size_t)(sheet->maxx)-width < col)
buf[(size_t)(sheet->maxx)-width] = '\0';
wcolor_set(stdscr, usecp, NULL);
mvwaddstr(stdscr, sheet->oriy, sheet->orix+width, buf);
mvwaddstr(stdscr, (int)(sheet->oriy), (int)(sheet->orix+width), buf);
wcolor_set(stdscr, 0, NULL);
}
@ -555,7 +552,8 @@ void redraw_sheet(Sheet *sheet)
if (invert) (void)wattron(stdscr,DEF_CELLCURSOR);
if (sc.bold) wattron(stdscr,A_BOLD);
if (sc.underline) wattron(stdscr,A_UNDERLINE);
(void)mvwaddstr(stdscr, y+(CoordT)(sheet->oriy), sheet->orix + width,
(void)mvwaddstr(stdscr, y+(int)(sheet->oriy),
(int)(sheet->orix + width),
buf+cutoff);
for (fill=mbslen(buf+cutoff); fill<realsize; ++fill)
(void)waddch(stdscr,(chtype)(unsigned char)' ');
@ -596,7 +594,9 @@ void redraw_sheet(Sheet *sheet)
}
}
*mbspos(buf, sheet->maxx) = 0;
(void)mvwaddstr(stdscr, sheet->oriy+(size_t)(sheet->maxy)-1, sheet->orix, buf);
(void)mvwaddstr(stdscr, (int)(sheet->oriy) + sheet->maxy - 1,
(int)(sheet->orix), buf);
for (col = mbslen(buf); col < (size_t)sheet->maxx; ++col)
(void)waddch(stdscr, ' ');
}
@ -753,11 +753,11 @@ int line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt,
char *end = mbspos(src, 1);
while (src != end) {
char k = *src;
memmove(dest+1, dest, src-dest);
*dest = k;
src++;
dest++;
char k = *src;
memmove(dest+1, dest, (size_t)(src-dest));
*dest = k;
src++;
dest++;
}
(*x)++;
}
@ -769,11 +769,11 @@ int line_edit(Sheet *sheet, char *buf, size_t size, const char *prompt,
char open = 0, close = 0, dir = 1;
switch (*dest) {
case ')': dir = -1;
case ')': dir = -1; /* FALL THROUGH */
case '(': open = '('; close = ')'; break;
case '}': dir = -1;
case '}': dir = -1; /* FALL THROUGH */
case '{': open = '{'; close = '}'; break;
case ']': dir = -1;
case ']': dir = -1; /* FALL THROUGH */
case '[': open = '['; close = ']'; break;
default: break;
}
@ -1147,7 +1147,7 @@ static Key wgetc(void)
}
void find_helpfile(char *buf, int size, const char *argv0)
void find_helpfile(char *buf, size_t size, const char *argv0)
{
strncpy(buf, HELPFILE, size);
buf[size-1] = 0;

View File

@ -23,7 +23,7 @@ void show_text(const char *text);
Key show_menu(Sheet *cursheet);
int line_menu(const char *prompt, const char **choice, int curx);
void find_helpfile(char *buf, int size, const char *argv0);
void find_helpfile(char *buf, size_t size, const char *argv0);
#ifdef __cplusplus
}

View File

@ -283,7 +283,7 @@ class TeapotTable {open : {public Fl_Table}}
case FL_F+8: k = ctrl?K_RECALC:K_CLOCK; break;
case FL_F+9: k = ctrl?K_RECALC:K_CLOCK; break;
case FL_F+10: k = (Key)'/'; break;
case FL_Tab: if (shift) { k = K_CLOCK; break; }
case FL_Tab: if (shift) { k = K_CLOCK; } break;
case FL_Enter:
case FL_KP_Enter:
k = alt ? (shift ? K_EDIT_STYLE_EXPR : K_MENTER) : K_ENTER;
@ -1047,7 +1047,7 @@ declblock {\#ifndef ENABLE_HELP} {after {\#endif}} {
}
Function
{find_helpfile(char *buf, int size, const char *argv0)}
{find_helpfile(char *buf, size_t size, const char *argv0)}
{open C return_type void} {code
{
fl_filename_absolute(buf, size, argv0);

27
src/teapot-gdb.py Normal file
View File

@ -0,0 +1,27 @@
class tokenprinter:
def __init__(self, value):
self.value = value;
def children(self):
vtyp = str(self.value['type'])
if (vtyp == "EMPTY"): return [];
fieldOfType = { 'STRING':'string', 'FLOAT':'flt', 'INT':'integer',
'OPERATOR':'op', 'LIDENT':'lident', 'FIDENT':'fident',
'LOCATION':'location', 'EEK':'err', 'FUNCALL':'funcall',
'BOOL':'bl', 'STYLE':'style' };
name = fieldOfType[vtyp];
return [("u."+name, self.value['u'][name])]
def to_string(self):
vtyp = str(self.value['type'])
if (vtyp == "EMPTY"): return '<Empty Token>';
return '<Token>'
def ppfortoken(value):
"Return the token pretty-printer if 'value' is a Token."
typename = str(value.type.strip_typedefs().unqualified())
if (typename == 'struct Token_struc'): return tokenprinter(value)
return None
gdb.pretty_printers.append(ppfortoken)