]> granicus.if.org Git - nethack/commitdiff
pull request #411 - freeing termcap hilite entries
authorPatR <rankin@nethack.org>
Thu, 31 Dec 2020 22:49:21 +0000 (14:49 -0800)
committerPatR <rankin@nethack.org>
Thu, 31 Dec 2020 22:49:21 +0000 (14:49 -0800)
(strings to switch color) for ANSI_DEFAULT.  Instead of lumping
more conditional code into tty_shutdown() I put the new code
into a separate routine and also pulled the existing setup code
out of tty_startup() into a separate routine too.

It will be a miracle if this doesn't break anything due to the
crazy amount of convoluted conditionals present in termcap.c.

On the other hand, I found and fixed a bug while trying to test.
The ANSI_DEFAULT hilites for Gray and No_Color were null instead
of an empty string.  MS-DOS stdio apparently fixes that up, but
on OSX (after #undef UNIX and TERMLIB and TERMINFO and #define
ANSI_DEFAULT in termcap.c) I started seeing instances of "(null)"
on the map (OSX stdio does a different fix up for Null pointers)
as soon as I enabled 'color'.  It was an attempt to set No_Color.

Closes #411

win/tty/termcap.c

index d13eca893b9d1f7535df72aae4c9297391f9bc9e..7f40e730ea77ddf85092cd5b67af1d9636a4edab 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 termcap.c       $NHDT-Date: 1596498343 2020/08/03 23:45:43 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ */
+/* NetHack 3.7 termcap.c       $NHDT-Date: 1609454952 2020/12/31 22:49:12 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Pasi Kallinen, 2018. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -18,11 +18,11 @@ static char *FDECL(e_atr2str, (int));
 void FDECL(cmov, (int, int));
 void FDECL(nocmov, (int, int));
 #if defined(TEXTCOLOR) && defined(TERMLIB)
-#if !defined(UNIX) || !defined(TERMINFO)
-#ifndef TOS
+#if (!defined(UNIX) || !defined(TERMINFO)) && !defined(TOS)
 static void FDECL(analyze_seq, (char *, int *, int *));
 #endif
 #endif
+#if defined(TEXTCOLOR) && (defined(TERMLIB) || defined(ANSI_DEFAULT))
 static void NDECL(init_hilite);
 static void NDECL(kill_hilite);
 #endif
@@ -69,11 +69,11 @@ void
 tty_startup(wid, hgt)
 int *wid, *hgt;
 {
-    register int i;
 #ifdef TERMLIB
     register const char *term;
     register char *tptr;
     char *tbufptr, *pc;
+    int i;
 
 #ifdef VMS
     term = verify_termcap();
@@ -86,7 +86,7 @@ int *wid, *hgt;
         term = "builtin"; /* library has a default */
 #endif
     if (!term)
-#endif
+#endif /* TERMLIB */
 #ifndef ANSI_DEFAULT
         error("Can't get TERM.");
 #else
@@ -95,21 +95,26 @@ int *wid, *hgt;
         CO = 80;
         LI = 25;
         TI = VS = VE = TE = nullstr;
-        HO = "\033H";
-        CE = "\033K"; /* the VT52 termcap */
-        UP = "\033A";
-        nh_CM = "\033Y%c%c"; /* used with function tgoto() */
-        nh_ND = "\033C";
-        XD = "\033B";
-        BC = "\033D";
-        SO = "\033p";
-        SE = "\033q";
+        /*
+         * FIXME:  These variables ought to be declared 'const' (instead
+         * of using nhStr() to cast away const) to avoid '-Wwrite-sttings'
+         * warnings about assigning string literals to them.
+         */
+        HO = nhStr("\033H");
+        CE = nhStr("\033K"); /* the VT52 termcap */
+        UP = nhStr("\033A");
+        nh_CM = nhStr("\033Y%c%c"); /* used with function tgoto() */
+        nh_ND = nhStr("\033C");
+        XD = nhStr("\033B");
+        BC = nhStr("\033D");
+        SO = nhStr("\033p");
+        SE = nhStr("\033q");
         /* HI and HE will be updated in init_hilite if we're using color */
