[net.sources] TGRAPH

brandon@tdi2.UUCP (Brandon Allbery) (10/31/86)

#! /bin/sh
#
# Shell archive created Fri., Oct. 31, 1986 by tdi2!brandon.
# Contents:
#
#	-rw-r--r--   1 brandon  sys         2979 Oct 31 13:34 README
#	-rw-r--r--   1 brandon  sys          104 Oct 31 13:07 makefile
#	-rw-r--r--   1 brandon  sys         2120 Oct 31 12:49 tgraph.c
#	-rw-r--r--   1 brandon  sys         3910 Oct 31 13:15 tgload.c
#	-rw-r--r--   1 brandon  sys         1411 Oct 31 13:22 tgraph.h
#
# You may unpack this archive with sh or ksh, but not csh.
#

if test -r "README"; then
	echo "File README exists.  Enter new name or RETURN to skip.  (. to replace.)"
	read newname
	case "$newname" in
	".")	newname="README"
	esac
else
	newname="README"
fi
if test -z "$newname"; then
	echo "shx - $newname (skipped)"
else
	case "$newname" in
	"$sfile")
		echo "shx - $sfile (as $newname)"
		;;
	*)	echo "shx - $newname"
	esac
	sed 's/^X//' << '--EOF:README--' > "$newname"
XThis is tgraph, a character graphics package for SVR2 curses.  The main
Xfunction provided is also useful for SVR3 curses, which contains most of
Xthe rest of this package's functionality already.
X
XThe main user function is "wgraph(win, str)", which outputs graphic chars
Xas specified by str to the specified window.  This is something of a 
Xgeneralized "box" function.  The characters supported are:
X
X		newline:
X			print a newline
X
X		'-':
X			print a HLINE
X
X		'|':
X			print a VLINE
X
X		'+':
X			print a PLUS
X
X		'>':
X			print a LTEE
X
X		'<':
X			print a RTEE
X
X		'T':
X			print a TTEE
X
X		'i':
X			print a BTEE
X
X		'`':
X			print a LLCORNER
X
X		'/':
X			print a ULCORNER
X
X		',':
X			print a URCORNER
X
X		'.':
X			print a LRCORNER
X
X		'_':
X			print a horizontal bar on scan line 9
X
X		'=':
X			print a horizontal bar on scan line 1
X
X		'^':
X			print a UARROW
X
X		'v':
X			print a DARROW
X
X		'(':
X			print a LARROW
X
X		')':
X			print a RARROW
X
X		'$':
X			print a DIAMOND
X
X		'#':
X			print a CHECKERBOARD
X
X		'o':
X			print a DEGREE
X
X		'~':
X			print a PLMINUS
X
X		'*':
X			print a BULLET
X
X		'X':
X			print a BOARD
X
X		'I':
X			print a LANTERN
X
X		'@':
X			print a BLOCK
X
X		default:
X			print a space
X
XFor SVR2 curses, this package also defines the SVR3 special characters
XACS_*.  See tgraph.h for these.  They may be used anywhere a "character"
Xmay be passed to a curses function, e.g. addch(), box(), etc.
X
XYou must have defined the terminfo attributes:
X
X	sgr (parameter 9),
X	sgr0 (turn off parameter 9),
X	smacs (start special character set),
X	rmacs (end special character set)
X
XUnder SVR3 curses, you must also set up the following:
X
X	enacs (send terminal setup string for special character use),
X	acsc (character map for special characters; see your manual)
X
XUnder SVR2 curses, the special character set is specified by an ASCII file
Xin terminfo source format; by default, this file is /usr/lib/tgraph.  It
Xmay be changed via the environment variable TGRAPH.  Here is an example
Xtgraph database:
X
Xvt100 | vt100w | vt100-w | vt102,
X	hor=q, vert=x, ll=m, lr=j, ul=l, ur=k, utee=w, dtee=v, ltee=t, rtee=u,
X
Xwy50 | wy50w | wy50-w,
X	hor=:, vert=6, ll=1, lr=5, ul=2, ur=3, utee=0, dtee==, ltee=4, rtee=9,
X
X
XIf the terminal type isn't known to tgraph, it uses defaults -- these are the
Xsame as those used by SVR3 curses.
X
XThe tgraph database is similar to a terminfo source file.  However, the \s
Xescape sequence and escaped commas are not (yet) supported.  The capability
Xnames used are all strings, and only the first character of each is stored.
XThey are:
X
X        CAPNAME	      DEFAULT
X
X	"hor"		'-'
X	"vert"		'|'
X	"cross"		'+'
X	"ltee"		'+'
X	"rtee"		'+'
X	"utee"		'+'
X	"dtee"		'+'
X	"ll"		'+'
X	"ul"		'+'
X	"lr"		'+'
X	"ur"		'+'
X	"scan9"		'_'
X	"scan1"		'-'
X	"up"		'^'
X	"down"		'v'
X	"left"		'<'
X	"right"		'>'
X	"dimnd"		'+'
X	"check"		':'
X	"deg"		'\''
X	"plmin"		'#'
X	"bullet"	'o'
X	"board"		'#'
X	"lamp"		'#'
X	"block"		'#'
X
XOh -- who wants to try to hack this into 4.3BSD curses?  Can you specify an
XALTCHARSET attribute?
X
X++Brandon
--EOF:README--
fi

