plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

n2.c (5075B)


      1 /*
      2  * n2.c
      3  *
      4  * output, cleanup
      5  */
      6 
      7 #define _BSD_SOURCE 1	/* popen */
      8 #define _DEFAULT_SOURCE 1
      9 #include "tdef.h"
     10 #include "fns.h"
     11 #include "ext.h"
     12 #include <setjmp.h>
     13 
     14 #ifdef STRICT
     15 	/* not in ANSI or POSIX */
     16 FILE*	popen(char*, char*);
     17 #endif
     18 
     19 
     20 extern	jmp_buf	sjbuf;
     21 int	toolate;
     22 int	error;
     23 
     24 char	obuf[2*BUFSIZ];
     25 char	*obufp = obuf;
     26 
     27 	/* pipe command structure; allows redicously long commends for .pi */
     28 struct Pipe {
     29 	char	*buf;
     30 	int	tick;
     31 	int	cnt;
     32 } Pipe;
     33 
     34 
     35 int	xon	= 0;	/* records if in middle of \X */
     36 
     37 int pchar(Tchar i)
     38 {
     39 	int j;
     40 	static int hx = 0;	/* records if have seen HX */
     41 
     42 	if (hx) {
     43 		hx = 0;
     44 		j = absmot(i);
     45 		if (isnmot(i)) {
     46 			if (j > dip->blss)
     47 				dip->blss = j;
     48 		} else {
     49 			if (j > dip->alss)
     50 				dip->alss = j;
     51 			ralss = dip->alss;
     52 		}
     53 		return 0;
     54 	}
     55 	if (ismot(i)) {
     56 		pchar1(i);
     57 		return 0;
     58 	}
     59 	switch (j = cbits(i)) {
     60 	case 0:
     61 	case IMP:
     62 	case RIGHT:
     63 	case LEFT:
     64 		return 0;
     65 	case HX:
     66 		hx = 1;
     67 		return 0;
     68 	case XON:
     69 		xon++;
     70 		break;
     71 	case XOFF:
     72 		xon--;
     73 		break;
     74 	case PRESC:
     75 		if (!xon && !tflg && dip == &d[0])
     76 			j = eschar;	/* fall through */
     77 	default:
     78 		setcbits(i, trtab[j]);
     79 	}
     80 	if (NROFF & xon)	/* rob fix for man2html */
     81 		return 0;
     82 	pchar1(i);
     83 	return 0;
     84 }
     85 
     86 
     87 void pchar1(Tchar i)
     88 {
     89 	int j;
     90 
     91 	j = cbits(i);
     92 	if (dip != &d[0]) {
     93 		wbf(i);
     94 		dip->op = offset;
     95 		return;
     96 	}
     97 	if (!tflg && !print) {
     98 		if (j == '\n')
     99 			dip->alss = dip->blss = 0;
    100 		return;
    101 	}
    102 	if (j == FILLER && !xon)
    103 		return;
    104 	if (tflg) {	/* transparent mode, undiverted */
    105 		if (print)			/* assumes that it's ok to print */
    106 			/* OUT "%c", j PUT;	/* i.e., is ascii */
    107 			outascii(i);
    108 		return;
    109 	}
    110 	if (TROFF && ascii)
    111 		outascii(i);
    112 	else
    113 		ptout(i);
    114 }
    115 
    116 
    117 void outweird(int k)	/* like ptchname() but ascii */
    118 {
    119 	char *chn = chname(k);
    120 
    121 	switch (chn[0]) {
    122 	case MBchar:
    123 		OUT "%s", chn+1 PUT;	/* \n not needed? */
    124 		break;
    125 	case Number:
    126 		OUT "\\N'%s'", chn+1 PUT;
    127 		break;
    128 	case Troffchar:
    129 		if (strlen(chn+1) == 2)
    130 			OUT "\\(%s", chn+1 PUT;
    131 		else
    132 			OUT "\\C'%s'", chn+1 PUT;
    133 		break;
    134 	default:
    135 		OUT " %s? ", chn PUT;
    136 		break;
    137 	}
    138 }
    139 
    140 void outascii(Tchar i)	/* print i in best-guess ascii */
    141 {
    142 	int j = cbits(i);
    143 
    144 /* is this ever called with NROFF set? probably doesn't work at all. */
    145 
    146 	if (ismot(i))
    147 		oput(' ');
    148 	else if (j < ALPHABET && j >= ' ' || j == '\n' || j == '\t')
    149 		oput(j);
    150 	else if (j == DRAWFCN)
    151 		oputs("\\D");
    152 	else if (j == HYPHEN)
    153 		oput('-');
    154 	else if (j == MINUS)	/* special pleading for strange encodings */
    155 		oputs("\\-");
    156 	else if (j == PRESC)
    157 		oputs("\\e");
    158 	else if (j == FILLER)
    159 		oputs("\\&");
    160 	else if (j == UNPAD)
    161 		oputs("\\ ");
    162 	else if (j == OHC)	/* this will never occur;  stripped out earlier */
    163 		oputs("\\%");
    164 	else if (j == XON)
    165 		oputs("\\X");
    166 	else if (j == XOFF)
    167 		oputs(" ");
    168 	else if (j == LIG_FI)
    169 		oputs("fi");
    170 	else if (j == LIG_FL)
    171 		oputs("fl");
    172 	else if (j == LIG_FF)
    173 		oputs("ff");
    174 	else if (j == LIG_FFI)
    175 		oputs("ffi");
    176 	else if (j == LIG_FFL)
    177 		oputs("ffl");
    178 	else if (j == WORDSP) {		/* nothing at all */
    179 		if (xon)		/* except in \X */
    180 			oput(' ');
    181 
    182 	} else
    183 		outweird(j);
    184 }
    185 
    186 int flusho(void)
    187 {
    188 	if (NROFF && !toolate && t.twinit)
    189 			fwrite(t.twinit, strlen(t.twinit), 1, ptid);
    190 
    191 	if (obufp > obuf) {
    192 		if (pipeflg && !toolate) {
    193 			/* fprintf(stderr, "Pipe to <%s>\n", Pipe.buf); */
    194 			if (!Pipe.buf[0] || (ptid = popen(Pipe.buf, "w")) == NULL)
    195 				ERROR "pipe %s not created.", Pipe.buf WARN;
    196 			if (Pipe.buf)
    197 				free(Pipe.buf);
    198 		}
    199 		if (!toolate)
    200 			toolate++;
    201 		*obufp = 0;
    202 		fputs(obuf, ptid);
    203 		fflush(ptid);
    204 		obufp = obuf;
    205 	}
    206 	return 1;
    207 }
    208 
    209 
    210 void caseex(void)
    211 {
    212 	done(0);
    213 }
    214 
    215 
    216 void done(int x)
    217 {
    218 	int i;
    219 
    220 	error |= x;
    221 	app = ds = lgf = 0;
    222 	if (i = em) {
    223 		donef = -1;
    224 		eschar = '\\';
    225 		em = 0;
    226 		if (control(i, 0))
    227 			longjmp(sjbuf, 1);
    228 	}
    229 	if (!nfo)
    230 		done3(0);
    231 	mflg = 0;
    232 	dip = &d[0];
    233 	if (woff)	/* BUG!!! This isn't set anywhere */
    234 		wbf((Tchar)0);
    235 	if (pendw)
    236 		getword(1);
    237 	pendnf = 0;
    238 	if (donef == 1)
    239 		done1(0);
    240 	donef = 1;
    241 	ip = 0;
    242 	frame = stk;
    243 	nxf = frame + 1;
    244 	if (!ejf)
    245 		tbreak();
    246 	nflush++;
    247 	eject((Stack *)0);
    248 	longjmp(sjbuf, 1);
    249 }
    250 
    251 
    252 void done1(int x)
    253 {
    254 	error |= x;
    255 	if (numtabp[NL].val) {
    256 		trap = 0;
    257 		eject((Stack *)0);
    258 		longjmp(sjbuf, 1);
    259 	}
    260 	if (!ascii)
    261 		pttrailer();
    262 	done2(0);
    263 }
    264 
    265 
    266 void done2(int x)
    267 {
    268 	ptlead();
    269 	if (TROFF && !ascii)
    270 		ptstop();
    271 	flusho();
    272 	done3(x);
    273 }
    274 
    275 void done3(int x)
    276 {
    277 	error |= x;
    278 	flusho();
    279 	if (NROFF)
    280 		twdone();
    281 	if (pipeflg)
    282 		pclose(ptid);
    283 	exit(error);
    284 }
    285 
    286 
    287 void edone(int x)
    288 {
    289 	frame = stk;
    290 	nxf = frame + 1;
    291 	ip = 0;
    292 	done(x);
    293 }
    294 
    295 
    296 void casepi(void)
    297 {
    298 	int j;
    299 	char buf[NTM];
    300 
    301 	if (Pipe.buf == NULL) {
    302 		if ((Pipe.buf = (char *)calloc(NTM, sizeof(char))) == NULL) {
    303 			ERROR "No buf space for pipe cmd" WARN;
    304 			return;
    305 		}
    306 		Pipe.tick = 1;
    307 	} else
    308 		Pipe.buf[Pipe.cnt++] = '|';
    309 
    310 	getline(buf, NTM);
    311 	j = strlen(buf);
    312 	if (toolate) {
    313 		ERROR "Cannot create pipe to %s", buf WARN;
    314 		return;
    315 	}
    316 	Pipe.cnt += j;
    317 	if (j >= NTM +1) {
    318 		Pipe.tick++;
    319 		if ((Pipe.buf = (char *)realloc(Pipe.buf, Pipe.tick * NTM * sizeof(char))) == NULL) {
    320 			ERROR "No more buf space for pipe cmd" WARN;
    321 			return;
    322 		}
    323 	}
    324 	strcat(Pipe.buf, buf);
    325 	pipeflg++;
    326 }