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_BINARY_DIR}")
include_directories("${PROJECT_SOURCE_DIR}") include_directories("${PROJECT_SOURCE_DIR}")
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ARCH-NOTFOUND CACHE ".deb Architecture" STRING) set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ARCH-NOTFOUND CACHE STRING ".deb Architecture")
set(CPACK_RPM_PACKAGE_ARCHITECTURE ARCH-NOTFOUND CACHE ".rpm Architecture" STRING) 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_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 "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") 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 () 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}) include_directories(${FLTK_INCLUDE_DIR})
@ -46,11 +45,20 @@ if (FLTK_FOUND)
target_compile_options(fteapot PRIVATE -Wno-shadow -Wno-conversion -Wno-sign-conversion) 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)
find_package(JPEG)
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)
if (JPEG_FOUND)
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${JPEG_LIBRARIES} ${LIB_PORTABLEXDR}) target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${JPEG_LIBRARIES} ${LIB_PORTABLEXDR})
else () else ()
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${LIB_PORTABLEXDR})
endif ()
else ()
if (JPEG_FOUND)
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${JPEG_LIBRARIES} ${LIB_PORTABLEXDR}) target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${JPEG_LIBRARIES} ${LIB_PORTABLEXDR})
else ()
target_link_libraries(fteapot teapotlib ${FLTK_LIBRARIES} ${LIB_PORTABLEXDR})
endif ()
endif () endif ()
else () else ()
if (ENABLE_STATIC) if (ENABLE_STATIC)
@ -61,3 +69,12 @@ if (FLTK_FOUND)
endif () endif ()
install(TARGETS fteapot DESTINATION bin) install(TARGETS fteapot DESTINATION bin)
endif () 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: case LEFT:
if (fputs_close("\\JustLeft ", fp) == EOF) return strerror(errno); if (fputs_close("\\JustLeft ", fp) == EOF) return strerror(errno);
break;
case RIGHT: case RIGHT:
if (fputs_close("\\JustRight ", fp) == EOF) return strerror(errno); if (fputs_close("\\JustRight ", fp) == EOF) return strerror(errno);
break;
case CENTER: case CENTER:
if (fputs_close("\\JustCenter ", fp) == EOF) return strerror(errno); if (fputs_close("\\JustCenter ", fp) == EOF) return strerror(errno);
break;
default: assert(0); default: assert(0);
} }
printvalue(buf, sizeof(buf), 0, DIRECT_STRING, cs.fform, cs.precision, 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; result.type = LOCATION;
for (size_t len = 0; len < 3; ++len) 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); else return operand_type_error(cntxt, l.type, r.type);
@ -490,7 +490,7 @@ Token tmod(Token l, Token r)
{ {
result.type = LOCATION; result.type = LOCATION;
for (size_t len = 0; len < 3; ++len) 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); 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) for (Dimensions dim = X; dim < HYPER; ++dim)
{ {
int i = dim + 2; int i = (int)(dim) + 2;
bool fixed = false; bool fixed = false;
if (i < argc) if (i < argc)
{ {
if (argv[i].type == EEK) return argv[i]; switch (argv[i].type) {
if (!INTPATIBLE(argv[i])) return duperror(&result, usage); case EEK: return argv[i];
if (argv[i].type == INT && argv[i].u.integer > 0) fixed = true; 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]; if (fixed) result.u.location[dim] = argv[0].u.location[dim];
else result.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 /* don't free the location if it is the same as an argument, because
those get freed later: */ those get freed later: */
for (int i = 0; i < argc; ++i) 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); tfree(&location);
return result; return result;
} }
@ -599,8 +604,8 @@ static Token constant_func(FunctionIdentifier fi, int argc, const Token argv[])
if (argc < 1) { if (argc < 1) {
result.type = FLOAT; result.type = FLOAT;
switch (fi) { switch (fi) {
case FUNC_E: result.u.flt = CONST_E; case FUNC_E: result.u.flt = CONST_E; break;
case FUNC_TAU: result.u.flt = 2*CONST_PI; case FUNC_TAU: result.u.flt = 2*CONST_PI; break;
default: assert(0); default: assert(0);
} }
return result; 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 -1: return self_func(self, argc, argv);
case 0: arg = recompvalue(upd_sheet, upd_l); break; case 0: arg = recompvalue(upd_sheet, upd_l); break;
case 3: 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) switch (argv[2].u.fident)
{ {
case FUNC_DECIMAL: ff = FLT_DECIMAL; break; 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; 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:
arg = tcopy(argv[0]); 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 */ /*{{{*/ /* error */ /*{{{*/
static Token error_func(FunctionIdentifier self, int argc, const Token argv[]) 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_ERROR: result.u.bl = (val.type == EEK); break;
case FUNC_FUNCALL: result.u.bl = (val.type == FUNCALL); break; case FUNC_FUNCALL: result.u.bl = (val.type == FUNCALL); break;
case FUNC_BOOL: result.u.bl = (val.type == BOOL); break; case FUNC_BOOL: result.u.bl = (val.type == BOOL); break;
case FUNC_STYLE: result.u.bl = (val.type == STYLE); break;
case FUNC_NUMBER: case FUNC_NUMBER:
result.u.bl = val.type==FLOAT || val.type==INT || val.type==EMPTY; result.u.bl = val.type==FLOAT || val.type==INT || val.type==EMPTY;
break; break;
@ -1035,7 +1064,7 @@ 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) { if (argv[0].u.integer < NO_COLOR_SET || argv[0].u.integer > MAX_MAX_COLORS) {
const char *templ = _("Integer value (" INT_T_FMT const char *templ = _("Integer value (" INT_T_FMT
") out of range for color number"); ") out of range for color number");
result.type = EEK; result.type = EEK;
@ -1118,7 +1147,7 @@ STYLEFLAGFUNC(underline)
*/ */
static Token accum_func(FunctionIdentifier self, int argc, const Token argv[]) static Token accum_func(FunctionIdentifier self, int argc, const Token argv[])
{ {
Token (*tbin)(Token, Token); Token (*tbin)(Token, Token) = NULL;
int start = 0; int start = 0;
switch (self) { switch (self) {
case FUNC_CONCAT: tbin = tconcat; break; 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) const Location* newloc, const Token *newtok)
{ {
Token tmp = (id == FUNC_MIN) ? tle(*tok, *newtok) : tge(*tok, *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); tfree(tok);
*tok = *newtok; *tok = *newtok;
LOCATION_GETS(*loc, *newloc); LOCATION_GETS(*loc, *newloc);
} }
tfree(&tmp);
} else { /* failed comparison */ } else { /* failed comparison */
tfree(tok); tfree(tok);
*tok = tmp; *tok = tmp;
@ -1335,7 +1363,7 @@ static Token n_func(FunctionIdentifier self, int argc, const Token argv[])
as function calls */ /*{{{*/ as function calls */ /*{{{*/
static Token binop_func(FunctionIdentifier self, int argc, const Token argv[]) static Token binop_func(FunctionIdentifier self, int argc, const Token argv[])
{ {
Token (*tbin)(Token, Token); Token (*tbin)(Token, Token) = NULL;
switch (self) { switch (self) {
case FUNC_MINUS_SYMBOL: tbin = tsub; break; case FUNC_MINUS_SYMBOL: tbin = tsub; break;
case FUNC_SLASH: tbin = tdiv; 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 */ /*{{{*/ /* nearby integer (rounding) function */ /*{{{*/
static Token near_func(FunctionIdentifier self, int argc, const Token argv[]) static Token near_func(FunctionIdentifier self, int argc, const Token argv[])
{ {
FltT (*frnd)(FltT); FltT (*frnd)(FltT) = NULL;
switch (self) { switch (self) {
case FUNC_FLOOR: frnd = FLOORFLT; break; case FUNC_FLOOR: frnd = FLOORFLT; break;
case FUNC_CEIL: frnd = CEILFLT; 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 < 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) if (argv[0].type == STRING && argv[1].type == INT)
{ {
char ss[1024]; 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 < 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 = (int)(e - b + 1); if ( b < e ) {
if ( n >= 1024 ) n = 1024 - 1; result.type = EMPTY;
if (n > 0) { return result;
}
size_t n = (size_t)(e - b + 1);
if (n >= sizeof(ss)) n = sizeof(ss) - 1;
ss[n] = '\0'; ss[n] = '\0';
strncpy(ss, argv[0].u.string + b, n); strncpy(ss, argv[0].u.string + b, n);
result.type=STRING; result.type = STRING;
result.u.string=strdup(ss); result.u.string = strdup(ss);
}
else {
result.type = EMPTY;
}
}
else duperror(&result, usage);
return result; return result;
}
return duperror(&result, usage);
} }
/*}}}*/ /*}}}*/
@ -1783,7 +1810,7 @@ Tfunc tfunc[]=
[FUNC_NUMBER] = { "number", number_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_NUMBER] = { "number", number_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_OPERATOR] = { "operator", self_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_OPERATOR] = { "operator", self_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_STRING] = { "string", string_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 */ /* Style functions */
[FUNC_PRECISION] = { "precision", precision_func, PREFIX_FUNC, FUNCT, 0 }, [FUNC_PRECISION] = { "precision", precision_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_FOREGROUND] = { "foreground", aspect_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_DECIMAL] = { "decimal", self_func, PREFIX_FUNC, FUNCT, 0 },
[FUNC_HEXACT] = { "hexact", 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_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_IS, FUNC_FIND, FUNC_PRECISION, FUNC_FOREGROUND, FUNC_BACKGROUND,
FUNC_JUSTIFY, FUNC_FLOATFMT, FUNC_SHADOWED, FUNC_TRANSPARENT, FUNC_BOLD, 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 N_FUNCTION_IDS
} FunctionIdentifier; } FunctionIdentifier;
#define IS_RELATION_FUNC(f) (((f) >= FUNC_LESS_EQUAL) && ((f) <= FUNC_BANG_EQUAL)) #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 */ /* Forward declaration of Token, since this header is used in scanner.h */
typedef struct Token_struc Token; 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 */ /*{{{*/ /* do_edit -- set or modify cell contents */ /*{{{*/
static int do_edit(Sheet *cursheet, Key c, char *expr, TokVariety tv) static int do_edit(Sheet *cursheet, Key c, char *expr, TokVariety tv)
{ {
/* variables */ /*{{{*/ const char *promptfor[] = { [BASE_CONT] = _("Cell contents"),
char buf[1024]; [ITER_CONT] = _("Clocked cell contents"),
const char *prompt; [STYLE_CONT] = _("Style expression")
char *s; };
size_t x,offx;
Location scur; Location scur;
Token **t; Cell *cell = curcell(cursheet);
Token newcont; Token newcont;
Cell *cell;
/*}}}*/
cell = curcell(cursheet);
if (locked(cell)) line_msg(_("Edit cell:"),_("Cell is locked")); if (locked(cell)) line_msg(_("Edit cell:"),_("Cell is locked"));
else else
{ {
@ -163,18 +158,15 @@ static int do_edit(Sheet *cursheet, Key c, char *expr, TokVariety tv)
LOCATION_GETS(scur, cursheet->cur); LOCATION_GETS(scur, cursheet->cur);
if (expr) if (expr)
{ {
s = expr; char *s = expr;
t = scan(&s); Token **t = scan(&s);
prompt = _("Cell contents:");
if (tv == ITER_CONT) prompt = _("Clocked cell contents");
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(promptfor[tv], "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(promptfor[tv], "XXX unparseable expression");
} }
} }
tvecfree(t); tvecfree(t);
@ -182,7 +174,9 @@ static int do_edit(Sheet *cursheet, Key c, char *expr, TokVariety tv)
else else
{ {
Token cntt; Token cntt;
offx=0; size_t offx = 0;
char buf[1024];
char *s = NULL;
if (c == K_NONE) if (c == K_NONE)
{ {
cntt = gettok(cell, tv); cntt = gettok(cell, tv);
@ -222,16 +216,12 @@ static int do_edit(Sheet *cursheet, Key c, char *expr, TokVariety tv)
} }
do do
{ {
int r;
tfree(&newcont); tfree(&newcont);
newcont.type = EEK; newcont.type = EEK;
newcont.u.err = (char *)0; newcont.u.err = (char *)0;
x = mbslen(buf)-mbslen(s); size_t x = mbslen(buf)-mbslen(s);
prompt = _("Cell contents:"); int r = line_edit(cursheet, buf, sizeof(buf), promptfor[tv], &x, &offx);
if (tv == ITER_CONT) prompt = _("Clocked cell contents:"); if (r < 0) return r;
if ((r = line_edit(cursheet, buf, sizeof(buf), prompt, &x, &offx)) < 0)
return r;
s = buf; s = buf;
if (buf[0] == '"' && buf[strlen(buf)-1] != '"' if (buf[0] == '"' && buf[strlen(buf)-1] != '"'
&& strlen(buf)+1 < sizeof(buf)) && 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)+1] = 0;
buf[strlen(buf)] = '"'; buf[strlen(buf)] = '"';
} }
t = scan(&s); Token **t = scan(&s);
if (t != EMPTY_TVEC) { if (t != EMPTY_TVEC) {
newcont = eval_safe(t, LITERAL); newcont = eval_safe(t, LITERAL);
} }
@ -341,8 +331,8 @@ static void do_attribute(Sheet *cursheet, Key action)
ColorAspect ca = FOREGROUND; ColorAspect ca = FOREGROUND;
switch ((int)action) switch ((int)action)
{ {
case ADJUST_CENTER: ++adj; /* drop through */ case ADJUST_CENTER: ++adj; /* FALL THROUGH */
case ADJUST_RIGHT: ++adj; /* drop through */ case ADJUST_RIGHT: ++adj; /* FALL THROUGH */
case ADJUST_LEFT: case ADJUST_LEFT:
{ {
const char *templ = _("Change adjustment of block to %s?"); const char *templ = _("Change adjustment of block to %s?");
@ -354,9 +344,9 @@ static void do_attribute(Sheet *cursheet, Key action)
break; break;
} }
/* set float format */ /*{{{*/ /* set float format */ /*{{{*/
case ADJUST_HEXACT: ++ff; /* drop through */ case ADJUST_HEXACT: ++ff; /* FALL THROUGH */
case ADJUST_COMPACT: ++ff; /* drop through */ case ADJUST_COMPACT: ++ff; /* FALL THROUGH */
case ADJUST_SCIENTIFIC: ++ff; /* drop through */ case ADJUST_SCIENTIFIC: ++ff; /* FALL THROUGH */
case ADJUST_DECIMAL: case ADJUST_DECIMAL:
{ {
const char* templ = _("Change float format of block to %s?"); 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 */ case 2: /* use whole layer */
beg[X] = 0; end[X] = (CoordT)(sheet->dim[X]); beg[X] = 0; end[X] = (CoordT)(sheet->dim[X]);
beg[Y] = 0; end[Y] = (CoordT)(sheet->dim[Y]); beg[Y] = 0; end[Y] = (CoordT)(sheet->dim[Y]);
break;
case HYPER: assert(0); case HYPER: assert(0);
} }
break; break;
@ -1588,7 +1579,7 @@ int do_sheetcmd(Sheet *cursheet, Key c, bool moveonly)
/* FPAGE -- page right */ /*{{{*/ /* FPAGE -- page right */ /*{{{*/
case K_FPAGE: case K_FPAGE:
{ {
cursheet->offx += cursheet->width; cursheet->offx += (CoordT)cursheet->width;
relmoveto(cursheet, (CoordT)(cursheet->width), 0, 0); relmoveto(cursheet, (CoordT)(cursheet->width), 0, 0);
break; break;
} }

View File

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

View File

@ -103,7 +103,6 @@ static Token primary(Token *n[], int *i, EvalMethod meth)
} }
/*}}}*/ /*}}}*/
/* OPERATOR */ /*{{{*/
case OPERATOR: case OPERATOR:
{ {
switch (n[*i]->u.op) switch (n[*i]->u.op)
@ -142,12 +141,9 @@ static Token primary(Token *n[], int *i, EvalMethod meth)
return result; return result;
} }
fident = identcode(Op_Name[n[*i]->u.op], strlen(Op_Name[n[*i]->u.op])); fident = identcode(Op_Name[n[*i]->u.op], strlen(Op_Name[n[*i]->u.op]));
/* FALL THROUGH TO PROCESS OPERATOR AS FUNCTION CALL */
} }
} }
/*}}}*/ /* FALL THROUGH */
/* FIDENT */ /*{{{*/
case FIDENT: case FIDENT:
{ {
if (fident == -2) fident = n[*i]->u.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; } else result.u.funcall.argv = NULLTOKEN;
return result; return result;
} }
/*}}}*/
/* FUNCALL */ /*{{{*/ /* FUNCALL */ /*{{{*/
case 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; res.u.style.adjust = LEFT; return res.u.style;
} }
Cell *cell = CELL_AT(sheet, at); Cell *cell = CELL_AT(sheet, at);
if (!(cell->updated)) recompvalue(sheet, at);
assert(cell->updated); assert(cell->updated);
if (cell->tok[STYLE_VAL].type == STYLE) return cell->tok[STYLE_VAL].u.style; if (cell->tok[STYLE_VAL].type == STYLE) return cell->tok[STYLE_VAL].u.style;
Sheet *old_up_sh = upd_sheet; Sheet *old_up_sh = upd_sheet;
@ -703,10 +704,11 @@ Style getstyle(Sheet *sheet, const Location at)
case EMPTY: sty = res.u.style; break; case EMPTY: sty = res.u.style; break;
default: { default: {
char buf[4096]; char buf[4096];
const char *msg = _("Produced non-style value "); const char *msg = _("Produced non-style value at &(%d,%d,%d) '");
strcpy(buf, msg); sprintf(buf, msg, at[X], at[Y], at[Z]);
printtok(buf+strlen(msg), sizeof(buf)-strlen(msg)-1, 0, QUOTE_STRING, printtok(buf+strlen(buf), sizeof(buf)-strlen(buf)-1, 0, QUOTE_STRING,
FLT_COMPACT, -1, VERBOSE_ERROR, &tsty); FLT_COMPACT, -1, VERBOSE_ERROR, &tsty);
strcat(buf, "'");
line_msg(_("Cell style expr:"), msg); line_msg(_("Cell style expr:"), msg);
sty = res.u.style; sty = res.u.style;
break; break;
@ -788,7 +790,8 @@ bool overridestyle(Sheet *sheet, const Location at, Style sty) {
case STYLE: { case STYLE: {
Token tsty; tsty.type = STYLE; tsty.u.style = sty; Token tsty; tsty.type = STYLE; tsty.u.style = sty;
thecell->tok[STYLE_CONT] = tadd(tsty, stok); 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])); tfree(&(thecell->tok[STYLE_VAL]));
return true; return true;
} }
@ -1194,8 +1197,8 @@ const char *savecsv(Sheet *sheet, const char *name, char sep,
Cell *cw = CELL_AT(sheet,w); Cell *cw = CELL_AT(sheet,w);
if (cw != NULLCELL) if (cw != NULLCELL)
{ {
static const int bufchar = 511; static const size_t bufchar = 511;
static const int bufsz = bufchar*UTF8SZ + 1; static const size_t bufsz = bufchar*UTF8SZ + 1;
char *buf = malloc(bufsz); char *buf = malloc(bufsz);
Style sw = getstyle(sheet, w); Style sw = getstyle(sheet, w);
printvalue(buf, bufsz, bufchar, DIRECT_STRING, sw.fform, 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; Location w;
for (w[Z] = start[Z]; w[Z] >= fini[Z]; w[Z]--) for (w[Z] = start[Z]; w[Z] >= fini[Z]; w[Z]--)
for (w[Y] = start[Y]; w[Y] >= fini[Y]; w[Y]--) 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); resize(sh, w[X], w[Y], w[Z], NULL);
Location from; LOCATION_GETS(from,w); 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 */ /* ptokatprec -- like printtok but with an ambient precedence */
static size_t ptokatprec(char *dest, size_t size, size_t field_width, 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, ErrorFormat ef, const Token *tok,
FunctionPrecedence atprec) FunctionPrecedence atprec)
{ {
int digits = pl;
if (debug_level > 2) { if (debug_level > 2) {
printf("..Entering printtok; bufsize %zu, field_width %zu, qs %d, ff %s," printf("..Entering ptokatprec; bufsize %zu, field_width %zu, qs %d, ff %s,"
"prec %d, verr %d\n", "precision %d, verr %d, precedence %d\n",
size, field_width, sf, FloatFormat_Name[ff], digits, ef); size, field_width, sf, FloatFormat_Name[ff], digits,
ef, (int)atprec);
} }
if (size > 0 ) *dest = '\0'; if (size > 0 ) *dest = '\0';
if (tok == NULLTOKEN || tok->type == EMPTY) return 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; 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, (size_t)(len2-epos+1));
len2 -= epos - tpos; len2 -= (int)(epos - tpos);
} }
if (len2 < len) { use = buf2; len = len2; } 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; break;
default: assert(0); default: assert(0);
} }
assert(len < sizeof(buf)); assert((size_t)len < sizeof(buf));
char *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);
@ -248,7 +250,7 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width,
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*/
cur += ptokatprec(dest+cur, size-cur-1, field_width-cur, sf, ff, 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); NO_PRECEDENCE);
} }
if (cur < size) dest[cur++] = ')'; 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++] = '('; if (fp < atprec && cur < size) dest[cur++] = '(';
cur += print_chars(dest+cur, size-cur-1, tfunc[fid].display_symbol); cur += print_chars(dest+cur, size-cur-1, tfunc[fid].display_symbol);
cur += ptokatprec(dest+cur, size-cur-1, field_width-cur, sf, ff, 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++] = ')'; if (fp < atprec && cur < size) dest[cur++] = ')';
break; break;
} }
@ -290,7 +292,7 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width,
} }
if (specialrel) { if (specialrel) {
cur += ptokatprec(dest+cur, size-cur-1, field_width-cur, sf, ff, 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) { for (int ai = 1; ai < tok->u.funcall.argc && cur < size-1; ++ ai) {
dest[cur++] = ' '; dest[cur++] = ' ';
const char *use = 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); cur += print_chars(dest+cur, size-cur-1, use);
if (cur < size) dest[cur++] = ' '; if (cur < size) dest[cur++] = ' ';
cur += ptokatprec(dest+cur, size-cur-1, field_width-cur, sf, ff, 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, tok->u.funcall.argv[ai].u.funcall.argv + 1,
INFIX_REL); INFIX_REL);
} }
@ -315,7 +317,7 @@ static size_t ptokatprec(char *dest, size_t size, size_t field_width,
} else if (fp > PREFIX_NEG) { } else if (fp > PREFIX_NEG) {
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); pl, ef, tok->u.funcall.argv, fp);
if (arglen >= sizeof(powbuf)-1) assert(0); if (arglen >= sizeof(powbuf)-1) assert(0);
if (powbuf[0] == '-') { if (powbuf[0] == '-') {
parenarg = true; 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, 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++] = ')'; 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 && 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, (int)field_width - 5);
cur = (size_t)(ov - dest); cur = (size_t)(ov - dest);
cur += print_chars(dest+cur, size-cur-1, "...##"); cur += print_chars(dest+cur, size-cur-1, "...##");
dest[cur] = '\0';
} }
} }
return cur; 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)); if (xdrs->x_op == XDR_DECODE) memset(t,0,sizeof(OldToken));
else return false; 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; x=t->type;
if (t->type==OPERATOR) x|=t->u.op<<8; if (t->type==OPERATOR) x|=t->u.op<<8;
*/
result=xdr_int(xdrs,&x); result=xdr_int(xdrs,&x);
if ((x&0xff)==OPERATOR) t->u.op=(x>>8)&0xff; if ((x&0xff)==OPERATOR) t->u.op=(x>>8)&0xff;
t->type=x&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 */ /*{{{*/ /* xdr_mystring */ /*{{{*/
static bool_t xdr_mystring(XDR *xdrs, char **str) static bool_t xdr_mystring(XDR *xdrs, char **str)
{ {
static struct xdr_discrim arms[3]= static struct xdr_discrim arms[3]=
{ {
{ 0, (xdrproc_t)xdr_void }, { 0, (xdrproc_t)xdr_myvoid },
{ 1, (xdrproc_t)xdr_wrapstring }, { 1, (xdrproc_t)xdr_wrapstring },
{ -1, (xdrproc_t)0 } { -1, (xdrproc_t)0 }
}; };

View File

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

View File

@ -23,7 +23,7 @@ void show_text(const char *text);
Key show_menu(Sheet *cursheet); Key show_menu(Sheet *cursheet);
int line_menu(const char *prompt, const char **choice, int curx); 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 #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+8: k = ctrl?K_RECALC:K_CLOCK; break;
case FL_F+9: 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_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_Enter:
case FL_KP_Enter: case FL_KP_Enter:
k = alt ? (shift ? K_EDIT_STYLE_EXPR : K_MENTER) : K_ENTER; k = alt ? (shift ? K_EDIT_STYLE_EXPR : K_MENTER) : K_ENTER;
@ -1047,7 +1047,7 @@ declblock {\#ifndef ENABLE_HELP} {after {\#endif}} {
} }
Function 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 {open C return_type void} {code
{ {
fl_filename_absolute(buf, size, argv0); 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)