n5.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       n5.c (14292B)
       ---
            1 /*
            2  * troff5.c
            3  * 
            4  * misc processing requests
            5  */
            6 
            7 #include "tdef.h"
            8 #include "fns.h"
            9 #include "ext.h"
           10 
           11 int        iflist[NIF];
           12 int        ifx;
           13 int        ifnum = 0;        /* trying numeric expression for .if or .ie condition */
           14 
           15 void casead(void)
           16 {
           17         int i;
           18 
           19         ad = 1;
           20         /* leave admod alone */
           21         if (skip())
           22                 return;
           23         switch (i = cbits(getch())) {
           24         case 'r':        /* right adj, left ragged */
           25                 admod = 2;
           26                 break;
           27         case 'l':        /* left adj, right ragged */
           28                 admod = ad = 0;        /* same as casena */
           29                 break;
           30         case 'c':        /*centered adj*/
           31                 admod = 1;
           32                 break;
           33         case 'b': 
           34         case 'n':
           35                 admod = 0;
           36                 break;
           37         case '0': 
           38         case '2': 
           39         case '4':
           40                 ad = 0;
           41         case '1': 
           42         case '3': 
           43         case '5':
           44                 admod = (i - '0') / 2;
           45         }
           46 }
           47 
           48 
           49 void casena(void)
           50 {
           51         ad = 0;
           52 }
           53 
           54 
           55 void casefi(void)
           56 {
           57         tbreak();
           58         fi = 1;
           59         pendnf = 0;
           60 }
           61 
           62 
           63 void casenf(void)
           64 {
           65         tbreak();
           66         fi = 0;
           67 }
           68 
           69 
           70 void casers(void)
           71 {
           72         dip->nls = 0;
           73 }
           74 
           75 
           76 void casens(void)
           77 {
           78         dip->nls++;
           79 }
           80 
           81 int
           82 chget(int c)
           83 {
           84         Tchar i;
           85 
           86         i = 0;
           87         if (skip() || ismot(i = getch()) || cbits(i) == ' ' || cbits(i) == '\n') {
           88                 ch = i;
           89                 return(c);
           90         } else 
           91                 return cbits(i);        /* was (i & BYTEMASK) */
           92 }
           93 
           94 
           95 void casecc(void)
           96 {
           97         cc = chget('.');
           98 }
           99 
          100 
          101 void casec2(void)
          102 {
          103         c2 = chget('\'');
          104 }
          105 
          106 
          107 void casehc(void)
          108 {
          109         ohc = chget(OHC);
          110 }
          111 
          112 
          113 void casetc(void)
          114 {
          115         tabc = chget(0);
          116 }
          117 
          118 
          119 void caselc(void)
          120 {
          121         dotc = chget(0);
          122 }
          123 
          124 
          125 void casehy(void)
          126 {
          127         int i;
          128 
          129         hyf = 1;
          130         if (skip())
          131                 return;
          132         noscale++;
          133         i = atoi0();
          134         noscale = 0;
          135         if (nonumb)
          136                 return;
          137         hyf = max(i, 0);
          138 }
          139 
          140 
          141 void casenh(void)
          142 {
          143         hyf = 0;
          144 }
          145 
          146 int
          147 max(int aa, int bb)
          148 {
          149         if (aa > bb)
          150                 return(aa);
          151         else 
          152                 return(bb);
          153 }
          154 
          155 
          156 void casece(void)
          157 {
          158         int i;
          159 
          160         noscale++;
          161         skip();
          162         i = max(atoi0(), 0);
          163         if (nonumb)
          164                 i = 1;
          165         tbreak();
          166         ce = i;
          167         noscale = 0;
          168 }
          169 
          170 
          171 void casein(void)
          172 {
          173         int i;
          174 
          175         if (skip())
          176                 i = in1;
          177         else {
          178                 i = max(hnumb(&in), 0);
          179                 if (nonumb)
          180                         i = in1;
          181         }
          182         tbreak();
          183         in1 = in;
          184         in = i;
          185         if (!nc) {
          186                 un = in;
          187                 setnel();
          188         }
          189 }
          190 
          191 
          192 void casell(void)
          193 {
          194         int i;
          195 
          196         if (skip())
          197                 i = ll1;
          198         else {
          199                 i = max(hnumb(&ll), INCH / 10);
          200                 if (nonumb)
          201                         i = ll1;
          202         }
          203         ll1 = ll;
          204         ll = i;
          205         setnel();
          206 }
          207 
          208 
          209 void caselt(void)
          210 {
          211         int i;
          212 
          213         if (skip())
          214                 i = lt1;
          215         else {
          216                 i = max(hnumb(&lt), 0);
          217                 if (nonumb)
          218                         i = lt1;
          219         }
          220         lt1 = lt;
          221         lt = i;
          222 }
          223 
          224 
          225 void caseti(void)
          226 {
          227         int i;
          228 
          229         if (skip())
          230                 return;
          231         i = max(hnumb(&in), 0);
          232         tbreak();
          233         un1 = i;
          234         setnel();
          235 }
          236 
          237 
          238 void casels(void)
          239 {
          240         int i;
          241 
          242         noscale++;
          243         if (skip())
          244                 i = ls1;
          245         else {
          246                 i = max(inumb(&ls), 1);
          247                 if (nonumb)
          248                         i = ls1;
          249         }
          250         ls1 = ls;
          251         ls = i;
          252         noscale = 0;
          253 }
          254 
          255 
          256 void casepo(void)
          257 {
          258         int i;
          259 
          260         if (skip())
          261                 i = po1;
          262         else {
          263                 i = max(hnumb(&po), 0);
          264                 if (nonumb)
          265                         i = po1;
          266         }
          267         po1 = po;
          268         po = i;
          269         if (TROFF & !ascii)
          270                 esc += po - po1;
          271 }
          272 
          273 
          274 void casepl(void)
          275 {
          276         int i;
          277 
          278         skip();
          279         if ((i = vnumb(&pl)) == 0)
          280                 pl = 11 * INCH; /*11in*/
          281         else 
          282                 pl = i;
          283         if (numtabp[NL].val > pl)
          284                 numtabp[NL].val = pl;
          285 }
          286 
          287 
          288 void casewh(void)
          289 {
          290         int i, j, k;
          291 
          292         lgf++;
          293         skip();
          294         i = vnumb((int *)0);
          295         if (nonumb)
          296                 return;
          297         skip();
          298         j = getrq();
          299         if ((k = findn(i)) != NTRAP) {
          300                 mlist[k] = j;
          301                 return;
          302         }
          303         for (k = 0; k < NTRAP; k++)
          304                 if (mlist[k] == 0)
          305                         break;
          306         if (k == NTRAP) {
          307                 flusho();
          308                 ERROR "cannot plant trap." WARN;
          309                 return;
          310         }
          311         mlist[k] = j;
          312         nlist[k] = i;
          313 }
          314 
          315 
          316 void casech(void)
          317 {
          318         int i, j, k;
          319 
          320         lgf++;
          321         skip();
          322         if (!(j = getrq()))
          323                 return;
          324         else 
          325                 for (k = 0; k < NTRAP; k++)
          326                         if (mlist[k] == j)
          327                                 break;
          328         if (k == NTRAP)
          329                 return;
          330         skip();
          331         i = vnumb((int *)0);
          332         if (nonumb)
          333                 mlist[k] = 0;
          334         nlist[k] = i;
          335 }
          336 
          337 int
          338 findn(int i)
          339 {
          340         int k;
          341 
          342         for (k = 0; k < NTRAP; k++)
          343                 if ((nlist[k] == i) && (mlist[k] != 0))
          344                         break;
          345         return(k);
          346 }
          347 
          348 
          349 void casepn(void)
          350 {
          351         int i;
          352 
          353         skip();
          354         noscale++;
          355         i = max(inumb(&numtabp[PN].val), 0);
          356         noscale = 0;
          357         if (!nonumb) {
          358                 npn = i;
          359                 npnflg++;
          360         }
          361 }
          362 
          363 
          364 void casebp(void)
          365 {
          366         int i;
          367         Stack *savframe;
          368 
          369         if (dip != d)
          370                 return;
          371         savframe = frame;
          372         skip();
          373         if ((i = inumb(&numtabp[PN].val)) < 0)
          374                 i = 0;
          375         tbreak();
          376         if (!nonumb) {
          377                 npn = i;
          378                 npnflg++;
          379         } else if (dip->nls)
          380                 return;
          381         eject(savframe);
          382 }
          383 
          384 void casetm(void)
          385 {
          386         casetm1(0, stderr);
          387 }
          388 
          389 
          390 void casefm(void)
          391 {
          392         static struct fcache {
          393                 char *name;
          394                 FILE *fp;
          395         } fcache[15];
          396         int i;
          397 
          398         if ( skip() || !getname()) {
          399                 ERROR "fm: missing filename" WARN;
          400                 return;
          401         }
          402                 
          403         for (i = 0; i < 15 && fcache[i].fp != NULL; i++) {
          404                 if (strcmp(nextf, fcache[i].name) == 0)
          405                         break;
          406         }
          407         if (i >= 15) {
          408                 ERROR "fm: too many streams" WARN;
          409                 return;
          410         }
          411         if (fcache[i].fp == NULL) {
          412                 if( (fcache[i].fp = fopen(unsharp(nextf), "w")) == NULL) {
          413                         ERROR "fm: cannot open %s", nextf WARN;
          414                         return;
          415                 }
          416                 fcache[i].name = strdupl(nextf);
          417         }
          418         casetm1(0, fcache[i].fp);
          419 }
          420 
          421 void casetm1(int ab, FILE *out) 
          422 {
          423         int i, j, c;
          424         char *p;
          425         char tmbuf[NTM];
          426 
          427         lgf++;
          428         copyf++;
          429         if (ab) {
          430                 if (skip())
          431                         ERROR "User Abort" WARN;
          432                 else {
          433                         extern int error;
          434                         int savtrac = trace;
          435                         i = trace = 0;
          436                         noscale++;
          437                         i = inumb(&trace);
          438                         noscale--;
          439                         if (i) {
          440                                 error = i;
          441                                 if (nlflg || skip())
          442                                         ERROR "User Abort, exit code %d", i WARN;
          443                         }
          444                         trace = savtrac;
          445                 }
          446         } else
          447                 skip();        
          448         for (i = 0; i < NTM - 2; ) {
          449                 if ((c = cbits(getch())) == '\n' || c == RIGHT)
          450                         break;
          451                 else if (c == MINUS) {        /* special pleading for strange encodings */
          452                         tmbuf[i++] = '\\';
          453                         tmbuf[i++] = '-';
          454                 } else if (c == PRESC) {
          455                         tmbuf[i++] = '\\';
          456                         tmbuf[i++] = 'e';
          457                 } else if (c == FILLER) {
          458                         tmbuf[i++] = '\\';
          459                         tmbuf[i++] = '&';
          460                 } else if (c == UNPAD) {
          461                         tmbuf[i++] = '\\';
          462                         tmbuf[i++] = ' ';
          463                 } else if (c == OHC) {
          464                         tmbuf[i++] = '\\';
          465                         tmbuf[i++] = '%';
          466                 } else if (c >= ALPHABET) {
          467                         p = chname(c);
          468                         switch (*p) {
          469                         case MBchar:
          470                                 strcpy(&tmbuf[i], p+1);
          471                                 break;
          472                         case Number:
          473                                 sprintf(&tmbuf[i], "\\N'%s'", p+1);
          474                                 break;
          475                         case Troffchar:
          476                                 if ((j = strlen(p+1)) == 2)
          477                                         sprintf(&tmbuf[i], "\\(%s", p+1);
          478                                 else
          479                                         sprintf(&tmbuf[i], "\\C'%s'", p+1);
          480                                 break;
          481                         default:
          482                                 sprintf(&tmbuf[i]," %s? ", p);
          483                                 break;
          484                         }
          485                         j = strlen(&tmbuf[i]);
          486                         i += j;
          487                 } else
          488                         tmbuf[i++] = c;
          489         }
          490         tmbuf[i] = 0;
          491         if (ab)        /* truncate output */
          492                 obufp = obuf;        /* should be a function in n2.c */
          493         flusho();
          494         if (i)
          495                 fprintf(out, "%s\n", tmbuf);
          496         fflush(out);
          497         copyf--;
          498         lgf--;
          499 }
          500 
          501 
          502 void casesp(void)
          503 {
          504         casesp1(0);
          505 }
          506 
          507 void casesp1(int a)
          508 {
          509         int i, j, savlss;
          510 
          511         tbreak();
          512         if (dip->nls || trap)
          513                 return;
          514         i = findt1();
          515         if (!a) {
          516                 skip();
          517                 j = vnumb((int *)0);
          518                 if (nonumb)
          519                         j = lss;
          520         } else 
          521                 j = a;
          522         if (j == 0)
          523                 return;
          524         if (i < j)
          525                 j = i;
          526         savlss = lss;
          527         if (dip != d)
          528                 i = dip->dnl; 
          529         else 
          530                 i = numtabp[NL].val;
          531         if ((i + j) < 0)
          532                 j = -i;
          533         lss = j;
          534         newline(0);
          535         lss = savlss;
          536 }
          537 
          538 
          539 void casert(void)
          540 {
          541         int a, *p;
          542 
          543         skip();
          544         if (dip != d)
          545                 p = &dip->dnl; 
          546         else 
          547                 p = &numtabp[NL].val;
          548         a = vnumb(p);
          549         if (nonumb)
          550                 a = dip->mkline;
          551         if ((a < 0) || (a >= *p))
          552                 return;
          553         nb++;
          554         casesp1(a - *p);
          555 }
          556 
          557 
          558 void caseem(void)
          559 {
          560         lgf++;
          561         skip();
          562         em = getrq();
          563 }
          564 
          565 
          566 void casefl(void)
          567 {
          568         tbreak();
          569         if (!ascii)
          570                 ptflush();
          571         flusho();
          572 }
          573 
          574 
          575 void caseev(void)
          576 {
          577         int nxev;
          578 
          579         if (skip()) {
          580 e0:
          581                 if (evi == 0)
          582                         return;
          583                 nxev =  evlist[--evi];
          584                 goto e1;
          585         }
          586         noscale++;
          587         nxev = atoi0();
          588         noscale = 0;
          589         if (nonumb)
          590                 goto e0;
          591         flushi();
          592         if (nxev >= NEV || nxev < 0 || evi >= EVLSZ) {
          593                 flusho();
          594                 ERROR "cannot do .ev %d", nxev WARN;
          595                 if (error)
          596                         done2(040);
          597                 else 
          598                         edone(040);
          599                 return;
          600         }
          601         evlist[evi++] = ev;
          602 e1:
          603         if (ev == nxev)
          604                 return;
          605         ev = nxev;
          606         envp = &env[ev];
          607 }
          608 
          609 void envcopy(Env *e1, Env *e2)        /* copy env e2 to e1 */
          610 {
          611         *e1 = *e2;        /* rumor hath that this fails on some machines */
          612 }
          613 
          614 
          615 void caseel(void)
          616 {
          617         if (--ifx < 0) {
          618                 ifx = 0;
          619                 iflist[0] = 0;
          620         }
          621         caseif1(2);
          622 }
          623 
          624 
          625 void caseie(void)
          626 {
          627         if (ifx >= NIF) {
          628                 ERROR "if-else overflow." WARN;
          629                 ifx = 0;
          630                 edone(040);
          631         }
          632         caseif1(1);
          633         ifx++;
          634 }
          635 
          636 
          637 void caseif(void)
          638 {
          639         caseif1(0);
          640 }
          641 
          642 void caseif1(int x)
          643 {
          644         extern int falsef;
          645         int notflag, true;
          646         Tchar i;
          647 
          648         if (x == 2) {
          649                 notflag = 0;
          650                 true = iflist[ifx];
          651                 goto i1;
          652         }
          653         true = 0;
          654         skip();
          655         if ((cbits(i = getch())) == '!') {
          656                 notflag = 1;
          657         } else {
          658                 notflag = 0;
          659                 ch = i;
          660         }
          661         ifnum++;
          662         i = atoi0();
          663         ifnum = 0;
          664         if (!nonumb) {
          665                 if (i > 0)
          666                         true++;
          667                 goto i1;
          668         }
          669         i = getch();
          670         switch (cbits(i)) {
          671         case 'e':
          672                 if (!(numtabp[PN].val & 01))
          673                         true++;
          674                 break;
          675         case 'o':
          676                 if (numtabp[PN].val & 01)
          677                         true++;
          678                 break;
          679         case 'n':
          680                 if (NROFF)
          681                         true++;
          682                 break;
          683         case 't':
          684                 if (TROFF)
          685                         true++;
          686                 break;
          687         case ' ':
          688                 break;
          689         default:
          690                 true = cmpstr(i);
          691         }
          692 i1:
          693         true ^= notflag;
          694         if (x == 1)
          695                 iflist[ifx] = !true;
          696         if (true) {
          697 i2:
          698                 while ((cbits(i = getch())) == ' ')
          699                         ;
          700                 if (cbits(i) == LEFT)
          701                         goto i2;
          702                 ch = i;
          703                 nflush++;
          704         } else {
          705                 if (!nlflg) {
          706                         copyf++;
          707                         falsef++;
          708                         eatblk(0);
          709                         copyf--;
          710                         falsef--;
          711                 }
          712         }
          713 }
          714 
          715 void eatblk(int inblk)
          716 {
          717         int cnt, i;
          718 
          719         cnt = 0;
          720         do {
          721                 if (ch)        {
          722                         i = cbits(ch);
          723                         ch = 0;
          724                 } else
          725                         i = cbits(getch0());
          726                 if (i == ESC)
          727                         cnt++;
          728                 else {
          729                         if (cnt == 1)
          730                                 switch (i) {
          731                                 case '{':  i = LEFT; break;
          732                                 case '}':  i = RIGHT; break;
          733                                 case '\n': i = 'x'; break;
          734                                 }
          735                         cnt = 0;
          736                 }
          737                 if (i == LEFT) eatblk(1);
          738         } while ((!inblk && (i != '\n')) || (inblk && (i != RIGHT)));
          739         if (i == '\n') {
          740                 nlflg++;
          741                 if (ip == 0)
          742                         numtabp[CD].val++;
          743         }
          744 }
          745 
          746 int
          747 cmpstr(Tchar c)
          748 {
          749         int j, delim;
          750         Tchar i;
          751         int val;
          752         int savapts, savapts1, savfont, savfont1, savpts, savpts1;
          753         Tchar string[1280];
          754         Tchar *sp;
          755 
          756         if (ismot(c))
          757                 return(0);
          758         delim = cbits(c);
          759         savapts = apts;
          760         savapts1 = apts1;
          761         savfont = font;
          762         savfont1 = font1;
          763         savpts = pts;
          764         savpts1 = pts1;
          765         sp = string;
          766         while ((j = cbits(i = getch()))!=delim && j!='\n' && sp<&string[1280-1])
          767                 *sp++ = i;
          768         if (sp >= string + 1280) {
          769                 ERROR "too-long string compare." WARN;
          770                 edone(0100);
          771         }
          772         if (nlflg) {
          773                 val = sp==string;
          774                 goto rtn;
          775         }
          776         *sp = 0;
          777         apts = savapts;
          778         apts1 = savapts1;
          779         font = savfont;
          780         font1 = savfont1;
          781         pts = savpts;
          782         pts1 = savpts1;
          783         mchbits();
          784         val = 1;
          785         sp = string;
          786         while ((j = cbits(i = getch())) != delim && j != '\n') {
          787                 if (*sp != i) {
          788                         eat(delim);
          789                         val = 0;
          790                         goto rtn;
          791                 }
          792                 sp++;
          793         }
          794         if (*sp)
          795                 val = 0;
          796 rtn:
          797         apts = savapts;
          798         apts1 = savapts1;
          799         font = savfont;
          800         font1 = savfont1;
          801         pts = savpts;
          802         pts1 = savpts1;
          803         mchbits();
          804         return(val);
          805 }
          806 
          807 
          808 void caserd(void)
          809 {
          810 
          811         lgf++;
          812         skip();
          813         getname();
          814         if (!iflg) {
          815                 if (quiet) {
          816                         if (NROFF) {
          817                                 echo_off();
          818                                 flusho();
          819                         }
          820                         fprintf(stderr, "\007"); /*bell*/
          821                 } else {
          822                         if (nextf[0]) {
          823                                 fprintf(stderr, "%s:", nextf);
          824                         } else {
          825                                 fprintf(stderr, "\007"); /*bell*/
          826                         }
          827                 }
          828         }
          829         collect();
          830         tty++;
          831         pushi(RD_OFFSET, PAIR('r','d'));
          832 }
          833 
          834 int
          835 rdtty(void)
          836 {
          837         char        onechar;
          838 
          839         onechar = 0;
          840         if (read(0, &onechar, 1) == 1) {
          841                 if (onechar == '\n')
          842                         tty++;
          843                 else 
          844                         tty = 1;
          845                 if (tty != 3)
          846                         return(onechar);
          847         }
          848         tty = 0;
          849         if (NROFF && quiet)
          850                 echo_on();
          851         return(0);
          852 }
          853 
          854 
          855 void caseec(void)
          856 {
          857         eschar = chget('\\');
          858 }
          859 
          860 
          861 void caseeo(void)
          862 {
          863         eschar = 0;
          864 }
          865 
          866 
          867 void caseta(void)
          868 {
          869         int i, j, k;
          870 
          871         tabtab[0] = nonumb = 0;
          872         for (i = 0; ((i < (NTAB - 1)) && !nonumb); i++) {
          873                 if (skip())
          874                         break;
          875                 k = tabtab[max(i-1, 0)] & TABMASK;
          876                 if ((j = max(hnumb(&k), 0)) > TABMASK) {
          877                         ERROR "Tab too far away" WARN;
          878                         j = TABMASK;
          879                 }
          880                 tabtab[i] = j & TABMASK;
          881                 if (!nonumb) 
          882                         switch (cbits(ch)) {
          883                         case 'C':
          884                                 tabtab[i] |= CTAB;
          885                                 break;
          886                         case 'R':
          887                                 tabtab[i] |= RTAB;
          888                                 break;
          889                         default: /*includes L*/
          890                                 break;
          891                         }
          892                 nonumb = ch = 0;
          893         }
          894         if (!skip())
          895                 ERROR "Too many tab stops" WARN;
          896         tabtab[i] = 0;
          897 }
          898 
          899 
          900 void casene(void)
          901 {
          902         int i, j;
          903 
          904         skip();
          905         i = vnumb((int *)0);
          906         if (nonumb)
          907                 i = lss;
          908         if (dip == d && numtabp[NL].val == -1) {
          909                 newline(1);
          910                 return;
          911         }
          912         if (i > (j = findt1())) {
          913                 i = lss;
          914                 lss = j;
          915                 dip->nls = 0;
          916                 newline(0);
          917                 lss = i;
          918         }
          919 }
          920 
          921 
          922 void casetr(void)
          923 {
          924         int i, j;
          925         Tchar k;
          926 
          927         lgf++;
          928         skip();
          929         while ((i = cbits(k=getch())) != '\n') {
          930                 if (ismot(k))
          931                         return;
          932                 if (ismot(k = getch()))
          933                         return;
          934                 if ((j = cbits(k)) == '\n')
          935                         j = ' ';
          936                 trtab[i] = j;
          937         }
          938 }
          939 
          940 
          941 void casecu(void)
          942 {
          943         cu++;
          944         caseul();
          945 }
          946 
          947 
          948 void caseul(void)
          949 {
          950         int i;
          951 
          952         noscale++;
          953         skip();
          954         i = max(atoi0(), 0);
          955         if (nonumb)
          956                 i = 1;
          957         if (ul && (i == 0)) {
          958                 font = sfont;
          959                 ul = cu = 0;
          960         }
          961         if (i) {
          962                 if (!ul) {
          963                         sfont = font;
          964                         font = ulfont;
          965                 }
          966                 ul = i;
          967         }
          968         noscale = 0;
          969         mchbits();
          970 }
          971 
          972 
          973 void caseuf(void)
          974 {
          975         int i, j;
          976 
          977         if (skip() || !(i = getrq()) || i == 'S' ||  (j = findft(i))  == -1)
          978                 ulfont = ULFONT; /*default underline position*/
          979         else 
          980                 ulfont = j;
          981         if (NROFF && ulfont == FT)
          982                 ulfont = ULFONT;
          983 }
          984 
          985 
          986 void caseit(void)
          987 {
          988         int i;
          989 
          990         lgf++;
          991         it = itmac = 0;
          992         noscale++;
          993         skip();
          994         i = atoi0();
          995         skip();
          996         if (!nonumb && (itmac = getrq()))
          997                 it = i;
          998         noscale = 0;
          999 }
         1000 
         1001 
         1002 void casemc(void)
         1003 {
         1004         int i;
         1005 
         1006         if (icf > 1)
         1007                 ic = 0;
         1008         icf = 0;
         1009         if (skip())
         1010                 return;
         1011         ic = getch();
         1012         icf = 1;
         1013         skip();
         1014         i = max(hnumb((int *)0), 0);
         1015         if (!nonumb)
         1016                 ics = i;
         1017 }
         1018 
         1019 
         1020 void casemk(void)
         1021 {
         1022         int i, j;
         1023 
         1024         if (dip != d)
         1025                 j = dip->dnl; 
         1026         else 
         1027                 j = numtabp[NL].val;
         1028         if (skip()) {
         1029                 dip->mkline = j;
         1030                 return;
         1031         }
         1032         if ((i = getrq()) == 0)
         1033                 return;
         1034         numtabp[findr(i)].val = j;
         1035 }
         1036 
         1037 
         1038 void casesv(void)
         1039 {
         1040         int i;
         1041 
         1042         skip();
         1043         if ((i = vnumb((int *)0)) < 0)
         1044                 return;
         1045         if (nonumb)
         1046                 i = 1;
         1047         sv += i;
         1048         caseos();
         1049 }
         1050 
         1051 
         1052 void caseos(void)
         1053 {
         1054         int savlss;
         1055 
         1056         if (sv <= findt1()) {
         1057                 savlss = lss;
         1058                 lss = sv;
         1059                 newline(0);
         1060                 lss = savlss;
         1061                 sv = 0;
         1062         }
         1063 }
         1064 
         1065 
         1066 void casenm(void)
         1067 {
         1068         int i;
         1069 
         1070         lnmod = nn = 0;
         1071         if (skip())
         1072                 return;
         1073         lnmod++;
         1074         noscale++;
         1075         i = inumb(&numtabp[LN].val);
         1076         if (!nonumb)
         1077                 numtabp[LN].val = max(i, 0);
         1078         getnm(&ndf, 1);
         1079         getnm(&nms, 0);
         1080         getnm(&ni, 0);
         1081         getnm(&nmwid, 3);        /* really kludgy! */
         1082         noscale = 0;
         1083         nmbits = chbits;
         1084 }
         1085 
         1086 /*
         1087  * .nm relies on the fact that illegal args are skipped; don't warn
         1088  * for illegality of these
         1089  */
         1090 void getnm(int *p, int min)
         1091 {
         1092         int i;
         1093         int savtr = trace;
         1094 
         1095         eat(' ');
         1096         if (skip())
         1097                 return;
         1098         trace = 0;
         1099         i = atoi0();
         1100         if (nonumb)
         1101                 return;
         1102         *p = max(i, min);
         1103         trace = savtr;
         1104 }
         1105 
         1106 
         1107 void casenn(void)
         1108 {
         1109         noscale++;
         1110         skip();
         1111         nn = max(atoi0(), 1);
         1112         noscale = 0;
         1113 }
         1114 
         1115 
         1116 void caseab(void)
         1117 {
         1118         casetm1(1, stderr);
         1119         done3(0);
         1120 }
         1121 
         1122 
         1123 /* nroff terminal handling has been pretty well excised */
         1124 /* as part of the merge with troff.  these are ghostly remnants, */
         1125 /* called, but doing nothing. restore them at your peril. */
         1126 
         1127 
         1128 void save_tty(void)                        /*save any tty settings that may be changed*/
         1129 {
         1130 }
         1131 
         1132 
         1133 void restore_tty(void)                        /*restore tty settings from beginning*/
         1134 {
         1135 }
         1136 
         1137 
         1138 void set_tty(void)
         1139 {
         1140 }
         1141 
         1142 
         1143 void echo_off(void)                        /*turn off ECHO for .rd in "-q" mode*/
         1144 {
         1145 }
         1146 
         1147 
         1148 void echo_on(void)                        /*restore ECHO after .rd in "-q" mode*/
         1149 {
         1150 }