From e7e07cb067c5e6ebda4d9d60ad2d27fc0cb515b7 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 31 Dec 2020 14:49:21 -0800 Subject: [PATCH] pull request #411 - freeing termcap hilite entries (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 | 206 ++++++++++++++++++++++++++++++---------------- 1 file changed, 134 insertions(+), 72 deletions(-) diff --git a/win/tty/termcap.c b/win/tty/termcap.c index d13eca893..7f40e730e 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -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[] = ""; -- 2.50.1