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: termcap to terminfo converter Message-ID: <1050@panda.UUCP> Date: 31 Oct 85 14:12:33 GMT Sender: jpn@panda.UUCP Lines: 848 Approved: jpn@panda.UUCP Mod.sources: Volume 3, Issue 30 Submitted by: Robert Viduya The following is a program that I posted late last january. Due to requests on net.info-terms, I'm reposting it. The program 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 -- Robert Viduya 01111000 Office of Computing Services Georgia Institute of Technology UUCP: {akgua,allegra,amd,hplabs,ihnp4,masscomp,ut-ngp,rlgvax,sb1, .. uf-cgrl,unmvax,ut-sally}!gatech!{gitpyr,gt-oscar,gt-felix}!robert BITNET: CC100RV @ GITVM1 ------cut here---- #! /bin/sh # Run the following text with /bin/sh to create: # Makefile # captoinfo.c # getcap.c # putinfo.c # tget.c if test -f 'Makefile' then echo "`basename $0`: can't extract" 'Makefile' "- file exists" 1>&2 else sed 's/^X//' << '--End_of_Makefile--' > '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 --End_of_Makefile-- if test 198 -ne `wc -c < 'Makefile'` then echo "`basename $0`: error in" 'Makefile' ": sent 198 chars, received `wc -c < 'Makefile'`" 1>&2 fi fi if test -f 'captoinfo.c' then echo "`basename $0`: can't extract" 'captoinfo.c' "- file exists" 1>&2 else sed 's/^X//' << '--End_of_captoinfo.c--' > '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 * This code is copyrighted and may not be sold without due compensation X * to both Georgia Tech and myself. Since I refuse to go through all the X * legal hassles involved, good luck. Oh yeah... don't remove this X * paragraph either. X * X * Robert Viduya - Georgia Institute of Technology. X * X * {gitpyr,gt-oscar,gt-felix}!robert X */ X#include 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} --End_of_captoinfo.c-- if test 1086 -ne `wc -c < 'captoinfo.c'` then echo "`basename $0`: error in" 'captoinfo.c' ": sent 1086 chars, received `wc -c < 'captoinfo.c'`" 1>&2 fi fi if test -f 'getcap.c' then echo "`basename $0`: can't extract" 'getcap.c' "- file exists" 1>&2 else sed 's/^X//' << '--End_of_getcap.c--' > 'getcap.c' X#include X#include 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} --End_of_getcap.c-- if test 544 -ne `wc -c < 'getcap.c'` then echo "`basename $0`: error in" 'getcap.c' ": sent 544 chars, received `wc -c < 'getcap.c'`" 1>&2 fi fi if test -f 'putinfo.c' then echo "`basename $0`: can't extract" 'putinfo.c' "- file exists" 1>&2 else sed 's/^X//' << '--End_of_putinfo.c--' > 'putinfo.c' X#include X#include X#include 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} --End_of_putinfo.c-- if test 11301 -ne `wc -c < 'putinfo.c'` then echo "`basename $0`: error in" 'putinfo.c' ": sent 11301 chars, received `wc -c < 'putinfo.c'`" 1>&2 fi fi if test -f 'tget.c' then echo "`basename $0`: can't extract" 'tget.c' "- file exists" 1>&2 else sed 's/^X//' << '--End_of_tget.c--' > 'tget.c' X#include X#include X#include 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} --End_of_tget.c-- if test 3196 -ne `wc -c < 'tget.c'` then echo "`basename $0`: error in" 'tget.c' ": sent 3196 chars, received `wc -c < 'tget.c'`" 1>&2 fi fi exit