aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/troff/n9.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/troff/n9.c')
-rw-r--r--src/cmd/troff/n9.c488
1 files changed, 488 insertions, 0 deletions
diff --git a/src/cmd/troff/n9.c b/src/cmd/troff/n9.c
new file mode 100644
index 00000000..5cd70648
--- /dev/null
+++ b/src/cmd/troff/n9.c
@@ -0,0 +1,488 @@
+#include "tdef.h"
+#include "ext.h"
+#include "fns.h"
+
+/*
+ * troff9.c
+ *
+ * misc functions
+ */
+
+Tchar setz(void)
+{
+ Tchar i;
+
+ if (!ismot(i = getch()))
+ i |= ZBIT;
+ return(i);
+}
+
+void setline(void)
+{
+ Tchar *i;
+ Tchar c;
+ int length;
+ int j, w, cnt, delim, rem, temp;
+ Tchar linebuf[NC];
+
+ if (ismot(c = getch()))
+ return;
+ delim = cbits(c);
+ vflag = 0;
+ dfact = EM;
+ length = quant(atoi0(), HOR);
+ dfact = 1;
+ if (!length) {
+ eat(delim);
+ return;
+ }
+s0:
+ if ((j = cbits(c = getch())) == delim || j == '\n') {
+ ch = c;
+ c = RULE | chbits;
+ } else if (cbits(c) == FILLER)
+ goto s0;
+ w = width(c);
+ if (w <= 0) {
+ ERROR "zero-width underline character ignored" WARN;
+ c = RULE | chbits;
+ w = width(c);
+ }
+ i = linebuf;
+ if (length < 0) {
+ *i++ = makem(length);
+ length = -length;
+ }
+ if (!(cnt = length / w)) {
+ *i++ = makem(-(temp = ((w - length) / 2)));
+ *i++ = c;
+ *i++ = makem(-(w - length - temp));
+ goto s1;
+ }
+ if (rem = length % w) {
+ if (cbits(c) == RULE || cbits(c) == UNDERLINE || cbits(c) == ROOTEN)
+ *i++ = c | ZBIT;
+ *i++ = makem(rem);
+ }
+ if (cnt) {
+ *i++ = RPT;
+ *i++ = cnt;
+ *i++ = c;
+ }
+s1:
+ *i = 0;
+ eat(delim);
+ pushback(linebuf);
+}
+
+
+eat(int c)
+{
+ int i;
+
+ while ((i = cbits(getch())) != c && i != '\n')
+ ;
+ return(i);
+}
+
+
+void setov(void)
+{
+ int j, k;
+ Tchar i, o[NOV+1];
+ int delim, w[NOV+1];
+
+ if (ismot(i = getch()))
+ return;
+ delim = cbits(i);
+ for (k = 0; k < NOV && (j = cbits(i = getch())) != delim && j != '\n'; k++) {
+ o[k] = i;
+ w[k] = width(i);
+ }
+ o[k] = w[k] = 0;
+ if (o[0])
+ for (j = 1; j; ) {
+ j = 0;
+ for (k = 1; o[k] ; k++) {
+ if (w[k-1] < w[k]) {
+ j++;
+ i = w[k];
+ w[k] = w[k-1];
+ w[k-1] = i;
+ i = o[k];
+ o[k] = o[k-1];
+ o[k-1] = i;
+ }
+ }
+ }
+ else
+ return;
+ *pbp++ = makem(w[0] / 2);
+ for (k = 0; o[k]; k++)
+ ;
+ while (k>0) {
+ k--;
+ *pbp++ = makem(-((w[k] + w[k+1]) / 2));
+ *pbp++ = o[k];
+ }
+}
+
+
+void setbra(void)
+{
+ int k;
+ Tchar i, *j, dwn;
+ int cnt, delim;
+ Tchar brabuf[NC];
+
+ if (ismot(i = getch()))
+ return;
+ delim = cbits(i);
+ j = brabuf + 1;
+ cnt = 0;
+ if (NROFF)
+ dwn = (2 * t.Halfline) | MOT | VMOT;
+ else
+ dwn = EM | MOT | VMOT;
+ while ((k = cbits(i = getch())) != delim && k != '\n' && j <= brabuf + NC - 4) {
+ *j++ = i | ZBIT;
+ *j++ = dwn;
+ cnt++;
+ }
+ if (--cnt < 0)
+ return;
+ else if (!cnt) {
+ ch = *(j - 2);
+ return;
+ }
+ *j = 0;
+ if (NROFF)
+ *--j = *brabuf = (cnt * t.Halfline) | MOT | NMOT | VMOT;
+ else
+ *--j = *brabuf = (cnt * EM) / 2 | MOT | NMOT | VMOT;
+ *--j &= ~ZBIT;
+ pushback(brabuf);
+}
+
+
+void setvline(void)
+{
+ int i;
+ Tchar c, rem, ver, neg;
+ int cnt, delim, v;
+ Tchar vlbuf[NC];
+ Tchar *vlp;
+
+ if (ismot(c = getch()))
+ return;
+ delim = cbits(c);
+ dfact = lss;
+ vflag++;
+ i = quant(atoi0(), VERT);
+ dfact = 1;
+ if (!i) {
+ eat(delim);
+ vflag = 0;
+ return;
+ }
+ if ((cbits(c = getch())) == delim) {
+ c = BOXRULE | chbits; /*default box rule*/
+ } else
+ getch();
+ c |= ZBIT;
+ neg = 0;
+ if (i < 0) {
+ i = -i;
+ neg = NMOT;
+ }
+ if (NROFF)
+ v = 2 * t.Halfline;
+ else {
+ v = EM;
+ if (v < VERT) /* ATT EVK hack: Erik van Konijnenburg, */
+ v = VERT; /* hvlpb!evkonij, ATT NSI Hilversum, Holland */
+ }
+
+ cnt = i / v;
+ rem = makem(i % v) | neg;
+ ver = makem(v) | neg;
+ vlp = vlbuf;
+ if (!neg)
+ *vlp++ = ver;
+ if (absmot(rem) != 0) {
+ *vlp++ = c;
+ *vlp++ = rem;
+ }
+ while (vlp < vlbuf + NC - 3 && cnt--) {
+ *vlp++ = c;
+ *vlp++ = ver;
+ }
+ *(vlp - 2) &= ~ZBIT;
+ if (!neg)
+ vlp--;
+ *vlp = 0;
+ pushback(vlbuf);
+ vflag = 0;
+}
+
+#define NPAIR (NC/2-6) /* max pairs in spline, etc. */
+
+void setdraw(void) /* generate internal cookies for a drawing function */
+{
+ int i, j, k, dx[NPAIR], dy[NPAIR], delim, type;
+ Tchar c, drawbuf[NC];
+ int drawch = '.'; /* character to draw with */
+
+ /* input is \D'f dx dy dx dy ... c' (or at least it had better be) */
+ /* this does drawing function f with character c and the */
+ /* specified dx,dy pairs interpreted as appropriate */
+ /* pairs are deltas from last point, except for radii */
+
+ /* l dx dy: line from here by dx,dy */
+ /* c x: circle of diameter x, left side here */
+ /* e x y: ellipse of diameters x,y, left side here */
+ /* a dx1 dy1 dx2 dy2:
+ ccw arc: ctr at dx1,dy1, then end at dx2,dy2 from there */
+ /* ~ dx1 dy1 dx2 dy2...:
+ spline to dx1,dy1 to dx2,dy2 ... */
+ /* b x c:
+ built-up character of type c, ht x */
+ /* f dx dy ...: f is any other char: like spline */
+
+ if (ismot(c = getch()))
+ return;
+ delim = cbits(c);
+ numerr.escarg = type = cbits(getch());
+ if (type == '~') /* head off the .tr ~ problem */
+ type = 's';
+ for (i = 0; i < NPAIR ; i++) {
+ skip();
+ vflag = 0;
+ dfact = EM;
+ dx[i] = quant(atoi0(), HOR);
+ if (dx[i] > MAXMOT)
+ dx[i] = MAXMOT;
+ else if (dx[i] < -MAXMOT)
+ dx[i] = -MAXMOT;
+ skip();
+ if (type == 'c') {
+ dy[i] = 0;
+ goto eat;
+ }
+ vflag = 1;
+ dfact = lss;
+ dy[i] = quant(atoi0(), VERT);
+ if (dy[i] > MAXMOT)
+ dy[i] = MAXMOT;
+ else if (dy[i] < -MAXMOT)
+ dy[i] = -MAXMOT;
+eat:
+ if (cbits(c = getch()) != ' ') { /* must be the end */
+ if (cbits(c) != delim) {
+ drawch = cbits(c);
+ getch();
+ }
+ i++;
+ break;
+ }
+ }
+ dfact = 1;
+ vflag = 0;
+ if (TROFF) {
+ drawbuf[0] = DRAWFCN | chbits | ZBIT;
+ drawbuf[1] = type | chbits | ZBIT;
+ drawbuf[2] = drawch | chbits | ZBIT;
+ for (k = 0, j = 3; k < i; k++) {
+ drawbuf[j++] = MOT | ((dx[k] >= 0) ? dx[k] : (NMOT | -dx[k]));
+ drawbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ? dy[k] : (NMOT | -dy[k]));
+ }
+ if (type == DRAWELLIPSE) {
+ drawbuf[5] = drawbuf[4] | NMOT; /* so the net vertical is zero */
+ j = 6;
+ } else if (type == DRAWBUILD) {
+ drawbuf[4] = drawbuf[3] | NMOT; /* net horizontal motion is zero */
+ drawbuf[2] &= ~ZBIT; /* width taken from drawing char */
+ j = 5;
+ }
+ drawbuf[j++] = DRAWFCN | chbits | ZBIT; /* marks end for ptout */
+ drawbuf[j] = 0;
+ pushback(drawbuf);
+ }
+}
+
+
+void casefc(void)
+{
+ int i;
+ Tchar j;
+
+ gchtab[fc] &= ~FCBIT;
+ fc = IMP;
+ padc = ' ';
+ if (skip() || ismot(j = getch()) || (i = cbits(j)) == '\n')
+ return;
+ fc = i;
+ gchtab[fc] |= FCBIT;
+ if (skip() || ismot(ch) || (ch = cbits(ch)) == fc)
+ return;
+ padc = ch;
+}
+
+
+Tchar setfield(int x)
+{
+ Tchar ii, jj, *fp;
+ int i, j;
+ int length, ws, npad, temp, type;
+ Tchar **pp, *padptr[NPP];
+ Tchar fbuf[FBUFSZ];
+ int savfc, savtc, savlc;
+ Tchar rchar;
+ int savepos;
+ static Tchar wbuf[] = { WORDSP, 0};
+
+ if (x == tabch)
+ rchar = tabc | chbits;
+ else if (x == ldrch)
+ rchar = dotc | chbits;
+ temp = npad = ws = 0;
+ savfc = fc;
+ savtc = tabch;
+ savlc = ldrch;
+ tabch = ldrch = fc = IMP;
+ savepos = numtabp[HP].val;
+ gchtab[tabch] &= ~TABBIT;
+ gchtab[ldrch] &= ~LDRBIT;
+ gchtab[fc] &= ~FCBIT;
+ gchtab[IMP] |= TABBIT|LDRBIT|FCBIT;
+ for (j = 0; ; j++) {
+ if ((tabtab[j] & TABMASK) == 0) {
+ if (x == savfc)
+ ERROR "zero field width." WARN;
+ jj = 0;
+ goto rtn;
+ }
+ if ((length = ((tabtab[j] & TABMASK) - numtabp[HP].val)) > 0 )
+ break;
+ }
+ type = tabtab[j] & ~TABMASK;
+ fp = fbuf;
+ pp = padptr;
+ if (x == savfc) {
+ while (1) {
+ j = cbits(ii = getch());
+ jj = width(ii);
+ widthp = jj;
+ numtabp[HP].val += jj;
+ if (j == padc) {
+ npad++;
+ *pp++ = fp;
+ if (pp > padptr + NPP - 1)
+ break;
+ goto s1;
+ } else if (j == savfc)
+ break;
+ else if (j == '\n') {
+ temp = j;
+ if (nlflg && ip == 0) {
+ numtabp[CD].val--;
+ nlflg = 0;
+ }
+ break;
+ }
+ ws += jj;
+s1:
+ *fp++ = ii;
+ if (fp > fbuf + FBUFSZ - 3)
+ break;
+ }
+ if (ws)
+ *fp++ = WORDSP;
+ if (!npad) {
+ npad++;
+ *pp++ = fp;
+ *fp++ = 0;
+ }
+ *fp++ = temp;
+ *fp = 0;
+ temp = i = (j = length - ws) / npad;
+ i = (i / HOR) * HOR;
+ if ((j -= i * npad) < 0)
+ j = -j;
+ ii = makem(i);
+ if (temp < 0)
+ ii |= NMOT;
+ for (; npad > 0; npad--) {
+ *(*--pp) = ii;
+ if (j) {
+ j -= HOR;
+ (*(*pp)) += HOR;
+ }
+ }
+ pushback(fbuf);
+ jj = 0;
+ } else if (type == 0) {
+ /*plain tab or leader*/
+ if ((j = width(rchar)) > 0) {
+ int nchar = length / j;
+ while (nchar-->0 && pbp < &pbbuf[NC-3]) {
+ numtabp[HP].val += j;
+ widthp = j;
+ *pbp++ = rchar;
+ }
+ length %= j;
+ }
+ if (length)
+ jj = length | MOT;
+ else
+ jj = getch0();
+ if (savepos > 0)
+ pushback(wbuf);
+ } else {
+ /*center tab*/
+ /*right tab*/
+ while ((j = cbits(ii = getch())) != savtc && j != '\n' && j != savlc) {
+ jj = width(ii);
+ ws += jj;
+ numtabp[HP].val += jj;
+ widthp = jj;
+ *fp++ = ii;
+ if (fp > fbuf + FBUFSZ - 3)
+ break;
+ }
+ *fp++ = ii;
+ *fp = 0;
+ if (type == RTAB)
+ length -= ws;
+ else
+ length -= ws / 2; /*CTAB*/
+ pushback(fbuf);
+ if ((j = width(rchar)) != 0 && length > 0) {
+ int nchar = length / j;
+ while (nchar-- > 0 && pbp < &pbbuf[NC-3])
+ *pbp++ = rchar;
+ length %= j;
+ }
+ if (savepos > 0)
+ pushback(wbuf);
+ length = (length / HOR) * HOR;
+ jj = makem(length);
+ if (nlflg) {
+ if (ip == 0)
+ numtabp[CD].val--;
+ nlflg = 0;
+ }
+ }
+rtn:
+ gchtab[fc] &= ~FCBIT;
+ gchtab[tabch] &= ~TABBIT;
+ gchtab[ldrch] &= ~LDRBIT;
+ fc = savfc;
+ tabch = savtc;
+ ldrch = savlc;
+ gchtab[fc] |= FCBIT;
+ gchtab[tabch] = TABBIT;
+ gchtab[ldrch] |= LDRBIT;
+ numtabp[HP].val = savepos;
+ return(jj);
+}