#include <ctype.h>
#include <tic.h>
-MODULE_ID("$Id: lib_tparm.c,v 1.141 2023/04/08 18:24:18 tom Exp $")
+MODULE_ID("$Id: lib_tparm.c,v 1.153 2023/11/04 19:28:41 tom Exp $")
/*
* char *
#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;
}
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
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])
tparm_trace_call(tps, string, data);
+ if (TPS(fmt_buff) == NULL) {
+ T((T_RETURN("<null>")));
+ return NULL;
+ }
+
while ((cp - string) < (int) len2) {
if (*cp != '%') {
save_char(tps, UChar(*cp));
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;
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
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);
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;
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);
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
tps->tname = "_nc_tiparm";
#endif /* TRACE */
- if (tparm_setup(cur_term, string, &myData) == OK && ValidCap()) {
- if (myData.num_actual == 0) {
+ if (tparm_setup(cur_term, string, &myData) == OK && ValidCap(FALSE)) {
+#ifdef CUR
+ if (myData.num_actual != expected && cur_term != NULL) {
+ int needed = expected;
+ if (CHECK_CAP(to_status_line)) {
+ needed = 0; /* allow for xterm's status line */
+ } else if (CHECK_CAP(set_a_background)) {
+ needed = 0; /* allow for monochrome fakers */
+ } else if (CHECK_CAP(set_a_foreground)) {
+ needed = 0;
+ } else if (CHECK_CAP(set_background)) {
+ needed = 0;
+ } else if (CHECK_CAP(set_foreground)) {
+ needed = 0;
+ }
+#if NCURSES_XNAMES
+ else {
+ char *check;
+
+ check = tigetstr("xm");
+ if (CHECK_CAP(check)) {
+ needed = 3;
+ }
+ check = tigetstr("S0");
+ if (CHECK_CAP(check)) {
+ needed = 0; /* used in screen-base */
+ }
+ }
+#endif
+ if (myData.num_actual >= needed && myData.num_actual <= expected)
+ expected = myData.num_actual;
+ }
+#endif
+ if (myData.num_actual == 0 && expected) {
T(("missing parameter%s, expected %s%d",
expected > 1 ? "s" : "",
expected == 9 ? "up to " : "",