Interdata_v6/usr/source/troff/programs/tcat.c
#define SIGINT 2
#define SIGQIT 3
/*
C version of tcatsim
*/
#define OBSZ 512
#define MAXY 3071
#define US 037
#define GS 035
#define ESC 033
#define FF 014
#define DBL 0200
int pl 11*144;
int mpy 1;
int div 1;
char *ap;
int ch;
int nonumb;
int psize 10;
int dfact 1;
int ibuf[259];
char obuf[OBSZ];
char *obufp obuf;
int esc;
int escd;
int verd;
int esct;
int osize 02;
int size 02;
int rx;
int xx 0;
int yy MAXY+62+48;
int leadtot -31;
int ohy -1;
int ohx -1;
int oxb -1;
int oly -1;
int olx -1;
int tflag;
int railmag;
int lead;
int skip;
int pgskip;
int ksize ';';
int mcase;
int stab[]{010,0,01,07,02,03,04,05,0211,06,0212,0213,0214,0215,0216,0217};
int rtab[]{6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 28, 26, 18};
int ktab[]{';',';',';',';',';',';',':',':','9','9','9','9','8','8','8','9'};
int od 1;
int first 1;
int alpha;
extern char *asctab[128];
extern char *spectab[128];
int erase 1;
int xxx;
int sigint;
int sigqit;
main(argc,argv)
int argc;
char **argv;
{
register i, j;
register char *k;
extern ex();
while((--argc > 0) && ((++argv)[0][0]=='-')){
switch(argv[0][1]){
case 'p':
ap = &argv[0][2];
dfact = 72;
if(i = atoi())pl = i/3;
continue;
case 't':
tflag++;
continue;
case 's':
ap = &argv[0][2];
dfact = 1;
pgskip = atoi();
continue;
default:
dfact = 1;
ap = &argv[0][1];
if(i = atoi())mpy = i;
if(i = atoi())div = i;
continue;
}
}
if(argc){
if(fopen(argv[0], ibuf) < 0){
prstr("Cannot open: ");
prstr(argv[0]);
prstr("\n");
exit(1);
}
}
sigint=signal(SIGINT, ex);
sigqit=signal(SIGQIT,1);
while((i = getc(ibuf)) >= 0){
if(!i)continue;
if(i & 0200){
esc =+ (~i) & 0177;
continue;
}
if(esc){
if(escd)esc = -esc;
esct =+ esc;
xx =+ (esc*mpy + rx)/div;
rx = (esc*mpy + rx)%div;
sendpt();
esc = 0;
}
switch(i){
case 0100: /*init*/
escd = verd = mcase = railmag = xx = 0;
yy = MAXY + 48;
leadtot = -31;
ohy = oxb = oly = ohx = olx = -1;
oput(US);
flusho();
if(!first && !tflag)kwait();
if(first){
first = 0;
yy =+ 62;
}
init();
continue;
case 0101: /*lower rail*/
railmag =& ~01;
continue;
case 0102: /*upper rail*/
railmag =| 01;
continue;
case 0103: /*upper mag*/
railmag =| 02;
continue;
case 0104: /*lower mag*/
railmag =& ~02;
continue;
case 0105: /*lower case*/
mcase = 0;
continue;
case 0106: /*upper case*/
mcase = 0100;
continue;
case 0107: /*escape forward*/
escd = 0;
continue;
case 0110: /*escape backward*/
escd = 1;
continue;
case 0111: /*stop*/
continue;
case 0112: /*lead forward*/
verd = 0;
continue;
case 0113: /*undefined*/
continue;
case 0114: /*lead backward*/
verd = 1;
continue;
case 0115: /*undefined*/
case 0116:
case 0117:
continue;
}
if((i & 0340) == 0140){ /*leading*/
lead = (~i) & 037;
if(verd)lead = -lead;
if((leadtot =+ lead) > pl){
leadtot = lead;
oput(US);
flusho();
if(!tflag)kwait();
yy = MAXY;
if(pgskip)--pgskip;
init();
continue;
}
if(skip)continue;
if((yy =- (lead<<1)) < 0){
skip++;
yy = 0;
}else sendpt();
continue;
}
if((i & 0360) == 0120){ /*size change*/
i =& 017;
for(j = 0; i != (stab[j] & 017); j++);
osize = size;
size = stab[j];
psize = rtab[j];
ksize = ktab[j];
oput(ESC);
oput(ksize);
i = 0;
if(!(osize & DBL) && (size & DBL))i = -55;
else if((osize & DBL) && !(size & DBL))i = 55;
if(escd)i = -i;
esc =+ i;
continue;
}
if(i & 0300)continue;
i = (i & 077) | mcase;
if(railmag != 03)k = asctab[i];
else k = spectab[i];
if(alpha)sendpt();
if(k != -1){
oput(US);
while(*k & 0377)oput(*k++);
alpha++;
continue;
}else{
if(railmag != 03){
switch(i){
case 0124: lig("fi"); break;
case 0125: lig("fl"); break;
case 0126: lig("ff"); break;
case 0130: lig("ffl"); break;
case 0131: lig("ffi"); break;
default: continue;
}
}
continue;
}
}
ex();
}
lig(x)
char *x;
{
register i, j;
register char *k;
j = 0;
k = x;
oput(US);
oput(*k++);
i = psize * 8 * mpy / (div * 6); /* 8/36 em */
while(*k){
xx =+ i;
j =+ i;
sendpt();
oput(US);
oput(*k++);
}
xx =- j;
sendpt();
}
init(){
register i;
flusho();
if(erase){
oput(ESC);
oput(FF);
}else erase = 1;
oput(ESC);
oput(ksize);
/*delay about a second*/
/* let the system do it...
for(i = 960; i > 0; i--)oput(GS);
*/
skip = 0;
sendpt();
}
ex(){
yy = MAXY;
xx = 0;
sendpt();
oput(ESC);
oput(';');
oput(US);
flusho();
exit(0);
}
kwait(){
char buf[128]; char *bptr; char c;
if(pgskip) return;
next:
bptr=buf;
while((c=readch())&&(c!='\n')) *bptr++=c;
*bptr=0;
if(bptr!=buf){
bptr = buf;
if(*bptr == '!'){unix(&buf[1]); prstr("!\n"); goto next;}
else switch(*bptr++){
case 'e':
erase = 0;
goto next;
case 's':
ap = &buf[1];
dfact = 1;
pgskip = atoi() + 1;
goto next;
default:
prstr("?\n");
goto next;
}
}
else if (c==0) ex();
else return;
}
unix(line)
char line[];
{
int rc, status, unixpid;
if( (unixpid=fork())==0 ) {
signal(SIGINT,sigint); signal(SIGQIT,sigqit);
close(0); dup(2);
execl("/bin/sh", "-sh", "-c", line, 0);
exit(255);
}
else if(unixpid == -1)
return;
else{ signal(SIGINT,1); signal(SIGQIT,1);
while( (rc = wait(&status)) != unixpid && rc != -1 ) ;
signal(SIGINT,ex); signal(SIGQIT,sigqit);
}
}
readch(){
char c;
if (read(2,&c,1)<1) c=0;
return(c);
}
oput(i)
char i;
{
if(pgskip)return;
*obufp++ = i;
if(obufp >= (obuf + OBSZ))flusho();
}
flusho(){
write(od,obuf,obufp-obuf);
obufp = obuf;
}
sendpt(){
int hy,xb,ly,hx,lx;
oput(GS);
hy = ((yy>>7) & 037);
xb = ((xx & 03) + ((yy<<2) & 014) & 017);
ly = ((yy>>2) & 037);
hx = ((xx>>7) & 037);
lx = ((xx>>2) & 037);
if(hy != ohy)oput(hy | 040);
if(xb != oxb)oput(xb | 0140);
if((ly != oly) || (hx != ohx) || (xb != oxb))
oput(ly | 0140);
if(hx != ohx)oput(hx | 040);
oput(lx | 0100);
ohy = hy;
oxb = xb;
oly = ly;
ohx = hx;
olx = lx;
alpha = 0;
return;
}
prstr(s)
char *s;
{
register i;
for(i=0;*s;i++)s++;
write(2,s-i,i);
}
atoi()
{
register i, j, acc;
int field, digits, *dd, *tscale();
field = digits = acc = 0;
a1:
while(((j = (i = getch()) - '0') >= 0) && (j <= 9)){
field++;
digits++;
acc = 10*acc + j;
}
if(i == '.'){
field++;
digits = 0;
goto a1;
}
if(!(ch = i))ch = 'x';
dd = tscale(acc);
acc = dd[0];
if((field != digits) && (digits > 0)){
j = 1;
while(digits--)j =* 10;
acc = ldiv(dd[1],dd[0],j);
}
nonumb = !field;
ch = 0;
return(acc);
}
int *tscale(n)
int n;
{
register i, j;
static int aa[2];
switch(i = getch()){
case 'u':
j = 1;
break;
case 'p': /*Points*/
j = 6;
break;
case 'i': /*Inches*/
j = 432;
break;
case 'c': /*Centimeters; should be 170.0787*/
j = 170;
break;
case 'P': /*Picas*/
j = 72;
break;
default:
j = dfact;
ch = i;
}
aa[0] = n * j;
aa[1] = hmul(n,j);
return(aa);
}
getch(){
register i;
if(ch){
i = ch;
ch = 0;
return(i);
}
return(*ap++);
}