-        nh_HI = "\033p";
-        nh_HE = "\033q";
+        nh_HI = nhStr("\033p");
+        nh_HE = nhStr("\033q");
         *wid = CO;
         *hgt = LI;
-        CL = "\033E"; /* last thing set */
+        CL = nhStr("\033E"); /* last thing set */
         return;
     }
 #else /* TOS */
@@ -121,54 +126,40 @@ int *wid, *hgt;
             setclipped();
 #endif
 #endif
-        HO = "\033[H";
-        /*              nh_CD = "\033[J"; */
-        CE = "\033[K"; /* the ANSI termcap */
+        HO = nhStr("\033[H");
+        /*              nh_CD = nhStr("\033[J"); */
+        CE = nhStr("\033[K"); /* the ANSI termcap */
 #ifndef TERMLIB
-        nh_CM = "\033[%d;%dH";
+        nh_CM = nhStr("\033[%d;%dH");
 #else
-        nh_CM = "\033[%i%d;%dH";
+        nh_CM = nhStr("\033[%i%d;%dH");
 #endif
-        UP = "\033[A";
-        nh_ND = "\033[C";
-        XD = "\033[B";
+        UP = nhStr("\033[A");
+        nh_ND = nhStr("\033[C");
+        XD = nhStr("\033[B");
 #ifdef MICRO /* backspaces are non-destructive */
-        BC = "\b";
+        BC = nhStr("\b");
 #else
-        BC = "\033[D";
+        BC = nhStr("\033[D");
 #endif
-        nh_HI = SO = "\033[1m";
-        nh_US = "\033[4m";
-        MR = "\033[7m";
-        TI = nh_HE = ME = SE = nh_UE = "\033[0m";
+        nh_HI = SO = nhStr("\033[1m");
+        nh_US = nhStr("\033[4m");
+        MR = nhStr("\033[7m");
+        TI = nh_HE = ME = SE = nh_UE = nhStr("\033[0m");
         /* strictly, SE should be 2, and nh_UE should be 24,
            but we can't trust all ANSI emulators to be
            that complete.  -3. */
 #ifndef MICRO
-        AS = "\016";
-        AE = "\017";
+        AS = nhStr("\016");
+        AE = nhStr("\017");
 #endif
         TE = VS = VE = nullstr;
 #ifdef TEXTCOLOR
-        for (i = 0; i < CLR_MAX / 2; i++)
-            if (i != CLR_BLACK) {
-                hilites[i | BRIGHT] = (char *) alloc(sizeof("\033[1;3%dm"));
-                Sprintf(hilites[i | BRIGHT], "\033[1;3%dm", i);
-                if (i != CLR_GRAY)
-#ifdef MICRO
-                    if (i == CLR_BLUE)
-                        hilites[CLR_BLUE] = hilites[CLR_BLUE | BRIGHT];
-                    else
-#endif
-                    {
-                        hilites[i] = (char *) alloc(sizeof("\033[0;3%dm"));
-                        Sprintf(hilites[i], "\033[0;3%dm", i);
-                    }
-            }
+        init_hilite();
 #endif /* TEXTCOLOR */
         *wid = CO;
         *hgt = LI;
-        CL = "\033[2J"; /* last thing set */
+        CL = nhStr("\033[2J"); /* last thing set */
         return;
     }
 #endif /* TOS */
