]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - ncurses/tinfo/lib_tparm.c
ncurses 6.5 - patch 20240504
[ncurses.git] / ncurses / tinfo / lib_tparm.c
index 8f63c567a3de8211cc2e3174758996dab9d1017e..5666b27b7e098abace692da8f75276eb2b404543 100644 (file)
@@ -53,7 +53,7 @@
 #include <ctype.h>
 #include <tic.h>
 
-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("<null>")));
+       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;