Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site seismo.CSS.GOV Posting-Version: version B 2.10.2 9/3/84; site panda.UUCP Path: seismo!harvard!talcott!panda!sources-request From: sources-request@panda.UUCP Newsgroups: mod.sources Subject: tc: termcap capability in scripts Message-ID: <1115@panda.UUCP> Date: 15 Nov 85 12:54:13 GMT Sender: jpn@panda.UUCP Lines: 551 Approved: jpn@panda.UUCP 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 X#include 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~