[net.sources] C source for some TERMCAP

iverson@cory.Berkeley.EDU (Tim Iverson) (11/26/86)

Response for these files was rather large, so I am posting them
instead of using mail.  This allows those of you you don't want it
to see what's passing through your system on its way somewhere else.
To those who did request this source, I apologize for the long delay -
it was necessary to collect a sufficient number of requests in order to
decide whether posting was warranted or not.  Given the volume of requests
and the size of the code, it is warranted.  I hope some of you find this
useful.

Enclosed within are the files tputs.c, tgoto.c, tgetent.c, and
tgetstr.c.  These files incompletely implement the TERMCAP(3X)
routines (as found on most UNIX systems) for MS-DOS.  Tputs and
tgoto were obtained from the MS-DOS posting of Larn, while I wrote
the other two myself to allow a slightly more portable use of tputs
and tgoto.

For those who don't know what can be done with these routines,
they allow a program to treat most terminals with screen control
in a fairly standard manner, i.e. they permit the program to control
the cursor, add lines, delete lines, define scrolling regions (not
this implementation), etc. without resorting to using device specific
control codes.  For a more exact description, see the manual entries
'man 3 termcap' and 'man 5 termcap'.

Permission is hereby given to use this code in way you wish, whether
for profit or not.  You may even claim that you wrote it yourself
(uncool) or modify it to your little heart's content (real cool).

If anyone should decide to expand upon these routines in any way -
such as a curses library or something similar, please send me a copy,
I would greatly appreciate it.

Tim Iverson
iverson@cory.Berkeley.EDU
ucbvax!cory!iverson
~~~~~~~~~~~~~~~~~~~~~~~~ Cut Here ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	README
#	tgetent.c
#	tgetstr.c
#	tgoto.c
#	tputs.c
# This archive created: Wed Nov 26 00:44:52 1986
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'README'" '(1209 characters)'
if test -f 'README'
then
	echo shar: "will not over-write existing file 'README'"
else
cat << \!Funky!Stuff! > 'README'

Enclosed within are the files tputs.c, tgoto.c, tgetent.c, and
tgetstr.c.  These files incompletely implement the TERMCAP(3X)
routines (as found on most UNIX systems) for MS-DOS.  Tputs and
tgoto were obtained from the MS-DOS posting of Larn, while I wrote
the other two myself to allow a slightly more portable use of tputs
and tgoto.

For those who don't know what can be done with these routines,
they allow a program to treat most terminals with screen control
in a fairly standard manner, i.e. they permit the program to control
the cursor, add lines, delete lines, define scrolling regions (not
this implementation), etc. without resorting to using device specific
control codes.  For a more exact description, see the manual entries
'man 3 termcap' and 'man 5 termcap'.

Permission is hearby given to use this code in way you wish, whether
for proffit or not.  You may even claim that you wrote it yourself
(uncool) or modify it to your little heart's content (real cool).

If anyone should decide to expand upon these routines in any way -
such as a curses library or something similar, please send me a copy,
I would greatly appreciate it.

Tim Iverson
iverson@cory.Berkeley.EDU
ucbvax!cory!iverson
!Funky!Stuff!
fi  # end of overwriting check
echo shar: "extracting 'tgetent.c'" '(493 characters)'
if test -f 'tgetent.c'
then
	echo shar: "will not over-write existing file 'tgetent.c'"
else
cat << \!Funky!Stuff! > 'tgetent.c'
/*
 * termcap type tgetent() for f/nansi.sys
 *
 * Unlike UNIX, terminal type and buffer are ignored - the terminal
 * type  is assumed to be fansi.sys or nansi.sys (i.e ANSI 3.64).
 * For details see the UNIX TERMCAP(3X) man entry.
 */

int
tgetent(term_buf, type)
char *term_buf;		/* always a 1024 byte buffer that we ignore */
char *type;		/* terminal type - assumed to be f/nansi.sys */
{
	extern char *UP, *BC;

	UP = "\033[A";
	BC = "";
	return(1);	/* success! (well whaddya know?) */
}
!Funky!Stuff!
fi  # end of overwriting check
echo shar: "extracting 'tgetstr.c'" '(1588 characters)'
if test -f 'tgetstr.c'
then
	echo shar: "will not over-write existing file 'tgetstr.c'"
else
cat << \!Funky!Stuff! > 'tgetstr.c'
/*
 * tgetstr() for f/nansi.sys - tgetent must be called to init UP and BC
 * eventhough f/nansi.sys is assumed.
 *
 * As in the UNIX call, the area pointer is updated to point after
 * the end of the string and a pointer to the start of the string
 * is returned.  For details see the TERMCAP(3X) man entry.
 */

