mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
325 lines
4.9 KiB
C
325 lines
4.9 KiB
C
|
/*
|
||
|
* n2.c
|
||
|
*
|
||
|
* output, cleanup
|
||
|
*/
|
||
|
|
||
|
#include "tdef.h"
|
||
|
#include "fns.h"
|
||
|
#include "ext.h"
|
||
|
#include <setjmp.h>
|
||
|
|
||
|
#ifdef STRICT
|
||
|
/* not in ANSI or POSIX */
|
||
|
FILE* popen(char*, char*);
|
||
|
#endif
|
||
|
|
||
|
|
||
|
extern jmp_buf sjbuf;
|
||
|
int toolate;
|
||
|
int error;
|
||
|
|
||
|
char obuf[2*BUFSIZ];
|
||
|
char *obufp = obuf;
|
||
|
|
||
|
/* pipe command structure; allows redicously long commends for .pi */
|
||
|
struct Pipe {
|
||
|
char *buf;
|
||
|
int tick;
|
||
|
int cnt;
|
||
|
} Pipe;
|
||
|
|
||
|
|
||
|
int xon = 0; /* records if in middle of \X */
|
||
|
|
||
|
int pchar(Tchar i)
|
||
|
{
|
||
|
int j;
|
||
|
static int hx = 0; /* records if have seen HX */
|
||
|
|
||
|
if (hx) {
|
||
|
hx = 0;
|
||
|
j = absmot(i);
|
||
|
if (isnmot(i)) {
|
||
|
if (j > dip->blss)
|
||
|
dip->blss = j;
|
||
|
} else {
|
||
|
if (j > dip->alss)
|
||
|
dip->alss = j;
|
||
|
ralss = dip->alss;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
if (ismot(i)) {
|
||
|
pchar1(i);
|
||
|
return 0;
|
||
|
}
|
||
|
switch (j = cbits(i)) {
|
||
|
case 0:
|
||
|
case IMP:
|
||
|
case RIGHT:
|
||
|
case LEFT:
|
||
|
return 0;
|
||
|
case HX:
|
||
|
hx = 1;
|
||
|
return 0;
|
||
|
case XON:
|
||
|
xon++;
|
||
|
break;
|
||
|
case XOFF:
|
||
|
xon--;
|
||
|
break;
|
||
|
case PRESC:
|
||
|
if (!xon && !tflg && dip == &d[0])
|
||
|
j = eschar; /* fall through */
|
||
|
default:
|
||
|
setcbits(i, trtab[j]);
|
||
|
}
|
||
|
if (NROFF & xon) /* rob fix for man2html */
|
||
|
return 0;
|
||
|
pchar1(i);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void pchar1(Tchar i)
|
||
|
{
|
||
|
int j;
|
||
|
|
||
|
j = cbits(i);
|
||
|
if (dip != &d[0]) {
|
||
|
wbf(i);
|
||
|
dip->op = offset;
|
||
|
return;
|
||
|
}
|
||
|
if (!tflg && !print) {
|
||
|
if (j == '\n')
|
||
|
dip->alss = dip->blss = 0;
|
||
|
return;
|
||
|
}
|
||
|
if (j == FILLER && !xon)
|
||
|
return;
|
||
|
if (tflg) { /* transparent mode, undiverted */
|
||
|
if (print) /* assumes that it's ok to print */
|
||
|
/* OUT "%c", j PUT; /* i.e., is ascii */
|
||
|
outascii(i);
|
||
|
return;
|
||
|
}
|
||
|
if (TROFF && ascii)
|
||
|
outascii(i);
|
||
|
else
|
||
|
ptout(i);
|
||
|
}
|
||
|
|
||
|
|
||
|
void outweird(int k) /* like ptchname() but ascii */
|
||
|
{
|
||
|
char *chn = chname(k);
|
||
|
|
||
|
switch (chn[0]) {
|
||
|
case MBchar:
|
||
|
OUT "%s", chn+1 PUT; /* \n not needed? */
|
||
|
break;
|
||
|
case Number:
|
||
|
OUT "\\N'%s'", chn+1 PUT;
|
||
|
break;
|
||
|
case Troffchar:
|
||
|
if (strlen(chn+1) == 2)
|
||
|
OUT "\\(%s", chn+1 PUT;
|
||
|
else
|
||
|
OUT "\\C'%s'", chn+1 PUT;
|
||
|
break;
|
||
|
default:
|
||
|
OUT " %s? ", chn PUT;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void outascii(Tchar i) /* print i in best-guess ascii */
|
||
|
{
|
||
|
int j = cbits(i);
|
||
|
|
||
|
/* is this ever called with NROFF set? probably doesn't work at all. */
|
||
|
|
||
|
if (ismot(i))
|
||
|
oput(' ');
|
||
|
else if (j < ALPHABET && j >= ' ' || j == '\n' || j == '\t')
|
||
|
oput(j);
|
||
|
else if (j == DRAWFCN)
|
||
|
oputs("\\D");
|
||
|
else if (j == HYPHEN)
|
||
|
oput('-');
|
||
|
else if (j == MINUS) /* special pleading for strange encodings */
|
||
|
oputs("\\-");
|
||
|
else if (j == PRESC)
|
||
|
oputs("\\e");
|
||
|
else if (j == FILLER)
|
||
|
oputs("\\&");
|
||
|
else if (j == UNPAD)
|
||
|
oputs("\\ ");
|
||
|
else if (j == OHC) /* this will never occur; stripped out earlier */
|
||
|
oputs("\\%");
|
||
|
else if (j == XON)
|
||
|
oputs("\\X");
|
||
|
else if (j == XOFF)
|
||
|
oputs(" ");
|
||
|
else if (j == LIG_FI)
|
||
|
oputs("fi");
|
||
|
else if (j == LIG_FL)
|
||
|
oputs("fl");
|
||
|
else if (j == LIG_FF)
|
||
|
oputs("ff");
|
||
|
else if (j == LIG_FFI)
|
||
|
oputs("ffi");
|
||
|
else if (j == LIG_FFL)
|
||
|
oputs("ffl");
|
||
|
else if (j == WORDSP) { /* nothing at all */
|
||
|
if (xon) /* except in \X */
|
||
|
oput(' ');
|
||
|
|
||
|
} else
|
||
|
outweird(j);
|
||
|
}
|
||
|
|
||
|
int flusho(void)
|
||
|
{
|
||
|
if (NROFF && !toolate && t.twinit)
|
||
|
fwrite(t.twinit, strlen(t.twinit), 1, ptid);
|
||
|
|
||
|
if (obufp > obuf) {
|
||
|
if (pipeflg && !toolate) {
|
||
|
/* fprintf(stderr, "Pipe to <%s>\n", Pipe.buf); */
|
||
|
if (!Pipe.buf[0] || (ptid = popen(Pipe.buf, "w")) == NULL)
|
||
|
ERROR "pipe %s not created.", Pipe.buf WARN;
|
||
|
if (Pipe.buf)
|
||
|
free(Pipe.buf);
|
||
|
}
|
||
|
if (!toolate)
|
||
|
toolate++;
|
||
|
*obufp = 0;
|
||
|
fputs(obuf, ptid);
|
||
|
fflush(ptid);
|
||
|
obufp = obuf;
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
void caseex(void)
|
||
|
{
|
||
|
done(0);
|
||
|
}
|
||
|
|
||
|
|
||
|
void done(int x)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
error |= x;
|
||
|
app = ds = lgf = 0;
|
||
|
if (i = em) {
|
||
|
donef = -1;
|
||
|
eschar = '\\';
|
||
|
em = 0;
|
||
|
if (control(i, 0))
|
||
|
longjmp(sjbuf, 1);
|
||
|
}
|
||
|
if (!nfo)
|
||
|
done3(0);
|
||
|
mflg = 0;
|
||
|
dip = &d[0];
|
||
|
if (woff) /* BUG!!! This isn't set anywhere */
|
||
|
wbf((Tchar)0);
|
||
|
if (pendw)
|
||
|
getword(1);
|
||
|
pendnf = 0;
|
||
|
if (donef == 1)
|
||
|
done1(0);
|
||
|
donef = 1;
|
||
|
ip = 0;
|
||
|
frame = stk;
|
||
|
nxf = frame + 1;
|
||
|
if (!ejf)
|
||
|
tbreak();
|
||
|
nflush++;
|
||
|
eject((Stack *)0);
|
||
|
longjmp(sjbuf, 1);
|
||
|
}
|
||
|
|
||
|
|
||
|
void done1(int x)
|
||
|
{
|
||
|
error |= x;
|
||
|
if (numtabp[NL].val) {
|
||
|
trap = 0;
|
||
|
eject((Stack *)0);
|
||
|
longjmp(sjbuf, 1);
|
||
|
}
|
||
|
if (!ascii)
|
||
|
pttrailer();
|
||
|
done2(0);
|
||
|
}
|
||
|
|
||
|
|
||
|
void done2(int x)
|
||
|
{
|
||
|
ptlead();
|
||
|
if (TROFF && !ascii)
|
||
|
ptstop();
|
||
|
flusho();
|
||
|
done3(x);
|
||
|
}
|
||
|
|
||
|
void done3(int x)
|
||
|
{
|
||
|
error |= x;
|
||
|
flusho();
|
||
|
if (NROFF)
|
||
|
twdone();
|
||
|
if (pipeflg)
|
||
|
pclose(ptid);
|
||
|
exit(error);
|
||
|
}
|
||
|
|
||
|
|
||
|
void edone(int x)
|
||
|
{
|
||
|
frame = stk;
|
||
|
nxf = frame + 1;
|
||
|
ip = 0;
|
||
|
done(x);
|
||
|
}
|
||
|
|
||
|
|
||
|
void casepi(void)
|
||
|
{
|
||
|
int j;
|
||
|
char buf[NTM];
|
||
|
|
||
|
if (Pipe.buf == NULL) {
|
||
|
if ((Pipe.buf = (char *)calloc(NTM, sizeof(char))) == NULL) {
|
||
|
ERROR "No buf space for pipe cmd" WARN;
|
||
|
return;
|
||
|
}
|
||
|
Pipe.tick = 1;
|
||
|
} else
|
||
|
Pipe.buf[Pipe.cnt++] = '|';
|
||
|
|
||
|
getline(buf, NTM);
|
||
|
j = strlen(buf);
|
||
|
if (toolate) {
|
||
|
ERROR "Cannot create pipe to %s", buf WARN;
|
||
|
return;
|
||
|
}
|
||
|
Pipe.cnt += j;
|
||
|
if (j >= NTM +1) {
|
||
|
Pipe.tick++;
|
||
|
if ((Pipe.buf = (char *)realloc(Pipe.buf, Pipe.tick * NTM * sizeof(char))) == NULL) {
|
||
|
ERROR "No more buf space for pipe cmd" WARN;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
strcat(Pipe.buf, buf);
|
||
|
pipeflg++;
|
||
|
}
|