home *** CD-ROM | disk | FTP | other *** search
- #include "tdef.h"
- extern
- #include "d.h"
- extern
- #include "v.h"
- #ifdef NROFF
- extern
- #include "tw.h"
- #endif
- #include "s.h"
-
- /*
- troff3.c
-
- macro and string routines, storage allocation
- */
-
- unsigned blist[NBLIST];
- extern struct s *frame, *stk, *nxf;
- extern filep ip;
- extern filep offset;
- extern filep nextb;
- extern char *enda;
-
- extern int ch;
- extern int ibf;
- extern int lgf;
- extern int copyf;
- extern int ch0;
- extern int app;
- extern int ds;
- extern int nlflg;
- extern int *argtop;
- extern int *ap;
- extern int nchar;
- extern int pendt;
- extern int rchar;
- extern int dilev;
- extern int nonumb;
- extern int lt;
- extern int nrbits;
- extern int nform;
- extern int fmt[];
- extern int oldmn;
- extern int newmn;
- extern int macerr;
- extern filep apptr;
- extern int diflg;
- extern filep woff;
- extern filep roff;
- extern int wbfi;
- extern int po;
- extern int *cp;
- extern int xxx;
- int pagech = '%';
- int strflg;
- extern struct contab {
- int rq;
- union {
- int (*f)();
- unsigned mx;
- }x;
- }contab[NM];
- int wbuf[BLK];
- int rbuf[BLK];
-
- caseig(){
- register i;
-
- offset = 0;
- if((i = copyb()) != '.')control(i,1);
- }
- casern(){
- register i,j;
-
- lgf++;
- skip();
- if(((i=getrq())==0) || ((oldmn=findmn(i)) < 0))return;
- skip();
- clrmn(findmn(j=getrq()));
- if(j)contab[oldmn].rq = (contab[oldmn].rq & MMASK) | j;
- }
- caserm(){
- lgf++;
- while(!skip()){
- clrmn(findmn(getrq()));
- }
- }
- caseas(){
- app++;
- caseds();
- }
- caseds(){
- ds++;
- casede();
- }
- caseam(){
- app++;
- casede();
- }
- casede(){
- register i, req;
- register filep savoff;
- extern filep finds();
-
- if(dip != d)wbfl();
- req = '.';
- lgf++;
- skip();
- if((i=getrq())==0)goto de1;
- if((offset=finds(i)) == 0)goto de1;
- if(ds)copys();
- else req = copyb();
- wbfl();
- clrmn(oldmn);
- if(newmn)contab[newmn].rq = i | MMASK;
- if(apptr){
- savoff = offset;
- offset = apptr;
- wbt(IMP);
- offset = savoff;
- }
- offset = dip->op;
- if(req != '.')control(req,1);
- de1:
- ds = app = 0;
- return;
- }
- findmn(i)
- int i;
- {
- register j;
-
- for(j=0;j<NM;j++){
- if(i == (contab[j].rq & ~MMASK))break;
- }
- if(j==NM)j = -1;
- return(j);
- }
- clrmn(i)
- int i;
- {
- extern filep boff();
- if(i >= 0){
- if(contab[i].rq & MMASK)ffree(((filep)contab[i].x.mx)<<BLKBITS);
- contab[i].rq = 0;
- contab[i].x.mx = 0;
- }
- }
- filep finds(mn)
- int mn;
- {
- register i;
- extern filep boff();
- register filep savip;
- extern filep alloc();
- extern filep incoff();
-
- oldmn = findmn(mn);
- newmn = 0;
- apptr = (filep)0;
- if(app && (oldmn >= 0) && (contab[oldmn].rq & MMASK)){
- savip = ip;
- ip = (((filep)contab[oldmn].x.mx)<<BLKBITS);
- oldmn = -1;
- while((i=rbf()) != 0);
- apptr = ip;
- if(!diflg)ip = incoff(ip);
- nextb = ip;
- ip = savip;
- }else{
- for(i=0;i<NM;i++){
- if(contab[i].rq == 0)break;
- }
- if((i==NM) ||
- (nextb = alloc()) == 0){
- app = 0;
- if(macerr++ > 1)done2(02);
- prstr("Too many string/macro names.\n");
- edone(04);
- return(offset = 0);
- }
- contab[i].x.mx = (unsigned)(nextb>>BLKBITS);
- if(!diflg){
- newmn = i;
- if(oldmn == -1)contab[i].rq = -1;
- }else{
- contab[i].rq = mn | MMASK;
- }
- }
-
- app = 0;
- return(offset = nextb);
- }
- skip(){
- register i;
-
- while(((i=getch()) & CMASK) == ' ');
- ch=i;
- return(nlflg);
- }
- copyb()
- {
- register i, j, k;
- int ii, req, state;
- filep savoff;
-
- if(skip() || !(j=getrq()))j = '.';
- req = j;
- k = j>>BYTE;
- j &= BMASK;
- copyf++;
- flushi();
- nlflg = 0;
- state = 1;
- while(1){
- i = (ii = getch()) & CMASK;
- if(state == 3){
- if(i == k)break;
- if(!k){
- ch = ii;
- i = getach();
- ch = ii;
- if(!i)break;
- }
- state = 0;
- goto c0;
- }
- if(i == '\n'){
- state = 1;
- nlflg = 0;
- goto c0;
- }
- if((state == 1) && (i == '.')){
- state++;
- savoff = offset;
- goto c0;
- }
- if((state == 2) && (i == j)){
- state++;
- goto c0;
- }
- state = 0;
- c0:
- if(offset)wbf(ii);
- }
- if(offset){
- wbfl();
- offset = savoff;
- wbt(0);
- }
- copyf--;
- return(req);
- }
- copys()
- {
- register i;
-
- copyf++;
- if(skip())goto c0;
- if(((i=getch()) & CMASK) != '"')wbf(i);
- while(((i=getch()) & CMASK) != '\n')wbf(i);
- c0:
- wbt(0);
- copyf--;
- }
- filep alloc()
- {
- register i;
- extern filep boff();
- filep j;
-
- for(i=0;i<NBLIST;i++){
- if(blist[i] == 0)break;
- }
- if(i==NBLIST){
- j = 0;
- }else{
- blist[i] = -1;
- if((j = boff(i)) < NEV*EVS)j = 0;
- }
- return(nextb = j);
- }
- ffree(i)
- filep i;
- {
- register j;
-
- while((blist[j = blisti(i)]) != -1){
- i = ((filep)blist[j])<<BLKBITS;
- blist[j] = 0;
- }
- blist[j] = 0;
- }
- filep boff(i)
- int i;
- {
- return(((filep)i)*BLK + NEV*EVS);
- }
- wbt(i)
- int i;
- {
- wbf(i);
- wbfl();
- }
- wbf(i)
- int i;
- {
- register j;
-
- if(!offset)return;
- if(!woff){
- woff = offset;
- wbfi = 0;
- }
- wbuf[wbfi++] = i;
- if(!((++offset) & (BLK-1))){
- wbfl();
- if(blist[j = blisti(--offset)] == -1){
- if(alloc() == 0){
- prstr("Out of temp file space.\n");
- done2(01);
- }
- blist[j] = (unsigned)(nextb>>BLKBITS);
- }
- offset = ((filep)blist[j])<<BLKBITS;
- }
- if(wbfi >= BLK)wbfl();
- }
- wbfl(){
- if(woff == 0)return;
- lseek(ibf, ((long)woff) * sizeof(int), 0);
- write(ibf, (char *)wbuf, wbfi * sizeof(int));
- if((woff & (~(BLK-1))) == (roff & (~(BLK-1))))roff = -1;
- woff = 0;
- }
- blisti(i)
- filep i;
- {
- return((i-NEV*EVS)/(BLK));
- }
- rbf(){
- register i;
- extern filep incoff();
-
- if((i=rbf0(ip)) == 0){
- if(!app)i = popi();
- }else{
- ip = incoff(ip);
- }
- return(i);
- }
- rbf0(p)
- filep p;
- {
- register filep i;
-
- if((i = (p & (~(BLK-1)))) != roff){
- roff = i;
- lseek(ibf, ((long)roff) * sizeof(int), 0);
- if(read(ibf, (char *)rbuf, BLK * sizeof(int)) == 0)return(0);
- }
- return(rbuf[p & (BLK-1)]);
- }
- filep incoff(p)
- filep p;
- {
- register i;
- register filep j;
- if(!((j = (++p)) & (BLK-1))){
- if((i = blist[blisti(--p)]) == -1){
- prstr("Bad storage allocation.\n");
- done2(-5);
- }
- j = ((filep)i)<<BLKBITS;
- }
- return(j);
- }
- popi(){
- register struct s *p;
-
- if(frame == stk)return(0);
- if(strflg)strflg--;
- p = nxf = frame;
- p->nargs = 0;
- frame = p->pframe;
- ip = p->pip;
- nchar = p->pnchar;
- rchar = p->prchar;
- pendt = p->ppendt;
- ap = p->pap;
- cp = p->pcp;
- ch0 = p->pch0;
- return(p->pch);
- }
- pushi(newip)
- filep newip;
- {
- register struct s *p;
- extern char *setbrk();
-
- if((enda - sizeof(struct s)) < (char *)nxf)setbrk(DELTA);
- p = nxf;
- p->pframe = frame;
- p->pip = ip;
- p->pnchar = nchar;
- p->prchar = rchar;
- p->ppendt = pendt;
- p->pap = ap;
- p->pcp = cp;
- p->pch0 = ch0;
- p->pch = ch;
- cp = ap = 0;
- nchar = rchar = pendt = ch0 = ch = 0;
- frame = nxf;
- if(nxf->nargs == 0) nxf += 1;
- else nxf = (struct s *)argtop;
- return(ip = newip);
- }
- char *setbrk(x)
- int x;
- {
- register char *i;
- char *sbrk();
-
- if((i = sbrk(x)) == MAXPTR){
- prstrfl("Core limit reached.\n");
- edone(0100);
- }else{
- enda = i + x;
- }
- return(i);
- }
- getsn(){
- register i;
-
- if((i=getach()) == 0)return(0);
- if(i == '(')return(getrq());
- else return(i);
- }
- setstr(){
- register i;
-
- lgf++;
- if(((i=getsn()) == 0) ||
- ((i=findmn(i)) == -1) ||
- !(contab[i].rq & MMASK)){
- lgf--;
- return(0);
- }else{
- if((enda-2) < (char *)nxf)setbrk(DELTA);
- nxf->nargs = 0;
- strflg++;
- lgf--;
- return(pushi(((filep)contab[i].x.mx)<<BLKBITS));
- }
- }
- collect()
- {
- register i;
- register int *strp;
- int *lim;
- int **argpp, **argppend;
- int quote;
- struct s *savnxf;
-
- copyf++;
- nxf->nargs = 0;
- savnxf = nxf;
- if(skip())goto rtn;
- lim = (int *)(nxf = savnxf + sizeof(struct s)/sizeof(savnxf));
- strflg = 0;
- if((argppend =
- (argpp = (int **)savnxf+(sizeof(struct s)/sizeof(int **))) + (sizeof(struct s)-1))
- > (int **)enda)setbrk(DELTA);
- strp = (int *)argppend;
- for(i=8; i>=0; i--)argpp[i] = 0;
- while((argpp != argppend) && (!skip())){
- *argpp++ = strp;
- quote = 0;
- if(((i = getch()) & CMASK) == '"')quote++;
- else ch = i;
- while(1){
- i = getch();
- if( nlflg ||
- ((!quote) && ((i & CMASK) == ' ')))break;
- if(quote && ((i & CMASK) == '"') &&
- (((i=getch()) & CMASK) != '"')){
- ch = i;
- break;
- }
- *strp++ = i;
- if(strflg && (strp >= lim)){
- prstrfl("Macro argument too long.\n");
- copyf--;
- edone(004);
- }
- if((enda-4) <= (char *)strp)setbrk(DELTA);
- }
- *strp++ = 0;
- }
- nxf = savnxf;
- nxf->nargs = argpp -(int **)(nxf + 1);
- argtop = strp;
- rtn:
- copyf--;
- }
- seta()
- {
- register i;
-
- if(((i = (getch() & CMASK) - '0') > 0) &&
- (i <= 9) && (i <= frame->nargs))ap = *((int **)frame + i-1 + (sizeof(struct s)/sizeof(int **)));
- }
- caseda(){
- app++;
- casedi();
- }
- casedi(){
- register i, j;
- register *k;
-
- lgf++;
- if(skip() || ((i=getrq()) == 0)){
- if(dip != d)wbt(0);
- if(dilev > 0){
- v.dn = dip->dnl;
- v.dl = dip->maxl;
- dip = &d[--dilev];
- offset = dip->op;
- }
- goto rtn;
- }
- if(++dilev == NDI){
- --dilev;
- prstr("Cannot divert.\n");
- edone(02);
- }
- if(dip != d)wbt(0);
- diflg++;
- dip = &d[dilev];
- dip->op = finds(i);
- dip->curd = i;
- clrmn(oldmn);
- k = (int *)&dip->dnl;
- for(j=0; j<10; j++)k[j] = 0; /*not op and curd*/
- rtn:
- app = 0;
- diflg = 0;
- }
- casedt(){
- lgf++;
- dip->dimac = dip->ditrap = dip->ditf = 0;
- skip();
- dip->ditrap = vnumb((int *)0);
- if(nonumb)return;
- skip();
- dip->dimac = getrq();
- }
- casetl(){
- register i, j;
- int w1, w2, w3, delim;
- filep begin;
- extern width(), pchar();
-
- dip->nls = 0;
- skip();
- if(dip != d)wbfl();
- if((offset = begin = alloc()) == 0)return;
- if((delim = getch()) & MOT){
- ch = delim;
- delim = '\'';
- }else delim &= CMASK;
- if(!nlflg)
- while(((i = getch()) & CMASK) != '\n'){
- if((i & CMASK) == delim)i = IMP;
- wbf(i);
- }
- wbf(IMP);wbf(IMP);wbt(0);
-
- w1 = hseg(width,begin);
- w2 = hseg(width,(filep)0);
- w3 = hseg(width,(filep)0);
- offset = dip->op;
- #ifdef NROFF
- if(!offset)horiz(po);
- #endif
- hseg(pchar,begin);
- if(w2 || w3)horiz(j=quant((lt - w2)/2-w1,HOR));
- hseg(pchar,(filep)0);
- if(w3){
- horiz(lt-w1-w2-w3-j);
- hseg(pchar,(filep)0);
- }
- newline(0);
- if(dip != d){if(dip->dnl > dip->hnl)dip->hnl = dip->dnl;}
- else{if(v.nl > dip->hnl)dip->hnl = v.nl;}
- ffree(begin);
- }
- casepc(){
- pagech = chget(IMP);
- }
- hseg(f,p)
- int (*f)();
- filep p;
- {
- register acc, i;
- static filep q;
-
- acc = 0;
- if(p)q = p;
- while(1){
- i = rbf0(q);
- q = incoff(q);
- if(!i || (i == IMP))return(acc);
- if((i & CMASK) == pagech){
- nrbits = i & ~CMASK;
- nform = fmt[findr('%')];
- acc += fnumb(v.pn,f);
- }else acc += (*f)(i);
- }
- }
- casepm(){
- register i, k;
- register char *p;
- int xx, cnt, kk, tot;
- filep j;
- char *kvt();
- char pmline[10];
-
- kk = cnt = 0;
- tot = !skip();
- for(i = 0; i<NM; i++){
- if(!((xx = contab[i].rq) & MMASK))continue;
- p = pmline;
- j = (((filep)contab[i].x.mx)<<BLKBITS);
- k = 1;
- while((j = blist[blisti(j)]) != -1){k++; j <<= BLKBITS;}
- cnt++;
- kk += k;
- if(!tot){
- *p++ = xx & 0177;
- if(!(*p++ = (xx >> BYTE) & 0177))*(p-1) = ' ';
- *p++ = ' ';
- kvt(k,p);
- prstr(pmline);
- }
- }
- if(tot || (cnt > 1)){
- kvt(kk,pmline);
- prstr(pmline);
- }
- }
- char *kvt(k,p)
- int k;
- char *p;
- {
- if(k>=100)*p++ = k/100 + '0';
- if(k>=10)*p++ = (k%100)/10 + '0';
- *p++ = k%10 + '0';
- *p++ = '\n';
- *p = 0;
- return(p);
- }
- dummy(){}
-