ncurses 6.2 - patch 20200606
[ncurses.git] / progs / tic.c
index e0dab0706e98b09862d6e62d1f0cab4cd411bb44..ae172ece9fc93f4f17617f3a381cbb5f8e818592 100644 (file)
@@ -1,5 +1,6 @@
 /****************************************************************************
- * Copyright (c) 1998-2018,2019 Free Software Foundation, Inc.              *
+ * Copyright 2018-2019,2020 Thomas E. Dickey                                *
+ * Copyright 1998-2017,2018 Free Software Foundation, Inc.                  *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
@@ -48,7 +49,7 @@
 #include <parametrized.h>
 #include <transform.h>
 
-MODULE_ID("$Id: tic.c,v 1.275 2019/05/04 14:41:06 tom Exp $")
+MODULE_ID("$Id: tic.c,v 1.286 2020/05/31 21:05:44 tom Exp $")
 
 #define STDIN_NAME "<stdin>"
 
@@ -218,7 +219,8 @@ write_it(ENTRY * ep)
            while ((ch = *t++) != 0) {
                *d++ = (char) ch;
                if (ch == '\\') {
-                   *d++ = *t++;
+                   if ((*d++ = *t++) == '\0')
+                       break;
                } else if ((ch == '%')
                           && (*t == L_BRACE)) {
                    char *v = 0;
@@ -1024,10 +1026,14 @@ main(int argc, char *argv[])
                    if (!quiet) {
                        (void) fseek(tmp_fp, qp->cstart, SEEK_SET);
                        while (j-- > 0) {
-                           if (infodump)
-                               (void) putchar(fgetc(tmp_fp));
-                           else
-                               put_translate(fgetc(tmp_fp));
+                           int ch = fgetc(tmp_fp);
+                           if (ch == EOF || ferror(tmp_fp)) {
+                               break;
+                           } else if (infodump) {
+                               (void) putchar(ch);
+                           } else {
+                               put_translate(ch);
+                           }
                        }
                    }
 
@@ -1173,6 +1179,14 @@ check_acs(TERMTYPE2 *tp)
     }
 }
 
+static char *
+safe_strdup(const char *value)
+{
+    if (value == NULL)
+       value = "";
+    return strdup(value);
+}
+
 static bool
 same_color(NCURSES_CONST char *oldcap, NCURSES_CONST char *newcap, int limit)
 {
@@ -1183,8 +1197,8 @@ same_color(NCURSES_CONST char *oldcap, NCURSES_CONST char *newcap, int limit)
        int n;
        int same;
        for (n = same = 0; n < limit; ++n) {
-           char *oldvalue = strdup(TPARM_1(oldcap, n));
-           char *newvalue = strdup(TPARM_1(newcap, n));
+           char *oldvalue = safe_strdup(TIPARM_1(oldcap, n));
+           char *newvalue = safe_strdup(TIPARM_1(newcap, n));
            same += !strcmp(oldvalue, newvalue);
            free(oldvalue);
            free(newvalue);
@@ -1829,7 +1843,6 @@ expected_params(const char *name)
        DATA( "wingo",          1 ),
     };
     /* *INDENT-ON* */
-
 #undef DATA
 
     unsigned n;
@@ -1904,7 +1917,7 @@ check_params(TERMTYPE2 *tp, const char *name, char *value, int extended)
     int expected = expected_params(name);
     int actual = 0;
     int n;
-    bool params[NUM_PARM];
+    bool params[1 + NUM_PARM];
     char *s = value;
 
 #ifdef set_top_margin_parm
@@ -1913,7 +1926,7 @@ check_params(TERMTYPE2 *tp, const char *name, char *value, int extended)
        expected = 2;
 #endif
 