@@ -322,10 +313,10 @@ void
 tty_shutdown()
 {
     /* we only attempt to clean up a few individual termcap variables */
-#ifdef TERMLIB
-#ifdef TEXTCOLOR
+#if defined(TEXTCOLOR) && (defined(TERMLIB) || defined(ANSI_DEFAULT))
     kill_hilite();
 #endif
+#ifdef TERMLIB
     if (dynamic_HIHE) {
         free((genericptr_t) nh_HI), nh_HI = (char *) 0;
         free((genericptr_t) nh_HE), nh_HE = (char *) 0;
@@ -956,24 +947,40 @@ kill_hilite()
     if (hilites[CLR_BLACK] == nh_HI)
         return;
 
-    if (hilites[CLR_BLACK] != hilites[CLR_BLUE])
-        free(hilites[CLR_BLACK]);
-
+    if (hilites[CLR_BLACK]) {
+        if (hilites[CLR_BLACK] != hilites[CLR_BLUE])
+            free(hilites[CLR_BLACK]);
+        hilites[CLR_BLACK] = 0;
+    }
     /* CLR_BLUE overlaps CLR_BRIGHT_BLUE, do not free */
     /* CLR_GREEN overlaps CLR_BRIGHT_GREEN, do not free */
     /* CLR_CYAN overlaps CLR_BRIGHT_CYAN, do not free */
-    /* CLR_RED overlaps CLR_ORANGE, do not free */
     /* CLR_MAGENTA overlaps CLR_BRIGHT_MAGENTA, do not free */
+    /* CLR_RED overlaps CLR_ORANGE, do not free */
     /* CLR_BROWN overlaps CLR_YELLOW, do not free */
     /* CLR_GRAY is static 'nilstring', do not free */
     /* NO_COLOR is static 'nilstring', do not free */
-    free(hilites[CLR_BRIGHT_BLUE]);
-    free(hilites[CLR_BRIGHT_GREEN]);
-    free(hilites[CLR_BRIGHT_CYAN]);
-    free(hilites[CLR_YELLOW]);
-    free(hilites[CLR_ORANGE]);
-    free(hilites[CLR_BRIGHT_MAGENTA]);
-    free(hilites[CLR_WHITE]);
+    if (hilites[CLR_BRIGHT_BLUE])
+        free(hilites[CLR_BRIGHT_BLUE]),
+            hilites[CLR_BRIGHT_BLUE] = hilites[CLR_BLUE] = 0;
+    if (hilites[CLR_BRIGHT_GREEN])
+        free(hilites[CLR_BRIGHT_GREEN]),
+            hilites[CLR_BRIGHT_GREEN] = hilites[CLR_GREEN] = 0;
+    if (hilites[CLR_BRIGHT_CYAN])
+        free(hilites[CLR_BRIGHT_CYAN]),
+            hilites[CLR_BRIGHT_CYAN] = hilites[CLR_CYAN] = 0;
+    if (hilites[CLR_BRIGHT_MAGENTA])
+        free(hilites[CLR_BRIGHT_MAGENTA]),
+            hilites[CLR_BRIGHT_MAGENTA] = hilites[CLR_MAGENTA] = 0;
+    if (hilites[CLR_ORANGE])
+        free(hilites[CLR_ORANGE]),
+            hilites[CLR_ORANGE] = hilites[CLR_RED] = 0;
+    if (hilites[CLR_YELLOW])
+        free(hilites[CLR_YELLOW]),
+            hilites[CLR_YELLOW] = hilites[CLR_BROWN] = 0;
+    if (hilites[CLR_WHITE])
+        free(hilites[CLR_WHITE]), hilites[CLR_WHITE] = 0;
+    hilites[CLR_GRAY] = hilites[NO_COLOR] = 0;
 }
 
 #else /* UNIX && TERMINFO */
@@ -1071,17 +1078,17 @@ init_hilite()
     }
 
     if (tos_numcolors == 4) {
-        TI = "\033b0\033c3\033E\033e";
-        TE = "\033b3\033c0\033J";
+        TI = nhStr("\033b0\033c3\033E\033e");
+        TE = nhStr("\033b3\033c0\033J");
         nh_HE = COLHE;
         hilites[CLR_GREEN] = hilites[CLR_GREEN | BRIGHT] = "\033b2";
         hilites[CLR_RED] = hilites[CLR_RED | BRIGHT] = "\033b1";
     } else {
-        sprintf(hilites[CLR_BROWN], "\033b%c", (CLR_BROWN ^ BRIGHT) + '0');
-        sprintf(hilites[CLR_GREEN], "\033b%c", (CLR_GREEN ^ BRIGHT) + '0');
+        Sprintf(hilites[CLR_BROWN], "\033b%c", (CLR_BROWN ^ BRIGHT) + '0');
+        Sprintf(hilites[CLR_GREEN], "\033b%c", (CLR_GREEN ^ BRIGHT) + '0');
 
-        TI = "\033b0\033c\017\033E\033e";
-        TE = "\033b\017\033c0\033J";
+        TI = nhStr("\033b0\033c\017\033E\033e");
+        TE = nhStr("\033b\017\033c0\033J");
         nh_HE = COLHE;
         hilites[CLR_WHITE] = hilites[CLR_BLACK] = NOCOL;
         hilites[NO_COLOR] = hilites[CLR_GRAY];
@@ -1134,16 +1141,71 @@ kill_hilite()
     for (c = 0; c < CLR_MAX / 2; c++) {
         if (hilites[c | BRIGHT] == hilites[c])
             hilites[c | BRIGHT] = 0;
-        if (hilites[c] && (hilites[c] != nh_HI))
+        if (hilites[c] && hilites[c] != nh_HI)
             free((genericptr_t) hilites[c]), hilites[c] = 0;
-        if (hilites[c | BRIGHT] && (hilites[c | BRIGHT] != nh_HI))
+        if (hilites[c | BRIGHT] && hilites[c | BRIGHT] != nh_HI)
             free((genericptr_t) hilites[c | BRIGHT]), hilites[c | BRIGHT] = 0;
     }
 #endif
     return;
 }