#include <stdio.h>
#include <string.h>

/*
 * The ansi termcap "data base".  Here things are stored as they
 * should appear to the calling routine, not as they are within
 * the termcap data base.  If some ambitious soul wishes to provide
 * true termcap support by making tgetent and tgetstr use a termcap
 * style data base, it would provide greater portability, but only
 * after much work.
 */
static struct
{
	char *id;
	char *value;
} ansi[] =
{
	/* from vt100 functions within io.c */
	"cm", "\033[%i%d;%dH",		/* was "\033[%i%d;%dH" */
	"ce", "\033[K",
	"cl", "\033[2J\033[1;36m",
	"al", "\033[L",			/* only for f/nansi.sys */
	"dl", "\033[M",			/* only for f/nansi.sys */
	"so", "\033[1;33m",		/* bold yellow (only f/nansi) */
	"se", "\033[1;36m",		/* bold cyan (only f/nansi) */
	"co", "80",			/* a kludge, but true */
	"li", "25",
	NULL, NULL,
};

char *
tgetstr(id, area)
char *id;
char **area;
{
	register int i;
	char *cp;

	/* find the apropriate string in the "data base" */
	for (i = 0; ansi[i].id != NULL; i++)
		if (strcmp(id, ansi[i].id) == 0) break;

	/* return NULL for missing entries */
	if (ansi[i].id == NULL) return NULL;

	/* copy the string into the area */
	strcpy(cp = *area, ansi[i].value);
	*area += strlen(ansi[i].value) + 1;
	return cp;
}
!Funky!Stuff!
fi  # end of overwriting check
echo shar: "extracting 'tgoto.c'" '(3456 characters)'
if test -f 'tgoto.c'
then
	echo shar: "will not over-write existing file 'tgoto.c'"
else
cat << \!Funky!Stuff! > 'tgoto.c'
/*
 * This file (tgoto.c) was distributed as public domain by
 *
 * Peter Kerrigan
 * ICOM Systems
 * 3415 N. Kennicott Ave.
 * Arlington Hts, IL, 60004, USA.
 * +1 312 506 1444
 * Net: peter@icom.uucp or ..!ihnp4!icom!peter
 *
 * Mr. Kerrigan stated that the he recieved this file in a public
 * domain distribution of ex/vi.  For those who believe that a copyright
 * infringement has occured, please contact Mr. Kerrigan.
 *
 * Modified 11/23/86 by Tim Iverson to not print CTL-Z under MSDOS
 *			just as CTL-D is not printed under UNIX.
 */

/* Copyright (c) 1979 Regents of the University of California */

#include <string.h>

/*
 * If you wish to convert this file to its previous form,
 * uncomment the following definition of CTRL, replace the
 * one occurance of EOF_CHAR with CTRL(d), and delete the
 * ifdef'd MSDOS section.  Why you would want to do this
 * I don't know, but maybe you do.
 */
/* #define	CTRL(c)	('c' & 037)	/* This look like a magic cookie */

#define	CTRL(C)		('C' - 'A' + 1)	/* works for ascii 'A' to 'Z' */
#ifdef	MSDOS			/* char to avoid printing */
#define	EOF_CHAR	CTRL(Z)	/* for MSC, kills all output 'till next \n */
#else
#define	EOF_CHAR	CTRL(D)	/* for UNIX machines, does something bad */
#endif	/* MSDOS */

char	*UP;
char	*BC;

/*
 * Routine to perform cursor addressing.
 * CM is a string containing printf type escapes to allow
 * cursor addressing.  We start out ready to print the destination
 * line, and switch each time we print row or column.
 * The following escapes are defined for substituting row/column:
 *
 *	%d	as in printf
 *	%2	like %2d
 *	%3	like %3d
 *	%.	gives %c hacking special case characters
 *	%+x	like %c but adding x first
 *	%<xy	if value < x add y, else just use valueindexing)
 *	%r	reverses row/column
 *	%i	increments row/column (for one origin indexing)
 *	%%	gives %
 *
 * all other characters are ``self-inserting''.
 */