-    for (n = 0; n < NUM_PARM; n++)
+    for (n = 0; n <= NUM_PARM; n++)
        params[n] = FALSE;
 
     while (*s != 0) {
@@ -1939,7 +1952,7 @@ check_params(TERMTYPE2 *tp, const char *name, char *value, int extended)
 #if NCURSES_XNAMES
     if (extended) {
        int check = is_user_capability(name);
-       if (check != actual) {
+       if (check != actual && (check >= 0 && actual >= 0)) {
            _nc_warning("extended %s capability has %d parameters, expected %d",
                        name, actual, check);
        } else if (debug_level > 1) {
@@ -2186,6 +2199,19 @@ check_1_infotocap(const char *name, NCURSES_CONST char *value, int count)
        result = TPARM_3(value, numbers[1], strings[2], strings[3]);
        break;
     case Numbers:
+#define myParam(n) numbers[n]
+       result = TIPARM_9(value,
+                         myParam(1),
+                         myParam(2),
+                         myParam(3),
+                         myParam(4),
+                         myParam(5),
+                         myParam(6),
+                         myParam(7),
+                         myParam(8),
+                         myParam(9));
+#undef myParam
+       break;
     default:
        (void) _nc_tparm_analyze(value, p_is_s, &ignored);
 #define myParam(n) (p_is_s[n - 1] != 0 ? ((TPARM_ARG) strings[n]) : numbers[n])
@@ -2199,6 +2225,7 @@ check_1_infotocap(const char *name, NCURSES_CONST char *value, int count)
                         myParam(7),
                         myParam(8),
                         myParam(9));
+#undef myParam
        break;
     }
     return strdup(result);
@@ -2509,16 +2536,16 @@ check_sgr(TERMTYPE2 *tp, char *zero, int num, char *cap, const char *name)
     char *test;
 
     _nc_tparm_err = 0;
-    test = TPARM_9(set_attributes,
-                  num == 1,
-                  num == 2,
-                  num == 3,
-                  num == 4,
-                  num == 5,
-                  num == 6,
-                  num == 7,
-                  num == 8,
-                  num == 9);
+    test = TIPARM_9(set_attributes,
+                   num == 1,
+                   num == 2,
+                   num == 3,
+                   num == 4,
+                   num == 5,
+                   num == 6,
+                   num == 7,
+                   num == 8,
+                   num == 9);
     if (test != 0) {
        if (PRESENT(cap)) {
            if (!similar_sgr(num, test, cap)) {
@@ -2689,7 +2716,6 @@ check_conflict(TERMTYPE2 *tp)
                { NULL,   NULL },
            };
            /* *INDENT-ON* */
-
            /*
             * SVr4 curses defines the "xcurses" names listed above except for
             * the special cases in the "shifted" column.  When using these
@@ -2930,6 +2956,12 @@ check_termtype(TERMTYPE2 *tp, bool literal)
     check_printer(tp);
     check_screen(tp);
 
+    /*
+     * These are probably both or none.
+     */
+    PAIRED(parm_index, parm_rindex);
+    PAIRED(parm_ich, parm_dch);
+
     /*
      * These may be mismatched because the terminal description relies on
      * restoring the cursor visibility by resetting it.
@@ -2961,7 +2993,7 @@ check_termtype(TERMTYPE2 *tp, bool literal)
        if (PRESENT(exit_attribute_mode)) {
            zero = strdup(CHECK_SGR(0, exit_attribute_mode));
        } else {
-           zero = strdup(TPARM_9(set_attributes, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+           zero = strdup(TIPARM_9(set_attributes, 0, 0, 0, 0, 0, 0, 0, 0, 0));
        }
        if (_nc_tparm_err)
            _nc_warning("stack error in sgr(0) string");
@@ -3045,7 +3077,7 @@ check_termtype(TERMTYPE2 *tp, bool literal)
      * ncurses handles it.
      */
     if ((PRESENT(enter_insert_mode) || PRESENT(exit_insert_mode))
-       && PRESENT(parm_ich)) {
+       && PRESENT(insert_character)) {
        _nc_warning("non-curses applications may be confused by ich1 with smir/rmir");
     }