xref: /freebsd/contrib/ncurses/ncurses/tinfo/lib_termcap.c (revision 73f0a83d68863a383fd8953972cd36eb6420ec7d)
10e3d5408SPeter Wemm /****************************************************************************
2*73f0a83dSXin LI  * Copyright (c) 1998-2012,2013 Free Software Foundation, Inc.              *
30e3d5408SPeter Wemm  *                                                                          *
40e3d5408SPeter Wemm  * Permission is hereby granted, free of charge, to any person obtaining a  *
50e3d5408SPeter Wemm  * copy of this software and associated documentation files (the            *
60e3d5408SPeter Wemm  * "Software"), to deal in the Software without restriction, including      *
70e3d5408SPeter Wemm  * without limitation the rights to use, copy, modify, merge, publish,      *
80e3d5408SPeter Wemm  * distribute, distribute with modifications, sublicense, and/or sell       *
90e3d5408SPeter Wemm  * copies of the Software, and to permit persons to whom the Software is    *
100e3d5408SPeter Wemm  * furnished to do so, subject to the following conditions:                 *
110e3d5408SPeter Wemm  *                                                                          *
120e3d5408SPeter Wemm  * The above copyright notice and this permission notice shall be included  *
130e3d5408SPeter Wemm  * in all copies or substantial portions of the Software.                   *
140e3d5408SPeter Wemm  *                                                                          *
150e3d5408SPeter Wemm  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
160e3d5408SPeter Wemm  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
170e3d5408SPeter Wemm  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
180e3d5408SPeter Wemm  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
190e3d5408SPeter Wemm  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
200e3d5408SPeter Wemm  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
210e3d5408SPeter Wemm  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
220e3d5408SPeter Wemm  *                                                                          *
230e3d5408SPeter Wemm  * Except as contained in this notice, the name(s) of the above copyright   *
240e3d5408SPeter Wemm  * holders shall not be used in advertising or otherwise to promote the     *
250e3d5408SPeter Wemm  * sale, use or other dealings in this Software without prior written       *
260e3d5408SPeter Wemm  * authorization.                                                           *
270e3d5408SPeter Wemm  ****************************************************************************/
280e3d5408SPeter Wemm 
290e3d5408SPeter Wemm /****************************************************************************
300e3d5408SPeter Wemm  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
310e3d5408SPeter Wemm  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
327d0e8efaSRong-En Fan  *     and: Thomas E. Dickey                        1996-on                 *
3306bfebdeSXin LI  *     and: Juergen Pfeifer                                                 *
34a17d2cb2SPeter Wemm  *                                                                          *
35a17d2cb2SPeter Wemm  * some of the code in here was contributed by:                             *
36a17d2cb2SPeter Wemm  * Magnus Bengtsson, d6mbeng@dtek.chalmers.se (Nov'93)                      *
377d0e8efaSRong-En Fan  * (but it has changed a lot)                                               *
380e3d5408SPeter Wemm  ****************************************************************************/
390e3d5408SPeter Wemm 
405bd21f8aSPeter Wemm /* $FreeBSD$ */
415bd21f8aSPeter Wemm 
42d91c14deSPeter Wemm #define __INTERNAL_CAPS_VISIBLE
430e3d5408SPeter Wemm #include <curses.priv.h>
440e3d5408SPeter Wemm 
450e3d5408SPeter Wemm #include <termcap.h>
460e3d5408SPeter Wemm #include <tic.h>
47a17d2cb2SPeter Wemm #include <ctype.h>
480e3d5408SPeter Wemm 
4906bfebdeSXin LI #ifndef CUR
5006bfebdeSXin LI #define CUR SP_TERMTYPE
5106bfebdeSXin LI #endif
520e3d5408SPeter Wemm 
53*73f0a83dSXin LI MODULE_ID("$Id: lib_termcap.c,v 1.80 2013/06/08 16:48:47 tom Exp $")
540e3d5408SPeter Wemm 
55a17d2cb2SPeter Wemm NCURSES_EXPORT_VAR(char *) UP = 0;
56a17d2cb2SPeter Wemm NCURSES_EXPORT_VAR(char *) BC = 0;
570e3d5408SPeter Wemm 
58c8b9c85eSPeter Wemm #ifdef FREEBSD_NATIVE
59c8b9c85eSPeter Wemm extern char _nc_termcap[];	/* buffer to copy out */
60c8b9c85eSPeter Wemm #endif
61c8b9c85eSPeter Wemm 
624454585cSRong-En Fan #define MyCache  _nc_globals.tgetent_cache
634454585cSRong-En Fan #define CacheInx _nc_globals.tgetent_index
644454585cSRong-En Fan #define CacheSeq _nc_globals.tgetent_sequence
65a17d2cb2SPeter Wemm 
664454585cSRong-En Fan #define FIX_SGR0 MyCache[CacheInx].fix_sgr0
674454585cSRong-En Fan #define LAST_TRM MyCache[CacheInx].last_term
684454585cSRong-En Fan #define LAST_BUF MyCache[CacheInx].last_bufp
694454585cSRong-En Fan #define LAST_USE MyCache[CacheInx].last_used
704454585cSRong-En Fan #define LAST_SEQ MyCache[CacheInx].sequence
71a17d2cb2SPeter Wemm 
72*73f0a83dSXin LI /*
73*73f0a83dSXin LI  * Termcap names are matched only using the first two bytes.
74*73f0a83dSXin LI  * Ignore any extended names longer than two bytes, to avoid problems
75*73f0a83dSXin LI  * with legacy code which passes in parameters whose use is long forgotten.
76*73f0a83dSXin LI  */
77*73f0a83dSXin LI #define ValidCap(cap) (((cap)[0] != '\0') && ((cap)[1] != '\0'))
78*73f0a83dSXin LI #define SameCap(a,b)  (((a)[0] == (b)[0]) && ((a)[1] == (b)[1]))
79*73f0a83dSXin LI #define ValidExt(ext) (ValidCap(ext) && (ext)[2] == '\0')
80*73f0a83dSXin LI 
810e3d5408SPeter Wemm /***************************************************************************
820e3d5408SPeter Wemm  *
830e3d5408SPeter Wemm  * tgetent(bufp, term)
840e3d5408SPeter Wemm  *
850e3d5408SPeter Wemm  * In termcap, this function reads in the entry for terminal `term' into the
860e3d5408SPeter Wemm  * buffer pointed to by bufp. It must be called before any of the functions
870e3d5408SPeter Wemm  * below are called.
880e3d5408SPeter Wemm  * In this terminfo emulation, tgetent() simply calls setupterm() (which
890e3d5408SPeter Wemm  * does a bit more than tgetent() in termcap does), and returns its return
900e3d5408SPeter Wemm  * value (1 if successful, 0 if no terminal with the given name could be
910e3d5408SPeter Wemm  * found, or -1 if no terminal descriptions have been installed on the
920e3d5408SPeter Wemm  * system).  The bufp argument is ignored.
930e3d5408SPeter Wemm  *
940e3d5408SPeter Wemm  ***************************************************************************/
950e3d5408SPeter Wemm 
96952abd2aSPeter Wemm NCURSES_EXPORT(int)
9706bfebdeSXin LI NCURSES_SP_NAME(tgetent) (NCURSES_SP_DCLx char *bufp, const char *name)
980e3d5408SPeter Wemm {
9906bfebdeSXin LI     int rc = ERR;
1007d0e8efaSRong-En Fan     int n;
1017d0e8efaSRong-En Fan     bool found_cache = FALSE;
10206bfebdeSXin LI #ifdef USE_TERM_DRIVER
10306bfebdeSXin LI     TERMINAL *termp = 0;
10406bfebdeSXin LI #endif
1057d0e8efaSRong-En Fan 
1067d0e8efaSRong-En Fan     START_TRACE();
1070e3d5408SPeter Wemm     T((T_CALLED("tgetent()")));
1080e3d5408SPeter Wemm 
10906bfebdeSXin LI     TINFO_SETUP_TERM(&termp, (NCURSES_CONST char *) name,
11006bfebdeSXin LI 		     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)
115*73f0a83dSXin 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     }
16206bfebdeSXin LI     LAST_TRM = TerminalOf(SP_PARM);
1634454585cSRong-En Fan     LAST_SEQ = ++CacheSeq;
1640e3d5408SPeter Wemm 
165a17d2cb2SPeter Wemm     PC = 0;
166a17d2cb2SPeter Wemm     UP = 0;
167a17d2cb2SPeter Wemm     BC = 0;
1687d0e8efaSRong-En Fan     FIX_SGR0 = 0;		/* don't free it - application may still use */
169a17d2cb2SPeter Wemm 
17006bfebdeSXin LI     if (rc == 1) {
1710e3d5408SPeter Wemm 
1720e3d5408SPeter Wemm 	if (cursor_left)
1735d08fb1fSRong-En Fan 	    if ((backspaces_with_bs = (char) !strcmp(cursor_left, "\b")) == 0)
1740e3d5408SPeter Wemm 		backspace_if_not_bs = cursor_left;
1750e3d5408SPeter Wemm 
1760e3d5408SPeter Wemm 	/* we're required to export these */
1770e3d5408SPeter Wemm 	if (pad_char != NULL)
1780e3d5408SPeter Wemm 	    PC = pad_char[0];
1790e3d5408SPeter Wemm 	if (cursor_up != NULL)
1800e3d5408SPeter Wemm 	    UP = cursor_up;
1810e3d5408SPeter Wemm 	if (backspace_if_not_bs != NULL)
1820e3d5408SPeter Wemm 	    BC = backspace_if_not_bs;
1830e3d5408SPeter Wemm 
18406bfebdeSXin LI 	if ((FIX_SGR0 = _nc_trim_sgr0(&(TerminalOf(SP_PARM)->type))) != 0) {
1857d0e8efaSRong-En Fan 	    if (!strcmp(FIX_SGR0, exit_attribute_mode)) {
1867d0e8efaSRong-En Fan 		if (FIX_SGR0 != exit_attribute_mode) {
1877d0e8efaSRong-En Fan 		    free(FIX_SGR0);
188a17d2cb2SPeter Wemm 		}
1897d0e8efaSRong-En Fan 		FIX_SGR0 = 0;
190a17d2cb2SPeter Wemm 	    }
191a17d2cb2SPeter Wemm 	}
1927d0e8efaSRong-En Fan 	LAST_BUF = bufp;
1934454585cSRong-En Fan 	LAST_USE = TRUE;
194a17d2cb2SPeter Wemm 
19506bfebdeSXin LI 	SetNoPadding(SP_PARM);
19606bfebdeSXin LI 	(void) NCURSES_SP_NAME(baudrate) (NCURSES_SP_ARG);	/* sets ospeed as a side-effect */
1970e3d5408SPeter Wemm 
1980e3d5408SPeter Wemm /* LINT_PREPRO
1990e3d5408SPeter Wemm #if 0*/
2000e3d5408SPeter Wemm #include <capdefaults.c>
2010e3d5408SPeter Wemm /* LINT_PREPRO
2020e3d5408SPeter Wemm #endif*/
2030e3d5408SPeter Wemm 
204b589b6f2SPeter Wemm     }
205b589b6f2SPeter Wemm 
206c8b9c85eSPeter Wemm #ifdef FREEBSD_NATIVE
207c8b9c85eSPeter Wemm     /*
208c8b9c85eSPeter Wemm      * This is a REALLY UGLY hack. Basically, if we originate with
209c8b9c85eSPeter Wemm      * a termcap source, try and copy it out.
210c8b9c85eSPeter Wemm      */
211c8b9c85eSPeter Wemm     if (bufp && _nc_termcap[0])
212c8b9c85eSPeter Wemm 	strncpy(bufp, _nc_termcap, 1024);
213c8b9c85eSPeter Wemm #endif
214c8b9c85eSPeter Wemm 
21506bfebdeSXin LI     returnCode(rc);
2160e3d5408SPeter Wemm }
2170e3d5408SPeter Wemm 
21806bfebdeSXin LI #if NCURSES_SP_FUNCS
21906bfebdeSXin LI NCURSES_EXPORT(int)
22006bfebdeSXin LI tgetent(char *bufp, const char *name)
22106bfebdeSXin LI {
22206bfebdeSXin LI     return NCURSES_SP_NAME(tgetent) (CURRENT_SCREEN, bufp, name);
22306bfebdeSXin LI }
22406bfebdeSXin LI #endif
22506bfebdeSXin LI 
22606bfebdeSXin LI #if 0
22706bfebdeSXin LI static bool
22806bfebdeSXin LI same_tcname(const char *a, const char *b)
22906bfebdeSXin LI {
230*73f0a83dSXin LI     bool code = SameCap(a, b);
231*73f0a83dSXin LI     fprintf(stderr, "compare(%s,%s) %s\n", a, b, code ? "same" : "diff");
232*73f0a83dSXin LI     return code;
23306bfebdeSXin LI }
234*73f0a83dSXin LI 
23506bfebdeSXin LI #else
236*73f0a83dSXin LI #define same_tcname(a,b) SameCap(a,b)
23706bfebdeSXin LI #endif
23806bfebdeSXin LI 
2390e3d5408SPeter Wemm /***************************************************************************
2400e3d5408SPeter Wemm  *
2410e3d5408SPeter Wemm  * tgetflag(str)
2420e3d5408SPeter Wemm  *
2430e3d5408SPeter Wemm  * Look up boolean termcap capability str and return its value (TRUE=1 if
2440e3d5408SPeter Wemm  * present, FALSE=0 if not).
2450e3d5408SPeter Wemm  *
2460e3d5408SPeter Wemm  ***************************************************************************/
2470e3d5408SPeter Wemm 
248952abd2aSPeter Wemm NCURSES_EXPORT(int)
24906bfebdeSXin LI NCURSES_SP_NAME(tgetflag) (NCURSES_SP_DCLx NCURSES_CONST char *id)
25006bfebdeSXin LI {
25106bfebdeSXin LI     int result = 0;		/* Solaris returns zero for missing flag */
252*73f0a83dSXin LI     int j = -1;
25306bfebdeSXin LI 
25406bfebdeSXin LI     T((T_CALLED("tgetflag(%p, %s)"), (void *) SP_PARM, id));
255*73f0a83dSXin LI     if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
25606bfebdeSXin LI 	TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
25706bfebdeSXin LI 	struct name_table_entry const *entry_ptr;
25806bfebdeSXin LI 
25906bfebdeSXin LI 	entry_ptr = _nc_find_type_entry(id, BOOLEAN, TRUE);
26006bfebdeSXin LI 	if (entry_ptr != 0) {
26106bfebdeSXin LI 	    j = entry_ptr->nte_index;
26206bfebdeSXin LI 	}
26306bfebdeSXin LI #if NCURSES_XNAMES
26406bfebdeSXin LI 	else {
265*73f0a83dSXin LI 	    int i;
26606bfebdeSXin LI 	    for_each_ext_boolean(i, tp) {
26706bfebdeSXin LI 		const char *capname = ExtBoolname(tp, i, boolcodes);
268*73f0a83dSXin LI 		if (same_tcname(id, capname) && ValidExt(capname)) {
26906bfebdeSXin LI 		    j = i;
27006bfebdeSXin LI 		    break;
27106bfebdeSXin LI 		}
27206bfebdeSXin LI 	    }
27306bfebdeSXin LI 	}
27406bfebdeSXin LI #endif
27506bfebdeSXin LI 	if (j >= 0) {
27606bfebdeSXin LI 	    /* note: setupterm forces invalid booleans to false */
27706bfebdeSXin LI 	    result = tp->Booleans[j];
27806bfebdeSXin LI 	}
27906bfebdeSXin LI     }
28006bfebdeSXin LI     returnCode(result);
28106bfebdeSXin LI }
28206bfebdeSXin LI 
28306bfebdeSXin LI #if NCURSES_SP_FUNCS
28406bfebdeSXin LI NCURSES_EXPORT(int)
285bd2a8869SPeter Wemm tgetflag(NCURSES_CONST char *id)
2860e3d5408SPeter Wemm {
28706bfebdeSXin LI     return NCURSES_SP_NAME(tgetflag) (CURRENT_SCREEN, id);
2880e3d5408SPeter Wemm }
28906bfebdeSXin LI #endif
2900e3d5408SPeter Wemm 
2910e3d5408SPeter Wemm /***************************************************************************
2920e3d5408SPeter Wemm  *
2930e3d5408SPeter Wemm  * tgetnum(str)
2940e3d5408SPeter Wemm  *
2950e3d5408SPeter Wemm  * Look up numeric termcap capability str and return its value, or -1 if
2960e3d5408SPeter Wemm  * not given.
2970e3d5408SPeter Wemm  *
2980e3d5408SPeter Wemm  ***************************************************************************/
2990e3d5408SPeter Wemm 
300952abd2aSPeter Wemm NCURSES_EXPORT(int)
30106bfebdeSXin LI NCURSES_SP_NAME(tgetnum) (NCURSES_SP_DCLx NCURSES_CONST char *id)
30206bfebdeSXin LI {
30306bfebdeSXin LI     int result = ABSENT_NUMERIC;
304*73f0a83dSXin LI     int j = -1;
30506bfebdeSXin LI 
30606bfebdeSXin LI     T((T_CALLED("tgetnum(%p, %s)"), (void *) SP_PARM, id));
307*73f0a83dSXin LI     if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
30806bfebdeSXin LI 	TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
30906bfebdeSXin LI 	struct name_table_entry const *entry_ptr;
31006bfebdeSXin LI 
31106bfebdeSXin LI 	entry_ptr = _nc_find_type_entry(id, NUMBER, TRUE);
31206bfebdeSXin LI 	if (entry_ptr != 0) {
31306bfebdeSXin LI 	    j = entry_ptr->nte_index;
31406bfebdeSXin LI 	}
31506bfebdeSXin LI #if NCURSES_XNAMES
31606bfebdeSXin LI 	else {
317*73f0a83dSXin LI 	    int i;
31806bfebdeSXin LI 	    for_each_ext_number(i, tp) {
31906bfebdeSXin LI 		const char *capname = ExtNumname(tp, i, numcodes);
320*73f0a83dSXin LI 		if (same_tcname(id, capname) && ValidExt(capname)) {
32106bfebdeSXin LI 		    j = i;
32206bfebdeSXin LI 		    break;
32306bfebdeSXin LI 		}
32406bfebdeSXin LI 	    }
32506bfebdeSXin LI 	}
32606bfebdeSXin LI #endif
32706bfebdeSXin LI 	if (j >= 0) {
32806bfebdeSXin LI 	    if (VALID_NUMERIC(tp->Numbers[j]))
32906bfebdeSXin LI 		result = tp->Numbers[j];
33006bfebdeSXin LI 	}
33106bfebdeSXin LI     }
33206bfebdeSXin LI     returnCode(result);
33306bfebdeSXin LI }
33406bfebdeSXin LI 
33506bfebdeSXin LI #if NCURSES_SP_FUNCS
33606bfebdeSXin LI NCURSES_EXPORT(int)
337bd2a8869SPeter Wemm tgetnum(NCURSES_CONST char *id)
3380e3d5408SPeter Wemm {
33906bfebdeSXin LI     return NCURSES_SP_NAME(tgetnum) (CURRENT_SCREEN, id);
3400e3d5408SPeter Wemm }
34106bfebdeSXin LI #endif
3420e3d5408SPeter Wemm 
3430e3d5408SPeter Wemm /***************************************************************************
3440e3d5408SPeter Wemm  *
3450e3d5408SPeter Wemm  * tgetstr(str, area)
3460e3d5408SPeter Wemm  *
3470e3d5408SPeter Wemm  * Look up string termcap capability str and return a pointer to its value,
3480e3d5408SPeter Wemm  * or NULL if not given.
3490e3d5408SPeter Wemm  *
3500e3d5408SPeter Wemm  ***************************************************************************/
3510e3d5408SPeter Wemm 
352952abd2aSPeter Wemm NCURSES_EXPORT(char *)
35306bfebdeSXin LI NCURSES_SP_NAME(tgetstr) (NCURSES_SP_DCLx NCURSES_CONST char *id, char **area)
3540e3d5408SPeter Wemm {
355a17d2cb2SPeter Wemm     char *result = NULL;
356*73f0a83dSXin LI     int j = -1;
3570e3d5408SPeter Wemm 
35806bfebdeSXin LI     T((T_CALLED("tgetstr(%s,%p)"), id, (void *) area));
359*73f0a83dSXin LI     if (HasTInfoTerminal(SP_PARM) && ValidCap(id)) {
36006bfebdeSXin LI 	TERMTYPE *tp = &(TerminalOf(SP_PARM)->type);
36106bfebdeSXin LI 	struct name_table_entry const *entry_ptr;
36206bfebdeSXin LI 
36306bfebdeSXin LI 	entry_ptr = _nc_find_type_entry(id, STRING, TRUE);
36406bfebdeSXin LI 	if (entry_ptr != 0) {
36506bfebdeSXin LI 	    j = entry_ptr->nte_index;
36606bfebdeSXin LI 	}
36706bfebdeSXin LI #if NCURSES_XNAMES
36806bfebdeSXin LI 	else {
369*73f0a83dSXin LI 	    int i;
37006bfebdeSXin LI 	    for_each_ext_string(i, tp) {
3710e3d5408SPeter Wemm 		const char *capname = ExtStrname(tp, i, strcodes);
372*73f0a83dSXin LI 		if (same_tcname(id, capname) && ValidExt(capname)) {
37306bfebdeSXin LI 		    j = i;
37406bfebdeSXin LI 		    break;
37506bfebdeSXin LI 		}
37606bfebdeSXin LI 	    }
37706bfebdeSXin LI 	}
37806bfebdeSXin LI #endif
37906bfebdeSXin LI 	if (j >= 0) {
38006bfebdeSXin LI 	    result = tp->Strings[j];
381*73f0a83dSXin LI 	    TR(TRACE_DATABASE, ("found match %d: %s", j, _nc_visbuf(result)));
382bd2a8869SPeter Wemm 	    /* setupterm forces canceled strings to null */
383a17d2cb2SPeter Wemm 	    if (VALID_STRING(result)) {
384a17d2cb2SPeter Wemm 		if (result == exit_attribute_mode
3857d0e8efaSRong-En Fan 		    && FIX_SGR0 != 0) {
3867d0e8efaSRong-En Fan 		    result = FIX_SGR0;
387a17d2cb2SPeter Wemm 		    TR(TRACE_DATABASE, ("altered to : %s", _nc_visbuf(result)));
388a17d2cb2SPeter Wemm 		}
3895bd21f8aSPeter Wemm 		if (area != 0
390a17d2cb2SPeter Wemm 		    && *area != 0) {
391*73f0a83dSXin LI 		    _nc_STRCPY(*area, result, 1024);
3927d0e8efaSRong-En Fan 		    result = *area;
3935bd21f8aSPeter Wemm 		    *area += strlen(*area) + 1;
3942a043471SLuoqi Chen 		}
395a17d2cb2SPeter Wemm 	    }
3960e3d5408SPeter Wemm 	}
3970e3d5408SPeter Wemm     }
398a17d2cb2SPeter Wemm     returnPtr(result);
3990e3d5408SPeter Wemm }
4007d0e8efaSRong-En Fan 
40106bfebdeSXin LI #if NCURSES_SP_FUNCS
40206bfebdeSXin LI NCURSES_EXPORT(char *)
40306bfebdeSXin LI tgetstr(NCURSES_CONST char *id, char **area)
40406bfebdeSXin LI {
40506bfebdeSXin LI     return NCURSES_SP_NAME(tgetstr) (CURRENT_SCREEN, id, area);
40606bfebdeSXin LI }
40706bfebdeSXin LI #endif
40806bfebdeSXin LI 
4097d0e8efaSRong-En Fan #if NO_LEAKS
4107d0e8efaSRong-En Fan NCURSES_EXPORT(void)
4117d0e8efaSRong-En Fan _nc_tgetent_leaks(void)
4127d0e8efaSRong-En Fan {
4134454585cSRong-En Fan     for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) {
4147d0e8efaSRong-En Fan 	FreeIfNeeded(FIX_SGR0);
4154454585cSRong-En Fan 	if (LAST_TRM != 0)
4167d0e8efaSRong-En Fan 	    del_curterm(LAST_TRM);
4177d0e8efaSRong-En Fan     }
4187d0e8efaSRong-En Fan }
4197d0e8efaSRong-En Fan #endif
420