if test -r "makefile"; then
	echo "File makefile exists.  Enter new name or RETURN to skip.  (. to replace.)"
	read newname
	case "$newname" in
	".")	newname="makefile"
	esac
else
	newname="makefile"
fi
if test -z "$newname"; then
	echo "shx - $newname (skipped)"
else
	case "$newname" in
	"$sfile")
		echo "shx - $sfile (as $newname)"
		;;
	*)	echo "shx - $newname"
	esac
	sed 's/^X//' << '--EOF:makefile--' > "$newname"
X#CFLAGS = -O -Dstrchr=index
XCFLAGS = -O
X
Xtgraph.a: tgraph.o tgload.o
X	ar rcv tgraph.a tgraph.o tgload.o
--EOF:makefile--
fi

if test -r "tgraph.c"; then
	echo "File tgraph.c exists.  Enter new name or RETURN to skip.  (. to replace.)"
	read newname
	case "$newname" in
	".")	newname="tgraph.c"
	esac
else
	newname="tgraph.c"
fi
if test -z "$newname"; then
	echo "shx - $newname (skipped)"
else
	case "$newname" in
	"$sfile")
		echo "shx - $sfile (as $newname)"
		;;
	*)	echo "shx - $newname"
	esac
	sed 's/^X//' << '--EOF:tgraph.c--' > "$newname"