-#endif /* UNIX */
-#endif /* TEXTCOLOR */
+#endif /* UNIX && TERMINFO */
+#endif /* TEXTCOLOR && TERMLIB */
+
+#if defined(TEXTCOLOR) && !defined(TERMLIB) && defined(ANSI_DEFAULT)
+static char adef_nilstring[] = "";
+
+static void
+init_hilite()
+{
+    register int c;
+
+    if (!hilites[CLR_GRAY])
+        hilites[CLR_GRAY] = adef_nilstring;
+    if (!hilites[NO_COLOR])
+        hilites[NO_COLOR] = hilites[CLR_GRAY];
+
+    for (c = 0; c < CLR_MAX / 2; c++) {
+        if (c == CLR_BLACK)
+            continue;
+        hilites[c | BRIGHT] = (char *) alloc(sizeof "\033[1;3%dm");
+        Sprintf(hilites[c | BRIGHT], "\033[1;3%dm", c);
+        if (c == CLR_GRAY)
+            continue;
+#ifdef MICRO
+        if (c == CLR_BLUE) {
+            hilites[CLR_BLUE] = hilites[CLR_BLUE | BRIGHT];
+        } else
+#endif
+        {
+            hilites[c] = (char *) alloc(sizeof "\033[0;3%dm");
+            Sprintf(hilites[c], "\033[0;3%dm", c);
+        }
+    }
+}
+
+static void
+kill_hilite()
+{
+    register int c;
+
+    for (c = 0; c < CLR_MAX / 2; c++) {
+        if (c == CLR_BLACK)
+            continue;
+        if (c == CLR_GRAY || hilites[c] == adef_nilstring)
+            hilites[c] = 0;
+        if (hilites[c | BRIGHT] == adef_nilstring)
+            hilites[c] = 0;
+        if (hilites[c | BRIGHT] == hilites[c]) /* for blue */
+            hilites[c | BRIGHT] = 0;
+        if (hilites[c] && hilites[c] != nh_HI)
+            free((genericptr_t) hilites[c]), hilites[c] = 0;
+        if (hilites[c | BRIGHT] && hilites[c | BRIGHT] != nh_HI)
+            free((genericptr_t) hilites[c | BRIGHT]), hilites[c | BRIGHT] = 0;
+    }
+    return;
+}
+#endif /* TEXTCOLOR && !TERMLIB && ANSI_DEFAULT */
 
 static char nulstr[] = "";