+
+NCURSES_EXPORT(char *)
+tiparm(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";
+#endif /* TRACE */
+
+ if (tparm_setup(cur_term, string, &myData) == OK && ValidCap(TRUE)) {
+ va_list ap;
+
+ va_start(ap, string);
+ tparm_copy_valist(&myData, FALSE, ap);
+ va_end(ap);
+
+ result = tparam_internal(tps, string, &myData);
+ }
+ 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
+ * count is consistent with intended usage.
+ *
+ * Unlike the general-purpose tparm/tiparm, these internal calls are fairly
+ * well defined:
+ *
+ * expected == 0 - not applicable
+ * expected == 1 - set color, or vertical/horizontal addressing
+ * expected == 2 - cursor addressing
+ * expected == 4 - initialize color or color pair
+ * expected == 9 - set attributes
+ *
+ * Only for the last case (set attributes) should a parameter be optional.
+ * Also, a capability which calls for more parameters than expected should be
+ * ignored.
+ *
+ * Return a null if the parameter-checks fail. Otherwise, return a pointer to
+ * the formatted capability string.
+ */
+NCURSES_EXPORT(char *)
+_nc_tiparm(int expected, const char *string, ...)
+{
+ TPARM_STATE *tps = get_tparm_state(cur_term);
+ TPARM_DATA myData;
+ char *result = NULL;
+
+ _nc_tparm_err = 0;
+ T((T_CALLED("_nc_tiparm(%d, %s, ...)"), expected, _nc_visbuf(string)));
+#ifdef TRACE
+ tps->tname = "_nc_tiparm";
+#endif /* TRACE */
+
+ 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 " : "",
+ expected));
+ } else if (myData.num_actual > expected) {
+ T(("too many parameters, have %d, expected %d",
+ myData.num_actual,
+ expected));
+ } else if (expected != 9 && myData.num_actual != expected) {
+ T(("expected %d parameters, have %d",
+ myData.num_actual,
+ expected));
+ } else {
+ va_list ap;
+
+ va_start(ap, string);
+ tparm_copy_valist(&myData, FALSE, ap);
+ va_end(ap);
+
+ result = tparam_internal(tps, string, &myData);
+ }
+ }
+ returnPtr(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)));
+}