X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Flib_tparm.c;h=5666b27b7e098abace692da8f75276eb2b404543;hp=8f63c567a3de8211cc2e3174758996dab9d1017e;hb=HEAD;hpb=c0e9e7ee0d3cba0cfa8f6164f75007e198b997e5 diff --git a/ncurses/tinfo/lib_tparm.c b/ncurses/tinfo/lib_tparm.c index 8f63c567..5666b27b 100644 --- a/ncurses/tinfo/lib_tparm.c +++ b/ncurses/tinfo/lib_tparm.c @@ -53,7 +53,7 @@ #include #include -MODULE_ID("$Id: lib_tparm.c,v 1.142 2023/04/14 00:29:31 tom Exp $") +MODULE_ID("$Id: lib_tparm.c,v 1.153 2023/11/04 19:28:41 tom Exp $") /* * char * @@ -177,19 +177,21 @@ _nc_free_tparm(TERMINAL *termp) #if HAVE_TSEARCH if (MyCount != 0) { 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]; - if (ptr != NULL) { - tdelete(ptr, &MyCache, cmp_format); - free((char *) ptr->format); - free(ptr); + if (delete_tparm != NULL) { + which_tparm = 0; + twalk(MyCache, visit_nodes); + for (which_tparm = 0; which_tparm < MyCount; ++which_tparm) { + TPARM_DATA *ptr = delete_tparm[which_tparm]; + if (ptr != NULL) { + tdelete(ptr, &MyCache, cmp_format); + free((char *) ptr->format); + free(ptr); + } } + which_tparm = 0; + twalk(MyCache, visit_nodes); + FreeAndNull(delete_tparm); } - which_tparm = 0; - twalk(MyCache, visit_nodes); - FreeAndNull(delete_tparm); MyCount = 0; which_tparm = 0; } @@ -605,8 +607,8 @@ tparm_setup(TERMINAL *term, const char *string, TPARM_DATA *result) TPS(out_used) = 0; memset(result, 0, sizeof(*result)); - if (string == NULL) { - TR(TRACE_CALLS, ("%s: format is null", TPS(tname))); + if (!VALID_STRING(string)) { + TR(TRACE_CALLS, ("%s: format is invalid", TPS(tname))); rc = ERR; } else { #if HAVE_TSEARCH @@ -645,7 +647,7 @@ tparm_setup(TERMINAL *term, const char *string, TPARM_DATA *result) result->num_parsed = NUM_PARM; if (result->num_popped > NUM_PARM) result->num_popped = NUM_PARM; - result->num_actual = max(result->num_popped, result->num_parsed); + result->num_actual = Max(result->num_popped, result->num_parsed); for (n = 0; n < result->num_actual; ++n) { if (result->p_is_s[n]) @@ -796,6 +798,11 @@ tparam_internal(TPARM_STATE *tps, const char *string, TPARM_DATA *data) tparm_trace_call(tps, string, data); + if (TPS(fmt_buff) == NULL) { + T((T_RETURN(""))); + return NULL; + } + while ((cp - string) < (int) len2) { if (*cp != '%') { save_char(tps, UChar(*cp)); @@ -1113,8 +1120,10 @@ check_string_caps(TPARM_DATA *data, const char *string) want_type = 2; /* function key #1, transmit string #2 */ else if (CHECK_CAP(plab_norm)) want_type = 2; /* label #1, show string #2 */ +#ifdef pkey_plab else if (CHECK_CAP(pkey_plab)) want_type = 6; /* function key #1, type string #2, show string #3 */ +#endif #if NCURSES_XNAMES else { char *check; @@ -1138,10 +1147,11 @@ check_string_caps(TPARM_DATA *data, const char *string) return result; } -#define ValidCap() (myData.tparm_type == 0 || \ - check_string_caps(&myData, string)) +#define ValidCap(allow_strings) (myData.tparm_type == 0 || \ + (allow_strings && \ + check_string_caps(&myData, string))) #else -#define ValidCap() 1 +#define ValidCap(allow_strings) 1 #endif #if NCURSES_TPARM_VARARGS @@ -1158,7 +1168,7 @@ tparm(const char *string, ...) tps->tname = "tparm"; #endif /* TRACE */ - if (tparm_setup(cur_term, string, &myData) == OK && ValidCap()) { + if (tparm_setup(cur_term, string, &myData) == OK && ValidCap(TRUE)) { va_list ap; va_start(ap, string); @@ -1193,7 +1203,9 @@ tparm(const char *string, tps->tname = "tparm"; #endif /* TRACE */ - if (tparm_setup(cur_term, string, &myData) == OK && ValidCap()) { +#define string_ok (sizeof(char*) <= sizeof(TPARM_ARG)) + + if (tparm_setup(cur_term, string, &myData) == OK && ValidCap(string_ok)) { myData.param[0] = a1; myData.param[1] = a2; @@ -1224,7 +1236,7 @@ tiparm(const char *string, ...) tps->tname = "tiparm"; #endif /* TRACE */ - if (tparm_setup(cur_term, string, &myData) == OK && ValidCap()) { + if (tparm_setup(cur_term, string, &myData) == OK && ValidCap(TRUE)) { va_list ap; va_start(ap, string); @@ -1236,6 +1248,61 @@ tiparm(const char *string, ...) return result; } +/* + * Use tparm if the formatting string matches the expected number of parameters + * counting string-parameters. + */ +NCURSES_EXPORT(char *) +tiparm_s(int num_expected, int tparm_type, const char *string, ...) +{ + TPARM_STATE *tps = get_tparm_state(cur_term); + TPARM_DATA myData; + char *result = NULL; + + _nc_tparm_err = 0; +#ifdef TRACE + tps->tname = "tiparm_s"; +#endif /* TRACE */ + if (num_expected >= 0 && + num_expected <= 9 && + tparm_type >= 0 && + tparm_type < 7 && /* limit to 2 string parameters */ + tparm_setup(cur_term, string, &myData) == OK && + myData.tparm_type == tparm_type && + myData.num_actual == num_expected) { + va_list ap; + + va_start(ap, string); + tparm_copy_valist(&myData, FALSE, ap); + va_end(ap); + + result = tparam_internal(tps, string, &myData); + } + return result; +} + +/* + * Analyze the formatting string, return the analysis. + */ +NCURSES_EXPORT(int) +tiscan_s(int *num_expected, int *tparm_type, const char *string) +{ + TPARM_DATA myData; + int result = ERR; + +#ifdef TRACE + TPARM_STATE *tps = get_tparm_state(cur_term); + tps->tname = "tiscan_s"; +#endif /* TRACE */ + + if (tparm_setup(cur_term, string, &myData) == OK) { + *num_expected = myData.num_actual; + *tparm_type = myData.tparm_type; + result = OK; + } + return result; +} + /* * The internal-use flavor ensures that parameters are numbers, not strings. * In addition to ensuring that they are numbers, it ensures that the parameter @@ -1270,7 +1337,7 @@ _nc_tiparm(int expected, const char *string, ...) tps->tname = "_nc_tiparm"; #endif /* TRACE */ - if (tparm_setup(cur_term, string, &myData) == OK && ValidCap()) { + if (tparm_setup(cur_term, string, &myData) == OK && ValidCap(FALSE)) { #ifdef CUR if (myData.num_actual != expected && cur_term != NULL) { int needed = expected;