mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
1150 lines
14 KiB
C
1150 lines
14 KiB
C
/*
|
|
* troff5.c
|
|
*
|
|
* misc processing requests
|
|
*/
|
|
|
|
#include "tdef.h"
|
|
#include "fns.h"
|
|
#include "ext.h"
|
|
|
|
int iflist[NIF];
|
|
int ifx;
|
|
int ifnum = 0; /* trying numeric expression for .if or .ie condition */
|
|
|
|
void casead(void)
|
|
{
|
|
int i;
|
|
|
|
ad = 1;
|
|
/* leave admod alone */
|
|
if (skip())
|
|
return;
|
|
switch (i = cbits(getch())) {
|
|
case 'r': /* right adj, left ragged */
|
|
admod = 2;
|
|
break;
|
|
case 'l': /* left adj, right ragged */
|
|
admod = ad = 0; /* same as casena */
|
|
break;
|
|
case 'c': /*centered adj*/
|
|
admod = 1;
|
|
break;
|
|
case 'b':
|
|
case 'n':
|
|
admod = 0;
|
|
break;
|
|
case '0':
|
|
case '2':
|
|
case '4':
|
|
ad = 0;
|
|
case '1':
|
|
case '3':
|
|
case '5':
|
|
admod = (i - '0') / 2;
|
|
}
|
|
}
|
|
|
|
|
|
void casena(void)
|
|
{
|
|
ad = 0;
|
|
}
|
|
|
|
|
|
void casefi(void)
|
|
{
|
|
tbreak();
|
|
fi = 1;
|
|
pendnf = 0;
|
|
}
|
|
|
|
|
|
void casenf(void)
|
|
{
|
|
tbreak();
|
|
fi = 0;
|
|
}
|
|
|
|
|
|
void casers(void)
|
|
{
|
|
dip->nls = 0;
|
|
}
|
|
|
|
|
|
void casens(void)
|
|
{
|
|
dip->nls++;
|
|
}
|
|
|
|
int
|
|
chget(int c)
|
|
{
|
|
Tchar i;
|
|
|
|
i = 0;
|
|
if (skip() || ismot(i = getch()) || cbits(i) == ' ' || cbits(i) == '\n') {
|
|
ch = i;
|
|
return(c);
|
|
} else
|
|
return cbits(i); /* was (i & BYTEMASK) */
|
|
}
|
|
|
|
|
|
void casecc(void)
|
|
{
|
|
cc = chget('.');
|
|
}
|
|
|
|
|
|
void casec2(void)
|
|
{
|
|
c2 = chget('\'');
|
|
}
|
|
|
|
|
|
void casehc(void)
|
|
{
|
|
ohc = chget(OHC);
|
|
}
|
|
|
|
|
|
void casetc(void)
|
|
{
|
|
tabc = chget(0);
|
|
}
|
|
|
|
|
|
void caselc(void)
|
|
{
|
|
dotc = chget(0);
|
|
}
|
|
|
|
|
|
void casehy(void)
|
|
{
|
|
int i;
|
|
|
|
hyf = 1;
|
|
if (skip())
|
|
return;
|
|
noscale++;
|
|
i = atoi0();
|
|
noscale = 0;
|
|
if (nonumb)
|
|
return;
|
|
hyf = max(i, 0);
|
|
}
|
|
|
|
|
|
void casenh(void)
|
|
{
|
|
hyf = 0;
|
|
}
|
|
|
|
int
|
|
max(int aa, int bb)
|
|
{
|
|
if (aa > bb)
|
|
return(aa);
|
|
else
|
|
return(bb);
|
|
}
|
|
|
|
|
|
void casece(void)
|
|
{
|
|
int i;
|
|
|
|
noscale++;
|
|
skip();
|
|
i = max(atoi0(), 0);
|
|
if (nonumb)
|
|
i = 1;
|
|
tbreak();
|
|
ce = i;
|
|
noscale = 0;
|
|
}
|
|
|
|
|
|
void casein(void)
|
|
{
|
|
int i;
|
|
|
|
if (skip())
|
|
i = in1;
|
|
else {
|
|
i = max(hnumb(&in), 0);
|
|
if (nonumb)
|
|
i = in1;
|
|
}
|
|
tbreak();
|
|
in1 = in;
|
|
in = i;
|
|
if (!nc) {
|
|
un = in;
|
|
setnel();
|
|
}
|
|
}
|
|
|
|
|
|
void casell(void)
|
|
{
|
|
int i;
|
|
|
|
if (skip())
|
|
i = ll1;
|
|
else {
|
|
i = max(hnumb(&ll), INCH / 10);
|
|
if (nonumb)
|
|
i = ll1;
|
|
}
|
|
ll1 = ll;
|
|
ll = i;
|
|
setnel();
|
|
}
|
|
|
|
|
|
void caselt(void)
|
|
{
|
|
int i;
|
|
|
|
if (skip())
|
|
i = lt1;
|
|
else {
|
|
i = max(hnumb(<), 0);
|
|
if (nonumb)
|
|
i = lt1;
|
|
}
|
|
lt1 = lt;
|
|
lt = i;
|
|
}
|
|
|
|
|
|
void caseti(void)
|
|
{
|
|
int i;
|
|
|
|
if (skip())
|
|
return;
|
|
i = max(hnumb(&in), 0);
|
|
tbreak();
|
|
un1 = i;
|
|
setnel();
|
|
}
|
|
|
|
|
|
void casels(void)
|
|
{
|
|
int i;
|
|
|
|
noscale++;
|
|
if (skip())
|
|
i = ls1;
|
|
else {
|
|
i = max(inumb(&ls), 1);
|
|
if (nonumb)
|
|
i = ls1;
|
|
}
|
|
ls1 = ls;
|
|
ls = i;
|
|
noscale = 0;
|
|
}
|
|
|
|
|
|
void casepo(void)
|
|
{
|
|
int i;
|
|
|
|
if (skip())
|
|
i = po1;
|
|
else {
|
|
i = max(hnumb(&po), 0);
|
|
if (nonumb)
|
|
i = po1;
|
|
}
|
|
po1 = po;
|
|
po = i;
|
|
if (TROFF & !ascii)
|
|
esc += po - po1;
|
|
}
|
|
|
|
|
|
void casepl(void)
|
|
{
|
|
int i;
|
|
|
|
skip();
|
|
if ((i = vnumb(&pl)) == 0)
|
|
pl = 11 * INCH; /*11in*/
|
|
else
|
|
pl = i;
|
|
if (numtabp[NL].val > pl)
|
|
numtabp[NL].val = pl;
|
|
}
|
|
|
|
|
|
void casewh(void)
|
|
{
|
|
int i, j, k;
|
|
|
|
lgf++;
|
|
skip();
|
|
i = vnumb((int *)0);
|
|
if (nonumb)
|
|
return;
|
|
skip();
|
|
j = getrq();
|
|
if ((k = findn(i)) != NTRAP) {
|
|
mlist[k] = j;
|
|
return;
|
|
}
|
|
for (k = 0; k < NTRAP; k++)
|
|
if (mlist[k] == 0)
|
|
break;
|
|
if (k == NTRAP) {
|
|
flusho();
|
|
ERROR "cannot plant trap." WARN;
|
|
return;
|
|
}
|
|
mlist[k] = j;
|
|
nlist[k] = i;
|
|
}
|
|
|
|
|
|
void casech(void)
|
|
{
|
|
int i, j, k;
|
|
|
|
lgf++;
|
|
skip();
|
|
if (!(j = getrq()))
|
|
return;
|
|
else
|
|
for (k = 0; k < NTRAP; k++)
|
|
if (mlist[k] == j)
|
|
break;
|
|
if (k == NTRAP)
|
|
return;
|
|
skip();
|
|
i = vnumb((int *)0);
|
|
if (nonumb)
|
|
mlist[k] = 0;
|
|
nlist[k] = i;
|
|
}
|
|
|
|
int
|
|
findn(int i)
|
|
{
|
|
int k;
|
|
|
|
for (k = 0; k < NTRAP; k++)
|
|
if ((nlist[k] == i) && (mlist[k] != 0))
|
|
break;
|
|
return(k);
|
|
}
|
|
|
|
|
|
void casepn(void)
|
|
{
|
|
int i;
|
|
|
|
skip();
|
|
noscale++;
|
|
i = max(inumb(&numtabp[PN].val), 0);
|
|
noscale = 0;
|
|
if (!nonumb) {
|
|
npn = i;
|
|
npnflg++;
|
|
}
|
|
}
|
|
|
|
|
|
void casebp(void)
|
|
{
|
|
int i;
|
|
Stack *savframe;
|
|
|
|
if (dip != d)
|
|
return;
|
|
savframe = frame;
|
|
skip();
|
|
if ((i = inumb(&numtabp[PN].val)) < 0)
|
|
i = 0;
|
|
tbreak();
|
|
if (!nonumb) {
|
|
npn = i;
|
|
npnflg++;
|
|
} else if (dip->nls)
|
|
return;
|
|
eject(savframe);
|
|
}
|
|
|
|
void casetm(void)
|
|
{
|
|
casetm1(0, stderr);
|
|
}
|
|
|
|
|
|
void casefm(void)
|
|
{
|
|
static struct fcache {
|
|
char *name;
|
|
FILE *fp;
|
|
} fcache[15];
|
|
int i;
|
|
|
|
if ( skip() || !getname()) {
|
|
ERROR "fm: missing filename" WARN;
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < 15 && fcache[i].fp != NULL; i++) {
|
|
if (strcmp(nextf, fcache[i].name) == 0)
|
|
break;
|
|
}
|
|
if (i >= 15) {
|
|
ERROR "fm: too many streams" WARN;
|
|
return;
|
|
}
|
|
if (fcache[i].fp == NULL) {
|
|
if( (fcache[i].fp = fopen(unsharp(nextf), "w")) == NULL) {
|
|
ERROR "fm: cannot open %s", nextf WARN;
|
|
return;
|
|
}
|
|
fcache[i].name = strdupl(nextf);
|
|
}
|
|
casetm1(0, fcache[i].fp);
|
|
}
|
|
|
|
void casetm1(int ab, FILE *out)
|
|
{
|
|
int i, j, c;
|
|
char *p;
|
|
char tmbuf[NTM];
|
|
|
|
lgf++;
|
|
copyf++;
|
|
if (ab) {
|
|
if (skip())
|
|
ERROR "User Abort" WARN;
|
|
else {
|
|
extern int error;
|
|
int savtrac = trace;
|
|
i = trace = 0;
|
|
noscale++;
|
|
i = inumb(&trace);
|
|
noscale--;
|
|
if (i) {
|
|
error = i;
|
|
if (nlflg || skip())
|
|
ERROR "User Abort, exit code %d", i WARN;
|
|
}
|
|
trace = savtrac;
|
|
}
|
|
} else
|
|
skip();
|
|
for (i = 0; i < NTM - 2; ) {
|
|
if ((c = cbits(getch())) == '\n' || c == RIGHT)
|
|
break;
|
|
else if (c == MINUS) { /* special pleading for strange encodings */
|
|
tmbuf[i++] = '\\';
|
|
tmbuf[i++] = '-';
|
|
} else if (c == PRESC) {
|
|
tmbuf[i++] = '\\';
|
|
tmbuf[i++] = 'e';
|
|
} else if (c == FILLER) {
|
|
tmbuf[i++] = '\\';
|
|
tmbuf[i++] = '&';
|
|
} else if (c == UNPAD) {
|
|
tmbuf[i++] = '\\';
|
|
tmbuf[i++] = ' ';
|
|
} else if (c == OHC) {
|
|
tmbuf[i++] = '\\';
|
|
tmbuf[i++] = '%';
|
|
} else if (c >= ALPHABET) {
|
|
p = chname(c);
|
|
switch (*p) {
|
|
case MBchar:
|
|
sprintf(&tmbuf[i], p+1);
|
|
break;
|
|
case Number:
|
|
sprintf(&tmbuf[i], "\\N'%s'", p+1);
|
|
break;
|
|
case Troffchar:
|
|
if ((j = strlen(p+1)) == 2)
|
|
sprintf(&tmbuf[i], "\\(%s", p+1);
|
|
else
|
|
sprintf(&tmbuf[i], "\\C'%s'", p+1);
|
|
break;
|
|
default:
|
|
sprintf(&tmbuf[i]," %s? ", p);
|
|
break;
|
|
}
|
|
j = strlen(&tmbuf[i]);
|
|
i += j;
|
|
} else
|
|
tmbuf[i++] = c;
|
|
}
|
|
tmbuf[i] = 0;
|
|
if (ab) /* truncate output */
|
|
obufp = obuf; /* should be a function in n2.c */
|
|
flusho();
|
|
if (i)
|
|
fprintf(out, "%s\n", tmbuf);
|
|
fflush(out);
|
|
copyf--;
|
|
lgf--;
|
|
}
|
|
|
|
|
|
void casesp(void)
|
|
{
|
|
casesp1(0);
|
|
}
|
|
|
|
void casesp1(int a)
|
|
{
|
|
int i, j, savlss;
|
|
|
|
tbreak();
|
|
if (dip->nls || trap)
|
|
return;
|
|
i = findt1();
|
|
if (!a) {
|
|
skip();
|
|
j = vnumb((int *)0);
|
|
if (nonumb)
|
|
j = lss;
|
|
} else
|
|
j = a;
|
|
if (j == 0)
|
|
return;
|
|
if (i < j)
|
|
j = i;
|
|
savlss = lss;
|
|
if (dip != d)
|
|
i = dip->dnl;
|
|
else
|
|
i = numtabp[NL].val;
|
|
if ((i + j) < 0)
|
|
j = -i;
|
|
lss = j;
|
|
newline(0);
|
|
lss = savlss;
|
|
}
|
|
|
|
|
|
void casert(void)
|
|
{
|
|
int a, *p;
|
|
|
|
skip();
|
|
if (dip != d)
|
|
p = &dip->dnl;
|
|
else
|
|
p = &numtabp[NL].val;
|
|
a = vnumb(p);
|
|
if (nonumb)
|
|
a = dip->mkline;
|
|
if ((a < 0) || (a >= *p))
|
|
return;
|
|
nb++;
|
|
casesp1(a - *p);
|
|
}
|
|
|
|
|
|
void caseem(void)
|
|
{
|
|
lgf++;
|
|
skip();
|
|
em = getrq();
|
|
}
|
|
|
|
|
|
void casefl(void)
|
|
{
|
|
tbreak();
|
|
if (!ascii)
|
|
ptflush();
|
|
flusho();
|
|
}
|
|
|
|
|
|
void caseev(void)
|
|
{
|
|
int nxev;
|
|
|
|
if (skip()) {
|
|
e0:
|
|
if (evi == 0)
|
|
return;
|
|
nxev = evlist[--evi];
|
|
goto e1;
|
|
}
|
|
noscale++;
|
|
nxev = atoi0();
|
|
noscale = 0;
|
|
if (nonumb)
|
|
goto e0;
|
|
flushi();
|
|
if (nxev >= NEV || nxev < 0 || evi >= EVLSZ) {
|
|
flusho();
|
|
ERROR "cannot do .ev %d", nxev WARN;
|
|
if (error)
|
|
done2(040);
|
|
else
|
|
edone(040);
|
|
return;
|
|
}
|
|
evlist[evi++] = ev;
|
|
e1:
|
|
if (ev == nxev)
|
|
return;
|
|
ev = nxev;
|
|
envp = &env[ev];
|
|
}
|
|
|
|
void envcopy(Env *e1, Env *e2) /* copy env e2 to e1 */
|
|
{
|
|
*e1 = *e2; /* rumor hath that this fails on some machines */
|
|
}
|
|
|
|
|
|
void caseel(void)
|
|
{
|
|
if (--ifx < 0) {
|
|
ifx = 0;
|
|
iflist[0] = 0;
|
|
}
|
|
caseif1(2);
|
|
}
|
|
|
|
|
|
void caseie(void)
|
|
{
|
|
if (ifx >= NIF) {
|
|
ERROR "if-else overflow." WARN;
|
|
ifx = 0;
|
|
edone(040);
|
|
}
|
|
caseif1(1);
|
|
ifx++;
|
|
}
|
|
|
|
|
|
void caseif(void)
|
|
{
|
|
caseif1(0);
|
|
}
|
|
|
|
void caseif1(int x)
|
|
{
|
|
extern int falsef;
|
|
int notflag, true;
|
|
Tchar i;
|
|
|
|
if (x == 2) {
|
|
notflag = 0;
|
|
true = iflist[ifx];
|
|
goto i1;
|
|
}
|
|
true = 0;
|
|
skip();
|
|
if ((cbits(i = getch())) == '!') {
|
|
notflag = 1;
|
|
} else {
|
|
notflag = 0;
|
|
ch = i;
|
|
}
|
|
ifnum++;
|
|
i = atoi0();
|
|
ifnum = 0;
|
|
if (!nonumb) {
|
|
if (i > 0)
|
|
true++;
|
|
goto i1;
|
|
}
|
|
i = getch();
|
|
switch (cbits(i)) {
|
|
case 'e':
|
|
if (!(numtabp[PN].val & 01))
|
|
true++;
|
|
break;
|
|
case 'o':
|
|
if (numtabp[PN].val & 01)
|
|
true++;
|
|
break;
|
|
case 'n':
|
|
if (NROFF)
|
|
true++;
|
|
break;
|
|
case 't':
|
|
if (TROFF)
|
|
true++;
|
|
break;
|
|
case ' ':
|
|
break;
|
|
default:
|
|
true = cmpstr(i);
|
|
}
|
|
i1:
|
|
true ^= notflag;
|
|
if (x == 1)
|
|
iflist[ifx] = !true;
|
|
if (true) {
|
|
i2:
|
|
while ((cbits(i = getch())) == ' ')
|
|
;
|
|
if (cbits(i) == LEFT)
|
|
goto i2;
|
|
ch = i;
|
|
nflush++;
|
|
} else {
|
|
if (!nlflg) {
|
|
copyf++;
|
|
falsef++;
|
|
eatblk(0);
|
|
copyf--;
|
|
falsef--;
|
|
}
|
|
}
|
|
}
|
|
|
|
void eatblk(int inblk)
|
|
{
|
|
int cnt, i;
|
|
|
|
cnt = 0;
|
|
do {
|
|
if (ch) {
|
|
i = cbits(ch);
|
|
ch = 0;
|
|
} else
|
|
i = cbits(getch0());
|
|
if (i == ESC)
|
|
cnt++;
|
|
else {
|
|
if (cnt == 1)
|
|
switch (i) {
|
|
case '{': i = LEFT; break;
|
|
case '}': i = RIGHT; break;
|
|
case '\n': i = 'x'; break;
|
|
}
|
|
cnt = 0;
|
|
}
|
|
if (i == LEFT) eatblk(1);
|
|
} while ((!inblk && (i != '\n')) || (inblk && (i != RIGHT)));
|
|
if (i == '\n') {
|
|
nlflg++;
|
|
if (ip == 0)
|
|
numtabp[CD].val++;
|
|
}
|
|
}
|
|
|
|
int
|
|
cmpstr(Tchar c)
|
|
{
|
|
int j, delim;
|
|
Tchar i;
|
|
int val;
|
|
int savapts, savapts1, savfont, savfont1, savpts, savpts1;
|
|
Tchar string[1280];
|
|
Tchar *sp;
|
|
|
|
if (ismot(c))
|
|
return(0);
|
|
delim = cbits(c);
|
|
savapts = apts;
|
|
savapts1 = apts1;
|
|
savfont = font;
|
|
savfont1 = font1;
|
|
savpts = pts;
|
|
savpts1 = pts1;
|
|
sp = string;
|
|
while ((j = cbits(i = getch()))!=delim && j!='\n' && sp<&string[1280-1])
|
|
*sp++ = i;
|
|
if (sp >= string + 1280) {
|
|
ERROR "too-long string compare." WARN;
|
|
edone(0100);
|
|
}
|
|
if (nlflg) {
|
|
val = sp==string;
|
|
goto rtn;
|
|
}
|
|
*sp = 0;
|
|
apts = savapts;
|
|
apts1 = savapts1;
|
|
font = savfont;
|
|
font1 = savfont1;
|
|
pts = savpts;
|
|
pts1 = savpts1;
|
|
mchbits();
|
|
val = 1;
|
|
sp = string;
|
|
while ((j = cbits(i = getch())) != delim && j != '\n') {
|
|
if (*sp != i) {
|
|
eat(delim);
|
|
val = 0;
|
|
goto rtn;
|
|
}
|
|
sp++;
|
|
}
|
|
if (*sp)
|
|
val = 0;
|
|
rtn:
|
|
apts = savapts;
|
|
apts1 = savapts1;
|
|
font = savfont;
|
|
font1 = savfont1;
|
|
pts = savpts;
|
|
pts1 = savpts1;
|
|
mchbits();
|
|
return(val);
|
|
}
|
|
|
|
|
|
void caserd(void)
|
|
{
|
|
|
|
lgf++;
|
|
skip();
|
|
getname();
|
|
if (!iflg) {
|
|
if (quiet) {
|
|
if (NROFF) {
|
|
echo_off();
|
|
flusho();
|
|
}
|
|
fprintf(stderr, "\007"); /*bell*/
|
|
} else {
|
|
if (nextf[0]) {
|
|
fprintf(stderr, "%s:", nextf);
|
|
} else {
|
|
fprintf(stderr, "\007"); /*bell*/
|
|
}
|
|
}
|
|
}
|
|
collect();
|
|
tty++;
|
|
pushi(RD_OFFSET, PAIR('r','d'));
|
|
}
|
|
|
|
int
|
|
rdtty(void)
|
|
{
|
|
char onechar;
|
|
|
|
onechar = 0;
|
|
if (read(0, &onechar, 1) == 1) {
|
|
if (onechar == '\n')
|
|
tty++;
|
|
else
|
|
tty = 1;
|
|
if (tty != 3)
|
|
return(onechar);
|
|
}
|
|
tty = 0;
|
|
if (NROFF && quiet)
|
|
echo_on();
|
|
return(0);
|
|
}
|
|
|
|
|
|
void caseec(void)
|
|
{
|
|
eschar = chget('\\');
|
|
}
|
|
|
|
|
|
void caseeo(void)
|
|
{
|
|
eschar = 0;
|
|
}
|
|
|
|
|
|
void caseta(void)
|
|
{
|
|
int i, j, k;
|
|
|
|
tabtab[0] = nonumb = 0;
|
|
for (i = 0; ((i < (NTAB - 1)) && !nonumb); i++) {
|
|
if (skip())
|
|
break;
|
|
k = tabtab[max(i-1, 0)] & TABMASK;
|
|
if ((j = max(hnumb(&k), 0)) > TABMASK) {
|
|
ERROR "Tab too far away" WARN;
|
|
j = TABMASK;
|
|
}
|
|
tabtab[i] = j & TABMASK;
|
|
if (!nonumb)
|
|
switch (cbits(ch)) {
|
|
case 'C':
|
|
tabtab[i] |= CTAB;
|
|
break;
|
|
case 'R':
|
|
tabtab[i] |= RTAB;
|
|
break;
|
|
default: /*includes L*/
|
|
break;
|
|
}
|
|
nonumb = ch = 0;
|
|
}
|
|
if (!skip())
|
|
ERROR "Too many tab stops" WARN;
|
|
tabtab[i] = 0;
|
|
}
|
|
|
|
|
|
void casene(void)
|
|
{
|
|
int i, j;
|
|
|
|
skip();
|
|
i = vnumb((int *)0);
|
|
if (nonumb)
|
|
i = lss;
|
|
if (dip == d && numtabp[NL].val == -1) {
|
|
newline(1);
|
|
return;
|
|
}
|
|
if (i > (j = findt1())) {
|
|
i = lss;
|
|
lss = j;
|
|
dip->nls = 0;
|
|
newline(0);
|
|
lss = i;
|
|
}
|
|
}
|
|
|
|
|
|
void casetr(void)
|
|
{
|
|
int i, j;
|
|
Tchar k;
|
|
|
|
lgf++;
|
|
skip();
|
|
while ((i = cbits(k=getch())) != '\n') {
|
|
if (ismot(k))
|
|
return;
|
|
if (ismot(k = getch()))
|
|
return;
|
|
if ((j = cbits(k)) == '\n')
|
|
j = ' ';
|
|
trtab[i] = j;
|
|
}
|
|
}
|
|
|
|
|
|
void casecu(void)
|
|
{
|
|
cu++;
|
|
caseul();
|
|
}
|
|
|
|
|
|
void caseul(void)
|
|
{
|
|
int i;
|
|
|
|
noscale++;
|
|
skip();
|
|
i = max(atoi0(), 0);
|
|
if (nonumb)
|
|
i = 1;
|
|
if (ul && (i == 0)) {
|
|
font = sfont;
|
|
ul = cu = 0;
|
|
}
|
|
if (i) {
|
|
if (!ul) {
|
|
sfont = font;
|
|
font = ulfont;
|
|
}
|
|
ul = i;
|
|
}
|
|
noscale = 0;
|
|
mchbits();
|
|
}
|
|
|
|
|
|
void caseuf(void)
|
|
{
|
|
int i, j;
|
|
|
|
if (skip() || !(i = getrq()) || i == 'S' || (j = findft(i)) == -1)
|
|
ulfont = ULFONT; /*default underline position*/
|
|
else
|
|
ulfont = j;
|
|
if (NROFF && ulfont == FT)
|
|
ulfont = ULFONT;
|
|
}
|
|
|
|
|
|
void caseit(void)
|
|
{
|
|
int i;
|
|
|
|
lgf++;
|
|
it = itmac = 0;
|
|
noscale++;
|
|
skip();
|
|
i = atoi0();
|
|
skip();
|
|
if (!nonumb && (itmac = getrq()))
|
|
it = i;
|
|
noscale = 0;
|
|
}
|
|
|
|
|
|
void casemc(void)
|
|
{
|
|
int i;
|
|
|
|
if (icf > 1)
|
|
ic = 0;
|
|
icf = 0;
|
|
if (skip())
|
|
return;
|
|
ic = getch();
|
|
icf = 1;
|
|
skip();
|
|
i = max(hnumb((int *)0), 0);
|
|
if (!nonumb)
|
|
ics = i;
|
|
}
|
|
|
|
|
|
void casemk(void)
|
|
{
|
|
int i, j;
|
|
|
|
if (dip != d)
|
|
j = dip->dnl;
|
|
else
|
|
j = numtabp[NL].val;
|
|
if (skip()) {
|
|
dip->mkline = j;
|
|
return;
|
|
}
|
|
if ((i = getrq()) == 0)
|
|
return;
|
|
numtabp[findr(i)].val = j;
|
|
}
|
|
|
|
|
|
void casesv(void)
|
|
{
|
|
int i;
|
|
|
|
skip();
|
|
if ((i = vnumb((int *)0)) < 0)
|
|
return;
|
|
if (nonumb)
|
|
i = 1;
|
|
sv += i;
|
|
caseos();
|
|
}
|
|
|
|
|
|
void caseos(void)
|
|
{
|
|
int savlss;
|
|
|
|
if (sv <= findt1()) {
|
|
savlss = lss;
|
|
lss = sv;
|
|
newline(0);
|
|
lss = savlss;
|
|
sv = 0;
|
|
}
|
|
}
|
|
|
|
|
|
void casenm(void)
|
|
{
|
|
int i;
|
|
|
|
lnmod = nn = 0;
|
|
if (skip())
|
|
return;
|
|
lnmod++;
|
|
noscale++;
|
|
i = inumb(&numtabp[LN].val);
|
|
if (!nonumb)
|
|
numtabp[LN].val = max(i, 0);
|
|
getnm(&ndf, 1);
|
|
getnm(&nms, 0);
|
|
getnm(&ni, 0);
|
|
getnm(&nmwid, 3); /* really kludgy! */
|
|
noscale = 0;
|
|
nmbits = chbits;
|
|
}
|
|
|
|
/*
|
|
* .nm relies on the fact that illegal args are skipped; don't warn
|
|
* for illegality of these
|
|
*/
|
|
void getnm(int *p, int min)
|
|
{
|
|
int i;
|
|
int savtr = trace;
|
|
|
|
eat(' ');
|
|
if (skip())
|
|
return;
|
|
trace = 0;
|
|
i = atoi0();
|
|
if (nonumb)
|
|
return;
|
|
*p = max(i, min);
|
|
trace = savtr;
|
|
}
|
|
|
|
|
|
void casenn(void)
|
|
{
|
|
noscale++;
|
|
skip();
|
|
nn = max(atoi0(), 1);
|
|
noscale = 0;
|
|
}
|
|
|
|
|
|
void caseab(void)
|
|
{
|
|
casetm1(1, stderr);
|
|
done3(0);
|
|
}
|
|
|
|
|
|
/* nroff terminal handling has been pretty well excised */
|
|
/* as part of the merge with troff. these are ghostly remnants, */
|
|
/* called, but doing nothing. restore them at your peril. */
|
|
|
|
|
|
void save_tty(void) /*save any tty settings that may be changed*/
|
|
{
|
|
}
|
|
|
|
|
|
void restore_tty(void) /*restore tty settings from beginning*/
|
|
{
|
|
}
|
|
|
|
|
|
void set_tty(void)
|
|
{
|
|
}
|
|
|
|
|
|
void echo_off(void) /*turn off ECHO for .rd in "-q" mode*/
|
|
{
|
|
}
|
|
|
|
|
|
void echo_on(void) /*restore ECHO after .rd in "-q" mode*/
|
|
{
|
|
}
|