예제 #1
0
NCURSES_SP_NAME(tgetent) (NCURSES_SP_DCLx char *bufp, const char *name)
{
    int rc = ERR;
    int n;
    bool found_cache = FALSE;
#ifdef USE_TERM_DRIVER
    TERMINAL *termp = 0;
#endif

    START_TRACE();
    T((T_CALLED("tgetent()")));

    TINFO_SETUP_TERM(&termp, (NCURSES_CONST char *) name,
		     STDOUT_FILENO, &rc, TRUE);

#ifdef USE_TERM_DRIVER
    if (termp == 0 ||
	!((TERMINAL_CONTROL_BLOCK *) termp)->drv->isTerminfo)
	returnCode(rc);
#endif

    /*
     * In general we cannot tell if the fixed sgr0 is still used by the
     * caller, but if tgetent() is called with the same buffer, that is
     * good enough, since the previous data would be invalidated by the
     * current call.
     *
     * bufp may be a null pointer, e.g., GNU termcap.  That allocates data,
     * which is good until the next tgetent() call.  The conventional termcap
     * is inconvenient because of the fixed buffer size, but because it uses
     * caller-supplied buffers, can have multiple terminal descriptions in
     * use at a given time.
     */
    for (n = 0; n < TGETENT_MAX; ++n) {
	bool same_result = (MyCache[n].last_used && MyCache[n].last_bufp == bufp);
	if (same_result) {
	    CacheInx = n;
	    if (FIX_SGR0 != 0) {
		FreeAndNull(FIX_SGR0);
	    }
	    /*
	     * Also free the terminfo data that we loaded (much bigger leak).
	     */
	    if (LAST_TRM != 0 && LAST_TRM != TerminalOf(SP_PARM)) {
		TERMINAL *trm = LAST_TRM;
		NCURSES_SP_NAME(del_curterm) (NCURSES_SP_ARGx LAST_TRM);
		for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx)
		    if (LAST_TRM == trm)
			LAST_TRM = 0;
		CacheInx = n;
	    }
	    found_cache = TRUE;
	    break;
	}
    }
    if (!found_cache) {
	int best = 0;

	for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) {
	    if (LAST_SEQ < MyCache[best].sequence) {
		best = CacheInx;
	    }
	}
	CacheInx = best;
    }
    if (rc == 1) {
	LAST_TRM = TerminalOf(SP_PARM);
	LAST_SEQ = ++CacheSeq;
    } else {
	LAST_TRM = 0;
    }

    PC = 0;
    UP = 0;
    BC = 0;
    FIX_SGR0 = 0;		/* don't free it - application may still use */

    if (rc == 1) {

	if (cursor_left)
	    if ((backspaces_with_bs = (char) !strcmp(cursor_left, "\b")) == 0)
		backspace_if_not_bs = cursor_left;

	/* we're required to export these */
	if (pad_char != NULL)
	    PC = pad_char[0];
	if (cursor_up != NULL)
	    UP = cursor_up;
	if (backspace_if_not_bs != NULL)
	    BC = backspace_if_not_bs;

	if ((FIX_SGR0 = _nc_trim_sgr0(&TerminalType(TerminalOf(SP_PARM))))
	    != 0) {
	    if (!strcmp(FIX_SGR0, exit_attribute_mode)) {
		if (FIX_SGR0 != exit_attribute_mode) {
		    free(FIX_SGR0);
		}
		FIX_SGR0 = 0;
	    }
	}
	LAST_BUF = bufp;
	LAST_USE = TRUE;

	SetNoPadding(SP_PARM);
	(void) NCURSES_SP_NAME(baudrate) (NCURSES_SP_ARG);	/* sets ospeed as a side-effect */

/* LINT_PREPRO
#if 0*/
#include <capdefaults.c>
/* LINT_PREPRO
#endif*/

    }
    returnCode(rc);
}
예제 #2
0
tgetent(char *bufp, const char *name)
{
    int errcode;
    int n;
    bool found_cache = FALSE;

    START_TRACE();
    T((T_CALLED("tgetent()")));

    _nc_setupterm((NCURSES_CONST char *) name, STDOUT_FILENO, &errcode, TRUE);

    /*
     * In general we cannot tell if the fixed sgr0 is still used by the
     * caller, but if tgetent() is called with the same buffer, that is
     * good enough, since the previous data would be invalidated by the
     * current call.
     *
     * bufp may be a null pointer, e.g., GNU termcap.  That allocates data,
     * which is good until the next tgetent() call.  The conventional termcap
     * is inconvenient because of the fixed buffer size, but because it uses
     * caller-supplied buffers, can have multiple terminal descriptions in
     * use at a given time.
     */
    for (n = 0; n < TGETENT_MAX; ++n) {
	bool same_result = (MyCache[n].last_used && MyCache[n].last_bufp == bufp);
	if (same_result) {
	    CacheInx = n;
	    if (FIX_SGR0 != 0) {
		FreeAndNull(FIX_SGR0);
	    }
	    /*
	     * Also free the terminfo data that we loaded (much bigger leak).
	     */
	    if (LAST_TRM != 0 && LAST_TRM != cur_term) {
		TERMINAL *trm = LAST_TRM;
		del_curterm(LAST_TRM);
		for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx)
		    if (LAST_TRM == trm)
			LAST_TRM = 0;
		CacheInx = n;
	    }
	    found_cache = TRUE;
	    break;
	}
    }
    if (!found_cache) {
	int best = 0;

	for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) {
	    if (LAST_SEQ < MyCache[best].sequence) {
		best = CacheInx;
	    }
	}
	CacheInx = best;
    }
    LAST_TRM = cur_term;
    LAST_SEQ = ++CacheSeq;

    PC = 0;
    UP = 0;
    BC = 0;
    FIX_SGR0 = 0;		/* don't free it - application may still use */

    if (errcode == 1) {

	if (cursor_left)
	    if ((backspaces_with_bs = (char) !strcmp(cursor_left, "\b")) == 0)
		backspace_if_not_bs = cursor_left;

	/* we're required to export these */
	if (pad_char != NULL)
	    PC = pad_char[0];
	if (cursor_up != NULL)
	    UP = cursor_up;
	if (backspace_if_not_bs != NULL)
	    BC = backspace_if_not_bs;

	if ((FIX_SGR0 = _nc_trim_sgr0(&(cur_term->type))) != 0) {
	    if (!strcmp(FIX_SGR0, exit_attribute_mode)) {
		if (FIX_SGR0 != exit_attribute_mode) {
		    free(FIX_SGR0);
		}
		FIX_SGR0 = 0;
	    }
	}
	LAST_BUF = bufp;
	LAST_USE = TRUE;

	SetNoPadding(SP);
	(void) baudrate();	/* sets ospeed as a side-effect */

/* LINT_PREPRO
#if 0*/
#include <capdefaults.c>
/* LINT_PREPRO
#endif*/

    }

#ifdef FREEBSD_NATIVE
    /*
     * This is a REALLY UGLY hack. Basically, if we originate with
     * a termcap source, try and copy it out.
     */
    if (bufp && _nc_termcap[0])
	strncpy(bufp, _nc_termcap, 1024);
#endif

    returnCode(errcode);
}