tcm - merge/check termcap files
Sam McCall
ccsam at castor.ucdavis.edu
Tue Aug 8 04:08:09 AEST 1989
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# Makefile
# tcm.8
# mkdep
# newvers.sh
# README
# RELEASE
# tcm.c
# tcm.h
# This archive created: Mon Aug 7 10:58:23 1989
# By: Sam McCall ()
export PATH; PATH=/bin:$PATH
echo shar: extracting "'Makefile'" '(844 characters)'
if test -f 'Makefile'
then
echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^ X//' << \SHAR_EOF > 'Makefile'
X#
X# makefile for tcm
X#
XCC=/bin/cc
XCFLAGS=-O
X
XSRCS = tcm.c
XINCS = tcm.h
XOBJS = tcm.o version.o
XLIBS =
XETC = Makefile tcm.8 mkdep newvers.sh README RELEASE
XALL = $(ETC) $(SRCS) $(INCS)
XTARGETS = tcm
XPACKAGE = tcm
X
Xall: $(TARGETS)
X
Xtcm: $(OBJS)
X $(CC) -o tcm $(OBJS) $(LIBS)
X
X.c.o:
X $(CC) $(CFLAGS) -c $<
X
Xversion.c: always
X /bin/sh newvers.sh
X
Xdepend:
X /bin/sh mkdep $(SRCS)
X
Xclean:
X rm -f $(TARGETS) $(OBJS) version.c VERSION core a.out \
X $(PACKAGE).tar $(PACKAGE).shar
X
Xlint:
X lint $(SRCS)
X
Xtar:
X tar cvf $(PACKAGE).tar $(ALL)
X
Xshar:
X shar -a $(ALL) > $(PACKAGE).shar
X
Xalways:
X
X# DO NOT DELETE THIS LINE -- mkdep uses it.
X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
X
Xtcm.o: tcm.c /usr/include/stdio.h /usr/include/ctype.h /usr/include/sys/types.h
Xtcm.o: /usr/include/sys/stat.h tcm.h
X
X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
SHAR_EOF
if test 844 -ne "`wc -c < 'Makefile'`"
then
echo shar: error transmitting "'Makefile'" '(should have been 844 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'tcm.8'" '(4738 characters)'
if test -f 'tcm.8'
then
echo shar: will not over-write existing file "'tcm.8'"
else
sed 's/^ X//' << \SHAR_EOF > 'tcm.8'
X.\"
X.\" -sam Mon May 29 16:44:58 PDT 1989
X.\"
X.\" @(#)tcm.8 1.0 alpha 89/05/27
X.TH TCM 8 "29 May 1989"
X.SH NAME
Xtcm \- merge termcap files
X.SH SYNOPSIS
X.B tcm
X[
X.B \-ns
X]
X[
X.I output-file
X]
X.I filename
X\&.\|.\|.
X.SH VERSION
XVersion 1.0, alpha release
X.SH DESCRIPTION
X.LP
X.B tcm
Xmakes an attempt at rationally combining termcap files, while also
Xdoing some consistency checking and preserving the relative ordering
Xof the entries in the files.
XFor each
X.I filename
Xgiven,
X.B tcm
Xreads the termcap entries from that file, doing many consistency
Xchecks, noting the termcap's body and whether it is unique, and
Xalso noting the names for the termcap and whether they are unique.
XOne should note that, because the files are processed in left to
Xright order, the termcaps in the files listed first have a higher
Xpriority than the termcaps listed in the files listed last, even
Xthoug an attempt is made to preserve their relative ordering.
X.PP
XWhen a termcap is read that is unique, and all of its names are
Xunique, these are all stored away for later use.
X.PP
XWhen a termcap is read that is unique, and some of its names are
Xnot unique, the user is prompted to change, delete, or ignore this
Xname, unless the "smart" mode option is used.
X.PP
XWhen a termcap is read that is not unique, and if it has names that
Xare not known, these names are added to the names of the termcap
Xthat has already been saved, and this termcap is discarded.
X.PP
XAfter all termcap entries from all of the named files are read, the
Xinternal database is traversed in order, the termcaps that have been
Xchanged are modified, and are output to
X.I output-file.
X.PP
XWhen
X.B tcm
Xchanges a termcap entry, it will prepend a comment to the body of the
Xtermcap of the form:
X.PP
X.nf
X#
X# @@tcm@@: termcap was known as "foo|bar|baz"
X#
X.fi
X.PP
XThis indicates that the termcap, when read, was known by these names,
Xbut has since changed.
X.SH OPTIONS
X.TP 15
X.BI -n
XDo not generate any output; used when checking consistency.
X.TP
X.BI -s
X"Smart" mode. When a termcap name has already been seen
Xin conjunction with another termcap, don't ask to change
Xor delete it, simply ignore it. This is perhaps the perferred
Xmode of operation, since there are many name collisions in
Xcurrent termcap files, unfortunately.
X.SH EXAMPLES
X.B tcm
Xcan be used in many ways. For these examples, assume that the file
X.I foo
Xcontains some new termcap entries you wish to add to your system
Xtermcap file,
X.I /etc/termcap.
X.PP
XFirst,
X.I tcm
Xcan be used to check the consistency of /etc/termcap by simply
Xissuing the command
X.PP
X.B tcm -ns /etc/termcap
X.PP
XThis will tell you if there are any entries that
X.B tcm
Xdoes not understand, such as improperly continued lines or
Xbadly formatted comments.
X.PP
XTo make /etc/termcap consistent, name-wise, and to be prompted
Xfor the changes necessary, use the command
X.PP
X.B tcm termcap.fixed /etc/termcap
X.PP
XTo merge a termcap file 'foo' with /etc/termcap, for example,
Xand to use 'smart' mode, use the command
X.PP
X.B tcm -s termcap.merge foo /etc/termcap
X.SH DIAGNOSTICS
X.TP 15
X.BI "usage: %s [ -sn ] [ output-file ] file [file...]"
XArguments were used incorrectly.
X.I output-file
Xis not specified if using the
X.I -n
Xoption.
X.BI "%s exists."
X.I output-file
Xexists, and
X.B tcm
Xrefuses to overwrite it.
X.TP
X.BI "No output created."
XEither the
X.I -n
Xoption was specified or an error occurred that caused tcm
Xto turn off output, since the database output would be wrong
Xanyways.
X.TP
X.BI "Unrecognized termcap (file %s near line %d): %s"
X.B tcm
Xdid not like the format of the termcap near the specified line
Xin the named file. Typically, this is either due to an improperly
Xcontinued line just above the displayed area, or to trailing comments
Xin the named file.
X.TP
X.BI "EOF encountered."
XThe EOF character was typed when
X.B tcm
Xwas expecting input.
X.B tcm
Xexits upon such an error.
X.TP
X.BI "malloc failure in %s(%d,%d)"
XUnless there's an internal error causing
X.B tcm
Xto absorb all available memory, it's likely that more
Xis needed to do the task at hand.
X.TP
X.BI "%s(%s,%d) failure."
XAn error of this form indicates a serious internal error.
X.SH BUGS
XIt is important to note that
X.B tcm
Xdoes not do semantic checking of the termcap entries; it merely
Xlooks for really glaring problems, such as badly continued lines
Xor badly formatted comments. It is forgiving of comments inside
Xof termcaps, and it shouldn't be \- only comments before or after
Xtermcap entries are valid.
X.PP
XAlso,
X.B tcm
Xis not bright enough to realize that trailing comments in /etc/termcap
Xare okay.
X.SH "SEE ALSO"
Xtermcap(5)
X.SH AUTHOR
X.nf
XSam McCall
XUniversity of California, Davis
X
XBug reports or comments should be sent to samccall at ucdavis.edu
Xor ucbvax!ucdavis!samccall.
X.fi
SHAR_EOF
if test 4738 -ne "`wc -c < 'tcm.8'`"
then
echo shar: error transmitting "'tcm.8'" '(should have been 4738 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'mkdep'" '(1247 characters)'
if test -f 'mkdep'
then
echo shar: will not over-write existing file "'mkdep'"
else
sed 's/^ X//' << \SHAR_EOF > 'mkdep'
X#! /bin/sh
X#
X# @(#)mkdep.sh 1.7 (Berkeley) 10/13/87
X#
X
XPATH=/bin:/usr/bin:/usr/ucb
Xexport PATH
X
Xif [ $# = 0 ] ; then
X echo 'usage: mkdep [-p] [-f makefile] [flags] file ...'
X exit 1
Xfi
X
XMAKE=Makefile # default makefile name is "Makefile"
Xcase $1 in
X # -f allows you to select a makefile name
X -f)
X MAKE=$2
X shift; shift ;;
X
X # the -p flag produces "program: program.c" style dependencies
X # so .o's don't get produced
X -p)
X SED='-e s;\.o;;'
X shift ;;
Xesac
X
Xif [ ! -w $MAKE ]; then
X echo "mkdep: no writeable file \"$MAKE\""
X exit 1
Xfi
X
XTMP=/tmp/mkdep$$
X
Xtrap 'rm -f $TMP ; exit 1' 1 2 3 13 15
X
Xcp $MAKE ${MAKE}.bak
X
Xsed -e '/DO NOT DELETE THIS LINE/,$d' < $MAKE > $TMP
X
Xcat << _EOF_ >> $TMP
X# DO NOT DELETE THIS LINE -- mkdep uses it.
X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
X
X_EOF_
X
Xcc -M $* | /bin/sed -e "s; \./; ;g" $SED | \
X awk ' { \
X if ($1 != prev) { \
X if (rec != "") \
X print rec; rec = $0; prev = $1; \
X } \
X else { \
X if (length(rec $2) > 78) { \
X print rec; rec = $0; \
X } else \
X rec = rec " " $2 \
X } \
X } \
X END { \
X print rec \
X } ' >> $TMP
X
Xcat << _EOF_ >> $TMP
X
X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
X_EOF_
X
X# copy to preserve permissions
Xcp $TMP $MAKE
Xrm -f ${MAKE}.bak $TMP
Xexit 0
SHAR_EOF
if test 1247 -ne "`wc -c < 'mkdep'`"
then
echo shar: error transmitting "'mkdep'" '(should have been 1247 characters)'
fi
chmod +x 'mkdep'
fi # end of overwriting check
echo shar: extracting "'newvers.sh'" '(392 characters)'
if test -f 'newvers.sh'
then
echo shar: will not over-write existing file "'newvers.sh'"
else
sed 's/^ X//' << \SHAR_EOF > 'newvers.sh'
X#!/bin/sh
X#
Xif [ ! -r VERSION ]
Xthen
X /bin/echo 0 > VERSION
Xfi
Xtouch VERSION
Xr=`cat RELEASE` v=`cat VERSION` u=${USER-root} d=`pwd` h=`hostname` t=`date`
X(/bin/echo '#ifndef lint' ;
X /bin/echo "char version[] = \"${r} #${v}: ${t} ${u}@${h}:${d}\";" ;
X /bin/echo "char copyright[] = \"(C)1989 by Sam McCall\";" ;
X /bin/echo '#endif'
X ) > version.c
Xsleep 1
X/bin/echo `expr ${v} + 1` > VERSION
SHAR_EOF
if test 392 -ne "`wc -c < 'newvers.sh'`"
then
echo shar: error transmitting "'newvers.sh'" '(should have been 392 characters)'
fi
chmod +x 'newvers.sh'
fi # end of overwriting check
echo shar: extracting "'README'" '(347 characters)'
if test -f 'README'
then
echo shar: will not over-write existing file "'README'"
else
sed 's/^ X//' << \SHAR_EOF > 'README'
XFiles in this directory:
X
X Makefile
X README
X RELEASE
X mkdep
X newvers.sh
X tcm.8
X tcm.c
X tcm.h
X
XPermission is hereby granted to distribute and copy this code
Xas desired as long as this message remains with the code.
X
XMail comments, suggestions, or bug reports to
X
X ucbvax!ucdavis!samccall
Xor samccall at ucdavis.edu
X
X-sam Mon May 29 16:31:22 PDT 1989
SHAR_EOF
if test 347 -ne "`wc -c < 'README'`"
then
echo shar: error transmitting "'README'" '(should have been 347 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'RELEASE'" '(22 characters)'
if test -f 'RELEASE'
then
echo shar: will not over-write existing file "'RELEASE'"
else
sed 's/^ X//' << \SHAR_EOF > 'RELEASE'
Xtcm release 1.0 alpha
SHAR_EOF
if test 22 -ne "`wc -c < 'RELEASE'`"
then
echo shar: error transmitting "'RELEASE'" '(should have been 22 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'tcm.c'" '(10920 characters)'
if test -f 'tcm.c'
then
echo shar: will not over-write existing file "'tcm.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'tcm.c'
X/*
X * -sam Mon May 29 16:34:49 PDT 1989
X */
X#include <stdio.h>
X#include <ctype.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include "tcm.h"
X
X#define USAGE "usage: %s [ -sn ] [ output-file ] file [file...]\n",pname
X
Xchar *malloc();
Xchar *strcpy();
Xchar *strncpy();
Xchar *strcat();
Xchar *strncat();
Xchar *strsave();
X
Xchar *getinput();
Xchar *getlinput();
Xchar *gettcap();
Xchar *gettcapbyname();
Xchar *findtbody();
Xchar *dofixnames();
Xchar *findtnames();
Xchar *gettcapname();
Xstruct stat sbuf;
Xstruct nameent *getnameent();
Xstruct terment *gettcapent();
X
Xint lno;
Xint order;
Xint nosave = 0;
Xint smartmode = 0;
Xchar *pname;
X
X#define ISTCSTART(c) (isascii(c)&&isalnum(c))
X
Xmain(ac,av)
Xint ac;
Xchar **av;
X{
X int i;
X int aj;
X FILE *fpin,*fpdribble;
X
X pname = av[0];
X while(av[1][0]=='-'){
X aj=1;
X while(av[1][aj]){
X switch(av[1][aj]){
X case 's': smartmode++;
X aj++;
X continue;
X case 'n': nosave++;
X aj++;
X continue;
X default: (void)fprintf(stderr,USAGE);
X exit(1);
X }
X }
X ac--;
X av++;
X }
X if((nosave&&ac<2)||(!nosave&&ac<3)){
X (void)fprintf(stderr,USAGE);
X exit(1);
X }
X if(!nosave){
X if(stat(av[1],&sbuf)<0){
X if((fpdribble=fopen(av[1],"w"))==NULL){
X perror(av[1]);
X exit(1);
X }
X } else {
X (void)fprintf(stderr,"%s exists.\n",av[1]);
X exit(1);
X }
X ac--;av++;
X }
X lno=0;
X order=0;
X for(i=1;i<ac;i++){
X if((fpin=fopen(av[i],"r"))==NULL){
X perror(av[i]);
X exit(1);
X }
X while(getnewent(fpin,av[i],&lno,&order));
X (void)fclose(fpin);
X lno=0;
X order=0;
X }
X if(!nosave){
X dumpdb(fpdribble);
X } else {
X (void)printf("No output created.\n");
X }
X}
X
Xgetnewent(fp,fname,lno,order)
XFILE *fp;
Xchar *fname;
Xint *lno;
Xint *order;
X{
X char name[BUFSIZ];
X char buf[BUFSIZ];
X char nbuf[BUFSIZ];
X char tbuf[10*BUFSIZ];
X char *p,*q,*response;
X int tcunique;
X int looping;
X
X tbuf[0]='\0';
X buf[0]='\0';
X while(fgets(buf,sizeof(buf),fp)!=NULL){
X (*lno)++;
X /*
X * if the last character in the line, not counting
X * the newline, is an '\', then we have to continue.
X */
X if(buf[strlen(buf)-2]=='\\'){
X (void)strcat(tbuf,buf);
X continue;
X }
X /*
X * append comment lines right away
X */
X if(buf[0]=='#'){
X (void)strcat(tbuf,buf);
X continue;
X }
X if(buf[0]=='\n')
X continue;
X /*
X * just a normal line
X */
X (void)strcat(tbuf,buf);
X break;
X }
X if(buf[0]=='\0'||buf[0]=='\n')
X return(0);
X (*order)++;
X /*
X * now point to the names of the termcap
X */
X if((p=findtnames(tbuf))==NULL){
X (void)fprintf(stderr,
X "Unrecognized termcap (file %s near line %d):\n%s",
X fname,*lno,tbuf);
X (void)fprintf(stderr,"Ignoring.\n");
X return(0);
X }
X (void)strcpy(nbuf,p);
X tcunique=1;
X if(gettcapent(tbuf)){
X tcunique=0;
X }
X if(tcunique){
X if(!putintcaphash(tbuf)){
X (void)fprintf(stderr,"putintcaphash(%d) failure.\n",
X tbuf);
X exit(1);
X }
X if(!addorderent(*order,gettcapent(tbuf))){
X (void)fprintf(stderr,"addorderent(%d,%d) failure.\n",
X *order,tbuf);
X exit(1);
X }
X p=nbuf;
X while(*p){
X for(q=p;*q&&*q!='|';q++);
X (void)strncpy(name,p,(q-p));
X name[(q-p)]='\0';
X if(getnameent(name)){
X looping=1;
X while(looping){
X if(!smartmode){
X (void)printf(
X "Name \"%s\" already in use.\n",
X name);
X (void)printf(
X "Current termcap ...\n%s\n",
X tbuf);
X (void)printf(
X "Used in termcap ...\n%s\n",
X dofixnames(
X gettcapent(
X gettcapbyname(
X name))));
X } else {
X goto nameign;
X }
Xz1: response=getlinput(
X "(change/delete/ignore)? ");
X if(*response=='\0') goto z1;
X if(*response=='d'){
X setfixnames(tbuf);
X (void)printf("\n\n");
X goto namedrop;
X }
X if(*response=='i'){
X (void)printf("\n\n");
X goto nameign;
X }
X if(*response=='c'){
Xz2: (void)strcpy(name,
X getinput("New name: "));
X if(*name=='\0') goto z2;
X if(!getnameent(name)){
X looping=0;
X } else {
X (void)printf(
X "That name (%s) is also already in use.\n",name);
X }
X }
X }
X (void)printf("\n\n");
X setfixnames(tbuf);
X }
X if(!putinnamehash(name,tbuf)){
X (void)fprintf(stderr,
X "putinnamehash(%s) failure.\n",
X name);
X exit(1);
X }
Xnameign: if(!addname(gettcapent(tbuf),name)){
X (void)fprintf(stderr,
X "addname(%s) failure.\n",
X name);
X exit(1);
X }
Xnamedrop: if(*q=='|')
X p=q+1;
X else
X p=q;
X }
X } else {
X /*
X * now run through the list of names, taking those
X * that aren't already known, and add them to this
X * termcap.
X */
X p=nbuf;
X while(*p){
X for(q=p;*q&&*q!='|';q++);
X (void)strncpy(name,p,(q-p));
X name[(q-p)]='\0';
X if(!getnameent(name)){
X if(!putinnamehash(name,tbuf)){
X (void)fprintf(stderr,
X "putinnamehash(%s) failure.\n",
X name);
X exit(1);
X }
X if(!addname(gettcapent(tbuf),name)){
X (void)fprintf(stderr,
X "addname(%s) failure.\n",
X name);
X exit(1);
X }
X setfixnames(tbuf);
X }
X if(*q=='|')
X p=q+1;
X else
X p=q;
X }
X }
X return(1);
X}
X
Xdumpdb(fp)
XFILE *fp;
X{
X int i;
X struct orderent *p;
X
X for(i=0;i<ORDERTABSIZE;i++){
X p=ordertab[i];
X while(p){
X fputs(dofixnames(p->tptr),fp);
X p=p->next;
X }
X }
X}
X
X/*
X * hash function
X *
X * copied directly from 2nd edition dragon book
X * "Compilers - Principles, Techniques, and Tools"
X * Aho, Sethi, and Ullman
X */
Xhash(name,tabsize)
Xchar *name;
Xint tabsize;
X{
X char *p;
X unsigned h=0,g;
X
X if(!name)return(0);
X for(p=name;*p;p++){
X h=(h<<4)+(*p);
X if(g=h&0xf0000000){
X h=h^(g>>24);
X h=h^g;
X }
X }
X return(h%tabsize);
X}
X
Xaddorderent(order,tptr)
Xint order;
Xstruct terment *tptr;
X{
X struct orderent *qp;
X struct orderent *sp;
X
X if(order>ORDERTABSIZE||order<0) return(0);
X if((qp=(struct orderent *)malloc(sizeof(struct orderent)))==NULL){
X (void)fprintf(stderr,"malloc failure in addorderent(%d,%d)\n",
X order,tptr);
X exit(1);
X }
X sp=ordertab[order];
X if(sp){
X while(sp&&sp->next)sp=sp->next;
X sp->next=qp;
X } else {
X ordertab[order]=qp;
X }
X qp->tptr=tptr;
X return(1);
X}
X
Xstruct nameent *
Xgetnameent(name)
Xchar *name;
X{
X int hval;
X struct nameent *tp;
X
X hval = NAMEHASH(name);
X tp = nametab[hval];
X while(tp){
X if(!strcmp(tp->name,name))
X return(tp);
X tp=tp->next;
X }
X return((struct nameent *)NULL);
X}
X
X/*
X * assumes name not already in name hash table
X */
Xputinnamehash(name,tcap)
Xchar *name;
Xchar *tcap;
X{
X int hval;
X struct terment *tp;
X struct nameent *np;
X struct nameent *qp;
X
X if(!name||!tcap) return(0);
X if((tp=gettcapent(tcap))==NULL) return(0);
X hval = NAMEHASH(name);
X np = nametab[hval];
X if((qp = (struct nameent *)malloc(sizeof(struct nameent)))==NULL){
X (void)fprintf(stderr,
X "malloc failure in putinnamehash(%d,%d).\n",
X name,tcap);
X exit(1);
X }
X if(np){
X qp->next = np;
X } else {
X qp->next = (struct nameent *)NULL;
X }
X nametab[hval] = qp;
X qp->name=strsave(name);
X qp->tptr = tp;
X return(1);
X}
X
Xaddname(tcap,name)
Xstruct terment *tcap;
Xchar *name;
X{
X int i;
X char **p;
X
X if(!tcap) return(0);
X p=tcap->names;
X i=tcap->nnames++;
X if(i>=NTCNAMES){
X --tcap->nnames;
X return(0);
X }
X p[i]=strsave(name);
X return(1);
X}
X
Xchar *
Xgettcap(tent)
Xstruct terment *tent;
X{
X return(tent?tent->tcap:NULL);
X}
X
Xchar *
Xgettcapname(tent,i)
Xstruct terment *tent;
Xint i;
X{
X return(tent?tent->names[i]:(char *)NULL);
X}
X
Xgettcapnnames(tent)
Xstruct terment *tent;
X{
X return(tent?tent->nnames:0);
X}
X
Xchar *
Xgettcapbyname(name)
Xchar *name;
X{
X struct nameent *np;
X
X if(!name) return(NULL);
X if((np=getnameent(name))==NULL) return(NULL);
X return(np->tptr->tcap);
X}
X
Xstruct terment *
Xgettcapent(tcap)
Xchar *tcap;
X{
X struct terment *tp;
X char *b;
X
X if((b=findtbody(tcap))==NULL) return((struct terment *)NULL);
X tp = tcaptab[TCAPHASH(b)];
X while(tp){
X if(!strcmp(b,tp->tbody)){
X return(tp);
X }
X tp=tp->next;
X }
X return((struct terment *)NULL);
X}
X
X/*
X * assumes that this tcap not already in database.
X */
Xputintcaphash(tcap)
Xchar *tcap;
X{
X int hval;
X char *b;
X struct terment *qp;
X
X if((b=findtbody(tcap))==NULL){
X return(0);
X }
X hval = TCAPHASH(b);
X if((qp = (struct terment *)malloc(sizeof(struct terment)))==NULL){
X (void)fprintf(stderr,"malloc failure in putintcaphash(%d).\n",
X tcap);
X exit(1);
X }
X if(tcaptab[hval])
X qp->next = tcaptab[hval];
X else
X qp->next = (struct terment *)NULL;
X tcaptab[hval] = qp;
X tcaptab[hval]->tcap=strsave(tcap);
X tcaptab[hval]->tbody=findtbody(tcaptab[hval]->tcap);
X tcaptab[hval]->fixnames=0;
X tcaptab[hval]->nnames=0;
X return(1);
X}
X
Xchar *
Xstrsave(str)
Xchar *str;
X{
X char *sptr;
X
X if(!str){
X (void)fprintf(stderr,"strsave(%d) failure.\n",str);
X exit(1);
X }
X if((sptr=malloc((unsigned)strlen(str)+1))==NULL){
X (void)fprintf(stderr,"malloc failure in strsave(%s)\n",str);
X exit(1);
X }
X (void)strcpy(sptr,str);
X return(sptr);
X}
X
Xchar *
Xgetlinput(prompt)
Xchar *prompt;
X{
X static char rbuf[BUFSIZ];
X char *p;
X
X (void)printf(prompt);
X (void)fflush(stdout);
X (void)fflush(stdin);
X if(fgets(rbuf,BUFSIZ,stdin)==NULL){
X (void)fprintf(stderr,"EOF encountered.\n");
X exit(1);
X }
X p=rbuf;
X while(*p){
X if(isalpha(*p))
X if(isupper(*p))
X *p=tolower(*p);
X p++;
X }
X p=rbuf;
X while(*p&&*p!='\n')p++;
X if(*p=='\n')*p='\0';
X return(rbuf);
X}
X
Xchar *
Xgetinput(prompt)
Xchar *prompt;
X{
X static char rbuf[BUFSIZ];
X char *p;
X
X (void)printf(prompt);
X (void)fflush(stdout);
X (void)fflush(stdin);
X if(fgets(rbuf,BUFSIZ,stdin)==NULL){
X (void)fprintf(stderr,"EOF encountered.\n");
X exit(1);
X }
X p=rbuf;
X while(*p&&*p!='\n')p++;
X if(*p=='\n')*p='\0';
X return(rbuf);
X}
X
Xsetfixnames(tcap)
Xchar *tcap;
X{
X struct terment *tptr;
X
X if((tptr=gettcapent(tcap))==NULL){
X (void)fprintf(stderr,"setfixnames(%d) failure.\n",tcap);
X exit(1);
X }
X tptr->fixnames = 1;
X}
X
Xneedfixnames(tptr)
Xstruct terment *tptr;
X{
X return(tptr?tptr->fixnames:NULL);
X}
X
Xchar *
Xdofixnames(tptr)
Xstruct terment *tptr;
X{
X char *p;
X char *q,*s;
X static char rbuf[10*BUFSIZ];
X int i;
X int j;
X
X if(!needfixnames(tptr)) return(gettcap(tptr));
X p = gettcap(tptr);
X q = p;
X while(*q&&*q=='#'){
X q++;
X while(*q&&*q!='\n')q++;
X if(*q=='\n')q++;
X }
X s = q;
X while(*s&&*s!=':')s++;
X if(p!=q)(void)strncpy(rbuf,p,(q-p));
X rbuf[(q-p)]='\0';
X (void)strcat(rbuf,"#\n# @@tcm@@ termcap was known as \"");
X (void)strncat(rbuf,q,(s-q));
X (void)strcat(rbuf,"\"\n#\n");
X i = gettcapnnames(tptr);
X j = 0;
X while(j<i){
X (void)strcat(rbuf,gettcapname(tptr,j));
X if(++j<i)(void)strcat(rbuf,"|");
X }
X (void)strcat(rbuf,s);
X return(rbuf);
X}
X
Xchar *
Xfindtbody(tcap)
Xchar *tcap;
X{
X char *p;
X
X p=tcap;
X if(!p)return(NULL);
X while(*p&&*p=='#'){
X p++;
X while(*p&&*p!='\n')p++;
X if(*p=='\n')p++;
X }
X if(!ISTCSTART(*p)){
X return(NULL);
X }
X while(*p&&*p!=':')p++;
X return(!*p?NULL:p);
X}
X
Xchar *
Xfindtnames(tcap)
Xchar *tcap;
X{
X char *p,*q;
X static char rbuf[BUFSIZ];
X
X p=tcap;
X if(!p)return(NULL);
X while(*p&&*p=='#'){
X p++;
X while(*p&&*p!='\n')p++;
X if(*p=='\n')p++;
X }
X if(!ISTCSTART(*p)){
X return(NULL);
X }
X q=p;
X while(*q&&*q!=':')q++;
X (void)strncpy(rbuf,p,(q-p));
X rbuf[(q-p)]='\0';
X return(rbuf);
X}
SHAR_EOF
if test 10920 -ne "`wc -c < 'tcm.c'`"
then
echo shar: error transmitting "'tcm.c'" '(should have been 10920 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'tcm.h'" '(613 characters)'
if test -f 'tcm.h'
then
echo shar: will not over-write existing file "'tcm.h'"
else
sed 's/^ X//' << \SHAR_EOF > 'tcm.h'
X/*
X * -sam Mon May 29 16:34:33 PDT 1989
X */
X#define NAMETABSIZE 4001
X#define ORDERTABSIZE 1000
X#define TCAPTABSIZE 4001
X#define NTCNAMES 32
X
Xstruct terment {
X char *tcap;
X char *tbody;
X struct terment *next;
X int fixnames;
X int nnames;
X char *names[NTCNAMES];
X};
X
Xstruct nameent {
X struct nameent *next;
X struct terment *tptr;
X char *name;
X};
X
Xstruct orderent {
X struct orderent *next;
X struct terment *tptr;
X};
X
Xstruct nameent *nametab[NAMETABSIZE];
Xstruct orderent *ordertab[ORDERTABSIZE];
Xstruct terment *tcaptab[TCAPTABSIZE];
X
X#define NAMEHASH(n) hash(n,NAMETABSIZE)
X#define TCAPHASH(n) hash(n,TCAPTABSIZE)
SHAR_EOF
if test 613 -ne "`wc -c < 'tcm.h'`"
then
echo shar: error transmitting "'tcm.h'" '(should have been 613 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
More information about the Alt.sources
mailing list