]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - test/test_tparm.c
ncurses 6.4 - patch 20230423
[ncurses.git] / test / test_tparm.c
index 86828a64a1800b703b250d5af484f36441398a87..7b59eee9ceb9edab799b3441635e71fa819f942e 100644 (file)
 /*
  * Author: Thomas E. Dickey
  *
- * $Id: test_tparm.c,v 1.30 2023/04/15 22:31:47 tom Exp $
+ * $Id: test_tparm.c,v 1.36 2023/04/23 23:20:43 tom Exp $
  *
- * Exercise tparm, either for all possible capabilities with fixed parameters,
- * or one capability with all possible parameters.
- *
- * TODO: optionally test tiparm
- * TODO: add checks/logic to handle "%s" in tparm
+ * Exercise tparm/tiparm, either for all possible capabilities with fixed
+ * parameters, or one capability with specific combinations of parameters.
  */
 #define USE_TINFO
 #include <test.priv.h>
@@ -49,6 +46,8 @@
 #endif
 #endif
 
+#define MAX_PARM 9
+
 #define GrowArray(array,limit,length) \
            if (length + 2 >= limit) { \
                limit *= 2; \
@@ -70,7 +69,9 @@ failed(const char *msg)
 #if HAVE_TIGETSTR
 
 static int a_opt;
+static int i_opt;
 static int p_opt;
+static int s_opt;
 static int v_opt;
 
 /*
@@ -141,8 +142,8 @@ increment(long *all_parms, int *num_parms, int len_parms, int end_parms)
     int rc = 0;
     int n;
 
-    if (len_parms > 9)
-       len_parms = 9;
+    if (len_parms > MAX_PARM)
+       len_parms = MAX_PARM;
 
     if (end_parms < len_parms) {
        if (all_parms[end_parms]++ >= num_parms[end_parms]) {
@@ -163,27 +164,57 @@ increment(long *all_parms, int *num_parms, int len_parms, int end_parms)
 /* parse the format string to determine which positional parameters
  * are assumed to be strings.
  */
-#if HAVE__NC_TPARM_ANALYZE
+#if HAVE_TISCAN_S
+static int
+analyze_format(const char *format, int *mask, char **p_is_s)
+{
+    int arg_count;
+    int arg_mask;
+    int n;
+    if (tiscan_s(&arg_count, &arg_mask, format) == OK) {
+       *mask = arg_mask;
+       for (n = 0; n < MAX_PARM; ++n) {
+           static char dummy[1];
+           p_is_s[n] = (arg_mask & 1) ? dummy : NULL;
+           arg_mask >>= 1;
+       }
+    } else {
+       *mask = 0;
+       arg_count = 0;
+       for (n = 0; n < MAX_PARM; ++n) {
+           p_is_s[n] = NULL;
+       }
+    }
+    return arg_count;
+}
+#elif HAVE__NC_TPARM_ANALYZE
 extern int _nc_tparm_analyze(TERMINAL *, const char *, char **, int *);
 
 static int
-analyze_format(const char *format, char **p_is_s)
+analyze_format(const char *format, int *mask, char **p_is_s)
 {
     int popcount = 0;
     int analyzed = _nc_tparm_analyze(cur_term, format, p_is_s, &popcount);
+    int n;
     if (analyzed < popcount) {
        analyzed = popcount;
     }
+    *mask = 0;
+    for (n = 0; n < MAX_PARM; ++n) {
+       if (p_is_s[n])
+           *mask |= (1 << n);
+    }
     return analyzed;
 }
 #else
 /* TODO: make this work without direct use of ncurses internals. */
 static int
-analyze_format(const char *format, char **p_is_s)
+analyze_format(const char *format, int *mask, char **p_is_s)
 {
     int n;
     char *filler = strstr(format, "%s");
-    for (n = 0; n < 9; ++n) {
+    *mask = 0;
+    for (n = 0; n < MAX_PARM; ++n) {
        p_is_s[n] = filler;
     }
     return n;
@@ -191,29 +222,104 @@ analyze_format(const char *format, char **p_is_s)
 #endif
 
 #define NumStr(n) use_strings[n] \
-                 ? (long) (number[n] \
+                 ? (long) (my_intptr_t) (number[n] \
                     ? string[n] \
                     : NULL) \
                  : number[n]
 
+#define NS_0(fmt)      fmt
+#define NS_1(fmt)      NS_0(fmt), NumStr(0)
+#define NS_2(fmt)      NS_1(fmt), NumStr(1)
+#define NS_3(fmt)      NS_2(fmt), NumStr(2)
+#define NS_4(fmt)      NS_3(fmt), NumStr(3)
+#define NS_5(fmt)      NS_4(fmt), NumStr(4)
+#define NS_6(fmt)      NS_5(fmt), NumStr(5)
+#define NS_7(fmt)      NS_6(fmt), NumStr(6)
+#define NS_8(fmt)      NS_7(fmt), NumStr(7)
+#define NS_9(fmt)      NS_8(fmt), NumStr(8)
+
 static void
 test_tparm(const char *name, const char *format, long *number, char **string)
 {
-    char *use_strings[9];
-    char *result;
+    char *use_strings[MAX_PARM];
+    char *result = NULL;
     int nparam;
-
-    nparam = analyze_format(format, use_strings);
-    result = tparm(format,
-                  NumStr(0),
-                  NumStr(1),
-                  NumStr(2),
-                  NumStr(3),
-                  NumStr(4),
-                  NumStr(5),
-                  NumStr(6),
-                  NumStr(7),
-                  NumStr(8));
+    int mask;
+
+    nparam = analyze_format(format, &mask, use_strings);
+#if HAVE_TIPARM_S
+    if (s_opt) {
+       switch (nparam) {
+       case 0:
+           result = tiparm_s(0, mask, NS_0(format));
+           break;
+       case 1:
+           result = tiparm_s(1, mask, NS_1(format));
+           break;
+       case 2:
+           result = tiparm_s(2, mask, NS_2(format));
+           break;
+       case 3:
+           result = tiparm_s(3, mask, NS_3(format));
+           break;
+       case 4:
+           result = tiparm_s(4, mask, NS_4(format));
+           break;
+       case 5:
+           result = tiparm_s(5, mask, NS_5(format));
+           break;
+       case 6:
+           result = tiparm_s(6, mask, NS_6(format));
+           break;
+       case 7:
+           result = tiparm_s(7, mask, NS_7(format));
+           break;
+       case 8:
+           result = tiparm_s(8, mask, NS_8(format));
+           break;
+       case 9:
+           result = tiparm_s(9, mask, NS_9(format));
+           break;
+       }
+    } else
+#endif
+#if HAVE_TIPARM
+    if (i_opt) {
+       switch (nparam) {
+       case 0:
+           result = tiparm(NS_0(format));
+           break;
+       case 1:
+           result = tiparm(NS_1(format));
+           break;
+       case 2:
+           result = tiparm(NS_2(format));
+           break;
+       case 3:
+           result = tiparm(NS_3(format));
+           break;
+       case 4:
+           result = tiparm(NS_4(format));
+           break;
+       case 5:
+           result = tiparm(NS_5(format));
+           break;
+       case 6:
+           result = tiparm(NS_6(format));
+           break;
+       case 7:
+           result = tiparm(NS_7(format));
+           break;
+       case 8:
+           result = tiparm(NS_8(format));
+           break;
+       case 9:
+           result = tiparm(NS_9(format));
+           break;
+       }
+    } else
+#endif
+       result = tiparm(NS_9(format));
     total_tests++;
     if (result != NULL) {
        tputs(result, 1, output_func);
@@ -253,8 +359,14 @@ usage(int ok)
        ,"          to read a list from standard-input"
        ," -a       test all combinations of parameters"
        ,"          [value1...] forms a vector of maximum parameter-values."
+#if HAVE_TIPARM
+       ," -i       test tiparm rather than tparm"
+#endif
        ," -p       test capabilities with no parameters but having padding"
        ," -r NUM   repeat tests NUM times"
+#if HAVE_TIPARM_S
+       ," -s       test tiparm_s rather than tparm"
+#endif
        ," -v       show values and results"
     };
     unsigned n;
@@ -294,6 +406,8 @@ main(int argc, char *argv[])
     char **all_terms = typeCalloc(char *, max_terms);
 
     int use_caps;
+    int max_name = 10;         /* max # of items in cap_name[] */
+    int max_data = 10;         /* max # of items in cap_data[] */
     char **cap_name;
     char **cap_data;
 
@@ -306,7 +420,7 @@ main(int argc, char *argv[])
     if (all_caps == 0 || all_terms == 0 || num_parms == 0 || str_parms == 0)
        failed("no memory");
 
-    while ((ch = getopt(argc, argv, OPTS_COMMON "T:apr:v")) != -1) {
+    while ((ch = getopt(argc, argv, OPTS_COMMON "T:aipr:sv")) != -1) {
        switch (ch) {
        case 'T':
            t_opt = optarg;
@@ -314,12 +428,22 @@ main(int argc, char *argv[])
        case 'a':
            ++a_opt;
            break;
+#if HAVE_TIPARM
+       case 'i':
+           ++i_opt;
+           break;
+#endif
        case 'p':
            ++p_opt;
            break;
        case 'r':
            r_opt = atoi(optarg);
            break;
+#if HAVE_TIPARM_S
+       case 's':
+           ++s_opt;
+           break;
+#endif
        case 'v':
            ++v_opt;
            break;
@@ -451,8 +575,8 @@ main(int argc, char *argv[])
        }
     }
 
-    cap_name = typeMalloc(char *, 1 + len_caps);
-    cap_data = typeMalloc(char *, 1 + len_caps);
+    cap_name = typeMalloc(char *, (max_name = 1 + len_caps));
+    cap_data = typeMalloc(char *, (max_data = 1 + len_caps));
 
     if (r_opt <= 0)
        r_opt = 1;
@@ -476,6 +600,8 @@ main(int argc, char *argv[])
                TERMTYPE *term = (TERMTYPE *) cur_term;
                for (n = STRCOUNT; n < NUM_STRINGS(term); ++n) {
                    GrowArray(all_caps, max_caps, len_caps);
+                   GrowArray(cap_name, max_name, len_caps);
+                   GrowArray(cap_data, max_data, len_caps);
                    all_caps[len_caps++] = strdup(ExtStrname(term, (int) n, strnames));
                }
            }