|
|
1.1 root 1: /*
2: * req2.c
3: * Nroff/Troff.
4: * Requests (n-z).
5: */
6:
7: #include <ctype.h>
8: #include <sys/ascii.h>
9: #include "roff.h"
10:
11: /*
12: * Turn adjust mode off.
13: */
14: req_na()
15: {
16: adm = 0;
17: }
18:
19: /*
20: * Overstrike bold off.
21: * !V7.
22: */
23: req_nb()
24: {
25: enb = 0;
26: }
27:
28: /*
29: * Need.
30: */
31: req_ne(argc, argv) int argc; char *argv[];
32: {
33: register int need,
34: have;
35:
36: need = number(argv[1], SMVLSP, SDVLSP, 0, 1, unit(SMVLSP, SDVLSP));
37: if (cdivp->d_ctpp) {
38: have = cdivp->d_ctpp->t_apos;
39: if (have > pgl)
40: have = pgl;
41: } else
42: have = pgl;
43: have -= cdivp->d_rpos;
44: if (have >= need || nsm != 0)
45: return;
46: setbreak();
47: sspace(have);
48: }
49:
50: /*
51: * Go into no fill mode.
52: */
53: req_nf()
54: {
55: setbreak();
56: fill = 0;
57: }
58:
59: /*
60: * Turn off hyphenation.
61: */
62: req_nh()
63: {
64: hyp = 0; /* turn the durn thing off */
65: }
66:
67: /*
68: * Set number mode. (.nm) $$TO_DO$$
69: */
70: req_nm(argc, argv) int argc; char *argv[];
71: {
72: #if 1
73: printu(".nm");
74: #else
75: long smdigw, sddigw;
76:
77: smdigw = width('0') * swddiv;
78: sddigw = swddiv;
79: if ((lnn=number(argv[1], SMUNIT, SDUNIT, lnn, 0, 0)) <= 0) {
80: lnn = 0;
81: return;
82: }
83: if (argv[2][0] != '\0')
84: lnm = number(argv[2], SMUNIT, SDUNIT, 0, 0, 1);
85: if (argv[3][0] != '\0')
86: lns = number(argv[3], smdigw, sddigw, 0, 0, unit(smdigw, sddigw));
87: if (argv[4][0] != '\0')
88: lni = number(argv[4], smdigw, sddigw, 0, 0, unit(smdigw, sddigw);
89: #endif
90: }
91:
92: /*
93: * Turn off line number mode for n lines. (.nn) $$TO_DO$$
94: */
95: req_nn(argc, argv) int argc; char *argv[];
96: {
97: #if 1
98: printu(".nn");
99: #else
100: register int n;
101:
102: lnc = number(argv[1], SMUNIT, SDUNIT, 0, 0, 1);
103: #endif
104: }
105:
106: /*
107: * Define a number register.
108: */
109: req_nr(argc, argv) int argc; char *argv[];
110: {
111: register REG *rp;
112: char name[2];
113:
114: argname(argv[1], name);
115: #if 0
116: rp = getnreg(name, RNUMR); /* too many paramters! */
117: #else
118: rp = getnreg(name);
119: #endif
120: rp->n_reg.r_nval = number(argv[2], SMUNIT, SDUNIT, rp->n_reg.r_nval, 0, 0);
121: if (argc >= 4)
122: rp->n_reg.r_incr = numb(argv[3], SMUNIT, SDUNIT);
123: if (rp == nrpnreg)
124: npn = pno + 1;
125: }
126:
127: /*
128: * Turn no-space mode on.
129: */
130: req_ns()
131: {
132: nsm = 1;
133: }
134:
135: /*
136: * End input from current file and switch to given file.
137: */
138: req_nx(argc, argv) int argc; char *argv[];
139: {
140: register FILE *fp;
141: register STR *sp;
142:
143: sp = strp;
144: do {
145: if (sp == NULL) {
146: printe("cannot find current file");
147: return;
148: }
149: } while (sp->x2.s_type != SFILE);
150: if ((fp = fopen(argv[1], "r")) == NULL) {
151: printe("cannot open %s", argv[1]);
152: return;
153: }
154: fclose(sp->x2.s_fp);
155: sp->x2.s_fp = fp;
156: nfree(sp->x2.s_fname);
157: sp->x2.s_fname = duplstr(argv[1]);
158: sp->x2.s_clnc = 1;
159: sp->x2.s_nlnc = 1;
160: }
161:
162: /*
163: * Output saved space.
164: */
165: req_os()
166: {
167: sspace(svs);
168: }
169:
170: /*
171: * Set page number character in title.
172: */
173: req_pc(argc, argv) int argc; char *argv[];
174: {
175: tpc = argv[1][0];
176: }
177:
178: /*
179: * Pipe nroff output. (.pi) $$TO_DO$$
180: */
181: req_pi(argc, argv) int argc; char *argv[];
182: {
183: printu(".pi");
184: }
185:
186: /*
187: * Set page length.
188: */
189: req_pl(argc, argv) int argc; char *argv[];
190: {
191: pgl = number(argv[1], SMVLSP, SDVLSP, pgl, 0, unit(11*SMINCH, SDINCH));
192: if (pgl == 0)
193: pgl = unit(SMVLSP, SDVLSP);
194: }
195:
196: /*
197: * Print sizes of macros.
198: */
199: req_pm(argc, argv) int argc; char *argv[];
200: {
201: register REG **rpp,
202: *rp;
203: unsigned rnum, /* number of registers */
204: mnum, /* number of macros */
205: csize; /* total space */
206: int vflag;
207:
208: vflag = (argv[1][0] == '\0');
209: if (vflag)
210: fprintf(stderr, "Macro and register sizes:\n");
211: else
212: fprintf(stderr, "Macro and register size: ");
213: rnum = mnum = 0;
214: csize = 0;
215: for (rpp = ®t[0]; rpp < ®t[RHTSIZE]; rpp++) {
216: for (rp = *rpp; rp; rp = rp->t_reg.r_next)
217: switch (rp->t_reg.r_type) {
218: case RNUMR:
219: ++rnum;
220: if (vflag)
221: printnr(rp);
222: csize += sizeof(*rp);
223: break;
224: case RTEXT:
225: ++mnum;
226: csize += sizeof(*rp) - sizeof(rp->t_reg.r_macd);
227: csize += printm(rp, vflag);
228: break;
229: default:
230: panic("unknown macro/register type %d",
231: rp->t_reg.r_type);
232: }
233: }
234: fprintf(stderr, "%u registers, %u macros, %u bytes\n",
235: rnum, mnum, csize);
236: }
237:
238: /*
239: * Printnr prints out the size and name of a number register.
240: */
241: printnr(rp)
242: register REG *rp;
243: {
244: fprintf(stderr, "Register %.2s %u bytes\n", rp->t_reg.r_name,
245: sizeof(*rp));
246: }
247:
248: /*
249: * Printm returns the size of a macro and prints out its name if vflag.
250: */
251: printm(rp, vflag)
252: register REG *rp;
253: int vflag;
254: {
255: register MAC *mp;
256: unsigned size;
257: int type;
258: static char *tn[] = { "Macro/String", "Diversion" };
259:
260: size = 0;
261: mp = &rp->t_reg.r_macd;
262: type = mp->t_div.m_type;
263: if (type != MTEXT && type != MDIVN)
264: return (size);
265: fprintf(stderr, "%s %.2s", tn[type], rp->t_reg.r_name);
266: for (;;) {
267: size += sizeof(*mp);
268: mp = mp->t_div.m_next;
269: if (mp == NULL)
270: break;
271: if (mp->t_div.m_type != type)
272: fprintf(stderr, " (changed to %s)",
273: tn[mp->t_div.m_type]);
274: }
275: if (vflag)
276: fprintf(stderr, " uses %u bytes\n", size);
277: return (size);
278: }
279:
280:
281: /*
282: * Set page number.
283: */
284: req_pn(argc, argv) int argc; char *argv[];
285: {
286: if (argc >= 2) {
287: pno = number(argv[1], SMUNIT, SDUNIT, pno, 0, pno);
288: npn = pno + 1;
289: }
290: }
291:
292: /*
293: * Set page offset.
294: */
295: req_po(argc, argv) int argc; char *argv[];
296: {
297: setval(&pof, &oldpof, argv[1], SMEMSP, SDEMSP);
298: }
299:
300: /*
301: * Set pointsize.
302: */
303: req_ps(argc, argv) int argc; char *argv[];
304: {
305: register int n;
306:
307: n = number(argv[1], SMPOIN, SDPOIN, psz, 0, oldpsz);
308: newpsze(n);
309: }
310:
311: /*
312: * Copy a file verbatim to output.
313: * !V7.
314: */
315: req_rb(argc, argv) int argc; char *argv[];
316: {
317: setbreak();
318: if (argc < 2)
319: printe(".rb: no file specified");
320: else if (copy_file(argv[1]) == 0)
321: printe(".rb: cannot open file %s", argv[1]);
322: }
323:
324: /*
325: * Read an insertion from the standard input.
326: */
327: req_rd(argc, argv) int argc; char *argv[];
328: {
329: if (argc >= 2)
330: fprintf(stderr, "%s", argv[1]);
331: else
332: putc(A_BEL, stderr);
333: allstr(SSINP);
334: }
335:
336: /*
337: * Assign a named font to another name.
338: * !V7.
339: */
340: req_rf(argc, argv) int argc; char *argv[];
341: {
342: register int n;
343:
344: if (argc < 2) {
345: printe(".rf: requires name and new name");
346: return;
347: }
348: if ((n = font_number(argv[1], ".rf: ")) >= 0)
349: assign_font(argv[2], n);
350: }
351:
352: /*
353: * Remove text register or request.
354: */
355: req_rm(argc, argv) int argc; char *argv[];
356: {
357: char name[2];
358: register int i;
359:
360: for (i=1; i<argc; i++) {
361: argname(argv[i], name);
362: if (reltreg(name))
363: continue;
364: printe("cannot remove %s", argv[i]);
365: }
366: }
367:
368: /*
369: * Rename the given request or macro.
370: * Lookup is hashed, so just changing the name field does not work.
371: */
372: req_rn(argc, argv) int argc; char *argv[];
373: {
374: register REG *orp, *nrp;
375: char oname[2], nname[2];
376:
377: argname(argv[1], oname);
378: if ((orp = findreg(oname, RTEXT)) == NULL) {
379: printe("cannot find request %s", argv[1]);
380: return;
381: }
382: argname(argv[2], nname);
383: if ((nrp = makereg(nname, RTEXT)) == NULL) {
384: printe("cannot make request %s", argv[2]);
385: return;
386: }
387: nrp->t_reg.r_maxh = orp->t_reg.r_maxh;
388: nrp->t_reg.r_maxw = orp->t_reg.r_maxw;
389: nrp->t_reg.r_macd = orp->t_reg.r_macd;
390: reltreg(oname);
391: }
392:
393: /*
394: * Restore the cursor position, just in case it got garbaged.
395: * !V7.
396: */
397: req_rp()
398: {
399: addidir(DFPOS, 0);
400: }
401:
402: /*
403: * Remove number register.
404: */
405: req_rr(argc, argv) int argc; char *argv[];
406: {
407: char name[2];
408: register int i;
409:
410: for (i=1; i<argc; i++) {
411: argname(argv[i], name);
412: if (relnreg(name))
413: continue;
414: printe("cannot remove %s", argv[i]);
415: }
416: }
417:
418: /*
419: * Turn no space mode off.
420: */
421: req_rs()
422: {
423: nsm = 0;
424: }
425:
426: /*
427: * Return to marked vertical position.
428: */
429: req_rt(argc, argv) int argc; char *argv[];
430: {
431: register int n;
432:
433: if (argc == 1)
434: n = cdivp->d_mk;
435: else
436: n = numb(argv[1], SMVLSP, SDVLSP);
437: if (n >= cdivp->d_rpos)
438: return;
439: sspace(n - cdivp->d_rpos);
440: }
441:
442: /*
443: * Stack input and redirect from given file.
444: */
445: req_so(argc, argv) int argc; char *argv[];
446: {
447: adsfile(argv[1]);
448: }
449:
450: /*
451: * Space vertically.
452: */
453: req_sp(argc, argv) int argc; char *argv[];
454: {
455: if (nsm != 0)
456: return;
457: setbreak();
458: sspace(number(argv[1], SMVLSP, SDVLSP, 0, 1, unit(SMVLSP, SDVLSP)));
459: }
460:
461: /*
462: * Set space character size.
463: */
464: req_ss(argc, argv) int argc; char *argv[];
465: {
466: ssz = sszmul = number(argv[1], SMEMSP,
467: (ntroff == NROFF) ? SDEMSP : 36 * SDEMSP,
468: ssz, 0, ssz);
469: sszdiv = psz;
470: }
471:
472: /*
473: * Save vertical distance.
474: */
475: req_sv(argc, argv) int argc; char *argv[];
476: {
477: register int n;
478:
479: n = number(argv[1], SMVLSP, SDVLSP, 0, 0, unit(SMVLSP, SDVLSP));
480: if (mdivp->d_rpos+n > mdivp->d_ctpp->t_rpos)
481: svs = n;
482: else
483: sspace(n);
484: }
485:
486: /*
487: * Set tab stops.
488: */
489: req_ta(argc, argv) int argc; char *argv[];
490: {
491: register TAB *tp;
492: register int i;
493: register char *p;
494: int prevpos = 0;
495:
496: tp = &tab[1];
497: for (i=1; i<argc; i++) {
498: if (i > TABSIZE-2) {
499: printe("too many tab stops");
500: break;
501: }
502: p = argv[i];
503: if (*p == '\0') {
504: printe("bad tab stop");
505: break;
506: }
507: while (*p)
508: p++;
509: tp->t_jus = LJUS;
510: switch (*--p) {
511: case 'L':
512: tp->t_jus = LJUS;
513: *p = '\0';
514: break;
515: case 'C':
516: tp->t_jus = CJUS;
517: *p = '\0';
518: break;
519: case 'R':
520: tp->t_jus = RJUS;
521: *p = '\0';
522: break;
523: }
524: tp->t_pos = number(argv[i], SMEMSP, SDEMSP, prevpos, 0, 0);
525: if (tp->t_pos < prevpos) {
526: printe("bad tab stop");
527: break;
528: }
529: prevpos = tp->t_pos;
530: tp++;
531: }
532: tp->t_jus = '\0';
533: }
534:
535: /*
536: * Set tab character.
537: */
538: req_tc(argc, argv) int argc; char *argv[];
539: {
540: register int n;
541:
542: if (argc < 1) {
543: tbc = '\0';
544: return;
545: }
546: tbc = argv[1][0];
547: tfn = curfont;
548: if (argc > 2)
549: tbs = number(argv[2], SMEMSP, SDEMSP, tbs, 0, tbs);
550: if (argc > 3 && (n = font_number(argv[3], ".tc: ")) >= 0)
551: tfn = n;
552: }
553:
554: /*
555: * Temporary indent.
556: */
557: req_ti(argc, argv) int argc; char *argv[];
558: {
559: setbreak();
560: tin = number(argv[1], SMEMSP, SDEMSP, ind, 0, 0);
561: tif = 1;
562: }
563:
564: /*
565: * Three part title.
566: */
567: req_tl(argc, argv) int argc; char *argv[];
568: {
569: CODE *cp;
570: int i;
571: register int n;
572: char charbuf[CBFSIZE], endc, c;
573: register char *bp, *lp;
574:
575: envsave(ENVTITLE);
576: setline();
577: ind = 0;
578: lln = tln;
579: fill = 0;
580: setfont("R", 1);
581: bp = nextarg(miscbuf, NULL, 0);
582: if ((endc = *bp) != '\0')
583: bp++;
584: for (i=0; i<3; i++) {
585: lp = charbuf;
586: for (;;) {
587: if (*bp == '\0')
588: break;
589: if ((c = *bp++) == endc)
590: break;
591: if (c == tpc) {
592: char digits[5];
593: register char *dp = &digits[0];
594: register int pn = pno;
595:
596: for(; pn > 0; pn /= 10)
597: *dp++ = pn%10 + '0';
598: while (--dp > &digits[0])
599: *lp++ = *dp;
600: c = *dp;
601: }
602: if (lp >= &charbuf[CBFSIZE-2]) {
603: printe("section %d of title too large", i+1);
604: break;
605: }
606: *lp++ = c;
607: }
608: if (lp != charbuf) {
609: *lp = '\0';
610: adscore(charbuf);
611: strp->x1.s_eoff = 1;
612: process();
613: wordbreak(DHMOV);
614: }
615: switch (i) {
616: case 0:
617: n = llinsiz;
618: cp = llinptr;
619: break;
620: case 1:
621: n = (lln - llinsiz - n)/2;
622: nlinsiz = llinsiz += cp->l_arg.c_iarg = n;
623: cp = llinptr;
624: break;
625: case 2:
626: n = lln - llinsiz;
627: cp->l_arg.c_iarg += n;
628: llinsiz += n;
629: break;
630: }
631: }
632: linebreak(1);
633: envload(ENVTITLE);
634: }
635:
636: /*
637: * Print a message on the terminal.
638: */
639: req_tm(argc, argv) int argc; char *argv[];
640: {
641: fprintf(stderr, "%s\n", nextarg(miscbuf, NULL, 0));
642: }
643:
644: /*
645: * Translate on output.
646: */
647: req_tr(argc, argv) int argc; char *argv[];
648: {
649: register char c1, c2, *p;
650:
651: p = argv[1];
652: while (c1 = *p++) {
653: if ((c2 = *p++) == '\0') {
654: --p;
655: c2 = ' ';
656: }
657: if (!isascii(c1) || !isascii(c2)) /* Remove this! */
658: continue; /* $$TO_DO$$ */
659: if (c2 == ' ')
660: c2 = A_DEL; /* Or some other value? */
661: trantab[c1] = c2;
662: }
663: }
664:
665: /*
666: * Set underline font.
667: */
668: req_uf(argc, argv) int argc; char *argv[];
669: {
670: register int n;
671: char *name;
672:
673: name = (argc < 1) ? "I" : argv[1];
674: if ((n = font_number(name, ".uf: ")) >= 0)
675: ufn = n;
676: }
677:
678: /*
679: * Underline.
680: */
681: req_ul(argc, argv) int argc; char *argv[];
682: {
683: register int n;
684:
685: n = number(argv[1], SMUNIT, SDUNIT, 0, 0, 1);
686: if (n != 0) {
687: ufp = curfont; /* save current font */
688: setfontnum(ufn, 0); /* set underline font */
689: } else if (ulc != 0)
690: setfontnum(ufp, 1); /* restore previous font */
691: ulc = n; /* set underline count */
692: }
693:
694: /*
695: * Set vertical base line spacing.
696: */
697: req_vs(argc, argv) int argc; char *argv[];
698: {
699: setval(&vls, &oldvls, argv[1], SMPOIN, SDPOIN);
700: }
701:
702: /*
703: * Set a trap.
704: */
705: req_wh(argc, argv) int argc; char *argv[];
706: {
707: register TPL **tpp, *tp;
708: TPL *in;
709: register DIV *dp;
710: int rpos, apos;
711:
712: rpos = numb(argv[1], SMVLSP, SDVLSP);
713: apos = rpos>=0 ? rpos : pgl+rpos;
714: dp = mdivp;
715: for (tpp = &dp->d_stpl; tp = *tpp; tpp = &tp->t_next) {
716: if (apos == tp->t_apos) {
717: if (dp->d_trap == tp)
718: dp->d_trap = tp->t_next;
719: if (dp->d_ctpp == tp)
720: dp->d_ctpp = tp->t_next;
721: *tpp = tp->t_next;
722: nfree(tp);
723: if (argc < 3) /* .wh NN xx !replaces all at NN */
724: break; /* .wh NN !only removes 1st */
725: } else if (apos < tp->t_apos)
726: break;
727: }
728: if (argc >= 3) {
729: tp = (TPL *)nalloc(sizeof (TPL));
730: tp->t_rpos = rpos;
731: tp->t_apos = apos;
732: argname(argv[2], tp->t_name);
733:
734: if ((dp->d_stpl == NULL) || (dp->d_stpl->t_apos > apos)) {
735: tp->t_next = dp->d_stpl;
736: dp->d_stpl = tp;
737: }
738: else { in = dp->d_stpl;
739: while (in->t_next)
740: if (in->t_next->t_apos > apos)
741: break;
742: else
743: in = in->t_next;
744: tp->t_next = in->t_next;
745: in->t_next = tp;
746: }
747:
748: if (dp->d_trap==tp->t_next && apos>=0)
749: dp->d_trap = tp;
750: if (dp->d_ctpp==tp->t_next && apos>=dp->d_rpos)
751: dp->d_ctpp = tp;
752: }
753: }
754:
755: /* end of req2.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.