tc: termcap capability in scripts

sources-request at panda.UUCP sources-request at panda.UUCP
Fri Nov 15 22:54:13 AEST 1985


Mod.sources:  Volume 3, Issue 46
Submitted by: seismo!hao!cisden!lmc


tc is a program which inputs arguments denoting termcap capabilities on the
command line and then executes them. It gives shell scripts the same
termcap capabilities as C programs. Included is the program (tc.c) and a
manual page (tc.1). It is compiled with the command:

	cc tc.c -o tc -ltermlib

: This is a shar archieve.  Extract with sh, not csh.
: The rest of this file will extract:
: tc.c tc.1
echo extracting - tc.c
sed 's/^X//' > tc.c << '~FUNKY STUFF~'
X/*
X *      tc - termcaps for the shell.
X */
X#include <stdio.h>
X#include <ctype.h>
X
Xextern char *tgetdefstr(), *tgetstr(), *tgoto();
Xextern int tgetdefnum(), tgetnum();
X
Xtypedef struct tbl
X{   char *str;
X    short val;
X} lookuptbl;
X
X#define STRING  1
X#define STR1ARG 2
X#define STR2ARG 3
X#define NUMBER  4
X#define FLAG    5
X
Xlookuptbl tcaps[] = {
X	"AL",  STR1ARG,
X	"Bj",  STRING,
X	"Bl",  STRING,
X	"Br",  STRING,
X	"CC",  STRING,
X	"Cj",  STRING,
X	"CM",  STR2ARG,
X	"DC",  STR1ARG,
X	"DL",  STR1ARG,
X	"DO",  STR1ARG,
X	"EP",  FLAG,
X	"Ge",  STRING,
X	"Gs",  STRING,
X	"HD",  FLAG,
X	"Hl",  STRING,
X	"IC",  STR1ARG,
X	"K1",  STRING,
X	"K2",  STRING,
X	"K3",  STRING,
X	"K4",  STRING,
X	"K5",  STRING,
X	"LC",  FLAG,
X	"LE",  STR1ARG,
X	"Lj",  STRING,
X	"NL",  FLAG,
X	"OP",  FLAG,
X	"RI",  STR1ARG,
X	"Rj",  STRING,
X	"SF",  STR1ARG,
X	"SR",  STR1ARG,
X	"Tj",  STRING,
X	"Tl",  STRING,
X	"Tr",  STRING,
X	"UC",  FLAG,
X	"UP",  STR1ARG,
X	"Vl",  STRING,
X	"Xc",  STRING,
X	"ae",  STRING,
X	"al",  STRING,
X	"am",  FLAG,
X	"as",  STRING,
X	"bc",  STRING,
X	"bl",  STRING,
X	"bs",  FLAG,
X	"bt",  STRING,
X	"bw",  FLAG,
X	"cd",  STRING,
X	"ce",  STRING,
X	"ch",  STR1ARG,
X	"cl",  STRING,
X	"cm",  STR2ARG,
X	"co",  NUMBER,
X	"cr",  STRING,
X	"cs",  STR2ARG,
X	"ct",  STRING,
X	"cv",  STR1ARG,
X	"dB",  NUMBER,
X	"dC",  NUMBER,
X	"dF",  NUMBER,
X	"dN",  NUMBER,
X	"dT",  NUMBER,
X	"dV",  NUMBER,
X	"da",  FLAG,
X	"db",  FLAG,
X	"dc",  STRING,
X	"dl",  STRING,
X	"dm",  STRING,
X	"do",  STRING,
X	"ds",  STRING,
X	"ec",  STR1ARG,
X	"ed",  STRING,
X	"ei",  STRING,
X	"eo",  FLAG,
X	"es",  FLAG,
X	"ff",  STRING,
X	"fs",  STRING,
X	"gn",  FLAG,
X	"hc",  FLAG,
X	"hd",  STRING,
X	"ho",  STRING,
X	"hs",  FLAG,
X	"hu",  STRING,
X	"hz",  FLAG,
X	"ic",  STRING,
X	"if",  STRING,
X	"im",  STRING,
X	"in",  FLAG,
X	"ip",  STRING,
X	"is",  STRING,
X	"it",  NUMBER,
X	"k0",  STRING,
X	"k1",  STRING,
X	"k2",  STRING,
X	"k3",  STRING,
X	"k4",  STRING,
X	"k5",  STRING,
X	"k6",  STRING,
X	"k7",  STRING,
X	"k8",  STRING,
X	"k9",  STRING,
X	"kA",  STRING,
X	"kC",  STRING,
X	"kD",  STRING,
X	"kE",  STRING,
X	"kF",  STRING,
X	"kH",  STRING,
X	"kI",  STRING,
X	"kL",  STRING,
X	"kM",  STRING,
X	"kN",  STRING,
X	"kP",  STRING,
X	"kR",  STRING,
X	"kS",  STRING,
X	"kT",  STRING,
X	"ka",  STRING,
X	"kb",  STRING,
X	"kd",  STRING,
X	"ke",  STRING,
X	"kh",  STRING,
X	"kl",  STRING,
X	"km",  FLAG,
X	"kn",  NUMBER,
X	"ko",  STRING,
X	"kr",  STRING,
X	"ks",  STRING,
X	"kt",  STRING,
X	"ku",  STRING,
X	"l0",  STRING,
X	"l1",  STRING,
X	"l2",  STRING,
X	"l3",  STRING,
X	"l4",  STRING,
X	"l5",  STRING,
X	"l6",  STRING,
X	"l7",  STRING,
X	"l8",  STRING,
X	"l9",  STRING,
X	"le",  STRING,
X	"li",  NUMBER,
X	"ll",  STRING,
X	"lm",  NUMBER,
X	"ma",  STRING,
X	"mb",  STRING,
X	"md",  STRING,
X	"me",  STRING,
X	"mh",  STRING,
X	"mi",  FLAG,
X	"mk",  STRING,
X	"ml",  STRING,
X	"mm",  STRING,
X	"mo",  STRING,
X	"mp",  STRING,
X	"mr",  STRING,
X	"ms",  FLAG,
X	"mu",  STRING,
X	"nc",  FLAG,
X	"nd",  STRING,
X	"nl",  STRING,
X	"ns",  FLAG,
X	"nw",  STRING,
X	"os",  FLAG,
X	"pO",  STR1ARG,
X	"pb",  NUMBER,
X	"pc",  STRING,
X	"pf",  STRING,
X	"po",  STRING,
X	"ps",  STRING,
X	"pt",  FLAG,
X	"rP",  STRING,
X	"rc",  STRING,
X	"rf",  STRING,
X	"rp",  STR2ARG,
X	"rs",  STRING,
X	"sa",  STR2ARG,
X	"sc",  STRING,
X	"se",  STRING,
X	"sf",  STRING,
X	"sg",  NUMBER,
X	"so",  STRING,
X	"sr",  STRING,
X	"st",  STRING,
X	"ta",  STRING,
X	"tc",  STRING,
X	"te",  STRING,
X	"ti",  STRING,
X	"ts",  STR1ARG,
X	"uc",  STRING,
X	"ue",  STRING,
X	"ug",  NUMBER,
X	"ul",  FLAG,
X	"up",  STRING,
X	"us",  STRING,
X	"vb",  STRING,
X	"ve",  STRING,
X	"vi",  STRING,
X	"vs",  STRING,
X	"vt",  NUMBER,
X	"wi",  STRING,
X	"ws",  NUMBER,
X	"xb",  FLAG,
X	"xn",  FLAG,
X	"xo",  FLAG,
X	"xr",  FLAG,
X	"xs",  FLAG,
X	"xt",  FLAG,
X	"xv",  FLAG,
X	"xx",  FLAG,
X};
X
Xputx(c) { putchar (c); }
X
Xmain (argc, argv)
X    int argc;
X    char **argv;
X{
X    char tcbuf[1024];
X    char *cp, *arg;
X    int i, tgetnum(), tgetflag();
X    static int aflag = 0;
X
X    if (tgetent(tcbuf, getenv ("TERM")) <= 0) {
X	(void) fprintf (stderr, "tc: cannot find termcap for %s.\n", getenv ("TERM"));
X	exit (1);
X    }
X    cp = (char *) malloc (256);
X    argv++;
X    while (*argv) {
X	arg = *argv++;
X	if (strcmp (arg, "-a") == 0) {
X	    aflag = 1;
X	    continue;
X	}
X	i = lookup (arg, tcaps);
X	if (i < 0) {
X	    (void) fprintf (stderr, "tc: no such termcap: %s\n", arg);
X	    exit (2);
X	}
X	switch (tcaps[i].val & 017) {
X	case STRING:
X	    if (aflag)
X		show (tgetdefstr (arg, &cp));
X	    else
X		tputs (tgetdefstr (arg, &cp), 1, putx);
X	    break;
X	case STR1ARG:
X	    if (aflag)
X		show (tgetstr (arg, &cp));
X	    else
X		if (argv != NULL && isdigit (**argv))
X		    tputs (tgoto (tgetstr (arg, &cp),
X			atoi (*argv++), 0), 1, putx);
X		else {
X		    (void) fprintf (stderr, "tc: error in arguments to %s\n", arg);
X		    exit(3);
X		}
X	    break;
X	case STR2ARG:
X	    if (aflag)
X		show (tgetstr (arg, &cp));
X	    else
X		if (argv != NULL && argv[1] != NULL &&
X		    isdigit (**argv) && isdigit (*(argv[1])))
X		    tputs (tgoto (tgetstr (arg, &cp),
X			atoi (*argv++), atoi (*argv++)), 1, putx);
X		else {
X		    (void) fprintf (stderr, "tc: error in arguments to %s\n", arg);
X		    exit(3);
X		}
X	    break;
X	case NUMBER:
X	    if (aflag)
X		(void) printf ("%d\n", tgetdefnum (arg));
X	    break;
X	case FLAG:
X	    if (aflag)
X		(void) printf (tgetflag (arg) ? "true\n" : "false\n");
X	    break;
X	}
X    }
X    exit (0);
X}
X
X
X
X#define MAXLUPN 3      /* longer than longest possible name */
X/*  Lookup name in table.  Will take nonambiguous abbreviations.  If you
X    want to insist that a certain table entry must be spelled out, enter
X    it twice in the table.  Table entries must be sorted by name, and a
X    name which is a substring of a longer name comes earlier in the table.
X    Accepts upper or lower case if table entry is lower case.
X    Returns:
X     > 0 table entry index
X      -1 not found
X      -2 ambiguous
X*/
Xint lookup (name, table)
X    char *name;
X    lookuptbl *table;
X{
X    register char  *namptr,
X		   *tblptr;
X    int ind;
X    int value = 0;
X    short length;
X    short longest = 0;
X    int ambig = 0;
X    char lname[MAXLUPN];
X
X    if (name == NULL)
X	return -1;
X    namptr = name;
X    tblptr = lname;
X    for (;;) {
X	if ((*tblptr++ = isupper (*namptr)? tolower (*namptr++): *namptr++)
X	    == '\0')
X	    break;
X	if (tblptr >= &lname[MAXLUPN])
X	    return -1;
X    }
X
X    for (ind = 0; (tblptr = table->str) != 0; table++, ind++) {
X	namptr = lname;
X	for (; *tblptr == *namptr; tblptr++, namptr++) {
X	    if (*tblptr == '\0')
X		break;
X	}
X	if (*namptr == '\0') {  /* end of name or exact match */
X	    length = namptr - lname;
X	    if (longest < length) {
X		longest = length;
X		ambig = 0;
X		value = ind;
X		if (*tblptr == '\0')
X		    break;          /* exact match */
X	    }
X	    else /* longest == length */
X		ambig = 1;
X	}
X	else if ( *namptr < *tblptr )
X	    break;
X    }
X    if (ambig)
X	return -2;
X    if (longest)
X	return value;
X    return -1;
X}
X
X
Xshow (str)
X    char *str;
X{
X    char c;
X
X    if (str == (char *)0) {
X	(void) printf ("NULL\n");
X	return;
X    }
X    while (c = *str++ & 127)
X	if (c < ' ') {
X	    if (c == 27)
X		(void) printf ("\n");
X	    (void) printf ("^%c", c + '@');
X	} else if (c == 127)
X	    (void) printf ("^?");
X	else
X	    (void) printf ("%c", c);
X    (void) printf ("\n");
X    return;
X}
X
Xchar *
Xtgetdefstr (cap, ptr)
X    char *cap, *ptr;
X{
X    char *x;
X    static char *bs = "\b",
X		*ht = "\t",
X		*nl = "\n",
X		*cr = "\r",
X		*ff = "\f",
X		*nu = "\0",
X		*bl = "\007",
X		*nlcr = "\n\r";
X
X    if ((x = tgetstr (cap, ptr)) != (char *) 0)
X	return (x);
X    if (strcmp (cap, "pc") == 0)
X	return (nu);
X    if (strcmp (cap, "bc") == 0)
X	return (bs);
X    if (strcmp (cap, "ta") == 0)
X	return (ht);
X    if (strcmp (cap, "nl") == 0)
X	return (nl);
X    if (strcmp (cap, "cr") == 0)
X	return (cr);
X    if (strcmp (cap, "ff") == 0)
X	return (ff);
X    if (strcmp (cap, "nw") == 0)
X	return (nlcr);
X    if (strcmp (cap, "bl") == 0)
X	return (bl);
X    if (strcmp (cap, "ho") == 0)
X	return (tgoto (tgetstr ("cm", ptr), 0, 0));
X    if (strcmp (cap, "ll") == 0)
X	return (tgoto (tgetstr ("cm", ptr), tgetnum ("li") - 1, 0));
X    if (strcmp (cap, "rs") == 0)
X	return (tgetstr ("is", ptr));
X    if (strcmp (cap, "is") == 0)
X	return (tgetstr ("rs", ptr));
X    if (strcmp (cap, "rf") == 0)
X	return (tgetstr ("if", ptr));
X    if (strcmp (cap, "if") == 0)
X	return (tgetstr ("rf", ptr));
X
X    return ((char *) 0);
X}
X
X
Xtgetdefnum (cap)
X    char *cap;
X{
X    int x;
X
X    if ((x = tgetnum (cap)) != -1)
X	return (x);
X    if (strcmp (cap, "ws") == 0)
X	return (tgetnum ("co"));
X    return (0);
X}
~FUNKY STUFF~
echo extracting - tc.1
sed 's/^X//' > tc.1 << '~FUNKY STUFF~'
X.TH TC 1 "28 October 1985"
X.SH NAME
Xtc \- supply termcap capabilities to shell scripts
X.SH SYNOPSIS
X.B tc
X[ -a ] [ cap ] ...
X.SH DESCRIPTION
X.I Tc
Xperforms termcap services at the
Xshell level. Each of the arguments
Xconsists of the name of a termcap
Xcapability followed by optional
Xarguments. There may be any number of
Xarguments. The termcaps mentioned in
Xthe arguments are performed left to
Xright until the list is complete or
Xan error occurs.
X.LP
XThe
X.B -a
Xoption specifies that the termcap is
Xto be echoed to the screen in "ascii"
Xmode, where control characters are
Xdisplayed as ^x and escape characters
X(^[) are preceeded by new-lines.
XNumeric capabilities
Xare displayed in this mode as numbers
Xand flags by either "true" or
X"false"; without the
X.B -a
Xflag numeric and flag capabilities
Xare silently skipped.
X.LP
XThe capabilities that require
Xarguments (like cm and ch) check the
Xnext argument(s) for being
Xnumeric, and if so, are used;
Xotherwise an error is displayed and
Xan error exit taken.
X.LP
XA number of defaults are used when
Xcaps are not found in the terminal
Xdefinition. Some of these are spelled out in
Xtermcap(5), some are common sense:
X
X.nf
X.ul
X	cap     default if not found
X	bc      "\\b"
X	pc      "\\0"
X	ta      "\\t"
X	nl      "\\n"
X	cr      "\\r"
X	ff      "\\f"
X	nw      "\\n\\r"
X	ho      direct cursor motion to 0,0
X	ll      direct cursor motion to tgetnum("li")-1, 0
X	rs      is
X	is      rs
X	rf      if
X	if      rf
X	ws      co
X	unknown numbers default to zero
X
X.fi
X.SH "STATUS RETURNS"
XReturns status of 1 if terminal name
Xnot found, 2 if required cap not
Xa legal capability, 3 for argument error.
X.SH "SEE ALSO"
Xtct(1), termcap(3), termcap(5)
X.SH BUGS
XContains an internal database of
Xwhich capabilities exist, require arguments
Xand are numeric and flags. Will
Xrequire updating if list ever
Xchanges.
X.SH AUTHOR
XLyle McElhaney
~FUNKY STUFF~



More information about the Mod.sources mailing list