n5.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
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(<), 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 }