1*08e9b19aSmillert /* $OpenBSD: deroff.c,v 1.18 2023/09/27 21:06:33 millert Exp $ */
225a69cdcSmillert
325a69cdcSmillert /*-
425a69cdcSmillert * Copyright (c) 1988, 1993
525a69cdcSmillert * The Regents of the University of California. All rights reserved.
625a69cdcSmillert *
725a69cdcSmillert * Redistribution and use in source and binary forms, with or without
825a69cdcSmillert * modification, are permitted provided that the following conditions
925a69cdcSmillert * are met:
1025a69cdcSmillert * 1. Redistributions of source code must retain the above copyright
1125a69cdcSmillert * notice, this list of conditions and the following disclaimer.
1225a69cdcSmillert * 2. Redistributions in binary form must reproduce the above copyright
1325a69cdcSmillert * notice, this list of conditions and the following disclaimer in the
1425a69cdcSmillert * documentation and/or other materials provided with the distribution.
15f75387cbSmillert * 3. Neither the name of the University nor the names of its contributors
1625a69cdcSmillert * may be used to endorse or promote products derived from this software
1725a69cdcSmillert * without specific prior written permission.
1825a69cdcSmillert *
1925a69cdcSmillert * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2025a69cdcSmillert * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2125a69cdcSmillert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2225a69cdcSmillert * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2325a69cdcSmillert * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2425a69cdcSmillert * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2525a69cdcSmillert * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2625a69cdcSmillert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2725a69cdcSmillert * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2825a69cdcSmillert * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2925a69cdcSmillert * SUCH DAMAGE.
3025a69cdcSmillert */
3125a69cdcSmillert /*
3225a69cdcSmillert * Copyright (C) Caldera International Inc. 2001-2002.
3325a69cdcSmillert * All rights reserved.
3425a69cdcSmillert *
3525a69cdcSmillert * Redistribution and use in source and binary forms, with or without
3625a69cdcSmillert * modification, are permitted provided that the following conditions
3725a69cdcSmillert * are met:
3825a69cdcSmillert * 1. Redistributions of source code and documentation must retain the above
3925a69cdcSmillert * copyright notice, this list of conditions and the following disclaimer.
4025a69cdcSmillert * 2. Redistributions in binary form must reproduce the above copyright
4125a69cdcSmillert * notice, this list of conditions and the following disclaimer in the
4225a69cdcSmillert * documentation and/or other materials provided with the distribution.
4325a69cdcSmillert * 3. All advertising materials mentioning features or use of this software
4425a69cdcSmillert * must display the following acknowledgement:
4525a69cdcSmillert * This product includes software developed or owned by Caldera
4625a69cdcSmillert * International, Inc.
4725a69cdcSmillert * 4. Neither the name of Caldera International, Inc. nor the names of other
4825a69cdcSmillert * contributors may be used to endorse or promote products derived from
4925a69cdcSmillert * this software without specific prior written permission.
5025a69cdcSmillert *
5125a69cdcSmillert * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
5225a69cdcSmillert * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
5325a69cdcSmillert * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
5425a69cdcSmillert * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
5525a69cdcSmillert * IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT,
5625a69cdcSmillert * INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5725a69cdcSmillert * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
5825a69cdcSmillert * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5925a69cdcSmillert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
6025a69cdcSmillert * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
6125a69cdcSmillert * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
6225a69cdcSmillert * POSSIBILITY OF SUCH DAMAGE.
6325a69cdcSmillert */
6425a69cdcSmillert
6525a69cdcSmillert #include <err.h>
6625a69cdcSmillert #include <limits.h>
6725a69cdcSmillert #include <stdio.h>
6825a69cdcSmillert #include <stdlib.h>
6925a69cdcSmillert #include <string.h>
7025a69cdcSmillert #include <unistd.h>
7125a69cdcSmillert
7225a69cdcSmillert /*
7325a69cdcSmillert * Deroff command -- strip troff, eqn, and Tbl sequences from
7425a69cdcSmillert * a file. Has two flags argument, -w, to cause output one word per line
7525a69cdcSmillert * rather than in the original format.
7625a69cdcSmillert * -mm (or -ms) causes the corresponding macro's to be interpreted
7725a69cdcSmillert * so that just sentences are output
7825a69cdcSmillert * -ml also gets rid of lists.
7925a69cdcSmillert * Deroff follows .so and .nx commands, removes contents of macro
8025a69cdcSmillert * definitions, equations (both .EQ ... .EN and $...$),
8125a69cdcSmillert * Tbl command sequences, and Troff backslash constructions.
8225a69cdcSmillert *
8325a69cdcSmillert * All input is through the Cget macro;
8425a69cdcSmillert * the most recently read character is in c.
8525a69cdcSmillert *
8625a69cdcSmillert * Modified by Robert Henry to process -me and -man macros.
8725a69cdcSmillert */
8825a69cdcSmillert
8925a69cdcSmillert #define Cget ( (c=getc(infile)) == EOF ? eof() : ((c==ldelim)&&(filesp==files) ? skeqn() : c) )
9025a69cdcSmillert #define C1get ( (c=getc(infile)) == EOF ? eof() : c)
9125a69cdcSmillert
9225a69cdcSmillert #ifdef DEBUG
9325a69cdcSmillert # define C _C()
9425a69cdcSmillert # define C1 _C1()
95dc955345Sdanh #else /* not DEBUG */
9625a69cdcSmillert # define C Cget
9725a69cdcSmillert # define C1 C1get
98dc955345Sdanh #endif /* not DEBUG */
9925a69cdcSmillert
10025a69cdcSmillert #define SKIP while (C != '\n')
10125a69cdcSmillert #define SKIP_TO_COM SKIP; SKIP; pc=c; while (C != '.' || pc != '\n' || C > 'Z')pc=c
10225a69cdcSmillert
10325a69cdcSmillert #define YES 1
10425a69cdcSmillert #define NO 0
10525a69cdcSmillert #define MS 0 /* -ms */
10625a69cdcSmillert #define MM 1 /* -mm */
10725a69cdcSmillert #define ME 2 /* -me */
10825a69cdcSmillert #define MA 3 /* -man */
10925a69cdcSmillert
11025a69cdcSmillert #ifdef DEBUG
11125a69cdcSmillert char *mactab[] = { "-ms", "-mm", "-me", "-ma" };
112dc955345Sdanh #endif /* DEBUG */
11325a69cdcSmillert
11425a69cdcSmillert #define ONE 1
11525a69cdcSmillert #define TWO 2
11625a69cdcSmillert
11725a69cdcSmillert #define NOCHAR -2
11825a69cdcSmillert #define SPECIAL 0
11925a69cdcSmillert #define APOS 1
12025a69cdcSmillert #define PUNCT 2
12125a69cdcSmillert #define DIGIT 3
12225a69cdcSmillert #define LETTER 4
12325a69cdcSmillert
12425a69cdcSmillert #define MAXFILES 20
12525a69cdcSmillert
12625a69cdcSmillert int iflag;
12725a69cdcSmillert int wordflag;
12825a69cdcSmillert int msflag; /* processing a source written using a mac package */
12925a69cdcSmillert int mac; /* which package */
13025a69cdcSmillert int disp;
13125a69cdcSmillert int parag;
13225a69cdcSmillert int inmacro;
13325a69cdcSmillert int intable;
13425a69cdcSmillert int keepblock; /* keep blocks of text; normally false when msflag */
13525a69cdcSmillert
13625a69cdcSmillert char chars[128]; /* SPECIAL, PUNCT, APOS, DIGIT, or LETTER */
13725a69cdcSmillert
138*08e9b19aSmillert size_t linesz;
139*08e9b19aSmillert char *line;
14025a69cdcSmillert char *lp;
14125a69cdcSmillert
14225a69cdcSmillert int c;
14325a69cdcSmillert int pc;
14425a69cdcSmillert int ldelim;
14525a69cdcSmillert int rdelim;
14625a69cdcSmillert
14725a69cdcSmillert char fname[PATH_MAX];
14825a69cdcSmillert FILE *files[MAXFILES];
14925a69cdcSmillert FILE **filesp;
15025a69cdcSmillert FILE *infile;
15125a69cdcSmillert
15225a69cdcSmillert int argc;
15325a69cdcSmillert char **argv;
15425a69cdcSmillert
15525a69cdcSmillert /*
15625a69cdcSmillert * Macro processing
15725a69cdcSmillert *
15825a69cdcSmillert * Macro table definitions
15925a69cdcSmillert */
16025a69cdcSmillert typedef int pacmac; /* compressed macro name */
16125a69cdcSmillert int argconcat = 0; /* concat arguments together (-me only) */
16225a69cdcSmillert
16325a69cdcSmillert #define tomac(c1, c2) ((((c1) & 0xFF) << 8) | ((c2) & 0xFF))
16425a69cdcSmillert #define frommac(src, c1, c2) (((c1)=((src)>>8)&0xFF),((c2) =(src)&0xFF))
16525a69cdcSmillert
16625a69cdcSmillert struct mactab{
16725a69cdcSmillert int condition;
16825a69cdcSmillert pacmac macname;
16925a69cdcSmillert int (*func)(); /* XXX - args */
17025a69cdcSmillert };
17125a69cdcSmillert
17225a69cdcSmillert struct mactab troffmactab[];
17325a69cdcSmillert struct mactab ppmactab[];
17425a69cdcSmillert struct mactab msmactab[];
17525a69cdcSmillert struct mactab mmmactab[];
17625a69cdcSmillert struct mactab memactab[];
17725a69cdcSmillert struct mactab manmactab[];
17825a69cdcSmillert
17925a69cdcSmillert /*
18025a69cdcSmillert * Macro table initialization
18125a69cdcSmillert */
18225a69cdcSmillert #define M(cond, c1, c2, func) {cond, tomac(c1, c2), func}
18325a69cdcSmillert
18425a69cdcSmillert /*
18525a69cdcSmillert * Flags for matching conditions other than
18625a69cdcSmillert * the macro name
18725a69cdcSmillert */
18825a69cdcSmillert #define NONE 0
18925a69cdcSmillert #define FNEST 1 /* no nested files */
19025a69cdcSmillert #define NOMAC 2 /* no macro */
19125a69cdcSmillert #define MAC 3 /* macro */
19225a69cdcSmillert #define PARAG 4 /* in a paragraph */
19325a69cdcSmillert #define MSF 5 /* msflag is on */
19425a69cdcSmillert #define NBLK 6 /* set if no blocks to be kept */
19525a69cdcSmillert
19625a69cdcSmillert /*
19725a69cdcSmillert * Return codes from macro minions, determine where to jump,
19825a69cdcSmillert * how to repeat/reprocess text
19925a69cdcSmillert */
20025a69cdcSmillert #define COMX 1 /* goto comx */
20125a69cdcSmillert #define COM 2 /* goto com */
20225a69cdcSmillert
20325a69cdcSmillert int skeqn(void);
20425a69cdcSmillert int eof(void);
20525a69cdcSmillert int _C1(void);
20625a69cdcSmillert int _C(void);
20725a69cdcSmillert int EQ(void);
20825a69cdcSmillert int domacro(void);
20925a69cdcSmillert int PS(void);
21025a69cdcSmillert int skip(void);
21125a69cdcSmillert int intbl(void);
21225a69cdcSmillert int outtbl(void);
21325a69cdcSmillert int so(void);
21425a69cdcSmillert int nx(void);
21525a69cdcSmillert int skiptocom(void);
21625a69cdcSmillert int PP(pacmac);
21725a69cdcSmillert int AU(void);
21825a69cdcSmillert int SH(pacmac);
21925a69cdcSmillert int UX(void);
22025a69cdcSmillert int MMHU(pacmac);
22125a69cdcSmillert int mesnblock(pacmac);
22225a69cdcSmillert int mssnblock(pacmac);
22325a69cdcSmillert int nf(void);
22425a69cdcSmillert int ce(void);
22525a69cdcSmillert int meip(pacmac);
22625a69cdcSmillert int mepp(pacmac);
22725a69cdcSmillert int mesh(pacmac);
22825a69cdcSmillert int mefont(pacmac);
22925a69cdcSmillert int manfont(pacmac);
23025a69cdcSmillert int manpp(pacmac);
23125a69cdcSmillert int macsort(const void *, const void *);
23225a69cdcSmillert int sizetab(struct mactab *);
23325a69cdcSmillert void getfname(void);
23425a69cdcSmillert void textline(char *, int);
23525a69cdcSmillert void work(void);
23625a69cdcSmillert void regline(void (*)(char *, int), int);
23725a69cdcSmillert void macro(void);
23825a69cdcSmillert void tbl(void);
23925a69cdcSmillert void stbl(void);
24025a69cdcSmillert void eqn(void);
24125a69cdcSmillert void backsl(void);
24225a69cdcSmillert void sce(void);
24325a69cdcSmillert void refer(int);
24425a69cdcSmillert void inpic(void);
24525a69cdcSmillert void msputmac(char *, int);
24625a69cdcSmillert void msputwords(int);
24725a69cdcSmillert void meputmac(char *, int);
24825a69cdcSmillert void meputwords(int);
24925a69cdcSmillert void noblock(char, char);
25025a69cdcSmillert void defcomline(pacmac);
25125a69cdcSmillert void comline(void);
25225a69cdcSmillert void buildtab(struct mactab **, int *);
25325a69cdcSmillert FILE *opn(char *);
25425a69cdcSmillert struct mactab *macfill(struct mactab *, struct mactab *);
25525a69cdcSmillert __dead void usage(void);
25625a69cdcSmillert
25725a69cdcSmillert int
main(int ac,char ** av)25825a69cdcSmillert main(int ac, char **av)
25925a69cdcSmillert {
26025a69cdcSmillert int i, ch;
26125a69cdcSmillert int errflg = 0;
26225a69cdcSmillert int kflag = NO;
26325a69cdcSmillert
2640bd1216cSderaadt if (pledge("stdio rpath", NULL) == -1)
2650bd1216cSderaadt err(1, "pledge");
266a3c3e8edSderaadt
26725a69cdcSmillert iflag = NO;
26825a69cdcSmillert wordflag = NO;
26925a69cdcSmillert msflag = NO;
27025a69cdcSmillert mac = ME;
27125a69cdcSmillert disp = NO;
27225a69cdcSmillert parag = NO;
27325a69cdcSmillert inmacro = NO;
27425a69cdcSmillert intable = NO;
27525a69cdcSmillert ldelim = NOCHAR;
27625a69cdcSmillert rdelim = NOCHAR;
27725a69cdcSmillert keepblock = YES;
27825a69cdcSmillert
27925a69cdcSmillert while ((ch = getopt(ac, av, "ikpwm:")) != -1) {
28025a69cdcSmillert switch (ch) {
28125a69cdcSmillert case 'i':
28225a69cdcSmillert iflag = YES;
28325a69cdcSmillert break;
28425a69cdcSmillert case 'k':
28525a69cdcSmillert kflag = YES;
28625a69cdcSmillert break;
28725a69cdcSmillert case 'm':
28825a69cdcSmillert msflag = YES;
28925a69cdcSmillert keepblock = NO;
29025a69cdcSmillert switch (optarg[0]) {
29125a69cdcSmillert case 'm':
29225a69cdcSmillert mac = MM;
29325a69cdcSmillert break;
29425a69cdcSmillert case 's':
29525a69cdcSmillert mac = MS;
29625a69cdcSmillert break;
29725a69cdcSmillert case 'e':
29825a69cdcSmillert mac = ME;
29925a69cdcSmillert break;
30025a69cdcSmillert case 'a':
30125a69cdcSmillert mac = MA;
30225a69cdcSmillert break;
30325a69cdcSmillert case 'l':
30425a69cdcSmillert disp = YES;
30525a69cdcSmillert break;
30625a69cdcSmillert default:
30783977142Stedu errflg = 1;
30825a69cdcSmillert break;
30925a69cdcSmillert }
31083977142Stedu if (optarg[1] != '\0')
31183977142Stedu errflg = 1;
31225a69cdcSmillert break;
31325a69cdcSmillert case 'p':
31425a69cdcSmillert parag = YES;
31525a69cdcSmillert break;
31625a69cdcSmillert case 'w':
31725a69cdcSmillert wordflag = YES;
31825a69cdcSmillert kflag = YES;
31925a69cdcSmillert break;
32025a69cdcSmillert default:
32183977142Stedu errflg = 1;
32225a69cdcSmillert }
32325a69cdcSmillert }
32425a69cdcSmillert argc = ac - optind;
32525a69cdcSmillert argv = av + optind;
32625a69cdcSmillert
32725a69cdcSmillert if (kflag)
32825a69cdcSmillert keepblock = YES;
32925a69cdcSmillert if (errflg)
33025a69cdcSmillert usage();
33125a69cdcSmillert
33225a69cdcSmillert #ifdef DEBUG
33325a69cdcSmillert printf("msflag = %d, mac = %s, keepblock = %d, disp = %d\n",
33425a69cdcSmillert msflag, mactab[mac], keepblock, disp);
335dc955345Sdanh #endif /* DEBUG */
33625a69cdcSmillert if (argc == 0) {
33725a69cdcSmillert infile = stdin;
33825a69cdcSmillert } else {
33925a69cdcSmillert infile = opn(argv[0]);
34025a69cdcSmillert --argc;
34125a69cdcSmillert ++argv;
34225a69cdcSmillert }
34325a69cdcSmillert files[0] = infile;
34425a69cdcSmillert filesp = &files[0];
34525a69cdcSmillert
346*08e9b19aSmillert linesz = LINE_MAX;
347*08e9b19aSmillert if ((line = malloc(linesz)) == NULL)
348*08e9b19aSmillert err(1, NULL);
349*08e9b19aSmillert
35025a69cdcSmillert for (i = 'a'; i <= 'z'; ++i)
35125a69cdcSmillert chars[i] = LETTER;
35225a69cdcSmillert for (i = 'A'; i <= 'Z'; ++i)
35325a69cdcSmillert chars[i] = LETTER;
35425a69cdcSmillert for (i = '0'; i <= '9'; ++i)
35525a69cdcSmillert chars[i] = DIGIT;
35625a69cdcSmillert chars['\''] = APOS;
35725a69cdcSmillert chars['&'] = APOS;
35825a69cdcSmillert chars['.'] = PUNCT;
35925a69cdcSmillert chars[','] = PUNCT;
36025a69cdcSmillert chars[';'] = PUNCT;
36125a69cdcSmillert chars['?'] = PUNCT;
36225a69cdcSmillert chars[':'] = PUNCT;
36325a69cdcSmillert work();
36425a69cdcSmillert exit(0);
36525a69cdcSmillert }
36625a69cdcSmillert
36725a69cdcSmillert int
skeqn(void)36825a69cdcSmillert skeqn(void)
36925a69cdcSmillert {
37025a69cdcSmillert
37125a69cdcSmillert while ((c = getc(infile)) != rdelim) {
37225a69cdcSmillert if (c == EOF)
37325a69cdcSmillert c = eof();
37425a69cdcSmillert else if (c == '"') {
37525a69cdcSmillert while ((c = getc(infile)) != '"') {
37625a69cdcSmillert if (c == EOF ||
37725a69cdcSmillert (c == '\\' && (c = getc(infile)) == EOF))
37825a69cdcSmillert c = eof();
37925a69cdcSmillert }
38025a69cdcSmillert }
38125a69cdcSmillert }
38225a69cdcSmillert if (msflag)
38325a69cdcSmillert return((c = 'x'));
38425a69cdcSmillert return((c = ' '));
38525a69cdcSmillert }
38625a69cdcSmillert
38725a69cdcSmillert FILE *
opn(char * p)38825a69cdcSmillert opn(char *p)
38925a69cdcSmillert {
39025a69cdcSmillert FILE *fd;
39125a69cdcSmillert
39225a69cdcSmillert if ((fd = fopen(p, "r")) == NULL)
39325a69cdcSmillert err(1, "fopen %s", p);
39425a69cdcSmillert
39525a69cdcSmillert return(fd);
39625a69cdcSmillert }
39725a69cdcSmillert
39825a69cdcSmillert int
eof(void)39925a69cdcSmillert eof(void)
40025a69cdcSmillert {
40125a69cdcSmillert
40225a69cdcSmillert if (infile != stdin)
40325a69cdcSmillert fclose(infile);
40425a69cdcSmillert if (filesp > files)
40525a69cdcSmillert infile = *--filesp;
40625a69cdcSmillert else if (argc > 0) {
40725a69cdcSmillert infile = opn(argv[0]);
40825a69cdcSmillert --argc;
40925a69cdcSmillert ++argv;
41025a69cdcSmillert } else
41125a69cdcSmillert exit(0);
41225a69cdcSmillert return(C);
41325a69cdcSmillert }
41425a69cdcSmillert
41525a69cdcSmillert void
getfname(void)41625a69cdcSmillert getfname(void)
41725a69cdcSmillert {
41825a69cdcSmillert char *p;
41925a69cdcSmillert struct chain {
42025a69cdcSmillert struct chain *nextp;
42125a69cdcSmillert char *datap;
42225a69cdcSmillert } *q;
42325a69cdcSmillert static struct chain *namechain= NULL;
42425a69cdcSmillert
42525a69cdcSmillert while (C == ' ')
42625a69cdcSmillert ; /* nothing */
42725a69cdcSmillert
42825a69cdcSmillert for (p = fname ; p - fname < sizeof(fname) && (*p = c) != '\n' &&
42925a69cdcSmillert c != ' ' && c != '\t' && c != '\\'; ++p)
43025a69cdcSmillert C;
43125a69cdcSmillert *p = '\0';
43225a69cdcSmillert while (c != '\n')
43325a69cdcSmillert C;
43425a69cdcSmillert
43525a69cdcSmillert /* see if this name has already been used */
43625a69cdcSmillert for (q = namechain ; q; q = q->nextp)
43725a69cdcSmillert if (strcmp(fname, q->datap) == 0) {
43825a69cdcSmillert fname[0] = '\0';
43925a69cdcSmillert return;
44025a69cdcSmillert }
44125a69cdcSmillert
4429a97949aStedu q = malloc(sizeof(struct chain));
44325a69cdcSmillert if (q == NULL)
444e837b443Stom err(1, NULL);
44525a69cdcSmillert q->nextp = namechain;
44625a69cdcSmillert q->datap = strdup(fname);
44725a69cdcSmillert if (q->datap == NULL)
448e837b443Stom err(1, NULL);
44925a69cdcSmillert namechain = q;
45025a69cdcSmillert }
45125a69cdcSmillert
45225a69cdcSmillert void
textline(char * str,int constant)45325a69cdcSmillert textline(char *str, int constant)
45425a69cdcSmillert {
45525a69cdcSmillert
45625a69cdcSmillert if (wordflag) {
45725a69cdcSmillert msputwords(0);
45825a69cdcSmillert return;
45925a69cdcSmillert }
46025a69cdcSmillert puts(str);
46125a69cdcSmillert }
46225a69cdcSmillert
46325a69cdcSmillert void
work(void)46425a69cdcSmillert work(void)
46525a69cdcSmillert {
46625a69cdcSmillert
46725a69cdcSmillert for (;;) {
46825a69cdcSmillert C;
46925a69cdcSmillert #ifdef FULLDEBUG
47025a69cdcSmillert printf("Starting work with `%c'\n", c);
471dc955345Sdanh #endif /* FULLDEBUG */
47225a69cdcSmillert if (c == '.' || c == '\'')
47325a69cdcSmillert comline();
47425a69cdcSmillert else
47525a69cdcSmillert regline(textline, TWO);
47625a69cdcSmillert }
47725a69cdcSmillert }
47825a69cdcSmillert
47925a69cdcSmillert void
regline(void (* pfunc)(char *,int),int constant)48025a69cdcSmillert regline(void (*pfunc)(char *, int), int constant)
48125a69cdcSmillert {
48225a69cdcSmillert
48325a69cdcSmillert line[0] = c;
48425a69cdcSmillert lp = line;
485*08e9b19aSmillert for (;;) {
486*08e9b19aSmillert if (lp - line == linesz - 1) {
487*08e9b19aSmillert char *newline = reallocarray(line, linesz, 2);
488*08e9b19aSmillert if (newline == NULL)
489*08e9b19aSmillert err(1, NULL);
490*08e9b19aSmillert lp = newline + (lp - line);
491*08e9b19aSmillert line = newline;
492*08e9b19aSmillert linesz *= 2;
493*08e9b19aSmillert }
49425a69cdcSmillert if (c == '\\') {
49525a69cdcSmillert *lp = ' ';
49625a69cdcSmillert backsl();
49725a69cdcSmillert }
49825a69cdcSmillert if (c == '\n')
49925a69cdcSmillert break;
50025a69cdcSmillert if (intable && c == 'T') {
50125a69cdcSmillert *++lp = C;
50225a69cdcSmillert if (c == '{' || c == '}') {
50325a69cdcSmillert lp[-1] = ' ';
50425a69cdcSmillert *lp = C;
50525a69cdcSmillert }
50625a69cdcSmillert } else {
50725a69cdcSmillert *++lp = C;
50825a69cdcSmillert }
50925a69cdcSmillert }
51025a69cdcSmillert *lp = '\0';
51125a69cdcSmillert
51225a69cdcSmillert if (line[0] != '\0')
51325a69cdcSmillert (*pfunc)(line, constant);
51425a69cdcSmillert }
51525a69cdcSmillert
51625a69cdcSmillert void
macro(void)51725a69cdcSmillert macro(void)
51825a69cdcSmillert {
51925a69cdcSmillert
52025a69cdcSmillert if (msflag) {
52125a69cdcSmillert do {
52225a69cdcSmillert SKIP;
52325a69cdcSmillert } while (C!='.' || C!='.' || C=='.'); /* look for .. */
52425a69cdcSmillert if (c != '\n')
52525a69cdcSmillert SKIP;
52625a69cdcSmillert return;
52725a69cdcSmillert }
52825a69cdcSmillert SKIP;
52925a69cdcSmillert inmacro = YES;
53025a69cdcSmillert }
53125a69cdcSmillert
53225a69cdcSmillert void
tbl(void)53325a69cdcSmillert tbl(void)
53425a69cdcSmillert {
53525a69cdcSmillert
53625a69cdcSmillert while (C != '.')
53725a69cdcSmillert ; /* nothing */
53825a69cdcSmillert SKIP;
53925a69cdcSmillert intable = YES;
54025a69cdcSmillert }
54125a69cdcSmillert
54225a69cdcSmillert void
stbl(void)54325a69cdcSmillert stbl(void)
54425a69cdcSmillert {
54525a69cdcSmillert
54625a69cdcSmillert while (C != '.')
54725a69cdcSmillert ; /* nothing */
54825a69cdcSmillert SKIP_TO_COM;
54925a69cdcSmillert if (c != 'T' || C != 'E') {
55025a69cdcSmillert SKIP;
55125a69cdcSmillert pc = c;
55225a69cdcSmillert while (C != '.' || pc != '\n' || C != 'T' || C != 'E')
55325a69cdcSmillert pc = c;
55425a69cdcSmillert }
55525a69cdcSmillert }
55625a69cdcSmillert
55725a69cdcSmillert void
eqn(void)55825a69cdcSmillert eqn(void)
55925a69cdcSmillert {
56025a69cdcSmillert int c1, c2;
56125a69cdcSmillert int dflg;
56225a69cdcSmillert char last;
56325a69cdcSmillert
56425a69cdcSmillert last=0;
56525a69cdcSmillert dflg = 1;
56625a69cdcSmillert SKIP;
56725a69cdcSmillert
56825a69cdcSmillert for (;;) {
56925a69cdcSmillert if (C1 == '.' || c == '\'') {
57025a69cdcSmillert while (C1 == ' ' || c == '\t')
57125a69cdcSmillert ;
57225a69cdcSmillert if (c == 'E' && C1 == 'N') {
57325a69cdcSmillert SKIP;
57425a69cdcSmillert if (msflag && dflg) {
57525a69cdcSmillert putchar('x');
57625a69cdcSmillert putchar(' ');
57725a69cdcSmillert if (last) {
57825a69cdcSmillert putchar(last);
57925a69cdcSmillert putchar('\n');
58025a69cdcSmillert }
58125a69cdcSmillert }
58225a69cdcSmillert return;
58325a69cdcSmillert }
58425a69cdcSmillert } else if (c == 'd') {
58525a69cdcSmillert /* look for delim */
58625a69cdcSmillert if (C1 == 'e' && C1 == 'l')
58725a69cdcSmillert if (C1 == 'i' && C1 == 'm') {
58825a69cdcSmillert while (C1 == ' ')
58925a69cdcSmillert ; /* nothing */
59025a69cdcSmillert
59125a69cdcSmillert if ((c1 = c) == '\n' ||
59225a69cdcSmillert (c2 = C1) == '\n' ||
59325a69cdcSmillert (c1 == 'o' && c2 == 'f' && C1=='f')) {
59425a69cdcSmillert ldelim = NOCHAR;
59525a69cdcSmillert rdelim = NOCHAR;
59625a69cdcSmillert } else {
59725a69cdcSmillert ldelim = c1;
59825a69cdcSmillert rdelim = c2;
59925a69cdcSmillert }
60025a69cdcSmillert }
60125a69cdcSmillert dflg = 0;
60225a69cdcSmillert }
60325a69cdcSmillert
60425a69cdcSmillert if (c != '\n')
60525a69cdcSmillert while (C1 != '\n') {
60625a69cdcSmillert if (chars[c] == PUNCT)
60725a69cdcSmillert last = c;
60825a69cdcSmillert else if (c != ' ')
60925a69cdcSmillert last = 0;
61025a69cdcSmillert }
61125a69cdcSmillert }
61225a69cdcSmillert }
61325a69cdcSmillert
61425a69cdcSmillert /* skip over a complete backslash construction */
61525a69cdcSmillert void
backsl(void)61625a69cdcSmillert backsl(void)
61725a69cdcSmillert {
61825a69cdcSmillert int bdelim;
61925a69cdcSmillert
62025a69cdcSmillert sw:
62125a69cdcSmillert switch (C) {
62225a69cdcSmillert case '"':
62325a69cdcSmillert SKIP;
62425a69cdcSmillert return;
62525a69cdcSmillert
62625a69cdcSmillert case 's':
62725a69cdcSmillert if (C == '\\')
62825a69cdcSmillert backsl();
62925a69cdcSmillert else {
63025a69cdcSmillert while (C >= '0' && c <= '9')
63125a69cdcSmillert ; /* nothing */
63225a69cdcSmillert ungetc(c, infile);
63325a69cdcSmillert c = '0';
63425a69cdcSmillert }
63525a69cdcSmillert --lp;
63625a69cdcSmillert return;
63725a69cdcSmillert
63825a69cdcSmillert case 'f':
63925a69cdcSmillert case 'n':
64025a69cdcSmillert case '*':
64125a69cdcSmillert if (C != '(')
64225a69cdcSmillert return;
64325a69cdcSmillert
64425a69cdcSmillert case '(':
64525a69cdcSmillert if (msflag) {
64625a69cdcSmillert if (C == 'e') {
64725a69cdcSmillert if (C == 'm') {
64825a69cdcSmillert *lp = '-';
64925a69cdcSmillert return;
65025a69cdcSmillert }
65125a69cdcSmillert }
65225a69cdcSmillert else if (c != '\n')
65325a69cdcSmillert C;
65425a69cdcSmillert return;
65525a69cdcSmillert }
65625a69cdcSmillert if (C != '\n')
65725a69cdcSmillert C;
65825a69cdcSmillert return;
65925a69cdcSmillert
66025a69cdcSmillert case '$':
66125a69cdcSmillert C; /* discard argument number */
66225a69cdcSmillert return;
66325a69cdcSmillert
66425a69cdcSmillert case 'b':
66525a69cdcSmillert case 'x':
66625a69cdcSmillert case 'v':
66725a69cdcSmillert case 'h':
66825a69cdcSmillert case 'w':
66925a69cdcSmillert case 'o':
67025a69cdcSmillert case 'l':
67125a69cdcSmillert case 'L':
67225a69cdcSmillert if ((bdelim = C) == '\n')
67325a69cdcSmillert return;
67425a69cdcSmillert while (C != '\n' && c != bdelim)
67525a69cdcSmillert if (c == '\\')
67625a69cdcSmillert backsl();
67725a69cdcSmillert return;
67825a69cdcSmillert
67925a69cdcSmillert case '\\':
68025a69cdcSmillert if (inmacro)
68125a69cdcSmillert goto sw;
68225a69cdcSmillert
68325a69cdcSmillert default:
68425a69cdcSmillert return;
68525a69cdcSmillert }
68625a69cdcSmillert }
68725a69cdcSmillert
68825a69cdcSmillert void
sce(void)68925a69cdcSmillert sce(void)
69025a69cdcSmillert {
69125a69cdcSmillert char *ap;
69225a69cdcSmillert int n, i;
69325a69cdcSmillert char a[10];
69425a69cdcSmillert
69525a69cdcSmillert for (ap = a; C != '\n'; ap++) {
69625a69cdcSmillert *ap = c;
69725a69cdcSmillert if (ap == &a[9]) {
69825a69cdcSmillert SKIP;
69925a69cdcSmillert ap = a;
70025a69cdcSmillert break;
70125a69cdcSmillert }
70225a69cdcSmillert }
70325a69cdcSmillert if (ap != a)
70425a69cdcSmillert n = atoi(a);
70525a69cdcSmillert else
70625a69cdcSmillert n = 1;
70725a69cdcSmillert for (i = 0; i < n;) {
70825a69cdcSmillert if (C == '.') {
70925a69cdcSmillert if (C == 'c') {
71025a69cdcSmillert if (C == 'e') {
71125a69cdcSmillert while (C == ' ')
71225a69cdcSmillert ; /* nothing */
71325a69cdcSmillert if (c == '0') {
71425a69cdcSmillert SKIP;
71525a69cdcSmillert break;
71625a69cdcSmillert } else
71725a69cdcSmillert SKIP;
71825a69cdcSmillert }
71925a69cdcSmillert else
72025a69cdcSmillert SKIP;
72125a69cdcSmillert } else if (c == 'P' || C == 'P') {
72225a69cdcSmillert if (c != '\n')
72325a69cdcSmillert SKIP;
72425a69cdcSmillert break;
72525a69cdcSmillert } else if (c != '\n')
72625a69cdcSmillert SKIP;
72725a69cdcSmillert } else {
72825a69cdcSmillert SKIP;
72925a69cdcSmillert i++;
73025a69cdcSmillert }
73125a69cdcSmillert }
73225a69cdcSmillert }
73325a69cdcSmillert
73425a69cdcSmillert void
refer(int c1)73525a69cdcSmillert refer(int c1)
73625a69cdcSmillert {
73725a69cdcSmillert int c2;
73825a69cdcSmillert
73925a69cdcSmillert if (c1 != '\n')
74025a69cdcSmillert SKIP;
74125a69cdcSmillert
74225a69cdcSmillert for (c2 = -1;;) {
74325a69cdcSmillert if (C != '.')
74425a69cdcSmillert SKIP;
74525a69cdcSmillert else {
74625a69cdcSmillert if (C != ']')
74725a69cdcSmillert SKIP;
74825a69cdcSmillert else {
74925a69cdcSmillert while (C != '\n')
75025a69cdcSmillert c2 = c;
75125a69cdcSmillert if (c2 != -1 && chars[c2] == PUNCT)
75225a69cdcSmillert putchar(c2);
75325a69cdcSmillert return;
75425a69cdcSmillert }
75525a69cdcSmillert }
75625a69cdcSmillert }
75725a69cdcSmillert }
75825a69cdcSmillert
75925a69cdcSmillert void
inpic(void)76025a69cdcSmillert inpic(void)
76125a69cdcSmillert {
76225a69cdcSmillert int c1;
7631e6d1964Smillert char *p1, *ep;
76425a69cdcSmillert
76525a69cdcSmillert SKIP;
76625a69cdcSmillert p1 = line;
7671e6d1964Smillert ep = line + sizeof(line) - 1;
76825a69cdcSmillert c = '\n';
76925a69cdcSmillert for (;;) {
77025a69cdcSmillert c1 = c;
77125a69cdcSmillert if (C == '.' && c1 == '\n') {
77225a69cdcSmillert if (C != 'P') {
77325a69cdcSmillert if (c == '\n')
77425a69cdcSmillert continue;
77525a69cdcSmillert else {
77625a69cdcSmillert SKIP;
77725a69cdcSmillert c = '\n';
77825a69cdcSmillert continue;
77925a69cdcSmillert }
78025a69cdcSmillert }
78125a69cdcSmillert if (C != 'E') {
78225a69cdcSmillert if (c == '\n')
78325a69cdcSmillert continue;
78425a69cdcSmillert else {
78525a69cdcSmillert SKIP;
78625a69cdcSmillert c = '\n';
78725a69cdcSmillert continue;
78825a69cdcSmillert }
78925a69cdcSmillert }
79025a69cdcSmillert SKIP;
79125a69cdcSmillert return;
79225a69cdcSmillert }
79325a69cdcSmillert else if (c == '\"') {
79425a69cdcSmillert while (C != '\"') {
79525a69cdcSmillert if (c == '\\') {
79625a69cdcSmillert if (C == '\"')
79725a69cdcSmillert continue;
79825a69cdcSmillert ungetc(c, infile);
79925a69cdcSmillert backsl();
8001e6d1964Smillert } else if (p1 + 1 >= ep) {
8011e6d1964Smillert errx(1, ".PS length exceeds limit");
8021e6d1964Smillert } else {
80325a69cdcSmillert *p1++ = c;
80425a69cdcSmillert }
8051e6d1964Smillert }
80625a69cdcSmillert *p1++ = ' ';
80725a69cdcSmillert }
80825a69cdcSmillert else if (c == '\n' && p1 != line) {
80925a69cdcSmillert *p1 = '\0';
81025a69cdcSmillert if (wordflag)
81125a69cdcSmillert msputwords(NO);
81225a69cdcSmillert else {
81325a69cdcSmillert puts(line);
81425a69cdcSmillert putchar('\n');
81525a69cdcSmillert }
81625a69cdcSmillert p1 = line;
81725a69cdcSmillert }
81825a69cdcSmillert }
81925a69cdcSmillert }
82025a69cdcSmillert
82125a69cdcSmillert #ifdef DEBUG
82225a69cdcSmillert int
_C1(void)82325a69cdcSmillert _C1(void)
82425a69cdcSmillert {
82525a69cdcSmillert
82625a69cdcSmillert return(C1get);
82725a69cdcSmillert }
82825a69cdcSmillert
82925a69cdcSmillert int
_C(void)83025a69cdcSmillert _C(void)
83125a69cdcSmillert {
83225a69cdcSmillert
83325a69cdcSmillert return(Cget);
83425a69cdcSmillert }
835dc955345Sdanh #endif /* DEBUG */
83625a69cdcSmillert
83725a69cdcSmillert /*
83825a69cdcSmillert * Put out a macro line, using ms and mm conventions.
83925a69cdcSmillert */
84025a69cdcSmillert void
msputmac(char * s,int constant)84125a69cdcSmillert msputmac(char *s, int constant)
84225a69cdcSmillert {
84325a69cdcSmillert char *t;
84425a69cdcSmillert int found;
84525a69cdcSmillert int last;
84625a69cdcSmillert
84725a69cdcSmillert last = 0;
84825a69cdcSmillert found = 0;
84925a69cdcSmillert if (wordflag) {
85025a69cdcSmillert msputwords(YES);
85125a69cdcSmillert return;
85225a69cdcSmillert }
85325a69cdcSmillert while (*s) {
85425a69cdcSmillert while (*s == ' ' || *s == '\t')
85525a69cdcSmillert putchar(*s++);
85625a69cdcSmillert for (t = s ; *t != ' ' && *t != '\t' && *t != '\0' ; ++t)
85725a69cdcSmillert ; /* nothing */
85825a69cdcSmillert if (*s == '\"')
85925a69cdcSmillert s++;
86025a69cdcSmillert if (t > s + constant && chars[(unsigned char)s[0]] == LETTER &&
86125a69cdcSmillert chars[(unsigned char)s[1]] == LETTER) {
86225a69cdcSmillert while (s < t)
86325a69cdcSmillert if (*s == '\"')
86425a69cdcSmillert s++;
86525a69cdcSmillert else
86625a69cdcSmillert putchar(*s++);
86725a69cdcSmillert last = *(t-1);
86825a69cdcSmillert found++;
86925a69cdcSmillert } else if (found && chars[(unsigned char)s[0]] == PUNCT &&
87025a69cdcSmillert s[1] == '\0') {
87125a69cdcSmillert putchar(*s++);
87225a69cdcSmillert } else {
87325a69cdcSmillert last = *(t - 1);
87425a69cdcSmillert s = t;
87525a69cdcSmillert }
87625a69cdcSmillert }
87725a69cdcSmillert putchar('\n');
87825a69cdcSmillert if (msflag && chars[last] == PUNCT) {
87925a69cdcSmillert putchar(last);
88025a69cdcSmillert putchar('\n');
88125a69cdcSmillert }
88225a69cdcSmillert }
88325a69cdcSmillert
88425a69cdcSmillert /*
88525a69cdcSmillert * put out words (for the -w option) with ms and mm conventions
88625a69cdcSmillert */
88725a69cdcSmillert void
msputwords(int macline)88825a69cdcSmillert msputwords(int macline)
88925a69cdcSmillert {
89025a69cdcSmillert char *p, *p1;
89125a69cdcSmillert int i, nlet;
89225a69cdcSmillert
89325a69cdcSmillert for (p1 = line;;) {
89425a69cdcSmillert /*
89525a69cdcSmillert * skip initial specials ampersands and apostrophes
89625a69cdcSmillert */
89725a69cdcSmillert while (chars[(unsigned char)*p1] < DIGIT)
89825a69cdcSmillert if (*p1++ == '\0')
89925a69cdcSmillert return;
90025a69cdcSmillert nlet = 0;
90125a69cdcSmillert for (p = p1 ; (i = chars[(unsigned char)*p]) != SPECIAL ; ++p)
90225a69cdcSmillert if (i == LETTER)
90325a69cdcSmillert ++nlet;
90425a69cdcSmillert
90525a69cdcSmillert if (nlet > 1 && chars[(unsigned char)p1[0]] == LETTER) {
90625a69cdcSmillert /*
90725a69cdcSmillert * delete trailing ampersands and apostrophes
90825a69cdcSmillert */
90925a69cdcSmillert while ((i = chars[(unsigned char)p[-1]]) == PUNCT ||
91025a69cdcSmillert i == APOS )
91125a69cdcSmillert --p;
91225a69cdcSmillert while (p1 < p)
91325a69cdcSmillert putchar(*p1++);
91425a69cdcSmillert putchar('\n');
91525a69cdcSmillert } else {
91625a69cdcSmillert p1 = p;
91725a69cdcSmillert }
91825a69cdcSmillert }
91925a69cdcSmillert }
92025a69cdcSmillert
92125a69cdcSmillert /*
92225a69cdcSmillert * put out a macro using the me conventions
92325a69cdcSmillert */
92425a69cdcSmillert #define SKIPBLANK(cp) while (*cp == ' ' || *cp == '\t') { cp++; }
92525a69cdcSmillert #define SKIPNONBLANK(cp) while (*cp !=' ' && *cp !='\cp' && *cp !='\0') { cp++; }
92625a69cdcSmillert
92725a69cdcSmillert void
meputmac(char * cp,int constant)92825a69cdcSmillert meputmac(char *cp, int constant)
92925a69cdcSmillert {
93025a69cdcSmillert char *np;
93125a69cdcSmillert int found;
93225a69cdcSmillert int argno;
93325a69cdcSmillert int last;
93425a69cdcSmillert int inquote;
93525a69cdcSmillert
93625a69cdcSmillert last = 0;
93725a69cdcSmillert found = 0;
93825a69cdcSmillert if (wordflag) {
93925a69cdcSmillert meputwords(YES);
94025a69cdcSmillert return;
94125a69cdcSmillert }
94225a69cdcSmillert for (argno = 0; *cp; argno++) {
94325a69cdcSmillert SKIPBLANK(cp);
94425a69cdcSmillert inquote = (*cp == '"');
94525a69cdcSmillert if (inquote)
94625a69cdcSmillert cp++;
94725a69cdcSmillert for (np = cp; *np; np++) {
94825a69cdcSmillert switch (*np) {
94925a69cdcSmillert case '\n':
95025a69cdcSmillert case '\0':
95125a69cdcSmillert break;
95225a69cdcSmillert
95325a69cdcSmillert case '\t':
95425a69cdcSmillert case ' ':
95525a69cdcSmillert if (inquote)
95625a69cdcSmillert continue;
95725a69cdcSmillert else
95825a69cdcSmillert goto endarg;
95925a69cdcSmillert
96025a69cdcSmillert case '"':
96125a69cdcSmillert if (inquote && np[1] == '"') {
962f09d3110Smillert memmove(np, np + 1, strlen(np));
96325a69cdcSmillert np++;
96425a69cdcSmillert continue;
96525a69cdcSmillert } else {
96625a69cdcSmillert *np = ' '; /* bye bye " */
96725a69cdcSmillert goto endarg;
96825a69cdcSmillert }
96925a69cdcSmillert
97025a69cdcSmillert default:
97125a69cdcSmillert continue;
97225a69cdcSmillert }
97325a69cdcSmillert }
97425a69cdcSmillert endarg: ;
97525a69cdcSmillert /*
97625a69cdcSmillert * cp points at the first char in the arg
97725a69cdcSmillert * np points one beyond the last char in the arg
97825a69cdcSmillert */
97925a69cdcSmillert if ((argconcat == 0) || (argconcat != argno))
98025a69cdcSmillert putchar(' ');
98125a69cdcSmillert #ifdef FULLDEBUG
98225a69cdcSmillert {
98325a69cdcSmillert char *p;
98425a69cdcSmillert printf("[%d,%d: ", argno, np - cp);
98525a69cdcSmillert for (p = cp; p < np; p++) {
98625a69cdcSmillert putchar(*p);
98725a69cdcSmillert }
98825a69cdcSmillert printf("]");
98925a69cdcSmillert }
990dc955345Sdanh #endif /* FULLDEBUG */
99125a69cdcSmillert /*
99225a69cdcSmillert * Determine if the argument merits being printed
99325a69cdcSmillert *
99425a69cdcSmillert * constant is the cut off point below which something
99525a69cdcSmillert * is not a word.
99625a69cdcSmillert */
99725a69cdcSmillert if (((np - cp) > constant) &&
99825a69cdcSmillert (inquote || (chars[(unsigned char)cp[0]] == LETTER))) {
99995ca2293Smiod for (; cp < np; cp++)
100025a69cdcSmillert putchar(*cp);
100125a69cdcSmillert last = np[-1];
100225a69cdcSmillert found++;
100325a69cdcSmillert } else if (found && (np - cp == 1) &&
100425a69cdcSmillert chars[(unsigned char)*cp] == PUNCT) {
100525a69cdcSmillert putchar(*cp);
100625a69cdcSmillert } else {
100725a69cdcSmillert last = np[-1];
100825a69cdcSmillert }
100925a69cdcSmillert cp = np;
101025a69cdcSmillert }
101125a69cdcSmillert if (msflag && chars[last] == PUNCT)
101225a69cdcSmillert putchar(last);
101325a69cdcSmillert putchar('\n');
101425a69cdcSmillert }
101525a69cdcSmillert
101625a69cdcSmillert /*
101725a69cdcSmillert * put out words (for the -w option) with ms and mm conventions
101825a69cdcSmillert */
101925a69cdcSmillert void
meputwords(int macline)102025a69cdcSmillert meputwords(int macline)
102125a69cdcSmillert {
102225a69cdcSmillert
102325a69cdcSmillert msputwords(macline);
102425a69cdcSmillert }
102525a69cdcSmillert
102625a69cdcSmillert /*
102725a69cdcSmillert *
102825a69cdcSmillert * Skip over a nested set of macros
102925a69cdcSmillert *
103025a69cdcSmillert * Possible arguments to noblock are:
103125a69cdcSmillert *
103225a69cdcSmillert * fi end of unfilled text
103325a69cdcSmillert * PE pic ending
103425a69cdcSmillert * DE display ending
103525a69cdcSmillert *
103625a69cdcSmillert * for ms and mm only:
103725a69cdcSmillert * KE keep ending
103825a69cdcSmillert *
103925a69cdcSmillert * NE undocumented match to NS (for mm?)
104025a69cdcSmillert * LE mm only: matches RL or *L (for lists)
104125a69cdcSmillert *
104225a69cdcSmillert * for me:
104325a69cdcSmillert * ([lqbzcdf]
104425a69cdcSmillert */
104525a69cdcSmillert void
noblock(char a1,char a2)104625a69cdcSmillert noblock(char a1, char a2)
104725a69cdcSmillert {
104825a69cdcSmillert int c1,c2;
104925a69cdcSmillert int eqnf;
105025a69cdcSmillert int lct;
105125a69cdcSmillert
105225a69cdcSmillert lct = 0;
105325a69cdcSmillert eqnf = 1;
105425a69cdcSmillert SKIP;
105525a69cdcSmillert for (;;) {
105625a69cdcSmillert while (C != '.')
105725a69cdcSmillert if (c == '\n')
105825a69cdcSmillert continue;
105925a69cdcSmillert else
106025a69cdcSmillert SKIP;
106125a69cdcSmillert if ((c1 = C) == '\n')
106225a69cdcSmillert continue;
106325a69cdcSmillert if ((c2 = C) == '\n')
106425a69cdcSmillert continue;
106525a69cdcSmillert if (c1 == a1 && c2 == a2) {
106625a69cdcSmillert SKIP;
106725a69cdcSmillert if (lct != 0) {
106825a69cdcSmillert lct--;
106925a69cdcSmillert continue;
107025a69cdcSmillert }
107125a69cdcSmillert if (eqnf)
107225a69cdcSmillert putchar('.');
107325a69cdcSmillert putchar('\n');
107425a69cdcSmillert return;
107525a69cdcSmillert } else if (a1 == 'L' && c2 == 'L') {
107625a69cdcSmillert lct++;
107725a69cdcSmillert SKIP;
107825a69cdcSmillert }
107925a69cdcSmillert /*
108025a69cdcSmillert * equations (EQ) nested within a display
108125a69cdcSmillert */
108225a69cdcSmillert else if (c1 == 'E' && c2 == 'Q') {
108325a69cdcSmillert if ((mac == ME && a1 == ')')
108425a69cdcSmillert || (mac != ME && a1 == 'D')) {
108525a69cdcSmillert eqn();
108625a69cdcSmillert eqnf=0;
108725a69cdcSmillert }
108825a69cdcSmillert }
108925a69cdcSmillert /*
109025a69cdcSmillert * turning on filling is done by the paragraphing
109125a69cdcSmillert * macros
109225a69cdcSmillert */
109325a69cdcSmillert else if (a1 == 'f') { /* .fi */
109425a69cdcSmillert if ((mac == ME && (c2 == 'h' || c2 == 'p'))
109525a69cdcSmillert || (mac != ME && (c1 == 'P' || c2 == 'P'))) {
109625a69cdcSmillert SKIP;
109725a69cdcSmillert return;
109825a69cdcSmillert }
109925a69cdcSmillert } else {
110025a69cdcSmillert SKIP;
110125a69cdcSmillert }
110225a69cdcSmillert }
110325a69cdcSmillert }
110425a69cdcSmillert
110525a69cdcSmillert int
EQ(void)110625a69cdcSmillert EQ(void)
110725a69cdcSmillert {
110825a69cdcSmillert
110925a69cdcSmillert eqn();
111025a69cdcSmillert return(0);
111125a69cdcSmillert }
111225a69cdcSmillert
111325a69cdcSmillert int
domacro(void)111425a69cdcSmillert domacro(void)
111525a69cdcSmillert {
111625a69cdcSmillert
111725a69cdcSmillert macro();
111825a69cdcSmillert return(0);
111925a69cdcSmillert }
112025a69cdcSmillert
112125a69cdcSmillert int
PS(void)112225a69cdcSmillert PS(void)
112325a69cdcSmillert {
112425a69cdcSmillert
112525a69cdcSmillert for (C; c == ' ' || c == '\t'; C)
112625a69cdcSmillert ; /* nothing */
112725a69cdcSmillert
112825a69cdcSmillert if (c == '<') { /* ".PS < file" -- don't expect a .PE */
112925a69cdcSmillert SKIP;
113025a69cdcSmillert return(0);
113125a69cdcSmillert }
113225a69cdcSmillert if (!msflag)
113325a69cdcSmillert inpic();
113425a69cdcSmillert else
113525a69cdcSmillert noblock('P', 'E');
113625a69cdcSmillert return(0);
113725a69cdcSmillert }
113825a69cdcSmillert
113925a69cdcSmillert int
skip(void)114025a69cdcSmillert skip(void)
114125a69cdcSmillert {
114225a69cdcSmillert
114325a69cdcSmillert SKIP;
114425a69cdcSmillert return(0);
114525a69cdcSmillert }
114625a69cdcSmillert
114725a69cdcSmillert int
intbl(void)114825a69cdcSmillert intbl(void)
114925a69cdcSmillert {
115025a69cdcSmillert
115125a69cdcSmillert if (msflag)
115225a69cdcSmillert stbl();
115325a69cdcSmillert else
115425a69cdcSmillert tbl();
115525a69cdcSmillert return(0);
115625a69cdcSmillert }
115725a69cdcSmillert
115825a69cdcSmillert int
outtbl(void)115925a69cdcSmillert outtbl(void)
116025a69cdcSmillert {
116125a69cdcSmillert
116225a69cdcSmillert intable = NO;
116325a69cdcSmillert return(0);
116425a69cdcSmillert }
116525a69cdcSmillert
116625a69cdcSmillert int
so(void)116725a69cdcSmillert so(void)
116825a69cdcSmillert {
116925a69cdcSmillert
117025a69cdcSmillert if (!iflag) {
117125a69cdcSmillert getfname();
117225a69cdcSmillert if (fname[0]) {
117325a69cdcSmillert if (++filesp - &files[0] > MAXFILES)
117425a69cdcSmillert err(1, "too many nested files (max %d)",
117525a69cdcSmillert MAXFILES);
117625a69cdcSmillert infile = *filesp = opn(fname);
117725a69cdcSmillert }
117825a69cdcSmillert }
117925a69cdcSmillert return(0);
118025a69cdcSmillert }
118125a69cdcSmillert
118225a69cdcSmillert int
nx(void)118325a69cdcSmillert nx(void)
118425a69cdcSmillert {
118525a69cdcSmillert
118625a69cdcSmillert if (!iflag) {
118725a69cdcSmillert getfname();
118825a69cdcSmillert if (fname[0] == '\0')
118925a69cdcSmillert exit(0);
119025a69cdcSmillert if (infile != stdin)
119125a69cdcSmillert fclose(infile);
119225a69cdcSmillert infile = *filesp = opn(fname);
119325a69cdcSmillert }
119425a69cdcSmillert return(0);
119525a69cdcSmillert }
119625a69cdcSmillert
119725a69cdcSmillert int
skiptocom(void)119825a69cdcSmillert skiptocom(void)
119925a69cdcSmillert {
120025a69cdcSmillert
120125a69cdcSmillert SKIP_TO_COM;
120225a69cdcSmillert return(COMX);
120325a69cdcSmillert }
120425a69cdcSmillert
120525a69cdcSmillert int
PP(pacmac c12)120625a69cdcSmillert PP(pacmac c12)
120725a69cdcSmillert {
120825a69cdcSmillert int c1, c2;
120925a69cdcSmillert
121025a69cdcSmillert frommac(c12, c1, c2);
121125a69cdcSmillert printf(".%c%c", c1, c2);
121225a69cdcSmillert while (C != '\n')
121325a69cdcSmillert putchar(c);
121425a69cdcSmillert putchar('\n');
121525a69cdcSmillert return(0);
121625a69cdcSmillert }
121725a69cdcSmillert
121825a69cdcSmillert int
AU(void)121925a69cdcSmillert AU(void)
122025a69cdcSmillert {
122125a69cdcSmillert
122225a69cdcSmillert if (mac == MM)
122325a69cdcSmillert return(0);
122425a69cdcSmillert SKIP_TO_COM;
122525a69cdcSmillert return(COMX);
122625a69cdcSmillert }
122725a69cdcSmillert
122825a69cdcSmillert int
SH(pacmac c12)122925a69cdcSmillert SH(pacmac c12)
123025a69cdcSmillert {
123125a69cdcSmillert int c1, c2;
123225a69cdcSmillert
123325a69cdcSmillert frommac(c12, c1, c2);
123425a69cdcSmillert
123525a69cdcSmillert if (parag) {
123625a69cdcSmillert printf(".%c%c", c1, c2);
123725a69cdcSmillert while (C != '\n')
123825a69cdcSmillert putchar(c);
123925a69cdcSmillert putchar(c);
124025a69cdcSmillert putchar('!');
124125a69cdcSmillert for (;;) {
124225a69cdcSmillert while (C != '\n')
124325a69cdcSmillert putchar(c);
124425a69cdcSmillert putchar('\n');
124525a69cdcSmillert if (C == '.')
124625a69cdcSmillert return(COM);
124725a69cdcSmillert putchar('!');
124825a69cdcSmillert putchar(c);
124925a69cdcSmillert }
125025a69cdcSmillert /*NOTREACHED*/
125125a69cdcSmillert } else {
125225a69cdcSmillert SKIP_TO_COM;
125325a69cdcSmillert return(COMX);
125425a69cdcSmillert }
125525a69cdcSmillert }
125625a69cdcSmillert
125725a69cdcSmillert int
UX(void)125825a69cdcSmillert UX(void)
125925a69cdcSmillert {
126025a69cdcSmillert
126125a69cdcSmillert if (wordflag)
126225a69cdcSmillert printf("UNIX\n");
126325a69cdcSmillert else
126425a69cdcSmillert printf("UNIX ");
126525a69cdcSmillert return(0);
126625a69cdcSmillert }
126725a69cdcSmillert
126825a69cdcSmillert int
MMHU(pacmac c12)126925a69cdcSmillert MMHU(pacmac c12)
127025a69cdcSmillert {
127125a69cdcSmillert int c1, c2;
127225a69cdcSmillert
127325a69cdcSmillert frommac(c12, c1, c2);
127425a69cdcSmillert if (parag) {
127525a69cdcSmillert printf(".%c%c", c1, c2);
127625a69cdcSmillert while (C != '\n')
127725a69cdcSmillert putchar(c);
127825a69cdcSmillert putchar('\n');
127925a69cdcSmillert } else {
128025a69cdcSmillert SKIP;
128125a69cdcSmillert }
128225a69cdcSmillert return(0);
128325a69cdcSmillert }
128425a69cdcSmillert
128525a69cdcSmillert int
mesnblock(pacmac c12)128625a69cdcSmillert mesnblock(pacmac c12)
128725a69cdcSmillert {
128825a69cdcSmillert int c1, c2;
128925a69cdcSmillert
129025a69cdcSmillert frommac(c12, c1, c2);
129125a69cdcSmillert noblock(')', c2);
129225a69cdcSmillert return(0);
129325a69cdcSmillert }
129425a69cdcSmillert
129525a69cdcSmillert int
mssnblock(pacmac c12)129625a69cdcSmillert mssnblock(pacmac c12)
129725a69cdcSmillert {
129825a69cdcSmillert int c1, c2;
129925a69cdcSmillert
130025a69cdcSmillert frommac(c12, c1, c2);
130125a69cdcSmillert noblock(c1, 'E');
130225a69cdcSmillert return(0);
130325a69cdcSmillert }
130425a69cdcSmillert
130525a69cdcSmillert int
nf(void)130625a69cdcSmillert nf(void)
130725a69cdcSmillert {
130825a69cdcSmillert
130925a69cdcSmillert noblock('f', 'i');
131025a69cdcSmillert return(0);
131125a69cdcSmillert }
131225a69cdcSmillert
131325a69cdcSmillert int
ce(void)131425a69cdcSmillert ce(void)
131525a69cdcSmillert {
131625a69cdcSmillert
131725a69cdcSmillert sce();
131825a69cdcSmillert return(0);
131925a69cdcSmillert }
132025a69cdcSmillert
132125a69cdcSmillert int
meip(pacmac c12)132225a69cdcSmillert meip(pacmac c12)
132325a69cdcSmillert {
132425a69cdcSmillert
132525a69cdcSmillert if (parag)
132625a69cdcSmillert mepp(c12);
132725a69cdcSmillert else if (wordflag) /* save the tag */
132825a69cdcSmillert regline(meputmac, ONE);
132925a69cdcSmillert else
133025a69cdcSmillert SKIP;
133125a69cdcSmillert return(0);
133225a69cdcSmillert }
133325a69cdcSmillert
133425a69cdcSmillert /*
133525a69cdcSmillert * only called for -me .pp or .sh, when parag is on
133625a69cdcSmillert */
133725a69cdcSmillert int
mepp(pacmac c12)133825a69cdcSmillert mepp(pacmac c12)
133925a69cdcSmillert {
134025a69cdcSmillert
134125a69cdcSmillert PP(c12); /* eats the line */
134225a69cdcSmillert return(0);
134325a69cdcSmillert }
134425a69cdcSmillert
134525a69cdcSmillert /*
134625a69cdcSmillert * Start of a section heading; output the section name if doing words
134725a69cdcSmillert */
134825a69cdcSmillert int
mesh(pacmac c12)134925a69cdcSmillert mesh(pacmac c12)
135025a69cdcSmillert {
135125a69cdcSmillert
135225a69cdcSmillert if (parag)
135325a69cdcSmillert mepp(c12);
135425a69cdcSmillert else if (wordflag)
135525a69cdcSmillert defcomline(c12);
135625a69cdcSmillert else
135725a69cdcSmillert SKIP;
135825a69cdcSmillert return(0);
135925a69cdcSmillert }
136025a69cdcSmillert
136125a69cdcSmillert /*
136225a69cdcSmillert * process a font setting
136325a69cdcSmillert */
136425a69cdcSmillert int
mefont(pacmac c12)136525a69cdcSmillert mefont(pacmac c12)
136625a69cdcSmillert {
136725a69cdcSmillert
136825a69cdcSmillert argconcat = 1;
136925a69cdcSmillert defcomline(c12);
137025a69cdcSmillert argconcat = 0;
137125a69cdcSmillert return(0);
137225a69cdcSmillert }
137325a69cdcSmillert
137425a69cdcSmillert int
manfont(pacmac c12)137525a69cdcSmillert manfont(pacmac c12)
137625a69cdcSmillert {
137725a69cdcSmillert
137825a69cdcSmillert return(mefont(c12));
137925a69cdcSmillert }
138025a69cdcSmillert
138125a69cdcSmillert int
manpp(pacmac c12)138225a69cdcSmillert manpp(pacmac c12)
138325a69cdcSmillert {
138425a69cdcSmillert
138525a69cdcSmillert return(mepp(c12));
138625a69cdcSmillert }
138725a69cdcSmillert
138825a69cdcSmillert void
defcomline(pacmac c12)138925a69cdcSmillert defcomline(pacmac c12)
139025a69cdcSmillert {
139125a69cdcSmillert int c1, c2;
139225a69cdcSmillert
139325a69cdcSmillert frommac(c12, c1, c2);
139425a69cdcSmillert if (msflag && mac == MM && c2 == 'L') {
139525a69cdcSmillert if (disp || c1 == 'R') {
139625a69cdcSmillert noblock('L', 'E');
139725a69cdcSmillert } else {
139825a69cdcSmillert SKIP;
139925a69cdcSmillert putchar('.');
140025a69cdcSmillert }
140125a69cdcSmillert }
140225a69cdcSmillert else if (c1 == '.' && c2 == '.') {
140325a69cdcSmillert if (msflag) {
140425a69cdcSmillert SKIP;
140525a69cdcSmillert return;
140625a69cdcSmillert }
140725a69cdcSmillert while (C == '.')
140825a69cdcSmillert /*VOID*/;
140925a69cdcSmillert }
141025a69cdcSmillert ++inmacro;
141125a69cdcSmillert /*
141225a69cdcSmillert * Process the arguments to the macro
141325a69cdcSmillert */
141425a69cdcSmillert switch (mac) {
141525a69cdcSmillert default:
141625a69cdcSmillert case MM:
141725a69cdcSmillert case MS:
141825a69cdcSmillert if (c1 <= 'Z' && msflag)
141925a69cdcSmillert regline(msputmac, ONE);
142025a69cdcSmillert else
142125a69cdcSmillert regline(msputmac, TWO);
142225a69cdcSmillert break;
142325a69cdcSmillert case ME:
142425a69cdcSmillert regline(meputmac, ONE);
142525a69cdcSmillert break;
142625a69cdcSmillert }
142725a69cdcSmillert --inmacro;
142825a69cdcSmillert }
142925a69cdcSmillert
143025a69cdcSmillert void
comline(void)143125a69cdcSmillert comline(void)
143225a69cdcSmillert {
143325a69cdcSmillert int c1;
143425a69cdcSmillert int c2;
143525a69cdcSmillert pacmac c12;
143625a69cdcSmillert int mid;
143725a69cdcSmillert int lb, ub;
143825a69cdcSmillert int hit;
143925a69cdcSmillert static int tabsize = 0;
1440c9899b11Skrw static struct mactab *mactab = NULL;
144125a69cdcSmillert struct mactab *mp;
144225a69cdcSmillert
144325a69cdcSmillert if (mactab == 0)
144425a69cdcSmillert buildtab(&mactab, &tabsize);
144525a69cdcSmillert com:
144625a69cdcSmillert while (C == ' ' || c == '\t')
144725a69cdcSmillert ;
144825a69cdcSmillert comx:
144925a69cdcSmillert if ((c1 = c) == '\n')
145025a69cdcSmillert return;
145125a69cdcSmillert c2 = C;
145225a69cdcSmillert if (c1 == '.' && c2 != '.')
145325a69cdcSmillert inmacro = NO;
145425a69cdcSmillert if (msflag && c1 == '[') {
145525a69cdcSmillert refer(c2);
145625a69cdcSmillert return;
145725a69cdcSmillert }
145825a69cdcSmillert if (parag && mac==MM && c1 == 'P' && c2 == '\n') {
145925a69cdcSmillert printf(".P\n");
146025a69cdcSmillert return;
146125a69cdcSmillert }
146225a69cdcSmillert if (c2 == '\n')
146325a69cdcSmillert return;
146425a69cdcSmillert /*
146525a69cdcSmillert * Single letter macro
146625a69cdcSmillert */
146725a69cdcSmillert if (mac == ME && (c2 == ' ' || c2 == '\t') )
146825a69cdcSmillert c2 = ' ';
146925a69cdcSmillert c12 = tomac(c1, c2);
147025a69cdcSmillert /*
147125a69cdcSmillert * binary search through the table of macros
147225a69cdcSmillert */
147325a69cdcSmillert lb = 0;
147425a69cdcSmillert ub = tabsize - 1;
147525a69cdcSmillert while (lb <= ub) {
147625a69cdcSmillert mid = (ub + lb) / 2;
147725a69cdcSmillert mp = &mactab[mid];
147825a69cdcSmillert if (mp->macname < c12)
147925a69cdcSmillert lb = mid + 1;
148025a69cdcSmillert else if (mp->macname > c12)
148125a69cdcSmillert ub = mid - 1;
148225a69cdcSmillert else {
148325a69cdcSmillert hit = 1;
148425a69cdcSmillert #ifdef FULLDEBUG
148525a69cdcSmillert printf("preliminary hit macro %c%c ", c1, c2);
1486dc955345Sdanh #endif /* FULLDEBUG */
148725a69cdcSmillert switch (mp->condition) {
148825a69cdcSmillert case NONE:
148925a69cdcSmillert hit = YES;
149025a69cdcSmillert break;
149125a69cdcSmillert case FNEST:
149225a69cdcSmillert hit = (filesp == files);
149325a69cdcSmillert break;
149425a69cdcSmillert case NOMAC:
149525a69cdcSmillert hit = !inmacro;
149625a69cdcSmillert break;
149725a69cdcSmillert case MAC:
149825a69cdcSmillert hit = inmacro;
149925a69cdcSmillert break;
150025a69cdcSmillert case PARAG:
150125a69cdcSmillert hit = parag;
150225a69cdcSmillert break;
150325a69cdcSmillert case NBLK:
150425a69cdcSmillert hit = !keepblock;
150525a69cdcSmillert break;
150625a69cdcSmillert default:
150725a69cdcSmillert hit = 0;
150825a69cdcSmillert }
150925a69cdcSmillert
151025a69cdcSmillert if (hit) {
151125a69cdcSmillert #ifdef FULLDEBUG
151225a69cdcSmillert printf("MATCH\n");
1513dc955345Sdanh #endif /* FULLDEBUG */
151425a69cdcSmillert switch ((*(mp->func))(c12)) {
151525a69cdcSmillert default:
151625a69cdcSmillert return;
151725a69cdcSmillert case COMX:
151825a69cdcSmillert goto comx;
151925a69cdcSmillert case COM:
152025a69cdcSmillert goto com;
152125a69cdcSmillert }
152225a69cdcSmillert }
152325a69cdcSmillert #ifdef FULLDEBUG
152425a69cdcSmillert printf("FAIL\n");
1525dc955345Sdanh #endif /* FULLDEBUG */
152625a69cdcSmillert break;
152725a69cdcSmillert }
152825a69cdcSmillert }
152925a69cdcSmillert defcomline(c12);
153025a69cdcSmillert }
153125a69cdcSmillert
153225a69cdcSmillert int
macsort(const void * p1,const void * p2)153325a69cdcSmillert macsort(const void *p1, const void *p2)
153425a69cdcSmillert {
153525a69cdcSmillert struct mactab *t1 = (struct mactab *)p1;
153625a69cdcSmillert struct mactab *t2 = (struct mactab *)p2;
153725a69cdcSmillert
153825a69cdcSmillert return(t1->macname - t2->macname);
153925a69cdcSmillert }
154025a69cdcSmillert
154125a69cdcSmillert int
sizetab(struct mactab * mp)154225a69cdcSmillert sizetab(struct mactab *mp)
154325a69cdcSmillert {
154425a69cdcSmillert int i;
154525a69cdcSmillert
154625a69cdcSmillert i = 0;
154725a69cdcSmillert if (mp) {
154825a69cdcSmillert for (; mp->macname; mp++, i++)
154925a69cdcSmillert /*VOID*/ ;
155025a69cdcSmillert }
155125a69cdcSmillert return(i);
155225a69cdcSmillert }
155325a69cdcSmillert
155425a69cdcSmillert struct mactab *
macfill(struct mactab * dst,struct mactab * src)155525a69cdcSmillert macfill(struct mactab *dst, struct mactab *src)
155625a69cdcSmillert {
155725a69cdcSmillert
155825a69cdcSmillert if (src) {
155925a69cdcSmillert while (src->macname)
156025a69cdcSmillert *dst++ = *src++;
156125a69cdcSmillert }
156225a69cdcSmillert return(dst);
156325a69cdcSmillert }
156425a69cdcSmillert
156525a69cdcSmillert __dead void
usage(void)156625a69cdcSmillert usage(void)
156725a69cdcSmillert {
156825a69cdcSmillert extern char *__progname;
156925a69cdcSmillert
1570de4e3f8dSjmc fprintf(stderr, "usage: %s [-ikpw] [-m a | e | l | m | s] [file ...]\n", __progname);
157125a69cdcSmillert exit(1);
157225a69cdcSmillert }
157325a69cdcSmillert
157425a69cdcSmillert void
buildtab(struct mactab ** r_back,int * r_size)157525a69cdcSmillert buildtab(struct mactab **r_back, int *r_size)
157625a69cdcSmillert {
157725a69cdcSmillert int size;
157825a69cdcSmillert struct mactab *p, *p1, *p2;
157925a69cdcSmillert struct mactab *back;
158025a69cdcSmillert
158125a69cdcSmillert size = sizetab(troffmactab) + sizetab(ppmactab);
158225a69cdcSmillert p1 = p2 = NULL;
158325a69cdcSmillert if (msflag) {
158425a69cdcSmillert switch (mac) {
158525a69cdcSmillert case ME:
158625a69cdcSmillert p1 = memactab;
158725a69cdcSmillert break;
158825a69cdcSmillert case MM:
158925a69cdcSmillert p1 = msmactab;
159025a69cdcSmillert p2 = mmmactab;
159125a69cdcSmillert break;
159225a69cdcSmillert case MS:
159325a69cdcSmillert p1 = msmactab;
159425a69cdcSmillert break;
159525a69cdcSmillert case MA:
159625a69cdcSmillert p1 = manmactab;
159725a69cdcSmillert break;
159825a69cdcSmillert default:
159925a69cdcSmillert break;
160025a69cdcSmillert }
160125a69cdcSmillert }
160225a69cdcSmillert size += sizetab(p1);
160325a69cdcSmillert size += sizetab(p2);
16049a97949aStedu back = calloc(size+2, sizeof(struct mactab));
160525a69cdcSmillert if (back == NULL)
1606e837b443Stom err(1, NULL);
160725a69cdcSmillert
160825a69cdcSmillert p = macfill(back, troffmactab);
160925a69cdcSmillert p = macfill(p, ppmactab);
161025a69cdcSmillert p = macfill(p, p1);
161125a69cdcSmillert p = macfill(p, p2);
161225a69cdcSmillert
161325a69cdcSmillert qsort(back, size, sizeof(struct mactab), macsort);
161425a69cdcSmillert *r_size = size;
161525a69cdcSmillert *r_back = back;
161625a69cdcSmillert }
161725a69cdcSmillert
161825a69cdcSmillert /*
161925a69cdcSmillert * troff commands
162025a69cdcSmillert */
162125a69cdcSmillert struct mactab troffmactab[] = {
162225a69cdcSmillert M(NONE, '\\','"', skip), /* comment */
162325a69cdcSmillert M(NOMAC, 'd','e', domacro), /* define */
162425a69cdcSmillert M(NOMAC, 'i','g', domacro), /* ignore till .. */
162525a69cdcSmillert M(NOMAC, 'a','m', domacro), /* append macro */
162625a69cdcSmillert M(NBLK, 'n','f', nf), /* filled */
162725a69cdcSmillert M(NBLK, 'c','e', ce), /* centered */
162825a69cdcSmillert
162925a69cdcSmillert M(NONE, 's','o', so), /* source a file */
163025a69cdcSmillert M(NONE, 'n','x', nx), /* go to next file */
163125a69cdcSmillert
163225a69cdcSmillert M(NONE, 't','m', skip), /* print string on tty */
163325a69cdcSmillert M(NONE, 'h','w', skip), /* exception hyphen words */
163425a69cdcSmillert M(NONE, 0,0, 0)
163525a69cdcSmillert };
163625a69cdcSmillert
163725a69cdcSmillert /*
163825a69cdcSmillert * Preprocessor output
163925a69cdcSmillert */
164025a69cdcSmillert struct mactab ppmactab[] = {
164125a69cdcSmillert M(FNEST, 'E','Q', EQ), /* equation starting */
164225a69cdcSmillert M(FNEST, 'T','S', intbl), /* table starting */
164325a69cdcSmillert M(FNEST, 'T','C', intbl), /* alternative table? */
164425a69cdcSmillert M(FNEST, 'T','&', intbl), /* table reformatting */
164525a69cdcSmillert M(NONE, 'T','E', outtbl),/* table ending */
164625a69cdcSmillert M(NONE, 'P','S', PS), /* picture starting */
164725a69cdcSmillert M(NONE, 0,0, 0)
164825a69cdcSmillert };
164925a69cdcSmillert
165025a69cdcSmillert /*
165125a69cdcSmillert * Particular to ms and mm
165225a69cdcSmillert */
165325a69cdcSmillert struct mactab msmactab[] = {
165425a69cdcSmillert M(NONE, 'T','L', skiptocom), /* title follows */
165525a69cdcSmillert M(NONE, 'F','S', skiptocom), /* start footnote */
165625a69cdcSmillert M(NONE, 'O','K', skiptocom), /* Other kws */
165725a69cdcSmillert
165825a69cdcSmillert M(NONE, 'N','R', skip), /* undocumented */
165925a69cdcSmillert M(NONE, 'N','D', skip), /* use supplied date */
166025a69cdcSmillert
166125a69cdcSmillert M(PARAG, 'P','P', PP), /* begin parag */
166225a69cdcSmillert M(PARAG, 'I','P', PP), /* begin indent parag, tag x */
166325a69cdcSmillert M(PARAG, 'L','P', PP), /* left blocked parag */
166425a69cdcSmillert
166525a69cdcSmillert M(NONE, 'A','U', AU), /* author */
166625a69cdcSmillert M(NONE, 'A','I', AU), /* authors institution */
166725a69cdcSmillert
166825a69cdcSmillert M(NONE, 'S','H', SH), /* section heading */
166925a69cdcSmillert M(NONE, 'S','N', SH), /* undocumented */
167025a69cdcSmillert M(NONE, 'U','X', UX), /* unix */
167125a69cdcSmillert
167225a69cdcSmillert M(NBLK, 'D','S', mssnblock), /* start display text */
167325a69cdcSmillert M(NBLK, 'K','S', mssnblock), /* start keep */
167425a69cdcSmillert M(NBLK, 'K','F', mssnblock), /* start float keep */
167525a69cdcSmillert M(NONE, 0,0, 0)
167625a69cdcSmillert };
167725a69cdcSmillert
167825a69cdcSmillert struct mactab mmmactab[] = {
167925a69cdcSmillert M(NONE, 'H',' ', MMHU), /* -mm ? */
168025a69cdcSmillert M(NONE, 'H','U', MMHU), /* -mm ? */
168125a69cdcSmillert M(PARAG, 'P',' ', PP), /* paragraph for -mm */
168225a69cdcSmillert M(NBLK, 'N','S', mssnblock), /* undocumented */
168325a69cdcSmillert M(NONE, 0,0, 0)
168425a69cdcSmillert };
168525a69cdcSmillert
168625a69cdcSmillert struct mactab memactab[] = {
168725a69cdcSmillert M(PARAG, 'p','p', mepp),
168825a69cdcSmillert M(PARAG, 'l','p', mepp),
168925a69cdcSmillert M(PARAG, 'n','p', mepp),
169025a69cdcSmillert M(NONE, 'i','p', meip),
169125a69cdcSmillert
169225a69cdcSmillert M(NONE, 's','h', mesh),
169325a69cdcSmillert M(NONE, 'u','h', mesh),
169425a69cdcSmillert
169525a69cdcSmillert M(NBLK, '(','l', mesnblock),
169625a69cdcSmillert M(NBLK, '(','q', mesnblock),
169725a69cdcSmillert M(NBLK, '(','b', mesnblock),
169825a69cdcSmillert M(NBLK, '(','z', mesnblock),
169925a69cdcSmillert M(NBLK, '(','c', mesnblock),
170025a69cdcSmillert
170125a69cdcSmillert M(NBLK, '(','d', mesnblock),
170225a69cdcSmillert M(NBLK, '(','f', mesnblock),
170325a69cdcSmillert M(NBLK, '(','x', mesnblock),
170425a69cdcSmillert
170525a69cdcSmillert M(NONE, 'r',' ', mefont),
170625a69cdcSmillert M(NONE, 'i',' ', mefont),
170725a69cdcSmillert M(NONE, 'b',' ', mefont),
170825a69cdcSmillert M(NONE, 'u',' ', mefont),
170925a69cdcSmillert M(NONE, 'q',' ', mefont),
171025a69cdcSmillert M(NONE, 'r','b', mefont),
171125a69cdcSmillert M(NONE, 'b','i', mefont),
171225a69cdcSmillert M(NONE, 'b','x', mefont),
171325a69cdcSmillert M(NONE, 0,0, 0)
171425a69cdcSmillert };
171525a69cdcSmillert
171625a69cdcSmillert struct mactab manmactab[] = {
171725a69cdcSmillert M(PARAG, 'B','I', manfont),
171825a69cdcSmillert M(PARAG, 'B','R', manfont),
171925a69cdcSmillert M(PARAG, 'I','B', manfont),
172025a69cdcSmillert M(PARAG, 'I','R', manfont),
172125a69cdcSmillert M(PARAG, 'R','B', manfont),
172225a69cdcSmillert M(PARAG, 'R','I', manfont),
172325a69cdcSmillert
172425a69cdcSmillert M(PARAG, 'P','P', manpp),
172525a69cdcSmillert M(PARAG, 'L','P', manpp),
172625a69cdcSmillert M(PARAG, 'H','P', manpp),
172725a69cdcSmillert M(NONE, 0,0, 0)
172825a69cdcSmillert };
1729