Introduction
Introduction Statistics Contact Development Disclaimer Help
n9.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
n9.c (9091B)
---
1 #include "tdef.h"
2 #include "ext.h"
3 #include "fns.h"
4
5 /*
6 * troff9.c
7 *
8 * misc functions
9 */
10
11 Tchar setz(void)
12 {
13 Tchar i;
14
15 if (!ismot(i = getch()))
16 i |= ZBIT;
17 return(i);
18 }
19
20 void setline(void)
21 {
22 Tchar *i;
23 Tchar c;
24 int length;
25 int j, w, cnt, delim, rem, temp;
26 Tchar linebuf[NC];
27
28 if (ismot(c = getch()))
29 return;
30 delim = cbits(c);
31 vflag = 0;
32 dfact = EM;
33 length = quant(atoi0(), HOR);
34 dfact = 1;
35 if (!length) {
36 eat(delim);
37 return;
38 }
39 s0:
40 if ((j = cbits(c = getch())) == delim || j == '\n') {
41 ch = c;
42 c = RULE | chbits;
43 } else if (cbits(c) == FILLER)
44 goto s0;
45 w = width(c);
46 if (w <= 0) {
47 ERROR "zero-width underline character ignored" WARN;
48 c = RULE | chbits;
49 w = width(c);
50 }
51 i = linebuf;
52 if (length < 0) {
53 *i++ = makem(length);
54 length = -length;
55 }
56 if (!(cnt = length / w)) {
57 *i++ = makem(-(temp = ((w - length) / 2)));
58 *i++ = c;
59 *i++ = makem(-(w - length - temp));
60 goto s1;
61 }
62 if (rem = length % w) {
63 if (cbits(c) == RULE || cbits(c) == UNDERLINE || cbits(c…
64 *i++ = c | ZBIT;
65 *i++ = makem(rem);
66 }
67 if (cnt) {
68 *i++ = RPT;
69 *i++ = cnt;
70 *i++ = c;
71 }
72 s1:
73 *i = 0;
74 eat(delim);
75 pushback(linebuf);
76 }
77
78 int
79 eat(int c)
80 {
81 int i;
82
83 while ((i = cbits(getch())) != c && i != '\n')
84 ;
85 return(i);
86 }
87
88
89 void setov(void)
90 {
91 int j, k;
92 Tchar i, o[NOV+1];
93 int delim, w[NOV+1];
94
95 if (ismot(i = getch()))
96 return;
97 delim = cbits(i);
98 for (k = 0; k < NOV && (j = cbits(i = getch())) != delim && j !=…
99 o[k] = i;
100 w[k] = width(i);
101 }
102 o[k] = w[k] = 0;
103 if (o[0])
104 for (j = 1; j; ) {
105 j = 0;
106 for (k = 1; o[k] ; k++) {
107 if (w[k-1] < w[k]) {
108 j++;
109 i = w[k];
110 w[k] = w[k-1];
111 w[k-1] = i;
112 i = o[k];
113 o[k] = o[k-1];
114 o[k-1] = i;
115 }
116 }
117 }
118 else
119 return;
120 *pbp++ = makem(w[0] / 2);
121 for (k = 0; o[k]; k++)
122 ;
123 while (k>0) {
124 k--;
125 *pbp++ = makem(-((w[k] + w[k+1]) / 2));
126 *pbp++ = o[k];
127 }
128 }
129
130
131 void setbra(void)
132 {
133 int k;
134 Tchar i, *j, dwn;
135 int cnt, delim;
136 Tchar brabuf[NC];
137
138 if (ismot(i = getch()))
139 return;
140 delim = cbits(i);
141 j = brabuf + 1;
142 cnt = 0;
143 if (NROFF)
144 dwn = (2 * t.Halfline) | MOT | VMOT;
145 else
146 dwn = EM | MOT | VMOT;
147 while ((k = cbits(i = getch())) != delim && k != '\n' && j <= br…
148 *j++ = i | ZBIT;
149 *j++ = dwn;
150 cnt++;
151 }
152 if (--cnt < 0)
153 return;
154 else if (!cnt) {
155 ch = *(j - 2);
156 return;
157 }
158 *j = 0;
159 if (NROFF)
160 *--j = *brabuf = (cnt * t.Halfline) | MOT | NMOT | VMOT;
161 else
162 *--j = *brabuf = (cnt * EM) / 2 | MOT | NMOT | VMOT;
163 *--j &= ~ZBIT;
164 pushback(brabuf);
165 }
166
167
168 void setvline(void)
169 {
170 int i;
171 Tchar c, rem, ver, neg;
172 int cnt, delim, v;
173 Tchar vlbuf[NC];
174 Tchar *vlp;
175
176 if (ismot(c = getch()))
177 return;
178 delim = cbits(c);
179 dfact = lss;
180 vflag++;
181 i = quant(atoi0(), VERT);
182 dfact = 1;
183 if (!i) {
184 eat(delim);
185 vflag = 0;
186 return;
187 }
188 if ((cbits(c = getch())) == delim) {
189 c = BOXRULE | chbits; /*default box rule*/
190 } else
191 getch();
192 c |= ZBIT;
193 neg = 0;
194 if (i < 0) {
195 i = -i;
196 neg = NMOT;
197 }
198 if (NROFF)
199 v = 2 * t.Halfline;
200 else {
201 v = EM;
202 if (v < VERT) /* ATT EVK hack: Erik van K…
203 v = VERT; /* hvlpb!evkonij, ATT NSI Hilve…
204 }
205
206 cnt = i / v;
207 rem = makem(i % v) | neg;
208 ver = makem(v) | neg;
209 vlp = vlbuf;
210 if (!neg)
211 *vlp++ = ver;
212 if (absmot(rem) != 0) {
213 *vlp++ = c;
214 *vlp++ = rem;
215 }
216 while (vlp < vlbuf + NC - 3 && cnt--) {
217 *vlp++ = c;
218 *vlp++ = ver;
219 }
220 *(vlp - 2) &= ~ZBIT;
221 if (!neg)
222 vlp--;
223 *vlp = 0;
224 pushback(vlbuf);
225 vflag = 0;
226 }
227
228 #define NPAIR (NC/2-6) /* max pairs in spline, etc.…
229
230 void setdraw(void) /* generate internal cookies for a drawing fun…
231 {
232 int i, j, k, dx[NPAIR], dy[NPAIR], delim, type;
233 Tchar c, drawbuf[NC];
234 int drawch = '.'; /* character to draw with */
235
236 /* input is \D'f dx dy dx dy ... c' (or at least it had better b…
237 /* this does drawing function f with character c and the */
238 /* specified dx,dy pairs interpreted as appropriate */
239 /* pairs are deltas from last point, except for radii */
240
241 /* l dx dy: line from here by dx,dy */
242 /* c x: circle of diameter x, left side here */
243 /* e x y: ellipse of diameters x,y, left side here */
244 /* a dx1 dy1 dx2 dy2:
245 ccw arc: ctr at dx1,dy1, then end at dx2,dy2 fro…
246 /* ~ dx1 dy1 dx2 dy2...:
247 spline to dx1,dy1 to dx2,dy2 ... */
248 /* b x c:
249 built-up character of type c, ht x */
250 /* f dx dy ...: f is any other char: like spline */
251
252 if (ismot(c = getch()))
253 return;
254 delim = cbits(c);
255 numerr.escarg = type = cbits(getch());
256 if (type == '~') /* head off the .tr ~ problem */
257 type = 's';
258 for (i = 0; i < NPAIR ; i++) {
259 skip();
260 vflag = 0;
261 dfact = EM;
262 dx[i] = quant(atoi0(), HOR);
263 if (dx[i] > MAXMOT)
264 dx[i] = MAXMOT;
265 else if (dx[i] < -MAXMOT)
266 dx[i] = -MAXMOT;
267 skip();
268 if (type == 'c') {
269 dy[i] = 0;
270 goto eat;
271 }
272 vflag = 1;
273 dfact = lss;
274 dy[i] = quant(atoi0(), VERT);
275 if (dy[i] > MAXMOT)
276 dy[i] = MAXMOT;
277 else if (dy[i] < -MAXMOT)
278 dy[i] = -MAXMOT;
279 eat:
280 if (cbits(c = getch()) != ' ') { /* must be the e…
281 if (cbits(c) != delim) {
282 drawch = cbits(c);
283 getch();
284 }
285 i++;
286 break;
287 }
288 }
289 dfact = 1;
290 vflag = 0;
291 if (TROFF) {
292 drawbuf[0] = DRAWFCN | chbits | ZBIT;
293 drawbuf[1] = type | chbits | ZBIT;
294 drawbuf[2] = drawch | chbits | ZBIT;
295 for (k = 0, j = 3; k < i; k++) {
296 drawbuf[j++] = MOT | ((dx[k] >= 0) ? dx[k] : (NM…
297 drawbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ? dy[k…
298 }
299 if (type == DRAWELLIPSE) {
300 drawbuf[5] = drawbuf[4] | NMOT; /* so the…
301 j = 6;
302 } else if (type == DRAWBUILD) {
303 drawbuf[4] = drawbuf[3] | NMOT; /* net ho…
304 drawbuf[2] &= ~ZBIT; /* width tak…
305 j = 5;
306 }
307 drawbuf[j++] = DRAWFCN | chbits | ZBIT; /* marks …
308 drawbuf[j] = 0;
309 pushback(drawbuf);
310 }
311 }
312
313
314 void casefc(void)
315 {
316 int i;
317 Tchar j;
318
319 gchtab[fc] &= ~FCBIT;
320 fc = IMP;
321 padc = ' ';
322 if (skip() || ismot(j = getch()) || (i = cbits(j)) == '\n')
323 return;
324 fc = i;
325 gchtab[fc] |= FCBIT;
326 if (skip() || ismot(ch) || (ch = cbits(ch)) == fc)
327 return;
328 padc = ch;
329 }
330
331
332 Tchar setfield(int x)
333 {
334 Tchar ii, jj, *fp;
335 int i, j;
336 int length, ws, npad, temp, type;
337 Tchar **pp, *padptr[NPP];
338 Tchar fbuf[FBUFSZ];
339 int savfc, savtc, savlc;
340 Tchar rchar;
341 int savepos;
342 static Tchar wbuf[] = { WORDSP, 0};
343
344 rchar = 0;
345 if (x == tabch)
346 rchar = tabc | chbits;
347 else if (x == ldrch)
348 rchar = dotc | chbits;
349 temp = npad = ws = 0;
350 savfc = fc;
351 savtc = tabch;
352 savlc = ldrch;
353 tabch = ldrch = fc = IMP;
354 savepos = numtabp[HP].val;
355 gchtab[tabch] &= ~TABBIT;
356 gchtab[ldrch] &= ~LDRBIT;
357 gchtab[fc] &= ~FCBIT;
358 gchtab[IMP] |= TABBIT|LDRBIT|FCBIT;
359 for (j = 0; ; j++) {
360 if ((tabtab[j] & TABMASK) == 0) {
361 if (x == savfc)
362 ERROR "zero field width." WARN;
363 jj = 0;
364 goto rtn;
365 }
366 if ((length = ((tabtab[j] & TABMASK) - numtabp[HP].val))…
367 break;
368 }
369 type = tabtab[j] & ~TABMASK;
370 fp = fbuf;
371 pp = padptr;
372 if (x == savfc) {
373 while (1) {
374 j = cbits(ii = getch());
375 jj = width(ii);
376 widthp = jj;
377 numtabp[HP].val += jj;
378 if (j == padc) {
379 npad++;
380 *pp++ = fp;
381 if (pp > padptr + NPP - 1)
382 break;
383 goto s1;
384 } else if (j == savfc)
385 break;
386 else if (j == '\n') {
387 temp = j;
388 if (nlflg && ip == 0) {
389 numtabp[CD].val--;
390 nlflg = 0;
391 }
392 break;
393 }
394 ws += jj;
395 s1:
396 *fp++ = ii;
397 if (fp > fbuf + FBUFSZ - 3)
398 break;
399 }
400 if (ws)
401 *fp++ = WORDSP;
402 if (!npad) {
403 npad++;
404 *pp++ = fp;
405 *fp++ = 0;
406 }
407 *fp++ = temp;
408 *fp = 0;
409 temp = i = (j = length - ws) / npad;
410 i = (i / HOR) * HOR;
411 if ((j -= i * npad) < 0)
412 j = -j;
413 ii = makem(i);
414 if (temp < 0)
415 ii |= NMOT;
416 for (; npad > 0; npad--) {
417 *(*--pp) = ii;
418 if (j) {
419 j -= HOR;
420 (*(*pp)) += HOR;
421 }
422 }
423 pushback(fbuf);
424 jj = 0;
425 } else if (type == 0) {
426 /*plain tab or leader*/
427 if ((j = width(rchar)) > 0) {
428 int nchar = length / j;
429 while (nchar-->0 && pbp < &pbbuf[NC-3]) {
430 numtabp[HP].val += j;
431 widthp = j;
432 *pbp++ = rchar;
433 }
434 length %= j;
435 }
436 if (length)
437 jj = length | MOT;
438 else
439 jj = getch0();
440 if (savepos > 0)
441 pushback(wbuf);
442 } else {
443 /*center tab*/
444 /*right tab*/
445 while ((j = cbits(ii = getch())) != savtc && j != '\n' &…
446 jj = width(ii);
447 ws += jj;
448 numtabp[HP].val += jj;
449 widthp = jj;
450 *fp++ = ii;
451 if (fp > fbuf + FBUFSZ - 3)
452 break;
453 }
454 *fp++ = ii;
455 *fp = 0;
456 if (type == RTAB)
457 length -= ws;
458 else
459 length -= ws / 2; /*CTAB*/
460 pushback(fbuf);
461 if ((j = width(rchar)) != 0 && length > 0) {
462 int nchar = length / j;
463 while (nchar-- > 0 && pbp < &pbbuf[NC-3])
464 *pbp++ = rchar;
465 length %= j;
466 }
467 if (savepos > 0)
468 pushback(wbuf);
469 length = (length / HOR) * HOR;
470 jj = makem(length);
471 if (nlflg) {
472 if (ip == 0)
473 numtabp[CD].val--;
474 nlflg = 0;
475 }
476 }
477 rtn:
478 gchtab[fc] &= ~FCBIT;
479 gchtab[tabch] &= ~TABBIT;
480 gchtab[ldrch] &= ~LDRBIT;
481 fc = savfc;
482 tabch = savtc;
483 ldrch = savlc;
484 gchtab[fc] |= FCBIT;
485 gchtab[tabch] = TABBIT;
486 gchtab[ldrch] |= LDRBIT;
487 numtabp[HP].val = savepos;
488 return(jj);
489 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.