xref: /csrg-svn/old/roff/common_source/n9.c (revision 48302)
1*48302Sbostic /*-
2*48302Sbostic  * Copyright (c) 1991 The Regents of the University of California.
3*48302Sbostic  * All rights reserved.
4*48302Sbostic  *
5*48302Sbostic  * %sccs.include.proprietary.c%
6*48302Sbostic  */
7*48302Sbostic 
87073Srrh #ifndef lint
9*48302Sbostic static char sccsid[] = "@(#)n9.c	4.3 (Berkeley) 04/18/91";
10*48302Sbostic #endif /* not lint */
117073Srrh 
127073Srrh #include "tdef.h"
137073Srrh extern
147073Srrh #include "d.h"
157073Srrh extern
167073Srrh #include "v.h"
177073Srrh #ifdef NROFF
187073Srrh extern
197073Srrh #include "tw.h"
207073Srrh #endif
217073Srrh /*
227073Srrh troff9.c
237073Srrh 
247073Srrh misc functions
257073Srrh */
267073Srrh 
277073Srrh extern int cbuf[];
287073Srrh extern int *cp;
297073Srrh extern int ch;
307073Srrh extern int chbits;
317073Srrh extern int dfact;
327073Srrh extern int vflag;
337073Srrh extern int pts;
347073Srrh extern int fc;
357073Srrh extern int padc;
367073Srrh extern int tabtab[];
377073Srrh extern int nlflg;
387073Srrh extern int lss;
397073Srrh extern int tabch, ldrch;
407073Srrh extern int tabc, dotc;
417073Srrh extern int nchar, rchar;
427073Srrh extern int xxx;
437073Srrh 
setz()447073Srrh setz(){
457073Srrh 	register i;
467073Srrh 
477073Srrh 	if(!((i = getch()) & MOT))i |= ZBIT;
487073Srrh 	return(i);
497073Srrh }
setline()507073Srrh setline(){
517073Srrh 	register *i, length, c;
527073Srrh 	int w, cnt, delim, rem, temp;
537073Srrh 
547073Srrh 	if((delim = getch()) & MOT)return;
557073Srrh 		else delim &= CMASK;
567073Srrh 	vflag = 0;
577073Srrh 	dfact = EM;
587073Srrh 	length = quant(atoi(),HOR);
597073Srrh 	dfact = 1;
607073Srrh 	if(!length){
617073Srrh 		eat(delim);
627073Srrh 		return;
637073Srrh 	}
647073Srrh s0:
657073Srrh 	if(((c = getch()) & CMASK) == delim){
667073Srrh 		ch = c;
677073Srrh 		c = 0204 | chbits;
687073Srrh 	}else if((c & CMASK) == FILLER)goto s0;
697073Srrh 	w = width(c);
707073Srrh 	i = cbuf;
717073Srrh 	if(length < 0){
727073Srrh 		*i++ = makem(length);
737073Srrh 		length = -length;
747073Srrh 	}
757073Srrh 	if(!(cnt = length/w)){
767073Srrh 		*i++ = makem(-(temp = ((w-length)/2)));
777073Srrh 		*i++ = c;
787073Srrh 		*i++ = makem(-(w - length - temp));
797073Srrh 		goto s1;
807073Srrh 	}
817073Srrh 	if(rem = length%w){
827073Srrh 		switch(c & CMASK){
837073Srrh 			case 0204: /*rule*/
847073Srrh 			case 0224: /*underrule*/
857073Srrh 			case 0276: /*root en*/
867073Srrh 				*i++ = c | ZBIT;
877073Srrh 			default:
887073Srrh 				*i++ = makem(rem);
897073Srrh 		}
907073Srrh 	}
917073Srrh 	if(cnt){
927073Srrh 		*i++ = RPT;
937073Srrh 		*i++ = cnt;
947073Srrh 		*i++ = c;
957073Srrh 	}
967073Srrh s1:
977073Srrh 	*i++ = 0;
987073Srrh 	eat(delim);
997073Srrh 	cp = cbuf;
1007073Srrh }
eat(c)1017073Srrh eat(c)
1027073Srrh int c;
1037073Srrh {
1047073Srrh 	register i;
1057073Srrh 
1067073Srrh 	while(((i = getch() & CMASK) != c) &&
1077073Srrh 		(i != '\n'));
1087073Srrh 	return(i);
1097073Srrh }
setov()1107073Srrh setov(){
1117073Srrh 	register i, j, k;
11229546Smckusick 	int *p, delim, o[NOV+1], w[NOV+1];
1137073Srrh 
1147073Srrh 	if((delim = getch()) & MOT)return;
1157073Srrh 		else delim &= CMASK;
1167073Srrh 	for(k=0; (k<NOV) && ((j=(i = getch()) & CMASK) != delim) &&
1177073Srrh 		(j != '\n'); k++){
1187073Srrh 			o[k] = i;
1197073Srrh 			w[k] = width(i);
1207073Srrh 	}
1217073Srrh 	o[k] = w[k] = 0;
1227073Srrh 	if(o[0])for(j=1; j;){
1237073Srrh 		j = 0;
1247073Srrh 		for(k=1; o[k] ; k++){
1257073Srrh 			if(w[k-1] < w[k]){
1267073Srrh 				j++;
1277073Srrh 				i = w[k];
1287073Srrh 				w[k] = w[k-1];
1297073Srrh 				w[k-1] = i;
1307073Srrh 				i = o[k];
1317073Srrh 				o[k] = o[k-1];
1327073Srrh 				o[k-1] = i;
1337073Srrh 			}
1347073Srrh 		}
1357073Srrh 	}else return;
1367073Srrh 	p = cbuf;
1377073Srrh 	for(k=0; o[k]; k++){
1387073Srrh 		*p++ = o[k];
1397073Srrh 		*p++ = makem(-((w[k]+w[k+1])/2));
1407073Srrh 	}
1417073Srrh 	*p++ = makem(w[0]/2);
1427073Srrh 	*p = 0;
1437073Srrh 	cp = cbuf;
1447073Srrh }
setbra()1457073Srrh setbra(){
1467073Srrh 	register i, *j, k;
1477073Srrh 	int cnt, delim, dwn;
1487073Srrh 
1497073Srrh 	if((delim = getch()) & MOT)return;
1507073Srrh 		else delim &= CMASK;
1517073Srrh 	j = cbuf + 1;
1527073Srrh 	cnt = 0;
1537073Srrh #ifdef NROFF
1547073Srrh 	dwn = (2*t.Halfline) | MOT | VMOT;
1557073Srrh #endif
1567073Srrh #ifndef NROFF
1577073Srrh 	dwn = EM | MOT | VMOT;
1587073Srrh #endif
1597073Srrh 	while(((k = (i = getch()) & CMASK) != delim) && (k != '\n') &&
1607073Srrh 		(j <= (cbuf+NC-4))){
1617073Srrh 		*j++ = i | ZBIT;
1627073Srrh 		*j++ = dwn;
1637073Srrh 		cnt++;
1647073Srrh 	}
1657073Srrh 	if(--cnt < 0)return;
1667073Srrh 		else if (!cnt){
1677073Srrh 			ch = *(j-2);
1687073Srrh 			return;
1697073Srrh 	}
1707073Srrh 	*j = 0;
1717073Srrh #ifdef NROFF
1727073Srrh 	*--j = *cbuf = (cnt*t.Halfline) | MOT | NMOT | VMOT;
1737073Srrh #endif
1747073Srrh #ifndef NROFF
1757073Srrh 	*--j = *cbuf = (cnt*EM)/2 | MOT | NMOT | VMOT;
1767073Srrh #endif
1777073Srrh 	*--j &= ~ZBIT;
1787073Srrh 	cp = cbuf;
1797073Srrh }
setvline()1807073Srrh setvline(){
1817073Srrh 	register i, c, *k;
1827073Srrh 	int cnt, neg, rem, ver, delim;
1837073Srrh 
1847073Srrh 	if((delim = getch()) & MOT)return;
1857073Srrh 		else delim &= CMASK;
1867073Srrh 	dfact = lss;
1877073Srrh 	vflag++;
1887073Srrh 	i = quant(atoi(),VERT);
1897073Srrh 	dfact = 1;
1907073Srrh 	if(!i){
1917073Srrh 		eat(delim);
1927073Srrh 		vflag = 0;
1937073Srrh 		return;
1947073Srrh 	}
1957073Srrh 	if(((c = getch()) & CMASK) == delim){
1967073Srrh 		c = 0337 | chbits;	/*default box rule*/
1977073Srrh 	}else getch();
1987073Srrh 	c |= ZBIT;
1997073Srrh 	neg = 0;
2007073Srrh 	if(i < 0){
2017073Srrh 		i = -i;
2027073Srrh 		neg = NMOT;
2037073Srrh 	}
2047073Srrh #ifdef NROFF
2057073Srrh 	ver = 2*t.Halfline;
2067073Srrh #endif
2077073Srrh #ifndef NROFF
2087073Srrh 	ver = EM;
2097073Srrh #endif
2107073Srrh 	cnt = i/ver;
2117073Srrh 	rem = makem(i%ver) | neg;
2127073Srrh 	ver = makem(ver) | neg;
2137073Srrh 	k = cbuf;
2147073Srrh 	if(!neg)*k++ = ver;
2157073Srrh 	if(rem & ~MOTV){
2167073Srrh 		*k++ = c;
2177073Srrh 		*k++ = rem;
2187073Srrh 	}
2197073Srrh 	while((k < (cbuf+NC-3)) && cnt--){
2207073Srrh 		*k++ = c;
2217073Srrh 		*k++ = ver;
2227073Srrh 	}
2237073Srrh 	*(k-2) &= ~ZBIT;
2247073Srrh 	if(!neg)k--;
2257073Srrh 	*k = 0;
2267073Srrh 	cp = cbuf;
2277073Srrh 	vflag = 0;
2287073Srrh }
casefc()2297073Srrh casefc(){
2307073Srrh 	register i;
2317073Srrh 
2327073Srrh 	fc = IMP;
2337073Srrh 	padc = ' ';
2347073Srrh 	if(skip() ||
2357073Srrh 	   ((i = getch()) & MOT) ||
2367073Srrh 	   ((i &= CMASK) == '\n'))return;
2377073Srrh 	fc = i;
2387073Srrh 	if(skip() || (ch & MOT) || ((ch &= CMASK) == fc))return;
2397073Srrh 	padc = ch;
2407073Srrh }
setfield(x)2417073Srrh setfield(x)
2427073Srrh int x;
2437073Srrh {
2447073Srrh 	register i, j, *fp;
2457073Srrh 	int length, ws, npad, temp, type;
2467073Srrh 	int **pp, *padptr[NPP];
2477073Srrh 	static int fbuf[FBUFSZ];
2487073Srrh 	int savfc, savtc, savlc;
2497073Srrh 
2507073Srrh 	if(x == tabch) rchar = tabc | chbits;
2517073Srrh 	else if(x ==  ldrch) rchar = dotc | chbits;
2527073Srrh 	temp = npad = ws = 0;
2537073Srrh 	savfc = fc; savtc = tabch; savlc = ldrch;
2547073Srrh 	tabch = ldrch = fc = IMP;
2557073Srrh 	for(j=0;;j++){
2567073Srrh 		if((tabtab[j] & TMASK)== 0){
2577073Srrh 			if(x==savfc)prstr("Zero field width.\n");
2587073Srrh 			j = 0;
2597073Srrh 			goto rtn;
2607073Srrh 		}
2617073Srrh 		v.hp = sumhp();	/* XXX */
2627073Srrh 		if((length = ((tabtab[j] & TMASK) - v.hp)) > 0 )break;
2637073Srrh 	}
2647073Srrh 	type = tabtab[j] & (~TMASK);
2657073Srrh 	fp = fbuf;
2667073Srrh 	pp = padptr;
2677073Srrh 	if(x == savfc){while(1){
2687073Srrh 		if(((j = (i = getch()) & CMASK)) == padc){
2697073Srrh 			npad++;
2707073Srrh 			*pp++ = fp;
2717073Srrh 			if(pp > (padptr + NPP - 1))break;
2727073Srrh 			goto s1;
2737073Srrh 		}else if(j == savfc) break;
2747073Srrh 			else if(j == '\n'){
2757073Srrh 				temp = j;
2767073Srrh 				nlflg = 0;
2777073Srrh 				break;
2787073Srrh 			}
2797073Srrh 		ws += width(i);
2807073Srrh 	s1:
2817073Srrh 		*fp++ = i;
2827073Srrh 		if(fp > (fbuf + FBUFSZ -3))break;
2837073Srrh 	}
2847073Srrh 	if(!npad){
2857073Srrh 		npad++;
2867073Srrh 		*pp++ = fp;
2877073Srrh 		*fp++ = 0;
2887073Srrh 	}
2897073Srrh 	*fp++ = temp;
2907073Srrh 	*fp++ = 0;
2917073Srrh 	temp = i = (j = length-ws)/npad;
2927073Srrh 	i = (i/HOR)*HOR;
2937073Srrh 	if((j -= i*npad) <0)j = -j;
2947073Srrh 	i = makem(i);
2957073Srrh 	if(temp <0)i |= NMOT;
2967073Srrh 	for(;npad > 0; npad--){
2977073Srrh 		*(*--pp) = i;
2987073Srrh 		if(j){
2997073Srrh 			j -= HOR;
3007073Srrh 			(*(*pp)) += HOR;
3017073Srrh 		}
3027073Srrh 	}
3037073Srrh 	cp = fbuf;
3047073Srrh 	j = 0;
3057073Srrh 	}else if(type == 0){
3067073Srrh 	/*plain tab or leader*/
3077073Srrh 		if((j = width(rchar)) == 0)nchar = 0;
3087073Srrh 		else{
3097073Srrh 			nchar = length /j;
3107073Srrh 			length %= j;
3117073Srrh 		}
3127073Srrh 		if(length)j = length | MOT;
3137073Srrh 		else j = getch0();
3147073Srrh 	}else{
3157073Srrh 	/*center tab*/
3167073Srrh 	/*right tab*/
3177073Srrh 		while(((j = (i = getch()) & CMASK) != savtc) &&
3187073Srrh 			(j != '\n') && (j != savlc)){
3197073Srrh 			ws += width(i);
3207073Srrh 			*fp++ = i;
3217073Srrh 			if(fp > (fbuf +FBUFSZ - 3)) break;
3227073Srrh 		}
3237073Srrh 		*fp++ = i;
3247073Srrh 		*fp++ = 0;
3257073Srrh 		if(type == RTAB)length -= ws;
3267073Srrh 		else length -= ws/2; /*CTAB*/
3277073Srrh 		if(((j = width(rchar)) == 0) || (length <= 0))nchar = 0;
3287073Srrh 		else{
3297073Srrh 			nchar = length/j;
3307073Srrh 			length %= j;
3317073Srrh 		}
3327073Srrh 		length = (length/HOR)*HOR;
3337073Srrh 		j = makem(length);
3347073Srrh 		cp = fbuf;
3357073Srrh 		nlflg = 0;
3367073Srrh 	}
3377073Srrh rtn:
3387073Srrh 	fc = savfc; tabch = savtc; ldrch = savlc;
3397073Srrh 	return(j);
3407073Srrh }
341