-ltermcap

Chris Torek chris at umcp-cs.UUCP
Mon Aug 4 14:33:59 AEST 1986


>In article <2773 at mit-eddie.MIT.EDU> shawn at mit-eddie.MIT.EDU
>(Shawn F. Mckay) writes:
>>One would think I could say something like:
>>
>>char	buff[20];
>>	tgetstr ("cl", buff);

In article <2565 at rsch.wisc.edu> dave at rsch.wisc.edu (Dave Cohrs) replies:
>Read the termcap(3) man page more carefully. ...  So you want to do:
>
>	char buff[20];
>	char *bufptr = buff;
>	(void) tgetstr("cl", &bufptr);

Closer; but it is worse than that.  Termcap's design is quite messy
and error-prone.  I once outlined a better design, but have never
bothered to implement it.

Termcap first requires that you copy the terminal capability string
into a buffer.  It then interprets the copied string into another
buffer.  Both buffers are `owned' by you but `taken over' by termcap;
the first must last through all tget* calls, and the second as long
as you wish to use the decoded strings.  The following is pretty
much the minimum code required to obtain just the clear screen
entry:

#ifdef this_works_but_is_not_a_good_idea_anyway

char	*getenv();

char *
get_clear_screen()
{
	char tbuf[1024];		/* used only during interpretation */
	static char expbuf[1024];	/* stores interpreted strings */
	char *ep;			/* pointer into expbuf */
	char *term;

	if ((term = getenv("TERM")) == NULL)
		return (NULL);		/* terminal type unavailable */

	/* -1 => no termcap file; 0 => termcap file but $TERM not found */
	if (tgetent(tbuf, term) != 1)
		return (NULL);		/* failed for some reason */
	ep = expbuf;
	return (tgetstr("cl", &ep));
}

#endif

#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>

/*
 * Before you can use `cl', you must also set `ospeed' and `PC':
 */
extern short ospeed;
extern char PC;

/*
 * ospeed should be set to the output speed of the terminal, as
 * returned by gtty() / ioctl(TIOCGETP).  PC should be set to
 * the terminal's pad character (result from tgetstr("pc")),
 * or the default, NUL ('\0').  Note that tgetstr("pc") either
 * returns NULL (in which case PC should be '\0') or a pointer
 * which must be dereferenced to get the pad character.
 *
 * For this reason, the `get_clear_screen' routine defined above
 * is pretty much useless anyway.  Instead, you need something
 * more like this:
 */

static char tbuf[1024];		/* for intermediate results */
static char expbuf[1024];	/* for expanded (decoded) strings */
static char *expp;		/* pointer into expbuf */

static int started_tc;		/* true => got termcap started */
static int no_tc;		/* true => termcap unavailable */

char	*getenv();

#define	start_tc()	if (started_tc) /*void*/; else fire_up_termcap()

/*
 * Set things up so that tgetent() et al. are OK
 */
static void
fire_up_termcap()
{
	char *term;
	struct sgttyb sg;

	started_tc++;			/* well, soon */
	if ((term = getenv("TERM")) == NULL || tgetent(tbuf, term) != 1) {
		no_tc++;		/* no termcap available */
		return;
	}
	expp = expbuf;			/* init expansion pointer *?
	if (ioctl(0, TIOCGETP, &sg))
		ospeed = B1200;		/* just a guess */
	else
		ospeed = sg.sg_ospeed;
}

/*
 * Wrapper for tgetstr().
 */
char *
get_termcap_string(name)
	char *name;
{

	start_tc();
	return (no_tc ? NULL : tgetstr(name, &expp));
}

/*
 * Get the clear screen entry, and set up the pad character so that
 * we can use it.
 */
char *
get_clear_screen()
{
	char *p;

	if ((p = get_termcap_string("pc")) != NULL)
		PC = *p;
	return (get_termcap_string("cl"));
}

/*
 * This can now be printed via
 *
 *	int outc(c) int c; { return (putchar(c)); }
 *	...
 *	p = get_clear_screen();
 *	tputs(p, 1, outc);
 *
 */

/*
 * For good measure, some interface routines for other termcap things,
 * and an `outc' routine:
 */
int
outc(c)
	int c;
{

	return (putchar(c));
}

/*
 * Wrapper for tgetnum().
 */
int
get_termcap_number(name)
	char *name;
{

	start_tc();
	return (no_tc ? -1 : tgetnum(name));
}

/*
 * Wrapper for tgetflag().
 */
int
get_termcap_flag(name)
	char *name;
{

	start_tc();
	return (no_tc ? 0 : tgetflag(name));
}
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris at umcp-cs		ARPA:	chris at mimsy.umd.edu



More information about the Comp.unix.wizards mailing list