Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.2 9/18/84; site gitpyr.UUCP
Path: utzoo!watmath!clyde!bonnie!akgua!gatech!gitpyr!robert
From: rob...@gitpyr.UUCP (Robert Viduya)
Newsgroups: net.sources
Subject: termcap to terminfo translator
Message-ID: <83@gitpyr.UUCP>
Date: Wed, 30-Jan-85 15:42:01 EST
Article-I.D.: gitpyr.83
Posted: Wed Jan 30 15:42:01 1985
Date-Received: Fri, 1-Feb-85 23:35:32 EST
Distribution: net
Organization: Georgia Tech, Atlanta
Lines: 790
The following is a program that converts termcap database files to terminfo
source files. It reads the termcap file from standard input and writes the
terminfo source to standard output. I tried to be as complete as possible,
but I wasn't able to implement some things due to ambiguous documentation.
The unimplemented parts are in the %-escapes. I wasn't sure about some
of the more exotic termcap %-escapes like '%B'. However, things like '%c',
'%d', '%2d' and '%+' are implemented.
as usual, send bug reports...
robert
------
#!/bin/sh
# Posted from gitpyr!robert
# Run the following text with /bin/sh to create:
# Makefile
# captoinfo.c
# getcap.c
# putinfo.c
# tget.c
sed 's/^X//' << '--burp--' > Makefile
XCFLAGS = -O
XOBJS = captoinfo.o getcap.o putinfo.o tget.o
X
Xcaptoinfo: $(OBJS)
X cc $(CFLAGS) $(OBJS) -o captoinfo
X
Xcaptoinfo.o: captoinfo.c
X
Xgetcap.o: getcap.c
X
Xputinfo.o: putinfo.c
X
Xtget.o: tget.c
--burp--
sed 's/^X//' << '--burp--' > captoinfo.c
X/*
X * captoinfo:
X * Translate termcap terminal database to terminfo source
X * format.
X *
X * Captoinfo reads standard input, which is assumed to be
X * a termcap file and writes the equivalent to standard
X * output in terminfo source format.
X *
X * Robert Viduya - Georgia Institute of Technology.
X *
X * gitpyr!robert
X */
X#include <stdio.h>
X
X#define bool char
X#define TRUE 1
X#define FALSE 0
X
Xchar buffer[2048];
X
X
Xmain ()
X{
X int c;
X
X while ((c = getchar ()) != EOF) {
X if (c == '#') {
X (void) putchar (c);
X do {
X c = getchar ();
X (void) putchar (c);
X } while (c != '\n');
X }
X else {
X if (ungetc (c, stdin) == EOF) {
X fprintf (stderr, "ungetc failed.\n");
X exit (1);
X }
X get_termcap ();
X print_name ();
X print_bools ();
X print_nums ();
X print_strs ();
X }
X }
X exit (0);
X}
--burp--
sed 's/^X//' << '--burp--' > getcap.c
X#include <stdio.h>
X#include <ctype.h>
X
X#define bool char
X#define TRUE 1
X#define FALSE 0
X
Xextern char buffer[];
X
X
X/*
X * get_termcap:
X * read next termcap entry into buffer from standard input.
X */
Xget_termcap ()
X{
X int c;
X char *bptr;
X
X bptr = buffer;
X while ((c = getchar ()) != '\n') {
X if (c == '\\') {
X if ((c = getchar ()) != '\n') {
X if (ungetc (c, stdin) == EOF) {
X fprintf (stderr, "ungetc failed.\n");
X exit (1);
X }
X *(bptr++) = '\\';
X }
X }
X else {
X *(bptr++) = c;
X }
X }
X *bptr = '\0';
X}
--burp--
sed 's/^X//' << '--burp--' > putinfo.c
X#include <stdio.h>
X#include <strings.h>
X#include <ctype.h>
X
X#define bool char
X#define TRUE 1
X#define FALSE 0
X
X#define MAXINDEX(array) (sizeof(array)/sizeof(array[0]))
X
X/*
X * bools & boolcaps:
X * lookup translate table for boolean fields.
X */
Xstruct bools {
X char *capname; /* termcap name */
X char *infoname; /* terminfo name */
X};
Xstruct bools boolcaps[] = {
X { "bw", "bw" }, { "am", "am" }, { "xb", "xsb" },
X { "xs", "xhp" }, { "xn", "xenl" }, { "eo", "eo" },
X { "gn", "gn" }, { "hc", "hc" }, { "km", "km" },
X { "hs", "hs" }, { "in", "in" }, { "da", "da" },
X { "db", "db" }, { "mi", "mir" }, { "ms", "msgr" },
X { "os", "os" }, { "es", "eslok" }, { "xt", "xt" },
X { "hz", "hz" }, { "ul", "ul" }, { "xo", "xon" }
X};
X#define MAXBOOLS MAXINDEX(boolcaps)
X
X/*
X * nums & numcaps:
X * lookup translate table for numeric capabilities.
X */
Xstruct nums {
X char *capname; /* termcap name */
X char *infoname; /* terminfo name */
X};
Xstruct nums numcaps[] = {
X { "co", "cols" }, { "it", "it" }, { "li", "lines" },
X { "lm", "lm" }, { "sg", "xmc" }, { "pb", "pb" },
X { "vt", "vt" }, { "ws", "wsl" }
X};
X#define MAXNUMS MAXINDEX(numcaps)
X
X/*
X * strs & strcaps:
X * lookup translate table for string capabilities.
X */
Xstruct strs {
X char *capname; /* termcap name */
X char *infoname; /* terminfo name */
X char *dflt; /* default value */
X};
Xstruct strs strcaps[] = {
X { "bt", "cbt", ((char *)0) },
X { "bl", "bel", "\007" },
X { "cr", "cr", "\r" },
X { "cs", "csr", ((char *)0) },
X { "ct", "tbc", ((char *)0) },
X { "cl", "clear", ((char *)0) },
X { "ce", "el", ((char *)0) },
X { "cd", "ed", ((char *)0) },
X { "ch", "hpa", ((char *)0) },
X { "CC", "cmdch", ((char *)0) },
X { "cm", "cup", ((char *)0) },
X { "do", "cud1", "\n" },
X { "ho", "home", ((char *)0) },
X { "vi", "civis", ((char *)0) },
X { "le", "cub1", "\b" }, /* special case - check bc */
X { "CM", "mrcup", ((char *)0) },
X { "ve", "cnorm", ((char *)0) },
X { "nd", "cuf1", ((char *)0) },
X { "ll", "ll", ((char *)0) },
X { "up", "cuu1", ((char *)0) },
X { "vs", "cvvis", ((char *)0) },
X { "dc", "dch1", ((char *)0) },
X { "dl", "dl1", ((char *)0) },
X { "ds", "dsl", ((char *)0) },
X { "hd", "hd", ((char *)0) },
X { "as", "smacs", ((char *)0) },
X { "mb", "blink", ((char *)0) },
X { "md", "bold", ((char *)0) },
X { "ti", "smcup", ((char *)0) },
X { "dm", "smdc", ((char *)0) },
X { "mh", "dim", ((char *)0) },
X { "im", "smir", ((char *)0) },
X { "mp", "prot", ((char *)0) },
X { "mr", "rev", ((char *)0) },
X { "mk", "invis", ((char *)0) },
X { "so", "smso", ((char *)0) },
X { "us", "smul", ((char *)0) },
X { "ec", "ech", ((char *)0) },
X { "ae", "rmacs", ((char *)0) },
X { "me", "sgr0", ((char *)0) },
X { "te", "rmcup", ((char *)0) },
X { "ed", "rmdc", ((char *)0) },
X { "ei", "rmir", ((char *)0) },
X { "se", "rmso", ((char *)0) },
X { "ue", "rmul", ((char *)0) },
X { "vb", "flash", ((char *)0) },
X { "ff", "ff", ((char *)0) },
X { "fs", "fsl", ((char *)0) },
X { "is", "is1", ((char *)0) },
X { "i1", "is2", ((char *)0) },
X { "i2", "is3", ((char *)0) },
X { "if", "if", ((char *)0) },
X { "ic", "ich1", ((char *)0) },
X { "al", "il1", ((char *)0) },
X { "ip", "ip", ((char *)0) },
X { "kb", "kbs", "\b" },
X { "ka", "ktbc", ((char *)0) },
X { "kC", "kclr", ((char *)0) },
X { "kt", "kctab", ((char *)0) },
X { "kD", "kdch1", ((char *)0) },
X { "kL", "kdl1", ((char *)0) },
X { "kd", "kcud1", "\n" },
X { "kM", "krmir", ((char *)0) },
X { "kE", "kel", ((char *)0) },
X { "kS", "ked", ((char *)0) },
X { "k0", "kf0", ((char *)0) },
X { "k1", "kf1", ((char *)0) },
X { "k2", "kf2", ((char *)0) },
X { "k3", "kf3", ((char *)0) },
X { "k4", "kf4", ((char *)0) },
X { "k5", "kf5", ((char *)0) },
X { "k6", "kf6", ((char *)0) },
X { "k7", "kf7", ((char *)0) },
X { "k8", "kf8", ((char *)0) },
X { "k9", "kf9", ((char *)0) },
X { "kh", "khome", ((char *)0) },
X { "kI", "kich1", ((char *)0) },
X { "kA", "kil1", ((char *)0) },
X { "kl", "kcub1", "\b" },
X { "kH", "kll", ((char *)0) },
X { "kN", "knp", ((char *)0) },
X { "kP", "kpp", ((char *)0) },
X { "kr", "kcuf1", ((char *)0) },
X { "kF", "kind", ((char *)0) },
X { "kR", "kri", ((char *)0) },
X { "kT", "khts", ((char *)0) },
X { "ku", "kcuu1", ((char *)0) },
X { "ke", "rmkx", ((char *)0) },
X { "ks", "smkx", ((char *)0) },
X { "l0", "lf0", ((char *)0) },
X { "l1", "lf1", ((char *)0) },
X { "l2", "lf2", ((char *)0) },
X { "l3", "lf3", ((char *)0) },
X { "l4", "lf4", ((char *)0) },
X { "l5", "lf5", ((char *)0) },
X { "l6", "lf6", ((char *)0) },
X { "l7", "lf7", ((char *)0) },
X { "l8", "lf8", ((char *)0) },
X { "l9", "lf9", ((char *)0) },
X { "mm", "smm", ((char *)0) },
X { "mo", "rmm", ((char *)0) },
X { "nw", "nel", "\r\n" },
X { "pc", "pad", ((char *)0) },
X { "DC", "dch", ((char *)0) },
X { "DL", "dl", ((char *)0) },
X { "DO", "cud", ((char *)0) },
X { "IC", "ich", ((char *)0) },
X { "SF", "indn", ((char *)0) },
X { "AL", "il", ((char *)0) },
X { "LE", "cub", ((char *)0) },
X { "RI", "cuf", ((char *)0) },
X { "SR", "rin", ((char *)0) },
X { "UP", "cuu", ((char *)0) },
X { "pk", "pfkey", ((char *)0) },
X { "pl", "pfloc", ((char *)0) },
X { "px", "pfx", ((char *)0) },
X { "ps", "mc0", ((char *)0) },
X { "pf", "mc4", ((char *)0) },
X { "po", "mc5", ((char *)0) },
X { "rp", "rep", ((char *)0) },
X { "rs", "rs1", ((char *)0) },
X { "r1", "rs2", ((char *)0) },
X { "r2", "rs3", ((char *)0) },
X { "rf", "rf", ((char *)0) },
X { "rc", "rc", ((char *)0) },
X { "cv", "vpa", ((char *)0) },
X { "sc", "sc", ((char *)0) },
X { "sf", "ind", "\n" },
X { "sr", "ri", ((char *)0) },
X { "sa", "sgr", ((char *)0) },
X { "st", "hts", ((char *)0) },
X { "wi", "wind", ((char *)0) },
X { "ta", "ht", ((char *)0) }, /* conditional - check pt */
X { "ts", "tsl", ((char *)0) },
X { "uc", "uc", ((char *)0) },
X { "hu", "hu", ((char *)0) },
X { "iP", "iprog", ((char *)0) },
X { "K1", "ka1", ((char *)0) },
X { "K2", "kb2", ((char *)0) },
X { "K3", "ka3", ((char *)0) },
X { "K4", "kc1", ((char *)0) },
X { "K5", "kc3", ((char *)0) },
X { "pO", "mc5p", ((char *)0) },
X { "tc", "use", ((char *)0) }
X};
X#define MAXSTRS MAXINDEX(strcaps)
X
Xint tgetname (); /* get termcap name */
Xint tgetflag (); /* get termcap boolean value */
Xint tgetnum (); /* get termcap numeric value */
Xint tgetstr (); /* get termcap string value */
X
X
X/*
X * print_name:
X * print name and aliases of current termcap entry.
X */
Xprint_name ()
X{
X char name[100];
X
X tgetname (name);
X printf ("%s,\n", name);
X}
X
X/*
X * print_bools:
X * print all boolean fields of current termcap entry.
X */
Xprint_bools ()
X{
X int i, val;
X bool stuffprinted = FALSE;
X
X for (i = 0; i < MAXBOOLS; i++)
X if (val = tgetflag (boolcaps[i].capname)) {
X if (val == 1)
X printf ("\t%s,", boolcaps[i].infoname);
X else
X printf ("\t%s@,", boolcaps[i].infoname);
X stuffprinted = TRUE;
X }
X if (stuffprinted)
X (void) putchar ('\n');
X}
X
X/*
X * print_nums:
X * print all numeric fields of current termcap entry.
X */
Xprint_nums ()
X{
X int i, capval;
X bool stuffprinted = FALSE;
X
X for (i = 0; i < MAXNUMS; i++)
X if ((capval = tgetnum (numcaps[i].capname)) >= 0) {
X printf ("\t%s#%d,", numcaps[i].infoname, capval);
X stuffprinted = TRUE;
X }
X else if (capval == -2) {
X printf ("\t%s@,", numcaps[i].infoname);
X stuffprinted = TRUE;
X }
X if (stuffprinted)
X (void) putchar ('\n');
X}
X
X/*
X * print_strs:
X * print all string fields of current termcap entry.
X */
Xprint_strs ()
X{
X int i, count = 0;
X char capval[100];
X
X for (i = 0; i < MAXSTRS; i++) {
X tgetstr (strcaps[i].capname, capval);
X if (!capval[0]) {
X if (strcmp (strcaps[i].capname, "le") == 0) {
X tgetstr ("bc", capval);
X }
X else if (strcmp (strcaps[i].capname, "ta") == 0) {
X if (tgetflag ("pt")) {
X capval[0] = '\t';
X capval[1] = '\0';
X }
X }
X }
X if ((!capval[0]) && (strcaps[i].dflt))
X (void) strcpy (capval, strcaps[i].dflt);
X if (capval[0]) {
X if (strcmp (capval, "@") != 0) {
X printf ("\t%s=", strcaps[i].infoname);
X if (strcmp(strcaps[i].infoname,"use") != 0) {
X put_str (capval);
X printf (",");
X }
X else
X printf ("%s,", capval);
X }
X else
X printf ("%s@,", strcaps[i].infoname);
X count++;
X if (!(count %= 3))
X putchar ('\n');
X }
X }
X if (count)
X (void) putchar ('\n');
X}
X
X/*
X * put_str:
X * translate strings to printable format and print them.
X */
Xput_str (s)
Xchar *s;
X{
X bool rflag = FALSE; /* % codes */
X char *c;
X int parm;
X
X if ((isdigit (*s)) || (*s == '.')) { /* handle padding */
X printf ("$<");
X while ((isdigit (*s)) || (*s == '.')) {
X (void) putchar (*s);
X s++;
X }
X if (*s == '*') {
X (void) putchar (*s);
X s++;
X }
X (void) putchar ('>');
X }
X for (c = s; *c; c++) { /* scan for % codes (needs work) */
X if (*c == '%') {
X c++;
X switch (*c) {
X case 'r':
X rflag = TRUE;
X break;
X default:
X break; /* ignore */
X }
X }
X }
X parm = 0;
X while (*s) { /* print the string */
X switch (*s) {
X case '%':
X s++;
X switch (*s) {
X case '%':
X printf ("%%%%");
X break;
X case 'i':
X printf ("%%i");
X break;
X case 'd':
X parm++;
X if ((rflag) && (parm <= 2)) {
X if (parm == 1)
X printf ("%%p2%%d");
X else
X printf ("%%p1%%d");
X }
X else
X printf ("%%p%d%%d", parm);
X break;
X case '2':
X parm++;
X if ((rflag) && (parm <= 2)) {
X if (parm == 1)
X printf ("%%p2%%02d");
X else
X printf ("%%p1%%02d");
X }
X else
X printf ("%%p%d%%02d", parm);
X break;
X case '3':
X parm++;
X if ((rflag) && (parm <= 2)) {
X if (parm == 1)
X printf ("%%p2%%03d");
X else
X printf ("%%p1%%03d");
X }
X else
X printf ("%%p%d%%03d", parm);
X break;
X case '.':
X parm++;
X if ((rflag) && (parm <= 2)) {
X if (parm == 1)
X printf ("%%p2%%c");
X else
X printf ("%%p1%%c");
X }
X else
X printf ("%%p%d%%c", parm);
X break;
X case '+':
X s++;
X parm++;
X if ((rflag) && (parm <= 2)) {
X if (parm == 1)
X printf ("%%p2%%'%c'%%+%%c", *s);
X else
X printf ("%%p1%%'%c'%%+%%c", *s);
X }
X else
X printf ("%%p%d%%'%c'%%+%%c", parm, *s);
X break;
X default:
X break; /* ignore */
X }
X break;
X case '\200':
X printf ("\\0");
X break;
X case '\177':
X printf ("^?");
X break;
X case ',':
X printf ("\\,");
X break;
X case '\\':
X printf ("\\\\");
X break;
X case '^':
X printf ("\\^");
X break;
X case ':':
X printf ("\\:");
X break;
X case '\033':
X printf ("\\E");
X break;
X case '\n':
X printf ("\\n");
X break;
X case '\r':
X printf ("\\r");
X break;
X case '\t':
X printf ("\\t");
X break;
X case '\b':
X printf ("\\b");
X break;
X case '\f':
X printf ("\\f");
X break;
X case ' ':
X printf ("\\s");
X break;
X default:
X if (*s < ' ')
X printf ("^%c", *s + 'A' - 1);
X else
X (void) putchar (*s);
X break;
X }
X s++;
X }
X}
--burp--
sed 's/^X//' << '--burp--' > tget.c
X#include <stdio.h>
X#include <ctype.h>
X#include <strings.h>
X
X#define bool char
X#define TRUE 1
X#define FALSE 0
X
Xextern char buffer[];
X
X
X/*
X * scan:
X * scan for character in string, return position of character.
X * similar to index/strchr, except that if char not found, returns
X * pointer to null at end of string, instead of a null pointer.
X */
Xchar *
Xscan (s, c)
Xregister char *s;
Xregister char c;
X{
X while ((*s) && (*s != c))
X s++;
X return (s);
X}
X
X/* findcap:
X * returns pointer to just after capname (trailing ':' for flags,
X * '#' for nums, '=' for strs, '@' for disabled stuff) or to null
X * after termcap if not found.
X */
Xchar *
Xfindcap (capname)
Xchar *capname;
X{
X register char *bptr = buffer;
X register bool found = FALSE;
X char cap[3];
X
X cap[2] = '\0';
X while ((!found) && (*bptr)) {
X bptr = scan (bptr, ':');
X if (*bptr) {
X cap[0] = *(bptr + 1);
X cap[1] = *(bptr + 2);
X if (strcmp (cap,capname) == 0) {
X found = TRUE;
X bptr += 3; /* skip colon and capname */
X }
X else
X bptr++; /* skip colon */
X }
X }
X return (bptr);
X}
X
X/*
X * tgetname:
X * store name of termcap entry in name
X */
Xtgetname (name)
Xchar *name;
X{
X char *bptr;
X
X bptr = buffer;
X
X while ((*bptr) && (*bptr != ':'))
X *(name++) = *(bptr++);
X *(name) = '\0';
X}
X
X/*
X * tgetflag:
X * return 1 if capname present, 0 otherwise, -1 if '@'ed.
X */
Xint
Xtgetflag (capname)
Xchar *capname;
X{
X char *c;
X
X c = findcap (capname);
X if (*c == '\0')
X return (0);
X else if (*c == '@')
X return (-1);
X else
X return (1);
X}
X
X/*
X * tgetnum:
X * return value of capname, -1 if not present, -2 if '@'ed.
X */
Xint
Xtgetnum (capname)
Xchar *capname;
X{
X char *c;
X int val;
X
X c = findcap (capname);
X if (*c == '@')
X return (-2);
X else if (*c != '\0') {
X c++; /* skip '#' */
X val = 0;
X while (isdigit (*c)) {
X val = (val * 10) + (*c - '0');
X c++;
X }
X return (val);
X }
X else
X return (-1);
X}
X
X/*
X * tgetstr:
X * store binary value of capname into value, store null if
X * not present, store "@" if '@'ed.
X */
Xtgetstr (capname, value)
Xchar *capname;
Xregister char *value;
X{
X register char *c;
X
X c = findcap (capname);
X if (*c == '@')
X strcpy (value, "@");
X else if (*c != '\0') {
X c++; /* skip '=' */
X while ((*c) && (*c != ':')) {
X if (*c == '^') {
X c++;
X if (islower (*c))
X *(value++) = toupper(*(c++)) - '@'; /* ascii dependent */
X else
X *(value++) = *(c++) - '@'; /* ascii dependent */
X }
X else if (*c == '\\') {
X c++;
X switch (*c) {
X case 'E':
X *(value++) = '\033';
X c++;
X break;
X case 'n':
X *(value++) = '\n';
X c++;
X break;
X case 'r':
X *(value++) = '\r';
X c++;
X break;
X case 't':
X *(value++) = '\t';
X c++;
X break;
X case 'b':
X *(value++) = '\b';
X c++;
X break;
X case 'f':
X *(value++) = '\f';
X c++;
X break;
X default:
X if (isdigit (*c)) { /* octal value */
X *value = '\0';
X while (isdigit (*c)) {
X *value = ((*value) * 8) + ((*c) - '0');
X c++;
X }
X value++;
X }
X else
X *(value++) = *(c++);
X break;
X }
X }
X else
X *(value++) = *(c++);
X }
X *value = '\0';
X }
X else
X *value = '\0';
X}
--burp--
exit
--
Robert Viduya
Georgia Institute of Technology
...!{akgua,allegra,amd,hplabs,ihnp4,masscomp,ut-ngp}!gatech!gitpyr!robert
...!{rlgvax,sb1,uf-cgrl,unmvax,ut-sally}!gatech!gitpyr!robert
|