n5.c 14 KB

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