X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Flib_tparm.c;h=1ca0a45e6a3b448d6721cd45cbab6de158a91181;hp=0f0c62a491ba93ce052a90206ebc2d51e98aea28;hb=214f159cd8c0ea4fba47beb249379d0da2dfb8ca;hpb=7503e8d82292a2a0a4d8bb55bdf3f8a203159f68 diff --git a/ncurses/tinfo/lib_tparm.c b/ncurses/tinfo/lib_tparm.c index 0f0c62a4..1ca0a45e 100644 --- a/ncurses/tinfo/lib_tparm.c +++ b/ncurses/tinfo/lib_tparm.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright 2018-2019,2020 Thomas E. Dickey * + * Copyright 2018-2020,2021 Thomas E. Dickey * * Copyright 1998-2016,2017 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * @@ -53,7 +53,7 @@ #include #include -MODULE_ID("$Id: lib_tparm.c,v 1.127 2020/06/13 21:59:52 tom Exp $") +MODULE_ID("$Id: lib_tparm.c,v 1.135 2021/11/15 23:31:31 tom Exp $") /* * char * @@ -117,9 +117,14 @@ MODULE_ID("$Id: lib_tparm.c,v 1.127 2020/06/13 21:59:52 tom Exp $") NCURSES_EXPORT_VAR(int) _nc_tparm_err = 0; -#define TPS(var) _nc_prescreen.tparm_state.var +#define TPS(var) tps->var #define popcount _nc_popcount /* workaround for NetBSD 6.0 defect */ +#define get_tparm_state(term) \ + (term != NULL \ + ? &(term->tparm_state) \ + : &(_nc_prescreen.tparm_state)) + #define isUPPER(c) ((c) >= 'A' && (c) <= 'Z') #define isLOWER(c) ((c) >= 'a' && (c) <= 'z') #define tc_BUMP() if (level < 0 && number < 2) number++ @@ -171,16 +176,19 @@ visit_nodes(const void *nodep, const VISIT which, const int depth) NCURSES_EXPORT(void) _nc_free_tparm(void) { + TPARM_STATE *tps = get_tparm_state(cur_term); /* FIXME */ #if HAVE_TSEARCH if (MyCount != 0) { - delete_tparm = typeMalloc(TPARM_DATA *, MyCount); + delete_tparm = typeCalloc(TPARM_DATA *, MyCount); which_tparm = 0; twalk(MyCache, visit_nodes); for (which_tparm = 0; which_tparm < MyCount; ++which_tparm) { TPARM_DATA *ptr = delete_tparm[which_tparm]; - tdelete(ptr, &MyCache, cmp_format); - free((char *) ptr->format); - free(ptr); + if (ptr != NULL) { + tdelete(ptr, &MyCache, cmp_format); + free((char *) ptr->format); + free(ptr); + } } which_tparm = 0; twalk(MyCache, visit_nodes); @@ -198,105 +206,158 @@ _nc_free_tparm(void) } #endif -static NCURSES_INLINE void -get_space(size_t need) +static int +tparm_error(TPARM_STATE *tps, const char *message) { - need += TPS(out_used); - if (need > TPS(out_size)) { - TPS(out_size) = need * 2; - TYPE_REALLOC(char, TPS(out_size), TPS(out_buff)); - } + (void) tps; + (void) message; + DEBUG(2, ("%s: %s", message, _nc_visbuf(TPS(tparam_base)))); + return ++_nc_tparm_err; } +#define get_space(tps, need) \ +{ \ + size_t need2get = need + TPS(out_used); \ + if (need2get > TPS(out_size)) { \ + TPS(out_size) = need2get * 2; \ + TYPE_REALLOC(char, TPS(out_size), TPS(out_buff)); \ + } \ +} + +#if NCURSES_EXPANDED static NCURSES_INLINE void -save_text(const char *fmt, const char *s, int len) -{ - size_t s_len = (size_t) len + strlen(s) + strlen(fmt); - get_space(s_len + 1); + (get_space) (TPARM_STATE *tps, size_t need) { + get_space(tps, need); +} - _nc_SPRINTF(TPS(out_buff) + TPS(out_used), - _nc_SLIMIT(TPS(out_size) - TPS(out_used)) - fmt, s); - TPS(out_used) += strlen(TPS(out_buff) + TPS(out_used)); +#undef get_space +#endif + +#define save_text(tps, fmt, s, len) \ +{ \ + size_t s_len = (size_t) len + strlen(s) + strlen(fmt); \ + get_space(tps, s_len + 1); \ + _nc_SPRINTF(TPS(out_buff) + TPS(out_used), \ + _nc_SLIMIT(TPS(out_size) - TPS(out_used)) \ + fmt, s); \ + TPS(out_used) += strlen(TPS(out_buff) + TPS(out_used)); \ } +#if NCURSES_EXPANDED static NCURSES_INLINE void -save_number(const char *fmt, int number, int len) -{ - size_t s_len = (size_t) len + 30 + strlen(fmt); - get_space(s_len + 1); + (save_text) (TPARM_STATE *tps, const char *fmt, const char *s, int len) { + save_text(tps, fmt, s, len); +} - _nc_SPRINTF(TPS(out_buff) + TPS(out_used), - _nc_SLIMIT(TPS(out_size) - TPS(out_used)) - fmt, number); - TPS(out_used) += strlen(TPS(out_buff) + TPS(out_used)); +#undef save_text +#endif + +#define save_number(tps, fmt, number, len) \ +{ \ + size_t s_len = (size_t) len + 30 + strlen(fmt); \ + get_space(tps, s_len + 1); \ + _nc_SPRINTF(TPS(out_buff) + TPS(out_used), \ + _nc_SLIMIT(TPS(out_size) - TPS(out_used)) \ + fmt, number); \ + TPS(out_used) += strlen(TPS(out_buff) + TPS(out_used)); \ } +#if NCURSES_EXPANDED static NCURSES_INLINE void -save_char(int c) -{ - if (c == 0) - c = 0200; - get_space((size_t) 1); - TPS(out_buff)[TPS(out_used)++] = (char) c; + (save_number) (TPARM_STATE *tps, const char *fmt, int number, int len) { + save_number(tps, fmt, number, len); +} + +#undef save_number +#endif + +#define save_char(tps, c) \ +{ \ + get_space(tps, (size_t) 1); \ + TPS(out_buff)[TPS(out_used)++] = (char) ((c == 0) ? 0200 : c); \ } +#if NCURSES_EXPANDED static NCURSES_INLINE void -npush(int x) -{ - if (TPS(stack_ptr) < STACKSIZE) { - TPS(stack)[TPS(stack_ptr)].num_type = TRUE; - TPS(stack)[TPS(stack_ptr)].data.num = x; - TPS(stack_ptr)++; - } else { - DEBUG(2, ("npush: stack overflow: %s", _nc_visbuf(TPS(tparam_base)))); - _nc_tparm_err++; - } + (save_char) (TPARM_STATE *tps, int c) { + save_char(tps, c); } -static NCURSES_INLINE int -npop(void) -{ - int result = 0; - if (TPS(stack_ptr) > 0) { - TPS(stack_ptr)--; - if (TPS(stack)[TPS(stack_ptr)].num_type) - result = TPS(stack)[TPS(stack_ptr)].data.num; - } else { - DEBUG(2, ("npop: stack underflow: %s", _nc_visbuf(TPS(tparam_base)))); - _nc_tparm_err++; - } - return result; +#undef save_char +#endif + +#define npush(tps, x) \ +{ \ + if (TPS(stack_ptr) < STACKSIZE) { \ + TPS(stack)[TPS(stack_ptr)].num_type = TRUE; \ + TPS(stack)[TPS(stack_ptr)].data.num = x; \ + TPS(stack_ptr)++; \ + } else { \ + (void) tparm_error(tps, "npush: stack overflow"); \ + } \ } +#if NCURSES_EXPANDED static NCURSES_INLINE void -spush(char *x) -{ - if (TPS(stack_ptr) < STACKSIZE) { - TPS(stack)[TPS(stack_ptr)].num_type = FALSE; - TPS(stack)[TPS(stack_ptr)].data.str = x; - TPS(stack_ptr)++; - } else { - DEBUG(2, ("spush: stack overflow: %s", _nc_visbuf(TPS(tparam_base)))); - _nc_tparm_err++; - } + (npush) (TPARM_STATE *tps, int x) { + npush(tps, x); } +#undef npush +#endif + +#define spush(tps, x) \ +{ \ + if (TPS(stack_ptr) < STACKSIZE) { \ + TPS(stack)[TPS(stack_ptr)].num_type = FALSE; \ + TPS(stack)[TPS(stack_ptr)].data.str = x; \ + TPS(stack_ptr)++; \ + } else { \ + (void) tparm_error(tps, "spush: stack overflow"); \ + } \ +} + +#if NCURSES_EXPANDED +static NCURSES_INLINE void + (spush) (TPARM_STATE *tps, char *x) { + spush(tps, x); +} + +#undef spush +#endif + +#define npop(tps) \ + ((TPS(stack_ptr)-- > 0) \ + ? ((TPS(stack)[TPS(stack_ptr)].num_type) \ + ? TPS(stack)[TPS(stack_ptr)].data.num \ + : 0) \ + : (tparm_error(tps, "npop: stack underflow"), \ + TPS(stack_ptr) = 0)) + +#if NCURSES_EXPANDED +static NCURSES_INLINE int + (npop) (TPARM_STATE *tps) { + return npop(tps); +} +#undef npop +#endif + +#define spop(tps) \ + ((TPS(stack_ptr)-- > 0) \ + ? ((!TPS(stack)[TPS(stack_ptr)].num_type \ + && TPS(stack)[TPS(stack_ptr)].data.str != 0) \ + ? TPS(stack)[TPS(stack_ptr)].data.str \ + : dummy) \ + : (tparm_error(tps, "spop: stack underflow"), \ + dummy)) + +#if NCURSES_EXPANDED static NCURSES_INLINE char * -spop(void) -{ - char *result = dummy; - if (TPS(stack_ptr) > 0) { - TPS(stack_ptr)--; - if (!TPS(stack)[TPS(stack_ptr)].num_type - && TPS(stack)[TPS(stack_ptr)].data.str != 0) - result = TPS(stack)[TPS(stack_ptr)].data.str; - } else { - DEBUG(2, ("spop: stack underflow: %s", _nc_visbuf(TPS(tparam_base)))); - _nc_tparm_err++; - } - return result; + (spop) (TPARM_STATE *tps) { + return spop(tps); } +#undef spop +#endif static NCURSES_INLINE const char * parse_format(const char *s, char *format, int *len) @@ -405,8 +466,9 @@ parse_format(const char *s, char *format, int *len) * may be cases that we cannot see the explicit parameter numbers. */ NCURSES_EXPORT(int) -_nc_tparm_analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount) +_nc_tparm_analyze(TERMINAL *term, const char *string, char **p_is_s, int *popcount) { + TPARM_STATE *tps = get_tparm_state(term); size_t len2; int i; int lastpop = -1; @@ -539,8 +601,9 @@ _nc_tparm_analyze(const char *string, char *p_is_s[NUM_PARM], int *popcount) * TODO: cache the result so that this is done once per capability per term. */ static int -tparm_setup(const char *string, TPARM_DATA * result) +tparm_setup(TERMINAL *term, const char *string, TPARM_DATA *result) { + TPARM_STATE *tps = get_tparm_state(term); int rc = OK; TPS(out_used) = 0; @@ -556,8 +619,15 @@ tparm_setup(const char *string, TPARM_DATA * result) result->format = string; if ((ft = tfind(result, &MyCache, cmp_format)) != 0) { + size_t len2; fs = *(TPARM_DATA **) ft; *result = *fs; + if ((len2 = strlen(string)) + 2 > TPS(fmt_size)) { + TPS(fmt_size) += len2 + 2; + TPS(fmt_buff) = typeRealloc(char, TPS(fmt_size), TPS(fmt_buff)); + if (TPS(fmt_buff) == 0) + return ERR; + } } else #endif { @@ -566,7 +636,7 @@ tparm_setup(const char *string, TPARM_DATA * result) * string. Use this value to limit the number of arguments copied * from the variable-length argument list. */ - result->num_parsed = _nc_tparm_analyze(string, + result->num_parsed = _nc_tparm_analyze(term, string, result->p_is_s, &(result->num_popped)); if (TPS(fmt_buff) == 0) { @@ -589,12 +659,14 @@ tparm_setup(const char *string, TPARM_DATA * result) if ((fs = typeCalloc(TPARM_DATA, 1)) != 0) { *fs = *result; if ((fs->format = strdup(string)) != 0) { - if ((ft = tsearch(fs, &MyCache, cmp_format)) != 0) { + if (tsearch(fs, &MyCache, cmp_format) != 0) { ++MyCount; } else { + free(fs); rc = ERR; } } else { + free(fs); rc = ERR; } } else { @@ -615,7 +687,7 @@ tparm_setup(const char *string, TPARM_DATA * result) * long's, which is consistent with our va_arg() usage. */ static void -tparm_copy_valist(TPARM_DATA * data, int use_TPARM_ARG, va_list ap) +tparm_copy_valist(TPARM_DATA *data, int use_TPARM_ARG, va_list ap) { int i; @@ -642,7 +714,7 @@ tparm_copy_valist(TPARM_DATA * data, int use_TPARM_ARG, va_list ap) * will expand termcap strings OK. */ static bool -tparm_tc_compat(TPARM_DATA * data) +tparm_tc_compat(TPARM_STATE *tps, TPARM_DATA *data) { bool termcap_hack = FALSE; @@ -653,10 +725,11 @@ tparm_tc_compat(TPARM_DATA * data) termcap_hack = TRUE; for (i = data->num_parsed - 1; i >= 0; i--) { - if (data->p_is_s[i]) - spush(data->p_is_s[i]); - else - npush((int) data->param[i]); + if (data->p_is_s[i]) { + spush(tps, data->p_is_s[i]); + } else { + npush(tps, (int) data->param[i]); + } } } return termcap_hack; @@ -664,20 +737,20 @@ tparm_tc_compat(TPARM_DATA * data) #ifdef TRACE static void -tparm_trace_call(const char *string, TPARM_DATA * data) +tparm_trace_call(TPARM_STATE *tps, const char *string, TPARM_DATA *data) { if (USE_TRACEF(TRACE_CALLS)) { int i; for (i = 0; i < data->num_actual; i++) { if (data->p_is_s[i] != 0) { - save_text(", %s", _nc_visbuf(data->p_is_s[i]), 0); + save_text(tps, ", %s", _nc_visbuf(data->p_is_s[i]), 0); } else if ((long) data->param[i] > MAX_OF_TYPE(NCURSES_INT2) || (long) data->param[i] < 0) { _tracef("BUG: problem with tparm parameter #%d of %d", i + 1, data->num_actual); break; } else { - save_number(", %d", (int) data->param[i], 0); + save_number(tps, ", %d", (int) data->param[i], 0); } } _tracef(T_CALLED("%s(%s%s)"), TPS(tname), _nc_visbuf(string), TPS(out_buff)); @@ -687,27 +760,49 @@ tparm_trace_call(const char *string, TPARM_DATA * data) } #else -#define tparm_trace_call(string, data) /* nothing */ +#define tparm_trace_call(tps, string, data) /* nothing */ #endif /* TRACE */ +#define init_vars(name) \ + if (!name##_used) { \ + name##_used = TRUE; \ + memset(name##_vars, 0, sizeof(name##_vars)); \ + } + static NCURSES_INLINE char * -tparam_internal(const char *string, TPARM_DATA * data) +tparam_internal(TPARM_STATE *tps, const char *string, TPARM_DATA *data) { int number; int len; int level; int x, y; int i; + const char *s; const char *cp = string; size_t len2 = strlen(cp); bool incremented_two = FALSE; - bool termcap_hack = tparm_tc_compat(data); - - tparm_trace_call(string, data); + bool termcap_hack = tparm_tc_compat(tps, data); + /* + * SVr4 curses stores variables 'A' to 'Z' in the TERMINAL structure (so + * they are initialized once to zero), and variables 'a' to 'z' on the + * stack in tparm, referring to the former as "static" and the latter as + * "dynamic". However, it makes no check to ensure that the "dynamic" + * variables are initialized. + * + * Solaris xpg4 curses makes no distinction between the upper/lower, and + * stores the common set of 26 variables on the stack, without initializing + * them. + * + * In ncurses, both sets of variables are initialized on the first use. + */ + bool dynamic_used = FALSE; + int dynamic_vars[NUM_VARS]; + + tparm_trace_call(tps, string, data); while ((cp - string) < (int) len2) { if (*cp != '%') { - save_char(UChar(*cp)); + save_char(tps, UChar(*cp)); } else { TPS(tparam_base) = cp++; cp = parse_format(cp, TPS(fmt_buff), &len); @@ -715,40 +810,44 @@ tparam_internal(const char *string, TPARM_DATA * data) default: break; case '%': - save_char('%'); + save_char(tps, '%'); break; case 'd': /* FALLTHRU */ case 'o': /* FALLTHRU */ case 'x': /* FALLTHRU */ case 'X': /* FALLTHRU */ - save_number(TPS(fmt_buff), npop(), len); + x = npop(tps); + save_number(tps, TPS(fmt_buff), x, len); break; case 'c': /* FALLTHRU */ - save_char(npop()); + x = npop(tps); + save_char(tps, x); break; #ifdef EXP_XTERM_1005 case 'u': { unsigned char target[10]; - unsigned source = (unsigned) npop(); + unsigned source = (unsigned) npop(tps); int rc = _nc_conv_to_utf8(target, source, (unsigned) sizeof(target)); int n; for (n = 0; n < rc; ++n) { - save_char(target[n]); + save_char(tps, target[n]); } } break; #endif case 'l': - npush((int) strlen(spop())); + s = spop(tps); + npush(tps, (int) strlen(s)); break; case 's': - save_text(TPS(fmt_buff), spop(), len); + s = spop(tps); + save_text(tps, TPS(fmt_buff), s, len); break; case 'p': @@ -756,9 +855,9 @@ tparam_internal(const char *string, TPARM_DATA * data) i = (UChar(*cp) - '1'); if (i >= 0 && i < NUM_PARM) { if (data->p_is_s[i]) { - spush(data->p_is_s[i]); + spush(tps, data->p_is_s[i]); } else { - npush((int) data->param[i]); + npush(tps, (int) data->param[i]); } } break; @@ -767,10 +866,11 @@ tparam_internal(const char *string, TPARM_DATA * data) cp++; if (isUPPER(*cp)) { i = (UChar(*cp) - 'A'); - TPS(static_vars)[i] = npop(); + TPS(static_vars)[i] = npop(tps); } else if (isLOWER(*cp)) { i = (UChar(*cp) - 'a'); - TPS(dynamic_var)[i] = npop(); + init_vars(dynamic); + dynamic_vars[i] = npop(tps); } break; @@ -778,16 +878,17 @@ tparam_internal(const char *string, TPARM_DATA * data) cp++; if (isUPPER(*cp)) { i = (UChar(*cp) - 'A'); - npush(TPS(static_vars)[i]); + npush(tps, TPS(static_vars)[i]); } else if (isLOWER(*cp)) { i = (UChar(*cp) - 'a'); - npush(TPS(dynamic_var)[i]); + init_vars(dynamic); + npush(tps, dynamic_vars[i]); } break; case S_QUOTE: cp++; - npush(UChar(*cp)); + npush(tps, UChar(*cp)); cp++; break; @@ -798,83 +899,95 @@ tparam_internal(const char *string, TPARM_DATA * data) number = (number * 10) + (UChar(*cp) - '0'); cp++; } - npush(number); + npush(tps, number); break; case '+': - npush(npop() + npop()); + y = npop(tps); + x = npop(tps); + npush(tps, x + y); break; case '-': - y = npop(); - x = npop(); - npush(x - y); + y = npop(tps); + x = npop(tps); + npush(tps, x - y); break; case '*': - npush(npop() * npop()); + y = npop(tps); + x = npop(tps); + npush(tps, x * y); break; case '/': - y = npop(); - x = npop(); - npush(y ? (x / y) : 0); + y = npop(tps); + x = npop(tps); + npush(tps, y ? (x / y) : 0); break; case 'm': - y = npop(); - x = npop(); - npush(y ? (x % y) : 0); + y = npop(tps); + x = npop(tps); + npush(tps, y ? (x % y) : 0); break; case 'A': - y = npop(); - x = npop(); - npush(y && x); + y = npop(tps); + x = npop(tps); + npush(tps, y && x); break; case 'O': - y = npop(); - x = npop(); - npush(y || x); + y = npop(tps); + x = npop(tps); + npush(tps, y || x); break; case '&': - npush(npop() & npop()); + y = npop(tps); + x = npop(tps); + npush(tps, x & y); break; case '|': - npush(npop() | npop()); + y = npop(tps); + x = npop(tps); + npush(tps, x | y); break; case '^': - npush(npop() ^ npop()); + y = npop(tps); + x = npop(tps); + npush(tps, x ^ y); break; case '=': - y = npop(); - x = npop(); - npush(x == y); + y = npop(tps); + x = npop(tps); + npush(tps, x == y); break; case '<': - y = npop(); - x = npop(); - npush(x < y); + y = npop(tps); + x = npop(tps); + npush(tps, x < y); break; case '>': - y = npop(); - x = npop(); - npush(x > y); + y = npop(tps); + x = npop(tps); + npush(tps, x > y); break; case '!': - npush(!npop()); + x = npop(tps); + npush(tps, !x); break; case '~': - npush(~npop()); + x = npop(tps); + npush(tps, ~x); break; case 'i': @@ -904,7 +1017,7 @@ tparam_internal(const char *string, TPARM_DATA * data) break; case 't': - x = npop(); + x = npop(tps); if (!x) { /* scan forward for %e or %; at level zero */ cp++; @@ -963,9 +1076,16 @@ tparam_internal(const char *string, TPARM_DATA * data) cp++; } /* endwhile (*cp) */ - get_space((size_t) 1); + get_space(tps, (size_t) 1); TPS(out_buff)[TPS(out_used)] = '\0'; + if (TPS(stack_ptr) && !_nc_tparm_err) { + DEBUG(2, ("tparm: stack has %d item%s on return", + TPS(stack_ptr), + TPS(stack_ptr) == 1 ? "" : "s")); + _nc_tparm_err++; + } + T((T_RETURN("%s"), _nc_visbuf(TPS(out_buff)))); return (TPS(out_buff)); } @@ -975,22 +1095,23 @@ tparam_internal(const char *string, TPARM_DATA * data) NCURSES_EXPORT(char *) tparm(const char *string, ...) { + TPARM_STATE *tps = get_tparm_state(cur_term); TPARM_DATA myData; - va_list ap; char *result = NULL; _nc_tparm_err = 0; #ifdef TRACE - TPS(tname) = "tparm"; + tps->tname = "tparm"; #endif /* TRACE */ - if (tparm_setup(string, &myData) == OK) { + if (tparm_setup(cur_term, string, &myData) == OK) { + va_list ap; va_start(ap, string); tparm_copy_valist(&myData, TRUE, ap); va_end(ap); - result = tparam_internal(string, &myData); + result = tparam_internal(tps, string, &myData); } return result; } @@ -1009,15 +1130,16 @@ tparm(const char *string, TPARM_ARG a8, TPARM_ARG a9) { + TPARM_STATE *tps = get_tparm_state(cur_term); TPARM_DATA myData; char *result = NULL; _nc_tparm_err = 0; #ifdef TRACE - TPS(tname) = "tparm"; + tps->tname = "tparm"; #endif /* TRACE */ - if (tparm_setup(string, &myData) == OK) { + if (tparm_setup(cur_term, string, &myData) == OK) { myData.param[0] = a1; myData.param[1] = a2; @@ -1029,7 +1151,7 @@ tparm(const char *string, myData.param[7] = a8; myData.param[8] = a9; - result = tparam_internal(string, &myData); + result = tparam_internal(tps, string, &myData); } return result; } @@ -1039,22 +1161,23 @@ tparm(const char *string, NCURSES_EXPORT(char *) tiparm(const char *string, ...) { + TPARM_STATE *tps = get_tparm_state(cur_term); TPARM_DATA myData; - va_list ap; char *result = NULL; _nc_tparm_err = 0; #ifdef TRACE - TPS(tname) = "tiparm"; + tps->tname = "tiparm"; #endif /* TRACE */ - if (tparm_setup(string, &myData) == OK) { + if (tparm_setup(cur_term, string, &myData) == OK) { + va_list ap; va_start(ap, string); tparm_copy_valist(&myData, FALSE, ap); va_end(ap); - result = tparam_internal(string, &myData); + result = tparam_internal(tps, string, &myData); } return result; } @@ -1065,24 +1188,36 @@ tiparm(const char *string, ...) NCURSES_EXPORT(char *) _nc_tiparm(int expected, const char *string, ...) { + TPARM_STATE *tps = get_tparm_state(cur_term); TPARM_DATA myData; - va_list ap; char *result = NULL; _nc_tparm_err = 0; #ifdef TRACE - TPS(tname) = "_nc_tiparm"; + tps->tname = "_nc_tiparm"; #endif /* TRACE */ - if (tparm_setup(string, &myData) == OK + if (tparm_setup(cur_term, string, &myData) == OK && myData.num_actual <= expected && myData.tparm_type == 0) { + va_list ap; va_start(ap, string); tparm_copy_valist(&myData, FALSE, ap); va_end(ap); - result = tparam_internal(string, &myData); + result = tparam_internal(tps, string, &myData); } return result; } + +/* + * Improve tic's checks by resetting the terminfo "static variables" before + * calling functions which may update them. + */ +NCURSES_EXPORT(void) +_nc_reset_tparm(TERMINAL *term) +{ + TPARM_STATE *tps = get_tparm_state(term); + memset(TPS(static_vars), 0, sizeof(TPS(static_vars))); +}