X/*
X * wgraph(str)
X *
X * translate a string to a graphics rendition, via the "graph" database.
X * The terminal-independent codes in str are:
X *
X *	-	horizontal line
X *	|	vertical line
X *	+	cross
X *	T	upper tee
X *	i	lower tee (look at an `i' on a vt100 for details)
X *	>	left tee
X *	<	right tee
X *	,	LR corner
X *	.	UR corner (backslash would be preferable but you can't gage it)
X *	`	LL corner
X *	/	UL corner
X *
X * On SVR2, this provides SVR3 curses characters ACS_* for use everywhere.
X */
X
X#include <curses.h>
X#ifndef ACS_DIAMOND
X#include "tgraph.h"
X#define _TGLOAD_
X#endif  ACS_DIAMOND
X
Xwgraph(win, str)
XWINDOW *win;
Xchar *str; {
X#ifdef _TGLOAD_
X	static int tgr = 0;
X	
X	if (tgr == 0) {
X		__tgr_load();
X		tgr = 1;
X	}
X#endif _TGLOAD_
X	while (*str != '\0') {
X		switch (*str) {
X		case '\n':
X			waddch(win, '\n');
X			break;
X		case '-':
X			waddch(win, ACS_HLINE);
X			break;
X		case '|':
X			waddch(win, ACS_VLINE);
X			break;
X		case '+':
X			waddch(win, ACS_PLUS);
X			break;
X		case '>':
X			waddch(win, ACS_LTEE);
X			break;
X		case '<':
X			waddch(win, ACS_RTEE);
X			break;
X		case 'T':
X			waddch(win, ACS_TTEE);
X			break;
X		case 'i':
X			waddch(win, ACS_BTEE);
X			break;
X		case '`':
X			waddch(win, ACS_LLCORNER);
X			break;
X		case '/':
X			waddch(win, ACS_ULCORNER);
X			break;
X		case ',':
X			waddch(win, ACS_URCORNER);
X			break;
X		case '.':
X			waddch(win, ACS_LRCORNER);
X			break;
X		case '_':
X			waddch(win, ACS_S9);
X			break;
X		case '=':
X			waddch(win, ACS_S1);
X			break;
X		case '^':
X			waddch(win, ACS_UARROW);
X			break;
X		case 'v':
X			waddch(win, ACS_DARROW);
X			break;
X		case '(':
X			waddch(win, ACS_LARROW);
X			break;
X		case ')':
X			waddch(win, ACS_RARROW);
X			break;
X		case '$':
X			waddch(win, ACS_DIAMOND);
X			break;
X		case '#':
X			waddch(win, ACS_CKBOARD);
X			break;
X		case 'o':
X			waddch(win, ACS_DEGREE);
X			break;
X		case '~':
X			waddch(win, ACS_PLMINUS);
X			break;
X		case '*':
X			waddch(win, ACS_BULLET);
X			break;
X		case 'X':
X			waddch(win, ACS_BOARD);
X			break;
X		case 'I':
X			waddch(win, ACS_LANTERN);
X			break;
X		case '@':
X			waddch(win, ACS_BLOCK);
X			break;
X		default:
X			waddch(win, ' ');
X			break;
X		}
X		str++;
X	}
X}
--EOF:tgraph.c--
fi

if test -r "tgload.c"; then
	echo "File tgload.c exists.  Enter new name or RETURN to skip.  (. to replace.)"
	read newname
	case "$newname" in
	".")	newname="tgload.c"
	esac
else
	newname="tgload.c"
fi
if test -z "$newname"; then
	echo "shx - $newname (skipped)"
else
	case "$newname" in
	"$sfile")
		echo "shx - $sfile (as $newname)"
		;;
	*)	echo "shx - $newname"
	esac
	sed 's/^X//' << '--EOF:tgload.c--' > "$newname"
