xref: /freebsd/contrib/ncurses/ncurses/tinfo/lib_termcap.c (revision 21817992b3314c908ab50f0bb88d2ee750b9c4ac)
10e3d5408SPeter Wemm /****************************************************************************
2*21817992SBaptiste Daroussin  * Copyright 2018-2020,2023 Thomas E. Dickey                                *
3e1865124SBaptiste Daroussin  * Copyright 1998-2016,2017 Free Software Foundation, Inc.                  *
40e3d5408SPeter Wemm  *                                                                          *
50e3d5408SPeter Wemm  * Permission is hereby granted, free of charge, to any person obtaining a  *
60e3d5408SPeter Wemm  * copy of this software and associated documentation files (the            *
70e3d5408SPeter Wemm  * "Software"), to deal in the Software without restriction, including      *
80e3d5408SPeter Wemm  * without limitation the rights to use, copy, modify, merge, publish,      *
90e3d5408SPeter Wemm  * distribute, distribute with modifications, sublicense, and/or sell       *
100e3d5408SPeter Wemm  * copies of the Software, and to permit persons to whom the Software is    *
110e3d5408SPeter Wemm  * furnished to do so, subject to the following conditions:                 *
120e3d5408SPeter Wemm  *                                                                          *
130e3d5408SPeter Wemm  * The above copyright notice and this permission notice shall be included  *
140e3d5408SPeter Wemm  * in all copies or substantial portions of the Software.                   *
150e3d5408SPeter Wemm  *                                                                          *
160e3d5408SPeter Wemm  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
170e3d5408SPeter Wemm  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
180e3d5408SPeter Wemm  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
190e3d5408SPeter Wemm  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
200e3d5408SPeter Wemm  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
210e3d5408SPeter Wemm  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
220e3d5408SPeter Wemm  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
230e3d5408SPeter Wemm  *                                                                          *
240e3d5408SPeter Wemm  * Except as contained in this notice, the name(s) of the above copyright   *
250e3d5408SPeter Wemm  * holders shall not be used in advertising or otherwise to promote the     *
260e3d5408SPeter Wemm  * sale, use or other dealings in this Software without prior written       *
270e3d5408SPeter Wemm  * authorization.                                                           *
280e3d5408SPeter Wemm  ****************************************************************************/
290e3d5408SPeter Wemm 
300e3d5408SPeter Wemm /****************************************************************************
310e3d5408SPeter Wemm  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
320e3d5408SPeter Wemm  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
337d0e8efaSRong-En Fan  *     and: Thomas E. Dickey                        1996-on                 *
3406bfebdeSXin LI  *     and: Juergen Pfeifer                                                 *
35a17d2cb2SPeter Wemm  *                                                                          *
36a17d2cb2SPeter Wemm  * some of the code in here was contributed by:                             *
37a17d2cb2SPeter Wemm  * Magnus Bengtsson, d6mbeng@dtek.chalmers.se (Nov'93)                      *
387d0e8efaSRong-En Fan  * (but it has changed a lot)                                               *
390e3d5408SPeter Wemm  ****************************************************************************/
400e3d5408SPeter Wemm 
415bd21f8aSPeter Wemm /* $FreeBSD$ */
425bd21f8aSPeter Wemm 
43d91c14deSPeter Wemm #define __INTERNAL_CAPS_VISIBLE
440e3d5408SPeter Wemm #include <curses.priv.h>
450e3d5408SPeter Wemm 
460e3d5408SPeter Wemm #include <termcap.h>
470e3d5408SPeter Wemm #include <tic.h>
48a17d2cb2SPeter Wemm #include <ctype.h>
490e3d5408SPeter Wemm 
5006bfebdeSXin LI #ifndef CUR
5106bfebdeSXin LI #define CUR SP_TERMTYPE
5206bfebdeSXin LI #endif
530e3d5408SPeter Wemm 
54*21817992SBaptiste Daroussin MODULE_ID("$Id: lib_termcap.c,v 1.89 2023/05/27 20:13:10 tom Exp $")
550e3d5408SPeter Wemm 
56a17d2cb2SPeter Wemm NCURSES_EXPORT_VAR(char *) UP = 0;
57a17d2cb2SPeter Wemm NCURSES_EXPORT_VAR(char *) BC = 0;
580e3d5408SPeter Wemm 
59c8b9c85eSPeter Wemm #ifdef FREEBSD_NATIVE
60c8b9c85eSPeter Wemm extern char _nc_termcap[];	/* buffer to copy out */
61c8b9c85eSPeter Wemm #endif
62c8b9c85eSPeter Wemm 
634454585cSRong-En Fan #define MyCache  _nc_globals.tgetent_cache
644454585cSRong-En Fan #define CacheInx _nc_globals.tgetent_index
654454585cSRong-En Fan #define CacheSeq _nc_globals.tgetent_sequence
66a17d2cb2SPeter Wemm 
674454585cSRong-En Fan #define FIX_SGR0 MyCache[CacheInx].fix_sgr0
684454585cSRong-En Fan #define LAST_TRM MyCache[CacheInx].last_term
694454585cSRong-En Fan #define LAST_BUF MyCache[CacheInx].last_bufp
704454585cSRong-En Fan #define LAST_USE MyCache[CacheInx].last_used
714454585cSRong-En Fan #define LAST_SEQ MyCache[CacheInx].sequence
72a17d2cb2SPeter Wemm 
7373f0a83dSXin LI /*
7473f0a83dSXin LI  * Termcap names are matched only using the first two bytes.
7573f0a83dSXin LI  * Ignore any extended names longer than two bytes, to avoid problems
7673f0a83dSXin LI  * with legacy code which passes in parameters whose use is long forgotten.
7773f0a83dSXin LI  */
7873f0a83dSXin LI #define ValidCap(cap) (((cap)[0] != '\0') && ((cap)[1] != '\0'))
7973f0a83dSXin LI #define SameCap(a,b)  (((a)[0] == (b)[0]) && ((a)[1] == (b)[1]))
8073f0a83dSXin LI #define ValidExt(ext) (ValidCap(ext) && (ext)[2] == '\0')
8173f0a83dSXin LI 
820e3d5408SPeter Wemm /***************************************************************************
830e3d5408SPeter Wemm  *
840e3d5408SPeter Wemm  * tgetent(bufp, term)
850e3d5408SPeter Wemm  *
860e3d5408SPeter Wemm  * In termcap, this function reads in the entry for terminal `term' into the
870e3d5408SPeter Wemm  * buffer pointed to by bufp. It must be called before any of the functions
880e3d5408SPeter Wemm  * below are called.
890e3d5408SPeter Wemm  * In this terminfo emulation, tgetent() simply calls setupterm() (which
900e3d5408SPeter Wemm  * does a bit more than tgetent() in termcap does), and returns its return
910e3d5408SPeter Wemm  * value (1 if successful, 0 if no terminal with the given name could be
920e3d5408SPeter Wemm  * found, or -1 if no terminal descriptions have been installed on the
930e3d5408SPeter Wemm  * system).  The bufp argument is ignored.
940e3d5408SPeter Wemm  *
950e3d5408SPeter Wemm  ***************************************************************************/
960e3d5408SPeter Wemm 
97952abd2aSPeter Wemm NCURSES_EXPORT(int)
NCURSES_SP_NAME(tgetent)9806bfebdeSXin LI NCURSES_SP_NAME(tgetent) (NCURSES_SP_DCLx char *bufp, const char *name)
990e3d5408SPeter Wemm {
10006bfebdeSXin LI     int rc = ERR;
1017d0e8efaSRong-En Fan     int n;
1027d0e8efaSRong-En Fan     bool found_cache = FALSE;
10306bfebdeSXin LI #ifdef USE_TERM_DRIVER
10406bfebdeSXin LI     TERMINAL *termp = 0;
10506bfebdeSXin LI #endif
1067d0e8efaSRong-En Fan 
1077d0e8efaSRong-En Fan     START_TRACE();
1080e3d5408SPeter Wemm     T((T_CALLED("tgetent()")));
1090e3d5408SPeter Wemm 
110aae38d10SBaptiste Daroussin     TINFO_SETUP_TERM(&termp, name, STDOUT_FILENO, &rc, TRUE);
11106bfebdeSXin LI 
11206bfebdeSXin LI #ifdef USE_TERM_DRIVER
11306bfebdeSXin LI     if (termp == 0 ||
11406bfebdeSXin LI 	!((TERMINAL_CONTROL_BLOCK *) termp)->drv->isTerminfo)
11573f0a83dSXin LI 	returnCode(rc);
11606bfebdeSXin LI #endif
1177d0e8efaSRong-En Fan 
1187d0e8efaSRong-En Fan     /*
1197d0e8efaSRong-En Fan      * In general we cannot tell if the fixed sgr0 is still used by the
1207d0e8efaSRong-En Fan      * caller, but if tgetent() is called with the same buffer, that is
1217d0e8efaSRong-En Fan      * good enough, since the previous data would be invalidated by the
1227d0e8efaSRong-En Fan      * current call.
1234454585cSRong-En Fan      *
1244454585cSRong-En Fan      * bufp may be a null pointer, e.g., GNU termcap.  That allocates data,
1254454585cSRong-En Fan      * which is good until the next tgetent() call.  The conventional termcap
1264454585cSRong-En Fan      * is inconvenient because of the fixed buffer size, but because it uses
1274454585cSRong-En Fan      * caller-supplied buffers, can have multiple terminal descriptions in
1284454585cSRong-En Fan      * use at a given time.
1297d0e8efaSRong-En Fan      */
1304454585cSRong-En Fan     for (n = 0; n < TGETENT_MAX; ++n) {
1314454585cSRong-En Fan 	bool same_result = (MyCache[n].last_used && MyCache[n].last_bufp == bufp);
1327d0e8efaSRong-En Fan 	if (same_result) {
1334454585cSRong-En Fan 	    CacheInx = n;
1347d0e8efaSRong-En Fan 	    if (FIX_SGR0 != 0) {
1357d0e8efaSRong-En Fan 		FreeAndNull(FIX_SGR0);
1367d0e8efaSRong-En Fan 	    }
1377d0e8efaSRong-En Fan 	    /*
1387d0e8efaSRong-En Fan 	     * Also free the terminfo data that we loaded (much bigger leak).
1397d0e8efaSRong-En Fan 	     */
14006bfebdeSXin LI 	    if (LAST_TRM != 0 && LAST_TRM != TerminalOf(SP_PARM)) {
1417d0e8efaSRong-En Fan 		TERMINAL *trm = LAST_TRM;
14206bfebdeSXin LI 		NCURSES_SP_NAME(del_curterm) (NCURSES_SP_ARGx LAST_TRM);
1434454585cSRong-En Fan 		for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx)
1447d0e8efaSRong-En Fan 		    if (LAST_TRM == trm)
1457d0e8efaSRong-En Fan 			LAST_TRM = 0;
1464454585cSRong-En Fan 		CacheInx = n;
1477d0e8efaSRong-En Fan 	    }
1487d0e8efaSRong-En Fan 	    found_cache = TRUE;
1497d0e8efaSRong-En Fan 	    break;
1507d0e8efaSRong-En Fan 	}
1517d0e8efaSRong-En Fan     }
1527d0e8efaSRong-En Fan     if (!found_cache) {
1537d0e8efaSRong-En Fan 	int best = 0;
1547d0e8efaSRong-En Fan 
1554454585cSRong-En Fan 	for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) {
1564454585cSRong-En Fan 	    if (LAST_SEQ < MyCache[best].sequence) {
1574454585cSRong-En Fan 		best = CacheInx;
1587d0e8efaSRong-En Fan 	    }
1597d0e8efaSRong-En Fan 	}
1604454585cSRong-En Fan 	CacheInx = best;
1617d0e8efaSRong-En Fan     }
162aae38d10SBaptiste Daroussin     if (rc == 1) {
16306bfebdeSXin LI 	LAST_TRM = TerminalOf(SP_PARM);
1644454585cSRong-En Fan 	LAST_SEQ = ++CacheSeq;
165aae38d10SBaptiste Daroussin     } else {
166aae38d10SBaptiste Daroussin 	LAST_TRM = 0;
167aae38d10SBaptiste Daroussin     }
1680e3d5408SPeter Wemm 
169a17d2cb2SPeter Wemm     PC = 0;
170a17d2cb2SPeter Wemm     UP = 0;
171a17d2cb2SPeter Wemm     BC = 0;
1727d0e8efaSRong-En Fan     FIX_SGR0 = 0;		/* don't free it - application may still use */
173a17d2cb2SPeter Wemm 
17406bfebdeSXin LI     if (rc == 1) {
1750e3d5408SPeter Wemm 
1760e3d5408SPeter Wemm 	if (cursor_left)
1775d08fb1fSRong-En Fan 	    if ((backspaces_with_bs = (char) !strcmp(cursor_left, "\b")) == 0)
1780e3d5408SPeter Wemm 		backspace_if_not_bs = cursor_left;
1790e3d5408SPeter Wemm 
1800e3d5408SPeter Wemm 	/* we're required to export these */
1810e3d5408SPeter Wemm 	if (pad_char != NULL)
1820e3d5408SPeter Wemm 	    PC = pad_char[0];
1830e3d5408SPeter Wemm 	if (cursor_up != NULL)
1840e3d5408SPeter Wemm 	    UP = cursor_up;
1850e3d5408SPeter Wemm 	if (backspace_if_not_bs != NULL)
1860e3d5408SPeter Wemm 	    BC = backspace_if_not_bs;
1870e3d5408SPeter Wemm 
188aae38d10SBaptiste Daroussin 	if ((FIX_SGR0 = _nc_trim_sgr0(&TerminalType(TerminalOf(SP_PARM))))
189aae38d10SBaptiste Daroussin 	    != 0) {
1907d0e8efaSRong-En Fan 	    if (!strcmp(FIX_SGR0, exit_attribute_mode)) {
1917d0e8efaSRong-En Fan 		if (FIX_SGR0 != exit_attribute_mode) {
1927d0e8efaSRong-En Fan 		    free(FIX_SGR0);
193a17d2cb2SPeter Wemm 		}
1947d0e8efaSRong-En Fan 		FIX_SGR0 = 0;
195a17d2cb2SPeter Wemm 	    }
196a17d2cb2SPeter Wemm 	}
1977d0e8efaSRong-En Fan 	LAST_BUF = bufp;
1984454585cSRong-En Fan 	LAST_USE = TRUE;
199a17d2cb2SPeter Wemm 
20006bfebdeSXin LI 	SetNoPadding(SP_PARM);
20106bfebdeSXin LI 	(void) NCURSES_SP_NAME(baudrate) (NCURSES_SP_ARG);	/* sets ospeed as a side-effect */
2020e3d5408SPeter Wemm 
2030e3d5408SPeter Wemm /* LINT_PREPRO
2040e3d5408SPeter Wemm #if 0*/
2050e3d5408SPeter Wemm #include <capdefaults.c>
2060e3d5408SPeter Wemm /* LINT_PREPRO
2070e3d5408SPeter Wemm #endif*/
2080e3d5408SPeter Wemm 
209b589b6f2SPeter Wemm     }
210b589b6f2SPeter Wemm 
211c8b9c85eSPeter Wemm #ifdef FREEBSD_NATIVE
212c8b9c85eSPeter Wemm     /*
213c8b9c85eSPeter Wemm      * This is a REALLY UGLY hack. Basically, if we originate with
214c8b9c85eSPeter Wemm      * a termcap source, try and copy it out.
215c8b9c85eSPeter Wemm      */
216c8b9c85eSPeter Wemm     if (bufp && _nc_termcap[0])
217c8b9c85eSPeter Wemm 	strncpy(bufp, _nc_termcap, 1024);
218c8b9c85eSPeter Wemm #endif
219c8b9c85eSPeter Wemm 
22006bfebdeSXin LI     returnCode(rc);
2210e3d5408SPeter Wemm }
2220e3d5408SPeter Wemm 
22306bfebdeSXin LI #if NCURSES_SP_FUNCS
22406bfebdeSXin LI NCURSES_EXPORT(int)
tgetent(char * bufp,const char * name)22506bfebdeSXin LI tgetent(char *bufp, const char *name)
22606bfebdeSXin LI {
22706bfebdeSXin LI     return NCURSES_SP_NAME(tgetent) (CURRENT_SCREEN, bufp, name);
22806bfebdeSXin LI }
22906bfebdeSXin LI #endif
23006bfebdeSXin LI 
23106bfebdeSXin LI #if 0
23206bfebdeSXin LI static bool
23306bfebdeSXin LI same_tcname(const char *a, const char *b)
23406bfebdeSXin LI {
23573f0a83dSXin LI     bool code = SameCap(a, b);
23673f0a83dSXin LI     fprintf(stderr, "compare(%s,%s) %s\n", a, b, code ? "same" : "diff");
23773f0a83dSXin LI     return code;
23806bfebdeSXin LI }
23973f0a83dSXin LI 
24006bfebdeSXin LI #else
24173f0a83dSXin LI #define same_tcname(a,b) SameCap(a,b)
24206bfebdeSXin LI #endif
24306bfebdeSXin LI 
2440e3d5408SPeter Wemm /***************************************************************************
2450e3d5408SPeter Wemm  *
2460e3d5408SPeter Wemm  * tgetflag(str)
2470e3d5408SPeter Wemm  *
2480e3d5408SPeter Wemm  * Look up boolean termcap capability str and return its value (TRUE=1 if
2490e3d5408SPeter Wemm  * present, FALSE=0 if not).
2500e3d5408SPeter Wemm  *
2510e3d5408SPeter Wemm  ***************************************************************************/
2520e3d5408SPeter Wemm 
253952abd2aSPeter Wemm NCURSES_EXPORT(int)
NCURSES_SP_NAME(tgetflag)254aae38d10SBaptiste Daroussin NCURSES_SP_NAME(tgetflag) (NCURSES_SP_DCLx const char *id)
25506bfebdeSXin LI {
25606bfebdeSXin LI     int result = 0;		/* Solaris returns zero for missing flag */
25706bfebdeSXin LI 
25806bfebdeSXin LI     T((T_CALLED("tgetflag(%p, %s)"), (void *) SP_PARM, id));
25973f0a83dSXin LI     if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
260aae38d10SBaptiste Daroussin 	TERMTYPE2 *tp = &TerminalType(TerminalOf(SP_PARM));
26106bfebdeSXin LI 	struct name_table_entry const *entry_ptr;
262aae38d10SBaptiste Daroussin 	int j = -1;
26306bfebdeSXin LI 
26406bfebdeSXin LI 	entry_ptr = _nc_find_type_entry(id, BOOLEAN, TRUE);
26506bfebdeSXin LI 	if (entry_ptr != 0) {
26606bfebdeSXin LI 	    j = entry_ptr->nte_index;
26706bfebdeSXin LI 	}
26806bfebdeSXin LI #if NCURSES_XNAMES
26906bfebdeSXin LI 	else {
27073f0a83dSXin LI 	    int i;
27106bfebdeSXin LI 	    for_each_ext_boolean(i, tp) {
27206bfebdeSXin LI 		const char *capname = ExtBoolname(tp, i, boolcodes);
27373f0a83dSXin LI 		if (same_tcname(id, capname) && ValidExt(capname)) {
27406bfebdeSXin LI 		    j = i;
27506bfebdeSXin LI 		    break;
27606bfebdeSXin LI 		}
27706bfebdeSXin LI 	    }
27806bfebdeSXin LI 	}
27906bfebdeSXin LI #endif
28006bfebdeSXin LI 	if (j >= 0) {
28106bfebdeSXin LI 	    /* note: setupterm forces invalid booleans to false */
28206bfebdeSXin LI 	    result = tp->Booleans[j];
28306bfebdeSXin LI 	}
28406bfebdeSXin LI     }
28506bfebdeSXin LI     returnCode(result);
28606bfebdeSXin LI }
28706bfebdeSXin LI 
28806bfebdeSXin LI #if NCURSES_SP_FUNCS
28906bfebdeSXin LI NCURSES_EXPORT(int)
tgetflag(const char * id)290aae38d10SBaptiste Daroussin tgetflag(const char *id)
2910e3d5408SPeter Wemm {
29206bfebdeSXin LI     return NCURSES_SP_NAME(tgetflag) (CURRENT_SCREEN, id);
2930e3d5408SPeter Wemm }
29406bfebdeSXin LI #endif
2950e3d5408SPeter Wemm 
2960e3d5408SPeter Wemm /***************************************************************************
2970e3d5408SPeter Wemm  *
2980e3d5408SPeter Wemm  * tgetnum(str)
2990e3d5408SPeter Wemm  *
3000e3d5408SPeter Wemm  * Look up numeric termcap capability str and return its value, or -1 if
3010e3d5408SPeter Wemm  * not given.
3020e3d5408SPeter Wemm  *
3030e3d5408SPeter Wemm  ***************************************************************************/
3040e3d5408SPeter Wemm 
305952abd2aSPeter Wemm NCURSES_EXPORT(int)
NCURSES_SP_NAME(tgetnum)306aae38d10SBaptiste Daroussin NCURSES_SP_NAME(tgetnum) (NCURSES_SP_DCLx const char *id)
30706bfebdeSXin LI {
30806bfebdeSXin LI     int result = ABSENT_NUMERIC;
30906bfebdeSXin LI 
31006bfebdeSXin LI     T((T_CALLED("tgetnum(%p, %s)"), (void *) SP_PARM, id));
31173f0a83dSXin LI     if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
312aae38d10SBaptiste Daroussin 	TERMTYPE2 *tp = &TerminalType(TerminalOf(SP_PARM));
31306bfebdeSXin LI 	struct name_table_entry const *entry_ptr;
314aae38d10SBaptiste Daroussin 	int j = -1;
31506bfebdeSXin LI 
31606bfebdeSXin LI 	entry_ptr = _nc_find_type_entry(id, NUMBER, TRUE);
31706bfebdeSXin LI 	if (entry_ptr != 0) {
31806bfebdeSXin LI 	    j = entry_ptr->nte_index;
31906bfebdeSXin LI 	}
32006bfebdeSXin LI #if NCURSES_XNAMES
32106bfebdeSXin LI 	else {
32273f0a83dSXin LI 	    int i;
32306bfebdeSXin LI 	    for_each_ext_number(i, tp) {
32406bfebdeSXin LI 		const char *capname = ExtNumname(tp, i, numcodes);
32573f0a83dSXin LI 		if (same_tcname(id, capname) && ValidExt(capname)) {
32606bfebdeSXin LI 		    j = i;
32706bfebdeSXin LI 		    break;
32806bfebdeSXin LI 		}
32906bfebdeSXin LI 	    }
33006bfebdeSXin LI 	}
33106bfebdeSXin LI #endif
33206bfebdeSXin LI 	if (j >= 0) {
33306bfebdeSXin LI 	    if (VALID_NUMERIC(tp->Numbers[j]))
33406bfebdeSXin LI 		result = tp->Numbers[j];
33506bfebdeSXin LI 	}
33606bfebdeSXin LI     }
33706bfebdeSXin LI     returnCode(result);
33806bfebdeSXin LI }
33906bfebdeSXin LI 
34006bfebdeSXin LI #if NCURSES_SP_FUNCS
34106bfebdeSXin LI NCURSES_EXPORT(int)
tgetnum(const char * id)342aae38d10SBaptiste Daroussin tgetnum(const char *id)
3430e3d5408SPeter Wemm {
34406bfebdeSXin LI     return NCURSES_SP_NAME(tgetnum) (CURRENT_SCREEN, id);
3450e3d5408SPeter Wemm }
34606bfebdeSXin LI #endif
3470e3d5408SPeter Wemm 
3480e3d5408SPeter Wemm /***************************************************************************
3490e3d5408SPeter Wemm  *
3500e3d5408SPeter Wemm  * tgetstr(str, area)
3510e3d5408SPeter Wemm  *
3520e3d5408SPeter Wemm  * Look up string termcap capability str and return a pointer to its value,
3530e3d5408SPeter Wemm  * or NULL if not given.
3540e3d5408SPeter Wemm  *
3550e3d5408SPeter Wemm  ***************************************************************************/
3560e3d5408SPeter Wemm 
357952abd2aSPeter Wemm NCURSES_EXPORT(char *)
NCURSES_SP_NAME(tgetstr)358aae38d10SBaptiste Daroussin NCURSES_SP_NAME(tgetstr) (NCURSES_SP_DCLx const char *id, char **area)
3590e3d5408SPeter Wemm {
360a17d2cb2SPeter Wemm     char *result = NULL;
3610e3d5408SPeter Wemm 
36206bfebdeSXin LI     T((T_CALLED("tgetstr(%s,%p)"), id, (void *) area));
36373f0a83dSXin LI     if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
364aae38d10SBaptiste Daroussin 	TERMTYPE2 *tp = &TerminalType(TerminalOf(SP_PARM));
36506bfebdeSXin LI 	struct name_table_entry const *entry_ptr;
366aae38d10SBaptiste Daroussin 	int j = -1;
36706bfebdeSXin LI 
36806bfebdeSXin LI 	entry_ptr = _nc_find_type_entry(id, STRING, TRUE);
36906bfebdeSXin LI 	if (entry_ptr != 0) {
37006bfebdeSXin LI 	    j = entry_ptr->nte_index;
37106bfebdeSXin LI 	}
37206bfebdeSXin LI #if NCURSES_XNAMES
37306bfebdeSXin LI 	else {
37473f0a83dSXin LI 	    int i;
37506bfebdeSXin LI 	    for_each_ext_string(i, tp) {
3760e3d5408SPeter Wemm 		const char *capname = ExtStrname(tp, i, strcodes);
37773f0a83dSXin LI 		if (same_tcname(id, capname) && ValidExt(capname)) {
37806bfebdeSXin LI 		    j = i;
37906bfebdeSXin LI 		    break;
38006bfebdeSXin LI 		}
38106bfebdeSXin LI 	    }
38206bfebdeSXin LI 	}
38306bfebdeSXin LI #endif
38406bfebdeSXin LI 	if (j >= 0) {
38506bfebdeSXin LI 	    result = tp->Strings[j];
38673f0a83dSXin LI 	    TR(TRACE_DATABASE, ("found match %d: %s", j, _nc_visbuf(result)));
387bd2a8869SPeter Wemm 	    /* setupterm forces canceled strings to null */
388a17d2cb2SPeter Wemm 	    if (VALID_STRING(result)) {
389a17d2cb2SPeter Wemm 		if (result == exit_attribute_mode
3907d0e8efaSRong-En Fan 		    && FIX_SGR0 != 0) {
3917d0e8efaSRong-En Fan 		    result = FIX_SGR0;
392a17d2cb2SPeter Wemm 		    TR(TRACE_DATABASE, ("altered to : %s", _nc_visbuf(result)));
393a17d2cb2SPeter Wemm 		}
3945bd21f8aSPeter Wemm 		if (area != 0
395a17d2cb2SPeter Wemm 		    && *area != 0) {
39673f0a83dSXin LI 		    _nc_STRCPY(*area, result, 1024);
3977d0e8efaSRong-En Fan 		    result = *area;
3985bd21f8aSPeter Wemm 		    *area += strlen(*area) + 1;
3992a043471SLuoqi Chen 		}
400a17d2cb2SPeter Wemm 	    }
4010e3d5408SPeter Wemm 	}
4020e3d5408SPeter Wemm     }
403a17d2cb2SPeter Wemm     returnPtr(result);
4040e3d5408SPeter Wemm }
4057d0e8efaSRong-En Fan 
40606bfebdeSXin LI #if NCURSES_SP_FUNCS
40706bfebdeSXin LI NCURSES_EXPORT(char *)
tgetstr(const char * id,char ** area)408aae38d10SBaptiste Daroussin tgetstr(const char *id, char **area)
40906bfebdeSXin LI {
41006bfebdeSXin LI     return NCURSES_SP_NAME(tgetstr) (CURRENT_SCREEN, id, area);
41106bfebdeSXin LI }
41206bfebdeSXin LI #endif
41306bfebdeSXin LI 
4147d0e8efaSRong-En Fan #if NO_LEAKS
415aae38d10SBaptiste Daroussin #undef CacheInx
416aae38d10SBaptiste Daroussin #define CacheInx num
417aae38d10SBaptiste Daroussin NCURSES_EXPORT(void)
_nc_tgetent_leak(const TERMINAL * const termp)418*21817992SBaptiste Daroussin _nc_tgetent_leak(const TERMINAL *const termp)
419aae38d10SBaptiste Daroussin {
420aae38d10SBaptiste Daroussin     if (termp != 0) {
421aae38d10SBaptiste Daroussin 	int num;
422aae38d10SBaptiste Daroussin 	for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) {
423aae38d10SBaptiste Daroussin 	    if (LAST_TRM == termp) {
424aae38d10SBaptiste Daroussin 		FreeAndNull(FIX_SGR0);
425aae38d10SBaptiste Daroussin 		if (LAST_TRM != 0) {
426aae38d10SBaptiste Daroussin 		    LAST_TRM = 0;
427aae38d10SBaptiste Daroussin 		}
428aae38d10SBaptiste Daroussin 		break;
429aae38d10SBaptiste Daroussin 	    }
430aae38d10SBaptiste Daroussin 	}
431aae38d10SBaptiste Daroussin     }
432aae38d10SBaptiste Daroussin }
433aae38d10SBaptiste Daroussin 
4347d0e8efaSRong-En Fan NCURSES_EXPORT(void)
_nc_tgetent_leaks(void)4357d0e8efaSRong-En Fan _nc_tgetent_leaks(void)
4367d0e8efaSRong-En Fan {
437aae38d10SBaptiste Daroussin     int num;
4384454585cSRong-En Fan     for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) {
439aae38d10SBaptiste Daroussin 	if (LAST_TRM != 0) {
4407d0e8efaSRong-En Fan 	    del_curterm(LAST_TRM);
441aae38d10SBaptiste Daroussin 	    _nc_tgetent_leak(LAST_TRM);
442aae38d10SBaptiste Daroussin 	}
4437d0e8efaSRong-En Fan     }
4447d0e8efaSRong-En Fan }
4457d0e8efaSRong-En Fan #endif
446