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