X/*
X * wgraph(str)
X *
X * translate a string to a graphics rendition, via the "graph" database.
X * The terminal-independent codes in str are:
X *
X *	-	horizontal line
X *	|	vertical line
X *	+	cross
X *	T	upper tee
X *	i	lower tee (look at an `i' on a vt100 for details)
X *	>	left tee
X *	<	right tee
X *	,	LR corner
X *	.	UR corner (backslash would be preferable but you can't gage it)
X *	`	LL corner
X *	/	UL corner
X *
X * On SVR2, this provides SVR3 curses characters ACS_* for use everywhere.
X */
X
X#include <curses.h>
X
X#ifndef ACS_DIAMOND
X
Xextern char *strchr();
X
Xstruct graph {
X	char g_name[6];
X	char g_graph;
X} __graph[] = {
X	"hor",		'-',
X	"vert",		'|',
X	"cross",	'+',
X	"ltee",		'+',
X	"rtee",		'+',
X	"utee",		'+',
X	"dtee",		'+',
X	"ll",		'+',
X	"ul",		'+',
X	"lr",		'+',
X	"ur",		'+',
X	"scan9",	'_',
X	"scan1",	'-',
X	"up",		'^',
X	"down",		'v',
X	"left",		'<',
X	"right",	'>',
X	"dimnd",	'+',
X	"check",	':',
X	"deg",		'\'',
X	"plmin",	'#',
X	"bullet",	'o',
X	"board",	'#',
X	"lamp",		'#',
X	"block",	'#',
X	"",		'\0',
X};
X
Xextern char *getenv();
X
X/*
X * Format of tgraph database:  /usr/lib/tgraph
X *
X * ttyspec [ | ttyspec ...], name=ch, ...
X *
X * In other words, terminfo format.  However, a graphics code is ONE
X * character in length (this is forced by curses, unless someone wedges
X * wgraph into the curses source).
X *
X * NOTE:  They did (sVr3).  However, it remains one character per glyph.
X */
X
X__tgr_load() {
X	FILE *fp;
X	char *cp;
X
X	if ((cp = getenv("TGRAPH")) == (char *) 0)
X		cp = "/usr/lib/tgraph";
X	if ((fp = fopen(cp, "r")) == (FILE *) 0)
X		return;
X	if ((cp = getenv("TERM")) == (char *) 0)
X		cp = "unknown";
X	if (!__tgr_find(fp, cp))
X		return;
X	if (feof(fp)) {
X		fclose(fp);
X		return;
X	}
X	while (__tgr_gent(fp))
X		;
X	fclose(fp);
X}
X
X__tgr_find(fp, term)
XFILE *fp;
Xchar *term; {
X	char iline[1024];
X	char *cp, *dp;
X	char oldch;
X	
X	while (fgets(iline, sizeof iline, fp) != (char *) 0) {
X		if (iline[0] == '\n' || iline[0] == '\t' || iline[0] == ' ' || iline[0] == '#')
X			continue;
X		for (cp = iline; *cp != '\0' && *cp != '\n' && *cp != ','; cp++) {
X			while (*cp == ' ' || *cp == '\t')
X				cp++;
X			if (*cp == '\n' || *cp == ',' || *cp == '\0')
X				break;
X			for (dp = cp; *dp != ' ' && *dp != '\t' && *dp != ',' && *dp != '\n' && *dp != '\0'; dp++)
X				;
X			if (*dp == '\n' || *dp == '\0')
X				break;
X			oldch = *dp;
X			*dp = '\0';
X			if (strcmp(cp, term) == 0)
X				return 1;
X			if (oldch == '\n' || oldch == '\0')
X				break;
X			*dp = oldch;
X			cp = ++dp;
X		}
X	}
X	return 0;
X}
X
X__tgr_gent(fp)
XFILE *fp; {
X	static int atbol = 1;
X	char hunk[512];
X	char *hunkp;
X	char ch;
X	struct graph *tgrp;
X	
X	hunkp = hunk;
X	while ((ch = getc(fp)) != ',') {
X		if (feof(fp))
X			return 0;
X		if (ch == '\n') {
X			atbol = 1;
X			continue;
X		}
X		else if (atbol && ch != '\t' && ch != ' ')
X			return 0;
X		else if (hunkp == hunk && (ch == '\t' || ch == ' ')) {
X			atbol = 0;
X			continue;
X		}
X		else
X			atbol = 0;
X		*hunkp++ = ch;
X	}
X	*hunkp = '\0';
X	for (hunkp = hunk; *hunkp != '\0'; hunkp++)
X		if (*hunkp == '=')
X			break;
X	if (*hunkp == '\0')
X		return 1;
X	*hunkp++ = '\0';
X	for (tgrp = __graph; tgrp->g_name[0] != '\0'; tgrp++)
X		if (strcmp(tgrp->g_name, hunk) == 0)
X			break;
X	if (tgrp->g_name[0] == '\0')
X		return 1;
X	tgrp->g_graph = canon(hunkp) | A_ALTCHARSET;
X	return 1;
X}
X
Xcanon(str)
Xchar *str; {
X	char ch;
X
X	/* We only do the first character, that being the limit for curses */
X
X	switch (*str) {
X	case '\\':
X		switch (*++str) {
X		case 'n':
X			return '\n';
X		case 't':
X			return '\t';
X		case 'b':
X			return '\b';
X		case 'r':
X			return '\r';
X		case 'f':
X			return '\f';
X		case 'E':
X			return '\033';
X		case '0':
X		case '1':
X		case '2':
X		case '3':
X		case '4':
X		case '5':
X		case '6':
X		case '7':
X			ch = *str - '0';
X			while (*++str != '\0' && strchr("01234567", *str) != (char *) 0) {
X				ch *= 8;
X				ch += *str - '0';
X			}
X			return ch;
X		default:
X			return *str;
X		}
X	case '^':
X		return (*++str) & 0x1f;
X	default:
X		return *str;
X	}
X}
--EOF:tgload.c--
fi

