xref: /minix3/minix/commands/cawf/pass2.c (revision 4d3708913c2076bda91438dab93c91e44ba5a7cf)
1433d6423SLionel Sambuc /*
2433d6423SLionel Sambuc  *	pass2.c - cawf(1) pass 2 function
3433d6423SLionel Sambuc  */
4433d6423SLionel Sambuc 
5433d6423SLionel Sambuc /*
6433d6423SLionel Sambuc  *	Copyright (c) 1991 Purdue University Research Foundation,
7433d6423SLionel Sambuc  *	West Lafayette, Indiana 47907.  All rights reserved.
8433d6423SLionel Sambuc  *
9433d6423SLionel Sambuc  *	Written by Victor A. Abell <abe@mace.cc.purdue.edu>,  Purdue
10433d6423SLionel Sambuc  *	University Computing Center.  Not derived from licensed software;
11433d6423SLionel Sambuc  *	derived from awf(1) by Henry Spencer of the University of Toronto.
12433d6423SLionel Sambuc  *
13433d6423SLionel Sambuc  *	Permission is granted to anyone to use this software for any
14433d6423SLionel Sambuc  *	purpose on any computer system, and to alter it and redistribute
15433d6423SLionel Sambuc  *	it freely, subject to the following restrictions:
16433d6423SLionel Sambuc  *
17433d6423SLionel Sambuc  *	1. The author is not responsible for any consequences of use of
18433d6423SLionel Sambuc  *	   this software, even if they arise from flaws in it.
19433d6423SLionel Sambuc  *
20433d6423SLionel Sambuc  *	2. The origin of this software must not be misrepresented, either
21433d6423SLionel Sambuc  *	   by explicit claim or by omission.  Credits must appear in the
22433d6423SLionel Sambuc  *	   documentation.
23433d6423SLionel Sambuc  *
24433d6423SLionel Sambuc  *	3. Altered versions must be plainly marked as such, and must not
25433d6423SLionel Sambuc  *	   be misrepresented as being the original software.  Credits must
26433d6423SLionel Sambuc  *	   appear in the documentation.
27433d6423SLionel Sambuc  *
28433d6423SLionel Sambuc  *	4. This notice may not be removed or altered.
29433d6423SLionel Sambuc  */
30433d6423SLionel Sambuc 
31433d6423SLionel Sambuc #include "cawf.h"
32433d6423SLionel Sambuc #include <ctype.h>
33433d6423SLionel Sambuc 
34433d6423SLionel Sambuc /*
35433d6423SLionel Sambuc  * Pass2(line) - process the nroff requests in a line and break
36433d6423SLionel Sambuc  *		 text into words for pass 3
37433d6423SLionel Sambuc  */
38433d6423SLionel Sambuc 
Pass2(unsigned char * line)39d9494baaSJacob Adams void Pass2(unsigned char *line) {
40433d6423SLionel Sambuc 	int brk;			/* request break status */
41433d6423SLionel Sambuc 	unsigned char buf[MAXLINE];	/* working buffer */
42433d6423SLionel Sambuc 	unsigned char c;		/* character buffer */
43433d6423SLionel Sambuc 	double d;			/* temporary double */
44433d6423SLionel Sambuc 	double exscale;			/* expression scaling factor */
45433d6423SLionel Sambuc 	double expr[MAXEXP];            /* expressions */
46433d6423SLionel Sambuc 	unsigned char exsign[MAXEXP];	/* expression signs */
47433d6423SLionel Sambuc 	int i, j;			/* temporary indexes */
48433d6423SLionel Sambuc 	int inword;			/* word processing status */
49433d6423SLionel Sambuc 	int nexpr;			/* number of expressions */
50433d6423SLionel Sambuc 	unsigned char nm[4], nm1[4];	/* names */
51433d6423SLionel Sambuc 	int nsp;			/* number of spaces */
52433d6423SLionel Sambuc 	unsigned char op;		/* expression term operator */
53433d6423SLionel Sambuc 	unsigned char opstack[MAXSP];	/* expression operation stack */
54433d6423SLionel Sambuc 	unsigned char period;		/* end of word status */
55433d6423SLionel Sambuc 	unsigned char *s1, *s2, *s3;	/* temporary string pointers */
56433d6423SLionel Sambuc 	double sexpr[MAXEXP];           /* signed expressions */
57433d6423SLionel Sambuc 	int sp;				/* expression stack pointer */
58433d6423SLionel Sambuc 	unsigned char ssign;		/* expression's starting sign */
59433d6423SLionel Sambuc 	int tabpos;			/* tab position */
60433d6423SLionel Sambuc 	double tscale;			/* term scaling factor */
61433d6423SLionel Sambuc 	double tval;			/* term value */
62433d6423SLionel Sambuc 	double val;			/* term value */
63433d6423SLionel Sambuc 	double valstack[MAXSP];		/* expression value stack */
64433d6423SLionel Sambuc 	unsigned char xbuf[MAXLINE];	/* expansion buffer */
65433d6423SLionel Sambuc 
66433d6423SLionel Sambuc 	if (line == NULL) {
67433d6423SLionel Sambuc     /*
68433d6423SLionel Sambuc      * End of macro expansion.
69433d6423SLionel Sambuc      */
70433d6423SLionel Sambuc 		Pass3(DOBREAK, (unsigned char *)"need", NULL, 999);
71433d6423SLionel Sambuc 		return;
72433d6423SLionel Sambuc 	}
73433d6423SLionel Sambuc     /*
74433d6423SLionel Sambuc      * Adjust line number.
75433d6423SLionel Sambuc      */
76433d6423SLionel Sambuc 	if (Lockil == 0)
77433d6423SLionel Sambuc 		P2il++;
78433d6423SLionel Sambuc     /*
79433d6423SLionel Sambuc      * Empty line - "^[ \t]*$" or "^\\\"".
80433d6423SLionel Sambuc      */
81433d6423SLionel Sambuc 	if (regexec(Pat[6].pat, line)
82433d6423SLionel Sambuc 	||  strncmp((char *)line, "\\\"", 2) == 0) {
83433d6423SLionel Sambuc 		Pass3(DOBREAK, (unsigned char *)"space", NULL, 0);
84433d6423SLionel Sambuc 		return;
85433d6423SLionel Sambuc 	}
86433d6423SLionel Sambuc     /*
87433d6423SLionel Sambuc      * Line begins with white space.
88433d6423SLionel Sambuc      */
89433d6423SLionel Sambuc 	if (*line == ' ' || *line == '\t') {
90433d6423SLionel Sambuc 		Pass3(DOBREAK, (unsigned char *)"flush", NULL, 0);
91433d6423SLionel Sambuc 		Pass3(0, (unsigned char *)"", NULL, 0);
92433d6423SLionel Sambuc 	}
93433d6423SLionel Sambuc 	if (*line != '.' && *line != '\'') {
94433d6423SLionel Sambuc     /*
95433d6423SLionel Sambuc      * Line contains text (not an nroff request).
96433d6423SLionel Sambuc      */
97433d6423SLionel Sambuc 		if (Font[0] == 'R' && Backc == 0 && Aftnxt == NULL
98433d6423SLionel Sambuc 		&&  regexec(Pat[7].pat, line) == 0) {
99433d6423SLionel Sambuc 		    /*
100433d6423SLionel Sambuc 		     * The font is Roman, there is no "\\c" or "after next"
101433d6423SLionel Sambuc 		     * trap pending and and the line has no '\\', '\t', '-',
102433d6423SLionel Sambuc 		     * or "  "  (regular expression "\\|\t|-|  ").
103433d6423SLionel Sambuc 		     *
104433d6423SLionel Sambuc 		     * Output each word of the line as "<length> <word>".
105433d6423SLionel Sambuc 		     */
106433d6423SLionel Sambuc 			for (s1 = line;;) {
107*4d370891SDavid van Moolenbroek 				while (*s1 == ' ')
108433d6423SLionel Sambuc 					s1++;
109433d6423SLionel Sambuc 				if (*s1 == '\0')
110433d6423SLionel Sambuc 					break;
111433d6423SLionel Sambuc 				for (s2 = s1, s3 = buf; *s2 && *s2 != ' ';)
112433d6423SLionel Sambuc 				    *s3++ = Trtbl[(int)*s2++];
113433d6423SLionel Sambuc 				*s3 = '\0';
114433d6423SLionel Sambuc 				Pass3((s2 - s1), buf, NULL, 0);
115433d6423SLionel Sambuc 				s1 = *s2 ? ++s2 : s2;
116433d6423SLionel Sambuc 			}
117433d6423SLionel Sambuc 		    /*
118433d6423SLionel Sambuc 		     * Line terminates with punctuation and optional
119433d6423SLionel Sambuc 		     * bracketing (regular expression "[.!?:][\])'\"*]*$").
120433d6423SLionel Sambuc 		     */
121433d6423SLionel Sambuc 			if (regexec(Pat[8].pat, line))
122433d6423SLionel Sambuc 				Pass3(NOBREAK, (unsigned char *)"gap", NULL, 2);
123433d6423SLionel Sambuc 			if (Centering > 0) {
124433d6423SLionel Sambuc 				Pass3(DOBREAK,(unsigned char *)"center", NULL,
125433d6423SLionel Sambuc 					0);
126433d6423SLionel Sambuc 				Centering--;
127433d6423SLionel Sambuc 			} else if (Fill == 0)
128433d6423SLionel Sambuc 				Pass3(DOBREAK, (unsigned char *)"flush", NULL,
129433d6423SLionel Sambuc 					0);
130433d6423SLionel Sambuc 			return;
131433d6423SLionel Sambuc 		}
132433d6423SLionel Sambuc 	    /*
133433d6423SLionel Sambuc 	     * Line must be scanned a character at a time.
134433d6423SLionel Sambuc 	     */
135433d6423SLionel Sambuc 		inword = nsp = tabpos = 0;
136433d6423SLionel Sambuc 		period = '\0';
137433d6423SLionel Sambuc 		for (s1 = line;; s1++) {
138433d6423SLionel Sambuc 		    /*
139433d6423SLionel Sambuc 		     * Space or TAB causes state transition.
140433d6423SLionel Sambuc 		     */
141433d6423SLionel Sambuc 			if (*s1 == '\0' || *s1 == ' ' || *s1 == '\t') {
142433d6423SLionel Sambuc 				if (inword) {
143433d6423SLionel Sambuc 					if (!Backc) {
144433d6423SLionel Sambuc 						Endword();
145433d6423SLionel Sambuc 						Pass3(Wordl, Word, NULL, 0);
146433d6423SLionel Sambuc 						if (Uhyph) {
147433d6423SLionel Sambuc 						  Pass3(NOBREAK,
148433d6423SLionel Sambuc 						    (unsigned char *)"nohyphen",
149433d6423SLionel Sambuc 						    NULL, 0);
150433d6423SLionel Sambuc 						}
151433d6423SLionel Sambuc 					}
152433d6423SLionel Sambuc 					inword = 0;
153433d6423SLionel Sambuc 					nsp = 0;
154433d6423SLionel Sambuc 				}
155433d6423SLionel Sambuc 				if (*s1 == '\0')
156433d6423SLionel Sambuc 					break;
157433d6423SLionel Sambuc 			} else {
158433d6423SLionel Sambuc 				if (inword == 0) {
159433d6423SLionel Sambuc 					if (Backc == 0) {
160433d6423SLionel Sambuc 						Wordl = Wordx = 0;
161433d6423SLionel Sambuc 						Uhyph = 0;
162433d6423SLionel Sambuc 					}
163433d6423SLionel Sambuc 					Backc = 0;
164433d6423SLionel Sambuc 					inword = 1;
165433d6423SLionel Sambuc 					if (nsp > 1) {
166433d6423SLionel Sambuc 						Pass3(NOBREAK,
167433d6423SLionel Sambuc 						    (unsigned char *)"gap",
168433d6423SLionel Sambuc 						    NULL, nsp);
169433d6423SLionel Sambuc 					}
170433d6423SLionel Sambuc 				}
171433d6423SLionel Sambuc 			}
172433d6423SLionel Sambuc 		    /*
173433d6423SLionel Sambuc 		     * Process a character.
174433d6423SLionel Sambuc 		     */
175433d6423SLionel Sambuc 			switch (*s1) {
176433d6423SLionel Sambuc 		    /*
177433d6423SLionel Sambuc 		     * Space
178433d6423SLionel Sambuc 		     */
179433d6423SLionel Sambuc 	     		case ' ':
180433d6423SLionel Sambuc 				nsp++;
181433d6423SLionel Sambuc 				period = '\0';
182433d6423SLionel Sambuc 				break;
183433d6423SLionel Sambuc 		    /*
184433d6423SLionel Sambuc 		     * TAB
185433d6423SLionel Sambuc 		     */
186433d6423SLionel Sambuc 	     		case '\t':
187433d6423SLionel Sambuc 				tabpos++;
188433d6423SLionel Sambuc 				if (tabpos <= Ntabs) {
189433d6423SLionel Sambuc 					Pass3(NOBREAK,
190433d6423SLionel Sambuc 					    (unsigned char *)"tabto", NULL,
191433d6423SLionel Sambuc 					    Tabs[tabpos-1]);
192433d6423SLionel Sambuc 				}
193433d6423SLionel Sambuc 				nsp = 0;
194433d6423SLionel Sambuc 				period = '\0';
195433d6423SLionel Sambuc 				break;
196433d6423SLionel Sambuc 		    /*
197433d6423SLionel Sambuc 		     * Hyphen if word is being assembled
198433d6423SLionel Sambuc 		     */
199433d6423SLionel Sambuc 			case '-':
200433d6423SLionel Sambuc 				if (Wordl <= 0)
201433d6423SLionel Sambuc 				    goto ordinary_char;
202433d6423SLionel Sambuc 				if ((i = Findhy(NULL, 0, 0)) < 0) {
203433d6423SLionel Sambuc 				    Error(WARN, LINE, " no hyphen for font ",
204433d6423SLionel Sambuc 					(char *)Font);
205433d6423SLionel Sambuc 				    return;
206433d6423SLionel Sambuc 				}
207433d6423SLionel Sambuc 				Endword();
208433d6423SLionel Sambuc 				Pass3(Wordl, Word, NULL, Hychar[i].len);
209433d6423SLionel Sambuc 				Pass3(NOBREAK, (unsigned char *)"userhyphen",
210433d6423SLionel Sambuc 				    Hychar[i].str, Hychar[i].len);
211433d6423SLionel Sambuc 				Wordl = Wordx = 0;
212433d6423SLionel Sambuc 				period = '\0';
213433d6423SLionel Sambuc 				Uhyph = 1;
214433d6423SLionel Sambuc 				break;
215433d6423SLionel Sambuc 		    /*
216433d6423SLionel Sambuc 		     * Backslash
217433d6423SLionel Sambuc 		     */
218433d6423SLionel Sambuc 			case '\\':
219433d6423SLionel Sambuc 				s1++;
220433d6423SLionel Sambuc 				switch(*s1) {
221433d6423SLionel Sambuc 			    /*
222433d6423SLionel Sambuc 			     * Comment - "\\\""
223433d6423SLionel Sambuc 			     */
224433d6423SLionel Sambuc 				case '"':
225433d6423SLionel Sambuc 					while (*(s1+1))
226433d6423SLionel Sambuc 						s1++;
227433d6423SLionel Sambuc 					break;
228433d6423SLionel Sambuc 			    /*
229433d6423SLionel Sambuc 			     * Change font - "\\fN"
230433d6423SLionel Sambuc 			     */
231433d6423SLionel Sambuc 				case 'f':
232433d6423SLionel Sambuc 					s1 = Asmcode(&s1, nm);
233433d6423SLionel Sambuc 					if (nm[0] == 'P') {
234433d6423SLionel Sambuc 					    Font[0] = Prevfont;
235433d6423SLionel Sambuc 					    break;
236433d6423SLionel Sambuc 					}
237433d6423SLionel Sambuc 					for (i = 0; Fcode[i].nm; i++) {
238433d6423SLionel Sambuc 					    if (Fcode[i].nm == nm[0])
239433d6423SLionel Sambuc 						break;
240433d6423SLionel Sambuc 					}
241433d6423SLionel Sambuc 					if (Fcode[i].nm == '\0'
242433d6423SLionel Sambuc 					||  nm[1] != '\0') {
243433d6423SLionel Sambuc 					    Error(WARN, LINE, " unknown font ",
244433d6423SLionel Sambuc 					    	(char *)nm);
245433d6423SLionel Sambuc 					    break;
246433d6423SLionel Sambuc 					}
247433d6423SLionel Sambuc 					if (Fcode[i].status != '1') {
248433d6423SLionel Sambuc 					    Error(WARN, LINE,
249433d6423SLionel Sambuc 						" font undefined ", (char *)nm);
250433d6423SLionel Sambuc 					    break;
251433d6423SLionel Sambuc 					} else {
252433d6423SLionel Sambuc 					    Prevfont = Font[0];
253433d6423SLionel Sambuc 					    Font[0] = nm[0];
254433d6423SLionel Sambuc 					}
255433d6423SLionel Sambuc 					break;
256433d6423SLionel Sambuc 			    /*
257433d6423SLionel Sambuc 			     * Positive horizontal motion - "\\h\\n(NN" or
258433d6423SLionel Sambuc 			     * "\\h\\nN"
259433d6423SLionel Sambuc 			     */
260433d6423SLionel Sambuc 				case 'h':
261433d6423SLionel Sambuc 					if (s1[1] != '\\' || s1[2] != 'n') {
262433d6423SLionel Sambuc 					    Error(WARN, LINE,
263433d6423SLionel Sambuc 						" no \\n after \\h", NULL);
264433d6423SLionel Sambuc 					    break;
265433d6423SLionel Sambuc 					}
266433d6423SLionel Sambuc 					s1 +=2;
267433d6423SLionel Sambuc 					s1 = Asmcode(&s1, nm);
268433d6423SLionel Sambuc 					if ((i = Findnum(nm, 0, 0)) < 0)
269433d6423SLionel Sambuc 						goto unknown_num;
270433d6423SLionel Sambuc 					if ((j = Numb[i].val) < 0) {
271433d6423SLionel Sambuc 					    Error(WARN, LINE, " \\h < 0 ",
272433d6423SLionel Sambuc 					    NULL);
273433d6423SLionel Sambuc 					    break;
274433d6423SLionel Sambuc 					}
275433d6423SLionel Sambuc 					if (j == 0)
276433d6423SLionel Sambuc 						break;
277433d6423SLionel Sambuc 					if ((strlen((char *)s1+1) + j + 1)
278433d6423SLionel Sambuc 					>=  MAXLINE)
279433d6423SLionel Sambuc 						goto line_too_long;
280433d6423SLionel Sambuc 					for (s2 = &xbuf[1]; j; j--)
281433d6423SLionel Sambuc 						*s2++ = ' ';
282433d6423SLionel Sambuc 					(void) strcpy((char *)s2, (char *)s1+1);
283433d6423SLionel Sambuc 					s1 = xbuf;
284433d6423SLionel Sambuc 					break;
285433d6423SLionel Sambuc 			    /*
286433d6423SLionel Sambuc 			     * Save current position in register if "\\k<reg>"
287433d6423SLionel Sambuc 			     */
288433d6423SLionel Sambuc 			        case 'k':
289433d6423SLionel Sambuc 					s1 = Asmcode(&s1, nm);
290433d6423SLionel Sambuc 					if ((i = Findnum(nm, 0, 0)) < 0)
291433d6423SLionel Sambuc 					    i = Findnum(nm, 0, 1);
292433d6423SLionel Sambuc 					Numb[i].val =
293433d6423SLionel Sambuc 						(int)((double)Outll * Scalen);
294433d6423SLionel Sambuc 					break;
295433d6423SLionel Sambuc 			    /*
296433d6423SLionel Sambuc 			     * Interpolate number - "\\n(NN" or "\\nN"
297433d6423SLionel Sambuc 			     */
298433d6423SLionel Sambuc 				case 'n':
299433d6423SLionel Sambuc 					s1 = Asmcode(&s1, nm);
300433d6423SLionel Sambuc 					if ((i = Findnum(nm, 0, 0)) < 0) {
301433d6423SLionel Sambuc unknown_num:
302433d6423SLionel Sambuc 					    Error(WARN, LINE,
303433d6423SLionel Sambuc 					        " unknown number register ",
304433d6423SLionel Sambuc 						(char *)nm);
305433d6423SLionel Sambuc 					    break;
306433d6423SLionel Sambuc 					}
307433d6423SLionel Sambuc 					(void) sprintf((char *)buf, "%d",
308433d6423SLionel Sambuc 					    Numb[i].val);
309433d6423SLionel Sambuc 					if ((strlen((char *)buf)
310433d6423SLionel Sambuc 					   + strlen((char *)s1+1) + 1)
311433d6423SLionel Sambuc 					>=  MAXLINE) {
312433d6423SLionel Sambuc line_too_long:
313433d6423SLionel Sambuc 					    Error(WARN, LINE, " line too long",
314433d6423SLionel Sambuc 					        NULL);
315433d6423SLionel Sambuc 					    break;
316433d6423SLionel Sambuc 					}
317433d6423SLionel Sambuc 					(void) sprintf((char *)buf, "%d%s",
318433d6423SLionel Sambuc 					    Numb[i].val, (char *)s1+1);
319433d6423SLionel Sambuc 					(void) strcpy((char *)&xbuf[1],
320433d6423SLionel Sambuc 						(char *)buf);
321433d6423SLionel Sambuc 				        s1 = xbuf;
322433d6423SLionel Sambuc 					break;
323433d6423SLionel Sambuc 			    /*
324433d6423SLionel Sambuc 			     * Change size - "\\s[+-][0-9]" - NOP
325433d6423SLionel Sambuc 			     */
326433d6423SLionel Sambuc 				case 's':
327433d6423SLionel Sambuc 					s1++;
328433d6423SLionel Sambuc 					if (*s1 == '+' || *s1 == '-')
329433d6423SLionel Sambuc 						s1++;
330433d6423SLionel Sambuc 					while (*s1 && isdigit(*s1))
331433d6423SLionel Sambuc 						s1++;
332433d6423SLionel Sambuc 					s1--;
333433d6423SLionel Sambuc 					break;
334433d6423SLionel Sambuc 			    /*
335433d6423SLionel Sambuc 			     * Continue - "\\c"
336433d6423SLionel Sambuc 			     */
337433d6423SLionel Sambuc 				case 'c':
338433d6423SLionel Sambuc 					Backc = 1;
339433d6423SLionel Sambuc 					break;
340433d6423SLionel Sambuc 			    /*
341433d6423SLionel Sambuc 			     * Interpolate string - "\\*(NN" or "\\*N"
342433d6423SLionel Sambuc 			     */
343433d6423SLionel Sambuc 				case '*':
344433d6423SLionel Sambuc 					s1 = Asmcode(&s1, nm);
345433d6423SLionel Sambuc 					s2 = Findstr(nm, NULL, 0);
346433d6423SLionel Sambuc 					if (*s2 != '\0') {
347433d6423SLionel Sambuc 					    if ((strlen((char *)s2)
348433d6423SLionel Sambuc 					       + strlen((char *)s1+1) + 1)
349433d6423SLionel Sambuc 					    >=  MAXLINE)
350433d6423SLionel Sambuc 						goto line_too_long;
351433d6423SLionel Sambuc 					    (void) sprintf((char *)buf, "%s%s",
352433d6423SLionel Sambuc 						(char *)s2, (char *)s1+1);
353433d6423SLionel Sambuc 					    (void) strcpy((char *)&xbuf[1],
354433d6423SLionel Sambuc 						(char *)buf);
355433d6423SLionel Sambuc 					    s1 = xbuf;
356433d6423SLionel Sambuc 					}
357433d6423SLionel Sambuc 					break;
358433d6423SLionel Sambuc 			    /*
359433d6423SLionel Sambuc 			     * Discretionary hyphen - "\\%"
360433d6423SLionel Sambuc 			     */
361433d6423SLionel Sambuc 				case '%':
362433d6423SLionel Sambuc 					if (Wordl <= 0)
363433d6423SLionel Sambuc 					    break;
364433d6423SLionel Sambuc 					if ((i = Findhy(NULL, 0, 0)) < 0) {
365433d6423SLionel Sambuc 					    Error(WARN, LINE,
366433d6423SLionel Sambuc 					        " no hyphen for font ",
367433d6423SLionel Sambuc 						(char *)Font);
368433d6423SLionel Sambuc 					    break;
369433d6423SLionel Sambuc 					}
370433d6423SLionel Sambuc 					Endword();
371433d6423SLionel Sambuc 					Pass3(Wordl, Word, NULL, Hychar[i].len);
372433d6423SLionel Sambuc 					Pass3(NOBREAK,
373433d6423SLionel Sambuc 					    (unsigned char *) "hyphen",
374433d6423SLionel Sambuc 					    Hychar[i].str, Hychar[i].len);
375433d6423SLionel Sambuc 					Wordl = Wordx = 0;
376433d6423SLionel Sambuc 					Uhyph = 1;
377433d6423SLionel Sambuc 					break;
378433d6423SLionel Sambuc 			    /*
379433d6423SLionel Sambuc 			     * None of the above - may be special character
380433d6423SLionel Sambuc 			     * name.
381433d6423SLionel Sambuc 			     */
382433d6423SLionel Sambuc 				default:
383433d6423SLionel Sambuc 					s2 = s1--;
384433d6423SLionel Sambuc 					s1 = Asmcode(&s1, nm);
385433d6423SLionel Sambuc 					if ((i = Findchar(nm, 0, NULL, 0)) < 0){
386433d6423SLionel Sambuc 					    s1 = s2;
387433d6423SLionel Sambuc 					    goto ordinary_char;
388433d6423SLionel Sambuc 					}
389433d6423SLionel Sambuc 					if (strcmp((char *)nm, "em") == 0
390433d6423SLionel Sambuc 					&& Wordx > 0) {
391433d6423SLionel Sambuc 				    /*
392433d6423SLionel Sambuc 				     * "\\(em" is a special case when a word
393433d6423SLionel Sambuc 				     * has been assembled, because of
394433d6423SLionel Sambuc 				     * hyphenation.
395433d6423SLionel Sambuc 				     */
396433d6423SLionel Sambuc 					    Endword();
397433d6423SLionel Sambuc 					    Pass3(Wordl, Word, NULL,
398433d6423SLionel Sambuc 					        Schar[i].len);
399433d6423SLionel Sambuc 					    Pass3(NOBREAK,
400433d6423SLionel Sambuc 						(unsigned char *)"userhyphen",
401433d6423SLionel Sambuc 					        Schar[i].str, Schar[i].len);
402433d6423SLionel Sambuc 				            Wordl = Wordx = 0;
403433d6423SLionel Sambuc 					    period = '\0';
404433d6423SLionel Sambuc 					    Uhyph = 1;
405433d6423SLionel Sambuc 			 		}
406433d6423SLionel Sambuc 				    /*
407433d6423SLionel Sambuc 				     * Interpolate a special character
408433d6423SLionel Sambuc 				     */
409433d6423SLionel Sambuc 					if (Str2word(Schar[i].str,
410433d6423SLionel Sambuc 					    strlen((char *)Schar[i].str)) != 0)
411433d6423SLionel Sambuc 						return;
412433d6423SLionel Sambuc 				        Wordl += Schar[i].len;
413433d6423SLionel Sambuc 					period = '\0';
414433d6423SLionel Sambuc 				}
415433d6423SLionel Sambuc 				break;
416433d6423SLionel Sambuc 		    /*
417433d6423SLionel Sambuc 		     * Ordinary character
418433d6423SLionel Sambuc 		     */
419433d6423SLionel Sambuc 			default:
420433d6423SLionel Sambuc ordinary_char:
421433d6423SLionel Sambuc 				if (Str2word(s1, 1) != 0)
422433d6423SLionel Sambuc 					return;
423433d6423SLionel Sambuc 				Wordl++;
424433d6423SLionel Sambuc 				if (*s1 == '.' || *s1 == '!'
425433d6423SLionel Sambuc 				||  *s1 == '?' || *s1 == ':')
426433d6423SLionel Sambuc 				    period = '.';
427433d6423SLionel Sambuc 				else if (period == '.') {
428433d6423SLionel Sambuc 				    nm[0] = *s1;
429433d6423SLionel Sambuc 				    nm[1] = '\0';
430433d6423SLionel Sambuc 				    if (regexec(Pat[13].pat, nm) == 0)
431433d6423SLionel Sambuc 					 period = '\0';
432433d6423SLionel Sambuc 				}
433433d6423SLionel Sambuc 			}
434433d6423SLionel Sambuc 		}
435433d6423SLionel Sambuc 	    /*
436433d6423SLionel Sambuc 	     * End of line processing
437433d6423SLionel Sambuc 	     */
438433d6423SLionel Sambuc      		if (!Backc) {
439433d6423SLionel Sambuc 			if (period == '.')
440433d6423SLionel Sambuc 				Pass3(NOBREAK, (unsigned char *)"gap", NULL, 2);
441433d6423SLionel Sambuc 			if (Centering > 0) {
442433d6423SLionel Sambuc 				Pass3(DOBREAK, (unsigned char *)"center", NULL,
443433d6423SLionel Sambuc 				0);
444433d6423SLionel Sambuc 				Centering--;
445433d6423SLionel Sambuc 			} else if (!Fill)
446433d6423SLionel Sambuc 				Pass3(DOBREAK, (unsigned char *)"flush", NULL,
447433d6423SLionel Sambuc 				0);
448433d6423SLionel Sambuc 		}
449433d6423SLionel Sambuc 		if (Aftnxt == NULL)
450433d6423SLionel Sambuc 			return;
451433d6423SLionel Sambuc 		/* else fall through to process an "after next trap */
452433d6423SLionel Sambuc 	}
453433d6423SLionel Sambuc     /*
454433d6423SLionel Sambuc      * Special -man macro handling.
455433d6423SLionel Sambuc      */
456433d6423SLionel Sambuc 	if (Marg == MANMACROS) {
457433d6423SLionel Sambuc 	    /*
458433d6423SLionel Sambuc 	     * A text line - "^[^.]" - is only processed when there is an
459433d6423SLionel Sambuc 	     * "after next" directive.
460433d6423SLionel Sambuc 	     */
461433d6423SLionel Sambuc 		if (*line != '.' && *line != '\'') {
462433d6423SLionel Sambuc 			if (Aftnxt != NULL) {
463433d6423SLionel Sambuc 				if (regexec(Pat[9].pat, Aftnxt))  /* ",fP" */
464433d6423SLionel Sambuc 					Font[0] = Prevfont;
465433d6423SLionel Sambuc 				if (regexec(Pat[16].pat, Aftnxt))  /* ",fR" */
466433d6423SLionel Sambuc 					Font[0] = 'R';
467433d6423SLionel Sambuc 				if (regexec(Pat[10].pat, Aftnxt))  /* ",tP" */
468433d6423SLionel Sambuc 					Pass3(DOBREAK,
469433d6423SLionel Sambuc 						(unsigned char *)"toindent",
470433d6423SLionel Sambuc 						NULL, 0);
471433d6423SLionel Sambuc 				Free(&Aftnxt);
472433d6423SLionel Sambuc 			}
473433d6423SLionel Sambuc 			return;
474433d6423SLionel Sambuc 		}
475433d6423SLionel Sambuc 	    /*
476433d6423SLionel Sambuc 	     * Special footer handling - "^.lF"
477433d6423SLionel Sambuc 	     */
478433d6423SLionel Sambuc 		if (line[1] == 'l' && line[2] == 'F') {
479433d6423SLionel Sambuc 			s1 = Findstr((unsigned char *)"by", NULL, 0);
480433d6423SLionel Sambuc 			s2 = Findstr((unsigned char *)"nb", NULL, 0);
481433d6423SLionel Sambuc 			if (*s1 == '\0' || *s2 == '\0')
482433d6423SLionel Sambuc 				(void) sprintf((char *)buf, "%s%s",
483433d6423SLionel Sambuc 					(char *)s1, (char *)s2);
484433d6423SLionel Sambuc 			else
485433d6423SLionel Sambuc 				(void) sprintf((char *)buf, "%s; %s",
486433d6423SLionel Sambuc 					(char *)s1, (char *)s2);
487433d6423SLionel Sambuc 			Pass3(NOBREAK, (unsigned char *)"LF", buf, 0);
488433d6423SLionel Sambuc 			return;
489433d6423SLionel Sambuc 		}
490433d6423SLionel Sambuc 	}
491433d6423SLionel Sambuc     /*
492433d6423SLionel Sambuc      * Special -ms macro handling.
493433d6423SLionel Sambuc      */
494433d6423SLionel Sambuc 	if (Marg == MSMACROS) {
495433d6423SLionel Sambuc 	    /*
496433d6423SLionel Sambuc 	     * A text line - "^[^.]" - is only processed when there is an
497433d6423SLionel Sambuc 	     * "after next" directive.
498433d6423SLionel Sambuc 	     */
499433d6423SLionel Sambuc 		if (*line != '.' && *line != '\'') {
500433d6423SLionel Sambuc 			if (Aftnxt != NULL) {
501433d6423SLionel Sambuc 				if (regexec(Pat[10].pat, Aftnxt))  /* ",tP" */
502433d6423SLionel Sambuc 					Pass3(DOBREAK,
503433d6423SLionel Sambuc 						(unsigned char *)"toindent",
504433d6423SLionel Sambuc 						NULL, 0);
505433d6423SLionel Sambuc 				Free(&Aftnxt);
506433d6423SLionel Sambuc 			}
507433d6423SLionel Sambuc 			return;
508433d6423SLionel Sambuc 		}
509433d6423SLionel Sambuc 	    /*
510433d6423SLionel Sambuc 	     * Numbered headings - "^[.']nH"
511433d6423SLionel Sambuc 	     */
512433d6423SLionel Sambuc 		if (line[1] == 'n' && line[2] == 'H') {
513433d6423SLionel Sambuc 			s1 = Field(2, line, 0);
514433d6423SLionel Sambuc 			if (s1 != NULL) {
515433d6423SLionel Sambuc 				i = atoi((char *)s1) - 1;
516433d6423SLionel Sambuc 				if (i < 0) {
517433d6423SLionel Sambuc 					for (j = 0; j < MAXNHNR; j++) {
518433d6423SLionel Sambuc 						Nhnr[j] = 0;
519433d6423SLionel Sambuc 					}
520433d6423SLionel Sambuc 					i = 0;
521433d6423SLionel Sambuc 				} else if (i >= MAXNHNR) {
522433d6423SLionel Sambuc 				    (void) sprintf((char *)buf,
523433d6423SLionel Sambuc 					" over NH limit (%d)", MAXNHNR);
524433d6423SLionel Sambuc 				    Error(WARN, LINE, (char *)buf, NULL);
525433d6423SLionel Sambuc 				}
526433d6423SLionel Sambuc 			} else
527433d6423SLionel Sambuc 				i = 0;
528433d6423SLionel Sambuc 			Nhnr[i]++;
529433d6423SLionel Sambuc 			for (j = i + 1; j < MAXNHNR; j++) {
530433d6423SLionel Sambuc 				Nhnr[j] = 0;
531433d6423SLionel Sambuc 			}
532433d6423SLionel Sambuc 			s1 = buf;
533433d6423SLionel Sambuc 			for (j = 0; j <= i; j++) {
534433d6423SLionel Sambuc 				(void) sprintf((char *)s1, "%d.", Nhnr[j]);
535433d6423SLionel Sambuc 				s1 = buf + strlen((char *)buf);
536433d6423SLionel Sambuc 			}
537433d6423SLionel Sambuc 			(void) Findstr((unsigned char *)"Nh", buf, 1);
538433d6423SLionel Sambuc 			return;
539433d6423SLionel Sambuc 		}
540433d6423SLionel Sambuc 	}
541433d6423SLionel Sambuc     /*
542433d6423SLionel Sambuc      * Remaining lines should begin with a '.' or '\'' unless an "after next"
543433d6423SLionel Sambuc      * trap has failed.
544433d6423SLionel Sambuc      */
545433d6423SLionel Sambuc 	if (*line != '.' && *line != '\'') {
546433d6423SLionel Sambuc 		if (Aftnxt != NULL)
547433d6423SLionel Sambuc 			Error(WARN, LINE, " failed .it: ", (char *)Aftnxt);
548433d6423SLionel Sambuc 		else
549433d6423SLionel Sambuc 			Error(WARN, LINE, " unrecognized line ", NULL);
550433d6423SLionel Sambuc 		return;
551433d6423SLionel Sambuc 	}
552433d6423SLionel Sambuc 	brk = (*line == '.') ? DOBREAK : NOBREAK;
553433d6423SLionel Sambuc     /*
554433d6423SLionel Sambuc      * Evaluate expressions for "^[.'](ta|ll|ls|in|ti|po|ne|sp|pl|nr)"
555433d6423SLionel Sambuc      * Then process the requests.
556433d6423SLionel Sambuc      */
557433d6423SLionel Sambuc 	if (regexec(Pat[11].pat, &line[1])) {
558433d6423SLionel Sambuc 	    /*
559433d6423SLionel Sambuc 	     * Establish default scale factor.
560433d6423SLionel Sambuc 	     */
561433d6423SLionel Sambuc 		if ((line[1] == 'n' && line[2] == 'e')
562433d6423SLionel Sambuc 		||  (line[1] == 's' && line[2] == 'p')
563433d6423SLionel Sambuc 		||  (line[1] == 'p' && line[2] == 'l'))
564433d6423SLionel Sambuc 			exscale = Scalev;
565433d6423SLionel Sambuc 		else if (line[1] == 'n' && line[2] == 'r')
566433d6423SLionel Sambuc 			exscale = Scaleu;
567433d6423SLionel Sambuc 		else
568433d6423SLionel Sambuc 			exscale = Scalen;
569433d6423SLionel Sambuc 	    /*
570433d6423SLionel Sambuc 	     * Determine starting argument.
571433d6423SLionel Sambuc 	     */
572433d6423SLionel Sambuc 		if (line[1] == 'n' && line[2] == 'r')
573433d6423SLionel Sambuc 			s1 = Field(2, &line[3], 0);
574433d6423SLionel Sambuc 		else
575433d6423SLionel Sambuc 			s1 = Field(1, &line[3], 0);
576433d6423SLionel Sambuc 	    /*
577433d6423SLionel Sambuc 	     * Evaluate expressions.
578433d6423SLionel Sambuc 	     */
579433d6423SLionel Sambuc 		for (nexpr = 0; s1 != NULL &&*s1 != '\0'; ) {
580433d6423SLionel Sambuc 			while (*s1 == ' ' || *s1 == '\t')
581433d6423SLionel Sambuc 				s1++;
582433d6423SLionel Sambuc 			if (*s1 == '+' || *s1 == '-')
583433d6423SLionel Sambuc 				ssign = *s1++;
584433d6423SLionel Sambuc 			else
585433d6423SLionel Sambuc 				ssign = '\0';
586433d6423SLionel Sambuc 		    /*
587433d6423SLionel Sambuc 		     * Process terms.
588433d6423SLionel Sambuc 		     */
589433d6423SLionel Sambuc 			val = 0.0;
590433d6423SLionel Sambuc 			sp = -1;
591433d6423SLionel Sambuc 			c = '+';
592433d6423SLionel Sambuc 			s1--;
593433d6423SLionel Sambuc 			while (c == '+' || c == '*' || c == '%'
594433d6423SLionel Sambuc 			||  c == ')' || c == '-' || c == '/') {
595433d6423SLionel Sambuc 			    op = c;
596433d6423SLionel Sambuc 			    s1++;
597433d6423SLionel Sambuc 			    tscale = exscale;
598433d6423SLionel Sambuc 			    tval = 0.0;
599433d6423SLionel Sambuc 			/*
600433d6423SLionel Sambuc 			 * Pop stack on right parenthesis.
601433d6423SLionel Sambuc 			 */
602433d6423SLionel Sambuc 			    if (op == ')') {
603433d6423SLionel Sambuc 				tval = val;
604433d6423SLionel Sambuc 				if (sp >= 0) {
605433d6423SLionel Sambuc 				    val = valstack[sp];
606433d6423SLionel Sambuc 				    op = opstack[sp];
607433d6423SLionel Sambuc 				    sp--;
608433d6423SLionel Sambuc 				} else {
609433d6423SLionel Sambuc 				    Error(WARN, LINE,
610433d6423SLionel Sambuc 					" expression stack underflow", NULL);
611433d6423SLionel Sambuc 				    return;
612433d6423SLionel Sambuc 				}
613433d6423SLionel Sambuc 				tscale = Scaleu;
614433d6423SLionel Sambuc 			/*
615433d6423SLionel Sambuc 			 * Push stack on left parenthesis.
616433d6423SLionel Sambuc 			 */
617433d6423SLionel Sambuc 			    } else if (*s1 == '(') {
618433d6423SLionel Sambuc 				sp++;
619433d6423SLionel Sambuc 				if (sp >= MAXSP) {
620433d6423SLionel Sambuc 				    Error(WARN, LINE,
621433d6423SLionel Sambuc 				       " expression stack overflow", NULL);
622433d6423SLionel Sambuc 				    return;
623433d6423SLionel Sambuc 				}
624433d6423SLionel Sambuc 				valstack[sp] = val;
625433d6423SLionel Sambuc 				opstack[sp] = op;
626433d6423SLionel Sambuc 				val = 0.0;
627433d6423SLionel Sambuc 				c = '+';
628433d6423SLionel Sambuc 				continue;
629433d6423SLionel Sambuc 			    } else if (*s1 == '\\') {
630433d6423SLionel Sambuc 			      s1++;
631433d6423SLionel Sambuc 			      switch(*s1) {
632433d6423SLionel Sambuc 			/*
633433d6423SLionel Sambuc 			 * "\\"" begins a comment.
634433d6423SLionel Sambuc 			 */
635433d6423SLionel Sambuc 			      case '"':
636433d6423SLionel Sambuc 				while (*s1)
637433d6423SLionel Sambuc 					s1++;
638433d6423SLionel Sambuc 				break;
639433d6423SLionel Sambuc 			/*
640433d6423SLionel Sambuc 			 * Crude width calculation for "\\w"
641433d6423SLionel Sambuc 			 */
642433d6423SLionel Sambuc 			      case 'w':
643433d6423SLionel Sambuc 				s2 = ++s1;
644433d6423SLionel Sambuc 				if (*s1) {
645433d6423SLionel Sambuc 				    s1++;
646433d6423SLionel Sambuc 				    while (*s1 && *s1 != *s2)
647433d6423SLionel Sambuc 					s1++;
648433d6423SLionel Sambuc 				    tval = (double) (s1 - s2 - 1) * Scalen;
649433d6423SLionel Sambuc 				    if (*s1)
650433d6423SLionel Sambuc 					s1++;
651433d6423SLionel Sambuc 				}
652433d6423SLionel Sambuc 				break;
653433d6423SLionel Sambuc 			/*
654433d6423SLionel Sambuc 			 * Interpolate number register if "\\n".
655433d6423SLionel Sambuc 			 */
656433d6423SLionel Sambuc 			      case 'n':
657433d6423SLionel Sambuc 				s1 = Asmcode(&s1, nm);
658433d6423SLionel Sambuc 				if ((i = Findnum(nm, 0, 0)) >= 0)
659433d6423SLionel Sambuc 				    tval = Numb[i].val;
660433d6423SLionel Sambuc 			        s1++;
661433d6423SLionel Sambuc 			     }
662433d6423SLionel Sambuc 			/*
663433d6423SLionel Sambuc 			 * Assemble numeric value.
664433d6423SLionel Sambuc 			 */
665433d6423SLionel Sambuc 			    } else if (*s1 == '.' || isdigit(*s1)) {
666433d6423SLionel Sambuc 				for (i = 0; isdigit(*s1) || *s1 == '.'; s1++) {
667433d6423SLionel Sambuc 				    if (*s1 == '.') {
668433d6423SLionel Sambuc 					i = 10;
669433d6423SLionel Sambuc 					continue;
670433d6423SLionel Sambuc 				    }
671433d6423SLionel Sambuc 				    d = (double) (*s1 - '0');
672433d6423SLionel Sambuc 				    if (i) {
673433d6423SLionel Sambuc 					tval = tval + (d / (double) i);
674433d6423SLionel Sambuc 					i = i * 10;
675433d6423SLionel Sambuc 				    } else
676433d6423SLionel Sambuc 					tval = (tval * 10.0) + d;
677433d6423SLionel Sambuc 				}
678433d6423SLionel Sambuc 			    } else {
679433d6423SLionel Sambuc 			/*
680433d6423SLionel Sambuc 			 * It's not an expression.  Ignore extra scale.
681433d6423SLionel Sambuc 			 */
682433d6423SLionel Sambuc 				if ((i = Findscale((int)*s1, 0.0, 0)) < 0) {
683433d6423SLionel Sambuc 				    (void) sprintf((char *)buf,
684433d6423SLionel Sambuc 					" \"%s\" isn't an expression",
685433d6423SLionel Sambuc 					(char *)s1);
686433d6423SLionel Sambuc 				    Error(WARN, LINE, (char *)buf, NULL);
687433d6423SLionel Sambuc 				}
688433d6423SLionel Sambuc 				s1++;
689433d6423SLionel Sambuc 			    }
690433d6423SLionel Sambuc 			/*
691433d6423SLionel Sambuc 			 * Add term to expression value.
692433d6423SLionel Sambuc 			 */
693433d6423SLionel Sambuc 			    if ((i = Findscale((int)*s1, 0.0, 0)) >= 0) {
694433d6423SLionel Sambuc 				tval *= Scale[i].val;
695433d6423SLionel Sambuc 				s1++;
696433d6423SLionel Sambuc 			    } else
697433d6423SLionel Sambuc 				tval *= tscale;
698433d6423SLionel Sambuc 			    switch (op) {
699433d6423SLionel Sambuc 			    case '+':
700433d6423SLionel Sambuc 				val += tval;
701433d6423SLionel Sambuc 				break;
702433d6423SLionel Sambuc 			    case '-':
703433d6423SLionel Sambuc 				val -= tval;
704433d6423SLionel Sambuc 				break;
705433d6423SLionel Sambuc 			    case '*':
706433d6423SLionel Sambuc 				val *= tval;
707433d6423SLionel Sambuc 				break;
708433d6423SLionel Sambuc 			    case '/':
709433d6423SLionel Sambuc 			    case '%':
710433d6423SLionel Sambuc 				i = (int) val;
711433d6423SLionel Sambuc 				j = (int) tval;
712433d6423SLionel Sambuc 				if (j == 0) {
713433d6423SLionel Sambuc 				    Error(WARN, LINE,
714433d6423SLionel Sambuc 					(*s1 == '/') ? "div" : "mod",
715433d6423SLionel Sambuc 				        " by 0");
716433d6423SLionel Sambuc 				    return;
717433d6423SLionel Sambuc 				}
718433d6423SLionel Sambuc 				if (op == '/')
719433d6423SLionel Sambuc 					val = (double) (i / j);
720433d6423SLionel Sambuc 				else
721433d6423SLionel Sambuc 					val = (double) (i % j);
722433d6423SLionel Sambuc 				break;
723433d6423SLionel Sambuc 			    }
724433d6423SLionel Sambuc 			    c = *s1;
725433d6423SLionel Sambuc 			}
726433d6423SLionel Sambuc 		    /*
727433d6423SLionel Sambuc 		     * Save expression value and sign.
728433d6423SLionel Sambuc 		     */
729433d6423SLionel Sambuc 			if (nexpr >= MAXEXP) {
730433d6423SLionel Sambuc 				(void) sprintf((char *)buf,
731433d6423SLionel Sambuc 				    " at expression limit of %d", MAXEXP);
732433d6423SLionel Sambuc 				Error(WARN, LINE, (char *)buf, NULL);
733433d6423SLionel Sambuc 				return;
734433d6423SLionel Sambuc 			}
735433d6423SLionel Sambuc 			exsign[nexpr] = ssign;
736433d6423SLionel Sambuc 			expr[nexpr] = val;
737433d6423SLionel Sambuc 			if (ssign == '-')
738433d6423SLionel Sambuc 				sexpr[nexpr] = -1.0 * val;
739433d6423SLionel Sambuc 			else
740433d6423SLionel Sambuc 				sexpr[nexpr] = val;
741433d6423SLionel Sambuc 			nexpr++;
742433d6423SLionel Sambuc 			while (*s1 == ' ' || *s1 == '\t')
743433d6423SLionel Sambuc 				s1++;
744433d6423SLionel Sambuc 		}
745433d6423SLionel Sambuc 	    /*
746433d6423SLionel Sambuc 	     * Set parameters "(ll|ls|in|ti|po|pl)"
747433d6423SLionel Sambuc 	     */
748433d6423SLionel Sambuc 		if (regexec(Pat[12].pat, &line[1])) {
749433d6423SLionel Sambuc 			nm[0] = line[1];
750433d6423SLionel Sambuc 			nm[1] = line[2];
751433d6423SLionel Sambuc 			if ((i = Findparms(nm)) < 0) {
752433d6423SLionel Sambuc 				Error(WARN, LINE,
753433d6423SLionel Sambuc 				    " can't find parameter register ",
754433d6423SLionel Sambuc 				    (char *)nm);
755433d6423SLionel Sambuc 				return;
756433d6423SLionel Sambuc 			}
757433d6423SLionel Sambuc 			if (nexpr == 0 || exscale == 0.0)
758433d6423SLionel Sambuc 				j = Parms[i].prev;
759433d6423SLionel Sambuc 			else if (exsign[0] == '\0'
760433d6423SLionel Sambuc 			     ||  (nm[0] == 't' && nm[1] == 'i'))
761433d6423SLionel Sambuc 				 j = (int)(sexpr[0] / exscale);
762433d6423SLionel Sambuc 			else
763433d6423SLionel Sambuc 				j = Parms[i].val + (int)(sexpr[0] / exscale);
764433d6423SLionel Sambuc 			Parms[i].prev = Parms[i].val;
765433d6423SLionel Sambuc 			Parms[i].val = j;
766433d6423SLionel Sambuc 			nm[0] = (nexpr) ? exsign[0] : '\0';     /* for .ti */
767433d6423SLionel Sambuc 			nm[1] = '\0';
768433d6423SLionel Sambuc 			Pass3(brk, (unsigned char *)Parms[i].cmd, nm, j);
769433d6423SLionel Sambuc 			return;
770433d6423SLionel Sambuc 		}
771433d6423SLionel Sambuc 		if (line[1] == 'n') {
772433d6423SLionel Sambuc 			switch(line[2]) {
773433d6423SLionel Sambuc 	    /*
774433d6423SLionel Sambuc 	     * Need - "^[.']ne <expression>"
775433d6423SLionel Sambuc 	     */
776433d6423SLionel Sambuc 			case 'e':
777433d6423SLionel Sambuc 				if (nexpr && Scalev > 0.0)
778433d6423SLionel Sambuc 					i = (int) ((expr[0]/Scalev) + 0.99);
779433d6423SLionel Sambuc 				else
780433d6423SLionel Sambuc 					i = 0;
781433d6423SLionel Sambuc 				Pass3(DOBREAK, (unsigned char *)"need", NULL,
782433d6423SLionel Sambuc 					i);
783433d6423SLionel Sambuc 				return;
784433d6423SLionel Sambuc 	    /*
785433d6423SLionel Sambuc 	     * Number - "^[.']nr <name> <expression>"
786433d6423SLionel Sambuc 	     */
787433d6423SLionel Sambuc 			case 'r':
788433d6423SLionel Sambuc 				if ((s1 = Field(2, line, 0)) == NULL) {
789433d6423SLionel Sambuc 				    Error(WARN, LINE, " bad number register",
790433d6423SLionel Sambuc 				        NULL);
791433d6423SLionel Sambuc 				    return;
792433d6423SLionel Sambuc 				}
793433d6423SLionel Sambuc 				if ((i = Findnum(s1, 0, 0)) < 0)
794433d6423SLionel Sambuc 				    i = Findnum(s1, 0, 1);
795433d6423SLionel Sambuc 				if (nexpr < 1) {
796433d6423SLionel Sambuc 				    Numb[i].val = 0;
797433d6423SLionel Sambuc 				    return;
798433d6423SLionel Sambuc 				}
799433d6423SLionel Sambuc 				if (exsign[0] == '\0')
800433d6423SLionel Sambuc 				    Numb[i].val = (int) expr[0];
801433d6423SLionel Sambuc 				else
802433d6423SLionel Sambuc 				    Numb[i].val += (int) sexpr[0];
803433d6423SLionel Sambuc 				return;
804433d6423SLionel Sambuc 			}
805433d6423SLionel Sambuc 		}
806433d6423SLionel Sambuc 	    /*
807433d6423SLionel Sambuc 	     * Space - "^[.']sp <expression>"
808433d6423SLionel Sambuc 	     */
809433d6423SLionel Sambuc 		if (line[1] == 's' && line[2] == 'p') {
810433d6423SLionel Sambuc 			if (nexpr == 0)
811433d6423SLionel Sambuc 				i = 1;
812433d6423SLionel Sambuc 			else
813433d6423SLionel Sambuc 				i = (int)((expr[0] / Scalev) + 0.99);
814433d6423SLionel Sambuc 			while (i--)
815433d6423SLionel Sambuc 				Pass3(brk, (unsigned char *)"space", NULL, 0);
816433d6423SLionel Sambuc 			return;
817433d6423SLionel Sambuc 		}
818433d6423SLionel Sambuc 	    /*
819433d6423SLionel Sambuc 	     * Tab positions - "^[.']ta <pos1> <pos2> . . ."
820433d6423SLionel Sambuc 	     */
821433d6423SLionel Sambuc      		if (line[1] == 't' && line[2] == 'a') {
822433d6423SLionel Sambuc 			tval = 0.0;
823433d6423SLionel Sambuc 			for (j = 0; j < nexpr; j++) {
824433d6423SLionel Sambuc 				if (exsign[j] == '\0')
825433d6423SLionel Sambuc 					tval = expr[j];
826433d6423SLionel Sambuc 				else
827433d6423SLionel Sambuc 					tval += sexpr[j];
828433d6423SLionel Sambuc 				Tabs[j] = (int) (tval / Scalen);
829433d6423SLionel Sambuc 			}
830433d6423SLionel Sambuc 			Ntabs = nexpr;
831433d6423SLionel Sambuc 			return;
832433d6423SLionel Sambuc 		}
833433d6423SLionel Sambuc 	}
834433d6423SLionel Sambuc     /*
835433d6423SLionel Sambuc      * Process all other nroff requests via Nreq().
836433d6423SLionel Sambuc      */
837433d6423SLionel Sambuc 	(void) Nreq(line, brk);
838433d6423SLionel Sambuc 	return;
839433d6423SLionel Sambuc }
840