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