if test -r "tgraph.h"; then
	echo "File tgraph.h exists.  Enter new name or RETURN to skip.  (. to replace.)"
	read newname
	case "$newname" in
	".")	newname="tgraph.h"
	esac
else
	newname="tgraph.h"
fi
if test -z "$newname"; then
	echo "shx - $newname (skipped)"
else
	case "$newname" in
	"$sfile")
		echo "shx - $sfile (as $newname)"
		;;
	*)	echo "shx - $newname"
	esac
	sed 's/^X//' << '--EOF:tgraph.h--' > "$newname"
X/*
X * Pseudo functions for use with TGRAPH
X * #include <curses.h> before use
X */
X
X#define graph(str)		 wgraph(stdscr, str)
X#define mvgraph(y, x, str)	 (move(y,x)==ERR?ERR:graph(str))
X#define mvwgraph(win, y, x, str) (wmove(win,y,x)==ERR?ERR:wgraph(win,str))
X
X#ifndef ACS_HLINE
X
X/*
X * SVr3-compatible ACS indexes
X */
X
Xextern struct __g__ch_ {
X	char g_name[6];
X	char g_graph;
X} __graph[];
X
X#define ACS_HLINE	(__graph[0].g_graph)
X#define ACS_VLINE	(__graph[1].g_graph)
X#define ACS_PLUS	(__graph[2].g_graph)
X#define ACS_LTEE	(__graph[3].g_graph)
X#define ACS_RTEE	(__graph[4].g_graph)
X#define ACS_TTEE	(__graph[5].g_graph)
X#define ACS_BTEE	(__graph[6].g_graph)
X#define ACS_LLCORNER	(__graph[7].g_graph)
X#define ACS_ULCORNER	(__graph[8].g_graph)
X#define ACS_URCORNER	(__graph[9].g_graph)
X#define ACS_LRCORNER	(__graph[10].g_graph)
X#define ACS_S9	(__graph[11].g_graph)
X#define ACS_S1	(__graph[12].g_graph)
X#define ACS_UARROW	(__graph[13].g_graph)
X#define ACS_DARROW	(__graph[14].g_graph)
X#define ACS_LARROW	(__graph[15].g_graph)
X#define ACS_RARROW	(__graph[16].g_graph)
X#define ACS_DIAMOND	(__graph[17].g_graph)
X#define ACS_CKBOARD	(__graph[18].g_graph)
X#define ACS_DEGREE	(__graph[19].g_graph)
X#define ACS_PLMINUS	(__graph[20].g_graph)
X#define ACS_BULLET	(__graph[21].g_graph)
X#define ACS_BOARD	(__graph[22].g_graph)
X#define ACS_LANTERN	(__graph[23].g_graph)
X#define ACS_BLOCK	(__graph[24].g_graph)
X
X#endif ACS_HLINE
--EOF:tgraph.h--
fi

echo "End of archive."
exit 0