Introduction
Introduction Statistics Contact Development Disclaimer Help
n7.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
n7.c (12546B)
---
1 #define _BSD_SOURCE 1 /* isascii */
2 #include "tdef.h"
3 #include "fns.h"
4 #include "ext.h"
5
6 #ifdef STRICT
7 /* not in ANSI or POSIX */
8 #define isascii(a) ((a) >= 0 && (a) <= 127)
9 #endif
10
11 #define GETCH gettch
12 Tchar gettch(void);
13
14
15 /*
16 * troff7.c
17 *
18 * text
19 */
20
21 int brflg;
22
23 void tbreak(void)
24 {
25 int pad, k;
26 Tchar *i, j;
27 int resol;
28 int un0 = un;
29
30 trap = 0;
31 if (nb)
32 return;
33 if (dip == d && numtabp[NL].val == -1) {
34 newline(1);
35 return;
36 }
37 if (!nc) {
38 setnel();
39 if (!wch)
40 return;
41 if (pendw)
42 getword(1);
43 movword();
44 } else if (pendw && !brflg) {
45 getword(1);
46 movword();
47 }
48 *linep = dip->nls = 0;
49 if (NROFF && dip == d)
50 horiz(po);
51 if (lnmod)
52 donum();
53 lastl = ne;
54 if (brflg != 1) {
55 totout = 0;
56 } else if (ad) {
57 if ((lastl = ll - un) < ne)
58 lastl = ne;
59 }
60 if (admod && ad && (brflg != 2)) {
61 lastl = ne;
62 adsp = adrem = 0;
63 if (admod == 1)
64 un += quant(nel / 2, HOR);
65 else if (admod == 2)
66 un += nel;
67 }
68 totout++;
69 brflg = 0;
70 if (lastl + un > dip->maxl)
71 dip->maxl = lastl + un;
72 horiz(un);
73 if (NROFF) {
74 if (adrem % t.Adj)
75 resol = t.Hor;
76 else
77 resol = t.Adj;
78 } else
79 resol = HOR;
80
81 lastl = ne + (nwd-1) * adsp + adrem;
82 for (i = line; nc > 0; ) {
83 if ((cbits(j = *i++)) == ' ') {
84 pad = 0;
85 do {
86 pad += width(j);
87 nc--;
88 } while ((cbits(j = *i++)) == ' ');
89 i--;
90 pad += adsp;
91 --nwd;
92 if (adrem) {
93 if (adrem < 0) {
94 pad -= resol;
95 adrem += resol;
96 } else if ((totout & 01) || adrem / reso…
97 pad += resol;
98 adrem -= resol;
99 }
100 }
101 pchar((Tchar) WORDSP);
102 horiz(pad);
103 } else {
104 pchar(j);
105 nc--;
106 }
107 }
108 if (ic) {
109 if ((k = ll - un0 - lastl + ics) > 0)
110 horiz(k);
111 pchar(ic);
112 }
113 if (icf)
114 icf++;
115 else
116 ic = 0;
117 ne = nwd = 0;
118 un = in;
119 setnel();
120 newline(0);
121 if (dip != d) {
122 if (dip->dnl > dip->hnl)
123 dip->hnl = dip->dnl;
124 } else {
125 if (numtabp[NL].val > dip->hnl)
126 dip->hnl = numtabp[NL].val;
127 }
128 for (k = ls - 1; k > 0 && !trap; k--)
129 newline(0);
130 spread = 0;
131 }
132
133 void donum(void)
134 {
135 int i, nw;
136 int lnv = numtabp[LN].val;
137
138 nrbits = nmbits;
139 nw = width('1' | nrbits);
140 if (nn) {
141 nn--;
142 goto d1;
143 }
144 if (lnv % ndf) {
145 numtabp[LN].val++;
146 d1:
147 un += nw * (nmwid + nms + ni);
148 return;
149 }
150 i = 0;
151 do { /* count digits in numtabp[LN].val */
152 i++;
153 } while ((lnv /= 10) > 0);
154 horiz(nw * (ni + max(nmwid-i, 0)));
155 nform = 0;
156 fnumb(numtabp[LN].val, pchar);
157 un += nw * nms;
158 numtabp[LN].val++;
159 }
160
161
162 void text(void)
163 {
164 Tchar i;
165 static int spcnt;
166
167 nflush++;
168 numtabp[HP].val = 0;
169 if ((dip == d) && (numtabp[NL].val == -1)) {
170 newline(1);
171 return;
172 }
173 setnel();
174 if (ce || !fi) {
175 nofill();
176 return;
177 }
178 if (pendw)
179 goto t4;
180 if (pendt)
181 if (spcnt)
182 goto t2;
183 else
184 goto t3;
185 pendt++;
186 if (spcnt)
187 goto t2;
188 while ((cbits(i = GETCH())) == ' ') {
189 spcnt++;
190 numtabp[HP].val += sps;
191 widthp = sps;
192 }
193 if (nlflg) {
194 t1:
195 nflush = pendt = ch = spcnt = 0;
196 callsp();
197 return;
198 }
199 ch = i;
200 if (spcnt) {
201 t2:
202 tbreak();
203 if (nc || wch)
204 goto rtn;
205 un += spcnt * sps;
206 spcnt = 0;
207 setnel();
208 if (trap)
209 goto rtn;
210 if (nlflg)
211 goto t1;
212 }
213 t3:
214 if (spread)
215 goto t5;
216 if (pendw || !wch)
217 t4:
218 if (getword(0))
219 goto t6;
220 if (!movword())
221 goto t3;
222 t5:
223 if (nlflg)
224 pendt = 0;
225 adsp = adrem = 0;
226 if (ad) {
227 if (nwd == 1)
228 adsp = nel;
229 else
230 adsp = nel / (nwd - 1);
231 adsp = (adsp / HOR) * HOR;
232 adrem = nel - adsp*(nwd-1);
233 }
234 brflg = 1;
235 tbreak();
236 spread = 0;
237 if (!trap)
238 goto t3;
239 if (!nlflg)
240 goto rtn;
241 t6:
242 pendt = 0;
243 ckul();
244 rtn:
245 nflush = 0;
246 }
247
248
249 void nofill(void)
250 {
251 int j;
252 Tchar i;
253
254 if (!pendnf) {
255 over = 0;
256 tbreak();
257 if (trap)
258 goto rtn;
259 if (nlflg) {
260 ch = nflush = 0;
261 callsp();
262 return;
263 }
264 adsp = adrem = 0;
265 nwd = 10000;
266 }
267 while ((j = (cbits(i = GETCH()))) != '\n') {
268 if (j == ohc)
269 continue;
270 if (j == CONT) {
271 pendnf++;
272 nflush = 0;
273 flushi();
274 ckul();
275 return;
276 }
277 j = width(i);
278 widthp = j;
279 numtabp[HP].val += j;
280 storeline(i, j);
281 }
282 if (ce) {
283 ce--;
284 if ((i = quant(nel / 2, HOR)) > 0)
285 un += i;
286 }
287 if (!nc)
288 storeline((Tchar)FILLER, 0);
289 brflg = 2;
290 tbreak();
291 ckul();
292 rtn:
293 pendnf = nflush = 0;
294 }
295
296
297 void callsp(void)
298 {
299 int i;
300
301 if (flss)
302 i = flss;
303 else
304 i = lss;
305 flss = 0;
306 casesp1(i);
307 }
308
309
310 void ckul(void)
311 {
312 if (ul && (--ul == 0)) {
313 cu = 0;
314 font = sfont;
315 mchbits();
316 }
317 if (it && --it == 0 && itmac)
318 control(itmac, 0);
319 }
320
321
322 void storeline(Tchar c, int w)
323 {
324 int diff;
325
326 if (linep >= line + lnsize - 2) {
327 lnsize += LNSIZE;
328 diff = linep - line;
329 if (( line = (Tchar *)realloc((char *)line, lnsize * siz…
330 if (linep && diff)
331 linep = line + diff;
332 } else {
333 if (over) {
334 return;
335 } else {
336 flusho();
337 ERROR "Line overflow." WARN;
338 over++;
339 *linep++ = LEFTHAND;
340 w = width(LEFTHAND);
341 nc++;
342 c = '\n';
343 }
344 }
345 }
346 *linep++ = c;
347 ne += w;
348 nel -= w;
349 nc++;
350 }
351
352
353 void newline(int a)
354 {
355 int i, j, nlss;
356 int opn;
357
358 nlss = 0;
359 if (a)
360 goto nl1;
361 if (dip != d) {
362 j = lss;
363 pchar1((Tchar)FLSS);
364 if (flss)
365 lss = flss;
366 i = lss + dip->blss;
367 dip->dnl += i;
368 pchar1((Tchar)i);
369 pchar1((Tchar)'\n');
370 lss = j;
371 dip->blss = flss = 0;
372 if (dip->alss) {
373 pchar1((Tchar)FLSS);
374 pchar1((Tchar)dip->alss);
375 pchar1((Tchar)'\n');
376 dip->dnl += dip->alss;
377 dip->alss = 0;
378 }
379 if (dip->ditrap && !dip->ditf && dip->dnl >= dip->ditrap…
380 if (control(dip->dimac, 0)) {
381 trap++;
382 dip->ditf++;
383 }
384 return;
385 }
386 j = lss;
387 if (flss)
388 lss = flss;
389 nlss = dip->alss + dip->blss + lss;
390 numtabp[NL].val += nlss;
391 if (TROFF && ascii) {
392 dip->alss = dip->blss = 0;
393 }
394 pchar1((Tchar)'\n');
395 flss = 0;
396 lss = j;
397 if (numtabp[NL].val < pl)
398 goto nl2;
399 nl1:
400 ejf = dip->hnl = numtabp[NL].val = 0;
401 ejl = frame;
402 if (donef) {
403 if ((!nc && !wch) || ndone)
404 done1(0);
405 ndone++;
406 donef = 0;
407 if (frame == stk)
408 nflush++;
409 }
410 opn = numtabp[PN].val;
411 numtabp[PN].val++;
412 if (npnflg) {
413 numtabp[PN].val = npn;
414 npn = npnflg = 0;
415 }
416 nlpn:
417 if (numtabp[PN].val == pfrom) {
418 print++;
419 pfrom = -1;
420 } else if (opn == pto) {
421 print = 0;
422 opn = -1;
423 chkpn();
424 goto nlpn;
425 }
426 if (print)
427 ptpage(numtabp[PN].val); /* supposedly in a clean…
428 if (stop && print) {
429 dpn++;
430 if (dpn >= stop) {
431 dpn = 0;
432 ptpause();
433 }
434 }
435 nl2:
436 trap = 0;
437 if (numtabp[NL].val == 0) {
438 if ((j = findn(0)) != NTRAP)
439 trap = control(mlist[j], 0);
440 } else if ((i = findt(numtabp[NL].val - nlss)) <= nlss) {
441 if ((j = findn1(numtabp[NL].val - nlss + i)) == NTRAP) {
442 flusho();
443 ERROR "Trap botch." WARN;
444 done2(-5);
445 }
446 trap = control(mlist[j], 0);
447 }
448 }
449
450 int
451 findn1(int a)
452 {
453 int i, j;
454
455 for (i = 0; i < NTRAP; i++) {
456 if (mlist[i]) {
457 if ((j = nlist[i]) < 0)
458 j += pl;
459 if (j == a)
460 break;
461 }
462 }
463 return(i);
464 }
465
466
467 void chkpn(void)
468 {
469 pto = *(pnp++);
470 pfrom = pto>=0 ? pto : -pto;
471 if (pto == -INT_MAX) {
472 flusho();
473 done1(0);
474 }
475 if (pto < 0) {
476 pto = -pto;
477 print++;
478 pfrom = 0;
479 }
480 }
481
482 int
483 findt(int a)
484 {
485 int i, j, k;
486
487 k = INT_MAX;
488 if (dip != d) {
489 if (dip->dimac && (i = dip->ditrap - a) > 0)
490 k = i;
491 return(k);
492 }
493 for (i = 0; i < NTRAP; i++) {
494 if (mlist[i]) {
495 if ((j = nlist[i]) < 0)
496 j += pl;
497 if ((j -= a) <= 0)
498 continue;
499 if (j < k)
500 k = j;
501 }
502 }
503 i = pl - a;
504 if (k > i)
505 k = i;
506 return(k);
507 }
508
509 int
510 findt1(void)
511 {
512 int i;
513
514 if (dip != d)
515 i = dip->dnl;
516 else
517 i = numtabp[NL].val;
518 return(findt(i));
519 }
520
521
522 void eject(Stack *a)
523 {
524 int savlss;
525
526 if (dip != d)
527 return;
528 ejf++;
529 if (a)
530 ejl = a;
531 else
532 ejl = frame;
533 if (trap)
534 return;
535 e1:
536 savlss = lss;
537 lss = findt(numtabp[NL].val);
538 newline(0);
539 lss = savlss;
540 if (numtabp[NL].val && !trap)
541 goto e1;
542 }
543
544 int
545 movword(void)
546 {
547 int w;
548 Tchar i, *wp;
549 int savwch, hys;
550
551 over = 0;
552 wp = wordp;
553 if (!nwd) {
554 while (cbits(*wp++) == ' ') {
555 wch--;
556 wne -= sps;
557 }
558 wp--;
559 }
560 if (wne > nel && !hyoff && hyf && (!nwd || nel > 3 * sps) &&
561 (!(hyf & 02) || (findt1() > lss)))
562 hyphen(wp);
563 savwch = wch;
564 hyp = hyptr;
565 nhyp = 0;
566 while (*hyp && *hyp <= wp)
567 hyp++;
568 while (wch) {
569 if (hyoff != 1 && *hyp == wp) {
570 hyp++;
571 if (!wdstart || (wp > wdstart + 1 && wp < wdend …
572 (!(hyf & 04) || wp < wdend - 1) && …
573 (!(hyf & 010) || wp > wdstart + 2))) { …
574 nhyp++;
575 storeline((Tchar)IMP, 0);
576 }
577 }
578 i = *wp++;
579 w = width(i);
580 wne -= w;
581 wch--;
582 storeline(i, w);
583 }
584 if (nel >= 0) {
585 nwd++;
586 return(0); /* line didn't fill up */
587 }
588 if (TROFF)
589 xbits((Tchar)HYPHEN, 1);
590 hys = width((Tchar)HYPHEN);
591 m1:
592 if (!nhyp) {
593 if (!nwd)
594 goto m3;
595 if (wch == savwch)
596 goto m4;
597 }
598 if (*--linep != IMP)
599 goto m5;
600 if (!(--nhyp))
601 if (!nwd)
602 goto m2;
603 if (nel < hys) {
604 nc--;
605 goto m1;
606 }
607 m2:
608 if ((i = cbits(*(linep - 1))) != '-' && i != EMDASH) {
609 *linep = (*(linep - 1) & SFMASK) | HYPHEN;
610 w = width(*linep);
611 nel -= w;
612 ne += w;
613 linep++;
614 }
615 m3:
616 nwd++;
617 m4:
618 wordp = wp;
619 return(1); /* line filled up */
620 m5:
621 nc--;
622 w = width(*linep);
623 ne -= w;
624 nel += w;
625 wne += w;
626 wch++;
627 wp--;
628 goto m1;
629 }
630
631
632 void horiz(int i)
633 {
634 vflag = 0;
635 if (i)
636 pchar(makem(i));
637 }
638
639
640 void setnel(void)
641 {
642 if (!nc) {
643 linep = line;
644 if (un1 >= 0) {
645 un = un1;
646 un1 = -1;
647 }
648 nel = ll - un;
649 ne = adsp = adrem = 0;
650 }
651 }
652
653 int
654 getword(int x)
655 {
656 int j, k;
657 Tchar i, *wp;
658 int noword;
659 int obits;
660
661 j = 0;
662 noword = 0;
663 if (x)
664 if (pendw) {
665 *pendw = 0;
666 goto rtn;
667 }
668 if (wordp = pendw)
669 goto g1;
670 hyp = hyptr;
671 wordp = word;
672 over = wne = wch = 0;
673 hyoff = 0;
674 obits = chbits;
675 while (1) { /* picks up 1st char of word */
676 j = cbits(i = GETCH());
677 if (j == '\n') {
678 wne = wch = 0;
679 noword = 1;
680 goto rtn;
681 }
682 if (j == ohc) {
683 hyoff = 1; /* 1 => don't hyphenate */
684 continue;
685 }
686 if (j == ' ') {
687 numtabp[HP].val += sps;
688 widthp = sps;
689 storeword(i, sps);
690 continue;
691 }
692 break;
693 }
694 storeword(' ' | obits, sps);
695 if (spflg) {
696 storeword(' ' | obits, sps);
697 spflg = 0;
698 }
699 g0:
700 if (j == CONT) {
701 pendw = wordp;
702 nflush = 0;
703 flushi();
704 return(1);
705 }
706 if (hyoff != 1) {
707 if (j == ohc) {
708 hyoff = 2;
709 *hyp++ = wordp;
710 if (hyp > hyptr + NHYP - 1)
711 hyp = hyptr + NHYP - 1;
712 goto g1;
713 }
714 if (((j == '-' || j == EMDASH)) && !(i & ZBIT)) /…
715 if (wordp > word + 1) {
716 hyoff = 2;
717 *hyp++ = wordp + 1;
718 if (hyp > hyptr + NHYP - 1)
719 hyp = hyptr + NHYP - 1;
720 }
721 }
722 j = width(i);
723 numtabp[HP].val += j;
724 storeword(i, j);
725 g1:
726 j = cbits(i = GETCH());
727 if (j != ' ') {
728 static char *sentchar = ".?!"; /* sentence termin…
729 if (j != '\n')
730 goto g0;
731 wp = wordp-1; /* handle extra space at end of sen…
732 while (wp >= word) {
733 j = cbits(*wp--);
734 if (j=='"' || j=='\'' || j==')' || j==']' || j==…
735 continue;
736 for (k = 0; sentchar[k]; k++)
737 if (j == sentchar[k]) {
738 spflg++;
739 break;
740 }
741 break;
742 }
743 }
744 *wordp = 0;
745 numtabp[HP].val += sps;
746 rtn:
747 for (wp = word; *wp; wp++) {
748 if (ismot(j))
749 break; /* drechsler */
750 j = cbits(*wp);
751 if (j == ' ')
752 continue;
753 if (!(isascii(j) && isdigit(j)) && j != '-')
754 break;
755 }
756 if (*wp == 0) /* all numbers, so don't hyphenate */
757 hyoff = 1;
758 wdstart = 0;
759 wordp = word;
760 pendw = 0;
761 *hyp++ = 0;
762 setnel();
763 return(noword);
764 }
765
766
767 void storeword(Tchar c, int w)
768 {
769 Tchar *savp;
770 int i;
771
772 if (wordp >= word + wdsize - 2) {
773 wdsize += WDSIZE;
774 savp = word;
775 if (( word = (Tchar *)realloc((char *)word, wdsize * siz…
776 if (wordp)
777 wordp = word + (wordp - savp);
778 if (pendw)
779 pendw = word + (pendw - savp);
780 if (wdstart)
781 wdstart = word + (wdstart - savp);
782 if (wdend)
783 wdend = word + (wdend - savp);
784 for (i = 0; i < NHYP; i++)
785 if (hyptr[i])
786 hyptr[i] = word + (hyptr[i] - sa…
787 } else {
788 if (over) {
789 return;
790 } else {
791 flusho();
792 ERROR "Word overflow." WARN;
793 over++;
794 c = LEFTHAND;
795 w = width(LEFTHAND);
796 }
797 }
798 }
799 widthp = w;
800 wne += w;
801 *wordp++ = c;
802 wch++;
803 }
804
805
806 Tchar gettch(void)
807 {
808 extern int c_isalnum;
809 Tchar i;
810 int j;
811
812 if (TROFF)
813 return getch();
814
815 i = getch();
816 j = cbits(i);
817 if (ismot(i) || fbits(i) != ulfont)
818 return(i);
819 if (cu) {
820 if (trtab[j] == ' ') {
821 setcbits(i, '_');
822 setfbits(i, FT); /* default */
823 }
824 return(i);
825 }
826 /* should test here for characters that ought to be underlined */
827 /* in the old nroff, that was the 200 bit on the width! */
828 /* for now, just do letters, digits and certain special chars */
829 if (j <= 127) {
830 if (!isalnum(j))
831 setfbits(i, FT);
832 } else {
833 if (j < c_isalnum)
834 setfbits(i, FT);
835 }
836 return(i);
837 }
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.