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