/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. *//* * 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*);#endifextern 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++;}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
/*
* 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++;
}