|
|
1.1 root 1: /*
2: * req1.c
3: * Nroff/Troff.
4: * Requests (a-m).
5: */
6:
7: #include <ctype.h>
8: #include "roff.h"
9:
10: /*
11: * User abort.
12: */
13: req_ab()
14: {
15: register char *bp;
16:
17: bp = nextarg(miscbuf, NULL, 0);
18: if (*bp != '\0')
19: fprintf(stderr, "%s\n", bp);
20: else
21: fprintf(stderr, "User abort\n");
22: leave(1);
23: }
24:
25: /*
26: * Turn adjust mode on and set adjust type.
27: */
28: req_ad(argc, argv) int argc; char *argv[];
29: {
30: adm = 1;
31: if (argc < 2)
32: return;
33: switch (argv[1][0]) {
34: case 'l':
35: adj = LJUS;
36: return;
37: case 'c':
38: adj = CJUS;
39: return;
40: case 'r':
41: adj = RJUS;
42: return;
43: case 'b':
44: case 'u':
45: adj = FJUS;
46: return;
47: default:
48: printe("bad adjustment type");
49: return;
50: }
51: }
52:
53: /*
54: * Assign format.
55: */
56: req_af(argc, argv) int argc; char *argv[];
57: {
58: register REG *rp;
59: int n;
60: char name[2];
61: register char *p, c;
62:
63: argname(argv[1], name);
64: rp = getnreg(name);
65: if (index("iIaA", c=argv[2][0])) {
66: rp->n_reg.r_form = c;
67: return;
68: }
69: if (isascii(c) && isdigit(c)) {
70: n = '0';
71: p = &argv[2][1];
72: while (isascii(c = *p++) && isdigit(*p))
73: ;
74: if (p-argv[2] > 9) {
75: printe("field with too large");
76: return;
77: }
78: rp->n_reg.r_form = '0' + p-argv[2];
79: }
80: }
81:
82: /*
83: * Append to macro.
84: */
85: req_am(argc, argv) int argc; char *argv[];
86: {
87: register REG *rp;
88: register MAC *mp;
89: char name[2];
90:
91: argname(argv[1], name);
92: if ((rp=findreg(name, RTEXT)) == NULL) {
93: rp = makereg(name, RTEXT);
94: mp = &rp->t_reg.r_macd;
95: } else {
96: for (mp = &rp->t_reg.r_macd;
97: mp->t_div.m_next;
98: mp=mp->t_div.m_next)
99: ;
100: mp->t_div.m_next = (MAC *)nalloc(sizeof (*mp));
101: mp = mp->t_div.m_next;
102: }
103: deftext(mp, argv[2]);
104: }
105:
106: /*
107: * Append to string.
108: */
109: req_as(argc, argv) int argc; char *argv[];
110: {
111: register REG *rp;
112: register MAC *mp;
113: char name[2];
114: register char *cp;
115:
116: argname(argv[1], name);
117: if ((rp=findreg(name, RTEXT)) == NULL) {
118: rp = makereg(name, RTEXT);
119: mp = &rp->t_reg.r_macd;
120: } else {
121: for (mp = &rp->t_reg.r_macd; mp->t_div.m_next; mp=mp->t_div.m_next)
122: ;
123: mp->t_div.m_next = (MAC *)nalloc(sizeof *mp);
124: mp = mp->t_div.m_next;
125: }
126: cp = nalloc(strlen(argv[2]) + 1);
127: strcpy(cp, argv[2]);
128: mp->t_div.m_next = NULL;
129: mp->t_div.m_type = MTEXT;
130: mp->t_div.m_core = cp;
131: }
132:
133: /*
134: * Embolden. (.bd) $$TO_DO$$
135: */
136: req_bd(argc, argv) int argc; char *argv[];
137: {
138: printu(".bd");
139: }
140:
141: /*
142: * Overstrike bold command.
143: * !V7.
144: */
145: req_bo(argc, argv) int argc; char *argv[];
146: {
147: if (argc == 1)
148: enb++;
149: else
150: enb = atoi(argv[1]);
151: }
152:
153: /*
154: * Begin page.
155: */
156: req_bp(argc, argv) int argc; char *argv[];
157: {
158: setbreak();
159: if (argc >= 2) {
160: npn = numb(argv[1], SMUNIT, SDUNIT);
161: pspace();
162: return;
163: }
164: if (nsm == 0)
165: pspace();
166: }
167:
168: /*
169: * Break.
170: */
171: req_br()
172: {
173: setbreak();
174: }
175:
176: /*
177: * Set nobreak control character.
178: */
179: req_c2(argc, argv) int argc; char *argv[];
180: {
181: nbc = argc>1 ? argv[1][0] : '\'';
182: }
183:
184: /*
185: * Set control character.
186: */
187: req_cc(argc, argv) int argc; char *argv[];
188: {
189: ccc = argc>1 ? argv[1][0] : '.';
190: }
191:
192: /*
193: * Center all text.
194: */
195: req_ce(argc, argv) int argc; char *argv[];
196: {
197: setbreak();
198: cec = number(argv[1], SMUNIT, SDUNIT, 0, 0, 1);
199: }
200:
201: /*
202: * Change trap location.
203: */
204: req_ch(argc, argv) int argc; char *argv[];
205: {
206: register TPL **tpp, *tp;
207: register DIV *dp;
208: int rpos, apos;
209: char name[2];
210:
211: dp = mdivp;
212: argname(argv[1], name);
213: for (tpp = &dp->d_stpl; tp = *tpp; tpp = &tp->t_next) {
214: if (name[0]==tp->t_name[0] && name[1]==tp->t_name[1]) {
215: if (dp->d_trap == tp)
216: dp->d_trap = tp->t_next;
217: if (dp->d_ctpp == tp)
218: dp->d_ctpp = tp->t_next;
219: *tpp = tp->t_next;
220: nfree(tp);
221: break;
222: }
223: }
224: if (argc >= 3) {
225: rpos = numb(argv[2], SMVLSP, SDVLSP);
226: apos = rpos>=0 ? rpos : pgl+rpos;
227: for (tpp = &dp->d_stpl; tp = *tpp; tpp = &tp->t_next) {
228: if (apos <= tp->t_apos)
229: break;
230: }
231: tp = (TPL *)nalloc(sizeof (TPL));
232: tp->t_rpos = rpos;
233: tp->t_apos = apos;
234: tp->t_name[0] = name[0];
235: tp->t_name[1] = name[1];
236: tp->t_next = *tpp;
237: *tpp = tp;
238: if (dp->d_trap==tp->t_next && apos>=0)
239: dp->d_trap = tp;
240: if (dp->d_ctpp==tp->t_next && apos>=dp->d_rpos)
241: dp->d_ctpp = tp;
242: }
243: }
244:
245: /*
246: * Copy input verbatim to output.
247: * !V7.
248: * Added by steve 12/21/90, usage modified 6/19/91.
249: */
250: req_co(argc, argv) int argc; char *argv[];
251: {
252: register char *cp, *endmark;
253: register int c, i;
254: char *cp1;
255:
256: putchar('\n');
257: for (i = 1; i < argc; i++)
258: printf("%d ", number(argv[i], SMUNIT, SDUNIT, 0, 0, 0));
259: cp = endmark = ".co";
260: while ((c = getl(1)) != EOF) {
261: if (c == *cp) { /* match next endmark char */
262: cp++;
263: continue;
264: } else if (c == '\n' && *cp == '\0')
265: return; /* matched endmark, done */
266: for (cp1 = endmark; cp1 < cp; )
267: putchar(*cp1++); /* copy matched portion */
268: putchar(c); /* copy this character */
269: cp = endmark; /* try again from start */
270: }
271: printe(".co: unexpected EOF before %s", endmark);
272: }
273:
274: /*
275: * Set constant character space mode.
276: */
277: req_cs(argc, argv) int argc; char *argv[];
278: {
279: char name[2];
280: register int n, ems;
281:
282: argname(argv[1], name);
283: if ((n = font_number(name, ".cs: ")) < 0)
284: return;
285: ems = number(argv[3], SMPOIN, SDPOIN, 0, 0, unit(SMEMSP, SDEMSP));
286: dev_cs(n, numb(argv[2], (long)ems, 36L));
287: }
288:
289: /*
290: * Continous underline.
291: * This just does a .ul.
292: * This is wrong, .cu is supposed to underline spaces as well as words.
293: */
294: req_cu(argc, argv) int argc; char *argv[];
295: {
296: req_ul(argc, argv);
297: }
298:
299: /*
300: * Divert and append output to macro.
301: */
302: req_da(argc, argv) int argc; char *argv[];
303: {
304: register REG *rp;
305: register MAC *mp;
306: char name[2];
307:
308: if (argc < 2) {
309: enddivn();
310: return;
311: }
312: argname(argv[1], name);
313: newdivn(name);
314: if ((rp=findreg(name, RTEXT)) == NULL) {
315: rp = makereg(name, RTEXT);
316: cdivp->d_seek = tmpseek;
317: mp = &rp->t_reg.r_macd;
318: mp->t_div.m_next = NULL;
319: } else {
320: cdivp->d_maxh = rp->t_reg.r_maxh;
321: cdivp->d_maxw = rp->t_reg.r_maxw;
322: for (mp = &rp->t_reg.r_macd; mp->t_div.m_next; mp=mp->t_div.m_next)
323: ;
324: }
325: mp->t_div.m_type = MDIVN;
326: mp->t_div.m_size = 0;
327: mp->t_div.m_core = NULL;
328: mp->t_div.m_seek = tmpseek;
329: cdivp->d_macp = mp;
330: }
331:
332: /*
333: * Define a special character.
334: * Added by steve 4/16/91.
335: */
336: req_dc(argc, argv) int argc; char *argv[];
337: {
338: char name[2];
339:
340: argname(argv[1], name);
341: spc_def(name, (argc < 3) ? "" : argv[2]);
342: }
343:
344: /*
345: * Define a macro.
346: */
347: req_de(argc, argv) int argc; char *argv[];
348: {
349: register REG *rp;
350: char name[2];
351:
352: argname(argv[1], name);
353: rp = makereg(name, RTEXT);
354: deftext(&rp->t_reg.r_macd, argv[2]);
355: }
356:
357: /*
358: * Divert output to macro.
359: */
360: req_di(argc, argv) int argc; char *argv[];
361: {
362: register REG *rp;
363: char name[2];
364:
365: if (argc < 2) {
366: enddivn();
367: return;
368: }
369: argname(argv[1], name);
370: newdivn(name);
371: rp = makereg(name, RTEXT);
372: cdivp->d_macp = &rp->t_reg.r_macd;
373: cdivp->d_seek = tmpseek;
374: rp->t_reg.r_macd.t_div.m_next = NULL;
375: rp->t_reg.r_macd.t_div.m_type = MDIVN;
376: rp->t_reg.r_macd.t_div.m_size = 0;
377: rp->t_reg.r_macd.t_div.m_core = NULL;
378: rp->t_reg.r_macd.t_div.m_seek = tmpseek;
379: }
380:
381: /*
382: * Define a string.
383: */
384: req_ds(argc, argv) int argc; char *argv[];
385: {
386: register REG *rp;
387: char name[2];
388: register char *cp;
389:
390: argname(argv[1], name);
391: rp = makereg(name, RTEXT);
392: cp = nalloc(strlen(argv[2]) + 1);
393: strcpy(cp, argv[2]);
394: rp->t_reg.r_macd.t_div.m_next = NULL;
395: rp->t_reg.r_macd.t_div.m_type = MTEXT;
396: rp->t_reg.r_macd.t_div.m_core = cp;
397: }
398:
399: /*
400: * Set a diversion trap. (.dt) $$TO_DO$$
401: */
402: req_dt(argc, argv) int argc; char *argv[];
403: {
404: printu(".dt");
405: }
406:
407: /*
408: * Set escape character.
409: */
410: req_ec(argc, argv) int argc; char *argv[];
411: {
412: esc = argc>1 ? argv[1][0] : '\\';
413: }
414:
415: /*
416: * Else part of if-else.
417: */
418: req_el(argc, argv) int argc; char *argv[];
419: {
420: if (iestackx < 0) {
421: printe(".el without .ie");
422: return;
423: }
424: do_cond(!iestack[iestackx--], nextarg(miscbuf, NULL, 0));
425: }
426:
427: /*
428: * Set end macro.
429: */
430: req_em(argc, argv) int argc; char *argv[];
431: {
432: argname(argv[1], endtrap);
433: }
434:
435: /*
436: * Turn off escape mechanism.
437: */
438: req_eo()
439: {
440: esc = '\0';
441: }
442:
443: /*
444: * Change environments.
445: */
446: req_ev(argc, argv) int argc; char *argv[];
447: {
448: register int old, new;
449:
450: if (argc < 2) {
451: dprintd(DBGENVR, "pop environment\n");
452: if (envs == 0) {
453: printe("cannot pop environment");
454: return;
455: }
456: old = envstak[envs];
457: new = envstak[--envs];
458: } else {
459: new = numb(argv[1], SMUNIT, SDUNIT);
460: dprint2(DBGENVR, "push environment %d\n", new);
461: if (new < 0 || new >= ENVS) {
462: printe("environment does not exist");
463: return;
464: }
465: if (envs >= ENVSTACK) {
466: printe("environments stacked too deeply");
467: return;
468: }
469: old = envstak[envs];
470: envstak[++envs] = new;
471: }
472: dprint2(DBGENVR|DBGFILE, "writing environment %d\n", old);
473: envsave(old);
474: if (envinit[new] == 0) {
475: dprint2(DBGENVR, "initializing env %d\n", new);
476: envset();
477: envinit[new] = 1;
478: setfont("R", 1);
479: } else {
480: dprint2(DBGENVR|DBGFILE, "reading environment %d\n", new);
481: envload(new);
482: }
483: }
484:
485: /*
486: * Exit from nroff.
487: */
488: req_ex()
489: {
490: leave(0);
491: }
492:
493: /*
494: * Flush the buffers (used for transparent flushing...)
495: * !V7.
496: */
497: req_fb()
498: {
499: flushl(linebuf, llinptr); /* Flush the buffer... */
500: llinptr = linebuf; /* Reset the buffer... */
501: }
502:
503: /*
504: * Set field delimiter and pad character. (.fc) $$TO_DO$$
505: */
506: req_fc(argc, argv) int argc; char *argv[];
507: {
508: printu(".fc");
509: }
510:
511: /*
512: * Display a list of fonts to standard error.
513: * !V7.
514: */
515: req_fd()
516: {
517: font_display();
518: }
519:
520: /*
521: * Turn on fill mode.
522: */
523: req_fi()
524: {
525: setbreak();
526: fill = 1;
527: }
528:
529: /*
530: * Flush.
531: */
532: req_fl()
533: {
534: setbreak();
535: }
536:
537: /*
538: * Define font at position.
539: */
540: req_fp(argc, argv) int argc; char *argv[];
541: {
542: register int n;
543:
544: n = argv[1][0] - '0';
545: if ((1 <= n) && (n <= 9)) {
546: mapfont[n][0] = argv[2][0];
547: mapfont[n][1] = argv[2][1];
548: } else
549: printe("font position out of range");
550:
551: }
552:
553: /*
554: * Set current font.
555: */
556: req_ft(argc, argv) int argc; char *argv[];
557: {
558: char name[2];
559:
560: argname(argv[1], name);
561: setfont(name, 1);
562: }
563:
564: /*
565: * Force font size.
566: */
567: req_fz(argc, argv) int argc; char *argv[];
568: {
569: if (argc != 3)
570: printe(".fz: requires font name and size");
571: else
572: dev_fz(argv[1], argv[2]);
573: }
574:
575: /*
576: * Hyphenation mode. (.hc) $$TO_DO$$
577: */
578: req_hc(argc, argv) int argc; char *argv[];
579: {
580: printu(".hc");
581: }
582:
583: /*
584: * Hyphenation indicator character. (.hw) $$TO_DO$$
585: */
586: req_hw(argc, argv) int argc; char *argv[];
587: {
588: printu(".hw");
589: }
590:
591: /*
592: * Hyphenation exception words. (.hy) $$TO_DO$$
593: */
594: req_hy(argc, argv) int argc; char *argv[];
595: {
596: printu(".hy");
597: }
598:
599: /*
600: * If part of if-else.
601: */
602: req_ie(argc, argv) int argc; char *argv[];
603: {
604: if (iestackx >= IESTACKSIZE-1)
605: printe(".ie nested more than %d levels", IESTACKSIZE);
606: else
607: iestack[++iestackx] = req_if(argc, argv);
608: }
609:
610: /*
611: * If (conditional execution of command).
612: * This returns the condition and is called from 'req_ie'.
613: */
614: req_if()
615: {
616: int not, con;
617: unsigned char charbuf[CBFSIZE];
618: register int c;
619: register unsigned char *bp, *cp, *cp1, *cp2;
620:
621: bp = (unsigned char *)nextarg(miscbuf, NULL, 0);
622:
623: /* Look for leading '!'. */
624: if (*bp == '!') {
625: bp++;
626: not = 1;
627: } else
628: not = 0;
629:
630: /* Look for built-ins. */
631: switch (*bp++) {
632: case 'e': /* Current page number is even. */
633: con = !(pno % 2);
634: break;
635: case 'l':
636: con = lflag; /* Landscape mode. */
637: break;
638: case 'n': /* Formatter is Nroff. */
639: con = (ntroff == NROFF);
640: break;
641: case 'o': /* Current page number is odd. */
642: con = pno % 2;
643: break;
644: case 'p':
645: con = pflag; /* PostScript mode. */
646: break;
647: case 't': /* Formatter is Troff. */
648: con = (ntroff == TROFF);
649: break;
650: default:
651: c = *--bp; /* first character */
652: if ((isascii(c) && isdigit(c)) || c == '(' || c == '+' || c == '-') {
653: /* Numeric expression. */
654: bp = (unsigned char *)nextarg(bp, charbuf, CBFSIZE);
655: con = numb(charbuf, SMUNIT, SDUNIT) != 0;
656: break;
657: }
658:
659: /* String comparison. */
660: con = 0;
661: if (c == '\0')
662: break;
663: cp1 = ++bp; /* start of first string */
664: if ((cp = index(cp1, c)) == NULL)
665: break;
666: cp2 = ++cp; /* start of second string */
667: if ((cp = index(cp2, c)) == NULL)
668: break;
669: bp = cp + 1; /* bp points after third c */
670: if (cp - cp2 != (cp2-1) - cp1)
671: break; /* lengths differ, unequal */
672: con = strncmp(cp1, cp2, cp - cp2) == 0; /* compare strings */
673: }
674: if (not)
675: con = !con;
676: do_cond(con, bp);
677: return con;
678: }
679:
680: /*
681: * Ignore.
682: */
683: req_ig(argc, argv) int argc; char *argv[];
684: {
685: deftext(NULL, argv[1]);
686: }
687:
688: /*
689: * Set indent.
690: */
691: req_in(argc, argv) int argc; char *argv[];
692: {
693: setval(&ind, &oldind, argv[1], SMEMSP, SDEMSP);
694: setbreak();
695: }
696:
697:
698: /*
699: * Set an input line count trap.
700: */
701: req_it(argc, argv) int argc; char *argv[];
702: {
703: if (argc < 3) {
704: inpltrc = 0;
705: return;
706: }
707: inpltrc = numb(argv[1], SMUNIT, SDUNIT);
708: argname(argv[2], inptrap);
709: }
710:
711: /*
712: * Leader repetition character.
713: */
714: req_lc(argc, argv) int argc; char *argv[];
715: {
716: ldc = (argc < 1) ? '\0' : argv[1][0];
717: }
718:
719: /*
720: * Load a font width table.
721: * !V7.
722: * Added by steve 12/12/90.
723: */
724: req_lf(argc, argv) int argc; char *argv[];
725: {
726: if (argc < 3) {
727: printe(".lf: requires fontname and filename");
728: return;
729: }
730: load_font(argv[1], argv[2]);
731: if (argc == 4)
732: dev_fz(argv[1], argv[3]);
733: }
734:
735: /*
736: * Set ligature mode.
737: */
738: req_lg(argc, argv) int argc; char *argv[];
739: {
740: lgm = numb(argv[1], SMUNIT, SDUNIT) > 0;
741: }
742:
743: /*
744: * Set line length.
745: */
746: req_ll(argc, argv) int argc; char *argv[];
747: {
748: setval(&lln, &oldlln, argv[1], SMEMSP, SDEMSP);
749: }
750:
751: /*
752: * Set line spacing.
753: */
754: req_ls(argc, argv) int argc; char *argv[];
755: {
756: setval(&lsp, &oldlsp, argv[1], SMUNIT, SDUNIT);
757: }
758:
759: /*
760: * Set title length.
761: */
762: req_lt(argc, argv) int argc; char *argv[];
763: {
764: setval(&tln, &oldtln, argv[1], SMEMSP, SDEMSP);
765: }
766:
767: /*
768: * Set margin character.
769: */
770: req_mc(argc, argv) int argc; char *argv[];
771: {
772: if (argc < 2) {
773: mrc = '\0';
774: } else {
775: mrc = argv[1][0];
776: #ifdef mfn
777: /* Margin font number (if required later...) */
778: mfn = curfont;
779: #endif
780: }
781: if (argc > 2)
782: mar = number(argv[2], SMEMSP, SDEMSP, mar, 0, 0);
783: }
784:
785: /*
786: * Mark vertical place internally in diversion or in number register.
787: */
788: req_mk(argc, argv) int argc; char *argv[];
789: {
790: register REG *rp;
791: char name[2];
792:
793: if (argc == 1) {
794: cdivp->d_mk = cdivp->d_rpos;
795: return;
796: }
797: argname(argv[1], name);
798: if ((rp=findreg(name, RNUMR)) == NULL) {
799: rp = makereg(name, RNUMR);
800: rp->n_reg.r_incr = 1;
801: rp->n_reg.r_form = '1';
802: }
803: rp->n_reg.r_nval = cdivp->d_rpos;
804: }
805:
806: /* end of req1.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.