9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

n2.c (5055B)


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