char *
tgoto(CM, destcol, destline)
	char *CM;
	int destcol, destline;
{
	static char result[16];
	static char added[10];
	char *cp = CM;
	register char *dp = result;
	register int c;
	int oncol = 0;
	register int which;

	if (cp == 0) {
toohard:
		/*
		 * ``We don't do that under BOZO's big top''
		 */
		strcpy(result, "OOPS");
		return (result);
	}
	added[0] = 0;
	while (c = *cp++) {
		if (c != '%') {
			*dp++ = (char) c;
			continue;
		}
		which = oncol ? destcol : destline;
		switch (c = *cp++) {

		case 'n':
			destcol ^= 0140;
			destline ^= 0140;
			continue;

		case 'd':
			if (which < 10)
				goto one;
			if (which < 100)
				goto two;
			/* fall into... */

		case '3':
			*dp++ = (char) ((which / 100) | '0');
			which %= 100;
			/* fall into... */

		case '2':
two:	
			*dp++ = (char) (which / 10 | '0');
one:
			*dp++ = (char) (which % 10 | '0');
			oncol = 1 - oncol;
			continue;

		case '<':
			if (which < *dp++)
				which += *dp++;
			else
				dp++;
			goto casedot;

		case '+':
			which += *cp++;
			/* fall into... */

		case '.':
casedot:
			if (!UP)
				goto toohard;
			if (which == 0 || which == EOF_CHAR || which == '\t' || which == '\n') {
				do {
					strcat(added, oncol ? (BC ? BC : "\b") : UP);
					which++;
				} while (which == '\n');
			}
			*dp++ = (char) which;
			/* fall into... */

		case 'r':
			oncol = 1 - oncol;
			continue;

		case 'i':
			destcol++;
			destline++;
			continue;

		case '%':
			*dp++ = (char) c;
			continue;

		default:
			goto toohard;
		}
	}
	strcpy(dp, added);
	return (result);
}
!Funky!Stuff!
fi  # end of overwriting check
echo shar: "extracting 'tputs.c'" '(2200 characters)'
if test -f 'tputs.c'
then
	echo shar: "will not over-write existing file 'tputs.c'"
else
cat << \!Funky!Stuff! > 'tputs.c'
/*
 * This file (tputs.c) was distributed as public domain by
 *
 * Peter Kerrigan
 * ICOM Systems
 * 3415 N. Kennicott Ave.
 * Arlington Hts, IL, 60004, USA.
 * +1 312 506 1444
 * Net: peter@icom.uucp or ..!ihnp4!icom!peter
 *
 * Mr. Kerrigan stated that the he recieved this file in a public
 * domain distribution of ex/vi.  For those who believe that a copyright
 * infringement has occured, please contact Mr. Kerrigan.
 */

/* Copyright (c) 1979 Regents of the University of California */
#include <ctype.h>

/*
 * The following array gives the number of tens of milliseconds per
 * character for each speed as returned by gtty.  Thus since 300
 * baud returns a 7, there are 33.3 milliseconds per char at 300 baud.
 */
static
short	tmspc10[] = {
	0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10
};

short	ospeed;
char	PC;

/*
 * Put the character string cp out, with padding.
 * The number of affected lines is affcnt, and the routine
 * used to output one character is outc.
 */
tputs(cp, affcnt, outc)
	register char *cp;
	int affcnt;
	int (*outc)();
{
	register int i = 0;
	register int mspc10;

	if (cp == 0) return 0;

	/*
	 * Convert the number representing the delay.
	 */
	if (isdigit(*cp)) {
		do
			i = i * 10 + *cp++ - '0';
		while (isdigit(*cp));
	}
	i *= 10;
	if (*cp == '.') {
		cp++;
		if (isdigit(*cp))
			i += *cp - '0';
		/*
		 * Only one digit to the right of the decimal point.
		 */
		while (isdigit(*cp))
			cp++;
	}

	/*
	 * If the delay is followed by a `*', then
	 * multiply by the affected lines count.
	 */
	if (*cp == '*')
		cp++, i *= affcnt;

	/*
	 * The guts of the string.
	 */
	while (*cp)
		(*outc)(*cp++);

	/*
	 * If no delay needed, or output speed is
	 * not comprehensible, then don't try to delay.
	 */
	if (i == 0) return 0;
	if (ospeed <= 0 || ospeed >= (sizeof tmspc10 / sizeof tmspc10[0]))
		return 0;

	/*
	 * Round up by a half a character frame,
	 * and then do the delay.
	 * Too bad there are no user program accessible programmed delays.
	 * Transmitting pad characters slows many
	 * terminals down and also loads the system.
	 */
	mspc10 = tmspc10[ospeed];
	i += mspc10 / 2;
	for (i /= mspc10; i > 0; i--)
		(*outc)(PC);
}

!Funky!Stuff!
fi  # end of overwriting check
exit 0
#	End of shell archive